* add C027_Support fork
Fork of C027_Support by
Diff: MDM.cpp
- Revision:
- 75:ce6e12067d0c
- Parent:
- 74:208e3e32d263
- Child:
- 76:f7c3dd568dae
diff -r 208e3e32d263 -r ce6e12067d0c MDM.cpp --- a/MDM.cpp Thu May 15 22:20:42 2014 +0000 +++ b/MDM.cpp Fri May 16 14:13:00 2014 +0000 @@ -11,27 +11,40 @@ #define MAX_SIZE 128 //!< max expected messages //! test if it is a socket #define ISSOCKET(s) (((s) >= 0) && ((s) < (sizeof(_sockets)/sizeof(*_sockets)))) - +//! check for timeout +#define TIMEOUT(t, ms) ((ms != TIMEOUT_BLOCKING) && (ms < t.read_ms())) #ifdef MDM_DEBUG void dumpAtCmd(const char* buf, int len) { - printf(" %3d \"", len); + ::printf(" %3d \"", len); while (len --) { char ch = *buf++; - if (ch == '\r') puts("\\r"); - else if (ch == '\n') puts("\\n"); - else if (ch >= 0x20) putchar(ch); - else printf("\\x%02x", ch); + if ((ch > 0x1F) && (ch != 0x7F)) { // is printable + if (ch == '%') ::printf("%%"); + else if (ch == '"') ::printf("\\\""); + else if (ch == '\\') ::printf("\\\\"); + else putchar(ch); + } else { + if (ch == '\a') ::printf("\\a"); // BEL (0x07) + else if (ch == '\b') ::printf("\\b"); // Backspace (0x08) + else if (ch == '\t') ::printf("\\t"); // Horizontal Tab (0x09) + else if (ch == '\n') ::printf("\\n"); // Linefeed (0x0A) + else if (ch == '\v') ::printf("\\v"); // Vertical Tab (0x0B) + else if (ch == '\f') ::printf("\\f"); // Formfeed (0x0C) + else if (ch == '\r') ::printf("\\r"); // Carriage Return (0x0D) + else ::printf("\\x%02x", ch); + } } - puts("\"\r\n"); + ::printf("\"\r\n"); } - #define INFO (_debugLevel >= 1) ? : printf - #define TRACE (_debugLevel >= 2) ? : printf + #define ERROR(fmt) (_debugLevel < 0) ? : ::printf(RED(fmt)) + #define INFO(fmt) (_debugLevel < 1) ? : ::printf(GRE(fmt)) + #define TRACE(...) (_debugLevel < 2) ? : ::printf(__VA_ARGS__) #if 1 // colored terminal output using ANSI escape sequences - #define COL(c,t) "\33[" c t "\33[" "39m" + #define COL(c,t) "\033[" c t "\033[" "39m" #else #define COL(c,t) t #endif @@ -46,6 +59,7 @@ #else + #define ERROR(...) (void)0 // no tracing #define INFO(...) (void)0 // no tracing #define TRACE(...) (void)0 // no tracing @@ -80,7 +94,7 @@ { #ifdef MDM_DEBUG if (_debugLevel >= 3) { - printf("%10.3f AT send ", _debugTime.read_ms()*0.001); + ::printf("%10.3f AT send ", _debugTime.read_ms()*0.001); dumpAtCmd(buf,len); } #endif @@ -117,16 +131,13 @@ (type == TYPE_PLUS) ? CYA(" + ") : (type == TYPE_PROMPT) ? BLU(" > ") : "..." ; - printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s); + ::printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s); dumpAtCmd(buf, len); } #endif if ((ret != WAIT) && (ret != NOT_FOUND)) { int type = TYPE(ret); - if (type == TYPE_OK) return RESP_OK; - if (type == TYPE_ERROR) return RESP_ERROR; - if (type == TYPE_PROMPT) return RESP_PROMPT; // handle unsolicited commands here if (type == TYPE_PLUS) { const char* cmd = buf+3; @@ -208,14 +219,14 @@ if (WAIT != ret) return ret; } + if (type == TYPE_OK) return RESP_OK; + if (type == TYPE_ERROR) return RESP_ERROR; + if (type == TYPE_PROMPT) return RESP_PROMPT; } // relax a bit RELAX_MS(10); } - while ((timeout_ms == TIMEOUT_BLOCKING) || - (timer.read_ms() < timeout_ms)); - timer.stop(); - timer.reset(); + while (!TIMEOUT(timer, timeout_ms)); return WAIT; } @@ -244,28 +255,17 @@ const char* apn, const char* username, const char* password, PinName pn) { - DevStatus devStatus = {}; - bool mdmOk = init(simpin, &devStatus, pn); + bool ok = init(simpin, NULL, pn); #ifdef MDM_DEBUG - if (_debugLevel >= 1) dumpDevStatus(&devStatus); + if (_debugLevel >= 1) dumpDevStatus(&_dev); #endif - if (!mdmOk) + if (!ok) return false; - // wait until we are connected - int i = 180; - NetStatus netStatus = {}; - INFO("Modem::register\r\n"); - while (!checkNetStatus(&netStatus)) - { - if ((netStatus.reg == REG_DENIED) || (i == 0)) - break;; - i --; - RELAX_MS(1000); - } + ok = registerNet(); #ifdef MDM_DEBUG - if (_debugLevel >= 1) dumpNetStatus(&netStatus); + if (_debugLevel >= 1) dumpNetStatus(&_net); #endif - if ((netStatus.reg == REG_DENIED) || (i == 0)) + if (!ok) return false; IP ip = join(apn,username,password); #ifdef MDM_DEBUG @@ -292,9 +292,12 @@ if(RESP_OK == waitFinalResp(NULL,NULL,500)) break; } - if (i < 0) + if (i < 0) { + ERROR("No Reply from Modem"); return false; + } } + INFO("Modem::init\r\n"); // echo off sendFormated("AT E0\r\n"); @@ -363,9 +366,12 @@ if ((RESP_OK != ret) && (RESP_ERROR != ret)) return false; // Enter PIN if needed - if (_dev.sim == SIM_PIN) { + if (_dev.sim == SIM_MISSING) { + ERROR("SIM not inserted\r\n"); + return false; + } else if (_dev.sim == SIM_PIN) { if (!simpin) { - INFO("SIM PIN not available\r\n"); + ERROR("SIM PIN not available\r\n"); return false; } sendFormated("AT+CPIN=%s\r\n", simpin); @@ -398,12 +404,6 @@ sendFormated("AT+CGSN\r\n"); if (RESP_OK != waitFinalResp(_cbString, _dev.imei)) return false; -#if 0 - // Configure New message indication - sendFormated("AT+CNMI=2,1,0,0,0\r\n"); - if (RESP_OK != waitFinalResp()) - return false; -#endif // enable power saving if (_dev.lpm != LPM_DISABLED) { // enable power saving (requires flow control, cts at least) @@ -418,7 +418,7 @@ if (RESP_OK != waitFinalResp()) return false; // setup new message indication - sendFormated("AT+CNMI=1,1\r\n"); + sendFormated("AT+CNMI=2,1\r\n"); if (RESP_OK != waitFinalResp()) return false; // Request IMSI (International Mobile Subscriber Identification) @@ -462,10 +462,14 @@ int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim) { - if ((type == TYPE_PLUS) && sim){ - char s[16]; - if (sscanf(buf, "\r\n+CPIN: %[^\r]\r<n", s) >= 1) { - *sim = (strcmp("READY", s) == 0) ? SIM_READY : SIM_PIN; + if (sim) { + if (type == TYPE_PLUS){ + char s[16]; + if (sscanf(buf, "\r\n+CPIN: %[^\r]\r\n", s) >= 1) + *sim = (0 == strcmp("READY", s)) ? SIM_READY : SIM_PIN; + } else if (type == TYPE_ERROR) { + if (strstr(buf, "+CME ERROR: SIM not inserted")) + *sim = SIM_MISSING; } } return WAIT; @@ -480,53 +484,69 @@ return WAIT; } +bool MDMParser::registerNet(NetStatus* status /*= NULL*/, int timeout_ms /*= 180000*/) +{ + Timer timer; + timer.start(); + INFO("Modem::register\r\n"); + while (!checkNetStatus(status) && !TIMEOUT(timer, timeout_ms)) + RELAX_MS(1000); + if (_net.reg == REG_DENIED) + ERROR("Network Registration Denied\r\n"); + return (_net.reg == REG_ROAMING) || (_net.reg == REG_HOME); +} + bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/) { + memset(&_net, 0, sizeof(_net)); + _net.lac = 0xFFFF; + _net.ci = 0xFFFFFFFF; // check registration sendFormated("AT+CREG?\r\n"); if (RESP_OK != waitFinalResp()) return false; - if ((_net.reg != REG_ROAMING) && (_net.reg != REG_HOME)) - return false; - // check modem specific status messages - if (_dev.dev == DEV_LISA_C200) { - sendFormated("AT+CSS?\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - // get the Telephone number - sendFormated("AT$MDN?\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _net.num)) - return false; - // check if we have a Mobile Directory Number - if (memcmp(_net.num, "0000", 4) == 0) - return false; - // get the the Network access identifier string - char nai[64]; - sendFormated("AT$QCMIPNAI?\r\n"); - if (RESP_OK != waitFinalResp(_cbString, nai)) + if ((_net.reg == REG_ROAMING) || (_net.reg == REG_HOME)) + { + // check modem specific status messages + if (_dev.dev == DEV_LISA_C200) { + sendFormated("AT+CSS?\r\n"); + if (RESP_OK != waitFinalResp()) + return false; + // get the Telephone number + sendFormated("AT$MDN?\r\n"); + if (RESP_OK != waitFinalResp(_cbString, _net.num)) + return false; + // check if we have a Mobile Directory Number + if (!*_net.num || (memcmp(_net.num, "0000", 4) == 0)) + return false; + // get the the Network access identifier string + char nai[64]; + sendFormated("AT$QCMIPNAI?\r\n"); + if (RESP_OK != waitFinalResp(_cbString, nai)) + return false; + } else { + // check GPRS attach status + sendFormated("AT+CGATT?\r\n"); + if (RESP_OK != waitFinalResp(_cbCGATT, &_net.gprs)) + return false; + // check operator selection + sendFormated("AT+COPS?\r\n"); + if (RESP_OK != waitFinalResp(_cbCOPS, &_net)) + return false; + // Returns the MSISDNs related to this subscriber + sendFormated("AT+CNUM\r\n"); + if (RESP_OK != waitFinalResp(_cbCNUM, _net.num)) + return false; + } + // Returns the signal strength indication + sendFormated("AT+CSQ\r\n"); + if (RESP_OK != waitFinalResp(_cbCSQ, &_net)) return false; - } else { - // check GPRS attach status - sendFormated("AT+CGATT?\r\n"); - if (RESP_OK != waitFinalResp(_cbCGATT, &_net.gprs)) - return false; - // check operator selection - sendFormated("AT+COPS?\r\n"); - if (RESP_OK != waitFinalResp(_cbCOPS, &_net)) - return false; - // Returns the MSISDNs related to this subscriber - sendFormated("AT+CNUM\r\n"); - if (RESP_OK != waitFinalResp(_cbCNUM, _net.num)) - return false; - } - // Returns the signal strength indication - sendFormated("AT+CSQ\r\n"); - if (RESP_OK != waitFinalResp(_cbCSQ, &_net)) - return false; + } if (status) { memcpy(status, &_net, sizeof(NetStatus)); } - return true; + return ((_net.reg == REG_HOME) || (_net.reg == REG_ROAMING) || (_net.reg == REG_DENIED)); } int MDMParser::_cbCGATT(int type, const char* buf, int len, Gprs* gprs) @@ -636,7 +656,7 @@ // Activate the profile and make connection sendFormated("AT+UPSDA=" PROFILE ",3\r\n"); if (RESP_OK != waitFinalResp(NULL,NULL,150*1000)) { - INFO("Your modem APN/password/username may be wrong\r\n"); + ERROR("Your modem APN/password/username may be wrong\r\n"); return NOIP; } //Get local IP address @@ -900,18 +920,14 @@ cnt += blk; buf += blk; _sockets[socket].pending -= blk; - } else if ((_sockets[socket].state == SOCK_CONNECTED) && ( - (_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) || - (timer.read_ms() < _sockets[socket].timeout_ms))){ + } else if ((_sockets[socket].state == SOCK_CONNECTED) && + !TIMEOUT(timer, _sockets[socket].timeout_ms)) { // allow to receive unsolicited commands waitFinalResp(NULL, NULL, 10); } else { len = 0; // no more data and socket closed or timed-out } } - - timer.stop(); - timer.reset(); return cnt; } @@ -957,13 +973,11 @@ cnt += blk; buf += blk; _sockets[socket].pending -= blk; - } else if ((_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) || - (timer.read_ms() < _sockets[socket].timeout_ms)) { + } else if (!TIMEOUT(timer, _sockets[socket].timeout_ms)) { // allow to receive unsolicited commands waitFinalResp(NULL, NULL, 10); - } else { + } else len = 0; // no more data and socket closed or timed-out - } } timer.stop(); timer.reset(); @@ -1084,14 +1098,14 @@ void MDMParser::dumpDevStatus(MDMParser::DevStatus* status, _DPRINT dprint, void* param) { - dprint(param, "Modem Device Status:\r\n"); + dprint(param, "Modem::devStatus\r\n"); const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200" }; if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != MDMParser::DEV_UNKNOWN)) dprint(param, " Device: %s\r\n", txtDev[status->dev]); const char* txtLpm[] = { "Disabled", "Enabled", "Active" }; if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm)) dprint(param, " Power Save: %s\r\n", txtLpm[status->lpm]); - const char* txtSim[] = { "Unknown", "Pin", "Ready" }; + const char* txtSim[] = { "Unknown", "Missing", "Pin", "Ready" }; if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != MDMParser::SIM_UNKNOWN)) dprint(param, " SIM: %s\r\n", txtSim[status->sim]); if (*status->ccid) @@ -1113,7 +1127,7 @@ void MDMParser::dumpNetStatus(MDMParser::NetStatus *status, _DPRINT dprint, void* param) { - dprint(param, "Modem Network Status:\r\n"); + dprint(param, "Modem::netStatus\r\n"); const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" }; if (status->reg < sizeof(txtReg)/sizeof(*txtReg) && (status->reg != MDMParser::REG_UNKNOWN)) dprint(param, " Registration: %s\r\n", txtReg[status->reg]); @@ -1141,7 +1155,7 @@ _DPRINT dprint, void* param) { if (ip != NOIP) - dprint(param, "Modem IP Address: " IPSTR "\r\n", IPNUM(ip)); + dprint(param, "Modem:IP " IPSTR "\r\n", IPNUM(ip)); } // ----------------------------------------------------------------