Add methods to return IMEI, MEID, IMSI, ICCID and RSSI.

Fork of ublox-cellular-base by u-blox

Files at this revision

API Documentation at this revision

Comitter:
RobMeades
Date:
Tue Jan 09 13:20:15 2018 +0000
Parent:
13:158a035b1b50
Commit message:
Add methods to return IMEI, MEID, IMSI, ICCID and RSSI.

Changed in this revision

UbloxCellularBase.cpp Show annotated file Show diff for this revision Revisions of this file
UbloxCellularBase.h Show annotated file Show diff for this revision Revisions of this file
diff -r 158a035b1b50 -r e420232ee4e7 UbloxCellularBase.cpp
--- 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
 
diff -r 158a035b1b50 -r e420232ee4e7 UbloxCellularBase.h
--- a/UbloxCellularBase.h	Tue Jan 09 15:08:31 2018 +0500
+++ b/UbloxCellularBase.h	Tue Jan 09 13:20:15 2018 +0000
@@ -17,6 +17,7 @@
 #define _UBLOX_CELLULAR_BASE_
 
 #include "mbed.h"
+#include "mbed_toolchain.h" // for MBED_DEPRECATED
 #include "ATCmdParser.h"
 #include "FileHandle.h"
 
@@ -138,8 +139,41 @@
      *
      * @return true if successful, otherwise false.
      */
+    MBED_DEPRECATED("This method is now replaced by const char * imei(), please use that instead")
 	bool get_imei(char *imei_to_send, int size);
 
+    /** Get the IMEI of the module.
+     *
+     * @return a pointer to the IMEI as a null-terminated string.
+     */
+    const char *imei();
+
+    /** Get the Mobile Equipment ID (which may be the same as the IMEI).
+     *
+     * @return a pointer to the Mobile Equipment ID as a null-terminated string.
+     */
+    const char *meid();
+
+    /** Get the IMSI of the SIM.
+     *
+     * @return a pointer to the IMSI as a null-terminated string.
+     */
+    const char *imsi();
+
+    /** Get the ICCID of the SIM.
+     *
+     * @return a pointer to the ICCID as a null-terminated string.
+     */
+    const char *iccid();
+
+    /** Get the RSSI.
+     *
+     * @return the RSSI in dBm. If it is not possible to obtain an
+     *         RSSI reading at the time (e.g. because the modem is in
+     *         data mode rather than AT command mode) then 0 is returned.
+     */
+    int rssi();
+
 protected:
 
     #define OUTPUT_ENTER_KEY  "\r"