this is using the mbed os version 5-13-1
Revision 75:08eff6258e1b, committed 2019-03-14
- 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
--- 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";
+ }
+}