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:
Sun Mar 10 09:46:06 2019 +0000
Parent:
73:6f5021cbe752
Child:
75:08eff6258e1b
Commit message:
ATCmdManager now instaltiates ok

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/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/common_config.h Show annotated file Show diff for this revision Revisions of this file
source/https_certificates.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/network-helper.h Show annotated file Show diff for this revision Revisions of this file
source/wifi_demo.cpp Show annotated file Show diff for this revision Revisions of this file
source/wifi_demo.h Show annotated file Show diff for this revision Revisions of this file
--- a/mbed_app.json	Thu Feb 28 18:13:48 2019 +0000
+++ b/mbed_app.json	Sun Mar 10 09:46:06 2019 +0000
@@ -9,12 +9,15 @@
         },
        "wifi-ssid": {
             "help": "WiFi SSID",
-            "value": "\"VM9109107\""
+            "value": "\"VM9109107_5GEXT\""
         },
         "wifi-password": {
             "help": "WiFi Password",
             "value": "\"Bonga01shop02\""
-        }
+        },
+        "overrides": {
+            "lse_available": false 
+        }    
     },
     "macros": [
         "MBEDTLS_MPI_MAX_SIZE=1024",
@@ -25,17 +28,15 @@
         "MBED_HEAP_STATS_ENABLED=1"
     ],
     "target_overrides": {
-        "K64F": {
-            "target.features_add": ["BLE"],
-            "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"]
-        },
-        "NUCLEO_F401RE": {
-            "target.features_add": ["BLE"],
-            "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"]
-        },
-        "DISCO_L475VG_IOT01A": {
-            "target.features_add": ["BLE"],
-            "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"]
-        }
+         "*": {
+            "platform.stdio-baud-rate": 115200,
+            "platform.stdio-convert-newlines": true,
+            "mbed-trace.enable": 1,
+            "mbed-http.http-buffer-size": 2048,
+            "tls-socket.debug-level": 0,
+            "nsapi.default-wifi-security": "WPA_WPA2",
+            "nsapi.default-wifi-ssid": "\"VM9109107_5GEXT\"",
+            "nsapi.default-wifi-password": "\"Bonga01shop02\""
+      }
      }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/ATCmdManager.cpp	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,63 @@
