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 */
|
#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 bt_conn_init(void)
|
||||||
{
|
{
|
||||||
int err, i;
|
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 */
|
/* 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);
|
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
|
/* Look up a connection state. For BT_ADDR_LE_ANY, returns the first connection
|
||||||
* with the specific state
|
* with the specific state
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -109,6 +109,9 @@ struct acl_data {
|
||||||
/** BT_BUF_ACL_IN */
|
/** BT_BUF_ACL_IN */
|
||||||
u8_t type;
|
u8_t type;
|
||||||
|
|
||||||
|
/* Index into the bt_conn storage array */
|
||||||
|
u8_t id;
|
||||||
|
|
||||||
/** ACL connection handle */
|
/** ACL connection handle */
|
||||||
u16_t 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;
|
struct bt_hci_cp_host_num_completed_packets *cp;
|
||||||
u16_t handle = acl(buf)->handle;
|
u16_t handle = acl(buf)->handle;
|
||||||
struct bt_hci_handle_count *hc;
|
struct bt_hci_handle_count *hc;
|
||||||
|
struct bt_conn *conn;
|
||||||
|
|
||||||
net_buf_destroy(buf);
|
net_buf_destroy(buf);
|
||||||
|
|
||||||
|
@ -141,6 +145,21 @@ static void report_completed_packet(struct net_buf *buf)
|
||||||
return;
|
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);
|
BT_DBG("Reporting completed packet for handle %u", handle);
|
||||||
|
|
||||||
buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS,
|
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);
|
flags = bt_acl_flags(handle);
|
||||||
|
|
||||||
acl(buf)->handle = bt_acl_handle(handle);
|
acl(buf)->handle = bt_acl_handle(handle);
|
||||||
|
acl(buf)->id = BT_CONN_ID_INVALID;
|
||||||
|
|
||||||
net_buf_pull(buf, sizeof(*hdr));
|
net_buf_pull(buf, sizeof(*hdr));
|
||||||
|
|
||||||
|
@ -476,6 +496,8 @@ static void hci_acl(struct net_buf *buf)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acl(buf)->id = bt_conn_get_id(conn);
|
||||||
|
|
||||||
bt_conn_recv(conn, buf, flags);
|
bt_conn_recv(conn, buf, flags);
|
||||||
bt_conn_unref(conn);
|
bt_conn_unref(conn);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue