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/05/14 00:53:24 UTC

[1/4] incubator-mynewt-core git commit: BLE Host - Formalize some GATT thread safety reqs.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 9eeec05f0 -> 2dd32b7df


BLE Host - Formalize some GATT thread safety reqs.


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

Branch: refs/heads/develop
Commit: ee4fbed39aa002bd862ec0ae45b28ef61d0ef86b
Parents: 9eeec05
Author: Christopher Collins <cc...@apache.org>
Authored: Thu May 12 17:15:06 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu May 12 17:15:06 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_gattc.c             | 152 ++++++++++++++++++++++-
 net/nimble/host/src/ble_hs.c                |   2 +-
 net/nimble/host/src/test/ble_hs_test_util.c |  42 ++++++-
 net/nimble/host/src/test/ble_hs_test_util.h |   3 +
 net/nimble/host/src/test/ble_os_test.c      |   8 +-
 5 files changed, 193 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee4fbed3/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index b957a43..4e23f90 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -39,7 +39,15 @@
  * 2. The only resource protected by the mutex is the list of active procedures
  *    (ble_gattc_procs).  Thread-safety is achieved by locking the mutex during
  *    removal and insertion operations.  Procedure objects are only modified
- *    while they are not in the list.
+ *    while they are not in the list.  This is sufficient, as the host parent
+ *    task is the only task which inspects or modifies individual procedure
+ *    entries.  Tasks have the following permissions regarding procedure
+ *    entries:
+ *
+ *                | insert  | remove    | inspect   | modify
+ *    ------------+---------+-----------|-----------|---------
+ *    parent task | X       | X         | X         | X
+ *    other tasks | X       |           |           |
  */
 
 #include <stddef.h>
@@ -351,9 +359,30 @@ STATS_NAME_START(ble_gattc_stats)
     STATS_NAME(ble_gattc_stats, notify_fail)
     STATS_NAME(ble_gattc_stats, indicate)
     STATS_NAME(ble_gattc_stats, indicate_fail)
+    STATS_NAME(ble_gattc_stats, proc_timeout)
 STATS_NAME_END(ble_gattc_stats)
 
 /*****************************************************************************
+ * $debug                                                                    *
+ *****************************************************************************/
+
+static void
+ble_gattc_dbg_assert_proc_not_inserted(struct ble_gattc_proc *proc)
+{
+#if BLE_HS_DEBUG
+    struct ble_gattc_proc *cur;
+
+    ble_hs_lock();
+
+    STAILQ_FOREACH(cur, &ble_gattc_procs, next) {
+        BLE_HS_DBG_ASSERT(cur != proc);
+    }
+
+    ble_hs_unlock();
+#endif
+}
+
+/*****************************************************************************
  * $log                                                                      *
  *****************************************************************************/
 
@@ -576,6 +605,8 @@ ble_gattc_proc_free(struct ble_gattc_proc *proc)
     int rc;
 
     if (proc != NULL) {
+        ble_gattc_dbg_assert_proc_not_inserted(proc);
+
         rc = os_memblock_put(&ble_gattc_proc_pool, proc);
         BLE_HS_DBG_ASSERT_EVAL(rc == 0);
     }
@@ -584,6 +615,8 @@ ble_gattc_proc_free(struct ble_gattc_proc *proc)
 static void
 ble_gattc_proc_insert(struct ble_gattc_proc *proc)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     ble_hs_lock();
     STAILQ_INSERT_HEAD(&ble_gattc_procs, proc, next);
     ble_hs_unlock();
@@ -651,6 +684,9 @@ ble_gattc_extract(uint16_t conn_handle, uint8_t op)
     struct ble_gattc_proc *proc;
     struct ble_gattc_proc *prev;
 
+    /* Only the parent task is allowed to remove entries from the list. */
+    BLE_HS_DBG_ASSERT(ble_hs_is_parent_task());
+
     ble_hs_lock();
 
     prev = NULL;
@@ -679,6 +715,9 @@ ble_gattc_extract_by_conn(uint16_t conn_handle,
     struct ble_gattc_proc *prev;
     struct ble_gattc_proc *next;
 
+    /* Only the parent task is allowed to remove entries from the list. */
+    BLE_HS_DBG_ASSERT(ble_hs_is_parent_task());
+
     STAILQ_INIT(dst_list);
 
     ble_hs_lock();
@@ -714,6 +753,9 @@ ble_gattc_extract_expired(struct ble_gattc_proc_list *dst_list)
     uint32_t now;
     int32_t time_diff;
 
+    /* Only the parent task is allowed to remove entries from the list. */
+    BLE_HS_DBG_ASSERT(ble_hs_is_parent_task());
+
     now = os_time_get();
     STAILQ_INIT(dst_list);
 
@@ -750,6 +792,9 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle,
     struct ble_gattc_proc *prev;
     const void *rx_entry;
 
+    /* Only the parent task is allowed to remove entries from the list. */
+    BLE_HS_DBG_ASSERT(ble_hs_is_parent_task());
+
     ble_hs_lock();
 
     prev = NULL;
@@ -778,9 +823,9 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle,
 }
 
 /**
- * Searches the main proc list for an "expecting" entry whose connection handle
- * and op code match those specified.  If a matching entry is found, it is
- * removed from the list and returned.
+ * Searches the main proc list for an entry whose connection handle and op code
+ * match those specified.  If a matching entry is found, it is removed from the
+ * list and returned.
  *
  * @param conn_handle           The connection handle to match against.
  * @param rx_entries            The array of rx entries corresponding to the
@@ -803,7 +848,7 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle,
  * All procedures that failed due to memory exaustion have their pending flag
  * set so they can be retried.
  *
- * All procedures that have been expecting a response for longer than five
+ * All procedures that have been expecting a response for longer than 30
  * seconds are aborted, and their corresponding connection is terminated.
  *
  * Called by the host heartbeat timer; executed every second.
@@ -867,6 +912,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, mtu_fail);
@@ -889,6 +935,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
 static void
 ble_gattc_mtu_err(struct ble_gattc_proc *proc, int status, uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_mtu_cb(proc, status, att_handle, 0);
 }
 
@@ -969,6 +1016,7 @@ ble_gattc_disc_all_svcs_cb(struct ble_gattc_proc *proc,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_svcs_fail);
@@ -995,6 +1043,8 @@ ble_gattc_disc_all_svcs_go(struct ble_gattc_proc *proc, int cb_on_err)
     uint8_t uuid128[16];
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     rc = ble_uuid_16_to_128(BLE_ATT_UUID_PRIMARY_SERVICE, uuid128);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 
@@ -1020,6 +1070,8 @@ static void
 ble_gattc_disc_all_svcs_err(struct ble_gattc_proc *proc, int status,
                             uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
         /* Discovery is complete. */
         status = 0;
