-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nimble: Add example for periodic adv/sync
- Loading branch information
Showing
16 changed files
with
892 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <chip_name> | ||
``` | ||
|
||
### 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. |
4 changes: 4 additions & 0 deletions
4
examples/bluetooth/nimble/ble_periodic_adv/main/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
set(srcs "main.c") | ||
|
||
idf_component_register(SRCS "${srcs}" | ||
INCLUDE_DIRS ".") |
15 changes: 15 additions & 0 deletions
15
examples/bluetooth/nimble/ble_periodic_adv/main/Kconfig.projbuild
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
Oops, something went wrong.