Fork of ublox-at-cellular-interface to add LARA-R2 support

Dependents:  

Fork of ublox-at-cellular-interface by u-blox

Revision:
18:bfc869299185
Parent:
17:8696a2ecde3f
Child:
19:2e961ce171e6
diff -r 8696a2ecde3f -r bfc869299185 UbloxATCellularInterface.cpp
--- a/UbloxATCellularInterface.cpp	Mon Sep 24 13:44:28 2018 -0500
+++ b/UbloxATCellularInterface.cpp	Wed Sep 26 11:33:31 2018 -0500
@@ -46,7 +46,7 @@
             LOCK();
             at_timeout = _at_timeout;
             at_set_timeout(10); // Avoid blocking but also make sure we don't
-                                // time out if we get ahead of the serial port
+            // time out if we get ahead of the serial port
             _at->debug_on(false); // Debug here screws with the test output
             // Let the URCs run
             _at->recv(UNNATURAL_STRING);
@@ -105,21 +105,21 @@
 
     switch (nsapi_security)
     {
-        case NSAPI_SECURITY_NONE:
-            modem_security = 0;
-            break;
-        case NSAPI_SECURITY_PAP:
-            modem_security = 1;
-            break;
-        case NSAPI_SECURITY_CHAP:
-            modem_security = 2;
-            break;
-        case NSAPI_SECURITY_UNKNOWN:
-            modem_security = 3;
-            break;
-        default:
-            modem_security = 3;
-            break;
+    case NSAPI_SECURITY_NONE:
+        modem_security = 0;
+        break;
+    case NSAPI_SECURITY_PAP:
+        modem_security = 1;
+        break;
+    case NSAPI_SECURITY_CHAP:
+        modem_security = 2;
+        break;
+    case NSAPI_SECURITY_UNKNOWN:
+        modem_security = 3;
+        break;
+    default:
+        modem_security = 3;
+        break;
     }
 
     return modem_security;
@@ -191,7 +191,7 @@
         if (sscanf(buf, ": %d", &a) == 1) {
             socket = find_socket(a);
             tr_debug("Socket 0x%08x: handle %d closed by remote host",
-                     (unsigned int) socket, a);
+                    (unsigned int) socket, a);
             clear_socket(socket);
         }
     }
