From 9d3e15704c7e060cf02be4cac3ff78ba52c49ef3 Mon Sep 17 00:00:00 2001 From: Roshan Bangar Date: Tue, 6 Sep 2022 18:49:28 +0530 Subject: [PATCH] Nimble: Add example for periodic adv/sync --- examples/bluetooth/.build-test-rules.yml | 12 + .../nimble/ble_periodic_adv/CMakeLists.txt | 7 + .../nimble/ble_periodic_adv/README.md | 75 ++++++ .../ble_periodic_adv/main/CMakeLists.txt | 4 + .../ble_periodic_adv/main/Kconfig.projbuild | 15 ++ .../nimble/ble_periodic_adv/main/main.c | 221 ++++++++++++++++++ .../nimble/ble_periodic_adv/main/patterns.h | 173 ++++++++++++++ .../ble_periodic_adv/main/periodic_adv.h | 25 ++ .../ble_periodic_adv/sdkconfig.defaults | 15 ++ .../nimble/ble_periodic_sync/CMakeLists.txt | 6 + .../nimble/ble_periodic_sync/README.md | 84 +++++++ .../ble_periodic_sync/main/CMakeLists.txt | 2 + .../ble_periodic_sync/main/Kconfig.projbuild | 8 + .../nimble/ble_periodic_sync/main/main.c | 204 ++++++++++++++++ .../ble_periodic_sync/main/periodic_sync.h | 26 +++ .../ble_periodic_sync/sdkconfig.defaults | 15 ++ 16 files changed, 892 insertions(+) create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/README.md create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/main/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/main/main.c create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/main/patterns.h create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/main/periodic_adv.h create mode 100644 examples/bluetooth/nimble/ble_periodic_adv/sdkconfig.defaults create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/README.md create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/main/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/main/main.c create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/main/periodic_sync.h create mode 100644 examples/bluetooth/nimble/ble_periodic_sync/sdkconfig.defaults diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index 4b19301766..7cb1e0ad57 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -99,6 +99,18 @@ examples/bluetooth/nimble/ble_l2cap_coc: temporary: true reason: the other targets are not tested yet +examples/bluetooth/nimble/ble_periodic_adv: + enable: + - if: IDF_TARGET in ["esp32c2", "esp32c3", "esp32s3"] + temporary: true + reason: the other targets are not tested yet + +examples/bluetooth/nimble/ble_periodic_sync: + enable: + - if: IDF_TARGET in ["esp32c2", "esp32c3", "esp32s3"] + temporary: true + reason: the other targets are not tested yet + examples/bluetooth/nimble/ble_phy: enable: - if: IDF_TARGET in ["esp32c2", "esp32c3", "esp32s3"] diff --git a/examples/bluetooth/nimble/ble_periodic_adv/CMakeLists.txt b/examples/bluetooth/nimble/ble_periodic_adv/CMakeLists.txt new file mode 100644 index 0000000000..a143c9dd24 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/CMakeLists.txt @@ -0,0 +1,7 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../common/nimble_peripheral_utils) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ble_periodic_adv) diff --git a/examples/bluetooth/nimble/ble_periodic_adv/README.md b/examples/bluetooth/nimble/ble_periodic_adv/README.md new file mode 100644 index 0000000000..58d6b24d7e --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/README.md @@ -0,0 +1,75 @@ +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# BLE Periodic Advertiser Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example starts periodic advertising with non resolvable private address. + +It uses Bluetooth controller and NimBLE stack based BLE host. + +This example aims at understanding periodic advertisement and related NimBLE APIs. + + +To test this demo, any BLE Periodic Sync app can be used. + + +Note : + +* Make sure to run `python -m pip install --user -r $IDF_PATH/requirements.txt -r $IDF_PATH/tools/ble/requirements.txt` to install the dependency packages needed. +* Currently this Python utility is only supported on Linux (BLE communication is via BLuez + DBus). + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Configure the project + +Open the project configuration menu: + +```bash +idf.py menuconfig +``` + +In the `Example Configuration` menu: + +* Select I/O capabilities of device from `Example Configuration --> I/O Capability`, default is `Just_works`. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +There is this console output when periodic_adv is started: + +``` +I (313) BTDM_INIT: BT controller compile version [2ee0168] +I (313) phy_init: phy_version 912,d001756,Jun 2 2022,16:28:07 +I (353) system_api: Base MAC address is not set +I (353) system_api: read default base MAC address from EFUSE +I (353) BTDM_INIT: Bluetooth MAC: 84:f7:03:08:14:8e + +I (363) NimBLE_BLE_PERIODIC_ADV: BLE Host Task Started +I (373) NimBLE: Device Address: +I (373) NimBLE: d0:42:3a:95:84:05 +I (373) NimBLE: + +I (383) NimBLE: instance 1 started (periodic) +``` + +## Note +* Periodic sync transfer is not implemented for now. + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/nimble/ble_periodic_adv/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_periodic_adv/main/CMakeLists.txt new file mode 100644 index 0000000000..023dd5e462 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(srcs "main.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild new file mode 100644 index 0000000000..3dca6ecbf7 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild @@ -0,0 +1,15 @@ +menu "Example Configuration" + + config EXAMPLE_EXTENDED_ADV + bool + default y if SOC_ESP_NIMBLE_CONTROLLER + prompt "Enable Extended Adv" + help + Use this option to enable extended advertising in the example + + config EXAMPLE_RANDOM_ADDR + bool + prompt "Advertise RANDOM Address" + help + Use this option to advertise a random address instead of public address +endmenu diff --git a/examples/bluetooth/nimble/ble_periodic_adv/main/main.c b/examples/bluetooth/nimble/ble_periodic_adv/main/main.c new file mode 100644 index 0000000000..3b2be3b720 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/main/main.c @@ -0,0 +1,221 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "periodic_adv.h" +#include "host/ble_gap.h" +#include "host/ble_hs_adv.h" +#include "patterns.h" + +#if CONFIG_EXAMPLE_EXTENDED_ADV +static uint8_t periodic_adv_raw_data[] = {'E', 'S', 'P', '_', 'P', 'E', 'R', 'I', 'O', 'D', 'I', 'C', '_', 'A', 'D', 'V'}; +static uint8_t id_addr_type; +#endif + +static const char *tag = "NimBLE_BLE_PERIODIC_ADV"; +#if CONFIG_EXAMPLE_RANDOM_ADDR +static uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM; +#else +static uint8_t own_addr_type; +#endif + +void ble_store_config_init(void); + +#if CONFIG_EXAMPLE_EXTENDED_ADV +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +start_periodic_adv(void) +{ + int rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + /* configure global address */ + rc = ble_hs_id_infer_auto(0, &id_addr_type); + assert(rc == 0); + + struct ble_gap_periodic_adv_params pparams; + struct ble_gap_ext_adv_params params; + struct ble_hs_adv_fields adv_fields; + struct os_mbuf *data; + uint8_t instance = 1; + ble_addr_t addr; + + /* For periodic we use instance with non-connectable advertising */ + memset (¶ms, 0, sizeof(params)); + + /* advertise using random addr */ + params.own_addr_type = BLE_OWN_ADDR_RANDOM; + params.primary_phy = BLE_HCI_LE_PHY_1M; + params.secondary_phy = BLE_HCI_LE_PHY_2M; + params.sid = 2; + + /* configure instance 1 */ + rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, NULL, NULL); + assert (rc == 0); + + /* set random (NRPA) address for instance */ + rc = ble_hs_id_gen_rnd(1, &addr); + assert (rc == 0); + + rc = ble_gap_ext_adv_set_addr(instance, &addr ); + assert (rc == 0); + + memset(&adv_fields, 0, sizeof(adv_fields)); + adv_fields.name = (const uint8_t *)"Periodic ADV"; + adv_fields.name_len = strlen((char *)adv_fields.name); + + /* Default to legacy PDUs size, mbuf chain will be increased if needed + */ + data = os_msys_get_pkthdr(BLE_HCI_MAX_ADV_DATA_LEN, 0); + assert(data); + + rc = ble_hs_adv_set_fields_mbuf(&adv_fields, data); + assert(rc == 0); + + rc = ble_gap_ext_adv_set_data(instance, data); + assert(rc == 0); + + /* configure periodic advertising */ + memset(&pparams, 0, sizeof(pparams)); + pparams.include_tx_power = 0; + pparams.itvl_min = 160; + pparams.itvl_max = 240; + + rc = ble_gap_periodic_adv_configure(instance, &pparams); + assert(rc == 0); + + /* get mbuf for periodic data */ + data = os_msys_get_pkthdr(sizeof(ext_adv_pattern_1), 0); + assert(data); + + /* fill mbuf with periodic data */ + + rc = os_mbuf_append(data, ext_adv_pattern_1, sizeof(ext_adv_pattern_1)); + assert(rc == 0); + + data = os_msys_get_pkthdr(sizeof(periodic_adv_raw_data), 0); + assert(data); + + rc = os_mbuf_append(data, periodic_adv_raw_data, sizeof(periodic_adv_raw_data)); + assert(rc == 0); + rc = ble_gap_periodic_adv_set_data(instance, data); + assert (rc == 0); + + /* start periodic advertising */ + rc = ble_gap_periodic_adv_start(instance); + assert (rc == 0); + + /* start advertising */ + rc = ble_gap_ext_adv_start(instance, 0, 0); + assert (rc == 0); + + MODLOG_DFLT(INFO, "instance %u started (periodic)\n", instance); +} +#endif +static void +periodic_adv_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +#if CONFIG_EXAMPLE_RANDOM_ADDR +static void +periodic_adv_set_addr(void) +{ + ble_addr_t addr; + int rc; + + /* generate new non-resolvable private address */ + rc = ble_hs_id_gen_rnd(0, &addr); + assert(rc == 0); + + /* set generated address */ + rc = ble_hs_id_set_rnd(addr.val); + + assert(rc == 0); +} +#endif + +static void +periodic_adv_on_sync(void) +{ + int rc; + +#if CONFIG_EXAMPLE_RANDOM_ADDR + /* Generate a non-resolvable private address. */ + periodic_adv_set_addr(); + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(1); +#else + rc = ble_hs_util_ensure_addr(0); +#endif + assert(rc == 0); + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Printing ADDR */ + uint8_t addr_val[6] = {0}; + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + + MODLOG_DFLT(INFO, "Device Address: "); + print_addr(addr_val); + MODLOG_DFLT(INFO, "\n"); + /* Begin advertising. */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + start_periodic_adv(); +#endif +} + +void periodic_adv_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +void +app_main(void) +{ + int rc; + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + nimble_port_init(); + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = periodic_adv_on_reset; + ble_hs_cfg.sync_cb = periodic_adv_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble_periodic_adv"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(periodic_adv_host_task); +} diff --git a/examples/bluetooth/nimble/ble_periodic_adv/main/patterns.h b/examples/bluetooth/nimble/ble_periodic_adv/main/patterns.h new file mode 100644 index 0000000000..94b85f72c6 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/main/patterns.h @@ -0,0 +1,173 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +static const uint8_t ext_adv_pattern_1[] = { + 0x00, 0x02, 0x00, 0x04, 0x00, 0x06, 0x00, 0x08, 0x00, 0x0a, + 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x12, 0x00, 0x14, + 0x00, 0x16, 0x00, 0x18, 0x00, 0x1a, 0x00, 0x1c, 0x00, 0x1e, + 0x00, 0x20, 0x00, 0x22, 0x00, 0x24, 0x00, 0x26, 0x00, 0x28, + 0x00, 0x2a, 0x00, 0x2c, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x32, + 0x00, 0x34, 0x00, 0x36, 0x00, 0x38, 0x00, 0x3a, 0x00, 0x3c, + 0x00, 0x3e, 0x00, 0x40, 0x00, 0x42, 0x00, 0x44, 0x00, 0x46, + 0x00, 0x48, 0x00, 0x4a, 0x00, 0x4c, 0x00, 0x4e, 0x00, 0x50, + 0x00, 0x52, 0x00, 0x54, 0x00, 0x56, 0x00, 0x58, 0x00, 0x5a, + 0x00, 0x5c, 0x00, 0x5e, 0x00, 0x60, 0x00, 0x62, 0x00, 0x64, + 0x00, 0x66, 0x00, 0x68, 0x00, 0x6a, 0x00, 0x6c, 0x00, 0x6e, + 0x00, 0x70, 0x00, 0x72, 0x00, 0x74, 0x00, 0x76, 0x00, 0x78, + 0x00, 0x7a, 0x00, 0x7c, 0x00, 0x7e, 0x00, 0x80, 0x00, 0x82, + 0x00, 0x84, 0x00, 0x86, 0x00, 0x88, 0x00, 0x8a, 0x00, 0x8c, + 0x00, 0x8e, 0x00, 0x90, 0x00, 0x92, 0x00, 0x94, 0x00, 0x96, + 0x00, 0x98, 0x00, 0x9a, 0x00, 0x9c, 0x00, 0x9e, 0x00, 0xa0, + 0x00, 0xa2, 0x00, 0xa4, 0x00, 0xa6, 0x00, 0xa8, 0x00, 0xaa, + 0x00, 0xac, 0x00, 0xae, 0x00, 0xb0, 0x00, 0xb2, 0x00, 0xb4, + 0x00, 0xb6, 0x00, 0xb8, 0x00, 0xba, 0x00, 0xbc, 0x00, 0xbe, + 0x00, 0xc0, 0x00, 0xc2, 0x00, 0xc4, 0x00, 0xc6, 0x00, 0xc8, + 0x00, 0xca, 0x00, 0xcc, 0x00, 0xce, 0x00, 0xd0, 0x00, 0xd2, + 0x00, 0xd4, 0x00, 0xd6, 0x00, 0xd8, 0x00, 0xda, 0x00, 0xdc, + 0x00, 0xde, 0x00, 0xe0, 0x00, 0xe2, 0x00, 0xe4, 0x00, 0xe6, + 0x00, 0xe8, 0x00, 0xea, 0x00, 0xec, 0x00, 0xee, 0x00, 0xf0, + 0x00, 0xf2, 0x00, 0xf4, 0x00, 0xf6, 0x00, 0xf8, 0x00, 0xfa, + 0x00, 0xfc, 0x00, 0xfe, 0x01, 0x01, 0x01, 0x03, 0x01, 0x05, + 0x01, 0x07, 0x01, 0x09, 0x01, 0x0b, 0x01, 0x0d, 0x01, 0x0f, + 0x01, 0x11, 0x01, 0x13, 0x01, 0x15, 0x01, 0x17, 0x01, 0x19, + 0x01, 0x1b, 0x01, 0x1d, 0x01, 0x1f, 0x01, 0x21, 0x01, 0x23, + 0x01, 0x25, 0x01, 0x27, 0x01, 0x29, 0x01, 0x2b, 0x01, 0x2d, + 0x01, 0x2f, 0x01, 0x31, 0x01, 0x33, 0x01, 0x35, 0x01, 0x37, + 0x01, 0x39, 0x01, 0x3b, 0x01, 0x3d, 0x01, 0x3f, 0x01, 0x41, + 0x01, 0x43, 0x01, 0x45, 0x01, 0x47, 0x01, 0x49, 0x01, 0x4b, + 0x01, 0x4d, 0x01, 0x4f, 0x01, 0x51, 0x01, 0x53, 0x01, 0x55, + 0x01, 0x57, 0x01, 0x59, 0x01, 0x5b, 0x01, 0x5d, 0x01, 0x5f, + 0x01, 0x61, 0x01, 0x63, 0x01, 0x65, 0x01, 0x67, 0x01, 0x69, + 0x01, 0x6b, 0x01, 0x6d, 0x01, 0x6f, 0x01, 0x71, 0x01, 0x73, + 0x01, 0x75, 0x01, 0x77, 0x01, 0x79, 0x01, 0x7b, 0x01, 0x7d, + 0x01, 0x7f, 0x01, 0x81, 0x01, 0x83, 0x01, 0x85, 0x01, 0x87, + 0x01, 0x89, 0x01, 0x8b, 0x01, 0x8d, 0x01, 0x8f, 0x01, 0x91, + 0x01, 0x93, 0x01, 0x95, 0x01, 0x97, 0x01, 0x99, 0x01, 0x9b, + 0x01, 0x9d, 0x01, 0x9f, 0x01, 0xa1, 0x01, 0xa3, 0x01, 0xa5, + 0x01, 0xa7, 0x01, 0xa9, 0x01, 0xab, 0x01, 0xad, 0x01, 0xaf, + 0x01, 0xb1, 0x01, 0xb3, 0x01, 0xb5, 0x01, 0xb7, 0x01, 0xb9, + 0x01, 0xbb, 0x01, 0xbd, 0x01, 0xbf, 0x01, 0xc1, 0x01, 0xc3, + 0x01, 0xc5, 0x01, 0xc7, 0x01, 0xc9, 0x01, 0xcb, 0x01, 0xcd, + 0x01, 0xcf, 0x01, 0xd1, 0x01, 0xd3, 0x01, 0xd5, 0x01, 0xd7, + 0x01, 0xd9, 0x01, 0xdb, 0x01, 0xdd, 0x01, 0xdf, 0x01, 0xe1, + 0x01, 0xe3, 0x01, 0xe5, 0x01, 0xe7, 0x01, 0xe9, 0x01, 0xeb, + 0x01, 0xed, 0x01, 0xef, 0x01, 0xf1, 0x01, 0xf3, 0x01, 0xf5, + 0x01, 0xf7, 0x01, 0xf9, 0x01, 0xfb, 0x01, 0xfd, 0x02, 0x00, + 0x02, 0x02, 0x02, 0x04, 0x02, 0x06, 0x02, 0x08, 0x02, 0x0a, + 0x02, 0x0c, 0x02, 0x0e, 0x02, 0x10, 0x02, 0x12, 0x02, 0x14, + 0x02, 0x16, 0x02, 0x18, 0x02, 0x1a, 0x02, 0x1c, 0x02, 0x1e, + 0x02, 0x20, 0x02, 0x22, 0x02, 0x24, 0x02, 0x26, 0x02, 0x28, + 0x02, 0x2a, 0x02, 0x2c, 0x02, 0x2e, 0x02, 0x30, 0x02, 0x32, + 0x02, 0x34, 0x02, 0x36, 0x02, 0x38, 0x02, 0x3a, 0x02, 0x3c, + 0x02, 0x3e, 0x02, 0x40, 0x02, 0x42, 0x02, 0x44, 0x02, 0x46, + 0x02, 0x48, 0x02, 0x4a, 0x02, 0x4c, 0x02, 0x4e, 0x02, 0x50, + 0x02, 0x52, 0x02, 0x54, 0x02, 0x56, 0x02, 0x58, 0x02, 0x5a, + 0x02, 0x5c, 0x02, 0x5e, 0x02, 0x60, 0x02, 0x62, 0x02, 0x64, + 0x02, 0x66, 0x02, 0x68, 0x02, 0x6a, 0x02, 0x6c, 0x02, 0x6e, + 0x02, 0x70, 0x02, 0x72, 0x02, 0x74, 0x02, 0x76, 0x02, 0x78, + 0x02, 0x7a, 0x02, 0x7c, 0x02, 0x7e, 0x02, 0x80, 0x02, 0x82, + 0x02, 0x84, 0x02, 0x86, 0x02, 0x88, 0x02, 0x8a, 0x02, 0x8c, + 0x02, 0x8e, 0x02, 0x90, 0x02, 0x92, 0x02, 0x94, 0x02, 0x96, + 0x02, 0x98, 0x02, 0x9a, 0x02, 0x9c, 0x02, 0x9e, 0x02, 0xa0, + 0x02, 0xa2, 0x02, 0xa4, 0x02, 0xa6, 0x02, 0xa8, 0x02, 0xaa, + 0x02, 0xac, 0x02, 0xae, 0x02, 0xb0, 0x02, 0xb2, 0x02, 0xb4, + 0x02, 0xb6, 0x02, 0xb8, 0x02, 0xba, 0x02, 0xbc, 0x02, 0xbe, + 0x02, 0xc0, 0x02, 0xc2, 0x02, 0xc4, 0x02, 0xc6, 0x02, 0xc8, + 0x02, 0xca, 0x02, 0xcc, 0x02, 0xce, 0x02, 0xd0, 0x02, 0xd2, + 0x02, 0xd4, 0x02, 0xd6, 0x02, 0xd8, 0x02, 0xda, 0x02, 0xdc, + 0x02, 0xde, 0x02, 0xe0, 0x02, 0xe2, 0x02, 0xe4, 0x02, 0xe6, + 0x02, 0xe8, 0x02, 0xea, 0x02, 0xec, 0x02, 0xee, 0x02, 0xf0, + 0x02, 0xf2, 0x02, 0xf4, 0x02, 0xf6, 0x02, 0xf8, 0x02, 0xfa, + 0x02, 0xfc, 0x02, 0xfe, 0x03, 0x01, 0x03, 0x03, 0x03, 0x05, + 0x03, 0x07, 0x03, 0x09, 0x03, 0x0b, 0x03, 0x0d, 0x03, 0x0f, + 0x03, 0x11, 0x03, 0x13, 0x03, 0x15, 0x03, 0x17, 0x03, 0x19, + 0x03, 0x1b, 0x03, 0x1d, 0x03, 0x1f, 0x03, 0x21, 0x03, 0x23, + 0x03, 0x25, 0x03, 0x27, 0x03, 0x29, 0x03, 0x2b, 0x03, 0x2d, + 0x03, 0x2f, 0x03, 0x31, 0x03, 0x33, 0x03, 0x35, 0x03, 0x37, + 0x03, 0x39, 0x03, 0x3b, 0x03, 0x3d, 0x03, 0x3f, 0x03, 0x41, + 0x03, 0x43, 0x03, 0x45, 0x03, 0x47, 0x03, 0x49, 0x03, 0x4b, + 0x03, 0x4d, 0x03, 0x4f, 0x03, 0x51, 0x03, 0x53, 0x03, 0x55, + 0x03, 0x57, 0x03, 0x59, 0x03, 0x5b, 0x03, 0x5d, 0x03, 0x5f, + 0x03, 0x61, 0x03, 0x63, 0x03, 0x65, 0x03, 0x67, 0x03, 0x69, + 0x03, 0x6b, 0x03, 0x6d, 0x03, 0x6f, 0x03, 0x71, 0x03, 0x73, + 0x03, 0x75, 0x03, 0x77, 0x03, 0x79, 0x03, 0x7b, 0x03, 0x7d, + 0x03, 0x7f, 0x03, 0x81, 0x03, 0x83, 0x03, 0x85, 0x03, 0x87, + 0x03, 0x89, 0x03, 0x8b, 0x03, 0x8d, 0x03, 0x8f, 0x03, 0x91, + 0x03, 0x93, 0x03, 0x95, 0x03, 0x97, 0x03, 0x99, 0x03, 0x9b, + 0x03, 0x9d, 0x03, 0x9f, 0x03, 0xa1, 0x03, 0xa3, 0x03, 0xa5, + 0x03, 0xa7, 0x03, 0xa9, 0x03, 0xab, 0x03, 0xad, 0x03, 0xaf, + 0x03, 0xb1, 0x03, 0xb3, 0x03, 0xb5, 0x03, 0xb7, 0x03, 0xb9, + 0x03, 0xbb, 0x03, 0xbd, 0x03, 0xbf, 0x03, 0xc1, 0x03, 0xc3, + 0x03, 0xc5, 0x03, 0xc7, 0x03, 0xc9, 0x03, 0xcb, 0x03, 0xcd, + 0x03, 0xcf, 0x03, 0xd1, 0x03, 0xd3, 0x03, 0xd5, 0x03, 0xd7, + 0x03, 0xd9, 0x03, 0xdb, 0x03, 0xdd, 0x03, 0xdf, 0x03, 0xe1, + 0x03, 0xe3, 0x03, 0xe5, 0x03, 0xe7, 0x03, 0xe9, 0x03, 0xeb, + 0x03, 0xed, 0x03, 0xef, 0x03, 0xf1, 0x03, 0xf3, 0x03, 0xf5, + 0x03, 0xf7, 0x03, 0xf9, 0x03, 0xfb, 0x03, 0xfd, 0x04, 0x00, + 0x04, 0x02, 0x04, 0x04, 0x04, 0x06, 0x04, 0x08, 0x04, 0x0a, + 0x04, 0x0c, 0x04, 0x0e, 0x04, 0x10, 0x04, 0x12, 0x04, 0x14, + 0x04, 0x16, 0x04, 0x18, 0x04, 0x1a, 0x04, 0x1c, 0x04, 0x1e, + 0x04, 0x20, 0x04, 0x22, 0x04, 0x24, 0x04, 0x26, 0x04, 0x28, + 0x04, 0x2a, 0x04, 0x2c, 0x04, 0x2e, 0x04, 0x30, 0x04, 0x32, + 0x04, 0x34, 0x04, 0x36, 0x04, 0x38, 0x04, 0x3a, 0x04, 0x3c, + 0x04, 0x3e, 0x04, 0x40, 0x04, 0x42, 0x04, 0x44, 0x04, 0x46, + 0x04, 0x48, 0x04, 0x4a, 0x04, 0x4c, 0x04, 0x4e, 0x04, 0x50, + 0x04, 0x52, 0x04, 0x54, 0x04, 0x56, 0x04, 0x58, 0x04, 0x5a, + 0x04, 0x5c, 0x04, 0x5e, 0x04, 0x60, 0x04, 0x62, 0x04, 0x64, + 0x04, 0x66, 0x04, 0x68, 0x04, 0x6a, 0x04, 0x6c, 0x04, 0x6e, + 0x04, 0x70, 0x04, 0x72, 0x04, 0x74, 0x04, 0x76, 0x04, 0x78, + 0x04, 0x7a, 0x04, 0x7c, 0x04, 0x7e, 0x04, 0x80, 0x04, 0x82, + 0x04, 0x84, 0x04, 0x86, 0x04, 0x88, 0x04, 0x8a, 0x04, 0x8c, + 0x04, 0x8e, 0x04, 0x90, 0x04, 0x92, 0x04, 0x94, 0x04, 0x96, + 0x04, 0x98, 0x04, 0x9a, 0x04, 0x9c, 0x04, 0x9e, 0x04, 0xa0, + 0x04, 0xa2, 0x04, 0xa4, 0x04, 0xa6, 0x04, 0xa8, 0x04, 0xaa, + 0x04, 0xac, 0x04, 0xae, 0x04, 0xb0, 0x04, 0xb2, 0x04, 0xb4, + 0x04, 0xb6, 0x04, 0xb8, 0x04, 0xba, 0x04, 0xbc, 0x04, 0xbe, + 0x04, 0xc0, 0x04, 0xc2, 0x04, 0xc4, 0x04, 0xc6, 0x04, 0xc8, + 0x04, 0xca, 0x04, 0xcc, 0x04, 0xce, 0x04, 0xd0, 0x04, 0xd2, + 0x04, 0xd4, 0x04, 0xd6, 0x04, 0xd8, 0x04, 0xda, 0x04, 0xdc, + 0x04, 0xde, 0x04, 0xe0, 0x04, 0xe2, 0x04, 0xe4, 0x04, 0xe6, + 0x04, 0xe8, 0x04, 0xea, 0x04, 0xec, 0x04, 0xee, 0x04, 0xf0, + 0x04, 0xf2, 0x04, 0xf4, 0x04, 0xf6, 0x04, 0xf8, 0x04, 0xfa, + 0x04, 0xfc, 0x04, 0xfe, 0x05, 0x01, 0x05, 0x03, 0x05, 0x05, + 0x05, 0x07, 0x05, 0x09, 0x05, 0x0b, 0x05, 0x0d, 0x05, 0x0f, + 0x05, 0x11, 0x05, 0x13, 0x05, 0x15, 0x05, 0x17, 0x05, 0x19, + 0x05, 0x1b, 0x05, 0x1d, 0x05, 0x1f, 0x05, 0x21, 0x05, 0x23, + 0x05, 0x25, 0x05, 0x27, 0x05, 0x29, 0x05, 0x2b, 0x05, 0x2d, + 0x05, 0x2f, 0x05, 0x31, 0x05, 0x33, 0x05, 0x35, 0x05, 0x37, + 0x05, 0x39, 0x05, 0x3b, 0x05, 0x3d, 0x05, 0x3f, 0x05, 0x41, + 0x05, 0x43, 0x05, 0x45, 0x05, 0x47, 0x05, 0x49, 0x05, 0x4b, + 0x05, 0x4d, 0x05, 0x4f, 0x05, 0x51, 0x05, 0x53, 0x05, 0x55, + 0x05, 0x57, 0x05, 0x59, 0x05, 0x5b, 0x05, 0x5d, 0x05, 0x5f, + 0x05, 0x61, 0x05, 0x63, 0x05, 0x65, 0x05, 0x67, 0x05, 0x69, + 0x05, 0x6b, 0x05, 0x6d, 0x05, 0x6f, 0x05, 0x71, 0x05, 0x73, + 0x05, 0x75, 0x05, 0x77, 0x05, 0x79, 0x05, 0x7b, 0x05, 0x7d, + 0x05, 0x7f, 0x05, 0x81, 0x05, 0x83, 0x05, 0x85, 0x05, 0x87, + 0x05, 0x89, 0x05, 0x8b, 0x05, 0x8d, 0x05, 0x8f, 0x05, 0x91, + 0x05, 0x93, 0x05, 0x95, 0x05, 0x97, 0x05, 0x99, 0x05, 0x9b, + 0x05, 0x9d, 0x05, 0x9f, 0x05, 0xa1, 0x05, 0xa3, 0x05, 0xa5, + 0x05, 0xa7, 0x05, 0xa9, 0x05, 0xab, 0x05, 0xad, 0x05, 0xaf, + 0x05, 0xb1, 0x05, 0xb3, 0x05, 0xb5, 0x05, 0xb7, 0x05, 0xb9, + 0x05, 0xbb, 0x05, 0xbd, 0x05, 0xbf, 0x05, 0xc1, 0x05, 0xc3, + 0x05, 0xc5, 0x05, 0xc7, 0x05, 0xc9, 0x05, 0xcb, 0x05, 0xcd, + 0x05, 0xcf, 0x05, 0xd1, 0x05, 0xd3, 0x05, 0xd5, 0x05, 0xd7, + 0x05, 0xd9, 0x05, 0xdb, 0x05, 0xdd, 0x05, 0xdf, 0x05, 0xe1, + 0x05, 0xe3, 0x05, 0xe5, 0x05, 0xe7, 0x05, 0xe9, 0x05, 0xeb, + 0x05, 0xed, 0x05, 0xef, 0x05, 0xf1, 0x05, 0xf3, 0x05, 0xf5, + 0x05, 0xf7, 0x05, 0xf9, 0x05, 0xfb, 0x05, 0xfd, 0x06, 0x00, + 0x06, 0x02, 0x06, 0x04, 0x06, 0x06, 0x06, 0x08, 0x06, 0x0a, + 0x06, 0x0c, 0x06, 0x0e, 0x06, 0x10, 0x06, 0x12, 0x06, 0x14, + 0x06, 0x16, 0x06, 0x18, 0x06, 0x1a, 0x06, 0x1c, 0x06, 0x1e, + 0x06, 0x20, 0x06, 0x22, 0x06, 0x24, 0x06, 0x26, 0x06, 0x28, + 0x06, 0x2a, 0x06, 0x2c, 0x06, 0x2e, 0x06, 0x30, 0x06, 0x32, + 0x06, 0x34, 0x06, 0x36, 0x06, 0x38, 0x06, 0x3a, 0x06, 0x3c, + 0x06, 0x3e, 0x06, 0x40, 0x06, 0x42, 0x06, 0x44, 0x06, 0x46, + 0x06, 0x48, 0x06, 0x4a, 0x06, 0x4c, 0x06, 0x4e, 0x06, 0x50, + 0x06, 0x52, 0x06, 0x54, 0x06, 0x56, 0x06, 0x58, 0x06, 0x5a, + 0x06, 0x5c, 0x06, 0x5e, 0x06, 0x60, 0x06, 0x62, 0x06, 0x64, + 0x06, 0x66, 0x06, 0x68, 0x06, 0x6a, 0x06, 0x6c, 0x06, 0x6e, + 0x06, 0x70, 0x06, 0x72, 0x06, 0x74, 0x06, 0x76, 0x06, 0x78 +}; diff --git a/examples/bluetooth/nimble/ble_periodic_adv/main/periodic_adv.h b/examples/bluetooth/nimble/ble_periodic_adv/main/periodic_adv.h new file mode 100644 index 0000000000..bb1bdad298 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/main/periodic_adv.h @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_BLE_PERIODIC_ADV_ +#define H_BLE_PERIODIC_ADV_ + +#include +#include "nimble/ble.h" +#include "modlog/modlog.h" +#include "esp_peripheral.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_periodic_adv/sdkconfig.defaults b/examples/bluetooth/nimble/ble_periodic_adv/sdkconfig.defaults new file mode 100644 index 0000000000..60f9e68480 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_adv/sdkconfig.defaults @@ -0,0 +1,15 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_EXAMPLE_EXTENDED_ADV=y +CONFIG_BT_NIMBLE_EXT_ADV=y +CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS=1 diff --git a/examples/bluetooth/nimble/ble_periodic_sync/CMakeLists.txt b/examples/bluetooth/nimble/ble_periodic_sync/CMakeLists.txt new file mode 100644 index 0000000000..12971ca736 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) +set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_LIST_DIR}/../common/nimble_central_utils) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ble_periodic_sync) diff --git a/examples/bluetooth/nimble/ble_periodic_sync/README.md b/examples/bluetooth/nimble/ble_periodic_sync/README.md new file mode 100644 index 0000000000..11923e7ef9 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/README.md @@ -0,0 +1,84 @@ +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# BLE Periodic Sync Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example performs passive scan for non-connectable non-scannable extended advertisement, it then establishes the periodic sync with the advertiser and then listens to the periodic advertisements. + + +It uses ESP32C3's Bluetooth controller and NimBLE stack based BLE host. + +This example aims at understanding BLE periodic sync establishment and periodic advertisement reports. + +To test this demo, use any periodic advertiser with uses extended adv data as "ESP_PERIODIC_ADV". + + +Note : + +* Make sure to run `python -m pip install --user -r $IDF_PATH/requirements.txt -r $IDF_PATH/tools/ble/requirements.txt` to install the dependency packages needed. +* Currently this Python utility is only supported on Linux (BLE communication is via BLuez + DBus). + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Configure the Project + +Open the project configuration menu: + +```bash +idf.py menuconfig +``` + +In the `Example Configuration` menu: + +* Change the `Peer Address` option if needed. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +This is the console output on successful periodic sync: + +``` +I (311) BTDM_INIT: BT controller compile version [3a49744] +I (311) phy_init: phy_version 912,d001756,Jun 2 2022,16:28:07 +I (351) system_api: Base MAC address is not set +I (351) system_api: read default base MAC address from EFUSE +I (351) BTDM_INIT: Bluetooth MAC: 84:f7:03:08:14:8e + +I (361) NimBLE_BLE_PERIODIC_SYNC: BLE Host Task Started +I (941) NimBLE: Periodic sync event : + +I (941) NimBLE: Periodic adv report event: + +I (4241) NimBLE: Periodic adv report event: + +I (7541) NimBLE: Periodic adv report event: + +I (10841) NimBLE: Periodic adv report event: +``` + + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/nimble/ble_periodic_sync/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_periodic_sync/main/CMakeLists.txt new file mode 100644 index 0000000000..cf2c455cb5 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild new file mode 100644 index 0000000000..86199b5d91 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/main/Kconfig.projbuild @@ -0,0 +1,8 @@ +menu "Example Configuration" + config EXAMPLE_EXTENDED_ADV + bool + default y if SOC_ESP_NIMBLE_CONTROLLER + prompt "Enable Extended Adv" + help + Use this option to enable extended advertising in the example +endmenu diff --git a/examples/bluetooth/nimble/ble_periodic_sync/main/main.c b/examples/bluetooth/nimble/ble_periodic_sync/main/main.c new file mode 100644 index 0000000000..8d7cb55531 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/main/main.c @@ -0,0 +1,204 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "periodic_sync.h" +#include "host/ble_gap.h" + +static const char *tag = "NimBLE_BLE_PERIODIC_SYNC"; +static int synced = 0; +static int periodic_sync_gap_event(struct ble_gap_event *event, void *arg); + +void ble_store_config_init(void); + +static void +periodic_sync_scan(void) +{ + uint8_t own_addr_type; + struct ble_gap_disc_params disc_params; + int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Tell the controller to filter duplicates; we don't want to process + * repeated advertisements from the same device. + */ + disc_params.filter_duplicates = 0; + + /** + * Perform a passive scan. I.e., don't send follow-up scan requests to + * each advertiser. + */ + disc_params.passive = 1; + + /* Use defaults for the rest of the parameters. */ + disc_params.itvl = 0; + disc_params.window = 0; + disc_params.filter_policy = 0; + disc_params.limited = 0; + + rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, + periodic_sync_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error initiating GAP discovery procedure; rc=%d\n", + rc); + } +} + +void print_periodic_sync_data(struct ble_gap_event *event) +{ + MODLOG_DFLT(DEBUG, "status : %d\nperiodic_sync_handle : %d\nsid : %d\n", event->periodic_sync.status, event->periodic_sync.sync_handle, event->periodic_sync.sid); + MODLOG_DFLT(DEBUG, "adv addr : "); + for (int i = 0; i < 6; i++) { + MODLOG_DFLT(DEBUG, "%d ", event->periodic_sync.adv_addr.val[i]); + } + MODLOG_DFLT(DEBUG, "\nadv_phy : %s\n", event->periodic_sync.adv_phy == 1 ? "1m" : (event->periodic_sync.adv_phy == 2 ? "2m" : "coded")); + MODLOG_DFLT(DEBUG, "per_adv_ival : %d\n", event->periodic_sync.per_adv_ival); + MODLOG_DFLT(DEBUG, "adv_clk_accuracy : %d\n", event->periodic_sync.adv_clk_accuracy); +} +void print_periodic_adv_data(struct ble_gap_event *event) +{ + MODLOG_DFLT(DEBUG, "sync_handle : %d\n", event->periodic_report.sync_handle); + MODLOG_DFLT(DEBUG, "tx_power : %d\n", event->periodic_report.tx_power); + MODLOG_DFLT(DEBUG, "rssi : %d\n", event->periodic_report.rssi); + MODLOG_DFLT(DEBUG, "data_status : %d\n", event->periodic_report.data_status); + MODLOG_DFLT(DEBUG, "data_length : %d\n", event->periodic_report.data_length); + MODLOG_DFLT(DEBUG, "data : "); + for (int i = 0; i < event->periodic_report.data_length; i++) { + MODLOG_DFLT(DEBUG, "%c", ((char *)event->periodic_report.data)[i]); + } + MODLOG_DFLT(DEBUG, "\n"); +} +void print_periodic_sync_lost_data(struct ble_gap_event *event) +{ + MODLOG_DFLT(DEBUG, "sync_handle : %d\n", event->periodic_sync_lost.sync_handle); + MODLOG_DFLT(DEBUG, "reason : %s\n", event->periodic_sync_lost.reason == 13 ? "timeout" : (event->periodic_sync_lost.reason == 14 ? "terminated locally" : "Unknown reason")); +} +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that is + * established. periodic_sync uses the same callback for all connections. + * + * @param event The event being signalled. + * @param arg Application-specified argument; unused by + * periodic_sync. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +periodic_sync_gap_event(struct ble_gap_event *event, void *arg) +{ + switch (event->type) { +#if CONFIG_EXAMPLE_EXTENDED_ADV + case BLE_GAP_EVENT_EXT_DISC: + /* An advertisment report was received during GAP discovery. */ + struct ble_gap_ext_disc_desc *disc = ((struct ble_gap_ext_disc_desc *)(&event->disc)); + if (disc->sid == 2 && synced == 0) { + synced++; + const ble_addr_t addr; + uint8_t adv_sid; + struct ble_gap_periodic_sync_params params; + int rc; + memcpy((void *)&addr, (void *)&disc->addr, sizeof(disc->addr)); + memcpy(&adv_sid, &disc->sid, sizeof(disc->sid)); + params.skip = 10; + params.sync_timeout = 1000; + rc = ble_gap_periodic_adv_sync_create(&addr, adv_sid, ¶ms, periodic_sync_gap_event, NULL); + assert(rc == 0); + } + return 0; + case BLE_GAP_EVENT_PERIODIC_REPORT: + MODLOG_DFLT(INFO, "Periodic adv report event: \n"); + print_periodic_adv_data(event); + return 0; + case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: + MODLOG_DFLT(INFO, "Periodic sync lost\n"); + print_periodic_sync_lost_data(event); + synced = 0; + return 0; + case BLE_GAP_EVENT_PERIODIC_SYNC: + MODLOG_DFLT(INFO, "Periodic sync event : \n"); + print_periodic_sync_data(event); + return 0; +#endif + default: + return 0; + } +} + +static void +periodic_sync_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +periodic_sync_on_sync(void) +{ + int rc; + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Begin scanning for a peripheral to connect to. */ + periodic_sync_scan(); +} + +void periodic_sync_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +void +app_main(void) +{ + int rc; + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + nimble_port_init(); + /* Configure the host. */ + ble_hs_cfg.reset_cb = periodic_sync_on_reset; + ble_hs_cfg.sync_cb = periodic_sync_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Initialize data structures to track connected peers. */ + rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble_periodic_sync"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + nimble_port_freertos_init(periodic_sync_host_task); +} diff --git a/examples/bluetooth/nimble/ble_periodic_sync/main/periodic_sync.h b/examples/bluetooth/nimble/ble_periodic_sync/main/periodic_sync.h new file mode 100644 index 0000000000..5da9f33399 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/main/periodic_sync.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef H_BLE_PERIODIC_SYNC_ +#define H_BLE_PERIODIC_SYNC_ + +#include "modlog/modlog.h" +#include "esp_central.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_adv_fields; +struct ble_gap_conn_desc; +struct ble_hs_cfg; +union ble_store_value; +union ble_store_key; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_periodic_sync/sdkconfig.defaults b/examples/bluetooth/nimble/ble_periodic_sync/sdkconfig.defaults new file mode 100644 index 0000000000..60f9e68480 --- /dev/null +++ b/examples/bluetooth/nimble/ble_periodic_sync/sdkconfig.defaults @@ -0,0 +1,15 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_EXAMPLE_EXTENDED_ADV=y +CONFIG_BT_NIMBLE_EXT_ADV=y +CONFIG_BT_NIMBLE_MAX_PERIODIC_SYNCS=1