Bluetooth: controller: split: Add AuxPtr to ADV_EXT_IND PDU
Add implementation to support ADV_EXT_IND PDU with AuxPtr. Changes in this commit only prepares the ADV_EXT_IND PDU in the primary channel. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
eec42ca522
commit
fdd91bb116
3 changed files with 161 additions and 11 deletions
|
@ -191,7 +191,7 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
|
|||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
} else if (pdu->type == PDU_ADV_TYPE_EXT_IND) {
|
||||
struct pdu_adv_com_ext_adv *p;
|
||||
struct ext_adv_hdr _h, *h;
|
||||
struct ext_adv_hdr *h, _h;
|
||||
uint8_t *_ptr, *ptr;
|
||||
uint8_t len;
|
||||
|
||||
|
@ -222,7 +222,10 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
|
|||
ptr += BDADDR_SIZE;
|
||||
}
|
||||
|
||||
/* TODO: TargetA flag */
|
||||
/* TODO: TargetA flag in primary channel PDU only for directed
|
||||
*/
|
||||
|
||||
/* No CTEInfo flag in primary channel PDU */
|
||||
|
||||
/* ADI flag */
|
||||
if (_h.adi) {
|
||||
|
@ -239,6 +242,9 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
|
|||
/* No SyncInfo flag in primary channel PDU */
|
||||
|
||||
/* Tx Power flag */
|
||||
/* C1, Tx Power is optional on the LE 1M PHY, and reserved for
|
||||
* for future use on the LE Coded PHY.
|
||||
*/
|
||||
if (evt_prop & BIT(6) &&
|
||||
(!_h.aux_ptr || (phy_p != BIT(2)))) {
|
||||
h->tx_pwr = 1;
|
||||
|
@ -295,18 +301,23 @@ uint8_t ll_adv_params_set(uint16_t interval, uint8_t adv_type,
|
|||
aux = (void *)ptr;
|
||||
aux->phy = find_lsb_set(phy_s);
|
||||
}
|
||||
adv->phy_s = phy_s;
|
||||
|
||||
/* ADI */
|
||||
if (h->adi) {
|
||||
struct ext_adv_adi *adi;
|
||||
|
||||
ptr -= sizeof(struct ext_adv_adi);
|
||||
|
||||
/* NOTE: memcpy shall handle overlapping buffers */
|
||||
memcpy(ptr, _ptr, sizeof(struct ext_adv_adi));
|
||||
|
||||
adi = (void *)ptr;
|
||||
adi->sid = sid;
|
||||
}
|
||||
adv->sid = sid;
|
||||
|
||||
/* No CTEInfo field in primary channel PDU */
|
||||
|
||||
/* NOTE: TargetA, filled at enable and RPA timeout */
|
||||
|
||||
|
|
|
@ -37,36 +37,173 @@ uint8_t *ll_adv_aux_random_addr_get(uint8_t handle, uint8_t *addr)
|
|||
uint8_t ll_adv_aux_ad_data_set(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len,
|
||||
uint8_t *data)
|
||||
{
|
||||
struct pdu_adv_com_ext_adv *p;
|
||||
struct pdu_adv_com_ext_adv *p, *_p;
|
||||
struct ext_adv_hdr *h, _h;
|
||||
struct ll_adv_set *adv;
|
||||
struct ext_adv_hdr *h;
|
||||
uint8_t pdu_len, _pdu_len;
|
||||
struct pdu_adv *prev;
|
||||
struct pdu_adv *pdu;
|
||||
uint8_t *_ptr, *ptr;
|
||||
uint8_t idx;
|
||||
|
||||
/* TODO: */
|
||||
|
||||
/* 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_set_get(handle);
|
||||
if (!adv) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
/* Dont update data if not extended advertising. */
|
||||
/* Do not update data if not extended advertising. */
|
||||
prev = lll_adv_data_peek(&adv->lll);
|
||||
if (prev->type != PDU_ADV_TYPE_EXT_IND) {
|
||||
return 0;
|
||||
/* Advertising Handle has not been created using
|
||||
* Set Extended Advertising Parameter command
|
||||
*/
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
/* Get reference to previous PDU data */
|
||||
_p = (void *)&prev->adv_ext_ind;
|
||||
h = (void *)_p->ext_hdr_adi_adv_data;
|
||||
*(uint8_t *)&_h = *(uint8_t *)h;
|
||||
_ptr = (uint8_t *)h + sizeof(*h);
|
||||
|
||||
/* Get reference new PDU data buffer */
|
||||
pdu = lll_adv_data_alloc(&adv->lll, &idx);
|
||||
p = (void *)&pdu->adv_ext_ind;
|
||||
p->adv_mode = _p->adv_mode;
|
||||
h = (void *)p->ext_hdr_adi_adv_data;
|
||||
ptr = (uint8_t *)h + sizeof(*h);
|
||||
*(uint8_t *)h = 0;
|
||||
|
||||
if (!h->aux_ptr) {
|
||||
if (!len) {
|
||||
return 0;
|
||||
/* AdvA flag */
|
||||
if (_h.adv_addr) {
|
||||
_ptr += BDADDR_SIZE;
|
||||
}
|
||||
/* NOTE: as we will use auxiliary packet, we remove AdvA in primary
|
||||
* channel. i.e. Do nothing to add AdvA in the new PDU.
|
||||
*/
|
||||
|
||||
/* No TargetA in primary channel for undirected */
|
||||
/* No CTEInfo flag in primary channel PDU */
|
||||
|
||||
/* ADI flag */
|
||||
if (_h.adi) {
|
||||
_ptr += sizeof(struct ext_adv_adi);
|
||||
}
|
||||
h->adi = 1;
|
||||
ptr += sizeof(struct ext_adv_adi);
|
||||
|
||||
/* AuxPtr flag */
|
||||
if (_h.aux_ptr) {
|
||||
_ptr += sizeof(struct ext_adv_aux_ptr);
|
||||
}
|
||||
h->aux_ptr = 1;
|
||||
ptr += sizeof(struct ext_adv_aux_ptr);
|
||||
|
||||
/* No SyncInfo flag in primary channel PDU */
|
||||
|
||||
/* Tx Power flag */
|
||||
if (_h.tx_pwr) {
|
||||
_ptr++;
|
||||
|
||||
/* C1, Tx Power is optional on the LE 1M PHY, and reserved for
|
||||
* for future use on the LE Coded PHY.
|
||||
*/
|
||||
if (adv->lll.phy_p != BIT(2)) {
|
||||
h->tx_pwr = 1;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calc primary PDU len */
|
||||
_pdu_len = _ptr - (uint8_t *)_p;
|
||||
pdu_len = ptr - (uint8_t *)p;
|
||||
p->ext_hdr_len = pdu_len - offsetof(struct pdu_adv_com_ext_adv,
|
||||
ext_hdr_adi_adv_data);
|
||||
pdu->len = pdu_len;
|
||||
|
||||
/* Start filling primary PDU payload based on flags */
|
||||
|
||||
/* No AdvData in primary channel PDU */
|
||||
|
||||
/* No ACAD in primary channel PDU */
|
||||
|
||||
/* Tx Power */
|
||||
if (h->tx_pwr) {
|
||||
*--ptr = *--_ptr;
|
||||
}
|
||||
|
||||
/* No SyncInfo in primary channel PDU */
|
||||
|
||||
/* AuxPtr */
|
||||
if (_h.aux_ptr) {
|
||||
_ptr -= sizeof(struct ext_adv_aux_ptr);
|
||||
}
|
||||
{
|
||||
struct ext_adv_aux_ptr *aux;
|
||||
|
||||
ptr -= sizeof(struct ext_adv_aux_ptr);
|
||||
|
||||
/* NOTE: Channel Index, CA, Offset Units and AUX Offset will be
|
||||
* set in Advertiser Event.
|
||||
*/
|
||||
aux = (void *)ptr;
|
||||
aux->phy = find_lsb_set(adv->phy_s);
|
||||
}
|
||||
|
||||
/* ADI */
|
||||
{
|
||||
struct ext_adv_adi *adi;
|
||||
uint16_t did = UINT16_MAX;
|
||||
|
||||
ptr -= sizeof(struct ext_adv_adi);
|
||||
|
||||
adi = (void *)ptr;
|
||||
|
||||
if (_h.adi) {
|
||||
struct ext_adv_adi *_adi;
|
||||
|
||||
_ptr -= sizeof(struct ext_adv_adi);
|
||||
|
||||
/* NOTE: memcpy shall handle overlapping buffers */
|
||||
memcpy(ptr, _ptr, sizeof(struct ext_adv_adi));
|
||||
|
||||
_adi = (void *)_ptr;
|
||||
did = _adi->did;
|
||||
} else {
|
||||
adi->sid = adv->sid;
|
||||
}
|
||||
|
||||
if ((op == 0x04) || len || (_pdu_len != pdu_len)) {
|
||||
did++;
|
||||
}
|
||||
|
||||
adi->did = did;
|
||||
}
|
||||
|
||||
/* No CTEInfo field in primary channel PDU */
|
||||
|
||||
/* NOTE: TargetA, filled at enable and RPA timeout */
|
||||
|
||||
/* No AdvA in primary channel due to AuxPtr being added */
|
||||
|
||||
lll_adv_data_enqueue(&adv->lll, idx);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -9,8 +9,6 @@ struct ll_adv_set {
|
|||
struct ull_hdr ull;
|
||||
struct lll_adv lll;
|
||||
|
||||
uint8_t is_enabled:1;
|
||||
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
memq_link_t *link_cc_free;
|
||||
struct node_rx_pdu *node_rx_cc_free;
|
||||
|
@ -18,10 +16,14 @@ struct ll_adv_set {
|
|||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
uint32_t interval;
|
||||
uint8_t sid:4;
|
||||
uint8_t phy_s:3;
|
||||
#else /* !CONFIG_BT_CTLR_ADV_EXT */
|
||||
uint16_t interval;
|
||||
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
uint8_t is_enabled:1;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PRIVACY)
|
||||
uint8_t own_addr_type:2;
|
||||
uint8_t id_addr_type:1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue