this is using the mbed os version 5-13-1

Dependencies:   mbed-http

Files at this revision

API Documentation at this revision

Comitter:
ocomeni
Date:
Sat Apr 13 14:17:29 2019 +0000
Parent:
91:d6b6319ad681
Child:
93:06e755a80187
Commit message:
implemented DEFINE switch to resolve mbed memory pool allocation failure

Changed in this revision

mbed_app.json Show annotated file Show diff for this revision Revisions of this file
source/ATCmdManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/ATCmdManager.h Show annotated file Show diff for this revision Revisions of this file
source/WiFiManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/common_config.h Show annotated file Show diff for this revision Revisions of this file
source/common_types.h Show annotated file Show diff for this revision Revisions of this file
source/compiler_abstraction.h Show annotated file Show diff for this revision Revisions of this file
source/main-https.cpp Show annotated file Show diff for this revision Revisions of this file
source/mbed_memory_status.cpp Show annotated file Show diff for this revision Revisions of this file
source/mbed_memory_status.h Show annotated file Show diff for this revision Revisions of this file
--- a/mbed_app.json	Sun Apr 07 17:31:56 2019 +0000
+++ b/mbed_app.json	Sat Apr 13 14:17:29 2019 +0000
@@ -36,7 +36,7 @@
         "MBED_MEM_TRACING_ENABLED=1",
         "MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=0",
         "MBEDTLS_SSL_MAX_CONTENT_LEN=16384",
