Bluetooth: Add delay before sending Connection Update
BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] page 368: "The Peripheral device should not perform a Connection Parameter Update procedure within T GAP (conn_pause_peripheral) after establishing a connection." > HCI Event: LE Meta Event (0x3e) plen 19 [hci1] 11:14:22.496358 LE Connection Complete (0x01) Status: Success (0x00) Handle: 74 Role: Slave (0x01) Peer address type: Public (0x00) Peer address: 7C:7A:91:18:82:46 (Intel Corporate) Connection interval: 70.00 msec (0x0038) Connection latency: 0.00 msec (0x0000) Supervision timeout: 420 msec (0x002a) Master clock accuracy: 0x01 ...[5 seconds interval]... < ACL Data TX: Handle 74 flags 0x00 dlen 16 [hci1] 11:14:27.493541 LE L2CAP: Connection Parameter Update Request (0x12) ident 1 len 8 Min interval: 24 Max interval: 40 Slave latency: 0 Timeout multiplier: 42 Change-Id: Ibb301ea00c127542ba299ad0b94825ad1ed05c5c Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
372a8905d5
commit
562b491182
3 changed files with 41 additions and 10 deletions
|
@ -136,6 +136,21 @@ void notify_le_param_updated(struct bt_conn *conn)
|
|||
}
|
||||
}
|
||||
|
||||
static void le_conn_update(struct nano_work *work)
|
||||
{
|
||||
struct bt_conn_le *le = CONTAINER_OF(work, struct bt_conn_le,
|
||||
update_work);
|
||||
struct bt_conn *conn = CONTAINER_OF(le, struct bt_conn, le);
|
||||
const struct bt_le_conn_param *param;
|
||||
|
||||
param = BT_LE_CONN_PARAM(conn->le.interval_min,
|
||||
conn->le.interval_max,
|
||||
conn->le.latency,
|
||||
conn->le.timeout);
|
||||
|
||||
bt_conn_le_param_update(conn, param);
|
||||
}
|
||||
|
||||
static struct bt_conn *conn_new(void)
|
||||
{
|
||||
struct bt_conn *conn = NULL;
|
||||
|
@ -1005,6 +1020,7 @@ struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer)
|
|||
conn->type = BT_CONN_TYPE_LE;
|
||||
conn->le.interval_min = BT_GAP_INIT_CONN_INT_MIN;
|
||||
conn->le.interval_max = BT_GAP_INIT_CONN_INT_MAX;
|
||||
nano_delayed_work_init(&conn->le.update_work, le_conn_update);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
@ -1086,6 +1102,10 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
|
|||
notify_connected(conn);
|
||||
}
|
||||
|
||||
/* Cancel Connection Update if it is pending */
|
||||
if (conn->type == BT_CONN_TYPE_LE)
|
||||
nano_delayed_work_cancel(&conn->le.update_work);
|
||||
|
||||
/* Release the reference we took for the very first
|
||||
* state transition.
|
||||
*/
|
||||
|
@ -1289,6 +1309,9 @@ int bt_conn_le_param_update(struct bt_conn *conn,
|
|||
return -EALREADY;
|
||||
}
|
||||
|
||||
/* Cancel any pending update */
|
||||
nano_delayed_work_cancel(&conn->le.update_work);
|
||||
|
||||
if ((conn->role == BT_HCI_ROLE_SLAVE) &&
|
||||
!(bt_dev.le.features[0] & BT_HCI_LE_CONN_PARAM_REQ_PROC)) {
|
||||
return bt_l2cap_update_conn_param(conn, param);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Intel Corporation
|
||||
* Copyright (c) 2015 Intel Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,6 +17,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <misc/nano_work.h>
|
||||
|
||||
typedef enum __packed {
|
||||
BT_CONN_DISCONNECTED,
|
||||
|
@ -50,6 +51,9 @@ struct bt_conn_le {
|
|||
uint16_t timeout;
|
||||
|
||||
uint8_t features[8];
|
||||
|
||||
/* Delayed work for connection update handling */
|
||||
struct nano_delayed_work update_work;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
|
@ -135,7 +139,7 @@ void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey);
|
|||
/* Look up an existing connection */
|
||||
struct bt_conn *bt_conn_lookup_handle(uint16_t handle);
|
||||
|
||||
/* Look up a connection state. For NULL peer, returns the first connection
|
||||
/* Look up a connection state. For BT_ADDR_LE_ANY, returns the first connection
|
||||
* with the specific state
|
||||
*/
|
||||
struct bt_conn *bt_conn_lookup_state_le(const bt_addr_le_t *peer,
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
#define BT_DBG(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
||||
#define CONN_UPDATE_TIMEOUT (5 * sys_clock_ticks_per_sec)
|
||||
|
||||
/* Stacks for the fibers */
|
||||
static BT_STACK_NOINIT(rx_fiber_stack, CONFIG_BLUETOOTH_RX_STACK_SIZE);
|
||||
static BT_STACK_NOINIT(cmd_tx_fiber_stack, 256);
|
||||
|
@ -590,15 +593,16 @@ static int hci_le_read_remote_features(struct bt_conn *conn)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int update_conn_param(struct bt_conn *conn)
|
||||
static void update_conn_param(struct bt_conn *conn)
|
||||
{
|
||||
const struct bt_le_conn_param *param;
|
||||
|
||||
param = BT_LE_CONN_PARAM(conn->le.interval_min,
|
||||
conn->le.interval_max,
|
||||
conn->le.latency,
|
||||
conn->le.timeout);
|
||||
return bt_conn_le_param_update(conn, param);
|
||||
/*
|
||||
* Core 4.2 Vol 3, Part C, 9.3.12.2
|
||||
* The Peripheral device should not perform a Connection Parameter
|
||||
* Update procedure within 5 s after establishing a connection.
|
||||
*/
|
||||
nano_delayed_work_submit(&conn->le.update_work,
|
||||
conn->role == BT_HCI_ROLE_MASTER ? TICKS_NONE :
|
||||
CONN_UPDATE_TIMEOUT);
|
||||
}
|
||||
|
||||
static void le_conn_complete(struct net_buf *buf)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue