Skip to content

Commit 95bc5cf

Browse files
hermabecarlescufi
authored andcommitted
Bluetooth: Host: Add support for PAwR Sync
Adds API for Periodic Advertising with Responses - Scanner: - Synchronize to a PAwR train - Choose which subevents to synchronize to - Receive advertising reports from subevents - Send responses The support is enabled by CONFIG_BT_PER_ADV_SYNC_RSP, and requires a controller that selects CONFIG_BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT. Signed-off-by: Herman Berget <herman.berget@nordicsemi.no>
1 parent 9021e2f commit 95bc5cf

File tree

7 files changed

+411
-3
lines changed

7 files changed

+411
-3
lines changed

include/zephyr/bluetooth/bluetooth.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,20 @@ struct bt_le_per_adv_sync_synced_info {
13921392
*
13931393
*/
13941394
struct bt_conn *conn;
1395+
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
1396+
/** Number of subevents */
1397+
uint8_t num_subevents;
1398+
1399+
/** Subevent interval (N * 1.25 ms) */
1400+
uint8_t subevent_interval;
1401+
1402+
/** Response slot delay (N * 1.25 ms) */
1403+
uint8_t response_slot_delay;
1404+
1405+
/** Response slot spacing (N * 1.25 ms) */
1406+
uint8_t response_slot_spacing;
1407+
1408+
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
13951409
};
13961410

13971411
struct bt_le_per_adv_sync_term_info {
@@ -1420,6 +1434,13 @@ struct bt_le_per_adv_sync_recv_info {
14201434

14211435
/** The Constant Tone Extension (CTE) of the advertisement (@ref bt_df_cte_type) */
14221436
uint8_t cte_type;
1437+
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
1438+
/** The value of the event counter where the subevent indication was received. */
1439+
uint16_t periodic_event_counter;
1440+
1441+
/** The subevent where the subevend indication was received. */
1442+
uint8_t subevent;
1443+
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
14231444
};
14241445

14251446

@@ -1463,6 +1484,9 @@ struct bt_le_per_adv_sync_cb {
14631484
* @param sync The advertising set object.
14641485
* @param info Information about the periodic advertising event.
14651486
* @param buf Buffer containing the periodic advertising data.
1487+
* NULL if the controller failed to receive a subevent
1488+
* indication. Only happens if
1489+
* @kconfig{CONFIG_BT_PER_ADV_SYNC_RSP} is enabled.
14661490
*/
14671491
void (*recv)(struct bt_le_per_adv_sync *sync,
14681492
const struct bt_le_per_adv_sync_recv_info *info,
@@ -2515,6 +2539,79 @@ void bt_foreach_bond(uint8_t id, void (*func)(const struct bt_bond_info *info,
25152539
int bt_configure_data_path(uint8_t dir, uint8_t id, uint8_t vs_config_len,
25162540
const uint8_t *vs_config);
25172541

2542+
struct bt_le_per_adv_sync_subevent_params {
2543+
/** @brief Periodic Advertising Properties.
2544+
*
2545+
* Bit 6 is include TxPower, all others RFU.
2546+
*
2547+
*/
2548+
uint16_t properties;
2549+
2550+
/** Number of subevents to sync to */
2551+
uint8_t num_subevents;
2552+
2553+
/** @brief The subevent(s) to synchronize with
2554+
*
2555+
* The array must have @ref num_subevents elements.
2556+
*
2557+
*/
2558+
uint8_t *subevents;
2559+
};
2560+
2561+
/** @brief Synchronize with a subset of subevents
2562+
*
2563+
* Until this command is issued, the subevent(s) the controller is synchronized
2564+
* to is unspecified.
2565+
*
2566+
* @param per_adv_sync The periodic advertising sync object.
2567+
* @param params Parameters.
2568+
*
2569+
* @return 0 in case of success or negative value in case of error.
2570+
*/
2571+
int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync,
2572+
struct bt_le_per_adv_sync_subevent_params *params);
2573+
2574+
struct bt_le_per_adv_response_params {
2575+
/** @brief The periodic event counter of the request the response is sent to.
2576+
*
2577+
* @ref bt_le_per_adv_sync_recv_info
2578+
*
2579+
* @note The response can be sent up to one periodic interval after
2580+
* the request was received.
2581+
*
2582+
*/
2583+
uint16_t request_event;
2584+
2585+
/** @brief The subevent counter of the request the response is sent to.
2586+
*
2587+
* @ref bt_le_per_adv_sync_recv_info
2588+
*
2589+
*/
2590+
uint8_t request_subevent;
2591+
2592+
/** The subevent the response shall be sent in */
2593+
uint8_t response_subevent;
2594+
2595+
/** The response slot the response shall be sent in */
2596+
uint8_t response_slot;
2597+
};
2598+
2599+
/**
2600+
* @brief Set the data for a response slot in a specific subevent of the PAwR.
2601+
*
2602+
* This function is called by the Host to set the response dat.
2603+
* The data for a repsonse slot shall be transmitted only once.
2604+
*
2605+
* @param per_adv_sync The periodic advertising sync object.
2606+
* @param params Parameters.
2607+
* @param data The response data to send.
2608+
*
2609+
* @return Zero on success or (negative) error code otherwise.
2610+
*/
2611+
int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync,
2612+
const struct bt_le_per_adv_response_params *params,
2613+
const struct net_buf_simple *data);
2614+
25182615
/**
25192616
* @}
25202617
*/

include/zephyr/bluetooth/hci.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct bt_hci_cmd_hdr {
178178
#define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39
179179

180180
#define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43
181+
#define BT_LE_FEAT_BIT_PAWR_SCANNER 44
181182

182183
#define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \
183184
BIT((n) & 7))
@@ -244,6 +245,8 @@ struct bt_hci_cmd_hdr {
244245
BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION)
245246
#define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \
246247
BT_LE_FEAT_BIT_PAWR_ADVERTISER)
248+
#define BT_FEAT_LE_PAWR_SCANNER(feat) BT_LE_FEAT_TEST(feat, \
249+
BT_LE_FEAT_BIT_PAWR_SCANNER)
247250

248251
#define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \
249252
BT_FEAT_LE_CIS_PERIPHERAL(feat))
@@ -1511,6 +1514,27 @@ struct bt_hci_cp_le_set_pawr_subevent_data {
15111514
struct bt_hci_cp_le_set_pawr_subevent_data_element subevents[0];
15121515
} __packed;
15131516

1517+
1518+
#define BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA BT_OP(BT_OGF_LE, 0x0083)
1519+
struct bt_hci_cp_le_set_pawr_response_data {
1520+
uint16_t sync_handle;
1521+
uint16_t request_event;
1522+
uint8_t request_subevent;
1523+
uint8_t response_subevent;
1524+
uint8_t response_slot;
1525+
uint8_t response_data_length;
1526+
uint8_t response_data[0];
1527+
} __packed;
1528+
1529+
#define BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT BT_OP(BT_OGF_LE, 0x0084)
1530+
struct bt_hci_cp_le_set_pawr_sync_subevent {
1531+
uint16_t sync_handle;
1532+
uint16_t periodic_adv_properties;
1533+
uint8_t num_subevents;
1534+
uint8_t subevents[0];
1535+
} __packed;
1536+
1537+
15141538
#define BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x0086)
15151539
struct bt_hci_cp_le_set_per_adv_param_v2 {
15161540
uint8_t handle;
@@ -2330,6 +2354,51 @@ struct bt_hci_evt_remote_ext_features {
23302354
uint8_t features[8];
23312355
} __packed;
23322356

2357+
#define BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2 0x24
2358+
struct bt_hci_evt_le_per_adv_sync_established_v2 {
2359+
uint8_t status;
2360+
uint16_t handle;
2361+
uint8_t sid;
2362+
bt_addr_le_t adv_addr;
2363+
uint8_t phy;
2364+
uint16_t interval;
2365+
uint8_t clock_accuracy;
2366+
uint8_t num_subevents;
2367+
uint8_t subevent_interval;
2368+
uint8_t response_slot_delay;
2369+
uint8_t response_slot_spacing;
2370+
} __packed;
2371+
2372+
#define BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2 0x25
2373+
struct bt_hci_evt_le_per_advertising_report_v2 {
2374+
uint16_t handle;
2375+
int8_t tx_power;
2376+
int8_t rssi;
2377+
uint8_t cte_type;
2378+
uint16_t periodic_event_counter;
2379+
uint8_t subevent;
2380+
uint8_t data_status;
2381+
uint8_t length;
2382+
uint8_t data[0];
2383+
} __packed;
2384+
2385+
#define BT_HCI_EVT_LE_PAST_RECEIVED_V2 0x26
2386+
struct bt_hci_evt_le_past_received_v2 {
2387+
uint8_t status;
2388+
uint16_t conn_handle;
2389+
uint16_t service_data;
2390+
uint16_t sync_handle;
2391+
uint8_t adv_sid;
2392+
bt_addr_le_t addr;
2393+
uint8_t phy;
2394+
uint16_t interval;
2395+
uint8_t clock_accuracy;
2396+
uint8_t num_subevents;
2397+
uint8_t subevent_interval;
2398+
uint8_t response_slot_delay;
2399+
uint8_t response_slot_spacing;
2400+
} __packed;
2401+
23332402
#define BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST 0x27
23342403
struct bt_hci_evt_le_per_adv_subevent_data_request {
23352404
uint8_t adv_handle;
@@ -2881,6 +2950,9 @@ struct bt_hci_evt_le_biginfo_adv_report {
28812950
#define BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING BT_EVT_BIT(32)
28822951
#define BT_EVT_MASK_LE_BIGINFO_ADV_REPORT BT_EVT_BIT(33)
28832952

2953+
#define BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2 BT_EVT_BIT(35)
2954+
#define BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2 BT_EVT_BIT(36)
2955+
#define BT_EVT_MASK_LE_PAST_RECEIVED_V2 BT_EVT_BIT(37)
28842956
#define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38)
28852957
#define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39)
28862958

subsys/bluetooth/Kconfig.adv

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ config BT_PER_ADV_SYNC
6060
and deterministic receive data from that device in a connectionless
6161
manner.
6262

63+
config BT_PER_ADV_SYNC_RSP
64+
bool "Periodic Advertising with Responses sync support [EXPERIMENTAL]"
65+
select EXPERIMENTAL
66+
depends on BT_OBSERVER
67+
help
68+
Select this to enable Periodic Advertising with Responses Sync
69+
API support.
70+
6371
if BT_PER_ADV_SYNC
6472

6573
config BT_PER_ADV_SYNC_MAX

subsys/bluetooth/controller/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ config BT_CTLR_SYNC_PERIODIC_SUPPORT
5151
depends on BT_CTLR_ADV_EXT_SUPPORT
5252
bool
5353

54+
config BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT
55+
depends on BT_CTLR_SYNC_PERIODIC_SUPPORT
56+
bool
57+
5458
config BT_CTLR_SYNC_TRANSFER_SENDER_SUPPORT
5559
depends on BT_CTLR_SYNC_PERIODIC_SUPPORT || BT_CTLR_ADV_PERIODIC_SUPPORT
5660
bool
@@ -650,6 +654,15 @@ config BT_CTLR_SYNC_PERIODIC
650654
Enable support for Bluetooth 5.0 LE Periodic Advertising in
651655
Synchronization state in the Controller.
652656

657+
config BT_CTLR_SYNC_PERIODIC_RSP
658+
bool "LE Periodic Advertising with Responses in Synchronization State"
659+
depends on BT_OBSERVER && BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT
660+
select BT_CTLR_CHAN_SEL_2
661+
default y if BT_PER_ADV_SYNC_RSP
662+
help
663+
Enable support for Bluetooth 5.4 LE Periodic Advertising with
664+
Responses in Synchronization state in the Controller.
665+
653666
if BT_CTLR_SYNC_PERIODIC
654667

655668
config BT_CTLR_SYNC_PERIODIC_ADV_LIST

subsys/bluetooth/host/hci_core.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,6 +2325,15 @@ static const struct event_handler meta_events[] = {
23252325
EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed,
23262326
sizeof(struct bt_hci_evt_le_cte_req_failed)),
23272327
#endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */
2328+
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
2329+
EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2,
2330+
sizeof(struct bt_hci_evt_le_per_advertising_report_v2)),
2331+
EVENT_HANDLER(BT_HCI_EVT_LE_PAST_RECEIVED_V2, bt_hci_le_past_received_v2,
2332+
sizeof(struct bt_hci_evt_le_past_received_v2)),
2333+
EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2,
2334+
bt_hci_le_per_adv_sync_established_v2,
2335+
sizeof(struct bt_hci_evt_le_per_adv_sync_established_v2)),
2336+
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
23282337
#if defined(CONFIG_BT_PER_ADV_RSP)
23292338
EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST,
23302339
bt_hci_le_per_adv_subevent_data_request,
@@ -2911,6 +2920,12 @@ static int le_set_event_mask(void)
29112920
mask |= BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT;
29122921
}
29132922