-        "DEBUG_ISR_STACK_USAGE=1",
+        "DEBUG_ISR_STACK_USAGE=0",
         "MBED_CONF_APP_ERROR_FILENAME_CAPTURE_ENABLED=1"
     ],
     "target_overrides": {
--- a/source/ATCmdManager.cpp	Sun Apr 07 17:31:56 2019 +0000
+++ b/source/ATCmdManager.cpp	Sat Apr 13 14:17:29 2019 +0000
@@ -2,6 +2,7 @@
 #include "common_config.h"
 #include "common_types.h"
 #include "http_request.h"
+#include "mbed_memory_status.h"
 //#include "mbed_memory_status.h"
 
 ATCmdManager::ATCmdManager(PinName tx, PinName rx, SMDevicePeripheral *blePeripheral, 
@@ -64,6 +65,7 @@
     printf("\n --- ATCmdManager constructor completed ---\n");
     at_resp = AT_RESP_NONE;
     dataMode = AT_CMD_DATA_MODE;
+    print_heap_and_isr_stack_info();
     event_queue.call_every(3600000,&print_memory_info);
 }
 
@@ -89,7 +91,7 @@
                 // AT_SCAN_RESP response state
                 printf("\n [ATCMD MAN] WIFI SCAN RESPONSE RECEIVED!!\n");
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -97,7 +99,7 @@
                 // AT_DETAILED_SCAN_RESP response state
                 printf("\n [ATCMD MAN] WIFI DETAILED SCAN RESPONSE RECEIVED!!\n");
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -105,7 +107,7 @@
                 // AT_CONNECT_RESP response state 
                 printf("\n [ATCMD MAN] WIFI CONNECT RESPONSE RECEIVED!!\n");
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -114,7 +116,7 @@
                 //////_smutex.lock();
                 printf("\n [ATCMD MAN] WIFI DISCONNECT RESPONSE RECEIVED!!\n");
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -123,7 +125,7 @@
                 //////_smutex.lock();
                 printf("\n [ATCMD MAN] WIFI CONFIG RESPONSE RECEIVED!!\n");
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -131,7 +133,7 @@
                 // AT_CONFIG_RESP response state 
                 printf("\n [ATCMD MAN] WIFI INTERNET_CONFIG RESPONSE RECEIVED!!\n");
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -140,7 +142,7 @@
                 printf("\n [ATCMD MAN] WIFI HTTPS RESPONSE RECEIVED!!\n");
                 return_response();
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -149,7 +151,7 @@
                 printf("\n [ATCMD MAN] WIFI HTTPS DOWNLOAD RESPONSE RECEIVED!!\n");
                 return_response(true); // set download paramter to true
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -158,7 +160,7 @@
                 printf("\n [ATCMD MAN] WIFI HTTP RESPONSE RECEIVED!!\n");
                 return_response(); 
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -167,7 +169,7 @@
                 printf("\n [ATCMD MAN] WIFI HTTP RESPONSE RECEIVED!!\n");
                 return_response(true); // set download paramter to true
                 _smutex.lock();
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -175,7 +177,7 @@
                 // UNKNOWN response state
                 _smutex.lock();
                 printf("\n [ATCMD MAN] UNKNOWN RESPONSE RECEIVED!!\n");
-                _parser.send("OK\n");
+                _parser.send(OK_RESP);
                 _smutex.unlock();
                 at_resp = AT_RESP_NONE;
                 break;
@@ -329,7 +331,7 @@
 // OOB processing
 void ATCmdManager::_process_oob(uint32_t timeout, bool all){
     set_timeout(timeout);
-    static int cnt = 0;
+    int cnt = 0;
     int start;
     //channel_id_t chan_id;
     if(dataMode == AT_EXT_DATA_MODE)
@@ -337,32 +339,48 @@
         int n;
         //if(cnt++ % 10 == 0)printf("In EDM mode\n");
         uint8_t edm[EDM_HDR_LEN];
-        
+        char cmdType[16];
         // Poll for edm packets
         do{
-            n = _parser.read((char *)edm, EDM_HDR_LEN);
+            n = _parser.read((char *)edm, EDM_HDR_LEN-1);
             edm_hdr.startByte = edm[0];
             edm_hdr.payloadLen = edm[1]*256 + edm[2];
             edm_hdr.payloadID = edm[3]*256 + edm[4];
-            edm_hdr.channel_id = (channel_id_t) edm[5];
+            edm_hdr.channel_id = (channel_id_t) 0;
             start = Kernel::get_ms_count();
             if(n == -1) break; // break if it times out
-            printf("%d bytes read!\n", n);
-            if(n==EDM_HDR_LEN)
+            int pT;
+            if(edm_hdr.payloadID < AT_REQUEST) //
+            {
+                n += _parser.read((char *)edm, 1);
+                edm_hdr.channel_id = (channel_id_t) edm[0];
+                pT = 0;
+                strcpy(cmdType, "DATA COMMAND");
+            }
+            else
+            {
+                pT = 1;
+                strcpy(cmdType, "AT REQUEST");
+            }
+            //printf("%d bytes read! : type = %s\n", n, cmdType2str(edm_hdr.payloadID));
+            printf("%d bytes read! : CMD type = %s\n", n, cmdType);
+            if(n==(EDM_HDR_LEN-pT))
             printf("Start = %d, payloadID = %d len = %d chan_id = %d\n", edm_hdr.startByte, 
                                                                          edm_hdr.payloadID, 
                                                                          edm_hdr.payloadLen,
                                                                          edm_hdr.channel_id);
-            if(n == EDM_HDR_LEN && validate(edm_hdr)) // if AT command use process oob to decode
+            if(n == (EDM_HDR_LEN-pT) && validate(edm_hdr)) // if AT command use process oob to decode
             {
                 if(edm_hdr.payloadID == AT_REQUEST)
                 {
-                    _parser.process_oob();
+                    //_parser.process_oob();
+                    while (_parser.process_oob() && all) {
+                    }
                     break;
                 }
                 else
                 {
-                    int pLen = edm_hdr.payloadLen-2;
+                    int pLen = edm_hdr.payloadLen-2-pT;
                     rx_buf_ptr = (uint8_t *) malloc (pLen); // we already read 2 bytes from payload but expect 1 stop byte
                     rx_buf_ptr[pLen-1] = 0x00; // clear last byte so the readback value is as expected
                     n = _parser.read((char *)rx_buf_ptr, pLen);
@@ -391,7 +409,7 @@
                             printf("DATA_COMMAND received!\n");
                             if(createHttpRequest() == true){
                                 _smutex.lock();
-                                _parser.send("OK");
+                                _parser.send(OK_RESP);
                                 _smutex.unlock();
                             }
                             else{
@@ -399,6 +417,7 @@
                                 _parser.send("NACK");
                                 _smutex.unlock();
                             }
+                            free(rx_buf_ptr);
                             int stop = Kernel::get_ms_count();
                             printf("\n Time Elapsed = %d\n", stop-start);
                             break;
@@ -440,7 +459,7 @@
 
 void ATCmdManager::_oob_ok_hdlr(){
     _smutex.lock();
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
@@ -473,7 +492,10 @@
        //AT+UMRS=230400,2,8,1,1,1
         printf("\n Changing Baud Rate to %d\n", uOpts[0]);
 
+        _parser.send(OK_RESP);
+        wait(0.1);
         _serial.set_baud(uOpts[0]);
+        wait(0.1);
         printf("\n Baud Rate now %d\n", uOpts[0]);
 
     } else {
@@ -493,7 +515,7 @@
     printf("\n Received ATEO OOB command!!\n");
     printf("\n turning echo OFF!!\n");
     _parser.debug_on(false);
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
@@ -504,7 +526,7 @@
     printf("\n Received ATE1 OOB command!!\n");
     printf("\n turning echo ON!!\n");
     _parser.debug_on(true);
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
@@ -527,6 +549,7 @@
             case 2:
                 printf("\nATCmdParser: Extended data Mode request received\n");
                 dataMode = AT_EXT_DATA_MODE;
+                print_heap_and_isr_stack_info();
                 break;
             default:
                 printf("\nATCmdParser: ERROR - UNKNOWN DATA MODE RECEIVED!!! \n");
@@ -535,7 +558,7 @@
     } else {
         printf("\nATCmdParser: Retrieving Uart Options failed\n");
     }
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
@@ -558,28 +581,28 @@
     } else {
         printf("\nATCmdParser: Retrieving Uart Options failed");
     }
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
 void ATCmdManager::_oob_get_ble_role(){
     _smutex.lock();
     printf("\n Received get BLE role command!!\n");
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
 void ATCmdManager::_oob_ena_ble_peri(){
     _smutex.lock();
     printf("\n Received enable BLE Peripheral command!!\n");
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
 }
 
 void ATCmdManager::_oob_reboot(){
     _smutex.lock();
     printf("\n Received reboot command!!\n");
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _parser.send("System Resetting....\n");
     system_reset();
     _smutex.unlock();
@@ -617,7 +640,7 @@
 void ATCmdManager::_oob_scanWiFiNetworks(){
     _smutex.lock();
     printf("\n Received scanWiFiNetworks command!!\n");
-    _parser.send("OK\n");
+    _parser.send(OK_RESP);
     _smutex.unlock();
     wifi_cmd_t cmd = WIFI_CMD_SCAN;
     // queue next command
@@ -627,7 +650,12 @@
 
 void ATCmdManager::_oob_connect2WiFiNetwork()
 {
+    //_smutex.lock();
+    printf("\n Received WiFi Connect command!!\n");
+    _parser.send(OK_RESP);
     wifi_cmd_t cmd = WIFI_CMD_CONNECT;
+    printf("\n About to Queue wifi cmd = %d!!\n", cmd);
+    //_smutex.unlock();
     // queue next command
     queueWiFiCommand(cmd);
     return;
@@ -636,7 +664,11 @@
 
 void ATCmdManager::_oob_disconnectWiFiNetwork()
 {
+    _smutex.lock();
+    printf("\n Received WiFi Disconnect command!!\n");
+    _parser.send(OK_RESP);
     wifi_cmd_t cmd = WIFI_CMD_DISCONNECT;
+    _smutex.unlock();
     // queue next command
     queueWiFiCommand(cmd);
     return;
@@ -655,9 +687,19 @@
     printf("\n read string = %s , n = %d\n", str, n);
     //n = sscanf(str, "=%1d,%199[^,],%1d", &(uint8_t)internet_config.peer_id, 
     n = sscanf(str, "=%1d,%99[^,],%1d", &internet_config.peer_id, 
-                                         url, //internet_config.url,
-                                         &internet_config.connectionScheme);
-    strncpy(internet_config.url, url, strlen(url)+1);
+                                         url, //internet_config.url,    
+                                        &internet_config.connectionScheme);
+    char *p = strstr(url,"\""); 
+    if(p!=NULL)
+    {
+        strncpy(internet_config.url, &p[1], strlen(url));
+        p = strstr(internet_config.url,"\"");
+        *p = NULL;
+    }
+    else
+    {
+        strncpy(internet_config.url, url, strlen(url)+1);
+    }
     printf("\n read string = %s , n = %d -- strlen(url) = %d\n", internet_config.url, n, strlen(internet_config.url));
     if(n>0) 
     {
@@ -673,7 +715,7 @@
         // queue next data request
         queueWiFiDataRequest(data_msg);
         print_memory_info();
-        _parser.send("OK\n");
+        _parser.send(OK_RESP);
     } else {
         printf("\n[ATCMD MAN]: internet configuration failed %d fields parsed \n", n);
         _parser.send("NAK\n");
@@ -737,7 +779,7 @@
         data_msg.dataLen = sizeof(wifi_config_t);
         memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
         queueWiFiDataRequest(data_msg);
-        _parser.send("OK\n");
+        _parser.send(OK_RESP);
     } else {
         printf("\n[ATCMD MAN]: wifi configuration failed  \n");
         _parser.send("NAK\n");
@@ -754,14 +796,14 @@
     n = readStringBytes((uint8_t *)wifi_cfg.pass, 32);
     if(n>0) 
     {
-        printf("ATCMD MAN]: wifi_cfg.pass = %s\n", wifi_cfg.pass);
+        printf("ATCMD MAN]: wifi_cfg.pass = %s\n", "****************");
         // package and send on wifi data queue
         wifi_data_msg_t data_msg;
         data_msg.wifi_cmd = WIFI_CMD_CONFIG;
         data_msg.dataLen = sizeof(wifi_config_t);
         memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
         queueWiFiDataRequest(data_msg);
-        _parser.send("OK\n");
+        _parser.send(OK_RESP);
     } else {
         printf("\n[ATCMD MAN]: wifi configuration failed  \n");
         _parser.send("NAK\n");
@@ -785,7 +827,7 @@
         data_msg.dataLen = sizeof(wifi_config_t);
         memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
         queueWiFiDataRequest(data_msg);
-        _parser.send("OK\n");
+        _parser.send(OK_RESP);
     } else {
         printf("\n[ATCMD MAN]: wifi configuration failed  \n");
         _smutex.lock();
@@ -812,7 +854,7 @@
         data_msg.dataLen = sizeof(wifi_config_t);
         memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
         queueWiFiDataRequest(data_msg);
-        _parser.send("OK\n");
+        _parser.send(OK_RESP);
     } else {
         printf("\n[ATCMD MAN]: wifi configuration failed  \n");
         _parser.send("NAK\n");
@@ -823,9 +865,27 @@
 }
 
 bool  ATCmdManager::queueWiFiCommand(wifi_cmd_t cmd){
+    printf("[ATCMD MAN] about to be queued with wifi_cmd = %d\n", cmd);
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
     wifi_cmd_message_t *wifiCmd = _aT2WiFimPool->alloc();
+    if(wifiCmd == NULL){
+        printf("[ATCMD MAN] queued memory allocation failed\n");
+        print_memory_info();
+        print_heap_and_isr_stack_info();
+        return false;
+    }
+#else
+    wifi_cmd_message_t *wifiCmd = (wifi_cmd_message_t *) malloc(sizeof(wifi_cmd_message_t));
+    if(wifiCmd == NULL){
+        printf("[ATCMD MAN] tr malloc() : queued memory allocation failed\n");
+        print_memory_info();
+        print_heap_and_isr_stack_info();
+        return false;
+    }
+#endif
     wifiCmd->wifi_cmd            = cmd;
     _aT2WiFiCmdQueue->put(wifiCmd);
+    printf("[ATCMD MAN] queued wifi_cmd = %d\n", wifiCmd->wifi_cmd);
     return true;
 }
 
@@ -835,7 +895,11 @@
     if(evt.status == osEventMessage){
         at_resp_message_t *resp = (at_resp_message_t*)evt.value.p;
         setNextResponse(resp->at_resp);
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
         _wiFi2ATmPool->free(resp);
+#else
+        free(resp);
+#endif
     }
     return true;
 }
--- a/source/ATCmdManager.h	Sun Apr 07 17:31:56 2019 +0000
+++ b/source/ATCmdManager.h	Sat Apr 13 14:17:29 2019 +0000
@@ -13,6 +13,7 @@
 #define UBLOX_ODIN_W2_MISC_TIMEOUT    2000
 #endif
 
+#define OK_RESP "OK\n\r"
 extern void print_memory_info();
 class ATCmdManager {
 public:
--- a/source/WiFiManager.cpp	Sun Apr 07 17:31:56 2019 +0000
+++ b/source/WiFiManager.cpp	Sat Apr 13 14:17:29 2019 +0000
@@ -41,7 +41,11 @@
 }
   
 bool WiFiManager::queueATresponse(at_cmd_resp_t resp){
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
     at_resp_message_t *atResp  = _wiFi2ATmPool->alloc();
+#else
+    at_resp_message_t *atResp  = (at_resp_message_t *) malloc(sizeof(at_resp_message_t));
+#endif
     if(atResp == NULL) return false; // queue full;
     atResp->at_resp            = resp;
     _wiFi2ATCmdQueue->put(atResp);
@@ -154,7 +158,11 @@
     if(evt.status == osEventMessage){
         wifi_cmd_message_t *cmd = (wifi_cmd_message_t*)evt.value.p;
         setNextCommand(cmd->wifi_cmd);
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
         _aT2WiFimPool->free(cmd);
+#else
+        free(cmd);
+#endif
     }
     return true;
 }
@@ -174,11 +182,12 @@
 
 bool WiFiManager::setNextCommand(wifi_cmd_t cmd)
 {
-    printf("\n [WIFI-MAN] About to set next WiFi manager command \n");
+    printf("\n [WIFI-MAN] About to set next WiFi manager command to %d\n", cmd);
     if(wifiCmd == WIFI_CMD_NONE){
         wifiCmd = cmd;
         return true; // success
     }
+    printf("\n [WIFI-MAN] Busy : current state = %d \n", wifiCmd);
     return false; // wiFiManager busy
 }
 
@@ -268,7 +277,7 @@
 void WiFiManager::set_WIFI_PASSWORD(char * wifi_pass)
 {
     strcpy(wifi_config.pass, wifi_pass);
-    printf("[WIFI-MAN]  wifi_pass set to %s\n", wifi_config.pass);
+    printf("[WIFI-MAN]  wifi_pass set to %s\n", "****************");
     https_connection_active = false; // reset whenever any of the security credentials change
     delete socket;
 }
--- a/source/common_config.h	Sun Apr 07 17:31:56 2019 +0000
+++ b/source/common_config.h	Sat Apr 13 14:17:29 2019 +0000
@@ -11,7 +11,7 @@
 #ifndef UBLOX_ODIN_W2_RECV_TIMEOUT
 #define UBLOX_ODIN_W2_RECV_TIMEOUT    100
 #endif
-
+#define USE_MALLOC_FOR_COMMAND_MEMORY_POOL
 #define PQDSZ   2  // size of Pool/Queue data structures
 const uint8_t hello_msg[] = {0xaa,0x00,0x96,0x00,0x36,0x00,0x50,0x4f
                             ,0x53,0x54,0x20,0x2f,0x6e,0x75,0x64,0x67
--- a/source/common_types.h	Sun Apr 07 17:31:56 2019 +0000
+++ b/source/common_types.h	Sat Apr 13 14:17:29 2019 +0000
@@ -19,7 +19,7 @@
 
 /** ble configuration structure
 */
-typedef struct ble_config {
+typedef struct  {
     char      deviceName[BLE_MAX_DEVICE_NAME_LEN]; /* BLE Device Name */
     uint16_t  advInterval; /* advertising interval in msecs */
     uint16_t  advTimeout;  /* advertising timeout in secs */
@@ -29,7 +29,7 @@
 
 /** ble configuration structure
 */
-typedef struct wifi_config {
+typedef struct  {
     char             ssid[MAX_SSID_LEN]; /* WiFi SSID */
     char             pass[MAX_PASSKEY_LEN]; /* WiFi Passkey */
     nsapi_security_t security;  /* WiFi security */
@@ -37,13 +37,13 @@
 
 /** ble configuration structure
 */
-typedef struct app_config {
+typedef struct  {
     wifi_config_t wifi_config; /* wifi configuration */
     ble_config_t ble_config;   /* ble configuration */
 } app_config_t;
 
 
-typedef enum wifi_cmd
+typedef enum
 {
   WIFI_CMD_NONE,
   WIFI_CMD_CONFIG,
@@ -56,7 +56,7 @@
   WIFI_CMD_SEND_HTTP_REQ
 }wifi_cmd_t;
 
-typedef enum at_cmd_resp
+typedef enum
 {
   AT_RESP_NONE,
   AT_SCAN_RESP,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/compiler_abstraction.h	Sat Apr 13 14:17:29 2019 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) Nordic Semiconductor ASA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright notice, this
+ *   list of conditions and the following disclaimer in the documentation and/or
+ *   other materials provided with the distribution.
+ *
+ *   3. Neither the name of Nordic Semiconductor ASA nor the names of other
+ *   contributors to this software may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _COMPILER_ABSTRACTION_H
+#define _COMPILER_ABSTRACTION_H
+
+/*lint ++flb "Enter library region" */
+
+#if defined ( __CC_ARM )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            __inline                    
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __weak                      
+    #endif
+    
+    #ifndef __ALIGN
+        #define __ALIGN(n)          __align(n)                  
+    #endif
+    
+    #define GET_SP()                __current_sp()              
+  
+#elif defined ( __ICCARM__ )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __weak                      
+    #endif
+
+    /* Not defined for IAR since it requires a new line to work, and C preprocessor does not allow that. */
+    #ifndef __ALIGN
+        #define __ALIGN(n)          
+    #endif
+    
+    #define GET_SP()                __get_SP()                  
+    
+#elif defined   ( __GNUC__ )
+    
+    #ifndef __ASM
+        #define __ASM               __asm                       
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                      
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __attribute__((weak))       
+    #endif
+    
+    #ifndef __ALIGN
+        #define __ALIGN(n)          __attribute__((aligned(n))) 
+    #endif
+    
+    #define GET_SP()                gcc_current_sp()            
+
+    static inline unsigned int gcc_current_sp(void)
+    {
+        register unsigned sp __ASM("sp");
+        return sp;
+    }
+    
+#elif defined   ( __TASKING__ )
+        
+    #ifndef __ASM        
+        #define __ASM               __asm                      
+    #endif
+    
+    #ifndef __INLINE
+        #define __INLINE            inline                     
+    #endif
+    
+    #ifndef __WEAK
+        #define __WEAK              __attribute__((weak))      
+    #endif
+    
+    #ifndef __ALIGN
+        #define __ALIGN(n)          __align(n)                  
+    #endif
+    
+    #define GET_SP()                __get_MSP()                
+    
+#endif
+
+/*lint --flb "Leave library region" */
+
+#endif
+
--- a/source/main-https.cpp	Sun Apr 07 17:31:56 2019 +0000
+++ b/source/main-https.cpp	Sat Apr 13 14:17:29 2019 +0000
@@ -20,6 +20,7 @@
 #include "ATCmdManager.h"
 #include "BleManager.h"
 #include "WiFiManager.h"
+#include "mbed_memory_status.h"
 UARTService *uart;
 
 DigitalOut alivenessLED(LED1, 0);
@@ -56,21 +57,21 @@
 LEDService *ledServicePtr;
 
 /*  Queue and memory pool for AT to Wifi commands */
-MemoryPool<wifi_cmd_message_t, 16> aT2WiFimPool;
-Queue<wifi_cmd_message_t, 16> aT2WiFiCmdQueue;
+static MemoryPool<wifi_cmd_message_t, 16> aT2WiFimPool;
+static Queue<wifi_cmd_message_t, 16> aT2WiFiCmdQueue;
 
 /*  Queue and memory pool for WiFi to AT commands */
-MemoryPool<at_resp_message_t, 16> wiFi2ATmPool;
-Queue<at_resp_message_t, 16> wiFi2ATCmdQueue;
+static MemoryPool<at_resp_message_t, 16> wiFi2ATmPool;
+static Queue<at_resp_message_t, 16> wiFi2ATCmdQueue;
 
 /*  Queue and memory pool for AT to WiFi data */
-MemoryPool<wifi_data_msg_t, PQDSZ> aT2WiFiDatamPool;
-Queue<wifi_data_msg_t, PQDSZ> aT2WiFiDataQueue;
+static MemoryPool<wifi_data_msg_t, PQDSZ> aT2WiFiDatamPool;
+static Queue<wifi_data_msg_t, PQDSZ> aT2WiFiDataQueue;
 
 
 /*  Queue and memory pool for WiFi to AT data */
-MemoryPool<at_data_msg_t, PQDSZ> wiFi2ATDatamPool;
-Queue<at_data_msg_t, PQDSZ> wiFi2ATDataQueue;
+static MemoryPool<at_data_msg_t, PQDSZ> wiFi2ATDatamPool;
+static Queue<at_data_msg_t, PQDSZ> wiFi2ATDataQueue;
 
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/mbed_memory_status.cpp	Sat Apr 13 14:17:29 2019 +0000
@@ -0,0 +1,488 @@
+/*
+    mbed Memory Status Helper
+    Copyright (c) 2017 Max Vilimpoc
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+/**
+ * Purpose: Print out thread info and other useful details using
+ *          only raw serial access.
+ *
+ * Based on mbed_board.c's error printing functionality, minus
+ * pulling in all the printf() code.
+ */
+
+// Not great having to pull in all of mbed.h just to get the MBED_VERSION macro,
+// but it's the only way to do it for both pre- and post-5.4 releases
+//
+// If you're only supporting something newer than 5.4, you could use this alone:
+// #include "platform/mbed_version.h"
+//
+// platform/mbed_version.h says:
+// 999999 is default value for development version (master branch)
+
+#include "mbed.h"
+
+// Critical sections header file renamed in mbed OS 5.4 release
+// See: https://github.com/ARMmbed/mbed-os/commit/aff49d8d1e3b5d4dc18286b0510336c36ae9603c
+
+#ifndef MBED_VERSION
+#warning "You're probably using an unsupported version of mbed older than 5.2."
+#endif
+
+#if   MBED_VERSION >= 50400
+#include "platform/mbed_critical.h"
+#elif MBED_VERSION >= 50200
+#include "platform/critical.h"
+#endif
+
+#include "platform/mbed_stats.h"
+
+#if !MBED_STACK_STATS_ENABLED
+#warning MBED_STACK_STATS_ENABLED != 1, so there will be no stack usage measurements.
+#endif
+
+#ifndef DEBUG_ISR_STACK_USAGE
+#define DEBUG_ISR_STACK_USAGE  0
+#endif
+
+#ifndef DEBUG_MEMORY_CONTENTS
+#define DEBUG_MEMORY_CONTENTS  0
+#endif
+
+#define OUTPUT_SERIAL          1
+#define OUTPUT_RTT             0
+#define OUTPUT_SWO             0
+
+#if DEBUG_ISR_STACK_USAGE
+#include "compiler_abstraction.h"
+
+// Value is sprayed into all of the ISR stack at boot time.
+static const uint32_t ISR_STACK_CANARY = 0xAFFEC7ED; // AFFECTED
+
+// Refers to linker script defined symbol, may not be available
+// on all platforms.
+extern uint32_t __StackLimit;
+extern uint32_t __StackTop;
+
+void fill_isr_stack_with_canary(void)
+{
+    uint32_t * bottom = &__StackLimit;
+    uint32_t * top    = (uint32_t *) GET_SP();
+
+    for (; bottom < top; bottom++)
+    {
+        *bottom = ISR_STACK_CANARY;
+    }
+}
+#endif // DEBUG_ISR_STACK_USAGE
+
+#if OUTPUT_SERIAL && DEVICE_SERIAL
+#include "hal/serial_api.h"
+
+extern int      stdio_uart_inited;
+extern serial_t stdio_uart;
+
+static void output_serial_init(void)
+{
+    if (!stdio_uart_inited)
+    {
+        serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
+        serial_baud(&stdio_uart, 115200); // This is hard coded.
+    }
+}
+
+static void output_serial_print_label(const char * label)
+{
+#if MBED_VERSION < 50902
+    // After mbed OS 5.9.2, this locks up the system.
+    core_util_critical_section_enter();
+#endif
+
+    output_serial_init();
+
+    while (*label) serial_putc(&stdio_uart, *label++);
+
+#if MBED_VERSION < 50902
+    core_util_critical_section_exit();
+#endif
+}
+#endif // OUTPUT_SERIAL && DEVICE_SERIAL
+
+#if OUTPUT_RTT
+#include "RTT/SEGGER_RTT.h"
+
+enum
+{
+    DEFAULT_RTT_UP_BUFFER = 0
+};
+
+static void output_rtt_init(void)
+{
+    static int initialized = 0;
+
+    if (!initialized)
+    {
+        SEGGER_RTT_ConfigUpBuffer(DEFAULT_RTT_UP_BUFFER, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_TRIM);
+
+        initialized = 1;
+    }
+}
+
+static void output_rtt_print_label(const char * label)
+{
+    output_rtt_init();
+    SEGGER_RTT_WriteString(DEFAULT_RTT_UP_BUFFER, label);
+}
+#endif // OUTPUT_RTT
+
+#if OUTPUT_SWO
+#if defined (NRF52) && !defined (ENABLE_SWO)
+  #error "You need to enable SWO using `-D ENABLE_SWO` on the mbed compile command line."
+#endif
+
+#ifdef NRF52
+#include "nrf.h"
+#endif
+
+static void output_swo_init(void)
+{
+    static int initialized = 0;
+
+    if (!initialized)
+    {
+        NRF_CLOCK->TRACECONFIG = (NRF_CLOCK->TRACECONFIG & ~CLOCK_TRACECONFIG_TRACEPORTSPEED_Msk) |
+            (CLOCK_TRACECONFIG_TRACEPORTSPEED_4MHz << CLOCK_TRACECONFIG_TRACEPORTSPEED_Pos);
+
+        ITM->TCR |= 1;
+        ITM->TER |= 1;
+
+        initialized = 1;
+    }
+}
+
+static void output_swo_print_label(const char * label)
+{
+    output_swo_init();
+    while (*label) ITM_SendChar(*label++);
+}
+#endif // OUTPUT_SWO
+
+static void nway_print_label(const char * label)
+{
+#if OUTPUT_SERIAL
+    output_serial_print_label(label);
+#endif
+
+#if OUTPUT_RTT
+    output_rtt_print_label(label);
+#endif
+
+#if OUTPUT_SWO
+    output_swo_print_label(label);
+#endif
+}
+
+static const char HEX[] = "0123456789ABCDEF";
+
+static void debug_print_u32(uint32_t u32)
+{
+    char output[9] = {0};
+
+    // Always printed as big endian.
+    output[0] = HEX[(((uint32_t) u32 & 0xf0000000) >> 28)];
+    output[1] = HEX[(((uint32_t) u32 & 0x0f000000) >> 24)];
+    output[2] = HEX[(((uint32_t) u32 & 0x00f00000) >> 20)];
+    output[3] = HEX[(((uint32_t) u32 & 0x000f0000) >> 16)];
+    output[4] = HEX[(((uint32_t) u32 & 0x0000f000) >> 12)];
+    output[5] = HEX[(((uint32_t) u32 & 0x00000f00) >>  8)];
+    output[6] = HEX[(((uint32_t) u32 & 0x000000f0) >>  4)];
+    output[7] = HEX[(((uint32_t) u32 & 0x0000000f) >>  0)];
+
+    nway_print_label(output);
+}
+
+static void debug_print_pointer(const void * pointer)
+{
+    debug_print_u32((uint32_t) pointer);
+}
+
+#define DPL(X) nway_print_label((X))
+
+#if (defined (MBED_CONF_RTOS_PRESENT) && (MBED_CONF_RTOS_PRESENT != 0))
+#include "cmsis_os.h"
+
+// cmsis_os.h provides some useful defines:
+//
+// For mbed OS 5.4 and lower,  osCMSIS == 0x10002U (see: rtos/rtx/TARGET_CORTEX_M)
+// For mbed OS 5.5 and higher, osCMSIS == 0x20001U (see: rtos/TARGET_CORTEX/rtx{4|5})
+//
+// Starting in mbed OS 5.5, a new RTOS layer was introduced with a different API.
+
+#if (osCMSIS < 0x20000U)
+    // Temporarily #undef NULL or the compiler complains about previous def.
+    #undef NULL
+    #include "rt_TypeDef.h"
+#else
+    #include "rtx_lib.h"
+    // #include <stdlib.h>  // Include if you need malloc() / free() below. (probably better for non-C99 compilers)
+#endif
+
+#if (osCMSIS < 0x20000U)
+
+// No public forward declaration for this.
+extern "C" P_TCB rt_tid2ptcb (osThreadId thread_id);
+
+static void print_thread_info(osThreadId threadId)
+{
+    if (!threadId) return;
+
+    osEvent event;
+
+    P_TCB tcb = rt_tid2ptcb(threadId);
+
+    DPL("    stack ( start: ");
+    debug_print_pointer(tcb->stack);
+
+    event = _osThreadGetInfo(threadId, osThreadInfoStackSize);
+
+    DPL(" end: ");
+    debug_print_pointer(((uint8_t *) tcb->stack + event.value.v)); // (tcb->priv_stack)));
+
+    DPL(" size: ");
+    debug_print_u32(event.value.v);
+
+    event = _osThreadGetInfo(threadId, osThreadInfoStackMax);
+    DPL(" used: ");
+    debug_print_u32(event.value.v);
+
+
+    DPL(" ) ");
+
+    DPL("thread ( id: ");
+    debug_print_pointer(threadId);
+
+    event = _osThreadGetInfo(threadId, osThreadInfoEntry);
+    DPL(" entry: ");
+    debug_print_pointer(event.value.p);
+
+    DPL(" )\r\n");
+}
+
+void print_all_thread_info(void)
+{
+    osThreadEnumId enumId   = _osThreadsEnumStart();
+    osThreadId     threadId = (osThreadId) NULL; // Can't use nullptr yet because mbed doesn't support C++11.
+
+    while ((threadId = _osThreadEnumNext(enumId)))
+    {
+        print_thread_info(threadId);
+    }
+
+    _osThreadEnumFree(enumId);
+}
+
+#else
+
+static void print_thread_info(osThreadId threadId)
+{
+    // Refs: rtx_lib.h - #define os_thread_t osRtxThread_t
+    //       rtx_os.h  - typedef struct osRtxThread_s { } osRtxThread_t
+
+    if (!threadId) return;
+
+    os_thread_t * tcb = (os_thread_t *) threadId;
+
+    uint32_t stackSize = osThreadGetStackSize(threadId);
+    uint32_t stackUsed = osThreadGetStackSpace(threadId);
+
+    DPL("    stack ( start: ");
+    debug_print_pointer(tcb->stack_mem);
+
+    DPL(" end: ");
+    debug_print_pointer((uint8_t *) tcb->stack_mem + stackSize);
+
+    DPL(" size: ");
+    debug_print_u32(stackSize);
+
+    DPL(" used: ");
+    debug_print_u32(stackSize - stackUsed);
+
+    DPL(" ) ");
+
+    DPL("thread ( id: ");
+    debug_print_pointer(threadId);
+
+    DPL(" entry: ");
+    debug_print_u32(tcb->thread_addr);
+
+    DPL(" name: ");
+    DPL(osThreadGetName(threadId) ? osThreadGetName(threadId) : "unknown");
+
+    DPL(" )\r\n");
+}
+
+void print_all_thread_info(void)
+{
+    // Refs: mbed_stats.c - mbed_stats_stack_get_each()
+
+    uint32_t     threadCount = osThreadGetCount();
+    osThreadId_t threads[threadCount]; // g++ will throw a -Wvla on this, but it is likely ok.
+
+    // osThreadId_t * threads = malloc(sizeof(osThreadId_t) * threadCount);
+    // MBED_ASSERT(NULL != threads);
+
+    memset(threads, 0, threadCount * sizeof(osThreadId_t));
+
+    // This will probably only work if the number of threads remains constant
+    // (i.e. the number of thread control blocks remains constant)
+    //
+    // This is probably the case on a deterministic realtime embedded system
+    // with limited SRAM.
+
+    osKernelLock();
+
+    threadCount = osThreadEnumerate(threads, threadCount);
+
+    for (uint32_t i = 0; i < threadCount; i++)
+    {
+        // There seems to be a Heisenbug when calling print_thread_info()
+        // inside of osKernelLock()!
+
+        // This error may appear on the serial console:
+        // mbed assertation failed: os_timer->get_tick() == svcRtxKernelGetTickCount(), file: .\mbed-os\rtos\TARGET_CORTEX\mbed_rtx_idle.c
+
+        // The RTOS seems to be asserting an idle constraint violation due
+        // to the slowness of sending data through the serial port, but it
+        // does not happen consistently.
+        print_thread_info(threads[i]);
+    }
+
+    osKernelUnlock();
+
+    // free(threads);
+}
+
+#endif
+
+void print_current_thread_id(void)
+{
+    DPL("Current thread: ");
+    debug_print_pointer(osThreadGetId());
+    DPL("\r\n");
+}
+#endif // MBED_CONF_RTOS_PRESENT
+
+#if DEBUG_MEMORY_CONTENTS
+static void print_memory_contents(const uint32_t * start, const uint32_t * end)
+{
+    uint8_t line = 0;
+
+    for (; start < end; start++)
+    {
+        if (0 == line)
+        {
+            debug_print_pointer(start);
+            DPL(": ");
+        }
+
+        debug_print_u32(*start);
+
+        line++;
+
+        if (16 == line)
+        {
+            DPL("\r\n");
+            line = 0;
+        }
+    }
+}
+#endif
+
+extern uint32_t mbed_stack_isr_size;
+
+#if DEBUG_ISR_STACK_USAGE
+uint32_t calculate_isr_stack_usage(void)
+{
+    for (const uint32_t * stack = &__StackLimit; stack < &__StackTop; stack++)
+    {
+        if (*stack != ISR_STACK_CANARY)
+        {
+            return (uint32_t) &__StackTop - (uint32_t) stack;
+        }
+    }
+
+    return mbed_stack_isr_size;
+}
+#endif
+
+void print_heap_and_isr_stack_info(void)
+{
+    extern unsigned char * mbed_heap_start;
+    extern uint32_t        mbed_heap_size;
+
+    extern unsigned char * mbed_stack_isr_start;
+
+    mbed_stats_heap_t      heap_stats;
+
+    mbed_stats_heap_get(&heap_stats);
+
+    DPL("     heap ( start: ");
+    debug_print_pointer(mbed_heap_start);
+
+    DPL(" end: ");
+    debug_print_pointer(mbed_heap_start + mbed_heap_size);
+
+    DPL(" size: ");
+    debug_print_u32(mbed_heap_size);
+
+    DPL(" used: ");
+    debug_print_u32(heap_stats.max_size);
+
+    DPL(" )  alloc ( ok: ");
+    debug_print_u32(heap_stats.alloc_cnt);
+
+    DPL("  fail: ");
+    debug_print_u32(heap_stats.alloc_fail_cnt);
+
+    DPL(" )\r\n");
+
+    DPL("isr_stack ( start: ");
+    debug_print_pointer(mbed_stack_isr_start);
+
+    DPL(" end: ");
+    debug_print_pointer(mbed_stack_isr_start + mbed_stack_isr_size);
+
+    DPL(" size: ");
+    debug_print_u32(mbed_stack_isr_size);
+
+#if DEBUG_ISR_STACK_USAGE
+    DPL(" used: ");
+    debug_print_u32(calculate_isr_stack_usage());
+#endif
+
+    DPL(" )\r\n");
+
+#if DEBUG_MEMORY_CONTENTS
+    // Print ISR stack contents.
+    print_memory_contents(&__StackLimit, &__StackTop);
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/mbed_memory_status.h	Sat Apr 13 14:17:29 2019 +0000
@@ -0,0 +1,32 @@
+/*
+    mbed Memory Status Helper
+    Copyright (c) 2017 Max Vilimpoc
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#ifndef MEMORY_STATUS_H
+#define MEMORY_STATUS_H
+
+void print_current_thread_id(void);
+void print_all_thread_info(void);
+void print_heap_and_isr_stack_info(void);
+
+#endif /* MEMORY_STATUS_H */
+