You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/11/17 02:31:57 UTC

[5/5] incubator-mynewt-core git commit: BLE Host - L2CAP intrnl API chg: handle, not ptrs.

BLE Host - L2CAP intrnl API chg: handle, not ptrs.

This addresses a glaring inconsistency in the NimBLE host.  All other
transmit functions accepted a connection handle and a payload.  The
L2CAP tx functions were different; rather than taking a connection
handle, they took pointers to a connection and L2CAP channel.

A related difference was that the L2CAP tx functions required the caller
to lock the host mutex, while the other tx functions locked the mutex
themselves.

Now the L2CAP tx functions resemble the others:
    * they take a connection handle.
    * they lock the host mutex themselves.


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/2fcb28b2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/2fcb28b2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/2fcb28b2

Branch: refs/heads/develop
Commit: 2fcb28b27637886d7884e1f38dfc305f791aa665
Parents: a38b757
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Nov 16 16:16:27 2016 -0800
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Nov 16 18:31:44 2016 -0800

----------------------------------------------------------------------
 net/nimble/host/src/ble_hs_hci_evt.c        | 18 +++--
 net/nimble/host/src/ble_l2cap.c             | 44 ++++++++++--
 net/nimble/host/src/ble_l2cap_priv.h        |  3 +-
 net/nimble/host/src/ble_l2cap_sig.c         | 92 ++++++++++++++----------
 net/nimble/host/src/ble_l2cap_sig_cmd.c     | 37 ++++++----
 net/nimble/host/src/ble_l2cap_sig_priv.h    | 15 ++--
 net/nimble/host/test/src/ble_hs_test_util.c |  7 +-
 7 files changed, 140 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/net/nimble/host/src/ble_hs_hci_evt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_hci_evt.c b/net/nimble/host/src/ble_hs_hci_evt.c
index 911954a..d185a64 100644
--- a/net/nimble/host/src/ble_hs_hci_evt.c
+++ b/net/nimble/host/src/ble_hs_hci_evt.c
@@ -615,7 +615,8 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
     struct ble_hs_conn *conn;
     ble_l2cap_rx_fn *rx_cb;
     struct os_mbuf *rx_buf;
-    uint16_t handle;
+    uint16_t conn_handle;
+    int reject_cid;
     int rc;
 
     rc = ble_hs_hci_util_data_hdr_strip(om, &hci_hdr);
@@ -624,8 +625,8 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
     }
 
 #if (BLETEST_THROUGHPUT_TEST == 0)
-    BLE_HS_LOG(DEBUG, "ble_hs_hci_evt_acl_process(): handle=%u pb=%x len=%u "
-                      "data=",
+    BLE_HS_LOG(DEBUG, "ble_hs_hci_evt_acl_process(): conn_handle=%u pb=%x "
+                      "len=%u data=",
                BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc), 
                BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc), 
                hci_hdr.hdh_len);
@@ -638,15 +639,15 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
         goto err;
     }
 
-    handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc);
+    conn_handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc);
 
     ble_hs_lock();
 
-    conn = ble_hs_conn_find(handle);
+    conn = ble_hs_conn_find(conn_handle);
     if (conn == NULL) {
         rc = BLE_HS_ENOTCONN;
     } else {
-        rc = ble_l2cap_rx(conn, &hci_hdr, om, &rx_cb, &rx_buf);
+        rc = ble_l2cap_rx(conn, &hci_hdr, om, &rx_cb, &rx_buf, &reject_cid);
         om = NULL;
     }
 
@@ -657,7 +658,7 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
         /* Final fragment received. */
         BLE_HS_DBG_ASSERT(rx_cb != NULL);
         BLE_HS_DBG_ASSERT(rx_buf != NULL);
-        rc = rx_cb(handle, &rx_buf);
+        rc = rx_cb(conn_handle, &rx_buf);
         os_mbuf_free_chain(rx_buf);
         break;
 
@@ -666,6 +667,9 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om)
         break;
 
     default:
+        if (reject_cid != -1) {
+            ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid);
+        }
         goto err;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/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 ddc7a78..66701b1 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -186,18 +186,53 @@ ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     return rc;
 }
 
+/**
+ * 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_rx_buf            If a full L2CAP packet has been received, this
+ *                                  will point to the entire L2CAP packet.  To
+ *                                  process the packet, pass this buffer to the
+ *                                  receive handler (out_rx_cb).
+ * @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,
-             struct os_mbuf **out_rx_buf)
+             struct os_mbuf **out_rx_buf,
+             int *out_reject_cid)
 {
     struct ble_l2cap_chan *chan;
     struct ble_l2cap_hdr l2cap_hdr;
     uint8_t pb;
     int rc;
 
+    *out_reject_cid = -1;
+
     pb = BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc);
     switch (pb) {
     case BLE_HCI_PB_FIRST_FLUSH:
@@ -221,12 +256,7 @@ ble_l2cap_rx(struct ble_hs_conn *conn,
             if (l2cap_hdr.blh_cid != BLE_L2CAP_CID_BLACK_HOLE) {
                 BLE_HS_LOG(DEBUG, "rx on unknown L2CAP channel: %d\n",
                            l2cap_hdr.blh_cid);
-
-                chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_SIG);
-                if (chan != NULL) {
-                    ble_l2cap_sig_reject_invalid_cid_tx(conn, chan, 0, 0,
-                                                        l2cap_hdr.blh_cid);
-                }
+                *out_reject_cid = l2cap_hdr.blh_cid;
             }
             goto err;
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 016d291..79d58a7 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -104,7 +104,8 @@ 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,
-                 struct os_mbuf **out_rx_buf);
+                 struct os_mbuf **out_rx_buf,
+                 int *out_reject_cid);
 int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                  struct os_mbuf *txom);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/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 805b696..7954be9 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -190,8 +190,9 @@ ble_l2cap_sig_proc_insert(struct ble_l2cap_sig_proc *proc)
 {
     ble_l2cap_sig_dbg_assert_proc_not_inserted(proc);
 
-    BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
+    ble_hs_lock();
     STAILQ_INSERT_HEAD(&ble_l2cap_sig_procs, proc, next);
+    ble_hs_unlock();
 }
 
 /**
@@ -271,6 +272,24 @@ ble_l2cap_sig_rx_noop(uint16_t conn_handle,
     return BLE_HS_ENOTSUP;
 }
 
+static void
+ble_l2cap_sig_proc_set_timer(struct ble_l2cap_sig_proc *proc)
+{
+    proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT;
+    ble_hs_timer_resched();
+}
+
+static void
+ble_l2cap_sig_process_status(struct ble_l2cap_sig_proc *proc, int status)
+{
+    if (status == 0) {
+        ble_l2cap_sig_proc_set_timer(proc);
+        ble_l2cap_sig_proc_insert(proc);
+    } else {
+        ble_l2cap_sig_proc_free(proc);
+    }
+}
+
 /*****************************************************************************
  * $update                                                                   *
  *****************************************************************************/
@@ -296,9 +315,7 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
 {
     struct ble_l2cap_sig_update_req req;
     struct ble_gap_upd_params params;
-    struct ble_l2cap_chan *chan;
     ble_hs_conn_flags_t conn_flags;
-    struct ble_hs_conn *conn;
     uint16_t l2cap_result;
     int sig_err;
     int rc;
@@ -342,19 +359,15 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
     }
 
     /* Send L2CAP response. */
-    ble_hs_lock();
-    ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
-                                    &conn, &chan);
     if (!sig_err) {
-        rc = ble_l2cap_sig_update_rsp_tx(conn, chan, hdr->identifier,
+        rc = ble_l2cap_sig_update_rsp_tx(conn_handle, hdr->identifier,
                                          l2cap_result);
     } else {
-        ble_l2cap_sig_reject_tx(conn, chan, hdr->identifier,
+        ble_l2cap_sig_reject_tx(conn_handle, hdr->identifier,
                                 BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD,
                                 NULL, 0);
         rc = BLE_HS_L2C_ERR(BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD);
     }
-    ble_hs_unlock();
 
     return rc;
 }
@@ -416,6 +429,7 @@ ble_l2cap_sig_update(uint16_t conn_handle,
     struct ble_l2cap_sig_proc *proc;
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
+    int master;
     int rc;
 
     proc = NULL;
@@ -423,10 +437,12 @@ ble_l2cap_sig_update(uint16_t conn_handle,
     STATS_INC(ble_l2cap_stats, update_init);
 
     ble_hs_lock();
-
     ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
                                     &conn, &chan);
-    if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
+    master = conn->bhc_flags & BLE_HS_CONN_F_MASTER;
+    ble_hs_unlock();
+
+    if (master) {
         /* Only the slave can initiate the L2CAP connection update
          * procedure.
          */
@@ -444,7 +460,6 @@ ble_l2cap_sig_update(uint16_t conn_handle,
     proc->op = BLE_L2CAP_SIG_PROC_OP_UPDATE;
     proc->id = ble_l2cap_sig_next_id();
     proc->conn_handle = conn_handle;
-    proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT;
     proc->update.cb = cb;
     proc->update.cb_arg = cb_arg;
 
@@ -453,18 +468,10 @@ ble_l2cap_sig_update(uint16_t conn_handle,
     req.slave_latency = params->slave_latency;
     req.timeout_multiplier = params->timeout_multiplier;
 
-    rc = ble_l2cap_sig_update_req_tx(conn, chan, proc->id, &req);
-    if (rc == 0) {
-        ble_l2cap_sig_proc_insert(proc);
-    }
+    rc = ble_l2cap_sig_update_req_tx(conn_handle, proc->id, &req);
 
 done:
-    ble_hs_unlock();
-
-    if (rc != 0) {
-        ble_l2cap_sig_proc_free(proc);
-    }
-
+    ble_l2cap_sig_process_status(proc, rc);
     return rc;
 }
 
@@ -472,8 +479,6 @@ static int
 ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
     struct ble_l2cap_sig_hdr hdr;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     ble_l2cap_sig_rx_fn *rx_cb;
     int rc;
 
@@ -498,14 +503,10 @@ ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
 
     rx_cb = ble_l2cap_sig_dispatch_get(hdr.op);
     if (rx_cb == NULL) {
-        ble_hs_lock();
-        ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
-                                        &conn, &chan);
-        ble_l2cap_sig_reject_tx(conn, chan, hdr.identifier,
+        ble_l2cap_sig_reject_tx(conn_handle, hdr.identifier,
                                 BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD,
                                 NULL, 0);
         rc = BLE_HS_L2C_ERR(BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD);
-        ble_hs_unlock();
     } else {
         rc = rx_cb(conn_handle, &hdr, om);
     }
@@ -531,18 +532,26 @@ ble_l2cap_sig_create_chan(void)
     return chan;
 }
 
-static void
+/**
+ * @return                      The number of ticks until the next expiration
+ *                                  occurs.
+ */
+static int32_t
 ble_l2cap_sig_extract_expired(struct ble_l2cap_sig_proc_list *dst_list)
 {
     struct ble_l2cap_sig_proc *proc;
     struct ble_l2cap_sig_proc *prev;
     struct ble_l2cap_sig_proc *next;
     uint32_t now;
+    int32_t next_exp_in;
     int32_t time_diff;
 
     now = os_time_get();
     STAILQ_INIT(dst_list);
 
+    /* Assume each event is either expired or has infinite duration. */
+    next_exp_in = BLE_HS_FOREVER;
+
     ble_hs_lock();
 
     prev = NULL;
@@ -550,20 +559,27 @@ ble_l2cap_sig_extract_expired(struct ble_l2cap_sig_proc_list *dst_list)
     while (proc != NULL) {
         next = STAILQ_NEXT(proc, next);
     
-        time_diff = now - proc->exp_os_ticks;
-        if (time_diff >= 0) {
+        time_diff = proc->exp_os_ticks - now;
+        if (time_diff <= 0) {
+            /* Procedure has expired; move it to the destination list. */
             if (prev == NULL) {
                 STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next);
             } else {
                 STAILQ_REMOVE_AFTER(&ble_l2cap_sig_procs, prev, next);
             }
             STAILQ_INSERT_TAIL(dst_list, proc, next);
+        } else {
+            if (time_diff < next_exp_in) {
+                next_exp_in = time_diff;
+            }
         }
 
         proc = next;
     }
 
     ble_hs_unlock();
+
+    return next_exp_in;
 }
 
 void
@@ -590,22 +606,24 @@ ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason)
  * All procedures that have been expecting a response for longer than 30
  * seconds are aborted and their corresponding connection is terminated.
  *
- * Called by the heartbeat timer; executed at least once a second.
+ * Called by the timer timer; executed at least once a second.
  *
  * @return                      The number of ticks until this function should
  *                                  be called again; currently always
  *                                  UINT32_MAX.
  */
 int32_t
-ble_l2cap_sig_heartbeat(void)
+ble_l2cap_sig_timer(void)
 {
     struct ble_l2cap_sig_proc_list temp_list;
     struct ble_l2cap_sig_proc *proc;
+    int32_t ticks_until_exp;
 
     /* Remove timed-out procedures from the main list and insert them into a
-     * temporary list.
+     * temporary list.  This function also calculates the number of ticks until
+     * the next expiration will occur.
      */
-    ble_l2cap_sig_extract_expired(&temp_list);
+    ticks_until_exp = ble_l2cap_sig_extract_expired(&temp_list);
 
     /* Report a failure for each timed out procedure. */
     while ((proc = STAILQ_FIRST(&temp_list)) != NULL) {
@@ -616,7 +634,7 @@ ble_l2cap_sig_heartbeat(void)
         ble_l2cap_sig_proc_free(proc);
     }
 
-    return BLE_HS_FOREVER;
+    return ticks_until_exp;
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index a2bc91a..b8ab12b 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -60,6 +60,22 @@ err:
     return rc;
 }
 
+static int
+ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
+{
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    ble_hs_lock();
+    ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
+                                    &conn, &chan);
+    rc = ble_l2cap_tx(conn, chan, txom);
+    ble_hs_unlock();
+
+    return rc;
+}
+
 static void
 ble_l2cap_sig_hdr_swap(struct ble_l2cap_sig_hdr *dst,
                        struct ble_l2cap_sig_hdr *src)
@@ -108,8 +124,7 @@ ble_l2cap_sig_reject_write(void *payload, uint16_t len,
 }
 
 int
-ble_l2cap_sig_reject_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                        uint8_t id, uint16_t reason,
+ble_l2cap_sig_reject_tx(uint16_t conn_handle, uint8_t id, uint16_t reason,
                         void *data, int data_len)
 {
     struct ble_l2cap_sig_reject cmd;
@@ -129,7 +144,7 @@ ble_l2cap_sig_reject_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                                data, data_len);
 
     STATS_INC(ble_l2cap_stats, sig_rx);
-    rc = ble_l2cap_tx(conn, chan, txom);
+    rc = ble_l2cap_sig_tx(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -138,8 +153,7 @@ ble_l2cap_sig_reject_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
 }
 
 int
-ble_l2cap_sig_reject_invalid_cid_tx(struct ble_hs_conn *conn,
-                                    struct ble_l2cap_chan *chan, uint8_t id,
+ble_l2cap_sig_reject_invalid_cid_tx(uint16_t conn_handle, uint8_t id,
                                     uint16_t src_cid, uint16_t dst_cid)
 {
     int rc;
@@ -152,7 +166,7 @@ ble_l2cap_sig_reject_invalid_cid_tx(struct ble_hs_conn *conn,
         .remote_cid = src_cid,
     };
 
-    rc = ble_l2cap_sig_reject_tx(conn, chan, id,
+    rc = ble_l2cap_sig_reject_tx(conn_handle, id,
                                  BLE_L2CAP_SIG_ERR_INVALID_CID,
                                  &data, sizeof data);
     return rc;
@@ -185,8 +199,7 @@ ble_l2cap_sig_update_req_write(void *payload, int len,
 }
 
 int
-ble_l2cap_sig_update_req_tx(struct ble_hs_conn *conn,
-                            struct ble_l2cap_chan *chan, uint8_t id,
+ble_l2cap_sig_update_req_tx(uint16_t conn_handle, uint8_t id,
                             struct ble_l2cap_sig_update_req *req)
 {
     struct os_mbuf *txom;
@@ -203,7 +216,7 @@ ble_l2cap_sig_update_req_tx(struct ble_hs_conn *conn,
     ble_l2cap_sig_update_req_write(payload_buf, BLE_L2CAP_SIG_UPDATE_REQ_SZ,
                                    req);
 
-    rc = ble_l2cap_tx(conn, chan, txom);
+    rc = ble_l2cap_sig_tx(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -235,9 +248,7 @@ ble_l2cap_sig_update_rsp_write(void *payload, int len,
 }
 
 int
-ble_l2cap_sig_update_rsp_tx(struct ble_hs_conn *conn,
-                            struct ble_l2cap_chan *chan, uint8_t id,
-                            uint16_t result)
+ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id, uint16_t result)
 {
     struct ble_l2cap_sig_update_rsp rsp;
     struct os_mbuf *txom;
@@ -255,7 +266,7 @@ ble_l2cap_sig_update_rsp_tx(struct ble_hs_conn *conn,
     ble_l2cap_sig_update_rsp_write(payload_buf, BLE_L2CAP_SIG_UPDATE_RSP_SZ,
                                    &rsp);
 
-    rc = ble_l2cap_tx(conn, chan, txom);
+    rc = ble_l2cap_sig_tx(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/net/nimble/host/src/ble_l2cap_sig_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_priv.h b/net/nimble/host/src/ble_l2cap_sig_priv.h
index 4646fc2..72819de 100644
--- a/net/nimble/host/src/ble_l2cap_sig_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sig_priv.h
@@ -60,32 +60,27 @@ void ble_l2cap_sig_hdr_parse(void *payload, uint16_t len,
                              struct ble_l2cap_sig_hdr *hdr);
 void ble_l2cap_sig_hdr_write(void *payload, uint16_t len,
                              struct ble_l2cap_sig_hdr *hdr);
-int ble_l2cap_sig_reject_tx(struct ble_hs_conn *conn,
-                            struct ble_l2cap_chan *chan,
+int ble_l2cap_sig_reject_tx(uint16_t conn_handle,
                             uint8_t id, uint16_t reason,
                             void *data, int data_len);
 void ble_l2cap_sig_update_req_parse(void *payload, int len,
                                     struct ble_l2cap_sig_update_req *req);
 void ble_l2cap_sig_update_req_write(void *payload, int len,
                                     struct ble_l2cap_sig_update_req *src);
-int ble_l2cap_sig_update_req_tx(struct ble_hs_conn *conn,
-                                struct ble_l2cap_chan *chan, uint8_t id,
+int ble_l2cap_sig_update_req_tx(uint16_t conn_handle, uint8_t id,
                                 struct ble_l2cap_sig_update_req *req);
 void ble_l2cap_sig_update_rsp_parse(void *payload, int len,
                                     struct ble_l2cap_sig_update_rsp *cmd);
 void ble_l2cap_sig_update_rsp_write(void *payload, int len,
                                     struct ble_l2cap_sig_update_rsp *src);
-int ble_l2cap_sig_update_rsp_tx(struct ble_hs_conn *conn,
-                                struct ble_l2cap_chan *chan, uint8_t id,
+int ble_l2cap_sig_update_rsp_tx(uint16_t conn_handle, uint8_t id,
                                 uint16_t result);
 
-int ble_l2cap_sig_reject_invalid_cid_tx(struct ble_hs_conn *conn,
-                                        struct ble_l2cap_chan *chan,
-                                        uint8_t id,
+int ble_l2cap_sig_reject_invalid_cid_tx(uint16_t conn_handle, uint8_t id,
                                         uint16_t src_cid, uint16_t dst_cid);
 
 void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason);
-int32_t ble_l2cap_sig_heartbeat(void);
+int32_t ble_l2cap_sig_timer(void);
 struct ble_l2cap_chan *ble_l2cap_sig_create_chan(void);
 int ble_l2cap_sig_init(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2fcb28b2/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 58e3345..55528dd 100644
--- a/net/nimble/host/test/src/ble_hs_test_util.c
+++ b/net/nimble/host/test/src/ble_hs_test_util.c
@@ -839,13 +839,14 @@ ble_hs_test_util_l2cap_rx(uint16_t conn_handle,
     struct ble_hs_conn *conn;
     ble_l2cap_rx_fn *rx_cb;
     struct os_mbuf *rx_buf;
+    int reject_cid;
     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, &rx_buf);
+        rc = ble_l2cap_rx(conn, hci_hdr, om, &rx_cb, &rx_buf, &reject_cid);
     } else {
         os_mbuf_free_chain(om);
     }
@@ -862,6 +863,10 @@ ble_hs_test_util_l2cap_rx(uint16_t conn_handle,
     } else if (rc == BLE_HS_EAGAIN) {
         /* More fragments on the way. */
         rc = 0;
+    } else {
+        if (reject_cid != -1) {
+            ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid);
+        }
     }
 
     return rc;