Repository: incubator-mynewt-core Updated Branches: refs/heads/develop 2bbb29106 -> b41d25e6f
nimble/l2cap: Drop packets bigger than MTU on the channel Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/673169f5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/673169f5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/673169f5 Branch: refs/heads/develop Commit: 673169f527a2bde1fecbbaf848800f4546af2d38 Parents: 4ef28aa Author: Åukasz Rymanowski <[email protected]> Authored: Thu Feb 23 00:22:56 2017 +0100 Committer: Åukasz Rymanowski <[email protected]> Committed: Thu Feb 23 00:22:56 2017 +0100 ---------------------------------------------------------------------- net/nimble/host/src/ble_l2cap.c | 21 +++++++++++++++++++++ net/nimble/host/test/src/ble_gatt_read_test.c | 3 +++ net/nimble/host/test/src/ble_hs_test_util.c | 18 ++++++++++++++++++ net/nimble/host/test/src/ble_hs_test_util.h | 1 + net/nimble/host/test/src/ble_l2cap_test.c | 6 ++++-- 5 files changed, 47 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673169f5/net/nimble/host/src/ble_l2cap.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c index 2b60a30..e94a234 100644 --- a/net/nimble/host/src/ble_l2cap.c +++ b/net/nimble/host/src/ble_l2cap.c @@ -237,6 +237,21 @@ ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, 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. * @@ -317,6 +332,12 @@ ble_l2cap_rx(struct ble_hs_conn *conn, ble_l2cap_discard_rx(conn, chan); } + if (l2cap_hdr.len > ble_l2cap_get_mtu(chan)) { + /* More data then we expected on the channel */ + rc = BLE_HS_EBADDATA; + goto err; + } + /* Remember channel and length of L2CAP data for reassembly. */ conn->bhc_rx_chan = chan; chan->rx_len = l2cap_hdr.len; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673169f5/net/nimble/host/test/src/ble_gatt_read_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/test/src/ble_gatt_read_test.c b/net/nimble/host/test/src/ble_gatt_read_test.c index 835e256..3cd7849 100644 --- a/net/nimble/host/test/src/ble_gatt_read_test.c +++ b/net/nimble/host/test/src/ble_gatt_read_test.c @@ -248,6 +248,9 @@ ble_gatt_read_test_misc_verify_good(struct ble_hs_test_util_flat_attr *attr) ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); + /* Exchange MTU: We need plus 1 for the read response opcode */ + ble_hs_test_util_set_att_mtu(2, attr->value_len + 1); + rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673169f5/net/nimble/host/test/src/ble_hs_test_util.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/test/src/ble_hs_test_util.c b/net/nimble/host/test/src/ble_hs_test_util.c index f4fa339..cd9e1b2 100644 --- a/net/nimble/host/test/src/ble_hs_test_util.c +++ b/net/nimble/host/test/src/ble_hs_test_util.c @@ -991,6 +991,24 @@ ble_hs_test_util_l2cap_rx_payload_flat(uint16_t conn_handle, uint16_t cid, return rc; } +void +ble_hs_test_util_set_att_mtu(uint16_t conn_handle, uint16_t mtu) +{ + struct ble_l2cap_chan *chan; + struct ble_hs_conn *conn; + + if (mtu <= BLE_ATT_MTU_DFLT) { + return; + } + + ble_hs_lock(); + ble_att_conn_chan_find(conn_handle, &conn, &chan); + chan->my_mtu = mtu; + chan->peer_mtu = mtu; + chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU; + ble_hs_unlock(); +} + int ble_hs_test_util_rx_att_mtu_cmd(uint16_t conn_handle, int is_req, uint16_t mtu) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673169f5/net/nimble/host/test/src/ble_hs_test_util.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/test/src/ble_hs_test_util.h b/net/nimble/host/test/src/ble_hs_test_util.h index 57de72f..9914e83 100644 --- a/net/nimble/host/test/src/ble_hs_test_util.h +++ b/net/nimble/host/test/src/ble_hs_test_util.h @@ -151,6 +151,7 @@ int ble_hs_test_util_l2cap_rx(uint16_t conn_handle, int ble_hs_test_util_l2cap_rx_payload_flat(uint16_t conn_handle, uint16_t cid, const void *data, int len); void ble_hs_test_util_rx_hci_buf_size_ack(uint16_t buf_size); +void ble_hs_test_util_set_att_mtu(uint16_t conn_handle, uint16_t mtu); int ble_hs_test_util_rx_att_mtu_cmd(uint16_t conn_handle, int is_req, uint16_t mtu); int ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673169f5/net/nimble/host/test/src/ble_l2cap_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/test/src/ble_l2cap_test.c b/net/nimble/host/test/src/ble_l2cap_test.c index 7c60aa9..f4f16bc 100644 --- a/net/nimble/host/test/src/ble_l2cap_test.c +++ b/net/nimble/host/test/src/ble_l2cap_test.c @@ -337,6 +337,7 @@ TEST_CASE(ble_l2cap_test_case_frag_channels) { struct ble_hs_conn *conn; int rc; + uint16_t data_len = 30; ble_l2cap_test_util_init(); @@ -344,7 +345,7 @@ TEST_CASE(ble_l2cap_test_case_frag_channels) NULL, NULL); /* Receive a starting fragment on the first channel. */ - rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_TEST_CID, 30); + rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_TEST_CID, data_len); TEST_ASSERT(rc == 0); ble_hs_lock(); @@ -357,7 +358,8 @@ TEST_CASE(ble_l2cap_test_case_frag_channels) /* Receive a starting fragment on a different channel. The first fragment * should get discarded. */ - rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_CID_ATT, 30); + ble_hs_test_util_set_att_mtu(conn->bhc_handle, data_len); + rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_CID_ATT, data_len); TEST_ASSERT(rc == 0); ble_hs_lock();
