Bluetooth: controller: Fix Extended Advertising data population

Fix Extended Advertising Data population when there is no
Extended Header to be filled.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2020-11-06 15:56:03 +05:30 committed by Carles Cufí
commit 92a942257d
5 changed files with 35 additions and 16 deletions

View file

@ -3809,6 +3809,7 @@ static void le_ext_adv_report(struct pdu_data *pdu_data,
struct pdu_adv_hdr *h;
uint8_t sec_phy_curr = 0U;
uint8_t evt_type_curr;
uint8_t hdr_len;
uint8_t *ptr;
/* The Link Layer currently returns RSSI as an absolute value */
@ -3917,24 +3918,35 @@ static void le_ext_adv_report(struct pdu_data *pdu_data,
BT_DBG(" Tx pwr= %d dB", tx_pwr);
}
uint8_t len = ptr - (uint8_t *)p;
uint8_t hdr_len = len - offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data);
if (hdr_len > p->ext_hdr_len) {
hdr_len = ptr - (uint8_t *)p;
if (hdr_len <= (offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data) +
sizeof(struct pdu_adv_hdr))) {
hdr_len = offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data);
ptr = (uint8_t *)h;
}
if (hdr_len > (p->ext_hdr_len +
offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data))) {
BT_WARN(" Header length %u/%u, INVALID.", hdr_len,
p->ext_hdr_len);
} else {
uint8_t acad_len = p->ext_hdr_len - hdr_len;
uint8_t acad_len = p->ext_hdr_len +
offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data) -
hdr_len;
if (acad_len) {
ptr += acad_len;
len += acad_len;
hdr_len += acad_len;
BT_DBG("ACAD: <todo>");
}
if (len < adv->len) {
data_len_curr = adv->len - len;
if (hdr_len < adv->len) {
data_len_curr = adv->len - hdr_len;
data_curr = ptr;
BT_DBG(" AD Data (%u): <todo>", data_len);

View file

@ -418,7 +418,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
}
/* Calc primary PDU len */
len = ull_adv_aux_hdr_len_get(pri_com_hdr, pri_dptr);
len = ull_adv_aux_hdr_len_calc(pri_com_hdr, &pri_dptr);
ull_adv_aux_hdr_len_fill(pri_com_hdr, len);
/* Set PDU length */

View file

@ -628,14 +628,15 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
/* TODO: ACAD in secondary channel PDU */
/* Calc primary PDU len */
pri_len = ull_adv_aux_hdr_len_get(pri_com_hdr, pri_dptr);
pri_len = ull_adv_aux_hdr_len_calc(pri_com_hdr, &pri_dptr);
ull_adv_aux_hdr_len_fill(pri_com_hdr, pri_len);
/* set the primary PDU len */
pri_pdu->len = pri_len;
/* Calc previous secondary PDU len */
sec_len_prev = ull_adv_aux_hdr_len_get(sec_com_hdr_prev, sec_dptr_prev);
sec_len_prev = ull_adv_aux_hdr_len_calc(sec_com_hdr_prev,
&sec_dptr_prev);
/* Did we parse beyond PDU length? */
if (sec_len_prev > sec_pdu_prev->len) {
@ -645,7 +646,7 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
}
/* Calc current secondary PDU len */
sec_len = ull_adv_aux_hdr_len_get(sec_com_hdr, sec_dptr);
sec_len = ull_adv_aux_hdr_len_calc(sec_com_hdr, &sec_dptr);
ull_adv_aux_hdr_len_fill(sec_com_hdr, sec_len);
/* AD Data, add or remove */

View file

@ -85,17 +85,23 @@ uint8_t ull_adv_aux_hdr_set_clear(struct ll_adv_set *adv,
struct pdu_adv_adi *adi,
uint8_t *pri_idx);
/* helper function to calculate common ext adv payload header length */
/* helper function to calculate common ext adv payload header length and
* adjust the data pointer.
* NOTE: This function reverts the header data pointer if there is no
* header fields flags set, and hence no header fields have been
* populated.
*/
static inline uint8_t
ull_adv_aux_hdr_len_get(struct pdu_adv_com_ext_adv *com_hdr, uint8_t *dptr)
ull_adv_aux_hdr_len_calc(struct pdu_adv_com_ext_adv *com_hdr, uint8_t **dptr)
{
uint8_t len;
len = dptr - (uint8_t *)com_hdr;
len = *dptr - (uint8_t *)com_hdr;
if (len <= (offsetof(struct pdu_adv_com_ext_adv, ext_hdr_adi_adv_data) +
sizeof(struct pdu_adv_hdr))) {
len = offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data);
*dptr = (uint8_t *)com_hdr + len;
}
return len;

View file

@ -156,7 +156,7 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
/* TODO: AdvData */
/* Calc tertiary PDU len */
ter_len = ull_adv_aux_hdr_len_get(ter_com_hdr, ter_dptr);
ter_len = ull_adv_aux_hdr_len_calc(ter_com_hdr, &ter_dptr);
ull_adv_aux_hdr_len_fill(ter_com_hdr, ter_len);
ter_pdu->len = ter_len;