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 May 25 16:25:42 2019 +0000
Branch:
PassingRegression
Parent:
117:8fd05113efc1
Child:
119:8d939a902333
Commit message:
- fixed memory leak bug with ATCMD manager; - added BLE memory pool and queues and connected up to main, BLE manager and ATCMD; - code compiling; - python test passing

Changed in this revision

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/BleManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/BleManager.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/WiFiManager.h 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/main-https.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/source/ATCmdManager.cpp	Sun May 19 16:22:59 2019 +0000
+++ b/source/ATCmdManager.cpp	Sat May 25 16:25:42 2019 +0000
@@ -1,6 +1,5 @@
 #include "debug.h"
 #include "ATCmdManager.h"
-#include "common_config.h"
 #include "common_types.h"
 #include "main.h"
 #include "http_request.h"
@@ -18,6 +17,10 @@
                            Queue<wifi_data_msg_t, PQDSZ>          *aT2WiFiDataQueue, 
                            MemoryPool<at_data_msg_t, PQDSZ>       *wiFi2ATDatamPool, 
                            Queue<at_data_msg_t, PQDSZ>            *wiFi2ATDataQueue, 
+                           MemoryPool<at_ble_msg_t, PQDSZ_BLE>    *aT2BleDatamPool, 
+                           Queue<at_ble_msg_t, PQDSZ_BLE>         *aT2BleDataQueue, 
+                           MemoryPool<ble_at_msg_t, PQDSZ_BLE>    *ble2ATDatamPool, 
+                           Queue<ble_at_msg_t, PQDSZ_BLE>         *ble2ATDataQueue, 
                            bool debug)
     :
     _serial(tx, rx, DEFAULT_BAUD_RATE),
@@ -35,8 +38,11 @@
     
     _wiFi2ATDatamPool(wiFi2ATDatamPool),
     _wiFi2ATDataQueue(wiFi2ATDataQueue),
-    
-    _parser(&_serial)
+    _aT2BleDatamPool(aT2BleDatamPool),
+    _aT2BleDataQueue(aT2BleDataQueue),
+    _ble2ATDatamPool(ble2ATDatamPool),
+    _ble2ATDataQueue(ble2ATDataQueue),
+     _parser(&_serial)
     
 
 { 
@@ -50,6 +56,8 @@
     _parser.oob("AT\r", callback(this, &ATCmdManager::_oob_ok_hdlr));
     _parser.oob("ATE0", callback(this, &ATCmdManager::_oob_echo_off));
     _parser.oob("ATE1", callback(this, &ATCmdManager::_oob_echo_on));
+    _parser.oob("ATE2", callback(this, &ATCmdManager::_oob_debug_logs_on));
+    _parser.oob("ATE3", callback(this, &ATCmdManager::_oob_debug_logs_off));
     _parser.oob("AT+UMRS", callback(this, &ATCmdManager::_oob_uart_setup));
     
     _parser.oob("ATO", callback(this, &ATCmdManager::_oob_data_mode));
@@ -89,6 +97,8 @@
     //_event_queue.call_in(10, &print_heap_and_isr_stack_info);
     //print_heap_and_isr_stack_info();
     //_event_queue.call_every(3600000,&print_memory_info);
+    lastHttpRespTime = Kernel::get_ms_count();
+    lastCloudMsgType = 0x00;
     _event_queue.call_every(10000,&blinkLEDs);
 #ifdef BOX_UBLOX_DEMO_TESTING
     check_for_at_cmd = false;
@@ -236,6 +246,15 @@
                 at_resp = AT_RESP_NONE;
                 break;
             }
+            case AT_BLE_RESPONSE:  
+            {
+                // AT Event state 
+                dbg_printf(LOG, "\n [ATCMD MAN] BLE RESPONSE RECEIVED!!\r\n");
+                respStr = (char *) resp_data->buffer;
+                sendBleDataEvent(respStr, resp_data->dataLen);
+                at_resp = AT_RESP_NONE;
+                break;
+            }
             default:
                  //UNKNOWN response state
                 dbg_printf(LOG, "\n [ATCMD MAN] UNKNOWN RESPONSE RECEIVED!!\r\n");
@@ -443,6 +462,14 @@
 #ifdef FULL_DEBUG_ENABLED
     dbg_printf(LOG, "\nLen = %d\n", bodyLen);
 #endif
+    uint32_t msecsSinceLastMsg = Kernel::get_ms_count() - lastHttpRespTime;
+    if((lastCloudMsgType == BAR_DB_MSGTYPE || lastCloudMsgType == REC_DB_MSGTYPE) && 
+       lastCloudMsgType == (uint8_t) bodyPtr[8] && 
+      (msecsSinceLastMsg < CLOUD_RETRY_TIME_MS ))
+    {
+        return false;
+    }
+    lastCloudMsgType = (uint8_t) bodyPtr[8]; // pick out the MSGTYPE byte from payload
     http_req->body = (uint8_t *) outPtr;
     memcpy(outPtr, bodyPtr, bodyLen);
     if(bodyLen > 10){
@@ -463,7 +490,7 @@
         wifiStateControl = AT_HTTPS_RESP_DOWNLOAD;
         return true;
     }
