Bluetooth: controller: 255 byte AD payload support

Add 255 byte AD payload support.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2020-10-22 18:40:38 +05:30 committed by Carles Cufí
commit c2fc629dd2
7 changed files with 148 additions and 48 deletions

View file

@ -18,6 +18,7 @@
#include "hal/ticker.h"
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "ticker/ticker.h"
@ -71,6 +72,22 @@ static inline bool isr_rx_ci_tgta_check(struct lll_adv *lll,
static inline bool isr_rx_ci_adva_check(struct pdu_adv *adv,
struct pdu_adv *ci);
#if defined(CONFIG_BT_CTLR_ADV_EXT)
#define PAYLOAD_SIZE_MAX MAX(MIN(CONFIG_BT_CTLR_ADV_DATA_LEN_MAX, \
PDU_AC_EXT_PAYLOAD_SIZE_MAX), \
PDU_AC_PAYLOAD_SIZE_MAX)
#else
#define PAYLOAD_SIZE_MAX PDU_AC_PAYLOAD_SIZE_MAX
#endif
#define PDU_MEM_SIZE MROUND(PDU_AC_LL_HEADER_SIZE + PAYLOAD_SIZE_MAX)
#define PDU_POOL_SIZE (PDU_MEM_SIZE * 7)
static struct {
void *free;
uint8_t pool[PDU_POOL_SIZE];
} mem_pdu;
int lll_adv_init(void)
{
int err;
@ -95,6 +112,75 @@ int lll_adv_reset(void)
return 0;
}
int lll_adv_data_init(struct lll_adv_pdu *pdu)
{
struct pdu_adv *p;
p = mem_acquire(&mem_pdu.free);
if (!p) {
return -ENOMEM;
}
pdu->pdu[0] = (void *)p;
return 0;
}
int lll_adv_data_reset(struct lll_adv_pdu *pdu)
{
pdu->first = 0U;
pdu->last = 0U;
pdu->pdu[1] = NULL;
return 0;
}
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx)
{
uint8_t first, last;
struct pdu_adv *p;
first = pdu->first;
last = pdu->last;
if (first == last) {
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
} else {
uint8_t first_latest;
pdu->last = first;
cpu_dsb();
first_latest = pdu->first;
if (first_latest != first) {
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
}
}
*idx = last;
p = (void *)pdu->pdu[last];
if (p) {
return p;
}
p = mem_acquire(&mem_pdu.free);
if (p) {
pdu->pdu[last] = (void *)p;
return p;
}
/* TODO: Wait for semaphore before trying again */
LL_ASSERT(false);
return NULL;
}
void lll_adv_prepare(void *param)
{
int err;
@ -164,6 +250,10 @@ int lll_adv_scan_req_report(struct lll_adv *lll, struct pdu_adv *pdu_adv_rx,
static int init_reset(void)
{
/* Initialize AC PDU pool */
mem_init(mem_pdu.pool, PDU_MEM_SIZE,
(sizeof(mem_pdu.pool) / PDU_MEM_SIZE), &mem_pdu.free);
return 0;
}

View file

@ -7,10 +7,7 @@
struct lll_adv_pdu {
uint8_t volatile first;
uint8_t last;
/* TODO: use,
* struct pdu_adv *pdu[DOUBLE_BUFFER_SIZE];
*/
uint8_t pdu[DOUBLE_BUFFER_SIZE][PDU_AC_LL_SIZE_MAX];
uint8_t *pdu[DOUBLE_BUFFER_SIZE];
};
struct lll_adv_aux {
@ -102,40 +99,11 @@ struct lll_adv {
int lll_adv_init(void);
int lll_adv_reset(void);
int lll_adv_data_init(struct lll_adv_pdu *pdu);
int lll_adv_data_reset(struct lll_adv_pdu *pdu);
struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu, uint8_t *idx);
void lll_adv_prepare(void *param);
static inline struct pdu_adv *lll_adv_pdu_alloc(struct lll_adv_pdu *pdu,
uint8_t *idx)
{
uint8_t first, last;
first = pdu->first;
last = pdu->last;
if (first == last) {
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
} else {
uint8_t first_latest;
pdu->last = first;
cpu_dsb();
first_latest = pdu->first;
if (first_latest != first) {
last++;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
}
}
*idx = last;
return (void *)pdu->pdu[last];
}
static inline void lll_adv_pdu_enqueue(struct lll_adv_pdu *pdu, uint8_t idx)
{
pdu->last = idx;

View file

@ -519,6 +519,12 @@ void ll_reset(void)
#endif /* !CONFIG_BT_CTLR_ZLI */
}
#if defined(CONFIG_BT_BROADCASTER)
/* Finalize after adv state reset */
err = ull_adv_reset_finalize();
LL_ASSERT(!err);
#endif /* CONFIG_BT_BROADCASTER */
/* Common to init and reset */
err = init_reset();
LL_ASSERT(!err);

View file

@ -1290,12 +1290,12 @@ int ull_adv_init(void)
}
}
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC)) {
err = ull_adv_sync_init();
if (err) {
return err;
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
}
#endif /* CONFIG_BT_CTLR_ADV_AUX_SET */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
@ -1310,28 +1310,30 @@ int ull_adv_init(void)
int ull_adv_reset(void)
{
uint8_t handle;
int err;
#if defined(CONFIG_BT_CTLR_ADV_EXT)
#if defined(CONFIG_BT_HCI_RAW)
ll_adv_cmds = LL_ADV_CMDS_ANY;
#endif
#if defined(CONFIG_BT_CTLR_ADV_AUX_SET)
if (CONFIG_BT_CTLR_ADV_AUX_SET > 0) {
int err;
err = ull_adv_aux_reset();
if (err) {
return err;
}
}
#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
if (IS_ENABLED(CONFIG_BT_CTLR_ADV_PERIODIC)) {
int err;
err = ull_adv_sync_reset();
if (err) {
return err;
}
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
}
#endif /* CONFIG_BT_CTLR_ADV_AUX_SET */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
@ -1339,6 +1341,19 @@ int ull_adv_reset(void)
(void)disable(handle);
}
return 0;
}
int ull_adv_reset_finalize(void)
{
uint8_t handle;
int err;
for (handle = 0U; handle < BT_CTLR_ADV_SET; handle++) {
lll_adv_data_reset(&ll_adv[handle].lll.adv_data);
lll_adv_data_reset(&ll_adv[handle].lll.scan_rsp);
}
err = init_reset();
if (err) {
return err;
@ -1532,11 +1547,18 @@ void ull_adv_done(struct node_rx_event_done *done)
static int init_reset(void)
{
uint8_t handle;
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL) && \
!defined(CONFIG_BT_CTLR_ADV_EXT)
ll_adv[0].lll.tx_pwr_lvl = RADIO_TXP_DEFAULT;
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL && !CONFIG_BT_CTLR_ADV_EXT */
for (handle = 0U; handle < BT_CTLR_ADV_SET; handle++) {
lll_adv_data_init(&ll_adv[handle].lll.adv_data);
lll_adv_data_init(&ll_adv[handle].lll.scan_rsp);
}
return 0;
}

View file

@ -875,6 +875,7 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
{
struct lll_adv_aux *lll_aux;
struct ll_adv_aux_set *aux;
int err;
aux = aux_acquire();
if (!aux) {
@ -885,6 +886,12 @@ struct ll_adv_aux_set *ull_adv_aux_acquire(struct lll_adv *lll)
lll->aux = lll_aux;
lll_aux->adv = lll;
lll_adv_data_reset(&lll_aux->data);
err = lll_adv_data_init(&lll_aux->data);
if (err) {
return NULL;
}
/* NOTE: ull_hdr_init(&aux->ull); is done on start */
lll_hdr_init(lll_aux, aux);

View file

@ -18,6 +18,7 @@
/* Helper functions to initialise and reset ull_adv module */
int ull_adv_init(void);
int ull_adv_reset(void);
int ull_adv_reset_finalize(void);
/* Return ll_adv_set context (unconditional) */
struct ll_adv_set *ull_adv_set_get(uint8_t handle);

View file

@ -87,6 +87,12 @@ uint8_t ll_adv_sync_param_set(uint8_t handle, uint16_t interval, uint16_t flags)
lll->sync = lll_sync;
lll_sync->adv = lll;
lll_adv_data_reset(&lll_sync->data);
err = lll_adv_data_init(&lll_sync->data);
if (err) {
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
}
/* NOTE: ull_hdr_init(&sync->ull); is done on start */
lll_hdr_init(lll_sync, sync);