Kris Scholte Lubberink
/
bleswitcher
test
Diff: source/main.cpp
- Revision:
- 1:916188eae2bb
- Parent:
- 0:fcb1e0b995a9
- Child:
- 9:674ab70e0f36
--- a/source/main.cpp Thu Mar 08 18:08:23 2018 +0000 +++ b/source/main.cpp Fri Jun 01 13:54:04 2018 -0500 @@ -1,417 +1,417 @@ -/* 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. - */ - -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. - */ -class SMDevice : private mbed::NonCopyable<SMDevice>, - public SecurityManager::EventHandler -{ -public: - SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) : - _led1(LED1, 0), - _ble(ble), - _event_queue(event_queue), - _peer_address(peer_address), - _handle(0), - _is_connecting(false) { }; - - virtual ~SMDevice() - { - if (_ble.hasInitialized()) { - _ble.shutdown(); - } - }; - - /** Start BLE interface initialisation */ - void run() - { - ble_error_t error; - - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &SMDevice::blink); - - if (_ble.hasInitialized()) { - printf("Ble instance already initialised.\r\n"); - return; - } - - /* this will inform us off all events so we can schedule their handling - * using our event queue */ - _ble.onEventsToProcess( - makeFunctionPointer(this, &SMDevice::schedule_ble_events) - ); - - /* handle 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 */ - virtual void pairingRequest( - ble::connection_handle_t connectionHandle - ) { - printf("Pairing requested. Authorising.\r\n"); - _ble.securityManager().acceptPairingRequest(connectionHandle); - } - - /** Inform the application of a successful pairing. Terminate the demonstration. */ - virtual void pairingResult( - ble::connection_handle_t connectionHandle, - SecurityManager::SecurityCompletionStatus_t result - ) { - if (result == SecurityManager::SEC_STATUS_SUCCESS) { - printf("Pairing successful\r\n"); - } else { - printf("Pairing failed\r\n"); - } - - /* disconnect in 500 ms */ - _event_queue.call_in( - 500, &_ble.gap(), - &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION - ); - } - - /** Inform the application of change in encryption status. This will be - * communicated through the serial port */ - virtual void linkEncryptionResult( - ble::connection_handle_t connectionHandle, - ble::link_encryption_t result - ) { - if (result == ble::link_encryption_t::ENCRYPTED) { - printf("Link ENCRYPTED\r\n"); - } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) { - printf("Link ENCRYPTED_WITH_MITM\r\n"); - } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) { - printf("Link NOT_ENCRYPTED\r\n"); - } - } - -private: - /** Override to start chosen activity when initialisation completes */ - virtual void start() = 0; - - /** This is called when BLE interface is initialised and starts the demonstration */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - ble_error_t error; - - if (event->error) { - printf("Error during the initialisation\r\n"); - return; - } - - /* If the security manager is required this needs to be called before any - * calls to the Security manager happen. */ - error = _ble.securityManager().init(); - - if (error) { - printf("Error during init %d\r\n", error); - return; - } - - /* 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 */ - 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) - { - printf("Disconnected - demonstration ended \r\n"); - _event_queue.break_dispatch(); - }; - - /** End demonstration unexpectedly. Called if timeout is reached during advertising, - * scanning or connection initiation */ - void 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 schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) - { - _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); - }; - - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; - }; - -private: - DigitalOut _led1; - -protected: - BLE &_ble; - events::EventQueue &_event_queue; - BLEProtocol::AddressBytes_t &_peer_address; - ble::connection_handle_t _handle; - bool _is_connecting; -}; - -/** A peripheral device will advertise, accept the connection and request - * a change in link security. */ -class SMDevicePeripheral : public SMDevice { -public: - SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) - : SMDevice(ble, event_queue, peer_address) { } - - virtual void start() - { - /* Set up and start advertising */ - - 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; - } - - /** This tells the stack to generate a pairingRequest event - * which will require this application to respond before pairing - * can proceed. Setting it to false will automatically accept - * pairing. */ - _ble.securityManager().setPairingRequestAuthorisation(true); - }; - - /** This is called by Gap to notify the application we connected, - * in our case it immediately requests a change in link security */ - virtual void 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)); - - /* 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. */ -class SMDeviceCentral : public SMDevice { -public: - SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) - : SMDevice(ble, event_queue, peer_address) { } - - virtual void start() - { - /* 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); - - 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 on_scan(const Gap::AdvertisementCallbackParams_t *params) - { - /* don't bother with analysing scan result if we're already connecting */ - if (_is_connecting) { - return; - } - - /* parse the advertising payload, looking for a discoverable device */ - for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { - /* The advertising payload is a collection of key/value records where - * byte 0: length of the record excluding this byte - * byte 1: The key, it is the type of the data - * byte [2..N] The value. N is equal to byte0 - 1 */ - const uint8_t record_length = params->advertisingData[i]; - if (record_length == 0) { - continue; - } - - /* 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->addressType, - NULL, NULL - ); - - if (error) { - printf("Error during Gap::connect %d\r\n", error); - return; - } - - /* we may have already scan events waiting - * to be processed so we need to remember - * that we are already connecting and ignore them */ - _is_connecting = true; - - return; - } - - i += record_length; - } - }; - - /** 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) - { - 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); - - if (error) { - printf("Error during SM::requestPairing %d\r\n", error); - return; - } - - /* upon pairing success the application will disconnect */ - }; -}; - -int main() -{ - BLE& ble = BLE::Instance(); - events::EventQueue queue; - - { - 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; -} +/* 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. + */ + +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. + */ +class SMDevice : private mbed::NonCopyable<SMDevice>, + public SecurityManager::EventHandler +{ +public: + SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) : + _led1(LED1, 0), + _ble(ble), + _event_queue(event_queue), + _peer_address(peer_address), + _handle(0), + _is_connecting(false) { }; + + virtual ~SMDevice() + { + if (_ble.hasInitialized()) { + _ble.shutdown(); + } + }; + + /** Start BLE interface initialisation */ + void run() + { + ble_error_t error; + + /* to show we're running we'll blink every 500ms */ + _event_queue.call_every(500, this, &SMDevice::blink); + + if (_ble.hasInitialized()) { + printf("Ble instance already initialised.\r\n"); + return; + } + + /* this will inform us off all events so we can schedule their handling + * using our event queue */ + _ble.onEventsToProcess( + makeFunctionPointer(this, &SMDevice::schedule_ble_events) + ); + + /* handle 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 */ + virtual void pairingRequest( + ble::connection_handle_t connectionHandle + ) { + printf("Pairing requested. Authorising.\r\n"); + _ble.securityManager().acceptPairingRequest(connectionHandle); + } + + /** Inform the application of a successful pairing. Terminate the demonstration. */ + virtual void pairingResult( + ble::connection_handle_t connectionHandle, + SecurityManager::SecurityCompletionStatus_t result + ) { + if (result == SecurityManager::SEC_STATUS_SUCCESS) { + printf("Pairing successful\r\n"); + } else { + printf("Pairing failed\r\n"); + } + + /* disconnect in 500 ms */ + _event_queue.call_in( + 500, &_ble.gap(), + &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION + ); + } + + /** Inform the application of change in encryption status. This will be + * communicated through the serial port */ + virtual void linkEncryptionResult( + ble::connection_handle_t connectionHandle, + ble::link_encryption_t result + ) { + if (result == ble::link_encryption_t::ENCRYPTED) { + printf("Link ENCRYPTED\r\n"); + } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) { + printf("Link ENCRYPTED_WITH_MITM\r\n"); + } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) { + printf("Link NOT_ENCRYPTED\r\n"); + } + } + +private: + /** Override to start chosen activity when initialisation completes */ + virtual void start() = 0; + + /** This is called when BLE interface is initialised and starts the demonstration */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *event) + { + ble_error_t error; + + if (event->error) { + printf("Error during the initialisation\r\n"); + return; + } + + /* If the security manager is required this needs to be called before any + * calls to the Security manager happen. */ + error = _ble.securityManager().init(); + + if (error) { + printf("Error during init %d\r\n", error); + return; + } + + /* 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 */ + 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) + { + printf("Disconnected - demonstration ended \r\n"); + _event_queue.break_dispatch(); + }; + + /** End demonstration unexpectedly. Called if timeout is reached during advertising, + * scanning or connection initiation */ + void 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 schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) + { + _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); + }; + + /** Blink LED to show we're running */ + void blink(void) + { + _led1 = !_led1; + }; + +private: + DigitalOut _led1; + +protected: + BLE &_ble; + events::EventQueue &_event_queue; + BLEProtocol::AddressBytes_t &_peer_address; + ble::connection_handle_t _handle; + bool _is_connecting; +}; + +/** A peripheral device will advertise, accept the connection and request + * a change in link security. */ +class SMDevicePeripheral : public SMDevice { +public: + SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) + : SMDevice(ble, event_queue, peer_address) { } + + virtual void start() + { + /* Set up and start advertising */ + + 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; + } + + /** This tells the stack to generate a pairingRequest event + * which will require this application to respond before pairing + * can proceed. Setting it to false will automatically accept + * pairing. */ + _ble.securityManager().setPairingRequestAuthorisation(true); + }; + + /** This is called by Gap to notify the application we connected, + * in our case it immediately requests a change in link security */ + virtual void 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)); + + /* 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. */ +class SMDeviceCentral : public SMDevice { +public: + SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) + : SMDevice(ble, event_queue, peer_address) { } + + virtual void start() + { + /* 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); + + 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 on_scan(const Gap::AdvertisementCallbackParams_t *params) + { + /* don't bother with analysing scan result if we're already connecting */ + if (_is_connecting) { + return; + } + + /* parse the advertising payload, looking for a discoverable device */ + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { + /* The advertising payload is a collection of key/value records where + * byte 0: length of the record excluding this byte + * byte 1: The key, it is the type of the data + * byte [2..N] The value. N is equal to byte0 - 1 */ + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + + /* 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->addressType, + NULL, NULL + ); + + if (error) { + printf("Error during Gap::connect %d\r\n", error); + return; + } + + /* we may have already scan events waiting + * to be processed so we need to remember + * that we are already connecting and ignore them */ + _is_connecting = true; + + return; + } + + i += record_length; + } + }; + + /** 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) + { + 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); + + if (error) { + printf("Error during SM::requestPairing %d\r\n", error); + return; + } + + /* upon pairing success the application will disconnect */ + }; +}; + +int main() +{ + BLE& ble = BLE::Instance(); + events::EventQueue queue; + + { + 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; +}