Bluetooth: host: Add handling of failures in per sync established evt
Handling of HCI_LE_Periodic_Advertising_Sync_Established didn't have implemented handling of possible failures of periodic advertising synchronization. There are two situations definded by BT 5.3 Core spec: - There is no AUX_SYNC_IND pdu within 6 periodic advertising events. If that happens, status of the command is set to (0x3E) Connection Failed To Be Established / Synchronization Timeout. - Periodic advertising has wrong CTE type while periodic advertising list is not used to determine the advertiser to listen. In this case status of the command is set to (0x1A) Unsupported Remote Feature. The commit provides missing functionality. In case of error, the periodic advertising will be deleted and application will be notified by call to terminated callback. The callback data were extended by err member. It provides information why periodic advertising was terminated. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
a09ba37334
commit
ea1340acd3
2 changed files with 16 additions and 3 deletions
|
@ -1153,6 +1153,9 @@ struct bt_le_per_adv_sync_term_info {
|
||||||
|
|
||||||
/** Advertiser SID */
|
/** Advertiser SID */
|
||||||
uint8_t sid;
|
uint8_t sid;
|
||||||
|
|
||||||
|
/** Cause of periodic advertising termination */
|
||||||
|
uint8_t reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bt_le_per_adv_sync_recv_info {
|
struct bt_le_per_adv_sync_recv_info {
|
||||||
|
|
|
@ -686,6 +686,7 @@ void bt_hci_le_per_adv_sync_established(struct net_buf *buf)
|
||||||
struct bt_le_per_adv_sync_synced_info sync_info;
|
struct bt_le_per_adv_sync_synced_info sync_info;
|
||||||
struct bt_le_per_adv_sync *pending_per_adv_sync;
|
struct bt_le_per_adv_sync *pending_per_adv_sync;
|
||||||
struct bt_le_per_adv_sync_cb *listener;
|
struct bt_le_per_adv_sync_cb *listener;
|
||||||
|
bool unexpected_evt;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
pending_per_adv_sync = get_pending_per_adv_sync();
|
pending_per_adv_sync = get_pending_per_adv_sync();
|
||||||
|
@ -716,22 +717,29 @@ void bt_hci_le_per_adv_sync_established(struct net_buf *buf)
|
||||||
BT_PER_ADV_SYNC_SYNCING_USE_LIST) &&
|
BT_PER_ADV_SYNC_SYNCING_USE_LIST) &&
|
||||||
((pending_per_adv_sync->sid != evt->sid) ||
|
((pending_per_adv_sync->sid != evt->sid) ||
|
||||||
bt_addr_le_cmp(&pending_per_adv_sync->addr, &evt->adv_addr)))) {
|
bt_addr_le_cmp(&pending_per_adv_sync->addr, &evt->adv_addr)))) {
|
||||||
struct bt_le_per_adv_sync_term_info term_info;
|
|
||||||
|
|
||||||
BT_ERR("Unexpected per adv sync established event");
|
BT_ERR("Unexpected per adv sync established event");
|
||||||
|
/* Request terminate of pending periodic advertising in controller */
|
||||||
per_adv_sync_terminate(sys_le16_to_cpu(evt->handle));
|
per_adv_sync_terminate(sys_le16_to_cpu(evt->handle));
|
||||||
|
|
||||||
|
unexpected_evt = true;
|
||||||
|
} else {
|
||||||
|
unexpected_evt = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unexpected_evt || evt->status != BT_HCI_ERR_SUCCESS) {
|
||||||
if (pending_per_adv_sync) {
|
if (pending_per_adv_sync) {
|
||||||
|
struct bt_le_per_adv_sync_term_info term_info;
|
||||||
|
|
||||||
/* Terminate the pending PA sync and notify app */
|
/* Terminate the pending PA sync and notify app */
|
||||||
term_info.addr = &pending_per_adv_sync->addr;
|
term_info.addr = &pending_per_adv_sync->addr;
|
||||||
term_info.sid = pending_per_adv_sync->sid;
|
term_info.sid = pending_per_adv_sync->sid;
|
||||||
|
term_info.reason = unexpected_evt ? BT_HCI_ERR_UNSPECIFIED : evt->status;
|
||||||
|
|
||||||
/* Deleting before callback, so the caller will be able
|
/* Deleting before callback, so the caller will be able
|
||||||
* to restart sync in the callback.
|
* to restart sync in the callback.
|
||||||
*/
|
*/
|
||||||
per_adv_sync_delete(pending_per_adv_sync);
|
per_adv_sync_delete(pending_per_adv_sync);
|
||||||
|
|
||||||
|
|
||||||
SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs,
|
SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs,
|
||||||
listener,
|
listener,
|
||||||
node) {
|
node) {
|
||||||
|
@ -787,6 +795,8 @@ void bt_hci_le_per_adv_sync_lost(struct net_buf *buf)
|
||||||
|
|
||||||
term_info.addr = &per_adv_sync->addr;
|
term_info.addr = &per_adv_sync->addr;
|
||||||
term_info.sid = per_adv_sync->sid;
|
term_info.sid = per_adv_sync->sid;
|
||||||
|
/* There is no status in the per. adv. sync lost event */
|
||||||
|
term_info.reason = BT_HCI_ERR_UNSPECIFIED;
|
||||||
|
|
||||||
/* Deleting before callback, so the caller will be able to restart
|
/* Deleting before callback, so the caller will be able to restart
|
||||||
* sync in the callback
|
* sync in the callback
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue