Bluetooth: controller: Remove legacy LL

Remove the legacy Link Layer implementation.

Closes #24187.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Carles Cufi 2020-05-06 10:53:05 +02:00 committed by Carles Cufí
commit b67a31e411
40 changed files with 25 additions and 16933 deletions

View file

@ -10,7 +10,7 @@ config COUNTER_NRF_RTC
config COUNTER_TIMER0
bool "Enable Counter on TIMER0"
depends on HAS_HW_NRF_TIMER0
depends on !BT_LL_SW_LEGACY && !BT_LL_SW_SPLIT
depends on !BT_LL_SW_SPLIT
select COUNTER_NRF_TIMER
config COUNTER_TIMER1
@ -36,7 +36,7 @@ config COUNTER_TIMER4
config COUNTER_RTC0
bool "Enable Counter on RTC0"
depends on HAS_HW_NRF_RTC0
depends on !BT_LL_SW_LEGACY && !BT_LL_SW_SPLIT
depends on !BT_LL_SW_SPLIT
select COUNTER_NRF_RTC
config COUNTER_RTC1

View file

@ -80,7 +80,6 @@ CONFIG_BT_MESH_LABEL_COUNT=3
CONFIG_GPIO=y
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_JOB_PRIO=1
CONFIG_BT_RX_BUF_COUNT=5
CONFIG_BT_HCI_TX_STACK_SIZE=1024
#CONFIG_BT_DEBUG_HCI_CORE=y

View file

@ -10,8 +10,6 @@ add_subdirectory_ifdef(CONFIG_BT_SHELL shell)
add_subdirectory_ifdef(CONFIG_BT_CONN services)
add_subdirectory_ifdef(CONFIG_BT_MESH mesh)
if(CONFIG_BT_CTLR)
if(CONFIG_BT_LL_SW_LEGACY OR CONFIG_BT_LL_SW_SPLIT)
if(CONFIG_BT_CTLR AND CONFIG_BT_LL_SW_SPLIT)
add_subdirectory(controller)
endif()
endif()

View file

@ -34,7 +34,7 @@ BUILD_ASSERT(CONFIG_BT_CTLR_RX_PRIO < CONFIG_BT_HCI_TX_PRIO);
* interrupts disabled.
*/
#if !defined(CONFIG_TEST) && !defined(CONFIG_ARCH_POSIX) && \
(defined(CONFIG_BT_LL_SW_SPLIT) || defined(CONFIG_BT_LL_SW_LEGACY))
defined(CONFIG_BT_LL_SW_SPLIT)
BUILD_ASSERT(!IS_ENABLED(CONFIG_LOG_IMMEDIATE), "Immediate logging not "
"supported with the software Link Layer");
#endif

View file

@ -75,40 +75,6 @@ config BT_LL_SW_SPLIT
help
Use Zephyr software BLE Link Layer ULL LLL split implementation.
config BT_LL_SW_LEGACY
# NOTE: This OLD architecture implementation will be deprecated, with
# no further new feature development.
bool "Software-based BLE Link Layer (deprecated)"
select BT_RECV_IS_RX_THREAD
select BT_HAS_HCI_VS
select ENTROPY_GENERATOR
select ENTROPY_NRF5_RNG if SOC_COMPATIBLE_NRF
select ENTROPY_NRF5_BIAS_CORRECTION if SOC_COMPATIBLE_NRF
depends on SOC_COMPATIBLE_NRF
select BT_CTLR_LE_ENC_SUPPORT if !BT_CTLR_DATA_LENGTH_CLEAR && \
!BT_CTLR_PHY_2M_NRF
select BT_CTLR_CONN_PARAM_REQ_SUPPORT
select BT_CTLR_EXT_REJ_IND_SUPPORT
select BT_CTLR_SLAVE_FEAT_REQ_SUPPORT
select BT_CTLR_DATA_LEN_UPDATE_SUPPORT if !SOC_SERIES_NRF51X || \
BT_CTLR_DATA_LENGTH_CLEAR
select BT_CTLR_PRIVACY_SUPPORT if !SOC_SERIES_NRF51X
select BT_CTLR_EXT_SCAN_FP_SUPPORT
select BT_CTLR_PHY_UPDATE_SUPPORT if !SOC_SERIES_NRF51X || \
BT_CTLR_PHY_2M_NRF
select BT_CTLR_ADV_EXT_SUPPORT
select BT_CTLR_CHAN_SEL_2_SUPPORT
select BT_CTLR_MIN_USED_CHAN_SUPPORT
select BT_CTLR_DTM_HCI_SUPPORT
select BT_CTLR_XTAL_ADVANCED_SUPPORT
select BT_CTLR_SCHED_ADVANCED_SUPPORT
select BT_CTLR_TIFS_HW_SUPPORT
help
Use Zephyr software BLE Link Layer implementation.
endchoice
config BT_LLL_VENDOR_NORDIC
@ -393,7 +359,7 @@ config BT_CTLR_PRIVACY
bool "LE Controller-based Privacy"
depends on BT_CTLR_PRIVACY_SUPPORT
default y
select BT_CTLR_FILTER if (BT_LL_SW_SPLIT || BT_LL_SW_LEGACY)
select BT_CTLR_FILTER if BT_LL_SW_SPLIT
select BT_RPA
help
Enable support for Bluetooth v4.2 LE Controller-based Privacy feature
@ -519,7 +485,7 @@ config BT_CTLR_SMI_TX_SETTING
help
Enable support for Bluetooth 5.0 SMI TX through a system setting.
if BT_LL_SW_SPLIT || BT_LL_SW_LEGACY
if BT_LL_SW_SPLIT
config BT_CTLR_ADVANCED_FEATURES
bool "Show advanced features"
@ -582,28 +548,6 @@ config BT_CTLR_OPTIMIZE_FOR_SPEED
help
Optimize compilation of controller for execution speed.
if BT_LL_SW_LEGACY
config BT_CTLR_WORKER_PRIO
int "Radio and Ticker's Worker IRQ priority"
range 0 3 if SOC_SERIES_NRF51X
range 0 6 if SOC_COMPATIBLE_NRF52X
default 0
help
The interrupt priority for event preparation and radio IRQ. This value
shall be less than or equal to the Ticker's Job priority value.
config BT_CTLR_JOB_PRIO
int "Ticker's JOB IRQ priority"
range BT_CTLR_WORKER_PRIO 3 if SOC_SERIES_NRF51X
range BT_CTLR_WORKER_PRIO 6 if SOC_COMPATIBLE_NRF52X
default 0
help
The interrupt priority for Ticker's Job (SWI4) IRQ. This value shall
be greater than or equal to the Ticker's Worker IRQ priority value.
endif # BT_LL_SW_LEGACY
config BT_CTLR_XTAL_ADVANCED
bool "Advanced event preparation"
depends on BT_CTLR_XTAL_ADVANCED_SUPPORT
@ -849,7 +793,7 @@ config BT_MAYFLY_YIELD_AFTER_CALL
config BT_TICKER_COMPATIBILITY_MODE
bool "Ticker compatibility mode"
default y if SOC_SERIES_NRF51X || BT_LL_SW_LEGACY
default y if SOC_SERIES_NRF51X
help
This option enables legacy ticker scheduling which defers overlapping
ticker node timeouts and thereby prevents ticker interrupts during
@ -994,7 +938,7 @@ config BT_CTLR_DEBUG_PINS
when debugging with a logic analyzer or profiling certain sections of
the code.
endif # BT_LL_SW_SPLIT || BT_LL_SW_LEGACY
endif # BT_LL_SW_SPLIT
config BT_CTLR_ASSERT_HANDLER
bool "Application Defined Assertion Handler"

View file

@ -115,9 +115,6 @@ static void prio_recv_thread(void *p1, void *p2, void *p3)
buf = process_prio_evt(node_rx);
if (buf) {
#if defined(CONFIG_BT_LL_SW_LEGACY)
radio_rx_fc_set(node_rx->hdr.handle, 0);
#endif /* CONFIG_BT_LL_SW_LEGACY */
node_rx->hdr.next = NULL;
ll_rx_mem_release((void **)&node_rx);
@ -184,10 +181,6 @@ static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx,
break;
}
#if defined(CONFIG_BT_LL_SW_LEGACY)
radio_rx_fc_set(node_rx->hdr.handle, 0);
#endif /* CONFIG_BT_LL_SW_LEGACY */
node_rx->hdr.next = NULL;
ll_rx_mem_release((void **)&node_rx);

File diff suppressed because it is too large Load diff

View file

@ -1,235 +0,0 @@
/*
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
/*****************************************************************************
* Zephyr Kconfig defined
****************************************************************************/
#ifdef CONFIG_BT_MAX_CONN
#define RADIO_CONNECTION_CONTEXT_MAX CONFIG_BT_MAX_CONN
#else
#define RADIO_CONNECTION_CONTEXT_MAX 0
#endif
#ifdef CONFIG_BT_CTLR_RX_BUFFERS
#define RADIO_PACKET_COUNT_RX_MAX CONFIG_BT_CTLR_RX_BUFFERS
#endif
#ifdef CONFIG_BT_CTLR_TX_BUFFERS
#define RADIO_PACKET_COUNT_TX_MAX CONFIG_BT_CTLR_TX_BUFFERS
#endif
#ifdef CONFIG_BT_CTLR_TX_BUFFER_SIZE
#define RADIO_PACKET_TX_DATA_SIZE CONFIG_BT_CTLR_TX_BUFFER_SIZE
#endif
/*****************************************************************************
* Timer Resources (Controller defined)
****************************************************************************/
#define RADIO_TICKER_ID_EVENT 0
#define RADIO_TICKER_ID_MARKER_0 1
#define RADIO_TICKER_ID_PRE_EMPT 2
#define RADIO_TICKER_ID_ADV_STOP 3
#define RADIO_TICKER_ID_SCAN_STOP 4
#define RADIO_TICKER_ID_ADV 5
#define RADIO_TICKER_ID_SCAN 6
#define RADIO_TICKER_ID_FIRST_CONNECTION 7
#define RADIO_TICKER_INSTANCE_ID_RADIO 0
#define RADIO_TICKER_INSTANCE_ID_APP 1
#define RADIO_TICKER_USERS 3
#define RADIO_TICKER_USER_ID_WORKER MAYFLY_CALL_ID_0
#define RADIO_TICKER_USER_ID_JOB MAYFLY_CALL_ID_1
#define RADIO_TICKER_USER_ID_APP MAYFLY_CALL_ID_PROGRAM
#define RADIO_TICKER_USER_WORKER_OPS (7 + 1)
#define RADIO_TICKER_USER_JOB_OPS (2 + 1)
#define RADIO_TICKER_USER_APP_OPS (1 + 1)
#define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS + \
RADIO_TICKER_USER_JOB_OPS + \
RADIO_TICKER_USER_APP_OPS)
#define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION + \
RADIO_CONNECTION_CONTEXT_MAX)
/*****************************************************************************
* Controller Interface Defines
****************************************************************************/
#if defined(CONFIG_BT_CTLR_WORKER_PRIO)
#define RADIO_TICKER_USER_ID_WORKER_PRIO CONFIG_BT_CTLR_WORKER_PRIO
#else
#define RADIO_TICKER_USER_ID_WORKER_PRIO 0
#endif
#if defined(CONFIG_BT_CTLR_JOB_PRIO)
#define RADIO_TICKER_USER_ID_JOB_PRIO CONFIG_BT_CTLR_JOB_PRIO
#else
#define RADIO_TICKER_USER_ID_JOB_PRIO 0
#endif
/*****************************************************************************
* Controller Reference Defines (compile time override-able)
****************************************************************************/
/* Implementation default L2CAP MTU */
#ifndef RADIO_L2CAP_MTU_MAX
#define RADIO_L2CAP_MTU_MAX (LL_LENGTH_OCTETS_RX_MAX - 4)
#endif
/* Maximise L2CAP MTU to LL data PDU size */
#if (RADIO_L2CAP_MTU_MAX < (LL_LENGTH_OCTETS_RX_MAX - 4))
#undef RADIO_L2CAP_MTU_MAX
#define RADIO_L2CAP_MTU_MAX (LL_LENGTH_OCTETS_RX_MAX - 4)
#endif
/* Maximum LL PDU Receive pool size. */
#ifndef RADIO_PACKET_COUNT_RX_MAX
#define RADIO_PACKET_COUNT_RX ((RADIO_L2CAP_MTU_MAX + \
LL_LENGTH_OCTETS_RX_MAX + 3) / \
LL_LENGTH_OCTETS_RX_MAX)
#define RADIO_PACKET_COUNT_RX_MAX (RADIO_PACKET_COUNT_RX + \
((RADIO_CONNECTION_CONTEXT_MAX - 1) * \
(RADIO_PACKET_COUNT_RX - 1)))
#endif /* RADIO_PACKET_COUNT_RX_MAX */
/* Maximum LL PDU Transmit pool size and application tx count. */
#ifndef RADIO_PACKET_COUNT_TX_MAX
#define RADIO_PACKET_COUNT_APP_TX_MAX RADIO_CONNECTION_CONTEXT_MAX
#define RADIO_PACKET_COUNT_TX_MAX (RADIO_PACKET_COUNT_RX_MAX + \
RADIO_PACKET_COUNT_APP_TX_MAX)
#else
#define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_PACKET_COUNT_TX_MAX)
#endif
/* Tx Data Size */
#if !defined(RADIO_PACKET_TX_DATA_SIZE) || \
(RADIO_PACKET_TX_DATA_SIZE < RADIO_LL_LENGTH_OCTETS_RX_MIN)
#define RADIO_PACKET_TX_DATA_SIZE RADIO_LL_LENGTH_OCTETS_RX_MIN
#endif
/*****************************************************************************
* Controller Interface Structures
****************************************************************************/
struct radio_adv_data {
u8_t data[DOUBLE_BUFFER_SIZE][PDU_AC_SIZE_MAX];
u8_t first;
u8_t last;
};
struct radio_pdu_node_tx {
void *next;
u8_t pdu_data[1];
};
struct radio_le_conn_cmplt {
u8_t status;
u8_t role;
u8_t peer_addr_type;
u8_t peer_addr[BDADDR_SIZE];
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t peer_rpa[BDADDR_SIZE];
u8_t local_rpa[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
u16_t interval;
u16_t latency;
u16_t timeout;
u8_t mca;
};
struct radio_le_conn_update_cmplt {
u8_t status;
u16_t interval;
u16_t latency;
u16_t timeout;
};
struct radio_le_chan_sel_algo {
u8_t chan_sel_algo;
};
struct radio_le_phy_upd_cmplt {
u8_t status;
u8_t tx;
u8_t rx;
};
struct radio_pdu_node_rx_hdr {
union {
sys_snode_t node; /* used by slist */
void *next; /* used also by k_fifo once pulled */
void *link;
u8_t packet_release_last;
};
enum node_rx_type type;
u8_t user_meta; /* User metadata */
u16_t handle;
};
struct radio_pdu_node_rx {
struct radio_pdu_node_rx_hdr hdr;
u8_t pdu_data[1];
};
/*****************************************************************************
* Controller Interface Functions
****************************************************************************/
/* Downstream */
u32_t radio_init(void *hf_clock, u8_t sca, void *entropy,
u8_t connection_count_max,
u8_t rx_count_max, u8_t tx_count_max,
u16_t packet_data_octets_max,
u16_t packet_tx_data_size, u8_t *mem_radio,
u16_t mem_size);
struct device *radio_hf_clock_get(void);
void radio_ticks_active_to_start_set(u32_t ticks_active_to_start);
/* Downstream - Advertiser */
struct radio_adv_data *radio_adv_data_get(void);
struct radio_adv_data *radio_scan_data_get(void);
#if defined(CONFIG_BT_HCI_MESH_EXT)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u32_t radio_adv_enable(u8_t phy_p, u16_t interval, u8_t chan_map,
u8_t filter_policy, u8_t rl_idx,
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy,
u8_t rl_idx,
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t at_anchor, u32_t ticks_anchor, u8_t retry,
u8_t scan_window, u8_t scan_delay);
#else /* !CONFIG_BT_HCI_MESH_EXT */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u32_t radio_adv_enable(u8_t phy_p, u16_t interval, u8_t chan_map,
u8_t filter_policy, u8_t rl_idx);
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy,
u8_t rl_idx);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
#endif /* !CONFIG_BT_HCI_MESH_EXT */
u8_t radio_adv_disable(void);
u32_t ll_adv_is_enabled(u16_t handle);
u32_t radio_adv_filter_pol_get(void);
/* Downstream - Scanner */
u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr,
u16_t interval, u16_t window, u8_t filter_policy,
u8_t rpa_gen, u8_t rl_idx);
u8_t radio_scan_disable(bool scanner);
u32_t ll_scan_is_enabled(u16_t handle);
u32_t radio_scan_filter_pol_get(void);
u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr,
u16_t interval, u16_t latency,
u16_t timeout);
/* Upstream */
u8_t radio_rx_fc_set(u16_t handle, u8_t fc);
u8_t radio_rx_fc_get(u16_t *handle);
/* Callbacks */
extern void radio_active_callback(u8_t active);
extern void radio_event_callback(void);
extern void ll_adv_scan_state_cb(u8_t bm);

View file

@ -1,391 +0,0 @@
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
enum llcp {
LLCP_NONE,
LLCP_CONN_UPD,
LLCP_CHAN_MAP,
/*
* LLCP_TERMINATE,
* LLCP_FEATURE_EXCHANGE,
* LLCP_VERSION_EXCHANGE,
*/
#if defined(CONFIG_BT_CTLR_LE_ENC)
LLCP_ENCRYPTION,
#endif /* CONFIG_BT_CTLR_LE_ENC */
LLCP_CONNECTION_PARAM_REQ,
#if defined(CONFIG_BT_CTLR_LE_PING)
LLCP_PING,
#endif /* CONFIG_BT_CTLR_LE_PING */
#if defined(CONFIG_BT_CTLR_PHY)
LLCP_PHY_UPD,
#endif /* CONFIG_BT_CTLR_PHY */
};
struct shdr {
u32_t ticks_xtal_to_start;
u32_t ticks_active_to_start;
u32_t ticks_preempt_to_start;
u32_t ticks_slot;
};
struct connection {
struct shdr hdr;
u8_t access_addr[4];
u8_t crc_init[3];
u8_t data_chan_map[5];
u8_t chm_update;
u8_t data_chan_count:6;
u8_t data_chan_sel:1;
u8_t role:1;
union {
struct {
u8_t data_chan_hop;
u8_t data_chan_use;
};
u16_t data_chan_id;
};
u16_t handle;
u16_t event_counter;
u16_t conn_interval;
u16_t latency;
u16_t latency_prepare;
u16_t latency_event;
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
u16_t default_tx_octets;
u16_t max_tx_octets;
u16_t max_rx_octets;
#if defined(CONFIG_BT_CTLR_PHY)
u16_t default_tx_time;
u16_t max_tx_time;
u16_t max_rx_time;
#endif /* CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
u8_t phy_pref_tx:3;
u8_t phy_tx:3;
u8_t phy_pref_flags:1;
u8_t phy_flags:1;
u8_t phy_tx_time:3;
u8_t phy_pref_rx:3;
u8_t phy_rx:3;
#endif /* CONFIG_BT_CTLR_PHY */
u16_t connect_expire;
u16_t supervision_reload;
u16_t supervision_expire;
u16_t procedure_reload;
u16_t procedure_expire;
#if defined(CONFIG_BT_CTLR_LE_PING)
u16_t appto_reload;
u16_t appto_expire;
u16_t apto_reload;
u16_t apto_expire;
#endif /* CONFIG_BT_CTLR_LE_PING */
union {
struct {
u8_t reserved:5;
u8_t fex_valid:1;
} common;
struct {
u8_t terminate_ack:1;
u8_t rfu:4;
u8_t fex_valid:1;
} master;
struct {
u8_t latency_enabled:1;
u8_t latency_cancel:1;
u8_t sca:3;
u8_t fex_valid:1;
u32_t window_widening_periodic_us;
u32_t window_widening_max_us;
u32_t window_widening_prepare_us;
u32_t window_widening_event_us;
u32_t window_size_prepare_us;
u32_t window_size_event_us;
u32_t force;
u32_t ticks_to_offset;
} slave;
};
u8_t llcp_req;
u8_t llcp_ack;
enum llcp llcp_type;
union {
struct {
u16_t instant;
u16_t *pdu_win_offset;
u32_t ticks_anchor;
} conn_upd;
struct {
u8_t initiate:1;
u8_t chm[5];
u16_t instant;
} chan_map;
#if defined(CONFIG_BT_CTLR_PHY)
struct {
u8_t initiate:1;
u8_t cmd:1;
u8_t tx:3;
u8_t rx:3;
u16_t instant;
} phy_upd_ind;
#endif /* CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_LE_ENC)
struct {
enum {
LLCP_ENC_STATE_INPROG,
LLCP_ENC_STATE_INIT,
LLCP_ENC_STATE_LTK_WAIT,
} state:2 __packed;
u8_t error_code;
u8_t skd[16];
} encryption;
#endif /* CONFIG_BT_CTLR_LE_ENC */
} llcp;
struct {
u8_t req;
u8_t ack;
enum {
LLCP_CUI_STATE_INPROG,
LLCP_CUI_STATE_USE,
LLCP_CUI_STATE_SELECT
} state:2 __packed;
u8_t cmd:1;
u16_t interval;
u16_t latency;
u16_t timeout;
u32_t win_offset_us;
u8_t win_size;
} llcp_cu;
struct {
u8_t req;
u8_t ack;
u32_t features;
} llcp_feature;
struct {
u8_t req;
u8_t ack;
u8_t tx:1;
u8_t rx:1;
u8_t version_number;
u16_t company_id;
u16_t sub_version_number;
} llcp_version;
struct {
u8_t req;
u8_t ack;
u8_t reason_own;
u8_t reason_peer;
struct {
struct radio_pdu_node_rx_hdr hdr;
u8_t reason;
} radio_pdu_node_rx;
} llcp_terminate;
#if defined(CONFIG_BT_CTLR_LE_ENC)
struct {
u8_t req;
u8_t ack;
u8_t ediv[2];
u8_t rand[8];
u8_t ltk[16];
} llcp_enc;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
struct {
u8_t req;
u8_t ack;
enum {
LLCP_CPR_STATE_REQ,
LLCP_CPR_STATE_RSP,
LLCP_CPR_STATE_APP_REQ,
LLCP_CPR_STATE_APP_WAIT,
LLCP_CPR_STATE_RSP_WAIT,
LLCP_CPR_STATE_UPD
} state:3 __packed;
u8_t cmd:1;
u8_t disabled:1;
u8_t status;
u16_t interval_min;
u16_t interval_max;
u16_t latency;
u16_t timeout;
u8_t preferred_periodicity;
u16_t reference_conn_event_count;
u16_t offset0;
u16_t offset1;
u16_t offset2;
u16_t offset3;
u16_t offset4;
u16_t offset5;
u16_t *pdu_win_offset0;
u32_t ticks_ref;
u32_t ticks_to_offset_next;
} llcp_conn_param;
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
struct {
u8_t req;
u8_t ack;
u8_t state:3;
#define LLCP_LENGTH_STATE_REQ 0
#define LLCP_LENGTH_STATE_REQ_ACK_WAIT 1
#define LLCP_LENGTH_STATE_RSP_WAIT 2
#define LLCP_LENGTH_STATE_RSP_ACK_WAIT 3
#define LLCP_LENGTH_STATE_RESIZE 4
#define LLCP_LENGTH_STATE_RESIZE_RSP 5
#define LLCP_LENGTH_STATE_RESIZE_RSP_ACK_WAIT 6
u8_t disabled:1;
u16_t rx_octets;
u16_t tx_octets;
#if defined(CONFIG_BT_CTLR_PHY)
u16_t rx_time;
u16_t tx_time;
#endif /* CONFIG_BT_CTLR_PHY */
struct {
u16_t tx_octets;
#if defined(CONFIG_BT_CTLR_PHY)
u16_t tx_time;
#endif /* CONFIG_BT_CTLR_PHY */
} cache;
} llcp_length;
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
struct {
u8_t req;
u8_t ack;
u8_t state:2;
#define LLCP_PHY_STATE_REQ 0
#define LLCP_PHY_STATE_ACK_WAIT 1
#define LLCP_PHY_STATE_RSP_WAIT 2
#define LLCP_PHY_STATE_UPD 3
u8_t tx:3;
u8_t rx:3;
u8_t flags:1;
u8_t cmd:1;
u8_t disabled:1;
} llcp_phy;
#endif /* CONFIG_BT_CTLR_PHY */
struct ccm ccm_rx;
struct ccm ccm_tx;
struct radio_pdu_node_tx *pkt_tx_head;
struct radio_pdu_node_tx *pkt_tx_ctrl;
struct radio_pdu_node_tx *pkt_tx_ctrl_last;
struct radio_pdu_node_tx *pkt_tx_data;
struct radio_pdu_node_tx *pkt_tx_last;
u8_t packet_tx_head_len;
u8_t packet_tx_head_offset;
u8_t sn:1;
u8_t nesn:1;
u8_t pause_rx:1;
u8_t pause_tx:1;
u8_t enc_rx:1;
u8_t enc_tx:1;
u8_t refresh:1;
u8_t empty:1;
/* Detect empty L2CAP start frame */
u8_t start_empty:1;
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) || defined(CONFIG_BT_CTLR_PHY)
u8_t evt_len_upd:1;
u8_t evt_len_adv:1;
#endif
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
u8_t rssi_latest;
#if defined(CONFIG_BT_CTLR_CONN_RSSI_EVENT)
u8_t rssi_reported;
u8_t rssi_sample_count;
#endif /* CONFIG_BT_CTLR_CONN_RSSI_EVENT) */
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
s8_t tx_pwr_lvl;
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
};
#define CONNECTION_T_SIZE MROUND(sizeof(struct connection))
struct pdu_data_q_tx {
u16_t handle;
struct radio_pdu_node_tx *node_tx;
};
/* Minimum Rx Data allocation size */
#define PACKET_RX_DATA_SIZE_MIN \
MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) + \
(PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA))
/* Minimum Tx Ctrl allocation size */
#define PACKET_TX_CTRL_SIZE_MIN \
MROUND(offsetof(struct radio_pdu_node_tx, pdu_data) + \
offsetof(struct pdu_data, lldata) + 27)
/** @todo fix starvation when ctrl rx in radio ISR
* for multiple connections needs to tx back to peer.
*/
#define PACKET_MEM_COUNT_TX_CTRL 2
#define LL_MEM_CONN (sizeof(struct connection) * RADIO_CONNECTION_CONTEXT_MAX)
#define LL_MEM_RXQ (sizeof(void *) * (RADIO_PACKET_COUNT_RX_MAX + 4))
#define LL_MEM_TXQ (sizeof(struct pdu_data_q_tx) * \
(RADIO_PACKET_COUNT_TX_MAX + 2))
#define LL_MEM_RX_POOL_SZ (MROUND(offsetof(struct radio_pdu_node_rx, \
pdu_data) + \
MAX((PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA), \
(offsetof(struct pdu_data, lldata) + \
LL_LENGTH_OCTETS_RX_MAX))) * \
(RADIO_PACKET_COUNT_RX_MAX + 3))
#define LL_MEM_RX_LINK_POOL (sizeof(void *) * 2 * ((RADIO_PACKET_COUNT_RX_MAX +\
4) + RADIO_CONNECTION_CONTEXT_MAX))
#define LL_MEM_TX_CTRL_POOL (PACKET_TX_CTRL_SIZE_MIN * PACKET_MEM_COUNT_TX_CTRL)
#define LL_MEM_TX_DATA_POOL ((MROUND(offsetof( \
struct radio_pdu_node_tx, pdu_data) + \
offsetof(struct pdu_data, lldata) + \
RADIO_PACKET_TX_DATA_SIZE)) \
* (RADIO_PACKET_COUNT_TX_MAX + 1))
#define LL_MEM_TOTAL (LL_MEM_CONN + LL_MEM_RXQ + (LL_MEM_TXQ * 2) + \
LL_MEM_RX_POOL_SZ + \
LL_MEM_RX_LINK_POOL + LL_MEM_TX_CTRL_POOL + LL_MEM_TX_DATA_POOL)

