* add C027_Support fork

Fork of C027_Support by u-blox

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));
 }
     
 // ----------------------------------------------------------------