Skip to content

Commit 155405e

Browse files
committed
Bluetooth: controller: Refactor sync_info population
Based on review comments, refactor out sync_info population to be performed by the caller of the function that prepares the extended advertising PDU. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 7296a6e commit 155405e

File tree

4 files changed

+123
-86
lines changed

4 files changed

+123
-86
lines changed

subsys/bluetooth/controller/ll_sw/ull_adv.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2020 Nordic Semiconductor ASA
2+
* Copyright (c) 2016-2021 Nordic Semiconductor ASA
33
* Copyright (c) 2016 Vinayak Kariappa Chettimada
44
*
55
* SPDX-License-Identifier: Apache-2.0
@@ -10,6 +10,7 @@
1010
#include <zephyr.h>
1111
#include <soc.h>
1212
#include <bluetooth/hci.h>
13+
#include <sys/byteorder.h>
1314

1415
#include "hal/cpu.h"
1516
#include "hal/ccm.h"
@@ -1208,14 +1209,24 @@ uint8_t ll_adv_enable(uint8_t enable)
12081209
if (lll->sync) {
12091210
sync = HDR_LLL2ULL(lll->sync);
12101211
if (sync->is_enabled && !sync->is_started) {
1212+
struct pdu_adv_sync_info *sync_info;
1213+
uint8_t value[1 + sizeof(sync_info)];
12111214
uint8_t err;
12121215

12131216
err = ull_adv_aux_hdr_set_clear(adv,
12141217
ULL_ADV_PDU_HDR_FIELD_SYNC_INFO,
1215-
0, NULL, NULL, &pri_idx);
1218+
0, value, NULL, &pri_idx);
12161219
if (err) {
12171220
return err;
12181221
}
1222+
1223+
/* First byte in the length-value encoded
1224+
* parameter is size of sync_info structure,
1225+
* followed by pointer to sync_info in the
1226+
* PDU.
1227+
*/
1228+
memcpy(&sync_info, &value[1], sizeof(sync_info));
1229+
ull_adv_sync_info_fill(sync, sync_info);
12191230
} else {
12201231
/* Do not start periodic advertising */
12211232
sync = NULL;

subsys/bluetooth/controller/ll_sw/ull_adv_aux.c

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
2+
* Copyright (c) 2017-2021 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -22,7 +22,6 @@
2222
#include "pdu.h"
2323

2424
#include "lll.h"
25-
#include "lll_clock.h"
2625
#include "lll/lll_vendor.h"
2726
#include "lll/lll_adv_types.h"
2827
#include "lll_adv.h"
@@ -47,10 +46,6 @@ static int init_reset(void);
4746
#if (CONFIG_BT_CTLR_ADV_AUX_SET > 0)
4847
static inline struct ll_adv_aux_set *aux_acquire(void);
4948
static inline void aux_release(struct ll_adv_aux_set *aux);
50-
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
51-
static inline void sync_info_fill(struct lll_adv_sync *lll_sync,
52-
uint8_t **dptr);
53-
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
5449
static void mfy_aux_offset_get(void *param);
5550
static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
5651
uint16_t lazy, uint8_t force, void *param);
@@ -441,6 +436,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
441436
struct pdu_adv_ext_hdr *sec_hdr, sec_hdr_prev;
442437
struct pdu_adv *pri_pdu, *pri_pdu_prev;
443438
struct pdu_adv *sec_pdu_prev, *sec_pdu;
439+
struct pdu_adv_sync_info *sync_info;
444440
uint8_t *pri_dptr, *pri_dptr_prev;
445441
uint8_t *sec_dptr, *sec_dptr_prev;
446442
uint8_t pri_len, sec_len_prev;
@@ -611,16 +607,30 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
611607

612608
/* No SyncInfo flag in primary channel PDU */
613609
/* Add/Remove SyncInfo flag in secondary channel PDU */
614-
if ((sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_SYNC_INFO) ||
615-
(!(sec_hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_SYNC_INFO) &&
616-
sec_hdr_prev.sync_info)) {
610+
if (sec_hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_SYNC_INFO) {
617611
sec_hdr->sync_info = 1;
618-
}
619-
if (sec_hdr_prev.sync_info) {
620-
sec_dptr_prev += sizeof(struct pdu_adv_sync_info);
621-
}
622-
if (sec_hdr->sync_info) {
623-
sec_dptr += sizeof(struct pdu_adv_sync_info);
612+
sync_info = NULL;
613+
614+
/* return the size of sync info structure */
615+
*(uint8_t *)value = sizeof(*sync_info);
616+
value = (uint8_t *)value + 1;
617+
618+
/* return the pointer to sync info struct inside the PDU
619+
* buffer
620+
*/
621+
memcpy(value, &sec_dptr, sizeof(sec_dptr));
622+
value = (uint8_t *)value + sizeof(sec_dptr);
623+
624+
sec_dptr += sizeof(*sync_info);
625+
} else if (!(sec_hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_SYNC_INFO) &&
626+
sec_hdr_prev.sync_info) {
627+
sec_hdr->sync_info = 1;
628+
sync_info = (void *)sec_dptr_prev;
629+
630+
sec_dptr_prev += sizeof(*sync_info);
631+
sec_dptr += sizeof(*sync_info);
632+
} else {
633+
sync_info = NULL;
624634
}
625635

626636
/* Tx Power flag */
@@ -724,10 +734,15 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
724734
/* No SyncInfo in primary channel PDU */
725735
/* Fill SyncInfo in secondary channel PDU */
726736
if (sec_hdr_prev.sync_info) {
727-
sec_dptr_prev -= sizeof(struct pdu_adv_sync_info);
737+
sec_dptr_prev -= sizeof(*sync_info);
728738
}
739+
729740
if (sec_hdr->sync_info) {
730-
sync_info_fill(lll->sync, &sec_dptr);
741+
sec_dptr -= sizeof(*sync_info);
742+
}
743+
744+
if (sync_info) {
745+
memmove(sec_dptr, sync_info, sizeof(*sync_info));
731746
}
732747
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
733748

@@ -1016,37 +1031,6 @@ inline uint8_t ull_adv_aux_handle_get(struct ll_adv_aux_set *aux)
10161031
sizeof(struct ll_adv_aux_set));
10171032
}
10181033

