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:
Łukasz Rymanowski
2017-06-28 22:48:28 +02:00
parent 30eb800cbe
commit 3a0e8f86ed
3 changed files with 245 additions and 0 deletions
+6
View File
@@ -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);
+236
View File
@@ -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.
*
+3
View File
@@ -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