Bluetooth: controller: split: Support legacy AD/SR data

Added implementation to support setting of legacy
Advertising Data and Scan Response Data using Extended
Advertising Data set functions.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2020-04-08 16:29:21 +05:30 committed by Carles Cufí
commit b0dd599db1
3 changed files with 124 additions and 63 deletions

View file

@ -136,6 +136,9 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
if (evt_prop & BIT(3)) { if (evt_prop & BIT(3)) {
adv_type = 0x01; adv_type = 0x01;
} }
/* Mark the adv set as created */
adv->is_created = 1;
} else { } else {
/* - Connectable and scannable not allowed; /* - Connectable and scannable not allowed;
* - High duty cycle directed connectable not allowed * - High duty cycle directed connectable not allowed
@ -387,46 +390,13 @@ uint8_t ll_adv_data_set(uint8_t len, uint8_t const *const data)
const uint8_t handle = 0; const uint8_t handle = 0;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */ #endif /* !CONFIG_BT_CTLR_ADV_EXT */
struct ll_adv_set *adv; struct ll_adv_set *adv;
struct pdu_adv *prev;
struct pdu_adv *pdu;
uint8_t idx;
adv = ull_adv_set_get(handle); adv = ull_adv_set_get(handle);
if (!adv) { if (!adv) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
} }
/* Dont update data if directed or extended advertising. */ return adv_data_set(adv, len, data);
prev = lll_adv_data_peek(&adv->lll);
if ((prev->type == PDU_ADV_TYPE_DIRECT_IND) ||
(IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
(prev->type == PDU_ADV_TYPE_EXT_IND))) {
/* TODO: remember data, to be used if type is changed using
* parameter set function ll_adv_params_set afterwards.
*/
return 0;
}
/* update adv pdu fields. */
pdu = lll_adv_data_alloc(&adv->lll, &idx);
pdu->type = prev->type;
pdu->rfu = 0U;
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
pdu->chan_sel = prev->chan_sel;
} else {
pdu->chan_sel = 0U;
}
pdu->tx_addr = prev->tx_addr;
pdu->rx_addr = prev->rx_addr;
memcpy(&pdu->adv_ind.addr[0], &prev->adv_ind.addr[0], BDADDR_SIZE);
memcpy(&pdu->adv_ind.data[0], data, len);
pdu->len = BDADDR_SIZE + len;
lll_adv_data_enqueue(&adv->lll, idx);
return 0;
} }
#if defined(CONFIG_BT_CTLR_ADV_EXT) #if defined(CONFIG_BT_CTLR_ADV_EXT)
@ -439,30 +409,13 @@ uint8_t ll_adv_scan_rsp_set(uint8_t len, uint8_t const *const data)
const uint8_t handle = 0; const uint8_t handle = 0;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */ #endif /* !CONFIG_BT_CTLR_ADV_EXT */
struct ll_adv_set *adv; struct ll_adv_set *adv;
struct pdu_adv *prev;
struct pdu_adv *pdu;
uint8_t idx;
adv = ull_adv_set_get(handle); adv = ull_adv_set_get(handle);
if (!adv) { if (!adv) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
} }
/* update scan pdu fields. */ return scan_rsp_set(adv, len, data);
prev = lll_adv_scan_rsp_peek(&adv->lll);
pdu = lll_adv_scan_rsp_alloc(&adv->lll, &idx);
pdu->type = PDU_ADV_TYPE_SCAN_RSP;
pdu->rfu = 0;
pdu->chan_sel = 0;
pdu->tx_addr = prev->tx_addr;
pdu->rx_addr = 0;
pdu->len = BDADDR_SIZE + len;
memcpy(&pdu->scan_rsp.addr[0], &prev->scan_rsp.addr[0], BDADDR_SIZE);
memcpy(&pdu->scan_rsp.data[0], data, len);
lll_adv_scan_rsp_enqueue(&adv->lll, idx);
return 0;
} }
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT) #if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT)
@ -1223,6 +1176,70 @@ struct ll_adv_set *ull_adv_is_created_get(uint8_t handle)
} }
#endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_ADV_EXT */
uint8_t adv_data_set(struct ll_adv_set *adv, uint8_t len,
uint8_t const *const data)
{
struct pdu_adv *prev;
struct pdu_adv *pdu;
uint8_t idx;
/* Dont update data if directed or extended advertising. */
prev = lll_adv_data_peek(&adv->lll);
if ((prev->type == PDU_ADV_TYPE_DIRECT_IND) ||
(IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
(prev->type == PDU_ADV_TYPE_EXT_IND))) {
/* TODO: remember data, to be used if type is changed using
* parameter set function ll_adv_params_set afterwards.
*/
return 0;
}
/* update adv pdu fields. */
pdu = lll_adv_data_alloc(&adv->lll, &idx);
pdu->type = prev->type;
pdu->rfu = 0U;
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
pdu->chan_sel = prev->chan_sel;
} else {
pdu->chan_sel = 0U;
}
pdu->tx_addr = prev->tx_addr;
pdu->rx_addr = prev->rx_addr;
memcpy(&pdu->adv_ind.addr[0], &prev->adv_ind.addr[0], BDADDR_SIZE);
memcpy(&pdu->adv_ind.data[0], data, len);
pdu->len = BDADDR_SIZE + len;
lll_adv_data_enqueue(&adv->lll, idx);
return 0;
}
uint8_t scan_rsp_set(struct ll_adv_set *adv, uint8_t len,
uint8_t const *const data)
{
struct pdu_adv *prev;
struct pdu_adv *pdu;
uint8_t idx;
/* update scan pdu fields. */
prev = lll_adv_scan_rsp_peek(&adv->lll);
pdu = lll_adv_scan_rsp_alloc(&adv->lll, &idx);
pdu->type = PDU_ADV_TYPE_SCAN_RSP;
pdu->rfu = 0;
pdu->chan_sel = 0;
pdu->tx_addr = prev->tx_addr;
pdu->rx_addr = 0;
pdu->len = BDADDR_SIZE + len;
memcpy(&pdu->scan_rsp.addr[0], &prev->scan_rsp.addr[0], BDADDR_SIZE);
memcpy(&pdu->scan_rsp.data[0], data, len);
lll_adv_scan_rsp_enqueue(&adv->lll, idx);
return 0;
}
static int init_reset(void) static int init_reset(void)
{ {
return 0; return 0;

View file

@ -94,13 +94,22 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
} }
/* Get the advertising set instance */ /* Get the advertising set instance */
adv = ull_adv_set_get(handle); adv = ull_adv_is_created_get(handle);
if (!adv) { if (!adv) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
} }
lll = &adv->lll; lll = &adv->lll;
/* Do not use Common Extended Advertising Header Format if not extended
* advertising.
*/
_pri = lll_adv_data_peek(lll);
if (_pri->type != PDU_ADV_TYPE_EXT_IND) {
return adv_data_set(adv, len, data);
}
/* Allocate or existing Auxiliary channel instance */
lll_aux = lll->aux; lll_aux = lll->aux;
if (!lll_aux) { if (!lll_aux) {
aux = aux_acquire(); aux = aux_acquire();
@ -120,15 +129,6 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
aux = (void *)HDR_LLL2EVT(lll_aux); aux = (void *)HDR_LLL2EVT(lll_aux);
} }
/* Do not update data if not extended advertising. */
_pri = lll_adv_data_peek(lll);
if (_pri->type != PDU_ADV_TYPE_EXT_IND) {
/* Advertising Handle has not been created using
* Set Extended Advertising Parameter command
*/
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* Get reference to previous primary PDU data */ /* Get reference to previous primary PDU data */
_p = (void *)&_pri->adv_ext_ind; _p = (void *)&_pri->adv_ext_ind;
hp = (void *)_p->ext_hdr_adi_adv_data; hp = (void *)_p->ext_hdr_adi_adv_data;
@ -426,8 +426,44 @@ uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, ui
uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len, uint8_t ll_adv_aux_sr_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len,
uint8_t *data) uint8_t *data)
{ {
struct ll_adv_set *adv;
struct pdu_adv *_pri;
struct lll_adv *lll;
/* op param definitions:
* 0x00 - Intermediate fragment of fragmented extended advertising data
* 0x01 - First fragment of fragmented extended advertising data
* 0x02 - Last fragemnt of fragemented extended advertising data
* 0x03 - Complete extended advertising data
* 0x04 - Unchanged data (just update the advertising data)
* All other values, Reserved for future use
*/
/* TODO: handle other op values */
if ((op != 0x03) && (op != 0x04)) {
/* FIXME: error code */
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* Get the advertising set instance */
adv = ull_adv_is_created_get(handle);
if (!adv) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
lll = &adv->lll;
/* Do not use Common Extended Advertising Header Format if not extended
* advertising.
*/
_pri = lll_adv_data_peek(lll);
if (_pri->type != PDU_ADV_TYPE_EXT_IND) {
return scan_rsp_set(adv, len, data);
}
/* TODO: */ /* TODO: */
return 0;
return BT_HCI_ERR_CMD_DISALLOWED;
} }
uint16_t ll_adv_aux_max_data_length_get(void) uint16_t ll_adv_aux_max_data_length_get(void)

View file

@ -27,6 +27,14 @@ uint32_t ull_adv_filter_pol_get(uint8_t handle);
/* Return ll_adv_set context if created */ /* Return ll_adv_set context if created */
struct ll_adv_set *ull_adv_is_created_get(uint8_t handle); struct ll_adv_set *ull_adv_is_created_get(uint8_t handle);
/* Helper function to construct AD data */
uint8_t adv_data_set(struct ll_adv_set *adv, uint8_t len,
uint8_t const *const data);
/* Helper function to construct SR data */
uint8_t scan_rsp_set(struct ll_adv_set *adv, uint8_t len,
uint8_t const *const data);
#if defined(CONFIG_BT_CTLR_ADV_EXT) #if defined(CONFIG_BT_CTLR_ADV_EXT)
int ull_adv_aux_init(void); int ull_adv_aux_init(void);
int ull_adv_aux_reset(void); int ull_adv_aux_reset(void);