Bluetooth: Fix reporting packets for disconnected connections
A connection might have gotten disconnected by the time that an ACL buffer is free up, in which case there is no need to send a HCI command for it. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
a73d3737f1
commit
c136a2eb83
3 changed files with 53 additions and 0 deletions
|
@ -2060,6 +2060,28 @@ int bt_conn_auth_pairing_confirm(struct bt_conn *conn)
|
|||
}
|
||||
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
|
||||
|
||||
u8_t bt_conn_get_id(struct bt_conn *conn)
|
||||
{
|
||||
return conn - conns;
|
||||
}
|
||||
|
||||
struct bt_conn *bt_conn_lookup_id(u8_t id)
|
||||
{
|
||||
struct bt_conn *conn;
|
||||
|
||||
if (id >= ARRAY_SIZE(conns)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn = &conns[id];
|
||||
|
||||
if (!atomic_get(&conn->ref)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bt_conn_ref(conn);
|
||||
}
|
||||
|
||||
int bt_conn_init(void)
|
||||
{
|
||||
int err, i;
|
||||
|
|
|
@ -167,6 +167,15 @@ struct bt_conn *bt_conn_lookup_handle(u16_t handle);
|
|||
/* Compare an address with bt_conn destination address */
|
||||
int bt_conn_addr_le_cmp(const struct bt_conn *conn, const bt_addr_le_t *peer);
|
||||
|
||||
|
||||
/* Helpers for identifying & looking up connections based on the the index to
|
||||
* the connection list. This is useful for O(1) lookups, but can't be used
|
||||
* e.g. as the handle since that's assigned to us by the controller.
|
||||
*/
|
||||
#define BT_CONN_ID_INVALID 0xff
|
||||
u8_t bt_conn_get_id(struct bt_conn *conn);
|
||||
struct bt_conn *bt_conn_lookup_id(u8_t id);
|
||||
|
||||
/* Look up a connection state. For BT_ADDR_LE_ANY, returns the first connection
|
||||
* with the specific state
|
||||
*/
|
||||
|
|
|
@ -109,6 +109,9 @@ struct acl_data {
|
|||
/** BT_BUF_ACL_IN */
|
||||
u8_t type;
|
||||
|
||||
/* Index into the bt_conn storage array */
|
||||
u8_t id;
|
||||
|
||||
/** ACL connection handle */
|
||||
u16_t handle;
|
||||
};
|
||||
|
@ -133,6 +136,7 @@ static void report_completed_packet(struct net_buf *buf)
|
|||
struct bt_hci_cp_host_num_completed_packets *cp;
|
||||
u16_t handle = acl(buf)->handle;
|
||||
struct bt_hci_handle_count *hc;
|
||||
struct bt_conn *conn;
|
||||
|
||||
net_buf_destroy(buf);
|
||||
|
||||
|
@ -141,6 +145,21 @@ static void report_completed_packet(struct net_buf *buf)
|
|||
return;
|
||||
}
|
||||
|
||||
conn = bt_conn_lookup_id(acl(buf)->id);
|
||||
if (!conn) {
|
||||
BT_WARN("Unable to look up conn with id 0x%02x", acl(buf)->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (conn->state != BT_CONN_CONNECTED &&
|
||||
conn->state != BT_CONN_DISCONNECT) {
|
||||
BT_WARN("Not reporting packet for non-connected conn");
|
||||
bt_conn_unref(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
bt_conn_unref(conn);
|
||||
|
||||
BT_DBG("Reporting completed packet for handle %u", handle);
|
||||
|
||||
buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS,
|
||||
|
@ -458,6 +477,7 @@ static void hci_acl(struct net_buf *buf)
|
|||
flags = bt_acl_flags(handle);
|
||||
|
||||
acl(buf)->handle = bt_acl_handle(handle);
|
||||
acl(buf)->id = BT_CONN_ID_INVALID;
|
||||
|
||||
net_buf_pull(buf, sizeof(*hdr));
|
||||
|
||||
|
@ -476,6 +496,8 @@ static void hci_acl(struct net_buf *buf)
|
|||
return;
|
||||
}
|
||||
|
||||
acl(buf)->id = bt_conn_get_id(conn);
|
||||
|
||||
bt_conn_recv(conn, buf, flags);
|
||||
bt_conn_unref(conn);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue