Bluetooth: Initiate LE Exchange Remote Features

Adds host bits to initiate LL LE Exchange Feature procedure if
supported. Both the master and slave can initate it for controllers
newer than 4.0. For 4.0 controllers only master can do that.
Inform upper stack layers of the slave about the connection is ready
to use only when LE Exchange Feature isn't supported. Otherwise
upper layers shall be notified about new connection when Connection
Parameters Update procedure is finished.

Change-Id: Ief29744e498873f79fc6f62f98c083fecaeae24e
Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
Signed-off-by: Mariusz Skamra <mariusz.skamra@tieto.com>
This commit is contained in:
Arkadiusz Lichwa 2015-07-27 17:28:59 +03:00 committed by Anas Nashif
commit d3dc91e73a
2 changed files with 36 additions and 3 deletions

View file

@ -728,12 +728,31 @@ static void hci_disconn_complete(struct bt_buf *buf)
}
}
static int hci_le_read_remote_features(struct bt_conn *conn)
{
struct bt_hci_cp_le_read_remote_features *cp;
struct bt_buf *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_READ_REMOTE_FEATURES,
sizeof(*cp));
if (!buf) {
return -ENOBUFS;
}
cp = bt_buf_add(buf, sizeof(*cp));
cp->handle = sys_cpu_to_le16(conn->handle);
bt_hci_cmd_send(BT_HCI_OP_LE_READ_REMOTE_FEATURES, buf);
return 0;
}
static void le_conn_complete(struct bt_buf *buf)
{
struct bt_hci_evt_le_conn_complete *evt = (void *)buf->data;
uint16_t handle = sys_le16_to_cpu(evt->handle);
struct bt_conn *conn;
struct bt_keys *keys;
int err;
BT_DBG("status %u handle %u role %u %s\n", evt->status, handle,
evt->role, bt_addr_le_str(&evt->peer_addr));
@ -781,12 +800,22 @@ static void le_conn_complete(struct bt_buf *buf)
bt_conn_set_state(conn, BT_CONN_CONNECTED);
if ((evt->role == BT_HCI_ROLE_SLAVE) &&
!(bt_dev.le_features[0] & BT_HCI_LE_CONN_PARAM_REQ_PROC)) {
bt_l2cap_update_conn_param(conn);
if ((evt->role == BT_HCI_ROLE_MASTER) ||
(bt_dev.le_features[0] & BT_HCI_LE_SLAVE_FEATURES)) {
err = hci_le_read_remote_features(conn);
if (!err) {
goto done;
}
} else if (!(bt_dev.le_features[0] & BT_HCI_LE_CONN_PARAM_REQ_PROC)) {
err = bt_l2cap_update_conn_param(conn);
if (!err) {
goto done;
}
}
bt_conn_connected(conn);
done:
bt_conn_put(conn);
bt_le_scan_update();
}
@ -808,6 +837,8 @@ static void le_remote_feat_complete(struct bt_buf *buf)
sizeof(conn->le_features));
}
/* TODO Update connection parameters or notify about connection */
bt_conn_put(conn);
}

View file

@ -167,6 +167,8 @@ static void le_conn_param_rsp(struct bt_conn *conn, struct bt_buf *buf)
}
BT_DBG("LE conn param rsp result %u\n", sys_le16_to_cpu(rsp->result));
bt_conn_connected(conn);
}
static uint16_t le_validate_conn_params(uint16_t min, uint16_t max,