mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-19 11:37:56 +00:00
nimble/gap: Add GAP API for extended connection
For now we have separate function but maybe we could do it better. X-Original-Commit: a1ad55b988b7bea5426c1645a20a1055112a0999
This commit is contained in:
@@ -587,6 +587,12 @@ int ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms,
|
||||
const struct ble_gap_conn_params *params,
|
||||
ble_gap_event_fn *cb, void *cb_arg);
|
||||
int ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg);
|
||||
int ble_gap_conn_cancel(void);
|
||||
int ble_gap_conn_active(void);
|
||||
int ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason);
|
||||
|
||||
@@ -2613,6 +2613,242 @@ ble_gap_conn_create_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
static void
|
||||
ble_gap_copy_params(struct hci_ext_conn_params *hcc_params,
|
||||
const struct ble_gap_conn_params *gap_params)
|
||||
{
|
||||
hcc_params->scan_itvl = gap_params->scan_itvl;
|
||||
hcc_params->scan_window = gap_params->scan_window;
|
||||
hcc_params->conn_itvl_max = gap_params->itvl_max;
|
||||
hcc_params->conn_itvl_min = gap_params->itvl_min;
|
||||
hcc_params->max_ce_len = gap_params->max_ce_len;
|
||||
hcc_params->min_ce_len = gap_params->min_ce_len;
|
||||
hcc_params->conn_latency = gap_params->latency;
|
||||
hcc_params->supervision_timeout = gap_params->supervision_timeout;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gap_ext_conn_create_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params)
|
||||
{
|
||||
uint8_t buf[BLE_HCI_CMD_HDR_LEN + sizeof(struct hci_ext_create_conn)];
|
||||
struct hci_ext_create_conn hcc = {};
|
||||
int rc;
|
||||
|
||||
if (peer_addr == NULL) {
|
||||
/* Application wants to connect to any device in the white list. The
|
||||
* peer address type and peer address fields are ignored by the
|
||||
* controller; fill them with dummy values.
|
||||
*/
|
||||
hcc.filter_policy = BLE_HCI_CONN_FILT_USE_WL;
|
||||
hcc.peer_addr_type = 0;
|
||||
memset(hcc.peer_addr, 0, sizeof hcc.peer_addr);
|
||||
} else {
|
||||
hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL;
|
||||
hcc.peer_addr_type = peer_addr->type;;
|
||||
memcpy(hcc.peer_addr, peer_addr->val, sizeof hcc.peer_addr);
|
||||
}
|
||||
|
||||
hcc.own_addr_type = own_addr_type;
|
||||
|
||||
hcc.init_phy_mask = phy_mask;
|
||||
|
||||
if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) {
|
||||
/* XXX same structs */
|
||||
ble_gap_copy_params(&hcc.params[0], phy_1m_conn_params);
|
||||
}
|
||||
|
||||
if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) {
|
||||
/* XXX same structs */
|
||||
ble_gap_copy_params(&hcc.params[1], phy_2m_conn_params);
|
||||
}
|
||||
|
||||
if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) {
|
||||
/* XXX same structs */
|
||||
ble_gap_copy_params(&hcc.params[2], phy_coded_conn_params);
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_build_le_ext_create_conn(&hcc, buf, sizeof buf);
|
||||
if (rc != 0) {
|
||||
return BLE_HS_EUNKNOWN;
|
||||
}
|
||||
|
||||
rc = ble_hs_hci_cmd_tx_empty_ack(buf);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a connect procedure.
|
||||
*
|
||||
* @param own_addr_type The type of address the stack should use for
|
||||
* itself during connection establishment.
|
||||
* o BLE_OWN_ADDR_PUBLIC
|
||||
* o BLE_OWN_ADDR_RANDOM
|
||||
* o BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT
|
||||
* o BLE_OWN_ADDR_RPA_RANDOM_DEFAULT
|
||||
* @param peer_addr The address of the peer to connect to.
|
||||
* If this parameter is NULL, the white list
|
||||
* is used.
|
||||
* @param duration_ms The duration of the discovery procedure.
|
||||
* On expiration, the procedure ends and a
|
||||
* BLE_GAP_EVENT_DISC_COMPLETE event is
|
||||
* reported. Units are milliseconds.
|
||||
* @param phy_mask Define on which PHYs connection attempt should
|
||||
* be done
|
||||
* @param phy_1m_conn_params Additional arguments specifying the particulars
|
||||
* of the connect procedure. When
|
||||
* BLE_GAP_LE_PHY_1M_MASK is set in phy_mask
|
||||
* this parameter can be specify to null for
|
||||
* default values.
|
||||
* @param phy_2m_conn_params Additional arguments specifying the particulars
|
||||
* of the connect procedure. When
|
||||
* BLE_GAP_LE_PHY_2M_MASK is set in phy_mask
|
||||
* this parameter can be specify to null for
|
||||
* default values.
|
||||
* @param phy_coded_conn_params Additional arguments specifying the particulars
|
||||
* of the connect procedure. When
|
||||
* BLE_GAP_LE_PHY_CODED_MASK is set in phy_mask
|
||||
* this parameter can be specify to null for
|
||||
* default values.
|
||||
* @param cb The callback to associate with this connect
|
||||
* procedure. When the connect procedure
|
||||
* completes, the result is reported through
|
||||
* this callback. If the connect procedure
|
||||
* succeeds, the connection inherits this
|
||||
* callback as its event-reporting mechanism.
|
||||
* @param cb_arg The optional argument to pass to the callback
|
||||
* function.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* BLE_HS_EALREADY if a connection attempt is
|
||||
* already in progress;
|
||||
* BLE_HS_EBUSY if initiating a connection is not
|
||||
* possible because scanning is in progress;
|
||||
* BLE_HS_EDONE if the specified peer is already
|
||||
* connected;
|
||||
* Other nonzero on error.
|
||||
*/
|
||||
int
|
||||
ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr,
|
||||
int32_t duration_ms, uint8_t phy_mask,
|
||||
const struct ble_gap_conn_params *phy_1m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_2m_conn_params,
|
||||
const struct ble_gap_conn_params *phy_coded_conn_params,
|
||||
ble_gap_event_fn *cb, void *cb_arg)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_ROLE_CENTRAL)
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
|
||||
uint32_t duration_ticks;
|
||||
int rc;
|
||||
|
||||
STATS_INC(ble_gap_stats, initiate);
|
||||
|
||||
ble_hs_lock();
|
||||
|
||||
if (ble_gap_conn_active()) {
|
||||
rc = BLE_HS_EALREADY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ble_gap_disc_active()) {
|
||||
rc = BLE_HS_EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!ble_hs_conn_can_alloc()) {
|
||||
rc = BLE_HS_ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (peer_addr &&
|
||||
peer_addr->type != BLE_ADDR_PUBLIC &&
|
||||
peer_addr->type != BLE_ADDR_RANDOM &&
|
||||
peer_addr->type != BLE_ADDR_PUBLIC_ID &&
|
||||
peer_addr->type != BLE_ADDR_RANDOM_ID) {
|
||||
|
||||
rc = BLE_HS_EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((phy_mask & BLE_GAP_LE_PHY_1M_MASK) && phy_1m_conn_params == NULL) {
|
||||
phy_1m_conn_params = &ble_gap_conn_params_dflt;
|
||||
}
|
||||
|
||||
if ((phy_mask & BLE_GAP_LE_PHY_2M_MASK) && phy_2m_conn_params == NULL) {
|
||||
phy_2m_conn_params = &ble_gap_conn_params_dflt;
|
||||
}
|
||||
|
||||
if ((phy_mask & BLE_GAP_LE_PHY_CODED_MASK) && phy_coded_conn_params == NULL) {
|
||||
phy_coded_conn_params = &ble_gap_conn_params_dflt;
|
||||
}
|
||||
|
||||
if (duration_ms == 0) {
|
||||
duration_ms = BLE_GAP_CONN_DUR_DFLT;
|
||||
}
|
||||
|
||||
if (duration_ms != BLE_HS_FOREVER) {
|
||||
rc = os_time_ms_to_ticks(duration_ms, &duration_ticks);
|
||||
if (rc != 0) {
|
||||
/* Duration too great. */
|
||||
rc = BLE_HS_EINVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify peer not already connected. */
|
||||
if (ble_hs_conn_find_by_addr(peer_addr) != NULL) {
|
||||
rc = BLE_HS_EDONE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* XXX: Verify conn_params. */
|
||||
|
||||
rc = ble_hs_id_use_addr(own_addr_type);
|
||||
if (rc != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ble_gap_master.cb = cb;
|
||||
ble_gap_master.cb_arg = cb_arg;
|
||||
ble_gap_master.conn.using_wl = peer_addr == NULL;
|
||||
ble_gap_master.conn.our_addr_type = own_addr_type;
|
||||
|
||||
ble_gap_master.op = BLE_GAP_OP_M_CONN;
|
||||
|
||||
rc = ble_gap_ext_conn_create_tx(own_addr_type, peer_addr, phy_mask,
|
||||
phy_1m_conn_params, phy_2m_conn_params,
|
||||
phy_coded_conn_params);
|
||||
if (rc != 0) {
|
||||
ble_gap_master_reset_state();
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (duration_ms != BLE_HS_FOREVER) {
|
||||
ble_gap_master_set_timer(duration_ticks);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
done:
|
||||
ble_hs_unlock();
|
||||
|
||||
if (rc != 0) {
|
||||
STATS_INC(ble_gap_stats, initiate_fail);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initiates a connect procedure.
|
||||
*
|
||||
|
||||
@@ -215,6 +215,9 @@ int ble_hs_hci_cmd_build_le_set_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
|
||||
uint8_t rx_phys_mask, uint16_t phy_opts,
|
||||
uint8_t *dst, int dst_len);
|
||||
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user