-    return true;
+    return false;
 }
 // OOB processing
 void ATCmdManager::_process_oob(uint32_t timeout, bool all){
@@ -516,7 +543,13 @@
                     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);
-                    if(n == -1) break; // timeout!
+                    if(n == -1) 
+                    {
+                        dbg_printf(LOG, "Timeout while reading message payload bytes - expected %d!\r\n", pLen);
+                        free(rx_buf_ptr); // make sure to free buffer
+                        rx_buf_ptr = NULL;
+                        break; // timeout!
+                    }
                     dbg_printf(LOG, "%d bytes read - expected %d!\n", n, pLen);
                     printBufferInHex(rx_buf_ptr, pLen);
                     dbg_printf(LOG, "rx_buf_ptr[pLen-1] = %0x\n",rx_buf_ptr[pLen-1]);
@@ -720,6 +753,23 @@
 }
 
 
+
+void ATCmdManager::_oob_debug_logs_on()
+{
+    initialise_debug(LOG | ERR | TXT | DBG);
+    dbg_printf(LOG, "\n Received ATE2 OOB command!!\n");
+    dbg_printf(LOG, "\n debug logs ON!!\n");
+    sendAtConfirmation(OK_RESP);   //_parser.send(OK_RESP);
+}
+
+void ATCmdManager::_oob_debug_logs_off()
+{
+    dbg_printf(LOG, "\n Received ATE3 OOB command!!\n");
+    dbg_printf(LOG, "\n turning debug logs OFF!!\n");
+    initialise_debug(NONE);
+    sendAtConfirmation(OK_RESP);   //_parser.send(OK_RESP);
+}
+
 void ATCmdManager::_oob_data_mode(){
     dbg_printf(LOG, "\n Received EDM mode command!!\n");
     int dmode;
@@ -773,12 +823,12 @@
 }
 
 void ATCmdManager::_oob_get_ble_role(){
+    trigger_start_BLE();
     dbg_printf(LOG, "\n Received get BLE role command!!\n");
     sendAtConfirmation("+UBTLE:2\r\nOK\r\n");   //_parser.send(OK_RESP);
 }
 
 void ATCmdManager::_oob_ena_ble_peri(){
-    trigger_start_BLE();
     dbg_printf(LOG, "\n Received enable BLE Peripheral command!!\n");
     sendAtConfirmation(OK_RESP);   //_parser.send(OK_RESP);
 }
@@ -1190,6 +1240,31 @@
 }
 
 
+void ATCmdManager::sendBleDataEvent(const char *buf, int len)
+{
+    _smutex.lock();
+    switch(dataMode){
+        case AT_CMD_DATA_MODE:
+            _parser.send(buf);
+            break;
+        case AT_STD_DATA_MODE:
+            _parser.send(buf);
+            break;
+        case AT_EXT_DATA_MODE:
+        {
+            outputEDMdata((const uint8_t *) buf, len, DATA_MSG_ID, EVENT_MSG_TYPE, BLE_CHANNEL);
+            break;
+        }
+        default:
+            _parser.send(buf);
+            break;
+    }
+    _smutex.unlock();
+    _wiFi2ATDatamPool->free(resp_data);
+    resp_data = NULL;
+}
+
+
 void ATCmdManager::sendConnectEvent(const uint8_t *buf, int len)
 {
     switch(dataMode){
@@ -1252,4 +1327,5 @@
                   EVENT_MSG_TYPE, WIFI_CHANNEL);
     _wiFi2ATDatamPool->free(resp_data);
     resp_data = NULL;
+    lastHttpRespTime = Kernel::get_ms_count();
 }
--- a/source/ATCmdManager.h	Sun May 19 16:22:59 2019 +0000
+++ b/source/ATCmdManager.h	Sat May 25 16:25:42 2019 +0000
@@ -6,6 +6,7 @@
 #include "ATCmdParser.h"
 #include "BleManager.h"
 #include "WiFiManager.h"
+#include "common_config.h"
 
 #define NUM_UART_OPTIONS       6
 #ifndef UBLOX_ODIN_W2_MISC_TIMEOUT
@@ -30,6 +31,10 @@
                  Queue<wifi_data_msg_t, PQDSZ> *aT2WiFiDataQueue, 
                  MemoryPool<at_data_msg_t, PQDSZ> *wiFi2ATDatamPool, 
                  Queue<at_data_msg_t, PQDSZ> *wiFi2ATDataQueue, 
+                 MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+                 Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+                 MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+                 Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
                  bool debug = false);
 public:
     void runMain();
@@ -50,6 +55,8 @@
     WiFiManager *wiFiManager;
     at_cmd_resp_t at_resp;
     at_data_mode_t dataMode;
+    uint32_t lastHttpRespTime;
+    uint8_t lastCloudMsgType;
     /*  Queue and memory pool for AT to Wifi commands */
     MemoryPool<wifi_cmd_message_t, 16> *_aT2WiFimPool;
     Queue<wifi_cmd_message_t, 16> *_aT2WiFiCmdQueue;
@@ -66,6 +73,16 @@
     /*  Queue and memory pool for WiFi to AT data */
     MemoryPool<at_data_msg_t, PQDSZ> *_wiFi2ATDatamPool;
     Queue<at_data_msg_t, PQDSZ> *_wiFi2ATDataQueue;
+
+    /*  Queue and memory pool for AT to BLE data */
+    MemoryPool<at_ble_msg_t, PQDSZ_BLE> *_aT2BleDatamPool;
+    Queue<at_ble_msg_t, PQDSZ_BLE> *_aT2BleDataQueue;
+    
+    
+    /*  Queue and memory pool for BLE to AT data */
+    MemoryPool<ble_at_msg_t, PQDSZ_BLE> *_ble2ATDatamPool;
+    Queue<ble_at_msg_t, PQDSZ_BLE> *_ble2ATDataQueue;
+
     
     //pointer to response data - should be deleted after processing
     at_data_msg_t *resp_data;
@@ -90,6 +107,8 @@
     void _oob_echo_off();
     void _oob_uart_setup();
     void _oob_echo_on();
+    void _oob_debug_logs_on();
+    void _oob_debug_logs_off();
     void _oob_data_mode();
     void _oob_get_mac_addr();
     void _oob_get_ble_role();
@@ -132,6 +151,7 @@
     void        sendConnectEvent(const uint8_t *buf, int len);
     int         readAtCommandString(char *strbuf, size_t bufLen);
     void        updateWiFiMgrStatus();
+    void        sendBleDataEvent(const char *buf, int len);
     
     /**
     * Allows timeout to be changed between commands
--- a/source/BleManager.cpp	Sun May 19 16:22:59 2019 +0000
+++ b/source/BleManager.cpp	Sat May 25 16:25:42 2019 +0000
@@ -61,10 +61,19 @@
  *  your application is interested in.
  */
 SMDevice::SMDevice(BLE &ble, events::EventQueue &event_queue, 
-                   BLEProtocol::AddressBytes_t &peer_address, ble_config_t *ble_config) :
+                   BLEProtocol::AddressBytes_t &peer_address, 
+                   MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+                   Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+                   MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+                   Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
+                   ble_config_t *ble_config) :
         _ble(ble),
         _event_queue(event_queue),
         _peer_address(peer_address),
+        _aT2BleDatamPool (aT2BleDatamPool),
+        _aT2BleDataQueue (aT2BleDataQueue),
+        _ble2ATDatamPool (ble2ATDatamPool),
+        _ble2ATDataQueue (ble2ATDataQueue),
         ble_config(ble_config),
         _handle(0),
         _is_connecting(false), 
@@ -384,8 +393,16 @@
 
 /** A peripheral device will advertise, accept the connection and request
  * a change in link security. */
-SMDevicePeripheral::SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address, ble_config_t *ble_config)
-        : SMDevice(ble, event_queue, peer_address, ble_config) { }
+SMDevicePeripheral::SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address, 
+                                       MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+                                       Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+                                       MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+                                       Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
+                                       ble_config_t *ble_config)
+        : SMDevice(ble, event_queue, peer_address, 
+                   aT2BleDatamPool, aT2BleDataQueue, 
+                   ble2ATDatamPool, ble2ATDataQueue, 
+                   ble_config) { }
 
 void SMDevicePeripheral::start()
 {
@@ -520,8 +537,16 @@
 
 /** A central device will scan, connect to a peer and request pairing. */
 
-SMDeviceCentral::SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address, ble_config_t *ble_config)
-    : SMDevice(ble, event_queue, peer_address, ble_config) { };
+SMDeviceCentral::SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address, 
+                                 MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+                                 Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+                                 MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+                                 Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
+                                 ble_config_t *ble_config)
+    : SMDevice(ble, event_queue, peer_address, 
+               aT2BleDatamPool, aT2BleDataQueue, 
+               ble2ATDatamPool, ble2ATDataQueue, 
+               ble_config) { };
 
 void SMDeviceCentral::start()
 {
--- a/source/BleManager.h	Sun May 19 16:22:59 2019 +0000
+++ b/source/BleManager.h	Sat May 25 16:25:42 2019 +0000
@@ -55,7 +55,12 @@
 {
 public:
     SMDevice(BLE &ble, events::EventQueue &event_queue, 
-             BLEProtocol::AddressBytes_t &peer_address, ble_config_t *ble_config);
+             BLEProtocol::AddressBytes_t &peer_address, 
+             MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+             Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+             MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+             Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
+             ble_config_t *ble_config);
 
     virtual ~SMDevice();
 
@@ -131,6 +136,14 @@
 
 private:
     DigitalOut _led1;
+    /*  Queue and memory pool for AT to BLE data */
+    MemoryPool<at_ble_msg_t, PQDSZ_BLE> *_aT2BleDatamPool;
+    Queue<at_ble_msg_t, PQDSZ_BLE> *_aT2BleDataQueue;
+    
+    
+    /*  Queue and memory pool for BLE to AT data */
+    MemoryPool<ble_at_msg_t, PQDSZ_BLE> *_ble2ATDatamPool;
+    Queue<ble_at_msg_t, PQDSZ_BLE> *_ble2ATDataQueue;
 
 protected:
     BLE &_ble;
@@ -146,7 +159,12 @@
 class SMDevicePeripheral : public SMDevice {
 public:
     SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, 
-                       BLEProtocol::AddressBytes_t &peer_address, ble_config_t *ble_config);
+                       BLEProtocol::AddressBytes_t &peer_address, 
+                       MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+                       Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+                       MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+                       Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
+                       ble_config_t *ble_config);
 
     virtual void start();
 
@@ -162,7 +180,12 @@
 class SMDeviceCentral : public SMDevice {
 public:
     SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, 
-                    BLEProtocol::AddressBytes_t &peer_address, ble_config_t *ble_config);
+                    BLEProtocol::AddressBytes_t &peer_address, 
+                    MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool, 
+                    Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue, 
+                    MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool, 
+                    Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue, 
+                    ble_config_t *ble_config);
 
     virtual void start();
 
--- a/source/WiFiManager.cpp	Sun May 19 16:22:59 2019 +0000
+++ b/source/WiFiManager.cpp	Sat May 25 16:25:42 2019 +0000
@@ -40,13 +40,16 @@
     http_response = NULL;
     chunkNum = 0;
     socket = NULL;
+    responseString = NULL;
+    responseBytes = NULL;
+    at_data_resp = NULL;
     https_connection_active = false;
     use_full_hostname       = false;
     wifiBusy = 0;
     wifiWatchdogTimer.start();
     watchdogCnt = 0;
     //_event_queue.call_every(10000, this, &WiFiManager::callWifiWatchDog);
-    watchDogTick.attach(callback(this, &WiFiManager::callWifiWatchDogIsr), 10000.0); // call flip function every 10 seconds
+    watchDogTick.attach(callback(this, &WiFiManager::callWifiWatchDogIsr), 10.0); // call flip function every 10 seconds
     
 }
 