@@ -211,7 +211,7 @@
         if (sscanf(buf, ": %d", &a) == 1) {
             socket = find_socket(a);
             tr_debug("Socket 0x%08x: handle %d connection lost",
-                     (unsigned int) socket, a);
+                    (unsigned int) socket, a);
             clear_socket(socket);
             if (_connection_status_cb) {
                 _connection_status_cb(NSAPI_ERROR_CONNECTION_LOST);
@@ -241,9 +241,9 @@
 // Active a connection profile on board the modem.
 // Note: the AT interface should be locked before this is called.
 bool UbloxATCellularInterface::activate_profile(const char* apn,
-                                                const char* username,
-                                                const char* password,
-                                                nsapi_security_t auth)
+        const char* username,
+        const char* password,
+        nsapi_security_t auth)
 {
     bool activated = false;
     bool success = false;
@@ -269,7 +269,7 @@
         // 1 = PAP (Password Authentication Protocol)
         // 2 = CHAP (Challenge Handshake Authentication Protocol)
         for (int protocol = nsapi_security_to_modem_security(NSAPI_SECURITY_NONE);
-             success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP)); protocol++) {
+                success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP)); protocol++) {
             if ((_auth == NSAPI_SECURITY_UNKNOWN) || (nsapi_security_to_modem_security(_auth) == protocol)) {
                 if (_at->send("AT+UPSD=" PROFILE ",6,%d", protocol) && _at->recv("OK")) {
                     // Activate, waiting 30 seconds for the connection to be made
@@ -298,8 +298,8 @@
     //+CGDCONT: <cid>,"IP","<apn name>","<ip adr>",0,0,0,0,0,0
     if (_at->send("AT+CGDCONT?")) {
         if (_at->recv("+CGDCONT: %d,\"IP\",\"%*[^\"]\",\"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\",%*d,%*d,%*d,%*d,%*d,%*d",
-                      &t, ip) &&
-            _at->recv("OK")) {
+                &t, ip) &&
+                _at->recv("OK")) {
             // Check if the IP address is valid
             if (address.set_ip_address(ip)) {
                 cid = t;
@@ -321,10 +321,10 @@
 // Activate a profile by context ID.
 // Note: the AT interface should be locked before this is called.
 bool UbloxATCellularInterface::activate_profile_by_cid(int cid,
-                                                       const char* apn,
-                                                       const char* username,
-                                                       const char* password,
-                                                       nsapi_security_t auth)
+        const char* apn,
+        const char* username,
+        const char* password,
+        nsapi_security_t auth)
 {
     bool success = false;
     int at_timeout = _at_timeout;
@@ -332,9 +332,9 @@
     // Must be detached to change CGDCONT
     if (_at->send("AT+CGATT=0") && _at->recv("OK")) {
         if (_at->send("AT+CGDCONT=%d,\"IP\",\"%s\"", cid, apn) && _at->recv("OK") &&
-            _at->send("AT+UAUTHREQ=%d,%d,\"%s\",\"%s\"", cid, nsapi_security_to_modem_security(auth),
-                      username, password) && _at->recv("OK") &&
-            _at->send("AT+UPSD=" PROFILE ",100,%d", cid) && _at->recv("OK")) {
+                _at->send("AT+UAUTHREQ=%d,%d,\"%s\",\"%s\"", cid, nsapi_security_to_modem_security(auth),
+                        username, password) && _at->recv("OK") &&
+                        _at->send("AT+UPSD=" PROFILE ",100,%d", cid) && _at->recv("OK")) {
 
             // Wait 30 seconds for the connection to be made
             at_set_timeout(30000);
@@ -357,7 +357,7 @@
 
     // Check the profile
     if (_at->send("AT+UPSND=" PROFILE ",8") && _at->recv("+UPSND: %*d,%*d,%d\n", &active) &&
-        _at->recv("OK")) {
+            _at->recv("OK")) {
         if (active == 0) {
             // If the caller hasn't entered an APN, try to find it
             if (_apn == NULL) {
@@ -426,7 +426,7 @@
 
 // Create a socket.
 nsapi_error_t UbloxATCellularInterface::socket_open(nsapi_socket_t *handle,
-                                                    nsapi_protocol_t proto)
+        nsapi_protocol_t proto)
 {
     nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
     bool success = false;
@@ -450,7 +450,7 @@
         if (success) {
             nsapi_error = NSAPI_ERROR_NO_SOCKET;
             if (_at->recv("+USOCR: %d\n", &modem_handle) && (modem_handle != SOCKET_UNUSED) &&
-                _at->recv("OK")) {
+                    _at->recv("OK")) {
                 tr_debug("Socket 0x%8x: handle %d was created", (unsigned int) socket, modem_handle);
                 clear_socket(socket);
                 socket->modem_handle         = modem_handle;
@@ -478,7 +478,7 @@
     MBED_ASSERT (check_socket(socket));
 
     if (_at->send("AT+USOCL=%d", socket->modem_handle) &&
-        _at->recv("OK")) {
+            _at->recv("OK")) {
         clear_socket(socket);
         nsapi_error = NSAPI_ERROR_OK;
     }
@@ -489,7 +489,7 @@
 
 // Bind a local port to a socket.
 nsapi_error_t UbloxATCellularInterface::socket_bind(nsapi_socket_t handle,
-                                                    const SocketAddress &address)
+        const SocketAddress &address)
 {
     nsapi_error_t nsapi_error = NSAPI_ERROR_NO_SOCKET;
     int proto;
@@ -504,18 +504,18 @@
 
     // Query the socket type
     if (_at->send("AT+USOCTL=%d,0", socket->modem_handle) &&
-        _at->recv("+USOCTL: %*d,0,%d\n", &proto) &&
-        _at->recv("OK")) {
+            _at->recv("+USOCTL: %*d,0,%d\n", &proto) &&
+            _at->recv("OK")) {
         savedSocket = *socket;
         nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
         // Now close the socket and re-open it with the binding given
         if (_at->send("AT+USOCL=%d", socket->modem_handle) &&
-            _at->recv("OK")) {
+                _at->recv("OK")) {
             clear_socket(socket);
             nsapi_error = NSAPI_ERROR_CONNECTION_LOST;
             if (_at->send("AT+USOCR=%d,%d", proto, address.get_port()) &&
-                _at->recv("+USOCR: %d\n", &modem_handle) && (modem_handle != SOCKET_UNUSED) &&
-                _at->recv("OK")) {
+                    _at->recv("+USOCR: %d\n", &modem_handle) && (modem_handle != SOCKET_UNUSED) &&
+                    _at->recv("OK")) {
                 *socket = savedSocket;
                 nsapi_error = NSAPI_ERROR_OK;
             }
@@ -528,20 +528,20 @@
 
 // Connect to a socket
 nsapi_error_t UbloxATCellularInterface::socket_connect(nsapi_socket_t handle,
-                                                       const SocketAddress &address)
+        const SocketAddress &address)
 {
     nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
     SockCtrl *socket = (SockCtrl *) handle;
     LOCK();
 
     tr_debug("socket_connect(0x%08x, %s(:%d))", (unsigned int) handle,
-             address.get_ip_address(), address.get_port());
+            address.get_ip_address(), address.get_port());
 
     MBED_ASSERT (check_socket(socket));
 
     if (_at->send("AT+USOCO=%d,\"%s\",%d", socket->modem_handle,
-                  address.get_ip_address(), address.get_port()) &&
-        _at->recv("OK")) {
+            address.get_ip_address(), address.get_port()) &&
+            _at->recv("OK")) {
         nsapi_error = NSAPI_ERROR_OK;
     }
 
@@ -551,8 +551,8 @@
 
 // Send to a socket.
 nsapi_size_or_error_t UbloxATCellularInterface::socket_send(nsapi_socket_t handle,
-                                                            const void *data,
-                                                            nsapi_size_t size)
+        const void *data,
+        nsapi_size_t size)
 {
     nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
     bool success = true;
@@ -579,7 +579,7 @@
         if (_at->send("AT+USOWR=%d,%d", socket->modem_handle, blk) && _at->recv("@")) {
             wait_ms(50);
             if ((_at->write(buf, blk) < (int) blk) ||
-                 !_at->recv("OK")) {
+                    !_at->recv("OK")) {
                 success = false;
             }
         } else {
@@ -603,9 +603,9 @@
 
 // Send to an IP address.
 nsapi_size_or_error_t UbloxATCellularInterface::socket_sendto(nsapi_socket_t handle,
-                                                              const SocketAddress &address,
-                                                              const void *data,
-                                                              nsapi_size_t size)
+        const SocketAddress &address,
+        const void *data,
+        nsapi_size_t size)
 {
     nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
     bool success = true;
@@ -615,7 +615,7 @@
     SockCtrl *socket = (SockCtrl *) handle;
 
     tr_debug("socket_sendto(0x%8x, %s(:%d), 0x%08x, %d)", (unsigned int) handle,
-             address.get_ip_address(), address.get_port(), (unsigned int) data, size);
+            address.get_ip_address(), address.get_port(), (unsigned int) data, size);
 
     MBED_ASSERT (check_socket(socket));
 
@@ -630,11 +630,11 @@
         LOCK();
 
         if (_at->send("AT+USOST=%d,\"%s\",%d,%d", socket->modem_handle,
-                      address.get_ip_address(), address.get_port(), blk) &&
-            _at->recv("@")) {
+                address.get_ip_address(), address.get_port(), blk) &&
+                _at->recv("@")) {
             wait_ms(50);
             if ((_at->write(buf, blk) >= (int) blk) &&
-                 _at->recv("OK")) {
+                    _at->recv("OK")) {
             } else {
                 success = false;
             }
@@ -659,8 +659,8 @@
 
 // Receive from a socket, TCP style.
 nsapi_size_or_error_t UbloxATCellularInterface::socket_recv(nsapi_socket_t handle,
-                                                            void *data,
-                                                            nsapi_size_t size)
+        void *data,
+        nsapi_size_t size)
 {
     nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
     bool success = true;
@@ -674,7 +674,7 @@
     int at_timeout;
 
     tr_debug("socket_recv(0x%08x, 0x%08x, %d)",
-             (unsigned int) handle, (unsigned int) data, size);
+            (unsigned int) handle, (unsigned int) data, size);
 
     MBED_ASSERT (check_socket(socket));
 
@@ -690,62 +690,97 @@
         at_timeout = _at_timeout;
         at_set_timeout(1000);
 
-        read_blk = MAX_READ_SIZE;
-        if (read_blk > size) {
-            read_blk = size;
-        }
-        if (socket->pending > 0) {
-            tr_debug("Socket 0x%08x: modem handle %d has %d byte(s) pending",
-                     (unsigned int) socket, socket->modem_handle, socket->pending);
-            _at->debug_on(false); // ABSOLUTELY no time for debug here if you want to
-                                  // be able to read packets of any size without
-                                  // losing characters in UARTSerial
-            if (_at->send("AT+USORD=%d,%d", socket->modem_handle, read_blk) &&
-                _at->recv("+USORD: %*d,%d,\"", &usord_sz)) {
-                // Must use what +USORD returns here as it may be less or more than we asked for
-                if (usord_sz > socket->pending) {
-                    socket->pending = 0;
+        do {
+
+#ifdef USE_HEX_MODE_USORx
+            if (_at->send("AT+UDCONF=1,1") && _at->recv("OK")) {
+            } else {
+                success = false;
+                break;
+            }
+#endif
+            read_blk = MAX_READ_SIZE;
+            if (read_blk > size) {
+                read_blk = size;
+            }
+            if (socket->pending > 0) {
+                tr_debug("Socket 0x%08x: modem handle %d has %d byte(s) pending",
+                        (unsigned int) socket, socket->modem_handle, socket->pending);
+                _at->debug_on(false); // ABSOLUTELY no time for debug here if you want to
+                // be able to read packets of any size without
+                // losing characters in UARTSerial
+                if (_at->send("AT+USORD=%d,%d", socket->modem_handle, read_blk) &&
+                        _at->recv("+USORD: %*d,%d,\"", &usord_sz)) {
+                    // Must use what +USORD returns here as it may be less or more than we asked for
+                    if (usord_sz > socket->pending) {
+                        socket->pending = 0;
+                    } else {
+                        socket->pending -= usord_sz;
+                    }
+                    // Note: insert no debug between _at->recv() and _at->read(), no time...
+                    if (usord_sz > size) {
+                        usord_sz = size;
+                    }
+#ifdef USE_HEX_MODE_USORx
+                    read_sz = 0;
+                    char asciiBytes[2];
+                    while (success && (read_sz < usord_sz)) {
+                        // Read the 2 bytes of ascii text for this byte of data
+                        if (2 == _at->read(asciiBytes, 2)) {
+                            read_sz += 2;
+                            // convert to binary data and store in read buffer
+                            sscanf(asciiBytes, "%2hhx", buf+(read_sz/2));
+                        } else {
+                            success = false;
+                        }
+                    }
+#else
+                    read_sz = _at->read(buf, usorf_sz);
+#endif
+                    if (read_sz > 0) {
+                        tr_debug("...read %d byte(s) from modem handle %d...", read_sz,
+                                socket->modem_handle);
+                        if (_debug_trace_on) {
+                            tr_debug("Read returned %d,  |%*.*s|", read_sz, read_sz, read_sz, buf);
+                        }
+                        count += read_sz;
+                        buf += read_sz;
+                        size -= read_sz;
+                    } else {
+                        // read() should not fail
+                        success = false;
+                    }
+                    tr_debug("Socket 0x%08x: modem handle %d now has only %d byte(s) pending",
+                            (unsigned int) socket, socket->modem_handle, socket->pending);
+                    // Wait for the "OK" before continuing
+                    _at->recv("OK");
                 } else {
-                    socket->pending -= usord_sz; 
-                }
-                // Note: insert no debug between _at->recv() and _at->read(), no time...
-                if (usord_sz > size) {
-                    usord_sz = size;
-                }
-                read_sz = _at->read(buf, usord_sz);
-                if (read_sz > 0) {
-                    tr_debug("...read %d byte(s) from modem handle %d...", read_sz,
-                             socket->modem_handle);
-                    if (_debug_trace_on) {
-                        tr_debug("Read returned %d,  |%*.*s|", read_sz, read_sz, read_sz, buf);
-                    }
-                    count += read_sz;
-                    buf += read_sz;
-                    size -= read_sz;
-                } else {
-                    // read() should not fail
+                    // Should never fail to do _at->send()/_at->recv()
                     success = false;
                 }
-                tr_debug("Socket 0x%08x: modem handle %d now has only %d byte(s) pending",
-                         (unsigned int) socket, socket->modem_handle, socket->pending);
-                // Wait for the "OK" before continuing
-                _at->recv("OK");
+                _at->debug_on(_debug_trace_on);
+            } else if (timer.read_ms() < SOCKET_TIMEOUT) {
+                // Wait for URCs
+                _at->recv(UNNATURAL_STRING);
             } else {
-                // Should never fail to do _at->send()/_at->recv()
-                success = false;
+                if (count == 0) {
+                    // Timeout with nothing received
+                    nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK;
+                    success = false;
+                }
+                size = 0; // This simply to cause an exit
             }
-            _at->debug_on(_debug_trace_on);
-        } else if (timer.read_ms() < SOCKET_TIMEOUT) {
-            // Wait for URCs
-            _at->recv(UNNATURAL_STRING);
+
+        } while (0);  // Any fails that set success=false can simply break, avoids even worse nested if's
+
+#ifdef USE_HEX_MODE_USORx
+        // Set back to non-hex mode
+        if (_at->send("AT+UDCONF=1,0") && _at->recv("OK")) {
         } else {
-            if (count == 0) {
-                // Timeout with nothing received
-                nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK;
-                success = false;
-            }
-            size = 0; // This simply to cause an exit
+            success = false;
+            break;
         }
+#endif
 
         at_set_timeout(at_timeout);
         UNLOCK();
@@ -767,9 +802,9 @@
 
 // Receive a packet over a UDP socket.
 nsapi_size_or_error_t UbloxATCellularInterface::socket_recvfrom(nsapi_socket_t handle,
-                                                                SocketAddress *address,
-                                                                void *data,
-                                                                nsapi_size_t size)
+        SocketAddress *address,
+        void *data,
+        nsapi_size_t size)
 {
     nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
     bool success = true;
@@ -785,7 +820,7 @@
     int at_timeout;
 
     tr_debug("socket_recvfrom(0x%08x, 0x%08x, %d)",
-             (unsigned int) handle, (unsigned int) data, size);
+            (unsigned int) handle, (unsigned int) data, size);
 
     MBED_ASSERT (check_socket(socket));
 
@@ -796,83 +831,118 @@
         at_timeout = _at_timeout;
         at_set_timeout(1000);
 
-        read_blk = MAX_READ_SIZE;
-        if (read_blk > size) {
-            read_blk = size;
-        }
-        if (socket->pending > 0) {
-            tr_debug("Socket 0x%08x: modem handle %d has %d byte(s) pending",
-                     (unsigned int) socket, socket->modem_handle, socket->pending);
-            memset (ipAddress, 0, sizeof (ipAddress)); // Ensure terminator
+        do {
 
-            // Note: the maximum length of UDP packet we can receive comes from
-            // fitting all of the following into one buffer:
-            //
-            // +USORF: xx,"max.len.ip.address.ipv4.or.ipv6",yyyyy,wwww,"the_data"\r\n
-            //
-            // where xx is the handle, max.len.ip.address.ipv4.or.ipv6 is NSAPI_IP_SIZE,
-            // yyyyy is the port number (max 65536), wwww is the length of the data and
-            // the_data is binary data. I make that 29 + 48 + len(the_data),
-            // so the overhead is 77 bytes.
+#ifdef USE_HEX_MODE_USORx
+            if (_at->send("AT+UDCONF=1,1") && _at->recv("OK")) {
+            } else {
+                success = false;
+                break;
+            }
+#endif
+            read_blk = MAX_READ_SIZE;
+            if (read_blk > size) {
+                read_blk = size;
+            }
+            if (socket->pending > 0) {
+                tr_debug("Socket 0x%08x: modem handle %d has %d byte(s) pending",
+                        (unsigned int) socket, socket->modem_handle, socket->pending);
+                memset (ipAddress, 0, sizeof (ipAddress)); // Ensure terminator
+
+                // Note: the maximum length of UDP packet we can receive comes from
+                // fitting all of the following into one buffer:
+                //
+                // +USORF: xx,"max.len.ip.address.ipv4.or.ipv6",yyyyy,wwww,"the_data"\r\n
+                //
+                // where xx is the handle, max.len.ip.address.ipv4.or.ipv6 is NSAPI_IP_SIZE,
+                // yyyyy is the port number (max 65536), wwww is the length of the data and
+                // the_data is binary data. I make that 29 + 48 + len(the_data),
+                // so the overhead is 77 bytes.
 
-            _at->debug_on(false); // ABSOLUTELY no time for debug here if you want to
-                                  // be able to read packets of any size without
-                                  // losing characters in UARTSerial
-            if (_at->send("AT+USORF=%d,%d", socket->modem_handle, read_blk) &&
-                _at->recv("+USORF: %*d,\"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\",%d,%d,\"",
-                          ipAddress, &port, &usorf_sz)) {
-                // Must use what +USORF returns here as it may be less or more than we asked for
-                if (usorf_sz > socket->pending) {
-                    socket->pending = 0;
+                _at->debug_on(false); // ABSOLUTELY no time for debug here if you want to
+                // be able to read packets of any size without
+                // losing characters in UARTSerial
+                if (_at->send("AT+USORF=%d,%d", socket->modem_handle, read_blk) &&
+                        _at->recv("+USORF: %*d,\"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\",%d,%d,\"",
+                                ipAddress, &port, &usorf_sz)) {
+                    // Must use what +USORF returns here as it may be less or more than we asked for
+                    if (usorf_sz > socket->pending) {
+                        socket->pending = 0;
+                    } else {
+                        socket->pending -= usorf_sz;
+                    }
+                    // Note: insert no debug between _at->recv() and _at->read(), no time...
+                    if (usorf_sz > size) {
+                        usorf_sz = size;
+                    }
+#ifdef USE_HEX_MODE_USORx
+                    read_sz = 0;
+                    char asciiBytes[2];
+                    while (success && (read_sz < usorf_sz)) {
+                        // Read the 2 bytes of ascii text for this byte of data
+                        if (2 == _at->read(asciiBytes, 2)) {
+                            // convert to binary data and store in read buffer
+                            //tr_debug("%c %c", asciiBytes[0], asciiBytes[1]);
+                            sscanf(asciiBytes, "%2hhx", buf+(read_sz/2));
+                            read_sz += 2;
+                        } else {
+                            success = false;
+                        }
+                    }
+#else
+                    read_sz = _at->read(buf, usorf_sz);
+#endif
+                    if (read_sz > 0) {
+                        address->set_ip_address(ipAddress);
+                        address->set_port(port);
+                        tr_debug("...read %d byte(s) from modem handle %d...", read_sz,
+                                socket->modem_handle);
+                        if (_debug_trace_on) {
+                            tr_debug("Read returned %d,  |%*.*s|", read_sz, read_sz, read_sz, buf);
+                        }
+                        count += read_sz;
+                        buf += read_sz;
+                        size -= read_sz;
+                        if ((usorf_sz < read_blk) || (usorf_sz == MAX_READ_SIZE)) {
+                            size = 0; // If we've received less than we asked for, or
+                            // the max size, then a whole UDP packet has arrived and
+                            // this means DONE.
+                        }
+                    } else {
+                        // read() should not fail
+                        success = false;
+                    }
+                    tr_debug("Socket 0x%08x: modem handle %d now has only %d byte(s) pending",
+                            (unsigned int) socket, socket->modem_handle, socket->pending);
+                    // Wait for the "OK" before continuing
+                    _at->recv("OK");
                 } else {
-                    socket->pending -= usorf_sz; 
-                }
-                // Note: insert no debug between _at->recv() and _at->read(), no time...
-                if (usorf_sz > size) {
-                    usorf_sz = size;
-                }
-                read_sz = _at->read(buf, usorf_sz);
-                if (read_sz > 0) {
-                    address->set_ip_address(ipAddress);
-                    address->set_port(port);
-                    tr_debug("...read %d byte(s) from modem handle %d...", read_sz,
-                             socket->modem_handle);
-                    if (_debug_trace_on) {
-                        tr_debug("Read returned %d,  |%*.*s|", read_sz, read_sz, read_sz, buf);
-                    }
-                    count += read_sz;
-                    buf += read_sz;
-                    size -= read_sz;
-                    if ((usorf_sz < read_blk) || (usorf_sz == MAX_READ_SIZE)) {
-                        size = 0; // If we've received less than we asked for, or
-                                  // the max size, then a whole UDP packet has arrived and
-                                  // this means DONE.
-                    }
-                } else {
-                    // read() should not fail
+                    // Should never fail to do _at->send()/_at->recv()
                     success = false;
                 }
-                tr_debug("Socket 0x%08x: modem handle %d now has only %d byte(s) pending",
-                         (unsigned int) socket, socket->modem_handle, socket->pending);
-                // Wait for the "OK" before continuing
-                _at->recv("OK");
+                _at->debug_on(_debug_trace_on);
+            } else if (timer.read_ms() < SOCKET_TIMEOUT) {
+                // Wait for URCs
+                _at->recv(UNNATURAL_STRING);
             } else {
-                // Should never fail to do _at->send()/_at->recv()
-                success = false;
+                if (count == 0) {
+                    // Timeout with nothing received
+                    nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK;
+                    success = false;
+                }
+                size = 0; // This simply to cause an exit
             }
-            _at->debug_on(_debug_trace_on);
-        } else if (timer.read_ms() < SOCKET_TIMEOUT) {
-            // Wait for URCs
-            _at->recv(UNNATURAL_STRING);
+
+        } while (0);  // Any fails that set success=false can simply break, avoids even worse nested if's
+
+#ifdef USE_HEX_MODE_USORx
+        // Set back to non-hex mode
+        if (_at->send("AT+UDCONF=1,0") && _at->recv("OK")) {
         } else {
-            if (count == 0) {
-                // Timeout with nothing received
-                nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK;
-                success = false;
-            }
-            size = 0; // This simply to cause an exit
+            success = false;
+            break;
         }
-
+#endif
         at_set_timeout(at_timeout);
         UNLOCK();
     }
@@ -894,8 +964,8 @@
 // Attach an event callback to a socket, required for asynchronous
 // data reception
 void UbloxATCellularInterface::socket_attach(nsapi_socket_t handle,
-                                             void (*callback)(void *),
-                                             void *data)
+        void (*callback)(void *),
+        void *data)
 {
     SockCtrl *socket = (SockCtrl *) handle;
 
@@ -907,29 +977,29 @@
 
 // Unsupported TCP server functions.
 nsapi_error_t UbloxATCellularInterface::socket_listen(nsapi_socket_t handle,
-                                                      int backlog)
+        int backlog)
 {
     return NSAPI_ERROR_UNSUPPORTED;
 }
 nsapi_error_t UbloxATCellularInterface::socket_accept(nsapi_socket_t server,
-                                                      nsapi_socket_t *handle,
-                                                      SocketAddress *address)
+        nsapi_socket_t *handle,
+        SocketAddress *address)
 {
     return NSAPI_ERROR_UNSUPPORTED;
 }
 
 // Unsupported option functions.
 nsapi_error_t UbloxATCellularInterface::setsockopt(nsapi_socket_t handle,
-                                                   int level, int optname,
-                                                   const void *optval,
-                                                   unsigned optlen)
+        int level, int optname,
+        const void *optval,
+        unsigned optlen)
 {
     return NSAPI_ERROR_UNSUPPORTED;
 }
 nsapi_error_t UbloxATCellularInterface::getsockopt(nsapi_socket_t handle,
-                                                   int level, int optname,
-                                                   void *optval,
-                                                   unsigned *optlen)
+        int level, int optname,
+        void *optval,
+        unsigned *optlen)
 {
     return NSAPI_ERROR_UNSUPPORTED;
 }
@@ -940,9 +1010,9 @@
 
 // Constructor.
 UbloxATCellularInterface::UbloxATCellularInterface(PinName tx,
-                                                   PinName rx,
-                                                   int baud,
-                                                   bool debug_on)
+        PinName rx,
+        int baud,
+        bool debug_on)
 {
     _sim_pin_check_change_pending = false;
     _sim_pin_check_change_pending_enabled_value = false;
@@ -987,7 +1057,7 @@
     // Let the event thread shut down tidily
     _run_event_thread = false;
     event_thread.join();
-    
+
     // Free _ip if it was ever allocated
     free(_ip);
 }
@@ -1000,8 +1070,8 @@
 
 // Set APN, user name and password.
 void  UbloxATCellularInterface::set_credentials(const char *apn,
-                                                const char *uname,
-                                                const char *pwd)
+        const char *uname,
+        const char *pwd)
 {
     _apn = apn;
     _uname = uname;
@@ -1016,8 +1086,8 @@
 
 // Get the IP address of a host.
 nsapi_error_t UbloxATCellularInterface::gethostbyname(const char *host,
-                                                      SocketAddress *address,
-                                                      nsapi_version_t version)
+        SocketAddress *address,
+        nsapi_version_t version)
 {
     nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
     int at_timeout;
@@ -1032,8 +1102,8 @@
         at_set_timeout(60000);
         memset (ipAddress, 0, sizeof (ipAddress)); // Ensure terminator
         if (_at->send("AT+UDNSRN=0,\"%s\"", host) &&
-            _at->recv("+UDNSRN: \"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\"", ipAddress) &&
-            _at->recv("OK")) {
+                _at->recv("+UDNSRN: \"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\"", ipAddress) &&
+                _at->recv("OK")) {
             if (address->set_ip_address(ipAddress)) {
                 nsapi_error = NSAPI_ERROR_OK;
             }
@@ -1047,9 +1117,9 @@
 
 // Make a cellular connection
 nsapi_error_t UbloxATCellularInterface::connect(const char *sim_pin,
-                                                const char *apn,
-                                                const char *uname,
-                                                const char *pwd)
+        const char *apn,
+        const char *uname,
+        const char *pwd)
 {
     nsapi_error_t nsapi_error;
 
@@ -1110,136 +1180,136 @@
 #if defined(TARGET_UBLOX_C030_R410M) || defined (TARGET_SR_L475RG_R410)
     if (registered) {
 #else
-    if (registered && connect_modem_stack()) {
+        if (registered && connect_modem_stack()) {
 #endif
-        nsapi_error = NSAPI_ERROR_OK;
-    }
-
-    return nsapi_error;
-}
-
-// User initiated disconnect.
-nsapi_error_t UbloxATCellularInterface::disconnect()
-{
-    nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
+            nsapi_error = NSAPI_ERROR_OK;
+        }
 
-    if (disconnect_modem_stack() && nwk_deregistration()) {
-        nsapi_error = NSAPI_ERROR_OK;
-    }
-
-    return nsapi_error;
-}
-
-// Enable or disable SIM PIN check lock.
-nsapi_error_t UbloxATCellularInterface::set_sim_pin_check(bool set,
-                                                          bool immediate,
-                                                          const char *sim_pin)
-{
-    nsapi_error_t nsapi_error = NSAPI_ERROR_AUTH_FAILURE;
-
-    if (sim_pin != NULL) {
-        _pin = sim_pin;
+        return nsapi_error;
     }
 
-    if (immediate) {
-        if (init()) {
-            if (sim_pin_check_enable(set)) {
-                nsapi_error = NSAPI_ERROR_OK;
-            }
-        } else {
-            nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
+    // User initiated disconnect.
+    nsapi_error_t UbloxATCellularInterface::disconnect()
+    {
+        nsapi_error_t nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
+
+        if (disconnect_modem_stack() && nwk_deregistration()) {
+            nsapi_error = NSAPI_ERROR_OK;
         }
-    } else {
-        nsapi_error = NSAPI_ERROR_OK;
-        _sim_pin_check_change_pending = true;
-        _sim_pin_check_change_pending_enabled_value = set;
+
+        return nsapi_error;
     }
 
-    return nsapi_error;
-}
+    // Enable or disable SIM PIN check lock.
+    nsapi_error_t UbloxATCellularInterface::set_sim_pin_check(bool set,
+            bool immediate,
+            const char *sim_pin)
+    {
+        nsapi_error_t nsapi_error = NSAPI_ERROR_AUTH_FAILURE;
 
-// Change the PIN code for the SIM card.
-nsapi_error_t UbloxATCellularInterface::set_new_sim_pin(const char *new_pin,
-                                                        bool immediate,
-                                                        const char *old_pin)
-{
-    nsapi_error_t nsapi_error = NSAPI_ERROR_AUTH_FAILURE;
+        if (sim_pin != NULL) {
+            _pin = sim_pin;
+        }
 
-    if (old_pin != NULL) {
-        _pin = old_pin;
-    }
-
-    if (immediate) {
-        if (init()) {
-            if (change_sim_pin(new_pin)) {
-                nsapi_error = NSAPI_ERROR_OK;
+        if (immediate) {
+            if (init()) {
+                if (sim_pin_check_enable(set)) {
+                    nsapi_error = NSAPI_ERROR_OK;
+                }
+            } else {
+                nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
             }
         } else {
-            nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
+            nsapi_error = NSAPI_ERROR_OK;
+            _sim_pin_check_change_pending = true;
+            _sim_pin_check_change_pending_enabled_value = set;
         }
-    } else {
-        nsapi_error = NSAPI_ERROR_OK;
-        _sim_pin_change_pending = true;
-        _sim_pin_change_pending_new_pin_value = new_pin;
+
+        return nsapi_error;
     }
 
-    return nsapi_error;
-}
+    // Change the PIN code for the SIM card.
+    nsapi_error_t UbloxATCellularInterface::set_new_sim_pin(const char *new_pin,
+            bool immediate,
+            const char *old_pin)
+    {
+        nsapi_error_t nsapi_error = NSAPI_ERROR_AUTH_FAILURE;
 
-// Determine if the connection is up.
-bool UbloxATCellularInterface::is_connected()
-{
-    return get_ip_address() != NULL;
-}
+        if (old_pin != NULL) {
+            _pin = old_pin;
+        }
 
-// Get the IP address of the on-board modem IP stack.
-const char * UbloxATCellularInterface::get_ip_address()
-{
-    SocketAddress address;
-    LOCK();
+        if (immediate) {
+            if (init()) {
+                if (change_sim_pin(new_pin)) {
+                    nsapi_error = NSAPI_ERROR_OK;
+                }
+            } else {
+                nsapi_error = NSAPI_ERROR_DEVICE_ERROR;
+            }
+        } else {
+            nsapi_error = NSAPI_ERROR_OK;
+            _sim_pin_change_pending = true;
+            _sim_pin_change_pending_new_pin_value = new_pin;
+        }
 
-    if (_ip == NULL) {
-        // Temporary storage for an IP address string with terminator
-        _ip = (char *) malloc(NSAPI_IP_SIZE);
+        return nsapi_error;
+    }
+
+    // Determine if the connection is up.
+    bool UbloxATCellularInterface::is_connected()
+    {
+        return get_ip_address() != NULL;
     }
 
-    if (_ip != NULL) {
-        memset(_ip, 0, NSAPI_IP_SIZE); // Ensure a terminator
-        // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>]
-        // If we get back a quoted "w.x.y.z" then we have an IP address,
-        // otherwise we don't.
-        if (!_at->send("AT+UPSND=" PROFILE ",0") ||
-            !_at->recv("+UPSND: " PROFILE ",0,\"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\"", _ip) ||
-            !_at->recv("OK") ||
-            !address.set_ip_address(_ip) || // Return NULL if the address is not a valid one
-            !address) { // Return null if the address is zero
-            free (_ip);
-            _ip = NULL;
+    // Get the IP address of the on-board modem IP stack.
+    const char * UbloxATCellularInterface::get_ip_address()
+    {
+        SocketAddress address;
+        LOCK();
+
+        if (_ip == NULL) {
+            // Temporary storage for an IP address string with terminator
+            _ip = (char *) malloc(NSAPI_IP_SIZE);
         }
+
+        if (_ip != NULL) {
+            memset(_ip, 0, NSAPI_IP_SIZE); // Ensure a terminator
+            // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>]
+            // If we get back a quoted "w.x.y.z" then we have an IP address,
+            // otherwise we don't.
+            if (!_at->send("AT+UPSND=" PROFILE ",0") ||
+                    !_at->recv("+UPSND: " PROFILE ",0,\"%" u_stringify(NSAPI_IP_SIZE) "[^\"]\"", _ip) ||
+                    !_at->recv("OK") ||
+                    !address.set_ip_address(_ip) || // Return NULL if the address is not a valid one
+                    !address) { // Return null if the address is zero
+                free (_ip);
+                _ip = NULL;
+            }
+        }
+
+        UNLOCK();
+        return _ip;
     }
 
-    UNLOCK();
-    return _ip;
-}
-
-// Get the local network mask.
-const char *UbloxATCellularInterface::get_netmask()
-{
-    // Not implemented.
-    return NULL;
-}
+    // Get the local network mask.
+    const char *UbloxATCellularInterface::get_netmask()
+    {
+        // Not implemented.
+        return NULL;
+    }
 
-// Get the local gateways.
-const char *UbloxATCellularInterface::get_gateway()
-{
-    return get_ip_address();
-}
+    // Get the local gateways.
+    const char *UbloxATCellularInterface::get_gateway()
+    {
+        return get_ip_address();
+    }
 
-// Callback in case the connection is lost.
-void UbloxATCellularInterface::connection_status_cb(Callback<void(nsapi_error_t)> cb)
-{
-    _connection_status_cb = cb;
-}
+    // Callback in case the connection is lost.
+    void UbloxATCellularInterface::connection_status_cb(Callback<void(nsapi_error_t)> cb)
+    {
+        _connection_status_cb = cb;
+    }
 
-// End of file
+    // End of file