mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
fix(ble): update the example docs for pawr
(cherry picked from commit 164fec9e74)
Co-authored-by: cjin <jinchen@espressif.com>
This commit is contained in:
@@ -230,12 +230,12 @@ examples/bluetooth/nimble/ble_multi_conn:
|
||||
examples/bluetooth/nimble/ble_pawr_adv:
|
||||
<<: *bt_default_depends
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32c6"
|
||||
- if: SOC_ESP_NIMBLE_CONTROLLER == 1 and IDF_TARGET != "esp32c2"
|
||||
|
||||
examples/bluetooth/nimble/ble_pawr_adv_conn:
|
||||
<<: *bt_default_depends
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32c6"
|
||||
- if: SOC_ESP_NIMBLE_CONTROLLER == 1 and IDF_TARGET != "esp32c2"
|
||||
|
||||
examples/bluetooth/nimble/ble_periodic_adv:
|
||||
<<: *bt_default_depends
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
| Supported Targets | ESP32-C6 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
|
||||
# Important Note
|
||||
*This example currently requires an external Bluetooth controller supporting PAwR functionality, as the ESP chips listed above do not have native controller support for PAwR features and under development phase*
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
|
||||
# BLE Periodic Advertiser With Response (PAwR) Advertiser Example
|
||||
|
||||
@@ -14,7 +10,7 @@
|
||||
|
||||
This example starts PAwR advertising with configurable subevents and response slots.
|
||||
|
||||
It uses external Bluetooth controller and NimBLE stack based BLE host.
|
||||
It uses Bluetooth controller and NimBLE stack based BLE host.
|
||||
|
||||
This example aims at understanding PAwR advertisement and related NimBLE APIs.
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "host/ble_hs.h"
|
||||
|
||||
#define BLE_PAWR_EVENT_INTERVAL (600)
|
||||
#define BLE_PAWR_PERIODIC_EVENT_INTERVAL_MS (3000)
|
||||
#define BLE_PAWR_NUM_SUBEVTS (10)
|
||||
#define BLE_PAWR_SUB_INTERVAL (44) /*!< Interval between subevents (N * 1.25 ms) */
|
||||
#define BLE_PAWR_RSP_SLOT_DELAY (20) /*!< The first response slot delay (N * 1.25 ms)*/
|
||||
@@ -135,8 +136,8 @@ start_periodic_adv(void)
|
||||
/* configure periodic advertising */
|
||||
memset(&pparams, 0, sizeof(pparams));
|
||||
pparams.include_tx_power = 0;
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_PERIODIC_EVENT_INTERVAL_MS);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_PERIODIC_EVENT_INTERVAL_MS);
|
||||
/* Configure the parameters of PAwR. */
|
||||
pparams.num_subevents = BLE_PAWR_NUM_SUBEVTS;
|
||||
pparams.subevent_interval = BLE_PAWR_SUB_INTERVAL;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
This tutorial examines the BLE Periodic Advertisement with Responses (PAwR) example code for ESP32 chipsets with BLE 5.0+ support. The code demonstrates how to implement PAwR functionality using NimBLE APIs, which enables bidirectional communication between advertiser and scanner devices in a power-efficient manner.
|
||||
This tutorial examines the BLE Periodic Advertisement with Responses (PAwR) example code for ESP32 chipsets with BLE 5.0+ support. The code demonstrates how to implement PAwR functionality using NimBLE APIs, which enables bidirectional communication between advertiser and scanner devices.
|
||||
|
||||
## Includes
|
||||
|
||||
@@ -123,7 +123,7 @@ esp_err_t esp_nimble_init(void)
|
||||
The example defines several PAwR parameters
|
||||
|
||||
```c
|
||||
#define BLE_PAWR_EVENT_INTERVAL (600)
|
||||
#define BLE_PAWR_PERIODIC_EVENT_INTERVAL_MS (3000)
|
||||
#define BLE_PAWR_NUM_SUBEVTS (10)
|
||||
#define BLE_PAWR_SUB_INTERVAL (44) /*!< Interval between subevents (N * 1.25 ms) */
|
||||
#define BLE_PAWR_RSP_SLOT_DELAY (20) /*!< The first response slot delay (N * 1.25 ms) */
|
||||
@@ -142,22 +142,6 @@ These parameters control:
|
||||
|
||||
- Data length for subevent payloads
|
||||
|
||||
|
||||
## Periodic Advertising Configuration
|
||||
```c
|
||||
memset(&pparams, 0, sizeof(pparams));
|
||||
pparams.include_tx_power = 0;
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.num_subevents = BLE_PAWR_NUM_SUBEVTS;
|
||||
pparams.subevent_interval = BLE_PAWR_SUB_INTERVAL;
|
||||
pparams.response_slot_delay = BLE_PAWR_RSP_SLOT_DELAY;
|
||||
pparams.response_slot_spacing = BLE_PAWR_RSP_SLOT_SPACING;
|
||||
pparams.num_response_slots = BLE_PAWR_NUM_RSP_SLOTS;
|
||||
|
||||
rc = ble_gap_periodic_adv_configure(instance, &pparams);
|
||||
assert(rc == 0);
|
||||
```
|
||||
## Key PAwR Parameters:
|
||||
|
||||
- num_subevents: Number of subevents per periodic interval (10)
|
||||
@@ -226,8 +210,8 @@ start_periodic_adv(void)
|
||||
/* configure periodic advertising */
|
||||
memset(&pparams, 0, sizeof(pparams));
|
||||
pparams.include_tx_power = 0;
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_PERIODIC_EVENT_INTERVAL_MS);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_PERIODIC_EVENT_INTERVAL_MS);
|
||||
/* Configure the parameters of PAwR. */
|
||||
pparams.num_subevents = BLE_PAWR_NUM_SUBEVTS;
|
||||
pparams.subevent_interval = BLE_PAWR_SUB_INTERVAL;
|
||||
@@ -312,9 +296,7 @@ This PAwR example demonstrates:
|
||||
|
||||
2. Bidirectional communication between advertiser and scanners
|
||||
|
||||
3. Efficient power usage through scheduled communication windows
|
||||
|
||||
4. Use of extended advertising to announce PAwR capabilities
|
||||
3. Use of extended advertising to announce PAwR capabilities
|
||||
|
||||
The implementation shows how to:
|
||||
|
||||
@@ -326,4 +308,4 @@ The implementation shows how to:
|
||||
|
||||
- Manage the advertising lifecycle
|
||||
|
||||
PAwR is particularly useful for applications requiring periodic, bidirectional communication with multiple devices while maintaining low power consumption.
|
||||
PAwR is particularly useful for applications requiring periodic, bidirectional communication with multiple devices
|
||||
@@ -1,8 +1,5 @@
|
||||
| Supported Targets | ESP32-C6 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# Important Note
|
||||
*This example currently requires an external Bluetooth controller supporting PAwR functionality, as the ESP chips listed above do not have native controller support for PAwR features and under development phase*
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
|
||||
# BLE Periodic Advertiser With Response (PAwR) Sync Example
|
||||
|
||||
@@ -20,6 +17,7 @@ To test this demo, any BLE advertiser supporting PAwR can be used.(check /exampl
|
||||
- Configurable synchronization parameters (skip factor, timeout)
|
||||
- Detailed reporting of PAwR advertisement data
|
||||
- Handling of synchronization loss events
|
||||
- Configuration of PAwR response data
|
||||
|
||||
Note :
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
#define TAG "NimBLE_BLE_PAwR"
|
||||
#define TARGET_NAME "Nimble_PAwR"
|
||||
#define BLE_PAWR_RSP_DATA_IDX (2)
|
||||
#define BLE_PAWR_RSP_DATA_LEN (16)
|
||||
|
||||
static uint8_t sub_data_pattern[BLE_PAWR_RSP_DATA_LEN] = {0};
|
||||
|
||||
static int create_periodic_sync(struct ble_gap_ext_disc_desc *disc);
|
||||
@@ -60,7 +62,7 @@ gap_event_cb(struct ble_gap_event *event, void *arg)
|
||||
.request_event = event->periodic_report.event_counter,
|
||||
.request_subevent = event->periodic_report.subevent,
|
||||
.response_subevent = event->periodic_report.subevent,
|
||||
.response_slot = 2,
|
||||
.response_slot = BLE_PAWR_RSP_DATA_IDX,
|
||||
};
|
||||
|
||||
struct os_mbuf *data = os_msys_get_pkthdr(BLE_PAWR_RSP_DATA_LEN, 0);
|
||||
|
||||
@@ -140,6 +140,7 @@ The example defines several key parameters:
|
||||
```c
|
||||
#define TAG "NimBLE_BLE_PAwR"
|
||||
#define TARGET_NAME "Nimble_PAwR"
|
||||
#define BLE_PAWR_RSP_DATA_IDX (2)
|
||||
#define BLE_PAWR_RSP_DATA_LEN (16)
|
||||
static uint8_t sub_data_pattern[BLE_PAWR_RSP_DATA_LEN] = {0};
|
||||
```
|
||||
@@ -147,6 +148,8 @@ These parameters control:
|
||||
|
||||
- Target advertiser name to sync with
|
||||
|
||||
- Response slot index to send response data at
|
||||
|
||||
- Response data length
|
||||
|
||||
- Data pattern for responses
|
||||
@@ -232,7 +235,7 @@ case BLE_GAP_EVENT_PERIODIC_REPORT:
|
||||
.request_event = event->periodic_report.event_counter,
|
||||
.request_subevent = event->periodic_report.subevent,
|
||||
.response_subevent = event->periodic_report.subevent,
|
||||
.response_slot = rsp_slot_idx
|
||||
.response_slot = BLE_PAWR_RSP_DATA_IDX
|
||||
};
|
||||
|
||||
// Prepare response data
|
||||
@@ -245,9 +248,12 @@ case BLE_GAP_EVENT_PERIODIC_REPORT:
|
||||
event->periodic_report.sync_handle, ¶m, data);
|
||||
break;
|
||||
```
|
||||
|
||||
By default the response data will be sent within the same subevent where the periodic advertising report is received.
|
||||
|
||||
## Subevent Configuration
|
||||
|
||||
After sync establishment:
|
||||
After sync establishment, sync to configurable subevents:
|
||||
|
||||
```c
|
||||
// Choose subevents to listen to
|
||||
@@ -256,6 +262,8 @@ int result = ble_gap_periodic_adv_sync_subev(
|
||||
event->periodic_sync.sync_handle, 0, sizeof(subevents), subevents);
|
||||
```
|
||||
|
||||
The subevents sync selection depends on the subevent number of the Periodic Advertising device.
|
||||
|
||||
## Error Handling
|
||||
When sync is lost:
|
||||
```c
|
||||
@@ -270,4 +278,4 @@ case BLE_GAP_EVENT_PERIODIC_SYNC_LOST:
|
||||
|
||||
## Conclusion
|
||||
|
||||
This implementation demonstrates a complete PAwR synchronization solution, showcasing advertiser discovery via extended scanning, periodic sync establishment with configurable subevents (0-4), and efficient bidirectional communication through managed response slots. The robust architecture handles sync loss recovery while maintaining low-power operation, making it ideal for IoT applications requiring scheduled, bidirectional communication with multiple endpoints. The solution leverages BLE 5.0's PAwR features to optimize power efficiency and reliability in dense RF environments.
|
||||
This implementation demonstrates a complete PAwR synchronization solution, showcasing advertiser discovery via extended scanning, periodic sync establishment with configurable subevents (0-4), and efficient bidirectional communication through managed response slots. The robust architecture handles sync loss recovery, making it ideal for IoT applications requiring scheduled, bidirectional communication with multiple endpoints.
|
||||
@@ -1,8 +1,5 @@
|
||||
| Supported Targets | ESP32-C6 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# Important Note
|
||||
*This example currently requires an external Bluetooth controller supporting PAwR functionality, as the ESP chips listed above do not have native controller support for PAwR features and under development phase*
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
|
||||
# BLE Periodic Advertiser With Response (PAwR) Advertiser Connection Example
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "host/ble_hs.h"
|
||||
|
||||
#define BLE_PAWR_EVENT_INTERVAL (520)
|
||||
#define BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS (3000)
|
||||
#define BLE_PAWR_NUM_SUBEVTS (10)
|
||||
#define BLE_PAWR_SUB_INTERVAL (52) /*!< Interval between subevents (N * 1.25 ms) */
|
||||
#define BLE_PAWR_RSP_SLOT_DELAY (5) /*!< The first response slot delay (N * 1.25 ms)*/
|
||||
@@ -217,8 +217,8 @@ start_periodic_adv(void)
|
||||
/* configure periodic advertising */
|
||||
memset(&pparams, 0, sizeof(pparams));
|
||||
pparams.include_tx_power = 0;
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS);
|
||||
/* Configure the parameters of PAwR. */
|
||||
pparams.num_subevents = BLE_PAWR_NUM_SUBEVTS;
|
||||
pparams.subevent_interval = BLE_PAWR_SUB_INTERVAL;
|
||||
|
||||
@@ -123,6 +123,7 @@ esp_err_t esp_nimble_init(void)
|
||||
## PAwR Configuration
|
||||
```c
|
||||
#define BLE_PAWR_EVENT_INTERVAL (520)
|
||||
#define BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS (3000)
|
||||
#define BLE_PAWR_NUM_SUBEVTS (10)
|
||||
#define BLE_PAWR_SUB_INTERVAL (52)
|
||||
#define BLE_PAWR_RSP_SLOT_DELAY (5)
|
||||
@@ -130,33 +131,123 @@ esp_err_t esp_nimble_init(void)
|
||||
#define BLE_PAWR_NUM_RSP_SLOTS (25)
|
||||
#define BLE_PAWR_SUB_DATA_LEN (20)
|
||||
```
|
||||
These parameters configure PAwR interval, subevents, response slot timing, and payload length.
|
||||
These parameters control:
|
||||
|
||||
## Periodic Advertising Configuration
|
||||
- The interval between periodic advertising events
|
||||
|
||||
```c
|
||||
memset(&pparams, 0, sizeof(pparams));
|
||||
pparams.include_tx_power = 0;
|
||||
pparams.itvl_min = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(3000);
|
||||
pparams.num_subevents = BLE_PAWR_NUM_SUBEVTS;
|
||||
pparams.subevent_interval = BLE_PAWR_SUB_INTERVAL;
|
||||
pparams.response_slot_delay = BLE_PAWR_RSP_SLOT_DELAY;
|
||||
pparams.response_slot_spacing = BLE_PAWR_RSP_SLOT_SPACING;
|
||||
pparams.num_response_slots = BLE_PAWR_NUM_RSP_SLOTS;
|
||||
```
|
||||
- Number of subevents per periodic interval
|
||||
|
||||
These values are passed to ble_gap_periodic_adv_configure() to start PAwR.
|
||||
- Timing of response slots
|
||||
|
||||
- Data length for subevent payloads
|
||||
|
||||
## Key PAwR Parameters:
|
||||
|
||||
- num_subevents: Number of subevents per periodic interval (10)
|
||||
|
||||
- subevent_interval: Time between subevents (44 × 1.25ms = 55ms)
|
||||
|
||||
- response_slot_delay: First response slot delay (20 × 1.25ms = 25ms)
|
||||
|
||||
- response_slot_spacing: Time between slots (32 × 0.125ms = 4ms)
|
||||
|
||||
- num_response_slots: Number of response slots per subevent (5)
|
||||
|
||||
## PAwR Advertisement
|
||||
The start_periodic_adv() function:
|
||||
- Configures extended advertising parameters
|
||||
- Sets up periodic advertising using subevent and slot parameters
|
||||
- Starts extended + periodic advertising
|
||||
|
||||
The start_periodic_adv() function configures and starts PAwR:
|
||||
```c
|
||||
static void
|
||||
start_periodic_adv(void)
|
||||
{
|
||||
int rc;
|
||||
uint8_t addr[6];
|
||||
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 = 0;
|
||||
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_ENH)
|
||||
struct ble_gap_periodic_adv_enable_params eparams;
|
||||
memset(&eparams, 0, sizeof(eparams));
|
||||
#endif
|
||||
|
||||
/* Get the local public address. */
|
||||
rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr, NULL);
|
||||
assert (rc == 0);
|
||||
|
||||
ESP_LOGI(TAG, "Device Address %02x:%02x:%02x:%02x:%02x:%02x", addr[5], addr[4], addr[3],
|
||||
addr[2], addr[1], addr[0]);
|
||||
|
||||
/* For periodic we use instance with non-connectable advertising */
|
||||
memset (¶ms, 0, sizeof(params));
|
||||
params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
|
||||
params.primary_phy = BLE_HCI_LE_PHY_CODED;
|
||||
params.secondary_phy = BLE_HCI_LE_PHY_1M;
|
||||
params.sid = 0;
|
||||
params.itvl_min = BLE_GAP_ADV_ITVL_MS(50);
|
||||
params.itvl_max = BLE_GAP_ADV_ITVL_MS(50);
|
||||
|
||||
rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, gap_event_cb, NULL);
|
||||
assert (rc == 0);
|
||||
|
||||
memset(&adv_fields, 0, sizeof(adv_fields));
|
||||
adv_fields.name = (const uint8_t *)"Nimble_PAwR_CONN";
|
||||
adv_fields.name_len = strlen((char *)adv_fields.name);
|
||||
|
||||
/* 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 = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS);
|
||||
pparams.itvl_max = BLE_GAP_PERIODIC_ITVL_MS(BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS);
|
||||
/* Configure the parameters of PAwR. */
|
||||
pparams.num_subevents = BLE_PAWR_NUM_SUBEVTS;
|
||||
pparams.subevent_interval = BLE_PAWR_SUB_INTERVAL;
|
||||
pparams.response_slot_delay = BLE_PAWR_RSP_SLOT_DELAY;
|
||||
pparams.response_slot_spacing = BLE_PAWR_RSP_SLOT_SPACING;
|
||||
pparams.num_response_slots = BLE_PAWR_NUM_RSP_SLOTS;
|
||||
|
||||
rc = ble_gap_periodic_adv_configure(instance, &pparams);
|
||||
assert(rc == 0);
|
||||
|
||||
/* start periodic advertising */
|
||||
#if MYNEWT_VAL(BLE_PERIODIC_ADV_ENH)
|
||||
eparams.include_adi = 1;
|
||||
rc = ble_gap_periodic_adv_start(instance, &eparams);
|
||||
#else
|
||||
rc = ble_gap_periodic_adv_start(instance);
|
||||
#endif
|
||||
assert (rc == 0);
|
||||
|
||||
/* start advertising */
|
||||
rc = ble_gap_ext_adv_start(instance, 0, 0);
|
||||
assert (rc == 0);
|
||||
|
||||
ESP_LOGI(TAG, "instance %u started (periodic)\n", instance);
|
||||
}
|
||||
```
|
||||
Key steps:
|
||||
|
||||
- Configure extended advertising parameters
|
||||
|
||||
- Set up periodic advertising with subevent and response slot parameters
|
||||
|
||||
- Start both periodic and extended advertising
|
||||
|
||||
## Need of Extended Advertisement in Periodic Advertisement
|
||||
|
||||
Extended advertisements contain synchronization info that lets scanners align with periodic advertising. This enables precise subevent-based communicati
|
||||
Extended advertisements contain synchronization info that lets scanners align with periodic advertising. This enables precise subevent-based communication.
|
||||
|
||||
## GAP Event Callback
|
||||
|
||||
@@ -175,7 +266,7 @@ case BLE_GAP_EVENT_DISCONNECT:
|
||||
|
||||
## Using ble_gap_connect_with_synced()
|
||||
|
||||
The API ble_gap_connect_with_synced() is a NimBLE API used by a PAwR Advertiser to initiate a BLE connection with a synced scanner. This allows the advertiser to transition from scheduled subevent-based communication to a higher-throughput, lower-latency connection with a specific scanner.
|
||||
The API ble_gap_connect_with_synced() is a NimBLE API used by a PAwR Advertiser to initiate a BLE connection with a synced scanner as central role. This allows the advertiser to transition from scheduled subevent-based communication to a higher-throughput, lower-latency connection with a specific scanner.
|
||||
|
||||
This is especially useful in use cases where on-demand, peer-to-peer data exchange is needed.
|
||||
```c
|
||||
@@ -207,41 +298,6 @@ void pawr_host_task(void *param)
|
||||
nimble_port_freertos_deinit();
|
||||
}
|
||||
```
|
||||
## Parameter Configuration
|
||||
|
||||
The below snippets represent the parameter configuration for extended and periodic advertisement.
|
||||
|
||||
### For Extended Advertisement
|
||||
|
||||
```c
|
||||
params.own_addr_type = BLE_OWN_ADDR_RANDOM; //Own address type is set to Random
|
||||
params.primary_phy = BLE_HCI_LE_PHY_1M; // Primary advertising PHY is set to 1M
|
||||
params.secondary_phy = BLE_HCI_LE_PHY_2M; // Secondary advertising PHY is set to 2M
|
||||
params.sid = 2; // Advertising set Id is assigned with value 2.
|
||||
```
|
||||
|
||||
### For Periodic Advertisement
|
||||
|
||||
```c
|
||||
memset(&pparams, 0, sizeof(pparams));
|
||||
pparams.include_tx_power = 0; // Indicates that TX power is not included in advertising PDU
|
||||
pparams.itvl_min = BLE_GAP_ADV_ITVL_MS(120); // Minimum advertising interval of 240ms
|
||||
pparams.itvl_max = BLE_GAP_ADV_ITVL_MS(240); //Maximum advertising interval of 480ms
|
||||
```
|
||||
|
||||
Periodic advertisement is started for a particular advertisement instance by calling the API `ble_gap_periodic_adv_start(instance)`. This function takes instance-id as an input parameter. It defines the hci command by initializing the command parameters which are represented in the following lines.
|
||||
|
||||
```c
|
||||
struct ble_hci_le_set_periodic_adv_enable_cp cmd;
|
||||
cmd.enable = 0x01;
|
||||
cmd.adv_handle = instance;
|
||||
```
|
||||
|
||||
Extended advertising is invoked for a particular instance using the API call `ble_gap_ext_adv_start(instance, 0, 0)`.Instance-id, duration, and max_events are input parameters for this API call respectively.
|
||||
|
||||
Duration represents the time for which the adverteiment will take place. Upon expiration, the advertising procedure ends, and the BLE_GAP_EVENT_ADV_COMPLETE event is reported.0 value is used for no expiration.
|
||||
|
||||
max_events Number of advertising events that should be sent before advertising ends and a BLE_GAP_EVENT_ADV_COMPLETE event is reported.0 value is used for no limit.
|
||||
|
||||
## Conclusion
|
||||
|
||||
@@ -252,5 +308,5 @@ This PAwR with connection example demonstrates:
|
||||
- Periodic advertising with subevents and response slots
|
||||
- Dynamic connection initiation based on scanner responses
|
||||
- Use of extended advertisement for synchronization
|
||||
- Efficient, scalable, low-power bidirectional communication
|
||||
- Efficient, scalable, bidirectional communication
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
| Supported Targets | ESP32-C6 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
## Important Note
|
||||
*This example currently requires an external Bluetooth controller supporting PAwR functionality, as the ESP chips listed above do not have native controller support for PAwR features and under development phase*
|
||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- | --------- | -------- |
|
||||
|
||||
# BLE Periodic Advertiser With Response (PAwR) Sync Connection Example
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#define TAG "NimBLE_BLE_PAwR_CONN"
|
||||
#define TARGET_NAME "Nimble_PAwR_CONN"
|
||||
#define BLE_PAWR_RSP_SLOT_INDEX (2)
|
||||
#define BLE_PAWR_RSP_DATA_LEN (10)
|
||||
static uint8_t sub_data_pattern[BLE_PAWR_RSP_DATA_LEN] = {0};
|
||||
|
||||
@@ -114,7 +115,7 @@ gap_event_cb(struct ble_gap_event *event, void *arg)
|
||||
.request_event = event->periodic_report.event_counter,
|
||||
.request_subevent = event->periodic_report.subevent,
|
||||
.response_subevent = event->periodic_report.subevent,
|
||||
.response_slot = 2,
|
||||
.response_slot = BLE_PAWR_RSP_SLOT_INDEX,
|
||||
};
|
||||
|
||||
struct os_mbuf *data = os_msys_get_pkthdr(BLE_PAWR_RSP_DATA_LEN, 0);
|
||||
|
||||
@@ -114,19 +114,14 @@ esp_err_t esp_nimble_init(void)
|
||||
|
||||
Configures a passive extended scan to detect periodic advertisers:
|
||||
```c
|
||||
static void start_scan(void) {
|
||||
struct ble_gap_ext_disc_params d = {
|
||||
.itvl = BLE_GAP_SCAN_ITVL_MS(600), // Scan every 600ms
|
||||
.window = BLE_GAP_SCAN_ITVL_MS(300), // Listen for 300ms
|
||||
.passive= 1 // Do not send scan requests
|
||||
};
|
||||
// Start discovery; gap_event_cb handles each advertisement
|
||||
ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, 1, 0, 0,
|
||||
NULL, &d, gap_event_cb, NULL);
|
||||
}
|
||||
```
|
||||
memset(&disc_params, 0, sizeof(disc_params));
|
||||
disc_params.itvl = BLE_GAP_SCAN_ITVL_MS(600);
|
||||
disc_params.window = BLE_GAP_SCAN_ITVL_MS(300);
|
||||
disc_params.passive = 1;
|
||||
|
||||
- BLE_OWN_ADDR_PUBLIC: Use the device’s public address.
|
||||
rc = ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, 1, 0, 0, NULL, &disc_params,
|
||||
gap_event_cb, NULL);
|
||||
```
|
||||
|
||||
- gap_event_cb: Processes discovery events (EXT_DISC) to find our target.`
|
||||
|
||||
@@ -151,60 +146,54 @@ static int create_periodic_sync(struct ble_gap_ext_disc_desc *disc) {
|
||||
```
|
||||
- disc->addr / sid: Address and Sync ID identify the PAwR train.
|
||||
|
||||
- ble_gap_periodic_adv_sync_create: Starts low-power sync to periodic events.
|
||||
- ble_gap_periodic_adv_sync_create: Starts sync to periodic events.
|
||||
|
||||
## Subevent Synchronization
|
||||
|
||||
After sync establishment, sync to configurable subevents:
|
||||
|
||||
```c
|
||||
// Choose subevents to listen to
|
||||
uint8_t subevents[] = {0, 1, 2, 3, 4};
|
||||
int result = ble_gap_periodic_adv_sync_subev(
|
||||
event->periodic_sync.sync_handle, 0, sizeof(subevents), subevents);
|
||||
```
|
||||
|
||||
The subevents sync selection depends on the subevent number of the Periodic Advertising device.
|
||||
|
||||
## Sending Response Data
|
||||
|
||||
Once synchronized, respond during periodic reports:
|
||||
Respond after receiving periodic reports:
|
||||
|
||||
```c
|
||||
case BLE_GAP_EVENT_PERIODIC_REPORT:
|
||||
ESP_LOGI(TAG, "[Periodic Adv Report] handle:%d, event_counter(%d), subevent(%d)",
|
||||
event->periodic_report.sync_handle,
|
||||
event->periodic_report.event_counter,
|
||||
event->periodic_report.subevent);
|
||||
|
||||
case BLE_GAPCreate Periodic Sync
|
||||
struct ble_gap_periodic_adv_response_params param = {
|
||||
.request_event = event->periodic_report.event_counter,
|
||||
.request_subevent = event->periodic_report.subevent,
|
||||
.response_subevent = event->periodic_report.subevent,
|
||||
.response_slot = BLE_PAWR_RSP_SLOT_INDEX,
|
||||
};
|
||||
|
||||
When a periodic advertiser is found, request synchronization:
|
||||
struct os_mbuf *data = os_msys_get_pkthdr(BLE_PAWR_RSP_DATA_LEN, 0);
|
||||
if (!data) {
|
||||
ESP_LOGE(TAG, "No memory");
|
||||
return 0;
|
||||
}
|
||||
// create a special data for checking manually in ADV side
|
||||
|
||||
static int create_periodic_sync(struct ble_gap_ext_disc_desc *disc) {
|
||||
struct ble_gap_periodic_sync_params p = {
|
||||
.skip = 0, // Do not skip any events
|
||||
.sync_timeout = 4000, // Give 4000ms to establish sync
|
||||
.reports_disabled= 0, // Keep reports enabled
|
||||
#if CONFIG_EXAMPLE_PERIODIC_ADV_ENH
|
||||
.filter_duplicates = 1, // Only receive when data-id changes
|
||||
#endif
|
||||
};
|
||||
// Initiate sync; callback will receive PERIODIC_SYNC
|
||||
return ble_gap_periodic_adv_sync_create(
|
||||
&disc->addr, disc->sid, &p,
|
||||
gap_event_cb, NULL);
|
||||
}
|
||||
sub_data_pattern[0] = event->periodic_report.subevent;
|
||||
rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, device_addr, NULL);
|
||||
sub_data_pattern[1] = param.response_slot;
|
||||
memcpy(&sub_data_pattern[2],device_addr,BLE_DEV_ADDR_LEN);
|
||||
|
||||
disc->addr / sid: Address and Sync ID identify the PAwR train.
|
||||
os_mbuf_append(data, sub_data_pattern, BLE_PAWR_RSP_DATA_LEN);
|
||||
|
||||
ble_gap_periodic_adv_sync_create: Starts low-power sync to periodic events.
|
||||
|
||||
_EVENT_PERIODIC_REPORT: {
|
||||
struct ble_gap_periodic_adv_response_params r = {
|
||||
.request_event = event->periodic_report.event_counter,
|
||||
.request_subevent = event->periodic_report.subevent,
|
||||
.response_subevent= event->periodic_report.subevent,
|
||||
.response_slot = 2, // Always use slot 2
|
||||
};
|
||||
// Allocate buffer for response payload
|
||||
struct os_mbuf *m = os_msys_get_pkthdr(BLE_PAWR_RSP_DATA_LEN, 0);
|
||||
// First byte: subevent index
|
||||
sub_data_pattern[0] = event->periodic_report.subevent;
|
||||
// Next 6 bytes: our public address
|
||||
ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, device_addr, NULL);
|
||||
memcpy(&sub_data_pattern[1], device_addr, BLE_DEV_ADDR_LEN);
|
||||
// Fill remaining bytes with slot index
|
||||
sub_data_pattern[7] = r.response_slot;
|
||||
os_mbuf_append(m, sub_data_pattern, BLE_PAWR_RSP_DATA_LEN);
|
||||
// Send response data back to advertiser
|
||||
ble_gap_periodic_adv_set_response_data(
|
||||
event->periodic_report.sync_handle,
|
||||
&r, m);
|
||||
break;
|
||||
}
|
||||
rc = ble_gap_periodic_adv_set_response_data(event->periodic_report.sync_handle, ¶m, data);
|
||||
```
|
||||
- os_msys_get_pkthdr: Allocates memory for the response.
|
||||
|
||||
@@ -263,7 +252,7 @@ This PAwR Sync + Conn example demonstrates:
|
||||
|
||||
- Passive discovery of periodic advertisers.
|
||||
|
||||
- Low-power synchronization to scheduled subevents.
|
||||
- Synchronization to scheduled subevents.
|
||||
|
||||
- Slot-based responses with custom payload.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user