+#include "ATCmdManager.h"
+#include "common_config.h"
+
+ATCmdManager::ATCmdManager(PinName tx, PinName rx, bool debug)
+    :
+    _serial(tx, rx, DEFAULT_BAUD_RATE),
+    _parser(&_serial)
+
+{ 
+// constructor
+    _serial.set_baud(DEFAULT_BAUD_RATE);
+    _parser.debug_on(debug);
+    _parser.set_delimiter("\r\n");
+    _parser.oob("ATE0", callback(this, &ATCmdManager::_oob_startup_hdlr));
+    printf("\n --- ATCmdManager constructor completed ---\n");
+    // AT+UBTLE
+}
+
+
+void ATCmdManager::runMain(){
+    while(true){
+        _process_oob(UBLOX_ODIN_W2_RECV_TIMEOUT, true);
+        wait_ms(MAIN_LOOP_WAIT_TIME_MS); // allow BTLE to be
+    }
+    
+}
+
+
+// OOB processing
+void ATCmdManager::_process_oob(uint32_t timeout, bool all){
+    set_timeout(timeout);
+    // Poll for inbound packets
+    while (_parser.process_oob() && all) {
+    }
+    set_timeout();
+}
+
+
+// OOB message handlers
+void ATCmdManager::_oob_startup_hdlr(){
+}
+
+
+void ATCmdManager::_oob_bleRole_hdlr(){
+}
+
+
+void ATCmdManager::_oob_wifiMode_err(){
+}
+
+
+void ATCmdManager::_oob_conn_already(){
+}
+
+
+void ATCmdManager::_oob_err(){
+}
+
+void ATCmdManager::set_timeout(uint32_t timeout_ms)
+{
+    _parser.set_timeout(timeout_ms);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/ATCmdManager.h	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,44 @@
+#ifndef __ATCMD_MANAGER_H__
+#define __ATCMD_MANAGER_H__
+#include <mbed.h>
+#include "ATCmdParser.h"
+
+#define MAIN_LOOP_WAIT_TIME_MS 10 // milliseconds
+#ifndef UBLOX_ODIN_W2_MISC_TIMEOUT
+#define UBLOX_ODIN_W2_MISC_TIMEOUT    2000
+#endif
+
+
+class ATCmdManager {
+public:
+    ATCmdManager(PinName tx, PinName rx, bool debug = false);
+public:
+    void runMain();
+
+
+
+private:
+// UART settings
+    UARTSerial _serial;
+    Mutex _smutex; // Protect serial port access
+    Mutex _rmutex; // Reset protection
+
+    // AT Command Parser
+    ATCmdParser _parser;
+    // OOB processing
+    void _process_oob(uint32_t timeout, bool all);
+    // OOB message handlers
+    void _oob_startup_hdlr();
+    void _oob_bleRole_hdlr();
+    void _oob_wifiMode_err();
+    void _oob_conn_already();
+    void _oob_err();
+    
+    /**
+    * Allows timeout to be changed between commands
+    *
+    * @param timeout_ms timeout of the connection
+    */
+    void set_timeout(uint32_t timeout_ms =  UBLOX_ODIN_W2_MISC_TIMEOUT);
+};
+#endif // __ATCMD_MANAGER_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BleManager.cpp	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,557 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifdef BLE_SECURITY_ENABLED
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "ble/BLE.h"
+#include "SecurityManager.h"
+#include "pretty_printer.h"
+
+#if MBED_CONF_APP_FILESYSTEM_SUPPORT
+#include "LittleFileSystem.h"
+#include "HeapBlockDevice.h"
+#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
+
+/** This example demonstrates all the basic setup required
+ *  for pairing and setting up link security both as a central and peripheral
+ *
+ *  The example is implemented as two classes, one for the peripheral and one
+ *  for central inheriting from a common base. They are run in sequence and
+ *  require a peer device to connect to. During the peripheral device demonstration
+ *  a peer device is required to connect. In the central device demonstration
+ *  this peer device will be scanned for and connected to - therefore it should
+ *  be advertising with the same address as when it connected.
+ *
+ *  During the test output is written on the serial connection to monitor its
+ *  progress.
+ */
+
+static const char DEVICE_NAME[] = "SM_device";
+
+/* we have to specify the disconnect call because of ambiguous overloads */
+typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t);
+const static disconnect_call_t disconnect_call = &Gap::disconnect;
+
+/* for demonstration purposes we will store the peer device address
+ * of the device that connects to us in the first demonstration
+ * so we can use its address to reconnect to it later */
+static BLEProtocol::AddressBytes_t peer_address;
+
+/** Base class for both peripheral and central. The same class that provides
+ *  the logic for the application also implements the SecurityManagerEventHandler
+ *  which is the interface used by the Security Manager to communicate events
+ *  back to the applications. You can provide overrides for a selection of events
+ *  your application is interested in.
+ */
+class SMDevice : private mbed::NonCopyable<SMDevice>,
+                 public SecurityManager::EventHandler,
+                 public ble::Gap::EventHandler
+{
+public:
+    SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) :
+        _led1(LED1, 0),
+        _ble(ble),
+        _event_queue(event_queue),
+        _peer_address(peer_address),
+        _handle(0),
+        _is_connecting(false) { };
+
+    virtual ~SMDevice()
+    {
+        if (_ble.hasInitialized()) {
+            _ble.shutdown();
+        }
+    };
+
+    /** Start BLE interface initialisation */
+    void run()
+    {
+        ble_error_t error;
+
+        /* to show we're running we'll blink every 500ms */
+        _event_queue.call_every(500, this, &SMDevice::blink);
+
+        if (_ble.hasInitialized()) {
+            printf("Ble instance already initialised.\r\n");
+            return;
+        }
+
+        /* this will inform us off all events so we can schedule their handling
+         * using our event queue */
+        _ble.onEventsToProcess(
+            makeFunctionPointer(this, &SMDevice::schedule_ble_events)
+        );
+
+        /* handle gap events */
+        _ble.gap().setEventHandler(this);
+
+        error = _ble.init(this, &SMDevice::on_init_complete);
+
+        if (error) {
+            printf("Error returned by BLE::init.\r\n");
+            return;
+        }
+
+        /* this will not return until shutdown */
+        _event_queue.dispatch_forever();
+    };
+
+private:
+    /** Override to start chosen activity when initialisation completes */
+    virtual void start() = 0;
+
+    /** This is called when BLE interface is initialised and starts the demonstration */
+    void on_init_complete(BLE::InitializationCompleteCallbackContext *event)
+    {
+        ble_error_t error;
+
+        if (event->error) {
+            printf("Error during the initialisation\r\n");
+            return;
+        }
+
+        /* This path will be used to store bonding information but will fallback
+         * to storing in memory if file access fails (for example due to lack of a filesystem) */
+        const char* db_path = "/fs/bt_sec_db";
+        /* If the security manager is required this needs to be called before any
+         * calls to the Security manager happen. */
+        error = _ble.securityManager().init(
+            true,
+            false,
+            SecurityManager::IO_CAPS_NONE,
+            NULL,
+            false,
+            db_path
+        );
+
+        if (error) {
+            printf("Error during init %d\r\n", error);
+            return;
+        }
+
+        error = _ble.securityManager().preserveBondingStateOnReset(true);
+
+        if (error) {
+            printf("Error during preserveBondingStateOnReset %d\r\n", error);
+        }
+
+#if MBED_CONF_APP_FILESYSTEM_SUPPORT
+        /* Enable privacy so we can find the keys */
+        error = _ble.gap().enablePrivacy(true);
+
+        if (error) {
+            printf("Error enabling privacy\r\n");
+        }
+
+        Gap::PeripheralPrivacyConfiguration_t configuration_p = {
+            /* use_non_resolvable_random_address */ false,
+            Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS
+        };
+        _ble.gap().setPeripheralPrivacyConfiguration(&configuration_p);
+
+        Gap::CentralPrivacyConfiguration_t configuration_c = {
+            /* use_non_resolvable_random_address */ false,
+            Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD
+        };
+        _ble.gap().setCentralPrivacyConfiguration(&configuration_c);
+
+        /* this demo switches between being master and slave */
+        _ble.securityManager().setHintFutureRoleReversal(true);
+#endif
+
+        /* Tell the security manager to use methods in this class to inform us
+         * of any events. Class needs to implement SecurityManagerEventHandler. */
+        _ble.securityManager().setSecurityManagerEventHandler(this);
+
+        /* gap events also handled by this class */
+        _ble.gap().setEventHandler(this);
+
+        /* print device address */
+        Gap::AddressType_t addr_type;
+        Gap::Address_t addr;
+        _ble.gap().getAddress(&addr_type, addr);
+        print_address(addr);
+
+        /* start test in 500 ms */
+        _event_queue.call_in(500, this, &SMDevice::start);
+    };
+
+    /** Schedule processing of events from the BLE in the event queue. */
+    void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context)
+    {
+        _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents));
+    };
+
+    /** Blink LED to show we're running */
+    void blink(void)
+    {
+        _led1 = !_led1;
+    };
+
+private:
+    /* Event handler */
+
+    /** Respond to a pairing request. This will be called by the stack
+     * when a pairing request arrives and expects the application to
+     * call acceptPairingRequest or cancelPairingRequest */
+    virtual void pairingRequest(
+        ble::connection_handle_t connectionHandle
+    ) {
+        printf("Pairing requested - authorising\r\n");
+        _ble.securityManager().acceptPairingRequest(connectionHandle);
+    }
+
+    /** Inform the application of a successful pairing. Terminate the demonstration. */
+    virtual void pairingResult(
+        ble::connection_handle_t connectionHandle,
+        SecurityManager::SecurityCompletionStatus_t result
+    ) {
+        if (result == SecurityManager::SEC_STATUS_SUCCESS) {
+            printf("Pairing successful\r\n");
+        } else {
+            printf("Pairing failed\r\n");
+        }
+    }
+
+    /** Inform the application of change in encryption status. This will be
+     * communicated through the serial port */
+    virtual void linkEncryptionResult(
+        ble::connection_handle_t connectionHandle,
+        ble::link_encryption_t result
+    ) {
+        if (result == ble::link_encryption_t::ENCRYPTED) {
+            printf("Link ENCRYPTED\r\n");
+        } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) {
+            printf("Link ENCRYPTED_WITH_MITM\r\n");
+        } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) {
+            printf("Link NOT_ENCRYPTED\r\n");
+        }
+
+        /* disconnect in 2 s */
+        _event_queue.call_in(
+            2000,
+            &_ble.gap(),
+            disconnect_call,
+            _handle,
+            ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION)
+        );
+    }
+
+    /** This is called by Gap to notify the application we disconnected,
+     *  in our case it ends the demonstration. */
+    virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &)
+    {
+        printf("Diconnected\r\n");
+        _event_queue.break_dispatch();
+    };
+
+    virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &)
+    {
+        printf("Advertising timed out - aborting\r\n");
+        _event_queue.break_dispatch();
+    }
+
+    virtual void onScanTimeout(const ble::ScanTimeoutEvent &)
+    {
+        printf("Scan timed out - aborting\r\n");
+        _event_queue.break_dispatch();
+    }
+
+private:
+    DigitalOut _led1;
+
+protected:
+    BLE &_ble;
+    events::EventQueue &_event_queue;
+    BLEProtocol::AddressBytes_t &_peer_address;
+    ble::connection_handle_t _handle;
+    bool _is_connecting;
+};
+
+/** A peripheral device will advertise, accept the connection and request
+ * a change in link security. */
+class SMDevicePeripheral : public SMDevice {
+public:
+    SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
+        : SMDevice(ble, event_queue, peer_address) { }
+
+    virtual void start()
+    {
+        /* Set up and start advertising */
+        uint8_t adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
+        /* use the helper to build the payload */
+        ble::AdvertisingDataBuilder adv_data_builder(
+            adv_buffer
+        );
+
+        adv_data_builder.setFlags();
+        adv_data_builder.setName(DEVICE_NAME);
+
+        /* Set payload for the set */
+        ble_error_t error = _ble.gap().setAdvertisingPayload(
+            ble::LEGACY_ADVERTISING_HANDLE,
+            adv_data_builder.getAdvertisingData()
+        );
+
+        if (error) {
+            print_error(error, "Gap::setAdvertisingPayload() failed");
+            _event_queue.break_dispatch();
+            return;
+        }
+
+        ble::AdvertisingParameters adv_parameters(
+            ble::advertising_type_t::CONNECTABLE_UNDIRECTED
+        );
+
+        error = _ble.gap().setAdvertisingParameters(
+            ble::LEGACY_ADVERTISING_HANDLE,
+            adv_parameters
+        );
+
+        if (error) {
+            print_error(error, "Gap::setAdvertisingParameters() failed");
+            return;
+        }
+
+        error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
+
+        if (error) {
+            print_error(error, "Gap::startAdvertising() failed");
+            return;
+        }
+
+        printf("Please connect to device\r\n");
+
+        /** This tells the stack to generate a pairingRequest event
+         * which will require this application to respond before pairing
+         * can proceed. Setting it to false will automatically accept
+         * pairing. */
+        _ble.securityManager().setPairingRequestAuthorisation(true);
+    };
+
+    /** This is called by Gap to notify the application we connected,
+     *  in our case it immediately requests a change in link security */
+    virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event)
+    {
+        ble_error_t error;
+
+        /* remember the device that connects to us now so we can connect to it
+         * during the next demonstration */
+        memcpy(_peer_address, event.getPeerAddress().data(), sizeof(_peer_address));
+
+        printf("Connected to peer: ");
+        print_address(event.getPeerAddress().data());
+
+        _handle = event.getConnectionHandle();
+
+        /* Request a change in link security. This will be done
+         * indirectly by asking the master of the connection to
+         * change it. Depending on circumstances different actions
+         * may be taken by the master which will trigger events
+         * which the applications should deal with. */
+        error = _ble.securityManager().setLinkSecurity(
+            _handle,
+            SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM
+        );
+
+        if (error) {
+            printf("Error during SM::setLinkSecurity %d\r\n", error);
+            return;
+        }
+    };
+};
+
+/** A central device will scan, connect to a peer and request pairing. */
+class SMDeviceCentral : public SMDevice {
+public:
+    SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
+        : SMDevice(ble, event_queue, peer_address) { }
+
+    virtual void start()
+    {
+        ble::ScanParameters params;
+        ble_error_t error = _ble.gap().setScanParameters(params);
+
+        if (error) {
+            print_error(error, "Error in Gap::startScan %d\r\n");
+            return;
+        }
+
+        /* start scanning, results will be handled by onAdvertisingReport */
+        error = _ble.gap().startScan();
+
+        if (error) {
+            print_error(error, "Error in Gap::startScan %d\r\n");
+            return;
+        }
+
+        printf("Please advertise\r\n");
+
+        printf("Scanning for: ");
+        print_address(_peer_address);
+    }
+
+private:
+    /* Gap::EventHandler */
+
+    /** Look at scan payload to find a peer device and connect to it */
+    virtual void onAdvertisingReport(const ble::AdvertisingReportEvent &event)
+    {
+        /* don't bother with analysing scan result if we're already connecting */
+        if (_is_connecting) {
+            return;
+        }
+
+        /* parse the advertising payload, looking for a discoverable device */
+        if (memcmp(event.getPeerAddress().data(), _peer_address, sizeof(_peer_address)) == 0) {
+            ble_error_t error = _ble.gap().stopScan();
+
+            if (error) {
+                print_error(error, "Error caused by Gap::stopScan");
+                return;
+            }
+
+            ble::ConnectionParameters connection_params(
+                ble::phy_t::LE_1M,
+                ble::scan_interval_t(50),
+                ble::scan_window_t(50),
+                ble::conn_interval_t(50),
+                ble::conn_interval_t(100),
+                ble::slave_latency_t(0),
+                ble::supervision_timeout_t(100)
+            );
+            connection_params.setOwnAddressType(ble::own_address_type_t::RANDOM);
+
+            error = _ble.gap().connect(
+                event.getPeerAddressType(),
+                event.getPeerAddress(),
+                connection_params
+            );
+
+            if (error) {
+                print_error(error, "Error caused by Gap::connect");
+                return;
+            }
+
+            /* we may have already scan events waiting
+             * to be processed so we need to remember
+             * that we are already connecting and ignore them */
+            _is_connecting = true;
+
+            return;
+        }
+    }
+
+    /** This is called by Gap to notify the application we connected,
+     *  in our case it immediately request pairing */
+    virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event)
+    {
+        if (event.getStatus() == BLE_ERROR_NONE) {
+            /* store the handle for future Security Manager requests */
+            _handle = event.getConnectionHandle();
+
+            printf("Connected\r\n");
+
+            /* in this example the local device is the master so we request pairing */
+            ble_error_t error = _ble.securityManager().requestPairing(_handle);
+
+             if (error) {
+                 printf("Error during SM::requestPairing %d\r\n", error);
+                 return;
+             }
+
+            /* upon pairing success the application will disconnect */
+        }
+
+        /* failed to connect - restart scan */
+        ble_error_t error = _ble.gap().startScan();
+
+        if (error) {
+            print_error(error, "Error in Gap::startScan %d\r\n");
+            return;
+        }
+    };
+};
+
+
+#if MBED_CONF_APP_FILESYSTEM_SUPPORT
+bool create_filesystem()
+{
+    static LittleFileSystem fs("fs");
+
+    /* replace this with any physical block device your board supports (like an SD card) */
+    static HeapBlockDevice bd(4096, 256);
+
+    int err = bd.init();
+
+    if (err) {
+        return false;
+    }
+
+    err = bd.erase(0, bd.size());
+
+    if (err) {
+        return false;
+    }
+
+    err = fs.mount(&bd);
+
+    if (err) {
+        /* Reformat if we can't mount the filesystem */
+        printf("No filesystem found, formatting...\r\n");
+
+        err = fs.reformat(&bd);
+
+        if (err) {
+            return false;
+        }
+    }
+
+    return true;
+}
+#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
+
+int main()
+{
+    BLE& ble = BLE::Instance();
+    events::EventQueue queue;
+
+#if MBED_CONF_APP_FILESYSTEM_SUPPORT
+    /* if filesystem creation fails or there is no filesystem the security manager
+     * will fallback to storing the security database in memory */
+    if (!create_filesystem()) {
+        printf("Filesystem creation failed, will use memory storage\r\n");
+    }
+#endif
+
+    while(1) {
+        {
+            printf("\r\n PERIPHERAL \r\n\r\n");
+            SMDevicePeripheral peripheral(ble, queue, peer_address);
+            peripheral.run();
+        }
+
+        {
+            printf("\r\n CENTRAL \r\n\r\n");
+            SMDeviceCentral central(ble, queue, peer_address);
+            central.run();
+        }
+    }
+
+    return 0;
+}
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BleManager.h	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,3 @@
+#ifdndef __BLE_MANAGER_H__
+#define __BLE_MANAGER_H__
+#endif // __BLE_MANAGER_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/common_config.h	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,15 @@
+#ifndef __COMMON_CONFIG_H__
+#define __COMMON_CONFIG_H__
+
+#define   DEFAULT_BAUD_RATE   115200
+#define BUFFER_LEN 256
+#define TX_BUFFER_LEN 4*256
+#define RX_BUFFER_LEN 4*256
+#define BTLE_THREAD_PRIORITY osPriorityRealtime
+#define WIFI_THREAD_PRIORITY osPriorityRealtime
+#define ATCMD_THREAD_PRIORITY osPriorityRealtime
+#ifndef UBLOX_ODIN_W2_RECV_TIMEOUT
+#define UBLOX_ODIN_W2_RECV_TIMEOUT    2000
+#endif
+
+#endif // __COMMON_CONFIG_H__
\ No newline at end of file
--- a/source/https_certificates.h	Thu Feb 28 18:13:48 2019 +0000
+++ b/source/https_certificates.h	Sun Mar 10 09:46:06 2019 +0000
@@ -3,7 +3,8 @@
  *
  * To add more root certificates, just concatenate them.
  */
- 
+ #ifndef __HTTPS_CERTIFICATES__
+ #define __HTTPS_CERTIFICATES__
  const char SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n"
     "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n"
     "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n"
@@ -73,3 +74,5 @@
     "rqXRfboQnoZsG4q5WTP468SQvvG5\n"
     "-----END CERTIFICATE-----\n"
 ;
+
+#endif //__HTTPS_CERTIFICATES__
--- a/source/main-https.cpp	Thu Feb 28 18:13:48 2019 +0000
+++ b/source/main-https.cpp	Sun Mar 10 09:46:06 2019 +0000
@@ -9,31 +9,24 @@
 #include <mbed.h>
 #include "ble/BLE.h"
 //#include "BLE.h"
-#include "mbed_trace.h"
-#include "https_request.h"
-#include "http_request.h"
-#include "network-helper.h"
 #include "ATCmdParser.h"
 //#include "BLEDevice.h"
 
 #include "LEDService.h"
 #include "ble/services/UARTService.h"
-
+#include "common_config.h"
+#include "ATCmdManager.h"
 UARTService *uart;
 
 DigitalOut alivenessLED(LED1, 0);
 DigitalOut actuatedLED(LED2, 0);
 
-#define   DEFAULT_BAUD_RATE   115200
 
-RawSerial *device; // tx, rx
-UARTSerial *_serial; // tx, rx
-ATCmdParser *_parser;
+static RawSerial *device; // tx, rx
+static UARTSerial *_serial; // tx, rx
+static ATCmdParser *_parser;
 const static char     DEVICE_NAME[] = "BLE-UART";
 static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
