Implementation of the CellularInterface for u-blox C027 and C030 (non-N2xx flavour) modems that uses the IP stack on-board the cellular modem, hence not requiring LWIP (and so less RAM) and allowing any AT command exchanges to be carried out at the same time as data transfers (since the modem remains in AT mode all the time). This library may be used from mbed 5.5 onwards. If you need to use SMS, USSD or access the modem file system at the same time as using the CellularInterface then use ublox-at-cellular-interface-ext instead.

Dependents:   example-ublox-cellular-interface example-ublox-cellular-interface_r410M example-ublox-mbed-client example-ublox-cellular-interface ... more

Files at this revision

API Documentation at this revision

Comitter:
fahimalavi
Date:
Mon May 20 07:56:16 2019 +0000
Parent:
24:35d5b2a02df8
Parent:
23:9098a541452b
Child:
26:4f28a1eaa2aa
Commit message:
Merging : Context activation in case of R412M (2G, NB1, CAT-M1)

Changed in this revision

UbloxATCellularInterface.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/TESTS/unit_tests/default/main.cpp	Fri Apr 19 15:40:46 2019 +0500
+++ b/TESTS/unit_tests/default/main.cpp	Mon May 20 07:56:16 2019 +0000
@@ -1,3 +1,4 @@
+
 #include "UbloxATCellularInterface.h"
 #include "greentea-client/test_env.h"
 #include "unity.h"
@@ -141,6 +142,8 @@
 // The maximum number of sockets that can be open at one time
 #define MAX_NUM_SOCKETS 7
 
+int previousSelectedRat = -1, previousPreferredRat = -1, previousSecondPreferredRat = -1;
+
 // ----------------------------------------------------------------
 // PRIVATE VARIABLES
 // ----------------------------------------------------------------
@@ -399,9 +402,6 @@
 {
     char ntp_values[48] = { 0 };
     time_t timestamp = 0;
-    struct tm *localTime;
-    char timeString[25];
-    time_t TIME1970 = 2208988800U;
     int len;
     bool comms_done = false;
 
@@ -419,6 +419,8 @@
 
     tr_debug("UDP: %d byte(s) returned by NTP server.", len);
     if (len >= 43) {
+    	struct tm *localTime;
+    	time_t TIME1970 = 2208988800U;
         timestamp |= ((int) *(ntp_values + 40)) << 24;
         timestamp |= ((int) *(ntp_values + 41)) << 16;
         timestamp |= ((int) *(ntp_values + 42)) << 8;
@@ -428,6 +430,7 @@
         tr_debug("srand() called");
         localTime = localtime(&timestamp);
         if (localTime) {
+        	char timeString[25];
             if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) {
                 printf("NTP timestamp is %s.\n", timeString);
             }
@@ -496,10 +499,10 @@
     const char *imsi;
     const char *iccid;
     int rssi;
-    
+
     // Power-up the modem
     interface->init();
-    
+
     // Check all of the IMEI, MEID, IMSI and ICCID calls
     imei = interface->imei();
     if (imei != NULL) {
@@ -507,37 +510,37 @@
     } else {
         TEST_ASSERT(false);
     }
-    
+
     meid = interface->meid();
     if (meid != NULL) {
         tr_debug("MEID is %s.", meid);
     } else {
         TEST_ASSERT(false);
     }
-    
+
     imsi = interface->imsi();
     if (imsi != NULL) {
         tr_debug("IMSI is %s.", imsi);
     } else {
         TEST_ASSERT(false);
     }
-    
+
     iccid = interface->iccid();
     if (iccid != NULL) {
         tr_debug("ICCID is %s.", iccid);
     } else {
         TEST_ASSERT(false);
     }
-    
+
     // Check the RSSI call at least doesn't assert
     rssi = interface->rssi();
     tr_debug("RSSI is %d dBm.", rssi);
-    
+
     // Now connect and check that the answers for the
     // static fields are the same while connected
     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
-    
+
     TEST_ASSERT(strcmp(imei, interface->imei()) == 0);
     TEST_ASSERT(strcmp(meid, interface->meid()) == 0);
     TEST_ASSERT(strcmp(imsi, interface->imsi()) == 0);
@@ -1066,6 +1069,138 @@
     delete pLocalInterface;
 }
 
+void test_set_new_rat() {
+
+	int currentSelectedRat = -1, currentPreferredRat = -1, currentSecondPreferredRat = -1;
+
+    // Power-up the modem
+    TEST_ASSERT(interface->init());
+
+    // Check if modem is registered with network
+    if (interface->is_registered_csd() || interface->is_registered_psd() || interface->is_registered_eps()) {
+        tr_error("RAT should only be set in detached state");
+        // Deregister from Network
+        TEST_ASSERT(interface->nwk_deregistration());
+    }
+
+    // Get and store initial RAT set on modem
+    TEST_ASSERT(interface->get_modem_rat(&previousSelectedRat, &previousPreferredRat, &previousSecondPreferredRat));
+    tr_debug("previous selected RAT: %d\nprevious preferred RAT: %d\nprevious second preferred RAT: %d\n", previousSelectedRat, previousPreferredRat, previousSecondPreferredRat);
+
+#ifdef TARGET_UBLOX_C030_U201
+    // Set new RAT
+    TEST_ASSERT(interface->set_modem_rat(UbloxATCellularInterface::GSM_UMTS, UbloxATCellularInterface::UMTS));
+    tr_debug("RAT configured\n");
+
+    // Get latest set RAT on modem
+    TEST_ASSERT(interface->get_modem_rat(&currentSelectedRat, &currentPreferredRat, &currentSecondPreferredRat));
+    tr_debug("new selected RAT: %d\nnew preferred RAT: %d\nnew second preferred RAT: %d\n", currentSelectedRat, currentPreferredRat, currentSecondPreferredRat);
+
+    // Check RAT configured correctly
+    TEST_ASSERT((currentSelectedRat == UbloxATCellularInterface::GSM_UMTS) && (currentPreferredRat == UbloxATCellularInterface::UMTS));
+#endif
+
+#ifdef TARGET_UBLOX_C030_R412M
+    // Set new RAT
+    TEST_ASSERT(interface->set_modem_rat(UbloxATCellularInterface::LTE_CATM1, UbloxATCellularInterface::LTE_CATNB1));
+    tr_debug("RAT configured\n");
+
+    // Get latest set RAT on modem
+    TEST_ASSERT(interface->get_modem_rat(&currentSelectedRat, &currentPreferredRat, &currentSecondPreferredRat));
+    tr_debug("new selected RAT: %d\nnew preferred RAT: %d\nnew second preferred RAT: %d\n", currentSelectedRat, currentPreferredRat, currentSecondPreferredRat);
+
+    // Check RAT configured correctly
+    TEST_ASSERT((currentSelectedRat == UbloxATCellularInterface::LTE_CATM1) && (currentPreferredRat == UbloxATCellularInterface::LTE_CATNB1));
+#endif
+}
+
+void test_reboot() {
+
+    // Rebooting modem for settings to take effect
+	TEST_ASSERT(interface->reboot_modem());
+}
+
+void test_registration() {
+
+    TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
+                                   MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
+
+    TEST_ASSERT(interface->nwk_deregistration());
+}
+
+
+void test_set_previous_rat() {
+
+	int currentSelectedRat = -1, currentPreferredRat = -1, currentSecondPreferredRat = -1;
+
+    // Restore RAT to previous settings
+    TEST_ASSERT(interface->set_modem_rat((UbloxATCellularInterface::RAT)previousSelectedRat, (UbloxATCellularInterface::RAT)previousPreferredRat, (UbloxATCellularInterface::RAT)previousSecondPreferredRat));
+    tr_debug("RAT configured\n");
+
+    TEST_ASSERT(interface->get_modem_rat(&currentSelectedRat, &currentPreferredRat, &currentSecondPreferredRat));
+    tr_debug("current selected RAT: %d\ncurrent preferred RAT: %d\ncurrent second preferred RAT: %d\n", currentSelectedRat, currentPreferredRat, currentSecondPreferredRat);
+
+    // Check RAT configured correctly
+    TEST_ASSERT((currentSelectedRat == previousSelectedRat) && (currentPreferredRat == previousPreferredRat));
+
+    // Rebooting modem for settings to take effect
+	TEST_ASSERT(interface->reboot_modem());
+}
+
+#ifdef TARGET_UBLOX_C030_R41XM
+void test_mno_profile() {
+
+    int previous_profile, current_profile;
+
+    // Power-up the modem
+    TEST_ASSERT(interface->init());
+
+    // Check if modem is registered with network
+    if (interface->is_registered_csd() || interface->is_registered_psd() || interface->is_registered_eps()) {
+        tr_error("MNO profile should only be set in detached state");
+        // Deregister from Network
+        TEST_ASSERT(interface->nwk_deregistration());
+    }
+
+    // Getting current mno profile
+    TEST_ASSERT(interface->get_mno_profile(&previous_profile));
+    tr_debug("Previous MNO profile is: %d\n\n", previous_profile);
+
+    // Set MNO profile
+    TEST_ASSERT(interface->set_mno_profile((UbloxATCellularInterface::MNOProfile)MBED_CONF_UBLOX_CELL_DEFAULT_MNO_PROFILE));
+    tr_debug("MNO configured\n");
+
+    // Rebooting modem for settings to take effect
+	TEST_ASSERT(interface->reboot_modem());
+	tr_debug("Reboot successful\n");
+	wait_ms(5000);
+
+    // Check MNO profile configured correctly
+    TEST_ASSERT(interface->get_mno_profile(&current_profile));
+    tr_debug("New MNO profile is: %d\n\n", current_profile);
+
+    TEST_ASSERT((UbloxATCellularInterface::MNOProfile)current_profile == (UbloxATCellularInterface::MNOProfile)MBED_CONF_UBLOX_CELL_DEFAULT_MNO_PROFILE);
+
+    TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
+                                   MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
+
+    TEST_ASSERT(interface->nwk_deregistration());
+
+    // Restore MNO profile to previous settings
+    TEST_ASSERT(interface->set_mno_profile((UbloxATCellularInterface::MNOProfile)previous_profile));
+    tr_debug("Previous MNO configured\n");
+
+    // Rebooting modem for settings to take effect
+	TEST_ASSERT(interface->reboot_modem());
+	tr_debug("Reboot successful\n");
+	wait_ms(5000);
+
+    // Check MNO profile configured correctly
+    TEST_ASSERT(interface->get_mno_profile(&current_profile));
+    TEST_ASSERT((current_profile == previous_profile));
+}
+#endif
+
 // ----------------------------------------------------------------
 // TEST ENVIRONMENT
 // ----------------------------------------------------------------
@@ -1105,6 +1240,15 @@
     Case("Check SIM pin, pending", test_check_sim_pin_pending),
     Case("Check SIM pin, immediate", test_check_sim_pin_immediate),
 #endif
+#if defined (TARGET_UBLOX_C030_U201) || defined (TARGET_UBLOX_C030_R412M)
+    Case("Set RAT test", test_set_new_rat),
+    Case("Reboot test", test_reboot),
+    Case("Register with network test", test_registration),
+    Case("Set previous RAT test", test_set_previous_rat),
+#endif
+#ifdef TARGET_UBLOX_C030_R41XM
+    Case("MNO profile test", test_mno_profile),
+#endif
 #ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 for this
     Case("Connect using local instance, must be last test", test_connect_local_instance_last_test)
 #endif
--- a/TESTS/unit_tests/default/template_mbed_app.txt	Fri Apr 19 15:40:46 2019 +0500
+++ b/TESTS/unit_tests/default/template_mbed_app.txt	Mon May 20 07:56:16 2019 +0000
@@ -63,7 +63,8 @@
         "udp-max-frag-packet-size": {
             "help": "The maximum size of UDP data to test with that we know will be fragmented across multiple UDP packets",
             "value": 1500
-        }
+        },
+        "change-rat-mno-to-default": 0
     },
     "target_overrides": {
         "*": {
--- a/TESTS/unit_tests/dynamic/main.cpp	Fri Apr 19 15:40:46 2019 +0500
+++ b/TESTS/unit_tests/dynamic/main.cpp	Mon May 20 07:56:16 2019 +0000
@@ -128,9 +128,6 @@
 {
     char ntp_values[48] = { 0 };
     time_t timestamp = 0;
-    struct tm *localTime;
-    char timeString[25];
-    time_t TIME1970 = 2208988800U;
     int len;
     bool comms_done = false;
 
@@ -148,6 +145,8 @@
 
     tr_debug("UDP: %d byte(s) returned by NTP server.", len);
     if (len >= 43) {
+    	struct tm *localTime;
+        time_t TIME1970 = 2208988800U;
         timestamp |= ((int) *(ntp_values + 40)) << 24;
         timestamp |= ((int) *(ntp_values + 41)) << 16;
         timestamp |= ((int) *(ntp_values + 42)) << 8;
@@ -157,6 +156,7 @@
         tr_debug("srand() called");
         localTime = localtime(&timestamp);
         if (localTime) {
+        	char timeString[25];
             if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) {
                 printf("NTP timestamp is %s.\n", timeString);
             }
--- a/UbloxATCellularInterface.cpp	Fri Apr 19 15:40:46 2019 +0500
+++ b/UbloxATCellularInterface.cpp	Mon May 20 07:56:16 2019 +0000
@@ -34,13 +34,12 @@
 // Event thread for asynchronous received data handling.
 void UbloxATCellularInterface::handle_event(){
     pollfh fhs;
-    int count;
     int at_timeout;
-
     fhs.fh = _fh;
     fhs.events = POLLIN;
 
     while (_run_event_thread) {
+    	int count;
         count = poll(&fhs, 1, 1000);
         if (count > 0 && (fhs.revents & POLLIN)) {
             LOCK();
@@ -137,13 +136,13 @@
     int a;
     int b;
     char buf[32];
-    SockCtrl *socket;
-
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     // +UUSORD: <socket>,<length>
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
+
         if (sscanf(buf, ": %d,%d", &a, &b) == 2) {
+        	SockCtrl *socket;
             socket = find_socket(a);
             if (socket != NULL) {
                 socket->pending = b;
@@ -163,13 +162,12 @@
     int a;
     int b;
     char buf[32];
-    SockCtrl *socket;
-
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     // +UUSORF: <socket>,<length>
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
         if (sscanf(buf, ": %d,%d", &a, &b) == 2) {
+        	SockCtrl *socket;
             socket = find_socket(a);
             if (socket != NULL) {
                 socket->pending = b;
@@ -188,13 +186,12 @@
 {
     int a;
     char buf[32];
-    SockCtrl *socket;
-
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     // +UUSOCL: <socket>
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
         if (sscanf(buf, ": %d", &a) == 1) {
+        	SockCtrl *socket;
             socket = find_socket(a);
             tr_debug("Socket 0x%08x: handle %d closed by remote host",
                      (unsigned int) socket, a);
@@ -208,13 +205,12 @@
 {
     int a;
     char buf[32];
-    SockCtrl *socket;
-
     // Note: not calling _at->recv() from here as we're
     // already in an _at->recv()
     // +UUPSDD: <socket>
     if (read_at_to_char(buf, sizeof (buf), '\n') > 0) {
         if (sscanf(buf, ": %d", &a) == 1) {
+        	SockCtrl *socket;
             socket = find_socket(a);
             tr_debug("Socket 0x%08x: handle %d connection lost",
                      (unsigned int) socket, a);
@@ -296,13 +292,13 @@
 {
     bool success = false;
     int cid = -1;
-    char ip[NSAPI_IP_SIZE];
     SocketAddress address;
     int t;
     int at_timeout = _at_timeout;
 
     //+CGDCONT: <cid>,"IP","<apn name>","<ip adr>",0,0,0,0,0,0
     if (_at->send("AT+CGDCONT?")) {
+    	char ip[NSAPI_IP_SIZE];
         if (_at->recv("+CGDCONT: %d,\"IP\",\"%*[^\"]\",\"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\",%*d,%*d,%*d,%*d,%*d,%*d",
                       &t, ip) &&
             _at->recv("OK")) {
@@ -501,7 +497,6 @@
                                                     nsapi_protocol_t proto)
 {
     nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
-    bool success = false;
     int modem_handle;
     SockCtrl *socket;
     LOCK();
@@ -511,6 +506,7 @@
     tr_debug("socket_open(%d)", proto);
 
     if (socket != NULL) {
+    	bool success = false;
         if (proto == NSAPI_UDP) {
             success = _at->send("AT+USOCR=17");
         } else if (proto == NSAPI_TCP) {
@@ -743,7 +739,7 @@
     int read_sz;
     Timer timer;
     SockCtrl *socket = (SockCtrl *) handle;
-    int at_timeout;
+
 
     tr_debug("socket_recv(0x%08x, 0x%08x, %d)",
              (unsigned int) handle, (unsigned int) data, size);
@@ -758,6 +754,7 @@
     timer.start();
 
     while (success && (size > 0)) {
+    	int at_timeout;
         LOCK();
         at_timeout = _at_timeout;
         at_set_timeout(1000);
@@ -854,7 +851,6 @@
     int read_sz;
     Timer timer;
     SockCtrl *socket = (SockCtrl *) handle;
-    int at_timeout;
 
     tr_debug("socket_recvfrom(0x%08x, 0x%08x, %d)",
              (unsigned int) handle, (unsigned int) data, size);
@@ -864,6 +860,7 @@
     timer.start();
 
     while (success && (size > 0)) {
+    	int at_timeout;
         LOCK();
         at_timeout = _at_timeout;
         at_set_timeout(1000);
@@ -1025,7 +1022,9 @@
     _apn = NULL;
     _uname = NULL;
     _pwd = NULL;
-    _connection_status_cb = NULL;
+
+
+
 
     // Initialise sockets storage
     memset(_sockets, 0, sizeof(_sockets));
@@ -1040,6 +1039,8 @@
 
     // Nullify the temporary IP address storage
     _ip = NULL;
+    _connection_status_cb = NULL;
+
 
     // Initialise the base class, which starts the AT parser
     baseClassInit(tx, rx, baud, debug_on);
@@ -1094,12 +1095,13 @@
                                                       nsapi_version_t version)
 {
     nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
-    int at_timeout;
-    char ipAddress[NSAPI_IP_SIZE];
+
 
     if (address->set_ip_address(host)) {
         nsapi_error = NSAPI_ERROR_OK;
     } else {
+    	int at_timeout;
+    	char ipAddress[NSAPI_IP_SIZE];
         LOCK();
         // This interrogation can sometimes take longer than the usual 8 seconds
         at_timeout = _at_timeout;