Skip to content

Commit 02e2866

Browse files
cvinayaknordicjm
authored andcommitted
[nrf fromtree] Bluetooth: Controller: Fix device address in Periodic Adv Sync
Fix incorrect device address reported in the LE Periodic Advertising Sync Established event when using Periodic Advertiser List. During Extended Scanning there can be an ADV_EXT_IND PDU received between currently being received ADV_EXT_IND PDU and AUX_ADV_IND PDU; if the one received between has an address match then incorrectly the Periodic Synchronization was established to the device whos AUX_ADV_IND PDU is being received. Fix by storing the auxiliary context that has the address match and compare with it when matching the SID in SyncInfo of AUX_ADV_IND PDU being received prior to creating the synchronization. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]> (cherry picked from commit 83e2ec3) Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 59ae559 commit 02e2866

File tree

4 files changed

+94
-19
lines changed

4 files changed

+94
-19
lines changed

subsys/bluetooth/controller/ll_sw/ull_scan_aux.c

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -444,19 +444,30 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
444444

445445
ptr = h->data;
446446

447+
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
448+
bool is_aux_addr_match = false;
449+
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
450+
447451
if (h->adv_addr) {
448452
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
449453
/* Check if Periodic Advertising Synchronization to be created
450454
*/
451455
if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) {
452-
/* Check address and update internal state */
453456
#if defined(CONFIG_BT_CTLR_PRIVACY)
454-
ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr,
455-
ftr->rl_idx);
457+
uint8_t rl_idx = ftr->rl_idx;
456458
#else /* !CONFIG_BT_CTLR_PRIVACY */
457-
ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr, 0U);
459+
uint8_t rl_idx = 0U;
458460
#endif /* !CONFIG_BT_CTLR_PRIVACY */
459461

462+
/* Check address and update internal state */
463+
is_aux_addr_match =
464+
ull_sync_setup_addr_check(sync, scan->periodic.filter_policy,
465+
pdu->tx_addr, ptr, rl_idx);
466+
if (is_aux_addr_match) {
467+
scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH;
468+
} else {
469+
scan->periodic.state = LL_SYNC_STATE_IDLE;
470+
}
460471
}
461472
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
462473

@@ -489,14 +500,21 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
489500
si = (void *)ptr;
490501
ptr += sizeof(*si);
491502

503+
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
492504
/* Check if Periodic Advertising Synchronization to be created.
493505
* Setup synchronization if address and SID match in the
494506
* Periodic Advertiser List or with the explicitly supplied.
507+
*
508+
* is_aux_addr_match, device address in auxiliary channel PDU;
509+
* scan->periodic.param has not been assigned yet.
510+
* Otherwise, address was in primary channel PDU and we are now
511+
* checking SID (in SyncInfo) in auxiliary channel PDU.
495512
*/
496-
if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && aux && sync && adi &&
513+
if (sync && aux && (is_aux_addr_match || (scan->periodic.param == aux)) && adi &&
497514
ull_sync_setup_sid_match(sync, scan, PDU_ADV_ADI_SID_GET(adi))) {
498515
ull_sync_setup(scan, aux->lll.phy, rx, si);
499516
}
517+
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
500518
}
501519

502520
if (h->tx_pwr) {
@@ -692,6 +710,15 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
692710
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
693711

694712
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
713+
/* Store the aux context that has Periodic Advertising
714+
* Synchronization address match.
715+
*/
716+
if (sync && (scan->periodic.state == LL_SYNC_STATE_ADDR_MATCH)) {
717+
scan->periodic.param = aux;
718+
}
719+
720+
/* Store the node rx allocated for incomplete report, if needed.
721+
*/
695722
aux->rx_incomplete = rx_incomplete;
696723
rx_incomplete = NULL;
697724
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
@@ -916,6 +943,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
916943
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
917944
if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) {
918945
scan->periodic.state = LL_SYNC_STATE_IDLE;
946+
scan->periodic.param = NULL;
919947
}
920948
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
921949

@@ -1518,7 +1546,16 @@ static void ticker_op_cb(uint32_t status, void *param)
15181546
}
15191547

