Parcourir la source

Nimble: Add example for periodic adv/sync

Roshan Bangar il y a 3 ans
Parent
commit
10eacf0360

+ 12 - 0
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"]

+ 7 - 0
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)

+ 75 - 0
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 <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 - 0
examples/bluetooth/nimble/ble_periodic_adv/main/CMakeLists.txt

@@ -0,0 +1,4 @@
+set(srcs "main.c")
+
+idf_component_register(SRCS "${srcs}"
+                    INCLUDE_DIRS ".")

+ 15 - 0
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

+ 221 - 0
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 (&params, 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, &params, 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);
+}

+ 173 - 0
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
+};

+ 25 - 0
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 <stdbool.h>
+#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

+ 15 - 0
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

+ 6 - 0
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)

+ 84 - 0
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 <chip_name>
+```
+
+### 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.

+ 2 - 0
examples/bluetooth/nimble/ble_periodic_sync/main/CMakeLists.txt

@@ -0,0 +1,2 @@
+idf_component_register(SRCS "main.c"
+                    INCLUDE_DIRS ".")

+ 8 - 0
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

+ 204 - 0
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, &params, 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);
+}

+ 26 - 0
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

+ 15 - 0
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