Skip to content

Commit

Permalink
Bluetooth: host: Fallback to L2CAP for CPUP if rejected by master on LL
Browse files Browse the repository at this point in the history
Fallback to L2CAP Connection Parameters Update Request if LL Connection
Update Request was rejected by remote device that has this marked as
supported in features. This can happen if procedure is supported only
by remote controller, but not enabled by host. This is connection
parameters update with iOS devices.

Signed-off-by: Szymon Janc <[email protected]>
  • Loading branch information
sjanc authored and nashif committed Nov 6, 2018
1 parent 22236c9 commit b697901
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 10 deletions.
29 changes: 19 additions & 10 deletions subsys/bluetooth/host/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,20 @@ static int send_conn_le_param_update(struct bt_conn *conn,
* it; or if local role is master then use LE connection update.
*/
if ((BT_FEAT_LE_CONN_PARAM_REQ_PROC(bt_dev.le.features) &&
BT_FEAT_LE_CONN_PARAM_REQ_PROC(conn->le.features)) ||
(conn->role == BT_HCI_ROLE_MASTER)) {
return bt_conn_le_conn_update(conn, param);
BT_FEAT_LE_CONN_PARAM_REQ_PROC(conn->le.features) &&
!atomic_test_bit(conn->flags, BT_CONN_SLAVE_PARAM_L2CAP)) ||
(conn->role == BT_HCI_ROLE_MASTER)) {
int rc;

rc = bt_conn_le_conn_update(conn, param);

/* store those in case of fallback to L2CAP */
if (rc == 0) {
conn->le.pending_latency = param->latency;
conn->le.pending_timeout = param->timeout;
}

return rc;
}

/* If remote master does not support LL Connection Parameters Request
Expand Down Expand Up @@ -237,8 +248,8 @@ static void conn_le_update_timeout(struct k_work *work)
if (atomic_test_and_clear_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET)) {
param = BT_LE_CONN_PARAM(conn->le.interval_min,
conn->le.interval_max,
conn->le.latency,
conn->le.timeout);
conn->le.pending_latency,
conn->le.pending_timeout);

send_conn_le_param_update(conn, param);
} else {
Expand Down Expand Up @@ -1814,13 +1825,11 @@ int bt_conn_le_param_update(struct bt_conn *conn,
return send_conn_le_param_update(conn, param);
}

/* store new conn params to be used by update timer
* TODO this overwrites current latency and timeout
*/
/* store new conn params to be used by update timer */
conn->le.interval_min = param->interval_min;
conn->le.interval_max = param->interval_max;
conn->le.latency = param->latency;
conn->le.timeout = param->timeout;
conn->le.pending_latency = param->latency;
conn->le.pending_timeout = param->timeout;
atomic_set_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET);
}

Expand Down
3 changes: 3 additions & 0 deletions subsys/bluetooth/host/conn_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum {
BT_CONN_AUTO_DATA_LEN, /* Auto data len change in progress */
BT_CONN_SLAVE_PARAM_UPDATE, /* If slave param update timer fired */
BT_CONN_SLAVE_PARAM_SET, /* If slave param were set from app */
BT_CONN_SLAVE_PARAM_L2CAP, /* If should force L2CAP for CPUP */

/* Total number of flags - must be at the end of the enum */
BT_CONN_NUM_FLAGS,
Expand All @@ -46,6 +47,8 @@ struct bt_conn_le {

u16_t latency;
u16_t timeout;
u16_t pending_latency;
u16_t pending_timeout;

u8_t features[8];

Expand Down
12 changes: 12 additions & 0 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,18 @@ static void le_conn_update_complete(struct net_buf *buf)
conn->le.latency = sys_le16_to_cpu(evt->latency);
conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout);
notify_le_param_updated(conn);
} else if (evt->status == BT_HCI_ERR_UNSUPP_REMOTE_FEATURE &&
conn->role == BT_HCI_ROLE_SLAVE &&
!atomic_test_and_set_bit(conn->flags,
BT_CONN_SLAVE_PARAM_L2CAP)) {
struct bt_le_conn_param param;

param.interval_min = conn->le.interval_min;
param.interval_max = conn->le.interval_max;
param.latency = conn->le.pending_latency;
param.timeout = conn->le.pending_timeout;

bt_l2cap_update_conn_param(conn, &param);
}

bt_conn_unref(conn);
Expand Down

0 comments on commit b697901

Please sign in to comment.