View file

@ -1,194 +0,0 @@
/*
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <string.h>
#include <soc.h>
#include <device.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>
#include <bluetooth/hci.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ll
#include "common/log.h"
#include "hal/cpu.h"
#include "hal/cntr.h"
#include "hal/ccm.h"
#include "hal/radio.h"
#include "hal/ticker.h"
#include "hal/debug.h"
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "util/mayfly.h"
#include "ticker/ticker.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ctrl_internal.h"
#include "ll.h"
#include "ll_feat.h"
#include "ll_filter.h"
#include "ll_settings.h"
/* Global singletons */
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
#define FLASH_TICKER_NODES 1 /* No. of tickers reserved for flashing */
#define FLASH_TICKER_USER_APP_OPS 1 /* No. of additional ticker operations */
#else
#define FLASH_TICKER_NODES 0
#define FLASH_TICKER_USER_APP_OPS 0
#endif
#define TICKER_NODES (RADIO_TICKER_NODES + FLASH_TICKER_NODES)
#define TICKER_USER_APP_OPS (RADIO_TICKER_USER_APP_OPS + \
FLASH_TICKER_USER_APP_OPS)
#define TICKER_USER_OPS (RADIO_TICKER_USER_OPS + \
FLASH_TICKER_USER_APP_OPS)
/* memory for ticker nodes/instances */
static u8_t MALIGN(4) _ticker_nodes[TICKER_NODES][TICKER_NODE_T_SIZE];
/* memory for users/contexts operating on ticker module */
static u8_t MALIGN(4) _ticker_users[MAYFLY_CALLER_COUNT][TICKER_USER_T_SIZE];
/* memory for user/context simultaneous API operations */
static u8_t MALIGN(4) _ticker_user_ops[TICKER_USER_OPS][TICKER_USER_OP_T_SIZE];
/* memory for Bluetooth Controller (buffers, queues etc.) */
static u8_t MALIGN(4) _radio[LL_MEM_TOTAL];
static struct k_sem *sem_recv;
void radio_active_callback(u8_t active)
{
}
void radio_event_callback(void)
{
k_sem_give(sem_recv);
}
ISR_DIRECT_DECLARE(radio_nrf5_isr)
{
DEBUG_RADIO_ISR(1);
isr_radio();
ISR_DIRECT_PM();
DEBUG_RADIO_ISR(0);
return 1;
}
static void rtc0_nrf5_isr(void *arg)
{
DEBUG_TICKER_ISR(1);
/* On compare0 run ticker worker instance0 */
if (NRF_RTC0->EVENTS_COMPARE[0]) {
NRF_RTC0->EVENTS_COMPARE[0] = 0;
ticker_trigger(0);
}
mayfly_run(MAYFLY_CALL_ID_0);
DEBUG_TICKER_ISR(0);
}
static void swi5_nrf5_isr(void *arg)
{
DEBUG_TICKER_JOB(1);
mayfly_run(MAYFLY_CALL_ID_1);
DEBUG_TICKER_JOB(0);
}
int ll_init(struct k_sem *sem_rx)
{
struct device *clk;
struct device *entropy;
u32_t err;
sem_recv = sem_rx;
clk = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock)));
if (!clk) {
return -ENODEV;
}
clock_control_on(clk, CLOCK_CONTROL_NRF_SUBSYS_LF);
entropy = device_get_binding(DT_CHOSEN_ZEPHYR_ENTROPY_LABEL);
if (!entropy) {
return -ENODEV;
}
/* TODO: bind and use counter driver */
cntr_init();
mayfly_init();
_ticker_users[MAYFLY_CALL_ID_0][0] = RADIO_TICKER_USER_WORKER_OPS;
_ticker_users[MAYFLY_CALL_ID_1][0] = RADIO_TICKER_USER_JOB_OPS;
_ticker_users[MAYFLY_CALL_ID_2][0] = 0;
_ticker_users[MAYFLY_CALL_ID_PROGRAM][0] = TICKER_USER_APP_OPS;
err = ticker_init(RADIO_TICKER_INSTANCE_ID_RADIO,
TICKER_NODES, &_ticker_nodes[0],
MAYFLY_CALLER_COUNT, &_ticker_users[0],
TICKER_USER_OPS, &_ticker_user_ops[0],
hal_ticker_instance0_caller_id_get,
hal_ticker_instance0_sched,
hal_ticker_instance0_trigger_set);
LL_ASSERT(!err);
err = radio_init(clk, CLOCK_CONTROL_NRF_K32SRC_ACCURACY, entropy,
RADIO_CONNECTION_CONTEXT_MAX,
RADIO_PACKET_COUNT_RX_MAX,
RADIO_PACKET_COUNT_TX_MAX,
LL_LENGTH_OCTETS_RX_MAX,
RADIO_PACKET_TX_DATA_SIZE, &_radio[0], sizeof(_radio));
if (err) {
BT_ERR("Required RAM size: %d, supplied: %u.", err,
sizeof(_radio));
return -ENOMEM;
}
/* reset whitelist, resolving list and initialise RPA timeout*/
if (IS_ENABLED(CONFIG_BT_CTLR_FILTER)) {
ll_filter_reset(true);
}
IRQ_DIRECT_CONNECT(RADIO_IRQn, CONFIG_BT_CTLR_WORKER_PRIO,
radio_nrf5_isr, 0);
IRQ_CONNECT(RTC0_IRQn, CONFIG_BT_CTLR_WORKER_PRIO,
rtc0_nrf5_isr, NULL, 0);
IRQ_CONNECT(SWI5_IRQn, CONFIG_BT_CTLR_JOB_PRIO,
swi5_nrf5_isr, NULL, 0);
irq_enable(RADIO_IRQn);
irq_enable(RTC0_IRQn);
irq_enable(SWI5_IRQn);
return 0;
}
void ll_timeslice_ticker_id_get(u8_t * const instance_index, u8_t * const user_id)
{
*user_id = (TICKER_NODES - FLASH_TICKER_NODES); /* The last index in the total tickers */
*instance_index = RADIO_TICKER_INSTANCE_ID_RADIO;
}

View file

@ -17,17 +17,10 @@
#include "pdu.h"
#include "lll.h"
#if defined(CONFIG_BT_LL_SW_LEGACY)
#include <sys/slist.h>
#include "ctrl.h"
#define ull_adv_is_enabled ll_adv_is_enabled
#define ull_scan_is_enabled ll_scan_is_enabled
#elif defined(CONFIG_BT_LL_SW_SPLIT)
#include "lll_scan.h"
#include "ull_scan_types.h"
#include "ull_adv_internal.h"
#include "ull_scan_internal.h"
#endif
static u8_t pub_addr[BDADDR_SIZE];
static u8_t rnd_addr[BDADDR_SIZE];

View file

