From f8f02740acdf4d302d5c2f91ee2e34444d405671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 12 Mar 2019 13:13:12 +0100 Subject: [PATCH] nimble/host: Fix credits setting for L2CAP CoC With current implementation we could end up having credits 0 when requested L2CAP CoC MTU is much lower than MTU on L2CAP channel. This patch fixes it. --- nimble/host/src/ble_l2cap_coc.c | 5 ++++- nimble/host/test/src/ble_l2cap_test.c | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 4dd2a9356..61345f5af 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -255,7 +255,10 @@ ble_l2cap_coc_chan_alloc(uint16_t conn_handle, uint16_t psm, uint16_t mtu, /* Number of credits should allow to send full SDU with on given * L2CAP MTU */ - chan->coc_rx.credits = (mtu + (chan->my_mtu - 1) / 2) / chan->my_mtu; + chan->coc_rx.credits = mtu / chan->my_mtu; + if (mtu % chan->my_mtu) { + chan->coc_rx.credits++; + } chan->initial_credits = chan->coc_rx.credits; return chan; diff --git a/nimble/host/test/src/ble_l2cap_test.c b/nimble/host/test/src/ble_l2cap_test.c index e0c537ffc..106b9f68b 100644 --- a/nimble/host/test/src/ble_l2cap_test.c +++ b/nimble/host/test/src/ble_l2cap_test.c @@ -719,6 +719,18 @@ ble_l2cap_test_event(struct ble_l2cap_event *event, void *arg) } } +static uint16_t ble_l2cap_calculate_credits(uint16_t mtu, uint16_t mps) +{ + int credits; + + credits = mtu / mps; + if (mtu % mps) { + credits++; + } + + return credits; +} + static void ble_l2cap_test_coc_connect(struct test_data *t) { @@ -747,8 +759,9 @@ ble_l2cap_test_coc_connect(struct test_data *t) return; } - req.credits = htole16((t->mtu + (MYNEWT_VAL(BLE_L2CAP_COC_MTU) - 1) / 2) / - MYNEWT_VAL(BLE_L2CAP_COC_MTU)); + req.credits = htole16( + ble_l2cap_calculate_credits(t->mtu, + MYNEWT_VAL(BLE_L2CAP_COC_MTU))); req.mps = htole16(MYNEWT_VAL(BLE_L2CAP_COC_MTU)); req.mtu = htole16(t->mtu); req.psm = htole16(t->psm); @@ -812,8 +825,9 @@ ble_l2cap_test_coc_connect_by_peer(struct test_data *t) rsp.result = htole16(ev->l2cap_status); } else { /* Receive response from peer.*/ - rsp.credits = htole16((t->mtu + (MYNEWT_VAL(BLE_L2CAP_COC_MTU) - 1) / 2) / - MYNEWT_VAL(BLE_L2CAP_COC_MTU)); + rsp.credits = htole16( + ble_l2cap_calculate_credits(t->mtu, + MYNEWT_VAL(BLE_L2CAP_COC_MTU))); rsp.dcid = current_cid++; rsp.mps = htole16(MYNEWT_VAL(BLE_L2CAP_COC_MTU)); rsp.mtu = htole16(t->mtu);