15201548
#else /* CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS */
1521-
1549+
/* NOTE: BT_CTLR_SCAN_AUX_USE_CHAINS is alternative new design with less RAM
1550+
* usage for supporting Extended Scanning of simultaneous interleaved
1551+
* Extended Advertising chains.
1552+
*
1553+
* TODO: As the previous design has Bluetooth Qualified Design Listing by
1554+
* Nordic Semiconductor ASA, both implementation are present in this file,
1555+
* and default builds use CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS=n. Remove old
1556+
* implementation when we have a new Bluetooth Qualified Design Listing
1557+
* with the new Extended Scanning and Periodic Sync implementation.
1558+
*/
15221559
void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
15231560
{
15241561
struct node_rx_pdu *rx_incomplete;
@@ -1778,19 +1815,30 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
17781815

17791816
ptr = h->data;
17801817

1818+
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
1819+
bool is_aux_addr_match = false;
1820+
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
1821+
17811822
if (h->adv_addr) {
17821823
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
17831824
/* Check if Periodic Advertising Synchronization to be created
17841825
*/
17851826
if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) {
1786-
/* Check address and update internal state */
17871827
#if defined(CONFIG_BT_CTLR_PRIVACY)
1788-
ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr,
1789-
ftr->rl_idx);
1828+
uint8_t rl_idx = ftr->rl_idx;
17901829
#else /* !CONFIG_BT_CTLR_PRIVACY */
1791-
ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr, 0U);
1830+
uint8_t rl_idx = 0U;
17921831
#endif /* !CONFIG_BT_CTLR_PRIVACY */
17931832

1833+
/* Check address and update internal state */
1834+
is_aux_addr_match =
1835+
ull_sync_setup_addr_check(sync, scan->periodic.filter_policy,
1836+
pdu->tx_addr, ptr, rl_idx);
1837+
if (is_aux_addr_match) {
1838+
scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH;
1839+
} else {
1840+
scan->periodic.state = LL_SYNC_STATE_IDLE;
1841+
}
17941842
}
17951843
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
17961844

@@ -1823,14 +1871,21 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
18231871
si = (void *)ptr;
18241872
ptr += sizeof(*si);
18251873

1874+
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
18261875
/* Check if Periodic Advertising Synchronization to be created.
18271876
* Setup synchronization if address and SID match in the
18281877
* Periodic Advertiser List or with the explicitly supplied.
1878+
*
1879+
* is_aux_addr_match, device address in auxiliary channel PDU;
1880+
* scan->periodic.param has not been assigned yet.
1881+
* Otherwise, address was in primary channel PDU and we are now
1882+
* checking SID (in SyncInfo) in auxiliary channel PDU.
18291883
*/
1830-
if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && chain && sync && adi &&
1831-
ull_sync_setup_sid_match(sync, scan, PDU_ADV_ADI_SID_GET(adi))) {
1884+
if (sync && chain && (is_aux_addr_match || (scan->periodic.param == chain)) &&
1885+
adi && ull_sync_setup_sid_match(sync, scan, PDU_ADV_ADI_SID_GET(adi))) {
18321886
ull_sync_setup(scan, chain->lll.phy, rx, si);
18331887
}
1888+
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
18341889
}
18351890

18361891
if (h->tx_pwr) {
@@ -2012,6 +2067,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
20122067
#endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */
20132068

20142069
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
2070+
/* Store the chain context that has Periodic Advertising
2071+
* Synchronization address match.
2072+
*/
2073+
if (sync && (scan->periodic.state == LL_SYNC_STATE_ADDR_MATCH)) {
2074+
scan->periodic.param = chain;
2075+
}
2076+
20152077
if (sync_lll) {
20162078
struct ll_sync_set *sync_set = HDR_LLL2ULL(sync_lll);
20172079

@@ -2153,6 +2215,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx)
21532215
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC)
21542216
if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) {
21552217
scan->periodic.state = LL_SYNC_STATE_IDLE;
2218+
scan->periodic.param = NULL;
21562219
}
21572220
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
21582221

subsys/bluetooth/controller/ll_sw/ull_scan_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ struct ll_scan_set {
3131
* cancelling sync create, hence the volatile keyword.
3232
*/
3333
struct ll_sync_set *volatile sync;
34+
35+
/* Non-NULL when Periodic Advertising Synchronisation address
36+
* matched.
37+
*/
38+
void *param;
3439
} periodic;
3540
#endif
3641
};

subsys/bluetooth/controller/ll_sw/ull_sync.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,13 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type,
152152

