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 config COUNTER_TIMER0
bool "Enable Counter on TIMER0" bool "Enable Counter on TIMER0"
depends on HAS_HW_NRF_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 select COUNTER_NRF_TIMER
config COUNTER_TIMER1 config COUNTER_TIMER1
@ -36,7 +36,7 @@ config COUNTER_TIMER4
config COUNTER_RTC0 config COUNTER_RTC0
bool "Enable Counter on RTC0" bool "Enable Counter on RTC0"
depends on HAS_HW_NRF_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 select COUNTER_NRF_RTC
config COUNTER_RTC1 config COUNTER_RTC1

View file

@ -80,7 +80,6 @@ CONFIG_BT_MESH_LABEL_COUNT=3
CONFIG_GPIO=y CONFIG_GPIO=y
CONFIG_BT_CTLR_ADVANCED_FEATURES=y CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_JOB_PRIO=1
CONFIG_BT_RX_BUF_COUNT=5 CONFIG_BT_RX_BUF_COUNT=5
CONFIG_BT_HCI_TX_STACK_SIZE=1024 CONFIG_BT_HCI_TX_STACK_SIZE=1024
#CONFIG_BT_DEBUG_HCI_CORE=y #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_CONN services)
add_subdirectory_ifdef(CONFIG_BT_MESH mesh) add_subdirectory_ifdef(CONFIG_BT_MESH mesh)
if(CONFIG_BT_CTLR) if(CONFIG_BT_CTLR AND CONFIG_BT_LL_SW_SPLIT)
if(CONFIG_BT_LL_SW_LEGACY OR CONFIG_BT_LL_SW_SPLIT) add_subdirectory(controller)
add_subdirectory(controller)
endif()
endif() endif()

View file

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

View file

