Skip to content

Commit aecdf4c

Browse files
ppryga-nordicThalley
authored andcommitted
Bluetooth: controller: df: fix error in remove CTE from per adv
cte_info_clear function is responsible for remove of CTE from periodic advertising PDUs, including remove from optional chained PDUs. The function uses subortinate function rem_cte_info_from_per_- adv_chain to remove CTE from chained PDUs. The rem_cte_info_from_per_adv_chain had pdu_prev and pdu as arguments. After return from the function the pdu_prev should point to last PDU from previously used periodic advertising data and pdu should point to last new periodic advertising data. The rem_cte_info_from_per_adv_chain function removes CTEInfo from all but last one PDU. Last PDU must have removed AuxPtr field also. Remove of CTEInfo and AuxPtr from last PDU is done explicitly in the cte_info_clear function. Unfortunately rem_cte_info_from_per_adv_chain had wrong type of parameters for pdu_prev and pdu. These parameters were pointers instead od double pointers. That caused cte_info_clear function to remove CTEInfo and AuxPtr from first PDU in a chain, which is AUX_SYNC_IND. Changed parameters pdu_prev and pdu in the rem_cte_info_from_per_adv_- chain to be double pointers. Added small corrections in comments. Signed-off-by: Piotr Pryga <[email protected]> Co-authored-by: Emil Gydesen <[email protected]>
1 parent 4e43295 commit aecdf4c

File tree

1 file changed

+19
-23
lines changed
  • subsys/bluetooth/controller/ll_sw

1 file changed

+19
-23
lines changed

subsys/bluetooth/controller/ll_sw/ull_df.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -722,10 +722,8 @@ static uint8_t cte_info_set(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_cf
722722
cte_info.type = df_cfg->cte_type;
723723
cte_info.time = df_cfg->cte_length;
724724

725-
/* Note: ULL_ADV_PDU_HDR_FIELD_CTE_INFO is just information that extra_data
725+
/* Note: ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS is just information that extra_data
726726
* is required in case of this ull_adv_sync_pdu_alloc.
727-
* Other flags here do not change anything. It may be changed to use
728-
* true/false flag for extra_data allocation.
729727
*/
730728
err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_ALWAYS, &pdu_prev, &pdu,
731729
NULL, &extra_data, ter_idx);
@@ -802,17 +800,17 @@ static bool pdu_ext_adv_is_empty_without_cte(const struct pdu_adv *pdu)
802800
* advertising chain. If particular PDU is empty (holds cte_info only) it will be removed from
803801
* chain.
804802
*
805-
* @param lll_sync Pointer to periodic advertising sync object.
806-
* @param pdu_prev Pointer to a PDU that is already in use by LLL or was updated with new PDU
807-
* payload.
808-
* @param pdu Pointer to a new head of periodic advertising chain. The pointer may have
809-
* the same value as @p pdu_prev, if payload of PDU pointerd by @p pdu_prev was
810-
* already updated.
803+
* @param[in] lll_sync Pointer to periodic advertising sync object.
804+
* @param[in-out] pdu_prev Pointer to a PDU that is already in use by LLL or was updated with new
805+
* PDU payload. Points to last PDU in a previous chain after return.
806+
* @param[in-out] pdu Pointer to a new head of periodic advertising chain. The pointer may have
807+
* the same value as @p pdu_prev, if payload of PDU pointerd by @p pdu_prev
808+
* was already updated. Points to last PDU in a new chain after return.
811809
*
812810
* @return Zero in case of success, other value in case of failure.
813811
*/
814812
static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
815-
struct pdu_adv *pdu_prev, struct pdu_adv *pdu)
813+
struct pdu_adv **pdu_prev, struct pdu_adv **pdu)
816814
{
817815
struct pdu_adv *pdu_new, *pdu_chained;
818816
uint8_t pdu_rem_field_flags;
@@ -826,12 +824,12 @@ static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
826824
* new chain then. Reuse already allocated PDUs and allocate new ones only if the chain
827825
* was not updated yet.
828826
*/
829-
new_chain = (pdu_prev == pdu ? false : true);
827+
new_chain = (*pdu_prev == *pdu ? false : true);
830828

831829
/* Get next PDU in a chain. Alway use pdu_prev because it points to actual
832830
* former chain.
833831
*/
834-
pdu_chained = lll_adv_pdu_linked_next_get(pdu_prev);
832+
pdu_chained = lll_adv_pdu_linked_next_get(*pdu_prev);
835833

836834
/* Go through existing chain and remove CTE info. */
837835
while (pdu_chained) {
@@ -844,10 +842,10 @@ static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
844842
* is changed in rigth place by use of pdu_prev. That makes sure there
845843
* is no PDU released twice (here and when LLL swaps PDU buffers).
846844
*/
847-
lll_adv_pdu_linked_append(NULL, pdu_prev);
845+
lll_adv_pdu_linked_append(NULL, *pdu_prev);
848846
} else {
849847
/* Update one before pdu_chained */
850-
err = ull_adv_sync_pdu_set_clear(lll_sync, pdu_prev, pdu, 0,
848+
err = ull_adv_sync_pdu_set_clear(lll_sync, *pdu_prev, *pdu, 0,
851849
pdu_rem_field_flags, NULL);
852850
if (err != BT_HCI_ERR_SUCCESS) {
853851
/* TODO: return here leaves periodic advertising chain in
@@ -861,17 +859,17 @@ static uint8_t rem_cte_info_from_per_adv_chain(struct lll_adv_sync *lll_sync,
861859
*/
862860
if (new_chain) {
863861
pdu_new = lll_adv_pdu_alloc_pdu_adv();
864-
lll_adv_pdu_linked_append(pdu_new, pdu);
865-
pdu = pdu_new;
862+
lll_adv_pdu_linked_append(pdu_new, *pdu);
863+
*pdu = pdu_new;
866864
} else {
867-
pdu = lll_adv_pdu_linked_next_get(pdu);
865+
*pdu = lll_adv_pdu_linked_next_get(*pdu);
868866
}
869867

870868
/* Move to next chained PDU (it moves through chain that is in use
871869
* by LLL or is new one with updated advertising payload).
872870
*/
873-
pdu_prev = pdu_chained;
874-
pdu_chained = lll_adv_pdu_linked_next_get(pdu_prev);
871+
*pdu_prev = pdu_chained;
872+
pdu_chained = lll_adv_pdu_linked_next_get(*pdu_prev);
875873
}
876874
}
877875

@@ -901,10 +899,8 @@ static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_
901899

902900
lll_sync = adv->lll.sync;
903901

904-
/* NOTE: ULL_ADV_PDU_HDR_FIELD_CTE_INFO is just information that extra_data
902+
/* NOTE: ULL_ADV_PDU_EXTRA_DATA_ALLOC_NEVER is just information that extra_data
905903
* should be removed in case of this call ull_adv_sync_pdu_alloc.
906-
* Other flags here do not change anything. It may be changed to use
907-
* true/false flag for extra_data allocation.
908904
*/
909905
err = ull_adv_sync_pdu_alloc(adv, ULL_ADV_PDU_EXTRA_DATA_ALLOC_NEVER, &pdu_prev, &pdu,
910906
&extra_data_prev, &extra_data, ter_idx);
@@ -922,7 +918,7 @@ static uint8_t cte_info_clear(struct ll_adv_set *adv, struct lll_df_adv_cfg *df_
922918
pdu_rem_field_flags = ULL_ADV_PDU_HDR_FIELD_CTE_INFO;
923919

924920
#if (CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX > 1)
925-
err = rem_cte_info_from_per_adv_chain(lll_sync, pdu_prev, pdu);
921+
err = rem_cte_info_from_per_adv_chain(lll_sync, &pdu_prev, &pdu);
926922
if (err != BT_HCI_ERR_SUCCESS) {
927923
return err;
928924
}

0 commit comments

Comments
 (0)