@@ -58,7 +61,7 @@
 
 void WiFiManager::callWifiWatchDogIsr()
 {
-    _event_queue.call(this, &WiFiManager::callWifiWatchDog);    
+    _event_queue.call_in(10, this, &WiFiManager::callWifiWatchDog);    
 }
 void WiFiManager::callWifiWatchDog()
 {
@@ -67,22 +70,22 @@
 #else
     static int inactivity_monitor = 0;
     watchdogCnt++;
-    if(watchdogCnt >= 6 && responseString==NULL) // every minute
+    if(watchdogCnt >= 6 && outputBuffersAvailable()) // every minute
     {
-        responseString = (char *) malloc(120);
+        char * respStr = (char *) malloc(120);
         sprintf(responseString, "\r\n[WiFi-MAN] WiFi Manager Alive : state = %d busy = %d httpsConnActive = %d\r\n",
                                 wifiCmd, wifiBusy, https_connection_active);
-        sendATresponseString(WIFI_WATCH_DOG);
+        sendThreadATresponseString(respStr, WIFI_WATCH_DOG);
         watchdogCnt = 0;
     }
     else if(wifiWatchdogTimer.read() > 30 && responseString==NULL)
     {
         if(wifiCmd == WIFI_CMD_NONE)
             inactivity_monitor++;
-        responseString = (char *) malloc(120);
+        char * respStr = (char *) malloc(120);
         sprintf(responseString, "\r\n[WiFi-MAN] Main Loop InActive : state = %d busy = %d httpsConnActive = %d\r\n", 
                                  wifiCmd, wifiBusy, https_connection_active);
-        sendATresponseString(WIFI_WATCH_DOG);
+        sendThreadATresponseString(respStr, WIFI_WATCH_DOG);
         if(inactivity_monitor >= 3)
         {
             free_DataMsg();
@@ -91,7 +94,59 @@
     }
 #endif    
 }
-  
+
+void  WiFiManager::sendThreadATresponseString(const char * buf, at_cmd_resp_t at_cmd)
+{
+    if(at_data_resp != NULL) return;
+    int strLen = strlen(buf) + 1;
+    at_data_resp = new at_data_msg_t;
+    // set string length 
+    at_data_resp->dataLen = strLen;
+    memcpy(at_data_resp->buffer, buf, strLen);
+    // package and send on wifi data queue    
+    at_data_resp->at_resp = at_cmd;
+    bool queueResult = true;
+    int wait_count = 0;
+    do
+    {
+        if(!queueResult){
+            wait_count+=10;
+            dbg_printf(LOG, "ATCMD Queue full waiting %d ms so far...\n", wait_count*10);
+            wait_ms(10);
+        }
+        queueResult = queueWiFiDataResponse(*at_data_resp);
+    }while(queueResult == false && wait_count<QUEUE_WAIT_TIMEOUT_MS);
+    delete at_data_resp;
+    at_data_resp = NULL;
+}
+
+
+bool WiFiManager::outputBuffersAvailable()
+{
+    int timeout = 0;
+    while(timeout < 100)
+    {
+        if(responseBytes==NULL && responseString==NULL && at_data_resp==NULL)
+        {
+            return true;
+        }
+        else
+        {
+            timeout += 10;
+            wait_ms(10);
+        }
+    }
+    if(responseBytes==NULL && responseString==NULL && at_data_resp==NULL)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
 bool WiFiManager::queueATresponse(at_cmd_resp_t resp){
 #ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
     at_resp_message_t *atResp  = _wiFi2ATmPool->alloc();
@@ -158,11 +213,15 @@
                 wifiBusy = 1;
                 error = connect();
                 int secCount = 0;
-                while(secCount++ < WIFI_CONNECT_TIMEOUT_SECS || is_connected==false){
+                while(secCount++ < WIFI_CONNECT_TIMEOUT_SECS && is_connected==false){
                     wait(1); // wait 1 sec
                 }
                 wifiCmd = WIFI_CMD_NONE;
                 if(is_connected==false){
+                    if(outputBuffersAvailable() == false) // first free it
+                    {
+                        free(responseString);
+                    }
                     dbg_printf(LOG, "[WIFI MAN] +++ WIFI CONNECTION TIMEOUT +++ \r\n");
                     //queueATresponse(AT_COMMAND_FAILED);
                     responseString = (char *) malloc(100);
@@ -214,14 +273,20 @@
             }
             case WIFI_CMD_NETWORK_STATUS:
                 wifiBusy = 1;
-                getNetworkStatus();
+                if(outputBuffersAvailable())
+                {
+                    getNetworkStatus();
+                }
                 sendATresponseString(AT_NETWORK_STATUS_RESP);
                 wifiCmd = WIFI_CMD_NONE;
                 wifiBusy = 0;
                 break;
             case WIFI_CMD_WIFI_STATUS:
                 wifiBusy = 1;
-                getWiFiStatus();
+                if(outputBuffersAvailable())
+                {
+                    getWiFiStatus();
+                }
                 sendATresponseString(AT_WIFI_STATUS_RESP);
                 wifiCmd = WIFI_CMD_NONE;
                 wifiBusy = 0;
@@ -230,7 +295,7 @@
             {
                 wifiBusy = 1;
 #ifdef SEND_DEBUG_MESSAGES
-                if(responseString == NULL)
+                if(outputBuffersAvailable())
                 {
                     responseString = (char *) malloc(100);
                     sprintf(responseString, "\r\nHTTP REQUEST RECEIVED\r\n");
@@ -251,7 +316,7 @@
                 int oldChunkNum = chunkNum;
                 while(!backgroundTaskCompleted && msecCount < 6000)
                 {
-                    msecCount++;
+                    msecCount+=10;
                     wait_ms(10);
                     if(oldChunkNum != chunkNum) // new payload received
                     {
@@ -273,7 +338,7 @@
 #else
                 result = createHttpsRequest();
 #endif
-                if(result == false)
+                if(result == false && outputBuffersAvailable())
                 {
                     responseString = (char *) malloc(100);
                     if(http_result==TLS_CONNECTION_FAILED)
@@ -551,7 +616,7 @@
         //printBufferInHex(responseBytes, HOSTNAME_RESPONSE_LEN);
         //sendATresponseBytes(CONNECT_EVENT, HOSTNAME_RESPONSE_LEN);
     }
-    else // -ve number means error
+    else if(outputBuffersAvailable()) // -ve number means error
     {
         responseString = (char *) malloc(20);
         dbg_printf(LOG, "[WIFI-MAN] hostname translation failed\r\n");
@@ -724,14 +789,17 @@
             dbg_printf(LOG, "Global IP address set!\r\n");
             dbg_printf(LOG, "[WIFI-MAN] IP address: %s\n", network->get_ip_address());
             dbg_printf(LOG, "[WIFI-MAN] Connected to the network %s\n", wifi_config->ssid);
-            responseString = (char *) malloc(MAX_RESPONSE_STRING_LEN); 
-            sprintf(responseString, "\r\n%s%d,%s,%d\r\n", WIFI_LINK_ENABLED, 
-                                                          WIFI_CHANNEL,
-                                                          network->get_mac_address(),
-                                                          DEFAULT_WIFI_CHANNEL);
-            
-            is_connected = true;
-            wifiBusy = 0;
+            if(outputBuffersAvailable())
+            {
+                responseString = (char *) malloc(MAX_RESPONSE_STRING_LEN); 
+                sprintf(responseString, "\r\n%s%d,%s,%d\r\n", WIFI_LINK_ENABLED, 
+                                                              WIFI_CHANNEL,
+                                                              network->get_mac_address(),
+                                                              DEFAULT_WIFI_CHANNEL);
+                
+                is_connected = true;
+                wifiBusy = 0;
+            }
             break;
         case NSAPI_STATUS_DISCONNECTED:
             dbg_printf(LOG, "No connection to network!\r\n");
@@ -788,52 +856,56 @@
 
 void WiFiManager::processGetHostByNameResult(nsapi_error_t result, SocketAddress *address)
 {
+    
     dbg_printf(LOG, "gethostbyname_callback called... result = %d \r\n", result);
     print_memory_info();
-    responseBytes = new uint8_t[HOSTNAME_RESPONSE_LEN]; //malloc(HOSTNAME_RESPONSE_LEN);
-    int i = 0;
-    responseBytes[i++] = IPv4_CONNECTION; // connect type IPv4
-    responseBytes[i++] = TCP_PROTOCOL; // Protocol = TCP
-    if(is_connected && result>=0)
+    if(outputBuffersAvailable())
     {
-        memcpy(&responseBytes[i], address->get_ip_bytes(), 4); // remote IPv4 address
-        strcpy(internet_config->remote_IPv4Address, address->get_ip_address());
-        i +=4;
-        uint16_t port = address->get_port();
-        internet_config->remote_port = port;
-        memcpy(&responseBytes[i], &port, 2); // remote IPv4 port #
-        i +=2;
-        // local IPv4 address
-        int ipAddr[4];
-        strcpy(internet_config->local_IPv4Address, network->get_ip_address());
-        sscanf(internet_config->local_IPv4Address, "%d.%d.%d.%d", &ipAddr[0], &ipAddr[1], 
-                                                                 &ipAddr[2], &ipAddr[3]);
-        responseBytes[i++] = (uint8_t) ipAddr[0];
-        responseBytes[i++] = (uint8_t) ipAddr[1];
-        responseBytes[i++] = (uint8_t) ipAddr[2];
-        responseBytes[i++] = (uint8_t) ipAddr[3];
-        // local port number
-        responseBytes[i++] = 0;
-        responseBytes[i]   = 0;
-        printBufferInHex(responseBytes, HOSTNAME_RESPONSE_LEN);
-        sendATresponseBytes(CONNECT_EVENT, HOSTNAME_RESPONSE_LEN);
-    }
-    else
-    {
-        // if unconnected set ip and port to zeroes
-        memset(&responseBytes[i], 0x00, 6);
-        delete responseBytes;
-        dbg_printf(LOG, "\r\nHOSTNAME TRANSLATION FAILURE : error code = %d \r\n", result);
-        if(responseString == NULL)
+        responseBytes = new uint8_t[HOSTNAME_RESPONSE_LEN]; //malloc(HOSTNAME_RESPONSE_LEN);
+        int i = 0;
+        responseBytes[i++] = IPv4_CONNECTION; // connect type IPv4
+        responseBytes[i++] = TCP_PROTOCOL; // Protocol = TCP
+        if(is_connected && result>=0)
         {
-            responseString = (char *) malloc(100);
-            sprintf(responseString, "\r\nHOSTNAME TRANSLATION FAILURE : error code = %d \r\n", result);
-            sendATresponseString(AT_EVENT);
+            memcpy(&responseBytes[i], address->get_ip_bytes(), 4); // remote IPv4 address
+            strcpy(internet_config->remote_IPv4Address, address->get_ip_address());
+            i +=4;
+            uint16_t port = address->get_port();
+            internet_config->remote_port = port;
+            memcpy(&responseBytes[i], &port, 2); // remote IPv4 port #
+            i +=2;
+            // local IPv4 address
+            int ipAddr[4];
+            strcpy(internet_config->local_IPv4Address, network->get_ip_address());
+            sscanf(internet_config->local_IPv4Address, "%d.%d.%d.%d", &ipAddr[0], &ipAddr[1], 
+                                                                     &ipAddr[2], &ipAddr[3]);
+            responseBytes[i++] = (uint8_t) ipAddr[0];
+            responseBytes[i++] = (uint8_t) ipAddr[1];
+            responseBytes[i++] = (uint8_t) ipAddr[2];
+            responseBytes[i++] = (uint8_t) ipAddr[3];
+            // local port number
+            responseBytes[i++] = 0;
+            responseBytes[i]   = 0;
+            printBufferInHex(responseBytes, HOSTNAME_RESPONSE_LEN);
+            sendATresponseBytes(CONNECT_EVENT, HOSTNAME_RESPONSE_LEN);
         }
-        use_full_hostname = not use_full_hostname;
+        else
+        {
+            // if unconnected set ip and port to zeroes
+            memset(&responseBytes[i], 0x00, 6);
+            delete responseBytes;
+            dbg_printf(LOG, "\r\nHOSTNAME TRANSLATION FAILURE : error code = %d \r\n", result);
+            if(responseString == NULL)
+            {
+                responseString = (char *) malloc(100);
+                sprintf(responseString, "\r\nHOSTNAME TRANSLATION FAILURE : error code = %d \r\n", result);
+                sendATresponseString(AT_EVENT);
+            }
+            use_full_hostname = not use_full_hostname;
+       }
+       wifiBusy = 0;
+       backgroundTaskCompleted = true;
    }
-    wifiBusy = 0;
-    backgroundTaskCompleted = true;
     
 }
 
--- a/source/WiFiManager.h	Sun May 19 16:22:59 2019 +0000
+++ b/source/WiFiManager.h	Sat May 25 16:25:42 2019 +0000
@@ -120,7 +120,8 @@
     bool                  createTLSconnection(const char *hostName);
     void                  printBufferInHex(const uint8_t *buf, int pLen);
     bool                  copyResponseHdr2Queue(const uint8_t * buf);
-    void                  sendATresponseString(at_cmd_resp_t);
+    void                  sendATresponseString(at_cmd_resp_t at_cmd);
+    void                  sendThreadATresponseString(const char *buf, at_cmd_resp_t at_cmd);
     void                  sendATresponseBytes(at_cmd_resp_t at_cmd, int len);
     void                  getNetworkStatus();
     void                  getWiFiStatus();
@@ -133,6 +134,7 @@
     void                  callWifiWatchDog();
     void                  callWifiWatchDogIsr();
     void                  processGetHostByNameResult(nsapi_error_t result, SocketAddress *addr);
+    bool                  outputBuffersAvailable();
 
 
 
--- a/source/common_config.h	Sun May 19 16:22:59 2019 +0000
+++ b/source/common_config.h	Sat May 25 16:25:42 2019 +0000
@@ -12,7 +12,7 @@
 #define UBLOX_ODIN_W2_RECV_TIMEOUT    5
 #endif
 #define USE_MALLOC_FOR_COMMAND_MEMORY_POOL
-#define WIFI_CONNECT_TIMEOUT_SECS 10
+#define WIFI_CONNECT_TIMEOUT_SECS 30
 #define MAIN_LOOP_WAIT_TIME_MS 100 // milliseconds
 #define WIFI_MAIN_LOOP_WAIT_TIME_MS 101 // milliseconds
 #define MAX_RESPONSE_STRING_LEN   512 // maximum response string length of 512 bytes
@@ -36,12 +36,15 @@
 #define IP_PEER_HANDLE            0x02
 #define BTLE_PEER_HANDLE          0x01
 #define DEFAULT_LOCAL_PORT        0
-#define PQDSZ   2  // size of Pool/Queue data structures
+#define PQDSZ                     2  // size of Wifi Pool/Queue data structures
+#define PQDSZ_BLE                 8  // size of BLE Pool/Queue data structures
 #define MAX_HTTP_HDR_LEN          512
 #define HTTP_HEADER_START_LINE    "HTTP/1.1 "
 #define HTTP_HEADER_CONTENT_TYPE  "Content-Type:"
 #define HTTP_HEADER_CONTENT_LEN   "Content-Length:"
 #define QUEUE_WAIT_TIMEOUT_MS     1000
+#define CLOUD_RETRY_TIME_MS       10000
+#define MAX_BLE_PACKET_SIZE       20
 //#define ENABLE_MEMORY_CHECKS
 #define SEND_DEBUG_MESSAGES
 typedef enum
--- a/source/common_types.h	Sun May 19 16:22:59 2019 +0000
+++ b/source/common_types.h	Sat May 25 16:25:42 2019 +0000
@@ -19,7 +19,8 @@
 #define MAX_IPv4_LEN         16
 #define MAX_CLOUD_USER_ID_LEN   32
 #define MAX_CLOUD_PASSWORD_LEN  32
-
+#define REC_DB_MSGTYPE          0x09
+#define BAR_DB_MSGTYPE          0x06
 /** ble configuration structure
 */
 typedef struct  {
@@ -109,7 +110,8 @@
   CONNECT_EVENT = 16,
   DATA_EVENT = 17,
   AT_COMMAND_FAILED = 18,
-  WIFI_WATCH_DOG = 19
+  WIFI_WATCH_DOG = 19,
+  AT_BLE_RESPONSE = 20
 }at_cmd_resp_t;
 
 typedef enum edm_msg_id
@@ -254,4 +256,31 @@
 } app_config_t;
 
 
+/* BLE data types */
+
+typedef enum
+{
+  BLE_CMD_NONE,
+  BLE_CMD_CONFIG,
+  BLE_CMD_CONNECT,
+  BLE_CMD_DISCONNECT,
+  BLE_CMD_SEND_AT_DATA_2BLE
+}ble_cmd_t;
+
+
+
+typedef struct {
+    ble_cmd_t     ble_cmd;                     /* BLE command             */
+    int           dataLen;                     /* size of data in buffer */
+    uint8_t       buffer[MAX_BLE_PACKET_SIZE]; /* buffer length     */
+} at_ble_msg_t;
+
+
+typedef struct {
+    at_cmd_resp_t at_resp;              /* AT response */
+    int           dataLen;              /* size of data in buffer */
+    uint8_t       buffer[MAX_BLE_PACKET_SIZE]; /* buffer length     */
+} ble_at_msg_t;
+
+
 #endif  // __COMMON_TYPES_H__
\ No newline at end of file
--- a/source/main-https.cpp	Sun May 19 16:22:59 2019 +0000
+++ b/source/main-https.cpp	Sat May 25 16:25:42 2019 +0000
@@ -81,6 +81,16 @@
 static Queue<at_data_msg_t, PQDSZ> wiFi2ATDataQueue;
 
 
+/*  Queue and memory pool for AT to BLE data */
+static MemoryPool<at_ble_msg_t, PQDSZ_BLE> aT2BleDatamPool;
+static Queue<at_ble_msg_t, PQDSZ_BLE> aT2BleDataQueue;
+
+
+/*  Queue and memory pool for BLE to AT data */
+static MemoryPool<ble_at_msg_t, PQDSZ_BLE> ble2ATDatamPool;
+static Queue<ble_at_msg_t, PQDSZ_BLE> ble2ATDataQueue;
+
+
 
 
 /* creates three tread objects with different priorities */
@@ -122,6 +132,9 @@
 
 Mutex _smutex; // Protect memory access
 
+bool ble_mgr_started;
+bool wifi_mgr_started;
+
 uint64_t lastTime = 0;
 uint64_t now = 0;
 uint32_t callCount = 0;
@@ -149,8 +162,8 @@
 
 void printWaitAbortKeyPress(int numSecs, const char * printStr=NULL)
 {
-#ifdef DEBUG_ENABLED
-    return
+#ifndef DEBUG_ENABLED
+    return;
 #endif
     dbg_printf(LOG, "%s", printStr);
     dbg_printf(LOG, "Waiting for %d seconds... [press key to abort]\n", numSecs);
@@ -306,15 +319,21 @@
 #endif
     dbg_printf(LOG, "\r\n PERIPHERAL \r\n\r\n");
     peripheral = new SMDevicePeripheral(_ble, eventQueue_ble, peer_address, 
+                                        &aT2BleDatamPool, &aT2BleDataQueue,
+                                        &ble2ATDatamPool, &ble2ATDataQueue,
                                         &app_config.ble_config);
 
     peripheral->run();
     btle_thread.start(callback(&eventQueue_ble, &EventQueue::dispatch_forever));
+    ble_mgr_started = true;
+    wait_ms(10);
 }
 
 void stop_BLE()
 {
     delete peripheral;
+    ble_mgr_started = false;
+    wait_ms(10);
 }
 
 void start_WiFi()
@@ -335,11 +354,13 @@
     printWaitAbortKeyPress(120, "Wait after WiFi Manager dispatch\r\n");
     // dispatch wifi event queue on event thread
     wifi_evt_thread.start(callback(&eventQueue_wifi, &EventQueue::dispatch_forever));
+    wifi_mgr_started = true;
 }
 
 void stop_WiFi()
 {
     delete network;
+    wifi_mgr_started = false;
 }
 
 
@@ -368,7 +389,7 @@
 
 //#define USE_DEFAULT_CONFIGURATION
 //#define TEST_NVSTORE
-#define STARTUP_DEBUG_ENABLE
+//#define STARTUP_DEBUG_ENABLE
 //#define AUTO_START_BLE_MANAGER
 //#define AUTO_START_WIFI_MANAGER
 #define PAUSE_SECONDS   0
@@ -383,8 +404,12 @@
     setupDefaultCloudConfig();
 #endif
     device = new RawSerial(USBTX, USBRX, app_config.uart_config.baudrate);
+#if defined (STARTUP_DEBUG_ENABLE) || defined (DEBUG_ENABLED)
     uint8_t debug_level = (LOG | ERR | TXT | DBG);
     initialise_debug(debug_level);
+#else
+    initialise_debug(NONE);
+#endif
 #ifdef MBED_MAJOR_VERSION
     dbg_printf(LOG, "Mbed OS version %d.%d.%d\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
 #endif
@@ -428,6 +453,8 @@
                                                 &wiFi2ATmPool, &wiFi2ATCmdQueue,
                                                 &aT2WiFiDatamPool, &aT2WiFiDataQueue,
                                                 &wiFi2ATDatamPool, &wiFi2ATDataQueue,
+                                                &aT2BleDatamPool, &aT2BleDataQueue,
+                                                &ble2ATDatamPool, &ble2ATDataQueue,
                                                 false);
     atcmd_thread.start(callback(aTCmdManager, &ATCmdManager::runMain));
     dbg_printf(LOG, "\r\n after starting atcmd thread \r\n");
@@ -446,6 +473,10 @@
                 mainLoop = MAIN_IDLE;
                 break;
             case START_WIFI:
+                if(!ble_mgr_started)
+                {
+                    start_BLE();
+                }
                 start_WiFi();
                 mainLoop = MAIN_IDLE;
                 break;