1019-
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
1020-
static inline void sync_info_fill(struct lll_adv_sync *lll_sync,
1021-
uint8_t **dptr)
1022-
{
1023-
struct ll_adv_sync_set *sync;
1024-
struct pdu_adv_sync_info *si;
1025-
1026-
*dptr -= sizeof(*si);
1027-
si = (void *)*dptr;
1028-
1029-
/* NOTE: sync offset and offset unit filled by secondary prepare */
1030-
si->offs_units = 0U;
1031-
/* If sync_info is part of ADV PDU the offs_adjust field
1032-
* is always set to 0.
1033-
*/
1034-
si->offs_adjust = 0U;
1035-
si->offs = 0U;
1036-
1037-
sync = HDR_LLL2ULL(lll_sync);
1038-
si->interval = sys_cpu_to_le16(sync->interval);
1039-
memcpy(si->sca_chm, lll_sync->data_chan_map,
1040-
sizeof(si->sca_chm));
1041-
si->sca_chm[4] &= 0x1f;
1042-
si->sca_chm[4] |= lll_clock_sca_local_get() << 5;
1043-
memcpy(&si->aa, lll_sync->access_addr, sizeof(si->aa));
1044-
memcpy(si->crc_init, lll_sync->crc_init, sizeof(si->crc_init));
1045-
1046-
si->evt_cntr = 0U; /* NOTE: Filled by secondary prepare */
1047-
}
1048-
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
1049-
10501034
static void mfy_aux_offset_get(void *param)
10511035
{
10521036
struct ll_adv_set *adv = param;

subsys/bluetooth/controller/ll_sw/ull_adv_internal.h

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
2+
* Copyright (c) 2017-2021 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -111,39 +111,6 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
111111
struct pdu_adv_adi *adi,
112112
uint8_t *pri_idx);
113113

114-
/* helper function to release periodic advertising instance */
115-
void ull_adv_sync_release(struct ll_adv_sync_set *sync);
116-
117-
/* helper function to allocate new PDU data for AUX_SYNC_IND and return
118-
* previous and new PDU for further processing.
119-
*/
120-
uint8_t ull_adv_sync_pdu_alloc(struct ll_adv_set *adv,
121-
uint16_t hdr_add_fields,
122-
uint16_t hdr_rem_fields,
123-
struct ull_adv_ext_hdr_data *hdr_data,
124-
struct pdu_adv **ter_pdu_prev,
125-
struct pdu_adv **ter_pdu_new,
126-
void **extra_data_prev,
127-
void **extra_data_new,
128-
uint8_t *ter_idx);
129-
130-
/* helper function to set/clear common extended header format fields
131-
* for AUX_SYNC_IND PDU.
132-
*/
133-
uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
134-
struct pdu_adv *ter_pdu_prev,
135-
struct pdu_adv *ter_pdu,
136-
uint16_t hdr_add_fields,
137-
uint16_t hdr_rem_fields,
138-
struct ull_adv_ext_hdr_data *hdr_data);
139-
140-
/* helper function to update extra_data field */
141-
void ull_adv_sync_extra_data_set_clear(void *extra_data_prev,
142-
void *extra_data_new,
143-
uint16_t hdr_add_fields,
144-
uint16_t hdr_rem_fields,
145-
void *data);
146-
147114
/* helper function to calculate common ext adv payload header length and
148115
* adjust the data pointer.
149116
* NOTE: This function reverts the header data pointer if there is no
@@ -184,10 +151,47 @@ uint32_t ull_adv_sync_start(struct ll_adv_set *adv,
184151
struct ll_adv_sync_set *sync,
185152
uint32_t ticks_anchor);
186153

154+
/* helper function to release periodic advertising instance */
155+
void ull_adv_sync_release(struct ll_adv_sync_set *sync);
156+
157+
/* helper function to fill initial value of sync_info structure */
158+
void ull_adv_sync_info_fill(struct ll_adv_sync_set *sync,
159+
struct pdu_adv_sync_info *si);
160+
187161
/* helper function to update periodic advertising event length */
188162
void ull_adv_sync_update(struct ll_adv_sync_set *sync, uint32_t slot_plus_us,
189163
uint32_t slot_minus_us);
190164

165+
/* helper function to allocate new PDU data for AUX_SYNC_IND and return
166+
* previous and new PDU for further processing.
167+
*/
168+
uint8_t ull_adv_sync_pdu_alloc(struct ll_adv_set *adv,
169+
uint16_t hdr_add_fields,
170+
uint16_t hdr_rem_fields,
171+
struct ull_adv_ext_hdr_data *hdr_data,
172+
struct pdu_adv **ter_pdu_prev,
173+
struct pdu_adv **ter_pdu_new,
174+
void **extra_data_prev,
175+
void **extra_data_new,
176+
uint8_t *ter_idx);
177+
178+
/* helper function to set/clear common extended header format fields
179+
* for AUX_SYNC_IND PDU.
180+
*/
181+
uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
182+
struct pdu_adv *ter_pdu_prev,
183+
struct pdu_adv *ter_pdu,
184+
uint16_t hdr_add_fields,
185+
uint16_t hdr_rem_fields,
186+
struct ull_adv_ext_hdr_data *hdr_data);
187+
188+
/* helper function to update extra_data field */
189+
void ull_adv_sync_extra_data_set_clear(void *extra_data_prev,
190+
void *extra_data_new,
191+
uint16_t hdr_add_fields,
192+
uint16_t hdr_rem_fields,
193+
void *data);
194+
191195
/* helper function to schedule a mayfly to get sync offset */
192196
void ull_adv_sync_offset_get(struct ll_adv_set *adv);
193197

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
2+
* Copyright (c) 2017-2021 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -22,6 +22,7 @@
2222
#include "pdu.h"
2323

2424
#include "lll.h"
25+
#include "lll_clock.h"
2526
#include "lll/lll_vendor.h"
2627
#include "lll/lll_adv_types.h"
2728
#include "lll_adv.h"
@@ -525,6 +526,8 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
525526
}
526527

527528
if (adv->is_enabled && !sync->is_started) {
529+
struct pdu_adv_sync_info *sync_info;
530+
uint8_t value[1 + sizeof(sync_info)];
528531
uint32_t ticks_slot_overhead_aux;
529532
struct lll_adv_aux *lll_aux;
530533
struct ll_adv_aux_set *aux;
@@ -537,11 +540,18 @@ uint8_t ll_adv_sync_enable(uint8_t handle, uint8_t enable)
537540
/* Add sync_info into auxiliary PDU */
538541
err = ull_adv_aux_hdr_set_clear(adv,
539542
ULL_ADV_PDU_HDR_FIELD_SYNC_INFO,
540-
0, NULL, NULL, &pri_idx);
543+
0, value, NULL, &pri_idx);
541544
if (err) {
542545
return err;
543546
}
544547

548+
/* First byte in the length-value encoded parameter is size of
549+
* sync_info structure, followed by pointer to sync_info in the
550+
* PDU.
551+
*/
552+
memcpy(&sync_info, &value[1], sizeof(sync_info));
553+
ull_adv_sync_info_fill(sync, sync_info);
554+
545555
if (lll_aux) {
546556
/* FIXME: Find absolute ticks until after auxiliary PDU
547557
* on air to place the periodic advertising PDU.
@@ -695,6 +705,34 @@ void ull_adv_sync_release(struct ll_adv_sync_set *sync)
695705
sync_release(sync);
696706
}
697707

708+
void ull_adv_sync_info_fill(struct ll_adv_sync_set *sync,
709+
struct pdu_adv_sync_info *si)
710+
{
711+
struct lll_adv_sync *lll_sync;
712+
713+
/* NOTE: sync offset and offset unit filled by secondary prepare.
714+
*
715+
* If sync_info is part of ADV PDU the offs_adjust field
716+
* is always set to 0.
717+
*/
718+
si->offs_units = 0U;
719+
si->offs_adjust = 0U;
720+
si->offs = 0U;
721+
722+
/* Fill the interval, channel map, access address and CRC init */
723+
si->interval = sys_cpu_to_le16(sync->interval);
724+
lll_sync = &sync->lll;
725+
memcpy(si->sca_chm, lll_sync->data_chan_map,
726+
sizeof(si->sca_chm));
727+
si->sca_chm[4] &= 0x1f;
728+
si->sca_chm[4] |= lll_clock_sca_local_get() << 5;
729+
memcpy(&si->aa, lll_sync->access_addr, sizeof(si->aa));
730+
memcpy(si->crc_init, lll_sync->crc_init, sizeof(si->crc_init));
731+
732+
/* NOTE: Filled by secondary prepare */
733+
si->evt_cntr = 0U;
734+
}
735+
698736
void ull_adv_sync_offset_get(struct ll_adv_set *adv)
699737
{
700738
static memq_link_t link;

0 commit comments

Comments
 (0)