Hi,
I don’t know where to send bugreports, so here it is.
I noticed tcp/ip communication problems on our SL8082T modules (gprs, wip) and spent some time to create a minimal example. Didn’t take much - just send data and it gets corrupted. Well, maybe not that simple… The example uses two timers to periodically send some unique bytes to server. I think the error appears even with one timer, but much less frequently (don’t remember which code I had running overnight). With this code, I see about 10 errors per 30 minutes. Changing the timers from 3 seconds to 2 seconds showed no errors during the 30 minutes I tested. Scroll down the code a few lines for a log snippet.
Could be the same problem described here: https://forum.sierrawireless.com/t/lost-data-over-tcp-ip-ssl/7328/1 (lost data over TCP/IP (SSL))
If anybody knows a workaround, I’d very much like to try it. I must be missing something, or misusing something…
-“Open AT Application Framework package”,“2.52.2.A5.201412171046”
-“Open AT OS Package”,“6.52.0.201402271535”
-“Firmware Package”,“7.52.2.A5.201411281219”
-“Internet Library Package”,“5.56.0.201305170830”
#define GPRS_APN "replace"
#define GPRS_USER ""
#define GPRS_PASSWORD ""
#define GPRS_PINCODE "7999"
#define TCP_PEER_STRADDR "replace.com"
#define TCP_PEER_PORT 40900
// 12 errors in 30 minutes
#define HEARTBEAT1_PERIOD 31
#define HEARTBEAT2_PERIOD 32
// no errors in 30 minutes
//#define HEARTBEAT1_PERIOD 21
//#define HEARTBEAT2_PERIOD 22
// -----------------------------------------------------------------------------
//
// netcat can be used on the server to listen for the connection.
//
// example of data corruption (if no errors, wait at least for 30 minutes):
//
// abc@machine: nc -vvv -l 0.0.0.0 40900
// Listening on [0.0.0.0] (family 0, port 40900)
// Connection from [83.180.13.158] port 40900 [tcp/*] accepted (family 2, sport 49152)
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvtuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_``abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrsttuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkljklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// ...
//
/*
ati9
"DWL"," S4_1_0_21BT R2371 CNSHZ-ED-XP0031 2014/11/27 16:53:47","","Sierra Wireless",0,"","00000000","00000000"
"FW","FW_752_A5_68_F2_5.SL808Fx","R7.52.2.A5.201411281219.SL8082T","Sierra Wireless",1804452,"112814 12:19","02e18b16","10002020"
"MODEM 3G+","Revision: S4_1_0_21AP R2371 CNSHZ-ED-XP0031 2014/11/27 16:53:47"
"OAT","1.0.0.20150403050918","MyApplication","Test",109016,"040315 05:09","6318a5a2","10700000"
-"Developer Studio","3.3.0.201501281210"
-"Open AT Application Framework package","2.52.2.A5.201412171046"
-"Open AT OS Package","6.52.0.201402271535"
-"Firmware Package","7.52.2.A5.201411281219"
-"Internet Library Package","5.56.0.201305170830"
"ROM","8400000"
"RAM","4000000"
"OATRAM","b00000"
"DWLNAME","SL808x"
*/
#include "adl_global.h"
#include "generated.h"
#include "wip.h"
// Stack size Declaration
#ifdef __GNU_GCC__
// GCC needs more stack than ARM compilers
#define DECLARE_CALL_STACK(X) (X*3)
#define DECLARE_LOWIRQ_STACK(X) const u32 wm_apmIRQLowLevelStackSize = X*3
#define DECLARE_HIGHIRQ_STACK(X) const u32 wm_apmIRQHighLevelStackSize = X*3
#else
#define DECLARE_CALL_STACK(X) (X)
#define DECLARE_LOWIRQ_STACK(X) const u32 wm_apmIRQLowLevelStackSize = X
#define DECLARE_HIGHIRQ_STACK(X) const u32 wm_apmIRQHighLevelStackSize = X
#endif // #ifndef __GNU_GCC__
/////////////////////////////////////////////////////////////////////////////
#define GPRS_BEARER "GPRS"
#define REG_STATE_REG 1
#define REG_STATE_ROAM 5
#define CREG_POLLING_PERIOD 20
#define ASSERT( pred ) if( !(pred)) TRACE(( 1, "ASSERT %i: " #pred "\n", __LINE__))
static wip_channel_t g_socket;
// every call returns the next byte in a cycle from '1' to 'y', and ends with '\n'.
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// 123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
// ..
static u8 get_next_byte(void)
{
static u8 b = '1';
if (b == 'z') {
b = '1';
return '\n';
} else {
return b++;
}
}
// send len num bytes to g_socket. get the bytes on-by-one from get_next_byte()
static void send_next_bytes(u8 len)
{
if (g_socket && len) {
static u8 buf[255];
memset(buf, '*', sizeof(buf));
u8 i;
for (i = 0; i < len; i++) {
buf[i] = get_next_byte();
}
int n = wip_write(g_socket, buf, len);
if (n <= 0) {
TRACE(( 1, "send_next_bytes wip_write error %i", n ));
}
}
}
static void SendHeartbeat2(u8 Id, void* ctx)
{
send_next_bytes(1);
}
static void SendHeartbeat1(u8 Id, void* ctx)
{
send_next_bytes(3);
}
// Handling events happening on the TCP client socket.
static void cbevh(wip_event_t *ev, void *ctx)
{
switch (ev->kind)
{
case WIP_CEV_OPEN:
{
TRACE((1, "WIP_CEV_OPEN"));
g_socket = ev->channel;
break;
}
case WIP_CEV_READ: break;
case WIP_CEV_WRITE:
{
TRACE((1, "WIP_CEV_WRITE - %d bytes can be written", ev->content.write.writable));
break;
}
case WIP_CEV_ERROR:
case WIP_CEV_PEER_CLOSE:
default:
{
TRACE((1, "WIP_CEV EVENT %d. restart modem.", ev->kind));
wip_close(ev->channel);
g_socket = 0;
break;
}
}
}
static void cbEvhBearer(wip_bearer_t b, s8 event, void *ctx)
{
TRACE((1, "cbEvhBearer: event %i", event));
if (WIP_BEV_IP_CONNECTED == event) {
TRACE(( 1, "cbEvhBearer: connecting to client " TCP_PEER_STRADDR ":%i", TCP_PEER_PORT ));
wip_channel_t socket;
socket = wip_TCPClientCreate(TCP_PEER_STRADDR, TCP_PEER_PORT, cbevh, NULL);
ASSERT(socket);
} else {
TRACE((1, "cbEvhBearer: unknown event. restart modem.")) ;
}
}
static void OpenAndStartBearer(u8 Id, void* ctx)
{
TRACE((1, "OpenAndStartBearer"));
static wip_bearer_t br;
s8 r = wip_bearerOpen(&br, GPRS_BEARER, cbEvhBearer, NULL);
ASSERT(r == OK);
r = wip_bearerSetOpts(br,
WIP_BOPT_GPRS_APN, GPRS_APN,
WIP_BOPT_LOGIN, GPRS_USER,
WIP_BOPT_PASSWORD, GPRS_PASSWORD,
WIP_BOPT_END);
ASSERT(r == OK);
r = wip_bearerStart(br);
ASSERT(OK == r || WIP_BERR_OK_INPROGRESS == r);
}
static void PollCreg(u8 Id, void* ctx);
static bool cbPollCreg(adl_atResponse_t* Params) {
TRACE((1, "cbPollCreg"));
ascii regStateString[300]; // nowhere is said how large this should be to guarantee safety.
wm_strGetParameterString(regStateString, Params->StrData, 2);
s32 regStateInt = wm_atoi(regStateString);
if (REG_STATE_REG == regStateInt || REG_STATE_ROAM == regStateInt) {
TRACE((1, "cbPollCreg: Registered on GPRS network."));
OpenAndStartBearer(0, NULL) ;
} else {
adl_tmrSubscribe(FALSE, CREG_POLLING_PERIOD, ADL_TMR_TYPE_100MS, (adl_tmrHandler_t)PollCreg);
}
return FALSE;
}
static void PollCreg(u8 Id, void* ctx)
{
TRACE((1, "PollCreg: waiting for GPRS network registration."));
adl_atCmdCreate("AT+CREG?", FALSE, (adl_atRspHandler_t)cbPollCreg, ADL_STR_CREG, NULL);
}
static void cbEvhSim(u8 event)
{
TRACE((1, "cbEvhSim: event %d", event));
if (ADL_SIM_EVENT_FULL_INIT == event) {
PollCreg(0, NULL);
}
}
void CfgGprs()
{
TRACE((1, "CfgGprs: waiting for SIM."));
adl_simSubscribe(cbEvhSim, GPRS_PINCODE);
}
void main_task(void)
{
TRACE(( 1, "main_task init" ));
wip_logEvents = true;
adl_tmrSubscribe(TRUE, HEARTBEAT1_PERIOD, ADL_TMR_TYPE_100MS, (adl_tmrHandler_t)SendHeartbeat1);
adl_tmrSubscribe(TRUE, HEARTBEAT2_PERIOD, ADL_TMR_TYPE_100MS, (adl_tmrHandler_t)SendHeartbeat2);
// initialize the network stack
s8 ret = wip_netInitOpts(WIP_NET_OPT_END);
if (OK == ret) {
CfgGprs();
} else {
TRACE((1, "ERROR: net stack init failed: %i : restart modem.", ret));
}
}