@ -1,509 +0,0 @@
/*
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr.h>
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "hal/debug.h"
#include "ll_filter.h"
#include "ll_adv.h"
static struct ll_adv_set ll_adv;
struct ll_adv_set *ll_adv_set_get(void)
{
return &ll_adv;
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval,
u8_t adv_type, u8_t own_addr_type,
u8_t direct_addr_type, u8_t const *const direct_addr,
u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr,
u8_t phy_p, u8_t skip, u8_t phy_s, u8_t sid, u8_t sreq)
{
u8_t const pdu_adv_type[] = {PDU_ADV_TYPE_ADV_IND,
PDU_ADV_TYPE_DIRECT_IND,
PDU_ADV_TYPE_SCAN_IND,
PDU_ADV_TYPE_NONCONN_IND,
PDU_ADV_TYPE_DIRECT_IND,
PDU_ADV_TYPE_EXT_IND};
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_params_set(u16_t interval, u8_t adv_type,
u8_t own_addr_type, u8_t direct_addr_type,
u8_t const *const direct_addr, u8_t chan_map,
u8_t filter_policy)
{
u8_t const pdu_adv_type[] = {PDU_ADV_TYPE_ADV_IND,
PDU_ADV_TYPE_DIRECT_IND,
PDU_ADV_TYPE_SCAN_IND,
PDU_ADV_TYPE_NONCONN_IND,
PDU_ADV_TYPE_DIRECT_IND};
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
struct radio_adv_data *radio_adv_data;
struct pdu_adv *pdu;
if (ll_adv_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
/* TODO: check and fail (0x12, invalid HCI cmd param) if invalid
* evt_prop bits.
*/
ll_adv.phy_p = BIT(0);
/* extended */
if (adv_type > 0x04) {
/* legacy */
if (evt_prop & BIT(4)) {
u8_t const leg_adv_type[] = { 0x03, 0x04, 0x02, 0x00};
adv_type = leg_adv_type[evt_prop & 0x03];
/* high duty cycle directed */
if (evt_prop & BIT(3)) {
adv_type = 0x01;
}
} else {
/* - Connectable and scannable not allowed;
* - High duty cycle directed connectable not allowed
*/
if (((evt_prop & 0x03) == 0x03) ||
((evt_prop & 0x0C) == 0x0C)) {
return 0x12; /* invalid HCI cmd param */
}
adv_type = 0x05; /* PDU_ADV_TYPE_EXT_IND */
ll_adv.phy_p = phy_p;
}
}
#endif /* CONFIG_BT_CTLR_ADV_EXT */
/* remember params so that set adv/scan data and adv enable
* interface can correctly update adv/scan data in the
* double buffer between caller and controller context.
*/
/* Set interval for Undirected or Low Duty Cycle Directed Advertising */
if (adv_type != 0x01) {
ll_adv.interval = interval;
} else {
ll_adv.interval = 0;
}
ll_adv.chan_map = chan_map;
ll_adv.filter_policy = filter_policy;
/* update the "current" primary adv data */
radio_adv_data = radio_adv_data_get();
pdu = (struct pdu_adv *)&radio_adv_data->data[radio_adv_data->last][0];
pdu->type = pdu_adv_type[adv_type];
pdu->rfu = 0;
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2) &&
((pdu->type == PDU_ADV_TYPE_ADV_IND) ||
(pdu->type == PDU_ADV_TYPE_DIRECT_IND))) {
pdu->chan_sel = 1;
} else {
pdu->chan_sel = 0;
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
ll_adv.own_addr_type = own_addr_type;
if (ll_adv.own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
ll_adv.own_addr_type == BT_ADDR_LE_RANDOM_ID) {
ll_adv.id_addr_type = direct_addr_type;
memcpy(&ll_adv.id_addr, direct_addr, BDADDR_SIZE);
}
#endif /* CONFIG_BT_CTLR_PRIVACY */
pdu->tx_addr = own_addr_type & 0x1;
pdu->rx_addr = 0;
if (pdu->type == PDU_ADV_TYPE_DIRECT_IND) {
pdu->rx_addr = direct_addr_type;
memcpy(&pdu->direct_ind.tgt_addr[0], direct_addr, BDADDR_SIZE);
pdu->len = sizeof(struct pdu_adv_direct_ind);
#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;
u8_t *_ptr, *ptr;
u8_t len;
p = (void *)&pdu->adv_ext_ind;
h = (void *)p->ext_hdr_adi_adv_data;
ptr = (u8_t *)h + sizeof(*h);
_ptr = ptr;
/* No ACAD and no AdvData */
p->ext_hdr_len = 0;
p->adv_mode = evt_prop & 0x03;
/* Zero-init header flags */
*(u8_t *)&_h = *(u8_t *)h;
*(u8_t *)h = 0;
/* AdvA flag */
if (_h.adv_addr) {
_ptr += BDADDR_SIZE;
}
if (!p->adv_mode &&
(!_h.aux_ptr ||
(!(evt_prop & BIT(5)) && (phy_p != BIT(2))))) {
/* TODO: optional on 1M with Aux Ptr */
h->adv_addr = 1;
/* NOTE: AdvA is filled at enable */
ptr += BDADDR_SIZE;
}
/* TODO: TargetA flag */
/* ADI flag */
if (_h.adi) {
h->adi = 1;
ptr += sizeof(struct ext_adv_adi);
}
/* AuxPtr flag */
if (_h.aux_ptr) {
h->aux_ptr = 1;
ptr += sizeof(struct ext_adv_aux_ptr);
}
/* No SyncInfo flag in primary channel PDU */
/* Tx Power flag */
if (evt_prop & BIT(6) &&
(!_h.aux_ptr || (phy_p != BIT(2)))) {
h->tx_pwr = 1;
ptr++;
}
/* Calc primary PDU len */
len = ptr - (u8_t *)p;
if (len > (offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data) + sizeof(*h))) {
p->ext_hdr_len = len -
offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data);
pdu->len = len;
} else {
pdu->len = offsetof(struct pdu_adv_com_ext_adv,
ext_hdr_adi_adv_data);
}
/* 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) {
u8_t _tx_pwr;
_tx_pwr = 0;
if (tx_pwr) {
if (*tx_pwr != 0x7F) {
_tx_pwr = *tx_pwr;
} else {
*tx_pwr = _tx_pwr;
}
}
ptr--;
*ptr = _tx_pwr;
}
/* No SyncInfo in primary channel PDU */
/* AuxPtr */
if (h->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(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;
}
/* NOTE: TargetA, filled at enable and RPA timeout */
/* NOTE: AdvA, filled at enable and RPA timeout */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
} else if (pdu->len == 0) {
pdu->len = BDADDR_SIZE;
}
/* update the current scan data */
radio_adv_data = radio_scan_data_get();
pdu = (struct pdu_adv *)&radio_adv_data->data[radio_adv_data->last][0];
pdu->type = PDU_ADV_TYPE_SCAN_RSP;
pdu->rfu = 0;
pdu->chan_sel = 0;
pdu->tx_addr = own_addr_type & 0x1;
pdu->rx_addr = 0;
if (pdu->len == 0) {
pdu->len = BDADDR_SIZE;
}
return 0;
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_data_set(u16_t handle, u8_t len, u8_t const *const data)
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_data_set(u8_t len, u8_t const *const data)
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
{
struct radio_adv_data *radio_adv_data;
struct pdu_adv *prev;
struct pdu_adv *pdu;
u8_t last;
/* Dont update data if directed or extended advertising. */
radio_adv_data = radio_adv_data_get();
prev = (struct pdu_adv *)&radio_adv_data->data[radio_adv_data->last][0];
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;
}
/* use the last index in double buffer, */
if (radio_adv_data->first == radio_adv_data->last) {
last = radio_adv_data->last + 1;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
} else {
last = radio_adv_data->last;
}
/* update adv pdu fields. */
pdu = (struct pdu_adv *)&radio_adv_data->data[last][0];
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;
/* commit the update so controller picks it. */
radio_adv_data->last = last;
return 0;
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_scan_rsp_set(u16_t handle, u8_t len, u8_t const *const data)
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_scan_rsp_set(u8_t len, u8_t const *const data)
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
{
struct radio_adv_data *radio_scan_data;
struct pdu_adv *prev;
struct pdu_adv *pdu;
u8_t last;
/* use the last index in double buffer, */
radio_scan_data = radio_scan_data_get();
if (radio_scan_data->first == radio_scan_data->last) {
last = radio_scan_data->last + 1;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0;
}
} else {
last = radio_scan_data->last;
}
/* update scan pdu fields. */
prev = (struct pdu_adv *)
&radio_scan_data->data[radio_scan_data->last][0];
pdu = (struct pdu_adv *)&radio_scan_data->data[last][0];
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);
/* commit the update so controller picks it. */
radio_scan_data->last = last;
return 0;
}
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT)
#if defined(CONFIG_BT_HCI_MESH_EXT)
u8_t ll_adv_enable(u16_t handle, u8_t enable,
u8_t at_anchor, u32_t ticks_anchor, u8_t retry,
u8_t scan_window, u8_t scan_delay)
#else /* !CONFIG_BT_HCI_MESH_EXT */
u8_t ll_adv_enable(u16_t handle, u8_t enable)
#endif /* !CONFIG_BT_HCI_MESH_EXT */
#else /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
u8_t ll_adv_enable(u8_t enable)
#endif /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
{
struct radio_adv_data *radio_scan_data;
struct radio_adv_data *radio_adv_data;
u8_t rl_idx = FILTER_IDX_NONE;
struct pdu_adv *pdu_scan;
struct pdu_adv *pdu_adv;
u32_t status;
if (!enable) {
return radio_adv_disable();
} else if (ll_adv_is_enabled(0)) {
return 0;
}
radio_adv_data = radio_adv_data_get();
pdu_adv = (struct pdu_adv *)&radio_adv_data->data
[radio_adv_data->last][0];
radio_scan_data = radio_scan_data_get();
pdu_scan = (struct pdu_adv *)&radio_scan_data->data
[radio_scan_data->last][0];
if (0) {
#if defined(CONFIG_BT_CTLR_ADV_EXT)
} else if (pdu_adv->type == PDU_ADV_TYPE_EXT_IND) {
struct pdu_adv_com_ext_adv *p;
struct ext_adv_hdr *h;
u8_t *ptr;
p = (void *)&pdu_adv->adv_ext_ind;
h = (void *)p->ext_hdr_adi_adv_data;
ptr = (u8_t *)h + sizeof(*h);
/* AdvA, fill here at enable */
if (h->adv_addr) {
u8_t *tx_addr = ll_addr_get(pdu_adv->tx_addr, NULL);
/* TODO: Privacy check */
if (pdu_adv->tx_addr && !mem_nz(tx_addr, BDADDR_SIZE)) {
return BT_HCI_ERR_INVALID_PARAM;
}
memcpy(ptr, tx_addr, BDADDR_SIZE);
}
/* TODO: TargetA, fill here at enable */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
} else {
bool priv = false;
#if defined(CONFIG_BT_CTLR_PRIVACY)
/* Prepare whitelist and optionally resolving list */
ll_filters_adv_update(ll_adv.filter_policy);
if (ll_adv.own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
ll_adv.own_addr_type == BT_ADDR_LE_RANDOM_ID) {
/* Look up the resolving list */
rl_idx = ll_rl_find(ll_adv.id_addr_type,
ll_adv.id_addr, NULL);
if (rl_idx != FILTER_IDX_NONE) {
/* Generate RPAs if required */
ll_rl_rpa_update(false);
}
ll_rl_pdu_adv_update(rl_idx, pdu_adv);
ll_rl_pdu_adv_update(rl_idx, pdu_scan);
priv = true;
}
#endif /* !CONFIG_BT_CTLR_PRIVACY */
if (!priv) {
memcpy(&pdu_adv->adv_ind.addr[0],
ll_addr_get(pdu_adv->tx_addr, NULL),
BDADDR_SIZE);
memcpy(&pdu_scan->scan_rsp.addr[0],
ll_addr_get(pdu_adv->tx_addr, NULL),
BDADDR_SIZE);
}
/* In case the local IRK was not set or no match was
* found the fallback address was used instead, check
* that a valid address has been set.
*/
if (pdu_adv->tx_addr &&
!mem_nz(pdu_adv->adv_ind.addr, BDADDR_SIZE)) {
return BT_HCI_ERR_INVALID_PARAM;
}
}
#if defined(CONFIG_BT_HCI_MESH_EXT)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
status = radio_adv_enable(ll_adv.phy_p, ll_adv.interval,
ll_adv.chan_map, ll_adv.filter_policy,
rl_idx,
#else /* !CONFIG_BT_CTLR_ADV_EXT */
status = radio_adv_enable(ll_adv.interval, ll_adv.chan_map,
ll_adv.filter_policy, rl_idx,
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
at_anchor, ticks_anchor, retry,
scan_window, scan_delay);
#else /* !CONFIG_BT_HCI_MESH_EXT */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
status = radio_adv_enable(ll_adv.phy_p, ll_adv.interval,
ll_adv.chan_map, ll_adv.filter_policy,
rl_idx);
#else /* !CONFIG_BT_CTLR_ADV_EXT */
status = radio_adv_enable(ll_adv.interval, ll_adv.chan_map,
ll_adv.filter_policy, rl_idx);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
#endif /* !CONFIG_BT_HCI_MESH_EXT */
return status;
}

View file

@ -1,25 +0,0 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
struct ll_adv_set {
u8_t chan_map:3;
u8_t filter_policy:2;
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t own_addr_type:2;
u8_t id_addr_type:1;
u8_t rl_idx;
u8_t id_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t phy_p:3;
u32_t interval;
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u16_t interval;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
};
struct ll_adv_set *ll_adv_set_get(void);

View file

@ -1,81 +0,0 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr.h>
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
u8_t ll_adv_aux_random_addr_set(u8_t handle, u8_t *addr)
{
/* TODO: store in adv set instance */
return 0;
}
u8_t *ll_adv_aux_random_addr_get(u8_t handle, u8_t *addr)
{
/* TODO: copy adv set instance addr into addr and/or return reference */
return NULL;
}
u8_t ll_adv_aux_ad_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data)
{
struct pdu_adv_com_ext_adv *p;
struct radio_adv_data *ad;
struct ext_adv_hdr *h;
struct pdu_adv *pdu;
/* TODO: */
ad = radio_adv_data_get();
pdu = (void *)ad->data[ad->last];
p = (void *)&pdu->adv_ext_ind;
h = (void *)p->ext_hdr_adi_adv_data;
if (!h->aux_ptr) {
}
return 0;
}
u8_t ll_adv_aux_sr_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data)
{
/* TODO: */
return 0;
}
u16_t ll_adv_aux_max_data_length_get(void)
{
/* TODO: return a Kconfig value */
return 0;
}
u8_t ll_adv_aux_set_count_get(void)
{
/* TODO: return a Kconfig value */
return 0;
}
u8_t ll_adv_aux_set_remove(u8_t handle)
{
/* TODO: reset/release primary channel and Aux channel PDUs */
return 0;
}
u8_t ll_adv_aux_set_clear(void)
{
/* TODO: reset/release all adv set primary channel and Aux channel
* PDUs
*/
return 0;
}

View file

@ -1,16 +0,0 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
u8_t ll_adv_aux_random_addr_set(u8_t handle, u8_t *addr);
u8_t *ll_adv_aux_random_addr_get(u8_t handle, u8_t *addr);
u8_t ll_adv_aux_ad_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data);
u8_t ll_adv_aux_sr_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data);
u16_t ll_adv_aux_max_data_length_get(void);
u8_t ll_adv_aux_set_count_get(void);
u8_t ll_adv_aux_set_remove(u8_t handle);
u8_t ll_adv_aux_set_clear(void);

View file

@ -1,949 +0,0 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr.h>
#include <sys/byteorder.h>
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "ll_adv.h"
#include "ll_filter.h"
#define ADDR_TYPE_ANON 0xFF
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_ctlr_ll_filter
#include "common/log.h"
#include "hal/debug.h"
/* Hardware whitelist */
static struct ll_filter wl_filter;
u8_t wl_anon;
#if defined(CONFIG_BT_CTLR_PRIVACY)
#include "common/rpa.h"
/* Whitelist peer list */
static struct {
u8_t taken:1;
u8_t id_addr_type:1;
u8_t rl_idx;
bt_addr_t id_addr;
} wl[WL_SIZE];
static u8_t rl_enable;
static struct rl_dev {
u8_t taken:1;
u8_t rpas_ready:1;
u8_t pirk:1;
u8_t lirk:1;
u8_t dev:1;
u8_t wl:1;
u8_t id_addr_type:1;
bt_addr_t id_addr;
u8_t local_irk[16];
u8_t pirk_idx;
bt_addr_t curr_rpa;
bt_addr_t peer_rpa;
bt_addr_t *local_rpa;
} rl[CONFIG_BT_CTLR_RL_SIZE];
static u8_t peer_irks[CONFIG_BT_CTLR_RL_SIZE][16];
static u8_t peer_irk_rl_ids[CONFIG_BT_CTLR_RL_SIZE];
static u8_t peer_irk_count;
static bt_addr_t local_rpas[CONFIG_BT_CTLR_RL_SIZE];
BUILD_ASSERT(ARRAY_SIZE(wl) < FILTER_IDX_NONE);
BUILD_ASSERT(ARRAY_SIZE(rl) < FILTER_IDX_NONE);
/* Hardware filter for the resolving list */
static struct ll_filter rl_filter;
#define DEFAULT_RPA_TIMEOUT_MS (900 * 1000)
u32_t rpa_timeout_ms;
s64_t rpa_last_ms;
struct k_delayed_work rpa_work;
#define LIST_MATCH(list, i, type, addr) (list[i].taken && \
(list[i].id_addr_type == (type & 0x1)) && \
!memcmp(list[i].id_addr.val, addr, BDADDR_SIZE))
static void wl_clear(void)
{
for (int i = 0; i < WL_SIZE; i++) {
wl[i].taken = 0U;
}
}
static u8_t wl_find(u8_t addr_type, u8_t *addr, u8_t *free)
{
int i;
if (free) {
*free = FILTER_IDX_NONE;
}
for (i = 0; i < WL_SIZE; i++) {
if (LIST_MATCH(wl, i, addr_type, addr)) {
return i;
} else if (free && !wl[i].taken && (*free == FILTER_IDX_NONE)) {
*free = i;
}
}
return FILTER_IDX_NONE;
}
static u32_t wl_add(bt_addr_le_t *id_addr)
{
u8_t i, j;
i = wl_find(id_addr->type, id_addr->a.val, &j);
/* Duplicate check */
if (i < ARRAY_SIZE(wl)) {
return 0;
} else if (j >= ARRAY_SIZE(wl)) {
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
}
i = j;
wl[i].id_addr_type = id_addr->type & 0x1;
bt_addr_copy(&wl[i].id_addr, &id_addr->a);
/* Get index to Resolving List if applicable */
j = ll_rl_find(id_addr->type, id_addr->a.val, NULL);
if (j < ARRAY_SIZE(rl)) {
wl[i].rl_idx = j;
rl[j].wl = 1U;
} else {
wl[i].rl_idx = FILTER_IDX_NONE;
}
wl[i].taken = 1U;
return 0;
}
static u32_t wl_remove(bt_addr_le_t *id_addr)
{
/* find the device and mark it as empty */
u8_t i = wl_find(id_addr->type, id_addr->a.val, NULL);
if (i < ARRAY_SIZE(wl)) {
u8_t j = wl[i].rl_idx;
if (j < ARRAY_SIZE(rl)) {
rl[j].wl = 0U;
}
wl[i].taken = 0U;
return 0;
}
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */
static void filter_clear(struct ll_filter *filter)
{
filter->enable_bitmask = 0U;
filter->addr_type_bitmask = 0U;
}
static void filter_insert(struct ll_filter *filter, int index, u8_t addr_type,
u8_t *bdaddr)
{
filter->enable_bitmask |= BIT(index);
filter->addr_type_bitmask |= ((addr_type & 0x01) << index);
memcpy(&filter->bdaddr[index][0], bdaddr, BDADDR_SIZE);
}
#if !defined(CONFIG_BT_CTLR_PRIVACY)
static u32_t filter_add(struct ll_filter *filter, u8_t addr_type, u8_t *bdaddr)
{
int index;
if (filter->enable_bitmask == 0xFF) {
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
}
for (index = 0;
(filter->enable_bitmask & BIT(index));
index++) {
}
filter_insert(filter, index, addr_type, bdaddr);
return 0;
}
static u32_t filter_remove(struct ll_filter *filter, u8_t addr_type,
u8_t *bdaddr)
{
int index;
if (!filter->enable_bitmask) {
return BT_HCI_ERR_INVALID_PARAM;
}
index = 8;
while (index--) {
if ((filter->enable_bitmask & BIT(index)) &&
(((filter->addr_type_bitmask >> index) & 0x01) ==
(addr_type & 0x01)) &&
!memcmp(filter->bdaddr[index], bdaddr, BDADDR_SIZE)) {
filter->enable_bitmask &= ~BIT(index);
filter->addr_type_bitmask &= ~BIT(index);
return 0;
}
}
return BT_HCI_ERR_INVALID_PARAM;
}
#endif
#if defined(CONFIG_BT_CTLR_PRIVACY)
bool ctrl_lrpa_used(u8_t rl_idx)
{
return rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].lirk;
}
bt_addr_t *ctrl_lrpa_get(u8_t rl_idx)
{
if ((rl_idx >= ARRAY_SIZE(rl)) || !rl[rl_idx].lirk ||
!rl[rl_idx].rpas_ready) {
return NULL;
}
return rl[rl_idx].local_rpa;
}
u8_t *ctrl_irks_get(u8_t *count)
{
*count = peer_irk_count;
return (u8_t *)peer_irks;
}
u8_t ctrl_rl_idx(bool whitelist, u8_t devmatch_id)
{
u8_t i;
if (whitelist) {
LL_ASSERT(devmatch_id < ARRAY_SIZE(wl));
LL_ASSERT(wl[devmatch_id].taken);
i = wl[devmatch_id].rl_idx;
} else {
LL_ASSERT(devmatch_id < ARRAY_SIZE(rl));
i = devmatch_id;
LL_ASSERT(rl[i].taken);
}
return i;
}
u8_t ctrl_rl_irk_idx(u8_t irkmatch_id)
{
u8_t i;
LL_ASSERT(irkmatch_id < peer_irk_count);
i = peer_irk_rl_ids[irkmatch_id];
LL_ASSERT(i < CONFIG_BT_CTLR_RL_SIZE);
LL_ASSERT(rl[i].taken);
return i;
}
bool ctrl_irk_whitelisted(u8_t rl_idx)
{
if (rl_idx >= ARRAY_SIZE(rl)) {
return false;
}
LL_ASSERT(rl[rl_idx].taken);
return rl[rl_idx].wl;
}
#endif
struct ll_filter *ctrl_filter_get(bool whitelist)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
if (whitelist) {
return &wl_filter;
}
return &rl_filter;
#else
LL_ASSERT(whitelist);
return &wl_filter;
#endif
}
u8_t ll_wl_size_get(void)
{
return WL_SIZE;
}
u8_t ll_wl_clear(void)
{
if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
wl_clear();
#else
filter_clear(&wl_filter);
#endif /* CONFIG_BT_CTLR_PRIVACY */
wl_anon = 0U;
return 0;
}
u8_t ll_wl_add(bt_addr_le_t *addr)
{
if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
if (addr->type == ADDR_TYPE_ANON) {
wl_anon = 1U;
return 0;
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
return wl_add(addr);
#else
return filter_add(&wl_filter, addr->type, addr->a.val);
#endif /* CONFIG_BT_CTLR_PRIVACY */
}
u8_t ll_wl_remove(bt_addr_le_t *addr)
{
if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
if (addr->type == ADDR_TYPE_ANON) {
wl_anon = 0U;
return 0;
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
return wl_remove(addr);
#else
return filter_remove(&wl_filter, addr->type, addr->a.val);
#endif /* CONFIG_BT_CTLR_PRIVACY */
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
static void filter_wl_update(void)
{
u8_t i;
/* Populate filter from wl peers */
for (i = 0U; i < WL_SIZE; i++) {
u8_t j;
if (!wl[i].taken) {
continue;
}
j = wl[i].rl_idx;
if (!rl_enable || j >= ARRAY_SIZE(rl) || !rl[j].pirk ||
rl[j].dev) {
filter_insert(&wl_filter, i, wl[i].id_addr_type,
wl[i].id_addr.val);
}
}
}
static void filter_rl_update(void)
{
u8_t i;
/* Populate filter from rl peers */
for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
if (rl[i].taken) {
filter_insert(&rl_filter, i, rl[i].id_addr_type,
rl[i].id_addr.val);
}
}
}
void ll_filters_adv_update(u8_t adv_fp)
{
/* Clear before populating filter */
filter_clear(&wl_filter);
/* enabling advertising */
if (adv_fp && !(radio_scan_filter_pol_get() & 0x1)) {
/* whitelist not in use, update whitelist */
filter_wl_update();
}
/* Clear before populating rl filter */
filter_clear(&rl_filter);
if (rl_enable && !ll_scan_is_enabled(0)) {
/* rl not in use, update resolving list LUT */
filter_rl_update();
}
}
void ll_filters_scan_update(u8_t scan_fp)
{
/* Clear before populating filter */
filter_clear(&wl_filter);
/* enabling advertising */
if ((scan_fp & 0x1) && !radio_adv_filter_pol_get()) {
/* whitelist not in use, update whitelist */
filter_wl_update();
}
/* Clear before populating rl filter */
filter_clear(&rl_filter);
if (rl_enable && !ll_adv_is_enabled(0)) {
/* rl not in use, update resolving list LUT */
filter_rl_update();
}
}
u8_t ll_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free)
{
u8_t i;
if (free) {
*free = FILTER_IDX_NONE;
}
for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
if (LIST_MATCH(rl, i, id_addr_type, id_addr)) {
return i;
} else if (free && !rl[i].taken && (*free == FILTER_IDX_NONE)) {
*free = i;
}
}
return FILTER_IDX_NONE;
}
bool ctrl_rl_idx_allowed(u8_t irkmatch_ok, u8_t rl_idx)
{
/* If AR is disabled or we don't know the device or we matched an IRK
* then we're all set.
*/
if (!rl_enable || rl_idx >= ARRAY_SIZE(rl) || irkmatch_ok) {
return true;
}
LL_ASSERT(rl_idx < CONFIG_BT_CTLR_RL_SIZE);
LL_ASSERT(rl[rl_idx].taken);
return !rl[rl_idx].pirk || rl[rl_idx].dev;
}
void ll_rl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr)
{
LL_ASSERT(rl_idx < CONFIG_BT_CTLR_RL_SIZE);
LL_ASSERT(rl[rl_idx].taken);
*id_addr_type = rl[rl_idx].id_addr_type;
memcpy(id_addr, rl[rl_idx].id_addr.val, BDADDR_SIZE);
}
bool ctrl_rl_addr_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx)
{
u8_t i, j;
/* If AR is disabled or we matched an IRK then we're all set. No hw
* filters are used in this case.
*/
if (!rl_enable || *rl_idx != FILTER_IDX_NONE) {
return true;
}
for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
if (rl[i].taken && (rl[i].id_addr_type == id_addr_type)) {
u8_t *addr = rl[i].id_addr.val;
for (j = 0U; j < BDADDR_SIZE; j++) {
if (addr[j] != id_addr[j]) {
break;
}
}
if (j == BDADDR_SIZE) {
*rl_idx = i;
return !rl[i].pirk || rl[i].dev;
}
}
}
return true;
}
bool ctrl_rl_addr_resolve(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx)
{
/* Unable to resolve if AR is disabled, no RL entry or no local IRK */
if (!rl_enable || rl_idx >= ARRAY_SIZE(rl) || !rl[rl_idx].lirk) {
return false;
}
if ((id_addr_type != 0U) && ((id_addr[5] & 0xc0) == 0x40)) {
return bt_rpa_irk_matches(rl[rl_idx].local_irk,
(bt_addr_t *)id_addr);
}
return false;
}
bool ctrl_rl_enabled(void)
{
return rl_enable;
}
#if defined(CONFIG_BT_BROADCASTER)
void ll_rl_pdu_adv_update(u8_t idx, struct pdu_adv *pdu)
{
u8_t *adva = pdu->type == PDU_ADV_TYPE_SCAN_RSP ?
&pdu->scan_rsp.addr[0] :
&pdu->adv_ind.addr[0];
struct ll_adv_set *ll_adv = ll_adv_set_get();
/* AdvA */
if (idx < ARRAY_SIZE(rl) && rl[idx].lirk) {
LL_ASSERT(rl[idx].rpas_ready);
pdu->tx_addr = 1U;
memcpy(adva, rl[idx].local_rpa->val, BDADDR_SIZE);
} else {
pdu->tx_addr = ll_adv->own_addr_type & 0x1;
ll_addr_get(ll_adv->own_addr_type & 0x1, adva);
}
/* TargetA */
if (pdu->type == PDU_ADV_TYPE_DIRECT_IND) {
if (idx < ARRAY_SIZE(rl) && rl[idx].pirk) {
pdu->rx_addr = 1U;
memcpy(&pdu->direct_ind.tgt_addr[0],
rl[idx].peer_rpa.val, BDADDR_SIZE);
} else {
pdu->rx_addr = ll_adv->id_addr_type;
memcpy(&pdu->direct_ind.tgt_addr[0],
ll_adv->id_addr, BDADDR_SIZE);
}
}
}
static void rpa_adv_refresh(void)
{
struct radio_adv_data *radio_adv_data;
struct ll_adv_set *ll_adv;
struct pdu_adv *prev;
struct pdu_adv *pdu;
u8_t last;
u8_t idx;
ll_adv = ll_adv_set_get();
if (ll_adv->own_addr_type != BT_ADDR_LE_PUBLIC_ID &&
ll_adv->own_addr_type != BT_ADDR_LE_RANDOM_ID) {
return;
}
idx = ll_rl_find(ll_adv->id_addr_type, ll_adv->id_addr, NULL);
if (idx >= ARRAY_SIZE(rl)) {
return;
}
radio_adv_data = radio_adv_data_get();
prev = (struct pdu_adv *)&radio_adv_data->data[radio_adv_data->last][0];
/* use the last index in double buffer, */
if (radio_adv_data->first == radio_adv_data->last) {
last = radio_adv_data->last + 1;
if (last == DOUBLE_BUFFER_SIZE) {
last = 0U;
}
} else {
last = radio_adv_data->last;
}
/* update adv pdu fields. */
pdu = (struct pdu_adv *)&radio_adv_data->data[last][0];
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;
}
ll_rl_pdu_adv_update(idx, pdu);
memcpy(&pdu->adv_ind.data[0], &prev->adv_ind.data[0],
prev->len - BDADDR_SIZE);
pdu->len = prev->len;
/* commit the update so controller picks it. */
radio_adv_data->last = last;
}
#endif
static void rl_clear(void)
{
for (u8_t i = 0; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
rl[i].taken = 0U;
}
peer_irk_count = 0U;
}
static int rl_access_check(bool check_ar)
{
if (check_ar) {
/* If address resolution is disabled, allow immediately */
if (!rl_enable) {
return -1;
}
}
return (ll_adv_is_enabled(0) || ll_scan_is_enabled(0)) ? 0 : 1;
}
void ll_rl_rpa_update(bool timeout)
{
u8_t i;
int err;
s64_t now = k_uptime_get();
bool all = timeout || (rpa_last_ms == -1) ||
(now - rpa_last_ms >= rpa_timeout_ms);
BT_DBG("");
for (i = 0U; i < CONFIG_BT_CTLR_RL_SIZE; i++) {
if ((rl[i].taken) && (all || !rl[i].rpas_ready)) {
if (rl[i].pirk) {
u8_t irk[16];
/* TODO: move this swap to the driver level */
sys_memcpy_swap(irk, peer_irks[rl[i].pirk_idx],
16);
err = bt_rpa_create(irk, &rl[i].peer_rpa);
LL_ASSERT(!err);
}
if (rl[i].lirk) {
bt_addr_t rpa;
err = bt_rpa_create(rl[i].local_irk, &rpa);
LL_ASSERT(!err);
/* pointer read/write assumed to be atomic
* so that if ISR fires the local_rpa pointer
* will always point to a valid full RPA
*/
rl[i].local_rpa = &rpa;
bt_addr_copy(&local_rpas[i], &rpa);
rl[i].local_rpa = &local_rpas[i];
}
rl[i].rpas_ready = 1U;
}
}
if (all) {
rpa_last_ms = now;
}
if (timeout) {
#if defined(CONFIG_BT_BROADCASTER)
if (ll_adv_is_enabled(0)) {
rpa_adv_refresh();
}
#endif
}
}
static void rpa_timeout(struct k_work *work)
{
ll_rl_rpa_update(true);
k_delayed_work_submit(&rpa_work, K_MSEC(rpa_timeout_ms));
}
static void rpa_refresh_start(void)
{
BT_DBG("");
k_delayed_work_submit(&rpa_work, K_MSEC(rpa_timeout_ms));
}
static void rpa_refresh_stop(void)
{
k_delayed_work_cancel(&rpa_work);
}
void ll_adv_scan_state_cb(u8_t bm)
{
if (bm) {
rpa_refresh_start();
} else {
rpa_refresh_stop();
}
}
u8_t ll_rl_size_get(void)
{
return CONFIG_BT_CTLR_RL_SIZE;
}
u8_t ll_rl_clear(void)
{
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
rl_clear();
return 0;
}
u8_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
const u8_t lirk[16])
{
u8_t i, j;
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
i = ll_rl_find(id_addr->type, id_addr->a.val, &j);
/* Duplicate check */
if (i < ARRAY_SIZE(rl)) {
return BT_HCI_ERR_INVALID_PARAM;
} else if (j >= ARRAY_SIZE(rl)) {
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
}
/* Device not found but empty slot found */
i = j;
bt_addr_copy(&rl[i].id_addr, &id_addr->a);
rl[i].id_addr_type = id_addr->type & 0x1;
rl[i].pirk = mem_nz((u8_t *)pirk, 16);
rl[i].lirk = mem_nz((u8_t *)lirk, 16);
if (rl[i].pirk) {
/* cross-reference */
rl[i].pirk_idx = peer_irk_count;
peer_irk_rl_ids[peer_irk_count] = i;
/* AAR requires big-endian IRKs */
sys_memcpy_swap(peer_irks[peer_irk_count++], pirk, 16);
}
if (rl[i].lirk) {
memcpy(rl[i].local_irk, lirk, 16);
rl[i].local_rpa = NULL;
}
(void)memset(rl[i].curr_rpa.val, 0x00, sizeof(rl[i].curr_rpa));
rl[i].rpas_ready = 0U;
/* Default to Network Privacy */
rl[i].dev = 0U;
/* Add reference to a whitelist entry */
j = wl_find(id_addr->type, id_addr->a.val, NULL);
if (j < ARRAY_SIZE(wl)) {
wl[j].rl_idx = i;
rl[i].wl = 1U;
} else {
rl[i].wl = 0U;
}
rl[i].taken = 1U;
return 0;
}
u8_t ll_rl_remove(bt_addr_le_t *id_addr)
{
u8_t i;
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* find the device and mark it as empty */
i = ll_rl_find(id_addr->type, id_addr->a.val, NULL);
if (i < ARRAY_SIZE(rl)) {
u8_t j, k;
if (rl[i].pirk) {
/* Swap with last item */
u8_t pi = rl[i].pirk_idx, pj = peer_irk_count - 1;
if (pj && pi != pj) {
memcpy(peer_irks[pi], peer_irks[pj], 16);
for (k = 0U;
k < CONFIG_BT_CTLR_RL_SIZE;
k++) {
if (rl[k].taken && rl[k].pirk &&
rl[k].pirk_idx == pj) {
rl[k].pirk_idx = pi;
peer_irk_rl_ids[pi] = k;
break;
}
}
}
peer_irk_count--;
}
/* Check if referenced by a whitelist entry */
j = wl_find(id_addr->type, id_addr->a.val, NULL);
if (j < ARRAY_SIZE(wl)) {
wl[j].rl_idx = FILTER_IDX_NONE;
}
rl[i].taken = 0U;
return 0;
}
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
void ll_rl_crpa_set(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx, u8_t *crpa)
{
if ((crpa[5] & 0xc0) == 0x40) {
if (id_addr) {
/* find the device and return its RPA */
rl_idx = ll_rl_find(id_addr_type, id_addr, NULL);
}
if (rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].taken) {
memcpy(rl[rl_idx].curr_rpa.val, crpa,
sizeof(bt_addr_t));
}
}
}
u8_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa)
{
u8_t i;
/* find the device and return its RPA */
i = ll_rl_find(id_addr->type, id_addr->a.val, NULL);
if (i < ARRAY_SIZE(rl) &&
mem_nz(rl[i].curr_rpa.val, sizeof(rl[i].curr_rpa.val))) {
bt_addr_copy(crpa, &rl[i].curr_rpa);
return 0;
}
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
u8_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa)
{
u8_t i;
/* find the device and return the local RPA */
i = ll_rl_find(id_addr->type, id_addr->a.val, NULL);
if (i < ARRAY_SIZE(rl)) {
bt_addr_copy(lrpa, rl[i].local_rpa);
return 0;
}
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
u8_t ll_rl_enable(u8_t enable)
{
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
switch (enable) {
case BT_HCI_ADDR_RES_DISABLE:
rl_enable = 0U;
break;
case BT_HCI_ADDR_RES_ENABLE:
rl_enable = 1U;
break;
default:
return BT_HCI_ERR_INVALID_PARAM;
}
return 0;
}
void ll_rl_timeout_set(u16_t timeout)
{
rpa_timeout_ms = timeout * 1000U;
}
u8_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode)
{
u8_t i;
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* find the device and mark it as empty */
i = ll_rl_find(id_addr->type, id_addr->a.val, NULL);
if (i < ARRAY_SIZE(rl)) {
switch (mode) {
case BT_HCI_LE_PRIVACY_MODE_NETWORK:
rl[i].dev = 0U;
break;
case BT_HCI_LE_PRIVACY_MODE_DEVICE:
rl[i].dev = 1U;
break;
default:
return BT_HCI_ERR_INVALID_PARAM;
}
} else {
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
return 0;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */
void ll_filter_reset(bool init)
{
wl_anon = 0U;
#if defined(CONFIG_BT_CTLR_PRIVACY)
wl_clear();
rl_enable = 0U;
rpa_timeout_ms = DEFAULT_RPA_TIMEOUT_MS;
rpa_last_ms = -1;
rl_clear();
if (init) {
k_delayed_work_init(&rpa_work, rpa_timeout);
} else {
k_delayed_work_cancel(&rpa_work);
}
#else
filter_clear(&wl_filter);
#endif /* CONFIG_BT_CTLR_PRIVACY */
}

View file

@ -1,36 +0,0 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#define WL_SIZE 8
#define FILTER_IDX_NONE 0xFF
struct ll_filter {
u8_t enable_bitmask;
u8_t addr_type_bitmask;
u8_t bdaddr[WL_SIZE][BDADDR_SIZE];
};
void ll_filter_reset(bool init);
void ll_filters_adv_update(u8_t adv_fp);
void ll_filters_scan_update(u8_t scan_fp);
struct ll_filter *ctrl_filter_get(bool whitelist);
bool ctrl_lrpa_used(u8_t rl_idx);
bt_addr_t *ctrl_lrpa_get(u8_t rl_idx);
u8_t *ctrl_irks_get(u8_t *count);
u8_t ctrl_rl_idx(bool whitelist, u8_t devmatch_id);
u8_t ctrl_rl_irk_idx(u8_t irkmatch_id);
bool ctrl_irk_whitelisted(u8_t rl_idx);
bool ctrl_rl_enabled(void);
void ll_rl_rpa_update(bool timeout);
u8_t ll_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free);
bool ctrl_rl_addr_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx);
bool ctrl_rl_addr_resolve(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx);
bool ctrl_rl_idx_allowed(u8_t irkmatch_ok, u8_t rl_idx);
void ll_rl_pdu_adv_update(u8_t idx, struct pdu_adv *pdu);

View file

@ -1,62 +0,0 @@
/*
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "ll_filter.h"
u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t filter_policy, u8_t peer_addr_type,
u8_t *peer_addr, u8_t own_addr_type,
u16_t interval, u16_t latency,
u16_t timeout)
{
u32_t status;
u8_t rpa_gen = 0U;
u8_t rl_idx = FILTER_IDX_NONE;
if (ll_scan_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
status = radio_connect_enable(peer_addr_type, peer_addr, interval,
latency, timeout);
if (status) {
return status;
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
ll_filters_scan_update(filter_policy);
if (!filter_policy && ctrl_rl_enabled()) {
/* Look up the resolving list */
rl_idx = ll_rl_find(peer_addr_type, peer_addr, NULL);
}
if (own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
own_addr_type == BT_ADDR_LE_RANDOM_ID) {
/* Generate RPAs if required */
ll_rl_rpa_update(false);
own_addr_type &= 0x1;
rpa_gen = 1U;
}
#endif
return radio_scan_enable(0, own_addr_type,
ll_addr_get(own_addr_type, NULL),
scan_interval, scan_window,
filter_policy, rpa_gen, rl_idx);
}

View file

@ -1,79 +0,0 @@
/*
* Copyright (c) 2017-2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <zephyr.h>
#include <bluetooth/hci.h>
#include "hal/ticker.h"
#include "ticker/ticker.h"
#include "ll.h"
#include "ll_mesh.h"
u8_t ll_mesh_advertise(u8_t handle, u8_t own_addr_type,
u8_t const *const rand_addr,
u8_t chan_map, u8_t tx_pwr,
u8_t min_tx_delay, u8_t max_tx_delay,
u8_t retry, u8_t interval,
u8_t scan_window, u8_t scan_delay, u8_t scan_filter,
u8_t data_len, u8_t const *const data)
{
u32_t ticks_anchor;
u8_t err;
/* convert to 625 us units for internal use */
interval = ((u32_t)interval + 1) * 10000U / 625;
#if defined(CONFIG_BT_CTLR_ADV_EXT)
/* Non-conn Non-Scan advertising */
err = ll_adv_params_set(handle, 0, interval, 0x03, own_addr_type,
0, NULL, chan_map, 0, NULL, 0, 0, 0, 0, 0);
#else
err = ll_adv_params_set(interval, 0x03, own_addr_type, 0, NULL,
chan_map, 0);
#endif
if (err) {
return err;
}
/* TODO: use the supplied random address instead of global random
* address.
*/
/* TODO: Tx power */
/* TODO: multi-instance adv data support */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
ll_adv_data_set(handle, data_len, data);
#else
ll_adv_data_set(data_len, data);
#endif
/* TODO: scan filter */
/* TODO: calculate random tx delay */
ticks_anchor = ticker_ticks_now_get();
ticks_anchor += HAL_TICKER_US_TO_TICKS(min_tx_delay * 10000U);
/* Enable advertising instance */
err = ll_adv_enable(handle, 1,
1, ticks_anchor, retry,
scan_window, scan_delay);
return err;
}
u8_t ll_mesh_advertise_cancel(u8_t handle)
{
u8_t err;
/* TODO: multi-instance support */
err = ll_adv_enable(handle, 0, 0, 0, 0, 0, 0);
return err;
}

View file