-#define BUFFER_LEN 256
-#define TX_BUFFER_LEN 4*256
-#define RX_BUFFER_LEN 4*256
 char buffer[BUFFER_LEN];
 uint8_t TxBuffer[TX_BUFFER_LEN];
 uint8_t RxBuffer[RX_BUFFER_LEN];
@@ -42,7 +35,30 @@
 
 LEDService *ledServicePtr;
 
+
+/* allocate statically stacks for the three threads */
+//unsigned char rt_stk[1024];
+//unsigned char hp_stk[1024];
+//unsigned char lp_stk[1024];
+unsigned char btle_stk[1024];
+unsigned char wifi_stk[1024];
+unsigned char atcmd_stk[1024];
+static bool bleInitializationCompleted = false;
+
+/* creates three tread objects with different priorities */
+//Thread real_time_thread(osPriorityRealtime, 1024, &rt_stk[0]);
+//Thread high_prio_thread(osPriorityHigh, 1024, &hp_stk[0]);
+//Thread low_prio_thread(osPriorityNormal, 1024, &lp_stk[0]);
+Thread btle_thread(BTLE_THREAD_PRIORITY, 1024, &btle_stk[0]);
+Thread wifi_thread(WIFI_THREAD_PRIORITY, 1024, &wifi_stk[0]);
+Thread atcmd_thread(ATCMD_THREAD_PRIORITY, 1024, &atcmd_stk[0]);
+
+
+/* create a semaphore to synchronize the threads */
+Semaphore sync_sema;
+
 Thread t;
+#include "network-helper.h"
 
 /* List of trusted root CA certificates
  * currently two: GlobalSign, the CA for os.mbed.com and Let's Encrypt, the CA for httpbin.org
@@ -51,8 +67,29 @@
  */
 #include "https_certificates.h"
 
+// wifi demo
+#include "wifi_demo.h"
 
 
+// check free memory
+
+void performFreeMemoryCheck()
+{
+       // perform free memory check
+    int blockSize = 16;
+    int i = 1;
+    printf("Checking memory with blocksize %d char ...\n", blockSize);
+    while (true) {
+        char *p = (char *) malloc(i * blockSize);
+        if (p == NULL)
+            break;
+        free(p);
+        ++i;
+    }
+    printf("Ok for %d char\n", (i - 1) * blockSize);
+
+}
+
 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
 {
     (void) params;
@@ -115,13 +152,31 @@
     /* Initialization error handling should go here */
 }
 
+
+/*  handle BLE timouts  */
+static int bleTimoutCount = 0;
+
+void printBleTimeoutMsg()
+{
+    bleTimoutCount++;
+    device->printf("\n --- BLE Times out!! bleTimoutCount = %d --- \n", bleTimoutCount);
+}
+
+//void timeoutCallback(Gap::TimeoutEventCallback_t* context) {
+void timeoutCallback(Gap::TimeoutSource_t timeoutSource) {
+    BLE &ble = BLE::Instance();
+    eventQueue.call(printBleTimeoutMsg);
+}
+
+
+
 void printMacAddress()
 {
     /* Print out device MAC address to the console*/
     Gap::AddressType_t addr_type;
     Gap::Address_t address;
     BLE::Instance().gap().getAddress(&addr_type, address);
-    printf("DEVICE MAC ADDRESS: ");
+    printf("\nDEVICE MAC ADDRESS: ");
     for (int i = 5; i >= 1; i--){
         printf("%02x:", address[i]);
     }
@@ -149,6 +204,7 @@
 
     ble.gap().onDisconnection(disconnectionCallback);
     ble.gattServer().onDataWritten(onDataWrittenCallback);
+    ble.gap().onTimeout(timeoutCallback);
 
     bool initialValueForLEDCharacteristic = false;
     ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic);
@@ -163,9 +219,11 @@
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
+    ble.gap().setAdvertisingTimeout(300); /* 16 * 1000ms. */
     ble.gap().startAdvertising();
 
     printMacAddress();
+    bleInitializationCompleted = true;
 }
 
 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
@@ -184,6 +242,25 @@
 }
 
 
+void restartBleAdvertising()
+{
+    BLE &ble = BLE::Instance();
+    
+    //ble.init(bleInitComplete);
+     // clear advertising payload
+    ble.gap().clearAdvertisingPayload();
+    /* setup advertising */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+    /* set up the services that can be discovered */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
+    ble.gap().startAdvertising();
+    eventQueue.dispatch(1000);        // Dispatch time - 1000msec
+}
+
 static int uartExpectedRcvCount = 0;
 static int uartCharRcvCount = 0;
 static bool UartBusy = false;
@@ -303,230 +380,74 @@
 //RawSerial device(MBED_CONF_APP_UART1_TX, MBED_CONF_APP_UART1_RX); // tx, rx
 
 
-int chunkNum;
-void dump_response(HttpResponse* res) {
-    device->printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str());
-
-    device->printf("Headers:\n");
-    for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
-        device->printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
-    }
-    device->printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
-}
-
-void completed(){
-    }
-void dump_chunked_response(const char *at, uint32_t length) {
-    device->printf("\n Chunked response: Chunk %d : Total Bytes = %d\n", chunkNum , length);
-    //device->printf("\n Try Print Header as string:\n\n ");
-    //device->printf("recv %d [%.*s]\n", length, strstr((char *)at, "\r\n")-(char *)at, (char *)at);
-    //if(false)
-    if(chunkNum < 2)
-    for(int i=0; i < length; i++){
-        
-        while(device->writeable())
-        {
-            device->putc((uint8_t)at[i]);
-        }
-        //int resp = write( (const uint8_t *)at, (int) length, &completed, SERIAL_EVENT_TX_COMPLETE);
-    }
-    if(false)
-    for (size_t ix = 0; ix < length; ix++) {
-        device->printf("%02X: ", at[ix]);
-        if((ix % 32) == 0 and ix)
-        device->printf("\n");
-    }
-    device->printf("\n\n");
-    chunkNum++;
-    //device->printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
-}
 
 
 // Wifi-demo
 void wifi_demo(NetworkInterface* network){
-    if (!network) {
-        device->printf("Cannot connect to the network, see serial output\n");
-        return 1;
-    }
-
-    mbed_trace_init();
-
-    // GET request to os.mbed.com
+    int n = wifi_demo_func(network);
+    if(n > 0)// error
     {
-        chunkNum = 0;
-        device->printf("\n----- HTTPS GET request -----\n");
-
-        HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt", &dump_chunked_response);
-
-        HttpResponse* get_res = get_req->send();
-        if (!get_res) {
-            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
-            return 1;
-        }
-        device->printf("\n----- HTTPS GET response -----\n");
-        dump_response(get_res);
-        delete get_req;
+        device->printf("\n --- Error running wifi demo --- \n");
     }
-    
-    
-    
-     // Do a GET request to httpbin.org
-    {
-        chunkNum = 0;
-        device->printf("\n----- HTTP GET request to httpbin.org  -----\n");
-
-        // By default the body is automatically parsed and stored in a buffer, this is memory heavy.
-        // To receive chunked response, pass in a callback as last parameter to the constructor.
-        HttpRequest* get_req = new HttpRequest(network, HTTP_GET, "http://httpbin.org/status/418");
+}
 
-        HttpResponse* get_res = get_req->send();
-        if (!get_res) {
-            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
-            return 1;
-        }
-
-        device->printf("\n----- HTTP GET response from httpbin.org -----\n");
-        dump_response(get_res);
-
-        delete get_req;
-    }
-    
-    
-    // Do a GET request to ovh.net
-    if(false)
+// Wifi-demo2
+void wifi_demo2(){
+    //int n = wifi_demo_func(network);
+    int n =5;
+    if(n > 0)// error
     {
-       chunkNum = 0;
-       device->printf("\n----- HTTP GET request to ovh.net  -----\n");
-        Timer t;
-        // By default the body is automatically parsed and stored in a buffer, this is memory heavy.
-        // To receive chunked response, pass in a callback as last parameter to the constructor.
-        t.start();
-        HttpRequest* get_req = new HttpRequest(network, HTTP_GET, "http://www.ovh.net/files/1Mio.dat", &dump_chunked_response);
-
-        HttpResponse* get_res = get_req->send();
-        if (!get_res) {
-            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
-            return 1;
-        }
-
-        device->printf("\n----- HTTP GET response from ovh.net -----\n");
-        dump_response(get_res);
-        t.stop();
-        device->printf("The time taken was %f seconds\n", t.read());
-
-
-        delete get_req;
+        device->printf("\n --- Error running wifi demo --- \n");
     }
-    
-    {
-        device->printf("\n----- HTTPS GET request (large file!) -----\n");
-
-        HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt");
+}
 
-        HttpResponse* get_res = get_req->send();
-        if (!get_res) {
-            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
-            return 1;
-        }
-        /*
-        while (0 < (response = socket.recv(p, remaining))) {
-            p += response;
-            rcount += response;
-            remaining -= response;
-        }
-        */
-        device->printf("\n----- HTTPS GET response -----\n");
-        dump_response(get_res);
-
-
-
-        delete get_req;
-    }
-
-    // POST request to httpbin.org
-    {
-        device->printf("\n----- HTTPS POST request -----\n");
-
-        HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://httpbin.org/post");
-        post_req->set_header("Content-Type", "application/json");
-
-        const char body[] = "{\"hello\":\"world\"}";
-
-        HttpResponse* post_res = post_req->send(body, strlen(body));
-        if (!post_res) {
-            device->printf("HttpRequest failed (error code %d)\n", post_req->get_error());
-            return 1;
-        }
-
-        device->printf("\n----- HTTPS POST response -----\n");
-        dump_response(post_res);
-
-        delete post_req;
-    }
-
-
-    // POST request to ws.dnanudge.io:80
-    {
-        device->printf("\n----- HTTP POST request (http://ws.dnanudge.io/nudgebox/v1) -----\n");
+void reportGapState()
+{
+     BLE &ble = BLE::Instance();
+     Gap::GapState_t gapState = ble.gap().getState();
+     char connStr[20] = " Not Connected ";
+     char advStr[20] = " Not Advertising ";
+     char devName[20] = "";
+     if(gapState.advertising){
+         strncpy(advStr, " Advertising ", 20);
+     }
+     if(gapState.connected){
+         strncpy(connStr, " Connected ", 20);
+     }
+     device->printf("\n Advertising Status = %s\n Connection Status = %s\n", advStr, connStr);
+     unsigned nLen;
+     ble_error_t error;
+     error =  ble.gap().getDeviceName((uint8_t *) devName, &nLen);
+     if(error != BLE_ERROR_NONE)
+     {
+        device->printf("\n Error Reading BLE device Name \n");
+        return;
+     }
+     devName[nLen] = NULL;
+     device->printf("\n BLE Device name = %s : Name Len %d\n", devName, nLen);
+     for(int i=0;i<8;i++)
+     device->putc(devName[i]);
+     
+}
 
-        HttpRequest* post_req = new HttpRequest(network, HTTP_POST, "http://ws.dnanudge.io/nudgebox/v1");
-        post_req->set_header("Host", "ws.dnanudge.io");
-        post_req->set_header("Accept", "*/*");
-        post_req->set_header("Content-Type", "application/octet-stream");
-        post_req->set_header("Content-Length", "20");
-                               // 00    08    6a    48    f8    2d    8e    82    01    68
-        const uint8_t body[] = {0x00, 0x08, 0x6a, 0x48, 0xf8, 0x2d, 0x8e, 0x82, 0x01, 0x68, 
-                               // 65    6c    6c    6f    00    00    67    c3    19    f8
-                                0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x00, 0x67, 0xc3, 0x19, 0xf8};
-
-        HttpResponse* post_res = post_req->send(body, 20);
-        if (!post_res) {
-            device->printf("HttpRequest failed (error code %d)\n", post_req->get_error());
-            return 1;
-        }
-
-        device->printf("\n----- HTTPS POST response -----\n");
-        dump_response(post_res);
-
-        delete post_req;
+void printWait(int numSecs)
+{
+    printf("Waiting for %d seconds...\n", numSecs);
+    for(int i=0;i<numSecs;i++){
+        printf("%d", i);
+        wait(0.5);
+        eventQueue.dispatch(500);        // Dispatch time - 500msec
     }
-
+}
 
-    // POST request to httpbin.org
-    if(false)
-    {
-        device->printf("\n----- HTTPS POST request to AWS -----\n");
-
-        HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://q6bc0dxw7f.execute-api.eu-west-2.amazonaws.com/test/samples/v1");
-        post_req->set_header("Content-Type", "application/json");
-
-        const char body[] = 
-                            "{"
-                            "\"firstName\": \"Maria\", "
-                            "\"lastName\": \"Huntera\", "
-                            "\"dob\": \"1970-12-03\", "
-                            "\"mobile\": \"07841887580\", "
-                            "\"cartridgeId\": \"DN00000000RMPOE\", "
-                            "\"labSampleId\": \"DYYAK\""
-                            "}";
-        HttpResponse* post_res = post_req->send(body, strlen(body));
-        if (!post_res) {
-            device->printf("HttpRequest failed (error code %d)\n", post_req->get_error());
-            return 1;
-        }
-
-        device->printf("\n----- HTTPS POST response from AWS -----\n");
-        dump_response(post_res);
-
-        delete post_req;
-    }
- }
+static int reset_counter = 0;
 
 int main() {
+    reset_counter++;
     //RawSerial *device(USBTX, USBRX); // tx, rx
     device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
     
-    device->printf("\n --- Running UART-BLE-UartService --- \n");
+    device->printf("\n --- Running UART-BLE-UartService --- (rst_cnt = %d)\n", reset_counter);
     // Start the event queue
     //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
 
@@ -537,26 +458,125 @@
     ////////////////////////////////////////////////////////////////////////////////
     // BLE Initialization /////////////////////////////////////////////////////////
     device->printf("\n --- about to instantiate BLE instance --- \n");
-    device->getc();
     //cbMAIN_driverLock();
     BLE &ble = BLE::Instance();
     device->printf("\n --- BLE Instance Instantiated --- \n");
     //ble.onEventsToProcess(scheduleBleEventsProcessing);
     //device->printf("\n --- BLE scheduleBleEventsProcessing setup --- \n");
     //ble.init(bleInitComplete);
-    bleInitialization();
+    btle_thread.start(callback(bleInitialization));
     //cbMAIN_driverUnlock();
+    
+    device->printf("\n --- Waiting for BLE Initialization to be completed --- \n");
+    int i = 0;
+    while(!ble.hasInitialized() && i < 20){
+        // dispatch function
+        eventQueue.dispatch(1000);        // Dispatch time - 1000msec
+        // 400 msec - Only 2 set of events will be dispatched as period is 200 msec
+        
+        device->putc('0'+(i++ % 10));
+    }
+    btle_thread.join();
+    if(i < 20)
     device->printf("\n --- BLE Initialization completed --- \n");
-    device->printf("\n Press any key to start Wifi demo: ");
+    else
+    device->printf("\n --- BLE Initialization failed --- \n");
+    wait(1); // wait for advertising interval so advertising has started 
+    //reportGapState();
+    //device->printf("\n Press any key to stop BLE advertising: ");
+    //ble.gap().stopAdvertising();
+    //ble.shutdown();
+    //reportGapState();
+    //device->getc();
+    //device->printf("\n Press any key to restart BLE advertising: ");
+    //device->getc();
+    //restartBleAdvertising();
+    //reportGapState();
+    //device->printf("\n Press any key to stop BLE advertising: ");
+    //device->getc();
+    //device->baud(115200);
+    //ble.gap().stopAdvertising();
+    //ble.shutdown();
+    reportGapState();
+    ////////////////////////////////////////////////////////////////////////////////
+    // BLE Initialization /////////////////////////////////////////////////////////
+#ifdef false
+    device->printf("\n --- about to shutdown BLE instance --- \n");
+    device->printf("\n Press any key: ");
     device->getc();
+    //ble.gap().clearAdvertisingPayload();
+    ble.gap().stopAdvertising();
+    ble.gap().reset();
+    //ble.shutdown();
+    //delete ble;
     ////////////////////////////////////////////////////////////////////////////////////
-
-    //device->baud(115200);
+#endif
+     btle_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
+     printWait(30);
+     //device->printf("\n Press any key to start Wifi demo: ");
+     //device->getc();
+     int start = Kernel::get_ms_count();
      NetworkInterface* network = connect_to_default_network_interface();
+     int stop = Kernel::get_ms_count();
+     device->printf("\n The Wifi Network scan took %d ms or %4.1f seconds\n", (stop - start), (float)((stop - start)/1000.0));
      // run on separate thread;
-     t.start(wifi_demo(network));
-     network->disconnect();   
+     t.start(callback(wifi_demo, network));
+     //t.start(wifi_demo2());
      t.join(); 
+     //network->disconnect(); 
+     //delete network;
+     printMacAddress();  
+     reportGapState();
+     //device->printf("\n Press any key to restart BLE : ");
+     //device->getc();
+     
+     
+    
+    ////////////////////////////////////////////////////////////////////////////////
+    // BLE Initialization /////////////////////////////////////////////////////////
+    //device->printf("\n --- about to shutdown BLE instance --- \n");
+    //ble.shutdown();
+    //ble.gap().clearAdvertisingPayload();
+    //delete ble;
+    //device->printf("\n --- about to instantiate new BLE instance --- \n");
+    //cbMAIN_driverLock();
+    //BLE &ble = BLE::Instance();
+    //device->printf("\n --- BLE Instance Instantiated --- \n");
+    //ble.onEventsToProcess(scheduleBleEventsProcessing);
+    //device->printf("\n --- BLE scheduleBleEventsProcessing setup --- \n");
+    //ble.init(bleInitComplete);
+#ifdef false
+    device->printf("\n --- Restarting BLE Initialization --- \n");
+    ble.gap().reset();
+  
+    btle_thread.start(callback(bleInitialization));
+    btle_thread.join();
+    
+    //ble.init(bleInitComplete);
+    //cbMAIN_driverUnlock();
+    
+    device->printf("\n --- Waiting for BLE Initialization to be completed --- \n");
+    i = 0;
+    while(!ble.hasInitialized() && i < 20){
+        // dispatch function
+        eventQueue.dispatch(1000);        // Dispatch time - 1000msec
+        // 400 msec - Only 2 set of events will be dispatched as period is 200 msec
+        
+        device->putc('0'+(i++ % 10));
+    }
+    if(i < 20)
+    device->printf("\n --- BLE Initialization completed --- \n");
+    else
+    device->printf("\n --- BLE Initialization failed --- \n");
+#endif
+    wait(1); // wait for advertising interval so advertising has started 
+    reportGapState();
+    
+     
+     //reportGapState();
+     //restartBleAdvertising();
+     //printMacAddress();
+     //reportGapState();
     
     for(int i=0;i<255;i++)
     {
@@ -564,11 +584,12 @@
     }
     int n;
     //ReadUartBytes(RxBuffer, RX_BUFFER_LEN, 4);
+    reportGapState();
     device->printf("\n\n\nEnter # of expected bytes: ");
     n = ReadUartBytes(RxBuffer, RX_BUFFER_LEN, 4, true);
-    int rxLen = (int) 100*(RxBuffer[0]-'0') + 10*(RxBuffer[1]-'0') + (RxBuffer[2]-'0');
+    uint8_t rxLen = (uint8_t) (100*(RxBuffer[0]-'0') + 10*(RxBuffer[1]-'0') + (RxBuffer[2]-'0')) %256;
     device->printf("\n\nExpected # of Received Bytes = %d\n", rxLen);
-    BackGndUartRead(RxBuffer, RX_BUFFER_LEN, rxLen);
+    BackGndUartRead(RxBuffer, RX_BUFFER_LEN, (int) rxLen);
     //device->printf("--- Writing back received data --- \n\n");
     //n = WriteUartBytes(RxBuffer, TX_BUFFER_LEN, rxLen);
     //write("\n\ntesting Serial Write\n", 40); //, checkUartReceive, SERIAL_EVENT_TX_COMPLETE);
@@ -576,14 +597,23 @@
 
     device->printf("\nATCmdParser with ESP8266 example");
     device->printf("\n Waiting for 2 minutes ");
-    wait(120);
-    eventQueue.dispatch_forever();
-    return 0;
+    wait(2);
+    device->printf("\n Waiting finished!!!\n\n ");
+    reportGapState();
+    //eventQueue.dispatch_forever();
+    
+    
+    
+    //btle_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
     device->printf("\n About to delete RawSerial device instance ");
     delete device;
+    ATCmdManager *aTCmdManager = new ATCmdManager(USBTX, USBRX, true);
+#ifdef false
     _serial = new UARTSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
+    _parser = new ATCmdParser(_serial);
+    _parser->printf("\n _serial printf being used for this \n\n");
+    device->printf("\n device printf being used now \n\n");
     printf("\n ATCmdParser printf being used now \n\n");
-    _parser = new ATCmdParser(_serial);
     _parser->debug_on( 1 );
     _parser->set_delimiter( "\r\n" );
 
@@ -598,9 +628,11 @@
         printf("\nATCmdParser: Retrieving FW version failed");
         return -1;
     }
