Skip to content

Commit b1653b8

Browse files
committed
Bluetooth: controller: Add/Remove ACAD on create/terminate BIG
Added implementation to add/remove ACAD field in the common extended header format of the periodic advertising PDU on create/terminate BIG. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent f3d9808 commit b1653b8

File tree

3 files changed

+169
-2
lines changed

3 files changed

+169
-2
lines changed

subsys/bluetooth/controller/ll_sw/ull_adv_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ void ull_adv_sync_update(struct ll_adv_sync_set *sync, uint32_t slot_plus_us,
187187
/* helper function to schedule a mayfly to get sync offset */
188188
void ull_adv_sync_offset_get(struct ll_adv_set *adv);
189189

190+
/* helper function to reserve ACAD field in PDU buffer */
191+
uint8_t ull_adv_sync_acad_enable(struct lll_adv_sync *lll_sync,
192+
uint8_t acad_len, void **acad);
193+
190194
int ull_adv_iso_init(void);
191195
int ull_adv_iso_reset(void);
192196

subsys/bluetooth/controller/ll_sw/ull_adv_iso.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
6363
struct node_rx_pdu *node_rx;
6464
struct ll_adv_iso *adv_iso;
6565
struct ll_adv_set *adv;
66+
uint8_t *acad;
67+
uint8_t err;
6668

6769
adv_iso = ull_adv_iso_get(big_handle);
6870

@@ -130,6 +132,17 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
130132
if (num_bis != 1) {
131133
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
132134
}
135+
136+
/* Add ACAD to AUX_SYNC_IND */
137+
err = ull_adv_sync_acad_enable(lll_adv_sync,
138+
(sizeof(struct pdu_big_info) + 2),
139+
(void **)&acad);
140+
if (err) {
141+
return err;
142+
}
143+
acad[0] = sizeof(struct pdu_big_info) + 1;
144+
acad[1] = BT_DATA_BIG_INFO;
145+
133146
/* TODO: For now we can just use the unique BIG handle as the BIS
134147
* handle until we support multiple BIS
135148
*/
@@ -146,8 +159,6 @@ uint8_t ll_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis,
146159
adv_iso->encryption = encryption;
147160
memcpy(adv_iso->bcode, bcode, sizeof(adv_iso->bcode));
148161

149-
/* TODO: Add ACAD to AUX_SYNC_IND */
150-
151162
/* TODO: start sending BIS empty data packet for each BIS */
152163
ull_adv_iso_start(adv_iso, 0 /* TODO: Calc ticks_anchor */);
153164

@@ -204,6 +215,7 @@ uint8_t ll_big_terminate(uint8_t big_handle, uint8_t reason)
204215
struct ll_adv_iso *adv_iso;
205216
struct lll_adv *lll_adv;
206217
uint32_t ret;
218+
uint8_t err;
207219

208220
adv_iso = ull_adv_iso_get(big_handle);
209221
if (!adv_iso) {
@@ -218,6 +230,12 @@ uint8_t ll_big_terminate(uint8_t big_handle, uint8_t reason)
218230

219231
lll_adv_sync = lll_adv->sync;
220232

233+
/* Remove ACAD to AUX_SYNC_IND */
234+
err = ull_adv_sync_acad_enable(lll_adv_sync, 0, NULL);
235+
if (err) {
236+
return err;
237+
}
238+
221239
/* TODO: Terminate all BIS data paths */
222240

223241
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,151 @@ uint8_t ull_adv_sync_pdu_alloc(struct ll_adv_set *adv,
790790
return 0;
791791
}
792792

793+
uint8_t ull_adv_sync_acad_enable(struct lll_adv_sync *lll_sync,
794+
uint8_t acad_len, void **acad)
795+
{
796+
struct pdu_adv_com_ext_adv *ter_com_hdr, *ter_com_hdr_prev;
797+
struct pdu_adv_ext_hdr *ter_hdr, ter_hdr_prev;
798+
struct pdu_adv *ter_pdu, *ter_pdu_prev;
799+
uint8_t *ter_dptr, *ter_dptr_prev;
800+
uint16_t ter_len, ter_len_prev;
801+
uint8_t acad_len_prev;
802+
uint8_t *ad_data;
803+
uint8_t ter_idx;
804+
uint8_t ad_len;
805+
806+
/* Get reference to previous tertiary PDU data */
807+
ter_pdu_prev = lll_adv_sync_data_peek(lll_sync, NULL);
808+
ter_com_hdr_prev = (void *)&ter_pdu_prev->adv_ext_ind;
809+
ter_hdr = (void *)ter_com_hdr_prev->ext_hdr_adv_data;
810+
ter_hdr_prev = *ter_hdr;
811+
ter_dptr_prev = ter_hdr->data;
812+
813+
/* Get reference to new tertiary PDU data buffer */
814+
ter_pdu = lll_adv_sync_data_alloc(lll_sync, NULL, &ter_idx);
815+
ter_pdu->type = ter_pdu_prev->type;
816+
ter_pdu->rfu = 0U;
817+
ter_pdu->chan_sel = 0U;
818+
ter_com_hdr = (void *)&ter_pdu->adv_ext_ind;
819+
ter_com_hdr->adv_mode = ter_com_hdr_prev->adv_mode;
820+
ter_hdr = (void *)ter_com_hdr->ext_hdr_adv_data;
821+
ter_dptr = ter_hdr->data;
822+
*(uint8_t *)ter_hdr = 0U;
823+
824+
/* No AdvA */
825+
/* No TargetA */
826+
827+
/* TODO: CTEInfo */
828+
829+
/* No ADI */
830+
831+
/* AuxPtr */
832+
if (ter_hdr_prev.aux_ptr) {
833+
ter_dptr_prev += sizeof(struct pdu_adv_aux_ptr);
834+
835+
ter_hdr->aux_ptr = 1;
836+
ter_dptr += sizeof(struct pdu_adv_aux_ptr);
837+
}
838+
839+
/* No SyncInfo */
840+
841+
/* Tx Power flag */
842+
if (ter_hdr_prev.tx_pwr) {
843+
ter_dptr_prev++;
844+
845+
ter_hdr->tx_pwr = 1;
846+
ter_dptr++;
847+
}
848+
849+
/* Calc previous ACAD len and update PDU len */
850+
ter_len_prev = ter_dptr_prev - (uint8_t *)ter_com_hdr_prev;
851+
if (ter_len_prev < (ter_com_hdr_prev->ext_hdr_len +
852+
offsetof(struct pdu_adv_com_ext_adv,
853+
ext_hdr_adv_data))) {
854+
acad_len_prev = ter_com_hdr_prev->ext_hdr_len +
855+
offsetof(struct pdu_adv_com_ext_adv,
856+
ext_hdr_adv_data) - ter_len_prev;
857+
ter_len_prev += acad_len_prev;
858+
ter_dptr_prev += acad_len_prev;
859+
} else {
860+
acad_len_prev = 0;
861+
ter_len_prev = offsetof(struct pdu_adv_com_ext_adv,
862+
ext_hdr_adv_data);
863+
ter_dptr_prev = (uint8_t *)ter_com_hdr_prev + ter_len_prev;
864+
}
865+
866+
/* Did we parse beyond PDU length? */
867+
if (ter_len_prev > ter_pdu_prev->len) {
868+
/* we should not encounter invalid length */
869+
return BT_HCI_ERR_UNSPECIFIED;
870+
}
871+
872+
/* Fill new ACAD */
873+
if (acad) {
874+
*acad = ter_dptr;
875+
ter_dptr += acad_len;
876+
}
877+
878+
/* Calc current tertiary PDU len */
879+
ter_len = ull_adv_aux_hdr_len_calc(ter_com_hdr, &ter_dptr);
880+
ull_adv_aux_hdr_len_fill(ter_com_hdr, ter_len);
881+
882+
/* Calc the previous AD data length in auxiliary PDU */
883+
ad_len = ter_pdu_prev->len - ter_len_prev;
884+
ad_data = ter_dptr_prev;
885+
886+
/* Add AD len to tertiary PDU length */
887+
ter_len += ad_len;
888+
889+
/* Check AdvData overflow */
890+
if (ter_len > PDU_AC_PAYLOAD_SIZE_MAX) {
891+
return BT_HCI_ERR_PACKET_TOO_LONG;
892+
}
893+
894+
/* set the tertiary PDU len */
895+
ter_pdu->len = ter_len;
896+
897+
/* Start filling tertiary PDU payload based on flags from here
898+
* ==============================================================
899+
*/
900+
901+
/* Fill AdvData in tertiary PDU */
902+
memmove(ter_dptr, ad_data, ad_len);
903+
904+
/* NOTE: ACAD in tertiary PDU is filled by the caller of this
905+
* function. Only decrement the new ACAD length.
906+
*/
907+
ter_dptr_prev -= acad_len_prev;
908+
if (acad) {
909+
ter_dptr -= acad_len;
910+
}
911+
912+
/* Tx Power */
913+
if (ter_hdr->tx_pwr) {
914+
*--ter_dptr = *--ter_dptr_prev;
915+
}
916+
917+
/* No SyncInfo in tertiary PDU */
918+
919+
/* AuxPtr */
920+
if (ter_hdr_prev.aux_ptr) {
921+
ter_dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
922+
923+
ull_adv_aux_ptr_fill(&ter_dptr, lll_sync->adv->phy_s);
924+
}
925+
926+
/* No ADI */
927+
928+
/* TODO: CTEInfo */
929+
930+
/* No TargetA*/
931+
/* No AdvA */
932+
933+
lll_adv_sync_data_enqueue(lll_sync, ter_idx);
934+
935+
return 0;
936+
}
937+
793938
/* @brief Set or clear fields in extended advertising header and store
794939
* extra_data if requested.
795940
*

0 commit comments

Comments
 (0)