@ -1,14 +0,0 @@
/*
* Copyright (c) 2017-2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
u8_t ll_mesh_advertise(u8_t handle, u8_t own_addr_type,
u8_t const *const rand_addr,
u8_t chan_map, u8_t tx_pwr,
u8_t min_tx_delay, u8_t max_tx_delay,
u8_t retry, u8_t interval,
u8_t scan_window, u8_t scan_delay, u8_t scan_filter,
u8_t data_len, u8_t const *const data);
u8_t ll_mesh_advertise_cancel(u8_t handle);

View file

@ -1,110 +0,0 @@
/*
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "ll_filter.h"
static struct {
u16_t interval;
u16_t window;
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t type:4;
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t type:1;
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t own_addr_type:2;
u8_t filter_policy:2;
} ll_scan;
u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
u8_t own_addr_type, u8_t filter_policy)
{
if (ll_scan_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
/* type value:
* 0000b - legacy 1M passive
* 0001b - legacy 1M active
* 0010b - Ext. 1M passive
* 0011b - Ext. 1M active
* 0100b - invalid
* 0101b - invalid
* 0110b - invalid
* 0111b - invalid
* 1000b - Ext. Coded passive
* 1001b - Ext. Coded active
*/
ll_scan.type = type;
ll_scan.interval = interval;
ll_scan.window = window;
ll_scan.own_addr_type = own_addr_type;
ll_scan.filter_policy = filter_policy;
return 0;
}
u8_t ll_scan_enable(u8_t enable)
{
u8_t rpa_gen = 0U;
u32_t status;
u32_t scan;
if (!enable) {
return radio_scan_disable(true);
}
scan = ll_scan_is_enabled(0);
/* Initiator and scanning are not supported */
if (scan & BIT(2)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
if (scan) {
/* Duplicate filtering is processed in the HCI layer */
return 0;
}
if (ll_scan.own_addr_type & 0x1) {
if (!mem_nz(ll_addr_get(1, NULL), BDADDR_SIZE)) {
return BT_HCI_ERR_INVALID_PARAM;
}
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
ll_filters_scan_update(ll_scan.filter_policy);
if ((ll_scan.type & 0x1) &&
(ll_scan.own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
ll_scan.own_addr_type == BT_ADDR_LE_RANDOM_ID)) {
/* Generate RPAs if required */
ll_rl_rpa_update(false);
rpa_gen = 1U;
}
#endif
status = radio_scan_enable(ll_scan.type, ll_scan.own_addr_type & 0x1,
ll_addr_get(ll_scan.own_addr_type & 0x1,
NULL),
ll_scan.interval, ll_scan.window,
ll_scan.filter_policy, rpa_gen,
FILTER_IDX_NONE);
return status;
}

View file

@ -1,354 +0,0 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <string.h>
#include <toolchain.h>
#include <zephyr/types.h>
#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>
#include "hal/cpu.h"
#include "hal/cntr.h"
#include "hal/ccm.h"
#include "hal/radio.h"
#if defined(CONFIG_BT_LL_SW_LEGACY)
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#endif
#include "ll_test.h"
#define CNTR_MIN_DELTA 3
static const u32_t test_sync_word = 0x71764129;
static u8_t test_phy;
static u8_t test_phy_flags;
static u16_t test_num_rx;
static bool started;
/* NOTE: The PRBS9 sequence used as packet payload.
* The bytes in the sequence are in the right order, but the bits of each byte
* in the array are reverse from that found by running the PRBS9 algorithm. This
* is done to transmit MSbit first on air.
*/
static const u8_t prbs9[] = {
0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B,
0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23,
0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B,
0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA,
0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A,
0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE,
0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E,
0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87,
0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5,
0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11,
0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D,
0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65,
0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D,
0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F,
0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF,
0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3,
0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2,
0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88,
0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E,
0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32,
0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6,
0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF,
0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7,
0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1,
0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1,
0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44,
0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27,
0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99,
0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3,
0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57,
0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB,
0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7};
/* TODO: fill correct prbs15 */
static const u8_t prbs15[255] = { 0x00, };
static u8_t tx_req;
static u8_t volatile tx_ack;
static void isr_tx(void *param)
{
u32_t l, i, s, t;
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* Exit if radio disabled */
if (((tx_req - tx_ack) & 0x01) == 0U) {
tx_ack = tx_req;
return;
}
/* LE Test Packet Interval */
l = radio_tmr_end_get() - radio_tmr_ready_get();
i = ((l + 249 + 624) / 625) * 625U;
t = radio_tmr_end_get() - l + i;
t -= radio_tx_ready_delay_get(test_phy, test_phy_flags);
/* Set timer capture in the future. */
radio_tmr_sample();
s = radio_tmr_sample_get();
while (t < s) {
t += 625U;
}
/* Setup next Tx */
radio_switch_complete_and_disable();
radio_tmr_start_us(1, t);
radio_tmr_aa_capture();
radio_tmr_end_capture();
/* TODO: check for probable stale timer capture being set */
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(t + radio_tx_ready_delay_get(test_phy,
test_phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
}
static void isr_rx(void *param)
{
u8_t crc_ok = 0U;
u8_t trx_done;
/* Read radio status and events */
trx_done = radio_is_done();
if (trx_done) {
crc_ok = radio_crc_is_valid();
}
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
/* Exit if radio disabled */
if (!trx_done) {
return;
}
/* Setup next Rx */
radio_switch_complete_and_rx(test_phy);
/* Count Rx-ed packets */
if (crc_ok) {
test_num_rx++;
}
}
static u32_t init(u8_t chan, u8_t phy, void (*isr)(void *param))
{
struct device *hf_clock;
if (started) {
return 1;
}
/* start coarse timer */
cntr_start();
/* Setup resources required by Radio */
hf_clock = radio_hf_clock_get();
clock_control_on(hf_clock, NULL); /* start clock, blocking. */
while (clock_control_get_status(hf_clock, NULL) !=
CLOCK_CONTROL_STATUS_ON) {
}
/* Reset Radio h/w */
radio_reset();
radio_isr_set(isr, NULL);
/* Store value needed in Tx/Rx ISR */
if (phy < 0x04) {
test_phy = BIT(phy - 1);
test_phy_flags = 1U;
} else {
test_phy = BIT(2);
test_phy_flags = 0U;
}
/* Setup Radio in Tx/Rx */
/* NOTE: No whitening in test mode. */
radio_phy_set(test_phy, test_phy_flags);
radio_tmr_tifs_set(150);
radio_tx_power_max_set();
radio_freq_chan_set((chan << 1) + 2);
radio_aa_set((u8_t *)&test_sync_word);
radio_crc_configure(0x65b, 0x555555);
radio_pkt_configure(8, 255, (test_phy << 1));
return 0;
}
u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
{
u32_t start_us;
u8_t *payload;
u8_t *pdu;
u32_t err;
if ((type > 0x07) || !phy || (phy > 0x04)) {
return 1;
}
err = init(chan, phy, isr_tx);
if (err) {
return err;
}
tx_req++;
pdu = radio_pkt_scratch_get();
payload = &pdu[2];
switch (type) {
case 0x00:
memcpy(payload, prbs9, len);
break;
case 0x01:
(void)memset(payload, 0x0f, len);
break;
case 0x02:
(void)memset(payload, 0x55, len);
break;
case 0x03:
memcpy(payload, prbs15, len);
break;
case 0x04:
(void)memset(payload, 0xff, len);
break;
case 0x05:
(void)memset(payload, 0x00, len);
break;
case 0x06:
(void)memset(payload, 0xf0, len);
break;
case 0x07:
(void)memset(payload, 0xaa, len);
break;
}
pdu[0] = type;
pdu[1] = len;
radio_pkt_tx_set(pdu);
radio_switch_complete_and_disable();
start_us = radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
radio_tmr_aa_capture();
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(start_us +
radio_tx_ready_delay_get(test_phy,
test_phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(start_us);
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
started = true;
return 0;
}
u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
{
u32_t err;
if (!phy || (phy > 0x03)) {
return 1;
}
err = init(chan, phy, isr_rx);
if (err) {
return err;
}
radio_pkt_rx_set(radio_pkt_scratch_get());
radio_switch_complete_and_rx(test_phy);
radio_tmr_start(0, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_on();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
started = true;
return 0;
}
u32_t ll_test_end(u16_t *num_rx)
{
struct device *clock;
u8_t ack;
if (!started) {
return 1;
}
/* Return packets Rx-ed/Completed */
*num_rx = test_num_rx;
test_num_rx = 0U;
/* Disable Radio, if in Rx test */
ack = tx_ack;
if (tx_req == ack) {
radio_disable();
} else {
/* Wait for Tx to complete */
tx_req = ack + 2;
while (tx_req != tx_ack) {
cpu_sleep();
}
}
/* Stop packet timer */
radio_tmr_stop();
/* Release resources acquired for Radio */
clock = radio_hf_clock_get();
clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
/* Stop coarse timer */
cntr_stop();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_off();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
started = false;
return 0;
}

View file

@ -18,10 +18,7 @@
#include "common/log.h"
#include "hal/debug.h"
#if defined(CONFIG_BT_LL_SW_LEGACY)
#define MAYFLY_CALL_ID_WORKER MAYFLY_CALL_ID_0
#define MAYFLY_CALL_ID_JOB MAYFLY_CALL_ID_1
#elif defined(CONFIG_BT_LL_SW_SPLIT)
#if defined(CONFIG_BT_LL_SW_SPLIT)
#include "ll_sw/lll.h"
#define MAYFLY_CALL_ID_LLL TICKER_USER_ID_LLL
#define MAYFLY_CALL_ID_WORKER TICKER_USER_ID_ULL_HIGH
@ -70,14 +67,7 @@ u32_t mayfly_is_enabled(u8_t caller_id, u8_t callee_id)
u32_t mayfly_prio_is_equal(u8_t caller_id, u8_t callee_id)
{
return (caller_id == callee_id) ||
#if defined(CONFIG_BT_LL_SW_LEGACY)
#if (CONFIG_BT_CTLR_WORKER_PRIO == CONFIG_BT_CTLR_JOB_PRIO)
((caller_id == MAYFLY_CALL_ID_WORKER) &&
(callee_id == MAYFLY_CALL_ID_JOB)) ||
((caller_id == MAYFLY_CALL_ID_JOB) &&
(callee_id == MAYFLY_CALL_ID_WORKER)) ||
#endif
#elif defined(CONFIG_BT_LL_SW_SPLIT)
#if defined(CONFIG_BT_LL_SW_SPLIT)
#if (CONFIG_BT_CTLR_LLL_PRIO == CONFIG_BT_CTLR_ULL_HIGH_PRIO)
((caller_id == MAYFLY_CALL_ID_LLL) &&
(callee_id == MAYFLY_CALL_ID_WORKER)) ||

View file

@ -29,11 +29,6 @@ static inline void hal_swi_lll_pend(void)
NVIC_SetPendingIRQ(HAL_SWI_RADIO_IRQ);
}
#elif defined(CONFIG_BT_LL_SW_LEGACY)
/* Legacy controller uses max. one SWI */
#define HAL_SWI_WORKER_IRQ RTC0_IRQn
#define HAL_SWI_JOB_IRQ SWI5_IRQn
#else
#error "CTRL architecture not defined"
#endif

View file

@ -21,18 +21,7 @@
#include "common/log.h"
#include "hal/debug.h"
#if defined(CONFIG_BT_LL_SW_LEGACY)
#define TICKER_MAYFLY_CALL_ID_TRIGGER MAYFLY_CALL_ID_0
#define TICKER_MAYFLY_CALL_ID_WORKER MAYFLY_CALL_ID_0
#define TICKER_MAYFLY_CALL_ID_JOB MAYFLY_CALL_ID_1
#define TICKER_MAYFLY_CALL_ID_PROGRAM MAYFLY_CALL_ID_PROGRAM
static u8_t const caller_id_lut[] = {
TICKER_CALL_ID_WORKER,
TICKER_CALL_ID_JOB,
TICKER_CALL_ID_NONE,
TICKER_CALL_ID_PROGRAM
};
#elif defined(CONFIG_BT_LL_SW_SPLIT)
#if defined(CONFIG_BT_LL_SW_SPLIT)
#include "ll_sw/lll.h"
#define TICKER_MAYFLY_CALL_ID_ISR TICKER_USER_ID_LLL
#define TICKER_MAYFLY_CALL_ID_TRIGGER TICKER_USER_ID_ULL_HIGH

View file

@ -1,40 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
if(CONFIG_BT_LL_SW_LEGACY)
zephyr_library_sources(
ll_sw/ctrl.c
ll_sw/ll.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_BROADCASTER
ll_sw/ll_adv.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_OBSERVER
ll_sw/ll_scan.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_FILTER
ll_sw/ll_filter.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CENTRAL
ll_sw/ll_master.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_ADV_EXT
ll_sw/ll_adv_aux.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_HCI_MESH_EXT
ll_sw/ll_mesh.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_DTM
ll_sw/ll_test.c
)
endif()
if(CONFIG_BT_LL_SW_SPLIT)
zephyr_library_sources(
ll_sw/nordic/lll/lll.c

View file

@ -79,9 +79,9 @@ config BT_HCI_TX_STACK_SIZE
default 512 if BT_H4
default 512 if BT_H5
default 416 if BT_SPI
default 940 if BT_CTLR && (BT_LL_SW_LEGACY || BT_LL_SW_SPLIT) && NO_OPTIMIZATIONS
default 1024 if BT_CTLR && (BT_LL_SW_LEGACY || BT_LL_SW_SPLIT) && BT_CENTRAL
default 640 if BT_CTLR && (BT_LL_SW_LEGACY || BT_LL_SW_SPLIT)
default 940 if BT_CTLR && BT_LL_SW_SPLIT && NO_OPTIMIZATIONS
default 1024 if BT_CTLR && BT_LL_SW_SPLIT && BT_CENTRAL
default 640 if BT_CTLR && BT_LL_SW_SPLIT
default 512 if BT_USERCHAN
default 640 if BT_STM32_IPM
# Even if no driver is selected the following default is still

View file

@ -22,8 +22,7 @@ zephyr_library_sources_ifdef(
rfcomm.c
)
if(CONFIG_BT_CTLR)
if(CONFIG_BT_LL_SW_LEGACY OR CONFIG_BT_LL_SW_SPLIT)
if(CONFIG_BT_CTLR AND CONFIG_BT_LL_SW_SPLIT)
zephyr_library_sources(
ll.c
ticker.c
@ -31,5 +30,4 @@ if(CONFIG_BT_CTLR)
zephyr_include_directories(
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/nordic
)
endif()
endif()

View file

@ -2484,7 +2484,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
#if defined(CONFIG_BT_HCI_MESH_EXT)
SHELL_CMD(mesh_adv, NULL, "<on, off>", cmd_mesh_adv),
#endif /* CONFIG_BT_HCI_MESH_EXT */
#if defined(CONFIG_BT_LL_SW_LEGACY) || defined(CONFIG_BT_LL_SW_SPLIT)
#if defined(CONFIG_BT_LL_SW_SPLIT)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
#if defined(CONFIG_BT_BROADCASTER)
SHELL_CMD_ARG(advx, NULL, "<on off> [coded] [anon] [txp]", cmd_advx,
@ -2495,9 +2495,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
2, 1),
#endif /* CONFIG_BT_OBSERVER */
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#if defined(CONFIG_BT_LL_SW_LEGACY)
SHELL_CMD_ARG(ll-addr, NULL, "<random|public>", cmd_ll_addr_get, 2, 0),
#endif
#if defined(CONFIG_BT_CTLR_DTM)
SHELL_CMD_ARG(test_tx, NULL, "<chan> <len> <type> <phy>", cmd_test_tx,
5, 0),
@ -2505,7 +2502,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
4, 0),
SHELL_CMD_ARG(test_end, NULL, HELP_NONE, cmd_test_end, 1, 0),
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#endif /* defined(CONFIG_BT_LL_SW_LEGACY) || defined(CONFIG_BT_LL_SW_SPLIT) */
#endif /* defined(CONFIG_BT_LL_SW_SPLIT) */
#if defined(CONFIG_BT_LL_SW_SPLIT)
SHELL_CMD(ull_reset, NULL, HELP_NONE, cmd_ull_reset),
#endif /* CONFIG_BT_LL_SW_SPLIT */

View file

@ -1,17 +0,0 @@
CONFIG_BT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_PRIVACY=y
CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y
CONFIG_BT_GATT_BAS=y
CONFIG_BT_GATT_HRS=y
CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_BT_DEVICE_NAME="bsim_test"
CONFIG_BT_L2CAP_TX_BUF_COUNT=6
CONFIG_BT_LL_SW_LEGACY=y

View file

@ -1,41 +0,0 @@
#!/usr/bin/env bash
# Copyright 2018 Oticon A/S
# SPDX-License-Identifier: Apache-2.0
# Basic connection test: a central connects to a peripheral and expects a
# notification
simulation_id="basic_conn"
verbosity_level=2
process_ids=""; exit_code=0
function Execute(){
if [ ! -f $1 ]; then
echo -e " \e[91m`pwd`/`basename $1` cannot be found (did you forget to\
compile it?)\e[39m"
exit 1
fi
timeout 5 $@ & process_ids="$process_ids $!"
}
: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}"
#Give a default value to BOARD if it does not have one yet:
BOARD="${BOARD:-nrf52_bsim}"
cd ${BSIM_OUT_PATH}/bin
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_app_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=0 \
-testid=peripheral -rs=23
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_app_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=0 \
-testid=central -rs=6
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=2 -sim_length=20e6 $@
for process_id in $process_ids; do
wait $process_id || let "exit_code=$?"
done
exit $exit_code #the last exit code != 0

View file

@ -1,41 +0,0 @@
#!/usr/bin/env bash
# Copyright 2018 Oticon A/S
# SPDX-License-Identifier: Apache-2.0
# Basic connection test: a central connects to a peripheral and expects a
# notification
simulation_id="basic_conn_encr"
verbosity_level=2
process_ids=""; exit_code=0
function Execute(){
if [ ! -f $1 ]; then
echo -e " \e[91m`pwd`/`basename $1` cannot be found (did you forget to\
compile it?)\e[39m"
exit 1
fi
timeout 5 $@ & process_ids="$process_ids $!"
}
: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}"
#Give a default value to BOARD if it does not have one yet:
BOARD="${BOARD:-nrf52_bsim}"
cd ${BSIM_OUT_PATH}/bin
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_app_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=1 \
-testid=peripheral -rs=23
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_app_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=1 \
-testid=central_encrypted -rs=6
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=2 -sim_length=20e6 $@
for process_id in $process_ids; do
wait $process_id || let "exit_code=$?"
done
exit $exit_code #the last exit code != 0

View file

@ -51,7 +51,6 @@ function compile(){
sed -i "1i $(wc -l ${map_file_name} | cut -d" " -f1)" ${map_file_name}
}
app=tests/bluetooth/bsim_bt/bsim_test_app compile
app=tests/bluetooth/bsim_bt/bsim_test_app conf_file=prj_split.conf \
compile
app=tests/bluetooth/bsim_bt/bsim_test_app conf_file=prj_split_privacy.conf \

View file

@ -1,25 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
CONFIG_BT=y
CONFIG_BT_HCI_RAW=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_ECC=y
CONFIG_BT_TINYCRYPT_ECC=y
##
## Enabling BT_CTRL_DTM_HCI requires BT_LL_SW which requires BT_CTRL
##
CONFIG_BT_CTLR=y
CONFIG_BT_LL_SW_LEGACY=y
CONFIG_BT_CTLR_CRYPTO=y
CONFIG_BT_CTLR_LE_ENC=y
CONFIG_BT_CTLR_PRIVACY=y
CONFIG_BT_CTLR_DTM_HCI=y
CONFIG_BT_CTLR_TX_BUFFER_SIZE=60
CONFIG_BT_CTLR_DATA_LENGTH_MAX=60
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_TICKLESS_IDLE=y
CONFIG_TICKLESS_KERNEL=y

View file

@ -1,17 +0,0 @@
CONFIG_BT=y
CONFIG_BT_CTLR=y
CONFIG_BT_LL_SW_LEGACY=y
CONFIG_BT_HCI_ACL_FLOW_CONTROL=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y
CONFIG_BT_SMP_SC_ONLY=y
CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_BREDR=n
CONFIG_FLASH=y
CONFIG_SOC_FLASH_NRF_RADIO_SYNC=y
CONFIG_ZTEST=y

View file

@ -1,43 +0,0 @@
CONFIG_BT=y
CONFIG_BT_CTLR=y
CONFIG_BT_LL_SW_LEGACY=y
CONFIG_BT_CTLR_DUP_FILTER_LEN=16
CONFIG_BT_CTLR_CONN_PARAM_REQ=n
CONFIG_BT_CTLR_LE_PING=n
CONFIG_BT_CTLR_PRIVACY=n
CONFIG_BT_CTLR_EXT_SCAN_FP=n
CONFIG_BT_DATA_LEN_UPDATE=n
CONFIG_BT_PHY_UPDATE=n
CONFIG_BT_CTLR_CHAN_SEL_2=n
CONFIG_BT_CTLR_MIN_USED_CHAN=n
CONFIG_BT_CTLR_ADV_EXT=n
CONFIG_BT_CTLR_DTM_HCI=y
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_WORKER_PRIO=0
CONFIG_BT_CTLR_JOB_PRIO=0
CONFIG_BT_CTLR_XTAL_ADVANCED=y
CONFIG_BT_CTLR_SCHED_ADVANCED=y
CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n
CONFIG_BT_CTLR_TIFS_HW=y
CONFIG_BT_CTLR_FAST_ENC=n
CONFIG_BT_CTLR_CONN_RSSI=n
CONFIG_BT_CTLR_ADV_INDICATION=n
CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n
CONFIG_BT_CTLR_SCAN_REQ_RSSI=n
CONFIG_BT_CTLR_GPIO_PA=n
CONFIG_BT_CTLR_GPIO_LNA=n
CONFIG_BT_CTLR_PROFILE_ISR=n
CONFIG_BT_CTLR_DEBUG_PINS=n
CONFIG_BT_HCI_VS_EXT=n
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y
CONFIG_BT_SMP_SC_ONLY=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_BREDR=n
CONFIG_FLASH=y
CONFIG_SOC_FLASH_NRF_RADIO_SYNC=y
CONFIG_ZTEST=y

View file

@ -1,63 +0,0 @@
CONFIG_BT=y
CONFIG_BT_CTLR=y
CONFIG_BT_LL_SW_LEGACY=y
CONFIG_BT_CTLR_DUP_FILTER_LEN=16
CONFIG_BT_CTLR_CONN_PARAM_REQ=y
CONFIG_BT_CTLR_LE_PING=y
CONFIG_BT_CTLR_PRIVACY=y
CONFIG_BT_CTLR_EXT_SCAN_FP=y
CONFIG_BT_DATA_LEN_UPDATE=y
CONFIG_BT_PHY_UPDATE=y
CONFIG_BT_CTLR_CHAN_SEL_2=y
CONFIG_BT_CTLR_MIN_USED_CHAN=y
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_DTM_HCI=y
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_PHY_2M=y
CONFIG_BT_CTLR_PHY_2M_NRF=y
CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_CTLR_WORKER_PRIO=0
CONFIG_BT_CTLR_JOB_PRIO=1
CONFIG_BT_CTLR_XTAL_ADVANCED=n
CONFIG_BT_CTLR_SCHED_ADVANCED=n
CONFIG_BT_CTLR_RADIO_ENABLE_FAST=y
CONFIG_BT_CTLR_TIFS_HW=n
CONFIG_BT_CTLR_FAST_ENC=y
CONFIG_BT_CTLR_TX_RETRY_DISABLE=y
CONFIG_BT_CTLR_CONN_RSSI=y
CONFIG_BT_CTLR_ADV_INDICATION=y
CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=y
CONFIG_BT_CTLR_SCAN_REQ_RSSI=y
CONFIG_BT_CTLR_SCAN_INDICATION=y
CONFIG_BT_CTLR_GPIO_PA=y
CONFIG_BT_CTLR_GPIO_PA_PIN=26
CONFIG_BT_CTLR_GPIO_LNA=y
CONFIG_BT_CTLR_GPIO_LNA_PIN=27
CONFIG_BT_CTLR_PROFILE_ISR=y
CONFIG_BT_CTLR_DEBUG_PINS=y
CONFIG_BT_HCI_VS_EXT=y
CONFIG_BT_HCI_MESH_EXT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y
CONFIG_BT_SMP_SC_ONLY=y
CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_BT_USE_DEBUG_KEYS=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_DEBUG_MONITOR=y
CONFIG_BT_DEBUG_HCI_CORE=y
CONFIG_BT_DEBUG_CONN=y
CONFIG_BT_DEBUG_KEYS=y
CONFIG_BT_DEBUG_L2CAP=y
CONFIG_BT_DEBUG_SMP=y
CONFIG_BT_DEBUG_HCI_DRIVER=y
CONFIG_BT_SMP_SELFTEST=y
CONFIG_BT_DEBUG_ATT=y
CONFIG_BT_DEBUG_GATT=y
CONFIG_BT_BREDR=n
CONFIG_DEBUG=y
CONFIG_FLASH=y
CONFIG_SOC_FLASH_NRF_RADIO_SYNC=n
CONFIG_ZTEST=y

View file

@ -1,48 +0,0 @@
CONFIG_BT=y
CONFIG_BT_CTLR=y
CONFIG_BT_LL_SW_LEGACY=y
CONFIG_BT_CTLR_DUP_FILTER_LEN=0
CONFIG_BT_CTLR_CONN_PARAM_REQ=n
CONFIG_BT_CTLR_EXT_REJ_IND=n
CONFIG_BT_CTLR_SLAVE_FEAT_REQ=n
CONFIG_BT_CTLR_LE_PING=n
CONFIG_BT_CTLR_PRIVACY=n
CONFIG_BT_CTLR_EXT_SCAN_FP=n
CONFIG_BT_DATA_LEN_UPDATE=n
CONFIG_BT_PHY_UPDATE=n
CONFIG_BT_CTLR_CHAN_SEL_2=n
CONFIG_BT_CTLR_MIN_USED_CHAN=n
CONFIG_BT_CTLR_ADV_EXT=n
CONFIG_BT_CTLR_DTM_HCI=n
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_FILTER=n
CONFIG_BT_CTLR_WORKER_PRIO=0
CONFIG_BT_CTLR_JOB_PRIO=0
CONFIG_BT_CTLR_XTAL_ADVANCED=n
CONFIG_BT_CTLR_SCHED_ADVANCED=n
CONFIG_BT_CTLR_RADIO_ENABLE_FAST=n
CONFIG_BT_CTLR_TIFS_HW=y
CONFIG_BT_CTLR_FAST_ENC=n
CONFIG_BT_CTLR_CONN_RSSI=n
CONFIG_BT_CTLR_ADV_INDICATION=n
CONFIG_BT_CTLR_SCAN_REQ_NOTIFY=n
CONFIG_BT_CTLR_SCAN_REQ_RSSI=n
CONFIG_BT_CTLR_PROFILE_ISR=n
CONFIG_BT_CTLR_GPIO_PA=n
CONFIG_BT_CTLR_GPIO_LNA=n
CONFIG_BT_CTLR_PROFILE_ISR=n
CONFIG_BT_CTLR_DEBUG_PINS=n
CONFIG_BT_HCI_VS_EXT=n
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y
CONFIG_BT_SMP_SC_ONLY=y
CONFIG_BT_TINYCRYPT_ECC=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_BREDR=n
CONFIG_FLASH=y
CONFIG_SOC_FLASH_NRF_RADIO_SYNC=y
CONFIG_ZTEST=y

View file

@ -73,22 +73,6 @@ tests:
bluetooth.init.test_9:
extra_args: CONF_FILE=prj_9.conf
platform_whitelist: qemu_cortex_m3
bluetooth.init.test_controller:
extra_args: CONF_FILE=prj_controller.conf
platform_whitelist: nrf52840dk_nrf52840 nrf52dk_nrf52832
nrf51dk_nrf51422 96b_nitrogen
bluetooth.init.test_controller_4_0:
extra_args: CONF_FILE=prj_controller_4_0.conf
platform_whitelist: nrf52840dk_nrf52840 nrf52dk_nrf52832
nrf51dk_nrf51422
bluetooth.init.test_controller_tiny:
extra_args: CONF_FILE=prj_controller_tiny.conf
platform_whitelist: nrf52840dk_nrf52840 nrf52dk_nrf52832
nrf51dk_nrf51422
bluetooth.init.test_controller_dbg:
extra_args: CONF_FILE=prj_controller_dbg.conf
platform_whitelist: nrf52840dk_nrf52840 nrf52dk_nrf52832
nrf51dk_nrf51422 96b_nitrogen
bluetooth.init.test_controller_ll_sw_split:
extra_args: CONF_FILE=prj_controller_ll_sw_split.conf
platform_whitelist: nrf52840dk_nrf52840 nrf52dk_nrf52832

View file

@ -18,9 +18,6 @@ CONFIG_BT_PHY_UPDATE=n
# This test barely fits in RAM, don't pull in logging
CONFIG_TEST_LOGGING_DEFAULTS=n
# Use legacy LL until RAM utilization is optimized in the new LL
CONFIG_BT_LL_SW_LEGACY=y
CONFIG_BT_CTLR_DUP_FILTER_LEN=0
CONFIG_BT_CTLR_LE_ENC=n
CONFIG_BT_CTLR_LE_PING=n