@ -75,40 +75,6 @@ config BT_LL_SW_SPLIT
help help
Use Zephyr software BLE Link Layer ULL LLL split implementation. 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 endchoice
config BT_LLL_VENDOR_NORDIC config BT_LLL_VENDOR_NORDIC
@ -393,7 +359,7 @@ config BT_CTLR_PRIVACY
bool "LE Controller-based Privacy" bool "LE Controller-based Privacy"
depends on BT_CTLR_PRIVACY_SUPPORT depends on BT_CTLR_PRIVACY_SUPPORT
default y 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 select BT_RPA
help help
Enable support for Bluetooth v4.2 LE Controller-based Privacy feature Enable support for Bluetooth v4.2 LE Controller-based Privacy feature
@ -519,7 +485,7 @@ config BT_CTLR_SMI_TX_SETTING
help help
Enable support for Bluetooth 5.0 SMI TX through a system setting. 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 config BT_CTLR_ADVANCED_FEATURES
bool "Show advanced features" bool "Show advanced features"
@ -582,28 +548,6 @@ config BT_CTLR_OPTIMIZE_FOR_SPEED
help help
Optimize compilation of controller for execution speed. 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 config BT_CTLR_XTAL_ADVANCED
bool "Advanced event preparation" bool "Advanced event preparation"
depends on BT_CTLR_XTAL_ADVANCED_SUPPORT depends on BT_CTLR_XTAL_ADVANCED_SUPPORT
@ -849,7 +793,7 @@ config BT_MAYFLY_YIELD_AFTER_CALL
config BT_TICKER_COMPATIBILITY_MODE config BT_TICKER_COMPATIBILITY_MODE
bool "Ticker compatibility mode" bool "Ticker compatibility mode"
default y if SOC_SERIES_NRF51X || BT_LL_SW_LEGACY default y if SOC_SERIES_NRF51X
help help
This option enables legacy ticker scheduling which defers overlapping This option enables legacy ticker scheduling which defers overlapping
ticker node timeouts and thereby prevents ticker interrupts during 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 when debugging with a logic analyzer or profiling certain sections of
the code. the code.
endif # BT_LL_SW_SPLIT || BT_LL_SW_LEGACY endif # BT_LL_SW_SPLIT
config BT_CTLR_ASSERT_HANDLER config BT_CTLR_ASSERT_HANDLER
bool "Application Defined Assertion 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); buf = process_prio_evt(node_rx);
if (buf) { 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; node_rx->hdr.next = NULL;
ll_rx_mem_release((void **)&node_rx); 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; 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; node_rx->hdr.next = NULL;
ll_rx_mem_release((void **)&node_rx); 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 "pdu.h"
#include "lll.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 "lll_scan.h"
#include "ull_scan_types.h" #include "ull_scan_types.h"
#include "ull_adv_internal.h" #include "ull_adv_internal.h"
#include "ull_scan_internal.h" #include "ull_scan_internal.h"
#endif
static u8_t pub_addr[BDADDR_SIZE]; static u8_t pub_addr[BDADDR_SIZE];
static u8_t rnd_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 "common/log.h"
#include "hal/debug.h" #include "hal/debug.h"
#if defined(CONFIG_BT_LL_SW_LEGACY) #if defined(CONFIG_BT_LL_SW_SPLIT)
#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)
#include "ll_sw/lll.h" #include "ll_sw/lll.h"
#define MAYFLY_CALL_ID_LLL TICKER_USER_ID_LLL #define MAYFLY_CALL_ID_LLL TICKER_USER_ID_LLL
#define MAYFLY_CALL_ID_WORKER TICKER_USER_ID_ULL_HIGH #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) u32_t mayfly_prio_is_equal(u8_t caller_id, u8_t callee_id)
{ {
return (caller_id == callee_id) || return (caller_id == callee_id) ||
#if defined(CONFIG_BT_LL_SW_LEGACY) #if defined(CONFIG_BT_LL_SW_SPLIT)
#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 (CONFIG_BT_CTLR_LLL_PRIO == CONFIG_BT_CTLR_ULL_HIGH_PRIO) #if (CONFIG_BT_CTLR_LLL_PRIO == CONFIG_BT_CTLR_ULL_HIGH_PRIO)
((caller_id == MAYFLY_CALL_ID_LLL) && ((caller_id == MAYFLY_CALL_ID_LLL) &&
(callee_id == MAYFLY_CALL_ID_WORKER)) || (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); 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 #else
#error "CTRL architecture not defined" #error "CTRL architecture not defined"
#endif #endif

View file

@ -21,18 +21,7 @@
#include "common/log.h" #include "common/log.h"
#include "hal/debug.h" #include "hal/debug.h"
#if defined(CONFIG_BT_LL_SW_LEGACY) #if defined(CONFIG_BT_LL_SW_SPLIT)
#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)
#include "ll_sw/lll.h" #include "ll_sw/lll.h"
#define TICKER_MAYFLY_CALL_ID_ISR TICKER_USER_ID_LLL #define TICKER_MAYFLY_CALL_ID_ISR TICKER_USER_ID_LLL
#define TICKER_MAYFLY_CALL_ID_TRIGGER TICKER_USER_ID_ULL_HIGH #define TICKER_MAYFLY_CALL_ID_TRIGGER TICKER_USER_ID_ULL_HIGH

View file

@ -1,40 +1,5 @@
# SPDX-License-Identifier: Apache-2.0 # 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) if(CONFIG_BT_LL_SW_SPLIT)
zephyr_library_sources( zephyr_library_sources(
ll_sw/nordic/lll/lll.c 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_H4
default 512 if BT_H5 default 512 if BT_H5
default 416 if BT_SPI default 416 if BT_SPI
default 940 if BT_CTLR && (BT_LL_SW_LEGACY || BT_LL_SW_SPLIT) && NO_OPTIMIZATIONS default 940 if BT_CTLR && BT_LL_SW_SPLIT && NO_OPTIMIZATIONS
default 1024 if BT_CTLR && (BT_LL_SW_LEGACY || BT_LL_SW_SPLIT) && BT_CENTRAL default 1024 if BT_CTLR && BT_LL_SW_SPLIT && BT_CENTRAL
default 640 if BT_CTLR && (BT_LL_SW_LEGACY || BT_LL_SW_SPLIT) default 640 if BT_CTLR && BT_LL_SW_SPLIT
default 512 if BT_USERCHAN default 512 if BT_USERCHAN
default 640 if BT_STM32_IPM default 640 if BT_STM32_IPM
# Even if no driver is selected the following default is still # Even if no driver is selected the following default is still

View file

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

View file

@ -2484,7 +2484,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
#if defined(CONFIG_BT_HCI_MESH_EXT) #if defined(CONFIG_BT_HCI_MESH_EXT)
SHELL_CMD(mesh_adv, NULL, "<on, off>", cmd_mesh_adv), SHELL_CMD(mesh_adv, NULL, "<on, off>", cmd_mesh_adv),
#endif /* CONFIG_BT_HCI_MESH_EXT */ #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_CTLR_ADV_EXT)
#if defined(CONFIG_BT_BROADCASTER) #if defined(CONFIG_BT_BROADCASTER)
SHELL_CMD_ARG(advx, NULL, "<on off> [coded] [anon] [txp]", cmd_advx, 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), 2, 1),
#endif /* CONFIG_BT_OBSERVER */ #endif /* CONFIG_BT_OBSERVER */
#endif /* CONFIG_BT_CTLR_ADV_EXT */ #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) #if defined(CONFIG_BT_CTLR_DTM)
SHELL_CMD_ARG(test_tx, NULL, "<chan> <len> <type> <phy>", cmd_test_tx, SHELL_CMD_ARG(test_tx, NULL, "<chan> <len> <type> <phy>", cmd_test_tx,
5, 0), 5, 0),
@ -2505,7 +2502,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
4, 0), 4, 0),
SHELL_CMD_ARG(test_end, NULL, HELP_NONE, cmd_test_end, 1, 0), SHELL_CMD_ARG(test_end, NULL, HELP_NONE, cmd_test_end, 1, 0),
#endif /* CONFIG_BT_CTLR_ADV_EXT */ #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) #if defined(CONFIG_BT_LL_SW_SPLIT)
SHELL_CMD(ull_reset, NULL, HELP_NONE, cmd_ull_reset), SHELL_CMD(ull_reset, NULL, HELP_NONE, cmd_ull_reset),
#endif /* CONFIG_BT_LL_SW_SPLIT */ #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} 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 \ app=tests/bluetooth/bsim_bt/bsim_test_app conf_file=prj_split.conf \
compile compile
app=tests/bluetooth/bsim_bt/bsim_test_app conf_file=prj_split_privacy.conf \ 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: bluetooth.init.test_9:
extra_args: CONF_FILE=prj_9.conf extra_args: CONF_FILE=prj_9.conf
platform_whitelist: qemu_cortex_m3 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: bluetooth.init.test_controller_ll_sw_split:
extra_args: CONF_FILE=prj_controller_ll_sw_split.conf extra_args: CONF_FILE=prj_controller_ll_sw_split.conf
platform_whitelist: nrf52840dk_nrf52840 nrf52dk_nrf52832 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 # This test barely fits in RAM, don't pull in logging
CONFIG_TEST_LOGGING_DEFAULTS=n 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_DUP_FILTER_LEN=0
CONFIG_BT_CTLR_LE_ENC=n CONFIG_BT_CTLR_LE_ENC=n
CONFIG_BT_CTLR_LE_PING=n CONFIG_BT_CTLR_LE_PING=n