Okundu Omeni
/
wifi-https-ble-sm-uart-atcmd-5-13-1
this is using the mbed os version 5-13-1
Diff: source/BleManager.cpp
- Revision:
- 76:6afda865fbf8
- Parent:
- 75:08eff6258e1b
- Child:
- 77:0b505d1e15f4
--- a/source/BleManager.cpp Thu Mar 14 21:34:06 2019 +0000 +++ b/source/BleManager.cpp Fri Mar 15 14:26:44 2019 +0000 @@ -16,7 +16,9 @@ #include <events/mbed_events.h> #include <mbed.h> +#include "common_config.h" #include "ble/BLE.h" +#include "ble/services/UARTService.h" #include "SecurityManager.h" #include "BleManager.h" #if MBED_CONF_APP_FILESYSTEM_SUPPORT @@ -26,7 +28,9 @@ static const uint8_t DEVICE_NAME[] = "SM_device"; - +//static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; +extern UARTService *uart; +extern char buffer[BUFFER_LEN]; /** This example demonstrates all the basic setup required * for pairing and setting up link security both as a central and peripheral * @@ -142,11 +146,13 @@ printf("Link NOT_ENCRYPTED\r\n"); } +#ifdef DEMO_BLE_SECURITY /* disconnect in 2 s */ _event_queue.call_in( 2000, &_ble.gap(), &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION ); +#endif } /** Override to start chosen activity when initialisation completes */ @@ -226,6 +232,7 @@ * 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); + _ble.gattServer().onDataWritten(this, &SMDevice::onDataWrittenCallback); /* start test in 500 ms */ _event_queue.call_in(500, this, &SMDevice::start); @@ -256,6 +263,46 @@ _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); }; +/** Echo received data back */ +void SMDevice::EchoBleUartReceived() +{ + uart->writeString(buffer); + uart->writeString("\n"); //flushes uart output buffer and sends data +} + + +/** + * This callback allows the LEDService to receive updates to the ledState Characteristic. + * + * @param[in] params + * Information about the characterisitc being updated. + */ +void SMDevice::onDataWrittenCallback(const GattWriteCallbackParams *params) { + if ((uart != NULL) && (params->handle == uart->getTXCharacteristicHandle())) { + uint16_t bytesRead = params->len; + + printf("received %u bytes\n\r ", bytesRead); + + if(bytesRead >= 255){ + printf("Overflow command %u n\r ", bytesRead); + bytesRead = 255; + } + + unsigned index = 0; + for (; index < bytesRead; index++) { + buffer[index] = params->data[index]; + } + + buffer[index++] = 0; + + printf("Data : %s ",buffer); + printf("\r\n"); + /* start echo in 50 ms */ + _event_queue.call_in(50, this, &SMDevice::EchoBleUartReceived); + //_event_queue.call(EchoBleUartReceived); + + } +} /** Blink LED to show we're running */ void SMDevice::blink(void) { @@ -284,9 +331,26 @@ GapAdvertisingData::COMPLETE_LOCAL_NAME, DEVICE_NAME, sizeof(DEVICE_NAME) - ); + ); + /* Setup primary service */ + uart = new UARTService(_ble); + - error = _ble.gap().setAdvertisingPayload(advertising_data); + /* add device name */ + error = advertising_data.addData( + GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS , + (const uint8_t *)UARTServiceUUID_reversed, + sizeof(sizeof(UARTServiceUUID_reversed)) + ); + /* setup advertising */ + //error = _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)); + //error = _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + /* set up the services that can be discovered */ + //error = _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); + + + //error = _ble.gap().setAdvertisingPayload(advertising_data); if (error) { printf("Error during Gap::setAdvertisingPayload\r\n"); @@ -297,8 +361,10 @@ _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); + //_ble.gap().setAdvertisingInterval(20); + //_ble.gap().setAdvertisingTimeout(0); + _ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ + _ble.gap().setAdvertisingTimeout(300); /* 16 * 1000ms. */ error = _ble.gap().startAdvertising(); @@ -495,592 +561,3 @@ 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 -#include "LittleFileSystem.h" -#include "HeapBlockDevice.h" -#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT - -/** This example demonstrates all the basic setup required - * for pairing and setting up link security both as a central and peripheral - * - * The example is implemented as two classes, one for the peripheral and one - * for central inheriting from a common base. They are run in sequence and - * require a peer device to connect to. During the peripheral device demonstration - * a peer device is required to connect. In the central device demonstration - * this peer device will be scanned for and connected to - therefore it should - * be advertising with the same address as when it connected. - * - * During the test output is written on the serial connection to monitor its - * progress. - */ - -static const char DEVICE_NAME[] = "SM_device"; - -/* we have to specify the disconnect call because of ambiguous overloads */ -//typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t); -//const static disconnect_call_t disconnect_call = &Gap::disconnect; -//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 - * 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 Gap::EventHandler -{ -public: - SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) : - _led1(LED1, 0), - _ble(ble), - _event_queue(event_queue), - _peer_address(peer_address), - _handle(0), - _is_connecting(false) { }; - - virtual ~SMDevice() - { - if (_ble.hasInitialized()) { - _ble.shutdown(); - } - }; - - /** Start BLE interface initialisation */ - void run() - { - ble_error_t error; - - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &SMDevice::blink); - - if (_ble.hasInitialized()) { - printf("Ble instance already initialised.\r\n"); - return; - } - - /* this will inform us off all events so we can schedule their handling - * using our event queue */ - _ble.onEventsToProcess( - makeFunctionPointer(this, &SMDevice::schedule_ble_events) - ); - - /* handle gap events */ - _ble.gap().setEventHandler(this); - - error = _ble.init(this, &SMDevice::on_init_complete); - - if (error) { - printf("Error returned by BLE::init.\r\n"); - return; - } - - /* this will not return until shutdown */ - _event_queue.dispatch_forever(); - }; - -private: - /** Override to start chosen activity when initialisation completes */ - virtual void start() = 0; - - /** This is called when BLE interface is initialised and starts the demonstration */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - ble_error_t error; - - if (event->error) { - printf("Error during the initialisation\r\n"); - return; - } - - /* This path will be used to store bonding information but will fallback - * to storing in memory if file access fails (for example due to lack of a filesystem) */ - const char* db_path = "/fs/bt_sec_db"; - /* If the security manager is required this needs to be called before any - * calls to the Security manager happen. */ - error = _ble.securityManager().init( - true, - false, - SecurityManager::IO_CAPS_NONE, - NULL, - false, - db_path - ); - - if (error) { - printf("Error during init %d\r\n", error); - return; - } - - error = _ble.securityManager().preserveBondingStateOnReset(true); - - if (error) { - printf("Error during preserveBondingStateOnReset %d\r\n", error); - } - -#if MBED_CONF_APP_FILESYSTEM_SUPPORT - /* Enable privacy so we can find the keys */ - error = _ble.gap().enablePrivacy(true); - - if (error) { - printf("Error enabling privacy\r\n"); - } - - Gap::PeripheralPrivacyConfiguration_t configuration_p = { - /* use_non_resolvable_random_address */ false, - Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS - }; - _ble.gap().setPeripheralPrivacyConfiguration(&configuration_p); - - Gap::CentralPrivacyConfiguration_t configuration_c = { - /* use_non_resolvable_random_address */ false, - Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD - }; - _ble.gap().setCentralPrivacyConfiguration(&configuration_c); - - /* this demo switches between being master and slave */ - _ble.securityManager().setHintFutureRoleReversal(true); -#endif - - /* Tell the security manager to use methods in this class to inform us - * of any events. Class needs to implement SecurityManagerEventHandler. */ - _ble.securityManager().setSecurityManagerEventHandler(this); - - /* gap events also handled by this class */ - _ble.gap().setEventHandler(this); - - /* print device address */ - Gap::AddressType_t addr_type; - Gap::Address_t addr; - _ble.gap().getAddress(&addr_type, addr); - print_address(addr); - - /* start test in 500 ms */ - _event_queue.call_in(500, this, &SMDevice::start); - }; - - /** Schedule processing of events from the BLE in the event queue. */ - void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) - { - _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); - }; - - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; - }; - -private: - /* Event handler */ - - /** Respond to a pairing request. This will be called by the stack - * when a pairing request arrives and expects the application to - * call acceptPairingRequest or cancelPairingRequest */ - virtual void pairingRequest( - ble::connection_handle_t connectionHandle - ) { - printf("Pairing requested - authorising\r\n"); - _ble.securityManager().acceptPairingRequest(connectionHandle); - } - - /** Inform the application of a successful pairing. Terminate the demonstration. */ - virtual void pairingResult( - ble::connection_handle_t connectionHandle, - SecurityManager::SecurityCompletionStatus_t result - ) { - if (result == SecurityManager::SEC_STATUS_SUCCESS) { - printf("Pairing successful\r\n"); - } else { - printf("Pairing failed\r\n"); - } - } - - /** Inform the application of change in encryption status. This will be - * communicated through the serial port */ - virtual void linkEncryptionResult( - ble::connection_handle_t connectionHandle, - ble::link_encryption_t result - ) { - if (result == ble::link_encryption_t::ENCRYPTED) { - printf("Link ENCRYPTED\r\n"); - } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) { - printf("Link ENCRYPTED_WITH_MITM\r\n"); - } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) { - printf("Link NOT_ENCRYPTED\r\n"); - } - - /* disconnect in 2 s */ - _event_queue.call_in( - 2000, - &_ble.gap(), - &Gap::disconnect, //disconnect_call, - _handle, - (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 Gap::DisconnectionCompleteEvent &) - virtual void onDisconnectionComplete(const Gap::DisconnectionCallbackParams_t *params) - { - printf("Disconnected\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(); - //} - -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 */ -#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::Gap::AdvertisingDataBuilder adv_data_builder( - adv_buffer, 32 - ); - - adv_data_builder.setFlags(); - adv_data_builder.setName(DEVICE_NAME); - - /* Set payload for the set */ - ble_error_t error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "Gap::setAdvertisingPayload() failed"); - _event_queue.break_dispatch(); - return; - } - - ble::gap::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED - ); - - error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "Gap::setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "Gap::startAdvertising() failed"); - return; - } -#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 - * which will require this application to respond before pairing - * can proceed. Setting it to false will automatically accept - * pairing. */ - _ble.securityManager().setPairingRequestAuthorisation(true); - }; - - /** This is called by Gap to notify the application we connected, - * in our case it immediately requests a change in link security */ - //virtual void onConnectionComplete(const ble::ConnectionCompleteEvent_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.peerAddr, 6); - - printf("Connected to peer: "); - print_address(event.peerAddr); - - _handle = 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() - { - ble::ScanParameters params; - ble_error_t error = _ble.gap().setScanParameters(params); - - if (error) { - print_error(error, "Error in Gap::startScan %d\r\n"); - return; - } - - /* start scanning, results will be handled by onAdvertisingReport */ - error = _ble.gap().startScan(); - - if (error) { - print_error(error, "Error in Gap::startScan %d\r\n"); - return; - } - - printf("Please advertise\r\n"); - - printf("Scanning for: "); - print_address(_peer_address); - } - -private: - /* Gap::EventHandler */ - - /** Look at scan payload to find a peer device and connect to it */ - virtual void onAdvertisingReport(const Gap::AdvertisementCallbackParams_t &event) - { - /* don't bother with analysing scan result if we're already connecting */ - if (_is_connecting) { - return; - } - - /* parse the advertising payload, looking for a discoverable device */ - if (memcmp(event.peerAddr, _peer_address, sizeof(_peer_address)) == 0) { - ble_error_t error = _ble.gap().stopScan(); - - if (error) { - print_error(error, "Error caused by Gap::stopScan"); - return; - } - - ble::ConnectionParameters connection_params( - ble::phy_t::LE_1M, - ble::scan_interval_t(50), - ble::scan_window_t(50), - ble::conn_interval_t(50), - ble::conn_interval_t(100), - ble::slave_latency_t(0), - ble::supervision_timeout_t(100) - ); - connection_params.setOwnAddressType(ble::own_address_type_t::RANDOM); - - error = _ble.gap().connect( - event.getPeerAddressType(), - event.getPeerAddress(), - connection_params - ); - - if (error) { - print_error(error, "Error caused by Gap::connect"); - return; - } - - /* we may have already scan events waiting - * to be processed so we need to remember - * that we are already connecting and ignore them */ - _is_connecting = true; - - return; - } - } - - /** This is called by Gap to notify the application we connected, - * in our case it immediately request pairing */ - virtual void onConnectionComplete(const Gap::ConnectionCallbackParams_t &event) - { - if (event.getStatus() == BLE_ERROR_NONE) { - /* store the handle for future Security Manager requests */ - _handle = event.getConnectionHandle(); - - printf("Connected\r\n"); - - /* in this example the local device is the master so we request pairing */ - ble_error_t error = _ble.securityManager().requestPairing(_handle); - - if (error) { - printf("Error during SM::requestPairing %d\r\n", error); - return; - } - - /* upon pairing success the application will disconnect */ - } - - /* failed to connect - restart scan */ - ble_error_t error = _ble.gap().startScan(); - - if (error) { - print_error(error, "Error in Gap::startScan %d\r\n"); - return; - } - }; -}; - - -#if MBED_CONF_APP_FILESYSTEM_SUPPORT -bool create_filesystem() -{ - static LittleFileSystem fs("fs"); - - /* replace this with any physical block device your board supports (like an SD card) */ - static HeapBlockDevice bd(4096, 256); - - int err = bd.init(); - - if (err) { - return false; - } - - err = bd.erase(0, bd.size()); - - if (err) { - return false; - } - - err = fs.mount(&bd); - - if (err) { - /* Reformat if we can't mount the filesystem */ - printf("No filesystem found, formatting...\r\n"); - - err = fs.reformat(&bd); - - if (err) { - return false; - } - } - - return true; -} -#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT -#ifdef BLE_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 - -#endif \ No newline at end of file