153153
scan->periodic.cancelled = 0U;
154154
scan->periodic.state = LL_SYNC_STATE_IDLE;
155+
scan->periodic.param = NULL;
155156
scan->periodic.filter_policy =
156157
options & BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_USE_LIST;
157158
if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
158159
scan_coded->periodic.cancelled = 0U;
159160
scan_coded->periodic.state = LL_SYNC_STATE_IDLE;
161+
scan_coded->periodic.param = NULL;
160162
scan_coded->periodic.filter_policy =
161163
scan->periodic.filter_policy;
162164
}
@@ -880,12 +882,12 @@ void ull_sync_release(struct ll_sync_set *sync)
880882
mem_release(sync, &sync_free);
881883
}
882884

883-
void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *scan,
885+
bool ull_sync_setup_addr_check(struct ll_sync_set *sync, uint8_t filter_policy,
884886
uint8_t addr_type, uint8_t *addr, uint8_t rl_idx)
885887
{
886888
/* Check if Periodic Advertiser list to be used */
887889
if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST) &&
888-
scan->periodic.filter_policy) {
890+
filter_policy) {
889891
/* Check in Periodic Advertiser List */
890892
if (ull_filter_ull_pal_addr_match(addr_type, addr)) {
891893
/* Remember the address, to check with
@@ -896,7 +898,7 @@ void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *sca
896898
BDADDR_SIZE);
897899

898900
/* Address matched */
899-
scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH;
901+
return true;
900902

901903
/* Check in Resolving List */
902904
} else if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY) &&
@@ -911,14 +913,14 @@ void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *sca
911913
sync->peer_addr_resolved = 1U;
912914

913915
/* Address matched */
914-
scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH;
916+
return true;
915917
}
916918

917919
/* Check with explicitly supplied address */
918920
} else if ((addr_type == sync->peer_id_addr_type) &&
919921
!memcmp(addr, sync->peer_id_addr, BDADDR_SIZE)) {
920922
/* Address matched */
921-
scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH;
923+
return true;
922924

923925
/* Check identity address with explicitly supplied address */
924926
} else if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY) &&
@@ -930,9 +932,11 @@ void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *sca
930932
sync->peer_addr_resolved = 1U;
931933

932934
/* Identity address matched */
933-
scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH;
935+
return true;
934936
}
935937
}
938+
939+
return false;
936940
}
937941

938942
bool ull_sync_setup_sid_match(struct ll_sync_set *sync, struct ll_scan_set *scan, uint8_t sid)
@@ -1060,6 +1064,7 @@ void ull_sync_setup(struct ll_scan_set *scan, uint8_t phy,
10601064

10611065
/* Set the state to sync create */
10621066
scan->periodic.state = LL_SYNC_STATE_CREATED;
1067+
scan->periodic.param = NULL;
10631068
if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) {
10641069
struct ll_scan_set *scan_1m;
10651070

@@ -1069,8 +1074,10 @@ void ull_sync_setup(struct ll_scan_set *scan, uint8_t phy,
10691074

10701075
scan_coded = ull_scan_set_get(SCAN_HANDLE_PHY_CODED);
10711076
scan_coded->periodic.state = LL_SYNC_STATE_CREATED;
1077+
scan_coded->periodic.param = NULL;
10721078
} else {
10731079
scan_1m->periodic.state = LL_SYNC_STATE_CREATED;
1080+
scan_1m->periodic.param = NULL;
10741081
}
10751082
}
10761083

subsys/bluetooth/controller/ll_sw/ull_sync_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ int ull_sync_reset(void);
99
uint16_t ull_sync_handle_get(struct ll_sync_set *sync);
1010
struct ll_sync_set *ull_sync_is_enabled_get(uint16_t handle);
1111
void ull_sync_release(struct ll_sync_set *sync);
12-
void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *scan,
12+
bool ull_sync_setup_addr_check(struct ll_sync_set *sync, uint8_t filter_policy,
1313
uint8_t addr_type, uint8_t *addr, uint8_t rl_idx);
1414
bool ull_sync_setup_sid_match(struct ll_sync_set *sync, struct ll_scan_set *scan, uint8_t sid);
1515
void ull_sync_create_from_sync_transfer(uint16_t conn_handle, uint16_t service_data,

0 commit comments

Comments
 (0)