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:
parent
7d16ab50d7
commit
c2fc629dd2
7 changed files with 148 additions and 48 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue