nimble/l2cap: Add helper to create L2CAP channel for LE CoC With this patch, creating L2CAP channel for LE CoC purposes is moved to ble_l2cap_coc.c. It is because in that file we want to have all the logic related to CoC e.g. credits, available servers, data handling
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/eb576bc2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/eb576bc2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/eb576bc2 Branch: refs/heads/master Commit: eb576bc2036d1322cbc1fb216dea8fa0153968d9 Parents: 98ebb51 Author: Åukasz Rymanowski <[email protected]> Authored: Thu Feb 2 11:27:14 2017 +0100 Committer: Åukasz Rymanowski <[email protected]> Committed: Fri Mar 3 12:40:42 2017 +0100 ---------------------------------------------------------------------- net/nimble/host/src/ble_l2cap_coc.c | 57 ++++++++++++++++++++++++++- net/nimble/host/src/ble_l2cap_coc_priv.h | 11 ++++-- net/nimble/host/src/ble_l2cap_sig.c | 43 +++++--------------- 3 files changed, 73 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/eb576bc2/net/nimble/host/src/ble_l2cap_coc.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap_coc.c b/net/nimble/host/src/ble_l2cap_coc.c index 6286d43..46b903b 100644 --- a/net/nimble/host/src/ble_l2cap_coc.c +++ b/net/nimble/host/src/ble_l2cap_coc.c @@ -87,7 +87,7 @@ ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, return 0; } -uint16_t +static uint16_t ble_l2cap_coc_get_cid(void) { static uint16_t next_cid = BLE_L2CAP_COC_CID_START; @@ -100,7 +100,7 @@ ble_l2cap_coc_get_cid(void) return next_cid++; } -struct ble_l2cap_coc_srv * +static struct ble_l2cap_coc_srv * ble_l2cap_coc_srv_find(uint16_t psm) { struct ble_l2cap_coc_srv *cur, *srv; @@ -116,6 +116,59 @@ ble_l2cap_coc_srv_find(uint16_t psm) return srv; } +static int +ble_l2cap_coc_rx_fn(uint16_t conn_handle, struct os_mbuf **rxom) +{ + return 0; +} + +struct ble_l2cap_chan * +ble_l2cap_coc_chan_alloc(uint16_t conn_handle, uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, + void *cb_arg) +{ + struct ble_l2cap_chan *chan; + + chan = ble_l2cap_chan_alloc(); + if (!chan) { + return NULL; + } + + chan->conn_handle = conn_handle; + chan->psm = psm; + chan->cb = cb; + chan->cb_arg = cb_arg; + chan->scid = ble_l2cap_coc_get_cid(); + chan->my_mtu = BLE_L2CAP_COC_MTU; + chan->rx_fn = ble_l2cap_coc_rx_fn; + chan->coc_rx.mtu = mtu; + chan->coc_rx.credits = 10; /* FIXME Calculate it */ + chan->coc_rx.sdu = sdu_rx; + + return chan; +} + +int +ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, + struct ble_l2cap_chan **chan) +{ + struct ble_l2cap_coc_srv *srv; + + /* Check if there is server registered on this PSM */ + srv = ble_l2cap_coc_srv_find(psm); + if (!srv) { + return BLE_HS_ENOTSUP; + } + + *chan = ble_l2cap_coc_chan_alloc(conn_handle, psm, srv->mtu, NULL, srv->cb, + srv->cb_arg); + if (!*chan) { + return BLE_HS_ENOMEM; + } + + return 0; +} + int ble_l2cap_coc_init(void) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/eb576bc2/net/nimble/host/src/ble_l2cap_coc_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap_coc_priv.h b/net/nimble/host/src/ble_l2cap_coc_priv.h index 31e81e7..63c593e 100644 --- a/net/nimble/host/src/ble_l2cap_coc_priv.h +++ b/net/nimble/host/src/ble_l2cap_coc_priv.h @@ -23,9 +23,9 @@ #include <inttypes.h> #include "syscfg/syscfg.h" #include "os/queue.h" +#include "os/os_mbuf.h" #include "host/ble_l2cap.h" #include "ble_l2cap_sig_priv.h" - #ifdef __cplusplus extern "C" { #endif @@ -52,10 +52,15 @@ struct ble_l2cap_coc_srv { #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 int ble_l2cap_coc_init(void); -uint16_t ble_l2cap_coc_get_cid(void); int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); -struct ble_l2cap_coc_srv * ble_l2cap_coc_srv_find(uint16_t psm); +int ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, + struct ble_l2cap_chan **chan); +struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, + ble_l2cap_event_fn *cb, + void *cb_arg); #else #define ble_l2cap_coc_init() 0 #define ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg) BLE_HS_ENOTSUP http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/eb576bc2/net/nimble/host/src/ble_l2cap_sig.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c index 7919a89..d6219d3 100644 --- a/net/nimble/host/src/ble_l2cap_sig.c +++ b/net/nimble/host/src/ble_l2cap_sig.c @@ -551,6 +551,8 @@ static int ble_l2cap_sig_ble_hs_err2coc_err(uint16_t ble_hs_err) { switch (ble_hs_err) { + case BLE_HS_ENOTSUP: + return BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM; case BLE_HS_ENOMEM: return BLE_L2CAP_COC_ERR_NO_RESOURCES; case BLE_HS_EAUTHEN: @@ -631,8 +633,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_l2cap_sig_le_con_req *req; struct os_mbuf *txom; struct ble_l2cap_sig_le_con_rsp *rsp; - struct ble_l2cap_coc_srv *srv; - struct ble_l2cap_chan *chan; + struct ble_l2cap_chan *chan = NULL; struct ble_hs_conn *conn; uint16_t scid; @@ -657,13 +658,6 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, ble_hs_lock(); conn = ble_hs_conn_find_assert(conn_handle); - /* Check if there is server registered on this PSM */ - srv = ble_l2cap_coc_srv_find(le16toh(req->psm)); - if (!srv) { - rsp->result = htole16(BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM); - goto failed; - } - /* Verify CID */ scid = le16toh(req->scid); if (scid < BLE_L2CAP_COC_CID_START || scid > BLE_L2CAP_COC_CID_END) { @@ -672,19 +666,15 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto failed; } - chan = ble_l2cap_chan_alloc(); - if (!chan) { - rsp->result = htole16(BLE_L2CAP_COC_ERR_NO_RESOURCES); + rc = ble_l2cap_coc_create_srv_chan(conn_handle, le16toh(req->psm), &chan); + if (rc != 0) { + uint16_t coc_err = ble_l2cap_sig_ble_hs_err2coc_err(rc); + rsp->result = htole16(coc_err); goto failed; } - chan->cb = srv->cb; - chan->cb_arg = srv->cb_arg; - chan->conn_handle = conn_handle; - chan->dcid = scid; - chan->my_mtu = BLE_L2CAP_COC_MTU; - /* Fill up remote configuration. Note MPS is the L2CAP MTU*/ + chan->dcid = scid; chan->peer_mtu = le16toh(req->mps); chan->coc_tx.credits = le16toh(req->credits); chan->coc_tx.mtu = le16toh(req->mtu); @@ -697,10 +687,6 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto failed; } - chan->scid = ble_l2cap_coc_get_cid(); - chan->coc_rx.mtu = srv->mtu; - chan->coc_rx.credits = 10; //FIXME Calculate it - rsp->dcid = htole16(chan->scid); rsp->credits = htole16(chan->coc_rx.credits); rsp->mps = htole16(chan->my_mtu); @@ -795,7 +781,7 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, struct ble_l2cap_sig_proc *proc; struct os_mbuf *txom; struct ble_l2cap_sig_le_con_req *req; - struct ble_l2cap_chan *chan; + struct ble_l2cap_chan *chan = NULL; int rc; if (!sdu_rx || !cb) { @@ -810,7 +796,7 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, return BLE_HS_ENOTCONN; } - chan = ble_l2cap_chan_alloc(); + chan = ble_l2cap_coc_chan_alloc(conn_handle, psm, mtu, sdu_rx, cb, cb_arg); if (!chan) { ble_hs_unlock(); return BLE_HS_ENOMEM; @@ -823,15 +809,6 @@ ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, return BLE_HS_ENOMEM; } - chan->scid = ble_l2cap_coc_get_cid(); - chan->my_mtu = BLE_L2CAP_COC_MTU; - chan->coc_rx.credits = 10; - chan->coc_rx.mtu = mtu; - chan->coc_rx.sdu = sdu_rx; - chan->cb = cb; - chan->cb_arg = cb_arg; - chan->conn_handle = conn_handle; - proc->op = BLE_L2CAP_SIG_PROC_OP_CONNECT; proc->id = ble_l2cap_sig_next_id(); proc->conn_handle = conn_handle;
