Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions subsys/bluetooth/host/classic/conn_br.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,30 @@ const bt_addr_t *bt_conn_get_dst_br(const struct bt_conn *conn)

return &conn->br.dst;
}

void bt_br_acl_recv(struct bt_conn *conn, struct net_buf *buf, bool complete)
{
uint16_t acl_total_len;
struct bt_l2cap_hdr *hdr;
struct net_buf_simple_state state;

do {
net_buf_simple_save(&buf->b, &state);

hdr = (void *)buf->data;
acl_total_len = sys_le16_to_cpu(hdr->len) + sizeof(*hdr);
if (buf->len > acl_total_len) {
LOG_DBG("Multiple L2CAP packet (%u > %u)", buf->len, acl_total_len);
buf->len = acl_total_len;
} else if (buf->len < acl_total_len) {
LOG_ERR("Short packet (%u < %u)", buf->len, acl_total_len);
break;
}
bt_l2cap_recv(conn, net_buf_ref(buf), complete);

net_buf_simple_restore(&buf->b, &state);
net_buf_pull(buf, acl_total_len);
} while (buf->len > 0);

net_buf_unref(buf);
}
2 changes: 2 additions & 0 deletions subsys/bluetooth/host/classic/conn_br_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
*/

int bt_hci_connect_br_cancel(struct bt_conn *conn);

void bt_br_acl_recv(struct bt_conn *conn, struct net_buf *buf, bool complete);
28 changes: 10 additions & 18 deletions subsys/bluetooth/host/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,12 +388,11 @@
conn->rx = NULL;
}

static void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
static void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf,
uint8_t flags)
{

Check notice on line 393 in subsys/bluetooth/host/conn.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/conn.c:393 -static void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf, - uint8_t flags) +static void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
uint16_t acl_total_len;

bt_acl_set_ncp_sent(buf, false);

/* Check packet boundary flags */
switch (flags) {
case BT_ACL_START:
Expand All @@ -405,7 +404,7 @@
LOG_DBG("First, len %u final %u", buf->len,
(buf->len < sizeof(uint16_t)) ? 0 : sys_get_le16(buf->data));

conn->rx = net_buf_ref(buf);
conn->rx = buf;
break;
case BT_ACL_CONT:
if (!conn->rx) {
Expand Down Expand Up @@ -435,6 +434,7 @@
}

net_buf_add_mem(conn->rx, buf->data, buf->len);
net_buf_unref(buf);
break;
default:
/* BT_ACL_START_NO_FLUSH and BT_ACL_COMPLETE are not allowed on
Expand All @@ -451,27 +451,17 @@
/* Still not enough data received to retrieve the L2CAP header
* length field.
*/
bt_send_one_host_num_completed_packets(conn->handle);
bt_acl_set_ncp_sent(buf, true);
net_buf_unref(buf);

return;
}

acl_total_len = sys_get_le16(conn->rx->data) + sizeof(struct bt_l2cap_hdr);

if (conn->rx->len < acl_total_len) {
/* L2CAP frame not complete. */
bt_send_one_host_num_completed_packets(conn->handle);
bt_acl_set_ncp_sent(buf, true);
net_buf_unref(buf);

return;
}

net_buf_unref(buf);

if (conn->rx->len > acl_total_len) {
if ((conn->type != BT_CONN_TYPE_BR) && (conn->rx->len > acl_total_len)) {
LOG_ERR("ACL len mismatch (%u > %u)", conn->rx->len, acl_total_len);
bt_conn_reset_rx_state(conn);
return;
Expand All @@ -481,10 +471,12 @@
buf = conn->rx;
conn->rx = NULL;

__ASSERT(buf->ref == 1, "buf->ref %d", buf->ref);

LOG_DBG("Successfully parsed %u byte L2CAP packet", buf->len);
bt_l2cap_recv(conn, buf, true);
if (IS_ENABLED(CONFIG_BT_CLASSIC) && (conn->type == BT_CONN_TYPE_BR)) {
bt_br_acl_recv(conn, buf, true);
} else {
bt_l2cap_recv(conn, buf, true);
}
}

void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags)
Expand Down
7 changes: 1 addition & 6 deletions subsys/bluetooth/host/conn_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,8 @@
struct bt_buf_data buf_data;

/* Index into the bt_conn storage array */
uint8_t index;

/** Host has already sent a Host Number of Completed Packets
* for this buffer.
*/
bool host_ncp_sent;
uint8_t index;

Check notice on line 217 in subsys/bluetooth/host/conn_internal.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/conn_internal.h:217 - uint8_t index; + uint8_t index;
/** ACL connection handle */
uint16_t handle;
};
Expand Down
29 changes: 19 additions & 10 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,6 @@
/* Other possible errors are handled by handle_event_common function */
}

void bt_acl_set_ncp_sent(struct net_buf *packet, bool value)
{
acl(packet)->host_ncp_sent = value;
}

void bt_send_one_host_num_completed_packets(uint16_t handle)
{
if (!IS_ENABLED(CONFIG_BT_HCI_ACL_FLOW_CONTROL)) {
Expand Down Expand Up @@ -278,7 +273,9 @@
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
void bt_hci_host_num_completed_packets(struct net_buf *buf)
{
struct bt_hci_cp_host_num_completed_packets *cp;
uint16_t handle = acl(buf)->handle;
struct bt_hci_handle_count *hc;
struct bt_conn *conn;
uint8_t index = acl(buf)->index;

Expand All @@ -288,10 +285,6 @@

net_buf_destroy(buf);

if (acl(buf)->host_ncp_sent) {
return;
}

/* Do nothing if controller to host flow control is not supported */
if (!BT_CMD_TEST(bt_dev.supported_commands, 10, 5)) {
return;
Expand All @@ -312,7 +305,23 @@

bt_conn_unref(conn);

bt_send_one_host_num_completed_packets(handle);
LOG_DBG("Reporting completed packet for handle %u", handle);

buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS,
sizeof(*cp) + sizeof(*hc));
if (!buf) {

Check notice on line 312 in subsys/bluetooth/host/hci_core.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/hci_core.c:312 - buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, - sizeof(*cp) + sizeof(*hc)); + buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, sizeof(*cp) + sizeof(*hc));
LOG_ERR("Unable to allocate new HCI command");
return;
}

cp = net_buf_add(buf, sizeof(*cp));
cp->num_handles = sys_cpu_to_le16(1);

hc = net_buf_add(buf, sizeof(*hc));
hc->handle = sys_cpu_to_le16(handle);
hc->count = sys_cpu_to_le16(1);

Check notice on line 323 in subsys/bluetooth/host/hci_core.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/hci_core.c:323 - hc->count = sys_cpu_to_le16(1); + hc->count = sys_cpu_to_le16(1);
bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
}
#endif /* defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL) */

Expand Down
2 changes: 0 additions & 2 deletions subsys/bluetooth/host/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,5 +582,3 @@ int bt_hci_le_read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time);
bool bt_drv_quirk_no_auto_dle(void);

void bt_tx_irq_raise(void);
void bt_send_one_host_num_completed_packets(uint16_t handle);
void bt_acl_set_ncp_sent(struct net_buf *packet, bool value);
Loading