* add C027_Support fork

Fork of C027_Support by u-blox

Revision:
54:7ba8e4c218e2
Parent:
52:8071747a7cb3
Child:
55:e6cfbedfae8c
diff -r 8071747a7cb3 -r 7ba8e4c218e2 MDM.cpp
--- a/MDM.cpp	Mon May 12 07:39:29 2014 +0000
+++ b/MDM.cpp	Mon May 12 13:00:27 2014 +0000
@@ -4,7 +4,7 @@
 #include "MDM.h"
 
 #define TRACE           (1/*1=off,0=trace*/)?:printf
-//#define DEBUG         // enable this for AT command debugging
+#define DEBUG         // enable this for AT command debugging
 #define PROFILE         "0"   // this is the psd profile used
 #define MAX_SIZE        256  // max expected messages
 // some helper 
@@ -43,6 +43,8 @@
     inst = this;
     memset(&_dev, 0, sizeof(_dev));
     memset(&_net, 0, sizeof(_net));
+    _net.lac = 0xFFFF;
+    _net.ci = 0xFFFFFFFF;
     _ip        = NOIP;
     memset(_sockets, 0, sizeof(_sockets));
 }
@@ -82,7 +84,7 @@
             int type = TYPE(ret);
             const char* s = (type == TYPE_UNKNOWN)? YEL("UNK") : 
                             (type == TYPE_TEXT)   ? MAG("TXT") : 
-                            (type == TYPE_RESP_OK   )  ? GRE("RESP_OK ") : 
+                            (type == TYPE_OK   )  ? GRE("OK ") : 
                             (type == TYPE_ERROR)  ? RED("ERR") : 
                             (type == TYPE_PLUS)   ? CYA(" + ") : 
                             (type == TYPE_PROMPT) ? BLU(" > ") : 
@@ -101,7 +103,7 @@
             // handle unsolicited commands here
             if (type == TYPE_PLUS) {
                 const char* cmd = buf+3;
-                int a, b;
+                int a, b, c, d, r;
                 char s[32];
 
                 // SMS Command ---------------------------------
@@ -128,12 +130,14 @@
                 if (_dev.dev == DEV_LISA_C200) {
                     // CDMA Specific -------------------------------------------
                     // +CREG: <n><SID>,<NID>,<stat>
-                    if (sscanf(cmd, "CREG: %*d,%*d,%*d,%d",&a) == 1) {
-                        if      (a == 0) _net.reg = REG_NONE;     // not registered, home network
-                        else if (a == 1) _net.reg = REG_HOME;     // registered, home network
-                        else if (a == 2) _net.reg = REG_NONE;     // not registered, but MT is currently searching a new operator to register to
-                        else if (a == 3) _net.reg = REG_DENIED;   // registration denied
-                        else if (a == 5) _net.reg = REG_ROAMING;  // registered, roaming
+                    if (sscanf(cmd, "CREG: %*d,%d,%d,%d",&a,&b,&c) == 3) {
+                        // _net.sid = a;
+                        // _net.nid = b;
+                        if      (c == 0) _net.reg = REG_NONE;     // not registered, home network
+                        else if (c == 1) _net.reg = REG_HOME;     // registered, home network
+                        else if (c == 2) _net.reg = REG_NONE;     // not registered, but MT is currently searching a new operator to register to
+                        else if (c == 3) _net.reg = REG_DENIED;   // registration denied
+                        else if (c == 5) _net.reg = REG_ROAMING;  // registered, roaming
                         _net.act = ACT_CDMA;
                     // +CSS: <mode>[,<format>,<oper>[,<AcT>]]
                     } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) {
@@ -143,7 +147,8 @@
                     // GSM/UMTS Specific -------------------------------------------
                     // +CREG: <n>, <stat>[,<lac>,<ci>[,AcT]]
                     b = 255;
-                    if (sscanf(cmd, "CREG: %*d,%d,%*d,%d",&a,&b) >= 1) {
+                    r = sscanf(cmd, "CREG: %*d,%d,\"%X\",\"%X\",%d",&a,&b,&c,&d);
+                    if (r >= 1) {
                         // network status
                         if      (a == 0) _net.reg = REG_NONE;     // 0: not registered, home network
                         else if (a == 1) _net.reg = REG_HOME;     // 1: registered, home network
@@ -151,14 +156,19 @@
                         else if (a == 3) _net.reg = REG_DENIED;   // 3: registration denied
                         else if (a == 4) _net.reg = REG_UNKNOWN;  // 4: unknown
                         else if (a == 5) _net.reg = REG_ROAMING;  // 5: registered, roaming
+                        if ((r >= 2) && (b != 0xFFFF))      _net.lac = b; // location area code
+                        if ((r >= 3) && (c != 0xFFFFFFFF))  _net.ci  = c; // cell ID
                         // access technology
-                        if      (b == 0) _net.act = ACT_GSM;      // 0: GSM
-                        else if (b == 1) _net.act = ACT_GSM;      // 1: GSM COMPACT
-                        else if (b == 2) _net.act = ACT_UTRAN;    // 2: UTRAN
-                        else if (b == 3) _net.act = ACT_EDGE;     // 3: GSM with EDGE availability
-                        else if (b == 4) _net.act = ACT_UTRAN;    // 4: UTRAN with HSDPA availability
-                        else if (b == 5) _net.act = ACT_UTRAN;    // 5: UTRAN with HSUPA availability
-                        else if (b == 6) _net.act = ACT_UTRAN;    // 6: UTRAN with HSDPA and HSUPA availability
+                        if (r >= 4) {
+                            if      (d == 0) _net.act = ACT_GSM;      // 0: GSM
+                            else if (d == 1) _net.act = ACT_GSM;      // 1: GSM COMPACT
+                            else if (d == 2) _net.act = ACT_UTRAN;    // 2: UTRAN
+                            else if (d == 3) _net.act = ACT_EDGE;     // 3: GSM with EDGE availability
+                            else if (d == 4) _net.act = ACT_UTRAN;    // 4: UTRAN with HSDPA availability
+                            else if (d == 5) _net.act = ACT_UTRAN;    // 5: UTRAN with HSUPA availability
+                            else if (d == 6) _net.act = ACT_UTRAN;    // 6: UTRAN with HSDPA and HSUPA availability
+                        }
+                        
                     // +UUPSDD: <profile_id> 
                     } else if (sscanf(cmd, "UUPSDD: %d",&a) == 1) {
                         if (*PROFILE == a) _ip = NOIP;
@@ -383,6 +393,10 @@
 
 bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/)
 {
+    // enable the network registration unsolicited result code
+    sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2);
+    if (RESP_OK != waitFinalResp())
+        return false;
     // check registration
     sendFormated("AT+CREG?\r\n");
     if (RESP_OK != waitFinalResp())
@@ -425,7 +439,7 @@
     }  
     // Returns the signal strength indication
     sendFormated("AT+CSQ\r\n");
-    if (RESP_OK != waitFinalResp(_cbCSQ, &_net.rssi))
+    if (RESP_OK != waitFinalResp(_cbCSQ, &_net))
         return false;
     if (status) {
         memcpy(status, &_net, sizeof(NetStatus));
@@ -466,14 +480,15 @@
     return WAIT;
 }
                     
-int MDMParser::_cbCSQ(int type, const char* buf, int len, int* rssi)
+int MDMParser::_cbCSQ(int type, const char* buf, int len, NetStatus* status)
 {
-    if ((type == TYPE_PLUS) && rssi){
-        int a;
+    if ((type == TYPE_PLUS) && status){
+        int a,b;
+        char _ber[] = { 49, 43, 37, 25, 19, 13, 7, 0 }; // see 3GPP TS 45.008 [20] subclause 8.2.4
         // +CSQ: <rssi>,<qual>
-        if (sscanf(buf, "\r\n+CSQ: %d,%*d",&a) == 1) {
-            if (a != 99) *rssi = -113 + 2*a;  // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps
-            //if (b != 99) int qual = b;  // 
+        if (sscanf(buf, "\r\n+CSQ: %d,%d",&a,&b) == 2) {
+            if (a != 99) status->rssi = -113 + 2*a;  // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps
+            if ((b != 99) && (b < sizeof(_ber))) status->ber = _ber[b];  // 
         }
     }
     return WAIT;
@@ -932,7 +947,65 @@
     }
     return true;
 }
-    
+   
+// ----------------------------------------------------------------
+ 
+void MDMParser::dumpDevStatus(MDMParser::DevStatus* status) 
+{
+    printf("Device Status:\r\n");
+    const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200" };
+    if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != MDMParser::DEV_UNKNOWN))
+        printf("  Device:       %s\r\n", txtDev[status->dev]);
+    const char* txtLpm[] = { "Disabled", "Enabled", "Active" };
+    if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm))
+        printf("  Power Save:   %s\r\n", txtLpm[status->lpm]);
+    const char* txtSim[] = { "Unknown", "Pin", "Ready" };
+    if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != MDMParser::SIM_UNKNOWN))
+        printf("  SIM:          %s\r\n", txtSim[status->sim]);
+    if (*status->ccid)  
+        printf("  CCID:         %s\r\n", status->ccid);
+    if (*status->imei) 
+        printf("  IMEI:         %s\r\n", status->imei);
+    if (*status->imsi)  
+        printf("  IMSI:         %s\r\n", status->imsi);
+    if (*status->meid) 
+        printf("  MEID:         %s\r\n", status->meid); // LISA-C
+    if (*status->manu) 
+        printf("  Manufacturer: %s\r\n", status->manu);
+    if (*status->model)  
+        printf("  Model:        %s\r\n", status->model);
+    if (*status->ver)  
+        printf("  Version:      %s\r\n", status->ver);
+}
+
+void MDMParser::dumpNetStatus(MDMParser::NetStatus *status)
+{
+    printf("Network Status:\r\n");
+    const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" };
+    if (status->reg < sizeof(txtReg)/sizeof(*txtReg) && (status->reg != MDMParser::REG_UNKNOWN))
+        printf("  Registration:       %s\r\n", txtReg[status->reg]);
+    const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" };
+    if (status->act < sizeof(txtAct)/sizeof(*txtAct) && (status->act != MDMParser::ACT_UNKNOWN))
+        printf("  Access Technology:  %s\r\n", txtAct[status->act]);
+    if (status->rssi) 
+        printf("  Signal Strength:    %d dBm\r\n", status->rssi);
+    if (status->ber) 
+        printf("  Bit Error Rate:     %d\r\n", status->ber);
+    if (*status->opr)  
+        printf("  Operator:           %s\r\n", status->opr);
+    if (status->lac != 0xFFFF)  
+        printf("  Location Area Code: %04X\r\n", status->lac);
+    if (status->ci != 0xFFFFFFFF)  
+        printf("  Cell ID:            %08X\r\n", status->ci);
+    if (*status->num)  
+        printf("  Phone Number:       %s\r\n", status->num);
+}
+
+void MDMParser::dumpIp(MDMParser::IP ip) 
+{
+    printf("IP Address: " IPSTR "\r\n", IPNUM(ip));
+}
+
 // ----------------------------------------------------------------
   
 int MDMParser::_cbCUSD(int type, const char* buf, int len, char* resp)