Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/bluetooth/gap.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern "C" {
#define BT_DATA_LE_SC_CONFIRM_VALUE 0x22 /* LE SC Confirmation Value */
#define BT_DATA_LE_SC_RANDOM_VALUE 0x23 /* LE SC Random Value */
#define BT_DATA_URI 0x24 /* URI */
#define BT_DATA_CHANNEL_MAP_UPDATE_IND 0x28 /* Channel Map Update Indication */
#define BT_DATA_MESH_PROV 0x29 /* Mesh Provisioning PDU */
#define BT_DATA_MESH_MESSAGE 0x2a /* Mesh Networking PDU */
#define BT_DATA_MESH_BEACON 0x2b /* Mesh Beacon */
Expand Down
1 change: 1 addition & 0 deletions subsys/bluetooth/controller/ll_sw/lll.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ enum node_rx_type {
NODE_RX_TYPE_SYNC,
NODE_RX_TYPE_SYNC_REPORT,
NODE_RX_TYPE_SYNC_LOST,
NODE_RX_TYPE_SYNC_CHM_COMPLETE,
NODE_RX_TYPE_SYNC_ISO,
NODE_RX_TYPE_SYNC_ISO_LOST,
NODE_RX_TYPE_EXT_ADV_TERMINATE,
Expand Down
9 changes: 7 additions & 2 deletions subsys/bluetooth/controller/ll_sw/lll_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ struct lll_adv_sync {
uint16_t latency_event;
uint16_t event_counter;

uint8_t data_chan_map[5];
uint8_t data_chan_count:6;
uint16_t data_chan_id;
struct {
uint8_t data_chan_map[PDU_CHANNEL_MAP_SIZE];
uint8_t data_chan_count:6;
} chm[DOUBLE_BUFFER_SIZE];
uint8_t chm_first;
uint8_t chm_last;
uint16_t chm_instant;

uint32_t ticks_offset;

Expand Down
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/ll_sw/lll_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct lll_conn {
uint16_t latency_event;
uint16_t event_counter;

uint8_t data_chan_map[5];
uint8_t data_chan_map[PDU_CHANNEL_MAP_SIZE];
uint8_t data_chan_count:6;
uint8_t data_chan_sel:1;
uint8_t role:1;
Expand Down
9 changes: 7 additions & 2 deletions subsys/bluetooth/controller/ll_sw/lll_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ struct lll_sync {
uint16_t skip_event;
uint16_t event_counter;

uint8_t data_chan_map[5];
uint8_t data_chan_count:6;
uint16_t data_chan_id;
struct {
uint8_t data_chan_map[PDU_CHANNEL_MAP_SIZE];
uint8_t data_chan_count:6;
} chm[DOUBLE_BUFFER_SIZE];
uint8_t chm_first;
uint8_t chm_last;
uint16_t chm_instant;

uint32_t window_widening_periodic_us;
uint32_t window_widening_max_us;
Expand Down
49 changes: 45 additions & 4 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,23 @@ static int init_reset(void)
return 0;
}

static bool is_instant_or_past(uint16_t event_counter, uint16_t instant)
{
uint16_t instant_latency;

instant_latency = (event_counter - instant) &
EVENT_INSTANT_MAX;

return instant_latency <= EVENT_INSTANT_LATENCY_MAX;
}

static int prepare_cb(struct lll_prepare_param *p)
{
struct lll_adv_sync *lll;
uint32_t ticks_at_event;
uint32_t ticks_at_start;
uint8_t data_chan_count;
uint8_t *data_chan_map;
uint16_t event_counter;
uint8_t data_chan_use;
struct pdu_adv *pdu;
Expand All @@ -133,10 +145,18 @@ static int prepare_cb(struct lll_prepare_param *p)
/* Reset accumulated latencies */
lll->latency_prepare = 0;

/* Process channel map update, if any */
if ((lll->chm_first != lll->chm_last) &&
is_instant_or_past(event_counter, lll->chm_instant)) {
/* At or past the instant, use channelMapNew */
lll->chm_first = lll->chm_last;
}

/* Calculate the radio channel to use */
data_chan_map = lll->chm[lll->chm_first].data_chan_map;
data_chan_count = lll->chm[lll->chm_first].data_chan_count;
data_chan_use = lll_chan_sel_2(event_counter, lll->data_chan_id,
&lll->data_chan_map[0],
lll->data_chan_count);
data_chan_map, data_chan_count);

/* Start setting up of Radio h/w */
radio_reset();
Expand Down Expand Up @@ -264,14 +284,35 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param)

static void isr_done(void *param)
{
struct lll_adv_sync *lll;
struct lll_adv_sync *lll = param;

lll = param;
#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
if (lll->cte_started) {
lll_df_conf_cte_tx_disable();
}
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */

/* Signal thread mode to remove Channel Map Update Indication in the
* ACAD.
*/
if ((lll->chm_first != lll->chm_last) &&
is_instant_or_past(lll->event_counter, lll->chm_instant)) {
struct node_rx_hdr *rx;

/* Allocate, prepare and dispatch Channel Map Update
* complete message towards ULL, then subsequently to
* the thread context.
*/
rx = ull_pdu_rx_alloc();
LL_ASSERT(rx);

rx->type = NODE_RX_TYPE_SYNC_CHM_COMPLETE;
rx->rx_ftr.param = lll;

ull_rx_put(rx->link, rx);
ull_rx_sched();
}

lll_isr_done(lll);
}

Expand Down
19 changes: 17 additions & 2 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ static int prepare_cb(struct lll_prepare_param *p)
struct node_rx_pdu *node_rx;
uint32_t ticks_at_event;
uint32_t ticks_at_start;
uint8_t data_chan_count;
uint8_t *data_chan_map;
uint16_t event_counter;
uint32_t remainder_us;
uint8_t data_chan_use;
Expand Down Expand Up @@ -141,10 +143,23 @@ static int prepare_cb(struct lll_prepare_param *p)
lll->window_widening_event_us = lll->window_widening_max_us;
}

/* Process channel map update, if any */
if (lll->chm_first != lll->chm_last) {
uint16_t instant_latency;

instant_latency = (event_counter - lll->chm_instant) &
EVENT_INSTANT_MAX;
if (instant_latency <= EVENT_INSTANT_LATENCY_MAX) {
/* At or past the instant, use channelMapNew */
lll->chm_first = lll->chm_last;
}
}

/* Calculate the radio channel to use */
data_chan_map = lll->chm[lll->chm_first].data_chan_map;
data_chan_count = lll->chm[lll->chm_first].data_chan_count;
data_chan_use = lll_chan_sel_2(event_counter, lll->data_chan_id,
&lll->data_chan_map[0],
lll->data_chan_count);
data_chan_map, data_chan_count);

/* Start setting up Radio h/w */
radio_reset();
Expand Down
26 changes: 19 additions & 7 deletions subsys/bluetooth/controller/ll_sw/pdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@
/* Standard allows 2 us timing uncertainty inside the event */
#define EVENT_MSS_MAX_US (EVENT_MSS_US + EVENT_CLOCK_JITTER_US)

/* Instant maximum value and maximum latency (or delta) past the instant */
#define EVENT_INSTANT_MAX 0xffff
#define EVENT_INSTANT_LATENCY_MAX 0x7fff

/* Offset Units field encoding */
#define OFFS_UNIT_30_US 30
#define OFFS_UNIT_300_US 300
Expand All @@ -113,6 +117,9 @@
#define WIN_DELAY_UNCODED 2500
#define WIN_DELAY_CODED 3750

/* Channel Map Size */
#define PDU_CHANNEL_MAP_SIZE 5

/*
* Macros to return correct Data Channel PDU time
* Note: formula is valid for 1M, 2M and Coded S8
Expand Down Expand Up @@ -221,7 +228,7 @@ struct pdu_adv_connect_ind {
uint16_t interval;
uint16_t latency;
uint16_t timeout;
uint8_t chan_map[5];
uint8_t chan_map[PDU_CHANNEL_MAP_SIZE];
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint8_t hop:5;
uint8_t sca:3;
Expand All @@ -244,9 +251,9 @@ struct pdu_adv_ext_hdr {
uint8_t aux_ptr:1;
uint8_t sync_info:1;
uint8_t tx_pwr:1;
uint8_t rfu1:1;
uint8_t rfu:1;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
uint8_t rfu1:1;
uint8_t rfu:1;
uint8_t tx_pwr:1;
uint8_t sync_info:1;
uint8_t aux_ptr:1;
Expand Down Expand Up @@ -359,7 +366,7 @@ struct pdu_adv_sync_info {
#error "Unsupported endianness"
#endif
uint16_t interval;
uint8_t sca_chm[5];
uint8_t sca_chm[PDU_CHANNEL_MAP_SIZE];
uint32_t aa;
uint8_t crc_init[3];
uint16_t evt_cntr;
Expand All @@ -370,6 +377,11 @@ struct pdu_adv_sync_info {
#define PDU_SYNC_INFO_SCA_CHM_SCA_BIT_MASK \
(0x07 << (PDU_SYNC_INFO_SCA_CHM_SCA_BIT_POS))

struct pdu_adv_sync_chm_upd_ind {
uint8_t chm[PDU_CHANNEL_MAP_SIZE];
uint16_t instant;
} __packed;

enum pdu_adv_type {
PDU_ADV_TYPE_ADV_IND = 0x00,
PDU_ADV_TYPE_DIRECT_IND = 0x01,
Expand Down Expand Up @@ -472,7 +484,7 @@ struct pdu_data_llctrl_conn_update_ind {
} __packed;

struct pdu_data_llctrl_chan_map_ind {
uint8_t chm[5];
uint8_t chm[PDU_CHANNEL_MAP_SIZE];
uint16_t instant;
} __packed;

Expand Down Expand Up @@ -798,7 +810,7 @@ enum pdu_big_ctrl_type {
};

struct pdu_big_ctrl_chan_map_ind {
uint8_t chm[5];
uint8_t chm[PDU_CHANNEL_MAP_SIZE];
uint16_t instant;
} __packed;

Expand Down Expand Up @@ -898,7 +910,7 @@ struct pdu_big_info {

uint16_t base_crc_init;

uint8_t chm_phy[5]; /* 37 bit chm; 3 bit phy */
uint8_t chm_phy[PDU_CHANNEL_MAP_SIZE]; /* 37 bit chm; 3 bit phy */
uint8_t payload_count_framing[5]; /* 39 bit count; 1 bit framing */

uint8_t giv; /* encryption required */
Expand Down
32 changes: 30 additions & 2 deletions subsys/bluetooth/controller/ll_sw/ull.c
Original file line number Diff line number Diff line change
Expand Up @@ -818,10 +818,12 @@ uint8_t ll_rx_get(void **node_rx, uint16_t *handle)
uint8_t cmplt = 0U;

#if defined(CONFIG_BT_CONN) || \
(defined(CONFIG_BT_OBSERVER) && defined(CONFIG_BT_CTLR_ADV_EXT))
(defined(CONFIG_BT_OBSERVER) && defined(CONFIG_BT_CTLR_ADV_EXT)) || \
defined(CONFIG_BT_CTLR_ADV_PERIODIC)
ll_rx_get_again:
#endif /* CONFIG_BT_CONN ||
* (CONFIG_BT_OBSERVER && CONFIG_BT_CTLR_ADV_EXT)
* (CONFIG_BT_OBSERVER && CONFIG_BT_CTLR_ADV_EXT) ||
* CONFIG_BT_CTLR_ADV_PERIODIC
*/

*node_rx = NULL;
Expand Down Expand Up @@ -865,6 +867,26 @@ uint8_t ll_rx_get(void **node_rx, uint16_t *handle)
#endif /* CONFIG_BT_CONN ||
* (CONFIG_BT_OBSERVER && CONFIG_BT_CTLR_ADV_EXT)
*/

#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
} else if (rx->type == NODE_RX_TYPE_SYNC_CHM_COMPLETE) {
(void)memq_dequeue(memq_ll_rx.tail,
&memq_ll_rx.head, NULL);
mem_release(link, &mem_link_rx.free);

ll_rx_link_inc_quota(1);

/* Remove Channel Map Update Indication from
* ACAD.
*/
ull_adv_sync_chm_complete(rx);

mem_release(rx, &mem_pdu_rx.free);

rx_alloc(1);

goto ll_rx_get_again;
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */
}

