Skip to content

Commit 616ebcf

Browse files
ppryga-nordiccfriedt
authored andcommitted
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 151a32d commit 616ebcf

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
@@ -920,7 +920,7 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
920920
void *hdr_data)
921921
{
922922
struct pdu_adv_com_ext_adv *ter_com_hdr, *ter_com_hdr_prev;
923-
struct pdu_adv_ext_hdr *ter_hdr, ter_hdr_prev;
923+
struct pdu_adv_ext_hdr ter_hdr = { 0 }, ter_hdr_prev = { 0 };
924924
uint8_t *ter_dptr, *ter_dptr_prev;
925925
uint8_t acad_len_prev;
926926
uint8_t ter_len_prev;
@@ -935,13 +935,10 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
935935

936936
/* Get common pointers from reference to previous tertiary PDU data */
937937
ter_com_hdr_prev = (void *)&ter_pdu_prev->adv_ext_ind;
938-
ter_hdr = (void *)ter_com_hdr_prev->ext_hdr_adv_data;
939-
if (ter_com_hdr_prev->ext_hdr_len) {
940-
ter_hdr_prev = *ter_hdr;
941-
} else {
942-
*(uint8_t *)&ter_hdr_prev = 0U;
938+
if (ter_com_hdr_prev->ext_hdr_len != 0) {
939+
ter_hdr_prev = ter_com_hdr_prev->ext_hdr;
943940
}
944-
ter_dptr_prev = ter_hdr->data;
941+
ter_dptr_prev = ter_com_hdr_prev->ext_hdr.data;
945942

946943
/* Set common fields in reference to new tertiary PDU data buffer */
947944
ter_pdu->type = ter_pdu_prev->type;
@@ -951,26 +948,29 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
951948
ter_pdu->tx_addr = ter_pdu_prev->tx_addr;
952949
ter_pdu->rx_addr = ter_pdu_prev->rx_addr;
953950

951+
/* Get common pointers from current tertiary PDU data.
952+
* It is possbile that the current tertiary is the same as
953+
* previous one. It may happen if update periodic advertising
954+
* chain in place.
955+
*/
954956
ter_com_hdr = (void *)&ter_pdu->adv_ext_ind;
955957
ter_com_hdr->adv_mode = ter_com_hdr_prev->adv_mode;
956-
ter_hdr = (void *)ter_com_hdr->ext_hdr_adv_data;
957-
ter_dptr = ter_hdr->data;
958-
*(uint8_t *)ter_hdr = 0U;
958+
ter_dptr = ter_com_hdr->ext_hdr.data;
959959

960960
/* No AdvA in AUX_SYNC_IND */
961961
/* No TargetA in AUX_SYNC_IND */
962962

963963
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
964964
/* If requested add or update CTEInfo */
965965
if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
966-
ter_hdr->cte_info = 1;
966+
ter_hdr.cte_info = 1;
967967
cte_info = *(uint8_t *)hdr_data;
968968
hdr_data = (uint8_t *)hdr_data + 1;
969969
ter_dptr += sizeof(struct pdu_cte_info);
970970
/* If CTEInfo exists in prev and is not requested to be removed */
971971
} else if (!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) &&
972972
ter_hdr_prev.cte_info) {
973-
ter_hdr->cte_info = 1;
973+
ter_hdr.cte_info = 1;
974974
ter_dptr += sizeof(struct pdu_cte_info);
975975
}
976976

@@ -986,9 +986,9 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
986986
if ((hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) ||
987987
(!(hdr_rem_fields & ULL_ADV_PDU_HDR_FIELD_AUX_PTR) &&
988988
ter_hdr_prev.aux_ptr)) {
989-
ter_hdr->aux_ptr = 1;
989+
ter_hdr.aux_ptr = 1;
990990
}
991-
if (ter_hdr->aux_ptr) {
991+
if (ter_hdr.aux_ptr) {
992992
ter_dptr += sizeof(struct pdu_adv_aux_ptr);
993993
}
994994
if (ter_hdr_prev.aux_ptr) {
@@ -1001,7 +1001,7 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
10011001
if (ter_hdr_prev.tx_pwr) {
10021002
ter_dptr_prev++;
10031003

1004-
ter_hdr->tx_pwr = 1;
1004+
ter_hdr.tx_pwr = 1;
10051005
ter_dptr++;
10061006
}
10071007

@@ -1010,10 +1010,15 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
10101010
hdr_buf_len = ter_com_hdr_prev->ext_hdr_len +
10111011
PDU_AC_EXT_HEADER_SIZE_MIN;
10121012
if (ter_len_prev <= hdr_buf_len) {
1013+
/* There are some data, except ACAD, in extended header if ter_len_prev
1014+
* equals to hdr_buf_len. There is ACAD if the size of ter_len_prev
1015+
* is smaller than hdr_buf_len.
1016+
*/
10131017
acad_len_prev = hdr_buf_len - ter_len_prev;
10141018
ter_len_prev += acad_len_prev;
10151019
ter_dptr_prev += acad_len_prev;
10161020
} else {
1021+
/* There are no data in extended header, all flags are zeros. */
10171022
acad_len_prev = 0;
10181023
/* NOTE: If no flags are set then extended header length will be
10191024
* zero. Under this condition the current ter_len_prev
@@ -1096,14 +1101,14 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
10961101
}
10971102

10981103
/* Tx Power */
1099-
if (ter_hdr->tx_pwr) {
1104+
if (ter_hdr.tx_pwr) {
11001105
*--ter_dptr = *--ter_dptr_prev;
11011106
}
11021107

11031108
/* No SyncInfo in AUX_SYNC_IND */
11041109

11051110
/* AuxPtr */
1106-
if (ter_hdr->aux_ptr) {
1111+
if (ter_hdr.aux_ptr) {
11071112
/* ToDo Update setup of aux_ptr - check documentation */
11081113
if (ter_hdr_prev.aux_ptr) {
11091114
ter_dptr_prev -= sizeof(struct pdu_adv_aux_ptr);
@@ -1118,7 +1123,7 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
11181123
/* No ADI in AUX_SYNC_IND*/
11191124

11201125
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
1121-
if (ter_hdr->cte_info) {
1126+
if (ter_hdr.cte_info) {
11221127
if (hdr_add_fields & ULL_ADV_PDU_HDR_FIELD_CTE_INFO) {
11231128
*--ter_dptr = cte_info;
11241129
} else {
@@ -1130,6 +1135,10 @@ uint8_t ull_adv_sync_pdu_set_clear(struct lll_adv_sync *lll_sync,
11301135
/* No TargetA in AUX_SYNC_IND */
11311136
/* No AdvA in AUX_SYNC_IND */
11321137

1138+
if (ter_com_hdr->ext_hdr_len != 0) {
1139+
ter_com_hdr->ext_hdr = ter_hdr;
1140+
}
1141+
11331142
return 0;
11341143
}
11351144

0 commit comments

Comments
 (0)