diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..5857a01a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,43 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'type: bug' +assignees: '' + +--- + +### Description of defect + + + +#### Target(s) and toolchain(s) (name and version) displaying this defect ? + + +#### What version of the example and mbed-os are you using (tag or sha) ? + + + +#### How is this defect reproduced ? + +#### Please attach a file containing the log with traces enabled. + + diff --git a/.github/workflows/build_examples.yml b/.github/workflows/build_examples.yml new file mode 100644 index 00000000..ba9a2edf --- /dev/null +++ b/.github/workflows/build_examples.yml @@ -0,0 +1,31 @@ +name: Build examples +on: + workflow_dispatch: + schedule: + - cron: '0 1 * * 6' + pull_request: +jobs: + run-conditional-feature-compilation-test: + name: Build BLE examples + runs-on: ubuntu-latest + container: mbedos/mbed-os-env:latest + strategy: + matrix: + MBED_TARGET: ["DISCO_L475VG_IOT01A", "NRF52840_DK"] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Deploy + run: | + git clone https://github.com/ARMmbed/mbed-os.git + for i in BLE_* ; do cd $i ; mbed config root . ; rm -rf mbed-os ; ln -s $PWD/../mbed-os mbed-os ; mbed update ; cd .. ; done + + - name: Build mbed-cli v1 + run: | + for i in BLE_* ; do cd $i ; mbed compile -t GCC_ARM -m ${{ matrix.MBED_TARGET }} || exit 1 ; cd .. ; done + + - name: Build cmake + run: | + python3 -m pip install mbed-tools --upgrade # remove after docker image is updated to contain new tools + for i in BLE_* ; do cd $i ; mbed-tools compile -t GCC_ARM -m ${{ matrix.MBED_TARGET }} || exit 1 ; cd .. ; done diff --git a/.github/workflows/run_conditional_ble_feature_compilation.yml b/.github/workflows/run_conditional_ble_feature_compilation.yml new file mode 100644 index 00000000..a239a26a --- /dev/null +++ b/.github/workflows/run_conditional_ble_feature_compilation.yml @@ -0,0 +1,25 @@ +name: run conditional BLE feature compilation +on: + workflow_dispatch: + schedule: + - cron: '0 1 * * 6' +jobs: + run-conditional-feature-compilation-test: + name: Conditional BLE features compilation tested + runs-on: ubuntu-latest + container: mbedos/mbed-os-env:latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Build + run: | + cd BLE_SupportedFeatures + mbed deploy + for f in ../resources/test_configs/*; do + echo "Configuration file ${f}: " + echo "-------------------------------------------------------------------------" + cat "${f}" + echo "-------------------------------------------------------------------------" + mbed compile -t GCC_ARM -m NRF52840_DK --app-config "${f}" + done diff --git a/.gitignore b/.gitignore index f656732e..235a1a4d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,24 +26,21 @@ *.out *.app -.yotta.json -build/ -yotta_modules/ -yotta_targets/ -.DS_Store - # clion .idea/ cmake-build-*/ -CMakeLists.txt # exporters GettingStarted.html # mbed build system +mbed-os-experimental-ble-services/ +mbed-os-ble-utils/ mbed-os/ mbed_settings.py mbed_config.h *.pyc -TARGET_CORDIO_BLUENRG/ +BUILD/ +cmake_build/ +.mbedls* diff --git a/BLE_Advertising/CMakeLists.txt b/BLE_Advertising/CMakeLists.txt new file mode 100644 index 00000000..a70e302c --- /dev/null +++ b/BLE_Advertising/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_Advertising) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_BatteryLevel/img/scan_result.png b/BLE_Advertising/img/scan_result.png similarity index 100% rename from BLE_BatteryLevel/img/scan_result.png rename to BLE_Advertising/img/scan_result.png diff --git a/BLE_BatteryLevel/img/start_scan.png b/BLE_Advertising/img/start_scan.png similarity index 100% rename from BLE_BatteryLevel/img/start_scan.png rename to BLE_Advertising/img/start_scan.png diff --git a/BLE_Advertising/mbed-os-ble-utils.lib b/BLE_Advertising/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_Advertising/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_Advertising/mbed-os.lib b/BLE_Advertising/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_Advertising/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_Advertising/mbed_app.json b/BLE_Advertising/mbed_app.json new file mode 100644 index 00000000..f81ce44c --- /dev/null +++ b/BLE_Advertising/mbed_app.json @@ -0,0 +1,28 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_Advertising/readme.md b/BLE_Advertising/readme.md new file mode 100644 index 00000000..5e492d06 --- /dev/null +++ b/BLE_Advertising/readme.md @@ -0,0 +1,37 @@ +This example shows how to advertise a value of battery service data. The battery value is simulated. +The battery level is a percentage, with 100% being a fully charged battery and 0% being a fully drained battery. +The level starts at 50% and drains every second second, until it hits 10% when it jumps to 100% and continues draining. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Connect for Mobile* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Connect for Mobile. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + + ![](img/start_scan.png) + + **figure 1** How to start scan using nRF Connect for Mobile 4.0.5 + +1. Find your device; it should be named `BATTERY`. + + ![](img/scan_result.png) + + **figure 2** Scan results using nRF Connect for Mobile 4.0.5 + +1. Click on the entry to see the payload details + + +If you can see the battery level, and if its value is changing, the application is working properly. + diff --git a/BLE_Advertising/source/main.cpp b/BLE_Advertising/source/main.cpp new file mode 100644 index 00000000..ebab4116 --- /dev/null +++ b/BLE_Advertising/source/main.cpp @@ -0,0 +1,190 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2019 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 +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "pretty_printer.h" +#include "mbed-trace/mbed_trace.h" + +const static char DEVICE_NAME[] = "BATTERY"; + +using namespace std::literals::chrono_literals; + +static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +class BatteryDemo : ble::Gap::EventHandler { +public: + BatteryDemo(BLE &ble, events::EventQueue &event_queue) : + _ble(ble), + _event_queue(event_queue), + _battery_level(50), + _adv_data_builder(_adv_buffer) + { + } + + void start() + { + /* mbed will call on_init_complete when when ble is ready */ + _ble.init(this, &BatteryDemo::on_init_complete); + + /* this will never return */ + _event_queue.dispatch_forever(); + } + +private: + /** Callback triggered when the ble initialization process has finished */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *params) + { + if (params->error != BLE_ERROR_NONE) { + print_error(params->error, "Ble initialization failed."); + return; + } + + print_mac_address(); + + start_advertising(); + } + + void start_advertising() + { + /* create advertising parameters and payload */ + + ble::AdvertisingParameters adv_parameters( + /* you cannot connect to this device, you can only read its advertising data, + * scannable means that the device has extra advertising data that the peer can receive if it + * "scans" it which means it is using active scanning (it sends a scan request) */ + ble::advertising_type_t::SCANNABLE_UNDIRECTED, + ble::adv_interval_t(ble::millisecond_t(1000)) + ); + + /* when advertising you can optionally add extra data that is only sent + * if the central requests it by doing active scanning (sending scan requests), + * in this example we set this payload first because we want to later reuse + * the same _adv_data_builder builder for payload updates */ + + const uint8_t _vendor_specific_data[4] = { 0xAD, 0xDE, 0xBE, 0xEF }; + _adv_data_builder.setManufacturerSpecificData(_vendor_specific_data); + + _ble.gap().setAdvertisingScanResponse( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + /* now we set the advertising payload that gets sent during advertising without any scan requests */ + + _adv_data_builder.clear(); + _adv_data_builder.setFlags(); + _adv_data_builder.setName(DEVICE_NAME); + + /* we add the battery level as part of the payload so it's visible to any device that scans, + * this part of the payload will be updated periodically without affecting the rest of the payload */ + _adv_data_builder.setServiceData(GattService::UUID_BATTERY_SERVICE, {&_battery_level, 1}); + + /* setup advertising */ + + ble_error_t error = _ble.gap().setAdvertisingParameters( + ble::LEGACY_ADVERTISING_HANDLE, + adv_parameters + ); + + if (error) { + print_error(error, "_ble.gap().setAdvertisingParameters() failed"); + return; + } + + error = _ble.gap().setAdvertisingPayload( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + if (error) { + print_error(error, "_ble.gap().setAdvertisingPayload() failed"); + return; + } + + /* start advertising */ + + error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + + if (error) { + print_error(error, "_ble.gap().startAdvertising() failed"); + return; + } + + /* we simulate battery discharging by updating it every second */ + _event_queue.call_every( + 1000ms, + [this]() { + update_battery_level(); + } + ); + } + + void update_battery_level() + { + if (_battery_level-- == 10) { + _battery_level = 100; + } + + /* update the payload with the new value of the bettery level, the rest of the payload remains the same */ + ble_error_t error = _adv_data_builder.setServiceData(GattService::UUID_BATTERY_SERVICE, make_Span(&_battery_level, 1)); + + if (error) { + print_error(error, "_adv_data_builder.setServiceData() failed"); + return; + } + + /* set the new payload, we don't need to stop advertising */ + error = _ble.gap().setAdvertisingPayload( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + if (error) { + print_error(error, "_ble.gap().setAdvertisingPayload() failed"); + return; + } + } + +private: + BLE &_ble; + events::EventQueue &_event_queue; + + uint8_t _battery_level; + + uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; + ble::AdvertisingDataBuilder _adv_data_builder; +}; + +/* Schedule processing of events from the BLE middleware in the event queue. */ +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ + event_queue.call(Callback(&context->ble, &BLE::processEvents)); +} + +int main() +{ + mbed_trace_init(); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(schedule_ble_events); + + BatteryDemo demo(ble, event_queue); + demo.start(); + + return 0; +} diff --git a/BLE_BatteryLevel/.mbed b/BLE_BatteryLevel/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_BatteryLevel/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_BatteryLevel/img/connection.png b/BLE_BatteryLevel/img/connection.png deleted file mode 100644 index 046fc94c..00000000 Binary files a/BLE_BatteryLevel/img/connection.png and /dev/null differ diff --git a/BLE_BatteryLevel/img/discovery.png b/BLE_BatteryLevel/img/discovery.png deleted file mode 100644 index 90fb664d..00000000 Binary files a/BLE_BatteryLevel/img/discovery.png and /dev/null differ diff --git a/BLE_BatteryLevel/img/notifications.png b/BLE_BatteryLevel/img/notifications.png deleted file mode 100644 index fd092cb3..00000000 Binary files a/BLE_BatteryLevel/img/notifications.png and /dev/null differ diff --git a/BLE_BatteryLevel/img/register_to_notifications.png b/BLE_BatteryLevel/img/register_to_notifications.png deleted file mode 100644 index 87cdc0a0..00000000 Binary files a/BLE_BatteryLevel/img/register_to_notifications.png and /dev/null differ diff --git a/BLE_BatteryLevel/mbed-os.lib b/BLE_BatteryLevel/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_BatteryLevel/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_BatteryLevel/mbed_app.json b/BLE_BatteryLevel/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_BatteryLevel/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_BatteryLevel/module.json b/BLE_BatteryLevel/module.json deleted file mode 100644 index 42d3f5ab..00000000 --- a/BLE_BatteryLevel/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-batterylevel", - "version": "0.0.1", - "description": "An example of creating and updating a simple GATT Service using the BLE_API", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/BLE_BatteryLevel/readme.md b/BLE_BatteryLevel/readme.md deleted file mode 100644 index 1662eadf..00000000 --- a/BLE_BatteryLevel/readme.md +++ /dev/null @@ -1,68 +0,0 @@ -This example creates and updates a standard Battery Level service containing a single -GATT characteristic. - -The [battery service transmits](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml) a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery. - -Although the sample application runs on a BLE device, it doesn't show the device's real battery level (because that changes very slowly and will make for a dull example). Instead, it transmits a fake battery level that starts at 50% (half charged). Every half second, it increments the battery level, going in single increments until reaching 100% (as if the battery is charging). It then drops down to 20% to start incrementing again. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named `BATTERY`. - - ![](img/scan_result.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *Battery service* has the UUID 0x180F and includes the *Battery level* characteristic which has the UUID 0x2A19. - - ![](img/discovery.png) - - **figure 4** Representation of the Battery service using Master Control Panel 4.0.5 - -1. Register for the notifications sent by the *Battery level* characteristic. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. You should see the battery level value change every half second. It begins at 50, goes up to 100 (in steps of 1), resets to 20 and so on. - - ![](img/notifications.png) - - **figure 6** Notifications view using Master Control Panel 4.0.5 - -If you can see the characteristic, and if its value is incrementing correctly, the application is working properly. - diff --git a/BLE_BatteryLevel/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_BatteryLevel/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_BatteryLevel/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_BatteryLevel/source/main.cpp b/BLE_BatteryLevel/source/main.cpp deleted file mode 100644 index 39ed78fb..00000000 --- a/BLE_BatteryLevel/source/main.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2014 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 -#include -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/services/BatteryService.h" -#include "pretty_printer.h" - -static DigitalOut led1(LED1, 1); - -const static char DEVICE_NAME[] = "BATTERY"; - -static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -class BatteryDemo : ble::Gap::EventHandler { -public: - BatteryDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _battery_uuid(GattService::UUID_BATTERY_SERVICE), - _battery_level(50), - _battery_service(ble, _battery_level), - _adv_data_builder(_adv_buffer) { } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &BatteryDemo::on_init_complete); - - _event_queue.call_every(500, this, &BatteryDemo::blink); - _event_queue.call_every(1000, this, &BatteryDemo::update_sensor_value); - - _event_queue.dispatch_forever(); - } - -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - print_error(params->error, "Ble initialization failed."); - return; - } - - print_mac_address(); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - _adv_data_builder.setFlags(); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_battery_uuid, 1)); - _adv_data_builder.setName(DEVICE_NAME); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingPayload() failed"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "_ble.gap().startAdvertising() failed"); - return; - } - } - - void update_sensor_value() { - if (_ble.gap().getState().connected) { - _battery_level++; - if (_battery_level > 100) { - _battery_level = 20; - } - - _battery_service.updateBatteryLevel(_battery_level); - } - } - - void blink(void) { - led1 = !led1; - } - -private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - - UUID _battery_uuid; - - uint8_t _battery_level; - BatteryService _battery_service; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - BatteryDemo demo(ble, event_queue); - demo.start(); - - return 0; -} diff --git a/BLE_BatteryLevel/source/pretty_printer.h b/BLE_BatteryLevel/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_BatteryLevel/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_Beacon/.mbed b/BLE_Beacon/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_Beacon/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_Beacon/img/beacon_details.png b/BLE_Beacon/img/beacon_details.png deleted file mode 100644 index 2835e694..00000000 Binary files a/BLE_Beacon/img/beacon_details.png and /dev/null differ diff --git a/BLE_Beacon/img/discovery.png b/BLE_Beacon/img/discovery.png deleted file mode 100644 index 48b15406..00000000 Binary files a/BLE_Beacon/img/discovery.png and /dev/null differ diff --git a/BLE_Beacon/mbed-os.lib b/BLE_Beacon/mbed-os.lib deleted file mode 100644 index 0a5af545..00000000 --- a/BLE_Beacon/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 \ No newline at end of file diff --git a/BLE_Beacon/mbed_app.json b/BLE_Beacon/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_Beacon/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_Beacon/module.json b/BLE_Beacon/module.json deleted file mode 100644 index e0b3e29c..00000000 --- a/BLE_Beacon/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-beacon", - "version": "0.0.1", - "description": "BLE iBeacon example, building with yotta", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/BLE_Beacon/readme.md b/BLE_Beacon/readme.md deleted file mode 100644 index 20a175d6..00000000 --- a/BLE_Beacon/readme.md +++ /dev/null @@ -1,52 +0,0 @@ -This example creates a BLE beacon: a method of advertising a small amount of information to nearby devices. The information doesn't have to be human-readable; it can be in a format that only an application can use. - -Beacons are very easy to set up: the code for all beacons is the same, and only the information you want to advertise - the beacon payload - needs to change. - -This example advertises a UUID, a major and minor number and the transmission strength. The major and minor numbers are an example of information that is not (normally) meaningful to humans, but that an application can use to identify the beacon and display related information. For example, if the major number is a store ID and the minor number is a location in that store, then a matching application can use these numbers to query a database and display location-specific information. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Connect for Mobile](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be tagged as an `iBeacon` and observe its advertisements (there is no need to connect to the beacon). - - ![](img/discovery.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. View the beacon's details; the exact steps depend on which scanner you're using. - - ![](img/beacon_details.png) - - **figure 3** Beacon details using nRF Master Control Panel 4.0.5 - - -**Tip:** If you are in an area with many BLE devices, it may be difficult to identify your beacon. The simplest solution is to turn your board off and on, initiate a new scan on your BLE scanner every time, and look for the beacon that appears only when your board is on. - -If you can see the beacon and all its information, the application worked properly. - -For more information, see the [mbed Classic version of this application](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_iBeacon/). diff --git a/BLE_Beacon/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_Beacon/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_Beacon/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_Beacon/source/main.cpp b/BLE_Beacon/source/main.cpp deleted file mode 100644 index c1f777bd..00000000 --- a/BLE_Beacon/source/main.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 -#include -#include "ble/BLE.h" -#include "pretty_printer.h" - -static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -/** @deprecated This demo is deprecated and no replacement is currently available. - */ -MBED_DEPRECATED_SINCE( - "mbed-os-5.11", - "This demo is deprecated and no replacement is currently available." -) -class BeaconDemo : ble::Gap::EventHandler { -public: - BeaconDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _adv_data_builder(_adv_buffer) { } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &BeaconDemo::on_init_complete); - - _event_queue.dispatch_forever(); - } - -private: - /** - * iBeacon payload builder. - * - * This data structure contains the payload of an iBeacon. The payload is - * built at construction time and application code can set up an iBeacon by - * injecting the raw field into the GAP advertising payload as a - * GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA. - */ - union Payload { - /** - * Raw data of the payload. - */ - uint8_t raw[25]; - struct { - /** - * Beacon manufacturer identifier. - */ - uint16_t companyID; - - /** - * Packet ID; Equal to 2 for an iBeacon. - */ - uint8_t ID; - - /** - * Length of the remaining data presents in the payload. - */ - uint8_t len; - - /** - * Beacon UUID. - */ - uint8_t proximityUUID[16]; - - /** - * Beacon Major group ID. - */ - uint16_t majorNumber; - - /** - * Beacon minor ID. - */ - uint16_t minorNumber; - - /** - * Tx power received at 1 meter; in dBm. - */ - uint8_t txPower; - }; - - /** - * Assemble an iBeacon payload. - * - * @param[in] uuid Beacon network ID. iBeacon operators use this value - * to group their iBeacons into a single network, a single region and - * identify their organization among others. - * - * @param[in] majNum Beacon major group ID. iBeacon exploitants may use - * this field to divide the region into subregions, their network into - * subnetworks. - * - * @param[in] minNum Identifier of the Beacon in its subregion. - * - * @param[in] transmitPower Measured transmit power of the beacon at 1 - * meter. Scanners use this parameter to approximate the distance - * to the beacon. - * - * @param[in] companyIDIn ID of the beacon manufacturer. - */ - Payload( - const uint8_t *uuid, - uint16_t majNum, - uint16_t minNum, - uint8_t transmitPower, - uint16_t companyIDIn - ) : companyID(companyIDIn), - ID(0x02), - len(0x15), - majorNumber(__REV16(majNum)), - minorNumber(__REV16(minNum)), - txPower(transmitPower) - { - memcpy(proximityUUID, uuid, 16); - } - }; - - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - printf("Ble initialization failed."); - return; - } - - print_mac_address(); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - _adv_data_builder.setFlags(); - - /** - * The Beacon payload has the following composition: - * 128-Bit / 16byte UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 - * Major/Minor = 0x1122 / 0x3344 - * Tx Power = 0xC8 = 200, 2's compliment is 256-200 = (-56dB) - * - * Note: please remember to calibrate your beacons TX Power for more accurate results. - */ - static const uint8_t uuid[] = { 0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, - 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61 }; - uint16_t major_number = 1122; - uint16_t minor_number = 3344; - uint16_t tx_power = 0xC8; - uint16_t comp_id = 0x004C; - - Payload ibeacon(uuid, major_number, minor_number, tx_power, comp_id); - - _adv_data_builder.setManufacturerSpecificData(ibeacon.raw); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingPayload() failed"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "_ble.gap().startAdvertising() failed"); - return; - } - } - -private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - BeaconDemo demo(ble, event_queue); - demo.start(); - - return 0; -} diff --git a/BLE_Beacon/source/pretty_printer.h b/BLE_Beacon/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_Beacon/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_Button/.mbed b/BLE_Button/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_Button/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_Button/img/button_depressed.png b/BLE_Button/img/button_depressed.png deleted file mode 100644 index a9da976a..00000000 Binary files a/BLE_Button/img/button_depressed.png and /dev/null differ diff --git a/BLE_Button/img/button_pressed.png b/BLE_Button/img/button_pressed.png deleted file mode 100644 index af8a889a..00000000 Binary files a/BLE_Button/img/button_pressed.png and /dev/null differ diff --git a/BLE_Button/img/connection.png b/BLE_Button/img/connection.png deleted file mode 100644 index cb269cf3..00000000 Binary files a/BLE_Button/img/connection.png and /dev/null differ diff --git a/BLE_Button/img/discovery.png b/BLE_Button/img/discovery.png deleted file mode 100644 index 02fb19a8..00000000 Binary files a/BLE_Button/img/discovery.png and /dev/null differ diff --git a/BLE_Button/img/register_to_notifications.png b/BLE_Button/img/register_to_notifications.png deleted file mode 100644 index 345e2826..00000000 Binary files a/BLE_Button/img/register_to_notifications.png and /dev/null differ diff --git a/BLE_Button/img/scan_results.png b/BLE_Button/img/scan_results.png deleted file mode 100644 index 0c1e8cf3..00000000 Binary files a/BLE_Button/img/scan_results.png and /dev/null differ diff --git a/BLE_Button/img/start_scan.png b/BLE_Button/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/BLE_Button/img/start_scan.png and /dev/null differ diff --git a/BLE_Button/mbed-os.lib b/BLE_Button/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_Button/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_Button/mbed_app.json b/BLE_Button/mbed_app.json deleted file mode 100644 index 92571a16..00000000 --- a/BLE_Button/mbed_app.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "config": { - "ble_button_pin_name": { - "help": "The pin name used as button in this application", - "macro_name": "BLE_BUTTON_PIN_NAME", - "required": true - } - }, - "target_overrides": { - "NRF51_DK": { - "ble_button_pin_name": "BUTTON1" - }, - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "SW2" - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"], - "ble_button_pin_name": "BUTTON1" - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"], - "ble_button_pin_name": "BUTTON1" - }, - "MTB_UBLOX_NINA_B1": { - "ble_button_pin_name": "BUTTON1" - } - } -} diff --git a/BLE_Button/module.json b/BLE_Button/module.json deleted file mode 100644 index 484fa72b..00000000 --- a/BLE_Button/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-button", - "version": "0.0.1", - "description": "The *input service template* demonstrates the use of a simple input (boolean values) from a read-only characteristic.", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "bin": "./source", - "dependencies": { - "ble": "^2.0.0" - } -} diff --git a/BLE_Button/readme.md b/BLE_Button/readme.md deleted file mode 100644 index b0d72030..00000000 --- a/BLE_Button/readme.md +++ /dev/null @@ -1,99 +0,0 @@ -BLE_Button is a BLE service template. It handles a read-only characteristic with a simple input (boolean values). The input's source is the button on the board itself - the characteristic's value changes when the button is pressed or released. - -The template covers: - -1. Setting up advertising and connection modes. - -1. Creating an input characteristic: read-only, boolean, with notifications. - -1. Constructing a service class and adding it to the BLE stack. - -1. Assigning UUIDs to the service and its characteristic. - -1. Pushing notifications when the characteristic's value changes. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -### Porting this example on new boards - -This example requires a board with at least a button to work. While the pin name of the button is defined for the `NRF51_DK`, `NRF52_DK`, `K64F` and `NUCLEO_F401RE`, it is not specified for other boards. - -It is easy to add the button configuration for your board: -* Open the file named `mbed_app.json` at the root of this example. -* In the section `target_overides` add a new object named after your target if it doesn't exist. This object contain overridden parameters for your target. -* Override the property `ble_button_pin_name` in your target object. The value of the property should be equal to the pin name to use as a button. - -As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. - -```json - "NUCLEO_F411RE": { - "ble_button_pin_name": "USER_BUTTON" - } -``` - - **Note:** You can get more informations about the configuration system in the [documentation](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) - - **Important:** If your target use an ST BLE shield, other parameters have to be overridden for your target. More information are available in the global [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md#targets-for-ble) - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should appear with the name `Button` in the scanner. - - ![](img/scan_results.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with the device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *Button service* has the UUID `0xA000` and includes the *Button state characteristic* which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value. - - ![](img/discovery.png) - - **figure 4** Representation of the Button service using Master Control Panel 4.0.5 - -1. Register for the notifications sent by the button state characteristic then the scanner will automatically receive a notification containing the new state of the button every time the state of the button changes. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. Pressing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x01. - - ![](img/button_pressed.png) - - **figure 6** Notification of button pressed using Master Control Panel 4.0.5 - -1. Releasing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x00. - - ![](img/button_depressed.png) - - **figure 7** Notification of button depressed using Master Control Panel 4.0.5 diff --git a/BLE_Button/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_Button/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_Button/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_Button/source/ButtonService.h b/BLE_Button/source/ButtonService.h deleted file mode 100644 index 58b66c02..00000000 --- a/BLE_Button/source/ButtonService.h +++ /dev/null @@ -1,42 +0,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. - */ - -#ifndef __BLE_BUTTON_SERVICE_H__ -#define __BLE_BUTTON_SERVICE_H__ - -class ButtonService { -public: - const static uint16_t BUTTON_SERVICE_UUID = 0xA000; - const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001; - - ButtonService(BLE &_ble, bool buttonPressedInitial) : - ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) - { - GattCharacteristic *charTable[] = {&buttonState}; - GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - ble.gattServer().addService(buttonService); - } - - void updateButtonState(bool newState) { - ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool)); - } - -private: - BLE &ble; - ReadOnlyGattCharacteristic buttonState; -}; - -#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */ diff --git a/BLE_Button/source/main.cpp b/BLE_Button/source/main.cpp deleted file mode 100644 index 9516db5e..00000000 --- a/BLE_Button/source/main.cpp +++ /dev/null @@ -1,166 +0,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 - -#include -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ButtonService.h" -#include "pretty_printer.h" - -const static char DEVICE_NAME[] = "Button"; - -static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE); - - -class BatteryDemo : ble::Gap::EventHandler { -public: - BatteryDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _led1(LED1, 1), - _button(BLE_BUTTON_PIN_NAME), - _button_service(NULL), - _button_uuid(ButtonService::BUTTON_SERVICE_UUID), - _adv_data_builder(_adv_buffer) { } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &BatteryDemo::on_init_complete); - - _event_queue.call_every(500, this, &BatteryDemo::blink); - - _event_queue.dispatch_forever(); - } - -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - printf("Ble initialization failed."); - return; - } - - print_mac_address(); - - /* Setup primary service. */ - - _button_service = new ButtonService(_ble, false /* initial value for button pressed */); - - _button.fall(Callback(this, &BatteryDemo::button_pressed)); - _button.rise(Callback(this, &BatteryDemo::button_released)); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - uint8_t adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - - ble::AdvertisingDataBuilder adv_data_builder(adv_buffer); - - adv_data_builder.setFlags(); - adv_data_builder.setLocalServiceList(mbed::make_Span(&_button_uuid, 1)); - adv_data_builder.setName(DEVICE_NAME); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingPayload() failed"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "_ble.gap().startAdvertising() failed"); - return; - } - } - - void button_pressed(void) { - _event_queue.call(Callback(_button_service, &ButtonService::updateButtonState), true); - } - - void button_released(void) { - _event_queue.call(Callback(_button_service, &ButtonService::updateButtonState), false); - } - - void blink(void) { - _led1 = !_led1; - } - -private: - /* Event handler */ - - virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - - DigitalOut _led1; - InterruptIn _button; - ButtonService *_button_service; - - UUID _button_uuid; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - BatteryDemo demo(ble, event_queue); - demo.start(); - - return 0; -} - diff --git a/BLE_Button/source/pretty_printer.h b/BLE_Button/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_Button/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_GAP/.mbed b/BLE_GAP/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_GAP/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_GAP/CMakeLists.txt b/BLE_GAP/CMakeLists.txt new file mode 100644 index 00000000..f046279a --- /dev/null +++ b/BLE_GAP/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GAP) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_GAP/README.md b/BLE_GAP/README.md index 8f6132b9..8ccd40a9 100644 --- a/BLE_GAP/README.md +++ b/BLE_GAP/README.md @@ -9,7 +9,7 @@ and print over the serial connection information about current activity. The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. +- [nRF Connect for Mobile](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. diff --git a/BLE_GAP/mbed-os-ble-utils.lib b/BLE_GAP/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GAP/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GAP/mbed-os.lib b/BLE_GAP/mbed-os.lib index 38ad3522..144619b6 100644 --- a/BLE_GAP/mbed-os.lib +++ b/BLE_GAP/mbed-os.lib @@ -1 +1 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GAP/mbed_app.json b/BLE_GAP/mbed_app.json index f6d83692..f81ce44c 100644 --- a/BLE_GAP/mbed_app.json +++ b/BLE_GAP/mbed_app.json @@ -1,26 +1,28 @@ { "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, "K64F": { + "target.components_add": ["BlueNRG_MS"], "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] + "target.extra_labels_add": ["CORDIO"] }, "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] + "target.extra_labels_add": ["CORDIO"] }, "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] + "target.features_add": ["BLE"] }, "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] + "target.features_add": ["BLE"] } } } diff --git a/BLE_GAP/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_GAP/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_GAP/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_GAP/source/main.cpp b/BLE_GAP/source/main.cpp index aff9dc93..010107c1 100644 --- a/BLE_GAP/source/main.cpp +++ b/BLE_GAP/source/main.cpp @@ -15,101 +15,89 @@ */ #include -#include #include "ble/BLE.h" -#include "gap/Gap.h" -#include "gap/AdvertisingDataParser.h" #include "pretty_printer.h" +#include "mbed-trace/mbed_trace.h" /** This example demonstrates all the basic setup required - * to advertise, scan and connect to other devices. + * to advertise and scan. * * It contains a single class that performs both scans and advertisements. * * The demonstrations happens in sequence, after each "mode" ends - * the demo jumps to the next mode to continue. There are several modes - * that show scanning and several showing advertising. These are configured - * according to the two arrays containing parameters. During scanning - * a connection will be made to a connectable device upon its discovery. + * the demo jumps to the next mode to continue. + * + * You may connect to the device during advertising and if you advertise + * this demo will try to connect during the scanning phase. Connection + * will terminate the phase early. At the end of the phase some stats + * will be shown about the phase. */ -events::EventQueue event_queue; - -/* Duration of each mode in milliseconds */ -static const size_t MODE_DURATION_MS = 6000; - -/* Time between each mode in milliseconds */ -static const size_t TIME_BETWEEN_MODES_MS = 2000; - -/* how long to wait before disconnecting in milliseconds */ -static const size_t CONNECTION_DURATION = 3000; - -/* how many advertising sets we want to crate at once */ -static const uint8_t ADV_SET_NUMBER = 2; +/* demo config */ +/* you can adjust these parameters and see the effect on the performance */ -static const uint16_t MAX_ADVERTISING_PAYLOAD_SIZE = 1000; +/* Advertising parameters are mainly defined by an advertising type and + * and an interval between advertisements. Lower interval increases the + * chances of being seen at the cost of increased power usage. + * + * The Bluetooth controller may run concurrent operations with the radio; + * to help it, a minimum and maximum advertising interval should be + * provided. + * + * Most bluetooth time units are specific to each operation. For example + * adv_interval_t is expressed in multiples of 625 microseconds. If precision + * is not require you may use a conversion from milliseconds. + */ +static const ble::AdvertisingParameters advertising_params( + ble::advertising_type_t::CONNECTABLE_UNDIRECTED, + ble::adv_interval_t(ble::millisecond_t(25)), /* this could also be expressed as ble::adv_interval_t(40) */ + ble::adv_interval_t(ble::millisecond_t(50)) /* this could also be expressed as ble::adv_interval_t(80) */ +); + +/* if the controller support it we can advertise multiple sets */ +static const ble::AdvertisingParameters extended_advertising_params( + ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED, + ble::adv_interval_t(600), + ble::adv_interval_t(800) +); + +static const std::chrono::milliseconds advertising_duration = 10000ms; + +/* Scanning happens repeatedly and is defined by: + * - The scan interval which is the time (in 0.625us) between each scan cycle. + * - The scan window which is the scanning time (in 0.625us) during a cycle. + * If the scanning process is active, the local device sends scan requests + * to discovered peer to get additional data. + */ +static const ble::ScanParameters scan_params( + ble::phy_t::LE_1M, + ble::scan_interval_t(80), + ble::scan_window_t(60), + false /* active scanning */ +); -typedef struct { - ble::advertising_type_t type; - ble::adv_interval_t min_interval; - ble::adv_interval_t max_interval; -} DemoAdvParams_t; +static const ble::scan_duration_t scan_duration(ble::millisecond_t(10000)); -typedef struct { - ble::scan_interval_t interval; - ble::scan_window_t window; - ble::scan_duration_t duration; - bool active; -} DemoScanParam_t; +/* config end */ -/** the entries in this array are used to configure our advertising - * parameters for each of the modes we use in our demo */ -static const DemoAdvParams_t advertising_params[] = { -/* advertising type | min interval - 0.625us | max interval - 0.625us */ - { ble::advertising_type_t::CONNECTABLE_UNDIRECTED, ble::adv_interval_t(40), ble::adv_interval_t(80) }, - { ble::advertising_type_t::SCANNABLE_UNDIRECTED, ble::adv_interval_t(100), ble::adv_interval_t(200) }, - { ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED, ble::adv_interval_t(100), ble::adv_interval_t(200) } -}; +events::EventQueue event_queue; -/* when we cycle through all our advertising modes we will move to scanning modes */ - -/** the entries in this array are used to configure our scanning - * parameters for each of the modes we use in our demo */ -static const DemoScanParam_t scanning_params[] = { -/* interval window duration active */ -/* 0.625ms 0.625ms 10ms */ - { ble::scan_interval_t(4), ble::scan_window_t(4), ble::scan_duration_t(0), false }, - { ble::scan_interval_t(160), ble::scan_window_t(100), ble::scan_duration_t(300), false }, - { ble::scan_interval_t(160), ble::scan_window_t(40), ble::scan_duration_t(0), true }, - { ble::scan_interval_t(500), ble::scan_window_t(10), ble::scan_duration_t(0), false } -}; +using namespace std::chrono; +using std::milli; +using namespace std::literals::chrono_literals; -/* helper that gets the number of items in arrays */ -template -size_t size(const T (&)[N]) -{ - return N; -} +/* Delay between steps */ +static const std::chrono::milliseconds delay = 3000ms; -/** Demonstrate advertising, scanning and connecting - */ +/** Demonstrate advertising, scanning and connecting */ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandler { public: GapDemo(BLE& ble, events::EventQueue& event_queue) : _ble(ble), _gap(ble.gap()), - _event_queue(event_queue), - _led1(LED1, 0), - _set_index(0), - _is_in_scanning_mode(true), - _is_connecting(false), - _on_duration_end_id(0), - _scan_count(0), - _blink_event(0) { - for (uint8_t i = 0; i < size(_adv_handles); ++i) { - _adv_handles[i] = ble::INVALID_ADVERTISING_HANDLE; - } + _event_queue(event_queue) + { } ~GapDemo() @@ -122,11 +110,6 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle /** Start BLE interface initialisation */ void run() { - if (_ble.hasInitialized()) { - printf("Ble instance already initialised.\r\n"); - return; - } - /* handle gap events */ _gap.setEventHandler(this); @@ -136,9 +119,6 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle return; } - /* to show we're running we'll blink every 500ms */ - _blink_event = _event_queue.call_every(500, this, &GapDemo::blink); - /* this will not return until shutdown */ _event_queue.dispatch_forever(); } @@ -155,88 +135,41 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle print_mac_address(); /* setup the default phy used in connection to 2M to reduce power consumption */ - if (is_2m_phy_supported()) { + if (_gap.isFeatureSupported(ble::controller_supported_features_t::LE_2M_PHY)) { ble::phy_set_t phys(/* 1M */ false, /* 2M */ true, /* coded */ false); ble_error_t error = _gap.setPreferredPhys(/* tx */&phys, /* rx */&phys); + + /* PHY 2M communication will only take place if both peers support it */ if (error) { print_error(error, "GAP::setPreferedPhys failed"); } - } - - /* all calls are serialised on the user thread through the event queue */ - _event_queue.call(this, &GapDemo::demo_mode_start); - } - - /** queue up start of the current demo mode */ - void demo_mode_start() - { - if (_is_in_scanning_mode) { - _event_queue.call(this, &GapDemo::scan); } else { - _event_queue.call(this, &GapDemo::advertise); + /* otherwise it will use 1M by default */ } - /* for performance measurement keep track of duration of the demo mode */ - _demo_duration.start(); - /* keep track of our state */ - _is_connecting = false; - - /* queue up next demo mode */ - _on_duration_end_id = _event_queue.call_in( - MODE_DURATION_MS, - this, - &GapDemo::end_demo_mode - ); - - printf("\r\n"); + /* all calls are serialised on the user thread through the event queue */ + _event_queue.call(this, &GapDemo::advertise); } /** Set up and start advertising */ void advertise() { - const DemoAdvParams_t &adv_params = advertising_params[_set_index]; - - /* - * Advertising parameters are mainly defined by an advertising type and - * and an interval between advertisements. lower interval increases the - * chances of being seen at the cost of more power. - * The Bluetooth controller may run concurrent operations with the radio; - * to help it, a minimum and maximum advertising interval should be - * provided. - * - * With Bluetooth 5; it is possible to advertise concurrently multiple - * payloads at different rate. The combination of payload and its associated - * parameters is named an advertising set. To refer to these advertising - * sets the Bluetooth system use an advertising set handle that needs to - * be created first. - * The only exception is the legacy advertising handle which is usable - * on Bluetooth 4 and Bluetooth 5 system. It is created at startup and - * its lifecycle is managed by the system. - */ - ble_error_t error = _gap.setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - ble::AdvertisingParameters( - adv_params.type, - adv_params.min_interval, - adv_params.max_interval - ) - ); + ble_error_t error = _gap.setAdvertisingParameters(ble::LEGACY_ADVERTISING_HANDLE, advertising_params); if (error) { print_error(error, "Gap::setAdvertisingParameters() failed"); return; } + /* to create a payload we'll use a helper class that builds a valid payload */ + /* AdvertisingDataSimpleBuilder is a wrapper over AdvertisingDataBuilder that allocated the buffer for us */ + ble::AdvertisingDataSimpleBuilder data_builder; + + /* builder methods can be chained together as they return the builder object */ + data_builder.setFlags().setName("Legacy Set"); + /* Set payload for the set */ - /* Use the simple builder to construct the payload; it fails at runtime - * if there is not enough space left in the buffer */ - error = _gap.setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - ble::AdvertisingDataSimpleBuilder() - .setFlags() - .setName("Legacy advertiser") - .getAdvertisingData() - ); + error = _gap.setAdvertisingPayload(ble::LEGACY_ADVERTISING_HANDLE, data_builder.getAdvertisingData()); if (error) { print_error(error, "Gap::setAdvertisingPayload() failed"); return; @@ -249,122 +182,68 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle return; } - printf("Advertising started (type: 0x%x, interval: [%d : %d]ms)\r\n", - adv_params.type.value(), - adv_params.min_interval.valueInMs(), adv_params.max_interval.valueInMs() ); - - if (is_extended_advertising_supported()) { - advertise_extended(); - } - } - - void advertise_extended() - { - const DemoAdvParams_t &adv_params = advertising_params[_set_index]; - - /* this is the memory backing for the payload */ - uint8_t adv_buffer[MAX_ADVERTISING_PAYLOAD_SIZE]; - - /* how many sets */ - uint8_t max_adv_set = std::min( - _gap.getMaxAdvertisingSetNumber(), - (uint8_t) size(_adv_handles) - ); - - /* one advertising set is reserved for legacy advertising */ - if (max_adv_set < 2) { - return; - } - - /* how much payload in a set */ - uint16_t max_adv_size = std::min( - (uint16_t) _gap.getMaxAdvertisingDataLength(), - MAX_ADVERTISING_PAYLOAD_SIZE + printf( + "\r\nAdvertising started (type: 0x%x, interval: [%d : %d]ms)\r\n", + advertising_params.getType(), + advertising_params.getMinPrimaryInterval().valueInMs(), + advertising_params.getMaxPrimaryInterval().valueInMs() ); - /* create and start all requested (and possible) advertising sets */ - for (uint8_t i = 0; i < (max_adv_set - 1); ++i) { - /* create the advertising set with its parameter */ - /* this time we do not use legacy PDUs */ - ble_error_t error = _gap.createAdvertisingSet( - &_adv_handles[i], - ble::AdvertisingParameters( - adv_params.type, - adv_params.min_interval, - adv_params.max_interval - ).setUseLegacyPDU(false) - ); +#if BLE_FEATURE_EXTENDED_ADVERTISING + /* if we support extended advertising we'll also additionally advertise another set at the same time */ + if (_gap.isFeatureSupported(ble::controller_supported_features_t::LE_EXTENDED_ADVERTISING)) { + /* With Bluetooth 5; it is possible to advertise concurrently multiple + * payloads at different rate. The combination of payload and its associated + * parameters is named an advertising set. To refer to these advertising + * sets the Bluetooth system use an advertising set handle that needs to + * be created first. + * The only exception is the legacy advertising handle which is usable + * on Bluetooth 4 and Bluetooth 5 system. It is created at startup and + * its lifecycle is managed by the system. + */ + ble_error_t error = _gap.createAdvertisingSet(&_extended_adv_handle, extended_advertising_params); if (error) { print_error(error, "Gap::createAdvertisingSet() failed"); return; } - /* use the helper to build the payload */ - ble::AdvertisingDataBuilder adv_data_builder( - adv_buffer, - max_adv_size - ); - - /* set the flags */ - error = adv_data_builder.setFlags(); - if (error) { - print_error(error, "AdvertisingDataBuilder::setFlags() failed"); - return; - } - - /* set different name for each set */ - MBED_ASSERT(i < 9); - char device_name[] = "Advertiser x"; - snprintf(device_name, size(device_name), "Advertiser %d", i%10); - error = adv_data_builder.setName(device_name); - if (error) { - print_error(error, "AdvertisingDataBuilder::setName() failed"); - return; - } + /* we can reuse the builder, we just replace the name */ + data_builder.setName("Extended Set"); /* Set payload for the set */ - error = _gap.setAdvertisingPayload( - _adv_handles[i], - adv_data_builder.getAdvertisingData() - ); + error = _gap.setAdvertisingPayload(_extended_adv_handle, data_builder.getAdvertisingData()); if (error) { print_error(error, "Gap::setAdvertisingPayload() failed"); return; } /* Start advertising the set */ - error = _gap.startAdvertising(_adv_handles[i]); + error = _gap.startAdvertising(_extended_adv_handle); if (error) { print_error(error, "Gap::startAdvertising() failed"); return; } - printf("Advertising started (type: 0x%x, interval: [%d : %d]ms)\r\n", - adv_params.type.value(), - adv_params.min_interval.valueInMs(), adv_params.max_interval.valueInMs() ); + printf( + "Advertising started (type: 0x%x, interval: [%d : %d]ms)\r\n", + extended_advertising_params.getType(), + extended_advertising_params.getMinPrimaryInterval().valueInMs(), + extended_advertising_params.getMaxPrimaryInterval().valueInMs() + ); } +#endif // BLE_FEATURE_EXTENDED_ADVERTISING + + _demo_duration.reset(); + _demo_duration.start(); + + /* this will stop advertising if no connection takes place in the meantime */ + _cancel_handle = _event_queue.call_in(advertising_duration, [this]{ end_advertising_mode(); }); } /** Set up and start scanning */ void scan() { - const DemoScanParam_t &scan_params = scanning_params[_set_index]; - - /* - * Scanning happens repeatedly and is defined by: - * - The scan interval which is the time (in 0.625us) between each scan cycle. - * - The scan window which is the scanning time (in 0.625us) during a cycle. - * If the scanning process is active, the local device sends scan requests - * to discovered peer to get additional data. - */ - ble_error_t error = _gap.setScanParameters( - ble::ScanParameters( - ble::phy_t::LE_1M, // scan on the 1M PHY - scan_params.interval, - scan_params.window, - scan_params.active - ) - ); + ble_error_t error = _gap.setScanParameters(scan_params); if (error) { print_error(error, "Error caused by Gap::setScanParameters"); return; @@ -372,52 +251,32 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle /* start scanning and attach a callback that will handle advertisements * and scan requests responses */ - error = _gap.startScan(scan_params.duration); + error = _gap.startScan(scan_duration); if (error) { print_error(error, "Error caused by Gap::startScan"); return; } - printf("Scanning started (interval: %dms, window: %dms, timeout: %dms).\r\n", - scan_params.interval.valueInMs(), scan_params.window.valueInMs(), scan_params.duration.valueInMs()); - } + printf("\r\nScanning started (interval: %dms, window: %dms, timeout: %dms).\r\n", + scan_params.get1mPhyConfiguration().getInterval().valueInMs(), + scan_params.get1mPhyConfiguration().getWindow().valueInMs(), + scan_duration.valueInMs()); - /** Finish the mode by shutting down advertising or scanning and move to the next mode. */ - void end_demo_mode() - { - if (_is_in_scanning_mode) { - end_scanning_mode(); - } else { - end_advertising_mode(); - } - - /* alloted time has elapsed or be connected, move to next demo mode */ - _event_queue.call(this, &GapDemo::next_demo_mode); - } - - /** Execute the disconnection */ - void do_disconnect(ble::connection_handle_t handle) - { - printf("Disconnecting\r\n"); - _gap.disconnect(handle, ble::local_disconnection_reason_t::USER_TERMINATION); - } - - bool is_2m_phy_supported() - { - return _gap.isFeatureSupported(ble::controller_supported_features_t::LE_2M_PHY); + _demo_duration.reset(); + _demo_duration.start(); } - bool is_extended_advertising_supported() + /* helper function to hide the casts */ + int read_demo_duration_in_ms() { - return _gap.isFeatureSupported(ble::controller_supported_features_t::LE_EXTENDED_ADVERTISING); + return duration_cast>(_demo_duration.elapsed_time()).count(); } - private: /* Gap::EventHandler */ /** Look at scan payload to find a peer device and connect to it */ - virtual void onAdvertisingReport(const ble::AdvertisingReportEvent &event) + void onAdvertisingReport(const ble::AdvertisingReportEvent &event) override { /* keep track of scan events for performance reporting */ _scan_count++; @@ -441,14 +300,14 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle /* skip non discoverable device */ if (field.type != ble::adv_data_type_t::FLAGS || field.value.size() != 1 || - !(field.value[0] & GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) { + !ble::adv_data_flags_t(field.value[0]).getGeneralDiscoverable()) { continue; } /* connect to a discoverable device */ /* abort timeout as the mode will end on disconnection */ - _event_queue.cancel(_on_duration_end_id); + _event_queue.cancel(_cancel_handle); printf("We found a connectable device\r\n"); ble_error_t error = _gap.connect( @@ -458,8 +317,6 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle ); if (error) { print_error(error, "Error caused by Gap::connect"); - /* since no connection will be attempted end the mode */ - _event_queue.call(this, &GapDemo::end_demo_mode); return; } @@ -471,74 +328,132 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle } } - virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &event) + void onAdvertisingEnd(const ble::AdvertisingEndEvent &event) override { - if (event.isConnected()) { - printf("Stopped advertising early due to connection\r\n"); + ble::advertising_handle_t adv_handle = event.getAdvHandle(); + if (event.getStatus() == BLE_ERROR_UNSPECIFIED) { + printf("Error: Failed to stop advertising set %d\r\n", adv_handle); + } else { + printf("Stopped advertising set %d\r\n", adv_handle); + + if (event.getStatus() == BLE_ERROR_TIMEOUT) { + printf("Stopped due to timeout\r\n"); + } else if (event.getStatus() == BLE_ERROR_LIMIT_REACHED) { + printf("Stopped due to max number of adv events reached\r\n"); + } else if (event.getStatus() == BLE_ERROR_NONE) { + if (event.isConnected()) { + printf("Stopped early due to connection\r\n"); + } else { + printf("Stopped due to user request\r\n"); + } + } } + +#if BLE_FEATURE_EXTENDED_ADVERTISING + if (event.getAdvHandle() == _extended_adv_handle) { + /* we were waiting for it to stop before destroying it and starting scanning */ + ble_error_t error = _gap.destroyAdvertisingSet(_extended_adv_handle); + if (error) { + print_error(error, "Error caused by Gap::destroyAdvertisingSet"); + } + + _extended_adv_handle = ble::INVALID_ADVERTISING_HANDLE; + + _is_in_scanning_phase = true; + + _event_queue.call_in(delay, [this]{ scan(); }); + } +#endif //BLE_FEATURE_EXTENDED_ADVERTISING } - virtual void onScanTimeout(const ble::ScanTimeoutEvent&) + void onAdvertisingStart(const ble::AdvertisingStartEvent &event) override { - printf("Stopped scanning early due to timeout parameter\r\n"); - _demo_duration.stop(); + printf("Advertising set %d started\r\n", event.getAdvHandle()); + } + + void onScanTimeout(const ble::ScanTimeoutEvent&) override + { + printf("Stopped scanning due to timeout parameter\r\n"); + _event_queue.call(this, &GapDemo::end_scanning_mode); } /** This is called by Gap to notify the application we connected, * in our case it immediately disconnects */ - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) + void onConnectionComplete(const ble::ConnectionCompleteEvent &event) override { + _is_connecting = false; _demo_duration.stop(); - if (event.getStatus() == BLE_ERROR_NONE) { - printf("Connected in %dms\r\n", _demo_duration.read_ms()); - - /* cancel the connect timeout since we connected */ - _event_queue.cancel(_on_duration_end_id); +#if BLE_FEATURE_EXTENDED_ADVERTISING + if (!_is_in_scanning_phase) { + /* if we have more than one advertising sets one of them might still be active */ + if (_extended_adv_handle != ble::INVALID_ADVERTISING_HANDLE) { + /* if it's still active, stop it */ + if (_gap.isAdvertisingActive(_extended_adv_handle)) { + _gap.stopAdvertising(_extended_adv_handle); + } else if (_gap.isAdvertisingActive(ble::LEGACY_ADVERTISING_HANDLE)) { + _gap.stopAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + } + } + } +#endif // BLE_FEATURE_EXTENDED_ADVERTISING - _event_queue.call_in( - CONNECTION_DURATION, - this, - &GapDemo::do_disconnect, - event.getConnectionHandle() - ); - } else { - printf("Failed to connect after scanning %d advertisements\r\n", _scan_count); - _event_queue.call(this, &GapDemo::end_demo_mode); + if (event.getStatus() != BLE_ERROR_NONE) { + print_error(event.getStatus(), "Connection failed"); + return; } + + printf("Connected in %dms\r\n", read_demo_duration_in_ms()); + + /* cancel the connect timeout since we connected */ + _event_queue.cancel(_cancel_handle); + + _cancel_handle = _event_queue.call_in( + delay, + [this, handle=event.getConnectionHandle()]{ + _gap.disconnect(handle, ble::local_disconnection_reason_t::USER_TERMINATION); + } + ); + } /** This is called by Gap to notify the application we disconnected, * in our case it calls next_demo_mode() to progress the demo */ - virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) + void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) override { printf("Disconnected\r\n"); - /* we have successfully disconnected ending the demo, move to next mode */ - _event_queue.call(this, &GapDemo::end_demo_mode); + /* if it wasn't us disconnecting then we should cancel our attempt */ + if (event.getReason() == ble::disconnection_reason_t::REMOTE_USER_TERMINATED_CONNECTION) { + _event_queue.cancel(_cancel_handle); + } + + if (_is_in_scanning_phase) { + _event_queue.call(this, &GapDemo::end_scanning_mode); + } else { + _event_queue.call(this, &GapDemo::end_advertising_mode); + } } /** * Implementation of Gap::EventHandler::onReadPhy */ - virtual void onReadPhy( + void onReadPhy( ble_error_t error, ble::connection_handle_t connectionHandle, ble::phy_t txPhy, ble::phy_t rxPhy - ) { + ) override + { if (error) { printf( "Phy read on connection %d failed with error code %s\r\n", - connectionHandle, - BLE::errorToString(error) + connectionHandle, BLE::errorToString(error) ); } else { printf( "Phy read on connection %d - Tx Phy: %s, Rx Phy: %s\r\n", - connectionHandle, - phy_to_string(txPhy), - phy_to_string(rxPhy) + connectionHandle, phy_to_string(txPhy), phy_to_string(rxPhy) ); } } @@ -546,53 +461,44 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle /** * Implementation of Gap::EventHandler::onPhyUpdateComplete */ - virtual void onPhyUpdateComplete( + void onPhyUpdateComplete( ble_error_t error, ble::connection_handle_t connectionHandle, ble::phy_t txPhy, ble::phy_t rxPhy - ) { + ) override + { if (error) { printf( "Phy update on connection: %d failed with error code %s\r\n", - connectionHandle, - BLE::errorToString(error) + connectionHandle, BLE::errorToString(error) ); } else { printf( "Phy update on connection %d - Tx Phy: %s, Rx Phy: %s\r\n", - connectionHandle, - phy_to_string(txPhy), - phy_to_string(rxPhy) + connectionHandle, phy_to_string(txPhy), phy_to_string(rxPhy) ); } } -private: - - /** Clean up internal state after last run, cycle to the next mode and launch it */ - void next_demo_mode() + /** + * Implementation of Gap::EventHandler::onDataLengthChange + */ + void onDataLengthChange( + ble::connection_handle_t connectionHandle, + uint16_t txSize, + uint16_t rxSize + ) override { - /* reset the demo ready for the next mode */ - _scan_count = 0; - _demo_duration.stop(); - _demo_duration.reset(); - - /* cycle through all demo modes */ - _set_index++; - - /* switch between advertising and scanning when we go - * through all the params in the array */ - if (_set_index >= (_is_in_scanning_mode ? size(scanning_params) : size(advertising_params))) { - _set_index = 0; - _is_in_scanning_mode = !_is_in_scanning_mode; - } - - _ble.shutdown(); - _event_queue.cancel(_blink_event); - _event_queue.break_dispatch(); + printf( + "Data length changed on the connection %d.\r\n" + "Maximum sizes for over the air packets are:\r\n" + "%d octets for transmit and %d octets for receive.\r\n", + connectionHandle, txSize, rxSize + ); } +private: /** Finish the mode by shutting down advertising or scanning and move to the next mode. */ void end_scanning_mode() { @@ -602,66 +508,60 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle if (error) { print_error(error, "Error caused by Gap::stopScan"); } + + _is_in_scanning_phase = false; + _scan_count = 0; + + _event_queue.call_in(delay, this, &GapDemo::advertise); } void end_advertising_mode() { print_advertising_performance(); - _gap.stopAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + printf("Requesting stop advertising.\r\n"); - if (is_extended_advertising_supported()) { - end_extended_advertising(); - } - } - - void end_extended_advertising() - { - /* iterate over the advertising handles */ - for (uint8_t i = 0; i < size(_adv_handles); ++i) { - /* check if the set has been sucesfully created */ - if (_adv_handles[i] == ble::INVALID_ADVERTISING_HANDLE) { - continue; - } + _gap.stopAdvertising(ble::LEGACY_ADVERTISING_HANDLE); +#if BLE_FEATURE_EXTENDED_ADVERTISING + if (_extended_adv_handle != ble::INVALID_ADVERTISING_HANDLE) { /* if it's still active, stop it */ - if (_gap.isAdvertisingActive(_adv_handles[i])) { - ble_error_t error = _gap.stopAdvertising(_adv_handles[i]); + if (_gap.isAdvertisingActive(_extended_adv_handle)) { + ble_error_t error = _gap.stopAdvertising(_extended_adv_handle); if (error) { print_error(error, "Error caused by Gap::stopAdvertising"); - continue; } } - - ble_error_t error = _gap.destroyAdvertisingSet(_adv_handles[i]); - if (error) { - print_error(error, "Error caused by Gap::destroyAdvertisingSet"); - continue; - } - - _adv_handles[i] = ble::INVALID_ADVERTISING_HANDLE; } + /* we have to wait before we destroy it until it's stopped */ +#else + _is_in_scanning_phase = true; + + _event_queue.call_in(delay, [this]{ scan(); }); +#endif // BLE_FEATURE_EXTENDED_ADVERTISING } /** print some information about our radio activity */ void print_scanning_performance() { /* measure time from mode start, may have been stopped by timeout */ - uint16_t duration_ms = _demo_duration.read_ms(); + uint16_t duration_ms = read_demo_duration_in_ms(); /* convert ms into timeslots for accurate calculation as internally * all durations are in timeslots (0.625ms) */ uint16_t duration_ts = ble::scan_interval_t(ble::millisecond_t(duration_ms)).value(); - uint16_t interval_ts = scanning_params[_set_index].interval.value(); - uint16_t window_ts = scanning_params[_set_index].window.value(); + uint16_t interval_ts = scan_params.get1mPhyConfiguration().getInterval().value(); + uint16_t window_ts = scan_params.get1mPhyConfiguration().getWindow().value(); /* this is how long we scanned for in timeslots */ uint16_t rx_ts = (duration_ts / interval_ts) * window_ts; /* convert to milliseconds */ uint16_t rx_ms = ble::scan_interval_t(rx_ts).valueInMs(); - printf("We have scanned for %dms with an interval of %d" - " timeslots and a window of %d timeslots\r\n", - duration_ms, interval_ts, window_ts); + printf( + "We have scanned for %dms with an interval of %d" + " timeslots and a window of %d timeslots\r\n", + duration_ms, interval_ts, window_ts + ); printf("We have been listening on the radio for at least %dms\r\n", rx_ms); } @@ -670,77 +570,79 @@ class GapDemo : private mbed::NonCopyable, public ble::Gap::EventHandle void print_advertising_performance() { /* measure time from mode start, may have been stopped by timeout */ - uint16_t duration_ms = _demo_duration.read_ms(); - uint8_t number_of_active_sets = 0; - - for (uint8_t i = 0; i < size(_adv_handles); ++i) { - if (_adv_handles[i] != ble::INVALID_ADVERTISING_HANDLE) { - if (_gap.isAdvertisingActive(_adv_handles[i])) { - number_of_active_sets++; - } - } - } + uint16_t duration_ms = read_demo_duration_in_ms(); /* convert ms into timeslots for accurate calculation as internally * all durations are in timeslots (0.625ms) */ uint16_t duration_ts = ble::adv_interval_t(ble::millisecond_t(duration_ms)).value(); - uint16_t interval_ts = advertising_params[_set_index].max_interval.value(); + uint16_t interval_ts = advertising_params.getMaxPrimaryInterval().value(); /* this is how many times we advertised */ - uint16_t events = (duration_ts / interval_ts) * number_of_active_sets; - - printf("We have advertised for %dms with an interval of at least %d timeslots\r\n", - duration_ms, interval_ts); - - if (number_of_active_sets > 1) { - printf("We had %d active advertising sets\r\n", number_of_active_sets); + uint16_t events = (duration_ts / interval_ts); + uint16_t extended_events = 0; + +#if BLE_FEATURE_EXTENDED_ADVERTISING + if (_extended_adv_handle != ble::INVALID_ADVERTISING_HANDLE) { + duration_ts = ble::adv_interval_t(ble::millisecond_t(duration_ms)).value(); + interval_ts = extended_advertising_params.getMaxPrimaryInterval().value(); + /* this is how many times we advertised */ + extended_events = (duration_ts / interval_ts); } +#endif // BLE_FEATURE_EXTENDED_ADVERTISING + + printf("We have advertised for %dms\r\n", duration_ms); /* non-scannable and non-connectable advertising * skips rx events saving on power consumption */ - if (advertising_params[_set_index].type == ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED) { + if (advertising_params.getType() == ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED) { printf("We created at least %d tx events\r\n", events); } else { printf("We created at least %d tx and rx events\r\n", events); } - } - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; +#if BLE_FEATURE_EXTENDED_ADVERTISING + if (extended_events) { + if (extended_advertising_params.getType() == ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED) { + printf("We created at least %d tx events with extended advertising\r\n", extended_events); + } else { + printf("We created at least %d tx and rx events with extended advertising\r\n", extended_events); + } + } + +#endif // BLE_FEATURE_EXTENDED_ADVERTISING } private: - BLE &_ble; - ble::Gap &_gap; + BLE &_ble; + ble::Gap &_gap; events::EventQueue &_event_queue; - DigitalOut _led1; /* Keep track of our progress through demo modes */ - size_t _set_index; - bool _is_in_scanning_mode; - bool _is_connecting; + bool _is_in_scanning_phase = false; + bool _is_connecting = false; /* Remember the call id of the function on _event_queue - * so we can cancel it if we need to end the mode early */ - int _on_duration_end_id; + * so we can cancel it if we need to end the phase early */ + int _cancel_handle = 0; /* Measure performance of our advertising/scanning */ - Timer _demo_duration; - size_t _scan_count; - - int _blink_event; + Timer _demo_duration; + size_t _scan_count = 0; - ble::advertising_handle_t _adv_handles[ADV_SET_NUMBER]; +#if BLE_FEATURE_EXTENDED_ADVERTISING + ble::advertising_handle_t _extended_adv_handle = ble::INVALID_ADVERTISING_HANDLE; +#endif // BLE_FEATURE_EXTENDED_ADVERTISING }; /** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ event_queue.call(Callback(&context->ble, &BLE::processEvents)); } int main() { + mbed_trace_init(); + BLE &ble = BLE::Instance(); /* this will inform us off all events so we can schedule their handling @@ -749,11 +651,7 @@ int main() GapDemo demo(ble, event_queue); - while (1) { - demo.run(); - wait_ms(TIME_BETWEEN_MODES_MS); - printf("\r\nStarting next GAP demo mode\r\n"); - }; + demo.run(); return 0; } diff --git a/BLE_GAP/source/pretty_printer.h b/BLE_GAP/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_GAP/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_GAPButton/.mbed b/BLE_GAPButton/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_GAPButton/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_GAPButton/README.md b/BLE_GAPButton/README.md deleted file mode 100644 index 65b76c64..00000000 --- a/BLE_GAPButton/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# Button count over GAP - -This application shows how to use GAP to transmit a simple value to a disconnected peer listening for advertisement every time that a value is updated: - -1. The value is a count of how many times a button on the device was pressed (the code actually monitors the button's releases, not press downs). - -1. We transmit the value in the SERVICE_DATA field of the advertising payload. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -### Porting this example on new boards - -This example requires a board with at least 1 button to work. While the pin name of the button is defined for the `NRF51_DK`, `NRF52_DK`, `K64F` and `NUCLEO_F401RE`, it is not specified for other boards. - -It is easy to add the button configuration for your board: -* Open the file named `mbed_app.json` at the root of this example. -* In the section `target_overides` add a new object named after your target if it doesn't exist. This object contain overridden parameters for your target. -* Override the property `ble_button_pin_name` in your target object. The value of the property should be equal to the pin name to use as a button. - -As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. - -```json - "NUCLEO_F411RE": { - "ble_button_pin_name": "USER_BUTTON" - } -``` - - **Note:** You can get more informations about the configuration system in the [documentation](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) - - **Important:** If your target use an ST BLE shield, other parameters have to be overridden for your target. More information are available in the global [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md#targets-for-ble) - - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. - -1. Open the BLE scanner on your phone. - -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5. - -1. Find your device; it should be named `GAPButton`; and look at the advertisement broadcasted by your device (there is no need to connect to your device). - - ![](img/discovery.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5. - -1. The Service Data field of the advertisement packet broadcasted by your device reflects the button press count. The starting value is 0. - - ![](img/initial_state.png) - - **figure 3** Initial state of the button using nRF Master Control Panel 4.0.5. - -1. Press the button on the device. - - ![](img/first_press.png) - - **figure 3** State after 1 button press using nRF Master Control Panel 4.0.5. - -1. The Service Data field value of the advertisement packet should change every time you press the button. - - ![](img/result.png) - - **figure 3** State after 6 button press using nRF Master Control Panel 4.0.5. - -## Note - -Since broadcasting is not reliable and your phone may scan intermittently, it is possible that your phone will miss button updates. diff --git a/BLE_GAPButton/img/discovery.png b/BLE_GAPButton/img/discovery.png deleted file mode 100644 index 21010d54..00000000 Binary files a/BLE_GAPButton/img/discovery.png and /dev/null differ diff --git a/BLE_GAPButton/img/first_press.png b/BLE_GAPButton/img/first_press.png deleted file mode 100644 index f72cb1ee..00000000 Binary files a/BLE_GAPButton/img/first_press.png and /dev/null differ diff --git a/BLE_GAPButton/img/initial_state.png b/BLE_GAPButton/img/initial_state.png deleted file mode 100644 index 22adc383..00000000 Binary files a/BLE_GAPButton/img/initial_state.png and /dev/null differ diff --git a/BLE_GAPButton/img/result.png b/BLE_GAPButton/img/result.png deleted file mode 100644 index c0681355..00000000 Binary files a/BLE_GAPButton/img/result.png and /dev/null differ diff --git a/BLE_GAPButton/img/start_scan.png b/BLE_GAPButton/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/BLE_GAPButton/img/start_scan.png and /dev/null differ diff --git a/BLE_GAPButton/mbed-os.lib b/BLE_GAPButton/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_GAPButton/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_GAPButton/mbed_app.json b/BLE_GAPButton/mbed_app.json deleted file mode 100644 index 92571a16..00000000 --- a/BLE_GAPButton/mbed_app.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "config": { - "ble_button_pin_name": { - "help": "The pin name used as button in this application", - "macro_name": "BLE_BUTTON_PIN_NAME", - "required": true - } - }, - "target_overrides": { - "NRF51_DK": { - "ble_button_pin_name": "BUTTON1" - }, - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "SW2" - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"], - "ble_button_pin_name": "BUTTON1" - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"], - "ble_button_pin_name": "BUTTON1" - }, - "MTB_UBLOX_NINA_B1": { - "ble_button_pin_name": "BUTTON1" - } - } -} diff --git a/BLE_GAPButton/module.json b/BLE_GAPButton/module.json deleted file mode 100644 index 83c154cf..00000000 --- a/BLE_GAPButton/module.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "ble-gapbutton", - "version": "0.0.1", - "bin": "./source", - "description": "BLE button that uses gap advertisement to broadcast its state.", - "author": "Liyou Zhou", - "license": "Apache-2.0", - "dependencies": { - "mbed-drivers": "*", - "ble": "^2.0.0" - } -} diff --git a/BLE_GAPButton/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_GAPButton/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_GAPButton/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_GAPButton/source/main.cpp b/BLE_GAPButton/source/main.cpp deleted file mode 100644 index 0fdd26e9..00000000 --- a/BLE_GAPButton/source/main.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-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 -#include -#include "ble/BLE.h" -#include "pretty_printer.h" - -static const char DEVICE_NAME[] = "GAPButton"; - -static EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -/** Demonstrate advertising, scanning and connecting - */ -class GapButtonDemo : private mbed::NonCopyable, public ble::Gap::EventHandler -{ -public: - GapButtonDemo(BLE& ble, events::EventQueue& event_queue) : - _ble(ble), - _event_queue(event_queue), - _led1(LED1, 0), - /* We can arbiturarily choose the GAPButton service UUID to be 0xAA00 - * as long as it does not overlap with the UUIDs defined here: - * https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */ - _button_uuid(0xAA00), - _button(BLE_BUTTON_PIN_NAME), - _adv_data_builder(_adv_buffer) { } - - ~GapButtonDemo() - { - if (_ble.hasInitialized()) { - _ble.shutdown(); - } - } - - /** Start BLE interface initialisation */ - void run() - { - if (_ble.hasInitialized()) { - printf("Ble instance already initialised.\r\n"); - return; - } - - /* handle gap events */ - _ble.gap().setEventHandler(this); - - ble_error_t error = _ble.init(this, &GapButtonDemo::on_init_complete); - - if (error) { - printf("Error returned by BLE::init.\r\n"); - return; - } - - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &GapButtonDemo::blink); - - /* this will not return until shutdown */ - _event_queue.dispatch_forever(); - } - -private: - /** This is called when BLE interface is initialised and starts the first mode */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - if (event->error) { - printf("Error during the initialisation\r\n"); - return; - } - - print_mac_address(); - - _button.rise(Callback(this, &GapButtonDemo::button_pressed_callback)); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - _adv_data_builder.setFlags(); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_button_uuid, 1)); - _adv_data_builder.setName(DEVICE_NAME); - - update_button_payload(); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingPayload() failed"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "_ble.gap().startAdvertising() failed"); - return; - } - } - - void update_button_payload() - { - /* The Service Data data type consists of a service UUID with the data associated with that service. */ - ble_error_t error = _adv_data_builder.setServiceData( - _button_uuid, - mbed::make_Span(&_button_count, 1) - ); - - if (error != BLE_ERROR_NONE) { - print_error(error, "Updating payload failed"); - } - } - - void button_pressed_callback() - { - ++_button_count; - - /* Calling BLE api in interrupt context may cause race conditions - Using mbed-events to schedule calls to BLE api for safety */ - _event_queue.call(Callback(this, &GapButtonDemo::update_button_payload)); - } - - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; - } - -private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - - DigitalOut _led1; - const UUID _button_uuid; - - InterruptIn _button; - uint8_t _button_count; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - - /* this will inform us of all events so we can schedule their handling - * using our event queue */ - ble.onEventsToProcess(schedule_ble_events); - - GapButtonDemo demo(ble, event_queue); - - demo.run(); - - return 0; -} diff --git a/BLE_GAPButton/source/pretty_printer.h b/BLE_GAPButton/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_GAPButton/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_GattClient/.mbed b/BLE_GattClient/.mbed deleted file mode 100644 index a5265a69..00000000 --- a/BLE_GattClient/.mbed +++ /dev/null @@ -1,2 +0,0 @@ -ROOT=. -TARGET=NRF52_DK diff --git a/BLE_GattClient/README.md b/BLE_GattClient/README.md deleted file mode 100644 index a6fbe00e..00000000 --- a/BLE_GattClient/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# BLE Gatt Client example - -This application demonstrates detailed uses of the GattClient APIs. - -When the application is started it advertises itself to its environment with the -device name `GattClient`. Once you have connected to the device with your mobile -phone, the application starts a discovery of the GATT server exposed by your -mobile phone. - -After the discovery, this application reads the value of the characteristics -discovered and subscribes to the characteristics emitting notifications or -indications. - -The device prints the value of any indication or notification received from the -mobile phone. - -# Running the application - -## Requirements - -You may use a generic BLE scanners: - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - - diff --git a/BLE_GattClient/mbed-os.lib b/BLE_GattClient/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_GattClient/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_GattClient/mbed_app.json b/BLE_GattClient/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_GattClient/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_GattClient/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_GattClient/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_GattClient/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_GattClient/source/BLEProcess.h b/BLE_GattClient/source/BLEProcess.h deleted file mode 100644 index a298477d..00000000 --- a/BLE_GattClient/source/BLEProcess.h +++ /dev/null @@ -1,231 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 GATT_EXAMPLE_BLE_PROCESS_H_ -#define GATT_EXAMPLE_BLE_PROCESS_H_ - -#include -#include - -#include "events/EventQueue.h" -#include "platform/Callback.h" -#include "platform/NonCopyable.h" - -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/FunctionPointerWithContext.h" - -/** - * Handle initialization and shutdown of the BLE Instance. - * - * Setup advertising payload and manage advertising state. - * Delegate to GattClientProcess once the connection is established. - */ -class BLEProcess : private mbed::NonCopyable { -public: - /** - * Construct a BLEProcess from an event queue and a ble interface. - * - * Call start() to initiate ble processing. - */ - BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) : - _event_queue(event_queue), - _ble_interface(ble_interface), - _post_init_cb() { - } - - ~BLEProcess() - { - stop(); - } - - /** - * Initialize the ble interface, configure it and start advertising. - */ - bool start() - { - printf("Ble process started.\r\n"); - - if (_ble_interface.hasInitialized()) { - printf("Error: the ble instance has already been initialized.\r\n"); - return false; - } - - _ble_interface.onEventsToProcess( - makeFunctionPointer(this, &BLEProcess::schedule_ble_events) - ); - - ble_error_t error = _ble_interface.init( - this, &BLEProcess::when_init_complete - ); - - if (error) { - printf("Error: %u returned by BLE::init.\r\n", error); - return false; - } - - return true; - } - - /** - * Close existing connections and stop the process. - */ - void stop() - { - if (_ble_interface.hasInitialized()) { - _ble_interface.shutdown(); - printf("Ble process stopped."); - } - } - - /** - * Subscription to the ble interface initialization event. - * - * @param[in] cb The callback object that will be called when the ble - * interface is initialized. - */ - void on_init(mbed::Callback cb) - { - _post_init_cb = cb; - } - -private: - /** - * Sets up adverting payload and start advertising. - * - * This function is invoked when the ble interface is initialized. - */ - void when_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - if (event->error) { - printf("Error %u during the initialization\r\n", event->error); - return; - } - printf("Ble instance initialized\r\n"); - - Gap &gap = _ble_interface.gap(); - ble_error_t error = gap.setAdvertisingPayload(make_advertising_data()); - if (error) { - printf("Error %u during gap.setAdvertisingPayload\r\n", error); - return; - } - - gap.setAdvertisingParams(make_advertising_params()); - - gap.onConnection(this, &BLEProcess::when_connection); - gap.onDisconnection(this, &BLEProcess::when_disconnection); - - start_advertising(); - - if (_post_init_cb) { - _post_init_cb(_ble_interface, _event_queue); - } - } - - /** - * Start the gatt client process when a connection event is received. - */ - void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) - { - printf("Connected.\r\n"); - } - - /** - * Stop the gatt client process when the device is disconnected then restart - * advertising. - */ - void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) - { - printf("Disconnected.\r\n"); - start_advertising(); - } - - /** - * Setup the advertising parameters. - */ - void setup_advertising() - { - Gap &gap = _ble_interface.gap(); - gap.setAdvertisingPayload(make_advertising_data()); - gap.setAdvertisingParams(make_advertising_params()); - } - - /** - * Start the advertising process; it ends when a device connects. - */ - void start_advertising() - { - ble_error_t error = _ble_interface.gap().startAdvertising(); - if (error) { - printf("Error %u during gap.startAdvertising.\r\n", error); - } else { - printf("Advertising started.\r\n"); - } - } - - /** - * Schedule processing of events from the BLE middleware in the event queue. - */ - void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event) - { - _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents)); - } - - /** - * Build data advertised by the BLE interface. - */ - static GapAdvertisingData make_advertising_data(void) - { - static const uint8_t device_name[] = "GattClient"; - 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) - ); - - return advertising_data; - } - - /** - * Build advertising parameters used by the BLE interface. - */ - static GapAdvertisingParams make_advertising_params(void) - { - return GapAdvertisingParams( - /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, - /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500), - /* timeout */ 0 - ); - } - - events::EventQueue &_event_queue; - BLE &_ble_interface; - mbed::Callback _post_init_cb; -}; - - -#endif /* GATT_EXAMPLE_BLE_PROCESS_H_ */ diff --git a/BLE_GattClient_CharacteristicUpdates/CMakeLists.txt b/BLE_GattClient_CharacteristicUpdates/CMakeLists.txt new file mode 100644 index 00000000..9722ad00 --- /dev/null +++ b/BLE_GattClient_CharacteristicUpdates/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GattClient_CharacteristicUpdates) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_GattClient_CharacteristicUpdates/README.md b/BLE_GattClient_CharacteristicUpdates/README.md new file mode 100644 index 00000000..ee349f36 --- /dev/null +++ b/BLE_GattClient_CharacteristicUpdates/README.md @@ -0,0 +1,22 @@ +# BLE Gatt Client example of characteristic and service discovery + +This application demonstrates detailed use of the `GattClient` APIs. + +When the application is started it advertises itself to its environment with the device name "GattClient" +and also tries to connect to any device with the name "GattServer". Once connection has been achieved +it will start a discovery of the GATT server exposed by the peer. + +After the discovery, this application reads the value of the characteristics discovered and subscribes +to the characteristics emitting notifications or indications. + +The device prints the value of any indication or notification received from the peer's GATT Server. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). diff --git a/BLE_GattClient_CharacteristicUpdates/mbed-os-ble-utils.lib b/BLE_GattClient_CharacteristicUpdates/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GattClient_CharacteristicUpdates/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GattClient_CharacteristicUpdates/mbed-os.lib b/BLE_GattClient_CharacteristicUpdates/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_GattClient_CharacteristicUpdates/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GattClient_CharacteristicUpdates/mbed_app.json b/BLE_GattClient_CharacteristicUpdates/mbed_app.json new file mode 100644 index 00000000..f81ce44c --- /dev/null +++ b/BLE_GattClient_CharacteristicUpdates/mbed_app.json @@ -0,0 +1,28 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_GattClient/source/main.cpp b/BLE_GattClient_CharacteristicUpdates/source/main.cpp similarity index 83% rename from BLE_GattClient/source/main.cpp rename to BLE_GattClient_CharacteristicUpdates/source/main.cpp index 02784948..1d91d406 100644 --- a/BLE_GattClient/source/main.cpp +++ b/BLE_GattClient_CharacteristicUpdates/source/main.cpp @@ -1,6 +1,6 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2018 ARM Limited + * Copyright (c) 2006-2019 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,24 +15,13 @@ * limitations under the License. */ -#include -#include -#include - #include "events/EventQueue.h" #include "platform/NonCopyable.h" -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GattClient.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" #include "ble/GattClient.h" -#include "ble/DiscoveredService.h" -#include "ble/DiscoveredCharacteristic.h" -#include "ble/CharacteristicDescriptorDiscovery.h" -#include "BLEProcess.h" +#include "gatt_client_process.h" +#include "mbed-trace/mbed_trace.h" /** * Handle discovery of the GATT server. @@ -42,19 +31,14 @@ * notifications or indication when available. The client report server * indications and notification until the connection end. */ -class GattClientProcess : private mbed::NonCopyable, - public ble::Gap::EventHandler { - +class GattClientDemo : private mbed::NonCopyable, public GattClient::EventHandler +{ // Internal typedef to this class type. // It is used as a shorthand to pass member function as callbacks. - typedef GattClientProcess Self; - - typedef CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t - DiscoveryCallbackParams_t; - - typedef CharacteristicDescriptorDiscovery::TerminationCallbackParams_t - TerminationCallbackParams_t; + typedef GattClientDemo Self; + typedef CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t DiscoveryCallbackParams_t; + typedef CharacteristicDescriptorDiscovery::TerminationCallbackParams_t TerminationCallbackParams_t; typedef DiscoveredCharacteristic::Properties_t Properties_t; public: @@ -64,28 +48,18 @@ class GattClientProcess : private mbed::NonCopyable, * * The function start() shall be called to initiate the discovery process. */ - GattClientProcess() : - _client(NULL), - _connection_handle(), - _characteristics(NULL), - _it(NULL), - _descriptor_handle(0), - _ble_interface(NULL), - _event_queue(NULL) { - } + GattClientDemo() { } - ~GattClientProcess() + ~GattClientDemo() { stop(); } - void init(BLE &ble_interface, events::EventQueue &event_queue) + void start(BLE &ble, events::EventQueue &event_queue) { - _ble_interface = &ble_interface; + _ble = &ble; _event_queue = &event_queue; - _client = &_ble_interface->gattClient(); - - _ble_interface->gap().setEventHandler(this); + _client = &_ble->gattClient(); } /** @@ -96,8 +70,10 @@ class GattClientProcess : private mbed::NonCopyable, * @param[in] connection_handle Reference of the connection to the GATT * server which will be discovered. */ - void start() + void start_discovery(BLE &ble_interface, events::EventQueue &event_queue, const ble::ConnectionCompleteEvent &event) { + _connection_handle = event.getConnectionHandle(); + // setup the event handlers called during the process _client->onDataWritten().add(as_cb(&Self::when_descriptor_written)); _client->onHVX().add(as_cb(&Self::when_characteristic_changed)); @@ -118,6 +94,13 @@ class GattClientProcess : private mbed::NonCopyable, return; } + // register as a handler for GattClient events + _client->setEventHandler(this); + + // this might not result in a new value but if it does we will be informed through + // an call in the event handler we just registered + _client->negotiateAttMtu(_connection_handle); + printf("Client process started: initiate service discovery.\r\n"); } @@ -133,15 +116,15 @@ class GattClientProcess : private mbed::NonCopyable, // unregister event handlers _client->onDataWritten().detach(as_cb(&Self::when_descriptor_written)); _client->onHVX().detach(as_cb(&Self::when_characteristic_changed)); - _client->onServiceDiscoveryTermination(NULL); + _client->onServiceDiscoveryTermination(nullptr); // remove discovered characteristics clear_characteristics(); // clean up the instance _connection_handle = 0; - _characteristics = NULL; - _it = NULL; + _characteristics = nullptr; + _it = nullptr; _descriptor_handle = 0; printf("Client process stopped.\r\n"); @@ -149,25 +132,19 @@ class GattClientProcess : private mbed::NonCopyable, private: /** - * Event handler invoked when a connection is established. - * - * This function setup the connection handle to operate on then start the - * discovery process. - */ - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) - { - _connection_handle = event.getConnectionHandle(); - _event_queue->call(mbed::callback(this, &Self::start)); - } - - /** - * Stop the discovery process and clean the instance. + * Implementation of GattClient::EventHandler::onAttMtuChange event */ - virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) + virtual void onAttMtuChange( + ble::connection_handle_t connectionHandle, + uint16_t attMtuSize + ) { - if (_client && event.getConnectionHandle() == _connection_handle) { - stop(); - } + printf( + "ATT_MTU changed on the connection %d to a new value of %d.\r\n", + connectionHandle, + attMtuSize + /* maximum size of an attribute written in a single operation is one less */ + ); } private: @@ -232,7 +209,7 @@ class GattClientProcess : private mbed::NonCopyable, * * @see GattClient::onServiceDiscoveryTermination */ - void when_service_discovery_ends(Gap::Handle_t connection_handle) + void when_service_discovery_ends(ble::connection_handle_t connection_handle) { if (!_characteristics) { printf("No characteristics discovered, end of the process.\r\n"); @@ -242,7 +219,7 @@ class GattClientProcess : private mbed::NonCopyable, printf("All services and characteristics discovered, process them.\r\n"); // reset iterator and start processing characteristics in order - _it = NULL; + _it = nullptr; _event_queue->call(mbed::callback(this, &Self::process_next_characteristic)); } @@ -294,9 +271,7 @@ class GattClientProcess : private mbed::NonCopyable, void read_characteristic(const DiscoveredCharacteristic &characteristic) { printf("Initiating read at %u.\r\n", characteristic.getValueHandle()); - ble_error_t error = characteristic.read( - 0, as_cb(&Self::when_characteristic_read) - ); + ble_error_t error = characteristic.read(0, as_cb(&Self::when_characteristic_read)); if (error) { printf( @@ -382,7 +357,8 @@ class GattClientProcess : private mbed::NonCopyable, * If a CCCD has been found subscribe to server initiated events by writing * its value. */ - void when_descriptor_discovery_ends(const TerminationCallbackParams_t *event) { + void when_descriptor_discovery_ends(const TerminationCallbackParams_t *event) + { // shall never happen but happen with android devices ... // process the next charateristic if (!_descriptor_handle) { @@ -449,7 +425,7 @@ class GattClientProcess : private mbed::NonCopyable, struct DiscoveredCharacteristicNode { DiscoveredCharacteristicNode(const DiscoveredCharacteristic &c) : - value(c), next(NULL) { } + value(c), next(nullptr) { } DiscoveredCharacteristic value; DiscoveredCharacteristicNode *next; @@ -463,12 +439,12 @@ class GattClientProcess : private mbed::NonCopyable, DiscoveredCharacteristicNode* new_node = new(std::nothrow) DiscoveredCharacteristicNode(*characteristic); - if (new_node == false) { + if (new_node == nullptr) { printf("Error while allocating a new characteristic.\r\n"); return false; } - if (_characteristics == NULL) { + if (_characteristics == nullptr) { _characteristics = new_node; } else { DiscoveredCharacteristicNode* c = _characteristics; @@ -500,9 +476,8 @@ class GattClientProcess : private mbed::NonCopyable, * instance. */ template - FunctionPointerWithContext as_cb( - void (Self::*member)(ContextType context) - ) { + FunctionPointerWithContext as_cb(void (Self::*member)(ContextType context)) + { return makeFunctionPointer(this, member); } @@ -546,35 +521,35 @@ class GattClientProcess : private mbed::NonCopyable, printf(" ]"); } - GattClient *_client; - Gap::Handle_t _connection_handle; - DiscoveredCharacteristicNode *_characteristics; - DiscoveredCharacteristicNode *_it; - GattAttribute::Handle_t _descriptor_handle; - BLE *_ble_interface; - events::EventQueue *_event_queue; +private: + BLE *_ble = nullptr; + events::EventQueue *_event_queue = nullptr; + GattClient *_client = nullptr; + + ble::connection_handle_t _connection_handle = 0; + DiscoveredCharacteristicNode *_characteristics = nullptr; + DiscoveredCharacteristicNode *_it = nullptr; + GattAttribute::Handle_t _descriptor_handle = 0; }; -int main() { +int main() +{ + mbed_trace_init(); - BLE &ble_interface = BLE::Instance(); + BLE &ble = BLE::Instance(); events::EventQueue event_queue; - BLEProcess ble_process(event_queue, ble_interface); - GattClientProcess gatt_client_process; - // Register GattClientProcess::init in the ble_process; this function will - // be called once the ble_interface is initialized. - ble_process.on_init( - mbed::callback(&gatt_client_process, &GattClientProcess::init) - ); + GattClientDemo demo; - // bind the event queue to the ble interface, initialize the interface - // and start advertising - ble_process.start(); + /* this process will handle basic ble setup and advertising for us */ + GattClientProcess ble_process(event_queue, ble); + + /* once it's done it will let us continue with our demo */ + ble_process.on_init(mbed::callback(&demo, &GattClientDemo::start)); + ble_process.on_connect(mbed::callback(&demo, &GattClientDemo::start_discovery)); - // Process the event queue. - event_queue.dispatch_forever(); + ble_process.start(); return 0; } diff --git a/BLE_GattClient_CharacteristicWrite/CMakeLists.txt b/BLE_GattClient_CharacteristicWrite/CMakeLists.txt new file mode 100644 index 00000000..1d85d80b --- /dev/null +++ b/BLE_GattClient_CharacteristicWrite/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GattClient_CharacteristicWrite) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_GattClient_CharacteristicWrite/mbed-os-ble-utils.lib b/BLE_GattClient_CharacteristicWrite/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GattClient_CharacteristicWrite/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GattClient_CharacteristicWrite/mbed-os.lib b/BLE_GattClient_CharacteristicWrite/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_GattClient_CharacteristicWrite/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GattClient_CharacteristicWrite/mbed_app.json b/BLE_GattClient_CharacteristicWrite/mbed_app.json new file mode 100644 index 00000000..f81ce44c --- /dev/null +++ b/BLE_GattClient_CharacteristicWrite/mbed_app.json @@ -0,0 +1,28 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_GattClient_CharacteristicWrite/readme.md b/BLE_GattClient_CharacteristicWrite/readme.md new file mode 100644 index 00000000..81f8fbad --- /dev/null +++ b/BLE_GattClient_CharacteristicWrite/readme.md @@ -0,0 +1,25 @@ +# Write characteristic with GattClient + +This example demonstrates using the `GattClient` API to write to remote `GattServer`. + +This example works best with the `BLE_GattServer_CharacteristicWrite` examples which provides the characteristic to write to. +Alternatively you can create your own GATT Server with a writable characteristic with UUID `0xA001` of size 1 byte. + +This demo will run a GattClient and attempt to find a device with a name "GattServer". It will also accept a connection, +advertising as "GattClient". + +After connection completes it will attempt to discover all services and characteristics, looking for the writable +characteristic. If it finds it, it will read and write the characteristic every 5 seconds, incrementing the byte value +every time. + +Both applications should print the changing value in sync. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). diff --git a/BLE_GattClient_CharacteristicWrite/source/main.cpp b/BLE_GattClient_CharacteristicWrite/source/main.cpp new file mode 100644 index 00000000..0083ee34 --- /dev/null +++ b/BLE_GattClient_CharacteristicWrite/source/main.cpp @@ -0,0 +1,174 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 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 "ble/BLE.h" +#include "ble_app.h" +#include "mbed-trace/mbed_trace.h" + +/* GATT server needs free functions */ +void service_discovery(const DiscoveredService *service); +void characteristic_discovery(const DiscoveredCharacteristic *characteristic); +void discovery_termination(ble::connection_handle_t connectionHandle); +void on_read(const GattReadCallbackParams *response); +void on_write(const GattWriteCallbackParams *response); + +class GattClientDemo : public ble::Gap::EventHandler { + const static uint16_t EXAMPLE_SERVICE_UUID = 0xA000; + const static uint16_t WRITABLE_CHARACTERISTIC_UUID = 0xA001; + + friend void service_discovery(const DiscoveredService *service); + friend void characteristic_discovery(const DiscoveredCharacteristic *characteristic); + friend void discovery_termination(ble::connection_handle_t connectionHandle); + friend void on_read(const GattReadCallbackParams *response); + friend void on_write(const GattWriteCallbackParams *response); + +public: + static GattClientDemo &get_instance() { + static GattClientDemo instance; + return instance; + } + + void start() { + _ble_app.add_gap_event_handler(this); + _ble_app.set_target_name("GattServer"); + + /* once it's done it will let us continue with our demo by calling on_init */ + _ble_app.start(callback(this, &GattClientDemo::on_init)); + /* the above function does not return until we call _ble_app.stop() somewhere else */ + } + +private: + /** Callback triggered when the ble initialization process has finished */ + void on_init(BLE &ble, events::EventQueue &event_queue) { + _ble = &ble; + _event_queue = &event_queue; + _ble->gattClient().onDataRead(::on_read); + _ble->gattClient().onDataWritten(::on_write); + } + + void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { + printf("We are looking for a service with UUID 0xA000\r\n"); + printf("And a characteristic with UUID 0xA001\r\n"); + + _ble->gattClient().onServiceDiscoveryTermination(::discovery_termination); + _ble->gattClient().launchServiceDiscovery( + event.getConnectionHandle(), + ::service_discovery, + ::characteristic_discovery, + EXAMPLE_SERVICE_UUID, + WRITABLE_CHARACTERISTIC_UUID + ); + } + +private: + void service_discovery(const DiscoveredService *service) { + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + if (service->getUUID().getShortUUID() == EXAMPLE_SERVICE_UUID) { + printf("We found the service we were looking for\r\n"); + } + } + } + + void characteristic_discovery(const DiscoveredCharacteristic *characteristic) { + if (characteristic->getUUID().getShortUUID() == WRITABLE_CHARACTERISTIC_UUID) { + printf("We found the characteristic we were looking for\r\n"); + writable_characteristic = *characteristic; + writable_characteristic_found = true; + } + } + + void discovery_termination(ble::connection_handle_t connectionHandle) { + if (writable_characteristic_found) { + writable_characteristic_found = false; + _event_queue->call([this]{ writable_characteristic.read(); }); + } + } + + void on_read(const GattReadCallbackParams *response) { + if (response->handle == writable_characteristic.getValueHandle()) { + /* increment the value we just read */ + uint8_t value = response->data[0]; + value++; + + /* and write it back */ + writable_characteristic.write(1, &value); + + printf("Written new value of %x\r\n", value); + } + } + + void on_write(const GattWriteCallbackParams *response) { + if (response->handle == writable_characteristic.getValueHandle()) { + /* this concludes the example, we stop the app running the ble process in the background */ + _ble_app.stop(); + } + } + +private: + GattClientDemo() {}; + ~GattClientDemo() {}; + +private: + /** Simplified BLE application that automatically advertises and scans. It will + * initialise BLE and run the event queue */ + BLEApp _ble_app; + + BLE *_ble = nullptr; + events::EventQueue *_event_queue = nullptr; + + DiscoveredCharacteristic writable_characteristic; + bool writable_characteristic_found = false; +}; + +/* redirect to demo instance functions */ +void service_discovery(const DiscoveredService *service) { + GattClientDemo::get_instance().service_discovery(service); +} + +void characteristic_discovery(const DiscoveredCharacteristic *characteristic) { + GattClientDemo::get_instance().characteristic_discovery(characteristic); +} + +void discovery_termination(ble::connection_handle_t connectionHandle) { + GattClientDemo::get_instance().discovery_termination(connectionHandle); +} + +void on_read(const GattReadCallbackParams *response) { + GattClientDemo::get_instance().on_read(response); +} + +void on_write(const GattWriteCallbackParams *response) { + GattClientDemo::get_instance().on_write(response); +} + +int main() +{ + printf("\r\nGattClient demo of a writable characteristic\r\n"); + + mbed_trace_init(); + + GattClientDemo &demo = GattClientDemo::get_instance(); + + /* this demo will run and sleep for 5 seconds, during which time ble will be shut down */ + while (1) { + demo.start(); + printf("Sleeping...\r\n"); + ThisThread::sleep_for(5s); + } + + return 0; +} diff --git a/BLE_GattServer/.mbed b/BLE_GattServer/.mbed deleted file mode 100644 index 0ba62b08..00000000 --- a/BLE_GattServer/.mbed +++ /dev/null @@ -1,3 +0,0 @@ -ROOT=. -TARGET=NRF52_DK -TOOLCHAIN=GCC_ARM diff --git a/BLE_GattServer/mbed-os.lib b/BLE_GattServer/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_GattServer/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_GattServer/mbed_app.json b/BLE_GattServer/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_GattServer/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_GattServer/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_GattServer/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_GattServer/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_GattServer/source/BLEProcess.h b/BLE_GattServer/source/BLEProcess.h deleted file mode 100644 index 30ba7d02..00000000 --- a/BLE_GattServer/source/BLEProcess.h +++ /dev/null @@ -1,206 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2017 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 GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ -#define GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ - -#include -#include - -#include "events/EventQueue.h" -#include "platform/Callback.h" -#include "platform/NonCopyable.h" - -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/FunctionPointerWithContext.h" - -/** - * Handle initialization adn shutdown of the BLE Instance. - * - * Setup advertising payload and manage advertising state. - * Delegate to GattClientProcess once the connection is established. - */ -class BLEProcess : private mbed::NonCopyable { -public: - /** - * Construct a BLEProcess from an event queue and a ble interface. - * - * Call start() to initiate ble processing. - */ - BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) : - _event_queue(event_queue), - _ble_interface(ble_interface), - _post_init_cb() { - } - - ~BLEProcess() - { - stop(); - } - - /** - * Subscription to the ble interface initialization event. - * - * @param[in] cb The callback object that will be called when the ble - * interface is initialized. - */ - void on_init(mbed::Callback cb) - { - _post_init_cb = cb; - } - - /** - * Initialize the ble interface, configure it and start advertising. - */ - bool start() - { - printf("Ble process started.\r\n"); - - if (_ble_interface.hasInitialized()) { - printf("Error: the ble instance has already been initialized.\r\n"); - return false; - } - - _ble_interface.onEventsToProcess( - makeFunctionPointer(this, &BLEProcess::schedule_ble_events) - ); - - ble_error_t error = _ble_interface.init( - this, &BLEProcess::when_init_complete - ); - - if (error) { - printf("Error: %u returned by BLE::init.\r\n", error); - return false; - } - - return true; - } - - /** - * Close existing connections and stop the process. - */ - void stop() - { - if (_ble_interface.hasInitialized()) { - _ble_interface.shutdown(); - printf("Ble process stopped."); - } - } - -private: - - /** - * Schedule processing of events from the BLE middleware in the event queue. - */ - void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event) - { - _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents)); - } - - /** - * Sets up adverting payload and start advertising. - * - * This function is invoked when the ble interface is initialized. - */ - void when_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - if (event->error) { - printf("Error %u during the initialization\r\n", event->error); - return; - } - printf("Ble instance initialized\r\n"); - - Gap &gap = _ble_interface.gap(); - ble_error_t error = gap.setAdvertisingPayload(make_advertising_data()); - if (error) { - printf("Error %u during gap.setAdvertisingPayload\r\n", error); - return; - } - - gap.setAdvertisingParams(make_advertising_params()); - - gap.onConnection(this, &BLEProcess::when_connection); - gap.onDisconnection(this, &BLEProcess::when_disconnection); - - start_advertising(); - - if (_post_init_cb) { - _post_init_cb(_ble_interface, _event_queue); - } - } - - void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) - { - printf("Connected.\r\n"); - } - - void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) - { - printf("Disconnected.\r\n"); - start_advertising(); - } - - void start_advertising(void) - { - ble_error_t error = _ble_interface.gap().startAdvertising(); - if (error) { - printf("Error %u during gap.startAdvertising.\r\n", error); - return; - } else { - printf("Advertising started.\r\n"); - } - } - - static GapAdvertisingData make_advertising_data(void) - { - static const uint8_t device_name[] = "GattServer"; - 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) - ); - - return advertising_data; - } - - static GapAdvertisingParams make_advertising_params(void) - { - return GapAdvertisingParams( - /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, - /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500), - /* timeout */ 0 - ); - } - - events::EventQueue &_event_queue; - BLE &_ble_interface; - mbed::Callback _post_init_cb; -}; - -#endif /* GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ */ diff --git a/BLE_GattServer/source/main.cpp b/BLE_GattServer/source/main.cpp deleted file mode 100644 index 29cc72ad..00000000 --- a/BLE_GattServer/source/main.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2017 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 - -#include "platform/Callback.h" -#include "events/EventQueue.h" -#include "platform/NonCopyable.h" - -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GattClient.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/GattServer.h" -#include "BLEProcess.h" - -using mbed::callback; - -/** - * A Clock service that demonstrate the GattServer features. - * - * The clock service host three characteristics that model the current hour, - * minute and second of the clock. The value of the second characteristic is - * incremented automatically by the system. - * - * A client can subscribe to updates of the clock characteristics and get - * notified when one of the value is changed. Clients can also change value of - * the second, minute and hour characteristric. - */ -class ClockService { - typedef ClockService Self; - -public: - ClockService() : - _hour_char("485f4145-52b9-4644-af1f-7a6b9322490f", 0), - _minute_char("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0), - _second_char("8dd6a1b7-bc75-4741-8a26-264af75807de", 0), - _clock_service( - /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed", - /* characteristics */ _clock_characteristics, - /* numCharacteristics */ sizeof(_clock_characteristics) / - sizeof(_clock_characteristics[0]) - ), - _server(NULL), - _event_queue(NULL) - { - // update internal pointers (value, descriptors and characteristics array) - _clock_characteristics[0] = &_hour_char; - _clock_characteristics[1] = &_minute_char; - _clock_characteristics[2] = &_second_char; - - // setup authorization handlers - _hour_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - _minute_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - _second_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - } - - - - void start(BLE &ble_interface, events::EventQueue &event_queue) - { - if (_event_queue) { - return; - } - - _server = &ble_interface.gattServer(); - _event_queue = &event_queue; - - // register the service - printf("Adding demo service\r\n"); - ble_error_t err = _server->addService(_clock_service); - - if (err) { - printf("Error %u during demo service registration.\r\n", err); - return; - } - - // read write handler - _server->onDataSent(as_cb(&Self::when_data_sent)); - _server->onDataWritten(as_cb(&Self::when_data_written)); - _server->onDataRead(as_cb(&Self::when_data_read)); - - // updates subscribtion handlers - _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled)); - _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled)); - _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received)); - - // print the handles - printf("clock service registered\r\n"); - printf("service handle: %u\r\n", _clock_service.getHandle()); - printf("\thour characteristic value handle %u\r\n", _hour_char.getValueHandle()); - printf("\tminute characteristic value handle %u\r\n", _minute_char.getValueHandle()); - printf("\tsecond characteristic value handle %u\r\n", _second_char.getValueHandle()); - - _event_queue->call_every(1000 /* ms */, callback(this, &Self::increment_second)); - } - -private: - - /** - * Handler called when a notification or an indication has been sent. - */ - void when_data_sent(unsigned count) - { - printf("sent %u updates\r\n", count); - } - - /** - * Handler called after an attribute has been written. - */ - void when_data_written(const GattWriteCallbackParams *e) - { - printf("data written:\r\n"); - printf("\tconnection handle: %u\r\n", e->connHandle); - printf("\tattribute handle: %u", e->handle); - if (e->handle == _hour_char.getValueHandle()) { - printf(" (hour characteristic)\r\n"); - } else if (e->handle == _minute_char.getValueHandle()) { - printf(" (minute characteristic)\r\n"); - } else if (e->handle == _second_char.getValueHandle()) { - printf(" (second characteristic)\r\n"); - } else { - printf("\r\n"); - } - printf("\twrite operation: %u\r\n", e->writeOp); - printf("\toffset: %u\r\n", e->offset); - printf("\tlength: %u\r\n", e->len); - printf("\t data: "); - - for (size_t i = 0; i < e->len; ++i) { - printf("%02X", e->data[i]); - } - - printf("\r\n"); - } - - /** - * Handler called after an attribute has been read. - */ - void when_data_read(const GattReadCallbackParams *e) - { - printf("data read:\r\n"); - printf("\tconnection handle: %u\r\n", e->connHandle); - printf("\tattribute handle: %u", e->handle); - if (e->handle == _hour_char.getValueHandle()) { - printf(" (hour characteristic)\r\n"); - } else if (e->handle == _minute_char.getValueHandle()) { - printf(" (minute characteristic)\r\n"); - } else if (e->handle == _second_char.getValueHandle()) { - printf(" (second characteristic)\r\n"); - } else { - printf("\r\n"); - } - } - - /** - * Handler called after a client has subscribed to notification or indication. - * - * @param handle Handle of the characteristic value affected by the change. - */ - void when_update_enabled(GattAttribute::Handle_t handle) - { - printf("update enabled on handle %d\r\n", handle); - } - - /** - * Handler called after a client has cancelled his subscription from - * notification or indication. - * - * @param handle Handle of the characteristic value affected by the change. - */ - void when_update_disabled(GattAttribute::Handle_t handle) - { - printf("update disabled on handle %d\r\n", handle); - } - - /** - * Handler called when an indication confirmation has been received. - * - * @param handle Handle of the characteristic value that has emitted the - * indication. - */ - void when_confirmation_received(GattAttribute::Handle_t handle) - { - printf("confirmation received on handle %d\r\n", handle); - } - - /** - * Handler called when a write request is received. - * - * This handler verify that the value submitted by the client is valid before - * authorizing the operation. - */ - void authorize_client_write(GattWriteAuthCallbackParams *e) - { - printf("characteristic %u write authorization\r\n", e->handle); - - if (e->offset != 0) { - printf("Error invalid offset\r\n"); - e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; - return; - } - - if (e->len != 1) { - printf("Error invalid len\r\n"); - e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; - return; - } - - if ((e->data[0] >= 60) || - ((e->data[0] >= 24) && (e->handle == _hour_char.getValueHandle()))) { - printf("Error invalid data\r\n"); - e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; - return; - } - - e->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } - - /** - * Increment the second counter. - */ - void increment_second(void) - { - uint8_t second = 0; - ble_error_t err = _second_char.get(*_server, second); - if (err) { - printf("read of the second value returned error %u\r\n", err); - return; - } - - second = (second + 1) % 60; - - err = _second_char.set(*_server, second); - if (err) { - printf("write of the second value returned error %u\r\n", err); - return; - } - - if (second == 0) { - increment_minute(); - } - } - - /** - * Increment the minute counter. - */ - void increment_minute(void) - { - uint8_t minute = 0; - ble_error_t err = _minute_char.get(*_server, minute); - if (err) { - printf("read of the minute value returned error %u\r\n", err); - return; - } - - minute = (minute + 1) % 60; - - err = _minute_char.set(*_server, minute); - if (err) { - printf("write of the minute value returned error %u\r\n", err); - return; - } - - if (minute == 0) { - increment_hour(); - } - } - - /** - * Increment the hour counter. - */ - void increment_hour(void) - { - uint8_t hour = 0; - ble_error_t err = _hour_char.get(*_server, hour); - if (err) { - printf("read of the hour value returned error %u\r\n", err); - return; - } - - hour = (hour + 1) % 24; - - err = _hour_char.set(*_server, hour); - if (err) { - printf("write of the hour value returned error %u\r\n", err); - return; - } - } - -private: - /** - * Helper that construct an event handler from a member function of this - * instance. - */ - template - FunctionPointerWithContext as_cb(void (Self::*member)(Arg)) - { - return makeFunctionPointer(this, member); - } - - /** - * Read, Write, Notify, Indicate Characteristic declaration helper. - * - * @tparam T type of data held by the characteristic. - */ - template - class ReadWriteNotifyIndicateCharacteristic : public GattCharacteristic { - public: - /** - * Construct a characteristic that can be read or written and emit - * notification or indication. - * - * @param[in] uuid The UUID of the characteristic. - * @param[in] initial_value Initial value contained by the characteristic. - */ - ReadWriteNotifyIndicateCharacteristic(const UUID & uuid, const T& initial_value) : - GattCharacteristic( - /* UUID */ uuid, - /* Initial value */ &_value, - /* Value size */ sizeof(_value), - /* Value capacity */ sizeof(_value), - /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, - /* Descriptors */ NULL, - /* Num descriptors */ 0, - /* variable len */ false - ), - _value(initial_value) { - } - - /** - * Get the value of this characteristic. - * - * @param[in] server GattServer instance that contain the characteristic - * value. - * @param[in] dst Variable that will receive the characteristic value. - * - * @return BLE_ERROR_NONE in case of success or an appropriate error code. - */ - ble_error_t get(GattServer &server, T& dst) const - { - uint16_t value_length = sizeof(dst); - return server.read(getValueHandle(), &dst, &value_length); - } - - /** - * Assign a new value to this characteristic. - * - * @param[in] server GattServer instance that will receive the new value. - * @param[in] value The new value to set. - * @param[in] local_only Flag that determine if the change should be kept - * locally or forwarded to subscribed clients. - */ - ble_error_t set( - GattServer &server, const uint8_t &value, bool local_only = false - ) const { - return server.write(getValueHandle(), &value, sizeof(value), local_only); - } - - private: - uint8_t _value; - }; - - ReadWriteNotifyIndicateCharacteristic _hour_char; - ReadWriteNotifyIndicateCharacteristic _minute_char; - ReadWriteNotifyIndicateCharacteristic _second_char; - - // list of the characteristics of the clock service - GattCharacteristic* _clock_characteristics[3]; - - // demo service - GattService _clock_service; - - GattServer* _server; - events::EventQueue *_event_queue; -}; - -int main() { - BLE &ble_interface = BLE::Instance(); - events::EventQueue event_queue; - ClockService demo_service; - BLEProcess ble_process(event_queue, ble_interface); - - ble_process.on_init(callback(&demo_service, &ClockService::start)); - - // bind the event queue to the ble interface, initialize the interface - // and start advertising - ble_process.start(); - - // Process the event queue. - event_queue.dispatch_forever(); - - return 0; -} diff --git a/BLE_GattServer_AddService/CMakeLists.txt b/BLE_GattServer_AddService/CMakeLists.txt new file mode 100644 index 00000000..9c81f825 --- /dev/null +++ b/BLE_GattServer_AddService/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GattServer_AddService) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_HeartRate/img/connection.png b/BLE_GattServer_AddService/img/connection.png similarity index 100% rename from BLE_HeartRate/img/connection.png rename to BLE_GattServer_AddService/img/connection.png diff --git a/BLE_GattServer_AddService/img/connection_ble_profile.png b/BLE_GattServer_AddService/img/connection_ble_profile.png new file mode 100644 index 00000000..c518c0da Binary files /dev/null and b/BLE_GattServer_AddService/img/connection_ble_profile.png differ diff --git a/BLE_HeartRate/img/discovery.png b/BLE_GattServer_AddService/img/discovery.png similarity index 100% rename from BLE_HeartRate/img/discovery.png rename to BLE_GattServer_AddService/img/discovery.png diff --git a/BLE_GattServer_AddService/img/discovery_ble_profile.png b/BLE_GattServer_AddService/img/discovery_ble_profile.png new file mode 100644 index 00000000..5c46f16f Binary files /dev/null and b/BLE_GattServer_AddService/img/discovery_ble_profile.png differ diff --git a/BLE_HeartRate/img/notifications.png b/BLE_GattServer_AddService/img/notifications.png similarity index 100% rename from BLE_HeartRate/img/notifications.png rename to BLE_GattServer_AddService/img/notifications.png diff --git a/BLE_GattServer_AddService/img/notifications_ble_profile.png b/BLE_GattServer_AddService/img/notifications_ble_profile.png new file mode 100644 index 00000000..f1ec9ea2 Binary files /dev/null and b/BLE_GattServer_AddService/img/notifications_ble_profile.png differ diff --git a/BLE_HeartRate/img/register_to_notifications.png b/BLE_GattServer_AddService/img/register_to_notifications.png similarity index 100% rename from BLE_HeartRate/img/register_to_notifications.png rename to BLE_GattServer_AddService/img/register_to_notifications.png diff --git a/BLE_GattServer_AddService/img/register_to_notifications_ble_profile.png b/BLE_GattServer_AddService/img/register_to_notifications_ble_profile.png new file mode 100644 index 00000000..9bc35ec2 Binary files /dev/null and b/BLE_GattServer_AddService/img/register_to_notifications_ble_profile.png differ diff --git a/BLE_HeartRate/img/scan_result.png b/BLE_GattServer_AddService/img/scan_result.png similarity index 100% rename from BLE_HeartRate/img/scan_result.png rename to BLE_GattServer_AddService/img/scan_result.png diff --git a/BLE_GattServer_AddService/img/scan_result_ble_profile.png b/BLE_GattServer_AddService/img/scan_result_ble_profile.png new file mode 100644 index 00000000..1ba46615 Binary files /dev/null and b/BLE_GattServer_AddService/img/scan_result_ble_profile.png differ diff --git a/BLE_Beacon/img/start_scan.png b/BLE_GattServer_AddService/img/start_scan.png similarity index 100% rename from BLE_Beacon/img/start_scan.png rename to BLE_GattServer_AddService/img/start_scan.png diff --git a/BLE_GattServer_AddService/img/start_scan_ble_profile.png b/BLE_GattServer_AddService/img/start_scan_ble_profile.png new file mode 100644 index 00000000..a03b3dc8 Binary files /dev/null and b/BLE_GattServer_AddService/img/start_scan_ble_profile.png differ diff --git a/BLE_GattServer_AddService/mbed-os-ble-utils.lib b/BLE_GattServer_AddService/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GattServer_AddService/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GattServer_AddService/mbed-os.lib b/BLE_GattServer_AddService/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_GattServer_AddService/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GattServer_AddService/mbed_app.json b/BLE_GattServer_AddService/mbed_app.json new file mode 100644 index 00000000..f81ce44c --- /dev/null +++ b/BLE_GattServer_AddService/mbed_app.json @@ -0,0 +1,28 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_GattServer_AddService/readme.md b/BLE_GattServer_AddService/readme.md new file mode 100644 index 00000000..7c0fe9b0 --- /dev/null +++ b/BLE_GattServer_AddService/readme.md @@ -0,0 +1,85 @@ +# BLE Service Example + +This application shows how to add a new service and allow clients to interact with it. +This application transmits a heart rate value using the [Bluetooth SIG Heart Rate Profile](https://developer.bluetooth.org/TechnologyOverview/Pages/HRP.aspx). +The heart rate value is simulated by the application itself, not by a sensor, so that you don't have to get a sensor just to run the example. +The demo will advertise connectable advertising. Upon connection the client will be able to subscribe to heart rate value updates. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *ST BLE Profile* version 2.0.0 or *nRF Connect for Mobile* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Connect for Mobile. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + + ![](img/start_scan_ble_profile.png) + + **figure 1.a** How to start scan using ST BLE Profile 2.0.0 + + ![](img/start_scan.png) + + **figure 1.b** How to start scan using nRF Connect for Mobile 4.0.5 + +1. Find your device; it should be named `HRM`. + + ![](img/scan_result_ble_profile.png) + + **figure 2.a** Scan results using ST BLE Profile 2.0.0 + + ![](img/scan_result.png) + + **figure 2.b** Scan results using nRF Connect for Mobile 4.0.5 + +1. Establish a connection with your device. + + ![](img/connection_ble_profile.png) + + **figure 3.a** How to establish a connection using ST BLE Profile 2.0.0 + + ![](img/connection.png) + + **figure 3.b** How to establish a connection using Master Control Panel 4.0.5 + +1. Discover the services and the characteristics on the device. The *Heart Rate* service has the UUID `0x180D` and includes the *Heart Rate Measurement* characteristic which has the UUID `0x2A37`. + + ![](img/discovery_ble_profile.png) + + **figure 4.a** Representation of the Heart Rate service using ST BLE Profile 2.0.0 + + ![](img/discovery.png) + + **figure 4.b** Representation of the Heart Rate service using Master Control Panel 4.0.5 + +1. Register for the notifications sent by the *Heart Rate Measurement* characteristic. + + ![](img/register_to_notifications_ble_profile.png) + + **figure 5.a** How to register to notifications using ST BLE Profile 2.0.0 + + ![](img/register_to_notifications.png) + + **figure 5.b** How to register to notifications using Master Control Panel 4.0.5 + + +1. You should see the heart rate value change every half second.
For ST BLE Profile, it begins at 60, goes up to 100 (in steps of 1), resets to 60 and so on. + + ![](img/notifications_ble_profile.png) + + **figure 6.a** Notifications view using ST BLE Profile 2.0.0 + + For Master Control Panel, it begins at 100, goes up to 175 (in steps of 1), resets to 100 and so on. + + ![](img/notifications.png) + + **figure 6.b** Notifications view using Master Control Panel 4.0.5 diff --git a/BLE_HeartRate/source/main.cpp b/BLE_GattServer_AddService/source/main.cpp similarity index 61% rename from BLE_HeartRate/source/main.cpp rename to BLE_GattServer_AddService/source/main.cpp index 26d3ac49..308e7a8f 100644 --- a/BLE_HeartRate/source/main.cpp +++ b/BLE_GattServer_AddService/source/main.cpp @@ -15,11 +15,13 @@ */ #include -#include #include "ble/BLE.h" #include "ble/gap/Gap.h" #include "ble/services/HeartRateService.h" #include "pretty_printer.h" +#include "mbed-trace/mbed_trace.h" + +using namespace std::literals::chrono_literals; const static char DEVICE_NAME[] = "Heartrate"; @@ -30,27 +32,24 @@ class HeartrateDemo : ble::Gap::EventHandler { HeartrateDemo(BLE &ble, events::EventQueue &event_queue) : _ble(ble), _event_queue(event_queue), - _led1(LED1, 1), - _connected(false), - _hr_uuid(GattService::UUID_HEART_RATE_SERVICE), - _hr_counter(100), - _hr_service(ble, _hr_counter, HeartRateService::LOCATION_FINGER), - _adv_data_builder(_adv_buffer) { } - - void start() { - _ble.gap().setEventHandler(this); + _heartrate_uuid(GattService::UUID_HEART_RATE_SERVICE), + _heartrate_value(100), + _heartrate_service(ble, _heartrate_value, HeartRateService::LOCATION_FINGER), + _adv_data_builder(_adv_buffer) + { + } + void start() + { _ble.init(this, &HeartrateDemo::on_init_complete); - _event_queue.call_every(500, this, &HeartrateDemo::blink); - _event_queue.call_every(1000, this, &HeartrateDemo::update_sensor_value); - _event_queue.dispatch_forever(); } private: /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { + void on_init_complete(BLE::InitializationCompleteCallbackContext *params) + { if (params->error != BLE_ERROR_NONE) { printf("Ble initialization failed."); return; @@ -58,20 +57,32 @@ class HeartrateDemo : ble::Gap::EventHandler { print_mac_address(); + /* this allows us to receive events like onConnectionComplete() */ + _ble.gap().setEventHandler(this); + + /* heart rate value updated every second */ + _event_queue.call_every( + 1000ms, + [this] { + update_sensor_value(); + } + ); + start_advertising(); } - void start_advertising() { + void start_advertising() + { /* Create advertising parameters and payload */ ble::AdvertisingParameters adv_parameters( ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) + ble::adv_interval_t(ble::millisecond_t(100)) ); _adv_data_builder.setFlags(); _adv_data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_hr_uuid, 1)); + _adv_data_builder.setLocalServiceList({&_heartrate_uuid, 1}); _adv_data_builder.setName(DEVICE_NAME); /* Setup advertising */ @@ -104,64 +115,68 @@ class HeartrateDemo : ble::Gap::EventHandler { printf("_ble.gap().startAdvertising() failed\r\n"); return; } - } - void update_sensor_value() { - if (_connected) { - // Do blocking calls or whatever is necessary for sensor polling. - // In our case, we simply update the HRM measurement. - _hr_counter++; + printf("Heart rate sensor advertising, please connect\r\n"); + } - // 100 <= HRM bps <=175 - if (_hr_counter == 175) { - _hr_counter = 100; - } + void update_sensor_value() + { + /* you can read in the real value but here we just simulate a value */ + _heartrate_value++; - _hr_service.updateHeartRate(_hr_counter); + /* 60 <= bpm value < 110 */ + if (_heartrate_value == 110) { + _heartrate_value = 60; } - } - void blink(void) { - _led1 = !_led1; + _heartrate_service.updateHeartRate(_heartrate_value); } + /* these implement ble::Gap::EventHandler */ private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - _connected = false; + /* when we connect we stop advertising, restart advertising so others can connect */ + virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) + { + if (event.getStatus() == ble_error_t::BLE_ERROR_NONE) { + printf("Client connected, you may now subscribe to updates\r\n"); + } } - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { - if (event.getStatus() == BLE_ERROR_NONE) { - _connected = true; + /* when we connect we stop advertising, restart advertising so others can connect */ + virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) + { + printf("Client disconnected, restarting advertising\r\n"); + + ble_error_t error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + + if (error) { + printf("_ble.gap().startAdvertising() failed\r\n"); + return; } } private: BLE &_ble; events::EventQueue &_event_queue; - DigitalOut _led1; - - bool _connected; - UUID _hr_uuid; - - uint8_t _hr_counter; - HeartRateService _hr_service; + UUID _heartrate_uuid; + uint16_t _heartrate_value; + HeartRateService _heartrate_service; uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; ble::AdvertisingDataBuilder _adv_data_builder; }; -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { +/* Schedule processing of events from the BLE middleware in the event queue. */ +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ event_queue.call(Callback(&context->ble, &BLE::processEvents)); } int main() { + mbed_trace_init(); + BLE &ble = BLE::Instance(); ble.onEventsToProcess(schedule_ble_events); diff --git a/BLE_GattServer_CharacteristicUpdates/CMakeLists.txt b/BLE_GattServer_CharacteristicUpdates/CMakeLists.txt new file mode 100644 index 00000000..59aed54b --- /dev/null +++ b/BLE_GattServer_CharacteristicUpdates/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GattServer_CharacteristicUpdates) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_GattServer_CharacteristicUpdates/README.md b/BLE_GattServer_CharacteristicUpdates/README.md new file mode 100644 index 00000000..b62d7b38 --- /dev/null +++ b/BLE_GattServer_CharacteristicUpdates/README.md @@ -0,0 +1,21 @@ +# BLE Gatt Server example + +This application demonstrates detailed uses of the GattServer APIs. + +It starts by advertising to its environment with the device name "GattServer". Once you connect to the device with +a BLE scanner on your phone, the scanner shows a service with three characteristics - each representing the hour, +minute and second of a clock. + +To see the clock values updating subscribe to the service using the "Enable CCCDs" (or similar) option provided +by the scanner. Now the values get updated once a second. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + diff --git a/BLE_GattServer_CharacteristicUpdates/mbed-os-ble-utils.lib b/BLE_GattServer_CharacteristicUpdates/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GattServer_CharacteristicUpdates/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GattServer_CharacteristicUpdates/mbed-os.lib b/BLE_GattServer_CharacteristicUpdates/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_GattServer_CharacteristicUpdates/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GattServer_CharacteristicUpdates/mbed_app.json b/BLE_GattServer_CharacteristicUpdates/mbed_app.json new file mode 100644 index 00000000..f81ce44c --- /dev/null +++ b/BLE_GattServer_CharacteristicUpdates/mbed_app.json @@ -0,0 +1,28 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/deprecated/BLE_GattServer/main.cpp b/BLE_GattServer_CharacteristicUpdates/source/main.cpp similarity index 66% rename from deprecated/BLE_GattServer/main.cpp rename to BLE_GattServer_CharacteristicUpdates/source/main.cpp index 29cc72ad..d32f793b 100644 --- a/deprecated/BLE_GattServer/main.cpp +++ b/BLE_GattServer_CharacteristicUpdates/source/main.cpp @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2017 ARM Limited + * Copyright (c) 2017-2019 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,21 +14,14 @@ * limitations under the License. */ -#include - #include "platform/Callback.h" #include "events/EventQueue.h" -#include "platform/NonCopyable.h" - #include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GattClient.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/GattServer.h" -#include "BLEProcess.h" +#include "gatt_server_process.h" +#include "mbed-trace/mbed_trace.h" using mbed::callback; +using namespace std::literals::chrono_literals; /** * A Clock service that demonstrate the GattServer features. @@ -41,9 +34,7 @@ using mbed::callback; * notified when one of the value is changed. Clients can also change value of * the second, minute and hour characteristric. */ -class ClockService { - typedef ClockService Self; - +class ClockService : public ble::GattServer::EventHandler { public: ClockService() : _hour_char("485f4145-52b9-4644-af1f-7a6b9322490f", 0), @@ -54,34 +45,25 @@ class ClockService { /* characteristics */ _clock_characteristics, /* numCharacteristics */ sizeof(_clock_characteristics) / sizeof(_clock_characteristics[0]) - ), - _server(NULL), - _event_queue(NULL) + ) { - // update internal pointers (value, descriptors and characteristics array) + /* update internal pointers (value, descriptors and characteristics array) */ _clock_characteristics[0] = &_hour_char; _clock_characteristics[1] = &_minute_char; _clock_characteristics[2] = &_second_char; - // setup authorization handlers - _hour_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - _minute_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - _second_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + /* setup authorization handlers */ + _hour_char.setWriteAuthorizationCallback(this, &ClockService::authorize_client_write); + _minute_char.setWriteAuthorizationCallback(this, &ClockService::authorize_client_write); + _second_char.setWriteAuthorizationCallback(this, &ClockService::authorize_client_write); } - - - void start(BLE &ble_interface, events::EventQueue &event_queue) + void start(BLE &ble, events::EventQueue &event_queue) { - if (_event_queue) { - return; - } - - _server = &ble_interface.gattServer(); + _server = &ble.gattServer(); _event_queue = &event_queue; - // register the service - printf("Adding demo service\r\n"); + printf("Registering demo service\r\n"); ble_error_t err = _server->addService(_clock_service); if (err) { @@ -89,60 +71,52 @@ class ClockService { return; } - // read write handler - _server->onDataSent(as_cb(&Self::when_data_sent)); - _server->onDataWritten(as_cb(&Self::when_data_written)); - _server->onDataRead(as_cb(&Self::when_data_read)); + /* register handlers */ + _server->setEventHandler(this); - // updates subscribtion handlers - _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled)); - _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled)); - _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received)); - - // print the handles printf("clock service registered\r\n"); printf("service handle: %u\r\n", _clock_service.getHandle()); - printf("\thour characteristic value handle %u\r\n", _hour_char.getValueHandle()); - printf("\tminute characteristic value handle %u\r\n", _minute_char.getValueHandle()); - printf("\tsecond characteristic value handle %u\r\n", _second_char.getValueHandle()); + printf("hour characteristic value handle %u\r\n", _hour_char.getValueHandle()); + printf("minute characteristic value handle %u\r\n", _minute_char.getValueHandle()); + printf("second characteristic value handle %u\r\n", _second_char.getValueHandle()); - _event_queue->call_every(1000 /* ms */, callback(this, &Self::increment_second)); + _event_queue->call_every(1000ms, callback(this, &ClockService::increment_second)); } + /* GattServer::EventHandler */ private: - /** * Handler called when a notification or an indication has been sent. */ - void when_data_sent(unsigned count) + void onDataSent(const GattDataSentCallbackParams ¶ms) override { - printf("sent %u updates\r\n", count); + printf("sent updates\r\n"); } /** * Handler called after an attribute has been written. */ - void when_data_written(const GattWriteCallbackParams *e) + void onDataWritten(const GattWriteCallbackParams ¶ms) override { printf("data written:\r\n"); - printf("\tconnection handle: %u\r\n", e->connHandle); - printf("\tattribute handle: %u", e->handle); - if (e->handle == _hour_char.getValueHandle()) { + printf("connection handle: %u\r\n", params.connHandle); + printf("attribute handle: %u", params.handle); + if (params.handle == _hour_char.getValueHandle()) { printf(" (hour characteristic)\r\n"); - } else if (e->handle == _minute_char.getValueHandle()) { + } else if (params.handle == _minute_char.getValueHandle()) { printf(" (minute characteristic)\r\n"); - } else if (e->handle == _second_char.getValueHandle()) { + } else if (params.handle == _second_char.getValueHandle()) { printf(" (second characteristic)\r\n"); } else { printf("\r\n"); } - printf("\twrite operation: %u\r\n", e->writeOp); - printf("\toffset: %u\r\n", e->offset); - printf("\tlength: %u\r\n", e->len); - printf("\t data: "); + printf("write operation: %u\r\n", params.writeOp); + printf("offset: %u\r\n", params.offset); + printf("length: %u\r\n", params.len); + printf("data: "); - for (size_t i = 0; i < e->len; ++i) { - printf("%02X", e->data[i]); + for (size_t i = 0; i < params.len; ++i) { + printf("%02X", params.data[i]); } printf("\r\n"); @@ -151,16 +125,16 @@ class ClockService { /** * Handler called after an attribute has been read. */ - void when_data_read(const GattReadCallbackParams *e) + void onDataRead(const GattReadCallbackParams ¶ms) override { printf("data read:\r\n"); - printf("\tconnection handle: %u\r\n", e->connHandle); - printf("\tattribute handle: %u", e->handle); - if (e->handle == _hour_char.getValueHandle()) { + printf("connection handle: %u\r\n", params.connHandle); + printf("attribute handle: %u", params.handle); + if (params.handle == _hour_char.getValueHandle()) { printf(" (hour characteristic)\r\n"); - } else if (e->handle == _minute_char.getValueHandle()) { + } else if (params.handle == _minute_char.getValueHandle()) { printf(" (minute characteristic)\r\n"); - } else if (e->handle == _second_char.getValueHandle()) { + } else if (params.handle == _second_char.getValueHandle()) { printf(" (second characteristic)\r\n"); } else { printf("\r\n"); @@ -172,9 +146,9 @@ class ClockService { * * @param handle Handle of the characteristic value affected by the change. */ - void when_update_enabled(GattAttribute::Handle_t handle) + void onUpdatesEnabled(const GattUpdatesEnabledCallbackParams ¶ms) override { - printf("update enabled on handle %d\r\n", handle); + printf("update enabled on handle %d\r\n", params.attHandle); } /** @@ -183,9 +157,9 @@ class ClockService { * * @param handle Handle of the characteristic value affected by the change. */ - void when_update_disabled(GattAttribute::Handle_t handle) + void onUpdatesDisabled(const GattUpdatesDisabledCallbackParams ¶ms) override { - printf("update disabled on handle %d\r\n", handle); + printf("update disabled on handle %d\r\n", params.attHandle); } /** @@ -194,11 +168,12 @@ class ClockService { * @param handle Handle of the characteristic value that has emitted the * indication. */ - void when_confirmation_received(GattAttribute::Handle_t handle) + void onConfirmationReceived(const GattConfirmationReceivedCallbackParams ¶ms) override { - printf("confirmation received on handle %d\r\n", handle); + printf("confirmation received on handle %d\r\n", params.attHandle); } +private: /** * Handler called when a write request is received. * @@ -303,16 +278,6 @@ class ClockService { } private: - /** - * Helper that construct an event handler from a member function of this - * instance. - */ - template - FunctionPointerWithContext as_cb(void (Self::*member)(Arg)) - { - return makeFunctionPointer(this, member); - } - /** * Read, Write, Notify, Indicate Characteristic declaration helper. * @@ -335,10 +300,10 @@ class ClockService { /* Value size */ sizeof(_value), /* Value capacity */ sizeof(_value), /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, - /* Descriptors */ NULL, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, + /* Descriptors */ nullptr, /* Num descriptors */ 0, /* variable len */ false ), @@ -368,9 +333,8 @@ class ClockService { * @param[in] local_only Flag that determine if the change should be kept * locally or forwarded to subscribed clients. */ - ble_error_t set( - GattServer &server, const uint8_t &value, bool local_only = false - ) const { + ble_error_t set(GattServer &server, const uint8_t &value, bool local_only = false) const + { return server.write(getValueHandle(), &value, sizeof(value), local_only); } @@ -378,34 +342,33 @@ class ClockService { uint8_t _value; }; - ReadWriteNotifyIndicateCharacteristic _hour_char; - ReadWriteNotifyIndicateCharacteristic _minute_char; - ReadWriteNotifyIndicateCharacteristic _second_char; - - // list of the characteristics of the clock service - GattCharacteristic* _clock_characteristics[3]; +private: + GattServer *_server = nullptr; + events::EventQueue *_event_queue = nullptr; - // demo service GattService _clock_service; + GattCharacteristic* _clock_characteristics[3]; - GattServer* _server; - events::EventQueue *_event_queue; + ReadWriteNotifyIndicateCharacteristic _hour_char; + ReadWriteNotifyIndicateCharacteristic _minute_char; + ReadWriteNotifyIndicateCharacteristic _second_char; }; -int main() { - BLE &ble_interface = BLE::Instance(); +int main() +{ + mbed_trace_init(); + + BLE &ble = BLE::Instance(); events::EventQueue event_queue; ClockService demo_service; - BLEProcess ble_process(event_queue, ble_interface); + /* this process will handle basic ble setup and advertising for us */ + GattServerProcess ble_process(event_queue, ble); + + /* once it's done it will let us continue with our demo */ ble_process.on_init(callback(&demo_service, &ClockService::start)); - // bind the event queue to the ble interface, initialize the interface - // and start advertising ble_process.start(); - // Process the event queue. - event_queue.dispatch_forever(); - return 0; } diff --git a/BLE_GattServer_CharacteristicWrite/CMakeLists.txt b/BLE_GattServer_CharacteristicWrite/CMakeLists.txt new file mode 100644 index 00000000..15eca093 --- /dev/null +++ b/BLE_GattServer_CharacteristicWrite/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GattServer_CharacteristicWrite) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_GattServer_CharacteristicWrite/mbed-os-ble-utils.lib b/BLE_GattServer_CharacteristicWrite/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GattServer_CharacteristicWrite/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GattServer_CharacteristicWrite/mbed-os.lib b/BLE_GattServer_CharacteristicWrite/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_GattServer_CharacteristicWrite/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GattServer_CharacteristicWrite/mbed_app.json b/BLE_GattServer_CharacteristicWrite/mbed_app.json new file mode 100644 index 00000000..f81ce44c --- /dev/null +++ b/BLE_GattServer_CharacteristicWrite/mbed_app.json @@ -0,0 +1,28 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_GattServer_CharacteristicWrite/readme.md b/BLE_GattServer_CharacteristicWrite/readme.md new file mode 100644 index 00000000..57261b75 --- /dev/null +++ b/BLE_GattServer_CharacteristicWrite/readme.md @@ -0,0 +1,21 @@ +# Create a writable characteristic on GattServer + +This example creates a writable characteristic and notifies the user of any writes by printing to the serial. +The example will advertise as "GattServer" and await connection. + +This example can be used together with `BLE_GattClient_CharacteristicWrite` running on another board or with +a phone running a BLE scanner application. Either one can connect and write a new value to the writable +characteristic with UUID `0xA001`. + +As the application runs it will update you about its progress over serial and then proceed to print the value +of the writable characteristic every time it's updated. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). diff --git a/BLE_GattServer_CharacteristicWrite/source/main.cpp b/BLE_GattServer_CharacteristicWrite/source/main.cpp new file mode 100644 index 00000000..a8a3993d --- /dev/null +++ b/BLE_GattServer_CharacteristicWrite/source/main.cpp @@ -0,0 +1,95 @@ +/* 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 +#include "ble/BLE.h" +#include "gatt_server_process.h" +#include "mbed-trace/mbed_trace.h" + +static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE); + +class GattServerDemo : ble::GattServer::EventHandler { + + const static uint16_t EXAMPLE_SERVICE_UUID = 0xA000; + const static uint16_t WRITABLE_CHARACTERISTIC_UUID = 0xA001; + +public: + GattServerDemo() + { + const UUID uuid = WRITABLE_CHARACTERISTIC_UUID; + _writable_characteristic = new ReadWriteGattCharacteristic (uuid, &_characteristic_value); + + if (!_writable_characteristic) { + printf("Allocation of ReadWriteGattCharacteristic failed\r\n"); + } + } + + ~GattServerDemo() + { + } + + void start(BLE &ble, events::EventQueue &event_queue) + { + const UUID uuid = EXAMPLE_SERVICE_UUID; + GattCharacteristic* charTable[] = { _writable_characteristic }; + GattService example_service(uuid, charTable, 1); + + ble.gattServer().addService(example_service); + + ble.gattServer().setEventHandler(this); + + printf("Example service added with UUID 0xA000\r\n"); + printf("Connect and write to characteristic 0xA001\r\n"); + } + +private: + /** + * This callback allows the LEDService to receive updates to the ledState Characteristic. + * + * @param[in] params Information about the characterisitc being updated. + */ + virtual void onDataWritten(const GattWriteCallbackParams ¶ms) + { + if ((params.handle == _writable_characteristic->getValueHandle()) && (params.len == 1)) { + printf("New characteristic value written: %x\r\n", *(params.data)); + } + } + +private: + ReadWriteGattCharacteristic *_writable_characteristic = nullptr; + uint8_t _characteristic_value = 0; +}; + +int main() +{ + mbed_trace_init(); + + BLE &ble = BLE::Instance(); + + printf("\r\nGattServer demo of a writable characteristic\r\n"); + + GattServerDemo demo; + + /* this process will handle basic setup and advertising for us */ + GattServerProcess ble_process(event_queue, ble); + + /* once it's done it will let us continue with our demo*/ + ble_process.on_init(callback(&demo, &GattServerDemo::start)); + + ble_process.start(); + + return 0; +} diff --git a/BLE_GattServer_ExperimentalServices/CMakeLists.txt b/BLE_GattServer_ExperimentalServices/CMakeLists.txt new file mode 100644 index 00000000..e11b3955 --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_GattServer_ExperimentalServices) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) +add_subdirectory(mbed-os-experimental-ble-services/services/CurrentTime) +add_subdirectory(mbed-os-experimental-ble-services/services/LinkLoss) + +add_executable(${APP_TARGET}) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils + ble-service-link-loss + ble-service-current-time +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_GattServer_ExperimentalServices/README.md b/BLE_GattServer_ExperimentalServices/README.md new file mode 100644 index 00000000..58e38322 --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/README.md @@ -0,0 +1,102 @@ +# Experimental Services +This example demonstrates the Link Loss and Current Time Services from the [Experimental BLE Services](https://github.com/ARMmbed/mbed-os-experimental-ble-services) repository. + +## Overview + +### Link Loss Service +The application sends an alert message over a serial terminal once the connection to the client is lost without prior warning. +The client sets the alert level by writing a valid byte to the alert level characteristic inside the Link Loss Service (LLS): + +* 0x00 ("No Alert") +* 0x01 ("Mild Alert") +* 0x02 ("High Alert") + +The alert ends after a user-defined timeout (= 1 minute). + +### Current Time Service +The application permits reading/writing of the device's current time. +In the latter case, the client sets the current time by writing a stream of bytes to the current time characteristic inside the Current Time Service (CTS). +Table 1 shows the byte stream required to set the device's current time to Wed, 28 Oct 2009 11:35:37. + +| B0 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | +|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| +| 0xD9 | 0x07 | 0x0A | 0x1C | 0x0B | 0x23 | 0x25 | 0x03 | 0x00 | 0x00 | + +**Table 1. Byte stream required to set the device's current time to Wed, 28 Oct 2009 11:35:37** + +## Usage + +### Hardware Requirements +Please refer to the main [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +### Build Instructions +Please refer to the main [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +### Demonstration +**Note:** The steps given below demonstrate the application using an Android smartphone running nRF Connect 4.24.3. +The illustrations will be different for other clients. +* Build the application and flash the board +* Open a serial terminal on your host to receive serial prints from the application: + `mbed term -b 115200` +* Open nRF Connect, locate your device and press connect (Fig. 1) + +![](img/connect.png) + +**Fig. 1 Connecting to the device** + +#### Link Loss Service + +* Select the Link Loss Service from the list of available services (Fig. 2) + +![](img/select_lls.png) + +**Fig. 2 Selecting the Link Loss Service** + +* Press the upward pointing arrow to interact with the alert level characteristic (Fig. 3) + +![](img/interact_alert_level.png) + +**Fig. 3. Interacting with the alert level characteristic** + +* Select an appropriate alert level from the dropdown menu and press send (Fig. 4) + +![](img/write_alert_level.png) + +**Fig. 4. Writing the alert level characteristic** + +* Confirm that the value parameter was updated after the write (Fig. 5) + +![](img/read_alert_level.png) + +**Fig. 5. Reading the alert level characteristic** + +* Go far enough away from the device so that nRF Connect disconnects in an ungraceful fashion +* The alert level should appear at your terminal, e.g. "High Alert!" + +#### Current Time Service + +* Select the Current Time Service from the list of available services (Fig. 6) + +![](img/select_cts.png) + +**Fig. 6. Selecting the Current Time Service** + +* Press the upward pointing arrow to interact with the current time characteristic (Fig. 7) + +![](img/interact_current_time.png) + +**Fig. 7. Interacting with the current time characteristic** + +* Create a new write value for the byte stream in Table 1, save and load it, and press send (Fig. 8) + +![](img/write_current_time.png) + +**Fig. 8. Writing the current time characteristic** + +* Confirm that the value parameter was updated with the correct date/time after the write (Fig. 9) + +![](img/read_current_time.png) + +**Fig. 9. Reading the current time characteristic** + +* The current time in seconds should appear at your terminal, i.e. "1256729737" diff --git a/BLE_GattServer_ExperimentalServices/img/connect.png b/BLE_GattServer_ExperimentalServices/img/connect.png new file mode 100755 index 00000000..cd49a0a7 Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/connect.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/interact_alert_level.png b/BLE_GattServer_ExperimentalServices/img/interact_alert_level.png new file mode 100755 index 00000000..2fc3a3f1 Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/interact_alert_level.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/interact_current_time.png b/BLE_GattServer_ExperimentalServices/img/interact_current_time.png new file mode 100755 index 00000000..291bf32d Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/interact_current_time.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/read_alert_level.png b/BLE_GattServer_ExperimentalServices/img/read_alert_level.png new file mode 100755 index 00000000..1a43531b Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/read_alert_level.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/read_current_time.png b/BLE_GattServer_ExperimentalServices/img/read_current_time.png new file mode 100755 index 00000000..d2c2696d Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/read_current_time.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/select_cts.png b/BLE_GattServer_ExperimentalServices/img/select_cts.png new file mode 100755 index 00000000..e9d5cfcc Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/select_cts.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/select_lls.png b/BLE_GattServer_ExperimentalServices/img/select_lls.png new file mode 100755 index 00000000..6915eba9 Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/select_lls.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/write_alert_level.png b/BLE_GattServer_ExperimentalServices/img/write_alert_level.png new file mode 100755 index 00000000..8dd57e45 Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/write_alert_level.png differ diff --git a/BLE_GattServer_ExperimentalServices/img/write_current_time.png b/BLE_GattServer_ExperimentalServices/img/write_current_time.png new file mode 100755 index 00000000..2082b745 Binary files /dev/null and b/BLE_GattServer_ExperimentalServices/img/write_current_time.png differ diff --git a/BLE_GattServer_ExperimentalServices/mbed-os-ble-utils.lib b/BLE_GattServer_ExperimentalServices/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_GattServer_ExperimentalServices/mbed-os-experimental-ble-services.lib b/BLE_GattServer_ExperimentalServices/mbed-os-experimental-ble-services.lib new file mode 100644 index 00000000..901cb503 --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/mbed-os-experimental-ble-services.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-experimental-ble-services diff --git a/BLE_GattServer_ExperimentalServices/mbed-os.lib b/BLE_GattServer_ExperimentalServices/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_GattServer_ExperimentalServices/mbed_app.json b/BLE_GattServer_ExperimentalServices/mbed_app.json new file mode 100644 index 00000000..729ca99c --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/mbed_app.json @@ -0,0 +1,23 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200 + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_GattServer_ExperimentalServices/source/main.cpp b/BLE_GattServer_ExperimentalServices/source/main.cpp new file mode 100644 index 00000000..0a38c80f --- /dev/null +++ b/BLE_GattServer_ExperimentalServices/source/main.cpp @@ -0,0 +1,187 @@ +/* mbed Microcontroller Library + * Copyright (c) 2020 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "ble/BLE.h" +#include "ble/gap/Gap.h" +#include "pretty_printer.h" +#include "ble-service-link-loss/LinkLossService.h" +#include "ble-service-current-time/CurrentTimeService.h" +#include "mbed-trace/mbed_trace.h" + +using namespace std::literals::chrono_literals; + +const static char DEVICE_NAME[] = "ExperimentalServices"; + +static events::EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE); +static ChainableGapEventHandler chainable_gap_event_handler; + +class ExperimentalServicesDemo : ble::Gap::EventHandler, LinkLossService::EventHandler, CurrentTimeService::EventHandler { +public: + ExperimentalServicesDemo(BLE &ble, events::EventQueue &event_queue, ChainableGapEventHandler &chainable_gap_event_handler) : + _ble(ble), + _event_queue(event_queue), + _chainable_gap_event_handler(chainable_gap_event_handler), + _link_loss_service(_ble, _event_queue, _chainable_gap_event_handler), + _current_time_service(_ble, _event_queue), + _adv_data_builder(_adv_buffer) + { + } + + void start() + { + _ble.init(this, &ExperimentalServicesDemo::on_init_complete); + + _event_queue.dispatch_forever(); + } + +private: + void on_init_complete(BLE::InitializationCompleteCallbackContext *params) + { + if (params->error != BLE_ERROR_NONE) { + printf("Ble initialization failed."); + return; + } + + print_mac_address(); + + /* The ChainableGapEventHandler allows us to dispatch events from GAP to more than a single event handler */ + _chainable_gap_event_handler.addEventHandler(this); + _ble.gap().setEventHandler(&_chainable_gap_event_handler); + + _link_loss_service.init(); + + _link_loss_service.set_event_handler(this); + _link_loss_service.set_alert_timeout(60000ms); + + _current_time_service.init(); + + _current_time_service.set_event_handler(this); + + start_advertising(); + } + + void start_advertising() + { + ble::AdvertisingParameters adv_parameters( + ble::advertising_type_t::CONNECTABLE_UNDIRECTED, + ble::adv_interval_t(ble::millisecond_t(100)) + ); + + _adv_data_builder.setFlags(); + _adv_data_builder.setAppearance(ble::adv_data_appearance_t::UNKNOWN); + _adv_data_builder.setName(DEVICE_NAME); + + ble_error_t error = _ble.gap().setAdvertisingParameters( + ble::LEGACY_ADVERTISING_HANDLE, + adv_parameters + ); + + if (error) { + printf("_ble.gap().setAdvertisingParameters() failed\r\n"); + return; + } + + error = _ble.gap().setAdvertisingPayload( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + if (error) { + printf("_ble.gap().setAdvertisingPayload() failed\r\n"); + return; + } + + error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + + if (error) { + printf("_ble.gap().startAdvertising() failed\r\n"); + return; + } + + printf("Device advertising, please connect\r\n"); + } + + void on_alert_requested(LinkLossService::AlertLevel level) final + { + if (level == LinkLossService::AlertLevel::MILD_ALERT) { + printf("Mild Alert!\r\n"); + } else { + printf("High Alert!\r\n"); + } + } + + void on_alert_end() final + { + printf("Alert ended\r\n"); + } + + void on_current_time_changed(time_t current_time, uint8_t adjust_reason) final + { + printf("Current time: %ld - Adjust reason: %d\r\n", (long)current_time, adjust_reason); + } + +private: + void onConnectionComplete(const ble::ConnectionCompleteEvent &event) override + { + if (event.getStatus() == ble_error_t::BLE_ERROR_NONE) { + printf("Client connected, you may now subscribe to updates\r\n"); + } + } + + void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) override + { + printf("Client disconnected, restarting advertising\r\n"); + + ble_error_t error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + + if (error) { + printf("_ble.gap().startAdvertising() failed\r\n"); + return; + } + } + +private: + BLE &_ble; + events::EventQueue &_event_queue; + ChainableGapEventHandler &_chainable_gap_event_handler; + + LinkLossService _link_loss_service; + CurrentTimeService _current_time_service; + + uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; + ble::AdvertisingDataBuilder _adv_data_builder; +}; + +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ + event_queue.call(Callback(&context->ble, &BLE::processEvents)); +} + +int main() +{ + mbed_trace_init(); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(schedule_ble_events); + + set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37 + + ExperimentalServicesDemo demo(ble, event_queue, chainable_gap_event_handler); + demo.start(); + + return 0; +} diff --git a/BLE_HeartRate/.mbed b/BLE_HeartRate/.mbed deleted file mode 100644 index 759f2942..00000000 --- a/BLE_HeartRate/.mbed +++ /dev/null @@ -1,3 +0,0 @@ -TARGET=NRF51_DK -TOOLCHAIN=GCC_ARM -ROOT=. diff --git a/BLE_HeartRate/img/start_scan.png b/BLE_HeartRate/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/BLE_HeartRate/img/start_scan.png and /dev/null differ diff --git a/BLE_HeartRate/mbed-os.lib b/BLE_HeartRate/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_HeartRate/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_HeartRate/mbed_app.json b/BLE_HeartRate/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_HeartRate/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_HeartRate/module.json b/BLE_HeartRate/module.json deleted file mode 100644 index 5b6dd868..00000000 --- a/BLE_HeartRate/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-heartrate", - "version": "0.0.1", - "description": "BLE Heartreate example, building with yotta", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/BLE_HeartRate/readme.md b/BLE_HeartRate/readme.md deleted file mode 100644 index 715a413a..00000000 --- a/BLE_HeartRate/readme.md +++ /dev/null @@ -1,64 +0,0 @@ -# BLE Heart Rate Monitor - -This application transmits a heart rate value using the [Bluetooth SIG Heart Rate Profile](https://developer.bluetooth.org/TechnologyOverview/Pages/HRP.aspx). The heart rate value is provided by the application itself, not by a sensor, so that you don't have to get a sensor just to run the example. - -Technical details are better presented [in the mbed Classic equivalent of this example](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_HeartRate/). - -# Running the application - -## Requirements - -To see the heart rate information on your phone, use a BLE scanner: - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named `HRM`. - - ![](img/scan_result.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *Heart Rate* service has the UUID `0x180D` and includes the *Heart Rate Measurement* characteristic which has the UUID `0x2A37`. - - ![](img/discovery.png) - - **figure 4** Representation of the Heart Rate service using Master Control Panel 4.0.5 - -1. Register for the notifications sent by the *Heart Rate Measurement* characteristic. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. You should see the heart rate value change every half second. It begins at 100, goes up to 175 (in steps of 1), resets to 100 and so on. - - ![](img/notifications.png) - - **figure 6** Notifications view using Master Control Panel 4.0.5 diff --git a/BLE_HeartRate/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_HeartRate/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_HeartRate/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_HeartRate/source/pretty_printer.h b/BLE_HeartRate/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_HeartRate/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_LED/.mbed b/BLE_LED/.mbed deleted file mode 100644 index d0a01aed..00000000 --- a/BLE_LED/.mbed +++ /dev/null @@ -1,3 +0,0 @@ -ROOT=. -TARGET=DISCO_L475VG_IOT01A -TOOLCHAIN=ARM diff --git a/BLE_LED/img/LED_OFF.png b/BLE_LED/img/LED_OFF.png deleted file mode 100644 index 92598671..00000000 Binary files a/BLE_LED/img/LED_OFF.png and /dev/null differ diff --git a/BLE_LED/img/LED_ON.png b/BLE_LED/img/LED_ON.png deleted file mode 100644 index 1d71afc5..00000000 Binary files a/BLE_LED/img/LED_ON.png and /dev/null differ diff --git a/BLE_LED/img/connection.png b/BLE_LED/img/connection.png deleted file mode 100644 index 4b4e5379..00000000 Binary files a/BLE_LED/img/connection.png and /dev/null differ diff --git a/BLE_LED/img/discovery.png b/BLE_LED/img/discovery.png deleted file mode 100644 index 129dc714..00000000 Binary files a/BLE_LED/img/discovery.png and /dev/null differ diff --git a/BLE_LED/img/scan_results.png b/BLE_LED/img/scan_results.png deleted file mode 100644 index 972f43a8..00000000 Binary files a/BLE_LED/img/scan_results.png and /dev/null differ diff --git a/BLE_LED/img/start_scan.png b/BLE_LED/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/BLE_LED/img/start_scan.png and /dev/null differ diff --git a/BLE_LED/img/write_characteristic.png b/BLE_LED/img/write_characteristic.png deleted file mode 100644 index 853a9ae6..00000000 Binary files a/BLE_LED/img/write_characteristic.png and /dev/null differ diff --git a/BLE_LED/img/write_pannel.png b/BLE_LED/img/write_pannel.png deleted file mode 100644 index c738ce01..00000000 Binary files a/BLE_LED/img/write_pannel.png and /dev/null differ diff --git a/BLE_LED/mbed-os.lib b/BLE_LED/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_LED/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_LED/mbed_app.json b/BLE_LED/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_LED/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_LED/module.json b/BLE_LED/module.json deleted file mode 100644 index bfff0062..00000000 --- a/BLE_LED/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-led", - "version": "0.0.1", - "description": "A simple service that demonstrates the use of a read-write characteristic to control a LED", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/BLE_LED/readme.md b/BLE_LED/readme.md deleted file mode 100644 index 8984462b..00000000 --- a/BLE_LED/readme.md +++ /dev/null @@ -1,93 +0,0 @@ -To help you create your own BLE services, we have created this service template. -The LED example demonstrates the use of a read-write characteristic to control a -LED through a phone app. - -The template covers: - -* Setting up advertising and connection states. -* Assigning UUIDs to the service and its characteristic. -* Creating an input characteristic: read-write, boolean. This characteristic offers control of the LED. -* Constructing a service class and adding it to the BLE stack. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install: - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -*NOTE:* If you have more than a single mbed board (e.g. nrf51dk or mkit) you can -run the BLE_LED and BLE_LEDBlinker at the same time. For more information please -refer to the BLE_LEDBlinker demo. - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. - -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named `LED`. - - ![](img/scan_results.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *LED service* has the UUID `0xA000` and includes the *LED state characteristic* which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value. - - ![](img/discovery.png) - - **figure 4** Representation of the Led service using Master Control Panel 4.0.5 - -1. Open the write pannel of the *LED state* characteristic. - - ![](img/write_characteristic.png) - - **figure 5** How to read and write a characteristic value using Master Control Panel 4.0.5 - - -1. The characteristic accept a 1 byte value: - - ![](img/write_pannel.png) - - **figure 6** Write characteristic panel using Master Control Panel 4.0.5 - - * `0x00`: LED ON/OFF (board dependant) - - ![](img/LED_ON.png) - - **figure 6** Write characteristic panel to set the LED on using Master Control Panel 4.0.5 - - - * `0x01`: LED OFF/ON (board dependant) - - ![](img/LED_OFF.png) - - **figure 6** Write characteristic panel to set the LED off using Master Control Panel 4.0.5 - - -1. Toggle the LED characteristic value and see the LED turn ON or turn OFF according to the value you set. - -If you can see the characteristic, and the LED is turned on/off as you toggle its value, the application is working properly. diff --git a/BLE_LED/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_LED/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_LED/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_LED/source/LEDService.h b/BLE_LED/source/LEDService.h deleted file mode 100644 index 40dd2f08..00000000 --- a/BLE_LED/source/LEDService.h +++ /dev/null @@ -1,44 +0,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. - */ - -#ifndef __BLE_LED_SERVICE_H__ -#define __BLE_LED_SERVICE_H__ - -class LEDService { -public: - const static uint16_t LED_SERVICE_UUID = 0xA000; - const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001; - - LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) : - ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic) - { - GattCharacteristic *charTable[] = {&ledState}; - GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - - ble.gattServer().addService(ledService); - } - - GattAttribute::Handle_t getValueHandle() const - { - return ledState.getValueHandle(); - } - -private: - BLEDevice &ble; - ReadWriteGattCharacteristic ledState; -}; - -#endif /* #ifndef __BLE_LED_SERVICE_H__ */ diff --git a/BLE_LED/source/main.cpp b/BLE_LED/source/main.cpp deleted file mode 100644 index a9170a68..00000000 --- a/BLE_LED/source/main.cpp +++ /dev/null @@ -1,163 +0,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 -#include -#include "ble/BLE.h" -#include "LEDService.h" -#include "pretty_printer.h" - -const static char DEVICE_NAME[] = "LED"; - -static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE); - -class LEDDemo : ble::Gap::EventHandler { -public: - LEDDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _alive_led(LED1, 1), - _actuated_led(LED2, 0), - _led_uuid(LEDService::LED_SERVICE_UUID), - _led_service(NULL), - _adv_data_builder(_adv_buffer) { } - - ~LEDDemo() { - delete _led_service; - } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &LEDDemo::on_init_complete); - - _event_queue.call_every(500, this, &LEDDemo::blink); - - _event_queue.dispatch_forever(); - } - -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - printf("Ble initialization failed."); - return; - } - - _led_service = new LEDService(_ble, false); - - _ble.gattServer().onDataWritten(this, &LEDDemo::on_data_written); - - print_mac_address(); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - _adv_data_builder.setFlags(); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_led_uuid, 1)); - _adv_data_builder.setName(DEVICE_NAME); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - printf("_ble.gap().setAdvertisingParameters() failed\r\n"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - printf("_ble.gap().setAdvertisingPayload() failed\r\n"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - printf("_ble.gap().startAdvertising() failed\r\n"); - return; - } - } - - /** - * This callback allows the LEDService to receive updates to the ledState Characteristic. - * - * @param[in] params Information about the characterisitc being updated. - */ - void on_data_written(const GattWriteCallbackParams *params) { - if ((params->handle == _led_service->getValueHandle()) && (params->len == 1)) { - _actuated_led = *(params->data); - } - } - - void blink() { - _alive_led = !_alive_led; - } - -private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - DigitalOut _alive_led; - DigitalOut _actuated_led; - - UUID _led_uuid; - LEDService *_led_service; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - LEDDemo demo(ble, event_queue); - demo.start(); - - return 0; -} - diff --git a/BLE_LED/source/pretty_printer.h b/BLE_LED/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_LED/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/BLE_LEDBlinker/.mbed b/BLE_LEDBlinker/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_LEDBlinker/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_LEDBlinker/mbed-os.lib b/BLE_LEDBlinker/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_LEDBlinker/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_LEDBlinker/mbed_app.json b/BLE_LEDBlinker/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_LEDBlinker/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_LEDBlinker/module.json b/BLE_LEDBlinker/module.json deleted file mode 100644 index aecbe4c1..00000000 --- a/BLE_LEDBlinker/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-ledblinker", - "version": "0.0.1", - "description": "An initial demo showcasing the GattClient APIs. Drives an LED service exported by a BLE_LED peripheral. Shows scanning, connections, service-discovery, and reads/writes.", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "bin": "./source" -} diff --git a/BLE_LEDBlinker/readme.md b/BLE_LEDBlinker/readme.md deleted file mode 100644 index 1539d2dc..00000000 --- a/BLE_LEDBlinker/readme.md +++ /dev/null @@ -1,54 +0,0 @@ -# BLE LED Blinker - -This example demonstrates using the ``GattClient`` API to control BLE client devices. - -The example uses two applications running on two different devices: - -1. The first device - the central - runs the application ``BLE_LEDBlinker`` from this repository. This application sends an on/off toggle over BLE. - -1. The second device - the peripheral - runs the application [``BLE_LED``](https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_LED) to respond to the toggle. - - The toggle simply turns the LED on the peripheral device on and off. - -# Running the application - -## Requirements - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -This example requires *two* devices. - -## Building instructions - -You will need to build both applications and flash each one to a different board. - -Please note: The application ``BLE_LEDBlinker`` in this repository initiate a connection to all ble devices which advertise "LED" as complete local name. By default, the application `BLE_LED` advertise "LED" as complete local name. If you change the local name advertised by the application `BLE_LED` you should reflect your change in this application by changing the value of the constant `PEER_NAME` in `main.cpp`. - -**Tip:** You may notice that the application also checks the LED characteristic's UUID; you don't need to change this parameter's value, because it already matches the UUID provided by the second application, ``BLE_LED``. - -Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -1. Build both applications and install one on each device, as explained in the building instructions. - -1. The LED number two of the device running ``BLE_LED`` should blink. - - -## Monitoring the application through a serial port - -You can run ``BLE_LEDBlinker`` and see that it works properly by monitoring its serial output. - -You need a terminal program to listen to the output through a serial port. You can download one, for example: - -* Tera Term for Windows. -* CoolTerm for Mac OS X. -* GNU Screen for Linux. - -To see the application's output: - -1. Check which serial port your device is connected to. -1. Run a terminal program with the correct serial port and set the baud rate to 9600. For example, to use GNU Screen, run: ``screen /dev/tty.usbmodem1412 9600``. -1. The application should start printing the toggle's value to the terminal. - -**Note:** ``BLE_LEDBlinker`` will not run properly if the ``BLE_LED`` application is not running on a second device. The terminal will show a few print statements, but you will not be able to see the application in full operation. diff --git a/BLE_LEDBlinker/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_LEDBlinker/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_LEDBlinker/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_LEDBlinker/source/main.cpp b/BLE_LEDBlinker/source/main.cpp deleted file mode 100644 index a6f31ef7..00000000 --- a/BLE_LEDBlinker/source/main.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 -#include -#include "ble/BLE.h" -#include "ble/DiscoveredCharacteristic.h" -#include "ble/DiscoveredService.h" -#include "ble/gap/Gap.h" -#include "ble/gap/AdvertisingDataParser.h" -#include "pretty_printer.h" - -const static char PEER_NAME[] = "LED"; - -static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE); - -static DiscoveredCharacteristic led_characteristic; -static bool trigger_led_characteristic = false; - -void service_discovery(const DiscoveredService *service) { - if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { - printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); - } else { - printf("S UUID-"); - const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); - for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { - printf("%02x", longUUIDBytes[i]); - } - printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); - } -} - -void update_led_characteristic(void) { - if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) { - led_characteristic.read(); - } -} - -void characteristic_discovery(const DiscoveredCharacteristic *characteristicP) { - printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); - if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ - led_characteristic = *characteristicP; - trigger_led_characteristic = true; - } -} - -void discovery_termination(Gap::Handle_t connectionHandle) { - printf("terminated SD for handle %u\r\n", connectionHandle); - if (trigger_led_characteristic) { - trigger_led_characteristic = false; - event_queue.call(update_led_characteristic); - } -} - -void trigger_toggled_write(const GattReadCallbackParams *response) { - if (response->handle == led_characteristic.getValueHandle()) { - printf("trigger_toggled_write: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); - for (unsigned index = 0; index < response->len; index++) { - printf("%c[%02x]", response->data[index], response->data[index]); - } - printf("\r\n"); - - uint8_t toggledValue = response->data[0] ^ 0x1; - led_characteristic.write(1, &toggledValue); - } -} - -void trigger_read(const GattWriteCallbackParams *response) { - if (response->handle == led_characteristic.getValueHandle()) { - led_characteristic.read(); - } -} - -class LEDBlinkerDemo : ble::Gap::EventHandler { -public: - LEDBlinkerDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _alive_led(LED1, 1), - _actuated_led(LED2, 0), - _is_connecting(false) { } - - ~LEDBlinkerDemo() { } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &LEDBlinkerDemo::on_init_complete); - - _event_queue.call_every(500, this, &LEDBlinkerDemo::blink); - - _event_queue.dispatch_forever(); - } - -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - printf("Ble initialization failed."); - return; - } - - print_mac_address(); - - _ble.gattClient().onDataRead(trigger_toggled_write); - _ble.gattClient().onDataWritten(trigger_read); - - ble::ScanParameters scan_params; - _ble.gap().setScanParameters(scan_params); - _ble.gap().startScan(); - } - - void blink() { - _alive_led = !_alive_led; - } - -private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startScan(); - _is_connecting = false; - } - - void onConnectionComplete(const ble::ConnectionCompleteEvent& event) { - if (event.getOwnRole() == Gap::CENTRAL) { - _ble.gattClient().onServiceDiscoveryTermination(discovery_termination); - _ble.gattClient().launchServiceDiscovery( - event.getConnectionHandle(), - service_discovery, - characteristic_discovery, - 0xa000, - 0xa001 - ); - } else { - _ble.gap().startScan(); - } - _is_connecting = false; - } - - void onAdvertisingReport(const ble::AdvertisingReportEvent &event) { - /* don't bother with analysing scan result if we're already connecting */ - if (_is_connecting) { - return; - } - - ble::AdvertisingDataParser adv_data(event.getPayload()); - - /* parse the advertising payload, looking for a discoverable device */ - while (adv_data.hasNext()) { - ble::AdvertisingDataParser::element_t field = adv_data.next(); - - /* connect to a discoverable device */ - if (field.type == ble::adv_data_type_t::COMPLETE_LOCAL_NAME && - field.value.size() == strlen(PEER_NAME) && - (memcmp(field.value.data(), PEER_NAME, field.value.size()) == 0)) { - - printf("Adv from: "); - print_address(event.getPeerAddress().data()); - printf(" rssi: %d, scan response: %u, connectable: %u\r\n", - event.getRssi(), event.getType().scan_response(), event.getType().connectable()); - - ble_error_t error = _ble.gap().stopScan(); - - if (error) { - print_error(error, "Error caused by Gap::stopScan"); - return; - } - - const ble::ConnectionParameters connection_params; - - error = _ble.gap().connect( - event.getPeerAddressType(), - event.getPeerAddress(), - connection_params - ); - - if (error) { - _ble.gap().startScan(); - 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; - } - } - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - DigitalOut _alive_led; - DigitalOut _actuated_led; - bool _is_connecting; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - LEDBlinkerDemo demo(ble, event_queue); - demo.start(); - - return 0; -} diff --git a/BLE_LEDBlinker/source/pretty_printer.h b/BLE_LEDBlinker/source/pretty_printer.h deleted file mode 100644 index 7b1a7d6e..00000000 --- a/BLE_LEDBlinker/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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"; - } -} diff --git a/BLE_PeriodicAdvertising/.mbed b/BLE_PeriodicAdvertising/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_PeriodicAdvertising/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_PeriodicAdvertising/CMakeLists.txt b/BLE_PeriodicAdvertising/CMakeLists.txt new file mode 100644 index 00000000..fffb4e8c --- /dev/null +++ b/BLE_PeriodicAdvertising/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_PeriodicAdvertising) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_PeriodicAdvertising/README.md b/BLE_PeriodicAdvertising/README.md index ddc78b8b..464ce4bd 100644 --- a/BLE_PeriodicAdvertising/README.md +++ b/BLE_PeriodicAdvertising/README.md @@ -1,26 +1,18 @@ -# Periodic advertising and scanning +Demo of the periodic advertising. This requires two devices to run. Both devices run the same program. +They attempt to find find each other after which they adopt complementary roles. One sets up periodic advertising. +The other attempts to scan and sync with the periodic advertising. -Demo of the periodic advertising. This requires two devices to run. Both devices run the same program. They attempt to find find each other after which they adopt complementary roles. One sets up periodic advertising. The other attempts to scan and sync with the periodic advertising. - -The role of the scanner device can also be performed by a BLE scanner on a smartphone. Connect to the advertiser. This will establish it as the advertiser. After you disconnect the device will begin periodic advertising. +The role of the scanner device can also be performed by a BLE scanner on a smartphone. +Connect to the advertiser. This will establish it as the advertiser. After you disconnect the device will begin periodic +advertising. # Running the application ## Requirements -Devices must support extended advertising and periodic advertising (Bluetooth version 5+). - -The sample application can also be monitored by any BLE scanner on a smartphone. - -If you don't have a scanner on your phone, please install: +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Information about activity is printed over the serial connection - please have a client open. You may use: - -- [Tera Term](https://ttssh2.osdn.jp/index.html.en) +Devices must support extended advertising and periodic advertising (Bluetooth version 5+). ## Building instructions diff --git a/BLE_PeriodicAdvertising/mbed-os-ble-utils.lib b/BLE_PeriodicAdvertising/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_PeriodicAdvertising/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_PeriodicAdvertising/mbed-os.lib b/BLE_PeriodicAdvertising/mbed-os.lib index 0ec01f6e..144619b6 100644 --- a/BLE_PeriodicAdvertising/mbed-os.lib +++ b/BLE_PeriodicAdvertising/mbed-os.lib @@ -1 +1 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e \ No newline at end of file +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_PeriodicAdvertising/mbed_app.json b/BLE_PeriodicAdvertising/mbed_app.json index f6d83692..90065907 100644 --- a/BLE_PeriodicAdvertising/mbed_app.json +++ b/BLE_PeriodicAdvertising/mbed_app.json @@ -1,26 +1,28 @@ -{ + { "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, "K64F": { + "target.components_add": ["BlueNRG_MS"], "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] + "target.extra_labels_add": ["CORDIO"] }, "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] + "target.extra_labels_add": ["CORDIO"] }, "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] + "target.features_add": ["BLE"] }, "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] + "target.features_add": ["BLE"] } } } diff --git a/BLE_PeriodicAdvertising/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_PeriodicAdvertising/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_PeriodicAdvertising/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_PeriodicAdvertising/source/main.cpp b/BLE_PeriodicAdvertising/source/main.cpp index dc98e039..670f0822 100644 --- a/BLE_PeriodicAdvertising/source/main.cpp +++ b/BLE_PeriodicAdvertising/source/main.cpp @@ -15,23 +15,20 @@ */ #include -#include #include "ble/BLE.h" -#include "gap/Gap.h" -#include "gap/AdvertisingDataParser.h" #include "pretty_printer.h" -#include "BatteryService.h" +#include "mbed-trace/mbed_trace.h" /** This example demonstrates extended and periodic advertising */ +using namespace std::literals::chrono_literals; + events::EventQueue event_queue; static const char DEVICE_NAME[] = "Periodic"; static const uint16_t MAX_ADVERTISING_PAYLOAD_SIZE = 50; -static const uint16_t SCAN_TIME = 5000; -static const uint8_t CONNECTION_DURATION = 2; /** Demonstrate periodic advertising and scanning and syncing with the advertising */ @@ -40,18 +37,8 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E public: PeriodicDemo(BLE& ble, events::EventQueue& event_queue) : _ble(ble), - _gap(ble.gap()), _event_queue(event_queue), - _led1(LED1, 0), - _is_scanner(false), - _is_connecting_or_syncing(false), - _role_established(false), - _battery_uuid(GattService::UUID_BATTERY_SERVICE), - _battery_level(100), - _battery_service(ble, _battery_level), - _adv_data_builder(_adv_buffer), - _adv_handle(ble::INVALID_ADVERTISING_HANDLE), - _sync_handle(ble::INVALID_ADVERTISING_HANDLE) + _adv_data_builder(_adv_buffer) { } @@ -65,13 +52,8 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E /** Start BLE interface initialisation */ void run() { - if (_ble.hasInitialized()) { - printf("Ble instance already initialised.\r\n"); - return; - } - /* handle gap events */ - _gap.setEventHandler(this); + _ble.gap().setEventHandler(this); ble_error_t error = _ble.init(this, &PeriodicDemo::on_init_complete); if (error) { @@ -79,9 +61,6 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E return; } - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &PeriodicDemo::blink); - /* this will not return until shutdown */ _event_queue.dispatch_forever(); } @@ -95,8 +74,8 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E return; } - if (!_gap.isFeatureSupported(ble::controller_supported_features_t::LE_EXTENDED_ADVERTISING) || - !_gap.isFeatureSupported(ble::controller_supported_features_t::LE_PERIODIC_ADVERTISING)) { + if (!_ble.gap().isFeatureSupported(ble::controller_supported_features_t::LE_EXTENDED_ADVERTISING) || + !_ble.gap().isFeatureSupported(ble::controller_supported_features_t::LE_PERIODIC_ADVERTISING)) { printf("Periodic advertising not supported, cannot run example.\r\n"); return; } @@ -104,7 +83,7 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E print_mac_address(); /* all calls are serialised on the user thread through the event queue */ - _event_queue.call(this, &PeriodicDemo::start_role); + start_role(); } void start_role() @@ -134,44 +113,44 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E { ble_error_t error; - ble::AdvertisingParameters adv_params; - adv_params.setUseLegacyPDU(false); - adv_params.setOwnAddressType(ble::own_address_type_t::RANDOM); - - /* create the advertising set with its parameter if we haven't yet */ + /* only create the set first time we advertise */ if (_adv_handle == ble::INVALID_ADVERTISING_HANDLE) { - error = _gap.createAdvertisingSet( + ble::AdvertisingParameters adv_parameters( + ble::advertising_type_t::CONNECTABLE_NON_SCANNABLE_UNDIRECTED, + ble::adv_interval_t(ble::millisecond_t(10)) + ); + + adv_parameters.setUseLegacyPDU(false); + + error = _ble.gap().createAdvertisingSet( &_adv_handle, - adv_params + adv_parameters ); if (error) { print_error(error, "Gap::createAdvertisingSet() failed\r\n"); return; } - } else { - _gap.setAdvertisingParameters(_adv_handle, adv_params); - } - _adv_data_builder.clear(); - _adv_data_builder.setFlags(); - _adv_data_builder.setName(DEVICE_NAME); + _adv_data_builder.setFlags(); + _adv_data_builder.setName(DEVICE_NAME); - /* Set payload for the set */ - error = _gap.setAdvertisingPayload( - _adv_handle, - _adv_data_builder.getAdvertisingData() - ); + /* Set payload for the set */ + error = _ble.gap().setAdvertisingPayload( + _adv_handle, + _adv_data_builder.getAdvertisingData() + ); - if (error) { - print_error(error, "Gap::setAdvertisingPayload() failed\r\n"); - return; + if (error) { + print_error(error, "Gap::setAdvertisingPayload() failed\r\n"); + return; + } } /* since we have two boards which might start running this example at the same time * we randomise the interval of advertising to have them meet when one is advertising * and the other one is scanning (we use their random address as source of randomness) */ - ble::millisecond_t random_duration_ms((3 + rand() % 5) * 1000); + ble::millisecond_t random_duration_ms((2 + rand() % 5) * 1000); ble::adv_duration_t random_duration(random_duration_ms); error = _ble.gap().startAdvertising( @@ -189,12 +168,14 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E void advertise_periodic() { - ble::AdvertisingParameters adv_params; - adv_params.setType(ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED); - adv_params.setUseLegacyPDU(false); - adv_params.setOwnAddressType(ble::own_address_type_t::RANDOM); + ble::AdvertisingParameters adv_parameters( + ble::advertising_type_t::NON_CONNECTABLE_UNDIRECTED, + ble::adv_interval_t(ble::millisecond_t(200)) + ); - ble_error_t error = _gap.setAdvertisingParameters(_adv_handle, adv_params); + adv_parameters.setUseLegacyPDU(false); + + ble_error_t error = _ble.gap().setAdvertisingParameters(_adv_handle, adv_parameters); if (error) { print_error(error, "Gap::setAdvertisingParameters() failed\r\n"); @@ -203,45 +184,67 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E /* Start advertising the set as the advertising needs to be active * before we start periodic advertising */ - error = _gap.startAdvertising(_adv_handle); + error = _ble.gap().startAdvertising(_adv_handle); if (error) { print_error(error, "Gap::startAdvertising() failed\r\n"); return; } - error = _gap.setPeriodicAdvertisingParameters( - _adv_handle, - ble::periodic_interval_t(50), - ble::periodic_interval_t(500) - ); + /* periodic advertising will be enabled when advertising starts */ + } + + /** Set up and start scanning */ + void scan() + { + _is_connecting_or_syncing = false; + + ble::ScanParameters scan_params; + scan_params.setOwnAddressType(ble::own_address_type_t::RANDOM); + + ble_error_t error = _ble.gap().setScanParameters(scan_params); if (error) { - print_error(error, "Gap::setPeriodicAdvertisingParameters() failed\r\n"); + print_error(error, "Error caused by Gap::setScanParameters\r\n"); return; } - /* we will put the battery level data in there and update it every second */ - update_payload(); - - error = _gap.startPeriodicAdvertising(_adv_handle); + error = _ble.gap().startScan(ble::scan_duration_t(500)); if (error) { - print_error(error, "Gap::startPeriodicAdvertising() failed\r\n"); + print_error(error, "Error caused by Gap::startScan\r\n"); return; } - printf("Periodic advertising started\r\n"); + printf("Scanning started\r\n"); + } + + void scan_periodic() + { + _is_connecting_or_syncing = false; + + ble_error_t error = _ble.gap().startScan(); + + if (error) { + print_error(error, "Error caused by Gap::startScan\r\n"); + return; + } - /* tick over our fake battery data, this will also update the advertising payload */ - _event_queue.call_every(1000, this, &PeriodicDemo::update_sensor_value); + printf("Scanning for periodic advertising started\r\n"); } - void update_payload() + /* also updates periodic advertising payload */ + void update_sensor_value() { - /* advertising payload will have the battery level which we will update */ + /* simulate battery level */ + _battery_level--; + if (_battery_level < 1) { + _battery_level = 100; + } + + /* update the level in the payload */ ble_error_t error = _adv_data_builder.setServiceData( - _battery_uuid, + GattService::UUID_BATTERY_SERVICE, mbed::make_Span(&_battery_level, 1) ); @@ -252,63 +255,51 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E /* the data in the local host buffer has been updated but now * we have to update the data in the controller */ - error = _gap.setPeriodicAdvertisingPayload( + error = _ble.gap().setPeriodicAdvertisingPayload( _adv_handle, _adv_data_builder.getAdvertisingData() ); if (error) { print_error(error, "Gap::setPeriodicAdvertisingPayload() failed\r\n"); - return; } } - /** Set up and start scanning */ - void scan() - { - _is_connecting_or_syncing = false; - - ble::ScanParameters scan_params; - scan_params.setOwnAddressType(ble::own_address_type_t::RANDOM); - - ble_error_t error = _gap.setScanParameters(scan_params); - - if (error) { - print_error(error, "Error caused by Gap::setScanParameters\r\n"); - return; - } +private: + /* Gap::EventHandler */ - error = _gap.startScan(ble::scan_duration_t(500)); + void onAdvertisingStart(const ble::AdvertisingStartEvent &event) override + { + /* start periodic advertising only if we're already advertising after roles established */ + if (_role_established) { + ble_error_t error = _ble.gap().setPeriodicAdvertisingParameters( + _adv_handle, + ble::periodic_interval_t(100), + ble::periodic_interval_t(1000) + ); - if (error) { - print_error(error, "Error caused by Gap::startScan\r\n"); - return; - } + if (error) { + print_error(error, "Gap::setPeriodicAdvertisingParameters() failed\r\n"); + return; + } - printf("Scanning started\r\n"); - } + error = _ble.gap().startPeriodicAdvertising(_adv_handle); - void scan_periodic() - { - _is_connecting_or_syncing = false; + if (error) { + print_error(error, "Gap::startPeriodicAdvertising() failed\r\n"); + return; + } - ble_error_t error = _gap.startScan(); + printf("Periodic advertising started\r\n"); - if (error) { - print_error(error, "Error caused by Gap::startScan\r\n"); - return; + /* tick over our fake battery data, this will also update the advertising payload */ + _event_queue.call_every(1000ms, this, &PeriodicDemo::update_sensor_value); } - - printf("Scanning for periodic advertising started\r\n"); } -private: - /* Gap::EventHandler */ - /** Look at scan payload to find a peer device and connect to it */ - virtual void onAdvertisingReport( - const ble::AdvertisingReportEvent &event - ) { + void onAdvertisingReport(const ble::AdvertisingReportEvent &event) override + { /* don't bother with analysing scan result if we're already connecting */ if (_is_connecting_or_syncing) { return; @@ -332,15 +323,15 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E /* if we haven't established our roles connect, otherwise sync with advertising */ if (_role_established) { printf("We found the peer, syncing with SID %d" - "and periodic interval %dms\r\n", + " and periodic interval %dms\r\n", event.getSID(), event.getPeriodicInterval().valueInMs()); - ble_error_t error = _gap.createSync( + ble_error_t error = _ble.gap().createSync( event.getPeerAddressType(), event.getPeerAddress(), event.getSID(), 2, - ble::sync_timeout_t(ble::millisecond_t(500)) + ble::sync_timeout_t(ble::millisecond_t(5000)) ); if (error) { @@ -350,7 +341,7 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E } else { printf("We found the peer, connecting\r\n"); - ble_error_t error = _gap.connect( + ble_error_t error = _ble.gap().connect( event.getPeerAddressType(), event.getPeerAddress(), ble::ConnectionParameters() // use the default connection parameters @@ -372,67 +363,63 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E } } - virtual void onAdvertisingEnd( - const ble::AdvertisingEndEvent &event - ) { - if (event.isConnected()) { - printf("Stopped advertising due to connection\r\n"); - } else { - printf("Advertising ended\r\n"); - _event_queue.call(this, &PeriodicDemo::start_role); + void onAdvertisingEnd(const ble::AdvertisingEndEvent &event) override + { + printf("Advertising ended.\r\n"); + if (!event.isConnected()) { + printf("No device connected to us, switch modes.\r\n"); + start_role(); } } - virtual void onScanTimeout( - const ble::ScanTimeoutEvent& - ) { + void onScanTimeout(const ble::ScanTimeoutEvent&) override + { + printf("Scanning ended\r\n"); if (!_is_connecting_or_syncing) { - printf("Scanning ended, failed to find peer\r\n"); - _event_queue.call(this, &PeriodicDemo::start_role); + printf("Failed to find peer\r\n"); + start_role(); } } /** This is called by Gap to notify the application we connected */ - virtual void onConnectionComplete( - const ble::ConnectionCompleteEvent &event - ) { + void onConnectionComplete(const ble::ConnectionCompleteEvent &event) override + { if (event.getStatus() == BLE_ERROR_NONE) { printf("Connected to: "); print_address(event.getPeerAddress().data()); printf("Roles established\r\n"); _role_established = true; - /* 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 disconnect_call_t disconnect_call = &Gap::disconnect; - if (_is_scanner) { + printf("I will synchronise with periodic advertising\r\n"); _event_queue.call_in( - 2000, - &_ble.gap(), - disconnect_call, - event.getConnectionHandle(), - ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION) + 1000ms, + [this, handle = event.getConnectionHandle()] { + _ble.gap().disconnect( + handle, + ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION) + ); + } ); + } else { + printf("I will advertise periodic advertising\r\n"); } } else { printf("Failed to connect\r\n"); - _event_queue.call(this, &PeriodicDemo::start_role); + start_role(); } } /** This is called by Gap to notify the application we disconnected */ - virtual void onDisconnectionComplete( - const ble::DisconnectionCompleteEvent &event - ) { + void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) override + { printf("Disconnected\r\n"); - _event_queue.call(this, &PeriodicDemo::start_role); + start_role(); } /** Called when first advertising packet in periodic advertising is received. */ - virtual void onPeriodicAdvertisingSyncEstablished( - const ble::PeriodicAdvertisingSyncEstablishedEvent &event - ) { + void onPeriodicAdvertisingSyncEstablished(const ble::PeriodicAdvertisingSyncEstablishedEvent &event) override + { if (event.getStatus() == BLE_ERROR_NONE) { printf("Synced with periodic advertising\r\n"); _sync_handle = event.getSyncHandle(); @@ -442,9 +429,8 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E } /** Called when a periodic advertising packet is received. */ - virtual void onPeriodicAdvertisingReport( - const ble::PeriodicAdvertisingReportEvent &event - ) { + void onPeriodicAdvertisingReport(const ble::PeriodicAdvertisingReportEvent &event) override + { ble::AdvertisingDataParser adv_parser(event.getPayload()); /* parse the advertising payload, looking for a battery level */ @@ -452,11 +438,12 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E ble::AdvertisingDataParser::element_t field = adv_parser.next(); if (field.type == ble::adv_data_type_t::SERVICE_DATA) { - if (memcmp(field.value.data(), _battery_uuid.getBaseUUID(), _battery_uuid.getLen()) != 0) { + GattService::UUID_BATTERY_SERVICE; + if (*((uint16_t*)field.value.data()) != GattService::UUID_BATTERY_SERVICE) { printf("Unexpected service data\r\n"); } else { /* battery level is right after the UUID */ - const uint8_t *battery_level = field.value.data() + _battery_uuid.getLen(); + const uint8_t *battery_level = field.value.data() + sizeof(uint16_t); printf("Peer battery level: %d\r\n", *battery_level); } } @@ -464,60 +451,40 @@ class PeriodicDemo : private mbed::NonCopyable, public ble::Gap::E } /** Called when a periodic advertising sync has been lost. */ - virtual void onPeriodicAdvertisingSyncLoss( - const ble::PeriodicAdvertisingSyncLoss &event - ) { + void onPeriodicAdvertisingSyncLoss(const ble::PeriodicAdvertisingSyncLoss &event) override + { printf("Sync to periodic advertising lost\r\n"); _sync_handle = ble::INVALID_ADVERTISING_HANDLE; _event_queue.call(this, &PeriodicDemo::scan_periodic); } private: - void update_sensor_value() { - _battery_level--; - if (_battery_level < 1) { - _battery_level = 100; - } - - _battery_service.updateBatteryLevel(_battery_level); - update_payload(); - } - - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; - } - -private: - BLE &_ble; - ble::Gap &_gap; + BLE &_ble; events::EventQueue &_event_queue; - DigitalOut _led1; - - bool _is_scanner; - bool _is_connecting_or_syncing; - bool _role_established; - - UUID _battery_uuid; - uint8_t _battery_level; - BatteryService _battery_service; - uint8_t _adv_buffer[MAX_ADVERTISING_PAYLOAD_SIZE]; ble::AdvertisingDataBuilder _adv_data_builder; - ble::advertising_handle_t _adv_handle; - ble::periodic_sync_handle_t _sync_handle; + ble::advertising_handle_t _adv_handle = ble::INVALID_ADVERTISING_HANDLE; + ble::periodic_sync_handle_t _sync_handle = ble::INVALID_ADVERTISING_HANDLE; + + uint8_t _battery_level = 100; + + bool _is_scanner = false; + bool _is_connecting_or_syncing = false; + bool _role_established = false; }; /** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ event_queue.call(Callback(&context->ble, &BLE::processEvents)); } int main() { + mbed_trace_init(); + BLE &ble = BLE::Instance(); /* this will inform us off all events so we can schedule their handling diff --git a/BLE_PeriodicAdvertising/source/pretty_printer.h b/BLE_PeriodicAdvertising/source/pretty_printer.h deleted file mode 100644 index 46f0372b..00000000 --- a/BLE_PeriodicAdvertising/source/pretty_printer.h +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 -#include "ble/BLE.h" - -/* for seeding random number generator */ -static bool seeded = false; - -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 */ -inline 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); - - if (!seeded) { - seeded = true; - /* use the address as a seed */ - uint8_t* random_data = address; - srand(*((unsigned int*)random_data)); - } -} - -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"; - } -} diff --git a/BLE_Privacy/.mbed b/BLE_Privacy/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_Privacy/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_Privacy/README.md b/BLE_Privacy/README.md deleted file mode 100644 index d41ce7d7..00000000 --- a/BLE_Privacy/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Privacy - example usage of the privacy feature - -Demonstration of privacy features in Gap. It shows how to use private addresses when advertising and connecting and how filtering ties in with these operations. - -The application will start by repeatedly trying to connect to the same application running on another board. It will do this by advertising and scanning for random intervals waiting until the difference in intervals between the boards will make them meet when one is advertising and the other scanning. - -Two devices will be operating using random resolvable addresses. The application will connect to the peer and pair. It will attempt bonding and if possible create a whitelist based on the bond. - -Subsequent connections will turn on filtering if the whitelist has been successfully created. - -# Running the application - -## Requirements - -Application requires two devices. Each one should be loaded with the same example. The application will alternate between scanning and advertising until the two devices find each other and the demonstration proceeds. - -Information about activity is printed over the serial connection - please have two clients open, each connected to a device. You may use: - -- [Tera Term](https://ttssh2.osdn.jp/index.html.en) - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -Note: example currently doesn't use ST provided stack and instead uses a Cordio port for the ST. diff --git a/BLE_Privacy/mbed-os.lib b/BLE_Privacy/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_Privacy/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_Privacy/mbed_app.json b/BLE_Privacy/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_Privacy/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_Privacy/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_Privacy/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_Privacy/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_Privacy/source/pretty_printer.h b/BLE_Privacy/source/pretty_printer.h deleted file mode 100644 index 7b1a7d6e..00000000 --- a/BLE_Privacy/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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"; - } -} diff --git a/BLE_SM/.mbed b/BLE_SM/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/BLE_SM/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/BLE_SM/README.md b/BLE_SM/README.md deleted file mode 100644 index f082d213..00000000 --- a/BLE_SM/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# SM - example usage of the Security Manager to pair and encrypt - -Demonstration of possible usage of the Security Manager. Security Manager deals with pairing, authentication and encryption. - -The application demonstrates usage as a central and a peripheral. The central will connect to any connectable device present. Please have one ready and advertising. Application will attempt pairing. Please authorise your peer device to pair. - -Upon success it will disconnect and start advertising to demonstrate usage as a peripheral. Please scan and connect using your peer device. Upon connection grant pairing if prompted. Upon success the application will disconnect. Observe the terminal to keep track of the sequence. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Information about activity is printed over the serial connection - please have a client open. You may use: - -- [Tera Term](https://ttssh2.osdn.jp/index.html.en) - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -Note: this example currently is currently not supported on ST BLUENRG targets. diff --git a/BLE_SM/mbed-os.lib b/BLE_SM/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_SM/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_SM/mbed_app.json b/BLE_SM/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_SM/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_SM/module.json b/BLE_SM/module.json deleted file mode 100644 index ce0e2de6..00000000 --- a/BLE_SM/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-securitymanager", - "version": "0.0.1", - "description": "BLE Security Manager usage example", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "bin": "./source" -} diff --git a/BLE_SM/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_SM/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_SM/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_SM/source/main.cpp b/BLE_SM/source/main.cpp deleted file mode 100644 index 3b655190..00000000 --- a/BLE_SM/source/main.cpp +++ /dev/null @@ -1,555 +0,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 -#include -#include "ble/BLE.h" -#include "SecurityManager.h" -#include "pretty_printer.h" - -#if MBED_CONF_APP_FILESYSTEM_SUPPORT -#include "LittleFileSystem.h" -#include "HeapBlockDevice.h" -#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT - -/** This example demonstrates all the basic setup required - * for pairing and setting up link security both as a central and peripheral - * - * The example is implemented as two classes, one for the peripheral and one - * for central inheriting from a common base. They are run in sequence and - * require a peer device to connect to. During the peripheral device demonstration - * a peer device is required to connect. In the central device demonstration - * this peer device will be scanned for and connected to - therefore it should - * be advertising with the same address as when it connected. - * - * During the test output is written on the serial connection to monitor its - * progress. - */ - -static const char DEVICE_NAME[] = "SM_device"; - -/* we have to specify the disconnect call because of ambiguous overloads */ -typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t); -const static disconnect_call_t disconnect_call = &Gap::disconnect; - -/* for demonstration purposes we will store the peer device address - * of the device that connects to us in the first demonstration - * so we can use its address to reconnect to it later */ -static BLEProtocol::AddressBytes_t peer_address; - -/** Base class for both peripheral and central. The same class that provides - * the logic for the application also implements the SecurityManagerEventHandler - * which is the interface used by the Security Manager to communicate events - * back to the applications. You can provide overrides for a selection of events - * your application is interested in. - */ -class SMDevice : private mbed::NonCopyable, - public SecurityManager::EventHandler, - public ble::Gap::EventHandler -{ -public: - SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) : - _led1(LED1, 0), - _ble(ble), - _event_queue(event_queue), - _peer_address(peer_address), - _handle(0), - _is_connecting(false) { }; - - virtual ~SMDevice() - { - if (_ble.hasInitialized()) { - _ble.shutdown(); - } - }; - - /** Start BLE interface initialisation */ - void run() - { - ble_error_t error; - - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &SMDevice::blink); - - if (_ble.hasInitialized()) { - printf("Ble instance already initialised.\r\n"); - return; - } - - /* this will inform us off all events so we can schedule their handling - * using our event queue */ - _ble.onEventsToProcess( - makeFunctionPointer(this, &SMDevice::schedule_ble_events) - ); - - /* handle gap events */ - _ble.gap().setEventHandler(this); - - error = _ble.init(this, &SMDevice::on_init_complete); - - if (error) { - printf("Error returned by BLE::init.\r\n"); - return; - } - - /* this will not return until shutdown */ - _event_queue.dispatch_forever(); - }; - -private: - /** Override to start chosen activity when initialisation completes */ - virtual void start() = 0; - - /** This is called when BLE interface is initialised and starts the demonstration */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - ble_error_t error; - - if (event->error) { - printf("Error during the initialisation\r\n"); - return; - } - - /* This path will be used to store bonding information but will fallback - * to storing in memory if file access fails (for example due to lack of a filesystem) */ - const char* db_path = "/fs/bt_sec_db"; - /* If the security manager is required this needs to be called before any - * calls to the Security manager happen. */ - error = _ble.securityManager().init( - true, - false, - SecurityManager::IO_CAPS_NONE, - NULL, - false, - db_path - ); - - if (error) { - printf("Error during init %d\r\n", error); - return; - } - - error = _ble.securityManager().preserveBondingStateOnReset(true); - - if (error) { - printf("Error during preserveBondingStateOnReset %d\r\n", error); - } - -#if MBED_CONF_APP_FILESYSTEM_SUPPORT - /* Enable privacy so we can find the keys */ - error = _ble.gap().enablePrivacy(true); - - if (error) { - printf("Error enabling privacy\r\n"); - } - - Gap::PeripheralPrivacyConfiguration_t configuration_p = { - /* use_non_resolvable_random_address */ false, - Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS - }; - _ble.gap().setPeripheralPrivacyConfiguration(&configuration_p); - - Gap::CentralPrivacyConfiguration_t configuration_c = { - /* use_non_resolvable_random_address */ false, - Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD - }; - _ble.gap().setCentralPrivacyConfiguration(&configuration_c); - - /* this demo switches between being master and slave */ - _ble.securityManager().setHintFutureRoleReversal(true); -#endif - - /* Tell the security manager to use methods in this class to inform us - * of any events. Class needs to implement SecurityManagerEventHandler. */ - _ble.securityManager().setSecurityManagerEventHandler(this); - - /* gap events also handled by this class */ - _ble.gap().setEventHandler(this); - - /* print device address */ - Gap::AddressType_t addr_type; - Gap::Address_t addr; - _ble.gap().getAddress(&addr_type, addr); - print_address(addr); - - /* start test in 500 ms */ - _event_queue.call_in(500, this, &SMDevice::start); - }; - - /** Schedule processing of events from the BLE in the event queue. */ - void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) - { - _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); - }; - - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; - }; - -private: - /* Event handler */ - - /** Respond to a pairing request. This will be called by the stack - * when a pairing request arrives and expects the application to - * call acceptPairingRequest or cancelPairingRequest */ - virtual void pairingRequest( - ble::connection_handle_t connectionHandle - ) { - printf("Pairing requested - authorising\r\n"); - _ble.securityManager().acceptPairingRequest(connectionHandle); - } - - /** Inform the application of a successful pairing. Terminate the demonstration. */ - virtual void pairingResult( - ble::connection_handle_t connectionHandle, - SecurityManager::SecurityCompletionStatus_t result - ) { - if (result == SecurityManager::SEC_STATUS_SUCCESS) { - printf("Pairing successful\r\n"); - } else { - printf("Pairing failed\r\n"); - } - } - - /** Inform the application of change in encryption status. This will be - * communicated through the serial port */ - virtual void linkEncryptionResult( - ble::connection_handle_t connectionHandle, - ble::link_encryption_t result - ) { - if (result == ble::link_encryption_t::ENCRYPTED) { - printf("Link ENCRYPTED\r\n"); - } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) { - printf("Link ENCRYPTED_WITH_MITM\r\n"); - } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) { - printf("Link NOT_ENCRYPTED\r\n"); - } - - /* disconnect in 2 s */ - _event_queue.call_in( - 2000, - &_ble.gap(), - disconnect_call, - _handle, - ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION) - ); - } - - /** This is called by Gap to notify the application we disconnected, - * in our case it ends the demonstration. */ - virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &) - { - printf("Diconnected\r\n"); - _event_queue.break_dispatch(); - }; - - virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &) - { - printf("Advertising timed out - aborting\r\n"); - _event_queue.break_dispatch(); - } - - virtual void onScanTimeout(const ble::ScanTimeoutEvent &) - { - printf("Scan timed out - aborting\r\n"); - _event_queue.break_dispatch(); - } - -private: - DigitalOut _led1; - -protected: - BLE &_ble; - events::EventQueue &_event_queue; - BLEProtocol::AddressBytes_t &_peer_address; - ble::connection_handle_t _handle; - bool _is_connecting; -}; - -/** A peripheral device will advertise, accept the connection and request - * a change in link security. */ -class SMDevicePeripheral : public SMDevice { -public: - SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) - : SMDevice(ble, event_queue, peer_address) { } - - virtual void start() - { - /* Set up and start advertising */ - uint8_t adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - /* use the helper to build the payload */ - ble::AdvertisingDataBuilder adv_data_builder( - adv_buffer - ); - - adv_data_builder.setFlags(); - adv_data_builder.setName(DEVICE_NAME); - - /* Set payload for the set */ - ble_error_t error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "Gap::setAdvertisingPayload() failed"); - _event_queue.break_dispatch(); - return; - } - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED - ); - - error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "Gap::setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "Gap::startAdvertising() failed"); - return; - } - - printf("Please connect to device\r\n"); - - /** This tells the stack to generate a pairingRequest event - * which will require this application to respond before pairing - * can proceed. Setting it to false will automatically accept - * pairing. */ - _ble.securityManager().setPairingRequestAuthorisation(true); - }; - - /** This is called by Gap to notify the application we connected, - * in our case it immediately requests a change in link security */ - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) - { - ble_error_t error; - - /* remember the device that connects to us now so we can connect to it - * during the next demonstration */ - memcpy(_peer_address, event.getPeerAddress().data(), sizeof(_peer_address)); - - printf("Connected to peer: "); - print_address(event.getPeerAddress().data()); - - _handle = event.getConnectionHandle(); - - /* Request a change in link security. This will be done - * indirectly by asking the master of the connection to - * change it. Depending on circumstances different actions - * may be taken by the master which will trigger events - * which the applications should deal with. */ - error = _ble.securityManager().setLinkSecurity( - _handle, - SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM - ); - - if (error) { - printf("Error during SM::setLinkSecurity %d\r\n", error); - return; - } - }; -}; - -/** A central device will scan, connect to a peer and request pairing. */ -class SMDeviceCentral : public SMDevice { -public: - SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) - : SMDevice(ble, event_queue, peer_address) { } - - virtual void start() - { - ble::ScanParameters params; - ble_error_t error = _ble.gap().setScanParameters(params); - - if (error) { - print_error(error, "Error in Gap::startScan %d\r\n"); - return; - } - - /* start scanning, results will be handled by onAdvertisingReport */ - error = _ble.gap().startScan(); - - if (error) { - print_error(error, "Error in Gap::startScan %d\r\n"); - return; - } - - printf("Please advertise\r\n"); - - printf("Scanning for: "); - print_address(_peer_address); - } - -private: - /* Gap::EventHandler */ - - /** Look at scan payload to find a peer device and connect to it */ - virtual void onAdvertisingReport(const ble::AdvertisingReportEvent &event) - { - /* don't bother with analysing scan result if we're already connecting */ - if (_is_connecting) { - return; - } - - /* parse the advertising payload, looking for a discoverable device */ - if (memcmp(event.getPeerAddress().data(), _peer_address, sizeof(_peer_address)) == 0) { - ble_error_t error = _ble.gap().stopScan(); - - if (error) { - print_error(error, "Error caused by Gap::stopScan"); - return; - } - - ble::ConnectionParameters connection_params( - ble::phy_t::LE_1M, - ble::scan_interval_t(50), - ble::scan_window_t(50), - ble::conn_interval_t(50), - ble::conn_interval_t(100), - ble::slave_latency_t(0), - ble::supervision_timeout_t(100) - ); - connection_params.setOwnAddressType(ble::own_address_type_t::RANDOM); - - error = _ble.gap().connect( - event.getPeerAddressType(), - event.getPeerAddress(), - connection_params - ); - - if (error) { - print_error(error, "Error caused by Gap::connect"); - return; - } - - /* we may have already scan events waiting - * to be processed so we need to remember - * that we are already connecting and ignore them */ - _is_connecting = true; - - return; - } - } - - /** This is called by Gap to notify the application we connected, - * in our case it immediately request pairing */ - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) - { - if (event.getStatus() == BLE_ERROR_NONE) { - /* store the handle for future Security Manager requests */ - _handle = event.getConnectionHandle(); - - printf("Connected\r\n"); - - /* in this example the local device is the master so we request pairing */ - ble_error_t error = _ble.securityManager().requestPairing(_handle); - - if (error) { - printf("Error during SM::requestPairing %d\r\n", error); - return; - } - - /* upon pairing success the application will disconnect */ - } - - /* failed to connect - restart scan */ - ble_error_t error = _ble.gap().startScan(); - - if (error) { - print_error(error, "Error in Gap::startScan %d\r\n"); - return; - } - }; -}; - - -#if MBED_CONF_APP_FILESYSTEM_SUPPORT -bool create_filesystem() -{ - static LittleFileSystem fs("fs"); - - /* replace this with any physical block device your board supports (like an SD card) */ - static HeapBlockDevice bd(4096, 256); - - int err = bd.init(); - - if (err) { - return false; - } - - err = bd.erase(0, bd.size()); - - if (err) { - return false; - } - - err = fs.mount(&bd); - - if (err) { - /* Reformat if we can't mount the filesystem */ - printf("No filesystem found, formatting...\r\n"); - - err = fs.reformat(&bd); - - if (err) { - return false; - } - } - - return true; -} -#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT - -int main() -{ - BLE& ble = BLE::Instance(); - events::EventQueue queue; - -#if MBED_CONF_APP_FILESYSTEM_SUPPORT - /* if filesystem creation fails or there is no filesystem the security manager - * will fallback to storing the security database in memory */ - if (!create_filesystem()) { - printf("Filesystem creation failed, will use memory storage\r\n"); - } -#endif - - while(1) { - { - printf("\r\n PERIPHERAL \r\n\r\n"); - SMDevicePeripheral peripheral(ble, queue, peer_address); - peripheral.run(); - } - - { - printf("\r\n CENTRAL \r\n\r\n"); - SMDeviceCentral central(ble, queue, peer_address); - central.run(); - } - } - - return 0; -} diff --git a/BLE_SM/source/pretty_printer.h b/BLE_SM/source/pretty_printer.h deleted file mode 100644 index 7b1a7d6e..00000000 --- a/BLE_SM/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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"; - } -} diff --git a/BLE_SecurityAndPrivacy/CMakeLists.txt b/BLE_SecurityAndPrivacy/CMakeLists.txt new file mode 100644 index 00000000..8e04cd85 --- /dev/null +++ b/BLE_SecurityAndPrivacy/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_SecurityAndPrivacy) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_subdirectory(mbed-os-ble-utils) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble + mbed-ble-utils +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_SecurityAndPrivacy/README.md b/BLE_SecurityAndPrivacy/README.md new file mode 100644 index 00000000..8c10ce4e --- /dev/null +++ b/BLE_SecurityAndPrivacy/README.md @@ -0,0 +1,27 @@ +# Example using Security and Privacy + +Demonstration of Security Manager features. It shows how pairing and encryption works and how to use private addresses +when advertising and connecting and how filtering ties in with these operations. + +The application will start by repeatedly trying to connect to the same application running on another board. +It will do this by advertising and scanning for random intervals waiting until the difference in intervals +between the boards will make them meet when one is advertising and the other scanning. + +Two devices will be operating using resolvable private addresses. The application will connect to the peer and pair. + +Subsequent connections will turn on filtering based on peers identity addresses. + +# Running the application + +## Requirements + +Application requires two devices. Each one should be loaded with the same example. You may try to emulate the second +device with your phone. The demo advertise with the name "SecurityDemo". You must advertise with the same name. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +Note: example currently doesn't use ST provided stack and instead uses a Cordio port for the ST. diff --git a/BLE_SecurityAndPrivacy/mbed-os-ble-utils.lib b/BLE_SecurityAndPrivacy/mbed-os-ble-utils.lib new file mode 100644 index 00000000..929a3f10 --- /dev/null +++ b/BLE_SecurityAndPrivacy/mbed-os-ble-utils.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os-ble-utils/ diff --git a/BLE_SecurityAndPrivacy/mbed-os.lib b/BLE_SecurityAndPrivacy/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_SecurityAndPrivacy/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_SecurityAndPrivacy/mbed_app.json b/BLE_SecurityAndPrivacy/mbed_app.json new file mode 100644 index 00000000..89b96002 --- /dev/null +++ b/BLE_SecurityAndPrivacy/mbed_app.json @@ -0,0 +1,32 @@ +{ + "config": { + "filesystem-support": false + }, + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_Privacy/source/main.cpp b/BLE_SecurityAndPrivacy/source/main.cpp similarity index 54% rename from BLE_Privacy/source/main.cpp rename to BLE_SecurityAndPrivacy/source/main.cpp index e4769d94..b80a48e3 100644 --- a/BLE_Privacy/source/main.cpp +++ b/BLE_SecurityAndPrivacy/source/main.cpp @@ -15,16 +15,19 @@ */ #include -#include #include "ble/BLE.h" -#include "SecurityManager.h" -#include #include "pretty_printer.h" -#include "ble/gap/AdvertisingDataParser.h" +#include "mbed-trace/mbed_trace.h" -/** This example demonstrates privacy features in Gap. It shows how to use - * private addresses when advertising and connecting and how filtering ties - * in with these operations. +#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. It also demonstrates privacy + * features in Gap. It shows how to use private addresses when advertising and + * connecting and how filtering ties in with these operations. * * The application will start by repeatedly trying to connect to the same * application running on another board. It will do this by advertising and @@ -38,11 +41,12 @@ * turn on filtering based on stored IRKs. */ -static const char DEVICE_NAME[] = "Privacy"; +static const char DEVICE_NAME[] = "SecurityDemo"; + +using std::literals::chrono_literals::operator""ms; -/* 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; +/* Delay between steps */ +static const std::chrono::milliseconds delay = 3000ms; /** Base class for both peripheral and central. The same class that provides * the logic for the application also implements the SecurityManagerEventHandler @@ -50,33 +54,25 @@ const static disconnect_call_t disconnect_call = &Gap::disconnect; * back to the applications. You can provide overrides for a selection of events * your application is interested in. */ -class PrivacyDevice : private mbed::NonCopyable, - public SecurityManager::EventHandler, - public ble::Gap::EventHandler +class SecurityDemo : private mbed::NonCopyable, + public SecurityManager::EventHandler, + public ble::Gap::EventHandler { public: - PrivacyDevice(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _handle(0), - _bonded(false), - _led1(LED1, 0) { }; - - virtual ~PrivacyDevice() { - _ble.onEventsToProcess(NULL); + SecurityDemo(BLE &ble, events::EventQueue &event_queue) : + _ble(ble), _event_queue(event_queue) { }; + + virtual ~SecurityDemo() + { + _ble.onEventsToProcess(nullptr); }; /** Start BLE interface initialisation */ void run() { - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &PrivacyDevice::blink); - /* this will inform us off all events so we can schedule their handling * using our event queue */ - _ble.onEventsToProcess( - makeFunctionPointer(this, &PrivacyDevice::schedule_ble_events) - ); + _ble.onEventsToProcess(makeFunctionPointer(this, &SecurityDemo::schedule_ble_events)); /* handle gap events */ _ble.gap().setEventHandler(this); @@ -85,10 +81,10 @@ class PrivacyDevice : private mbed::NonCopyable, /* ble instance already initialised, skip init and start activity */ start(); } else { - ble_error_t error = _ble.init(this, &PrivacyDevice::on_init_complete); + ble_error_t error = _ble.init(this, &SecurityDemo::on_init_complete); if (error) { - printf("Error returned by BLE::init.\r\n"); + print_error(error, "Error returned by BLE::init.\r\n"); return; } } @@ -97,12 +93,9 @@ class PrivacyDevice : private mbed::NonCopyable, _event_queue.dispatch_forever(); }; - /** Override to start chosen activity when initialisation completes */ + /** Override to start chosen activity when the system starts */ virtual void start() = 0; - /** Override to start chosen activity after initial bonding */ - virtual void start_after_bonding() = 0; - /* callbacks */ /** This is called when BLE interface is initialised and starts the demonstration */ @@ -112,7 +105,6 @@ class PrivacyDevice : private mbed::NonCopyable, if (event->error) { printf("Error during the initialisation\r\n"); - _event_queue.break_dispatch(); return; } @@ -120,23 +112,41 @@ class PrivacyDevice : private mbed::NonCopyable, * to seed RNG as the address is unique */ print_local_address(); - /* Privacy requires the security manager */ + + /* 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"; error = _ble.securityManager().init( /* enableBonding */ true, /* requireMITM */ false, /* iocaps */ SecurityManager::IO_CAPS_NONE, - /* passkey */ NULL, + /* passkey */ nullptr, /* signing */ false, - /* dbFilepath */ NULL + /* dbFilepath */ db_path ); if (error) { - printf("Error during security manager initialisation\r\n"); - _event_queue.break_dispatch(); + print_error(error, "Error during initialising security manager\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); + +#if MBED_CONF_APP_FILESYSTEM_SUPPORT + error = _ble.securityManager().preserveBondingStateOnReset(true); + + if (error) { + print_error(error, "Error during preserveBondingStateOnReset %d\r\n"); + } +#endif // MBED_CONF_APP_FILESYSTEM_SUPPORT + + /* this demo switches between being master and slave */ + _ble.securityManager().setHintFutureRoleReversal(true); + /* 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); @@ -144,56 +154,39 @@ class PrivacyDevice : private mbed::NonCopyable, /* gap events also handled by this class */ _ble.gap().setEventHandler(this); - /* privacy */ - error = _ble.gap().enablePrivacy(true); - if (error) { - printf("Error enabling privacy.\r\n"); - _event_queue.break_dispatch(); + print_error(error, "Error enabling privacy.\r\n"); return; } - start(); + /* continuation is in onPrivacyEnabled() */ }; /** 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)); + _event_queue.call([&ble_instance = context->ble] { ble_instance.processEvents(); }); }; - /** Blink LED to show we're running */ - void blink(void) - { - _led1 = !_led1; - }; +private: + /* SecurityManager Event handler */ - void print_local_address() + /** 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 pairingRequest(ble::connection_handle_t connectionHandle) override { - /* show what address we are using now */ - Gap::AddressType_t addr_type; - Gap::Address_t addr; - _ble.gap().getAddress(&addr_type, addr); - printf("Device address: "); - print_address(addr); - - if (!_seeded) { - _seeded = true; - /* use the address as a seed */ - uint8_t* random_data = addr; - srand(*((unsigned int*)random_data)); - } + printf("Pairing requested - authorising\r\n"); + _ble.securityManager().acceptPairingRequest(connectionHandle); } -private: - /* Event handler */ - /** Inform the application of pairing */ - virtual void pairingResult( + void pairingResult( ble::connection_handle_t connectionHandle, SecurityManager::SecurityCompletionStatus_t result - ) { + ) override + { if (result == SecurityManager::SEC_STATUS_SUCCESS) { printf("Pairing successful\r\n"); _bonded = true; @@ -201,119 +194,155 @@ class PrivacyDevice : private mbed::NonCopyable, printf("Pairing failed\r\n"); } - /* disconnect in 2s */ _event_queue.call_in( - 2000, - &_ble.gap(), - disconnect_call, - connectionHandle, - ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION) + delay, + [this, connectionHandle] { + _ble.gap().disconnect(connectionHandle, ble::local_disconnection_reason_t::USER_TERMINATION); + } ); } + /** Inform the application of change in encryption status. This will be + * communicated through the serial port */ + void linkEncryptionResult(ble::connection_handle_t connectionHandle, ble::link_encryption_t result) override + { + 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"); + } + } + + void onPrivacyEnabled() override + { + /* all initialisation complete, start our main activity */ + start(); + } + + /* Gap Event handler */ + /** This is called by Gap to notify the application we connected */ - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) + void onConnectionComplete(const ble::ConnectionCompleteEvent &event) override { printf("Connected to peer: "); print_address(event.getPeerAddress().data()); - printf("Peer random resolvable address: "); - print_address(event.getPeerResolvablePrivateAddress().data()); + if (event.getPeerResolvablePrivateAddress() != ble::address_t()) { + printf("Peer random resolvable address: "); + print_address(event.getPeerResolvablePrivateAddress().data()); + } _handle = event.getConnectionHandle(); if (_bonded) { /* disconnect in 2s */ _event_queue.call_in( - 2000, - &_ble.gap(), - disconnect_call, + delay, + [this] { + _ble.gap().disconnect(_handle, ble::local_disconnection_reason_t::USER_TERMINATION); + } + ); + } else { + /* start bonding */ + ble_error_t error = _ble.securityManager().setLinkSecurity( _handle, - ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION) + SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM ); + if (error) { + print_error(error, "Failed to set link security\r\n"); + _ble.gap().disconnect(_handle, ble::local_disconnection_reason_t::USER_TERMINATION); + } } }; /** This is called by Gap to notify the application we disconnected */ - virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) + void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) override { if (_bonded) { /* we have connected to and bonded with the other device, from now * on we will use the second start function and stay in the same role * as peripheral or central */ - printf("Disconnected.\r\n"); - _event_queue.call_in(2000, this, &PrivacyDevice::start_after_bonding); + printf("Disconnected.\r\n\r\n"); + _event_queue.call_in(delay, [this] { start(); }); } else { printf("Failed to bond.\r\n"); _event_queue.break_dispatch(); } }; - virtual void onScanTimeout(const ble::ScanTimeoutEvent &) + void onScanTimeout(const ble::ScanTimeoutEvent &) override { /* if we failed to find the other device, abort so that we change roles */ printf("Haven't seen other device, switch modes.\r\n"); _event_queue.break_dispatch(); } -public: - static bool _seeded; + void onAdvertisingEnd(const ble::AdvertisingEndEvent &event) override + { + if (!event.isConnected()) { + printf("No device connected to us, switch modes.\r\n"); + _event_queue.break_dispatch(); + } + } + +private: + void print_local_address() + { + /* show what address we are using now */ + ble::own_address_type_t addr_type; + ble::address_t addr; + _ble.gap().getAddress(addr_type, addr); + printf("Device address: "); + print_address(addr); + static bool _seeded = false; + if (!_seeded) { + _seeded = true; + /* use the address as a seed */ + uint8_t* random_data = addr.data(); + srand(*((unsigned int*)random_data)); + } + } protected: BLE &_ble; events::EventQueue &_event_queue; - ble::connection_handle_t _handle; - bool _bonded; - -private: - DigitalOut _led1; + ble::connection_handle_t _handle = 0; + bool _bonded = false; }; /** A peripheral device will advertise and accept the connections */ -class PrivacyPeripheral : public PrivacyDevice { +class SecurityPeripheral : public SecurityDemo { public: - PrivacyPeripheral(BLE &ble, events::EventQueue &event_queue) - : PrivacyDevice(ble, event_queue) { } + SecurityPeripheral(BLE &ble, events::EventQueue &event_queue) + : SecurityDemo(ble, event_queue) { } /** Set up and start advertising accepting anyone */ - virtual void start() + void start() override { - if (!set_advertising_data()) { - return; - } - - Gap::PeripheralPrivacyConfiguration_t privacy_configuration = { + ble::peripheral_privacy_configuration_t privacy_configuration = { /* use_non_resolvable_random_address */ false, - Gap::PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE + ble::peripheral_privacy_configuration_t::PERFORM_PAIRING_PROCEDURE }; - _ble.gap().setPeripheralPrivacyConfiguration(&privacy_configuration); - - start_advertising(); - }; - - /** advertise and filter based on known devices */ - virtual void start_after_bonding() - { - Gap::PeripheralPrivacyConfiguration_t privacy_configuration = { - /* use_non_resolvable_random_address */ false, - Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS - }; + if (_bonded) { + /** advertise and filter based on known devices */ + printf("We are bonded, we will only accept known devices\r\n"); + privacy_configuration.resolution_strategy = + ble::peripheral_privacy_configuration_t::REJECT_NON_RESOLVED_ADDRESS; + } _ble.gap().setPeripheralPrivacyConfiguration(&privacy_configuration); start_advertising(); - } - - /* helper functions */ + }; private: - bool set_advertising_data() + void start_advertising() { uint8_t adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; /* use the helper to build the payload */ - ble::AdvertisingDataBuilder adv_data_builder( - adv_buffer - ); + ble::AdvertisingDataBuilder adv_data_builder(adv_buffer); adv_data_builder.setFlags(); adv_data_builder.setName(DEVICE_NAME); @@ -326,27 +355,18 @@ class PrivacyPeripheral : public PrivacyDevice { if (error) { print_error(error, "Gap::setAdvertisingPayload() failed"); - _event_queue.break_dispatch(); - return false; + return; } - return true; - } - - bool start_advertising() - { ble::AdvertisingParameters adv_parameters( ble::advertising_type_t::CONNECTABLE_UNDIRECTED ); - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); + error = _ble.gap().setAdvertisingParameters(ble::LEGACY_ADVERTISING_HANDLE, adv_parameters); if (error) { print_error(error, "Gap::setAdvertisingParameters() failed"); - return false; + return; } if (_bonded) { @@ -357,54 +377,40 @@ class PrivacyPeripheral : public PrivacyDevice { /* since we have two boards which might start running this example at the same time * we randomise the interval of advertising to have them meet when one is advertising * and the other one is scanning (we use their random address as source of randomness) */ - ble::millisecond_t random_duration_ms((1 + rand() % 5) * 1000); + ble::millisecond_t random_duration_ms((5 + rand() % 6) * 1000); ble::adv_duration_t random_duration(random_duration_ms); - error = _ble.gap().startAdvertising( - ble::LEGACY_ADVERTISING_HANDLE, - random_duration - ); + + error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE, random_duration); } if (error) { print_error(error, "Gap::startAdvertising() failed"); - _event_queue.break_dispatch(); - return false; + return; } printf("Advertising...\r\n"); - - return true; } }; /** A central device will scan and connect to a peer. */ -class PrivacyCentral : public PrivacyDevice { +class SecurityCentral : public SecurityDemo { public: - PrivacyCentral(BLE &ble, events::EventQueue &event_queue) - : PrivacyDevice(ble, event_queue), - _is_connecting(false) { } + SecurityCentral(BLE &ble, events::EventQueue &event_queue) + : SecurityDemo(ble, event_queue) { } /** start scanning and attach a callback that will handle advertisements * and scan requests responses */ - virtual void start() + void start() override { - Gap::CentralPrivacyConfiguration_t privacy_configuration = { + ble::central_privacy_configuration_t privacy_configuration = { /* use_non_resolvable_random_address */ false, - Gap::CentralPrivacyConfiguration_t::DO_NOT_RESOLVE - }; - - _ble.gap().setCentralPrivacyConfiguration(&privacy_configuration); - - start_scanning(); - } - - virtual void start_after_bonding() - { - Gap::CentralPrivacyConfiguration_t privacy_configuration = { - /* use_non_resolvable_random_address */ false, - Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FILTER + ble::central_privacy_configuration_t::DO_NOT_RESOLVE }; + if (_bonded) { + printf("We are bonded - we will only see known devices\r\n"); + privacy_configuration.resolution_strategy = ble::central_privacy_configuration_t::RESOLVE_AND_FILTER; + } _ble.gap().setCentralPrivacyConfiguration(&privacy_configuration); @@ -413,7 +419,8 @@ class PrivacyCentral : public PrivacyDevice { /* helper functions */ private: - bool start_scanning() { + bool start_scanning() + { ble_error_t error; ble::ScanParameters scan_params; _ble.gap().setScanParameters(scan_params); @@ -427,14 +434,11 @@ class PrivacyCentral : public PrivacyDevice { } else { /* otherwise only scan for a limited time before changing roles again * if we fail to find the other device */ - error = _ble.gap().startScan( - ble::scan_duration_t(ble::millisecond_t(4000)) - ); + error = _ble.gap().startScan(ble::scan_duration_t(ble::millisecond_t(5000))); } if (error) { - printf("Error during Gap::startScan %d\r\n", error); - _event_queue.break_dispatch(); + print_error(error, "Error during Gap::startScan\r\n"); return false; } @@ -447,7 +451,7 @@ class PrivacyCentral : public PrivacyDevice { /* Event handler */ /** Look at scan payload to find a peer device and connect to it */ - virtual void onAdvertisingReport(const ble::AdvertisingReportEvent &event) + void onAdvertisingReport(const ble::AdvertisingReportEvent &event) override { /* don't bother with analysing scan result if we're already connecting */ if (_is_connecting) { @@ -465,7 +469,8 @@ class PrivacyCentral : public PrivacyDevice { field.value.size() == strlen(DEVICE_NAME) && (memcmp(field.value.data(), DEVICE_NAME, field.value.size()) == 0)) { - printf("We found a connectable device\r\n"); + printf("We found a connectable device: \r\n"); + print_address(event.getPeerAddress().data()); ble_error_t error = _ble.gap().stopScan(); @@ -474,14 +479,14 @@ class PrivacyCentral : public PrivacyDevice { return; } - const ble::ConnectionParameters connection_params; - error = _ble.gap().connect( event.getPeerAddressType(), event.getPeerAddress(), - connection_params + ble::ConnectionParameters() ); + printf("Connecting...\r\n"); + if (error) { print_error(error, "Error caused by Gap::connect"); return; @@ -493,33 +498,75 @@ class PrivacyCentral : public PrivacyDevice { _is_connecting = true; return; - } } } private: - bool _is_connecting; + bool _is_connecting = false; }; -/* only seed the random number generation once per application run */ -bool PrivacyDevice::_seeded = false; +#if MBED_CONF_APP_FILESYSTEM_SUPPORT +bool create_filesystem() +{ + static LittleFileSystem fs("fs"); + + /* replace this with any physical block device your board supports (like an SD card) */ + static HeapBlockDevice bd(4096, 256); + + int err = bd.init(); + + if (err) { + return false; + } + + err = bd.erase(0, bd.size()); + + if (err) { + return false; + } + + err = fs.mount(&bd); + + if (err) { + /* Reformat if we can't mount the filesystem */ + printf("No filesystem found, formatting...\r\n"); + + err = fs.reformat(&bd); + + if (err) { + return false; + } + } + + return true; +} +#endif //MBED_CONF_APP_FILESYSTEM_SUPPORT int main() { + mbed_trace_init(); + 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) { + while(true) { { - events::EventQueue queue; printf("\r\n * Device is a peripheral *\r\n\r\n"); - PrivacyPeripheral peripheral(ble, queue); + SecurityPeripheral peripheral(ble, queue); peripheral.run(); } { - events::EventQueue queue; printf("\r\n * Device is a central *\r\n\r\n"); - PrivacyCentral central(ble, queue); + SecurityCentral central(ble, queue); central.run(); } } diff --git a/BLE_SupportedFeatures/CMakeLists.txt b/BLE_SupportedFeatures/CMakeLists.txt new file mode 100644 index 00000000..11b007e6 --- /dev/null +++ b/BLE_SupportedFeatures/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) 2020 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET BLE_SupportedFeatures) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + ./source +) + +target_sources(${APP_TARGET} + PRIVATE + source/main.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-events + mbed-ble +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() diff --git a/BLE_SupportedFeatures/mbed-os.lib b/BLE_SupportedFeatures/mbed-os.lib new file mode 100644 index 00000000..144619b6 --- /dev/null +++ b/BLE_SupportedFeatures/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed diff --git a/BLE_SupportedFeatures/mbed_app.json b/BLE_SupportedFeatures/mbed_app.json new file mode 100644 index 00000000..8924be3f --- /dev/null +++ b/BLE_SupportedFeatures/mbed_app.json @@ -0,0 +1,23 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200 + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/BLE_SupportedFeatures/readme.md b/BLE_SupportedFeatures/readme.md new file mode 100644 index 00000000..bf568f8b --- /dev/null +++ b/BLE_SupportedFeatures/readme.md @@ -0,0 +1,19 @@ +# BLE Supported Features + +This application will list BLE features supported by your device. Knowing which features +are supported, might have an influence on how exactly you implement BLE feature of your applications. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +After flashing your device open up a serial monitor and start your device to find out which optional BLE +features it supports. diff --git a/BLE_SupportedFeatures/source/main.cpp b/BLE_SupportedFeatures/source/main.cpp new file mode 100644 index 00000000..c3fe03e1 --- /dev/null +++ b/BLE_SupportedFeatures/source/main.cpp @@ -0,0 +1,104 @@ +/* mbed Microcontroller Library + * Copyright (c) 2021 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 +#include "ble/BLE.h" +#include "mbed-trace/mbed_trace.h" + +static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +class SupportedFeatures : ble::Gap::EventHandler { +public: + SupportedFeatures(BLE &ble, events::EventQueue &event_queue) : + _ble(ble), + _event_queue(event_queue) + { + } + + void start() + { + _ble.init(this, &SupportedFeatures::on_init_complete); + + _event_queue.dispatch_forever(); + } + +private: + /** Callback triggered when the ble initialization process has finished */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *params) + { + if (params->error != BLE_ERROR_NONE) { + printf("Ble initialization failed."); + return; + } + + /* display basic info and optional BLE features supported by our device */ + + printf("\r\nList of optional BLE features that are supported/unsupported by this board:\r\n"); + feature_support("LE_ENCRYPTION", ble::controller_supported_features_t::LE_ENCRYPTION); + feature_support("CONNECTION_PARAMETERS_REQUEST_PROCEDURE", ble::controller_supported_features_t::CONNECTION_PARAMETERS_REQUEST_PROCEDURE); + feature_support("EXTENDED_REJECT_INDICATION", ble::controller_supported_features_t::EXTENDED_REJECT_INDICATION); + feature_support("SLAVE_INITIATED_FEATURES_EXCHANGE", ble::controller_supported_features_t::SLAVE_INITIATED_FEATURES_EXCHANGE); + feature_support("SLAVE_INITIATED_FEATURES_EXCHANGE", ble::controller_supported_features_t::SLAVE_INITIATED_FEATURES_EXCHANGE); + feature_support("LE_PING", ble::controller_supported_features_t::LE_PING); + feature_support("LE_DATA_PACKET_LENGTH_EXTENSION", ble::controller_supported_features_t::LE_DATA_PACKET_LENGTH_EXTENSION); + feature_support("LL_PRIVACY", ble::controller_supported_features_t::LL_PRIVACY); + feature_support("EXTENDED_SCANNER_FILTER_POLICIES", ble::controller_supported_features_t::EXTENDED_SCANNER_FILTER_POLICIES); + feature_support("LE_2M_PHY", ble::controller_supported_features_t::LE_2M_PHY); + feature_support("STABLE_MODULATION_INDEX_TRANSMITTER", ble::controller_supported_features_t::STABLE_MODULATION_INDEX_TRANSMITTER); + feature_support("STABLE_MODULATION_INDEX_RECEIVER", ble::controller_supported_features_t::STABLE_MODULATION_INDEX_RECEIVER); + feature_support("LE_CODED_PHY", ble::controller_supported_features_t::LE_CODED_PHY); + feature_support("LE_EXTENDED_ADVERTISING", ble::controller_supported_features_t::LE_EXTENDED_ADVERTISING); + feature_support("LE_PERIODIC_ADVERTISING", ble::controller_supported_features_t::LE_PERIODIC_ADVERTISING); + feature_support("CHANNEL_SELECTION_ALGORITHM_2", ble::controller_supported_features_t::CHANNEL_SELECTION_ALGORITHM_2); + feature_support("LE_POWER_CLASS", ble::controller_supported_features_t::LE_POWER_CLASS); + } + +private: + /* pretty prints feature support */ + void feature_support(const char* feature_name, ble::controller_supported_features_t feature) + { + const bool supported = _ble.gap().isFeatureSupported(feature); + + if (supported) { + printf("+ %s feature supported\r\n", feature_name); + } else { + printf("- %s feature not supported\r\n", feature_name); + } + } + +private: + BLE &_ble; + events::EventQueue &_event_queue; +}; + +/* Schedule processing of events from the BLE middleware in the event queue. */ +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ + event_queue.call(mbed::Callback(&context->ble, &BLE::processEvents)); +} + +int main() +{ + mbed_trace_init(); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(schedule_ble_events); + + SupportedFeatures demo(ble, event_queue); + demo.start(); + + return 0; +} diff --git a/BLE_Thermometer/.mbed b/BLE_Thermometer/.mbed deleted file mode 100644 index e87b56dc..00000000 --- a/BLE_Thermometer/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. diff --git a/BLE_Thermometer/img/connection.png b/BLE_Thermometer/img/connection.png deleted file mode 100644 index 0f51e450..00000000 Binary files a/BLE_Thermometer/img/connection.png and /dev/null differ diff --git a/BLE_Thermometer/img/discovery.png b/BLE_Thermometer/img/discovery.png deleted file mode 100644 index 03abd2f2..00000000 Binary files a/BLE_Thermometer/img/discovery.png and /dev/null differ diff --git a/BLE_Thermometer/img/notifications.png b/BLE_Thermometer/img/notifications.png deleted file mode 100644 index 6a8455bd..00000000 Binary files a/BLE_Thermometer/img/notifications.png and /dev/null differ diff --git a/BLE_Thermometer/img/register_to_notifications.png b/BLE_Thermometer/img/register_to_notifications.png deleted file mode 100644 index 3191e7c2..00000000 Binary files a/BLE_Thermometer/img/register_to_notifications.png and /dev/null differ diff --git a/BLE_Thermometer/img/scan_results.png b/BLE_Thermometer/img/scan_results.png deleted file mode 100644 index 0f495f82..00000000 Binary files a/BLE_Thermometer/img/scan_results.png and /dev/null differ diff --git a/BLE_Thermometer/img/start_scan.png b/BLE_Thermometer/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/BLE_Thermometer/img/start_scan.png and /dev/null differ diff --git a/BLE_Thermometer/mbed-os.lib b/BLE_Thermometer/mbed-os.lib deleted file mode 100644 index 38ad3522..00000000 --- a/BLE_Thermometer/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#c966348d3f9ca80843be7cdc9b748f06ea73ced0 diff --git a/BLE_Thermometer/mbed_app.json b/BLE_Thermometer/mbed_app.json deleted file mode 100644 index f6d83692..00000000 --- a/BLE_Thermometer/mbed_app.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NRF52840_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] - }, - "NRF52_DK": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] - } - } -} diff --git a/BLE_Thermometer/module.json b/BLE_Thermometer/module.json deleted file mode 100644 index 7a8cb037..00000000 --- a/BLE_Thermometer/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-thermometer", - "version": "0.0.1", - "description": "This example demonstrates how to use the Health Thermometer Service. The Health Thermometer service reports two pieces of information, Temperature and Sensor Location.", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "bin": "./source" -} diff --git a/BLE_Thermometer/readme.md b/BLE_Thermometer/readme.md deleted file mode 100644 index 0373faf4..00000000 --- a/BLE_Thermometer/readme.md +++ /dev/null @@ -1,80 +0,0 @@ -# Thermometer - -This example uses the [Health Thermometer Profile](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml) to send thermometer information: - -1. Sensor location: thermometer placement on the body. The default value in this application is the ear (``LOCATION_EAR``). The [characteristic description](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml) shows the other possible values. - -1. Temperature: the initial temperature is 39.6, and it's incremented by 0.1 every half second. It resets to 39.6 when it reaches 43.0. - -For more information see: - -* [Health Thermometer Service](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml): GATT profile details. - -* [Temperature Measurement](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml): GATT characteristic details for temperature measurement. - -* [Temperature Type](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml): GATT characteristic details for temperature type (sensor location). - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. - -1. Open the BLE scanner on your phone. - -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named *Therm*. - - ![](img/scan_results.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - - -1. Discover the services and the characteristics on the device. The *Health Thermometer* service has the UUID `0x1809` and includes the *Temperature Measurement* characteristic which has the UUID `0x2A1C`. - - ![](img/discovery.png) - - **figure 4** Representation of the Thermometer service using Master Control Panel 4.0.5 - - -1. Register for the notifications sent by the *Temperature Measurement* characteristic. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. You should see the temperature value change every half second. It begins at 39.6, goes up to 43.0 (in steps of 0.1), resets to 39.6 and so on. - - ![](img/notifications.png) - - **figure 6** Notifications view using Master Control Panel 4.0.5 - - diff --git a/BLE_Thermometer/shields/TARGET_CORDIO_BLUENRG.lib b/BLE_Thermometer/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index 22b07f40..00000000 --- a/BLE_Thermometer/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#811f3fea7aa8083c0bbf378e1b51a8b131d7efcc diff --git a/BLE_Thermometer/source/main.cpp b/BLE_Thermometer/source/main.cpp deleted file mode 100644 index eb5ccad1..00000000 --- a/BLE_Thermometer/source/main.cpp +++ /dev/null @@ -1,156 +0,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 -#include "mbed.h" -#include "ble/BLE.h" -#include "ble/services/HealthThermometerService.h" -#include "pretty_printer.h" - -DigitalOut led1(LED1, 1); - -const static char DEVICE_NAME[] = "Therm"; - -static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -class BatteryDemo : ble::Gap::EventHandler { -public: - BatteryDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _thermometer_uuid(GattService::UUID_HEALTH_THERMOMETER_SERVICE), - _current_temperature(39.6), - _thermometer_service(NULL), - _adv_data_builder(_adv_buffer) { } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &BatteryDemo::on_init_complete); - - _event_queue.call_every(500, this, &BatteryDemo::blink); - _event_queue.call_every(1000, this, &BatteryDemo::update_sensor_value); - - _event_queue.dispatch_forever(); - } - -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - print_error(params->error, "Ble initialization failed."); - return; - } - - print_mac_address(); - - /* Setup primary service. */ - _thermometer_service = new HealthThermometerService(_ble, _current_temperature, HealthThermometerService::LOCATION_EAR); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - _adv_data_builder.setFlags(); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_thermometer_uuid, 1)); - _adv_data_builder.setAppearance(ble::adv_data_appearance_t::THERMOMETER_EAR); - _adv_data_builder.setName(DEVICE_NAME); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingPayload() failed"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "_ble.gap().startAdvertising() failed"); - return; - } - } - - void update_sensor_value() { - if (_ble.gap().getState().connected) { - _current_temperature = (_current_temperature + 0.1 > 43.0) ? 39.6 : _current_temperature + 0.1; - _thermometer_service->updateTemperature(_current_temperature); - } - } - - void blink(void) { - led1 = !led1; - } - -private: - /* Event handler */ - - void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - - UUID _thermometer_uuid; - - uint8_t _current_temperature; - HealthThermometerService *_thermometer_service; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - BatteryDemo demo(ble, event_queue); - demo.start(); - - return 0; -} diff --git a/BLE_Thermometer/source/pretty_printer.h b/BLE_Thermometer/source/pretty_printer.h deleted file mode 100644 index b540135e..00000000 --- a/BLE_Thermometer/source/pretty_printer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#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 */ -inline void print_address(const Gap::Address_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"; - } -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 701af041..e3957bfc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,4 +2,8 @@ Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor. -To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/latest/reference/contributing.html). +To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/mbed-os/latest/contributing/index.html). + +## Branches + +`Master` branch is for releases only. Please target the `development` branch for all your PRs. diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..fbd598cd --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,2 @@ +// This is internal file to run tests in internal Jenkins +ble_ci.run_job() diff --git a/README.md b/README.md index 24aae42a..a49975da 100644 --- a/README.md +++ b/README.md @@ -1,153 +1,246 @@ +![](./resources/official_armmbed_example_badge.png) # BLE Examples -This repo contains a collection of BLE example applications based on -mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli). Each example subdirectory contains a separate mbed-cli module meant for building an executable. -Please browse to subdirectories for specific documentation. +This repo contains a collection of BLE example applications based on Mbed OS. Each example subdirectory contains a separate Mbed OS project, along with a description of the example and additional instructions for running it. -Getting Started -=============== +You can build each project with all supported [Mbed OS build tools](https://os.mbed.com/docs/mbed-os/latest/tools/index.html). However, this file specifically refers to the command-line interface tools, [Arm Mbed CLI 1](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli) and [Mbed CLI 2](https://github.com/ARMmbed/mbed-tools#installation). +The [BLE documentation](https://os.mbed.com/docs/latest/reference/bluetooth.html) describes the BLE APIs on Mbed OS. -Pre-Requisites --------------- +## Mbed OS build tools -To build these examples, you need to have a computer with software installed as described [here](https://os.mbed.com/docs/latest/tools/index.html). +### Mbed CLI 2 +Starting with version 6.5, Mbed OS uses Mbed CLI 2. It uses Ninja as a build system, and CMake to generate the build environment and manage the build process in a compiler-independent manner. If you are working with Mbed OS version prior to 6.5 then check the section [Mbed CLI 1](#mbed-cli-1). -In order to use BLE in mbed OS you need one of the following hardware combinations: +[Install Mbed CLI 2](https://os.mbed.com/docs/mbed-os/latest/build-tools/install-or-upgrade.html). -* A Nordic nRF52-based board such as [nrf52DK](https://os.mbed.com/platforms/Nordic-nRF52-DK/) -* A supported target, such as the [NUCLEO-F401RE](http://www.st.com/en/evaluation-tools/nucleo-f401re.html), with a BLE shield or an external BLE peripheral, such as an [ST shield](http://www.st.com/web/catalog/tools/FM116/SC1075/PF260517). -* A [DISCO_L475VG_IOT01A (ref B-L475E-IOT01A)](http://www.st.com/en/evaluation-tools/b-l475e-iot01a.html) board. +### Mbed CLI 1 +[Install Mbed CLI 1](https://os.mbed.com/docs/mbed-os/latest/quick-start/offline-with-mbed-cli.html). -This target is currently not supported as the examples use Cordio link layer which doesn't have an implementation for it yet: -* A Nordic nRF51-based board such as [nrf51dk](https://www.nordicsemi.com/eng/Products/nRF51-DK) or [mkit](https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822-mKIT). -You may still use the deprecated examples for this target. The deprecated examples are located in the "deprecated" folder. +## Pre-Requisites + + +In order to use BLE in Mbed OS you need one of the following hardware combinations: + +* A supported target, such as the [NUCLEO-F401RE](https://os.mbed.com/platforms/ST-Nucleo-F401RE/), with a BLE shield or an external BLE peripheral, such as an [X-NUCLEO-BNRG2A1](https://os.mbed.com/components/X-NUCLEO-BNRG2A1/) or an [X-NUCLEO-IDB05A1](https://os.mbed.com/components/X-NUCLEO-IDB05A1/) ST BLE expansion board. +* A [DISCO_L475VG_IOT01A (ref B-L475E-IOT01A)](https://os.mbed.com/platforms/ST-Discovery-L475E-IOT01A/) board. +* A [DISCO_L562QE (ref STM32L562E-DK)](https://os.mbed.com/platforms/ST-Discovery-L562QE/) board. +* A [NUCLEO_WB55RG](https://os.mbed.com/platforms/ST-Nucleo-WB55RG/) board. +* A Nordic nRF52-based board such as [nRF52DK](https://os.mbed.com/platforms/Nordic-nRF52-DK/). +* An Embedded Planet [Agora](https://os.mbed.com/platforms/agora-dev/) board. The [BLE documentation](https://os.mbed.com/docs/latest/reference/bluetooth.html) describes the BLE APIs on mbed OS. -Targets for BLE ---------------- +### Targets for BLE The following targets have been tested and work with these examples: +* Targets with an ST BLE expansion board plugged in: + * NUCLEO_F401RE + * NUCLEO_L476RG + * NUCLEO_L446RE + * K64F + +* ST boards with embedded SPBTLE-RF module (BlueNRG-MS): + * DISCO_L475VG_IOT01A (ref B-L475E-IOT01A) + * DISCO_L562QE (ref STM32L562E-DK) + +* Board with wireless STM32WB microcontrollers: + * NUCLEO_WB55RG + * Nordic: - * NRF52_DK - * NRF52840_DK - -* Boards with an ST shield plugged in: - * K64F - * NUCLEO_F401RE - -* STMicroelectronics: - * DISCO_L475VG_IOT01A (ref B-L475E-IOT01A) - - **Important:** if an ST shield is used with the K64F board, an hardware is patch required. Check out https://developer.mbed.org/teams/ST/code/X_NUCLEO_IDB0XA1/ for more information. - - Note: The Cordio Link layer is used for NRF52 platforms by default. To switch to using the Softdevice, remove these lines in mbed_app.json. -Bluetooth 5 features are only supported by the Cordio implementation, and some examples (such as BLE_GAP) use these. If you're using the Softdevice you can use the deprecated examples in this case. - -For NRF52_DK: -``` - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S132_FULL", "NORDIC_SOFTDEVICE"] -``` + * NRF52_DK + * NRF52840_DK -For NRF52840_DK: -``` - "target.extra_labels_add": ["CORDIO", "CORDIO_LL", "SOFTDEVICE_NONE", "NORDIC_CORDIO"], - "target.extra_labels_remove": ["SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"] -``` - -The following board is currently not supported by non-deprecated examples as it doesn't yet support the Cordio stack: - * NRF51_DK +* Embedded Planet: + * EP_AGORA + +**Important:** If an ST BLE expansion is used with the K64F board, a hardware patch is required. Check out [X-NUCLEO-BNRG2A1](https://github.com/ARMmbed/mbed-os/tree/master/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_BlueNRG_2) or [X-NUCLEO-IDB05A1](https://os.mbed.com/components/X-NUCLEO-IDB05A1/) for more information. -### Using ST Nucleo shield on other targets +The following board is currently not supported as it doesn't yet support the Cordio stack: + * NRF51_DK -It is possible to use the ST Nucleo shield on boards not directly supported by these examples as long as the board has an Arduino UNO R3 connector. +### Using ST BLE expansion board on other targets -To makes the board compatible with the ST shield three things are required: +It is possible to use the ST BLE expansion on boards not directly supported by these examples as long as the board has an Arduino UNO R3 connector. + +To make the board compatible with the ST BLE expansion three things are required: * Add the BLE feature to your target. -* Add the BLE implementation for the ST shield to the list of modules which have to be compiled. -* Indicate to the BLE implementation that your board use an Arduino connector. +* Add the BLE implementation for the ST BLE expansion to the list of modules which have to be compiled. +* Indicate to the BLE implementation that your board uses an Arduino connector. All these operations can be done in the file `mbed_app.json` present in every example. -In the section `target_overrides` add a new object named after your target. -In this object two fields are required: +In the section `target_overrides`, add a new object named after your target with the following three fields: +* `"target.components_add": ["BlueNRG_2"]` Add the BlueNRG-2 component to the target. * `"target.features_add": ["BLE"]` Add the BLE feature to the target. -* `"target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"]`: Add the BLE implementation of the ST shield to the list of the application modules. +* `"target.extra_labels_add": ["CORDIO"]`: Add the BLE implementation of the ST BLE expansion to the list of the application modules. -As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. +Below is an example of the JSON to be added in the `target_overrides` section of `mbed_app.json`, with the `NUCLEO_F401RE` board. ```json - "NUCLEO_F411RE": { + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_2"], "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] + "target.extra_labels_add": ["CORDIO"] }, ``` - **Note:** You can get more information about the configuration system in the [documentation](https://os.mbed.com/docs/latest/reference/configuration.html) - - **Important:** It is required to apply an hardware patch to the ST shield if it is used on a board with an Arduino connector. Check out https://developer.mbed.org/teams/ST/code/X_NUCLEO_IDB0XA1/ for more information. +**Note:** Further information about the configuration system is available in the [documentation](https://os.mbed.com/docs/latest/reference/configuration.html). +**Important:** It is required to apply an hardware patch to the ST BLE expansion if it is used on a board with an Arduino connector. Check out [X-NUCLEO-BNRG2A1](https://github.com/ARMmbed/mbed-os/tree/master/connectivity/drivers/ble/FEATURE_BLE/COMPONENT_BlueNRG_2) or [X-NUCLEO-IDB05A1](https://os.mbed.com/components/X-NUCLEO-IDB05A1/) for more information. -Building and testing the examples ---------------------------------- -__To build an example:__ +## Building the examples 1. Clone the repository containing the collection of examples: - ``` - $ git clone https://github.com/ARMmbed/mbed-os-example-ble.git - ``` + ```bash + $ git clone https://github.com/ARMmbed/mbed-os-example-ble.git + ``` - **Tip:** If you don't have GitHub installed, you can [download a zip file](https://github.com/ARMmbed/mbed-os-example-ble/archive/master.zip) of the repository. + **Tip:** If you don't have git installed, you can [download a zip file](https://github.com/ARMmbed/mbed-os-example-ble/archive/master.zip) of the repository. -1. Using a command-line tool, navigate to any of the example directories, like BLE_Beacon: +1. Using a command-line tool, navigate to any of the example directories, like BLE_Advertising: - ``` - $ cd mbed-os-example-ble - $ cd BLE_Beacon - ``` + ```bash + $ cd mbed-os-example-ble + $ cd BLE_Advertising + ``` 1. Update the source tree: - ``` - mbed deploy - ``` + * Mbed CLI 2 + + ```bash + $ mbed-tools deploy + ``` + + * Mbed CLI 1 + + ```bash + $ mbed deploy + ``` + +1. Connect a USB cable between the USB port on the board and the host computer. + +1. Run the following command: this will build the example project, program the microcontroller flash memory, and then +open a serial terminal to the device. + + * Mbed CLI 2 + + ```bash + $ mbed-tools compile -m -t --flash --sterm --baudrate 115200 + ``` + + * Mbed CLI 1 + + ```bash + $ mbed compile -m -t --flash --sterm --baudrate 115200 + ``` + +Your PC may take a few minutes to compile your code. -1. Run the build: +The binary will be located in the following directory: +* **Mbed CLI 2** - `./cmake_build////` +* **Mbed CLI 1** - `./BUILD///` - ```mbed compile -t -m ``` +You can manually copy the binary to the target, which gets mounted on the host computer through USB, rather than using the `--flash` option. -__To run the application on your board:__ +You can also open a serial terminal separately, as explained below, rather than using the `--sterm` and `--baudrate` options. -1. Connect your mbed board to your computer over USB. It appears as removable storage. +## Running the examples -1. When you run the ``mbed compile`` command, as you did above, mbed cli creates a BIN or an HEX file in a ```BUILD//``` directory under the example's directory. Drag and drop the file to the removable storage. +When example application is running, information about activity is printed over the serial connection. +The default serial baudrate has been set to 115200 for these examples. +If not using the `--sterm` and `--baudrate` options when flashing, have a client +open and connected to the board. You may use: -Exactly which executables are generated depends on the target that you have -chosen. For Nordic Semiconductor targets, the following .hex files will be present: +- Mbed CLI 2 + ```bash + $ mbed-tools sterm -b 115200 + ``` - * `.hex` is the one which can be flashed to the target. - * `.elf` is an ELF binary containing symbols (useful for debugging). +- Mbed CLI 1 + ```bash + $ mbed sterm -b 115200 + ``` -**Note:** Depending on the build process, the file which has to be flashed on a Nordic target can also be named `-combined.hex`. If `-combined.hex` and `.hex` are present in the build directory, flash `-combined.hex. +- [Tera Term](https://ttssh2.osdn.jp/index.html.en) for Windows + +- screen or minicom for Linux + ```bash + screen /dev/serial/ 115200 + ``` + +To observe and/or interact with example applications please use any BLE scanner on a smartphone. +If you don't have a scanner on your phone, please install: + +- [nRF Connect for Mobile](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android and iOS. + +- [ST BLE Profile](https://play.google.com/store/apps/details?id=com.stm.bluetoothlevalidation) for Android. + + +## Using bare metal profile + +MBED BLE can support bare metal profile: https://os.mbed.com/docs/mbed-os/v6.10/bare-metal/using-the-bare-metal-profile.html + + +Here is an example with NUCLEO_WB55RG, update your local mbed_app.json: +``` +{ + "requires": ["bare-metal", "events", "cordio-stm32wb"], +``` + +## How to reduce application size + +Here are few tips to reduce further application size (this could be in addition of baremetal) + +Update in mbed_app.json: + +``` +{ + "target_overrides": { + "*": { + "target.c_lib": "small", + "target.printf_lib": "minimal-printf", + "platform.minimal-printf-enable-floating-point": false, + "platform.stdio-minimal-console-only": true, +... +``` + + +## Troubleshooting + +If you encounter problems with running the example, first try to update to the `development` branch of the example and +see if the problem persists. Make sure to run `mbed update` after you checkout the `development` branch to update the +libraries to the versions in that branch. + +If the problem persists, try turning on traces in the example. This is done by changing the config in `mbed_app.json`: + +``` + "mbed-trace.enable": true, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": true, + "cordio.trace-cordio-wsf-traces": true, + "ble.trace-human-readable-enums": true +``` -**Note:** On non Nordic targets, the file to flash can also be named `.bin`. Refer to mbed-cli, mbed-os and your board vendor documentation for more informations. +Compile with `--profile debug` and run with the serial connected to your PC. +This will enable all the traces in BLE. If the number of traces is too big for the serial to handle or the image +doesn't fit try turning off all except the first one (`mbed-trace.enable`) and/or lowering the `max-level` to +`"TRACE_LEVEL_WARNING"`. -Known issues -============ +Save the output of the serial to a file. Please open an issue in this repo, describe the problem and attach the file +containing the trace output. -* [NUCLEO_F411RE]: Some BLE examples doesn't work with the X-NUCLEO BLE shield. See [#40](https://github.com/ARMmbed/mbed-os-example-ble/issues/40) -* [NRF5] Impossible to debug or flash the examples with IAR: See [#39](https://github.com/ARMmbed/mbed-os-example-ble/issues/39) +## License and contributions -### License and contributions +The software is provided under Apache-2.0 license. Contributions to this project are accepted under the same license. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more info. -The software is provided under Apache-2.0 license. Contributions to this project are accepted under the same license. Please see contributing.md for more info. +## Branches -This project contains code from other projects. The original license text is included in those source files. They must comply with our license guide +`Master` branch is for releases only. Please target the `development` branch for all your PRs. diff --git a/deprecated/BLE_BatteryLevel/.mbed b/deprecated/BLE_BatteryLevel/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_BatteryLevel/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_BatteryLevel/img/connection.png b/deprecated/BLE_BatteryLevel/img/connection.png deleted file mode 100644 index 046fc94c..00000000 Binary files a/deprecated/BLE_BatteryLevel/img/connection.png and /dev/null differ diff --git a/deprecated/BLE_BatteryLevel/img/discovery.png b/deprecated/BLE_BatteryLevel/img/discovery.png deleted file mode 100644 index 90fb664d..00000000 Binary files a/deprecated/BLE_BatteryLevel/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_BatteryLevel/img/notifications.png b/deprecated/BLE_BatteryLevel/img/notifications.png deleted file mode 100644 index fd092cb3..00000000 Binary files a/deprecated/BLE_BatteryLevel/img/notifications.png and /dev/null differ diff --git a/deprecated/BLE_BatteryLevel/img/register_to_notifications.png b/deprecated/BLE_BatteryLevel/img/register_to_notifications.png deleted file mode 100644 index 87cdc0a0..00000000 Binary files a/deprecated/BLE_BatteryLevel/img/register_to_notifications.png and /dev/null differ diff --git a/deprecated/BLE_BatteryLevel/img/scan_result.png b/deprecated/BLE_BatteryLevel/img/scan_result.png deleted file mode 100644 index 4a492273..00000000 Binary files a/deprecated/BLE_BatteryLevel/img/scan_result.png and /dev/null differ diff --git a/deprecated/BLE_BatteryLevel/img/start_scan.png b/deprecated/BLE_BatteryLevel/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_BatteryLevel/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_BatteryLevel/mbed-os.lib b/deprecated/BLE_BatteryLevel/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_BatteryLevel/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_BatteryLevel/mbed_app.json b/deprecated/BLE_BatteryLevel/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_BatteryLevel/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_BatteryLevel/module.json b/deprecated/BLE_BatteryLevel/module.json deleted file mode 100644 index 42d3f5ab..00000000 --- a/deprecated/BLE_BatteryLevel/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-batterylevel", - "version": "0.0.1", - "description": "An example of creating and updating a simple GATT Service using the BLE_API", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/deprecated/BLE_BatteryLevel/readme.md b/deprecated/BLE_BatteryLevel/readme.md deleted file mode 100644 index 1662eadf..00000000 --- a/deprecated/BLE_BatteryLevel/readme.md +++ /dev/null @@ -1,68 +0,0 @@ -This example creates and updates a standard Battery Level service containing a single -GATT characteristic. - -The [battery service transmits](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml) a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery. - -Although the sample application runs on a BLE device, it doesn't show the device's real battery level (because that changes very slowly and will make for a dull example). Instead, it transmits a fake battery level that starts at 50% (half charged). Every half second, it increments the battery level, going in single increments until reaching 100% (as if the battery is charging). It then drops down to 20% to start incrementing again. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named `BATTERY`. - - ![](img/scan_result.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *Battery service* has the UUID 0x180F and includes the *Battery level* characteristic which has the UUID 0x2A19. - - ![](img/discovery.png) - - **figure 4** Representation of the Battery service using Master Control Panel 4.0.5 - -1. Register for the notifications sent by the *Battery level* characteristic. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. You should see the battery level value change every half second. It begins at 50, goes up to 100 (in steps of 1), resets to 20 and so on. - - ![](img/notifications.png) - - **figure 6** Notifications view using Master Control Panel 4.0.5 - -If you can see the characteristic, and if its value is incrementing correctly, the application is working properly. - diff --git a/deprecated/BLE_BatteryLevel/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_BatteryLevel/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index c8075908..00000000 --- a/deprecated/BLE_BatteryLevel/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc diff --git a/deprecated/BLE_BatteryLevel/source/main.cpp b/deprecated/BLE_BatteryLevel/source/main.cpp deleted file mode 100644 index a4f735e3..00000000 --- a/deprecated/BLE_BatteryLevel/source/main.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2014 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 -#include -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/services/BatteryService.h" - -DigitalOut led1(LED1, 1); - -const static char DEVICE_NAME[] = "BATTERY"; -static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE}; - -static uint8_t batteryLevel = 50; -static BatteryService* batteryServicePtr; - -static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) -{ - BLE::Instance().gap().startAdvertising(); -} - -void updateSensorValue() { - batteryLevel++; - if (batteryLevel > 100) { - batteryLevel = 20; - } - - batteryServicePtr->updateBatteryLevel(batteryLevel); -} - -void blinkCallback(void) -{ - led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ - - BLE &ble = BLE::Instance(); - if (ble.gap().getState().connected) { - eventQueue.call(updateSensorValue); - } -} - -/** - * This function is called when the ble initialization process has failled - */ -void onBleInitError(BLE &ble, ble_error_t error) -{ - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -/** - * Callback triggered when the ble initialization process has finished - */ -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - /* In case of error, forward the error handling to onBleInitError */ - onBleInitError(ble, error); - return; - } - - /* Ensure that it is the default instance of BLE */ - if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onDisconnection(disconnectionCallback); - - /* Setup primary service */ - batteryServicePtr = new BatteryService(ble, batteryLevel); - - /* 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().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.gap().setAdvertisingInterval(1000); /* 1000ms */ - ble.gap().startAdvertising(); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - eventQueue.call_every(500, blinkCallback); - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_Beacon/.mbed b/deprecated/BLE_Beacon/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_Beacon/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_Beacon/img/beacon_details.png b/deprecated/BLE_Beacon/img/beacon_details.png deleted file mode 100644 index 2835e694..00000000 Binary files a/deprecated/BLE_Beacon/img/beacon_details.png and /dev/null differ diff --git a/deprecated/BLE_Beacon/img/discovery.png b/deprecated/BLE_Beacon/img/discovery.png deleted file mode 100644 index 48b15406..00000000 Binary files a/deprecated/BLE_Beacon/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_Beacon/img/start_scan.png b/deprecated/BLE_Beacon/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_Beacon/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_Beacon/mbed-os.lib b/deprecated/BLE_Beacon/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_Beacon/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_Beacon/mbed_app.json b/deprecated/BLE_Beacon/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_Beacon/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_Beacon/module.json b/deprecated/BLE_Beacon/module.json deleted file mode 100644 index e0b3e29c..00000000 --- a/deprecated/BLE_Beacon/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-beacon", - "version": "0.0.1", - "description": "BLE iBeacon example, building with yotta", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/deprecated/BLE_Beacon/readme.md b/deprecated/BLE_Beacon/readme.md deleted file mode 100644 index 20a175d6..00000000 --- a/deprecated/BLE_Beacon/readme.md +++ /dev/null @@ -1,52 +0,0 @@ -This example creates a BLE beacon: a method of advertising a small amount of information to nearby devices. The information doesn't have to be human-readable; it can be in a format that only an application can use. - -Beacons are very easy to set up: the code for all beacons is the same, and only the information you want to advertise - the beacon payload - needs to change. - -This example advertises a UUID, a major and minor number and the transmission strength. The major and minor numbers are an example of information that is not (normally) meaningful to humans, but that an application can use to identify the beacon and display related information. For example, if the major number is a store ID and the minor number is a location in that store, then a matching application can use these numbers to query a database and display location-specific information. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Connect for Mobile](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be tagged as an `iBeacon` and observe its advertisements (there is no need to connect to the beacon). - - ![](img/discovery.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. View the beacon's details; the exact steps depend on which scanner you're using. - - ![](img/beacon_details.png) - - **figure 3** Beacon details using nRF Master Control Panel 4.0.5 - - -**Tip:** If you are in an area with many BLE devices, it may be difficult to identify your beacon. The simplest solution is to turn your board off and on, initiate a new scan on your BLE scanner every time, and look for the beacon that appears only when your board is on. - -If you can see the beacon and all its information, the application worked properly. - -For more information, see the [mbed Classic version of this application](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_iBeacon/). diff --git a/deprecated/BLE_Beacon/shields/TARGET_ST_BLUENRG.lib b/deprecated/BLE_Beacon/shields/TARGET_ST_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_Beacon/shields/TARGET_ST_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_Beacon/source/main.cpp b/deprecated/BLE_Beacon/source/main.cpp deleted file mode 100644 index d7c84b54..00000000 --- a/deprecated/BLE_Beacon/source/main.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 -#include -#include "ble/BLE.h" -#include "ble/services/iBeacon.h" - -static iBeacon* ibeaconPtr; - -static EventQueue eventQueue(/* event count */ 4 * EVENTS_EVENT_SIZE); - -/** - * This function is called when the ble initialization process has failled - */ -void onBleInitError(BLE &ble, ble_error_t error) -{ - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -/** - * Callback triggered when the ble initialization process has finished - */ -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - /* In case of error, forward the error handling to onBleInitError */ - onBleInitError(ble, error); - return; - } - - /* Ensure that it is the default instance of BLE */ - if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - /** - * The Beacon payload has the following composition: - * 128-Bit / 16byte UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 - * Major/Minor = 0x1122 / 0x3344 - * Tx Power = 0xC8 = 200, 2's compliment is 256-200 = (-56dB) - * - * Note: please remember to calibrate your beacons TX Power for more accurate results. - */ - static const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, - 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61}; - uint16_t majorNumber = 1122; - uint16_t minorNumber = 3344; - uint16_t txPower = 0xC8; - ibeaconPtr = new iBeacon(ble, uuid, majorNumber, minorNumber, txPower); - - ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ - ble.gap().startAdvertising(); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_Button/.mbed b/deprecated/BLE_Button/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_Button/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_Button/img/button_depressed.png b/deprecated/BLE_Button/img/button_depressed.png deleted file mode 100644 index a9da976a..00000000 Binary files a/deprecated/BLE_Button/img/button_depressed.png and /dev/null differ diff --git a/deprecated/BLE_Button/img/button_pressed.png b/deprecated/BLE_Button/img/button_pressed.png deleted file mode 100644 index af8a889a..00000000 Binary files a/deprecated/BLE_Button/img/button_pressed.png and /dev/null differ diff --git a/deprecated/BLE_Button/img/connection.png b/deprecated/BLE_Button/img/connection.png deleted file mode 100644 index cb269cf3..00000000 Binary files a/deprecated/BLE_Button/img/connection.png and /dev/null differ diff --git a/deprecated/BLE_Button/img/discovery.png b/deprecated/BLE_Button/img/discovery.png deleted file mode 100644 index 02fb19a8..00000000 Binary files a/deprecated/BLE_Button/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_Button/img/register_to_notifications.png b/deprecated/BLE_Button/img/register_to_notifications.png deleted file mode 100644 index 345e2826..00000000 Binary files a/deprecated/BLE_Button/img/register_to_notifications.png and /dev/null differ diff --git a/deprecated/BLE_Button/img/scan_results.png b/deprecated/BLE_Button/img/scan_results.png deleted file mode 100644 index 0c1e8cf3..00000000 Binary files a/deprecated/BLE_Button/img/scan_results.png and /dev/null differ diff --git a/deprecated/BLE_Button/img/start_scan.png b/deprecated/BLE_Button/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_Button/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_Button/mbed-os.lib b/deprecated/BLE_Button/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_Button/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_Button/mbed_app.json b/deprecated/BLE_Button/mbed_app.json deleted file mode 100644 index e834b5a8..00000000 --- a/deprecated/BLE_Button/mbed_app.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "config": { - "ble_button_pin_name": { - "help": "The pin name used as button in this application", - "macro_name": "BLE_BUTTON_PIN_NAME", - "required": true - } - }, - "target_overrides": { - "NRF51_DK": { - "ble_button_pin_name": "BUTTON1" - }, - "NRF52_DK": { - "ble_button_pin_name": "BUTTON1" - }, - "MTB_UBLOX_NINA_B1": { - "ble_button_pin_name": "BUTTON1" - }, - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "SW2" - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - } - } -} diff --git a/deprecated/BLE_Button/module.json b/deprecated/BLE_Button/module.json deleted file mode 100644 index 484fa72b..00000000 --- a/deprecated/BLE_Button/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-button", - "version": "0.0.1", - "description": "The *input service template* demonstrates the use of a simple input (boolean values) from a read-only characteristic.", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "bin": "./source", - "dependencies": { - "ble": "^2.0.0" - } -} diff --git a/deprecated/BLE_Button/readme.md b/deprecated/BLE_Button/readme.md deleted file mode 100644 index b0d72030..00000000 --- a/deprecated/BLE_Button/readme.md +++ /dev/null @@ -1,99 +0,0 @@ -BLE_Button is a BLE service template. It handles a read-only characteristic with a simple input (boolean values). The input's source is the button on the board itself - the characteristic's value changes when the button is pressed or released. - -The template covers: - -1. Setting up advertising and connection modes. - -1. Creating an input characteristic: read-only, boolean, with notifications. - -1. Constructing a service class and adding it to the BLE stack. - -1. Assigning UUIDs to the service and its characteristic. - -1. Pushing notifications when the characteristic's value changes. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -### Porting this example on new boards - -This example requires a board with at least a button to work. While the pin name of the button is defined for the `NRF51_DK`, `NRF52_DK`, `K64F` and `NUCLEO_F401RE`, it is not specified for other boards. - -It is easy to add the button configuration for your board: -* Open the file named `mbed_app.json` at the root of this example. -* In the section `target_overides` add a new object named after your target if it doesn't exist. This object contain overridden parameters for your target. -* Override the property `ble_button_pin_name` in your target object. The value of the property should be equal to the pin name to use as a button. - -As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. - -```json - "NUCLEO_F411RE": { - "ble_button_pin_name": "USER_BUTTON" - } -``` - - **Note:** You can get more informations about the configuration system in the [documentation](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) - - **Important:** If your target use an ST BLE shield, other parameters have to be overridden for your target. More information are available in the global [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md#targets-for-ble) - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should appear with the name `Button` in the scanner. - - ![](img/scan_results.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with the device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *Button service* has the UUID `0xA000` and includes the *Button state characteristic* which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value. - - ![](img/discovery.png) - - **figure 4** Representation of the Button service using Master Control Panel 4.0.5 - -1. Register for the notifications sent by the button state characteristic then the scanner will automatically receive a notification containing the new state of the button every time the state of the button changes. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. Pressing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x01. - - ![](img/button_pressed.png) - - **figure 6** Notification of button pressed using Master Control Panel 4.0.5 - -1. Releasing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x00. - - ![](img/button_depressed.png) - - **figure 7** Notification of button depressed using Master Control Panel 4.0.5 diff --git a/deprecated/BLE_Button/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_Button/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_Button/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_Button/source/ButtonService.h b/deprecated/BLE_Button/source/ButtonService.h deleted file mode 100644 index 86c92040..00000000 --- a/deprecated/BLE_Button/source/ButtonService.h +++ /dev/null @@ -1,42 +0,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. - */ - -#ifndef __BLE_BUTTON_SERVICE_H__ -#define __BLE_BUTTON_SERVICE_H__ - -class ButtonService { -public: - const static uint16_t BUTTON_SERVICE_UUID = 0xA000; - const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001; - - ButtonService(BLE &_ble, bool buttonPressedInitial) : - ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) - { - GattCharacteristic *charTable[] = {&buttonState}; - GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - ble.gattServer().addService(buttonService); - } - - void updateButtonState(bool newState) { - ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool)); - } - -private: - BLE &ble; - ReadOnlyGattCharacteristic buttonState; -}; - -#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */ diff --git a/deprecated/BLE_Button/source/main.cpp b/deprecated/BLE_Button/source/main.cpp deleted file mode 100644 index 66418d32..00000000 --- a/deprecated/BLE_Button/source/main.cpp +++ /dev/null @@ -1,122 +0,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 - -#include -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ButtonService.h" - -DigitalOut led1(LED1, 1); -InterruptIn button(BLE_BUTTON_PIN_NAME); - -static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE); - -const static char DEVICE_NAME[] = "Button"; -static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID}; - -ButtonService *buttonServicePtr; - -void buttonPressedCallback(void) -{ - eventQueue.call(Callback(buttonServicePtr, &ButtonService::updateButtonState), true); -} - -void buttonReleasedCallback(void) -{ - eventQueue.call(Callback(buttonServicePtr, &ButtonService::updateButtonState), false); -} - -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) -{ - BLE::Instance().gap().startAdvertising(); // restart advertising -} - -void blinkCallback(void) -{ - led1 = !led1; /* Do blinky on LED1 to indicate system aliveness. */ -} - -void onBleInitError(BLE &ble, ble_error_t error) -{ - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - /* In case of error, forward the error handling to onBleInitError */ - onBleInitError(ble, error); - return; - } - - /* Ensure that it is the default instance of BLE */ - if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onDisconnection(disconnectionCallback); - - button.fall(buttonPressedCallback); - button.rise(buttonReleasedCallback); - - /* Setup primary service. */ - buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */); - - /* 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().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ - ble.gap().startAdvertising(); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - eventQueue.call_every(500, blinkCallback); - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_GAP/.mbed b/deprecated/BLE_GAP/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_GAP/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_GAP/README.md b/deprecated/BLE_GAP/README.md deleted file mode 100644 index 8f6132b9..00000000 --- a/deprecated/BLE_GAP/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# GAP - Advertising, Scanning, Connecting - -Demo of the GAP profile. It shows advertising, scanning and connecting. The demo will cycle through several modes -and print over the serial connection information about current activity. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Information about activity is printed over the serial connection - please have a client open. You may use: - -- [Tera Term](https://ttssh2.osdn.jp/index.html.en) - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). diff --git a/deprecated/BLE_GAP/mbed-os.lib b/deprecated/BLE_GAP/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_GAP/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_GAP/mbed_app.json b/deprecated/BLE_GAP/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_GAP/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_GAP/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_GAP/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_GAP/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_GAP/source/main.cpp b/deprecated/BLE_GAP/source/main.cpp deleted file mode 100644 index 000bc166..00000000 --- a/deprecated/BLE_GAP/source/main.cpp +++ /dev/null @@ -1,599 +0,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 -#include -#include "ble/BLE.h" - -/** This example demonstrates all the basic setup required - * to advertise, scan and connect to other devices. - * - * It contains a single class that performs both scans and advertisements. - * - * The demonstrations happens in sequence, after each "mode" ends - * the demo jumps to the next mode to continue. There are several modes - * that show scanning and several showing advertising. These are configured - * according to the two arrays containing parameters. During scanning - * a connection will be made to a connectable device upon its discovery. - */ - -static const uint8_t DEVICE_NAME[] = "GAP_device"; - -/* Duration of each mode in milliseconds */ -static const size_t MODE_DURATION_MS = 6000; - -/* Time between each mode in milliseconds */ -static const size_t TIME_BETWEEN_MODES_MS = 2000; - -/* how long to wait before disconnecting in milliseconds */ -static const size_t CONNECTION_DURATION = 3000; - -typedef struct { - GapAdvertisingParams::AdvertisingType_t adv_type; - uint16_t interval; - uint16_t timeout; -} AdvModeParam_t; - -typedef struct { - uint16_t interval; - uint16_t window; - uint16_t timeout; - bool active; -} ScanModeParam_t; - -/** the entries in this array are used to configure our advertising - * parameters for each of the modes we use in our demo */ -static const AdvModeParam_t advertising_params[] = { - /* advertising type interval timeout */ - { GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, 40,/*ms*/ 3/*s*/}, - { GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED, 100, 4 }, - { GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED, 100, 0 } -}; - -/* when we cycle through all our advertising modes we will move to scanning modes */ - -/** the entries in this array are used to configure our scanning - * parameters for each of the modes we use in our demo */ -static const ScanModeParam_t scanning_params[] = { -/* interval window timeout active */ - { 4,/*ms*/ 4,/*ms*/ 0,/*s*/ false }, - { 160, 100, 3, false }, - { 160, 40, 0, true }, - { 500, 10, 0, false } -}; - -/* parameters to use when attempting to connect to maximise speed of connection */ -static const GapScanningParams connection_scan_params( - GapScanningParams::SCAN_INTERVAL_MAX, - GapScanningParams::SCAN_WINDOW_MAX, - 3, - false -); - -/* get number of items in our arrays */ -static const size_t SCAN_PARAM_SET_MAX = - sizeof(scanning_params) / sizeof(GapScanningParams); -static const size_t ADV_PARAM_SET_MAX = - sizeof(advertising_params) / sizeof(GapAdvertisingParams); - -static const char* 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"; - } -} - -/** Demonstrate advertising, scanning and connecting - */ -class GAPDevice : private mbed::NonCopyable, public Gap::EventHandler -{ -public: - GAPDevice() : - _ble(BLE::Instance()), - _led1(LED1, 0), - _set_index(0), - _is_in_scanning_mode(false), - _is_connecting(false), - _on_duration_end_id(0), - _scan_count(0) { }; - - ~GAPDevice() - { - if (_ble.hasInitialized()) { - _ble.shutdown(); - } - }; - - /** Start BLE interface initialisation */ - void run() - { - ble_error_t error; - - 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, &GAPDevice::schedule_ble_events) - ); - - /* handle timeouts, for example when connection attempts fail */ - _ble.gap().onTimeout( - makeFunctionPointer(this, &GAPDevice::on_timeout) - ); - - /* handle gap events */ - _ble.gap().setEventHandler(this); - - error = _ble.init(this, &GAPDevice::on_init_complete); - - if (error) { - printf("Error returned by BLE::init.\r\n"); - return; - } - - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &GAPDevice::blink); - - /* this will not return until shutdown */ - _event_queue.dispatch_forever(); - }; - -private: - /** This is called when BLE interface is initialised and starts the first mode */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - if (event->error) { - printf("Error during the initialisation\r\n"); - return; - } - - /* 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]); - - /* setup the default phy used in connection to 2M to reduce power consumption */ - Gap::PhySet_t tx_phys(/* 1M */ false, /* 2M */ true, /* coded */ false); - Gap::PhySet_t rx_phys(/* 1M */ false, /* 2M */ true, /* coded */ false); - ble_error_t err = _ble.gap().setPreferredPhys(&tx_phys, &rx_phys); - if (err) { - printf("INFO: GAP::setPreferedPhys failed with error code %s", BLE::errorToString(err)); - } - - /* all calls are serialised on the user thread through the event queue */ - _event_queue.call(this, &GAPDevice::demo_mode_start); - }; - - /** queue up start of the current demo mode */ - void demo_mode_start() - { - if (_is_in_scanning_mode) { - /* 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, &GAPDevice::on_connect); - _ble.gap().onDisconnection(this, &GAPDevice::on_disconnect); - - _event_queue.call(this, &GAPDevice::scan); - } else { - _event_queue.call(this, &GAPDevice::advertise); - } - - /* for performance measurement keep track of duration of the demo mode */ - _demo_duration.start(); - /* keep track of our state */ - _is_connecting = false; - - /* queue up next demo mode */ - _on_duration_end_id = _event_queue.call_in( - MODE_DURATION_MS, this, &GAPDevice::on_duration_end - ); - - printf("\r\n"); - } - - /** Set up and start advertising */ - void advertise() - { - 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; - } - - /* set the advertising parameters according to currently selected set, - * see @AdvertisingType_t for explanation of modes */ - GapAdvertisingParams::AdvertisingType_t adv_type = - advertising_params[_set_index].adv_type; - - /* how many milliseconds between advertisements, lower interval - * increases the chances of being seen at the cost of more power */ - uint16_t interval = advertising_params[_set_index].interval; - - /* advertising will continue for this many seconds or until connected */ - uint16_t timeout = advertising_params[_set_index].timeout; - - _ble.gap().setAdvertisingType(adv_type); - _ble.gap().setAdvertisingInterval(interval); - _ble.gap().setAdvertisingTimeout(timeout); - - error = _ble.gap().startAdvertising(); - - if (error) { - printf("Error during Gap::startAdvertising.\r\n"); - return; - } - - printf("Advertising started (type: 0x%x, interval: %dms, timeout: %ds)\r\n", - adv_type, interval, timeout); - }; - - /** Set up and start scanning */ - void scan() - { - ble_error_t error; - - /* scanning happens repeatedly, interval is the number of milliseconds - * between each cycle of scanning */ - uint16_t interval = scanning_params[_set_index].interval; - - /* number of milliseconds we scan for each time we enter - * the scanning cycle after the interval set above */ - uint16_t window = scanning_params[_set_index].window; - - /* how long to repeat the cycles of scanning in seconds */ - uint16_t timeout = scanning_params[_set_index].timeout; - - /* active scanning will send a scan request to any scanable devices that - * we see advertising */ - bool active = scanning_params[_set_index].active; - - /* set the scanning parameters according to currently selected set */ - error = _ble.gap().setScanParams(interval, window, timeout, active); - - if (error) { - printf("Error during Gap::setScanParams\r\n"); - return; - } - - /* start scanning and attach a callback that will handle advertisements - * and scan requests responses */ - error = _ble.gap().startScan(this, &GAPDevice::on_scan); - - if (error) { - printf("Error during Gap::startScan\r\n"); - return; - } - - printf("Scanning started (interval: %dms, window: %dms, timeout: %ds).\r\n", - interval, window, timeout); - }; - - /** After a set duration this cycles to the next demo mode - * unless a connection happened first */ - void on_duration_end() - { - print_performance(); - - /* alloted time has elapsed, move to next demo mode */ - _event_queue.call(this, &GAPDevice::demo_mode_end); - }; - - /** Look at scan payload to find a peer device and connect to it */ - void on_scan(const Gap::AdvertisementCallbackParams_t *params) - { - /* keep track of scan events for performance reporting */ - _scan_count++; - - /* 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; - } - const uint8_t type = params->advertisingData[i + 1]; - const uint8_t *value = params->advertisingData + i + 2; - - /* connect to a discoverable device */ - if ((type == GapAdvertisingData::FLAGS) - && (*value & GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) { - - /* abort timeout as the mode will end on disconnection */ - _event_queue.cancel(_on_duration_end_id); - - printf("We found a connectable device\r\n"); - - ble_error_t error = _ble.gap().connect( - params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, - NULL, &connection_scan_params - ); - - if (error) { - printf("Error during Gap::connect\r\n"); - /* since no connection will be attempted end the mode */ - _event_queue.call(this, &GAPDevice::demo_mode_end); - 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 disconnects */ - void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) - { - print_performance(); - - printf("Connected in %dms\r\n", _demo_duration.read_ms()); - - /* cancel the connect timeout since we connected */ - _event_queue.cancel(_on_duration_end_id); - - _event_queue.call_in( - CONNECTION_DURATION, &_ble.gap(), &Gap::disconnect, Gap::REMOTE_USER_TERMINATED_CONNECTION - ); - }; - - /** This is called by Gap to notify the application we disconnected, - * in our case it calls demo_mode_end() to progress the demo */ - void on_disconnect(const Gap::DisconnectionCallbackParams_t *event) - { - printf("Disconnected\r\n"); - - /* we have successfully disconnected ending the demo, move to next mode */ - _event_queue.call(this, &GAPDevice::demo_mode_end); - }; - - /** - * Implementation of Gap::EventHandler::onReadPhy - */ - virtual void onReadPhy( - ble_error_t error, - Gap::Handle_t connectionHandle, - Gap::Phy_t txPhy, - Gap::Phy_t rxPhy - ) { - if (error) { - printf( - "Phy read on connection %d failed with error code %s\r\n", - connectionHandle, - BLE::errorToString(error) - ); - } else { - printf( - "Phy read on connection %d - Tx Phy: %s, Rx Phy: %s\r\n", - connectionHandle, - to_string(txPhy), - to_string(rxPhy) - ); - } - } - - /** - * Implementation of Gap::EventHandler::onPhyUpdateComplete - */ - virtual void onPhyUpdateComplete( - ble_error_t error, - Gap::Handle_t connectionHandle, - Gap::Phy_t txPhy, - Gap::Phy_t rxPhy - ) { - if (error) { - printf( - "Phy update on connection: %d failed with error code %s\r\n", - connectionHandle, - BLE::errorToString(error) - ); - } else { - printf( - "Phy update on connection %d - Tx Phy: %s, Rx Phy: %s\r\n", - connectionHandle, - to_string(txPhy), - to_string(rxPhy) - ); - } - } - - /** called if timeout is reached during advertising, scanning - * or connection initiation */ - void on_timeout(const Gap::TimeoutSource_t source) - { - _demo_duration.stop(); - - switch (source) { - case Gap::TIMEOUT_SRC_ADVERTISING: - printf("Stopped advertising early due to timeout parameter\r\n"); - break; - case Gap::TIMEOUT_SRC_SCAN: - printf("Stopped scanning early due to timeout parameter\r\n"); - break; - case Gap::TIMEOUT_SRC_CONN: - printf("Failed to connect after scanning %d advertisements\r\n", _scan_count); - _event_queue.call(this, &GAPDevice::print_performance); - _event_queue.call(this, &GAPDevice::demo_mode_end); - break; - default: - printf("Unexpected timeout\r\n"); - break; - } - }; - - /** clean up after last run, cycle to the next mode and launch it */ - void demo_mode_end() - { - /* reset the demo ready for the next mode */ - _scan_count = 0; - _demo_duration.stop(); - _demo_duration.reset(); - - /* cycle through all demo modes */ - _set_index++; - - /* switch between advertising and scanning when we go - * through all the params in the array */ - if (_set_index >= (_is_in_scanning_mode? SCAN_PARAM_SET_MAX : ADV_PARAM_SET_MAX)) { - _set_index = 0; - _is_in_scanning_mode = !_is_in_scanning_mode; - } - - _ble.shutdown(); - _event_queue.break_dispatch(); - }; - - /** print some information about our radio activity */ - void print_performance() - { - /* measure time from mode start, may have been stopped by timeout */ - uint16_t duration = _demo_duration.read_ms(); - - if (_is_in_scanning_mode) { - /* convert ms into timeslots for accurate calculation as internally - * all durations are in timeslots (0.625ms) */ - uint16_t interval_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( - scanning_params[_set_index].interval - ); - uint16_t window_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( - scanning_params[_set_index].window - ); - uint16_t duration_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( - duration - ); - /* this is how long we scanned for in timeslots */ - uint16_t rx_ts = (duration_ts / interval_ts) * window_ts; - /* convert to milliseconds */ - uint16_t rx_ms = (rx_ts * GapScanningParams::UNIT_0_625_MS) / 1000; - - printf("We have scanned for %dms with an interval of %d" - " timeslot and a window of %d timeslots\r\n", - duration, interval_ts, window_ts); - - printf("We have been listening on the radio for at least %dms\r\n", rx_ms); - - } else /* advertising */ { - - /* convert ms into timeslots for accurate calculation as internally - * all durations are in timeslots (0.625ms) */ - uint16_t interval_ts = GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( - advertising_params[_set_index].interval - ); - uint16_t duration_ts = GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( - duration - ); - /* this is how many times we advertised */ - uint16_t events = duration_ts / interval_ts; - - printf("We have advertised for %dms" - " with an interval of %d timeslots\r\n", - duration, interval_ts); - - /* non-scannable and non-connectable advertising - * skips rx events saving on power consumption */ - if (advertising_params[_set_index].adv_type - == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { - printf("We created at least %d tx events\r\n", events); - } else { - printf("We created at least %d tx and rx events\r\n", events); - } - } - }; - - /** Schedule processing of events from the BLE middleware 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: - BLE &_ble; - events::EventQueue _event_queue; - DigitalOut _led1; - - /* Keep track of our progress through demo modes */ - size_t _set_index; - bool _is_in_scanning_mode; - bool _is_connecting; - - /* Remember the call id of the function on _event_queue - * so we can cancel it if we need to end the mode early */ - int _on_duration_end_id; - - /* Measure performance of our advertising/scanning */ - Timer _demo_duration; - size_t _scan_count; -}; - -int main() -{ - GAPDevice gap_device; - - while (1) { - gap_device.run(); - wait_ms(TIME_BETWEEN_MODES_MS); - printf("\r\nStarting next GAP demo mode\r\n"); - }; - - return 0; -} diff --git a/deprecated/BLE_GAPButton/.mbed b/deprecated/BLE_GAPButton/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_GAPButton/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_GAPButton/README.md b/deprecated/BLE_GAPButton/README.md deleted file mode 100644 index 65b76c64..00000000 --- a/deprecated/BLE_GAPButton/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# Button count over GAP - -This application shows how to use GAP to transmit a simple value to a disconnected peer listening for advertisement every time that a value is updated: - -1. The value is a count of how many times a button on the device was pressed (the code actually monitors the button's releases, not press downs). - -1. We transmit the value in the SERVICE_DATA field of the advertising payload. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -### Porting this example on new boards - -This example requires a board with at least 1 button to work. While the pin name of the button is defined for the `NRF51_DK`, `NRF52_DK`, `K64F` and `NUCLEO_F401RE`, it is not specified for other boards. - -It is easy to add the button configuration for your board: -* Open the file named `mbed_app.json` at the root of this example. -* In the section `target_overides` add a new object named after your target if it doesn't exist. This object contain overridden parameters for your target. -* Override the property `ble_button_pin_name` in your target object. The value of the property should be equal to the pin name to use as a button. - -As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. - -```json - "NUCLEO_F411RE": { - "ble_button_pin_name": "USER_BUTTON" - } -``` - - **Note:** You can get more informations about the configuration system in the [documentation](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) - - **Important:** If your target use an ST BLE shield, other parameters have to be overridden for your target. More information are available in the global [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md#targets-for-ble) - - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. - -1. Open the BLE scanner on your phone. - -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5. - -1. Find your device; it should be named `GAPButton`; and look at the advertisement broadcasted by your device (there is no need to connect to your device). - - ![](img/discovery.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5. - -1. The Service Data field of the advertisement packet broadcasted by your device reflects the button press count. The starting value is 0. - - ![](img/initial_state.png) - - **figure 3** Initial state of the button using nRF Master Control Panel 4.0.5. - -1. Press the button on the device. - - ![](img/first_press.png) - - **figure 3** State after 1 button press using nRF Master Control Panel 4.0.5. - -1. The Service Data field value of the advertisement packet should change every time you press the button. - - ![](img/result.png) - - **figure 3** State after 6 button press using nRF Master Control Panel 4.0.5. - -## Note - -Since broadcasting is not reliable and your phone may scan intermittently, it is possible that your phone will miss button updates. diff --git a/deprecated/BLE_GAPButton/img/discovery.png b/deprecated/BLE_GAPButton/img/discovery.png deleted file mode 100644 index 21010d54..00000000 Binary files a/deprecated/BLE_GAPButton/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_GAPButton/img/first_press.png b/deprecated/BLE_GAPButton/img/first_press.png deleted file mode 100644 index f72cb1ee..00000000 Binary files a/deprecated/BLE_GAPButton/img/first_press.png and /dev/null differ diff --git a/deprecated/BLE_GAPButton/img/initial_state.png b/deprecated/BLE_GAPButton/img/initial_state.png deleted file mode 100644 index 22adc383..00000000 Binary files a/deprecated/BLE_GAPButton/img/initial_state.png and /dev/null differ diff --git a/deprecated/BLE_GAPButton/img/result.png b/deprecated/BLE_GAPButton/img/result.png deleted file mode 100644 index c0681355..00000000 Binary files a/deprecated/BLE_GAPButton/img/result.png and /dev/null differ diff --git a/deprecated/BLE_GAPButton/img/start_scan.png b/deprecated/BLE_GAPButton/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_GAPButton/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_GAPButton/mbed-os.lib b/deprecated/BLE_GAPButton/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_GAPButton/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_GAPButton/mbed_app.json b/deprecated/BLE_GAPButton/mbed_app.json deleted file mode 100644 index 15fd0abc..00000000 --- a/deprecated/BLE_GAPButton/mbed_app.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "config": { - "ble_button_pin_name": { - "help": "The pin name used as button in this application", - "macro_name": "BLE_BUTTON_PIN_NAME", - "required": true - } - }, - "target_overrides": { - "NRF51_DK": { - "ble_button_pin_name": "BUTTON1" - }, - "NRF52_DK": { - "ble_button_pin_name": "BUTTON1" - }, - "MTB_UBLOX_NINA_B1": { - "ble_button_pin_name": "BUTTON1" - }, - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "SW2" - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "ble_button_pin_name": "USER_BUTTON" - } - } -} diff --git a/deprecated/BLE_GAPButton/module.json b/deprecated/BLE_GAPButton/module.json deleted file mode 100644 index 83c154cf..00000000 --- a/deprecated/BLE_GAPButton/module.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "ble-gapbutton", - "version": "0.0.1", - "bin": "./source", - "description": "BLE button that uses gap advertisement to broadcast its state.", - "author": "Liyou Zhou", - "license": "Apache-2.0", - "dependencies": { - "mbed-drivers": "*", - "ble": "^2.0.0" - } -} diff --git a/deprecated/BLE_GAPButton/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_GAPButton/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_GAPButton/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_GAPButton/source/main.cpp b/deprecated/BLE_GAPButton/source/main.cpp deleted file mode 100644 index 67305d6f..00000000 --- a/deprecated/BLE_GAPButton/source/main.cpp +++ /dev/null @@ -1,209 +0,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 -#include -#include "ble/BLE.h" - -DigitalOut led1(LED1, 1); -InterruptIn button(BLE_BUTTON_PIN_NAME); -uint8_t cnt; - -// Change your device name below -const char DEVICE_NAME[] = "GAPButton"; - -/* We can arbiturarily choose the GAPButton service UUID to be 0xAA00 - * as long as it does not overlap with the UUIDs defined here: - * https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */ -#define GAPButtonUUID 0xAA00 -const uint16_t uuid16_list[] = {GAPButtonUUID}; - -static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -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"); -} - -void updatePayload(void) -{ - // Update the count in the SERVICE_DATA field of the advertising payload - uint8_t service_data[3]; - service_data[0] = GAPButtonUUID & 0xff; - service_data[1] = GAPButtonUUID >> 8; - service_data[2] = cnt; // Put the button click count in the third byte - ble_error_t err = BLE::Instance().gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data)); - if (err != BLE_ERROR_NONE) { - print_error(err, "Updating payload failed"); - } -} - -void buttonPressedCallback(void) -{ - ++cnt; - - // Calling BLE api in interrupt context may cause race conditions - // Using mbed-events to schedule calls to BLE api for safety - eventQueue.call(updatePayload); -} - -void blinkCallback(void) -{ - led1 = !led1; -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -void bleInitComplete(BLE::InitializationCompleteCallbackContext *context) -{ - BLE& ble = context->ble; - ble_error_t err = context->error; - - if (err != BLE_ERROR_NONE) { - print_error(err, "BLE initialisation failed"); - return; - } - - // Set up the advertising flags. Note: not all combination of flags are valid - // BREDR_NOT_SUPPORTED: Device does not support Basic Rate or Enchanced Data Rate, It is Low Energy only. - // LE_GENERAL_DISCOVERABLE: Peripheral device is discoverable at any moment - err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - if (err != BLE_ERROR_NONE) { - print_error(err, "Setting GAP flags failed"); - return; - } - - // Put the device name in the advertising payload - err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); - if (err != BLE_ERROR_NONE) { - print_error(err, "Setting device name failed"); - return; - } - - err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); - if (err != BLE_ERROR_NONE) { - print_error(err, "Setting service UUID failed"); - return; - } - - // The Service Data data type consists of a service UUID with the data associated with that service. - // We will encode the number of button clicks in the Service Data field - // First two bytes of SERVICE_DATA field should contain the UUID of the service - uint8_t service_data[3]; - service_data[0] = GAPButtonUUID & 0xff; - service_data[1] = GAPButtonUUID >> 8; - service_data[2] = cnt; // Put the button click count in the third byte - err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data)); - if (err != BLE_ERROR_NONE) { - print_error(err, "Setting service data failed"); - return; - } - - // It is not connectable as we are just boardcasting - ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); - - // Send out the advertising payload every 1000ms - ble.gap().setAdvertisingInterval(1000); - - err = ble.gap().startAdvertising(); - if (err != BLE_ERROR_NONE) { - print_error(err, "Start advertising failed"); - return; - } - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - cnt = 0; - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble_error_t err = ble.init(bleInitComplete); - if (err != BLE_ERROR_NONE) { - print_error(err, "BLE initialisation failed"); - return 0; - } - - // Blink LED every 500 ms to indicate system aliveness - eventQueue.call_every(500, blinkCallback); - - // Register function to be called when button is released - button.rise(buttonPressedCallback); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_GattClient/.mbed b/deprecated/BLE_GattClient/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_GattClient/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_GattClient/BLEProcess.h b/deprecated/BLE_GattClient/BLEProcess.h deleted file mode 100644 index a298477d..00000000 --- a/deprecated/BLE_GattClient/BLEProcess.h +++ /dev/null @@ -1,231 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 GATT_EXAMPLE_BLE_PROCESS_H_ -#define GATT_EXAMPLE_BLE_PROCESS_H_ - -#include -#include - -#include "events/EventQueue.h" -#include "platform/Callback.h" -#include "platform/NonCopyable.h" - -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/FunctionPointerWithContext.h" - -/** - * Handle initialization and shutdown of the BLE Instance. - * - * Setup advertising payload and manage advertising state. - * Delegate to GattClientProcess once the connection is established. - */ -class BLEProcess : private mbed::NonCopyable { -public: - /** - * Construct a BLEProcess from an event queue and a ble interface. - * - * Call start() to initiate ble processing. - */ - BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) : - _event_queue(event_queue), - _ble_interface(ble_interface), - _post_init_cb() { - } - - ~BLEProcess() - { - stop(); - } - - /** - * Initialize the ble interface, configure it and start advertising. - */ - bool start() - { - printf("Ble process started.\r\n"); - - if (_ble_interface.hasInitialized()) { - printf("Error: the ble instance has already been initialized.\r\n"); - return false; - } - - _ble_interface.onEventsToProcess( - makeFunctionPointer(this, &BLEProcess::schedule_ble_events) - ); - - ble_error_t error = _ble_interface.init( - this, &BLEProcess::when_init_complete - ); - - if (error) { - printf("Error: %u returned by BLE::init.\r\n", error); - return false; - } - - return true; - } - - /** - * Close existing connections and stop the process. - */ - void stop() - { - if (_ble_interface.hasInitialized()) { - _ble_interface.shutdown(); - printf("Ble process stopped."); - } - } - - /** - * Subscription to the ble interface initialization event. - * - * @param[in] cb The callback object that will be called when the ble - * interface is initialized. - */ - void on_init(mbed::Callback cb) - { - _post_init_cb = cb; - } - -private: - /** - * Sets up adverting payload and start advertising. - * - * This function is invoked when the ble interface is initialized. - */ - void when_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - if (event->error) { - printf("Error %u during the initialization\r\n", event->error); - return; - } - printf("Ble instance initialized\r\n"); - - Gap &gap = _ble_interface.gap(); - ble_error_t error = gap.setAdvertisingPayload(make_advertising_data()); - if (error) { - printf("Error %u during gap.setAdvertisingPayload\r\n", error); - return; - } - - gap.setAdvertisingParams(make_advertising_params()); - - gap.onConnection(this, &BLEProcess::when_connection); - gap.onDisconnection(this, &BLEProcess::when_disconnection); - - start_advertising(); - - if (_post_init_cb) { - _post_init_cb(_ble_interface, _event_queue); - } - } - - /** - * Start the gatt client process when a connection event is received. - */ - void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) - { - printf("Connected.\r\n"); - } - - /** - * Stop the gatt client process when the device is disconnected then restart - * advertising. - */ - void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) - { - printf("Disconnected.\r\n"); - start_advertising(); - } - - /** - * Setup the advertising parameters. - */ - void setup_advertising() - { - Gap &gap = _ble_interface.gap(); - gap.setAdvertisingPayload(make_advertising_data()); - gap.setAdvertisingParams(make_advertising_params()); - } - - /** - * Start the advertising process; it ends when a device connects. - */ - void start_advertising() - { - ble_error_t error = _ble_interface.gap().startAdvertising(); - if (error) { - printf("Error %u during gap.startAdvertising.\r\n", error); - } else { - printf("Advertising started.\r\n"); - } - } - - /** - * Schedule processing of events from the BLE middleware in the event queue. - */ - void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event) - { - _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents)); - } - - /** - * Build data advertised by the BLE interface. - */ - static GapAdvertisingData make_advertising_data(void) - { - static const uint8_t device_name[] = "GattClient"; - 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) - ); - - return advertising_data; - } - - /** - * Build advertising parameters used by the BLE interface. - */ - static GapAdvertisingParams make_advertising_params(void) - { - return GapAdvertisingParams( - /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, - /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500), - /* timeout */ 0 - ); - } - - events::EventQueue &_event_queue; - BLE &_ble_interface; - mbed::Callback _post_init_cb; -}; - - -#endif /* GATT_EXAMPLE_BLE_PROCESS_H_ */ diff --git a/deprecated/BLE_GattClient/README.md b/deprecated/BLE_GattClient/README.md deleted file mode 100644 index a6fbe00e..00000000 --- a/deprecated/BLE_GattClient/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# BLE Gatt Client example - -This application demonstrates detailed uses of the GattClient APIs. - -When the application is started it advertises itself to its environment with the -device name `GattClient`. Once you have connected to the device with your mobile -phone, the application starts a discovery of the GATT server exposed by your -mobile phone. - -After the discovery, this application reads the value of the characteristics -discovered and subscribes to the characteristics emitting notifications or -indications. - -The device prints the value of any indication or notification received from the -mobile phone. - -# Running the application - -## Requirements - -You may use a generic BLE scanners: - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - - diff --git a/deprecated/BLE_GattClient/main.cpp b/deprecated/BLE_GattClient/main.cpp deleted file mode 100644 index 27bcdd93..00000000 --- a/deprecated/BLE_GattClient/main.cpp +++ /dev/null @@ -1,580 +0,0 @@ - -/* mbed Microcontroller Library - * Copyright (c) 2006-2017 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 -#include -#include - -#include "events/EventQueue.h" -#include "platform/NonCopyable.h" - -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GattClient.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/GattClient.h" -#include "ble/DiscoveredService.h" -#include "ble/DiscoveredCharacteristic.h" -#include "ble/CharacteristicDescriptorDiscovery.h" - -#include "BLEProcess.h" - -/** - * Handle discovery of the GATT server. - * - * First the GATT server is discovered in its entirety then each readable - * characteristic is read and the client register to characteristic - * notifications or indication when available. The client report server - * indications and notification until the connection end. - */ -class GattClientProcess : private mbed::NonCopyable { - - // Internal typedef to this class type. - // It is used as a shorthand to pass member function as callbacks. - typedef GattClientProcess Self; - - typedef CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t - DiscoveryCallbackParams_t; - - typedef CharacteristicDescriptorDiscovery::TerminationCallbackParams_t - TerminationCallbackParams_t; - - typedef DiscoveredCharacteristic::Properties_t Properties_t; - -public: - - /** - * Construct an empty client process. - * - * The function start() shall be called to initiate the discovery process. - */ - GattClientProcess() : - _client(NULL), - _connection_handle(), - _characteristics(NULL), - _it(NULL), - _descriptor_handle(0), - _ble_interface(NULL), - _event_queue(NULL) { - } - - ~GattClientProcess() - { - stop(); - } - - void init(BLE &ble_interface, events::EventQueue &event_queue) - { - _ble_interface = &ble_interface; - _event_queue = &event_queue; - _client = &_ble_interface->gattClient(); - - _ble_interface->gap().onConnection(as_cb(&Self::on_connection)); - _ble_interface->gap().onDisconnection(as_cb(&Self::on_disconnection)); - } - - /** - * Event handler invoked when a connection is established. - * - * This function setup the connection handle to operate on then start the - * discovery process. - */ - void on_connection(const Gap::ConnectionCallbackParams_t* connection_event) - { - _connection_handle = connection_event->handle; - _event_queue->call(mbed::callback(this, &Self::start)); - } - - /** - * Start the discovery process. - * - * @param[in] client The GattClient instance which will discover the distant - * GATT server. - * @param[in] connection_handle Reference of the connection to the GATT - * server which will be discovered. - */ - void start() - { - // setup the event handlers called during the process - _client->onDataWritten().add(as_cb(&Self::when_descriptor_written)); - _client->onHVX().add(as_cb(&Self::when_characteristic_changed)); - - // The discovery process will invoke when_service_discovered when a - // service is discovered, when_characteristic_discovered when a - // characteristic is discovered and when_service_discovery_ends once the - // discovery process has ended. - _client->onServiceDiscoveryTermination(as_cb(&Self::when_service_discovery_ends)); - ble_error_t error = _client->launchServiceDiscovery( - _connection_handle, - as_cb(&Self::when_service_discovered), - as_cb(&Self::when_characteristic_discovered) - ); - - if (error) { - printf("Error %u returned by _client->launchServiceDiscovery.\r\n", error); - return; - } - - printf("Client process started: initiate service discovery.\r\n"); - } - - /** - * Stop the discovery process and clean the instance. - */ - void on_disconnection(const Gap::DisconnectionCallbackParams_t* disconnection_event) - { - if (!_client || disconnection_event->handle != _connection_handle) { - return; - } - stop(); - } - - /** - * Stop the discovery process and clean the instance. - */ - void stop() - { - if (!_client) { - return; - } - - // unregister event handlers - _client->onDataWritten().detach(as_cb(&Self::when_descriptor_written)); - _client->onHVX().detach(as_cb(&Self::when_characteristic_changed)); - _client->onServiceDiscoveryTermination(NULL); - - // remove discovered characteristics - clear_characteristics(); - - // clean up the instance - _connection_handle = 0; - _characteristics = NULL; - _it = NULL; - _descriptor_handle = 0; - - printf("Client process stopped.\r\n"); - } - -private: -//////////////////////////////////////////////////////////////////////////////// -// Service and characteristic discovery process. - - /** - * Handle services discovered. - * - * The GattClient invokes this function when a service has been discovered. - * - * @see GattClient::launchServiceDiscovery - */ - void when_service_discovered(const DiscoveredService *discovered_service) - { - // print information of the service discovered - printf("Service discovered: value = "); - print_uuid(discovered_service->getUUID()); - printf(", start = %u, end = %u.\r\n", - discovered_service->getStartHandle(), - discovered_service->getEndHandle() - ); - } - - /** - * Handle characteristics discovered. - * - * The GattClient invoke this function when a characteristic has been - * discovered. - * - * @see GattClient::launchServiceDiscovery - */ - void when_characteristic_discovered(const DiscoveredCharacteristic *discovered_characteristic) - { - // print characteristics properties - printf("\tCharacteristic discovered: uuid = "); - print_uuid(discovered_characteristic->getUUID()); - printf(", properties = "); - print_properties(discovered_characteristic->getProperties()); - printf( - ", decl handle = %u, value handle = %u, last handle = %u.\r\n", - discovered_characteristic->getDeclHandle(), - discovered_characteristic->getValueHandle(), - discovered_characteristic->getLastHandle() - ); - - // add the characteristic into the list of discovered characteristics - bool success = add_characteristic(discovered_characteristic); - if (!success) { - printf("Error: memory allocation failure while adding the discovered characteristic.\r\n"); - _client->terminateServiceDiscovery(); - stop(); - return; - } - } - - /** - * Handle termination of the service and characteristic discovery process. - * - * The GattClient invokes this function when the service and characteristic - * discovery process ends. - * - * @see GattClient::onServiceDiscoveryTermination - */ - void when_service_discovery_ends(Gap::Handle_t connection_handle) - { - if (!_characteristics) { - printf("No characteristics discovered, end of the process.\r\n"); - return; - } - - printf("All services and characteristics discovered, process them.\r\n"); - - // reset iterator and start processing characteristics in order - _it = NULL; - _event_queue->call(mbed::callback(this, &Self::process_next_characteristic)); - } - -//////////////////////////////////////////////////////////////////////////////// -// Processing of characteristics based on their properties. - - /** - * Process the characteristics discovered. - * - * - If the characteristic is readable then read its value and print it. Then - * - If the characteristic can emit notification or indication then discover - * the characteristic CCCD and subscribe to the server initiated event. - * - Otherwise skip the characteristic processing. - */ - void process_next_characteristic(void) - { - if (!_it) { - _it = _characteristics; - } else { - _it = _it->next; - } - - while (_it) { - Properties_t properties = _it->value.getProperties(); - - if (properties.read()) { - read_characteristic(_it->value); - return; - } else if(properties.notify() || properties.indicate()) { - discover_descriptors(_it->value); - return; - } else { - printf( - "Skip processing of characteristic %u\r\n", - _it->value.getValueHandle() - ); - _it = _it->next; - } - } - - printf("All characteristics discovered have been processed.\r\n"); - } - - /** - * Initate the read of the characteristic in input. - * - * The completion of the operation will happens in when_characteristic_read() - */ - void read_characteristic(const DiscoveredCharacteristic &characteristic) - { - printf("Initiating read at %u.\r\n", characteristic.getValueHandle()); - ble_error_t error = characteristic.read( - 0, as_cb(&Self::when_characteristic_read) - ); - - if (error) { - printf( - "Error: cannot initiate read at %u due to %u\r\n", - characteristic.getValueHandle(), error - ); - stop(); - } - } - - /** - * Handle the reception of a read response. - * - * If the characteristic can emit notification or indication then start the - * discovery of the the characteristic descriptors then subscribe to the - * server initiated event by writing the CCCD discovered. Otherwise start - * the processing of the next characteristic discovered in the server. - */ - void when_characteristic_read(const GattReadCallbackParams *read_event) - { - printf("\tCharacteristic value at %u equal to: ", read_event->handle); - for (size_t i = 0; i < read_event->len; ++i) { - printf("0x%02X ", read_event->data[i]); - } - printf(".\r\n"); - - Properties_t properties = _it->value.getProperties(); - - if(properties.notify() || properties.indicate()) { - discover_descriptors(_it->value); - } else { - process_next_characteristic(); - } - } - - /** - * Initiate the discovery of the descriptors of the characteristic in input. - * - * When a descriptor is discovered, the function when_descriptor_discovered - * is invoked. - */ - void discover_descriptors(const DiscoveredCharacteristic &characteristic) - { - printf("Initiating descriptor discovery of %u.\r\n", characteristic.getValueHandle()); - - _descriptor_handle = 0; - ble_error_t error = characteristic.discoverDescriptors( - as_cb(&Self::when_descriptor_discovered), - as_cb(&Self::when_descriptor_discovery_ends) - ); - - if (error) { - printf( - "Error: cannot initiate discovery of %04X due to %u.\r\n", - characteristic.getValueHandle(), error - ); - stop(); - } - } - - /** - * Handle the discovery of the characteristic descriptors. - * - * If the descriptor found is a CCCD then stop the discovery. Once the - * process has ended subscribe to server initiated events by writing the - * value of the CCCD. - */ - void when_descriptor_discovered(const DiscoveryCallbackParams_t* event) - { - printf("\tDescriptor discovered at %u, UUID: ", event->descriptor.getAttributeHandle()); - print_uuid(event->descriptor.getUUID()); - printf(".\r\n"); - - if (event->descriptor.getUUID() == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) { - _descriptor_handle = event->descriptor.getAttributeHandle(); - _client->terminateCharacteristicDescriptorDiscovery( - event->characteristic - ); - } - } - - /** - * If a CCCD has been found subscribe to server initiated events by writing - * its value. - */ - void when_descriptor_discovery_ends(const TerminationCallbackParams_t *event) { - // shall never happen but happen with android devices ... - // process the next charateristic - if (!_descriptor_handle) { - printf("\tWarning: characteristic with notify or indicate attribute without CCCD.\r\n"); - process_next_characteristic(); - return; - } - - Properties_t properties = _it->value.getProperties(); - - uint16_t cccd_value = - (properties.notify() << 0) | (properties.indicate() << 1); - - ble_error_t error = _client->write( - GattClient::GATT_OP_WRITE_REQ, - _connection_handle, - _descriptor_handle, - sizeof(cccd_value), - reinterpret_cast(&cccd_value) - ); - - if (error) { - printf( - "Error: cannot initiate write of CCCD %u due to %u.\r\n", - _descriptor_handle, error - ); - stop(); - } - } - - /** - * Called when the CCCD has been written. - */ - void when_descriptor_written(const GattWriteCallbackParams* event) - { - // should never happen - if (!_descriptor_handle) { - printf("\tError: received write response to unsolicited request.\r\n"); - stop(); - return; - } - - printf("\tCCCD at %u written.\r\n", _descriptor_handle); - _descriptor_handle = 0; - process_next_characteristic(); - } - - /** - * Print the updated value of the characteristic. - * - * This function is called when the server emits a notification or an - * indication of a characteristic value the client has subscribed to. - * - * @see GattClient::onHVX() - */ - void when_characteristic_changed(const GattHVXCallbackParams* event) - { - printf("Change on attribute %u: new value = ", event->handle); - for (size_t i = 0; i < event->len; ++i) { - printf("0x%02X ", event->data[i]); - } - printf(".\r\n"); - } - - struct DiscoveredCharacteristicNode { - DiscoveredCharacteristicNode(const DiscoveredCharacteristic &c) : - value(c), next(NULL) { } - - DiscoveredCharacteristic value; - DiscoveredCharacteristicNode *next; - }; - - /** - * Add a discovered characteristic into the list of discovered characteristics. - */ - bool add_characteristic(const DiscoveredCharacteristic *characteristic) - { - DiscoveredCharacteristicNode* new_node = - new(std::nothrow) DiscoveredCharacteristicNode(*characteristic); - - if (new_node == false) { - printf("Error while allocating a new characteristic.\r\n"); - return false; - } - - if (_characteristics == NULL) { - _characteristics = new_node; - } else { - DiscoveredCharacteristicNode* c = _characteristics; - while(c->next) { - c = c->next; - } - c->next = new_node; - } - - return true; - } - - /** - * Clear the list of discovered characteristics. - */ - void clear_characteristics(void) - { - DiscoveredCharacteristicNode *c= _characteristics; - - while (c) { - DiscoveredCharacteristicNode *n = c->next; - delete c; - c = n; - } - } - - /** - * Helper to construct an event handler from a member function of this - * instance. - */ - template - FunctionPointerWithContext as_cb( - void (Self::*member)(ContextType context) - ) { - return makeFunctionPointer(this, member); - } - - /** - * Print the value of a UUID. - */ - static void print_uuid(const UUID &uuid) - { - const uint8_t *uuid_value = uuid.getBaseUUID(); - - // UUIDs are in little endian, print them in big endian - for (size_t i = 0; i < uuid.getLen(); ++i) { - printf("%02X", uuid_value[(uuid.getLen() - 1) - i]); - } - } - - /** - * Print the value of a characteristic properties. - */ - static void print_properties(const Properties_t &properties) - { - const struct { - bool (Properties_t::*fn)() const; - const char* str; - } prop_to_str[] = { - { &Properties_t::broadcast, "broadcast" }, - { &Properties_t::read, "read" }, - { &Properties_t::writeWoResp, "writeWoResp" }, - { &Properties_t::write, "write" }, - { &Properties_t::notify, "notify" }, - { &Properties_t::indicate, "indicate" }, - { &Properties_t::authSignedWrite, "authSignedWrite" } - }; - - printf("["); - for (size_t i = 0; i < (sizeof(prop_to_str) / sizeof(prop_to_str[0])); ++i) { - if ((properties.*(prop_to_str[i].fn))()) { - printf(" %s", prop_to_str[i].str); - } - } - printf(" ]"); - } - - GattClient *_client; - Gap::Handle_t _connection_handle; - DiscoveredCharacteristicNode *_characteristics; - DiscoveredCharacteristicNode *_it; - GattAttribute::Handle_t _descriptor_handle; - BLE *_ble_interface; - events::EventQueue *_event_queue; -}; - - -int main() { - - BLE &ble_interface = BLE::Instance(); - events::EventQueue event_queue; - BLEProcess ble_process(event_queue, ble_interface); - GattClientProcess gatt_client_process; - - // Register GattClientProcess::init in the ble_process; this function will - // be called once the ble_interface is initialized. - ble_process.on_init( - mbed::callback(&gatt_client_process, &GattClientProcess::init) - ); - - // bind the event queue to the ble interface, initialize the interface - // and start advertising - ble_process.start(); - - // Process the event queue. - event_queue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_GattClient/mbed-os.lib b/deprecated/BLE_GattClient/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_GattClient/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_GattClient/mbed_app.json b/deprecated/BLE_GattClient/mbed_app.json deleted file mode 100644 index d9083bba..00000000 --- a/deprecated/BLE_GattClient/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} \ No newline at end of file diff --git a/deprecated/BLE_GattClient/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_GattClient/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_GattClient/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_GattServer/.mbed b/deprecated/BLE_GattServer/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_GattServer/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_GattServer/BLEProcess.h b/deprecated/BLE_GattServer/BLEProcess.h deleted file mode 100644 index 30ba7d02..00000000 --- a/deprecated/BLE_GattServer/BLEProcess.h +++ /dev/null @@ -1,206 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2017 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 GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ -#define GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ - -#include -#include - -#include "events/EventQueue.h" -#include "platform/Callback.h" -#include "platform/NonCopyable.h" - -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/GapAdvertisingParams.h" -#include "ble/GapAdvertisingData.h" -#include "ble/FunctionPointerWithContext.h" - -/** - * Handle initialization adn shutdown of the BLE Instance. - * - * Setup advertising payload and manage advertising state. - * Delegate to GattClientProcess once the connection is established. - */ -class BLEProcess : private mbed::NonCopyable { -public: - /** - * Construct a BLEProcess from an event queue and a ble interface. - * - * Call start() to initiate ble processing. - */ - BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) : - _event_queue(event_queue), - _ble_interface(ble_interface), - _post_init_cb() { - } - - ~BLEProcess() - { - stop(); - } - - /** - * Subscription to the ble interface initialization event. - * - * @param[in] cb The callback object that will be called when the ble - * interface is initialized. - */ - void on_init(mbed::Callback cb) - { - _post_init_cb = cb; - } - - /** - * Initialize the ble interface, configure it and start advertising. - */ - bool start() - { - printf("Ble process started.\r\n"); - - if (_ble_interface.hasInitialized()) { - printf("Error: the ble instance has already been initialized.\r\n"); - return false; - } - - _ble_interface.onEventsToProcess( - makeFunctionPointer(this, &BLEProcess::schedule_ble_events) - ); - - ble_error_t error = _ble_interface.init( - this, &BLEProcess::when_init_complete - ); - - if (error) { - printf("Error: %u returned by BLE::init.\r\n", error); - return false; - } - - return true; - } - - /** - * Close existing connections and stop the process. - */ - void stop() - { - if (_ble_interface.hasInitialized()) { - _ble_interface.shutdown(); - printf("Ble process stopped."); - } - } - -private: - - /** - * Schedule processing of events from the BLE middleware in the event queue. - */ - void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event) - { - _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents)); - } - - /** - * Sets up adverting payload and start advertising. - * - * This function is invoked when the ble interface is initialized. - */ - void when_init_complete(BLE::InitializationCompleteCallbackContext *event) - { - if (event->error) { - printf("Error %u during the initialization\r\n", event->error); - return; - } - printf("Ble instance initialized\r\n"); - - Gap &gap = _ble_interface.gap(); - ble_error_t error = gap.setAdvertisingPayload(make_advertising_data()); - if (error) { - printf("Error %u during gap.setAdvertisingPayload\r\n", error); - return; - } - - gap.setAdvertisingParams(make_advertising_params()); - - gap.onConnection(this, &BLEProcess::when_connection); - gap.onDisconnection(this, &BLEProcess::when_disconnection); - - start_advertising(); - - if (_post_init_cb) { - _post_init_cb(_ble_interface, _event_queue); - } - } - - void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) - { - printf("Connected.\r\n"); - } - - void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) - { - printf("Disconnected.\r\n"); - start_advertising(); - } - - void start_advertising(void) - { - ble_error_t error = _ble_interface.gap().startAdvertising(); - if (error) { - printf("Error %u during gap.startAdvertising.\r\n", error); - return; - } else { - printf("Advertising started.\r\n"); - } - } - - static GapAdvertisingData make_advertising_data(void) - { - static const uint8_t device_name[] = "GattServer"; - 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) - ); - - return advertising_data; - } - - static GapAdvertisingParams make_advertising_params(void) - { - return GapAdvertisingParams( - /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, - /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500), - /* timeout */ 0 - ); - } - - events::EventQueue &_event_queue; - BLE &_ble_interface; - mbed::Callback _post_init_cb; -}; - -#endif /* GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ */ diff --git a/deprecated/BLE_GattServer/mbed-os.lib b/deprecated/BLE_GattServer/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_GattServer/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_GattServer/mbed_app.json b/deprecated/BLE_GattServer/mbed_app.json deleted file mode 100644 index d9083bba..00000000 --- a/deprecated/BLE_GattServer/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} \ No newline at end of file diff --git a/deprecated/BLE_GattServer/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_GattServer/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_GattServer/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_HeartRate/.mbed b/deprecated/BLE_HeartRate/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_HeartRate/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_HeartRate/img/connection.png b/deprecated/BLE_HeartRate/img/connection.png deleted file mode 100644 index 83c3570d..00000000 Binary files a/deprecated/BLE_HeartRate/img/connection.png and /dev/null differ diff --git a/deprecated/BLE_HeartRate/img/discovery.png b/deprecated/BLE_HeartRate/img/discovery.png deleted file mode 100644 index 50952435..00000000 Binary files a/deprecated/BLE_HeartRate/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_HeartRate/img/notifications.png b/deprecated/BLE_HeartRate/img/notifications.png deleted file mode 100644 index 5898de62..00000000 Binary files a/deprecated/BLE_HeartRate/img/notifications.png and /dev/null differ diff --git a/deprecated/BLE_HeartRate/img/register_to_notifications.png b/deprecated/BLE_HeartRate/img/register_to_notifications.png deleted file mode 100644 index 12a3af8e..00000000 Binary files a/deprecated/BLE_HeartRate/img/register_to_notifications.png and /dev/null differ diff --git a/deprecated/BLE_HeartRate/img/scan_result.png b/deprecated/BLE_HeartRate/img/scan_result.png deleted file mode 100644 index ec9e47d9..00000000 Binary files a/deprecated/BLE_HeartRate/img/scan_result.png and /dev/null differ diff --git a/deprecated/BLE_HeartRate/img/start_scan.png b/deprecated/BLE_HeartRate/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_HeartRate/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_HeartRate/mbed-os.lib b/deprecated/BLE_HeartRate/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_HeartRate/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_HeartRate/mbed_app.json b/deprecated/BLE_HeartRate/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_HeartRate/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_HeartRate/module.json b/deprecated/BLE_HeartRate/module.json deleted file mode 100644 index 5b6dd868..00000000 --- a/deprecated/BLE_HeartRate/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-heartrate", - "version": "0.0.1", - "description": "BLE Heartreate example, building with yotta", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/deprecated/BLE_HeartRate/readme.md b/deprecated/BLE_HeartRate/readme.md deleted file mode 100644 index 715a413a..00000000 --- a/deprecated/BLE_HeartRate/readme.md +++ /dev/null @@ -1,64 +0,0 @@ -# BLE Heart Rate Monitor - -This application transmits a heart rate value using the [Bluetooth SIG Heart Rate Profile](https://developer.bluetooth.org/TechnologyOverview/Pages/HRP.aspx). The heart rate value is provided by the application itself, not by a sensor, so that you don't have to get a sensor just to run the example. - -Technical details are better presented [in the mbed Classic equivalent of this example](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_HeartRate/). - -# Running the application - -## Requirements - -To see the heart rate information on your phone, use a BLE scanner: - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named `HRM`. - - ![](img/scan_result.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *Heart Rate* service has the UUID `0x180D` and includes the *Heart Rate Measurement* characteristic which has the UUID `0x2A37`. - - ![](img/discovery.png) - - **figure 4** Representation of the Heart Rate service using Master Control Panel 4.0.5 - -1. Register for the notifications sent by the *Heart Rate Measurement* characteristic. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. You should see the heart rate value change every half second. It begins at 100, goes up to 175 (in steps of 1), resets to 100 and so on. - - ![](img/notifications.png) - - **figure 6** Notifications view using Master Control Panel 4.0.5 diff --git a/deprecated/BLE_HeartRate/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_HeartRate/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_HeartRate/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_HeartRate/source/main.cpp b/deprecated/BLE_HeartRate/source/main.cpp deleted file mode 100644 index 1aa11154..00000000 --- a/deprecated/BLE_HeartRate/source/main.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 -#include -#include "ble/BLE.h" -#include "ble/Gap.h" -#include "ble/services/HeartRateService.h" - -DigitalOut led1(LED1, 1); - -const static char DEVICE_NAME[] = "HRM"; -static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; - -static uint8_t hrmCounter = 100; // init HRM to 100bps -static HeartRateService *hrServicePtr; - -static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) -{ - BLE::Instance().gap().startAdvertising(); // restart advertising -} - -void updateSensorValue() { - // Do blocking calls or whatever is necessary for sensor polling. - // In our case, we simply update the HRM measurement. - hrmCounter++; - - // 100 <= HRM bps <=175 - if (hrmCounter == 175) { - hrmCounter = 100; - } - - hrServicePtr->updateHeartRate(hrmCounter); -} - -void periodicCallback(void) -{ - led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ - - if (BLE::Instance().getGapState().connected) { - eventQueue.call(updateSensorValue); - } -} - -void onBleInitError(BLE &ble, ble_error_t error) -{ - (void)ble; - (void)error; - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - onBleInitError(ble, error); - return; - } - - if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onDisconnection(disconnectionCallback); - - /* Setup primary service. */ - hrServicePtr = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER); - - /* 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::GENERIC_HEART_RATE_SENSOR); - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); - ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.gap().setAdvertisingInterval(1000); /* 1000ms */ - ble.gap().startAdvertising(); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - eventQueue.call_every(500, periodicCallback); - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_LED/.mbed b/deprecated/BLE_LED/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_LED/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_LED/img/LED_OFF.png b/deprecated/BLE_LED/img/LED_OFF.png deleted file mode 100644 index 92598671..00000000 Binary files a/deprecated/BLE_LED/img/LED_OFF.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/LED_ON.png b/deprecated/BLE_LED/img/LED_ON.png deleted file mode 100644 index 1d71afc5..00000000 Binary files a/deprecated/BLE_LED/img/LED_ON.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/connection.png b/deprecated/BLE_LED/img/connection.png deleted file mode 100644 index 4b4e5379..00000000 Binary files a/deprecated/BLE_LED/img/connection.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/discovery.png b/deprecated/BLE_LED/img/discovery.png deleted file mode 100644 index 129dc714..00000000 Binary files a/deprecated/BLE_LED/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/scan_results.png b/deprecated/BLE_LED/img/scan_results.png deleted file mode 100644 index 972f43a8..00000000 Binary files a/deprecated/BLE_LED/img/scan_results.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/start_scan.png b/deprecated/BLE_LED/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_LED/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/write_characteristic.png b/deprecated/BLE_LED/img/write_characteristic.png deleted file mode 100644 index 853a9ae6..00000000 Binary files a/deprecated/BLE_LED/img/write_characteristic.png and /dev/null differ diff --git a/deprecated/BLE_LED/img/write_pannel.png b/deprecated/BLE_LED/img/write_pannel.png deleted file mode 100644 index c738ce01..00000000 Binary files a/deprecated/BLE_LED/img/write_pannel.png and /dev/null differ diff --git a/deprecated/BLE_LED/mbed-os.lib b/deprecated/BLE_LED/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_LED/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_LED/mbed_app.json b/deprecated/BLE_LED/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_LED/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_LED/module.json b/deprecated/BLE_LED/module.json deleted file mode 100644 index bfff0062..00000000 --- a/deprecated/BLE_LED/module.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ble-led", - "version": "0.0.1", - "description": "A simple service that demonstrates the use of a read-write characteristic to control a LED", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "targetDependencies": {}, - "bin": "./source" -} diff --git a/deprecated/BLE_LED/readme.md b/deprecated/BLE_LED/readme.md deleted file mode 100644 index 8984462b..00000000 --- a/deprecated/BLE_LED/readme.md +++ /dev/null @@ -1,93 +0,0 @@ -To help you create your own BLE services, we have created this service template. -The LED example demonstrates the use of a read-write characteristic to control a -LED through a phone app. - -The template covers: - -* Setting up advertising and connection states. -* Assigning UUIDs to the service and its characteristic. -* Creating an input characteristic: read-write, boolean. This characteristic offers control of the LED. -* Constructing a service class and adding it to the BLE stack. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install: - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -*NOTE:* If you have more than a single mbed board (e.g. nrf51dk or mkit) you can -run the BLE_LED and BLE_LEDBlinker at the same time. For more information please -refer to the BLE_LEDBlinker demo. - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - - -1. Build the application and install it on your board as explained in the building instructions. -1. Open the BLE scanner on your phone. - -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named `LED`. - - ![](img/scan_results.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - -1. Discover the services and the characteristics on the device. The *LED service* has the UUID `0xA000` and includes the *LED state characteristic* which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value. - - ![](img/discovery.png) - - **figure 4** Representation of the Led service using Master Control Panel 4.0.5 - -1. Open the write pannel of the *LED state* characteristic. - - ![](img/write_characteristic.png) - - **figure 5** How to read and write a characteristic value using Master Control Panel 4.0.5 - - -1. The characteristic accept a 1 byte value: - - ![](img/write_pannel.png) - - **figure 6** Write characteristic panel using Master Control Panel 4.0.5 - - * `0x00`: LED ON/OFF (board dependant) - - ![](img/LED_ON.png) - - **figure 6** Write characteristic panel to set the LED on using Master Control Panel 4.0.5 - - - * `0x01`: LED OFF/ON (board dependant) - - ![](img/LED_OFF.png) - - **figure 6** Write characteristic panel to set the LED off using Master Control Panel 4.0.5 - - -1. Toggle the LED characteristic value and see the LED turn ON or turn OFF according to the value you set. - -If you can see the characteristic, and the LED is turned on/off as you toggle its value, the application is working properly. diff --git a/deprecated/BLE_LED/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_LED/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_LED/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_LED/source/LEDService.h b/deprecated/BLE_LED/source/LEDService.h deleted file mode 100644 index 1223a779..00000000 --- a/deprecated/BLE_LED/source/LEDService.h +++ /dev/null @@ -1,43 +0,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. - */ - -#ifndef __BLE_LED_SERVICE_H__ -#define __BLE_LED_SERVICE_H__ - -class LEDService { -public: - const static uint16_t LED_SERVICE_UUID = 0xA000; - const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001; - - LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) : - ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic) - { - GattCharacteristic *charTable[] = {&ledState}; - GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - ble.addService(ledService); - } - - GattAttribute::Handle_t getValueHandle() const - { - return ledState.getValueHandle(); - } - -private: - BLEDevice &ble; - ReadWriteGattCharacteristic ledState; -}; - -#endif /* #ifndef __BLE_LED_SERVICE_H__ */ diff --git a/deprecated/BLE_LED/source/main.cpp b/deprecated/BLE_LED/source/main.cpp deleted file mode 100644 index 6c6f2574..00000000 --- a/deprecated/BLE_LED/source/main.cpp +++ /dev/null @@ -1,128 +0,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 -#include -#include "ble/BLE.h" -#include "LEDService.h" - -DigitalOut alivenessLED(LED1, 0); -DigitalOut actuatedLED(LED2, 0); - -const static char DEVICE_NAME[] = "LED"; -static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; - -static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE); - -LEDService *ledServicePtr; - -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) -{ - (void) params; - BLE::Instance().gap().startAdvertising(); -} - -void blinkCallback(void) -{ - alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */ -} - -/** - * This callback allows the LEDService to receive updates to the ledState Characteristic. - * - * @param[in] params - * Information about the characterisitc being updated. - */ -void onDataWrittenCallback(const GattWriteCallbackParams *params) { - if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) { - actuatedLED = *(params->data); - } -} - -/** - * This function is called when the ble initialization process has failled - */ -void onBleInitError(BLE &ble, ble_error_t error) -{ - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -/** - * Callback triggered when the ble initialization process has finished - */ -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - /* In case of error, forward the error handling to onBleInitError */ - onBleInitError(ble, error); - return; - } - - /* Ensure that it is the default instance of BLE */ - if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onDisconnection(disconnectionCallback); - ble.gattServer().onDataWritten(onDataWrittenCallback); - - bool initialValueForLEDCharacteristic = false; - ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic); - - /* 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().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ - ble.gap().startAdvertising(); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - eventQueue.call_every(500, blinkCallback); - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_LEDBlinker/.mbed b/deprecated/BLE_LEDBlinker/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_LEDBlinker/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_LEDBlinker/mbed-os.lib b/deprecated/BLE_LEDBlinker/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_LEDBlinker/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_LEDBlinker/mbed_app.json b/deprecated/BLE_LEDBlinker/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_LEDBlinker/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_LEDBlinker/module.json b/deprecated/BLE_LEDBlinker/module.json deleted file mode 100644 index aecbe4c1..00000000 --- a/deprecated/BLE_LEDBlinker/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-ledblinker", - "version": "0.0.1", - "description": "An initial demo showcasing the GattClient APIs. Drives an LED service exported by a BLE_LED peripheral. Shows scanning, connections, service-discovery, and reads/writes.", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "bin": "./source" -} diff --git a/deprecated/BLE_LEDBlinker/readme.md b/deprecated/BLE_LEDBlinker/readme.md deleted file mode 100644 index 1539d2dc..00000000 --- a/deprecated/BLE_LEDBlinker/readme.md +++ /dev/null @@ -1,54 +0,0 @@ -# BLE LED Blinker - -This example demonstrates using the ``GattClient`` API to control BLE client devices. - -The example uses two applications running on two different devices: - -1. The first device - the central - runs the application ``BLE_LEDBlinker`` from this repository. This application sends an on/off toggle over BLE. - -1. The second device - the peripheral - runs the application [``BLE_LED``](https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_LED) to respond to the toggle. - - The toggle simply turns the LED on the peripheral device on and off. - -# Running the application - -## Requirements - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -This example requires *two* devices. - -## Building instructions - -You will need to build both applications and flash each one to a different board. - -Please note: The application ``BLE_LEDBlinker`` in this repository initiate a connection to all ble devices which advertise "LED" as complete local name. By default, the application `BLE_LED` advertise "LED" as complete local name. If you change the local name advertised by the application `BLE_LED` you should reflect your change in this application by changing the value of the constant `PEER_NAME` in `main.cpp`. - -**Tip:** You may notice that the application also checks the LED characteristic's UUID; you don't need to change this parameter's value, because it already matches the UUID provided by the second application, ``BLE_LED``. - -Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -1. Build both applications and install one on each device, as explained in the building instructions. - -1. The LED number two of the device running ``BLE_LED`` should blink. - - -## Monitoring the application through a serial port - -You can run ``BLE_LEDBlinker`` and see that it works properly by monitoring its serial output. - -You need a terminal program to listen to the output through a serial port. You can download one, for example: - -* Tera Term for Windows. -* CoolTerm for Mac OS X. -* GNU Screen for Linux. - -To see the application's output: - -1. Check which serial port your device is connected to. -1. Run a terminal program with the correct serial port and set the baud rate to 9600. For example, to use GNU Screen, run: ``screen /dev/tty.usbmodem1412 9600``. -1. The application should start printing the toggle's value to the terminal. - -**Note:** ``BLE_LEDBlinker`` will not run properly if the ``BLE_LED`` application is not running on a second device. The terminal will show a few print statements, but you will not be able to see the application in full operation. diff --git a/deprecated/BLE_LEDBlinker/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_LEDBlinker/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_LEDBlinker/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_LEDBlinker/source/main.cpp b/deprecated/BLE_LEDBlinker/source/main.cpp deleted file mode 100644 index 94ad8d57..00000000 --- a/deprecated/BLE_LEDBlinker/source/main.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 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 -#include -#include "ble/BLE.h" -#include "ble/DiscoveredCharacteristic.h" -#include "ble/DiscoveredService.h" - -DigitalOut alivenessLED(LED1, 1); -static DiscoveredCharacteristic ledCharacteristic; -static bool triggerLedCharacteristic; -static const char PEER_NAME[] = "LED"; - -static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -void periodicCallback(void) { - alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */ -} - -void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { - // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME - // 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 - for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { - - const uint8_t record_length = params->advertisingData[i]; - if (record_length == 0) { - continue; - } - const uint8_t type = params->advertisingData[i + 1]; - const uint8_t* value = params->advertisingData + i + 2; - const uint8_t value_length = record_length - 1; - - if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { - if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) { - printf( - "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", - params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], - params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type - ); - BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); - break; - } - } - i += record_length; - } -} - -void serviceDiscoveryCallback(const DiscoveredService *service) { - if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { - printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); - } else { - printf("S UUID-"); - const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); - for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { - printf("%02x", longUUIDBytes[i]); - } - printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); - } -} - -void updateLedCharacteristic(void) { - if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) { - ledCharacteristic.read(); - } -} - -void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { - printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); - if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ - ledCharacteristic = *characteristicP; - triggerLedCharacteristic = true; - } -} - -void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { - printf("terminated SD for handle %u\r\n", connectionHandle); - if (triggerLedCharacteristic) { - triggerLedCharacteristic = false; - eventQueue.call(updateLedCharacteristic); - } -} - -void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { - if (params->role == Gap::CENTRAL) { - BLE &ble = BLE::Instance(); - ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); - ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001); - } -} - -void triggerToggledWrite(const GattReadCallbackParams *response) { - if (response->handle == ledCharacteristic.getValueHandle()) { - printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); - for (unsigned index = 0; index < response->len; index++) { - printf("%c[%02x]", response->data[index], response->data[index]); - } - printf("\r\n"); - - uint8_t toggledValue = response->data[0] ^ 0x1; - ledCharacteristic.write(1, &toggledValue); - } -} - -void triggerRead(const GattWriteCallbackParams *response) { - if (response->handle == ledCharacteristic.getValueHandle()) { - ledCharacteristic.read(); - } -} - -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) { - printf("disconnected\r\n"); - /* Start scanning and try to connect again */ - BLE::Instance().gap().startScan(advertisementCallback); -} - -void onBleInitError(BLE &ble, ble_error_t error) -{ - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - /* In case of error, forward the error handling to onBleInitError */ - onBleInitError(ble, error); - return; - } - - /* Ensure that it is the default instance of BLE */ - if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onDisconnection(disconnectionCallback); - ble.gap().onConnection(connectionCallback); - - ble.gattClient().onDataRead(triggerToggledWrite); - ble.gattClient().onDataWrite(triggerRead); - - // scan interval: 400ms and scan window: 400ms. - // Every 400ms the device will scan for 400ms - // This means that the device will scan continuously. - ble.gap().setScanParams(400, 400); - ble.gap().startScan(advertisementCallback); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - triggerLedCharacteristic = false; - eventQueue.call_every(500, periodicCallback); - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/deprecated/BLE_Privacy/.mbed b/deprecated/BLE_Privacy/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_Privacy/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_Privacy/README.md b/deprecated/BLE_Privacy/README.md deleted file mode 100644 index d41ce7d7..00000000 --- a/deprecated/BLE_Privacy/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Privacy - example usage of the privacy feature - -Demonstration of privacy features in Gap. It shows how to use private addresses when advertising and connecting and how filtering ties in with these operations. - -The application will start by repeatedly trying to connect to the same application running on another board. It will do this by advertising and scanning for random intervals waiting until the difference in intervals between the boards will make them meet when one is advertising and the other scanning. - -Two devices will be operating using random resolvable addresses. The application will connect to the peer and pair. It will attempt bonding and if possible create a whitelist based on the bond. - -Subsequent connections will turn on filtering if the whitelist has been successfully created. - -# Running the application - -## Requirements - -Application requires two devices. Each one should be loaded with the same example. The application will alternate between scanning and advertising until the two devices find each other and the demonstration proceeds. - -Information about activity is printed over the serial connection - please have two clients open, each connected to a device. You may use: - -- [Tera Term](https://ttssh2.osdn.jp/index.html.en) - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -Note: example currently doesn't use ST provided stack and instead uses a Cordio port for the ST. diff --git a/deprecated/BLE_Privacy/mbed-os.lib b/deprecated/BLE_Privacy/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_Privacy/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_Privacy/mbed_app.json b/deprecated/BLE_Privacy/mbed_app.json deleted file mode 100644 index 3d7e84e2..00000000 --- a/deprecated/BLE_Privacy/mbed_app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "target_overrides": { - - } -} diff --git a/deprecated/BLE_Privacy/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_Privacy/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_Privacy/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_Privacy/source/main.cpp b/deprecated/BLE_Privacy/source/main.cpp deleted file mode 100644 index 2e9fdf5a..00000000 --- a/deprecated/BLE_Privacy/source/main.cpp +++ /dev/null @@ -1,498 +0,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 -#include -#include "ble/BLE.h" -#include "SecurityManager.h" -#include - -/** This example demonstrates privacy features in Gap. It shows how to use - * private addresses when advertising and connecting and how filtering ties - * in with these operations. - * - * The application will start by repeatedly trying to connect to the same - * application running on another board. It will do this by advertising and - * scanning for random intervals waiting until the difference in intervals - * between the boards will make them meet when one is advertising and the - * other scanning. - * - * Two devices will be operating using random resolvable addresses. The - * applications will connect to the peer and pair. It will attempt bonding - * to store the IRK that resolve the peer. Subsequent connections will - * turn on filtering based on stored IRKs. - */ - -static const uint8_t DEVICE_NAME[] = "Privacy"; - -/** print device address to the terminal */ -void print_address(const Gap::Address_t &addr) -{ - printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n", - addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); -} - -/** 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 PrivacyDevice : private mbed::NonCopyable, - public SecurityManager::EventHandler -{ -public: - PrivacyDevice(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _handle(0), - _bonded(false), - _led1(LED1, 0) { }; - - virtual ~PrivacyDevice() { - _ble.onEventsToProcess(NULL); - }; - - /** Start BLE interface initialisation */ - void run() - { - /* to show we're running we'll blink every 500ms */ - _event_queue.call_every(500, this, &PrivacyDevice::blink); - - /* this will inform us off all events so we can schedule their handling - * using our event queue */ - _ble.onEventsToProcess( - makeFunctionPointer(this, &PrivacyDevice::schedule_ble_events) - ); - - if (_ble.hasInitialized()) { - /* ble instance already initialised, skip init and start activity */ - start(); - } else { - ble_error_t error = _ble.init(this, &PrivacyDevice::on_init_complete); - - if (error) { - printf("Error returned by BLE::init.\r\n"); - return; - } - } - - /* this will not return until shutdown */ - _event_queue.dispatch_forever(); - }; - - /** Override to start chosen activity when initialisation completes */ - virtual void start() = 0; - - /** Override to start chosen activity after initial bonding */ - virtual void start_after_bonding() = 0; - - /* event handler functions */ - - /** Inform the application of pairing */ - virtual void pairingResult( - ble::connection_handle_t connectionHandle, - SecurityManager::SecurityCompletionStatus_t result - ) { - if (result == SecurityManager::SEC_STATUS_SUCCESS) { - printf("Pairing successful\r\n"); - _bonded = true; - } else { - printf("Pairing failed\r\n"); - } - - /* disconnect in 2s */ - _event_queue.call_in( - 2000, &_ble.gap(), - &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION - ); - } - - /* callbacks */ - - /** 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"); - _event_queue.break_dispatch(); - return; - } - - /* for use by tools we print out own address and also use it - * to seed RNG as the address is unique */ - print_local_address(); - - /* 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, &PrivacyDevice::on_connect); - _ble.gap().onDisconnection(this, &PrivacyDevice::on_disconnect); - _ble.gap().onTimeout(makeFunctionPointer(this, &PrivacyDevice::on_timeout)); - - /* Privacy requires the security manager */ - - error = _ble.securityManager().init( - /* enableBonding */ true, - /* requireMITM */ false, - /* iocaps */ SecurityManager::IO_CAPS_NONE, - /* passkey */ NULL, - /* signing */ false, - /* dbFilepath */ NULL - ); - - if (error) { - printf("Error during security manager initialisation\r\n"); - _event_queue.break_dispatch(); - 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); - - /* privacy */ - - error = _ble.gap().enablePrivacy(true); - - if (error) { - printf("Error enabling privacy.\r\n"); - _event_queue.break_dispatch(); - return; - } - - start(); - }; - - /** This is called by Gap to notify the application we connected */ - void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) - { - printf("Connected to peer: "); - print_address(connection_event->peerAddr); - printf("Peer random resolvable address: "); - print_address(connection_event->peerResolvableAddr); - - _handle = connection_event->handle; - - if (_bonded) { - /* disconnect in 2s */ - _event_queue.call_in( - 2000, &_ble.gap(), - &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION - ); - } - }; - - /** This is called by Gap to notify the application we disconnected */ - void on_disconnect(const Gap::DisconnectionCallbackParams_t *event) - { - if (_bonded) { - /* we have connected to and bonded with the other device, from now - * on we will use the second start function and stay in the same role - * as peripheral or central */ - printf("Disconnected.\r\n"); - _event_queue.call_in(2000, this, &PrivacyDevice::start_after_bonding); - } else { - printf("Failed to bond.\r\n"); - _event_queue.break_dispatch(); - } - }; - - /** When scanning on advertising time runs out this is called */ - void on_timeout(const Gap::TimeoutSource_t source) - { - /* if we failed to find the other device, abort so that we change roles */ - printf("Haven't seen other device, switch modes.\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; - }; - - void print_local_address() - { - /* show what address we are using now */ - Gap::AddressType_t addr_type; - Gap::Address_t addr; - _ble.gap().getAddress(&addr_type, addr); - printf("Device address: "); - print_address(addr); - - if (!_seeded) { - _seeded = true; - /* use the address as a seed */ - uint8_t* random_data = addr; - srand(*((unsigned int*)random_data)); - } - } - -public: - static bool _seeded; - -protected: - BLE &_ble; - events::EventQueue &_event_queue; - ble::connection_handle_t _handle; - bool _bonded; - -private: - DigitalOut _led1; -}; - -/** A peripheral device will advertise and accept the connections */ -class PrivacyPeripheral : public PrivacyDevice { -public: - PrivacyPeripheral(BLE &ble, events::EventQueue &event_queue) - : PrivacyDevice(ble, event_queue) { } - - /** Set up and start advertising accepting anyone */ - virtual void start() - { - if (!set_advertising_data()) { - return; - } - - Gap::PeripheralPrivacyConfiguration_t privacy_configuration = { - /* use_non_resolvable_random_address */ false, - Gap::PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE - }; - - _ble.gap().setPeripheralPrivacyConfiguration(&privacy_configuration); - - start_advertising(); - }; - - /** advertise and filter based on known devices */ - virtual void start_after_bonding() - { - Gap::PeripheralPrivacyConfiguration_t privacy_configuration = { - /* use_non_resolvable_random_address */ false, - Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS - }; - - _ble.gap().setPeripheralPrivacyConfiguration(&privacy_configuration); - - start_advertising(); - } - - /* helper functions */ - -private: - bool set_advertising_data() - { - GapAdvertisingData advertising_data; - - /* add device name */ - advertising_data.addData( - GapAdvertisingData::COMPLETE_LOCAL_NAME, - DEVICE_NAME, - sizeof(DEVICE_NAME) - ); - - ble_error_t error = _ble.gap().setAdvertisingPayload(advertising_data); - - if (error) { - printf("Error during Gap::setAdvertisingPayload\r\n"); - _event_queue.break_dispatch(); - return false; - } - - return true; - } - - bool start_advertising() - { - _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - _ble.gap().setAdvertisingInterval(20); - - if (_bonded) { - /* if we bonded it means we have found the other device, from now on - * wait at each step until completion */ - _ble.gap().setAdvertisingTimeout(0); - } else { - /* since we have two boards which might start running this example at the same time - * we randomise the interval of advertising to have them meet when one is advertising - * and the other one is scanning (we use their random address as source of randomness) */ - const uint16_t random_interval = 1 + rand() % 5; - _ble.gap().setAdvertisingTimeout(random_interval); - } - - ble_error_t error = _ble.gap().startAdvertising(); - - if (error) { - printf("Error during Gap::startAdvertising.\r\n"); - _event_queue.break_dispatch(); - return false; - } - - printf("Advertising...\r\n"); - - return true; - } - -}; - -/** A central device will scan and connect to a peer. */ -class PrivacyCentral : public PrivacyDevice { -public: - PrivacyCentral(BLE &ble, events::EventQueue &event_queue) - : PrivacyDevice(ble, event_queue), - _is_connecting(false) { } - - /** start scanning and attach a callback that will handle advertisements - * and scan requests responses */ - virtual void start() - { - Gap::CentralPrivacyConfiguration_t privacy_configuration = { - /* use_non_resolvable_random_address */ false, - Gap::CentralPrivacyConfiguration_t::DO_NOT_RESOLVE - }; - - _ble.gap().setCentralPrivacyConfiguration(&privacy_configuration); - - start_scanning(); - } - - virtual void start_after_bonding() - { - Gap::CentralPrivacyConfiguration_t privacy_configuration = { - /* use_non_resolvable_random_address */ false, - Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FILTER - }; - - _ble.gap().setCentralPrivacyConfiguration(&privacy_configuration); - - start_scanning(); - } - - /* callbacks */ - - /** 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 + 2) < 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 max_record_length = params->advertisingDataLen - i; - const uint8_t record_length = std::min(params->advertisingData[i], - max_record_length); - const uint8_t type = params->advertisingData[i + 1]; - const uint8_t *value = params->advertisingData + i + 2; - - if (record_length < 2) { - /* malformed record */ - } else if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { - /* connect based on the name of the device */ - if (memcmp((const char*)DEVICE_NAME, (const char*)value, record_length - 1) == 0) { - _ble.gap().stopScan(); - - 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; - } - - /* 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; - } - }; - - /* helper functions */ -private: - bool start_scanning() { - if (_bonded) { - /* if we bonded it means we have found the other device, from now on - * wait at each step until completion */ - _ble.gap().setScanParams(4, 4, 0 /*timeout*/); - } else { - /* otherwise only scan for a limited time before changing roles again - * if we fail to find the other device */ - _ble.gap().setScanParams(4, 4, 4/*timeout*/); - } - - _is_connecting = false; - - ble_error_t error = _ble.gap().startScan(this, &PrivacyCentral::on_scan); - - if (error) { - printf("Error during Gap::startScan %d\r\n", error); - _event_queue.break_dispatch(); - return false; - } - - printf("Scanning...\r\n"); - - return true; - } - -private: - bool _is_connecting; -}; - -/* only seed the random number generation once per application run */ -bool PrivacyDevice::_seeded = false; - -int main() -{ - BLE& ble = BLE::Instance(); - - while(1) { - { - events::EventQueue queue; - printf("\r\n * Device is a peripheral *\r\n\r\n"); - PrivacyPeripheral peripheral(ble, queue); - peripheral.run(); - } - { - events::EventQueue queue; - printf("\r\n * Device is a central *\r\n\r\n"); - PrivacyCentral central(ble, queue); - central.run(); - } - } - - return 0; -} diff --git a/deprecated/BLE_SM/.mbed b/deprecated/BLE_SM/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_SM/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_SM/README.md b/deprecated/BLE_SM/README.md deleted file mode 100644 index f082d213..00000000 --- a/deprecated/BLE_SM/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# SM - example usage of the Security Manager to pair and encrypt - -Demonstration of possible usage of the Security Manager. Security Manager deals with pairing, authentication and encryption. - -The application demonstrates usage as a central and a peripheral. The central will connect to any connectable device present. Please have one ready and advertising. Application will attempt pairing. Please authorise your peer device to pair. - -Upon success it will disconnect and start advertising to demonstrate usage as a peripheral. Please scan and connect using your peer device. Upon connection grant pairing if prompted. Upon success the application will disconnect. Observe the terminal to keep track of the sequence. - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Information about activity is printed over the serial connection - please have a client open. You may use: - -- [Tera Term](https://ttssh2.osdn.jp/index.html.en) - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -Note: this example currently is currently not supported on ST BLUENRG targets. diff --git a/deprecated/BLE_SM/mbed-os.lib b/deprecated/BLE_SM/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_SM/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_SM/mbed_app.json b/deprecated/BLE_SM/mbed_app.json deleted file mode 100644 index c0c0def4..00000000 --- a/deprecated/BLE_SM/mbed_app.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "config": { - "filesystem_support": { - "help": "Whether filesystem is supported on the target", - "value": 1 - } - }, - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"], - "filesystem_support": 0 - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_SM/module.json b/deprecated/BLE_SM/module.json deleted file mode 100644 index ce0e2de6..00000000 --- a/deprecated/BLE_SM/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-securitymanager", - "version": "0.0.1", - "description": "BLE Security Manager usage example", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "bin": "./source" -} diff --git a/deprecated/BLE_SM/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_SM/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_SM/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_SM/source/main.cpp b/deprecated/BLE_SM/source/main.cpp deleted file mode 100644 index 61f9ec6d..00000000 --- a/deprecated/BLE_SM/source/main.cpp +++ /dev/null @@ -1,512 +0,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 -#include -#include "ble/BLE.h" -#include "SecurityManager.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 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, - 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"); - } - } - - /** 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, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION - ); - } - -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); - - /* 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("Diconnected\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; - } - - 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 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. */ -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); - - 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 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 */ - 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); - - 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 - -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; -} diff --git a/deprecated/BLE_Thermometer/.mbed b/deprecated/BLE_Thermometer/.mbed deleted file mode 100644 index ceaf11b8..00000000 --- a/deprecated/BLE_Thermometer/.mbed +++ /dev/null @@ -1 +0,0 @@ -ROOT=. \ No newline at end of file diff --git a/deprecated/BLE_Thermometer/img/connection.png b/deprecated/BLE_Thermometer/img/connection.png deleted file mode 100644 index 0f51e450..00000000 Binary files a/deprecated/BLE_Thermometer/img/connection.png and /dev/null differ diff --git a/deprecated/BLE_Thermometer/img/discovery.png b/deprecated/BLE_Thermometer/img/discovery.png deleted file mode 100644 index 03abd2f2..00000000 Binary files a/deprecated/BLE_Thermometer/img/discovery.png and /dev/null differ diff --git a/deprecated/BLE_Thermometer/img/notifications.png b/deprecated/BLE_Thermometer/img/notifications.png deleted file mode 100644 index 6a8455bd..00000000 Binary files a/deprecated/BLE_Thermometer/img/notifications.png and /dev/null differ diff --git a/deprecated/BLE_Thermometer/img/register_to_notifications.png b/deprecated/BLE_Thermometer/img/register_to_notifications.png deleted file mode 100644 index 3191e7c2..00000000 Binary files a/deprecated/BLE_Thermometer/img/register_to_notifications.png and /dev/null differ diff --git a/deprecated/BLE_Thermometer/img/scan_results.png b/deprecated/BLE_Thermometer/img/scan_results.png deleted file mode 100644 index 0f495f82..00000000 Binary files a/deprecated/BLE_Thermometer/img/scan_results.png and /dev/null differ diff --git a/deprecated/BLE_Thermometer/img/start_scan.png b/deprecated/BLE_Thermometer/img/start_scan.png deleted file mode 100644 index aa1a6fba..00000000 Binary files a/deprecated/BLE_Thermometer/img/start_scan.png and /dev/null differ diff --git a/deprecated/BLE_Thermometer/mbed-os.lib b/deprecated/BLE_Thermometer/mbed-os.lib deleted file mode 100644 index 69fff22f..00000000 --- a/deprecated/BLE_Thermometer/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 diff --git a/deprecated/BLE_Thermometer/mbed_app.json b/deprecated/BLE_Thermometer/mbed_app.json deleted file mode 100644 index 4309a7c2..00000000 --- a/deprecated/BLE_Thermometer/mbed_app.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "target_overrides": { - "K64F": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "NUCLEO_F401RE": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - }, - "DISCO_L475VG_IOT01A": { - "target.features_add": ["BLE"], - "target.extra_labels_add": ["CORDIO", "CORDIO_BLUENRG"] - } - } -} diff --git a/deprecated/BLE_Thermometer/module.json b/deprecated/BLE_Thermometer/module.json deleted file mode 100644 index 7a8cb037..00000000 --- a/deprecated/BLE_Thermometer/module.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ble-thermometer", - "version": "0.0.1", - "description": "This example demonstrates how to use the Health Thermometer Service. The Health Thermometer service reports two pieces of information, Temperature and Sensor Location.", - "licenses": [ - { - "url": "https://spdx.org/licenses/Apache-2.0", - "type": "Apache-2.0" - } - ], - "dependencies": { - "ble": "^2.0.0" - }, - "bin": "./source" -} diff --git a/deprecated/BLE_Thermometer/readme.md b/deprecated/BLE_Thermometer/readme.md deleted file mode 100644 index 0373faf4..00000000 --- a/deprecated/BLE_Thermometer/readme.md +++ /dev/null @@ -1,80 +0,0 @@ -# Thermometer - -This example uses the [Health Thermometer Profile](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml) to send thermometer information: - -1. Sensor location: thermometer placement on the body. The default value in this application is the ear (``LOCATION_EAR``). The [characteristic description](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml) shows the other possible values. - -1. Temperature: the initial temperature is 39.6, and it's incremented by 0.1 every half second. It resets to 39.6 when it reaches 43.0. - -For more information see: - -* [Health Thermometer Service](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml): GATT profile details. - -* [Temperature Measurement](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml): GATT characteristic details for temperature measurement. - -* [Temperature Type](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml): GATT characteristic details for temperature type (sensor location). - -# Running the application - -## Requirements - -The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : - -- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. - -- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. - -Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Building instructions - -Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). - -## Checking for success - -**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. - -1. Build the application and install it on your board as explained in the building instructions. - -1. Open the BLE scanner on your phone. - -1. Start a scan. - - ![](img/start_scan.png) - - **figure 1** How to start scan using nRF Master Control Panel 4.0.5 - -1. Find your device; it should be named *Therm*. - - ![](img/scan_results.png) - - **figure 2** Scan results using nRF Master Control Panel 4.0.5 - -1. Establish a connection with your device. - - ![](img/connection.png) - - **figure 3** How to establish a connection using Master Control Panel 4.0.5 - - -1. Discover the services and the characteristics on the device. The *Health Thermometer* service has the UUID `0x1809` and includes the *Temperature Measurement* characteristic which has the UUID `0x2A1C`. - - ![](img/discovery.png) - - **figure 4** Representation of the Thermometer service using Master Control Panel 4.0.5 - - -1. Register for the notifications sent by the *Temperature Measurement* characteristic. - - ![](img/register_to_notifications.png) - - **figure 5** How to register to notifications using Master Control Panel 4.0.5 - - -1. You should see the temperature value change every half second. It begins at 39.6, goes up to 43.0 (in steps of 0.1), resets to 39.6 and so on. - - ![](img/notifications.png) - - **figure 6** Notifications view using Master Control Panel 4.0.5 - - diff --git a/deprecated/BLE_Thermometer/shields/TARGET_CORDIO_BLUENRG.lib b/deprecated/BLE_Thermometer/shields/TARGET_CORDIO_BLUENRG.lib deleted file mode 100644 index a73dc227..00000000 --- a/deprecated/BLE_Thermometer/shields/TARGET_CORDIO_BLUENRG.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/cordio-ble-x-nucleo-idb0xa1/#5e49580a0303c48c11f78ad2e5d92b5ffc02aadc \ No newline at end of file diff --git a/deprecated/BLE_Thermometer/source/main.cpp b/deprecated/BLE_Thermometer/source/main.cpp deleted file mode 100644 index c499c238..00000000 --- a/deprecated/BLE_Thermometer/source/main.cpp +++ /dev/null @@ -1,119 +0,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 -#include "mbed.h" -#include "ble/BLE.h" -#include "ble/services/HealthThermometerService.h" - -DigitalOut led1(LED1, 1); - -const static char DEVICE_NAME[] = "Therm"; -static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE}; - -static float currentTemperature = 39.6; -static HealthThermometerService *thermometerServicePtr; - -static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -/* Restart Advertising on disconnection*/ -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) -{ - BLE::Instance().gap().startAdvertising(); -} - -void updateSensorValue(void) { - /* Do blocking calls or whatever is necessary for sensor polling. - In our case, we simply update the Temperature measurement. */ - currentTemperature = (currentTemperature + 0.1 > 43.0) ? 39.6 : currentTemperature + 0.1; - thermometerServicePtr->updateTemperature(currentTemperature); -} - -void periodicCallback(void) -{ - led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ - - if (BLE::Instance().gap().getState().connected) { - eventQueue.call(updateSensorValue); - } -} - -void onBleInitError(BLE &ble, ble_error_t error) -{ - /* Initialization error handling should go here */ -} - -void printMacAddress() -{ - /* Print out device MAC address to the console*/ - Gap::AddressType_t addr_type; - Gap::Address_t address; - BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); - for (int i = 5; i >= 1; i--){ - printf("%02x:", address[i]); - } - printf("%02x\r\n", address[0]); -} - -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE& ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { - onBleInitError(ble, error); - return; - } - - if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { - return; - } - - ble.gap().onDisconnection(disconnectionCallback); - - /* Setup primary service. */ - thermometerServicePtr = new HealthThermometerService(ble, currentTemperature, HealthThermometerService::LOCATION_EAR); - - /* 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::THERMOMETER_EAR); - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); - ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.gap().setAdvertisingInterval(1000); /* 1000ms */ - ble.gap().startAdvertising(); - - printMacAddress(); -} - -void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { - BLE &ble = BLE::Instance(); - eventQueue.call(Callback(&ble, &BLE::processEvents)); -} - -int main() -{ - eventQueue.call_every(500, periodicCallback); - - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(scheduleBleEventsProcessing); - ble.init(bleInitComplete); - - eventQueue.dispatch_forever(); - - return 0; -} diff --git a/resources/official_armmbed_example_badge.png b/resources/official_armmbed_example_badge.png new file mode 100644 index 00000000..42ddce24 Binary files /dev/null and b/resources/official_armmbed_example_badge.png differ diff --git a/resources/test_configs/mbed_app_features_00.json b/resources/test_configs/mbed_app_features_00.json new file mode 100644 index 00000000..0c120174 --- /dev/null +++ b/resources/test_configs/mbed_app_features_00.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": true, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": true + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_01.json b/resources/test_configs/mbed_app_features_01.json new file mode 100644 index 00000000..3d024d74 --- /dev/null +++ b/resources/test_configs/mbed_app_features_01.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_02.json b/resources/test_configs/mbed_app_features_02.json new file mode 100644 index 00000000..383fe276 --- /dev/null +++ b/resources/test_configs/mbed_app_features_02.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": false, + "ble.ble-feature-phy-management": true, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": true + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_03.json b/resources/test_configs/mbed_app_features_03.json new file mode 100644 index 00000000..7b3ea7dd --- /dev/null +++ b/resources/test_configs/mbed_app_features_03.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": true, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": true + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_04.json b/resources/test_configs/mbed_app_features_04.json new file mode 100644 index 00000000..6ab6965d --- /dev/null +++ b/resources/test_configs/mbed_app_features_04.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": true, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": true + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_05.json b/resources/test_configs/mbed_app_features_05.json new file mode 100644 index 00000000..490e060d --- /dev/null +++ b/resources/test_configs/mbed_app_features_05.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": false, + "ble.ble-feature-secure-connections": false, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": false, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_06.json b/resources/test_configs/mbed_app_features_06.json new file mode 100644 index 00000000..0d2236d4 --- /dev/null +++ b/resources/test_configs/mbed_app_features_06.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": false, + "ble.ble-role-central": false, + "ble.ble-role-peripheral": false, + "ble.ble-feature-gatt-client": false, + "ble.ble-feature-gatt-server": false, + "ble.ble-feature-security": false, + "ble.ble-feature-secure-connections": false, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": false, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_07.json b/resources/test_configs/mbed_app_features_07.json new file mode 100644 index 00000000..9f41c793 --- /dev/null +++ b/resources/test_configs/mbed_app_features_07.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": false, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": false, + "ble.ble-role-peripheral": false, + "ble.ble-feature-gatt-client": false, + "ble.ble-feature-gatt-server": false, + "ble.ble-feature-security": false, + "ble.ble-feature-secure-connections": false, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": false, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_08.json b/resources/test_configs/mbed_app_features_08.json new file mode 100644 index 00000000..3d615d5d --- /dev/null +++ b/resources/test_configs/mbed_app_features_08.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": false, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": false, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": false, + "ble.ble-feature-gatt-server": false, + "ble.ble-feature-security": false, + "ble.ble-feature-secure-connections": false, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": false, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_09.json b/resources/test_configs/mbed_app_features_09.json new file mode 100644 index 00000000..98a85eba --- /dev/null +++ b/resources/test_configs/mbed_app_features_09.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": false, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": false, + "ble.ble-feature-gatt-client": false, + "ble.ble-feature-gatt-server": false, + "ble.ble-feature-security": false, + "ble.ble-feature-secure-connections": false, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": false, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_10.json b/resources/test_configs/mbed_app_features_10.json new file mode 100644 index 00000000..44eb9e3f --- /dev/null +++ b/resources/test_configs/mbed_app_features_10.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": false, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": true, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": true + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_11.json b/resources/test_configs/mbed_app_features_11.json new file mode 100644 index 00000000..fa7afc51 --- /dev/null +++ b/resources/test_configs/mbed_app_features_11.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": false, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": true, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": true + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_12.json b/resources/test_configs/mbed_app_features_12.json new file mode 100644 index 00000000..3f7f8564 --- /dev/null +++ b/resources/test_configs/mbed_app_features_12.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": true, + "ble.ble-feature-signing": true, + "ble.ble-feature-whitelist": true, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": true, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +} diff --git a/resources/test_configs/mbed_app_features_13.json b/resources/test_configs/mbed_app_features_13.json new file mode 100644 index 00000000..37affa5e --- /dev/null +++ b/resources/test_configs/mbed_app_features_13.json @@ -0,0 +1,37 @@ +{ + "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "ble.ble-role-observer": true, + "ble.ble-role-broadcaster": true, + "ble.ble-role-central": true, + "ble.ble-role-peripheral": true, + "ble.ble-feature-gatt-client": true, + "ble.ble-feature-gatt-server": true, + "ble.ble-feature-security": true, + "ble.ble-feature-secure-connections": false, + "ble.ble-feature-signing": false, + "ble.ble-feature-whitelist": false, + "ble.ble-feature-privacy": true, + "ble.ble-feature-phy-management": false, + "ble.ble-feature-extended-advertising": false, + "ble.ble-feature-periodic-advertising": false + }, + "K64F": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NUCLEO_F401RE": { + "target.components_add": ["BlueNRG_MS"], + "target.features_add": ["BLE"], + "target.extra_labels_add": ["CORDIO"] + }, + "NRF52840_DK": { + "target.features_add": ["BLE"] + }, + "NRF52_DK": { + "target.features_add": ["BLE"] + } + } +}