nimble/ll: Refactor conn init param handling

This fixes handling of parameters used for conn init.

Firstly, we only need conn init params when intiating new connection so
we can have single, global instance of that params - no need to store
them in conns. This saves 72 bytes of RAM per connsm.

Secondly, we do not need to store all parameters from HCI command since
some of them are only used to initialize scanner and those can be used
immediately. We only need to store connection parameters for ext conn
create.

This also allows to share more code between legacy and ext conn create
code paths.
This commit is contained in:
Andrzej Kaczmarek
2021-11-02 12:54:47 +01:00
parent 2443892ccc
commit df6ac21d2f
10 changed files with 365 additions and 456 deletions
@@ -188,29 +188,6 @@ struct hci_conn_update
uint16_t max_ce_len;
};
struct hci_ext_conn_params
{
uint16_t scan_itvl;
uint16_t scan_window;
uint32_t conn_itvl;
uint16_t conn_itvl_ticks;
uint8_t conn_itvl_usecs;
uint16_t conn_latency;
uint16_t supervision_timeout;
uint16_t min_ce_len;
uint16_t max_ce_len;
};
struct hci_ext_create_conn
{
uint8_t filter_policy;
uint8_t own_addr_type;
uint8_t peer_addr_type;
uint8_t peer_addr[BLE_DEV_ADDR_LEN];
uint8_t init_phy_mask;
struct hci_ext_conn_params params[3];
};
/* Connection state machine */
struct ble_ll_conn_sm
{
@@ -379,10 +356,6 @@ struct ble_ll_conn_sm
/* XXX: for now, just store them all */
struct ble_ll_conn_params conn_cp;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
struct hci_ext_create_conn initial_params;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
uint8_t sync_transfer_mode;
uint16_t sync_transfer_skip;
@@ -197,10 +197,11 @@ int ble_ll_scan_can_chg_whitelist(void);
int ble_ll_scan_enabled(void);
/* Initialize the scanner when we start initiating */
struct hci_create_conn;
struct ble_ll_conn_create_scan;
struct ble_ll_conn_create_params;
int
ble_ll_scan_initiator_start(struct hci_create_conn *hcc,
struct ble_ll_conn_sm *connsm);
ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext,
struct ble_ll_conn_create_scan *cc_scan);
/* Returns storage for PDU data (for SCAN_REQ or CONNECT_IND) */
struct ble_ll_scan_pdu_data *ble_ll_scan_get_pdu_data(void);
@@ -227,12 +228,6 @@ void ble_ll_scan_wfr_timer_exp(void);
void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
/* Initialize the extended scanner when we start initiating */
struct hci_ext_create_conn;
int
ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc,
struct ble_ll_conn_sm *connsm);
/* Called to parse extended advertising*/
void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data);
#endif
@@ -202,6 +202,11 @@ void ble_phy_resolv_list_disable(void);
#define BLE_PHY_MASK_2M (BLE_HCI_LE_PHY_2M_PREF_MASK)
#define BLE_PHY_MASK_CODED (BLE_HCI_LE_PHY_CODED_PREF_MASK)
/* PHY indices (for a zero-based array) */
#define BLE_PHY_IDX_1M (0)
#define BLE_PHY_IDX_2M (1)
#define BLE_PHY_IDX_CODED (2)
#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY))
uint32_t ble_phy_mode_pdu_start_off(int phy);
void ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode);
+1 -1
View File
@@ -577,7 +577,7 @@ ble_ll_set_random_addr(const uint8_t *cmdbuf, uint8_t len, bool hci_adv_ext)
* Test specification extends this also to initiating.
*/
if (g_ble_ll_conn_create_sm || ble_ll_scan_enabled() ||
if (g_ble_ll_conn_create_sm.connsm || ble_ll_scan_enabled() ||
(!hci_adv_ext && ble_ll_adv_enabled())) {
return BLE_ERR_CMD_DISALLOWED;
}
+52 -95
View File
@@ -143,8 +143,7 @@ struct ble_ll_conn_global_params g_ble_ll_conn_params;
struct ble_ll_conn_sync_transfer_params g_ble_ll_conn_sync_transfer_params;
#endif
/* Pointer to connection state machine we are trying to create */
struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
struct ble_ll_conn_create_sm g_ble_ll_conn_create_sm;
/* Pointer to current connection */
struct ble_ll_conn_sm *g_ble_ll_conn_cur_sm;
@@ -421,25 +420,23 @@ ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *csm)
}
#endif
static void
ble_ll_conn_calc_itvl_ticks(struct ble_ll_conn_sm *connsm)
void
ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint32_t *itvl_ticks,
uint8_t *itvl_usecs)
{
uint32_t ticks;
uint32_t usecs;
/*
* Precalculate the number of ticks and remaining microseconds for
* the connection interval
*/
usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
usecs = itvl * BLE_LL_CONN_ITVL_USECS;
ticks = os_cputime_usecs_to_ticks(usecs);
connsm->conn_itvl_usecs = (uint8_t)(usecs -
os_cputime_ticks_to_usecs(ticks));
if (connsm->conn_itvl_usecs == 31) {
connsm->conn_itvl_usecs = 0;
usecs = usecs - os_cputime_ticks_to_usecs(ticks);
if (usecs == 31) {
usecs = 0;
++ticks;
}
connsm->conn_itvl_ticks = ticks;
*itvl_ticks = ticks;
*itvl_usecs = usecs;
}
/**
@@ -1578,37 +1575,23 @@ ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm)
*/
void
ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm,
struct hci_create_conn *hcc)
struct ble_ll_conn_create_scan *cc_scan,
struct ble_ll_conn_create_params *cc_params)
{
ble_ll_conn_master_common_init(connsm);
/* Set slave latency and supervision timeout */
connsm->slave_latency = hcc->conn_latency;
connsm->supervision_tmo = hcc->supervision_timeout;
connsm->own_addr_type = cc_scan->own_addr_type;
memcpy(&connsm->peer_addr, &cc_scan->peer_addr, BLE_DEV_ADDR_LEN);
connsm->peer_addr_type = cc_scan->peer_addr_type;
/* Set own address type and peer address if needed */
connsm->own_addr_type = hcc->own_addr_type;
if (hcc->filter_policy == 0) {
memcpy(&connsm->peer_addr, &hcc->peer_addr, BLE_DEV_ADDR_LEN);
connsm->peer_addr_type = hcc->peer_addr_type;
}
/* XXX: for now, just make connection interval equal to max */
connsm->conn_itvl = hcc->conn_itvl_max;
/* Check the min/max CE lengths are less than connection interval */
if (hcc->min_ce_len > (connsm->conn_itvl * 2)) {
connsm->min_ce_len = connsm->conn_itvl * 2;
} else {
connsm->min_ce_len = hcc->min_ce_len;
}
if (hcc->max_ce_len > (connsm->conn_itvl * 2)) {
connsm->max_ce_len = connsm->conn_itvl * 2;
} else {
connsm->max_ce_len = hcc->max_ce_len;
}
connsm->conn_itvl = cc_params->conn_itvl;
connsm->conn_itvl_ticks = cc_params->conn_itvl_ticks;
connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs;
connsm->slave_latency = cc_params->conn_latency;
connsm->supervision_tmo = cc_params->supervision_timeout;
connsm->min_ce_len = cc_params->min_ce_len;
connsm->max_ce_len = cc_params->max_ce_len;
}
static void
@@ -1684,54 +1667,20 @@ ble_ll_conn_init_phy(struct ble_ll_conn_sm *connsm, int phy)
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
void
ble_ll_conn_ext_master_init(struct ble_ll_conn_sm *connsm,
struct hci_ext_create_conn *hcc)
static void
ble_ll_conn_create_set_params(struct ble_ll_conn_sm *connsm, uint8_t phy)
{
struct ble_ll_conn_create_params *cc_params;
ble_ll_conn_master_common_init(connsm);
cc_params = &g_ble_ll_conn_create_sm.params[phy - 1];
/* Set own address type and peer address if needed */
connsm->own_addr_type = hcc->own_addr_type;
if (hcc->filter_policy == 0) {
memcpy(&connsm->peer_addr, &hcc->peer_addr, BLE_DEV_ADDR_LEN);
connsm->peer_addr_type = hcc->peer_addr_type;
}
connsm->slave_latency = cc_params->conn_latency;
connsm->supervision_tmo = cc_params->supervision_timeout;
connsm->initial_params = *hcc;
connsm->conn_itvl = cc_params->conn_itvl;
connsm->conn_itvl_ticks = cc_params->conn_itvl_ticks;
connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs;
}
void
ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm,
struct hci_ext_conn_params *hcc_params, int phy)
{
connsm->slave_latency = hcc_params->conn_latency;
connsm->supervision_tmo = hcc_params->supervision_timeout;
connsm->conn_itvl = hcc_params->conn_itvl;
connsm->conn_itvl_ticks = hcc_params->conn_itvl_ticks;
connsm->conn_itvl_usecs = hcc_params->conn_itvl_usecs;
/* Check the min/max CE lengths are less than connection interval */
if (hcc_params->min_ce_len > (connsm->conn_itvl * 2)) {
connsm->min_ce_len = connsm->conn_itvl * 2;
} else {
connsm->min_ce_len = hcc_params->min_ce_len;
}
if (hcc_params->max_ce_len > (connsm->conn_itvl * 2)) {
connsm->max_ce_len = connsm->conn_itvl * 2;
} else {
connsm->max_ce_len = hcc_params->max_ce_len;
}
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
ble_ll_conn_init_phy(connsm, phy);
#endif
}
#endif
static void
@@ -1862,8 +1811,6 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
connsm);
#endif
ble_ll_conn_calc_itvl_ticks(connsm);
/* Add to list of active connections */
SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle);
}
@@ -2170,7 +2117,10 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS;
connsm->tx_win_off = upd->winoffset;
connsm->conn_itvl = upd->interval;
ble_ll_conn_calc_itvl_ticks(connsm);
ble_ll_conn_itvl_to_ticks(connsm->conn_itvl, &connsm->conn_itvl_ticks,
&connsm->conn_itvl_usecs);
if (upd->winoffset != 0) {
usecs = upd->winoffset * BLE_LL_CONN_ITVL_USECS;
ticks = os_cputime_usecs_to_ticks(usecs);
@@ -2651,7 +2601,7 @@ ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm,
}
} else {
/* Get pointer to our device address */
connsm = g_ble_ll_conn_create_sm;
connsm = g_ble_ll_conn_create_sm.connsm;
if ((connsm->own_addr_type & 1) == 0) {
addr = g_dev_addr;
} else {
@@ -2764,12 +2714,11 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu,
struct ble_mbuf_hdr *rxhdr;
int8_t rpa_index;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
struct hci_ext_conn_params *ecp;
uint8_t phy;
#endif
int rc;
connsm = g_ble_ll_conn_create_sm;
connsm = g_ble_ll_conn_create_sm.connsm;
rxhdr = BLE_MBUF_HDR_PTR(rxpdu);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
@@ -2779,8 +2728,7 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu,
#else
phy = BLE_PHY_1M;
#endif
ecp = &connsm->initial_params.params[phy - 1];
ble_ll_conn_ext_set_params(connsm, ecp, phy);
ble_ll_conn_create_set_params(connsm, phy);
}
#endif
@@ -2806,6 +2754,12 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu,
return -1;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && BLE_LL_BT5_PHY_SUPPORTED
if (ext) {
ble_ll_conn_init_phy(connsm, phy);
}
#endif
return 0;
}
@@ -2814,7 +2768,7 @@ ble_ll_conn_send_connect_req_cancel(void)
{
struct ble_ll_conn_sm *connsm;
connsm = g_ble_ll_conn_create_sm;
connsm = g_ble_ll_conn_create_sm.connsm;
ble_ll_sched_rmv_elem(&connsm->conn_sch);
}
@@ -2825,8 +2779,8 @@ ble_ll_conn_master_start(uint8_t phy, uint8_t csa,
{
struct ble_ll_conn_sm *connsm;
connsm = g_ble_ll_conn_create_sm;
g_ble_ll_conn_create_sm = NULL;
connsm = g_ble_ll_conn_create_sm.connsm;
g_ble_ll_conn_create_sm.connsm = NULL;
connsm->peer_addr_type = addrd->adv_addr_type;
memcpy(connsm->peer_addr, addrd->adv_addr, 6);
@@ -3688,6 +3642,9 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr,
goto err_slave_start;
}
ble_ll_conn_itvl_to_ticks(connsm->conn_itvl, &connsm->conn_itvl_ticks,
&connsm->conn_itvl_usecs);
/* Start the connection state machine */
connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE;
ble_ll_conn_sm_new(connsm);
@@ -3751,7 +3708,7 @@ ble_ll_conn_module_reset(void)
}
/* Reset connection we are attempting to create */
g_ble_ll_conn_create_sm = NULL;
g_ble_ll_conn_create_sm.connsm = NULL;
/* Now go through and end all the connections */
while (1) {
+234 -254
View File
@@ -43,19 +43,22 @@ static ble_npl_time_t g_ble_ll_last_num_comp_pkt_evt;
extern uint8_t *g_ble_ll_conn_comp_ev;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static const uint8_t ble_ll_valid_conn_phy_mask = (BLE_HCI_LE_PHY_1M_PREF_MASK
static const uint8_t ble_ll_conn_create_valid_phy_mask = (
BLE_HCI_LE_PHY_1M_PREF_MASK |
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
| BLE_HCI_LE_PHY_2M_PREF_MASK
BLE_HCI_LE_PHY_2M_PREF_MASK |
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
| BLE_HCI_LE_PHY_CODED_PREF_MASK
BLE_HCI_LE_PHY_CODED_PREF_MASK |
#endif
);
static const uint8_t ble_ll_conn_required_phy_mask = (BLE_HCI_LE_PHY_1M_PREF_MASK
0);
static const uint8_t ble_ll_conn_create_required_phy_mask = (
BLE_HCI_LE_PHY_1M_PREF_MASK |
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
| BLE_HCI_LE_PHY_CODED_PREF_MASK
BLE_HCI_LE_PHY_CODED_PREF_MASK |
#endif
);
0);
#endif
/**
@@ -401,18 +404,74 @@ ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason)
}
}
static int
ble_ll_conn_hci_chk_scan_params(uint16_t itvl, uint16_t window)
int
ble_ll_conn_hci_create_check_scan(struct ble_ll_conn_create_scan *p)
{
/* Check interval and window */
if ((itvl < BLE_HCI_SCAN_ITVL_MIN) ||
(itvl > BLE_HCI_SCAN_ITVL_MAX) ||
(window < BLE_HCI_SCAN_WINDOW_MIN) ||
(window > BLE_HCI_SCAN_WINDOW_MAX) ||
(itvl < window)) {
if (p->filter_policy > BLE_HCI_INITIATOR_FILT_POLICY_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if ((p->filter_policy == 0) &&
(p->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if (p->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
if (p->init_phy_mask & ~ble_ll_conn_create_valid_phy_mask) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if (!(p->init_phy_mask & ble_ll_conn_create_required_phy_mask)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
#endif
return 0;
}
static int
ble_ll_conn_hci_create_check_params(struct ble_ll_conn_create_params *cc_params)
{
uint32_t supervision_tmo_us;
uint32_t conn_itvl_us;
if ((cc_params->conn_itvl < BLE_HCI_CONN_ITVL_MIN) ||
(cc_params->conn_itvl > BLE_HCI_CONN_ITVL_MAX) ||
(cc_params->conn_latency > BLE_HCI_CONN_LATENCY_MAX) ||
(cc_params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) ||
(cc_params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
/* Supervision timeout must be longer than (1 + latency) * interval * 2 */
supervision_tmo_us = cc_params->supervision_timeout *
BLE_HCI_CONN_SPVN_TMO_UNITS * 1000;
conn_itvl_us = cc_params->conn_itvl * BLE_LL_CONN_ITVL_USECS;
if (supervision_tmo_us <= (1 + cc_params->conn_latency) * conn_itvl_us * 2) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if (cc_params->min_ce_len > cc_params->max_ce_len) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
/* Adjust min/max ce length to be less than interval */
if (cc_params->min_ce_len > cc_params->conn_itvl) {
cc_params->min_ce_len = cc_params->conn_itvl;
}
if (cc_params->max_ce_len > cc_params->conn_itvl) {
cc_params->max_ce_len = cc_params->conn_itvl;
}
/* Precalculate conn interval */
ble_ll_conn_itvl_to_ticks(cc_params->conn_itvl, &cc_params->conn_itvl_ticks,
&cc_params->conn_itvl_usecs);
return 0;
}
@@ -426,11 +485,14 @@ ble_ll_conn_hci_chk_scan_params(uint16_t itvl, uint16_t window)
* @return int
*/
int
ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len)
ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len)
{
const struct ble_hci_le_create_conn_cp *cmd = (const void *) cmdbuf;
struct ble_ll_conn_create_scan cc_scan;
struct ble_ll_conn_create_params cc_params;
struct ble_ll_conn_sm *connsm;
struct hci_create_conn hcc = { 0 };
uint16_t conn_itvl_min;
uint16_t conn_itvl_max;
int rc;
if (len < sizeof(*cmd)) {
@@ -438,7 +500,7 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len)
}
/* If we are already creating a connection we should leave */
if (g_ble_ll_conn_create_sm) {
if (g_ble_ll_conn_create_sm.connsm) {
return BLE_ERR_CMD_DISALLOWED;
}
@@ -447,57 +509,48 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_CMD_DISALLOWED;
}
/* Retrieve command data */
hcc.scan_itvl = le16toh(cmd->scan_itvl);
hcc.scan_window = le16toh(cmd->scan_window);
rc = ble_ll_conn_hci_chk_scan_params(hcc.scan_itvl, hcc.scan_window);
if (rc) {
return BLE_ERR_INV_HCI_CMD_PARMS;
cc_scan.own_addr_type = cmd->own_addr_type;
cc_scan.filter_policy = cmd->filter_policy;
if (cc_scan.filter_policy == 0) {
cc_scan.peer_addr_type = cmd->peer_addr_type;
memcpy(&cc_scan.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);
} else {
cc_scan.peer_addr_type = 0;
memset(&cc_scan.peer_addr, 0, BLE_DEV_ADDR_LEN);
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
cc_scan.init_phy_mask = BLE_HCI_LE_PHY_1M_PREF_MASK;
#endif
/* Check filter policy */
hcc.filter_policy = cmd->filter_policy;
if (hcc.filter_policy > BLE_HCI_INITIATOR_FILT_POLICY_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
cc_scan.scan_params[PHY_UNCODED].itvl = le16toh(cmd->scan_itvl);
cc_scan.scan_params[PHY_UNCODED].window = le16toh(cmd->scan_window);
/* Get peer address type and address only if no whitelist used */
if (hcc.filter_policy == 0) {
hcc.peer_addr_type = cmd->peer_addr_type;
if (hcc.peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
memcpy(&hcc.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);
}
/* Get own address type (used in connection request) */
hcc.own_addr_type = cmd->own_addr_type;
if (hcc.own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
/* Check connection interval, latency and supervision timeoout */
hcc.conn_itvl_min = le16toh(cmd->min_conn_itvl);
hcc.conn_itvl_max = le16toh(cmd->max_conn_itvl);
hcc.conn_latency = le16toh(cmd->conn_latency);
hcc.supervision_timeout = le16toh(cmd->tmo);
rc = ble_ll_conn_hci_chk_conn_params(hcc.conn_itvl_min,
hcc.conn_itvl_max,
hcc.conn_latency,
hcc.supervision_timeout);
rc = ble_ll_conn_hci_create_check_scan(&cc_scan);
if (rc) {
return rc;
}
/* Min/max connection event lengths */
hcc.min_ce_len = le16toh(cmd->min_ce);
hcc.max_ce_len = le16toh(cmd->max_ce);
if (hcc.min_ce_len > hcc.max_ce_len) {
conn_itvl_min = le16toh(cmd->min_conn_itvl);
conn_itvl_max = le16toh(cmd->max_conn_itvl);
/* Check min/max interval here since generic check does not have min/max
* parameters to check.
*/
if (conn_itvl_min > conn_itvl_max) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
cc_params.conn_itvl = conn_itvl_max;
cc_params.conn_latency = le16toh(cmd->conn_latency);
cc_params.supervision_timeout = le16toh(cmd->tmo);
cc_params.min_ce_len = le16toh(cmd->min_ce);
cc_params.max_ce_len = le16toh(cmd->max_ce);
rc = ble_ll_conn_hci_create_check_params(&cc_params);
if (rc) {
return rc;
}
/* Make sure we can allocate an event to send the connection complete */
if (ble_ll_init_alloc_conn_comp_ev()) {
return BLE_ERR_MEM_CAPACITY;
@@ -510,18 +563,14 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len)
}
/* Initialize state machine in master role and start state machine */
ble_ll_conn_master_init(connsm, &hcc);
ble_ll_conn_master_init(connsm, &cc_scan, &cc_params);
ble_ll_conn_sm_new(connsm);
/* CSA will be selected when advertising is received */
/* Start scanning */
rc = ble_ll_scan_initiator_start(&hcc, connsm);
rc = ble_ll_scan_initiator_start(connsm, 0, &cc_scan);
if (rc) {
SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle);
STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
} else {
/* Set the connection state machine we are trying to create. */
g_ble_ll_conn_create_sm = connsm;
}
return rc;
@@ -529,68 +578,117 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len)
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static void
ble_ll_conn_hcc_params_set_fallback(struct hci_ext_create_conn *hcc,
const struct hci_ext_conn_params *fallback)
ble_ll_conn_hci_ext_create_set_fb_params(uint8_t init_phy_mask,
struct ble_ll_conn_create_params *cc_params_fb)
{
BLE_LL_ASSERT(fallback);
if (!(hcc->init_phy_mask & BLE_PHY_MASK_1M)) {
hcc->params[0] = *fallback;
if ((init_phy_mask & BLE_PHY_MASK_1M) == 0) {
g_ble_ll_conn_create_sm.params[BLE_PHY_IDX_1M] = *cc_params_fb;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
if (!(hcc->init_phy_mask & BLE_PHY_MASK_2M)) {
hcc->params[1] = *fallback;
if ((init_phy_mask & BLE_PHY_MASK_2M) == 0) {
g_ble_ll_conn_create_sm.params[BLE_PHY_IDX_2M] = *cc_params_fb;
}
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
if (!(hcc->init_phy_mask & BLE_PHY_MASK_CODED)) {
hcc->params[2] = *fallback;
if ((init_phy_mask & BLE_PHY_MASK_CODED) == 0) {
g_ble_ll_conn_create_sm.params[BLE_PHY_IDX_CODED] = *cc_params_fb;
}
#endif
}
static void
ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint16_t *itvl_ticks,
uint8_t *itvl_usecs)
static int
ble_ll_conn_hci_ext_create_parse_params(const struct conn_params *params,
uint8_t phy,
struct ble_ll_conn_create_scan *cc_scan,
struct ble_ll_conn_create_params *cc_params)
{
uint32_t ticks;
uint32_t usecs;
usecs = itvl * BLE_LL_CONN_ITVL_USECS;
ticks = os_cputime_usecs_to_ticks(usecs);
usecs = usecs - os_cputime_ticks_to_usecs(ticks);
if (usecs == 31) {
usecs = 0;
++ticks;
}
*itvl_ticks = ticks;
*itvl_usecs = usecs;
}
int
ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
{
const struct ble_hci_le_ext_create_conn_cp *cmd = (const void *) cmdbuf;
const struct conn_params *params = cmd->conn_params;
const struct hci_ext_conn_params *fallback_params = NULL;
struct hci_ext_create_conn hcc = { 0 };
struct ble_ll_conn_sm *connsm;
uint16_t conn_itvl_min;
uint16_t conn_itvl_max;
uint16_t scan_itvl;
uint16_t scan_window;
int rc;
/* validate length */
if (len < sizeof(*cmd)) {
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
/* Check min/max interval here since generic check does not have min/max
* parameters to check.
*/
if (conn_itvl_min > conn_itvl_max) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
len -= sizeof(*cmd);
cc_params->conn_itvl = conn_itvl_max;
cc_params->conn_latency = le16toh(params->conn_latency);
cc_params->supervision_timeout = le16toh(params->supervision_timeout);
cc_params->min_ce_len = le16toh(params->min_ce);
cc_params->max_ce_len = le16toh(params->max_ce);
rc = ble_ll_conn_hci_create_check_params(cc_params);
if (rc) {
return rc;
}
if (phy != BLE_PHY_2M) {
scan_itvl = le16toh(params->scan_itvl);
scan_window = le16toh(params->scan_window);
if ((scan_itvl < BLE_HCI_SCAN_ITVL_MIN) ||
(scan_itvl > BLE_HCI_SCAN_ITVL_MAX) ||
(scan_window < BLE_HCI_SCAN_WINDOW_MIN) ||
(scan_window > BLE_HCI_SCAN_WINDOW_MAX) ||
(scan_itvl < scan_window)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if (phy == BLE_PHY_1M) {
cc_scan->scan_params[PHY_UNCODED].itvl = scan_itvl;
cc_scan->scan_params[PHY_UNCODED].window = scan_window;
} else {
cc_scan->scan_params[PHY_CODED].itvl = scan_itvl;
cc_scan->scan_params[PHY_CODED].window = scan_window;
}
}
return 0;
}
int
ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len)
{
static const struct init_phy {
uint8_t idx;
uint8_t mask;
uint8_t phy;
} init_phys[] = {
{BLE_PHY_IDX_1M, BLE_PHY_MASK_1M, BLE_PHY_1M},
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
{BLE_PHY_IDX_2M, BLE_PHY_MASK_2M, BLE_PHY_2M},
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
{BLE_PHY_IDX_CODED, BLE_PHY_MASK_CODED, BLE_PHY_CODED},
#endif
};
const struct ble_hci_le_ext_create_conn_cp *cmd = (const void *)cmdbuf;
const struct conn_params *params = cmd->conn_params;
struct ble_ll_conn_create_scan cc_scan;
struct ble_ll_conn_create_params *cc_params;
struct ble_ll_conn_create_params *cc_params_fb;
struct ble_ll_conn_sm *connsm;
const struct init_phy *init_phy;
int rc;
/* validate length */
if (len < sizeof(*cmd) +
__builtin_popcount(cmd->init_phy_mask) * sizeof(*params)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
/* If we are already creating a connection we should leave */
if (g_ble_ll_conn_create_sm) {
if (g_ble_ll_conn_create_sm.connsm) {
return BLE_ERR_CMD_DISALLOWED;
}
@@ -599,161 +697,47 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_CMD_DISALLOWED;
}
hcc.filter_policy = cmd->filter_policy;
if (hcc.filter_policy > BLE_HCI_INITIATOR_FILT_POLICY_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
cc_scan.own_addr_type = cmd->own_addr_type;
cc_scan.filter_policy = cmd->filter_policy;
if (cc_scan.filter_policy == 0) {
cc_scan.peer_addr_type = cmd->peer_addr_type;
memcpy(cc_scan.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);
} else {
cc_scan.peer_addr_type = 0;
memset(cc_scan.peer_addr, 0, BLE_DEV_ADDR_LEN);
}
cc_scan.init_phy_mask = cmd->init_phy_mask;
rc = ble_ll_conn_hci_create_check_scan(&cc_scan);
if (rc) {
return rc;
}
hcc.own_addr_type = cmd->own_addr_type;
if (hcc.own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
cc_params_fb = NULL;
/* Validate peer address type only if no whitelist used */
if (hcc.filter_policy == 0) {
hcc.peer_addr_type = cmd->peer_addr_type;
for (int i = 0; i < ARRAY_SIZE(init_phys); i++) {
init_phy = &init_phys[i];
if (hcc.peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) {
return BLE_ERR_INV_HCI_CMD_PARMS;
if ((cc_scan.init_phy_mask & init_phy->mask) == 0) {
continue;
}
memcpy(hcc.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN);
}
cc_params = &g_ble_ll_conn_create_sm.params[init_phy->idx];
hcc.init_phy_mask = cmd->init_phy_mask;
if (hcc.init_phy_mask & ~ble_ll_valid_conn_phy_mask) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if (!(hcc.init_phy_mask & ble_ll_conn_required_phy_mask)) {
/* At least one of those need to be set */
return BLE_ERR_INV_HCI_CMD_PARMS;
}
if (hcc.init_phy_mask & BLE_PHY_MASK_1M) {
if (len < sizeof(*params)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
len -= sizeof(*params);
hcc.params[0].scan_itvl = le16toh(params->scan_itvl);
hcc.params[0].scan_window = le16toh(params->scan_window);
rc = ble_ll_conn_hci_chk_scan_params(hcc.params[0].scan_itvl,
hcc.params[0].scan_window);
rc = ble_ll_conn_hci_ext_create_parse_params(params, init_phy->phy,
&cc_scan, cc_params);
if (rc) {
return rc;
}
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
hcc.params[0].conn_latency = le16toh(params->conn_latency);
hcc.params[0].supervision_timeout = le16toh(params->supervision_timeout);
rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max,
hcc.params[0].conn_latency,
hcc.params[0].supervision_timeout);
if (rc) {
return rc;
if (!cc_params_fb) {
cc_params_fb = cc_params;
}
/* Min/max connection event lengths */
hcc.params[0].min_ce_len = le16toh(params->min_ce);
hcc.params[0].max_ce_len = le16toh(params->max_ce);
if (hcc.params[0].min_ce_len > hcc.params[0].max_ce_len) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
hcc.params[0].conn_itvl = conn_itvl_max;
ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[0].conn_itvl_ticks,
&hcc.params[0].conn_itvl_usecs);
fallback_params = &hcc.params[0];
params++;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
if (hcc.init_phy_mask & BLE_PHY_MASK_2M) {
if (len < sizeof(*params)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
len -= sizeof(*params);
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
hcc.params[1].conn_latency = le16toh(params->conn_latency);
hcc.params[1].supervision_timeout = le16toh(params->supervision_timeout);
rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max,
hcc.params[1].conn_latency,
hcc.params[1].supervision_timeout);
if (rc) {
return rc;
}
/* Min/max connection event lengths */
hcc.params[1].min_ce_len = le16toh(params->min_ce);
hcc.params[1].max_ce_len = le16toh(params->max_ce);
if (hcc.params[1].min_ce_len > hcc.params[1].max_ce_len) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
hcc.params[1].conn_itvl = conn_itvl_max;
ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[1].conn_itvl_ticks,
&hcc.params[1].conn_itvl_usecs);
if (!fallback_params) {
fallback_params = &hcc.params[1];
}
params++;
}
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
if (hcc.init_phy_mask & BLE_PHY_MASK_CODED) {
if (len < sizeof(*params)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
len -= sizeof(*params);
hcc.params[2].scan_itvl = le16toh(params->scan_itvl);
hcc.params[2].scan_window = le16toh(params->scan_window);
rc = ble_ll_conn_hci_chk_scan_params(hcc.params[2].scan_itvl,
hcc.params[2].scan_window);
if (rc) {
return rc;
}
conn_itvl_min = le16toh(params->conn_min_itvl);
conn_itvl_max = le16toh(params->conn_max_itvl);
hcc.params[2].conn_latency = le16toh(params->conn_latency);
hcc.params[2].supervision_timeout = le16toh(params->supervision_timeout);
rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max,
hcc.params[2].conn_latency,
hcc.params[2].supervision_timeout);
if (rc) {
return rc;
}
/* Min/max connection event lengths */
hcc.params[2].min_ce_len = le16toh(params->min_ce);
hcc.params[2].max_ce_len = le16toh(params->max_ce);
if (hcc.params[2].min_ce_len > hcc.params[2].max_ce_len) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
hcc.params[2].conn_itvl = conn_itvl_max;
ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[2].conn_itvl_ticks,
&hcc.params[2].conn_itvl_usecs);
if (!fallback_params) {
fallback_params = &hcc.params[2];
}
params++;
}
#endif
ble_ll_conn_hci_ext_create_set_fb_params(cc_scan.init_phy_mask,
cc_params_fb);
/* Make sure we can allocate an event to send the connection complete */
if (ble_ll_init_alloc_conn_comp_ev()) {
@@ -766,20 +750,16 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_CONN_LIMIT;
}
ble_ll_conn_hcc_params_set_fallback(&hcc, fallback_params);
/* Initialize state machine in master role and start state machine */
ble_ll_conn_ext_master_init(connsm, &hcc);
ble_ll_conn_master_init(connsm, &cc_scan,
&g_ble_ll_conn_create_sm.params[0]);
ble_ll_conn_sm_new(connsm);
/* Start scanning */
rc = ble_ll_scan_ext_initiator_start(&hcc, connsm);
rc = ble_ll_scan_initiator_start(connsm, 1, &cc_scan);
if (rc) {
SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle);
STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
} else {
/* Set the connection state machine we are trying to create. */
g_ble_ll_conn_create_sm = connsm;
}
return rc;
@@ -1125,10 +1105,10 @@ ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb)
* return disallowed as well
*/
OS_ENTER_CRITICAL(sr);
connsm = g_ble_ll_conn_create_sm;
connsm = g_ble_ll_conn_create_sm.connsm;
if (connsm && (connsm->conn_state == BLE_LL_CONN_STATE_IDLE)) {
/* stop scanning and end the connection event */
g_ble_ll_conn_create_sm = NULL;
g_ble_ll_conn_create_sm.connsm = NULL;
ble_ll_scan_sm_stop(1);
ble_ll_conn_end(connsm, BLE_ERR_UNK_CONN_ID);
+39 -13
View File
@@ -93,8 +93,38 @@ STAILQ_HEAD(ble_ll_conn_free_list, ble_ll_conn_sm);
extern struct ble_ll_conn_active_list g_ble_ll_conn_active_list;
extern struct ble_ll_conn_free_list g_ble_ll_conn_free_list;
/* Pointer to connection state machine we are trying to create */
extern struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
struct ble_ll_conn_create_scan {
uint8_t filter_policy;
uint8_t own_addr_type;
uint8_t peer_addr_type;
uint8_t peer_addr[BLE_DEV_ADDR_LEN];
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
uint8_t init_phy_mask;
#endif
struct {
uint16_t itvl;
uint16_t window;
} scan_params[2];
};
struct ble_ll_conn_create_params {
uint32_t conn_itvl;
uint32_t conn_itvl_ticks;
uint8_t conn_itvl_usecs;
uint16_t conn_latency;
uint16_t supervision_timeout;
uint16_t min_ce_len;
uint16_t max_ce_len;
};
struct ble_ll_conn_create_sm {
struct ble_ll_conn_sm *connsm;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
struct ble_ll_conn_create_params params[3];
#endif
};
extern struct ble_ll_conn_create_sm g_ble_ll_conn_create_sm;
/* Generic interface */
struct ble_ll_len_req;
@@ -123,15 +153,8 @@ void ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om,
uint8_t hdr_byte, uint16_t length);
struct ble_ll_conn_sm *ble_ll_conn_sm_get(void);
void ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm,
struct hci_create_conn *hcc);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
void ble_ll_conn_ext_master_init(struct ble_ll_conn_sm *connsm,
struct hci_ext_create_conn *hcc);
void ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm,
struct hci_ext_conn_params *hcc_params,
int phy);
#endif
struct ble_ll_conn_create_scan *cc_scan,
struct ble_ll_conn_create_params *cc_params);
struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle);
void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm);
@@ -158,7 +181,7 @@ void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm,
void ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm);
int ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd);
int ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len,
@@ -205,6 +228,9 @@ bool ble_ll_conn_cth_flow_enable(bool enabled);
void ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf);
#endif
void ble_ll_conn_itvl_to_ticks(uint32_t itvl,
uint32_t *itvl_ticks, uint8_t *itvl_usecs);
int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg);
int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg);
@@ -213,7 +239,7 @@ int ble_ll_conn_hci_le_rd_phy(const uint8_t *cmdbuf, uint8_t len,
int ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *connsm);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
int ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t cmdlen);
int ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len);
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
+2 -2
View File
@@ -910,7 +910,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
rc = ble_ll_hci_scan_set_enable(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_CREATE_CONN:
rc = ble_ll_conn_create(cmdbuf, len);
rc = ble_ll_conn_hci_create(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_CREATE_CONN_CANCEL:
if (len == 0) {
@@ -1113,7 +1113,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
rc = ble_ll_hci_ext_scan_set_enable(cmdbuf, len);
break;
case BLE_HCI_OCF_LE_EXT_CREATE_CONN:
rc = ble_ll_ext_conn_create(cmdbuf, len);
rc = ble_ll_conn_hci_ext_create(cmdbuf, len);
break;
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
+1 -1
View File
@@ -57,7 +57,7 @@ ble_ll_is_controller_busy(void)
#endif
return ble_ll_adv_enabled() || ble_ll_scan_enabled() ||
g_ble_ll_conn_create_sm;
g_ble_ll_conn_create_sm.connsm;
}
/**
* Called to determine if a change is allowed to the resolving list at this
+27 -54
View File
@@ -2411,65 +2411,37 @@ ble_ll_scan_can_chg_whitelist(void)
}
int
ble_ll_scan_initiator_start(struct hci_create_conn *hcc,
struct ble_ll_conn_sm *connsm)
{
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_phy *scanp;
int rc;
scansm = &g_ble_ll_scan_sm;
scansm->own_addr_type = hcc->own_addr_type;
scansm->scan_filt_policy = hcc->filter_policy;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
scansm->ext_scanning = 0;
#endif
scansm->connsm = connsm;
scansm->scanp = &scansm->scan_phys[PHY_UNCODED];
scansm->scanp_next = NULL;
scanp = scansm->scanp;
scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(hcc->scan_itvl);
scanp->timing.window = ble_ll_scan_time_hci_to_ticks(hcc->scan_window);
scanp->scan_type = BLE_SCAN_TYPE_INITIATE;
scanp->configured = 1;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
scanp = &scansm->scan_phys[PHY_CODED];
scanp->configured = 0;
#endif
rc = ble_ll_scan_sm_start(scansm);
return rc;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
int
ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc,
struct ble_ll_conn_sm *connsm)
ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext,
struct ble_ll_conn_create_scan *cc_scan)
{
struct ble_ll_scan_sm *scansm;
struct ble_ll_scan_phy *scanp_uncoded;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
struct ble_ll_scan_phy *scanp_coded;
struct hci_ext_conn_params *params;
#endif
uint8_t init_phy_mask;
int rc;
scansm = &g_ble_ll_scan_sm;
scansm->own_addr_type = hcc->own_addr_type;
scansm->scan_filt_policy = hcc->filter_policy;
scansm->own_addr_type = cc_scan->own_addr_type;
scansm->scan_filt_policy = cc_scan->filter_policy;
scansm->scanp = NULL;
scansm->scanp_next = NULL;
scansm->ext_scanning = 1;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
scansm->ext_scanning = ext;
init_phy_mask = cc_scan->init_phy_mask;
#else
init_phy_mask = BLE_PHY_MASK_1M;
#endif
scansm->connsm = connsm;
params = &hcc->params[0];
scanp_uncoded = &scansm->scan_phys[PHY_UNCODED];
if (hcc->init_phy_mask & BLE_PHY_MASK_1M) {
if (init_phy_mask & BLE_PHY_MASK_1M) {
scanp_uncoded->configured = 1;
scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl);
scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window);
scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks(
cc_scan->scan_params[PHY_UNCODED].itvl);
scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks(
cc_scan->scan_params[PHY_UNCODED].window);
scanp_uncoded->scan_type = BLE_SCAN_TYPE_INITIATE;
scansm->scanp = scanp_uncoded;
} else {
@@ -2477,12 +2449,13 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc,
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
params = &hcc->params[2];
scanp_coded = &scansm->scan_phys[PHY_CODED];
if (hcc->init_phy_mask & BLE_PHY_MASK_CODED) {
if (init_phy_mask & BLE_PHY_MASK_CODED) {
scanp_coded->configured = 1;
scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl);
scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window);
scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks(
cc_scan->scan_params[PHY_CODED].itvl);
scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks(
cc_scan->scan_params[PHY_CODED].window);
scanp_coded->scan_type = BLE_SCAN_TYPE_INITIATE;
if (scansm->scanp) {
scansm->scanp_next = scanp_coded;
@@ -2492,9 +2465,6 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc,
} else {
scanp_coded->configured = 0;
}
#else
scanp_coded = NULL;
#endif
/* if any of PHYs is configured for continuous scan we alter interval to
* fit other PHY
@@ -2509,12 +2479,15 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc,
scanp_uncoded->timing.interval += scanp_coded->timing.window;
}
}
#endif
rc = ble_ll_scan_sm_start(scansm);
if (rc == 0) {
g_ble_ll_conn_create_sm.connsm = connsm;
}
return rc;
}
#endif
/**
* Checks to see if the scanner is enabled.