2923+
if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) {
2924+
mask |= BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2;
2925+
mask |= BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2;
2926+
mask |= BT_EVT_MASK_LE_PAST_RECEIVED_V2;
2927+
}
2928+
29142929
sys_put_le64(mask, cp_mask->events);
29152930
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL);
29162931
}

subsys/bluetooth/host/hci_core.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,20 @@ struct bt_le_per_adv_sync {
227227

228228
/** Flags */
229229
ATOMIC_DEFINE(flags, BT_PER_ADV_SYNC_NUM_FLAGS);
230+
231+
#if defined(CONFIG_BT_PER_ADV_SYNC_RSP)
232+
/** Number of subevents */
233+
uint8_t num_subevents;
234+
235+
/** Subevent interval (N * 1.25ms) */
236+
uint8_t subevent_interval;
237+
238+
/** Response slot delay (N * 1.25ms) */
239+
uint8_t response_slot_delay;
240+
241+
/** Response slot spacing (N * 1.25ms) */
242+
uint8_t response_slot_spacing;
243+
#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */
230244
};
231245

232246
struct bt_dev_le {
@@ -459,12 +473,15 @@ void bt_hci_le_adv_report(struct net_buf *buf);
459473
void bt_hci_le_scan_timeout(struct net_buf *buf);
460474
void bt_hci_le_adv_ext_report(struct net_buf *buf);
461475
void bt_hci_le_per_adv_sync_established(struct net_buf *buf);
476+
void bt_hci_le_per_adv_sync_established_v2(struct net_buf *buf);
462477
void bt_hci_le_per_adv_report(struct net_buf *buf);
478+
void bt_hci_le_per_adv_report_v2(struct net_buf *buf);
463479
void bt_hci_le_per_adv_sync_lost(struct net_buf *buf);
464480
void bt_hci_le_biginfo_adv_report(struct net_buf *buf);
465481
void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf);
466482
void bt_hci_le_vs_df_connectionless_iq_report(struct net_buf *buf);
467483
void bt_hci_le_past_received(struct net_buf *buf);
484+
void bt_hci_le_past_received_v2(struct net_buf *buf);
468485

469486
/* Adv HCI event handlers */
470487
void bt_hci_le_adv_set_terminated(struct net_buf *buf);

0 commit comments

Comments
 (0)