-
+    //parser.recv("+CIPDATA:%d,", &len);
+    //parser.read(buffer, len);
     printf("\nDone\n");
-
+#endif
+    performFreeMemoryCheck();
 
     //eventQueue.dispatch_forever();
     //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
--- a/source/network-helper.h	Thu Feb 28 18:13:48 2019 +0000
+++ b/source/network-helper.h	Sun Mar 10 09:46:06 2019 +0000
@@ -25,6 +25,74 @@
             return "Unknown";
     }
 }
+#define MAX_CHANNEL_NUM 4
+const int channel_list [] = {1,11, 36, 44};
+int getAPcount(WiFiInterface *wifi)
+{
+    int count = 0;
+    for(uint8_t idx=0; idx< MAX_CHANNEL_NUM;idx++){
+        printf("\n Scanning channel %d - APs so far = %d\n", channel_list[idx], count);
+        wifi->set_channel(channel_list[idx]);
+        count += wifi->scan(NULL,0);
+        wait_ms(150); // wait for 150 ms between scans
+    }
+    printf("\n Total APs found = %d\n", count);
+    return count;
+}
+
+#define MAX_APs_PER_CHAN 3
+int getAPdetails(WiFiAccessPoint *ap, WiFiInterface *wifi, int apCount)
+{
+     int count =0;
+     for(uint8_t idx=0; idx< MAX_CHANNEL_NUM;idx++){
+        printf("\n Scanning channel %d - APs so far = %d  apCount =%d\n", channel_list[idx], count, apCount);
+        wifi->set_channel(channel_list[idx]);
+        count += wifi->scan(&ap[count],(apCount - count) % MAX_APs_PER_CHAN);
+        wait_ms(150); // wait for 150 ms between scans
+        if(count >= apCount) break;
+    }
+    wifi->set_channel(0);
+    printf("\n Total APs found = %d\n", count);
+    return count;
+}
+
+int scan_demo2(WiFiInterface *wifi)
+{
+    WiFiAccessPoint *ap;
+
+    printf("Scan:\n");
+
+    //int count = wifi->scan(NULL,0);
+    int count;
+    count = getAPcount(wifi);
+    if (count <= 0) {
+        printf("scan() failed with return value: %d\n", count);
+        return 0;
+    }
+
+    /* Limit number of network arbitrary to 15 */
+    count = count < 15 ? count : 15;
+
+    ap = new WiFiAccessPoint[count];
+    //count = wifi->scan(ap, count);
+    count = getAPdetails(ap, wifi, count);
+
+    if (count <= 0) {
+        printf("scan() failed with return value: %d\n", count);
+        return 0;
+    }
+
+    for (int i = 0; i < count; i++) {
+        printf("Network: %s secured: %s BSSID: %hhX:%hhX:%hhX:%hhx:%hhx:%hhx RSSI: %hhd Ch: %hhd\n", ap[i].get_ssid(),
+               sec2str(ap[i].get_security()), ap[i].get_bssid()[0], ap[i].get_bssid()[1], ap[i].get_bssid()[2],
+               ap[i].get_bssid()[3], ap[i].get_bssid()[4], ap[i].get_bssid()[5], ap[i].get_rssi(), ap[i].get_channel());
+    }
+    printf("%d networks available.\n", count);
+
+    delete[] ap;
+    return count;
+}
+
 
 int scan_demo(WiFiInterface *wifi)
 {
@@ -62,6 +130,7 @@
 }
 
 