*node_rx = rx;
Expand Down Expand Up @@ -2407,12 +2429,17 @@ static inline int rx_demux_rx(memq_link_t *link, struct node_rx_hdr *rx)
#endif /* CONFIG_BT_CONN */

#if defined(CONFIG_BT_OBSERVER) || \
defined(CONFIG_BT_CTLR_ADV_PERIODIC) || \
defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY) || \
defined(CONFIG_BT_CTLR_PROFILE_ISR) || \
defined(CONFIG_BT_CTLR_ADV_INDICATION) || \
defined(CONFIG_BT_CTLR_SCAN_INDICATION) || \
defined(CONFIG_BT_CONN)

#if defined(CONFIG_BT_CTLR_ADV_PERIODIC)
case NODE_RX_TYPE_SYNC_CHM_COMPLETE:
#endif /* CONFIG_BT_CTLR_ADV_PERIODIC */

#if defined(CONFIG_BT_OBSERVER)
case NODE_RX_TYPE_REPORT:
#endif /* CONFIG_BT_OBSERVER */
Expand Down Expand Up @@ -2441,6 +2468,7 @@ static inline int rx_demux_rx(memq_link_t *link, struct node_rx_hdr *rx)
}
break;
#endif /* CONFIG_BT_OBSERVER ||
* CONFIG_BT_CTLR_ADV_PERIODIC ||
* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY ||
* CONFIG_BT_CTLR_PROFILE_ISR ||
* CONFIG_BT_CTLR_ADV_INDICATION ||
Expand Down
Loading