Skip to content

nimble/host: Rework L2CAP RX #2022

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions nimble/host/src/ble_att.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ ble_att_rx_extended(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om)
}

static int
ble_att_rx(struct ble_l2cap_chan *chan)
ble_att_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om)
{
uint16_t conn_handle;

Expand All @@ -572,7 +572,7 @@ ble_att_rx(struct ble_l2cap_chan *chan)
return BLE_HS_ENOTCONN;
}

return ble_att_rx_extended(conn_handle, chan->scid, &chan->rx_buf);
return ble_att_rx_extended(conn_handle, chan->scid, om);
}

uint16_t
Expand Down
11 changes: 5 additions & 6 deletions nimble/host/src/ble_hs_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,6 @@ ble_hs_conn_alloc(uint16_t conn_handle)
void
ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
{
if (conn->bhc_rx_chan == chan) {
conn->bhc_rx_chan = NULL;
}

SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, next);
ble_l2cap_chan_free(conn, chan);
}
Expand Down Expand Up @@ -244,6 +240,9 @@ ble_hs_conn_free(struct ble_hs_conn *conn)
return;
}

os_mbuf_free_chain(conn->rx_frags);
conn->rx_frags = NULL;

ble_att_svr_prep_clear(&conn->bhc_att_svr.basc_prep_list);

while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) {
Expand Down Expand Up @@ -504,8 +503,8 @@ ble_hs_conn_timer(void)
* passes after a partial packet is received, the connection is
* terminated.
*/
if (conn->bhc_rx_chan != NULL) {
time_diff = conn->bhc_rx_timeout - now;
if (conn->rx_len) {
time_diff = conn->rx_frag_tmo - now;

if (time_diff <= 0) {
/* ACL reassembly has timed out.*/
Expand Down
14 changes: 12 additions & 2 deletions nimble/host/src/ble_hs_conn_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,18 @@ struct ble_hs_conn {
ble_hs_conn_flags_t bhc_flags;

struct ble_l2cap_chan_list bhc_channels;
struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */
ble_npl_time_t bhc_rx_timeout;

/* ACL RX fragments */
struct os_mbuf *rx_frags;
/* Expected data length for ACL RX */
uint16_t rx_len;
/* L2CAP Source CID for ACL RX */
uint16_t rx_cid;
#if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0
/* Timeout for next fragment for ACL RX */
ble_npl_time_t rx_frag_tmo;
#endif

#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
uint32_t l2cap_coc_cid_mask[BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN];
#endif
Expand Down
51 changes: 7 additions & 44 deletions nimble/host/src/ble_hs_hci_evt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,15 +1098,14 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
{
#if NIMBLE_BLE_CONNECT
struct hci_data_hdr hci_hdr;
struct ble_hs_conn *conn;
ble_l2cap_rx_fn *rx_cb;
uint16_t conn_handle;
int reject_cid;
uint8_t pb;
int rc;

rc = ble_hs_hci_util_data_hdr_strip(om, &hci_hdr);
if (rc != 0) {
goto err;
os_mbuf_free_chain(om);
return rc;
}

#if (BLETEST_THROUGHPUT_TEST == 0)
Expand All @@ -1122,50 +1121,14 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
#endif

if (hci_hdr.hdh_len != OS_MBUF_PKTHDR(om)->omp_len) {
rc = BLE_HS_EBADDATA;
goto err;
os_mbuf_free_chain(om);
return BLE_HS_EBADDATA;
}

conn_handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc);
pb = BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc);
rc = ble_l2cap_rx(conn_handle, pb, om);

ble_hs_lock();

conn = ble_hs_conn_find(conn_handle);
if (conn == NULL) {
/* Peer not connected; quietly discard packet. */
rc = BLE_HS_ENOTCONN;
reject_cid = -1;
} else {
/* Forward ACL data to L2CAP. */
rc = ble_l2cap_rx(conn, &hci_hdr, om, &rx_cb, &reject_cid);
om = NULL;
}

ble_hs_unlock();

switch (rc) {
case 0:
/* Final fragment received. */
BLE_HS_DBG_ASSERT(rx_cb != NULL);
rc = rx_cb(conn->bhc_rx_chan);
ble_l2cap_remove_rx(conn, conn->bhc_rx_chan);
break;

case BLE_HS_EAGAIN:
/* More fragments on the way. */
break;

default:
if (reject_cid != -1) {
ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid);
}
goto err;
}

return 0;

err:
os_mbuf_free_chain(om);
return rc;
#else
return BLE_HS_ENOTSUP;
Expand Down
Loading
Loading