diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 471f6cab97..3dddd878f7 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -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; @@ -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 diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index 1e83d33de2..ba034a2703 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -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); } @@ -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) { @@ -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.*/ diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h index 31e831c878..19b1d37524 100644 --- a/nimble/host/src/ble_hs_conn_priv.h +++ b/nimble/host/src/ble_hs_conn_priv.h @@ -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 diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 47430423be..89a1f193f1 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -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) @@ -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; diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index 2b979e9181..4bd30d0976 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -80,7 +80,6 @@ ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) return; } - os_mbuf_free_chain(chan->rx_buf); ble_l2cap_coc_cleanup_chan(conn, chan); #if MYNEWT_VAL(BLE_HS_DEBUG) @@ -99,18 +98,17 @@ ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan) } int -ble_l2cap_parse_hdr(struct os_mbuf *om, int off, - struct ble_l2cap_hdr *l2cap_hdr) +ble_l2cap_parse_hdr(struct os_mbuf *om, struct ble_l2cap_hdr *hdr) { int rc; - rc = os_mbuf_copydata(om, off, sizeof *l2cap_hdr, l2cap_hdr); + rc = os_mbuf_copydata(om, 0, sizeof(*hdr), hdr); if (rc != 0) { return BLE_HS_EMSGSIZE; } - l2cap_hdr->len = get_le16(&l2cap_hdr->len); - l2cap_hdr->cid = get_le16(&l2cap_hdr->cid); + hdr->len = get_le16(&hdr->len); + hdr->cid = get_le16(&hdr->cid); return 0; } @@ -233,212 +231,168 @@ ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) return ble_l2cap_coc_recv_ready(chan, sdu_rx); } -void -ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) +static uint16_t +ble_l2cap_get_mtu(struct ble_l2cap_chan *chan) { - conn->bhc_rx_chan = NULL; - os_mbuf_free_chain(chan->rx_buf); - chan->rx_buf = NULL; - chan->rx_len = 0; + if (chan->scid == BLE_L2CAP_CID_ATT) { + /* In case of ATT chan->my_mtu keeps preferred MTU which is later + * used during exchange MTU procedure. Helper below will gives us actual + * MTU on the channel, which is 23 or higher if exchange MTU has been + * done + */ + return ble_att_chan_mtu(chan); + } + + return chan->my_mtu; } static void -ble_l2cap_append_rx(struct ble_l2cap_chan *chan, struct os_mbuf *frag) +ble_l2cap_rx_free(struct ble_hs_conn *conn) { -#if MYNEWT_VAL(BLE_L2CAP_JOIN_RX_FRAGS) - struct os_mbuf *m; - - /* Copy the data from the incoming fragment into the packet in progress. */ - m = os_mbuf_pack_chains(chan->rx_buf, frag); - assert(m); -#else - /* Join disabled or append failed due to mbuf shortage. Just attach the - * mbuf to the end of the packet. - */ - os_mbuf_concat(chan->rx_buf, frag); -#endif + os_mbuf_free_chain(conn->rx_frags); + conn->rx_frags = NULL; + conn->rx_len = 0; + conn->rx_cid = 0; } static int -ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, - struct os_mbuf *om, - ble_l2cap_rx_fn **out_rx_cb) +ble_l2cap_rx_frags_process(struct ble_hs_conn *conn) { - int len_diff; + int rem_rx_len; int rc; - if (chan->rx_buf == NULL) { - /* First fragment in packet. */ - chan->rx_buf = om; - } else { - /* Continuation of packet in progress. */ - ble_l2cap_append_rx(chan, om); - } - - /* Determine if packet is fully reassembled. */ - len_diff = OS_MBUF_PKTLEN(chan->rx_buf) - chan->rx_len; - if (len_diff > 0) { - /* More data than expected; data corruption. */ - ble_l2cap_remove_rx(conn, chan); - rc = BLE_HS_EBADDATA; - } else if (len_diff == 0) { - /* All fragments received. */ - *out_rx_cb = chan->rx_fn; + rem_rx_len = conn->rx_len - OS_MBUF_PKTLEN(conn->rx_frags); + if (rem_rx_len == 0) { rc = 0; - } else { - /* More fragments remain. */ + } else if (rem_rx_len > 0) { #if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0 - conn->bhc_rx_timeout = + conn->rx_frag_tmo = ble_npl_time_get() + MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT); ble_hs_timer_resched(); #endif rc = BLE_HS_EAGAIN; + } else { + ble_l2cap_rx_free(conn); + rc = BLE_HS_EBADDATA; } return rc; } -static uint16_t -ble_l2cap_get_mtu(struct ble_l2cap_chan *chan) -{ - if (chan->scid == BLE_L2CAP_CID_ATT) { - /* In case of ATT chan->my_mtu keeps preferred MTU which is later - * used during exchange MTU procedure. Helper below will gives us actual - * MTU on the channel, which is 23 or higher if exchange MTU has been - * done - */ - return ble_att_chan_mtu(chan); - } - - return chan->my_mtu; -} - -/** - * Processes an incoming L2CAP fragment. - * - * @param conn The connection the L2CAP fragment was sent - * over. - * @param hci_hdr The ACL data header that was at the start of - * the L2CAP fragment. This header has been - * stripped from the mbuf parameter. - * @param om An mbuf containing the L2CAP data. If this is - * the first fragment, the L2CAP header is at - * the start of the mbuf. For subsequent - * fragments, the mbuf starts with L2CAP - * payload data. - * @param out_rx_cb If a full L2CAP packet has been received, a - * pointer to the appropriate handler gets - * written here. The caller should pass the - * receive buffer to this callback. - * @param out_reject_cid Indicates whether an L2CAP Command Reject - * command should be sent. If this equals -1, - * no reject should get sent. Otherwise, the - * value indicates the CID that the outgoing - * reject should specify. - * - * @return 0 if a complete L2CAP packet has been received. - * BLE_HS_EAGAIN if a partial L2CAP packet has - * been received; more fragments are expected. - * Other value on error. - */ int -ble_l2cap_rx(struct ble_hs_conn *conn, - struct hci_data_hdr *hci_hdr, - struct os_mbuf *om, - ble_l2cap_rx_fn **out_rx_cb, - int *out_reject_cid) +ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om) { + struct ble_hs_conn *conn; struct ble_l2cap_chan *chan; - struct ble_l2cap_hdr l2cap_hdr; - uint8_t pb; + struct ble_l2cap_hdr hdr; + struct os_mbuf *rx_frags; + uint16_t rx_len; + uint16_t rx_cid; int rc; - *out_reject_cid = -1; + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + if (!conn) { + /* Invalid connection handle, discard packet */ + os_mbuf_free_chain(om); + rc = BLE_HS_ENOTCONN; + goto done; + } - pb = BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc); switch (pb) { case BLE_HCI_PB_FIRST_FLUSH: - /* First fragment. */ - rc = ble_l2cap_parse_hdr(om, 0, &l2cap_hdr); - if (rc != 0) { - goto err; + if (conn->rx_frags) { + /* Previously received data is incomplete, discard it */ + ble_l2cap_rx_free(conn); } - - /* Strip L2CAP header from the front of the mbuf. */ - os_mbuf_adj(om, BLE_L2CAP_HDR_SZ); - - chan = ble_hs_conn_chan_find_by_scid(conn, l2cap_hdr.cid); - if (chan == NULL) { - rc = BLE_HS_ENOENT; - - /* Unsupported channel. If the target CID is the black hole - * channel, quietly drop the packet. Otherwise, send an invalid - * CID response. + conn->rx_frags = om; + break; + case BLE_HCI_PB_MIDDLE: + if (!conn->rx_frags) { + /* Received continuation without 1st packet, discard it. + * This can also happen if we received invalid data earlier which + * was discarded, so we'll just keep discarding until valid 1st + * packet is received. */ - if (l2cap_hdr.cid != BLE_L2CAP_CID_BLACK_HOLE) { - BLE_HS_LOG(DEBUG, "rx on unknown L2CAP channel: %d\n", - l2cap_hdr.cid); - *out_reject_cid = l2cap_hdr.cid; - } - goto err; - } - - /* For CIDs from dynamic range we check if SDU size isn't larger than MPS */ - if (chan->dcid >= BLE_L2CAP_COC_CID_START && - chan->dcid <= BLE_L2CAP_COC_CID_END && - l2cap_hdr.len > chan->my_coc_mps) { - /* Data exceeds MPS */ - BLE_HS_LOG(ERROR, "error: sdu_len > chan->my_coc_mps (%d>%d)\n", - l2cap_hdr.len, chan->my_coc_mps); - ble_l2cap_disconnect(chan); + os_mbuf_free_chain(om); rc = BLE_HS_EBADDATA; - goto err; + goto done; } - if (chan->rx_buf != NULL) { - /* Previous data packet never completed. Discard old packet. */ - ble_l2cap_remove_rx(conn, chan); - } + /* Append fragment to rx buffer */ +#if MYNEWT_VAL(BLE_L2CAP_JOIN_RX_FRAGS) + os_mbuf_pack_chains(conn->rx_frags, om); +#else + os_mbuf_concat(conn->rx_frag, om); +#endif + break; + default: + /* Invalid PB, discard packet */ + os_mbuf_free_chain(om); + ble_l2cap_rx_free(conn); + rc = BLE_HS_EBADDATA; + goto done; + } - if (l2cap_hdr.len > ble_l2cap_get_mtu(chan)) { - /* More data than we expected on the channel. - * Disconnect peer with invalid behaviour - */ - rc = BLE_HS_EBADDATA; - ble_l2cap_disconnect(chan); - goto err; + /* Parse L2CAP header if not yet done */ + if (!conn->rx_len) { + rc = ble_l2cap_parse_hdr(conn->rx_frags, &hdr); + if (rc) { + /* Incomplete header, wait for continuation */ + rc = BLE_HS_EAGAIN; + goto done; } - /* Remember channel and length of L2CAP data for reassembly. */ - conn->bhc_rx_chan = chan; - chan->rx_len = l2cap_hdr.len; - break; + os_mbuf_adj(conn->rx_frags, BLE_L2CAP_HDR_SZ); - case BLE_HCI_PB_MIDDLE: - chan = conn->bhc_rx_chan; - if (chan == NULL || chan->rx_buf == NULL) { - /* Middle fragment without the start. Discard new packet. */ - rc = BLE_HS_EBADDATA; - goto err; - } - break; + conn->rx_len = hdr.len; + conn->rx_cid = hdr.cid; + } - default: - rc = BLE_HS_EBADDATA; - goto err; + /* Process fragments */ + rc = ble_l2cap_rx_frags_process(conn); + if (rc) { + goto done; } - rc = ble_l2cap_rx_payload(conn, chan, om, out_rx_cb); - om = NULL; - if (rc != 0) { - goto err; + rx_frags = conn->rx_frags; + rx_len = conn->rx_len; + rx_cid = conn->rx_cid; + + conn->rx_frags = NULL; + ble_l2cap_rx_free(conn); + + chan = ble_hs_conn_chan_find_by_scid(conn, rx_cid); + + ble_hs_unlock(); + + if (!chan) { + ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, rx_cid); + return BLE_HS_ENOENT; } - return 0; + if (chan->dcid >= BLE_L2CAP_COC_CID_START && + chan->dcid <= BLE_L2CAP_COC_CID_END && + rx_len > chan->my_coc_mps) { + ble_l2cap_disconnect(chan); + return BLE_HS_EBADDATA; + } + + if (rx_len > ble_l2cap_get_mtu(chan)) { + ble_l2cap_disconnect(chan); + return BLE_HS_EBADDATA; + } + + rc = chan->rx_fn(chan, &rx_frags); + os_mbuf_free_chain(rx_frags); + + return rc; + +done: + ble_hs_unlock(); -err: - os_mbuf_free_chain(om); return rc; } diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 3a483c7510..cb74e7b70d 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -183,18 +183,13 @@ ble_l2cap_event_coc_received_data(struct ble_l2cap_chan *chan, } static int -ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) +ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om) { int rc; - struct os_mbuf **om; struct os_mbuf *rx_sdu; struct ble_l2cap_coc_endpoint *rx; uint16_t om_total; - /* Create a shortcut to rx_buf */ - om = &chan->rx_buf; - BLE_HS_DBG_ASSERT(*om != NULL); - /* Create a shortcut to rx endpoint */ rx = &chan->coc_rx; BLE_HS_DBG_ASSERT(rx != NULL); diff --git a/nimble/host/src/ble_l2cap_priv.h b/nimble/host/src/ble_l2cap_priv.h index 21e6a8bf64..926d1b9acb 100644 --- a/nimble/host/src/ble_l2cap_priv.h +++ b/nimble/host/src/ble_l2cap_priv.h @@ -49,16 +49,11 @@ extern STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats; extern struct os_mempool ble_l2cap_chan_pool; -/* This is nimble specific; packets sent to the black hole CID do not elicit - * an "invalid CID" response. - */ -#define BLE_L2CAP_CID_BLACK_HOLE 0xffff - #define BLE_L2CAP_HDR_SZ 4 typedef uint8_t ble_l2cap_chan_flags; -typedef int ble_l2cap_rx_fn(struct ble_l2cap_chan *chan); +typedef int ble_l2cap_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om); struct ble_l2cap_chan { SLIST_ENTRY(ble_l2cap_chan) next; @@ -81,9 +76,6 @@ struct ble_l2cap_chan { ble_l2cap_chan_flags flags; - struct os_mbuf *rx_buf; - uint16_t rx_len; /* Length of current reassembled rx packet. */ - ble_l2cap_rx_fn *rx_fn; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 @@ -109,8 +101,7 @@ typedef int ble_l2cap_tx_fn(struct ble_hs_conn *conn, SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan); -int ble_l2cap_parse_hdr(struct os_mbuf *om, int off, - struct ble_l2cap_hdr *l2cap_hdr); +int ble_l2cap_parse_hdr(struct os_mbuf *om, struct ble_l2cap_hdr *hdr); struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len); @@ -119,16 +110,10 @@ void ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); bool ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan); -int ble_l2cap_rx(struct ble_hs_conn *conn, - struct hci_data_hdr *hci_hdr, - struct os_mbuf *om, - ble_l2cap_rx_fn **out_rx_cb, - int *out_reject_cid); +int ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om); int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf *txom); -void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); - int ble_l2cap_init(void); /* Below experimental API is available when BLE_VERSION >= 52 */ diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index f360ad708b..e773b88e5c 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1860,16 +1860,14 @@ ble_l2cap_sig_rx_reject(uint16_t conn_handle, *****************************************************************************/ static int -ble_l2cap_sig_rx(struct ble_l2cap_chan *chan) +ble_l2cap_sig_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { struct ble_l2cap_sig_hdr hdr; ble_l2cap_sig_rx_fn *rx_cb; uint16_t conn_handle; - struct os_mbuf **om; int rc; conn_handle = chan->conn_handle; - om = &chan->rx_buf; STATS_INC(ble_l2cap_stats, sig_rx); diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index a83b9ff287..a6ed2986ce 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2684,13 +2684,12 @@ ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, } static int -ble_sm_rx(struct ble_l2cap_chan *chan) +ble_sm_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { struct ble_sm_result res; ble_sm_rx_fn *rx_cb; uint8_t op; uint16_t conn_handle; - struct os_mbuf **om; int rc; STATS_INC(ble_l2cap_stats, sm_rx); @@ -2700,9 +2699,6 @@ ble_sm_rx(struct ble_l2cap_chan *chan) return BLE_HS_ENOTCONN; } - om = &chan->rx_buf; - BLE_HS_DBG_ASSERT(*om != NULL); - rc = os_mbuf_copydata(*om, 0, 1, &op); if (rc != 0) { return BLE_HS_EBADDATA; @@ -2873,7 +2869,7 @@ ble_sm_init(void) * simple */ static int -ble_sm_rx(struct ble_l2cap_chan *chan) +ble_sm_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { struct ble_sm_pair_fail *cmd; struct os_mbuf *txom; diff --git a/nimble/host/test/src/ble_hs_test_util.c b/nimble/host/test/src/ble_hs_test_util.c index f5463b3ea4..f0b26128b0 100644 --- a/nimble/host/test/src/ble_hs_test_util.c +++ b/nimble/host/test/src/ble_hs_test_util.c @@ -104,7 +104,7 @@ ble_hs_test_util_prev_tx_dequeue(void) pb = BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc); TEST_ASSERT_FATAL(pb == BLE_HCI_PB_FIRST_NON_FLUSH); - rc = ble_l2cap_parse_hdr(om, 0, &l2cap_hdr); + rc = ble_l2cap_parse_hdr(om, &l2cap_hdr); TEST_ASSERT_FATAL(rc == 0); os_mbuf_adj(om, BLE_L2CAP_HDR_SZ); @@ -670,36 +670,13 @@ ble_hs_test_util_l2cap_rx(uint16_t conn_handle, struct hci_data_hdr *hci_hdr, struct os_mbuf *om) { - struct ble_hs_conn *conn; - ble_l2cap_rx_fn *rx_cb; - int reject_cid; + uint8_t pb; int rc; - ble_hs_lock(); - - conn = ble_hs_conn_find(conn_handle); - if (conn != NULL) { - rc = ble_l2cap_rx(conn, hci_hdr, om, &rx_cb, &reject_cid); - } else { - rc = os_mbuf_free_chain(om); - TEST_ASSERT_FATAL(rc == 0); - } - - ble_hs_unlock(); - - if (conn == NULL) { - rc = BLE_HS_ENOTCONN; - } else if (rc == 0) { - TEST_ASSERT_FATAL(rx_cb != NULL); - rc = rx_cb(conn->bhc_rx_chan); - ble_l2cap_remove_rx(conn, conn->bhc_rx_chan); - } else if (rc == BLE_HS_EAGAIN) { - /* More fragments on the way. */ + pb = BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc); + rc = ble_l2cap_rx(conn_handle, pb, om); + if (rc == BLE_HS_EAGAIN) { rc = 0; - } else { - if (reject_cid != -1) { - ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid); - } } return rc; @@ -1787,7 +1764,6 @@ ble_hs_test_util_mbuf_count(const struct ble_hs_test_util_mbuf_params *params) { const struct ble_att_prep_entry *prep; const struct os_mbuf_pkthdr *omp; - const struct ble_l2cap_chan *chan; const struct ble_hs_conn *conn; const struct os_mbuf *om; int count; @@ -1813,9 +1789,7 @@ ble_hs_test_util_mbuf_count(const struct ble_hs_test_util_mbuf_params *params) } if (params->rx_queue) { - SLIST_FOREACH(chan, &conn->bhc_channels, next) { - count += ble_hs_test_util_mbuf_chain_len(chan->rx_buf); - } + count += ble_hs_test_util_mbuf_chain_len(conn->rx_frags); } if (params->prep_list) { diff --git a/nimble/host/test/src/ble_l2cap_test.c b/nimble/host/test/src/ble_l2cap_test.c index 0f55bc006b..9b7c2ec32e 100644 --- a/nimble/host/test/src/ble_l2cap_test.c +++ b/nimble/host/test/src/ble_l2cap_test.c @@ -124,7 +124,7 @@ ble_l2cap_test_util_verify_tx_update_conn( } static int -ble_l2cap_test_util_dummy_rx(struct ble_l2cap_chan *chan) +ble_l2cap_test_util_dummy_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { return 0; } @@ -220,8 +220,7 @@ ble_l2cap_test_util_verify_first_frag(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_TEST_CID); ble_hs_unlock(); } @@ -240,8 +239,7 @@ ble_l2cap_test_util_verify_middle_frag(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_TEST_CID); ble_hs_unlock(); } @@ -260,7 +258,7 @@ ble_l2cap_test_util_verify_last_frag(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan == NULL); + TEST_ASSERT(conn->rx_len == 0); ble_hs_unlock(); } @@ -279,7 +277,7 @@ TEST_CASE_SELF(ble_l2cap_test_case_bad_header) NULL, NULL); rc = ble_l2cap_test_util_rx_first_frag(2, 14, 1234, 10); - TEST_ASSERT(rc == BLE_HS_ENOENT); + TEST_ASSERT(rc == BLE_HS_EBADDATA); ble_hs_test_util_assert_mbufs_freed(NULL); } @@ -386,8 +384,7 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_channels) ble_hs_lock(); conn = ble_hs_conn_find(2); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_TEST_CID); ble_hs_unlock(); /* Receive a starting fragment on a different channel. The first fragment @@ -400,8 +397,7 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_channels) ble_hs_lock(); conn = ble_hs_conn_find(2); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_CID_ATT); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_CID_ATT); ble_hs_unlock(); /* Terminate the connection. The received fragments should get freed.