drx

Revision:
14:e420232ee4e7
Parent:
13:158a035b1b50
Child:
15:93b157a47b8d
--- a/UbloxCellularBase.cpp	Tue Jan 09 15:08:31 2018 +0500
+++ b/UbloxCellularBase.cpp	Tue Jan 09 13:20:15 2018 +0000
@@ -27,6 +27,27 @@
 #define tr_error(format, ...) debug_if(_debug_trace_on, format "\n", ## __VA_ARGS__)
 #endif
 
+/* Array to convert the 3G qual number into a median EC_NO_LEV number.
+ */
+                            /* 0   1   2   3   4   5   6  7 */
+const int qualConvert3G[] = {44, 41, 35, 29, 23, 17, 11, 7};
+
+/* Array to convert the 3G "rssi" number into a dBm RSCP value rounded up to the
+ * nearest whole number.
+ */
+const int rscpConvert3G[] = {-108, -105, -103, -100,  -98,  -96,  -94,  -93,   /* 0 - 7 */
+                              -91,  -89,  -88,  -85,  -83,  -80,  -78,  -76,   /* 8 - 15 */
+                              -74,  -73,  -70,  -68,  -66,  -64,  -63,  -60,   /* 16 - 23 */
+                              -58,  -56,  -54,  -53,  -51,  -49,  -48,  -46};  /* 24 - 31 */
+
+/* Array to convert the LTE rssi number into a dBm value rounded up to the
+ * nearest whole number.
+ */
+const int rssiConvertLte[] = {-118, -115, -113, -110, -108, -105, -103, -100,   /* 0 - 7 */
+                               -98,  -95,  -93,  -90,  -88,  -85,  -83,  -80,   /* 8 - 15 */
+                               -78,  -76,  -74,  -73,  -71,  -69,  -68,  -65,   /* 16 - 23 */
+                               -63,  -61,  -60,  -59,  -58,  -55,  -53,  -48};  /* 24 - 31 */
+
 /**********************************************************************
  * PRIVATE METHODS
  **********************************************************************/
@@ -121,9 +142,9 @@
     _dev_info.reg_status_eps = static_cast<NetworkRegistrationStatusEps>(status);
 }
 
-void UbloxCellularBase::set_rat(int AcTStatus)
+void UbloxCellularBase::set_rat(int acTStatus)
 {
-    switch (AcTStatus) {
+    switch (acTStatus) {
         case GSM:
         case COMPACT_GSM:
             tr_info("Connected in GSM");
@@ -153,11 +174,11 @@
             tr_info("Connected to E_UTRAN NB1");
             break;
         default:
-            tr_info("Unknown RAT %d", AcTStatus);
+            tr_info("Unknown RAT %d", acTStatus);
             break;
     }
 
-    _dev_info.rat = static_cast<RadioAccessNetworkType>(AcTStatus);
+    _dev_info.rat = static_cast<RadioAccessNetworkType>(acTStatus);
 }
 
 bool UbloxCellularBase::get_iccid()
@@ -279,6 +300,7 @@
 {
     char buf[10];
     int status;
+    int acTStatus;
 
     // If this is the URC it will be a single
     // digit followed by \n.  If it is the
@@ -288,7 +310,10 @@
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
-        if (sscanf(buf, ": %*d,%d", &status) == 1) {
+        if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
+            set_nwk_reg_status_csd(status);
+            set_rat(acTStatus);
+        } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
             set_nwk_reg_status_csd(status);
         } else if (sscanf(buf, ": %d", &status) == 1) {
             set_nwk_reg_status_csd(status);
@@ -301,6 +326,7 @@
 {
     char buf[10];
     int status;
+    int acTStatus;
 
     // If this is the URC it will be a single
     // digit followed by \n.  If it is the
@@ -310,7 +336,10 @@
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
-        if (sscanf(buf, ": %*d,%d", &status) == 1) {
+        if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
+            set_nwk_reg_status_csd(status);
+            set_rat(acTStatus);
+        } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
             set_nwk_reg_status_psd(status);
         } else if (sscanf(buf, ": %d", &status) == 1) {
             set_nwk_reg_status_psd(status);
@@ -323,6 +352,7 @@
 {
     char buf[10];
     int status;
+    int acTStatus;
 
     // If this is the URC it will be a single
     // digit followed by \n.  If it is the
@@ -332,7 +362,10 @@
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
-        if (sscanf(buf, ": %*d,%d", &status) == 1) {
+        if (sscanf(buf, ": %*d,%d,%*d,%*d,%d,", &status, &acTStatus) == 2) {
+            set_nwk_reg_status_csd(status);
+            set_rat(acTStatus);
+        } else if (sscanf(buf, ": %*d,%d", &status) == 1) {
             set_nwk_reg_status_eps(status);
         } else if (sscanf(buf, ": %d", &status) == 1) {
             set_nwk_reg_status_eps(status);
@@ -909,10 +942,7 @@
     return success;
 }
 
-/** Get the IMEI.
-     *
-     * @return true if successful, otherwise false.
-     */
+// Get the IMEI.
 bool UbloxCellularBase::get_imei(char *imei_to_send, int size)
 {
     bool success;
@@ -934,5 +964,92 @@
     return success;
 }
 
+// Get the IMEI of the module.
+const char *UbloxCellularBase::imei()
+{
+    return _dev_info.imei;
+}
+
+// Get the Mobile Equipment ID (which may be the same as the IMEI).
+const char *UbloxCellularBase::meid()
+{
+    return _dev_info.meid;
+}
+
+// Get the IMSI of the SIM.
+const char *UbloxCellularBase::imsi()
+{
+    // (try) to update the IMSI, just in case the SIM has changed
+    get_imsi();
+    
+    return _dev_info.imsi;
+}
+
+// Get the ICCID of the SIM.
+const char *UbloxCellularBase::iccid()
+{
+    // (try) to update the ICCID, just in case the SIM has changed
+    get_iccid();
+    
+    return _dev_info.iccid;
+}
+
+// Get the RSSI in dBm.
+int UbloxCellularBase::rssi()
+{
+    char buf[7] = {0};
+    int rssi = 0;
+    int qual = 0;
+    int rssiRet = 0;
+    bool success;
+    LOCK();
+
+    MBED_ASSERT(_at != NULL);
+
+    success = _at->send("AT+CSQ") && _at->recv("+CSQ: %6[^\n]\nOK\n", buf);
+
+    if (success) {
+        if (sscanf(buf, "%d,%d", &rssi, &qual) == 2) {
+            // AT+CSQ returns a coded RSSI value and an RxQual value
+            // For 2G an RSSI of 0 corresponds to -113 dBm or less, 
+            // an RSSI of 31 corresponds to -51 dBm or less and hence
+            // each value is a 2 dB step.
+            // For LTE the mapping is defined in the array rssiConvertLte[].
+            // For 3G the mapping to RSCP is defined in the array rscpConvert3G[]
+            // and the RSSI value is then RSCP - the EC_NO_LEV number derived
+            // by putting the qual number through qualConvert3G[].
+            if ((rssi >= 0) && (rssi <= 31)) {
+                switch (_dev_info.rat) {
+                    case UTRAN:
+                    case HSDPA:
+                    case HSUPA:
+                    case HSDPA_HSUPA:
+                        // 3G
+                        if ((qual >= 0) && (qual <= 7)) {
+                            qual = qualConvert3G[qual];
+                        }
+                        rssiRet = rscpConvert3G[rssi];
+                        rssiRet -= qual;
+                        break;
+                    case LTE:
+                        // LTE
+                        rssiRet = rssiConvertLte[rssi];
+                        break;
+                    case GSM:
+                    case COMPACT_GSM:
+                    case EDGE:
+                    default:
+                        // GSM or assumed GSM if the RAT is not known
+                        rssiRet = -(113 - (rssi << 2));
+                        break;
+                }
+            }
+        }
+    }
+
+    UNLOCK();
+    return rssiRet;
+}
+
 // End of File