@@ -1041,6 +1093,8 @@ ble_gattc_disc_all_svcs_rx_adata(struct ble_gattc_proc *proc,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     switch (adata->value_len) {
     case 2:
         uuid16 = le16toh(adata->value);
@@ -1090,6 +1144,8 @@ ble_gattc_disc_all_svcs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0 || proc->disc_all_svcs.prev_handle == 0xffff) {
         /* Error or all svcs discovered. */
         ble_gattc_disc_all_svcs_cb(proc, status, 0, NULL);
@@ -1174,6 +1230,7 @@ ble_gattc_disc_svc_uuid_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_svc_uuid_fail);
@@ -1199,6 +1256,8 @@ ble_gattc_disc_svc_uuid_go(struct ble_gattc_proc *proc, int cb_on_err)
     struct ble_att_find_type_value_req req;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     req.bavq_start_handle = proc->disc_svc_uuid.prev_handle + 1;
     req.bavq_end_handle = 0xffff;
     req.bavq_attr_type = BLE_ATT_UUID_PRIMARY_SERVICE;
@@ -1223,6 +1282,8 @@ static void
 ble_gattc_disc_svc_uuid_err(struct ble_gattc_proc *proc, int status,
                             uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
         /* Discovery is complete. */
         status = 0;
@@ -1243,6 +1304,8 @@ ble_gattc_disc_svc_uuid_rx_hinfo(struct ble_gattc_proc *proc,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (hinfo->group_end_handle <= proc->disc_svc_uuid.prev_handle) {
         /* Peer sent services out of order; terminate procedure. */
         rc = BLE_HS_EBADDATA;
@@ -1275,6 +1338,8 @@ ble_gattc_disc_svc_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0 || proc->disc_svc_uuid.prev_handle == 0xffff) {
         /* Error or all svcs discovered. */
         ble_gattc_disc_svc_uuid_cb(proc, status, 0, NULL);
@@ -1360,6 +1425,7 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, find_inc_svcs_fail);
@@ -1387,6 +1453,8 @@ ble_gattc_find_inc_svcs_go(struct ble_gattc_proc *proc, int cb_on_err)
     uint8_t uuid128[16];
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (proc->find_inc_svcs.cur_start == 0) {
         /* Find the next included service. */
         read_type_req.batq_start_handle =
@@ -1422,6 +1490,8 @@ static void
 ble_gattc_find_inc_svcs_err(struct ble_gattc_proc *proc, int status,
                             uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (proc->find_inc_svcs.cur_start == 0 &&
         status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
 
@@ -1444,6 +1514,8 @@ ble_gattc_find_inc_svcs_rx_read_rsp(struct ble_gattc_proc *proc, int status,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (proc->find_inc_svcs.cur_start == 0) {
         /* Unexpected read response; terminate procedure. */
         rc = BLE_HS_EBADDATA;
@@ -1498,6 +1570,8 @@ ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (proc->find_inc_svcs.cur_start != 0) {
         /* We only read one 128-bit UUID service at a time.  Ignore the
          * additional services in the response.
@@ -1567,6 +1641,8 @@ ble_gattc_find_inc_svcs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0 || proc->find_inc_svcs.prev_handle == 0xffff) {
         /* Error or all svcs discovered. */
         ble_gattc_find_inc_svcs_cb(proc, status, 0, NULL);
@@ -1655,6 +1731,7 @@ ble_gattc_disc_all_chrs_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_chrs_fail);
@@ -1682,6 +1759,8 @@ ble_gattc_disc_all_chrs_go(struct ble_gattc_proc *proc, int cb_on_err)
     uint8_t uuid128[16];
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 
@@ -1708,6 +1787,8 @@ static void
 ble_gattc_disc_all_chrs_err(struct ble_gattc_proc *proc, int status,
                             uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
         /* Discovery is complete. */
         status = 0;
@@ -1729,6 +1810,8 @@ ble_gattc_disc_all_chrs_rx_adata(struct ble_gattc_proc *proc,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     memset(&chr, 0, sizeof chr);
     chr.decl_handle = adata->att_handle;
 
@@ -1781,6 +1864,8 @@ ble_gattc_disc_all_chrs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0 ||
         proc->disc_all_chrs.prev_handle == proc->disc_all_chrs.end_handle) {
 
@@ -1871,6 +1956,7 @@ ble_gattc_disc_chr_uuid_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_chrs_uuid_fail);
@@ -1898,6 +1984,8 @@ ble_gattc_disc_chr_uuid_go(struct ble_gattc_proc *proc, int cb_on_err)
     uint8_t uuid128[16];
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);
 
@@ -1924,6 +2012,8 @@ static void
 ble_gattc_disc_chr_uuid_err(struct ble_gattc_proc *proc, int status,
                             uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
         /* Discovery is complete. */
         status = 0;
@@ -1945,6 +2035,8 @@ ble_gattc_disc_chr_uuid_rx_adata(struct ble_gattc_proc *proc,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     memset(&chr, 0, sizeof chr);
     chr.decl_handle = adata->att_handle;
 
@@ -2005,6 +2097,8 @@ ble_gattc_disc_chr_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0 ||
         proc->disc_chr_uuid.prev_handle == proc->disc_chr_uuid.end_handle) {
 
@@ -2098,6 +2192,7 @@ ble_gattc_disc_all_dscs_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_dscs_fail);
@@ -2124,6 +2219,8 @@ ble_gattc_disc_all_dscs_go(struct ble_gattc_proc *proc, int cb_on_err)
     struct ble_att_find_info_req req;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     req.bafq_start_handle = proc->disc_all_dscs.prev_handle + 1;
     req.bafq_end_handle = proc->disc_all_dscs.end_handle;
 
@@ -2146,6 +2243,8 @@ static void
 ble_gattc_disc_all_dscs_err(struct ble_gattc_proc *proc, int status,
                             uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
         /* Discovery is complete. */
         status = 0;
@@ -2166,6 +2265,8 @@ ble_gattc_disc_all_dscs_rx_idata(struct ble_gattc_proc *proc,
     int cbrc;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (idata->attr_handle <= proc->disc_all_dscs.prev_handle) {
         /* Peer sent descriptors out of order; terminate procedure. */
         rc = BLE_HS_EBADDATA;
@@ -2196,6 +2297,8 @@ ble_gattc_disc_all_dscs_rx_complete(struct ble_gattc_proc *proc, int status)
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0 ||
         proc->disc_all_dscs.prev_handle == proc->disc_all_dscs.end_handle) {
 
@@ -2287,6 +2390,7 @@ ble_gattc_read_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_fail);
@@ -2311,6 +2415,7 @@ static void
 ble_gattc_read_err(struct ble_gattc_proc *proc, int status,
                    uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_read_cb(proc, status, att_handle, NULL);
 }
 
@@ -2324,6 +2429,8 @@ ble_gattc_read_rx_read_rsp(struct ble_gattc_proc *proc, int status,
 {
     struct ble_gatt_attr attr;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     attr.handle = proc->read.handle;
     attr.offset = 0;
     attr.value_len = value_len;
@@ -2406,6 +2513,7 @@ ble_gattc_read_uuid_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_uuid_fail);
@@ -2430,6 +2538,8 @@ static void
 ble_gattc_read_uuid_err(struct ble_gattc_proc *proc, int status,
                         uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status == BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_FOUND)) {
         /* Read is complete. */
         status = 0;
@@ -2448,6 +2558,8 @@ ble_gattc_read_uuid_rx_adata(struct ble_gattc_proc *proc,
     struct ble_gatt_attr attr;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     attr.handle = adata->att_handle;
     attr.offset = 0;
     attr.value_len = adata->value_len;
@@ -2468,6 +2580,7 @@ ble_gattc_read_uuid_rx_adata(struct ble_gattc_proc *proc,
 static int
 ble_gattc_read_uuid_rx_complete(struct ble_gattc_proc *proc, int status)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_read_uuid_cb(proc, status, 0, NULL);
     return BLE_HS_EDONE;
 }
@@ -2547,6 +2660,7 @@ ble_gattc_read_long_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_long_fail);
@@ -2573,6 +2687,8 @@ ble_gattc_read_long_go(struct ble_gattc_proc *proc, int cb_on_err)
     struct ble_att_read_req read_req;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (proc->read_long.offset == 0) {
         read_req.barq_handle = proc->read_long.handle;
         rc = ble_att_clt_tx_read(proc->conn_handle, &read_req);
@@ -2600,6 +2716,7 @@ static void
 ble_gattc_read_long_err(struct ble_gattc_proc *proc, int status,
                         uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_read_long_cb(proc, status, att_handle, NULL);
 }
 
@@ -2615,6 +2732,8 @@ ble_gattc_read_long_rx_read_rsp(struct ble_gattc_proc *proc, int status,
     uint16_t mtu;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     attr.handle = proc->read_long.handle;
     attr.offset = proc->read_long.offset;
     attr.value_len = value_len;
@@ -2721,6 +2840,7 @@ ble_gattc_read_mult_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_mult_fail);
@@ -2755,6 +2875,7 @@ static void
 ble_gattc_read_mult_err(struct ble_gattc_proc *proc, int status,
                         uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_read_mult_cb(proc, status, att_handle, NULL, 0);
 }
 
@@ -2870,6 +2991,7 @@ ble_gattc_write_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_fail);
@@ -2896,6 +3018,7 @@ static void
 ble_gattc_write_err(struct ble_gattc_proc *proc, int status,
                     uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_write_cb(proc, status, att_handle);
 }
 
@@ -2973,6 +3096,7 @@ ble_gattc_write_long_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_long_fail);
@@ -3003,6 +3127,8 @@ ble_gattc_write_long_go(struct ble_gattc_proc *proc, int cb_on_err)
     int max_sz;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (proc->write_long.attr.offset < proc->write_long.attr.value_len) {
         max_sz = ble_att_mtu(proc->conn_handle) -
                  BLE_ATT_PREP_WRITE_CMD_BASE_SZ;
@@ -3049,6 +3175,7 @@ static void
 ble_gattc_write_long_err(struct ble_gattc_proc *proc, int status,
                          uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_write_long_cb(proc, status, att_handle);
 }
 
@@ -3063,6 +3190,8 @@ ble_gattc_write_long_rx_prep(struct ble_gattc_proc *proc,
 {
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0) {
         rc = status;
         goto err;
@@ -3113,6 +3242,7 @@ err:
 static int
 ble_gattc_write_long_rx_exec(struct ble_gattc_proc *proc, int status)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_write_long_cb(proc, status, 0);
     return BLE_HS_EDONE;
 }
@@ -3192,6 +3322,7 @@ ble_gattc_write_reliable_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_reliable_fail);
@@ -3223,6 +3354,8 @@ ble_gattc_write_reliable_go(struct ble_gattc_proc *proc, int cb_on_err)
     int attr_idx;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     attr_idx = proc->write_reliable.cur_attr;
     if (attr_idx < proc->write_reliable.num_attrs) {
         attr = proc->write_reliable.attrs + attr_idx;
@@ -3269,6 +3402,8 @@ ble_gattc_write_reliable_rx_prep(struct ble_gattc_proc *proc,
     struct ble_gatt_attr *attr;
     int rc;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     if (status != 0) {
         rc = status;
         goto err;
@@ -3320,6 +3455,7 @@ err:
 static int
 ble_gattc_write_reliable_rx_exec(struct ble_gattc_proc *proc, int status)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_write_reliable_cb(proc, status, 0);
     return BLE_HS_EDONE;
 }
@@ -3476,6 +3612,7 @@ ble_gattc_indicate_cb(struct ble_gattc_proc *proc, int status,
     int rc;
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, indicate_fail);
@@ -3501,10 +3638,11 @@ static void
 ble_gattc_indicate_err(struct ble_gattc_proc *proc, int status,
                        uint16_t att_handle)
 {
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
     ble_gattc_indicate_cb(proc, status, att_handle);
 }
 
- /**
+/**
  * Handles an incoming handle-value-confirmation for the specified indication
  * proc.
  */
@@ -3513,6 +3651,8 @@ ble_gattc_indicate_rx_rsp(struct ble_gattc_proc *proc)
 {
     struct ble_hs_conn *conn;
 
+    ble_gattc_dbg_assert_proc_not_inserted(proc);
+
     ble_gattc_indicate_cb(proc, 0, 0);
 
     ble_hs_lock();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee4fbed3/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index fbbc14d..3bf9f35 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -113,7 +113,7 @@ ble_hs_thread_safe(void)
 int
 ble_hs_is_parent_task(void)
 {
-    return os_sched_get_current_task() == ble_hs_parent_task;
+    return !os_started() || os_sched_get_current_task() == ble_hs_parent_task;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee4fbed3/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c
index 87774cb..3d7a0b9 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -23,6 +23,7 @@
 #include "testutil/testutil.h"
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
+#include "nimble/hci_transport.h"
 #include "host/host_hci.h"
 #include "ble_hs_test_util.h"
 
@@ -169,6 +170,29 @@ ble_hs_test_util_prev_hci_tx_clear(void)
     ble_hs_test_util_num_prev_hci_txes = 0;
 }
 
+static void
+ble_hs_test_util_rx_hci_evt(uint8_t *evt)
+{
+    uint8_t *evbuf;
+    int totlen;
+    int rc;
+
+    totlen = BLE_HCI_EVENT_HDR_LEN + evt[1];
+    TEST_ASSERT_FATAL(totlen <= UINT8_MAX + BLE_HCI_EVENT_HDR_LEN);
+
+    if (os_started()) {
+        evbuf = os_memblock_get(&g_hci_cmd_pool);
+        TEST_ASSERT_FATAL(evbuf != NULL);
+
+        memcpy(evbuf, evt, totlen);
+        rc = ble_hci_transport_ctlr_event_send(evbuf);
+    } else {
+        rc = host_hci_event_rx(evt);
+    }
+
+    TEST_ASSERT_FATAL(rc == 0);
+}
+
 void
 ble_hs_test_util_build_cmd_complete(uint8_t *dst, int len,
                                     uint8_t param_len, uint8_t num_pkts,
@@ -637,7 +661,6 @@ ble_hs_test_util_rx_num_completed_pkts_event(
     uint8_t buf[1024];
     int num_entries;
     int off;
-    int rc;
     int i;
 
     /* Count number of entries. */
@@ -662,8 +685,21 @@ ble_hs_test_util_rx_num_completed_pkts_event(
 
     buf[1] = off - 2;
 
-    rc = host_hci_event_rx(buf);
-    TEST_ASSERT(rc == 0);
+    ble_hs_test_util_rx_hci_evt(buf);
+}
+
+void
+ble_hs_test_util_rx_disconn_complete_event(struct hci_disconn_complete *evt)
+{
+    uint8_t buf[BLE_HCI_EVENT_HDR_LEN + BLE_HCI_EVENT_DISCONN_COMPLETE_LEN];
+
+    buf[0] = BLE_HCI_EVCODE_DISCONN_CMP;
+    buf[1] = BLE_HCI_EVENT_DISCONN_COMPLETE_LEN;
+    buf[2] = evt->status;
+    htole16(buf + 3, evt->connection_handle);
+    buf[5] = evt->reason;
+
+    ble_hs_test_util_rx_hci_evt(buf);
 }
 
 uint8_t *

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee4fbed3/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h
index 0dc5caf..c642c65 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -25,6 +25,7 @@
 #include "ble_hs_priv.h"
 struct ble_hs_conn;
 struct ble_l2cap_chan;
+struct hci_disconn_complete;
 
 struct os_eventq ble_hs_test_util_evq;
 
@@ -96,6 +97,8 @@ void ble_hs_test_util_rx_att_err_rsp(struct ble_hs_conn *conn, uint8_t req_op,
 void ble_hs_test_util_set_startup_acks(void);
 void ble_hs_test_util_rx_num_completed_pkts_event(
     struct ble_hs_test_util_num_completed_pkts_entry *entries);
+void ble_hs_test_util_rx_disconn_complete_event(
+    struct hci_disconn_complete *evt);
 uint8_t *ble_hs_test_util_verify_tx_hci(uint8_t ogf, uint16_t ocf,
                                         uint8_t *out_param_len);
 void ble_hs_test_util_tx_all(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee4fbed3/net/nimble/host/src/test/ble_os_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_os_test.c b/net/nimble/host/src/test/ble_os_test.c
index 8ce02b4..0bd2a1d 100644
--- a/net/nimble/host/src/test/ble_os_test.c
+++ b/net/nimble/host/src/test/ble_os_test.c
@@ -67,12 +67,12 @@ ble_os_test_misc_init(void)
 {
     ble_hs_test_util_init();
 
-    ble_os_test_init_app_task();
-
     /* Receive acknowledgements for the startup sequence.  We sent the
      * corresponding requests when the host task was started.
      */
     ble_hs_test_util_set_startup_acks();
+
+    ble_os_test_init_app_task();
 }
 
 static int
@@ -323,7 +323,7 @@ ble_gap_terminate_test_task_handler(void *arg)
     disconn_evt.connection_handle = 1;
     disconn_evt.status = 0;
     disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
-    ble_gap_rx_disconn_complete(&disconn_evt);
+    ble_hs_test_util_rx_disconn_complete_event(&disconn_evt);
     TEST_ASSERT(disconn_handle == 1);
     TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(1));
     TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(2));
@@ -334,7 +334,7 @@ ble_gap_terminate_test_task_handler(void *arg)
     disconn_evt.connection_handle = 2;
     disconn_evt.status = 0;
     disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
-    ble_gap_rx_disconn_complete(&disconn_evt);
+    ble_hs_test_util_rx_disconn_complete_event(&disconn_evt);
     TEST_ASSERT(disconn_handle == 2);
     TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(1));
     TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(2));


[4/4] incubator-mynewt-core git commit: BLE Host - Enforce thread safety in unit tests.

Posted by cc...@apache.org.
BLE Host - Enforce thread safety in unit tests.


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

Branch: refs/heads/develop
Commit: 2dd32b7dfe83359d0f9c7975a9c0c17205687a98
Parents: ee4fbed
Author: Christopher Collins <cc...@apache.org>
Authored: Fri May 13 16:04:27 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri May 13 17:53:01 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_att_clt.c               |  42 +-
 net/nimble/host/src/ble_att_cmd.c               |   2 +-
 net/nimble/host/src/ble_att_priv.h              |   6 +-
 net/nimble/host/src/ble_att_svr.c               |  41 +-
 net/nimble/host/src/ble_gap.c                   |  43 +-
 net/nimble/host/src/ble_gap_priv.h              |   1 -
 net/nimble/host/src/ble_gatt_priv.h             |   5 +-
 net/nimble/host/src/ble_gattc.c                 |  11 +-
 net/nimble/host/src/ble_gatts.c                 | 143 ++++-
 net/nimble/host/src/ble_hs.c                    |  36 +-
 net/nimble/host/src/ble_hs_atomic.c             |  31 +-
 net/nimble/host/src/ble_hs_atomic_priv.h        |   2 +
 net/nimble/host/src/ble_hs_conn.c               |   2 +-
 net/nimble/host/src/ble_hs_conn_priv.h          |   1 +
 net/nimble/host/src/ble_hs_priv.h               |   1 -
 net/nimble/host/src/ble_l2cap_sig.c             |   3 +-
 net/nimble/host/src/test/ble_att_clt_test.c     | 157 +++---
 net/nimble/host/src/test/ble_att_svr_test.c     | 565 ++++++++++---------
 net/nimble/host/src/test/ble_gap_test.c         |  60 +-
 net/nimble/host/src/test/ble_gatt_disc_c_test.c |  34 +-
 net/nimble/host/src/test/ble_gatt_disc_d_test.c |  22 +-
 net/nimble/host/src/test/ble_gatt_disc_s_test.c |  46 +-
 net/nimble/host/src/test/ble_gatt_find_s_test.c |  55 +-
 net/nimble/host/src/test/ble_gatt_read_test.c   | 115 ++--
 net/nimble/host/src/test/ble_gatt_write_test.c  |  90 ++-
 .../host/src/test/ble_gatts_notify_test.c       |  67 +--
 net/nimble/host/src/test/ble_hs_conn_test.c     |  40 +-
 net/nimble/host/src/test/ble_hs_test_util.c     |  48 +-
 net/nimble/host/src/test/ble_hs_test_util.h     |  16 +-
 net/nimble/host/src/test/ble_l2cap_sm_test.c    | 155 +++--
 net/nimble/host/src/test/ble_l2cap_test.c       | 206 ++++---
 31 files changed, 1148 insertions(+), 898 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index 1a95bdc..5f628c6 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -59,9 +59,6 @@ static int
 ble_att_clt_append_blob(uint16_t conn_handle, struct os_mbuf *txom,
                         void *blob, int blob_len)
 {
-    uint16_t mtu;
-    int extra_len;
-    int cmd_len;
     int rc;
 
     if (blob_len < 0) {
@@ -71,13 +68,6 @@ ble_att_clt_append_blob(uint16_t conn_handle, struct os_mbuf *txom,
         return 0;
     }
 
-    mtu = ble_att_mtu(conn_handle);
-    cmd_len = OS_MBUF_PKTLEN(txom) + blob_len;
-    extra_len = cmd_len - mtu;
-    if (extra_len > 0) {
-        blob_len -= extra_len;
-    }
-
     rc = os_mbuf_append(txom, blob, blob_len);
     if (rc != 0) {
         return rc;
@@ -110,10 +100,14 @@ ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void **out_attr_val,
 }
 
 static int
-ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
+ble_att_clt_tx_req_flags(uint16_t conn_handle, struct os_mbuf *txom,
+                         ble_hs_conn_flags_t flags_on_success)
 {
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
+    uint16_t total_len;
+    uint16_t mtu;
+    int extra_len;
     int rc;
 
     BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1);
@@ -123,8 +117,22 @@ ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
 
     rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (rc == 0) {
+        /* Reduce the size of the transmission to fit the connection's ATT
+         * MTU.
+         */
+        total_len = OS_MBUF_PKTLEN(txom);
+        mtu = ble_l2cap_chan_mtu(chan);
+        extra_len = total_len - mtu;
+        if (extra_len > 0) {
+            os_mbuf_adj(txom, -extra_len);
+        }
+
         rc = ble_l2cap_tx(conn, chan, txom);
         txom = NULL;
+
+        if (rc == 0) {
+            conn->bhc_flags |= flags_on_success;
+        }
     }
 
     ble_hs_unlock();
@@ -133,6 +141,15 @@ ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
     return rc;
 }
 
+static int
+ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
+{
+    int rc;
+
+    rc = ble_att_clt_tx_req_flags(conn_handle, txom, 0);
+    return rc;
+}
+
 /*****************************************************************************
  * $error response                                                           *
  *****************************************************************************/
@@ -1437,7 +1454,8 @@ ble_att_clt_tx_indicate(uint16_t conn_handle,
         return rc;
     }
 
-    rc = ble_att_clt_tx_req(conn_handle, txom);
+    rc = ble_att_clt_tx_req_flags(conn_handle, txom,
+                                  BLE_HS_CONN_F_INDICATE_TXED);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_att_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_cmd.c b/net/nimble/host/src/ble_att_cmd.c
index 9fa6b21..2384ce1 100644
--- a/net/nimble/host/src/ble_att_cmd.c
+++ b/net/nimble/host/src/ble_att_cmd.c
@@ -614,7 +614,7 @@ ble_att_indicate_req_parse(void *payload, int len,
 
 void
 ble_att_indicate_req_write(void *payload, int len,
-                         struct ble_att_indicate_req *src)
+                           struct ble_att_indicate_req *src)
 {
     struct ble_att_indicate_req *dst;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h
index 77b5935..3cc19e9 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -115,9 +115,11 @@ struct ble_att_prep_entry {
     struct os_mbuf *bape_value;
 };
 
+SLIST_HEAD(ble_att_prep_entry_list, ble_att_prep_entry);
+
 struct ble_att_svr_conn {
     /** This list is sorted by attribute handle ID. */
-    SLIST_HEAD(, ble_att_prep_entry) basc_prep_list;
+    struct ble_att_prep_entry_list basc_prep_list;
     uint32_t basc_prep_write_rx_time;
 };
 
@@ -184,7 +186,7 @@ int ble_att_svr_rx_notify(uint16_t conn_handle,
                           struct os_mbuf **rxom);
 int ble_att_svr_rx_indicate(uint16_t conn_handle,
                             struct os_mbuf **rxom);
-void ble_att_svr_prep_clear(struct ble_att_svr_conn *basc);
+void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list);
 int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
                             struct ble_att_svr_access_ctxt *ctxt,
                             uint8_t *out_att_err);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index 76bf0e8..7690a27 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -2212,12 +2212,12 @@ ble_att_svr_prep_find_prev(struct ble_att_svr_conn *basc, uint16_t handle,
 }
 
 void
-ble_att_svr_prep_clear(struct ble_att_svr_conn *basc)
+ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list)
 {
     struct ble_att_prep_entry *entry;
 
-    while ((entry = SLIST_FIRST(&basc->basc_prep_list)) != NULL) {
-        SLIST_REMOVE_HEAD(&basc->basc_prep_list, bape_next);
+    while ((entry = SLIST_FIRST(prep_list)) != NULL) {
+        SLIST_REMOVE_HEAD(prep_list, bape_next);
         ble_att_svr_prep_free(entry);
     }
 }
@@ -2226,14 +2226,15 @@ ble_att_svr_prep_clear(struct ble_att_svr_conn *basc)
  * @return                      0 on success; ATT error code on failure.
  */
 static int
-ble_att_svr_prep_validate(struct ble_att_svr_conn *basc, uint16_t *err_handle)
+ble_att_svr_prep_validate(struct ble_att_prep_entry_list *prep_list,
+                          uint16_t *err_handle)
 {
     struct ble_att_prep_entry *entry;
     struct ble_att_prep_entry *prev;
     int cur_len;
 
     prev = NULL;
-    SLIST_FOREACH(entry, &basc->basc_prep_list, bape_next) {
+    SLIST_FOREACH(entry, prep_list, bape_next) {
         if (prev == NULL || prev->bape_handle != entry->bape_handle) {
             /* Ensure attribute write starts at offset 0. */
             if (entry->bape_offset != 0) {
@@ -2266,7 +2267,9 @@ ble_att_svr_prep_validate(struct ble_att_svr_conn *basc, uint16_t *err_handle)
  * @return                      0 on success; ATT error code on failure.
  */
 static int
-ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
+ble_att_svr_prep_write(uint16_t conn_handle,
+                       struct ble_att_prep_entry_list *prep_list,
+                       uint16_t *err_handle)
 {
     struct ble_att_svr_access_ctxt ctxt;
     struct ble_att_prep_entry *entry;
@@ -2280,7 +2283,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
     *err_handle = 0; /* Silence unnecessary warning. */
 
     /* First, validate the contents of the prepare queue. */
-    rc = ble_att_svr_prep_validate(&conn->bhc_att_svr, err_handle);
+    rc = ble_att_svr_prep_validate(prep_list, err_handle);
     if (rc != 0) {
         return rc;
     }
@@ -2289,7 +2292,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
 
     /* Contents are valid; perform the writes. */
     buf_off = 0;
-    entry = SLIST_FIRST(&conn->bhc_att_svr.basc_prep_list);
+    entry = SLIST_FIRST(prep_list);
     while (entry != NULL) {
         next = SLIST_NEXT(entry, bape_next);
 
@@ -2309,7 +2312,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
 
             ctxt.attr_data = flat_buf;
             ctxt.data_len = buf_off;
-            rc = ble_att_svr_write(conn->bhc_handle, attr, &ctxt, &att_err);
+            rc = ble_att_svr_write(conn_handle, attr, &ctxt, &att_err);
             if (rc != 0) {
                 *err_handle = entry->bape_handle;
                 return att_err;
@@ -2506,6 +2509,7 @@ ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
     return BLE_HS_ENOTSUP;
 #endif
 
+    struct ble_att_prep_entry_list prep_list;
     struct ble_att_exec_write_req req;
     struct ble_hs_conn *conn;
     struct os_mbuf *txom;
@@ -2540,18 +2544,29 @@ done:
         if (conn == NULL) {
             rc = BLE_HS_ENOTCONN;
         } else {
+            /* Extract the list of prepared writes from the connection so
+             * that they can be processed after the mutex is unlocked.  They
+             * aren't processed now because attribute writes involve executing
+             * an application callback.
+             */
+            prep_list = conn->bhc_att_svr.basc_prep_list;
+            SLIST_INIT(&conn->bhc_att_svr.basc_prep_list);
+        }
+        ble_hs_unlock();
+
+        if (conn != NULL) {
             if (req.baeq_flags & BLE_ATT_EXEC_WRITE_F_CONFIRM) {
                 /* Perform attribute writes. */
-                att_err = ble_att_svr_prep_write(conn, &err_handle);
+                att_err = ble_att_svr_prep_write(conn_handle, &prep_list,
+                                                 &err_handle);
                 if (att_err != 0) {
                     rc = BLE_HS_EAPP;
                 }
             }
 
-            /* Erase all prep entries. */
-            ble_att_svr_prep_clear(&conn->bhc_att_svr);
+            /* Free the prep entries. */
+            ble_att_svr_prep_clear(&prep_list);
         }
-        ble_hs_unlock();
     }
 
     rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c
index a0ca36c..14c921a 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -432,33 +432,6 @@ ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
     }
 }
 
-int
-ble_gap_update_in_progress(uint16_t conn_handle)
-{
-    struct ble_hs_conn *conn;
-
-    conn = ble_hs_conn_find(conn_handle);
-    return conn != NULL && conn->bhc_flags & BLE_HS_CONN_F_UPDATE;
-}
-
-static int
-ble_gap_update_set_flag(uint16_t conn_handle, int val)
-{
-    struct ble_hs_conn *conn;
-
-    conn = ble_hs_conn_find(conn_handle);
-    if (conn == NULL) {
-        return BLE_HS_ENOTCONN;
-    } else {
-        if (val) {
-            conn->bhc_flags |= BLE_HS_CONN_F_UPDATE;
-        } else {
-            conn->bhc_flags &= ~BLE_HS_CONN_F_UPDATE;
-        }
-        return 0;
-    }
-}
-
 static void
 ble_gap_update_notify(uint16_t conn_handle, int status)
 {
@@ -514,7 +487,7 @@ static void
 ble_gap_update_failed(uint16_t conn_handle, int status)
 {
     STATS_INC(ble_gap_stats, update_fail);
-    ble_gap_update_set_flag(conn_handle, 0);
+    ble_hs_atomic_conn_set_flags(conn_handle, BLE_HS_CONN_F_UPDATE, 0);
     ble_gap_update_notify(conn_handle, status);
 }
 
@@ -600,7 +573,8 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
         ble_gap_conn_to_snapshot(conn, &snap);
     }
 
-    ble_gap_update_set_flag(evt->connection_handle, 0);
+    conn->bhc_flags &= ~BLE_HS_CONN_F_UPDATE;
+
     ble_hs_unlock();
 
     if (conn != NULL) {
@@ -1913,7 +1887,8 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
         if (rc != 0) {
             ble_gap_update_failed(evt->connection_handle, rc);
         } else {
-            ble_gap_update_set_flag(evt->connection_handle, 1);
+            ble_hs_atomic_conn_set_flags(evt->connection_handle,
+                                         BLE_HS_CONN_F_UPDATE, 1);
         }
     } else {
         ble_gap_tx_param_neg_reply(evt->connection_handle, reject_reason);
@@ -1955,18 +1930,20 @@ ble_gap_update_params(uint16_t conn_handle, struct ble_gap_upd_params *params)
     return BLE_HS_ENOTSUP;
 #endif
 
+    struct ble_hs_conn *conn;
     int rc;
 
     ble_hs_lock();
 
     STATS_INC(ble_gap_stats, update);
 
-    if (!ble_hs_conn_exists(conn_handle)) {
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn == NULL) {
         rc = BLE_HS_ENOTCONN;
         goto done;
     }
 
-    if (ble_gap_update_in_progress(conn_handle)) {
+    if (conn->bhc_flags & BLE_HS_CONN_F_UPDATE) {
         rc = BLE_HS_EALREADY;
         goto done;
     }
@@ -1980,7 +1957,7 @@ ble_gap_update_params(uint16_t conn_handle, struct ble_gap_upd_params *params)
         goto done;
     }
 
-    ble_gap_update_set_flag(conn_handle, 1);
+    conn->bhc_flags |= BLE_HS_CONN_F_UPDATE;
 
 done:
     if (rc != 0) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_gap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h
index e84a276..d54328d 100644
--- a/net/nimble/host/src/ble_gap_priv.h
+++ b/net/nimble/host/src/ble_gap_priv.h
@@ -84,7 +84,6 @@ int ble_gap_ltk_event(uint16_t conn_handle,
                       struct ble_gap_ltk_params *ltk_params);
 int ble_gap_master_in_progress(void);
 int ble_gap_slave_in_progress(void);
-int ble_gap_update_in_progress(uint16_t conn_handle);
 
 void ble_gap_heartbeat(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_gatt_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt_priv.h b/net/nimble/host/src/ble_gatt_priv.h
index 44f79ec..9a4c4fb 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -91,11 +91,8 @@ typedef uint8_t ble_gatts_conn_flags;
 struct ble_gatts_conn {
     struct ble_gatts_clt_cfg *clt_cfgs;
     int num_clt_cfgs;
-    ble_gatts_conn_flags flags;
 };
 
-#define BLE_GATTS_CONN_F_INDICATION_TXED        0x01
-
 /*** @client. */
 int ble_gattc_locked_by_cur_task(void);
 int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, void *value,
@@ -145,7 +142,7 @@ int ble_gattc_init(void);
 #define BLE_GATTS_INC_SVC_LEN_NO_UUID           4
 #define BLE_GATTS_INC_SVC_LEN_UUID              6
 
-void ble_gatts_send_notifications(struct ble_hs_conn *conn);
+void ble_gatts_send_updates_for_conn(uint16_t conn_handle);
 
 /*** @misc. */
 void ble_gatts_conn_deinit(struct ble_gatts_conn *gatts_conn);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index 4e23f90..7bfd2dd 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -3658,12 +3658,14 @@ ble_gattc_indicate_rx_rsp(struct ble_gattc_proc *proc)
     ble_hs_lock();
     conn = ble_hs_conn_find(proc->conn_handle);
     if (conn != NULL) {
-        conn->bhc_gatt_svr.flags &= ~BLE_GATTS_CONN_F_INDICATION_TXED;
-
-        /* Send the next indication if one is pending. */
-        ble_gatts_send_notifications(conn);
+        conn->bhc_flags &= ~BLE_HS_CONN_F_INDICATE_TXED;
     }
     ble_hs_unlock();
+
+    /* Send the next indication if one is pending. */
+    if (conn != NULL) {
+        ble_gatts_send_updates_for_conn(proc->conn_handle);
+    }
 }
 
 /**
@@ -3702,6 +3704,7 @@ ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle,
                                  &ctxt, NULL);
     if (rc != 0) {
         /* Fatal error; application disallowed attribute read. */
+        BLE_HS_DBG_ASSERT(0);
         rc = BLE_HS_EAPP;
         goto done;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index b0d5c7c..f6fad75 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -980,39 +980,83 @@ ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn)
     return 0;
 }
 
-void
-ble_gatts_send_notifications(struct ble_hs_conn *conn)
+static int
+ble_gatts_send_one_update(uint16_t conn_handle)
 {
     struct ble_gatts_clt_cfg *clt_cfg;
+    struct ble_hs_conn *conn;
+    uint16_t chr_val_handle;
+    uint8_t att_op;
     int rc;
     int i;
 
-    /* Iterate through each configurable characteristic.  If a characteristic
-     * has been updated, try to send an indication or notification
-     * (never both).
-     */
-    for (i = 0; i < conn->bhc_gatt_svr.num_clt_cfgs; i++) {
-        clt_cfg = conn->bhc_gatt_svr.clt_cfgs + i;
+    /* Silence spurious gcc warning. */
+    chr_val_handle = 0;
 
-        if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_UPDATED) {
-            if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_INDICATE) {
-                if (!(conn->bhc_gatt_svr.flags &
-                      BLE_GATTS_CONN_F_INDICATION_TXED)) {
+    /* Assume no pending updates. */
+    att_op = 0;
 
-                    rc = ble_gattc_indicate(conn->bhc_handle,
-                                            clt_cfg->chr_def_handle + 1,
-                                            NULL, NULL);
-                    if (rc == 0) {
-                        conn->bhc_gatt_svr.flags |=
-                            BLE_GATTS_CONN_F_INDICATION_TXED;
-                        clt_cfg->flags &= ~BLE_GATTS_CLT_CFG_F_UPDATED;
-                    }
+    ble_hs_lock();
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn != NULL) {
+        for (i = 0; i < conn->bhc_gatt_svr.num_clt_cfgs; i++) {
+            clt_cfg = conn->bhc_gatt_svr.clt_cfgs + i;
+            if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_UPDATED) {
+                if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_NOTIFY) {
+                    att_op = BLE_ATT_OP_NOTIFY_REQ;
+                } else if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_INDICATE &&
+                           !(conn->bhc_flags & BLE_HS_CONN_F_INDICATE_TXED)) {
+                    att_op = BLE_ATT_OP_INDICATE_REQ;
                 }
-            } else if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_NOTIFY) {
-                rc = ble_gattc_notify(conn->bhc_handle,
-                                      clt_cfg->chr_def_handle + 1);
-                if (rc == 0) {
+
+                if (att_op != 0) {
+                    chr_val_handle = clt_cfg->chr_def_handle + 1;
                     clt_cfg->flags &= ~BLE_GATTS_CLT_CFG_F_UPDATED;
+                    break;
+                }
+            }
+        }
+    }
+    ble_hs_unlock();
+
+    switch (att_op) {
+    case 0:
+        return BLE_HS_EDONE;
+
+    case BLE_ATT_OP_NOTIFY_REQ:
+        rc = ble_gattc_notify(conn_handle, chr_val_handle);
+        return rc;
+        
+    case BLE_ATT_OP_INDICATE_REQ:
+        rc = ble_gattc_indicate(conn_handle, chr_val_handle, NULL, NULL);
+        return rc;
+
+    default:
+        BLE_HS_DBG_ASSERT(0);
+        return BLE_HS_EUNKNOWN;
+    }
+}
+
+static void
+ble_gatts_send_updates(uint16_t *conn_handles, int num_conns)
+{
+    int more_sends;
+    int rc;
+    int i;
+
+    more_sends = 1;
+
+    while (more_sends) {
+        for (i = 0; i < num_conns; i++) {
+            more_sends = 0;
+            for (i = 0; i < num_conns; i++) {
+                if (conn_handles[i] != BLE_HS_CONN_HANDLE_NONE) {
+                    rc = ble_gatts_send_one_update(conn_handles[i]);
+                    if (rc == 0) {
+                        more_sends = 1;
+                    } else {
+                        conn_handles[i] = BLE_HS_CONN_HANDLE_NONE;
+                    }
                 }
             }
         }
@@ -1020,10 +1064,47 @@ ble_gatts_send_notifications(struct ble_hs_conn *conn)
 }
 
 void
+ble_gatts_send_updates_for_conn(uint16_t conn_handle)
+{
+    ble_gatts_send_updates(&conn_handle, 1);
+}
+
+static int
+ble_gatts_conns_with_pending_updates(uint16_t *conn_handles)
+{
+    struct ble_gatts_clt_cfg *clt_cfg;
+    struct ble_hs_conn *conn;
+    int num_conns;
+    int i;
+
+    num_conns = 0;
+
+    for (conn = ble_hs_conn_first();
+         conn != NULL;
+         conn = SLIST_NEXT(conn, bhc_next)) {
+
+        /* XXX: Consider caching this information as a connection flag. */
+        for (i = 0; i < conn->bhc_gatt_svr.num_clt_cfgs; i++) {
+            clt_cfg = conn->bhc_gatt_svr.clt_cfgs + i;
+
+            if (clt_cfg->flags & BLE_GATTS_CLT_CFG_F_UPDATED) {
+                conn_handles[num_conns++] = conn->bhc_handle;
+                break;
+            }
+        }
+    }
+
+    return num_conns;
+}
+
+void
 ble_gatts_chr_updated(uint16_t chr_def_handle)
 {
     struct ble_gatts_clt_cfg *clt_cfg;
     struct ble_hs_conn *conn;
+    uint16_t conn_handles[NIMBLE_OPT_MAX_CONNECTIONS];
+    int any_updates;
+    int num_conns;
     int idx;
 
     /* Determine if notifications / indications are enabled for this
@@ -1034,6 +1115,9 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
         return;
     }
 
+    /* Assume no peers are subscribed to this characteristic. */
+    any_updates = 0;
+
     ble_hs_lock();
 
     for (conn = ble_hs_conn_first();
@@ -1048,12 +1132,19 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
             (BLE_GATTS_CLT_CFG_F_NOTIFY | BLE_GATTS_CLT_CFG_F_INDICATE)) {
 
             clt_cfg->flags |= BLE_GATTS_CLT_CFG_F_UPDATED;
-
-            ble_gatts_send_notifications(conn);
+            any_updates = 1;
         }
     }
 
+    if (any_updates) {
+        num_conns = ble_gatts_conns_with_pending_updates(conn_handles);
+    }
+
     ble_hs_unlock();
+
+    if (any_updates) {
+        ble_gatts_send_updates(conn_handles, num_conns);
+    }
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index 3bf9f35..bc83153 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -76,6 +76,10 @@ static struct os_mqueue ble_hs_tx_q;
 
 static struct os_mutex ble_hs_mutex;
 
+#if BLE_HS_DEBUG
+static uint8_t ble_hs_dbg_mutex_locked;
+#endif
+
 STATS_SECT_DECL(ble_hs_stats) ble_hs_stats;
 STATS_NAME_START(ble_hs_stats)
     STATS_NAME(ble_hs_stats, conn_create)
@@ -87,16 +91,16 @@ STATS_NAME_START(ble_hs_stats)
 STATS_NAME_END(ble_hs_stats)
 
 int
-ble_hs_locked(void)
-{
-    return ble_hs_mutex.mu_level > 0;
-}
-
-int
 ble_hs_locked_by_cur_task(void)
 {
     struct os_task *owner;
 
+#if BLE_HS_DEBUG
+    if (!os_started()) {
+        return ble_hs_dbg_mutex_locked;
+    }
+#endif
+
     owner = ble_hs_mutex.mu_owner;
     return owner != NULL && owner == os_sched_get_current_task();
 }
@@ -104,7 +108,7 @@ ble_hs_locked_by_cur_task(void)
 int
 ble_hs_thread_safe(void)
 {
-    return !os_started() || ble_hs_locked_by_cur_task();
+    return ble_hs_locked_by_cur_task();
 }
 
 /**
@@ -123,6 +127,13 @@ ble_hs_lock(void)
 
     BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
+#if BLE_HS_DEBUG
+    if (!os_started()) {
+        ble_hs_dbg_mutex_locked = 1;
+        return;
+    }
+#endif
+
     rc = os_mutex_pend(&ble_hs_mutex, 0xffffffff);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
 }
@@ -132,6 +143,14 @@ ble_hs_unlock(void)
 {
     int rc;
 
+#if BLE_HS_DEBUG
+    if (!os_started()) {
+        BLE_HS_DBG_ASSERT(ble_hs_dbg_mutex_locked);
+        ble_hs_dbg_mutex_locked = 0;
+        return;
+    }
+#endif
+
     rc = os_mutex_release(&ble_hs_mutex);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
 }
@@ -411,6 +430,9 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
         rc = BLE_HS_EOS;
         goto err;
     }
+#if BLE_HS_DEBUG
+    ble_hs_dbg_mutex_locked = 0;
+#endif
 
     return 0;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_hs_atomic.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.c b/net/nimble/host/src/ble_hs_atomic.c
index a09eaad..36a603d 100644
--- a/net/nimble/host/src/ble_hs_atomic.c
+++ b/net/nimble/host/src/ble_hs_atomic.c
@@ -57,7 +57,36 @@ ble_hs_atomic_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
         rc = BLE_HS_ENOTCONN;
     } else {
         rc = 0;
-        *out_flags = conn->bhc_flags;
+        if (out_flags != NULL) {
+            *out_flags = conn->bhc_flags;
+        }
+    }
+
+    ble_hs_unlock();
+
+    return rc;
+}
+
+int
+ble_hs_atomic_conn_set_flags(uint16_t conn_handle, ble_hs_conn_flags_t flags,
+                             int on)
+{
+    struct ble_hs_conn *conn;
+    int rc;
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn == NULL) {
+        rc = BLE_HS_ENOTCONN;
+    } else {
+        rc = 0;
+
+        if (on) {
+            conn->bhc_flags |= flags;
+        } else {
+            conn->bhc_flags &= ~flags;
+        }
     }
 
     ble_hs_unlock();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_hs_atomic_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic_priv.h b/net/nimble/host/src/ble_hs_atomic_priv.h
index 63a9a36..a08b7ca 100644
--- a/net/nimble/host/src/ble_hs_atomic_priv.h
+++ b/net/nimble/host/src/ble_hs_atomic_priv.h
@@ -26,5 +26,7 @@ int ble_hs_atomic_conn_delete(uint16_t conn_handle);
 void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
 int ble_hs_atomic_conn_flags(uint16_t conn_handle,
                              ble_hs_conn_flags_t *out_flags);
+int ble_hs_atomic_conn_set_flags(uint16_t conn_handle,
+                                 ble_hs_conn_flags_t flags, int on);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 4071f45..567da51 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -187,7 +187,7 @@ ble_hs_conn_free(struct ble_hs_conn *conn)
 
     ble_gatts_conn_deinit(&conn->bhc_gatt_svr);
 
-    ble_att_svr_prep_clear(&conn->bhc_att_svr);
+    ble_att_svr_prep_clear(&conn->bhc_att_svr.basc_prep_list);
 
     while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) {
         ble_hs_conn_delete_chan(conn, chan);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_hs_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn_priv.h b/net/nimble/host/src/ble_hs_conn_priv.h
index aba0e94..12e3fb0 100644
--- a/net/nimble/host/src/ble_hs_conn_priv.h
+++ b/net/nimble/host/src/ble_hs_conn_priv.h
@@ -31,6 +31,7 @@ typedef uint8_t ble_hs_conn_flags_t;
 
 #define BLE_HS_CONN_F_MASTER        0x01
 #define BLE_HS_CONN_F_UPDATE        0x02
+#define BLE_HS_CONN_F_INDICATE_TXED 0x04
 
 struct ble_hs_conn {
     SLIST_ENTRY(ble_hs_conn) bhc_next;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index 024b964..a436028 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -95,7 +95,6 @@ int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
 
 void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
 
-int ble_hs_locked(void);
 int ble_hs_locked_by_cur_task(void);
 int ble_hs_thread_safe(void);
 int ble_hs_is_parent_task(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/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 13c830b..ddb69e7 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -166,9 +166,8 @@ ble_l2cap_sig_proc_free(struct ble_l2cap_sig_proc *proc)
 static void
 ble_l2cap_sig_proc_insert(struct ble_l2cap_sig_proc *proc)
 {
-    ble_hs_lock();
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
     STAILQ_INSERT_HEAD(&ble_l2cap_sig_procs, proc, next);
-    ble_hs_unlock();
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_att_clt_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_att_clt_test.c b/net/nimble/host/src/test/ble_att_clt_test.c
index cd19431..dcb402e 100644
--- a/net/nimble/host/src/test/ble_att_clt_test.c
+++ b/net/nimble/host/src/test/ble_att_clt_test.c
@@ -24,16 +24,16 @@
 #include "host/ble_hs_test.h"
 #include "ble_hs_test_util.h"
 
-static void
-ble_att_clt_test_misc_init(struct ble_hs_conn **conn,
-                           struct ble_l2cap_chan **att_chan)
+/**
+ * @return                      The handle of the new test connection.
+ */
+static uint16_t
+ble_att_clt_test_misc_init(void)
 {
     ble_hs_test_util_init();
-
-    *conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                         NULL, NULL);
-    *att_chan = ble_hs_conn_chan_find(*conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(*att_chan != NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL,
+                                 NULL);
+    return 2;
 }
 
 static void
@@ -76,48 +76,46 @@ ble_att_clt_test_tx_write_req_or_cmd(uint16_t conn_handle,
 TEST_CASE(ble_att_clt_test_tx_find_info)
 {
     struct ble_att_find_info_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Success. */
     req.bafq_start_handle = 1;
     req.bafq_end_handle = 0xffff;
-    rc = ble_att_clt_tx_find_info(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_find_info(conn_handle, &req);
     TEST_ASSERT(rc == 0);
 
     /*** Error: start handle of 0. */
     req.bafq_start_handle = 0;
     req.bafq_end_handle = 0xffff;
-    rc = ble_att_clt_tx_find_info(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_find_info(conn_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 
     /*** Error: start handle greater than end handle. */
     req.bafq_start_handle = 500;
     req.bafq_end_handle = 499;
-    rc = ble_att_clt_tx_find_info(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_find_info(conn_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 
     /*** Success; start and end handles equal. */
     req.bafq_start_handle = 500;
     req.bafq_end_handle = 500;
-    rc = ble_att_clt_tx_find_info(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_find_info(conn_handle, &req);
     TEST_ASSERT(rc == 0);
 }
 
 TEST_CASE(ble_att_clt_test_rx_find_info)
 {
     struct ble_att_find_info_rsp rsp;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[1024];
     uint8_t uuid128_1[16] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
     int off;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** One 128-bit UUID. */
     /* Receive response with attribute mapping. */
@@ -131,7 +129,8 @@ TEST_CASE(ble_att_clt_test_rx_find_info)
     memcpy(buf + off, uuid128_1, 16);
     off += 16;
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     /*** One 16-bit UUID. */
@@ -146,7 +145,8 @@ TEST_CASE(ble_att_clt_test_rx_find_info)
     htole16(buf + off, 0x000f);
     off += 2;
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     /*** Two 16-bit UUIDs. */
@@ -166,7 +166,8 @@ TEST_CASE(ble_att_clt_test_rx_find_info)
     htole16(buf + off, 0x0011);
     off += 2;
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 }
 
@@ -174,16 +175,15 @@ static void
 ble_att_clt_test_case_tx_write_req_or_cmd(int is_req)
 {
     struct ble_att_write_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t value300[500] = { 0 };
     uint8_t value5[5] = { 6, 7, 54, 34, 8 };
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** 5-byte write. */
     req.bawq_handle = 0x1234;
-    ble_att_clt_test_tx_write_req_or_cmd(conn->bhc_handle, &req, value5,
+    ble_att_clt_test_tx_write_req_or_cmd(conn_handle, &req, value5,
                                          sizeof value5, is_req);
     ble_hs_test_util_tx_all();
     ble_att_clt_test_misc_verify_tx_write(0x1234, value5, sizeof value5,
@@ -191,7 +191,7 @@ ble_att_clt_test_case_tx_write_req_or_cmd(int is_req)
 
     /*** Overlong write; verify command truncated to ATT MTU. */
     req.bawq_handle = 0xab83;
-    ble_att_clt_test_tx_write_req_or_cmd(conn->bhc_handle, &req, value300,
+    ble_att_clt_test_tx_write_req_or_cmd(conn_handle, &req, value300,
                                          sizeof value300, is_req);
     ble_hs_test_util_tx_all();
     ble_att_clt_test_misc_verify_tx_write(0xab83, value300,
@@ -203,17 +203,16 @@ ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t offset,
                                 uint8_t *attr_data, uint16_t attr_data_len)
 {
     struct ble_att_prep_write_cmd req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     struct os_mbuf *om;
+    uint16_t conn_handle;
     int rc;
     int i;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     req.bapc_handle = handle;
     req.bapc_offset = offset;
-    rc = ble_att_clt_tx_prep_write(conn->bhc_handle, &req, attr_data,
+    rc = ble_att_clt_tx_prep_write(conn_handle, &req, attr_data,
                                    attr_data_len);
     TEST_ASSERT(rc == 0);
 
@@ -235,15 +234,14 @@ static void
 ble_att_clt_test_misc_exec_good(uint8_t flags)
 {
     struct ble_att_exec_write_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     struct os_mbuf *om;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     req.baeq_flags = flags;
-    rc = ble_att_clt_tx_exec_write(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_exec_write(conn_handle, &req);
     TEST_ASSERT(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -261,15 +259,14 @@ ble_att_clt_test_misc_prep_bad(uint16_t handle, uint16_t offset,
                                int status)
 {
     struct ble_att_prep_write_cmd req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     req.bapc_handle = handle;
     req.bapc_offset = offset;
-    rc = ble_att_clt_tx_prep_write(conn->bhc_handle, &req, attr_data,
+    rc = ble_att_clt_tx_prep_write(conn_handle, &req, attr_data,
                                    attr_data_len);
     TEST_ASSERT(rc == status);
 }
@@ -283,104 +280,105 @@ TEST_CASE(ble_att_clt_test_tx_write)
 TEST_CASE(ble_att_clt_test_tx_read)
 {
     struct ble_att_read_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Success. */
     req.barq_handle = 1;
-    rc = ble_att_clt_tx_read(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_read(conn_handle, &req);
     TEST_ASSERT(rc == 0);
 
     /*** Error: handle of 0. */
     req.barq_handle = 0;
-    rc = ble_att_clt_tx_read(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_read(conn_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 
 TEST_CASE(ble_att_clt_test_rx_read)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[1024];
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Basic success. */
     buf[0] = BLE_ATT_OP_READ_RSP;
     buf[1] = 0;
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 2);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 2);
     TEST_ASSERT(rc == 0);
 
     /*** Larger response. */
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 20);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 20);
     TEST_ASSERT(rc == 0);
 
     /*** Zero-length response. */
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 1);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 1);
     TEST_ASSERT(rc == 0);
 }
 
 TEST_CASE(ble_att_clt_test_tx_read_blob)
 {
     struct ble_att_read_blob_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Success. */
     req.babq_handle = 1;
     req.babq_offset = 0;
-    rc = ble_att_clt_tx_read_blob(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_read_blob(conn_handle, &req);
     TEST_ASSERT(rc == 0);
 
     /*** Error: handle of 0. */
     req.babq_handle = 0;
     req.babq_offset = 0;
-    rc = ble_att_clt_tx_read_blob(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_read_blob(conn_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 
 TEST_CASE(ble_att_clt_test_rx_read_blob)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[1024];
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Basic success. */
     buf[0] = BLE_ATT_OP_READ_BLOB_RSP;
     buf[1] = 0;
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 2);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 2);
     TEST_ASSERT(rc == 0);
 
     /*** Larger response. */
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 20);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 20);
     TEST_ASSERT(rc == 0);
 
     /*** Zero-length response. */
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 1);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 1);
     TEST_ASSERT(rc == 0);
 }
 
 TEST_CASE(ble_att_clt_test_tx_read_mult)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     struct os_mbuf *om;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Success. */
-    rc = ble_att_clt_tx_read_mult(conn->bhc_handle, ((uint16_t[]){ 1, 2 }), 2);
+    rc = ble_att_clt_tx_read_mult(conn_handle, ((uint16_t[]){ 1, 2 }), 2);
     TEST_ASSERT(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -393,25 +391,24 @@ TEST_CASE(ble_att_clt_test_tx_read_mult)
     TEST_ASSERT(le16toh(om->om_data + BLE_ATT_READ_MULT_REQ_BASE_SZ + 2) == 2);
 
     /*** Error: no handles. */
-    rc = ble_att_clt_tx_read_mult(conn->bhc_handle, NULL, 0);
+    rc = ble_att_clt_tx_read_mult(conn_handle, NULL, 0);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 
 TEST_CASE(ble_att_clt_test_rx_read_mult)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[1024];
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Basic success. */
     ble_att_read_mult_rsp_write(buf, sizeof buf);
     htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 0, 12);
 
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_READ_MULT_RSP_BASE_SZ + 2);
+        conn_handle, BLE_L2CAP_CID_ATT, buf, BLE_ATT_READ_MULT_RSP_BASE_SZ + 2);
     TEST_ASSERT(rc == 0);
 
     /*** Larger response. */
@@ -419,12 +416,12 @@ TEST_CASE(ble_att_clt_test_rx_read_mult)
     htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 2, 43);
     htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 4, 91);
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_READ_MULT_RSP_BASE_SZ + 6);
+        conn_handle, BLE_L2CAP_CID_ATT, buf, BLE_ATT_READ_MULT_RSP_BASE_SZ + 6);
     TEST_ASSERT(rc == 0);
 
     /*** Zero-length response. */
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_READ_MULT_RSP_BASE_SZ + 0);
+        conn_handle, BLE_L2CAP_CID_ATT, buf, BLE_ATT_READ_MULT_RSP_BASE_SZ + 0);
     TEST_ASSERT(rc == 0);
 }
 
@@ -462,12 +459,11 @@ TEST_CASE(ble_att_clt_test_tx_prep_write)
 TEST_CASE(ble_att_clt_test_rx_prep_write)
 {
     struct ble_att_prep_write_cmd rsp;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[1024];
     int rc;
 
-    ble_att_clt_test_misc_init(&conn, &chan);
+    conn_handle = ble_att_clt_test_misc_init();
 
     /*** Basic success. */
     rsp.bapc_handle = 0x1234;
@@ -475,7 +471,8 @@ TEST_CASE(ble_att_clt_test_rx_prep_write)
     ble_att_prep_write_rsp_write(buf, sizeof buf, &rsp);
     memset(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, 1, 5);
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ + 5);
+        conn_handle, BLE_L2CAP_CID_ATT, buf,
+        BLE_ATT_PREP_WRITE_CMD_BASE_SZ + 5);
     TEST_ASSERT(rc == 0);
 
     /*** 0-length write. */
@@ -483,25 +480,25 @@ TEST_CASE(ble_att_clt_test_rx_prep_write)
     rsp.bapc_offset = 0;
     ble_att_prep_write_rsp_write(buf, sizeof buf, &rsp);
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
+        conn_handle, BLE_L2CAP_CID_ATT, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
     TEST_ASSERT(rc == 0);
 }
 
 TEST_CASE(ble_att_clt_test_tx_exec_write)
 {
     struct ble_att_exec_write_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     int rc;
 
+    conn_handle = ble_att_clt_test_misc_init();
+
     /*** Success. */
     ble_att_clt_test_misc_exec_good(0);
     ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_CONFIRM);
 
     /*** Error: invalid flags value. */
-    ble_att_clt_test_misc_init(&conn, &chan);
     req.baeq_flags = 0x02;
-    rc = ble_att_clt_tx_exec_write(conn->bhc_handle, &req);
+    rc = ble_att_clt_tx_exec_write(conn_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 



[3/4] incubator-mynewt-core git commit: BLE Host - Enforce thread safety in unit tests.

Posted by cc...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_att_svr_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_att_svr_test.c b/net/nimble/host/src/test/ble_att_svr_test.c
index 770dcb9..7268111 100644
--- a/net/nimble/host/src/test/ble_att_svr_test.c
+++ b/net/nimble/host/src/test/ble_att_svr_test.c
@@ -41,29 +41,39 @@ static uint16_t ble_att_svr_test_n_attr_handle;
 static uint8_t ble_att_svr_test_attr_n[1024];
 static int ble_att_svr_test_attr_n_len;
 
-static void
-ble_att_svr_test_misc_init(struct ble_hs_conn **conn,
-                           struct ble_l2cap_chan **att_chan, uint16_t mtu)
+/**
+ * @return                      The handle of the new test connection.
+ */
+static uint16_t
+ble_att_svr_test_misc_init(uint16_t mtu)
 {
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
     ble_hs_test_util_init();
 
     ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
                                  NULL, NULL);
-    *conn = ble_hs_conn_find(2);
-    TEST_ASSERT_FATAL(*conn != NULL);
 
-    *att_chan = ble_hs_conn_chan_find(*conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(*att_chan != NULL);
+    ble_hs_lock();
+
+    rc = ble_hs_misc_conn_chan_find(2, BLE_L2CAP_CID_ATT, &conn, &chan);
+    TEST_ASSERT_FATAL(rc == 0);
 
     if (mtu != 0) {
-        (*att_chan)->blc_my_mtu = mtu;
-        (*att_chan)->blc_peer_mtu = mtu;
-        (*att_chan)->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+        chan->blc_my_mtu = mtu;
+        chan->blc_peer_mtu = mtu;
+        chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
     }
 
+    ble_hs_unlock();
+
     ble_att_svr_test_attr_r_1_len = 0;
     ble_att_svr_test_attr_r_2_len = 0;
     ble_att_svr_test_attr_w_1_len = 0;
+
+    return 2;
 }
 
 static int
@@ -297,8 +307,7 @@ ble_att_svr_test_misc_verify_w_2(void *data, int data_len)
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_err_rsp(struct ble_l2cap_chan *chan,
-                                        uint8_t req_op, uint16_t handle,
+ble_att_svr_test_misc_verify_tx_err_rsp(uint8_t req_op, uint16_t handle,
                                         uint8_t error_code)
 {
     struct ble_att_error_rsp rsp;
@@ -321,8 +330,7 @@ ble_att_svr_test_misc_verify_tx_err_rsp(struct ble_l2cap_chan *chan,
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_read_rsp(struct ble_l2cap_chan *chan,
-                                         uint8_t *attr_data, int attr_len)
+ble_att_svr_test_misc_verify_tx_read_rsp(uint8_t *attr_data, int attr_len)
 {
     struct os_mbuf *om;
     uint8_t u8;
@@ -348,8 +356,7 @@ ble_att_svr_test_misc_verify_tx_read_rsp(struct ble_l2cap_chan *chan,
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_read_blob_rsp(struct ble_l2cap_chan *chan,
-                                              uint8_t *attr_data, int attr_len)
+ble_att_svr_test_misc_verify_tx_read_blob_rsp(uint8_t *attr_data, int attr_len)
 {
     struct os_mbuf *om;
     uint8_t u8;
@@ -375,8 +382,7 @@ ble_att_svr_test_misc_verify_tx_read_blob_rsp(struct ble_l2cap_chan *chan,
 }
 
 static void
-ble_att_svr_test_misc_rx_read_mult_req(struct ble_hs_conn *conn,
-                                       struct ble_l2cap_chan *chan,
+ble_att_svr_test_misc_rx_read_mult_req(uint16_t conn_handle,
                                        uint16_t *handles, int num_handles,
                                        int success)
 {
@@ -393,7 +399,8 @@ ble_att_svr_test_misc_rx_read_mult_req(struct ble_hs_conn *conn,
         off += 2;
     }
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     if (success) {
         TEST_ASSERT(rc == 0);
     } else {
@@ -402,11 +409,13 @@ ble_att_svr_test_misc_rx_read_mult_req(struct ble_hs_conn *conn,
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_read_mult_rsp(struct ble_l2cap_chan *chan,
+ble_att_svr_test_misc_verify_tx_read_mult_rsp(uint16_t conn_handle,
                                               struct ble_gatt_attr *attrs,
                                               int num_attrs)
 {
+    struct ble_l2cap_chan *chan;
     struct os_mbuf *om;
+    uint16_t mtu;
     uint8_t *attr_value;
     uint8_t u8;
     int rc;
@@ -422,14 +431,20 @@ ble_att_svr_test_misc_verify_tx_read_mult_rsp(struct ble_l2cap_chan *chan,
     TEST_ASSERT(rc == 0);
     TEST_ASSERT(u8 == BLE_ATT_OP_READ_MULT_RSP);
 
+    ble_hs_lock();
+
+    rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
+                                    NULL, &chan);
+    TEST_ASSERT_FATAL(rc == 0);
+    mtu = ble_l2cap_chan_mtu(chan);
+
+    ble_hs_unlock();
+
     off = 1;
     for (i = 0; i < num_attrs; i++) {
         attr_value = attrs[i].value;
 
-        for (ii = 0;
-             ii < attrs[i].value_len && off < ble_l2cap_chan_mtu(chan);
-             ii++) {
-
+        for (ii = 0; ii < attrs[i].value_len && off < mtu; ii++) {
             rc = os_mbuf_copydata(om, off, 1, &u8);
             TEST_ASSERT(rc == 0);
             TEST_ASSERT(u8 == attr_value[ii]);
@@ -443,8 +458,7 @@ ble_att_svr_test_misc_verify_tx_read_mult_rsp(struct ble_l2cap_chan *chan,
 }
 
 static void
-ble_att_svr_test_misc_verify_all_read_mult(struct ble_hs_conn *conn,
-                                           struct ble_l2cap_chan *chan,
+ble_att_svr_test_misc_verify_all_read_mult(uint16_t conn_handle,
                                            struct ble_gatt_attr *attrs,
                                            int num_attrs)
 {
@@ -457,13 +471,14 @@ ble_att_svr_test_misc_verify_all_read_mult(struct ble_hs_conn *conn,
         handles[i] = attrs[i].handle;
     }
 
-    ble_att_svr_test_misc_rx_read_mult_req(conn, chan, handles, num_attrs, 1);
-    ble_att_svr_test_misc_verify_tx_read_mult_rsp(chan, attrs, num_attrs);
+    ble_att_svr_test_misc_rx_read_mult_req(conn_handle, handles, num_attrs, 1);
+    ble_att_svr_test_misc_verify_tx_read_mult_rsp(conn_handle,
+                                                  attrs, num_attrs);
 }
 
 
 static void
-ble_att_svr_test_misc_verify_tx_write_rsp(struct ble_l2cap_chan *chan)
+ble_att_svr_test_misc_verify_tx_write_rsp(void)
 {
     struct os_mbuf *om;
     uint8_t u8;
@@ -479,9 +494,11 @@ ble_att_svr_test_misc_verify_tx_write_rsp(struct ble_l2cap_chan *chan)
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_mtu_rsp(struct ble_l2cap_chan *chan)
+ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle)
 {
     struct ble_att_mtu_cmd rsp;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
     struct os_mbuf *om;
     uint8_t buf[BLE_ATT_MTU_CMD_SZ];
     int rc;
@@ -495,7 +512,12 @@ ble_att_svr_test_misc_verify_tx_mtu_rsp(struct ble_l2cap_chan *chan)
 
     ble_att_mtu_cmd_parse(buf, sizeof buf, &rsp);
 
+    ble_hs_lock();
+    rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
+                                    &conn, &chan);
+    TEST_ASSERT_FATAL(rc == 0);
     TEST_ASSERT(rsp.bamc_mtu == chan->blc_my_mtu);
+    ble_hs_unlock();
 }
 
 struct ble_att_svr_test_info_entry {
@@ -506,7 +528,6 @@ struct ble_att_svr_test_info_entry {
 
 static void
 ble_att_svr_test_misc_verify_tx_find_info_rsp(
-    struct ble_l2cap_chan *chan,
     struct ble_att_svr_test_info_entry *entries)
 {
     struct ble_att_svr_test_info_entry *entry;
@@ -570,7 +591,6 @@ struct ble_att_svr_test_type_value_entry {
 
 static void
 ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
-    struct ble_l2cap_chan *chan,
     struct ble_att_svr_test_type_value_entry *entries)
 {
     struct ble_att_svr_test_type_value_entry *entry;
@@ -620,7 +640,6 @@ struct ble_att_svr_test_group_type_entry {
 /** Returns the number of entries successfully verified. */
 static void
 ble_att_svr_test_misc_verify_tx_read_group_type_rsp(
-    struct ble_l2cap_chan *chan,
     struct ble_att_svr_test_group_type_entry *entries)
 {
     struct ble_att_svr_test_group_type_entry *entry;
@@ -690,7 +709,6 @@ struct ble_att_svr_test_type_entry {
 /** Returns the number of entries successfully verified. */
 static void
 ble_att_svr_test_misc_verify_tx_read_type_rsp(
-    struct ble_l2cap_chan *chan,
     struct ble_att_svr_test_type_entry *entries)
 {
     struct ble_att_svr_test_type_entry *entry;
@@ -729,8 +747,7 @@ ble_att_svr_test_misc_verify_tx_read_type_rsp(
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_prep_write_rsp(struct ble_l2cap_chan *chan,
-                                               uint16_t attr_handle,
+ble_att_svr_test_misc_verify_tx_prep_write_rsp(uint16_t attr_handle,
                                                uint16_t offset,
                                                void *data, int data_len)
 {
@@ -758,7 +775,7 @@ ble_att_svr_test_misc_verify_tx_prep_write_rsp(struct ble_l2cap_chan *chan,
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_exec_write_rsp(struct ble_l2cap_chan *chan)
+ble_att_svr_test_misc_verify_tx_exec_write_rsp(void)
 {
     struct os_mbuf *om;
 
@@ -775,29 +792,32 @@ ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu, uint16_t peer_sent,
     struct ble_att_mtu_cmd req;
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[BLE_ATT_MTU_CMD_SZ];
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
-
-    chan->blc_my_mtu = my_mtu;
+    conn_handle = ble_att_svr_test_misc_init(my_mtu);
 
     req.bamc_mtu = peer_sent;
     ble_att_mtu_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
 
-    TEST_ASSERT(chan->blc_peer_mtu == peer_actual);
-
-    ble_att_svr_test_misc_verify_tx_mtu_rsp(chan);
+    ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle);
 
+    ble_hs_lock();
+    rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT,
+                                    &conn, &chan);
+    TEST_ASSERT_FATAL(rc == 0);
+    TEST_ASSERT(chan->blc_peer_mtu == peer_actual);
     TEST_ASSERT(ble_l2cap_chan_mtu(chan) == chan_mtu);
+    ble_hs_unlock();
 }
 
 static void
-ble_att_svr_test_misc_prep_write(struct ble_hs_conn *conn,
-                                 struct ble_l2cap_chan *chan, uint16_t handle,
+ble_att_svr_test_misc_prep_write(uint16_t conn_handle, uint16_t attr_handle,
                                  uint16_t offset, void *data,
                                  int data_len, uint8_t error_code)
 {
@@ -805,28 +825,27 @@ ble_att_svr_test_misc_prep_write(struct ble_hs_conn *conn,
     uint8_t buf[1024];
     int rc;
 
-    prep_req.bapc_handle = handle;
+    prep_req.bapc_handle = attr_handle;
     prep_req.bapc_offset = offset;
     ble_att_prep_write_req_write(buf, sizeof buf, &prep_req);
     memcpy(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, data, data_len);
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ + data_len);
+        conn_handle, BLE_L2CAP_CID_ATT, buf,
+        BLE_ATT_PREP_WRITE_CMD_BASE_SZ + data_len);
 
     if (error_code == 0) {
         TEST_ASSERT(rc == 0);
-        ble_att_svr_test_misc_verify_tx_prep_write_rsp(chan, handle, offset,
+        ble_att_svr_test_misc_verify_tx_prep_write_rsp(attr_handle, offset,
                                                        data, data_len);
     } else {
         TEST_ASSERT(rc != 0);
-        ble_att_svr_test_misc_verify_tx_err_rsp(chan,
-                                                BLE_ATT_OP_PREP_WRITE_REQ,
-                                                handle, error_code);
+        ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_PREP_WRITE_REQ,
+                                                attr_handle, error_code);
     }
 }
 
 static void
-ble_att_svr_test_misc_exec_write(struct ble_hs_conn *conn,
-                                 struct ble_l2cap_chan *chan, uint8_t flags,
+ble_att_svr_test_misc_exec_write(uint16_t conn_handle, uint8_t flags,
                                  uint8_t error_code, uint16_t error_handle)
 {
     struct ble_att_exec_write_req exec_req;
@@ -835,24 +854,22 @@ ble_att_svr_test_misc_exec_write(struct ble_hs_conn *conn,
 
     exec_req.baeq_flags = flags;
     ble_att_exec_write_req_write(buf, sizeof buf, &exec_req);
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf,
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf,
                                                 BLE_ATT_EXEC_WRITE_REQ_SZ);
 
     if (error_code == 0) {
         TEST_ASSERT(rc == 0);
-        ble_att_svr_test_misc_verify_tx_exec_write_rsp(chan);
+        ble_att_svr_test_misc_verify_tx_exec_write_rsp();
     } else {
         TEST_ASSERT(rc != 0);
-        ble_att_svr_test_misc_verify_tx_err_rsp(chan,
-                                                BLE_ATT_OP_EXEC_WRITE_REQ,
+        ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_EXEC_WRITE_REQ,
                                                 error_handle, error_code);
     }
 }
 
 static void
-ble_att_svr_test_misc_rx_notify(struct ble_hs_conn *conn,
-                                struct ble_l2cap_chan *chan,
-                                uint16_t attr_handle,
+ble_att_svr_test_misc_rx_notify(uint16_t conn_handle, uint16_t attr_handle,
                                 void *attr_val, int attr_len, int good)
 {
     struct ble_att_notify_req req;
@@ -867,7 +884,8 @@ ble_att_svr_test_misc_rx_notify(struct ble_hs_conn *conn,
     memcpy(buf + off, attr_val, attr_len);
     off += attr_len;
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     if (good) {
         TEST_ASSERT(rc == 0);
     } else {
@@ -896,9 +914,7 @@ ble_att_svr_test_misc_notify_cb(uint16_t conn_handle, uint16_t attr_handle,
 }
 
 static void
-ble_att_svr_test_misc_verify_notify(struct ble_hs_conn *conn,
-                                    struct ble_l2cap_chan *chan,
-                                    uint16_t attr_handle,
+ble_att_svr_test_misc_verify_notify(uint16_t conn_handle, uint16_t attr_handle,
                                     void *attr_val, int attr_len, int good)
 {
     ble_att_svr_test_misc_notify_cb_arg = 0;
@@ -909,11 +925,11 @@ ble_att_svr_test_misc_verify_notify(struct ble_hs_conn *conn,
     ble_att_svr_test_n_attr_handle = 0;
     ble_att_svr_test_attr_n_len = 0;
 
-    ble_att_svr_test_misc_rx_notify(conn, chan, attr_handle, attr_val,
+    ble_att_svr_test_misc_rx_notify(conn_handle, attr_handle, attr_val,
                                     attr_len, good);
 
     if (good) {
-        TEST_ASSERT(ble_att_svr_test_n_conn_handle == conn->bhc_handle);
+        TEST_ASSERT(ble_att_svr_test_n_conn_handle == conn_handle);
         TEST_ASSERT(ble_att_svr_test_n_attr_handle == attr_handle);
         TEST_ASSERT(ble_att_svr_test_attr_n_len == attr_len);
         TEST_ASSERT(memcmp(ble_att_svr_test_attr_n, attr_val, attr_len) == 0);
@@ -925,7 +941,7 @@ ble_att_svr_test_misc_verify_notify(struct ble_hs_conn *conn,
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_indicate_rsp(struct ble_l2cap_chan *chan)
+ble_att_svr_test_misc_verify_tx_indicate_rsp(void)
 {
     struct os_mbuf *om;
 
@@ -937,9 +953,7 @@ ble_att_svr_test_misc_verify_tx_indicate_rsp(struct ble_l2cap_chan *chan)
 }
 
 static void
-ble_att_svr_test_misc_rx_indicate(struct ble_hs_conn *conn,
-                                  struct ble_l2cap_chan *chan,
-                                  uint16_t attr_handle,
+ble_att_svr_test_misc_rx_indicate(uint16_t conn_handle, uint16_t attr_handle,
                                   void *attr_val, int attr_len, int good)
 {
     struct ble_att_indicate_req req;
@@ -954,7 +968,8 @@ ble_att_svr_test_misc_rx_indicate(struct ble_hs_conn *conn,
     memcpy(buf + off, attr_val, attr_len);
     off += attr_len;
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     if (good) {
         TEST_ASSERT(rc == 0);
     } else {
@@ -963,8 +978,7 @@ ble_att_svr_test_misc_rx_indicate(struct ble_hs_conn *conn,
 }
 
 static void
-ble_att_svr_test_misc_verify_indicate(struct ble_hs_conn *conn,
-                                      struct ble_l2cap_chan *chan,
+ble_att_svr_test_misc_verify_indicate(uint16_t conn_handle,
                                       uint16_t attr_handle,
                                       void *attr_val, int attr_len, int good)
 {
@@ -976,15 +990,15 @@ ble_att_svr_test_misc_verify_indicate(struct ble_hs_conn *conn,
     ble_att_svr_test_n_attr_handle = 0;
     ble_att_svr_test_attr_n_len = 0;
 
-    ble_att_svr_test_misc_rx_indicate(conn, chan, attr_handle, attr_val,
+    ble_att_svr_test_misc_rx_indicate(conn_handle, attr_handle, attr_val,
                                       attr_len, good);
 
     if (good) {
-        TEST_ASSERT(ble_att_svr_test_n_conn_handle == conn->bhc_handle);
+        TEST_ASSERT(ble_att_svr_test_n_conn_handle == conn_handle);
         TEST_ASSERT(ble_att_svr_test_n_attr_handle == attr_handle);
         TEST_ASSERT(ble_att_svr_test_attr_n_len == attr_len);
         TEST_ASSERT(memcmp(ble_att_svr_test_attr_n, attr_val, attr_len) == 0);
-        ble_att_svr_test_misc_verify_tx_indicate_rsp(chan);
+        ble_att_svr_test_misc_verify_tx_indicate_rsp();
     } else {
         TEST_ASSERT(ble_att_svr_test_n_conn_handle == 0xffff);
         TEST_ASSERT(ble_att_svr_test_n_attr_handle == 0);
@@ -1013,21 +1027,21 @@ TEST_CASE(ble_att_svr_test_mtu)
 TEST_CASE(ble_att_svr_test_read)
 {
     struct ble_att_read_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[BLE_ATT_READ_REQ_SZ];
     uint8_t uuid[16] = {0};
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
+    conn_handle = ble_att_svr_test_misc_init(0);
 
     /*** Nonexistent attribute. */
     req.barq_handle = 0;
     ble_att_read_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(chan, BLE_ATT_OP_READ_REQ, 0,
+    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ, 0,
                                             BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Successful read. */
@@ -1039,10 +1053,11 @@ TEST_CASE(ble_att_svr_test_read)
 
     ble_att_read_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
     ble_att_svr_test_misc_verify_tx_read_rsp(
-        chan, ble_att_svr_test_attr_r_1, ble_att_svr_test_attr_r_1_len);
+        ble_att_svr_test_attr_r_1, ble_att_svr_test_attr_r_1_len);
 
     /*** Partial read. */
     ble_att_svr_test_attr_r_1 =
@@ -1052,31 +1067,32 @@ TEST_CASE(ble_att_svr_test_read)
 
     ble_att_read_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_rsp(chan, ble_att_svr_test_attr_r_1,
+    ble_att_svr_test_misc_verify_tx_read_rsp(ble_att_svr_test_attr_r_1,
                                              BLE_ATT_MTU_DFLT - 1);
 }
 
 TEST_CASE(ble_att_svr_test_read_blob)
 {
     struct ble_att_read_blob_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[BLE_ATT_READ_BLOB_REQ_SZ];
     uint8_t uuid[16] = {0};
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
+    conn_handle = ble_att_svr_test_misc_init(0);
 
     /*** Nonexistent attribute. */
     req.babq_handle = 0;
     req.babq_offset = 0;
     ble_att_read_blob_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(chan, BLE_ATT_OP_READ_BLOB_REQ, 0,
+    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_BLOB_REQ, 0,
                                             BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Short read failure. */
@@ -1090,9 +1106,10 @@ TEST_CASE(ble_att_svr_test_read_blob)
 
     ble_att_read_blob_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(chan, BLE_ATT_OP_READ_BLOB_REQ,
+    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_BLOB_REQ,
                                             req.babq_handle,
                                             BLE_ATT_ERR_ATTR_NOT_LONG);
 
@@ -1101,42 +1118,42 @@ TEST_CASE(ble_att_svr_test_read_blob)
 
     ble_att_read_blob_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_blob_rsp(chan,
-                                                  ble_att_svr_test_attr_r_1,
+    ble_att_svr_test_misc_verify_tx_read_blob_rsp(ble_att_svr_test_attr_r_1,
                                                   BLE_ATT_MTU_DFLT - 1);
 
     /*** Read remainder of attribute. */
     req.babq_offset = BLE_ATT_MTU_DFLT - 1;
     ble_att_read_blob_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
     ble_att_svr_test_misc_verify_tx_read_blob_rsp(
-        chan, ble_att_svr_test_attr_r_1 + BLE_ATT_MTU_DFLT - 1,
+        ble_att_svr_test_attr_r_1 + BLE_ATT_MTU_DFLT - 1,
         40 - (BLE_ATT_MTU_DFLT - 1));
 
     /*** Zero-length read. */
     req.babq_offset = ble_att_svr_test_attr_r_1_len;
     ble_att_read_blob_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_blob_rsp(chan,
-                                                  ble_att_svr_test_attr_r_1,
+    ble_att_svr_test_misc_verify_tx_read_blob_rsp(ble_att_svr_test_attr_r_1,
                                                   0);
 }
 
 TEST_CASE(ble_att_svr_test_read_mult)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     struct ble_gatt_attr attr1;
     struct ble_gatt_attr attr2;
+    uint16_t conn_handle;
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
+    conn_handle = ble_att_svr_test_misc_init(0);
 
     attr1.value = (uint8_t[]){ 1, 2, 3, 4 };
     attr1.value_len = 4;
@@ -1158,25 +1175,25 @@ TEST_CASE(ble_att_svr_test_read_mult)
 
     /*** Single nonexistent attribute. */
     ble_att_svr_test_misc_rx_read_mult_req(
-        conn, chan, ((uint16_t[]){ 100 }), 1, 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(chan, BLE_ATT_OP_READ_MULT_REQ,
+        conn_handle, ((uint16_t[]){ 100 }), 1, 0);
+    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
                                             100, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Single attribute. */
-    ble_att_svr_test_misc_verify_all_read_mult(conn, chan, &attr1, 1);
+    ble_att_svr_test_misc_verify_all_read_mult(conn_handle, &attr1, 1);
 
     /*** Two attributes. */
     ble_att_svr_test_misc_verify_all_read_mult(
-        conn, chan, ((struct ble_gatt_attr[]) { attr1, attr2 }), 2);
+        conn_handle, ((struct ble_gatt_attr[]) { attr1, attr2 }), 2);
 
     /*** Reverse order. */
     ble_att_svr_test_misc_verify_all_read_mult(
-        conn, chan, ((struct ble_gatt_attr[]) { attr2, attr1 }), 2);
+        conn_handle, ((struct ble_gatt_attr[]) { attr2, attr1 }), 2);
 
     /*** Second attribute nonexistent; verify only error txed. */
     ble_att_svr_test_misc_rx_read_mult_req(
-        conn, chan, ((uint16_t[]){ attr1.handle, 100 }), 2, 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(chan, BLE_ATT_OP_READ_MULT_REQ,
+        conn_handle, ((uint16_t[]){ attr1.handle, 100 }), 2, 0);
+    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
                                             100, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Response too long; verify only MTU bytes sent. */
@@ -1193,29 +1210,29 @@ TEST_CASE(ble_att_svr_test_read_mult)
     ble_att_svr_test_attr_r_2_len = attr2.value_len;
 
     ble_att_svr_test_misc_verify_all_read_mult(
-        conn, chan, ((struct ble_gatt_attr[]) { attr1, attr2 }), 2);
+        conn_handle, ((struct ble_gatt_attr[]) { attr1, attr2 }), 2);
 }
 
 TEST_CASE(ble_att_svr_test_write)
 {
     struct ble_att_write_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[BLE_ATT_WRITE_REQ_BASE_SZ + 8];
     uint8_t uuid[16] = {0};
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
+    conn_handle = ble_att_svr_test_misc_init(0);
 
     /*** Nonexistent attribute. */
     req.bawq_handle = 0;
     ble_att_write_req_write(buf, sizeof buf, &req);
     memcpy(buf + BLE_ATT_READ_REQ_SZ, ((uint8_t[]){0,1,2,3,4,5,6,7}), 8);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_WRITE_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
+        BLE_ATT_OP_WRITE_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Successful write. */
     rc = ble_att_svr_register(uuid, HA_FLAG_PERM_RW, &req.bawq_handle,
@@ -1226,16 +1243,16 @@ TEST_CASE(ble_att_svr_test_write)
     memcpy(buf + BLE_ATT_WRITE_REQ_BASE_SZ,
            ((uint8_t[]){0,1,2,3,4,5,6,7}), 8);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_write_rsp(chan);
+    ble_att_svr_test_misc_verify_tx_write_rsp();
 }
 
 TEST_CASE(ble_att_svr_test_find_info)
 {
     struct ble_att_find_info_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint16_t handle1;
     uint16_t handle2;
     uint16_t handle3;
@@ -1248,7 +1265,7 @@ TEST_CASE(ble_att_svr_test_find_info)
     };
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 128);
+    conn_handle = ble_att_svr_test_misc_init(128);
 
     /*** Start handle of 0. */
     req.bafq_start_handle = 0;
@@ -1256,10 +1273,11 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_INFO_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
+        BLE_ATT_OP_FIND_INFO_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Start handle > end handle. */
     req.bafq_start_handle = 101;
@@ -1267,10 +1285,11 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_INFO_REQ, 101, BLE_ATT_ERR_INVALID_HANDLE);
+        BLE_ATT_OP_FIND_INFO_REQ, 101, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** No attributes. */
     req.bafq_start_handle = 200;
@@ -1278,10 +1297,11 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
+        BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** Range too late. */
     rc = ble_att_svr_register(uuid1, HA_FLAG_PERM_RW, &handle1,
@@ -1293,10 +1313,11 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
+        BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** One 128-bit entry. */
     req.bafq_start_handle = handle1;
@@ -1304,9 +1325,10 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_info_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_info_rsp(
         ((struct ble_att_svr_test_info_entry[]) { {
             .handle = handle1,
             .uuid128 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
@@ -1324,9 +1346,10 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_info_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_info_rsp(
         ((struct ble_att_svr_test_info_entry[]) { {
             .handle = handle1,
             .uuid128 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
@@ -1347,9 +1370,10 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_info_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_info_rsp(
         ((struct ble_att_svr_test_info_entry[]) { {
             .handle = handle1,
             .uuid128 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
@@ -1366,9 +1390,10 @@ TEST_CASE(ble_att_svr_test_find_info)
 
     ble_att_find_info_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_info_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_info_rsp(
         ((struct ble_att_svr_test_info_entry[]) { {
             .handle = handle3,
             .uuid16 = 0x000f,
@@ -1380,9 +1405,8 @@ TEST_CASE(ble_att_svr_test_find_info)
 TEST_CASE(ble_att_svr_test_find_type_value)
 {
     struct ble_att_find_type_value_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     uint8_t buf[BLE_ATT_FIND_TYPE_VALUE_REQ_BASE_SZ + 2];
+    uint16_t conn_handle;
     uint16_t handle1;
     uint16_t handle2;
     uint16_t handle3;
@@ -1399,7 +1423,7 @@ TEST_CASE(ble_att_svr_test_find_type_value)
     };
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 128);
+    conn_handle = ble_att_svr_test_misc_init(128);
 
     /* One-time write of the attribute value at the end of the request. */
     ble_att_svr_test_attr_r_1 = (uint8_t[]){0x99, 0x99};
@@ -1415,10 +1439,11 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 0,
+        BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 0,
         BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Start handle > end handle. */
@@ -1427,10 +1452,11 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 101,
+        BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 101,
         BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** No attributes. */
@@ -1439,10 +1465,11 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
+        BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** Range too late. */
@@ -1455,10 +1482,11 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
+        BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** One entry, one attribute. */
@@ -1467,9 +1495,10 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
         ((struct ble_att_svr_test_type_value_entry[]) { {
             .first = handle1,
             .last = handle1,
@@ -1487,9 +1516,10 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
         ((struct ble_att_svr_test_type_value_entry[]) { {
             .first = handle1,
             .last = handle2,
@@ -1511,9 +1541,10 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
         ((struct ble_att_svr_test_type_value_entry[]) { {
             .first = handle1,
             .last = handle2,
@@ -1533,9 +1564,10 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
         ((struct ble_att_svr_test_type_value_entry[]) { {
             .first = handle1,
             .last = handle2,
@@ -1555,9 +1587,10 @@ TEST_CASE(ble_att_svr_test_find_type_value)
 
     ble_att_find_type_value_req_write(buf, sizeof buf, &req);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_find_type_value_rsp(
         ((struct ble_att_svr_test_type_value_entry[]) { {
             .first = handle1,
             .last = handle2,
@@ -1573,12 +1606,11 @@ static void
 ble_att_svr_test_misc_read_type(uint16_t mtu)
 {
     struct ble_att_read_type_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[BLE_ATT_READ_TYPE_REQ_SZ_16];
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, mtu);
+    conn_handle = ble_att_svr_test_misc_init(mtu);
 
     /*** Start handle of 0. */
     req.batq_start_handle = 0;
@@ -1588,10 +1620,11 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_TYPE_REQ, 0,
+        BLE_ATT_OP_READ_TYPE_REQ, 0,
         BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Start handle > end handle. */
@@ -1602,10 +1635,11 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_TYPE_REQ, 101,
+        BLE_ATT_OP_READ_TYPE_REQ, 101,
         BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** No attributes. */
@@ -1616,10 +1650,11 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_TYPE_REQ, 1,
+        BLE_ATT_OP_READ_TYPE_REQ, 1,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** Range too late. */
@@ -1631,10 +1666,11 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_TYPE_REQ, 200,
+        BLE_ATT_OP_READ_TYPE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** One characteristic from one service. */
@@ -1645,9 +1681,10 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_CHARACTERISTIC);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_type_rsp(
         ((struct ble_att_svr_test_type_entry[]) { {
             .handle = 2,
             .value = (uint8_t[]){ 0x01, 0x11 },
@@ -1664,9 +1701,10 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_CHARACTERISTIC);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_type_rsp(
         ((struct ble_att_svr_test_type_entry[]) { {
             .handle = 2,
             .value = (uint8_t[]){ 0x01, 0x11 },
@@ -1687,9 +1725,10 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_CHARACTERISTIC);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_type_rsp(
         ((struct ble_att_svr_test_type_entry[]) { {
             .handle = 12,
             .value = (uint8_t[]){ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
@@ -1705,9 +1744,10 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_CHARACTERISTIC);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_type_rsp(
         ((struct ble_att_svr_test_type_entry[]) { {
             .handle = 14,
             .value = (uint8_t[]){ 0x55, 0x55 },
@@ -1723,9 +1763,10 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_CHARACTERISTIC);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_type_rsp(
         ((struct ble_att_svr_test_type_entry[]) { {
             .handle = 16,
             .value = (uint8_t[]){ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
@@ -1742,9 +1783,10 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     htole16(buf + BLE_ATT_READ_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_CHARACTERISTIC);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_type_rsp(
         ((struct ble_att_svr_test_type_entry[]) { {
             .handle = 18,
             .value = (uint8_t[]){ 0x66, 0x66 },
@@ -1775,12 +1817,11 @@ TEST_CASE(ble_att_svr_test_read_type)
 TEST_CASE(ble_att_svr_test_read_group_type)
 {
     struct ble_att_read_group_type_req req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     uint8_t buf[BLE_ATT_READ_GROUP_TYPE_REQ_SZ_16];
     int rc;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 128);
+    conn_handle = ble_att_svr_test_misc_init(128);
 
     /*** Start handle of 0. */
     req.bagq_start_handle = 0;
@@ -1790,10 +1831,11 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat( conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ, 0,
+        BLE_ATT_OP_READ_GROUP_TYPE_REQ, 0,
         BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Start handle > end handle. */
@@ -1804,10 +1846,11 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ, 101,
+        BLE_ATT_OP_READ_GROUP_TYPE_REQ, 101,
         BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Invalid group UUID (0x1234). */
@@ -1817,10 +1860,11 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     ble_att_read_group_type_req_write(buf, sizeof buf, &req);
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ, 0x1234);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ, 110,
+        BLE_ATT_OP_READ_GROUP_TYPE_REQ, 110,
         BLE_ATT_ERR_UNSUPPORTED_GROUP);
 
     /*** No attributes. */
@@ -1831,10 +1875,11 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ, 1,
+        BLE_ATT_OP_READ_GROUP_TYPE_REQ, 1,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** Range too late. */
@@ -1846,10 +1891,11 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc != 0);
     ble_att_svr_test_misc_verify_tx_err_rsp(
-        chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ, 200,
+        BLE_ATT_OP_READ_GROUP_TYPE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** One 16-bit UUID service. */
@@ -1860,9 +1906,10 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(
         ((struct ble_att_svr_test_group_type_entry[]) { {
             .start_handle = 1,
             .end_handle = 5,
@@ -1879,9 +1926,10 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(
         ((struct ble_att_svr_test_group_type_entry[]) { {
             .start_handle = 1,
             .end_handle = 5,
@@ -1902,9 +1950,10 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(
         ((struct ble_att_svr_test_group_type_entry[]) { {
             .start_handle = 1,
             .end_handle = 5,
@@ -1925,9 +1974,10 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     htole16(buf + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
             BLE_ATT_UUID_PRIMARY_SERVICE);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(chan,
+    ble_att_svr_test_misc_verify_tx_read_group_type_rsp(
         ((struct ble_att_svr_test_group_type_entry[]) { {
             .start_handle = 11,
             .end_handle = 19,
@@ -1939,13 +1989,12 @@ TEST_CASE(ble_att_svr_test_read_group_type)
 
 TEST_CASE(ble_att_svr_test_prep_write)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
     int i;
 
     static uint8_t data[1024];
 
-    ble_att_svr_test_misc_init(&conn, &chan, 200);
+    conn_handle = ble_att_svr_test_misc_init(200);
 
     /* Initialize some attribute data. */
     for (i = 0; i < sizeof data; i++) {
@@ -1959,89 +2008,89 @@ TEST_CASE(ble_att_svr_test_prep_write)
                                           ble_att_svr_test_misc_attr_fn_w_2);
 
     /*** Empty write succeeds. */
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      0, 0);
 
     /*** Empty cancel succeeds. */
-    ble_att_svr_test_misc_exec_write(conn, chan, 0, 0, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
 
     /*** Failure for prep write to nonexistent attribute. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 53525, 0, data, 10,
+    ble_att_svr_test_misc_prep_write(conn_handle, 53525, 0, data, 10,
                                      BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Failure for write starting at nonzero offset. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 1, data, 10, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 1, data, 10, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      BLE_ATT_ERR_INVALID_OFFSET, 1);
     ble_att_svr_test_misc_verify_w_1(NULL, 0);
 
     /*** Success for clear starting at nonzero offset. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 1, data, 10, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, 0, 0, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 1, data, 10, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
     ble_att_svr_test_misc_verify_w_1(NULL, 0);
 
     /*** Failure for write with gap. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 10, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 11, data, 10, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 10, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 11, data, 10, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      BLE_ATT_ERR_INVALID_OFFSET, 1);
     ble_att_svr_test_misc_verify_w_1(NULL, 0);
 
     /*** Success for clear with gap. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 10, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 11, data, 10, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, 0, 0, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 10, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 11, data, 10, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, 0, 0, 0);
     ble_att_svr_test_misc_verify_w_1(NULL, 0);
 
     /*** Failure for overlong write. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 200, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 200, data + 200, 200, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 400, data + 400, 200, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 200, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 200, data + 200, 200, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 400, data + 400, 200, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN, 1);
     ble_att_svr_test_misc_verify_w_1(NULL, 0);
 
     /*** Successful two part write. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 20, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 20, data + 20, 20, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 20, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 20, data + 20, 20, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      0, 0);
     ble_att_svr_test_misc_verify_w_1(data, 40);
 
     /*** Successful three part write. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 35, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 35, data + 35, 43, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 78, data + 78, 1, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 35, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 35, data + 35, 43, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 78, data + 78, 1, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      0, 0);
     ble_att_svr_test_misc_verify_w_1(data, 79);
 
     /*** Successful two part write to two attributes. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 7, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 7, data + 7, 10, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 2, 0, data, 20, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 2, 20, data + 20, 10, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 7, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 7, data + 7, 10, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 2, 0, data, 20, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 2, 20, data + 20, 10, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      0, 0);
     ble_att_svr_test_misc_verify_w_1(data, 17);
     ble_att_svr_test_misc_verify_w_2(data, 30);
 
     /*** Fail write to second attribute; ensure first write doesn't occur. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 5, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 5, data + 5, 2, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 2, 0, data, 11, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 2, 12, data + 11, 19, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 5, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 5, data + 5, 2, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 2, 0, data, 11, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 2, 12, data + 11, 19, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      BLE_ATT_ERR_INVALID_OFFSET, 2);
     ble_att_svr_test_misc_verify_w_1(data, 17);
     ble_att_svr_test_misc_verify_w_2(data, 30);
 
     /*** Successful out of order write to two attributes. */
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 0, data, 9, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 2, 0, data, 18, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 1, 9, data + 9, 3, 0);
-    ble_att_svr_test_misc_prep_write(conn, chan, 2, 18, data + 18, 43, 0);
-    ble_att_svr_test_misc_exec_write(conn, chan, BLE_ATT_EXEC_WRITE_F_CONFIRM,
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 0, data, 9, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 2, 0, data, 18, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 1, 9, data + 9, 3, 0);
+    ble_att_svr_test_misc_prep_write(conn_handle, 2, 18, data + 18, 43, 0);
+    ble_att_svr_test_misc_exec_write(conn_handle, BLE_ATT_EXEC_WRITE_F_CONFIRM,
                                      0, 0);
     ble_att_svr_test_misc_verify_w_1(data, 12);
     ble_att_svr_test_misc_verify_w_2(data, 61);
@@ -2049,47 +2098,45 @@ TEST_CASE(ble_att_svr_test_prep_write)
 
 TEST_CASE(ble_att_svr_test_notify)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
+    conn_handle = ble_att_svr_test_misc_init(0);
 
     /*** Successful notifies; verify callback is executed. */
     /* 3-length attribute. */
-    ble_att_svr_test_misc_verify_notify(conn, chan, 10,
+    ble_att_svr_test_misc_verify_notify(conn_handle, 10,
                                         (uint8_t[]) { 1, 2, 3 }, 3, 1);
     /* 1-length attribute. */
-    ble_att_svr_test_misc_verify_notify(conn, chan, 1,
+    ble_att_svr_test_misc_verify_notify(conn_handle, 1,
                                         (uint8_t[]) { 0xff }, 1, 1);
     /* 0-length attribute. */
-    ble_att_svr_test_misc_verify_notify(conn, chan, 43, NULL, 0, 1);
+    ble_att_svr_test_misc_verify_notify(conn_handle, 43, NULL, 0, 1);
 
     /*** Bad notifies; verify callback is not executed. */
     /* Attribute handle of 0. */
-    ble_att_svr_test_misc_verify_notify(conn, chan, 0,
+    ble_att_svr_test_misc_verify_notify(conn_handle, 0,
                                         (uint8_t[]) { 1, 2, 3 }, 3, 0);
 }
 
 TEST_CASE(ble_att_svr_test_indicate)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
 
-    ble_att_svr_test_misc_init(&conn, &chan, 0);
+    conn_handle = ble_att_svr_test_misc_init(0);
 
     /*** Successful indicates; verify callback is executed. */
     /* 3-length attribute. */
-    ble_att_svr_test_misc_verify_indicate(conn, chan, 10,
+    ble_att_svr_test_misc_verify_indicate(conn_handle, 10,
                                           (uint8_t[]) { 1, 2, 3 }, 3, 1);
     /* 1-length attribute. */
-    ble_att_svr_test_misc_verify_indicate(conn, chan, 1,
+    ble_att_svr_test_misc_verify_indicate(conn_handle, 1,
                                           (uint8_t[]) { 0xff }, 1, 1);
     /* 0-length attribute. */
-    ble_att_svr_test_misc_verify_indicate(conn, chan, 43, NULL, 0, 1);
+    ble_att_svr_test_misc_verify_indicate(conn_handle, 43, NULL, 0, 1);
 
     /*** Bad indicates; verify callback is not executed. */
     /* Attribute handle of 0. */
-    ble_att_svr_test_misc_verify_indicate(conn, chan, 0,
+    ble_att_svr_test_misc_verify_indicate(conn_handle, 0,
                                           (uint8_t[]) { 1, 2, 3 }, 3, 0);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gap_test.c b/net/nimble/host/src/test/ble_gap_test.c
index 7da3d3f..92e7b3a 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -41,6 +41,16 @@ static void *ble_gap_test_disc_arg;
  * $misc                                                                     *
  *****************************************************************************/
 
+static int
+ble_gap_test_util_update_in_progress(uint16_t conn_handle)
+{
+    ble_hs_conn_flags_t conn_flags;
+    int rc;
+
+    rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
+    return rc == 0 && conn_flags & BLE_HS_CONN_F_UPDATE;
+}
+
 static void
 ble_gap_test_util_reset_cb_info(void)
 {
@@ -664,7 +674,7 @@ TEST_CASE(ble_gap_test_case_conn_dir_good)
     /* Verify tx of create connection command. */
     ble_gap_test_util_verify_tx_create_conn(BLE_HCI_CONN_FILT_NO_WL);
     TEST_ASSERT(ble_gap_master_in_progress());
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == BLE_HS_ENOTCONN);
 
     /* Receive connection complete event. */
     memset(&evt, 0, sizeof evt);
@@ -682,7 +692,7 @@ TEST_CASE(ble_gap_test_case_conn_dir_good)
     TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
     TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_addr, peer_addr, 6) == 0);
 
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
 }
 
 TEST_CASE(ble_gap_test_case_conn_dir_bad_args)
@@ -759,7 +769,7 @@ ble_gap_test_util_conn_cancel(uint8_t *peer_addr, uint8_t hci_status)
     rc = ble_gap_rx_conn_complete(&evt);
     TEST_ASSERT(rc == 0);
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == BLE_HS_ENOTCONN);
 }
 
 TEST_CASE(ble_gap_test_case_conn_cancel_bad_args)
@@ -816,7 +826,7 @@ TEST_CASE(ble_gap_test_case_conn_cancel_ctlr_fail)
     TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_addr,
                        peer_addr, 6) == 0);
 
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
 }
 
 TEST_SUITE(ble_gap_test_suite_conn_cancel)
@@ -888,7 +898,7 @@ TEST_CASE(ble_gap_test_case_conn_terminate_good)
     TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_addr, peer_addr, 6) == 0);
     TEST_ASSERT(ble_gap_test_conn_arg == NULL);
 
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == BLE_HS_ENOTCONN);
     TEST_ASSERT(!ble_gap_master_in_progress());
 }
 
@@ -927,7 +937,7 @@ TEST_CASE(ble_gap_test_case_conn_terminate_ctlr_fail)
     TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_addr, peer_addr, 6) == 0);
     TEST_ASSERT(ble_gap_test_conn_arg == NULL);
 
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
     TEST_ASSERT(!ble_gap_master_in_progress());
 }
 
@@ -938,7 +948,7 @@ TEST_CASE(ble_gap_test_case_conn_terminate_hci_fail)
     ble_gap_test_util_terminate(peer_addr, BLE_ERR_REPEATED_ATTEMPTS);
 
     TEST_ASSERT(ble_gap_test_conn_event == -1);
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
     TEST_ASSERT(!ble_gap_master_in_progress());
 }
 
@@ -1274,9 +1284,9 @@ ble_gap_test_util_update(struct ble_gap_upd_params *params,
     ble_gap_test_util_verify_tx_update_conn(params);
 
     if (rc == 0) {
-        TEST_ASSERT(ble_gap_update_in_progress(2));
+        TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
     } else {
-        TEST_ASSERT(!ble_gap_update_in_progress(2));
+        TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
         return;
     }
 
@@ -1299,7 +1309,7 @@ ble_gap_test_util_update(struct ble_gap_upd_params *params,
     TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
         params->supervision_timeout);
 
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     return;
 
@@ -1314,7 +1324,7 @@ fail:
                 BLE_GAP_INITIAL_CONN_LATENCY);
     TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
                 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 }
 
 static void
@@ -1348,7 +1358,7 @@ ble_gap_test_util_update_peer(uint8_t status,
                     params->supervision_timeout);
     }
 
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 }
 
 static void
@@ -1376,19 +1386,19 @@ ble_gap_test_util_update_req_pos(struct ble_gap_upd_params *peer_params,
         goto hci_fail;
     }
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(2));
+    TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
 
     /* Verify tx of connection parameters reply command. */
     ble_gap_test_util_verify_tx_params_reply_pos();
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(2));
+    TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
 
     /* Receive connection update complete event. */
     ble_gap_test_util_rx_update_complete(0, self_params);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     TEST_ASSERT(ble_gap_test_conn_event == BLE_GAP_EVENT_CONN_UPDATED);
     TEST_ASSERT(ble_gap_test_conn_status == 0);
@@ -1432,7 +1442,7 @@ ble_gap_test_util_update_req_neg(struct ble_gap_upd_params *peer_params,
                                  &reason);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     rc = ble_gap_test_util_rx_param_req(peer_params, 0, &cmd_idx, cmd_fail_idx,
                                         hci_status);
@@ -1440,13 +1450,13 @@ ble_gap_test_util_update_req_neg(struct ble_gap_upd_params *peer_params,
         goto hci_fail;
     }
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     /* Verify tx of connection parameters negative reply command. */
     ble_gap_test_util_verify_tx_params_reply_neg(reason);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     return;
 
@@ -1483,7 +1493,7 @@ ble_gap_test_util_update_req_concurrent(
                                  NULL);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     hci_status = cmd_fail_idx == 0 ? fail_status : 0;
     rc = ble_hs_test_util_conn_update(2, init_params, hci_status);
@@ -1495,14 +1505,14 @@ ble_gap_test_util_update_req_concurrent(
     ble_gap_test_util_verify_tx_update_conn(init_params);
 
     if (rc == 0) {
-        TEST_ASSERT(ble_gap_update_in_progress(2));
+        TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
     } else {
-        TEST_ASSERT(!ble_gap_update_in_progress(2));
+        TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
         return;
     }
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(2));
+    TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
 
     /* Receive connection parameter update request from peer. */
     ble_gap_test_conn_self_params = *self_params;
@@ -1512,19 +1522,19 @@ ble_gap_test_util_update_req_concurrent(
         goto hci_fail;
     }
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(2));
+    TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
 
     /* Verify tx of connection parameters reply command. */
     ble_gap_test_util_verify_tx_params_reply_pos();
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_gap_update_in_progress(2));
+    TEST_ASSERT(ble_gap_test_util_update_in_progress(2));
 
     /* Receive connection update complete event. */
     ble_gap_test_util_rx_update_complete(0, self_params);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(!ble_gap_update_in_progress(2));
+    TEST_ASSERT(!ble_gap_test_util_update_in_progress(2));
 
     TEST_ASSERT(ble_gap_test_conn_event == BLE_GAP_EVENT_CONN_UPDATED);
     TEST_ASSERT(ble_gap_test_conn_status == 0);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatt_disc_c_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_disc_c_test.c b/net/nimble/host/src/test/ble_gatt_disc_c_test.c
index d2d9acb..afffeef 100644
--- a/net/nimble/host/src/test/ble_gatt_disc_c_test.c
+++ b/net/nimble/host/src/test/ble_gatt_disc_c_test.c
@@ -52,10 +52,9 @@ ble_gatt_disc_c_test_init(void)
 
 static int
 ble_gatt_disc_c_test_misc_rx_rsp_once(
-    struct ble_hs_conn *conn, struct ble_gatt_disc_c_test_char *chars)
+    uint16_t conn_handle, struct ble_gatt_disc_c_test_char *chars)
 {
     struct ble_att_read_type_rsp rsp;
-    struct ble_l2cap_chan *chan;
     uint8_t buf[1024];
     int off;
     int rc;
@@ -104,26 +103,25 @@ ble_gatt_disc_c_test_misc_rx_rsp_once(
         }
     }
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     return i;
 }
 
 static void
-ble_gatt_disc_c_test_misc_rx_rsp(struct ble_hs_conn *conn,
-                                     uint16_t end_handle,
-                                     struct ble_gatt_disc_c_test_char *chars)
+ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle,
+                                 uint16_t end_handle,
+                                 struct ble_gatt_disc_c_test_char *chars)
 {
     int count;
     int idx;
 
     idx = 0;
     while (chars[idx].decl_handle != 0) {
-        count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn, chars + idx);
+        count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn_handle,
+                                                      chars + idx);
         if (count == 0) {
             break;
         }
@@ -133,7 +131,7 @@ ble_gatt_disc_c_test_misc_rx_rsp(struct ble_hs_conn *conn,
     if (chars[idx - 1].decl_handle != end_handle) {
         /* Send the pending ATT Request. */
         ble_hs_test_util_tx_all();
-        ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_READ_TYPE_REQ,
+        ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ,
                                         BLE_ATT_ERR_ATTR_NOT_FOUND,
                                         chars[idx - 1].decl_handle);
     }
@@ -208,21 +206,20 @@ ble_gatt_disc_c_test_misc_all(uint16_t start_handle, uint16_t end_handle,
                               int stop_after,
                               struct ble_gatt_disc_c_test_char *chars)
 {
-    struct ble_hs_conn *conn;
     int num_left;
     int rc;
 
     ble_gatt_disc_c_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     num_left = stop_after;
     rc = ble_gattc_disc_all_chrs(2, start_handle, end_handle,
                                  ble_gatt_disc_c_test_misc_cb, &num_left);
     TEST_ASSERT(rc == 0);
 
-    ble_gatt_disc_c_test_misc_rx_rsp(conn, end_handle, chars);
+    ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, chars);
     ble_gatt_disc_c_test_misc_verify_chars(chars, stop_after);
 }
 
@@ -232,13 +229,12 @@ ble_gatt_disc_c_test_misc_uuid(uint16_t start_handle, uint16_t end_handle,
                                struct ble_gatt_disc_c_test_char *rsp_chars,
                                struct ble_gatt_disc_c_test_char *ret_chars)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_gatt_disc_c_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     rc = ble_gattc_disc_chrs_by_uuid(2, start_handle, end_handle,
                                      uuid128,
@@ -246,7 +242,7 @@ ble_gatt_disc_c_test_misc_uuid(uint16_t start_handle, uint16_t end_handle,
                                      &stop_after);
     TEST_ASSERT(rc == 0);
 
-    ble_gatt_disc_c_test_misc_rx_rsp(conn, end_handle, rsp_chars);
+    ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, rsp_chars);
     ble_gatt_disc_c_test_misc_verify_chars(ret_chars, 0);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatt_disc_d_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_disc_d_test.c b/net/nimble/host/src/test/ble_gatt_disc_d_test.c
index a3c76a5..6b0a807 100644
--- a/net/nimble/host/src/test/ble_gatt_disc_d_test.c
+++ b/net/nimble/host/src/test/ble_gatt_disc_d_test.c
@@ -50,10 +50,9 @@ ble_gatt_disc_d_test_init(void)
 
 static int
 ble_gatt_disc_d_test_misc_rx_rsp_once(
-    struct ble_hs_conn *conn, struct ble_gatt_disc_d_test_dsc *dscs)
+    uint16_t conn_handle, struct ble_gatt_disc_d_test_dsc *dscs)
 {
     struct ble_att_find_info_rsp rsp;
-    struct ble_l2cap_chan *chan;
     uint8_t buf[1024];
     uint16_t uuid16_cur;
     uint16_t uuid16_0;
@@ -98,17 +97,15 @@ ble_gatt_disc_d_test_misc_rx_rsp_once(
         }
     }
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     return i;
 }
 
 static void
-ble_gatt_disc_d_test_misc_rx_rsp(struct ble_hs_conn *conn,
+ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle,
                                  uint16_t end_handle,
                                  struct ble_gatt_disc_d_test_dsc *dscs)
 {
@@ -117,7 +114,7 @@ ble_gatt_disc_d_test_misc_rx_rsp(struct ble_hs_conn *conn,
 
     idx = 0;
     while (dscs[idx].chr_def_handle != 0) {
-        count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn, dscs + idx);
+        count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn_handle, dscs + idx);
         if (count == 0) {
             break;
         }
@@ -127,7 +124,7 @@ ble_gatt_disc_d_test_misc_rx_rsp(struct ble_hs_conn *conn,
     if (dscs[idx - 1].dsc_handle != end_handle) {
         /* Send the pending ATT Request. */
         ble_hs_test_util_tx_all();
-        ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_FIND_INFO_REQ,
+        ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_FIND_INFO_REQ,
                                         BLE_ATT_ERR_ATTR_NOT_FOUND,
                                         end_handle);
     }
@@ -199,21 +196,20 @@ ble_gatt_disc_d_test_misc_all(uint16_t chr_def_handle, uint16_t end_handle,
                               int stop_after,
                               struct ble_gatt_disc_d_test_dsc *dscs)
 {
-    struct ble_hs_conn *conn;
     int num_left;
     int rc;
 
     ble_gatt_disc_d_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     num_left = stop_after;
     rc = ble_gattc_disc_all_dscs(2, chr_def_handle, end_handle,
                                  ble_gatt_disc_d_test_misc_cb, &num_left);
     TEST_ASSERT(rc == 0);
 
-    ble_gatt_disc_d_test_misc_rx_rsp(conn, end_handle, dscs);
+    ble_gatt_disc_d_test_misc_rx_rsp(2, end_handle, dscs);
     ble_gatt_disc_d_test_misc_verify_dscs(dscs, stop_after);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatt_disc_s_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_disc_s_test.c b/net/nimble/host/src/test/ble_gatt_disc_s_test.c
index 533340a..c59e578 100644
--- a/net/nimble/host/src/test/ble_gatt_disc_s_test.c
+++ b/net/nimble/host/src/test/ble_gatt_disc_s_test.c
@@ -58,10 +58,9 @@ ble_gatt_disc_s_test_misc_svc_length(struct ble_gatt_disc_s_test_svc *service)
 
 static int
 ble_gatt_disc_s_test_misc_rx_all_rsp_once(
-    struct ble_hs_conn *conn, struct ble_gatt_disc_s_test_svc *services)
+    uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
 {
     struct ble_att_read_group_type_rsp rsp;
-    struct ble_l2cap_chan *chan;
     uint8_t buf[1024];
     int off;
     int rc;
@@ -102,10 +101,8 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once(
         }
     }
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     return i;
@@ -113,14 +110,14 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once(
 
 static void
 ble_gatt_disc_s_test_misc_rx_all_rsp(
-    struct ble_hs_conn *conn, struct ble_gatt_disc_s_test_svc *services)
+    uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
 {
     int count;
     int idx;
 
     idx = 0;
     while (services[idx].start_handle != 0) {
-        count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn,
+        count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn_handle,
                                                           services + idx);
         idx += count;
     }
@@ -128,7 +125,8 @@ ble_gatt_disc_s_test_misc_rx_all_rsp(
     if (services[idx - 1].end_handle != 0xffff) {
         /* Send the pending ATT Request. */
         ble_hs_test_util_tx_all();
-        ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_READ_GROUP_TYPE_REQ,
+        ble_hs_test_util_rx_att_err_rsp(conn_handle,
+                                        BLE_ATT_OP_READ_GROUP_TYPE_REQ,
                                         BLE_ATT_ERR_ATTR_NOT_FOUND,
                                         services[idx - 1].start_handle);
     }
@@ -136,9 +134,8 @@ ble_gatt_disc_s_test_misc_rx_all_rsp(
 
 static int
 ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(
-    struct ble_hs_conn *conn, struct ble_gatt_disc_s_test_svc *services)
+    uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
 {
-    struct ble_l2cap_chan *chan;
     uint8_t buf[1024];
     int off;
     int rc;
@@ -162,10 +159,8 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(
         off += 2;
     }
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     return i;
@@ -173,14 +168,14 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(
 
 static void
 ble_gatt_disc_s_test_misc_rx_uuid_rsp(
-    struct ble_hs_conn *conn, struct ble_gatt_disc_s_test_svc *services)
+    uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services)
 {
     int count;
     int idx;
 
     idx = 0;
     while (services[idx].start_handle != 0) {
-        count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn,
+        count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn_handle,
                                                            services + idx);
         idx += count;
     }
@@ -188,7 +183,8 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp(
     if (services[idx - 1].end_handle != 0xffff) {
         /* Send the pending ATT Request. */
         ble_hs_test_util_tx_all();
-        ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_FIND_TYPE_VALUE_REQ,
+        ble_hs_test_util_rx_att_err_rsp(conn_handle,
+                                        BLE_ATT_OP_FIND_TYPE_VALUE_REQ,
                                         BLE_ATT_ERR_ATTR_NOT_FOUND,
                                         services[idx - 1].start_handle);
     }
@@ -243,18 +239,17 @@ ble_gatt_disc_s_test_misc_disc_cb(uint16_t conn_handle,
 static void
 ble_gatt_disc_s_test_misc_good_all(struct ble_gatt_disc_s_test_svc *services)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_gatt_disc_s_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     rc = ble_gattc_disc_all_svcs(2, ble_gatt_disc_s_test_misc_disc_cb, NULL);
     TEST_ASSERT(rc == 0);
 
-    ble_gatt_disc_s_test_misc_rx_all_rsp(conn, services);
+    ble_gatt_disc_s_test_misc_rx_all_rsp(2, services);
     ble_gatt_disc_s_test_misc_verify_services(services);
 }
 
@@ -262,13 +257,12 @@ static void
 ble_gatt_disc_s_test_misc_good_uuid(
     struct ble_gatt_disc_s_test_svc *services)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_gatt_disc_s_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     if (services[0].uuid16 != 0) {
         rc = ble_uuid_16_to_128(services[0].uuid16, services[0].uuid128);
@@ -278,7 +272,7 @@ ble_gatt_disc_s_test_misc_good_uuid(
                                     ble_gatt_disc_s_test_misc_disc_cb, NULL);
     TEST_ASSERT(rc == 0);
 
-    ble_gatt_disc_s_test_misc_rx_uuid_rsp(conn, services);
+    ble_gatt_disc_s_test_misc_rx_uuid_rsp(2, services);
     ble_gatt_disc_s_test_misc_verify_services(services);
 }
 


[2/4] incubator-mynewt-core git commit: BLE Host - Enforce thread safety in unit tests.

Posted by cc...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatt_find_s_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_find_s_test.c b/net/nimble/host/src/test/ble_gatt_find_s_test.c
index 6b360c6..9db15ff 100644
--- a/net/nimble/host/src/test/ble_gatt_find_s_test.c
+++ b/net/nimble/host/src/test/ble_gatt_find_s_test.c
@@ -63,10 +63,9 @@ ble_gatt_find_s_test_misc_cb(uint16_t conn_handle,
 }
 static int
 ble_gatt_find_s_test_misc_rx_read_type(
-    struct ble_hs_conn *conn, struct ble_gatt_find_s_test_entry *entries)
+    uint16_t conn_handle, struct ble_gatt_find_s_test_entry *entries)
 {
     struct ble_att_read_type_rsp rsp;
-    struct ble_l2cap_chan *chan;
     uint16_t uuid16;
     uint8_t buf[1024];
     int off;
@@ -109,36 +108,31 @@ ble_gatt_find_s_test_misc_rx_read_type(
     }
 
     if (i == 0) {
-        ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_READ_TYPE_REQ,
+        ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ,
                                         BLE_ATT_ERR_ATTR_NOT_FOUND, 0);
         return 0;
     }
 
     ble_att_read_type_rsp_write(buf + 0, BLE_ATT_READ_TYPE_RSP_BASE_SZ, &rsp);
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     return i;
 }
 
 static void
-ble_gatt_find_s_test_misc_rx_read(struct ble_hs_conn *conn, uint8_t *uuid128)
+ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, uint8_t *uuid128)
 {
-    struct ble_l2cap_chan *chan;
     uint8_t buf[17];
     int rc;
 
     buf[0] = BLE_ATT_OP_READ_RSP;
     memcpy(buf + 1, uuid128, 16);
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, 17);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 17);
     TEST_ASSERT(rc == 0);
 }
 
@@ -182,7 +176,7 @@ ble_gatt_find_s_test_misc_verify_tx_read(uint16_t handle)
 }
 
 static void
-ble_gatt_find_s_test_misc_find_inc(struct ble_hs_conn *conn,
+ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle,
                                    uint16_t start_handle, uint16_t end_handle,
                                    struct ble_gatt_find_s_test_entry *entries)
 {
@@ -193,7 +187,7 @@ ble_gatt_find_s_test_misc_find_inc(struct ble_hs_conn *conn,
     int rc;
     int i;
 
-    rc = ble_gattc_find_inc_svcs(conn->bhc_handle, start_handle, end_handle,
+    rc = ble_gattc_find_inc_svcs(conn_handle, start_handle, end_handle,
                                  ble_gatt_find_s_test_misc_cb, &service);
     TEST_ASSERT(rc == 0);
 
@@ -201,7 +195,7 @@ ble_gatt_find_s_test_misc_find_inc(struct ble_hs_conn *conn,
     idx = 0;
     while (1) {
         ble_gatt_find_s_test_misc_verify_tx_read_type(cur_start, end_handle);
-        num_found = ble_gatt_find_s_test_misc_rx_read_type(conn,
+        num_found = ble_gatt_find_s_test_misc_rx_read_type(conn_handle,
                                                            entries + idx);
         if (num_found == 0) {
             break;
@@ -211,7 +205,8 @@ ble_gatt_find_s_test_misc_find_inc(struct ble_hs_conn *conn,
             TEST_ASSERT(num_found == 1);
             ble_gatt_find_s_test_misc_verify_tx_read(
                 entries[idx].start_handle);
-            ble_gatt_find_s_test_misc_rx_read(conn, entries[idx].uuid128);
+            ble_gatt_find_s_test_misc_rx_read(conn_handle,
+                                              entries[idx].uuid128);
         }
 
         idx += num_found;
@@ -232,13 +227,11 @@ ble_gatt_find_s_test_misc_find_inc(struct ble_hs_conn *conn,
 
 TEST_CASE(ble_gatt_find_s_test_1)
 {
-    struct ble_hs_conn *conn;
-
     /* Two 16-bit UUID services; one response. */
     ble_gatt_find_s_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
-    ble_gatt_find_s_test_misc_find_inc(conn, 5, 10,
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
+    ble_gatt_find_s_test_misc_find_inc(2, 5, 10,
         ((struct ble_gatt_find_s_test_entry[]) { {
             .inc_handle = 6,
             .start_handle = 35,
@@ -256,9 +249,9 @@ TEST_CASE(ble_gatt_find_s_test_1)
 
     /* One 128-bit UUID service; two responses. */
     ble_gatt_find_s_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
-    ble_gatt_find_s_test_misc_find_inc(conn, 34, 100,
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
+    ble_gatt_find_s_test_misc_find_inc(2, 34, 100,
         ((struct ble_gatt_find_s_test_entry[]) { {
             .inc_handle = 36,
             .start_handle = 403,
@@ -271,9 +264,9 @@ TEST_CASE(ble_gatt_find_s_test_1)
 
     /* Two 128-bit UUID service; four responses. */
     ble_gatt_find_s_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
-    ble_gatt_find_s_test_misc_find_inc(conn, 34, 100,
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
+    ble_gatt_find_s_test_misc_find_inc(2, 34, 100,
         ((struct ble_gatt_find_s_test_entry[]) { {
             .inc_handle = 36,
             .start_handle = 403,
@@ -291,9 +284,9 @@ TEST_CASE(ble_gatt_find_s_test_1)
 
     /* Two 16-bit UUID; three 128-bit UUID; seven responses. */
     ble_gatt_find_s_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
-    ble_gatt_find_s_test_misc_find_inc(conn, 1, 100,
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
+    ble_gatt_find_s_test_misc_find_inc(2, 1, 100,
         ((struct ble_gatt_find_s_test_entry[]) { {
             .inc_handle = 36,
             .start_handle = 403,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatt_read_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_read_test.c b/net/nimble/host/src/test/ble_gatt_read_test.c
index edf7d63..03df56e 100644
--- a/net/nimble/host/src/test/ble_gatt_read_test.c
+++ b/net/nimble/host/src/test/ble_gatt_read_test.c
@@ -149,11 +149,10 @@ ble_gatt_read_test_long_cb(uint16_t conn_handle, struct ble_gatt_error *error,
 }
 
 static void
-ble_gatt_read_test_misc_rx_rsp_good_raw(struct ble_hs_conn *conn,
+ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle,
                                         uint8_t att_op,
                                         void *data, int data_len)
 {
-    struct ble_l2cap_chan *chan;
     uint8_t buf[1024];
     int rc;
 
@@ -165,40 +164,36 @@ ble_gatt_read_test_misc_rx_rsp_good_raw(struct ble_hs_conn *conn,
     buf[0] = att_op;
     memcpy(buf + 1, data, data_len);
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf,
-                                                1 + data_len);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, 1 + data_len);
     TEST_ASSERT(rc == 0);
 }
 
 static void
-ble_gatt_read_test_misc_rx_rsp_good(struct ble_hs_conn *conn,
+ble_gatt_read_test_misc_rx_rsp_good(uint16_t conn_handle,
                                     struct ble_gatt_attr *attr)
 {
-    ble_gatt_read_test_misc_rx_rsp_good_raw(conn, BLE_ATT_OP_READ_RSP,
+    ble_gatt_read_test_misc_rx_rsp_good_raw(conn_handle, BLE_ATT_OP_READ_RSP,
                                             attr->value,
                                             attr->value_len);
 }
 
 static void
-ble_gatt_read_test_misc_rx_rsp_bad(struct ble_hs_conn *conn,
+ble_gatt_read_test_misc_rx_rsp_bad(uint16_t conn_handle,
                                    uint8_t att_error, uint16_t err_handle)
 {
     /* Send the pending ATT Read Request. */
     ble_hs_test_util_tx_all();
 
-    ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_READ_REQ, att_error,
-                                    err_handle);
+    ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_REQ,
+                                    att_error, err_handle);
 }
 
 static int
-ble_gatt_read_test_misc_uuid_rx_rsp_good(struct ble_hs_conn *conn,
+ble_gatt_read_test_misc_uuid_rx_rsp_good(uint16_t conn_handle,
                                          struct ble_gatt_attr *attrs)
 {
     struct ble_att_read_type_rsp rsp;
-    struct ble_l2cap_chan *chan;
     uint8_t buf[1024];
     int prev_len;
     int off;
@@ -230,10 +225,8 @@ ble_gatt_read_test_misc_uuid_rx_rsp_good(struct ble_hs_conn *conn,
         off += attrs[i].value_len;
     }
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, off);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, off);
     TEST_ASSERT(rc == 0);
 
     return i;
@@ -242,21 +235,19 @@ ble_gatt_read_test_misc_uuid_rx_rsp_good(struct ble_hs_conn *conn,
 static void
 ble_gatt_read_test_misc_verify_good(struct ble_gatt_attr *attr)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_read(conn->bhc_handle, attr->handle, ble_gatt_read_test_cb,
-                        NULL);
+    rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
-    ble_gatt_read_test_misc_rx_rsp_good(conn, attr);
+    ble_gatt_read_test_misc_rx_rsp_good(2, attr);
 
     TEST_ASSERT(ble_gatt_read_test_num_attrs == 1);
-    TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == conn->bhc_handle);
+    TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == 2);
     TEST_ASSERT(ble_gatt_read_test_attrs[0].handle == attr->handle);
     TEST_ASSERT(ble_gatt_read_test_attrs[0].value_len == attr->value_len);
     TEST_ASSERT(memcmp(ble_gatt_read_test_attrs[0].value, attr->value,
@@ -267,21 +258,19 @@ static void
 ble_gatt_read_test_misc_verify_bad(uint8_t att_status,
                                    struct ble_gatt_attr *attr)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_read(conn->bhc_handle, attr->handle, ble_gatt_read_test_cb,
-                        NULL);
+    rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
-    ble_gatt_read_test_misc_rx_rsp_bad(conn, att_status, attr->handle);
+    ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, attr->handle);
 
     TEST_ASSERT(ble_gatt_read_test_num_attrs == 0);
-    TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == conn->bhc_handle);
+    TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2);
     TEST_ASSERT(ble_gatt_read_test_bad_status ==
                 BLE_HS_ERR_ATT_BASE + att_status);
     TEST_ASSERT(!ble_gattc_any_jobs());
@@ -293,26 +282,25 @@ ble_gatt_read_test_misc_uuid_verify_good(uint16_t start_handle,
                                          int stop_after,
                                          struct ble_gatt_attr *attrs)
 {
-    struct ble_hs_conn *conn;
     int num_read;
     int idx;
     int rc;
     int i;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_read_by_uuid(conn->bhc_handle, start_handle, end_handle,
-                                uuid128, ble_gatt_read_test_cb, &stop_after);
+    rc = ble_gattc_read_by_uuid(2, start_handle, end_handle, uuid128,
+                                ble_gatt_read_test_cb, &stop_after);
     TEST_ASSERT_FATAL(rc == 0);
 
     idx = 0;
     while (1) {
-        num_read = ble_gatt_read_test_misc_uuid_rx_rsp_good(conn, attrs + idx);
+        num_read = ble_gatt_read_test_misc_uuid_rx_rsp_good(2, attrs + idx);
         if (num_read == 0) {
             ble_hs_test_util_tx_all();
-            ble_hs_test_util_rx_att_err_rsp(conn, BLE_ATT_OP_READ_TYPE_REQ,
+            ble_hs_test_util_rx_att_err_rsp(2, BLE_ATT_OP_READ_TYPE_REQ,
                                             BLE_ATT_ERR_ATTR_NOT_FOUND,
                                             start_handle);
             break;
@@ -325,8 +313,7 @@ ble_gatt_read_test_misc_uuid_verify_good(uint16_t start_handle,
     TEST_ASSERT(idx == ble_gatt_read_test_num_attrs);
 
     for (i = 0; i < idx; i++) {
-        TEST_ASSERT(ble_gatt_read_test_attrs[i].conn_handle ==
-                    conn->bhc_handle);
+        TEST_ASSERT(ble_gatt_read_test_attrs[i].conn_handle == 2);
         TEST_ASSERT(ble_gatt_read_test_attrs[i].handle == attrs[i].handle);
         TEST_ASSERT(ble_gatt_read_test_attrs[i].value_len ==
                     attrs[i].value_len);
@@ -340,7 +327,6 @@ static void
 ble_gatt_read_test_misc_long_verify_good(int max_reads,
                                          struct ble_gatt_attr *attr)
 {
-    struct ble_hs_conn *conn;
     int reads_left;
     int chunk_sz;
     int rem_len;
@@ -349,15 +335,15 @@ ble_gatt_read_test_misc_long_verify_good(int max_reads,
     int rc;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     if (max_reads == 0) {
         max_reads = INT_MAX;
     }
     reads_left = max_reads;
-    rc = ble_gattc_read_long(conn->bhc_handle, attr->handle,
-                             ble_gatt_read_test_long_cb, &reads_left);
+    rc = ble_gattc_read_long(2, attr->handle, ble_gatt_read_test_long_cb,
+                             &reads_left);
     TEST_ASSERT_FATAL(rc == 0);
 
     off = 0;
@@ -373,7 +359,7 @@ ble_gatt_read_test_misc_long_verify_good(int max_reads,
         } else {
             att_op = BLE_ATT_OP_READ_BLOB_RSP;
         }
-        ble_gatt_read_test_misc_rx_rsp_good_raw(conn, att_op,
+        ble_gatt_read_test_misc_rx_rsp_good_raw(2, att_op,
                                                 attr->value + off, chunk_sz);
         rem_len -= chunk_sz;
         off += chunk_sz;
@@ -381,7 +367,7 @@ ble_gatt_read_test_misc_long_verify_good(int max_reads,
 
     TEST_ASSERT(ble_gatt_read_test_complete);
     TEST_ASSERT(!ble_gattc_any_jobs());
-    TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == conn->bhc_handle);
+    TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == 2);
     TEST_ASSERT(ble_gatt_read_test_attrs[0].handle == attr->handle);
     if (reads_left > 0) {
         TEST_ASSERT(ble_gatt_read_test_attrs[0].value_len == attr->value_len);
@@ -394,21 +380,20 @@ static void
 ble_gatt_read_test_misc_long_verify_bad(uint8_t att_status,
                                         struct ble_gatt_attr *attr)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_read_long(conn->bhc_handle, attr->handle,
+    rc = ble_gattc_read_long(2, attr->handle,
                              ble_gatt_read_test_long_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
-    ble_gatt_read_test_misc_rx_rsp_bad(conn, att_status, attr->handle);
+    ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, attr->handle);
 
     TEST_ASSERT(ble_gatt_read_test_num_attrs == 0);
-    TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == conn->bhc_handle);
+    TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2);
     TEST_ASSERT(ble_gatt_read_test_bad_status ==
                 BLE_HS_ERR_ATT_BASE + att_status);
     TEST_ASSERT(!ble_gattc_any_jobs());
@@ -430,7 +415,6 @@ static void
 ble_gatt_read_test_misc_mult_verify_good(struct ble_gatt_attr *attrs)
 {
     uint8_t expected_value[512];
-    struct ble_hs_conn *conn;
     uint16_t handles[256];
     int num_attrs;
     int chunk_sz;
@@ -439,8 +423,8 @@ ble_gatt_read_test_misc_mult_verify_good(struct ble_gatt_attr *attrs)
     int i;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     num_attrs = ble_gatt_read_test_misc_extract_handles(attrs, handles);
 
@@ -458,16 +442,16 @@ ble_gatt_read_test_misc_mult_verify_good(struct ble_gatt_attr *attrs)
         }
     }
 
-    rc = ble_gattc_read_mult(conn->bhc_handle, handles, num_attrs,
+    rc = ble_gattc_read_mult(2, handles, num_attrs,
                              ble_gatt_read_test_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
-    ble_gatt_read_test_misc_rx_rsp_good_raw(conn, BLE_ATT_OP_READ_MULT_RSP,
+    ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_MULT_RSP,
                                             expected_value, off);
 
     TEST_ASSERT(ble_gatt_read_test_complete);
     TEST_ASSERT(!ble_gattc_any_jobs());
-    TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == conn->bhc_handle);
+    TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == 2);
     TEST_ASSERT(ble_gatt_read_test_attrs[0].value_len == off);
     TEST_ASSERT(memcmp(ble_gatt_read_test_attrs[0].value, expected_value,
                        off) == 0);
@@ -478,25 +462,24 @@ ble_gatt_read_test_misc_mult_verify_bad(uint8_t att_status,
                                         uint16_t err_handle,
                                         struct ble_gatt_attr *attrs)
 {
-    struct ble_hs_conn *conn;
     uint16_t handles[256];
     int num_attrs;
     int rc;
 
     ble_gatt_read_test_misc_init();
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     num_attrs = ble_gatt_read_test_misc_extract_handles(attrs, handles);
 
-    rc = ble_gattc_read_mult(conn->bhc_handle, handles, num_attrs,
+    rc = ble_gattc_read_mult(2, handles, num_attrs,
                              ble_gatt_read_test_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
-    ble_gatt_read_test_misc_rx_rsp_bad(conn, att_status, err_handle);
+    ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, err_handle);
 
     TEST_ASSERT(ble_gatt_read_test_num_attrs == 0);
-    TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == conn->bhc_handle);
+    TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2);
     TEST_ASSERT(ble_gatt_read_test_bad_status ==
                 BLE_HS_ERR_ATT_BASE + att_status);
     TEST_ASSERT(!ble_gattc_any_jobs());

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatt_write_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_write_test.c b/net/nimble/host/src/test/ble_gatt_write_test.c
index b452e79..f12ea77 100644
--- a/net/nimble/host/src/test/ble_gatt_write_test.c
+++ b/net/nimble/host/src/test/ble_gatt_write_test.c
@@ -74,33 +74,26 @@ ble_gatt_write_test_cb_good(uint16_t conn_handle, struct ble_gatt_error *error,
 }
 
 static void
-ble_gatt_write_test_rx_rsp(struct ble_hs_conn *conn)
+ble_gatt_write_test_rx_rsp(uint16_t conn_handle)
 {
-    struct ble_l2cap_chan *chan;
     uint8_t op;
     int rc;
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
     op = BLE_ATT_OP_WRITE_RSP;
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, &op, 1);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                &op, 1);
     TEST_ASSERT(rc == 0);
 }
 
 static void
-ble_gatt_write_test_rx_prep_rsp(struct ble_hs_conn *conn, uint16_t attr_handle,
+ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t attr_handle,
                                 uint16_t offset,
                                 void *attr_data, uint16_t attr_data_len)
 {
     struct ble_att_prep_write_cmd rsp;
-    struct ble_l2cap_chan *chan;
     uint8_t buf[512];
     int rc;
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
     rsp.bapc_handle = attr_handle;
     rsp.bapc_offset = offset;
     ble_att_prep_write_rsp_write(buf, sizeof buf, &rsp);
@@ -108,40 +101,36 @@ ble_gatt_write_test_rx_prep_rsp(struct ble_hs_conn *conn, uint16_t attr_handle,
     memcpy(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, attr_data, attr_data_len);
 
     rc = ble_hs_test_util_l2cap_rx_payload_flat(
-        conn, chan, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ + attr_data_len);
+        conn_handle, BLE_L2CAP_CID_ATT, buf,
+        BLE_ATT_PREP_WRITE_CMD_BASE_SZ + attr_data_len);
     TEST_ASSERT(rc == 0);
 }
 
 static void
-ble_gatt_write_test_rx_exec_rsp(struct ble_hs_conn *conn)
+ble_gatt_write_test_rx_exec_rsp(uint16_t conn_handle)
 {
-    struct ble_l2cap_chan *chan;
     uint8_t op;
     int rc;
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
     op = BLE_ATT_OP_EXEC_WRITE_RSP;
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, &op, 1);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                &op, 1);
     TEST_ASSERT(rc == 0);
 }
 
 static void
 ble_gatt_write_test_misc_long_good(int attr_len)
 {
-    struct ble_hs_conn *conn;
     int off;
     int len;
     int rc;
 
     ble_gatt_write_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_write_long(conn->bhc_handle, 100,
-                              ble_gatt_write_test_attr_value,
+    rc = ble_gattc_write_long(2, 100, ble_gatt_write_test_attr_value,
                               attr_len, ble_gatt_write_test_cb_good,
                               &attr_len);
     TEST_ASSERT(rc == 0);
@@ -156,7 +145,7 @@ ble_gatt_write_test_misc_long_good(int attr_len)
         if (off + len > attr_len) {
             len = attr_len - off;
         }
-        ble_gatt_write_test_rx_prep_rsp(conn, 100, off,
+        ble_gatt_write_test_rx_prep_rsp(2, 100, off,
                                         ble_gatt_write_test_attr_value + off,
                                         len);
 
@@ -168,20 +157,19 @@ ble_gatt_write_test_misc_long_good(int attr_len)
 
     /* Receive Exec Write response. */
     ble_hs_test_util_tx_all();
-    ble_gatt_write_test_rx_exec_rsp(conn);
+    ble_gatt_write_test_rx_exec_rsp(2);
 
     /* Verify callback got called. */
     TEST_ASSERT(ble_gatt_write_test_cb_called);
 }
 
-typedef void ble_gatt_write_test_long_fail_fn(struct ble_hs_conn *conn,
+typedef void ble_gatt_write_test_long_fail_fn(uint16_t conn_handle,
                                               int off, int len);
 
 static void
 ble_gatt_write_test_misc_long_bad(int attr_len,
                                   ble_gatt_write_test_long_fail_fn *cb)
 {
-    struct ble_hs_conn *conn;
     int fail_now;
     int off;
     int len;
@@ -189,11 +177,10 @@ ble_gatt_write_test_misc_long_bad(int attr_len,
 
     ble_gatt_write_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_write_long(conn->bhc_handle, 100,
-                              ble_gatt_write_test_attr_value,
+    rc = ble_gattc_write_long(2, 100, ble_gatt_write_test_attr_value,
                               attr_len, ble_gatt_write_test_cb_good, NULL);
     TEST_ASSERT(rc == 0);
 
@@ -211,10 +198,9 @@ ble_gatt_write_test_misc_long_bad(int attr_len,
         }
         if (!fail_now) {
             ble_gatt_write_test_rx_prep_rsp(
-                conn, 100, off, ble_gatt_write_test_attr_value + off,
-                len);
+                2, 100, off, ble_gatt_write_test_attr_value + off, len);
         } else {
-            cb(conn, off, len);
+            cb(2, off, len);
             break;
         }
 
@@ -231,38 +217,38 @@ ble_gatt_write_test_misc_long_bad(int attr_len,
 }
 
 static void
-ble_gatt_write_test_misc_long_fail_handle(struct ble_hs_conn *conn,
+ble_gatt_write_test_misc_long_fail_handle(uint16_t conn_handle,
                                           int off, int len)
 {
     ble_gatt_write_test_rx_prep_rsp(
-        conn, 99, off, ble_gatt_write_test_attr_value + off,
+        conn_handle, 99, off, ble_gatt_write_test_attr_value + off,
         len);
 }
 
 static void
-ble_gatt_write_test_misc_long_fail_offset(struct ble_hs_conn *conn,
+ble_gatt_write_test_misc_long_fail_offset(uint16_t conn_handle,
                                           int off, int len)
 {
     ble_gatt_write_test_rx_prep_rsp(
-        conn, 100, off + 1, ble_gatt_write_test_attr_value + off,
+        conn_handle, 100, off + 1, ble_gatt_write_test_attr_value + off,
         len);
 }
 
 static void
-ble_gatt_write_test_misc_long_fail_value(struct ble_hs_conn *conn,
+ble_gatt_write_test_misc_long_fail_value(uint16_t conn_handle,
                                          int off, int len)
 {
     ble_gatt_write_test_rx_prep_rsp(
-        conn, 100, off, ble_gatt_write_test_attr_value + off + 1,
+        conn_handle, 100, off, ble_gatt_write_test_attr_value + off + 1,
         len);
 }
 
 static void
-ble_gatt_write_test_misc_long_fail_length(struct ble_hs_conn *conn,
+ble_gatt_write_test_misc_long_fail_length(uint16_t conn_handle,
                                           int off, int len)
 {
     ble_gatt_write_test_rx_prep_rsp(
-        conn, 100, off, ble_gatt_write_test_attr_value + off,
+        conn_handle, 100, off, ble_gatt_write_test_attr_value + off,
         len - 1);
 }
 
@@ -291,7 +277,6 @@ ble_gatt_write_test_reliable_cb_good(uint16_t conn_handle,
 static void
 ble_gatt_write_test_misc_reliable_good(struct ble_gatt_attr *attrs)
 {
-    struct ble_hs_conn *conn;
     int num_attrs;
     int attr_idx;
     int rc;
@@ -302,10 +287,10 @@ ble_gatt_write_test_misc_reliable_good(struct ble_gatt_attr *attrs)
     for (num_attrs = 0; attrs[num_attrs].handle != 0; num_attrs++)
         ;
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
-    rc = ble_gattc_write_reliable(conn->bhc_handle, attrs, num_attrs,
+    rc = ble_gattc_write_reliable(2, attrs, num_attrs,
                                   ble_gatt_write_test_reliable_cb_good, NULL);
     TEST_ASSERT(rc == 0);
 
@@ -314,7 +299,7 @@ ble_gatt_write_test_misc_reliable_good(struct ble_gatt_attr *attrs)
         ble_hs_test_util_tx_all();
 
         /* Receive Prep Write response. */
-        ble_gatt_write_test_rx_prep_rsp(conn, attrs[attr_idx].handle, 0,
+        ble_gatt_write_test_rx_prep_rsp(2, attrs[attr_idx].handle, 0,
                                         attrs[attr_idx].value,
                                         attrs[attr_idx].value_len);
 
@@ -324,7 +309,7 @@ ble_gatt_write_test_misc_reliable_good(struct ble_gatt_attr *attrs)
 
     /* Receive Exec Write response. */
     ble_hs_test_util_tx_all();
-    ble_gatt_write_test_rx_exec_rsp(conn);
+    ble_gatt_write_test_rx_exec_rsp(2);
 
     /* Verify callback got called. */
     TEST_ASSERT(ble_gatt_write_test_cb_called);
@@ -342,7 +327,7 @@ TEST_CASE(ble_gatt_write_test_no_rsp)
     ble_gatt_write_test_init();
 
     ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+                                 NULL, NULL);
 
     attr_len = 4;
     rc = ble_gattc_write_no_rsp(2, 100, ble_gatt_write_test_attr_value,
@@ -358,13 +343,12 @@ TEST_CASE(ble_gatt_write_test_no_rsp)
 
 TEST_CASE(ble_gatt_write_test_rsp)
 {
-    struct ble_hs_conn *conn;
     int attr_len;
 
     ble_gatt_write_test_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
-                                        NULL, NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
 
     attr_len = 4;
     ble_gattc_write(2, 100, ble_gatt_write_test_attr_value, attr_len,
@@ -377,7 +361,7 @@ TEST_CASE(ble_gatt_write_test_rsp)
     TEST_ASSERT(!ble_gatt_write_test_cb_called);
 
     /* Receive write response. */
-    ble_gatt_write_test_rx_rsp(conn);
+    ble_gatt_write_test_rx_rsp(2);
 
     /* Verify callback got called. */
     TEST_ASSERT(ble_gatt_write_test_cb_called);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_gatts_notify_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatts_notify_test.c b/net/nimble/host/src/test/ble_gatts_notify_test.c
index b0e079b..526e6d6 100644
--- a/net/nimble/host/src/test/ble_gatts_notify_test.c
+++ b/net/nimble/host/src/test/ble_gatts_notify_test.c
@@ -67,8 +67,7 @@ static uint8_t ble_gatts_notify_test_chr_2_val[1024];
 static int ble_gatts_notify_test_chr_2_len;
 
 static void
-ble_gatts_notify_test_misc_init(struct ble_hs_conn **conn,
-                                struct ble_l2cap_chan **att_chan)
+ble_gatts_notify_test_misc_init(uint16_t *out_conn_handle)
 {
     int rc;
 
@@ -84,16 +83,11 @@ ble_gatts_notify_test_misc_init(struct ble_hs_conn **conn,
 
     ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
                                  NULL, NULL);
-    *conn = ble_hs_conn_find(2);
-    TEST_ASSERT_FATAL(*conn != NULL);
-
-    *att_chan = ble_hs_conn_chan_find(*conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(*att_chan != NULL);
+    *out_conn_handle = 2;
 }
 
 static void
-ble_gatts_notify_test_misc_enable_notify(struct ble_hs_conn *conn,
-                                         struct ble_l2cap_chan *chan,
+ble_gatts_notify_test_misc_enable_notify(uint16_t conn_handle,
                                          uint16_t chr_def_handle,
                                          uint16_t flags)
 {
@@ -105,7 +99,8 @@ ble_gatts_notify_test_misc_enable_notify(struct ble_hs_conn *conn,
     ble_att_write_req_write(buf, sizeof buf, &req);
 
     htole16(buf + BLE_ATT_WRITE_REQ_BASE_SZ, flags);
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
 }
 
@@ -161,22 +156,21 @@ ble_gatts_notify_test_misc_access(uint16_t conn_handle,
 }
 
 static void
-ble_gatts_notify_test_misc_rx_indicate_rsp(struct ble_hs_conn *conn,
-                                           struct ble_l2cap_chan *chan)
+ble_gatts_notify_test_misc_rx_indicate_rsp(uint16_t conn_handle)
 {
     uint8_t buf[BLE_ATT_INDICATE_RSP_SZ];
     int rc;
 
     ble_att_indicate_rsp_write(buf, sizeof buf);
 
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
 }
 
 
 static void
-ble_gatts_notify_test_misc_verify_tx_n(struct ble_l2cap_chan *chan,
-                                       uint8_t *attr_data, int attr_len)
+ble_gatts_notify_test_misc_verify_tx_n(uint8_t *attr_data, int attr_len)
 {
     struct ble_att_notify_req req;
     struct os_mbuf *om;
@@ -196,8 +190,7 @@ ble_gatts_notify_test_misc_verify_tx_n(struct ble_l2cap_chan *chan,
 }
 
 static void
-ble_gatts_notify_test_misc_verify_tx_i(struct ble_l2cap_chan *chan,
-                                       uint8_t *attr_data, int attr_len)
+ble_gatts_notify_test_misc_verify_tx_i(uint8_t *attr_data, int attr_len)
 {
     struct ble_att_indicate_req req;
     struct os_mbuf *om;
@@ -218,17 +211,16 @@ ble_gatts_notify_test_misc_verify_tx_i(struct ble_l2cap_chan *chan,
 
 TEST_CASE(ble_gatts_notify_test_n)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
 
-    ble_gatts_notify_test_misc_init(&conn, &chan);
+    ble_gatts_notify_test_misc_init(&conn_handle);
 
     /* Enable notifications on both characteristics. */
     ble_gatts_notify_test_misc_enable_notify(
-        conn, chan, ble_gatts_notify_test_chr_1_def_handle,
+        conn_handle, ble_gatts_notify_test_chr_1_def_handle,
         BLE_GATTS_CLT_CFG_F_NOTIFY);
     ble_gatts_notify_test_misc_enable_notify(
-        conn, chan, ble_gatts_notify_test_chr_2_def_handle,
+        conn_handle, ble_gatts_notify_test_chr_2_def_handle,
         BLE_GATTS_CLT_CFG_F_NOTIFY);
 
     /* Update characteristic 1's value. */
@@ -237,8 +229,7 @@ TEST_CASE(ble_gatts_notify_test_n)
     ble_gatts_chr_updated(ble_gatts_notify_test_chr_1_def_handle);
 
     /* Verify notification sent properly. */
-    ble_gatts_notify_test_misc_verify_tx_n(chan,
-                                           ble_gatts_notify_test_chr_1_val,
+    ble_gatts_notify_test_misc_verify_tx_n(ble_gatts_notify_test_chr_1_val,
                                            ble_gatts_notify_test_chr_1_len);
 
     /* Update characteristic 2's value. */
@@ -248,24 +239,22 @@ TEST_CASE(ble_gatts_notify_test_n)
     ble_gatts_chr_updated(ble_gatts_notify_test_chr_2_def_handle);
 
     /* Verify notification sent properly. */
-    ble_gatts_notify_test_misc_verify_tx_n(chan,
-                                           ble_gatts_notify_test_chr_2_val,
+    ble_gatts_notify_test_misc_verify_tx_n(ble_gatts_notify_test_chr_2_val,
                                            ble_gatts_notify_test_chr_2_len);
 }
 
 TEST_CASE(ble_gatts_notify_test_i)
 {
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    uint16_t conn_handle;
 
-    ble_gatts_notify_test_misc_init(&conn, &chan);
+    ble_gatts_notify_test_misc_init(&conn_handle);
 
     /* Enable indications on both characteristics. */
     ble_gatts_notify_test_misc_enable_notify(
-        conn, chan, ble_gatts_notify_test_chr_1_def_handle,
+        conn_handle, ble_gatts_notify_test_chr_1_def_handle,
         BLE_GATTS_CLT_CFG_F_INDICATE);
     ble_gatts_notify_test_misc_enable_notify(
-        conn, chan, ble_gatts_notify_test_chr_2_def_handle,
+        conn_handle, ble_gatts_notify_test_chr_2_def_handle,
         BLE_GATTS_CLT_CFG_F_INDICATE);
 
     /* Toss both write responses. */
@@ -279,10 +268,8 @@ TEST_CASE(ble_gatts_notify_test_i)
     ble_gatts_chr_updated(ble_gatts_notify_test_chr_1_def_handle);
 
     /* Verify indication sent properly. */
-    ble_gatts_notify_test_misc_verify_tx_i(
-        chan,
-        ble_gatts_notify_test_chr_1_val,
-        ble_gatts_notify_test_chr_1_len);
+    ble_gatts_notify_test_misc_verify_tx_i(ble_gatts_notify_test_chr_1_val,
+                                           ble_gatts_notify_test_chr_1_len);
 
     /* Update characteristic 2's value. */
     ble_gatts_notify_test_chr_2_len = 16;
@@ -297,17 +284,15 @@ TEST_CASE(ble_gatts_notify_test_i)
     TEST_ASSERT(ble_hs_test_util_prev_tx_queue_sz() == 0);
 
     /* Receive the confirmation for the first indication. */
-    ble_gatts_notify_test_misc_rx_indicate_rsp(conn, chan);
+    ble_gatts_notify_test_misc_rx_indicate_rsp(conn_handle);
 
     /* Verify indication sent properly. */
     ble_hs_test_util_tx_all();
-    ble_gatts_notify_test_misc_verify_tx_i(
-        chan,
-        ble_gatts_notify_test_chr_2_val,
-        ble_gatts_notify_test_chr_2_len);
+    ble_gatts_notify_test_misc_verify_tx_i(ble_gatts_notify_test_chr_2_val,
+                                           ble_gatts_notify_test_chr_2_len);
 
     /* Receive the confirmation for the second indication. */
-    ble_gatts_notify_test_misc_rx_indicate_rsp(conn, chan);
+    ble_gatts_notify_test_misc_rx_indicate_rsp(conn_handle);
 
     /* Verify no pending GATT jobs. */
     TEST_ASSERT(!ble_gattc_any_jobs());

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_conn_test.c b/net/nimble/host/src/test/ble_hs_conn_test.c
index fa23c18..c56efe0 100644
--- a/net/nimble/host/src/test/ble_hs_conn_test.c
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -26,6 +26,18 @@
 #include "host/host_hci.h"
 #include "ble_hs_test_util.h"
 
+static int
+ble_hs_conn_test_util_any()
+{
+    struct ble_hs_conn *conn;
+
+    ble_hs_lock();
+    conn = ble_hs_conn_first();
+    ble_hs_unlock();
+
+    return conn != NULL;
+}
+
 TEST_CASE(ble_hs_conn_test_direct_connect_success)
 {
     struct hci_le_conn_complete evt;
@@ -38,7 +50,7 @@ TEST_CASE(ble_hs_conn_test_direct_connect_success)
 
     /* Ensure no current or pending connections. */
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 
     /* Initiate connection. */
     rc = ble_hs_test_util_conn_initiate(0, addr, NULL, NULL, NULL, 0);
@@ -57,6 +69,8 @@ TEST_CASE(ble_hs_conn_test_direct_connect_success)
     TEST_ASSERT(rc == 0);
     TEST_ASSERT(!ble_gap_master_in_progress());
 
+    ble_hs_lock();
+
     conn = ble_hs_conn_first();
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_handle == 2);
@@ -67,6 +81,8 @@ TEST_CASE(ble_hs_conn_test_direct_connect_success)
     TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
     TEST_ASSERT(chan->blc_peer_mtu == 0);
     TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+
+    ble_hs_unlock();
 }
 
 TEST_CASE(ble_hs_conn_test_direct_connect_hci_errors)
@@ -78,14 +94,14 @@ TEST_CASE(ble_hs_conn_test_direct_connect_hci_errors)
 
     /* Ensure no current or pending connections. */
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 
     /* Initiate connection; receive no HCI ack. */
     rc = ble_gap_conn_initiate(0, addr, NULL, NULL, NULL);
     TEST_ASSERT(rc == BLE_HS_ETIMEOUT);
 
     TEST_ASSERT(!ble_gap_master_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 }
 
 TEST_CASE(ble_hs_conn_test_direct_connectable_success)
@@ -101,7 +117,7 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
     /* Ensure no current or pending connections. */
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(!ble_gap_slave_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 
     /* Initiate advertising. */
     rc = ble_hs_test_util_adv_start(BLE_GAP_DISC_MODE_NON,
@@ -125,6 +141,8 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(!ble_gap_slave_in_progress());
 
+    ble_hs_lock();
+
     conn = ble_hs_conn_first();
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_handle == 2);
@@ -135,6 +153,8 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_success)
     TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
     TEST_ASSERT(chan->blc_peer_mtu == 0);
     TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+
+    ble_hs_unlock();
 }
 
 TEST_CASE(ble_hs_conn_test_direct_connectable_hci_errors)
@@ -145,9 +165,9 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_hci_errors)
 
     ble_hs_test_util_init();
 
-   /* Ensure no current or pending connections. */
+    /* Ensure no current or pending connections. */
     TEST_ASSERT(!ble_gap_slave_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 
     /* Initiate connection. */
     rc = ble_hs_test_util_adv_start(BLE_GAP_DISC_MODE_NON,
@@ -162,7 +182,7 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_hci_errors)
     rc = ble_gap_rx_conn_complete(&evt);
     TEST_ASSERT(rc == 0);
     TEST_ASSERT(ble_gap_slave_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 }
 
 TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
@@ -179,7 +199,7 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
     /* Ensure no current or pending connections. */
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(!ble_gap_slave_in_progress());
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
 
     /* Initiate advertising. */
     memset(&adv_fields, 0, sizeof adv_fields);
@@ -207,6 +227,8 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(!ble_gap_slave_in_progress());
 
+    ble_hs_lock();
+
     conn = ble_hs_conn_first();
     TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_handle == 2);
@@ -217,6 +239,8 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
     TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
     TEST_ASSERT(chan->blc_peer_mtu == 0);
     TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+
+    ble_hs_unlock();
 }
 
 TEST_SUITE(conn_suite)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c
index 3d7a0b9..d0b8c0b 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -299,12 +299,11 @@ ble_hs_test_util_set_ack_seq(struct ble_hs_test_util_phony_ack *acks)
     ble_hci_set_phony_ack_cb(ble_hs_test_util_phony_ack_cb);
 }
 
-struct ble_hs_conn *
+void
 ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr,
                              ble_gap_conn_fn *cb, void *cb_arg)
 {
     struct hci_le_conn_complete evt;
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_hs_test_util_set_ack(
@@ -325,12 +324,7 @@ ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr,
     rc = ble_gap_rx_conn_complete(&evt);
     TEST_ASSERT(rc == 0);
 
-    conn = ble_hs_conn_find(handle);
-    TEST_ASSERT_FATAL(conn != NULL);
-
     ble_hs_test_util_prev_hci_tx_clear();
-
-    return conn;
 }
 
 int
@@ -534,7 +528,7 @@ ble_hs_test_util_security_initiate(uint16_t conn_handle, uint8_t hci_status)
 }
 
 int
-ble_hs_test_util_l2cap_rx_first_frag(struct ble_hs_conn *conn, uint16_t cid,
+ble_hs_test_util_l2cap_rx_first_frag(uint16_t conn_handle, uint16_t cid,
                                      struct hci_data_hdr *hci_hdr,
                                      struct os_mbuf *om)
 {
@@ -543,24 +537,35 @@ ble_hs_test_util_l2cap_rx_first_frag(struct ble_hs_conn *conn, uint16_t cid,
     om = ble_l2cap_prepend_hdr(om, cid, OS_MBUF_PKTLEN(om));
     TEST_ASSERT_FATAL(om != NULL);
 
-    rc = ble_hs_test_util_l2cap_rx(conn, hci_hdr, om);
+    rc = ble_hs_test_util_l2cap_rx(conn_handle, hci_hdr, om);
     return rc;
 }
 
 int
-ble_hs_test_util_l2cap_rx(struct ble_hs_conn *conn,
+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;
     struct os_mbuf *rx_buf;
     int rc;
 
-    rc = ble_l2cap_rx(conn, hci_hdr, om, &rx_cb, &rx_buf);
-    if (rc == 0) {
+    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);
+    }
+
+    ble_hs_unlock();
+
+    if (conn == NULL) {
+        rc = BLE_HS_ENOTCONN;
+    } else if (rc == 0) {
         TEST_ASSERT_FATAL(rx_cb != NULL);
         TEST_ASSERT_FATAL(rx_buf != NULL);
-        rc = rx_cb(conn->bhc_handle, &rx_buf);
+        rc = rx_cb(conn_handle, &rx_buf);
         os_mbuf_free_chain(rx_buf);
     } else if (rc == BLE_HS_EAGAIN) {
         /* More fragments on the way. */
@@ -571,8 +576,7 @@ ble_hs_test_util_l2cap_rx(struct ble_hs_conn *conn,
 }
 
 int
-ble_hs_test_util_l2cap_rx_payload_flat(struct ble_hs_conn *conn,
-                                       struct ble_l2cap_chan *chan,
+ble_hs_test_util_l2cap_rx_payload_flat(uint16_t conn_handle, uint16_t cid,
                                        const void *data, int len)
 {
     struct hci_data_hdr hci_hdr;
@@ -586,21 +590,19 @@ ble_hs_test_util_l2cap_rx_payload_flat(struct ble_hs_conn *conn,
     TEST_ASSERT_FATAL(rc == 0);
 
     hci_hdr.hdh_handle_pb_bc =
-        host_hci_handle_pb_bc_join(conn->bhc_handle,
+        host_hci_handle_pb_bc_join(conn_handle,
                                    BLE_HCI_PB_FIRST_FLUSH, 0);
     hci_hdr.hdh_len = OS_MBUF_PKTHDR(om)->omp_len;
 
-    rc = ble_hs_test_util_l2cap_rx_first_frag(conn, chan->blc_cid, &hci_hdr,
-                                              om);
+    rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, cid, &hci_hdr, om);
     return rc;
 }
 
 void
-ble_hs_test_util_rx_att_err_rsp(struct ble_hs_conn *conn, uint8_t req_op,
+ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op,
                                 uint8_t error_code, uint16_t err_handle)
 {
     struct ble_att_error_rsp rsp;
-    struct ble_l2cap_chan *chan;
     uint8_t buf[BLE_ATT_ERROR_RSP_SZ];
     int rc;
 
@@ -610,10 +612,8 @@ ble_hs_test_util_rx_att_err_rsp(struct ble_hs_conn *conn, uint8_t req_op,
 
     ble_att_error_rsp_write(buf, sizeof buf, &rsp);
 
-    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    TEST_ASSERT_FATAL(chan != NULL);
-
-    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn, chan, buf, sizeof buf);
+    rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+                                                buf, sizeof buf);
     TEST_ASSERT(rc == 0);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h
index c642c65..baffffc 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -52,10 +52,8 @@ void ble_hs_test_util_build_cmd_complete(uint8_t *dst, int len,
 void ble_hs_test_util_build_cmd_status(uint8_t *dst, int len,
                                        uint8_t status, uint8_t num_pkts,
                                        uint16_t opcode);
-struct ble_hs_conn *ble_hs_test_util_create_conn(uint16_t handle,
-                                                 uint8_t *addr,
-                                                 ble_gap_conn_fn *cb,
-                                                 void *cb_arg);
+void ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr,
+                                  ble_gap_conn_fn *cb, void *cb_arg);
 int ble_hs_test_util_conn_initiate(int addr_type, uint8_t *addr,
                                    struct ble_gap_crt_params *params,
                                    ble_gap_conn_fn *cb, void *cb_arg,
@@ -81,18 +79,16 @@ int ble_hs_test_util_conn_update(uint16_t conn_handle,
                                  uint8_t hci_status);
 int ble_hs_test_util_security_initiate(uint16_t conn_handle,
                                        uint8_t hci_status);
-int ble_hs_test_util_l2cap_rx_first_frag(struct ble_hs_conn *conn,
-                                         uint16_t cid,
+int ble_hs_test_util_l2cap_rx_first_frag(uint16_t conn_handle, uint16_t cid,
                                          struct hci_data_hdr *hci_hdr,
                                          struct os_mbuf *om);
-int ble_hs_test_util_l2cap_rx(struct ble_hs_conn *conn,
+int ble_hs_test_util_l2cap_rx(uint16_t conn_handle,
                               struct hci_data_hdr *hci_hdr,
                               struct os_mbuf *om);
-int ble_hs_test_util_l2cap_rx_payload_flat(struct ble_hs_conn *conn,
-                                           struct ble_l2cap_chan *chan,
+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_rx_att_err_rsp(struct ble_hs_conn *conn, uint8_t req_op,
+void ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op,
                                      uint8_t error_code, uint16_t err_handle);
 void ble_hs_test_util_set_startup_acks(void);
 void ble_hs_test_util_rx_num_completed_pkts_event(

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_l2cap_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_sm_test.c b/net/nimble/host/src/test/ble_l2cap_sm_test.c
index e6adb05..43d9350 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -141,7 +141,7 @@ ble_l2cap_sm_test_util_conn_cb(int event, int status,
 }
 
 static void
-ble_l2cap_sm_test_util_rx_pair_cmd(struct ble_hs_conn *conn, uint8_t op,
+ble_l2cap_sm_test_util_rx_pair_cmd(uint16_t conn_handle, uint8_t op,
                                    struct ble_l2cap_sm_pair_cmd *cmd,
                                    int rx_status)
 {
@@ -166,31 +166,31 @@ ble_l2cap_sm_test_util_rx_pair_cmd(struct ble_hs_conn *conn, uint8_t op,
     ble_l2cap_sm_pair_cmd_write(v, payload_len, op == BLE_L2CAP_SM_OP_PAIR_REQ,
                                 cmd);
 
-    rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SM, &hci_hdr,
-                                              om);
+    rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SM,
+                                              &hci_hdr, om);
     TEST_ASSERT(rc == rx_status);
 }
 
 static void
-ble_l2cap_sm_test_util_rx_pair_req(struct ble_hs_conn *conn,
+ble_l2cap_sm_test_util_rx_pair_req(uint16_t conn_handle,
                                    struct ble_l2cap_sm_pair_cmd *req,
                                    int rx_status)
 {
-    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_REQ, req,
-                                       rx_status);
+    ble_l2cap_sm_test_util_rx_pair_cmd(conn_handle, BLE_L2CAP_SM_OP_PAIR_REQ,
+                                       req, rx_status);
 }
 
 static void
-ble_l2cap_sm_test_util_rx_pair_rsp(struct ble_hs_conn *conn,
+ble_l2cap_sm_test_util_rx_pair_rsp(uint16_t conn_handle,
                                    struct ble_l2cap_sm_pair_cmd *rsp,
                                    int rx_status)
 {
-    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_RSP, rsp,
-                                       rx_status);
+    ble_l2cap_sm_test_util_rx_pair_cmd(conn_handle, BLE_L2CAP_SM_OP_PAIR_RSP,
+                                       rsp, rx_status);
 }
 
 static void
-ble_l2cap_sm_test_util_rx_confirm(struct ble_hs_conn *conn,
+ble_l2cap_sm_test_util_rx_confirm(uint16_t conn_handle,
                                   struct ble_l2cap_sm_pair_confirm *cmd)
 {
     struct hci_data_hdr hci_hdr;
@@ -213,13 +213,13 @@ ble_l2cap_sm_test_util_rx_confirm(struct ble_hs_conn *conn,
 
     ble_l2cap_sm_pair_confirm_write(v, payload_len, cmd);
 
-    rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SM, &hci_hdr,
-                                              om);
+    rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SM,
+                                              &hci_hdr, om);
     TEST_ASSERT_FATAL(rc == 0);
 }
 
 static void
-ble_l2cap_sm_test_util_rx_random(struct ble_hs_conn *conn,
+ble_l2cap_sm_test_util_rx_random(uint16_t conn_handle,
                                  struct ble_l2cap_sm_pair_random *cmd,
                                  int exp_status)
 {
@@ -243,8 +243,8 @@ ble_l2cap_sm_test_util_rx_random(struct ble_hs_conn *conn,
 
     ble_l2cap_sm_pair_random_write(v, payload_len, cmd);
 
-    rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SM, &hci_hdr,
-                                              om);
+    rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SM,
+                                              &hci_hdr, om);
     TEST_ASSERT_FATAL(rc == exp_status);
 }
 
@@ -461,9 +461,17 @@ ble_l2cap_sm_test_util_peer_fail_inval(
     ble_l2cap_sm_test_util_init();
     ble_hs_test_util_set_public_addr(rsp_addr);
 
-    conn = ble_hs_test_util_create_conn(2, init_addr,
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        NULL);
+    ble_hs_test_util_create_conn(2, init_addr, ble_l2cap_sm_test_util_conn_cb,
+                                 NULL);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     if (!we_are_master) {
         conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
@@ -473,7 +481,7 @@ ble_l2cap_sm_test_util_peer_fail_inval(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req,
+    ble_l2cap_sm_test_util_rx_pair_req(2, pair_req,
                                        BLE_HS_SM_US_ERR(pair_fail->reason));
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
@@ -676,9 +684,17 @@ ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
     ble_hs_test_util_set_public_addr(rsp_addr);
     ble_l2cap_sm_dbg_set_next_pair_rand(random_rsp->value);
 
-    conn = ble_hs_test_util_create_conn(2, init_addr,
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        NULL);
+    ble_hs_test_util_create_conn(2, init_addr, ble_l2cap_sm_test_util_conn_cb,
+                                 NULL);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     /* Peer is the initiator so we must be the slave. */
     conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
@@ -686,7 +702,7 @@ ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req, 0);
+    ble_l2cap_sm_test_util_rx_pair_req(2, pair_req, 0);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair response. */
@@ -695,7 +711,7 @@ ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_req);
+    ble_l2cap_sm_test_util_rx_confirm(2, confirm_req);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair confirm. */
@@ -705,7 +721,7 @@ ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
 
     /* Receive a pair random from the peer. */
     ble_l2cap_sm_test_util_rx_random(
-        conn, random_req, BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH));
+        2, random_req, BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CONFIRM_MISMATCH));
 
     /* Ensure we sent the expected pair fail. */
     ble_hs_test_util_tx_all();
@@ -806,9 +822,18 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     ble_hs_test_util_set_public_addr(params->rsp_addr);
     ble_l2cap_sm_dbg_set_next_pair_rand(params->random_rsp.value);
 
-    conn = ble_hs_test_util_create_conn(2, params->init_addr,
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        &params->passkey);
+    ble_hs_test_util_create_conn(2, params->init_addr,
+                                 ble_l2cap_sm_test_util_conn_cb,
+                                 &params->passkey);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     /* Peer is the initiator so we must be the slave. */
     conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
@@ -817,7 +842,7 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, &params->pair_req, 0);
+    ble_l2cap_sm_test_util_rx_pair_req(2, &params->pair_req, 0);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -828,7 +853,7 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, &params->confirm_req);
+    ble_l2cap_sm_test_util_rx_confirm(2, &params->confirm_req);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -839,7 +864,7 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a pair random from the peer. */
-    ble_l2cap_sm_test_util_rx_random(conn, &params->random_req, 0);
+    ble_l2cap_sm_test_util_rx_random(2, &params->random_req, 0);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -1023,9 +1048,18 @@ ble_l2cap_sm_test_util_peer_bonding_good(uint8_t *ltk, int authenticated,
     memcpy(ltk_info.ltk, ltk, sizeof ltk_info.ltk);
     ltk_info.authenticated = authenticated;
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[6]){1,2,3,4,5,6}),
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        &ltk_info);
+    ble_hs_test_util_create_conn(2, ((uint8_t[6]){1,2,3,4,5,6}),
+                                 ble_l2cap_sm_test_util_conn_cb,
+                                 &ltk_info);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
@@ -1079,9 +1113,18 @@ ble_l2cap_sm_test_util_peer_bonding_bad(uint16_t ediv, uint64_t rand_num)
 
     ble_l2cap_sm_test_util_init();
 
-    conn = ble_hs_test_util_create_conn(2, ((uint8_t[6]){1,2,3,4,5,6}),
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        NULL);
+    ble_hs_test_util_create_conn(2, ((uint8_t[6]){1,2,3,4,5,6}),
+                                 ble_l2cap_sm_test_util_conn_cb,
+                                 NULL);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
@@ -1144,9 +1187,18 @@ ble_l2cap_sm_test_util_us_fail_inval(
     ble_l2cap_sm_test_util_init();
     ble_hs_test_util_set_public_addr(params->rsp_addr);
 
-    conn = ble_hs_test_util_create_conn(2, params->init_addr,
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        NULL);
+    ble_hs_test_util_create_conn(2, params->init_addr,
+                                 ble_l2cap_sm_test_util_conn_cb,
+                                 NULL);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
@@ -1163,7 +1215,7 @@ ble_l2cap_sm_test_util_us_fail_inval(
 
     /* Receive a pair response from the peer. */
     ble_l2cap_sm_test_util_rx_pair_rsp(
-        conn, &params->pair_rsp, BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_INVAL));
+        2, &params->pair_rsp, BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_INVAL));
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
@@ -1412,9 +1464,18 @@ ble_l2cap_sm_test_util_us_lgcy_good(
         ble_l2cap_sm_dbg_set_next_ltk(params->enc_info_req.ltk_le);
     }
 
-    conn = ble_hs_test_util_create_conn(2, params->rsp_addr,
-                                        ble_l2cap_sm_test_util_conn_cb,
-                                        NULL);
+    ble_hs_test_util_create_conn(2, params->rsp_addr,
+                                 ble_l2cap_sm_test_util_conn_cb,
+                                 NULL);
+
+    /* This test inspects and modifies the connection object without locking
+     * the host mutex.  It is not OK for real code to do this, but this test
+     * can assume the connection list is unchanging.
+     */
+    ble_hs_lock();
+    conn = ble_hs_conn_find(2);
+    TEST_ASSERT_FATAL(conn != NULL);
+    ble_hs_unlock();
 
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
@@ -1430,7 +1491,7 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a pair response from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_rsp(conn, &params->pair_rsp, 0);
+    ble_l2cap_sm_test_util_rx_pair_rsp(2, &params->pair_rsp, 0);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -1441,7 +1502,7 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, &params->confirm_rsp);
+    ble_l2cap_sm_test_util_rx_confirm(2, &params->confirm_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -1452,7 +1513,7 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Receive a pair random from the peer. */
-    ble_l2cap_sm_test_util_rx_random(conn, &params->random_rsp, 0);
+    ble_l2cap_sm_test_util_rx_random(2, &params->random_rsp, 0);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2dd32b7d/net/nimble/host/src/test/ble_l2cap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_test.c b/net/nimble/host/src/test/ble_l2cap_test.c
index 0229a54..23c0167 100644
--- a/net/nimble/host/src/test/ble_l2cap_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_test.c
@@ -50,7 +50,7 @@ ble_l2cap_test_util_init(void)
 }
 
 static void
-ble_l2cap_test_util_rx_update_req(struct ble_hs_conn *conn, uint8_t id,
+ble_l2cap_test_util_rx_update_req(uint16_t conn_handle, uint8_t id,
                                   struct ble_l2cap_sig_update_params *params)
 {
     struct ble_l2cap_sig_update_req req;
@@ -75,13 +75,13 @@ ble_l2cap_test_util_rx_update_req(struct ble_hs_conn *conn, uint8_t id,
 
     ble_hs_test_util_set_ack(
         host_hci_opcode_join(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CONN_UPDATE), 0);
-    rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SIG,
+    rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SIG,
                                               &hci_hdr, om);
     TEST_ASSERT_FATAL(rc == 0);
 }
 
 static int
-ble_l2cap_test_util_rx_update_rsp(struct ble_hs_conn *conn,
+ble_l2cap_test_util_rx_update_rsp(uint16_t conn_handle,
                                   uint8_t id, uint16_t result)
 {
     struct ble_l2cap_sig_update_rsp rsp;
@@ -101,7 +101,7 @@ ble_l2cap_test_util_rx_update_rsp(struct ble_hs_conn *conn,
     rsp.result = result;
     ble_l2cap_sig_update_rsp_write(v, BLE_L2CAP_SIG_UPDATE_RSP_SZ, &rsp);
 
-    rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SIG,
+    rc = ble_hs_test_util_l2cap_rx_first_frag(conn_handle, BLE_L2CAP_CID_SIG,
                                               &hci_hdr, om);
     return rc;
 }
@@ -202,14 +202,19 @@ ble_l2cap_test_util_dummy_rx(uint16_t conn_handle, struct os_mbuf **om)
     return 0;
 }
 
-static struct ble_hs_conn *
-ble_l2cap_test_util_create_conn(uint16_t handle, uint8_t *addr,
+static void
+ble_l2cap_test_util_create_conn(uint16_t conn_handle, uint8_t *addr,
                                 ble_gap_conn_fn *cb, void *cb_arg)
 {
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
 
-    conn = ble_hs_test_util_create_conn(handle, addr, cb, cb_arg);
+    ble_hs_test_util_create_conn(conn_handle, addr, cb, cb_arg);
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_find(conn_handle);
+    TEST_ASSERT_FATAL(conn != NULL);
 
     chan = ble_l2cap_chan_alloc();
     TEST_ASSERT_FATAL(chan != NULL);
@@ -223,11 +228,11 @@ ble_l2cap_test_util_create_conn(uint16_t handle, uint8_t *addr,
 
     ble_hs_test_util_prev_hci_tx_clear();
 
-    return conn;
+    ble_hs_unlock();
 }
 
 static int
-ble_l2cap_test_util_rx_first_frag(struct ble_hs_conn *conn,
+ble_l2cap_test_util_rx_first_frag(uint16_t conn_handle,
                                   uint16_t l2cap_frag_len,
                                   uint16_t cid, uint16_t l2cap_len)
 {
@@ -247,14 +252,14 @@ ble_l2cap_test_util_rx_first_frag(struct ble_hs_conn *conn,
     TEST_ASSERT_FATAL(om != NULL);
 
     hci_len = sizeof hci_hdr + l2cap_frag_len;
-    hci_hdr = BLE_L2CAP_TEST_UTIL_HCI_HDR(conn->bhc_handle,
+    hci_hdr = BLE_L2CAP_TEST_UTIL_HCI_HDR(conn_handle,
                                           BLE_HCI_PB_FIRST_FLUSH, hci_len);
-    rc = ble_hs_test_util_l2cap_rx(conn, &hci_hdr, om);
+    rc = ble_hs_test_util_l2cap_rx(conn_handle, &hci_hdr, om);
     return rc;
 }
 
 static int
-ble_l2cap_test_util_rx_next_frag(struct ble_hs_conn *conn, uint16_t hci_len)
+ble_l2cap_test_util_rx_next_frag(uint16_t conn_handle, uint16_t hci_len)
 {
     struct hci_data_hdr hci_hdr;
     struct os_mbuf *om;
@@ -267,47 +272,71 @@ ble_l2cap_test_util_rx_next_frag(struct ble_hs_conn *conn, uint16_t hci_len)
     v = os_mbuf_extend(om, hci_len);
     TEST_ASSERT_FATAL(v != NULL);
 
-    hci_hdr = BLE_L2CAP_TEST_UTIL_HCI_HDR(conn->bhc_handle,
+    hci_hdr = BLE_L2CAP_TEST_UTIL_HCI_HDR(conn_handle,
                                           BLE_HCI_PB_MIDDLE, hci_len);
-    rc = ble_hs_test_util_l2cap_rx(conn, &hci_hdr, om);
+    rc = ble_hs_test_util_l2cap_rx(conn_handle, &hci_hdr, om);
     return rc;
 }
 
 static void
-ble_l2cap_test_util_verify_first_frag(struct ble_hs_conn *conn,
+ble_l2cap_test_util_verify_first_frag(uint16_t conn_handle,
                                       uint16_t l2cap_frag_len,
                                       uint16_t l2cap_len)
 {
+    struct ble_hs_conn *conn;
     int rc;
 
-    rc = ble_l2cap_test_util_rx_first_frag(conn, l2cap_frag_len,
+    rc = ble_l2cap_test_util_rx_first_frag(conn_handle, l2cap_frag_len,
                                            BLE_L2CAP_TEST_CID, l2cap_len);
     TEST_ASSERT(rc == 0);
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_find(conn_handle);
+    TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan != NULL &&
                 conn->bhc_rx_chan->blc_cid == BLE_L2CAP_TEST_CID);
+
+    ble_hs_unlock();
 }
 
 static void
-ble_l2cap_test_util_verify_middle_frag(struct ble_hs_conn *conn,
+ble_l2cap_test_util_verify_middle_frag(uint16_t conn_handle,
                                        uint16_t hci_len)
 {
+    struct ble_hs_conn *conn;
     int rc;
 
-    rc = ble_l2cap_test_util_rx_next_frag(conn, hci_len);
+    rc = ble_l2cap_test_util_rx_next_frag(conn_handle, hci_len);
     TEST_ASSERT(rc == 0);
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_find(conn_handle);
+    TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan != NULL &&
                 conn->bhc_rx_chan->blc_cid == BLE_L2CAP_TEST_CID);
+
+    ble_hs_unlock();
 }
 
 static void
-ble_l2cap_test_util_verify_last_frag(struct ble_hs_conn *conn,
+ble_l2cap_test_util_verify_last_frag(uint16_t conn_handle,
                                      uint16_t hci_len)
 {
+    struct ble_hs_conn *conn;
     int rc;
 
-    rc = ble_l2cap_test_util_rx_next_frag(conn, hci_len);
+    rc = ble_l2cap_test_util_rx_next_frag(conn_handle, hci_len);
     TEST_ASSERT(rc == 0);
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_find(conn_handle);
+    TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_rx_chan == NULL);
+
+    ble_hs_unlock();
 }
 
 /*****************************************************************************
@@ -316,15 +345,14 @@ ble_l2cap_test_util_verify_last_frag(struct ble_hs_conn *conn,
 
 TEST_CASE(ble_l2cap_test_case_bad_header)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                           NULL, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    NULL, NULL);
 
-    rc = ble_l2cap_test_util_rx_first_frag(conn, 14, 1234, 10);
+    rc = ble_l2cap_test_util_rx_first_frag(2, 14, 1234, 10);
     TEST_ASSERT(rc == BLE_HS_ENOENT);
 }
 
@@ -335,14 +363,13 @@ TEST_CASE(ble_l2cap_test_case_bad_header)
 TEST_CASE(ble_l2cap_test_case_frag_single)
 {
     struct hci_data_hdr hci_hdr;
-    struct ble_hs_conn *conn;
     struct os_mbuf *om;
     int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                      NULL, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    NULL, NULL);
 
     /*** HCI header specifies middle fragment without start. */
     hci_hdr = BLE_L2CAP_TEST_UTIL_HCI_HDR(2, BLE_HCI_PB_MIDDLE, 10);
@@ -353,44 +380,42 @@ TEST_CASE(ble_l2cap_test_case_frag_single)
     om = ble_l2cap_prepend_hdr(om, 0, 5);
     TEST_ASSERT_FATAL(om != NULL);
 
-    rc = ble_hs_test_util_l2cap_rx(conn, &hci_hdr, om);
+    rc = ble_hs_test_util_l2cap_rx(2, &hci_hdr, om);
     TEST_ASSERT(rc == BLE_HS_EBADDATA);
 
     /*** Packet consisting of three fragments. */
-    ble_l2cap_test_util_verify_first_frag(conn, 10, 30);
-    ble_l2cap_test_util_verify_middle_frag(conn, 10);
-    ble_l2cap_test_util_verify_last_frag(conn, 10);
+    ble_l2cap_test_util_verify_first_frag(2, 10, 30);
+    ble_l2cap_test_util_verify_middle_frag(2, 10);
+    ble_l2cap_test_util_verify_last_frag(2, 10);
 
     /*** Packet consisting of five fragments. */
-    ble_l2cap_test_util_verify_first_frag(conn, 8, 49);
-    ble_l2cap_test_util_verify_middle_frag(conn, 13);
-    ble_l2cap_test_util_verify_middle_frag(conn, 2);
-    ble_l2cap_test_util_verify_middle_frag(conn, 21);
-    ble_l2cap_test_util_verify_last_frag(conn, 5);
+    ble_l2cap_test_util_verify_first_frag(2, 8, 49);
+    ble_l2cap_test_util_verify_middle_frag(2, 13);
+    ble_l2cap_test_util_verify_middle_frag(2, 2);
+    ble_l2cap_test_util_verify_middle_frag(2, 21);
+    ble_l2cap_test_util_verify_last_frag(2, 5);
 }
 
 TEST_CASE(ble_l2cap_test_case_frag_multiple)
 {
-    struct ble_hs_conn *conns[3];
-
     ble_l2cap_test_util_init();
 
-    conns[0] = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                          NULL, NULL);
-    conns[1] = ble_l2cap_test_util_create_conn(3, ((uint8_t[]){2,3,4,5,6,7}),
-                                          NULL, NULL);
-    conns[2] = ble_l2cap_test_util_create_conn(4, ((uint8_t[]){3,4,5,6,7,8}),
-                                          NULL, NULL);
-
-    ble_l2cap_test_util_verify_first_frag(conns[0], 3, 10);
-    ble_l2cap_test_util_verify_first_frag(conns[1], 2, 5);
-    ble_l2cap_test_util_verify_middle_frag(conns[0], 6);
-    ble_l2cap_test_util_verify_first_frag(conns[2], 1, 4);
-    ble_l2cap_test_util_verify_middle_frag(conns[1], 2);
-    ble_l2cap_test_util_verify_last_frag(conns[1], 1);
-    ble_l2cap_test_util_verify_middle_frag(conns[2], 2);
-    ble_l2cap_test_util_verify_last_frag(conns[2], 1);
-    ble_l2cap_test_util_verify_last_frag(conns[0], 1);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    NULL, NULL);
+    ble_l2cap_test_util_create_conn(3, ((uint8_t[]){2,3,4,5,6,7}),
+                                    NULL, NULL);
+    ble_l2cap_test_util_create_conn(4, ((uint8_t[]){3,4,5,6,7,8}),
+                                    NULL, NULL);
+
+    ble_l2cap_test_util_verify_first_frag(2, 3, 10);
+    ble_l2cap_test_util_verify_first_frag(3, 2, 5);
+    ble_l2cap_test_util_verify_middle_frag(2, 6);
+    ble_l2cap_test_util_verify_first_frag(4, 1, 4);
+    ble_l2cap_test_util_verify_middle_frag(3, 2);
+    ble_l2cap_test_util_verify_last_frag(3, 1);
+    ble_l2cap_test_util_verify_middle_frag(4, 2);
+    ble_l2cap_test_util_verify_last_frag(4, 1);
+    ble_l2cap_test_util_verify_last_frag(2, 1);
 }
 
 TEST_CASE(ble_l2cap_test_case_frag_channels)
@@ -400,22 +425,32 @@ TEST_CASE(ble_l2cap_test_case_frag_channels)
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                      NULL, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    NULL, NULL);
 
     /* Receive a starting fragment on the first channel. */
-    rc = ble_l2cap_test_util_rx_first_frag(conn, 14, BLE_L2CAP_TEST_CID, 30);
+    rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_TEST_CID, 30);
     TEST_ASSERT(rc == 0);
+
+    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->blc_cid == BLE_L2CAP_TEST_CID);
+    ble_hs_unlock();
 
     /* Receive a starting fragment on a different channel.  The first fragment
      * should get discarded.
      */
-    rc = ble_l2cap_test_util_rx_first_frag(conn, 14, BLE_L2CAP_CID_ATT, 30);
+    rc = ble_l2cap_test_util_rx_first_frag(2, 14, BLE_L2CAP_CID_ATT, 30);
     TEST_ASSERT(rc == 0);
+
+    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->blc_cid == BLE_L2CAP_CID_ATT);
+    ble_hs_unlock();
 }
 
 /*****************************************************************************
@@ -424,16 +459,15 @@ TEST_CASE(ble_l2cap_test_case_frag_channels)
 
 TEST_CASE(ble_l2cap_test_case_sig_unsol_rsp)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                           NULL, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    NULL, NULL);
 
     /* Receive an unsolicited response. */
-    rc = ble_l2cap_test_util_rx_update_rsp(conn, 100, 0);
+    rc = ble_l2cap_test_util_rx_update_rsp(2, 100, 0);
     TEST_ASSERT(rc == BLE_HS_ENOENT);
 
     /* Ensure we did not send anything in return. */
@@ -466,19 +500,20 @@ ble_l2cap_test_util_peer_updates(int accept)
 {
     struct ble_l2cap_sig_update_params l2cap_params;
     struct ble_gap_upd_params params;
-    struct ble_hs_conn *conn;
+    ble_hs_conn_flags_t conn_flags;
+    int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                           ble_l2cap_test_util_conn_cb,
-                                           &accept);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    ble_l2cap_test_util_conn_cb,
+                                    &accept);
 
     l2cap_params.itvl_min = 0x200;
     l2cap_params.itvl_max = 0x300;
     l2cap_params.slave_latency = 0;
     l2cap_params.timeout_multiplier = 0x100;
-    ble_l2cap_test_util_rx_update_req(conn, 1, &l2cap_params);
+    ble_l2cap_test_util_rx_update_req(2, 1, &l2cap_params);
 
     /* Ensure an update response command got sent. */
     ble_hs_process_tx_data_queue();
@@ -494,7 +529,8 @@ ble_l2cap_test_util_peer_updates(int accept)
         ble_l2cap_test_util_verify_tx_update_conn(&params);
     } else {
         /* Ensure no update got scheduled. */
-        TEST_ASSERT(!ble_gap_update_in_progress(BLE_HS_CONN_HANDLE_NONE));
+        rc = ble_hs_atomic_conn_flags(2, &conn_flags);
+        TEST_ASSERT(rc == 0 && !(conn_flags & BLE_HS_CONN_F_UPDATE));
     }
 }
 
@@ -509,24 +545,22 @@ static void
 ble_l2cap_test_util_we_update(int peer_accepts)
 {
     struct ble_l2cap_sig_update_params params;
-    struct ble_hs_conn *conn;
     uint8_t id;
     int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                      ble_l2cap_test_util_conn_cb, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    ble_l2cap_test_util_conn_cb, NULL);
 
     /* Only the slave can initiate the L2CAP connection update procedure. */
-    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+    ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 0);
 
     params.itvl_min = 0x200;
     params.itvl_min = 0x300;
     params.slave_latency = 0;
     params.timeout_multiplier = 0x100;
-    rc = ble_l2cap_sig_update(conn->bhc_handle, &params,
-                              ble_l2cap_test_util_update_cb, NULL);
+    rc = ble_l2cap_sig_update(2, &params, ble_l2cap_test_util_update_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -535,7 +569,7 @@ ble_l2cap_test_util_we_update(int peer_accepts)
     id = ble_l2cap_test_util_verify_tx_update_req(&params);
 
     /* Receive response from peer. */
-    rc = ble_l2cap_test_util_rx_update_rsp(conn, id, !peer_accepts);
+    rc = ble_l2cap_test_util_rx_update_rsp(2, id, !peer_accepts);
     TEST_ASSERT(rc == 0);
 
     /* Ensure callback got called. */
@@ -570,20 +604,18 @@ TEST_CASE(ble_l2cap_test_case_sig_update_init_reject)
 TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_master)
 {
     struct ble_l2cap_sig_update_params params;
-    struct ble_hs_conn *conn;
     int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                      ble_l2cap_test_util_conn_cb, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    ble_l2cap_test_util_conn_cb, NULL);
 
     params.itvl_min = 0x200;
     params.itvl_min = 0x300;
     params.slave_latency = 0;
     params.timeout_multiplier = 0x100;
-    rc = ble_l2cap_sig_update(conn->bhc_handle, &params,
-                              ble_l2cap_test_util_update_cb, NULL);
+    rc = ble_l2cap_sig_update(2, &params, ble_l2cap_test_util_update_cb, NULL);
     TEST_ASSERT_FATAL(rc == BLE_HS_EINVAL);
 
     /* Ensure callback never called. */
@@ -594,24 +626,22 @@ TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_master)
 TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_bad_id)
 {
     struct ble_l2cap_sig_update_params params;
-    struct ble_hs_conn *conn;
     uint8_t id;
     int rc;
 
     ble_l2cap_test_util_init();
 
-    conn = ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
-                                      ble_l2cap_test_util_conn_cb, NULL);
+    ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}),
+                                    ble_l2cap_test_util_conn_cb, NULL);
 
     /* Only the slave can initiate the L2CAP connection update procedure. */
-    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+    ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 0);
 
     params.itvl_min = 0x200;
     params.itvl_min = 0x300;
     params.slave_latency = 0;
     params.timeout_multiplier = 0x100;
-    rc = ble_l2cap_sig_update(conn->bhc_handle, &params,
-                              ble_l2cap_test_util_update_cb, NULL);
+    rc = ble_l2cap_sig_update(2, &params, ble_l2cap_test_util_update_cb, NULL);
     TEST_ASSERT_FATAL(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -620,14 +650,14 @@ TEST_CASE(ble_l2cap_test_case_sig_update_init_fail_bad_id)
     id = ble_l2cap_test_util_verify_tx_update_req(&params);
 
     /* Receive response from peer with incorrect ID. */
-    rc = ble_l2cap_test_util_rx_update_rsp(conn, id + 1, 0);
+    rc = ble_l2cap_test_util_rx_update_rsp(2, id + 1, 0);
     TEST_ASSERT(rc == BLE_HS_ENOENT);
 
     /* Ensure callback did not get called. */
     TEST_ASSERT(ble_l2cap_test_update_status == -1);
 
     /* Receive response from peer with correct ID. */
-    rc = ble_l2cap_test_util_rx_update_rsp(conn, id, 0);
+    rc = ble_l2cap_test_util_rx_update_rsp(2, id, 0);
     TEST_ASSERT(rc == 0);
 
     /* Ensure callback got called. */