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:
Thu Mar 14 21:34:06 2019 +0000
Parent:
74:f26e846adfe9
Child:
76:6afda865fbf8
Commit message:
Ble Security example now working!

Changed in this revision

mbed_app.json Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_CORDIO_BLUENRG.lib 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/Bounded.h Show annotated file Show diff for this revision Revisions of this file
source/Duration.h Show annotated file Show diff for this revision Revisions of this file
source/Types.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/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/pretty_printer.h Show annotated file Show diff for this revision Revisions of this file
--- a/mbed_app.json	Sun Mar 10 09:46:06 2019 +0000
+++ b/mbed_app.json	Thu Mar 14 21:34:06 2019 +0000
@@ -37,6 +37,10 @@
             "nsapi.default-wifi-security": "WPA_WPA2",
             "nsapi.default-wifi-ssid": "\"VM9109107_5GEXT\"",
             "nsapi.default-wifi-password": "\"Bonga01shop02\""
-      }
+      },
+        "MTB_UBLOX_ODIN_W2": {
+            "target.features_add": ["BLE"],
+            "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"]
+        }
      }
 }
--- a/shields/TARGET_CORDIO_BLUENRG.lib	Sun Mar 10 09:46:06 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#51f60dfea514e35e5aa13c8e24005ecadc24a9f5
--- a/source/ATCmdManager.cpp	Sun Mar 10 09:46:06 2019 +0000
+++ b/source/ATCmdManager.cpp	Thu Mar 14 21:34:06 2019 +0000
@@ -11,8 +11,23 @@
     _serial.set_baud(DEFAULT_BAUD_RATE);
     _parser.debug_on(debug);
     _parser.set_delimiter("\r\n");
-    _parser.oob("ATE0", callback(this, &ATCmdManager::_oob_startup_hdlr));
+    _parser.send("+STARTUP");
+    _parser.oob("ATE0", callback(this, &ATCmdManager::_oob_echo_off));
+    _parser.oob("ATE1", callback(this, &ATCmdManager::_oob_echo_on));
+    _parser.oob("AT+UMRS", callback(this, &ATCmdManager::_oob_uart_setup));
+    
+    _parser.oob("ATO", callback(this, &ATCmdManager::_oob_data_mode));
+    _parser.oob("AT+UMLA", callback(this, &ATCmdManager::_oob_get_mac_addr));
+    _parser.oob("AT+UBTLE?", callback(this, &ATCmdManager::_oob_get_ble_role));
+    _parser.oob("AT+UBTLE=2", callback(this, &ATCmdManager::_oob_ena_ble_peri));
+    _parser.oob("AT+CPWROFF", callback(this, &ATCmdManager::_oob_reboot));
+    _parser.oob("AT+CGMR", callback(this, &ATCmdManager::_oob_get_fw_ver));
+    
+
+    //_parser.oob("ATE0", callback(this, &ATCmdManager::_oob_startup_hdlr));
     printf("\n --- ATCmdManager constructor completed ---\n");
+    
+    //AT+UMRS=230400,2,8,1,1,1
     // AT+UBTLE
 }
 
@@ -56,8 +71,122 @@
 void ATCmdManager::_oob_err(){
 }
 
+void ATCmdManager::_oob_uart_setup(){
+    int uOpts[NUM_UART_OPTIONS];
+    //if(_parser.recv("=%d,%d,%d,%d,%d,%d", &uOpts[0], &uOpts[1], &uOpts[2], &uOpts[3], &uOpts[4], &uOpts[5])) {
+    if(_parser.scanf("=%d,%d,%d,%d,%d,%d", &uOpts[0], &uOpts[1], &uOpts[2], &uOpts[3], &uOpts[4], &uOpts[5]) >0) {
+        printf("\nATCmdParser: Uart Options=%d,%d,%d,%d,%d,%d\n", uOpts[0], uOpts[1], uOpts[2], uOpts[3], uOpts[4], uOpts[5]);
+    } else {
+        printf("\nATCmdParser: Retrieving Uart Options failed");
+    }
+}
+
 void ATCmdManager::set_timeout(uint32_t timeout_ms)
 {
     _parser.set_timeout(timeout_ms);
 }
 
