Skip to content

Commit 5aee904

Browse files
committed
Bluetooth: controller: ULL: ull_adv_sync_hdr_set_clear update PDU in place
Enabling or disabling transmission of Constant Tone Extension with periodic advertising PDUs requires update of a PDU content. CTE_INFO field of periodic advertising PDU must be filled with appropriate data. That operation may be done for periodic advertising PDU (or chain of PDUs) filled with other payload that wasn't enqueued towards LLL. In that situation PDUs are updated in place, to avoid increase of memory consumption. The commit changes ull_adv_sync_pdu_set_clear function to make possible update of the advertising PDU in place. Signed-off-by: Piotr Pryga <[email protected]>
1 parent e7efb85 commit 5aee904

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

subsys/bluetooth/controller/ll_sw/ull_adv_sync.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
884884
void *hdr_data)
885885
{
886886
struct pdu_adv_com_ext_adv *ter_com_hdr, *ter_com_hdr_prev;
887-
struct pdu_adv_ext_hdr *ter_hdr, ter_hdr_prev;
887+
struct pdu_adv_ext_hdr ter_hdr = { 0 }, ter_hdr_prev = { 0 };
888888
uint8_t *ter_dptr, *ter_dptr_prev;
889889
uint8_t acad_len_prev;
890890
uint8_t ter_len_prev;
@@ -899,13 +899,10 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
899899

900900
/* Get common pointers from reference to previous tertiary PDU data */
901901
ter_com_hdr_prev = (void *)&ter_pdu_prev->adv_ext_ind;
902-
ter_hdr = (void *)ter_com_hdr_prev->ext_hdr_adv_data;
903-
if (ter_com_hdr_prev->ext_hdr_len) {
904-
ter_hdr_prev = *ter_hdr;
905-
} else {
906-
*(uint8_t *)&ter_hdr_prev = 0U;
902+
if (ter_com_hdr_prev->ext_hdr_len != 0) {
903+
ter_hdr_prev = ter_com_hdr_prev->ext_hdr;
907904
}
908-
ter_dptr_prev = ter_hdr->data;
905+
ter_dptr_prev = ter_com_hdr_prev->ext_hdr.data;
909906

910907
/* Set common fields in reference to new tertiary PDU data buffer */
911908
ter_pdu->type = ter_pdu_prev->type;
@@ -915,26 +912,29 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
915912
ter_pdu->tx_addr = ter_pdu_prev->tx_addr;
916913
ter_pdu->rx_addr = ter_pdu_prev->rx_addr;
917914

915+
/* Get common pointers from current tertiary PDU data.
916+
* It is possbile that the current tertiary is the same as
917+
* previous one. It may happen if update periodic advertising
918+
* chain in place.
919+
*/
918920
ter_com_hdr = (void *)&ter_pdu->adv_ext_ind;
919921
ter_com_hdr->adv_mode = ter_com_hdr_prev->adv_mode;
920-
ter_hdr = (void *)ter_com_hdr->ext_hdr_adv_data;
921-
ter_dptr = ter_hdr->data;
922-
*(uint8_t *)ter_hdr = 0U;
922+
ter_dptr = ter_com_hdr->ext_hdr.data;
923923

924924
/* No AdvA in AUX_SYNC_IND */
925925
/* No TargetA in AUX_SYNC_IND */
926926

927927
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
928928
/* If requested add or update CTEInfo */
929929
if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
930-
ter_hdr->cte_info = 1;
930+
ter_hdr.cte_info = 1;
931931
cte_info = *(uint8_t *)hdr_data;
932932
hdr_data = (uint8_t *)hdr_data + 1;
933933
ter_dptr += sizeof(struct pdu_cte_info);
934934
/* If CTEInfo exists in prev and is not requested to be removed */
935935
} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) &&
936936
ter_hdr_prev.cte_info) {
937-
ter_hdr->cte_info = 1;
937+
ter_hdr.cte_info = 1;
938938
ter_dptr += sizeof(struct pdu_cte_info);
939939
}
940940

@@ -950,9 +950,9 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
950950
if ((hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) ||
951951
(!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) &&
952952
ter_hdr_prev.aux_ptr)) {
953-
ter_hdr->aux_ptr = 1;
953+
ter_hdr.aux_ptr = 1;
954954
}
955-
if (ter_hdr->aux_ptr) {
955+
if (ter_hdr.aux_ptr) {
956956
ter_dptr += sizeof(struct pdu_adv_aux_ptr);
957957
}
958958
if (ter_hdr_prev.aux_ptr) {
@@ -965,7 +965,7 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
965965
if (ter_hdr_prev.tx_pwr) {
966966
ter_dptr_prev++;
967967

968-
ter_hdr->tx_pwr = 1;
968+
ter_hdr.tx_pwr = 1;
969969
ter_dptr++;
970970
}
971971

@@ -974,10 +974,15 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
974974
hdr_buf_len = ter_com_hdr_prev->ext_hdr_len +
975975
PDU_AC_EXT_HEADER_SIZE_MIN;
976976
if (ter_len_prev <= hdr_buf_len) {
977+
/* There are some data, except ACAD, in extended header if ter_len_prev
978+
* equals to hdr_buf_len. There is ACAD if the size of ter_len_prev
979+
* is smaller than hdr_buf_len.
980+
*/
977981
acad_len_prev = hdr_buf_len - ter_len_prev;
978982
ter_len_prev += acad_len_prev;
979983
ter_dptr_prev += acad_len_prev;
980984
} else {
985+
/* There are no data in extended header, all flags are zeros. */
981986
acad_len_prev = 0;
982987
/* NOTE: If no flags are set then extended header length will be
983988
* zero. Under this condition the current ter_len_prev
@@ -1060,14 +1065,14 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
10601065
}
10611066

10621067
/* Tx Power */
1063-
if (ter_hdr->tx_pwr) {
1068+
if (ter_hdr.tx_pwr) {
10641069
*--ter_dptr = *--ter_dptr_prev;
10651070
}
10661071

10671072
/* No SyncInfo in AUX_SYNC_IND */
10681073

10691074
/* AuxPtr */
1070-
if (ter_hdr->aux_ptr) {
1075+
if (ter_hdr.aux_ptr) {
10711076
/* ToDo Update setup of aux_ptr - check documentation */
10721077
if (ter_hdr_prev.aux_ptr) {
10731078
ter_dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
@@ -1082,7 +1087,7 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
10821087
/* No ADI in AUX_SYNC_IND*/
10831088

10841089
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
1085-
if (ter_hdr->cte_info) {
1090+
if (ter_hdr.cte_info) {
10861091
if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
10871092
*--ter_dptr = cte_info;
10881093
} else {
@@ -1094,6 +1099,10 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
10941099
/* No TargetA in AUX_SYNC_IND */
10951100
/* No AdvA in AUX_SYNC_IND */
10961101

1102+
if (ter_com_hdr->ext_hdr_len != 0) {
1103+
ter_com_hdr->ext_hdr = ter_hdr;
1104+
}
1105+
10971106
return 0;
10981107
}
10991108

0 commit comments

Comments
 (0)