+
 /**
  * Connect to the network using the default networking interface,
  * you can also swap this out with a driver for a different networking interface
@@ -79,20 +148,35 @@
         printf("ERROR: No WiFiInterface found.\n");
         return NULL;
     }
+    nsapi_error_t error;
+    
+    error = network->set_blocking(false);
+    printf("Wifi Interface set to Non-Blocking .\n");
+    printf("Waiting for 30 seconds before starting scan...\n");
+    for(int i=0;i<30;i++){
+        printf("%d", i);
+        wait(1);
+    }
     int count;
     count = scan_demo(network);
+    //count = scan_demo2(network);
     if (count == 0) {
         printf("No WIFI APNs found - can't continue further.\n");
         return NULL;
     }
 
-    //printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID);
+    printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID);
     //ret = network->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
     //if (ret != 0) {
     //    printf("\nConnection error: %d\n", ret);
     //    return -1;
     //}
 #endif
+    printf("Waiting for 30 seconds before connecting...\n");
+    for(int i=0;i<30;i++){
+        printf("%d", i);
+        wait(1);
+    }
 
     //nsapi_error_t connect_status = network->connect();
     nsapi_error_t connect_status = network->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD, NSAPI_SECURITY_WPA_WPA2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/wifi_demo.cpp	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,236 @@
+
+#include "wifi_demo.h"
+#include "common_config.h"
+// Wifi-demo
+
+RawSerial *device; // tx, rx
+extern EventQueue eventQueue(/* event count */ 20 * EVENTS_EVENT_SIZE);
+int chunkNum;
+void dump_response(HttpResponse* res) {
+    device->printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str());
+
+    device->printf("Headers:\n");
+    for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
+        device->printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
+    }
+    device->printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
+}
+
+void completed(){
+    }
+void dump_chunked_response(const char *at, uint32_t length) {
+    device->printf("\n Chunked response: Chunk %d : Total Bytes = %d\n", chunkNum , length);
+    //device->printf("\n Try Print Header as string:\n\n ");
+    //device->printf("recv %d [%.*s]\n", length, strstr((char *)at, "\r\n")-(char *)at, (char *)at);
+    //if(false)
+    if(chunkNum < 2)
+    for(int i=0; i < length; i++){
+        
+        while(device->writeable())
+        {
+            device->putc((uint8_t)at[i]);
+        }
+        //int resp = write( (const uint8_t *)at, (int) length, &completed, SERIAL_EVENT_TX_COMPLETE);
+    }
+    if(false)
+    for (size_t ix = 0; ix < length; ix++) {
+        device->printf("%02X: ", at[ix]);
+        if((ix % 32) == 0 and ix)
+        device->printf("\n");
+    }
+    device->printf("\n\n");
+    chunkNum++;
+    //device->printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
+}
+
+
+int wifi_demo_func(NetworkInterface* network){
+    device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
+    if (!network) {
+        device->printf("Cannot connect to the network, see serial output\n");
+        return 1;
+    }
+    wait(1); // wait for 1 sec 
+
+    mbed_trace_init();
+    wait(1); // wait for 1 sec 
+
+    // GET request to os.mbed.com
+    {
+        chunkNum = 0;
+        device->printf("\n----- HTTPS GET request -----\n");
+
+        HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt", &dump_chunked_response);
+
+        HttpResponse* get_res = get_req->send();
+        if (!get_res) {
+            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
+            return 1;
+        }
+        device->printf("\n----- HTTPS GET response -----\n");
+        dump_response(get_res);
+        delete get_req;
+    }
+    
+    wait(1); // wait for 1 sec 
+    
+     // Do a GET request to httpbin.org
+    {
+        chunkNum = 0;
+        device->printf("\n----- HTTP GET request to httpbin.org  -----\n");
+
+        // By default the body is automatically parsed and stored in a buffer, this is memory heavy.
+        // To receive chunked response, pass in a callback as last parameter to the constructor.
+        HttpRequest* get_req = new HttpRequest(network, HTTP_GET, "http://httpbin.org/status/418");
+
+        HttpResponse* get_res = get_req->send();
+        if (!get_res) {
+            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
+            return 1;
+        }
+
+        device->printf("\n----- HTTP GET response from httpbin.org -----\n");
+        dump_response(get_res);
+
+        delete get_req;
+    }
+
+    wait(1); // wait for 1 sec 
+    
+    
+    // Do a GET request to ovh.net
+    if(false)
+    {
+       chunkNum = 0;
+       device->printf("\n----- HTTP GET request to ovh.net  (LARGE FILE) http://www.ovh.net/files/1Mio.dat -----\n");
+        Timer t;
+        // By default the body is automatically parsed and stored in a buffer, this is memory heavy.
+        // To receive chunked response, pass in a callback as last parameter to the constructor.
+        t.start();
+        HttpRequest* get_req = new HttpRequest(network, HTTP_GET, "http://www.ovh.net/files/1Mio.dat", &dump_chunked_response);
+
+        HttpResponse* get_res = get_req->send();
+        if (!get_res) {
+            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
+            return 1;
+        }
+
+        device->printf("\n----- HTTP GET response from ovh.net -----\n");
+        dump_response(get_res);
+        t.stop();
+        device->printf("The time taken was %f seconds\n", t.read());
+
+
+        delete get_req;
+    }
+     wait(1); // wait for 1 sec 
+   
+    {
+        device->printf("\n----- HTTPS GET request (small file!) -----\n");
+
+        HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt");
+
+        HttpResponse* get_res = get_req->send();
+        if (!get_res) {
+            device->printf("HttpRequest failed (error code %d)\n", get_req->get_error());
+            return 1;
+        }
+        /*
+        while (0 < (response = socket.recv(p, remaining))) {
+            p += response;
+            rcount += response;
+            remaining -= response;
+        }
+        */
+        device->printf("\n----- HTTPS GET response -----\n");
+        dump_response(get_res);
+
+
+
+        delete get_req;
+    }
+    wait(1); // wait for 1 sec 
+
+    // POST request to httpbin.org
+    {
+        device->printf("\n----- HTTPS POST request -----\n");
+
+        HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://httpbin.org/post");
+        post_req->set_header("Content-Type", "application/json");
+
+        const char body[] = "{\"hello\":\"world\"}";
+
+        HttpResponse* post_res = post_req->send(body, strlen(body));
+        if (!post_res) {
+            device->printf("HttpRequest failed (error code %d)\n", post_req->get_error());
+            return 1;
+        }
+
+        device->printf("\n----- HTTPS POST response -----\n");
+        dump_response(post_res);
+
+        delete post_req;
+    }
+
+    wait(1); // wait for 1 sec 
+
+    // POST request to ws.dnanudge.io:80
+    {
+        device->printf("\n----- HTTP POST request (http://ws.dnanudge.io/nudgebox/v1) -----\n");
+
+        HttpRequest* post_req = new HttpRequest(network, HTTP_POST, "http://ws.dnanudge.io/nudgebox/v1");
+        post_req->set_header("Host", "ws.dnanudge.io");
+        post_req->set_header("Accept", "*/*");
+        post_req->set_header("Content-Type", "application/octet-stream");
+        post_req->set_header("Content-Length", "20");
+                               // 00    08    6a    48    f8    2d    8e    82    01    68
+        const uint8_t body[] = {0x00, 0x08, 0x6a, 0x48, 0xf8, 0x2d, 0x8e, 0x82, 0x01, 0x68, 
+                               // 65    6c    6c    6f    00    00    67    c3    19    f8
+                                0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x00, 0x67, 0xc3, 0x19, 0xf8};
+
+        HttpResponse* post_res = post_req->send(body, 20);
+        if (!post_res) {
+            device->printf("HttpRequest failed (error code %d)\n", post_req->get_error());
+            return 1;
+        }
+
+        device->printf("\n----- HTTPS POST response -----\n");
+        dump_response(post_res);
+
+        delete post_req;
+    }
+
+    wait(1); // wait for 1 sec 
+
+    // POST request to httpbin.org
+    if(false)
+    {
+        device->printf("\n----- HTTPS POST request to AWS -----\n");
+
+        HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://q6bc0dxw7f.execute-api.eu-west-2.amazonaws.com/test/samples/v1");
+        post_req->set_header("Content-Type", "application/json");
+
+        const char body[] = 
+                            "{"
+                            "\"firstName\": \"Maria\", "
+                            "\"lastName\": \"Huntera\", "
+                            "\"dob\": \"1970-12-03\", "
+                            "\"mobile\": \"07841887580\", "
+                            "\"cartridgeId\": \"DN00000000RMPOE\", "
+                            "\"labSampleId\": \"DYYAK\""
+                            "}";
+        HttpResponse* post_res = post_req->send(body, strlen(body));
+        if (!post_res) {
+            device->printf("HttpRequest failed (error code %d)\n", post_req->get_error());
+            return 1;
+        }
+
+        device->printf("\n----- HTTPS POST response from AWS -----\n");
+        dump_response(post_res);
+
+        delete post_req;
+    }
+     wait(1); // wait for 1 sec 
+     delete device;
+     return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/wifi_demo.h	Sun Mar 10 09:46:06 2019 +0000
@@ -0,0 +1,20 @@
+#ifndef __WIFI_DEMO_H__
+#define __WIFI_DEMO_H__
+
+#ifndef __MBED_H__
+#define __MBED_H__
+#include "mbed.h"
+#endif
+
+#include "mbed_trace.h"
+#include "https_request.h"
+#include "http_request.h"
+/* List of trusted root CA certificates
+ * currently two: GlobalSign, the CA for os.mbed.com and Let's Encrypt, the CA for httpbin.org
+ *
+ * To add more root certificates, just concatenate them.
+ */
+#include "https_certificates.h"
+int wifi_demo_func(NetworkInterface* network);
+
+#endif // __WIFI_DEMO_H__
\ No newline at end of file