+
+void ATCmdManager::_oob_echo_off()
+{
+    _smutex.lock();
+    printf("\n Received ATEO OOB command!!\n");
+    printf("\n turning echo OFF!!\n");
+    _parser.debug_on(false);
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
+
+void ATCmdManager::_oob_echo_on()
+{
+    _smutex.lock();
+    printf("\n Received ATE1 OOB command!!\n");
+    printf("\n turning echo ON!!\n");
+    _parser.debug_on(true);
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
+
+void ATCmdManager::_oob_data_mode(){
+    int dataMode;
+    _smutex.lock();
+    printf("\n Received EDM mode command!!\n");
+    if(_parser.scanf("%d", &dataMode) >0) {
+        printf("\nATCmdParser: Data mode=%d\n", dataMode);
+        switch(dataMode)
+        {
+            case 0:
+                printf("\nATCmdParser: Command Mode request received");
+                break;
+            case 1:
+                printf("\nATCmdParser: Data Mode request received");
+                break;
+            case 2:
+                printf("\nATCmdParser: Extended data Mode request received");
+                break;
+            default:
+                printf("\nATCmdParser: ERROR - UNKNOWN DATA MODE RECEIVED!!! \n");
+                break;
+        }
+    } else {
+        printf("\nATCmdParser: Retrieving Uart Options failed");
+    }
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
+void ATCmdManager::_oob_get_mac_addr(){
+    int bleOrWifi;
+    _smutex.lock();
+    if(_parser.scanf("=%d", &bleOrWifi) >0) {
+        switch(bleOrWifi)
+        {
+            case 1:
+                printf("\nATCmdParser: BLE MAC Address request received");
+                break;
+            case 2:
+                printf("\nATCmdParser: WiFi MAC Address request received");
+                break;
+            default:
+                printf("\nATCmdParser: ERROR - UNKNOWN MAC ADDRESS REQUEST RECEIVED!!! \n");
+                break;
+        }
+    } else {
+        printf("\nATCmdParser: Retrieving Uart Options failed");
+    }
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
+void ATCmdManager::_oob_get_ble_role(){
+    _smutex.lock();
+    printf("\n Received get BLE role command!!\n");
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
+void ATCmdManager::_oob_ena_ble_peri(){
+    _smutex.lock();
+    printf("\n Received enable BLE Peripheral command!!\n");
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
+void ATCmdManager::_oob_reboot(){
+    _smutex.lock();
+    printf("\n Received reboot command!!\n");
+    _parser.send("OK\n");
+    _parser.send("System Resetting....\n");
+    system_reset();
+    _smutex.unlock();
+}
+
+void ATCmdManager::_oob_get_fw_ver(){
+    _smutex.lock();
+    printf("\n Received Firmware Version command!!\n");
+    _parser.send("OK\n");
+    _smutex.unlock();
+}
+
--- a/source/ATCmdManager.h	Sun Mar 10 09:46:06 2019 +0000
+++ b/source/ATCmdManager.h	Thu Mar 14 21:34:06 2019 +0000
@@ -3,7 +3,8 @@
 #include <mbed.h>
 #include "ATCmdParser.h"
 
-#define MAIN_LOOP_WAIT_TIME_MS 10 // milliseconds
+#define MAIN_LOOP_WAIT_TIME_MS 1000 // milliseconds
+#define NUM_UART_OPTIONS       6
 #ifndef UBLOX_ODIN_W2_MISC_TIMEOUT
 #define UBLOX_ODIN_W2_MISC_TIMEOUT    2000
 #endif
@@ -33,6 +34,15 @@
     void _oob_wifiMode_err();
     void _oob_conn_already();
     void _oob_err();
+    void _oob_echo_off();
+    void _oob_uart_setup();
+    void _oob_echo_on();
+    void _oob_data_mode();
+    void _oob_get_mac_addr();
+    void _oob_get_ble_role();
+    void _oob_ena_ble_peri();
+    void _oob_reboot();
+    void _oob_get_fw_ver();
     
     /**
     * Allows timeout to be changed between commands
--- a/source/BleManager.cpp	Sun Mar 10 09:46:06 2019 +0000
+++ b/source/BleManager.cpp	Thu Mar 14 21:34:06 2019 +0000
@@ -13,11 +13,515 @@
  * 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 "BleManager.h"
+#if MBED_CONF_APP_FILESYSTEM_SUPPORT
+#include "LittleFileSystem.h"
+#include "HeapBlockDevice.h"
+#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
+
+
+static const uint8_t DEVICE_NAME[] = "SM_device";
+
+/** 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 uint8_t DEVICE_NAME[] = "SM_device";
+
+/* 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.
+ */
+SMDevice::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) { }
+
+SMDevice::~SMDevice()
+{
+    if (_ble.hasInitialized()) {
+        _ble.shutdown();
+    }
+}
+
+/** Start BLE interface initialisation */
+void SMDevice::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 timeouts, for example when connection attempts fail */
+    _ble.gap().onTimeout(
+        makeFunctionPointer(this, &SMDevice::on_timeout)
+    );
+
+    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();
+}
+
+/* event handler functions */
+
+/** 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 */
+void SMDevice::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. */
+void SMDevice::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 */
+void SMDevice::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(),
+        &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION
+    );
+}
+
+/** Override to start chosen activity when initialisation completes */
+//void SMDevice::start() = 0;
+
+/** This is called when BLE interface is initialised and starts the demonstration */
+void SMDevice::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);
+
+    /* print device address */
+    Gap::AddressType_t addr_type;
+    Gap::Address_t addr;
+    _ble.gap().getAddress(&addr_type, addr);
+    printf("Device address: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+           addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+
+    /* when scanning we want to connect to a peer device so we need to
+     * attach callbacks that are used by Gap to notify us of events */
+    _ble.gap().onConnection(this, &SMDevice::on_connect);
+    _ble.gap().onDisconnection(this, &SMDevice::on_disconnect);
+
+    /* start test in 500 ms */
+    _event_queue.call_in(500, this, &SMDevice::start);
+}
+
+/** This is called by Gap to notify the application we connected */
+//void SMDevice::on_connect(const Gap::ConnectionCallbackParams_t *connection_event);
+
+/** This is called by Gap to notify the application we disconnected,
+ *  in our case it ends the demonstration. */
+void SMDevice::on_disconnect(const Gap::DisconnectionCallbackParams_t *event)
+{
+    printf("Disconnected\r\n");
+    _event_queue.break_dispatch();
+}
+
+/** End demonstration unexpectedly. Called if timeout is reached during advertising,
+ * scanning or connection initiation */
+void SMDevice::on_timeout(const Gap::TimeoutSource_t source)
+{
+    printf("Unexpected timeout - aborting\r\n");
+    _event_queue.break_dispatch();
+}
+
+/** Schedule processing of events from the BLE in the event queue. */
+void SMDevice::schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context)
+{
+    _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents));
+};
+
+/** Blink LED to show we're running */
+void SMDevice::blink(void)
+{
+    _led1 = !_led1;
+}
+
+
+/** 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)
+        : SMDevice(ble, event_queue, peer_address) { }
+
+void SMDevicePeripheral::start()
+{
+    /* Set up and start advertising */
+
+    ble_error_t error;
+    GapAdvertisingData advertising_data;
+
+    /* add advertising flags */
+    advertising_data.addFlags(GapAdvertisingData::LE_GENERAL_DISCOVERABLE
+                              | GapAdvertisingData::BREDR_NOT_SUPPORTED);
+
+    /* add device name */
+    advertising_data.addData(
+        GapAdvertisingData::COMPLETE_LOCAL_NAME,
+        DEVICE_NAME,
+        sizeof(DEVICE_NAME)
+    );
+
+    error = _ble.gap().setAdvertisingPayload(advertising_data);
+
+    if (error) {
+        printf("Error during Gap::setAdvertisingPayload\r\n");
+        return;
+    }
+
+    /* advertise to everyone */
+    _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    /* how many milliseconds between advertisements, lower interval
+     * increases the chances of being seen at the cost of more power */
+    _ble.gap().setAdvertisingInterval(20);
+    _ble.gap().setAdvertisingTimeout(0);
+
+    error = _ble.gap().startAdvertising();
+
+    if (error) {
+        printf("Error during Gap::startAdvertising.\r\n");
+        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 */
+void SMDevicePeripheral::on_connect(const Gap::ConnectionCallbackParams_t *connection_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, connection_event->peerAddr, sizeof(_peer_address));
+
+    printf("Connected to: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+            _peer_address[5], _peer_address[4], _peer_address[3],
+            _peer_address[2], _peer_address[1], _peer_address[0]);
+
+    /* store the handle for future Security Manager requests */
+    _handle = connection_event->handle;
+
+    /* 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. */
+
+SMDeviceCentral::SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
+    : SMDevice(ble, event_queue, peer_address) { };
+
+void SMDeviceCentral::start()
+{
+    /* start scanning and attach a callback that will handle advertisements
+     * and scan requests responses */
+    ble_error_t error = _ble.gap().startScan(this, &SMDeviceCentral::on_scan);
+
+    printf("Please advertise\r\n");
+
+    printf("Scanning for: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+           _peer_address[5], _peer_address[4], _peer_address[3],
+           _peer_address[2], _peer_address[1], _peer_address[0]);
+
+    if (error) {
+        printf("Error during Gap::startScan %d\r\n", error);
+        return;
+    }
+}
+
+/** Look at scan payload to find a peer device and connect to it */
+void SMDeviceCentral::on_scan(const Gap::AdvertisementCallbackParams_t *params)
+{
+    /* don't bother with analysing scan result if we're already connecting */
+    if (_is_connecting) {
+        return;
+    }
+
+    /* connect to the same device that connected to us */
+    if (memcmp(params->peerAddr, _peer_address, sizeof(_peer_address)) == 0) {
+
+        ble_error_t error = _ble.gap().connect(
+            params->peerAddr, params->peerAddrType,
+            NULL, NULL
+        );
+
+        if (error) {
+            printf("Error during Gap::connect %d\r\n", error);
+            return;
+        }
+
+        printf("Connecting... ");
+
+        /* 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 */
+void SMDeviceCentral::on_connect(const Gap::ConnectionCallbackParams_t *connection_event)
+{
+    ble_error_t error;
+
+    /* store the handle for future Security Manager requests */
+    _handle = connection_event->handle;
+
+    /* in this example the local device is the master so we request pairing */
+    error = _ble.securityManager().requestPairing(_handle);
+
+    printf("Connected\r\n");
+
+    if (error) {
+        printf("Error during SM::requestPairing %d\r\n", error);
+        return;
+    }
+
+    /* upon pairing success the application will disconnect */
+}
+
+
+
+#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
+#ifdef BLE_SECURITY_MAIN
+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
+
+#ifdef OLD_BLE_SECURITY
+/* 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 "ble/Gap.h"
+#include "Types.h"
+#include "ble/services/UARTService.h"
+
+//#include "ble/gap/Types.h"
+#include "SecurityManager.h"
 #include "pretty_printer.h"
 
 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
@@ -42,8 +546,10 @@
 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;
+//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;
+//typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t);
+//const static (Gap::*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
@@ -58,7 +564,7 @@
  */
 class SMDevice : private mbed::NonCopyable<SMDevice>,
                  public SecurityManager::EventHandler,
-                 public ble::Gap::EventHandler
+                 public Gap::EventHandler
 {
 public:
     SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) :
@@ -244,31 +750,37 @@
         _event_queue.call_in(
             2000,
             &_ble.gap(),
-            disconnect_call,
+            &Gap::disconnect, //disconnect_call,
             _handle,
-            ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION)
+             (Gap::DisconnectionReason_t)0x13
+             //Gap::DisconnectionReason_t::REMOTE_USER_TERMINATED_CONNECTION)
+            //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 &)
+    //virtual void onDisconnectionComplete(const Gap::DisconnectionCompleteEvent &)
+    virtual void onDisconnectionComplete(const Gap::DisconnectionCallbackParams_t *params)
     {
-        printf("Diconnected\r\n");
+        printf("Disconnected\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 onAdvertisingEnd(const ble::AdvertisingEndEvent &)
+    //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();
-    }
+    //virtual void onScanTimeout(const ble::ScanTimeoutEvent &)
+    //{
+    //    printf("Scan timed out - aborting\r\n");
+    //    _event_queue.break_dispatch();
+    //}
 
 private:
     DigitalOut _led1;
@@ -291,10 +803,12 @@
     virtual void start()
     {
         /* Set up and start advertising */
-        uint8_t adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
+#ifdef NEW_BLE5_API        
+        //uint8_t adv_buffer[Gap::LEGACY_ADVERTISING_MAX_SIZE];
+        uint8_t adv_buffer[32];
         /* use the helper to build the payload */
-        ble::AdvertisingDataBuilder adv_data_builder(
-            adv_buffer
+        ble::Gap::AdvertisingDataBuilder adv_data_builder(
+            adv_buffer, 32
         );
 
         adv_data_builder.setFlags();
@@ -312,7 +826,7 @@
             return;
         }
 
-        ble::AdvertisingParameters adv_parameters(
+        ble::gap::AdvertisingParameters adv_parameters(
             ble::advertising_type_t::CONNECTABLE_UNDIRECTED
         );
 
@@ -332,7 +846,19 @@
             print_error(error, "Gap::startAdvertising() failed");
             return;
         }
+#else
+    /* 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().setAdvertisingTimeout(300); /* 16 * 1000ms. */
+    _ble.gap().startAdvertising();
 
+#endif
         printf("Please connect to device\r\n");
 
         /** This tells the stack to generate a pairingRequest event
@@ -344,18 +870,19 @@
 
     /** 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)
+    //virtual void onConnectionComplete(const ble::ConnectionCompleteEvent_t &event)
+    virtual void onConnectionComplete(const Gap::ConnectionCallbackParams_t &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));
+        memcpy(_peer_address, event.peerAddr, 6);
 
         printf("Connected to peer: ");
-        print_address(event.getPeerAddress().data());
+        print_address(event.peerAddr);
 
-        _handle = event.getConnectionHandle();
+        _handle = event.handle;
 
         /* Request a change in link security. This will be done
          * indirectly by asking the master of the connection to
@@ -408,7 +935,7 @@
     /* Gap::EventHandler */
 
     /** Look at scan payload to find a peer device and connect to it */
-    virtual void onAdvertisingReport(const ble::AdvertisingReportEvent &event)
+    virtual void onAdvertisingReport(const Gap::AdvertisementCallbackParams_t &event)
     {
         /* don't bother with analysing scan result if we're already connecting */
         if (_is_connecting) {
@@ -416,7 +943,7 @@
         }
 
         /* parse the advertising payload, looking for a discoverable device */
-        if (memcmp(event.getPeerAddress().data(), _peer_address, sizeof(_peer_address)) == 0) {
+        if (memcmp(event.peerAddr, _peer_address, sizeof(_peer_address)) == 0) {
             ble_error_t error = _ble.gap().stopScan();
 
             if (error) {
@@ -457,7 +984,7 @@
 
     /** 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)
+    virtual void onConnectionComplete(const Gap::ConnectionCallbackParams_t &event)
     {
         if (event.getStatus() == BLE_ERROR_NONE) {
             /* store the handle for future Security Manager requests */
@@ -523,7 +1050,7 @@
     return true;
 }
 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
-
+#ifdef BLE_MAIN
 int main()
 {
     BLE& ble = BLE::Instance();
@@ -554,4 +1081,6 @@
     return 0;
 }
 
+#endif
+
 #endif
\ No newline at end of file
--- a/source/BleManager.h	Sun Mar 10 09:46:06 2019 +0000
+++ b/source/BleManager.h	Thu Mar 14 21:34:06 2019 +0000
@@ -1,3 +1,153 @@
-#ifdndef __BLE_MANAGER_H__
+#ifndef __BLE_MANAGER_H__
 #define __BLE_MANAGER_H__
+
+
+/* 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.
+ */
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "ble/BLE.h"
+#include "SecurityManager.h"
+
+/** 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.
+ */
+
+
+/* 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:
+    SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address);
+
+    virtual ~SMDevice();
+
+    /** Start BLE interface initialisation */
+    void run();
+
+    /* event handler functions */
+
+    /** 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
+    );
+
+    /** Inform the application of a successful pairing. Terminate the demonstration. */
+    virtual void pairingResult(
+        ble::connection_handle_t connectionHandle,
+        SecurityManager::SecurityCompletionStatus_t result
+    );
+
+    /** 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
+    );
+
+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);
+
+    /** This is called by Gap to notify the application we connected */
+    virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) = 0;
+
+    /** This is called by Gap to notify the application we disconnected,
+     *  in our case it ends the demonstration. */
+    void on_disconnect(const Gap::DisconnectionCallbackParams_t *event);
+
+    /** End demonstration unexpectedly. Called if timeout is reached during advertising,
+     * scanning or connection initiation */
+    void on_timeout(const Gap::TimeoutSource_t source);
+
+    /** Schedule processing of events from the BLE in the event queue. */
+    void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context);
+
+    /** Blink LED to show we're running */
+    void blink(void);
+
+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);
+
+    virtual void start();
+
+    /** This is called by Gap to notify the application we connected,
+     *  in our case it immediately requests a change in link security */
+    virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event);
+};
+
+/** 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);
+
+    virtual void start();
+
+    /** Look at scan payload to find a peer device and connect to it */
+    void on_scan(const Gap::AdvertisementCallbackParams_t *params);
+
+    /** This is called by Gap to notify the application we connected,
+     *  in our case it immediately request pairing */
+    virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event);
+};
+
+
+#if MBED_CONF_APP_FILESYSTEM_SUPPORT
+bool create_filesystem();
+#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
+
 #endif // __BLE_MANAGER_H__
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/Bounded.h	Thu Mar 14 21:34:06 2019 +0000
@@ -0,0 +1,108 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef BLE_COMMON_BOUNDED_H_
+#define BLE_COMMON_BOUNDED_H_
+
+#include <stdint.h>
+
+namespace ble {
+
+/**
+ * Restrict values of an integer type to a defined range.
+ *
+ * The range is a closed interval that includes its left-bound (Min) and
+ * right-bound value (Max).
+ *
+ * @tparam Rep The C++ integer type used to represent the values.
+ * @tparam Min Minimum value allowed.
+ * @tparam Max Maximum value allowed.
+ */
+template<typename Rep, Rep Min, Rep Max>
+struct Bounded {
+    /**
+     * Construct a bounded integer.
+     *
+     * If v is out of the range [Min : Max], then if it is less than Min, the
+     * value of the bounded integer will be Min. If it greater than Max, then
+     * the value of the bounded integer will be Max.
+     *
+     * @param v The value to store.
+     */
+    Bounded(Rep v) : _value(v)
+    {
+        if (v < Min) {
+            _value = v;
+        } else if (v > Max) {
+            _value = v;
+        }
+    }
+
+    /**
+     * Access the inner value.
+     *
+     * @return The current value.
+     */
+    Rep value() const
+    {
+        return _value;
+    }
+
+    /**
+     * The left-bound value.
+     *
+     * @return The lowest value that this type can represent
+     */
+    static Rep min()
+    {
+        return Min;
+    }
+
+    /**
+     * The right-bound value.
+     *
+     * @return The highest value that this type can represent
+     */
+    static Rep max()
+    {
+        return Max;
+    }
+
+    /**
+     * The left-bound value.
+     */
+    static const Rep MIN = Min;
+
+    /**
+     * The right-bound value.
+     */
+    static const Rep MAX = Max;
+
+private:
+    Rep _value;
+};
+
+/* ---------------------- Static variable initialization -------------------- */
+
+template<typename T, T Min, T Max>
+const T Bounded<T, Min, Max>::MIN;
+
+template<typename T, T Min, T Max>
+const T Bounded<T, Min, Max>::MAX;
+
+} // namespace ble
+
+#endif //BLE_COMMON_BOUNDED_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/Duration.h	Thu Mar 14 21:34:06 2019 +0000
@@ -0,0 +1,578 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef BLE_COMMON_DURATION_H_
+#define BLE_COMMON_DURATION_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include "platform/mbed_assert.h"
+
+namespace ble {
+
+#if !defined(DOXYGEN_ONLY)
+
+/**
+ * Define a compile time range.
+ * @tparam Min left-bound
+ * @tparam Max right-bound
+ */
+template<uint32_t Min, uint32_t Max>
+struct Range {
+    static const uint32_t MIN = Min;
+    static const uint32_t MAX = Max;
+};
+
+/**
+ * Deduce default range for C++ basic integer types.
+ *
+ *
+ * @tparam Rep The C++ integer type.
+ */
+template<typename Rep>
+struct DefaultRange;
+
+/**
+ * DefaultRange specialization for uint8_t.
+ */
+template<>
+struct DefaultRange<uint8_t> {
+    typedef Range<0, 0xFF> type;
+};
+
+/**
+ * DefaultRange specialization for uint16_t.
+ */
+template<>
+struct DefaultRange<uint16_t > {
+    typedef Range<0, 0xFFFF> type;
+};
+
+/**
+ * DefaultRange specialization for uint32_t
+ */
+template<>
+struct DefaultRange<uint32_t> {
+    typedef Range<0, 0xFFFFFFFF> type;
+};
+
+/**
+ * Represent an integral compile time value that can be used in Duration.
+ *
+ * @tparam T Type of the integral value.
+ * @tparam V The integer value representing a never ending duration.
+ */
+template<typename T, T V>
+struct Value {
+    static const T VALUE = V;
+};
+
+#endif
+
+/**
+ * Model BLE durations.
+ *
+ * @tparam Rep The representation type of the duration.
+ * @tparam TB The time base in micro seconds.
+ * @tparam Range Closed interval of the duration
+ * @tparam Forever The special value (if applicable) that represents a forever
+ * duration.
+ */
+template<
+    typename Rep,
+    uint32_t TB,
+    typename Range = typename DefaultRange<Rep>::type,
+    typename Forever = void*
+>
+struct Duration {
+    /**
+     * Type of the actual representation.
+     */
+    typedef Rep representation_t;
+
+    /**
+     * Construct a default Duration.
+     *
+     * It is initialized with the minimum value acceptable.
+     */
+    Duration() : duration(Range::MIN)
+    {
+    }
+
+    /**
+     * Construct a Duration from an integer value.
+     *
+     * @param v The value of the duration in TIME_BASE units.
+     */
+    explicit Duration(Rep v) : duration(clamp(v))
+    {
+    }
+
+    /**
+     * Construct a Duration from another Duration.
+     *
+     * @note The operation fail at compile time if there is a loss of precision.
+     *
+     * @tparam OtherRep The type used to represent the other Duration.
+     * @tparam OtherTB The time base in micro seconds of the other Duration.
+     * @tparam OtherRange The range of the other Duration.
+     * @tparam OtherF The forever value of the other type.
+     *
+     * @param other The Duration used to construct this object.
+     */
+    template<typename OtherRep, uint32_t OtherTB, typename OtherRange, typename OtherF>
+    Duration(Duration<OtherRep, OtherTB, OtherRange, OtherF> other) :
+        duration(clamp(other.value() * (OtherTB / TB)))
+    {
+        MBED_STATIC_ASSERT(OtherTB >= TB && (OtherTB % TB) == 0, "Incompatible units");
+    }
+
+    /**
+     * Construct a new Duration from a Duration in milliseconds.
+     *
+     * @note The result of the conversion is rounded up.
+     *
+     * @tparam OtherRep The representation type used by other_ms.
+     * @tparam OtherRange The range used by other_ms.
+     * @tparam OtherF The forever value used by other_ms.
+     *
+     * @param other_ms The Duration in millisecond to convert.
+     */
+    template<typename OtherRep, typename OtherRange, typename OtherF>
+    explicit Duration(Duration<OtherRep, 1000, OtherRange, OtherF> other_ms, void* = NULL) :
+        duration(clamp(((other_ms.value() * 1000) + TB - 1) / TB))
+    {
+    }
+
+    /**
+     * Return the duration in TB units.
+     *
+     * @return The duration in TB units.
+     */
+    Rep value() const
+    {
+        return duration;
+    }
+
+    /**
+     * Return the duration in milliseconds.
+     *
+     * @return The duration in milliseconds.
+     */
+    uint32_t valueInMs() const
+    {
+        return ((uint32_t)duration * TB) / 1000;
+    }
+
+    /**
+     * The time base.
+     */
+    static const uint32_t TIME_BASE = TB;
+
+    /**
+     * Left-bound of the duration range.
+     */
+    static const Rep MIN = Range::MIN;
+
+    /**
+     * Right bound of the duration range.
+     */
+    static const Rep MAX = Range::MAX;
+
+    /**
+     * Return the minimum duration.
+     *
+     * @return The minimum duration.
+     */
+    static Duration min()
+    {
+        return Duration(MIN);
+    }
+
+    /**
+     * Return the maximum duration.
+     *
+     * @return The maximum duration.
+     */
+    static Duration max()
+    {
+        return Duration(MAX);
+    }
+
+    /**
+     * Return a pointer to the value of the duration.
+     *
+     * @return a pointer to the value of the duration.
+     */
+    const Rep* storage() const
+    {
+        return &duration;
+    }
+
+    /**
+     * Return the Duration value meaning forever.
+     * @return the Duration value meaning forever.
+     */
+    static Duration forever()
+    {
+        return Duration(Forever::VALUE);
+    }
+
+private:
+    static Rep clamp(Rep in)
+    {
+        if (in < MIN) {
+            return MIN;
+        } else if (in > MAX) {
+            return MAX;
+        } else {
+            return in;
+        }
+    }
+
+    Rep duration;
+};
+
+/**
+ * Type that represents micro seconds.
+ */
+typedef Duration<uint32_t, 1> microsecond_t;
+
+/**
+ * Type that represents milliseconds.
+ */
+typedef Duration<uint32_t, 1000 * microsecond_t::TIME_BASE> millisecond_t;
+
+/**
+ * Type that represents seconds.
+ */
+typedef Duration<uint32_t, 1000 * millisecond_t::TIME_BASE> second_t;
+
+/**
+ * Cast a duration to another.
+ *
+ * @tparam DurationOut Type of the Duration in output.
+ * @tparam RepIn The representation type of duration.
+ * @tparam TBIn The timebase of duration.
+ * @tparam RangeIn The range of duration.
+ * @tparam FIn The Forever value of duration.
+ * @param duration The duration to convert.
+ * @return The converted duration. It is rounded up if precision is lost.
+ *
+ * @related Duration
+ */
+template<typename DurationOut, typename RepIn, uint32_t TBIn, typename RangeIn, typename FIn>
+DurationOut durationCast(Duration<RepIn, TBIn, RangeIn, FIn> duration)
+{
+    return DurationOut(((duration.value() * TBIn) + DurationOut::TIME_BASE - 1) / DurationOut::TIME_BASE);
+}
+
+/**
+ * Add two durations together and return the result in microseconds.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return The result of the addition of the two durations in microseconds.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS>
+microsecond_t  operator+(
+    Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
+    Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
+)
+{
+    return microsecond_t((lhs.value() * lhs.TIME_BASE) + (rhs.value() * rhs.TIME_BASE));
+}
+
+/**
+ * Add two durations together.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return The addition of the two durations in input.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t TB, typename Range, typename F>
+Duration<Rep, TB, Range, F> operator+(
+    Duration<Rep, TB, Range, F> lhs,
+    Duration<Rep, TB, Range, F> rhs
+)
+{
+    return Duration<Rep, TB, Range, F>(lhs.value() + rhs.value());
+}
+
+/**
+ * Multiply a duration and a positive integer.
+ *
+ * @param lhs The duration.
+ * @param rhs The integer.
+ *
+ * @return A duration that represents the multiplication of lhs with rhs.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t TB, typename Range, typename F>
+Duration<Rep, TB, Range, F> operator*(Duration<Rep, TB, Range, F> lhs, uint32_t rhs)
+{
+    return Duration<Rep, TB, Range, F>(lhs.value() * rhs);
+}
+
+/**
+ * Multiply a duration and a positive integer.
+ *
+ * @param lhs The integer.
+ * @param rhs The multiplication.
+ *
+ * @return A duration that represents the multiplication of lhs with rhs.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t TB, typename Range, typename F>
+Duration<Rep, TB, Range, F> operator*(uint32_t lhs, Duration<Rep, TB, Range, F> rhs)
+{
+    return Duration<Rep, TB, Range, F>(lhs * rhs.value());
+}
+
+/**
+ * Indicate if the duration lhs is less than the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is less than rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
+>
+bool operator<(Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs)
+{
+    return lhs.value() * lhs.TIME_BASE < rhs.value() * rhs.TIME_BASE;
+}
+
+/**
+ * Indicate if the duration lhs is less than the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is less than rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t Us, typename Range, typename F>
+bool operator<(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
+{
+    return lhs.value() < rhs.value();
+}
+
+/**
+ * Indicate if the duration lhs is less than or equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is less than or equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
+>
+bool operator<=(
+    Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
+    Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
+)
+{
+    return lhs.value() * lhs.TIME_BASE <= rhs.value() * rhs.TIME_BASE;
+}
+
+/**
+ * Indicate if the duration lhs is less than or equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is less than or equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t Us, typename Range>
+bool operator<=(Duration<Rep, Us, Range> lhs, Duration<Rep, Us, Range> rhs)
+{
+    return lhs.value() <= rhs.value();
+}
+
+/**
+ * Indicate if the duration lhs is equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
+>
+bool operator==(
+    Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
+    Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
+)
+{
+    return lhs.value() * lhs.TIME_BASE == rhs.value() * rhs.TIME_BASE;
+}
+
+/**
+ * Indicate if the duration lhs is equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t Us, typename Range, typename F>
+bool operator==(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
+{
+    return lhs.value() == rhs.value();
+}
+
+/**
+ * Indicate if the duration lhs is not equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is not equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
+>
+bool operator!=(
+    Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
+    Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
+)
+{
+    return !(lhs == rhs);
+}
+
+/**
+ * Indicate if the duration lhs is not equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is not equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t Us, typename Range, typename F>
+bool operator!=(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
+{
+    return !(lhs == rhs);
+}
+
+/**
+ * Indicate if the duration lhs greater or equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is greater or equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
+>
+bool operator>=(
+    Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
+    Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
+)
+{
+    return rhs <= lhs;
+}
+
+/**
+ * Indicate if the duration lhs greater or equal to the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is greater or equal to rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t Us, typename Range, typename F>
+bool operator>=(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
+{
+    return rhs <= lhs;
+}
+
+/**
+ * Indicate if the duration lhs greater than the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is greater than rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<
+    typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
+    typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
+>
+bool operator>(
+    Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
+    Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
+)
+{
+    return rhs < lhs;
+}
+
+/**
+ * Indicate if the duration lhs greater than the duration rhs.
+ * @param lhs Left hand side operand.
+ * @param rhs Right hand side operand.
+ * @return true if lhs is greater than rhs and false otherwise.
+ *
+ * @related Duration
+ */
+template<typename Rep, uint32_t Us, typename Range, typename F>
+bool operator>(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
+{
+    return rhs < lhs;
+}
+
+/* ---------------------- Static variable initialization -------------------- */
+
+#if !defined(DOXYGEN_ONLY)
+
+template<uint32_t Min, uint32_t Max>
+const uint32_t Range<Min, Max>::MIN;
+
+template<uint32_t Min, uint32_t Max>
+const uint32_t Range<Min, Max>::MAX;
+
+template<typename T, T V>
+const T Value<T, V>::VALUE;
+
+#endif
+
+template<typename Rep, uint32_t TB, typename Range, typename Forever>
+const uint32_t Duration<Rep, TB, Range, Forever>::TIME_BASE;
+
+template<typename Rep, uint32_t TB, typename Range, typename Forever>
+const Rep Duration<Rep, TB, Range, Forever>::MIN;
+
+template<typename Rep, uint32_t TB, typename Range, typename Forever>
+const Rep Duration<Rep, TB, Range, Forever>::MAX;
+
+}
+
+#endif //BLE_COMMON_DURATION_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/Types.h	Thu Mar 14 21:34:06 2019 +0000
@@ -0,0 +1,965 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef BLE_GAP_TYPES_H
+#define BLE_GAP_TYPES_H
+
+#include "Duration.h"
+#include "Bounded.h"
+#include "ble/SafeEnum.h"
+
+namespace ble {
+
+/**
+ * @addtogroup ble
+ * @{
+ * @addtogroup gap
+ * @{
+ */
+
+/* BLE units, using microseconds as the common denominator */
+
+/**
+ * Time interval between two advertisements.
+ *
+ * The duration is in unit of 625µs and ranges from 0x20 to 0xFFFFFF .
+ *
+ * @note before Bluetooth 5 range was 0x20 to 0xFFFF.
+ */
+typedef Duration<uint32_t, 625, Range<0x20, 0xFFFFFF> > adv_interval_t;
+
+/**
+ * Advertising process duration.
+ *
+ * The duration is in unit of 10ms and ranges from 0x0001 to 0xFFFF. The special
+ * value 0x0000 means the advertising process never ends; it is accessible with
+ * adv_duration_t::forever().
+ */
+typedef Duration<uint16_t, 10000, Range<0x00, 0xFFFF>, /* forever */ Value<uint16_t, 0x0000> > adv_duration_t;
+
+/**
+ * Scan process duration.
+ *
+ * The duration is in unit of 10ms and ranges from 0x0001 to 0xFFFF. The special
+ * value 0x0000 means the scan process never ends; it is accessible with
+ * scan_duration_t::forever().
+ */
+typedef Duration<uint16_t, 10000, Range<0x00, 0xFFFF>, /* forever */ Value<uint16_t, 0x0000> > scan_duration_t;
+
+/**
+ * Time interval between two scan processes.
+ *
+ * The duration is in unit of 1.28s and ranges from 0x0001 to 0xFFFF. The special
+ * value 0x0000 is used to indicate that scan_period_t is not used.
+ */
+typedef Duration<uint16_t, 1280000, Range<0x00, 0xFFFF> > scan_period_t;
+
+/**
+ * Time interval between two scans.
+ *
+ * The duration is in unit of 625µs and ranges from 0x04 to 0xFFFF.
+ */
+typedef Duration<uint16_t, 625, Range<0x04, 0xFFFF> > scan_interval_t;
+
+/**
+ * Duration of a scan.
+ *
+ * The duration is in unit of 625µs and ranges from 0x04 to 0xFFFF.
+ */
+typedef Duration<uint16_t, 625, Range<0x04, 0xFFFF> > scan_window_t;
+
+/**
+ * Time interval between two connection events.
+ *
+ * The interval is in unit of 1.250 milliseconds and ranges from 0x06 to 0xC80.
+ */
+typedef Duration<uint16_t, 1250, Range<0x06, 0x0C80> > conn_interval_t;
+
+/**
+ * Time after which a connection is loss of devices have not exchanged data.
+ *
+ * The duration is in unit of 10 milliseconds and ranges from 0x0A to 0xC80.
+ *
+ * @note this time should be no larger than (1 + ConnLatency) * ConnIntervalMax * 2
+ */
+typedef Duration<uint16_t, 10000, Range<0x0A, 0x0C80> > supervision_timeout_t;
+
+/**
+ * Duration of a connection event.
+ *
+ * The duration is in unit of 625µs and ranges from 0x0 to 0xFFFF .
+ */
+typedef Duration<uint16_t, 625, Range<0, 0xFFFF> > conn_event_length_t;
+
+/**
+ * Time after which a periodic sync link is considered lost if the receiver hasn't
+ * received anything from the advertiser.
+ *
+ * The duration is in unit of 10 milliseconds and ranges from 0x0A to 0x4000.
+ */
+typedef Duration<uint16_t, 10000, Range<0x0A, 0x4000> > sync_timeout_t;
+
+/**
+ * Interval between two periodic advertising events.
+ *
+ * The duration is in unit of 1.250ms and ranges from 0x06 to 0xFFFF.
+ */
+typedef Duration<uint16_t, 1250, Range<0x06, 0xFFFF> > periodic_interval_t;
+
+/**
+ * Number of connection events that can be skipped by the slave.
+ *
+ * It ranges from 0 to 0x1F3.
+ */
+typedef Bounded<uint16_t, 0, 0x01F3> slave_latency_t;
+
+/**
+ * Handle of an advertising set.
+ *
+ * @note Range of valid handle is comprised between 0x00 and 0xEF.
+ */
+typedef uint8_t advertising_handle_t;
+
+/**
+ * Handle of a sync representing a periodic advertiser.
+ *
+ * @note Range of valid handle is comprised between 0x0000 and 0xFFFF.
+ */
+typedef uint16_t periodic_sync_handle_t;
+
+/**
+ * Encapsulates the peripheral advertising modes.
+ *
+ * It determines how the device appears to other scanner and peripheral
+ * devices in the scanning range.
+ */
+struct advertising_type_t : SafeEnum<advertising_type_t, uint8_t> {
+    /// enumeration of advertising_type_t values
+    enum type {
+        /**
+         * Device is connectable, scannable and doesn't expect connection from a
+         * specific peer.
+         *
+         * @see Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1.
+         */
+        CONNECTABLE_UNDIRECTED = 0x00,
+
+        /**
+         * Device is connectable and expects connection from a specific peer.
+         * (3.75 ms or smaller Advertising Interval)
+         * @see Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2.
+         */
+        CONNECTABLE_DIRECTED = 0x01,
+
+        /**
+         * Device is scannable but not connectable.
+         *
+         * @see Vol 6, Part B, Section 2.3.1.4.
+         */
+        SCANNABLE_UNDIRECTED = 0x02,
+
+        /**
+         * Device is not connectable and not scannable.
+         *
+         * @see Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3.
+         */
+        NON_CONNECTABLE_UNDIRECTED = 0x03,
+
+        /**
+         * Device is connectable and expects connection from a specific peer (sent at long user set intervals).
+         */
+        CONNECTABLE_DIRECTED_LOW_DUTY = 0x04,
+
+#if !defined(DOXYGEN_ONLY)
+        // used by the PAL; naming in line with the the spec.
+        ADV_IND = 0x00,
+        ADV_DIRECT_IND = 0x01,
+        ADV_SCAN_IND = 0x02,
+        ADV_NONCONN_IND = 0x03,
+        ADV_DIRECT_IND_LOW_DUTY_CYCLE = 0x04
+#endif
+    };
+
+    /**
+     * Construct a new advertising_type_t value.
+     *
+     * @param value The value of the advertising_type_t created.
+     */
+    advertising_type_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+
+/** Used to indicate if the packet is complete and if it's truncated.
+ */
+struct advertising_data_status_t : SafeEnum<advertising_data_status_t, uint8_t> {
+    /// enumeration of advertising_data_status_t values
+    enum type {
+        COMPLETE = 0x00, /// Advertising payload complete.
+        INCOMPLETE_MORE_DATA = 0x01, /// Partial advertising payload, more to come.
+        INCOMPLETE_DATA_TRUNCATED = 0x02 /// Advertising payload incomplete, and no more is coming.
+    };
+
+    /**
+     * Construct a new advertising_data_status_t value.
+     *
+     * @param value The value of the advertising_data_status_t created.
+     */
+    advertising_data_status_t(type value) : SafeEnum(value)
+    {
+    }
+
+#if !defined(DOXYGEN_ONLY)
+
+    /**
+     * Explicit constructor from a raw value.
+     */
+    explicit advertising_data_status_t(uint8_t raw_value) :
+        SafeEnum(raw_value)
+    {
+    }
+
+#endif
+
+};
+
+/** Properties of an advertising event.
+ */
+struct advertising_event_t {
+
+private:
+    // Implementation note: The object is constructed from the field Event_Type
+    // of an LE Extended Advertising.
+    // Indexes and functions of bits are defined in BLUETOOTH SPECIFICATION
+    // Version 5.0 | Vol 2, Part E -
+    // Section 7.7.65.13 LE Extended Advertising report Event
+    enum {
+        CONNECTABLE_BIT = 0,
+        SCANNABLE_ADVERTISING_BIT = 1,
+        DIRECTED_ADVERTISING_BIT = 2,
+        SCAN_RESPONSE_BIT = 3,
+        LEGACY_PDU_BIT = 4,
+        DATA_STATUS_INDEX = 5,
+        DATA_STATUS_MASK = 0x03
+    };
+
+public:
+
+#if !defined(DOXYGEN_ONLY)
+
+    /** Create based on a raw value.
+     *
+     * @param value
+     */
+    explicit advertising_event_t(uint8_t value) : value(value)
+    {
+    }
+
+#endif
+
+    /** Is advertising connectable.
+     *
+     * @return True if connectable.
+     */
+    bool connectable() const
+    {
+        return static_cast<bool>(value & (1 << CONNECTABLE_BIT));
+    }
+
+    /** Is advertising scannable.
+     *
+     * @return True if scannable
+     */
+    bool scannable_advertising() const
+    {
+        return static_cast<bool>(value & (1 << SCANNABLE_ADVERTISING_BIT));
+    }
+
+    /** Is advertising directed.
+     *
+     * @return True if directed.
+     */
+    bool directed_advertising() const
+    {
+        return static_cast<bool>(value & (1 << DIRECTED_ADVERTISING_BIT));
+    }
+
+    /** Is this a scan response.
+     *
+     * @return True if scan response.
+     */
+    bool scan_response() const
+    {
+        return static_cast<bool>(value & (1 << SCAN_RESPONSE_BIT));
+    }
+
+    /** Is this legacy advertising.
+     *
+     * @return True if legacy.
+     */
+    bool legacy_advertising() const
+    {
+        return static_cast<bool>(value & (1 << LEGACY_PDU_BIT));
+    }
+
+    /** Payload completeness status.
+     *
+     * @return @see advertising_data_status_t for details.
+     */
+    advertising_data_status_t data_status() const
+    {
+        return static_cast<advertising_data_status_t::type>(
+            (value >> DATA_STATUS_INDEX) & DATA_STATUS_MASK
+        );
+    }
+
+    /** Is payload complete.
+     *
+     * @return True if payload is coplete.
+     */
+    bool complete() const
+    {
+        return data_status() == advertising_data_status_t::COMPLETE;
+    }
+
+    /** Is there more data coming.
+     *
+     * @return True if more data coming.
+     */
+    bool more_data_to_come() const
+    {
+        return data_status() == advertising_data_status_t::INCOMPLETE_MORE_DATA;
+    }
+
+    /** Is the payload truncated.
+     *
+     * @return True if no more data coming.
+     */
+    bool truncated() const
+    {
+        return data_status() == advertising_data_status_t::INCOMPLETE_DATA_TRUNCATED;
+    }
+
+private:
+    uint8_t value;
+};
+
+/**
+ * Identify an advertising SID. Range: [0x00, 0x0F]
+ */
+typedef uint8_t advertising_sid_t;
+
+/** Received signal strength. Range <-127, 20>.
+ *  @note Special value 127 means RSSI is not available. */
+typedef int8_t rssi_t;
+
+/**
+ * Describe the advertising power.
+ *
+ * Values between -127 and +126 are considered power values in dBm while
+ * the special value 127 can be used as a wildcard to indicate that the host
+ * has no preference or if the power information is not available.
+ */
+typedef int8_t advertising_power_t;
+
+/**
+ * Advertising policy filter modes.
+ *
+ * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.2.
+ */
+struct advertising_filter_policy_t : SafeEnum<advertising_filter_policy_t, uint8_t> {
+    /// enumeration of advertising_filter_policy_t values
+    enum type {
+        /**
+         * Process connection and scan requests from all devices. The whitelist is
+         * not used.
+         */
+        NO_FILTER = 0x00,
+
+        /**
+         * Process connection requests from all devices but filter out scan requests
+         * of devices that are not in the whitelist.
+         */
+        FILTER_SCAN_REQUESTS = 0x01,
+
+        /**
+         * Process scan requests from all devices but filter out connection requests
+         * of devices that are not in the whitelist.
+         */
+        FILTER_CONNECTION_REQUEST = 0x02,
+
+        /**
+         * Filter out scan or connection requests of devices that are not in the
+         * whitelist.
+         */
+        FILTER_SCAN_AND_CONNECTION_REQUESTS = 0x03
+    };
+
+    /**
+     * Construct a advertising_filter_policy_t.
+     * @param value The value of the advertising_filter_policy_t created.
+     */
+    advertising_filter_policy_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Scanning policy filter mode.
+ *
+ * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
+ */
+struct scanning_filter_policy_t : SafeEnum<scanning_filter_policy_t, uint8_t> {
+    /// enumeration of scanning_filter_policy_t values
+    enum type {
+        /**
+        * Accept all advertising packets except directed advertising packets not
+        * addressed to this device.
+        */
+        NO_FILTER = 0x00,
+
+        /**
+        * Accept only advertising packets from devices in the whitelist except
+        * directed advertising packets not addressed to this device.
+        */
+        FILTER_ADVERTISING = 0x01,
+
+        /**
+         * Accept all advertising packets except directed advertising packets
+         * where the initiator's identity address does not address this device.
+         *
+         * @note Directed advertising packets where the initiator's address is a
+         * resolvable private address that cannot be resolved are also accepted.
+         */
+        NO_FILTER_INCLUDE_UNRESOLVABLE_DIRECTED = 2,
+
+        /**
+         * Accept all advertising packets except:
+         * - Advertising packets where the advertiser's
+         * identity address is not in the whitelist.
+         * - Directed advertising packets where the initiator's identity address
+         * does not address this device.
+         *
+         * @note Directed advertising packets where the initiator's address is a
+         * resolvable private address that cannot be resolved are also accepted.
+         */
+        FILTER_ADVERTISING_INCLUDE_UNRESOLVABLE_DIRECTED = 3
+    };
+
+    /**
+     * Construct a new instance of scanning_filter_policy_t.
+     *
+     * @param value The value of the scanning_filter_policy_t created.
+     */
+    scanning_filter_policy_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Filter policy that you can use during connection initiation.
+ */
+struct initiator_filter_policy_t : SafeEnum<initiator_filter_policy_t, uint8_t> {
+    /// enumeration of initiator_filter_policy_t values.
+    enum type {
+        /**
+        * The whitelist is not used to determine which advertiser to connect to.
+        */
+        NO_FILTER,
+
+        /**
+        * The whitelist is used to determine which advertiser to connect to.
+        */
+        USE_WHITE_LIST
+    };
+
+    /**
+     * Construct a initiator_filter_policy_t.
+     * @param value The value of the initiator_filter_policy_t.
+     */
+    initiator_filter_policy_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Scanning policy filter mode.
+ *
+ * @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
+ */
+struct duplicates_filter_t : SafeEnum<duplicates_filter_t, uint8_t> {
+    /// enumeration of duplicates_filter_t values
+    enum type {
+        /**
+         * Disable duplicate filtering.
+         */
+        DISABLE,
+
+        /**
+         * Enable duplicate filtering.
+         */
+        ENABLE,
+
+        /**
+         * Enable duplicate filtering, and reset the cache periodically.
+         */
+        PERIODIC_RESET
+    };
+
+    /**
+     * Construct a new duplicates_filter_t value.
+     * @param value The value of the duplicates_filter_t created.
+     */
+    duplicates_filter_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Type used to model the own address used during the following GAP operations:
+ * advertising, scanning and initiating
+ */
+struct own_address_type_t : SafeEnum<own_address_type_t, uint8_t> {
+    /// enumeration of own_address_type_t values.
+    enum type {
+        /**
+         * Use the public device address.
+         */
+        PUBLIC = 0x00,
+
+        /**
+         * Use the random device address.
+         */
+        RANDOM = 0x01,
+
+        /**
+         * Generated resolvable private address based on the local IRK from the
+         * resolving list. Use the public address if no entry match in the resolving
+         * list.
+         */
+        RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK = 0x02,
+
+        /**
+         * Generated resolvable private address based on the local IRK from the
+         * resolving list. Use the random address if no entry match in the resolving
+         * list.
+         */
+        RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK = 0x03,
+    };
+
+    /**
+     * Construct a new instance of own_address_type_t.
+     * @param value The value of the own_address_type_t created.
+     */
+    own_address_type_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Type of an address to connect to.
+ *
+ * It is used to connect to a device directly with directed advertising.
+ */
+struct target_peer_address_type_t : SafeEnum<target_peer_address_type_t, uint8_t> {
+    /// enumeration of target_peer_address_type_t values.
+    enum type {
+        PUBLIC = 0x00, /**< Public Device Address or Public Identity Address. */
+        RANDOM = 0x01, /**< Random Device Address or Random (static) Identity Address. */
+    };
+
+    /**
+     * Create a new target_peer_address_type_t.
+     * @param value The value of the target_peer_address_type_t created.
+     */
+    target_peer_address_type_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Accuracy of the master clock.
+ */
+struct clock_accuracy_t : SafeEnum<clock_accuracy_t, uint8_t> {
+    /// enumeration of clock_accuracy_t values.
+    enum type {
+        /**
+         * 500 PPM
+         */
+        PPM_500 = 0x00,
+
+        /**
+         * 250 PPM
+         */
+        PPM_250 = 0x01,
+
+        /**
+         * 150 PPM
+         */
+        PPM_150 = 0x02,
+
+        /**
+         * 100 PPM
+         */
+        PPM_100 = 0x03,
+
+        /**
+         * 75 PPM
+         */
+        PPM_75 = 0x04,
+
+        /**
+         * 50 PPM
+         */
+        PPM_50 = 0x05,
+
+        /**
+         * 30 PPM
+         */
+        PPM_30 = 0x06,
+
+        /**
+         * 20 PPM
+         */
+        PPM_20 = 0x07
+    };
+
+    /** Get clock accuracy.
+     *
+     * @return Parts per million as a number.
+     */
+    uint16_t get_ppm()
+    {
+        switch (value()) {
+            case PPM_500:
+                return 500;
+            case PPM_250:
+                return 250;
+            case PPM_150:
+                return 150;
+            case PPM_100:
+                return 100;
+            case PPM_75:
+                return 75;
+            case PPM_50:
+                return 50;
+            case PPM_30:
+                return 30;
+            case PPM_20:
+                return 20;
+            default:
+                return 0;
+        }
+    }
+
+    /**
+     * Construct a new clock_accuracy_t value.
+     * @param value The value of the clock_accuracy_t created.
+     */
+    clock_accuracy_t(type value) : SafeEnum(value)
+    {
+    }
+
+#if !defined(DOXYGEN_ONLY)
+
+    /**
+     * Construct a new clock_accuracy_t value from a raw value.
+     * @param raw_value The value of the clock accuracy.
+     */
+    explicit clock_accuracy_t(uint8_t raw_value) : SafeEnum(raw_value)
+    {
+    }
+
+#endif
+};
+
+/**
+ * Enumeration of GAP roles.
+ *
+ * @note The BLE API does not express the broadcaster and scanner roles.
+ *
+ * @attention A device can fulfill different roles concurrently.
+ */
+struct connection_role_t : SafeEnum<connection_role_t, uint8_t> {
+    /** struct scoped enum wrapped by the class */
+    enum type {
+        /**
+         * Central Role.
+         *
+         * The device can scan and initiate connection to peripherals. It
+         * acts as the master when a connection is established.
+         *
+         * @note A central is a scanner.
+         */
+        CENTRAL = 0x00,
+
+        /**
+         * Peripheral Role.
+         *
+         * The device can advertise, and you can connect it by a central. It
+         * acts as a slave when connected.
+         *
+         * @note A peripheral is a broadcaster.
+         */
+        PERIPHERAL = 0x01
+    };
+
+    /**
+     * Construct a new instance of role_t.
+     *
+     * @param value The value of the role_t created.
+     */
+    connection_role_t(type value) : SafeEnum(value)
+    {
+    }
+
+#if !defined(DOXYGEN_ONLY)
+
+    /**
+     * Explicit constructor from a raw value.
+     * @param raw_value The role.
+     */
+    explicit connection_role_t(uint8_t raw_value) : SafeEnum(raw_value)
+    {
+    }
+
+#endif
+};
+
+/**
+ * Enumeration of disconnection reasons that should be transmited to the peer.
+ */
+struct local_disconnection_reason_t : SafeEnum<local_disconnection_reason_t, uint8_t> {
+    /// enumeration of local_disconnection_reason_t values.
+    enum type {
+        /**
+         * GAP or GATT failed to authenticate the peer.
+         */
+        AUTHENTICATION_FAILURE = 0x05,
+
+        /**
+         * Connection terminated by the user.
+         */
+        USER_TERMINATION = 0x13,
+
+        /**
+         * Connection termination due to low resources.
+         */
+        LOW_RESOURCES = 0x14,
+
+        /**
+         * Connection termination due to power off.
+         */
+        POWER_OFF = 0x15,
+
+        /**
+         * Remote feature not supported.
+         */
+        UNSUPPORTED_REMOTE_FEATURE = 0x1A,
+
+        /**
+         * Not possible to pai with a unit key.
+         */
+        PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
+
+        /**
+         * Connection parameters were unacceptable.
+         */
+        UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
+    };
+
+    /**
+     * Construct a new instance of disconnection_reason_t.
+     *
+     * @param value The value of the local_disconnection_reason_t created.
+     */
+    local_disconnection_reason_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+
+/**
+ * Enumeration of disconnection reasons received in a disconnection event.
+ */
+struct disconnection_reason_t : SafeEnum<disconnection_reason_t, uint8_t> {
+    /// enumeration of disconnection_reason_t values.
+    enum type {
+        /**
+         * GAP or GATT failed to authenticate the peer.
+         */
+        AUTHENTICATION_FAILURE = 0x05,
+
+        /**
+         * The connection timed out.
+         */
+        CONNECTION_TIMEOUT = 0x08,
+
+        /**
+         * Connection terminated by the user.
+         */
+        REMOTE_USER_TERMINATED_CONNECTION = 0x13,
+
+        /**
+         * Remote device terminated connection due to low resources.
+         */
+        REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14,
+
+        /**
+         * Remote device terminated connection due to power off.
+         */
+        REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15,
+
+        /**
+         * Indicate that the local user or the internal
+         * Bluetooth subsystem terminated the connection.
+         */
+        LOCAL_HOST_TERMINATED_CONNECTION = 0x16,
+
+        /**
+         * Connection parameters were unacceptable.
+         */
+        UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
+    };
+
+    /**
+     * Construct a new instance of disconnection_reason_t.
+     *
+     * @param value The value of the disconnection_reason_t created.
+     */
+    disconnection_reason_t(type value) : SafeEnum(value)
+    {
+    }
+};
+
+/**
+ * Privacy Configuration of the peripheral role.
+ *
+ * @note This configuration also applies to the broadcaster role configuration.
+ */
+struct peripheral_privacy_configuration_t {
+    /**
+     * Indicates if nonresolvable random address should be used when the
+     * peripheral advertises nonconnectable packets.
+     *
+     * Resolvable random address continues to be used for connectable packets.
+     */
+    bool use_non_resolvable_random_address;
+
+    /**
+     * Resolution strategy for initiator resolvable addresses when a
+     * connection request is received.
+     */
+    enum resolution_strategy_t {
+        /**
+         * Do not resolve the address of the initiator and accept the
+         * connection request.
+         */
+        DO_NOT_RESOLVE,
+
+        /**
+         * If a bond is present in the secure database and the address
+         * resolution fails, then reject the connection request with the error
+         * code AUTHENTICATION_FAILLURE.
+         */
+        REJECT_NON_RESOLVED_ADDRESS,
+
+        /**
+         * Perform the pairing procedure if the initiator resolvable
+         * address failed the resolution process.
+         */
+        PERFORM_PAIRING_PROCEDURE,
+
+        /**
+         * Perform the authentication procedure if the initiator resolvable
+         * address failed the resolution process.
+         */
+        PERFORM_AUTHENTICATION_PROCEDURE
+    };
+
+    MBED_DEPRECATED_SINCE("mbed-os-5.11", "Use resolution_strategy_t instead.")
+    typedef resolution_strategy_t ResolutionStrategy;
+
+    /**
+     * Connection strategy to use when a connection request contains a
+     * private resolvable address.
+     */
+    resolution_strategy_t resolution_strategy;
+};
+
+/**
+ * Privacy configuration of the central role.
+ *
+ * @note This configuration is also used when the local device operates as
+ * an observer.
+ */
+struct central_privay_configuration_t {
+    /**
+     * Indicates if nonresolvable random address should be used when the
+     * central or observer sends scan request packets.
+     *
+     * Resolvable random address continues to be used for connection requests.
+     */
+    bool use_non_resolvable_random_address;
+
+
+    /**
+     * Resolution strategy of resolvable addresses received in advertising
+     * packets.
+     */
+    enum resolution_strategy_t {
+        /**
+         * Do not resolve the address received in advertising packets.
+         */
+        DO_NOT_RESOLVE,
+
+        /**
+         * Resolve the resolvable addresses in the advertising packet and
+         * forward advertising packet to the application independently of
+         * the address resolution procedure result.
+         */
+        RESOLVE_AND_FORWARD,
+
+        /**
+         * Filter out packets containing a resolvable address that cannot be resolved
+         * by this device.
+         *
+         * @note Filtering is applied if the local device contains at least
+         * one bond.
+         */
+        RESOLVE_AND_FILTER
+    };
+
+    MBED_DEPRECATED_SINCE("mbed-os-5.11", "Use resolution_strategy_t instead.")
+    typedef resolution_strategy_t ResolutionStrategy;
+
+    /**
+     * Resolution strategy applied to advertising packets received by the
+     * local device.
+     */
+    resolution_strategy_t resolution_strategy;
+};
+
+
+/**
+ * @}
+ * @}
+ */
+
+} // namespace ble
+
+#endif //BLE_GAP_TYPES_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/WifiManager.h	Thu Mar 14 21:34:06 2019 +0000
@@ -0,0 +1,25 @@
+#ifndef __WIFI_MANAGER_H__
+#define __WIFI_MANAGER_H__
+
+class WifiManager {
+public:
+    WifiManager();
+public:
+    void scanChannels();
+    void getAvailableAPs();
+    void connect2AP(const char * WIFI_SSID, const char * WIFI_PASSWORD);
+    void sendHttpsRequest();
+    void sendHttpRequest();
+
+
+
+private:
+    
+    /**
+    * 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
\ No newline at end of file
--- a/source/main-https.cpp	Sun Mar 10 09:46:06 2019 +0000
+++ b/source/main-https.cpp	Thu Mar 14 21:34:06 2019 +0000
@@ -16,6 +16,7 @@
 #include "ble/services/UARTService.h"
 #include "common_config.h"
 #include "ATCmdManager.h"
+#include "BleManager.h"
 UARTService *uart;
 
 DigitalOut alivenessLED(LED1, 0);
@@ -25,7 +26,7 @@
 static RawSerial *device; // tx, rx
 static UARTSerial *_serial; // tx, rx
 static ATCmdParser *_parser;
-const static char     DEVICE_NAME[] = "BLE-UART";
+const static char     DEVICE_NAME_MAIN[] = "BLE-UART";
 static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
 char buffer[BUFFER_LEN];
 uint8_t TxBuffer[TX_BUFFER_LEN];
@@ -214,7 +215,7 @@
     /* 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));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME_MAIN, sizeof(DEVICE_NAME_MAIN));
     /* 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);
@@ -252,7 +253,7 @@
     /* 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));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME_MAIN, sizeof(DEVICE_NAME_MAIN));
     /* 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);
@@ -280,6 +281,24 @@
     return (int) txLen;
 }
 
+void printUartRxResult()
+{
+    
+    if(uartCharRcvCount == 0)
+    {
+        device->printf("\nFirst Call to UART attach callback!!\n");
+    }
+    else if(uartCharRcvCount >= uartExpectedRcvCount)
+    {
+        device->printf("\nNumber of Received Bytes = %d\n\n", uartCharRcvCount);
+        device->printf("--- Writing back received bytes --- \n");
+        int n;
+        n = WriteUartBytes(RxBuffer, TX_BUFFER_LEN, uartCharRcvCount);
+        UartBusy = false;
+    }
+}
+
+
 void UartRxcallback_ex() {
     if(uartCharRcvCount >= uartExpectedRcvCount)
     {
@@ -288,7 +307,7 @@
     }
     if(uartCharRcvCount == 0)
     {
-        device->printf("\nFirst Call to UART attach callback!!\n");
+        eventQueue.call(printUartRxResult);
     }
     // Note: you need to actually read from the serial to clear the RX interrupt
     RxBuffer[uartCharRcvCount] = (uint8_t) device->getc();
@@ -296,11 +315,7 @@
     if(uartCharRcvCount >= uartExpectedRcvCount)
     {
         alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
-        device->printf("\nNumber of Received Bytes = %d\n\n", uartCharRcvCount);
-        device->printf("--- Writing back received bytes --- \n");
-        int n;
-        n = WriteUartBytes(RxBuffer, TX_BUFFER_LEN, uartCharRcvCount);
-        UartBusy = false;
+        eventQueue.call(printUartRxResult);
     }
 }
 
@@ -314,14 +329,9 @@
         rxLen = bufSize;
     }
     uartExpectedRcvCount = rxLen;
+    device->printf("\nattaching to device UART\n\n");
     device->attach(&UartRxcallback_ex);
     device->printf("\nBackground UART read setup completed\n\n");
-    //for(int i=0;i<rxLen;i++)
-    //{
-    //    rxBuffer[i] = (uint8_t) getc();
-    //}
-    // return number of bytes written to UART
-    //return rxLen;
 }
 
 int ReadUartBytes(uint8_t * rxBuffer, size_t bufSize, int rxLen, bool echo)
@@ -435,6 +445,7 @@
     printf("Waiting for %d seconds...\n", numSecs);
     for(int i=0;i<numSecs;i++){
         printf("%d", i);
+        printf("\n");
         wait(0.5);
         eventQueue.dispatch(500);        // Dispatch time - 500msec
     }
@@ -442,30 +453,58 @@
 
 static int reset_counter = 0;
 
+
+
+
+
+int ble_security_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;
+}
+
 int main() {
     reset_counter++;
     //RawSerial *device(USBTX, USBRX); // tx, rx
     device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
-    
+    ble_security_main();
     device->printf("\n --- Running UART-BLE-UartService --- (rst_cnt = %d)\n", reset_counter);
-    // Start the event queue
-    //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
 
     eventQueue.call_every(500, blinkCallback);
     eventQueue.call_every(60000, HelloUart);
     //eventQueue.call_every(1000, checkUartReceive);
+    
     device->printf("\n --- EventQueues setup --- \n");
     ////////////////////////////////////////////////////////////////////////////////
     // BLE Initialization /////////////////////////////////////////////////////////
     device->printf("\n --- about to instantiate 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);
     btle_thread.start(callback(bleInitialization));
-    //cbMAIN_driverUnlock();
     
     device->printf("\n --- Waiting for BLE Initialization to be completed --- \n");
     int i = 0;
@@ -477,26 +516,13 @@
         device->putc('0'+(i++ % 10));
     }
     btle_thread.join();
-    if(i < 20)
-    device->printf("\n --- BLE Initialization completed --- \n");
-    else
-    device->printf("\n --- BLE Initialization failed --- \n");
+    if(i < 20){
+        device->printf("\n --- BLE Initialization completed --- \n");
+    }
+    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 /////////////////////////////////////////////////////////
@@ -512,17 +538,18 @@
     ////////////////////////////////////////////////////////////////////////////////////
 #endif
      btle_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
-     printWait(30);
+     printWait(5);
      //device->printf("\n Press any key to start Wifi demo: ");
      //device->getc();
+#ifdef false // comment out wifi part
      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(callback(wifi_demo, network));
-     //t.start(wifi_demo2());
      t.join(); 
+#endif
      //network->disconnect(); 
      //delete network;
      printMacAddress();  
@@ -530,54 +557,9 @@
      //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++)
     {
         device->putc(i);
@@ -596,18 +578,16 @@
  
 
     device->printf("\nATCmdParser with ESP8266 example");
-    device->printf("\n Waiting for 2 minutes ");
-    wait(2);
+    device->printf("\n Waiting for 5 seconds ");
+    printWait(5);
     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;
+    while(UartBusy){
+        wait(0.1);
+    }
     ATCmdManager *aTCmdManager = new ATCmdManager(USBTX, USBRX, true);
+    //ATCmdManager *aTCmdManager = new ATCmdManager(D1, D0, true);
+    aTCmdManager->runMain();
 #ifdef false
     _serial = new UARTSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
     _parser = new ATCmdParser(_serial);
@@ -632,7 +612,7 @@
     //parser.read(buffer, len);
     printf("\nDone\n");
 #endif
-    performFreeMemoryCheck();
+    //performFreeMemoryCheck();
 
     //eventQueue.dispatch_forever();
     //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
--- a/source/network-helper.h	Sun Mar 10 09:46:06 2019 +0000
+++ b/source/network-helper.h	Thu Mar 14 21:34:06 2019 +0000
@@ -152,8 +152,8 @@
     
     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("Waiting for 5 seconds before starting scan...\n");
+    for(int i=0;i<5;i++){
         printf("%d", i);
         wait(1);
     }
@@ -172,8 +172,8 @@
     //    return -1;
     //}
 #endif
-    printf("Waiting for 30 seconds before connecting...\n");
-    for(int i=0;i<30;i++){
+    printf("Waiting for 5 seconds before connecting...\n");
+    for(int i=0;i<5;i++){
         printf("%d", i);
         wait(1);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/pretty_printer.h	Thu Mar 14 21:34:06 2019 +0000
@@ -0,0 +1,95 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 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.
+ */
+
+#include <mbed.h>
+#include "ble/BLE.h"
+
+inline void print_error(ble_error_t error, const char* msg)
+{
+    printf("%s: ", msg);
+    switch(error) {
+        case BLE_ERROR_NONE:
+            printf("BLE_ERROR_NONE: No error");
+            break;
+        case BLE_ERROR_BUFFER_OVERFLOW:
+            printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted");
+            break;
+        case BLE_ERROR_NOT_IMPLEMENTED:
+            printf("BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW");
+            break;
+        case BLE_ERROR_PARAM_OUT_OF_RANGE:
+            printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range");
+            break;
+        case BLE_ERROR_INVALID_PARAM:
+            printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid");
+            break;
+        case BLE_STACK_BUSY:
+            printf("BLE_STACK_BUSY: The stack is busy");
+            break;
+        case BLE_ERROR_INVALID_STATE:
+            printf("BLE_ERROR_INVALID_STATE: Invalid state");
+            break;
+        case BLE_ERROR_NO_MEM:
+            printf("BLE_ERROR_NO_MEM: Out of Memory");
+            break;
+        case BLE_ERROR_OPERATION_NOT_PERMITTED:
+            printf("BLE_ERROR_OPERATION_NOT_PERMITTED");
+            break;
+        case BLE_ERROR_INITIALIZATION_INCOMPLETE:
+            printf("BLE_ERROR_INITIALIZATION_INCOMPLETE");
+            break;
+        case BLE_ERROR_ALREADY_INITIALIZED:
+            printf("BLE_ERROR_ALREADY_INITIALIZED");
+            break;
+        case BLE_ERROR_UNSPECIFIED:
+            printf("BLE_ERROR_UNSPECIFIED: Unknown error");
+            break;
+        case BLE_ERROR_INTERNAL_STACK_FAILURE:
+            printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure");
+            break;
+    }
+    printf("\r\n");
+}
+
+/** print device address to the terminal */
+void print_address(const uint8_t *addr)
+{
+    printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n",
+           addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+}
+
+inline void print_mac_address()
+{
+    /* 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: ");
+    print_address(address);
+}
+
+inline const char* phy_to_string(Gap::Phy_t phy) {
+    switch(phy.value()) {
+        case Gap::Phy_t::LE_1M:
+            return "LE 1M";
+        case Gap::Phy_t::LE_2M:
+            return "LE 2M";
+        case Gap::Phy_t::LE_CODED:
+            return "LE coded";
+        default:
+            return "invalid PHY";
+    }
+}