Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/develop 302848d80 -> 1281bf352


BLE host - Don't lock conn list before att tx.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/5bdd4af0
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/5bdd4af0
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/5bdd4af0

Branch: refs/heads/develop
Commit: 5bdd4af0ad4a321ff52354d5603cda7d75c54006
Parents: bb97c9c
Author: Christopher Collins <ccollins47...@gmail.com>
Authored: Wed Feb 17 13:00:03 2016 -0800
Committer: Christopher Collins <ccollins47...@gmail.com>
Committed: Wed Feb 17 15:11:07 2016 -0800

----------------------------------------------------------------------
 net/nimble/host/src/ble_att.c               |   14 +-
 net/nimble/host/src/ble_att_clt.c           | 1002 ++++++++++++++--------
 net/nimble/host/src/ble_att_priv.h          |   30 +-
 net/nimble/host/src/ble_att_svr.c           |   12 +-
 net/nimble/host/src/ble_gattc.c             |  583 +++++--------
 net/nimble/host/src/ble_hs_misc.c           |   54 ++
 net/nimble/host/src/ble_hs_priv.h           |    8 +
 net/nimble/host/src/ble_l2cap_sig.c         |   20 +-
 net/nimble/host/src/test/ble_att_clt_test.c |   44 +-
 9 files changed, 976 insertions(+), 791 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index fc15d1c..21e3574 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -104,17 +104,11 @@ int
 ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                        struct ble_l2cap_chan **out_chan)
 {
-    *out_chan = NULL;
-
-    *out_conn = ble_hs_conn_find(conn_handle);
-    if (*out_conn == NULL) {
-        return BLE_HS_ENOTCONN;
-    }
-
-    *out_chan = ble_hs_conn_chan_find(*out_conn, BLE_L2CAP_CID_ATT);
-    assert(*out_chan != NULL);
+    int rc;
 
-    return 0;
+    rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT,
+                                         out_conn, out_chan);
+    return rc;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 8f01c1e..3c132f6 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -31,53 +31,43 @@
 #include "ble_att_priv.h"
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
  */
 static int
-ble_att_clt_init_req(struct ble_hs_conn *conn, struct ble_l2cap_chan **chan,
-                     struct os_mbuf **txom, uint16_t initial_sz)
+ble_att_clt_init_req(uint16_t initial_sz, struct os_mbuf **out_txom)
 {
     void *buf;
     int rc;
 
-    *txom = NULL;
-
-    *chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-    assert(*chan != NULL);
-
-    if (!ble_hs_conn_can_tx(conn)) {
-        rc = BLE_HS_ECONGESTED;
-        goto err;
-    }
-
-    *txom = ble_hs_misc_pkthdr();
-    if (*txom == NULL) {
+    *out_txom = ble_hs_misc_pkthdr();
+    if (*out_txom == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
-    buf = os_mbuf_extend(*txom, initial_sz);
+    buf = os_mbuf_extend(*out_txom, initial_sz);
     if (buf == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
     /* The caller expects the initial buffer to be at the start of the mbuf. */
-    assert(buf == (*txom)->om_data);
+    assert(buf == (*out_txom)->om_data);
 
     return 0;
 
 err:
-    os_mbuf_free_chain(*txom);
-    *txom = NULL;
+    os_mbuf_free_chain(*out_txom);
+    *out_txom = NULL;
     return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 static int
-ble_att_clt_append_blob(struct ble_l2cap_chan *chan, struct os_mbuf *txom,
+ble_att_clt_append_blob(uint16_t conn_handle, struct os_mbuf *txom,
                         void *blob, int blob_len)
 {
     uint16_t mtu;
@@ -92,7 +82,7 @@ ble_att_clt_append_blob(struct ble_l2cap_chan *chan, struct 
os_mbuf *txom,
         return 0;
     }
 
-    mtu = ble_l2cap_chan_mtu(chan);
+    mtu = ble_att_mtu(conn_handle);
     cmd_len = OS_MBUF_PKTLEN(txom) + blob_len;
     extra_len = cmd_len - mtu;
     if (extra_len > 0) {
@@ -107,6 +97,9 @@ ble_att_clt_append_blob(struct ble_l2cap_chan *chan, struct 
os_mbuf *txom,
     return 0;
 }
 
+/**
+ * Lock restrictions: none.
+ */
 static int
 ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void **out_attr_val,
                                  uint16_t *out_attr_len)
@@ -128,12 +121,42 @@ ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void 
**out_attr_val,
     return 0;
 }
 
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+static int
+ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
+{
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    ble_hs_conn_lock();
+
+    rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
+    if (rc == 0) {
+        if (!ble_hs_conn_can_tx(conn)) {
+            rc = BLE_HS_ECONGESTED;
+        } else {
+            rc = ble_l2cap_tx(conn, chan, txom);
+            txom = NULL;
+        }
+    }
+
+    ble_hs_conn_unlock();
+
+    os_mbuf_free_chain(txom);
+    return rc;
+}
+
 /*****************************************************************************
  * $error response                                                           *
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **om)
@@ -159,54 +182,82 @@ ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf 
**om)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
  */
-int
-ble_att_clt_tx_mtu(struct ble_hs_conn *conn, struct ble_att_mtu_cmd *req)
+static int
+ble_att_clt_build_mtu_req(struct ble_att_mtu_cmd *req,
+                          struct os_mbuf **out_txom)
 {
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
     txom = NULL;
 
-    if (req->bamc_mtu < BLE_ATT_MTU_DFLT) {
-        rc = BLE_HS_EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_MTU_CMD_SZ);
+    rc = ble_att_clt_init_req(BLE_ATT_MTU_CMD_SZ, &txom);
     if (rc != 0) {
-        goto err;
+        goto done;
     }
 
     rc = ble_att_mtu_req_write(txom->om_data, txom->om_len, req);
     assert(rc == 0);
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+done:
     if (rc != 0) {
-        goto err;
+        os_mbuf_free_chain(txom);
+        txom = NULL;
     }
 
-    chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+    *out_txom = txom;
+    return rc;
+}
 
-    return 0;
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+int
+ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req)
+{
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    struct os_mbuf *txom;
+    int rc;
+
+    if (req->bamc_mtu < BLE_ATT_MTU_DFLT) {
+        return BLE_HS_EINVAL;
+    }
+
+    rc = ble_att_clt_build_mtu_req(req, &txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    ble_hs_conn_lock();
+
+    rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
+    if (rc == 0) {
+        chan->blc_flags |= BLE_L2CAP_CHAN_F_TXED_MTU;
+    }
+
+    ble_hs_conn_unlock();
 
-err:
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
 {
     struct ble_att_mtu_cmd rsp;
     struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     uint16_t mtu;
     int rc;
 
@@ -219,16 +270,10 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf 
**om)
 
         ble_hs_conn_lock();
 
-        conn = ble_hs_conn_find(conn_handle);
-        if (conn == NULL) {
-            rc = BLE_HS_ENOTCONN;
-        } else {
-            chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-            assert(chan != NULL);
-
+        rc = ble_att_conn_chan_find(conn_handle, NULL, &chan);
+        if (rc == 0) {
             ble_att_set_peer_mtu(chan, rsp.bamc_mtu);
             mtu = ble_l2cap_chan_mtu(chan);
-            rc = 0;
         }
 
         ble_hs_conn_unlock();
@@ -243,52 +288,72 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf 
**om)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
+ */
+static int
+ble_att_clt_build_find_info_req(struct ble_att_find_info_req *req,
+                                struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_FIND_INFO_REQ_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_find_info_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_find_info(struct ble_hs_conn *conn,
+ble_att_clt_tx_find_info(uint16_t conn_handle,
                          struct ble_att_find_info_req *req)
 {
 #if !NIMBLE_OPT_ATT_CLT_FIND_INFO
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->bafq_start_handle == 0 ||
         req->bafq_start_handle > req->bafq_end_handle) {
 
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_FIND_INFO_REQ_SZ);
+    rc = ble_att_clt_build_find_info_req(req, &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_att_find_info_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om)
@@ -376,10 +441,48 @@ done:
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
+ */
+static int
+ble_att_clt_build_find_type_value_req(struct ble_att_find_type_value_req *req,
+                                      void *attribute_value, int value_len,
+                                      struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_FIND_TYPE_VALUE_REQ_BASE_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_find_type_value_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+    rc = os_mbuf_append(txom, attribute_value, value_len);
+    if (rc != 0) {
+        rc = BLE_HS_ENOMEM;
+        goto done;
+    }
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_find_type_value(struct ble_hs_conn *conn,
+ble_att_clt_tx_find_type_value(uint16_t conn_handle,
                                struct ble_att_find_type_value_req *req,
                                void *attribute_value, int value_len)
 {
@@ -387,47 +490,32 @@ ble_att_clt_tx_find_type_value(struct ble_hs_conn *conn,
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->bavq_start_handle == 0 ||
         req->bavq_start_handle > req->bavq_end_handle) {
 
-        rc = BLE_HS_EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_init_req(conn, &chan, &txom,
-                              BLE_ATT_FIND_TYPE_VALUE_REQ_BASE_SZ);
-    if (rc != 0) {
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_find_type_value_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = os_mbuf_append(txom, attribute_value, value_len);
+    rc = ble_att_clt_build_find_type_value_req(req, attribute_value, value_len,
+                                               &txom);
     if (rc != 0) {
-        rc = BLE_HS_EMSGSIZE;
-        goto err;
+        return rc;
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
+/**
+ * Lock restrictions: none.
+ */
 static int
 ble_att_clt_parse_find_type_value_hinfo(
     struct os_mbuf **om, struct ble_att_find_type_value_hinfo *hinfo)
@@ -447,7 +535,8 @@ ble_att_clt_parse_find_type_value_hinfo(
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -488,10 +577,47 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, 
struct os_mbuf **rxom)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
+ */
+static int
+ble_att_clt_build_read_type_req(struct ble_att_read_type_req *req,
+                                void *uuid128, struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_READ_TYPE_REQ_BASE_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_read_type_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+    rc = ble_uuid_append(txom, uuid128);
+    if (rc != 0) {
+        rc = BLE_HS_ENOMEM;
+        goto done;
+    }
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_read_type(struct ble_hs_conn *conn,
+ble_att_clt_tx_read_type(uint16_t conn_handle,
                          struct ble_att_read_type_req *req,
                          void *uuid128)
 {
@@ -499,44 +625,26 @@ ble_att_clt_tx_read_type(struct ble_hs_conn *conn,
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->batq_start_handle == 0 ||
         req->batq_start_handle > req->batq_end_handle) {
 
-        rc = BLE_HS_EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_init_req(conn, &chan, &txom,
-                              BLE_ATT_READ_TYPE_REQ_BASE_SZ);
-    if (rc != 0) {
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_read_type_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_uuid_append(txom, uuid128);
+    rc = ble_att_clt_build_read_type_req(req, uuid128, &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
@@ -561,7 +669,8 @@ ble_att_clt_parse_read_type_adata(struct os_mbuf **om, int 
data_len,
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -608,49 +717,69 @@ done:
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
+ */
+static int
+ble_att_clt_build_read_req(struct ble_att_read_req *req,
+                           struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_READ_REQ_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_read_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_read(struct ble_hs_conn *conn, struct ble_att_read_req *req)
+ble_att_clt_tx_read(uint16_t conn_handle, struct ble_att_read_req *req)
 {
 #if !NIMBLE_OPT_ATT_CLT_READ
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->barq_handle == 0) {
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_READ_REQ_SZ);
+    rc = ble_att_clt_build_read_req(req, &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_att_read_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -681,50 +810,70 @@ ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf 
**rxom)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
  */
-int
-ble_att_clt_tx_read_blob(struct ble_hs_conn *conn,
+static int
+ble_att_clt_build_read_blob_req(struct ble_att_read_blob_req *req,
+                                struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_READ_BLOB_REQ_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_read_blob_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+int
+ble_att_clt_tx_read_blob(uint16_t conn_handle,
                          struct ble_att_read_blob_req *req)
 {
 #if !NIMBLE_OPT_ATT_CLT_READ_BLOB
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->babq_handle == 0) {
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_READ_BLOB_REQ_SZ);
+    rc = ble_att_clt_build_read_blob_req(req, &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_att_read_blob_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -755,17 +904,12 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, struct 
os_mbuf **rxom)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
  */
-int
-ble_att_clt_tx_read_mult(struct ble_hs_conn *conn,
-                         uint16_t *handles, int num_handles)
+static int
+ble_att_clt_build_read_mult_req(uint16_t *att_handles, int num_att_handles,
+                                struct os_mbuf **out_txom)
 {
-#if !NIMBLE_OPT_ATT_CLT_READ_MULT
-    return BLE_HS_ENOTSUP;
-#endif
-
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     void *buf;
     int rc;
@@ -773,45 +917,71 @@ ble_att_clt_tx_read_mult(struct ble_hs_conn *conn,
 
     txom = NULL;
 
-    if (num_handles < 1) {
-        rc = BLE_HS_EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_init_req(conn, &chan, &txom,
-                              BLE_ATT_READ_MULT_REQ_BASE_SZ);
+    rc = ble_att_clt_init_req(BLE_ATT_READ_MULT_REQ_BASE_SZ, &txom);
     if (rc != 0) {
-        goto err;
+        goto done;
     }
 
     rc = ble_att_read_mult_req_write(txom->om_data, txom->om_len);
     assert(rc == 0);
 
-    for (i = 0; i < num_handles; i++) {
+    for (i = 0; i < num_att_handles; i++) {
         buf = os_mbuf_extend(txom, 2);
         if (buf == NULL) {
             rc = BLE_HS_ENOMEM;
-            goto err;
+            goto done;
         }
 
-        htole16(buf, handles[i]);
+        htole16(buf, att_handles[i]);
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = 0;
+
+done:
     if (rc != 0) {
-        goto err;
+        os_mbuf_free_chain(txom);
+        txom = NULL;
     }
 
-    return 0;
-
-err:
-    os_mbuf_free_chain(txom);
+    *out_txom = txom;
     return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+int
+ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t *att_handles,
+                         int num_att_handles)
+{
+#if !NIMBLE_OPT_ATT_CLT_READ_MULT
+    return BLE_HS_ENOTSUP;
+#endif
+
+    struct os_mbuf *txom;
+    int rc;
+
+    if (num_att_handles < 1) {
+        return BLE_HS_EINVAL;
+    }
+
+    rc = ble_att_clt_build_read_mult_req(att_handles, num_att_handles, &txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -842,10 +1012,46 @@ ble_att_clt_rx_read_mult(uint16_t conn_handle, struct 
os_mbuf **rxom)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
+ */
+static int
+ble_att_clt_build_read_group_type_req(struct ble_att_read_group_type_req *req,
+                                      void *uuid128, struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_read_group_type_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+    rc = ble_uuid_append(txom, uuid128);
+    if (rc != 0) {
+        goto done;
+    }
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
+ble_att_clt_tx_read_group_type(uint16_t conn_handle,
                                struct ble_att_read_group_type_req *req,
                                void *uuid128)
 {
@@ -853,7 +1059,6 @@ ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
@@ -862,35 +1067,20 @@ ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
     if (req->bagq_start_handle == 0 ||
         req->bagq_start_handle > req->bagq_end_handle) {
 
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom,
-                              BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ);
+    rc = ble_att_clt_build_read_group_type_req(req, uuid128, &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_att_read_group_type_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_uuid_append(txom, uuid128);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
-    if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
@@ -921,7 +1111,8 @@ ble_att_clt_parse_read_group_type_adata(
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -970,23 +1161,23 @@ done:
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 static int
-ble_att_clt_tx_write_req_or_cmd(struct ble_hs_conn *conn,
-                                struct ble_att_write_req *req,
-                                void *value, uint16_t value_len,
-                                int is_req)
+ble_att_clt_build_write_req_or_cmd(uint16_t conn_handle,
+                                   struct ble_att_write_req *req,
+                                   void *value, uint16_t value_len, int is_req,
+                                   struct os_mbuf **out_txom)
 {
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
     txom = NULL;
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_WRITE_REQ_BASE_SZ);
+    rc = ble_att_clt_init_req(BLE_ATT_WRITE_REQ_BASE_SZ, &txom);
     if (rc != 0) {
-        goto err;
+        goto done;
     }
 
     if (is_req) {
@@ -996,30 +1187,54 @@ ble_att_clt_tx_write_req_or_cmd(struct ble_hs_conn *conn,
     }
     assert(rc == 0);
 
-    rc = ble_att_clt_append_blob(chan, txom, value, value_len);
+    rc = ble_att_clt_append_blob(conn_handle, txom, value, value_len);
     if (rc != 0) {
-        goto err;
+        goto done;
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+done:
     if (rc != 0) {
-        goto err;
+        os_mbuf_free_chain(txom);
+        txom = NULL;
     }
 
-    return 0;
-
-err:
-    os_mbuf_free_chain(txom);
+    *out_txom = txom;
     return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+static int
+ble_att_clt_tx_write_req_or_cmd(uint16_t conn_handle,
+                                struct ble_att_write_req *req,
+                                void *value, uint16_t value_len,
+                                int is_req)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    rc = ble_att_clt_build_write_req_or_cmd(conn_handle, req, value, value_len,
+                                            is_req, &txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_write_req(struct ble_hs_conn *conn,
-                         struct ble_att_write_req *req,
+ble_att_clt_tx_write_req(uint16_t conn_handle, struct ble_att_write_req *req,
                          void *value, uint16_t value_len)
 {
 #if !NIMBLE_OPT_ATT_CLT_WRITE
@@ -1028,19 +1243,17 @@ ble_att_clt_tx_write_req(struct ble_hs_conn *conn,
 
     int rc;
 
-    rc = ble_att_clt_tx_write_req_or_cmd(conn, req, value, value_len, 1);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
+    rc = ble_att_clt_tx_write_req_or_cmd(conn_handle, req, value, value_len,
+                                         1);
+    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_write_cmd(struct ble_hs_conn *conn,
+ble_att_clt_tx_write_cmd(uint16_t conn_handle,
                          struct ble_att_write_req *req,
                          void *value, uint16_t value_len)
 {
@@ -1050,16 +1263,14 @@ ble_att_clt_tx_write_cmd(struct ble_hs_conn *conn,
 
     int rc;
 
-    rc = ble_att_clt_tx_write_req_or_cmd(conn, req, value, value_len, 0);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
+    rc = ble_att_clt_tx_write_req_or_cmd(conn_handle, req, value, value_len,
+                                         0);
+    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -1078,10 +1289,49 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct 
os_mbuf **rxom)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+static int
+ble_att_clt_build_prep_write_req(uint16_t conn_handle,
+                                 struct ble_att_prep_write_cmd *req,
+                                 void *value, uint16_t value_len,
+                                 struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_PREP_WRITE_CMD_BASE_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_prep_write_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+    rc = ble_att_clt_append_blob(conn_handle, txom, value, value_len);
+    if (rc != 0) {
+        goto done;
+    }
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_prep_write(struct ble_hs_conn *conn,
+ble_att_clt_tx_prep_write(uint16_t conn_handle,
                           struct ble_att_prep_write_cmd *req,
                           void *value, uint16_t value_len)
 {
@@ -1089,58 +1339,40 @@ ble_att_clt_tx_prep_write(struct ble_hs_conn *conn,
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->bapc_handle == 0) {
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
     if (req->bapc_offset + value_len > BLE_ATT_ATTR_MAX_LEN) {
-        rc = BLE_HS_EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_init_req(conn, &chan, &txom,
-                              BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
-    if (rc != 0) {
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
     if (value_len >
-        ble_l2cap_chan_mtu(chan) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) {
+        ble_att_mtu(conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) {
 
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_prep_write_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_att_clt_append_blob(chan, txom, value, value_len);
+    rc = ble_att_clt_build_prep_write_req(conn_handle, req, value, value_len,
+                                          &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -1184,50 +1416,70 @@ done:
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions: none.
+ */
+static int
+ble_att_clt_build_exec_write_req(struct ble_att_exec_write_req *req,
+                                 struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_EXEC_WRITE_REQ_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_exec_write_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_exec_write(struct ble_hs_conn *conn,
+ble_att_clt_tx_exec_write(uint16_t conn_handle,
                           struct ble_att_exec_write_req *req)
 {
 #if !NIMBLE_OPT_ATT_CLT_EXEC_WRITE
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if ((req->baeq_flags & BLE_ATT_EXEC_WRITE_F_RESERVED) != 0) {
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_EXEC_WRITE_REQ_SZ);
+    rc = ble_att_clt_build_exec_write_req(req, &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_att_exec_write_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
@@ -1253,62 +1505,124 @@ ble_att_clt_rx_exec_write(uint16_t conn_handle, struct 
os_mbuf **rxom)
  *****************************************************************************/
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+static int
+ble_att_clt_build_notify_req(uint16_t conn_handle,
+                             struct ble_att_notify_req *req,
+                             void *value, uint16_t value_len,
+                             struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_NOTIFY_REQ_BASE_SZ, &txom);
+    if (rc != 0) {
+        goto done;
+    }
+
+    rc = ble_att_notify_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
+
+    rc = ble_att_clt_append_blob(conn_handle, txom, value, value_len);
+    if (rc != 0) {
+        goto done;
+    }
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
+    return rc;
+}
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_notify(struct ble_hs_conn *conn, struct ble_att_notify_req *req,
+ble_att_clt_tx_notify(uint16_t conn_handle, struct ble_att_notify_req *req,
                       void *value, uint16_t value_len)
 {
 #if !NIMBLE_OPT_ATT_CLT_NOTIFY
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->banq_handle == 0) {
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom, BLE_ATT_NOTIFY_REQ_BASE_SZ);
+    rc = ble_att_clt_build_notify_req(conn_handle, req, value, value_len,
+                                      &txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_att_notify_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_att_clt_append_blob(chan, txom, value, value_len);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
+    return 0;
+}
+
+/*****************************************************************************
+ * $handle value indication                                                  *
+ *****************************************************************************/
+
+/**
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
+ */
+static int
+ble_att_clt_build_indicate_req(uint16_t conn_handle,
+                               struct ble_att_indicate_req *req,
+                               void *value, uint16_t value_len,
+                               struct os_mbuf **out_txom)
+{
+    struct os_mbuf *txom;
+    int rc;
+
     txom = NULL;
+
+    rc = ble_att_clt_init_req(BLE_ATT_INDICATE_REQ_BASE_SZ, &txom);
     if (rc != 0) {
-        goto err;
+        goto done;
     }
 
-    return 0;
+    rc = ble_att_indicate_req_write(txom->om_data, txom->om_len, req);
+    assert(rc == 0);
 
-err:
-    os_mbuf_free_chain(txom);
+    rc = ble_att_clt_append_blob(conn_handle, txom, value, value_len);
+    if (rc != 0) {
+        goto done;
+    }
+
+done:
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        txom = NULL;
+    }
+
+    *out_txom = txom;
     return rc;
 }
 
-/*****************************************************************************
- * $handle value indication                                                  *
- *****************************************************************************/
-
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks ble_hs_conn.
  */
 int
-ble_att_clt_tx_indicate(struct ble_hs_conn *conn,
+ble_att_clt_tx_indicate(uint16_t conn_handle,
                         struct ble_att_indicate_req *req,
                         void *value, uint16_t value_len)
 {
@@ -1316,46 +1630,30 @@ ble_att_clt_tx_indicate(struct ble_hs_conn *conn,
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct ble_l2cap_chan *chan;
     struct os_mbuf *txom;
     int rc;
 
-    txom = NULL;
-
     if (req->baiq_handle == 0) {
-        rc = BLE_HS_EINVAL;
-        goto err;
+        return BLE_HS_EINVAL;
     }
 
-    rc = ble_att_clt_init_req(conn, &chan, &txom,
-                              BLE_ATT_INDICATE_REQ_BASE_SZ);
+    rc = ble_att_clt_build_indicate_req(conn_handle, req, value, value_len,
+                                        &txom);
     if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_att_indicate_req_write(txom->om_data, txom->om_len, req);
-    assert(rc == 0);
-
-    rc = ble_att_clt_append_blob(chan, txom, value, value_len);
-    if (rc != 0) {
-        goto err;
+        return rc;
     }
 
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
+ * Lock restrictions:
+ *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 4ebdea0..ad5937f 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -234,53 +234,51 @@ struct ble_att_read_group_type_adata {
 };
 
 int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_mtu(struct ble_hs_conn *conn,
-                       struct ble_att_mtu_cmd *req);
+int ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req);
 int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_read(struct ble_hs_conn *conn,
-                        struct ble_att_read_req *req);
+int ble_att_clt_tx_read(uint16_t conn_handle, struct ble_att_read_req *req);
 int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_read_blob(struct ble_hs_conn *conn,
+int ble_att_clt_tx_read_blob(uint16_t conn_handle,
                              struct ble_att_read_blob_req *req);
 int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_read_mult(struct ble_hs_conn *conn,
+int ble_att_clt_tx_read_mult(uint16_t conn_handle,
                              uint16_t *handles, int num_handles);
 int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_read_type(struct ble_hs_conn *conn,
+int ble_att_clt_tx_read_type(uint16_t conn_handle,
                              struct ble_att_read_type_req *req,
                              void *uuid128);
 int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
+int ble_att_clt_tx_read_group_type(uint16_t conn_handle,
                                    struct ble_att_read_group_type_req *req,
                                    void *uuid128);
 int ble_att_clt_rx_read_group_type(uint16_t conn_handle,
                                    struct os_mbuf **rxom);
-int ble_att_clt_tx_find_info(struct ble_hs_conn *conn,
+int ble_att_clt_tx_find_info(uint16_t conn_handle,
                              struct ble_att_find_info_req *req);
 int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om);
-int ble_att_clt_tx_find_type_value(struct ble_hs_conn *conn,
+int ble_att_clt_tx_find_type_value(uint16_t conn_handle,
                                    struct ble_att_find_type_value_req *req,
                                    void *attribute_value, int value_len);
 int ble_att_clt_rx_find_type_value(uint16_t conn_handle,
                                    struct os_mbuf **rxom);
-int ble_att_clt_tx_write_req(struct ble_hs_conn *conn,
+int ble_att_clt_tx_write_req(uint16_t conn_handle,
                              struct ble_att_write_req *req,
                              void *value, uint16_t value_len);
-int ble_att_clt_tx_write_cmd(struct ble_hs_conn *conn,
+int ble_att_clt_tx_write_cmd(uint16_t conn_handle,
                              struct ble_att_write_req *req,
                              void *value, uint16_t value_len);
-int ble_att_clt_tx_prep_write(struct ble_hs_conn *conn,
+int ble_att_clt_tx_prep_write(uint16_t conn_handle,
                               struct ble_att_prep_write_cmd *req,
                               void *value, uint16_t value_len);
 int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_exec_write(struct ble_hs_conn *conn,
+int ble_att_clt_tx_exec_write(uint16_t conn_handle,
                               struct ble_att_exec_write_req *req);
 int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom);
 int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom);
-int ble_att_clt_tx_notify(struct ble_hs_conn *conn,
+int ble_att_clt_tx_notify(uint16_t conn_handle,
                           struct ble_att_notify_req *req,
                           void *value, uint16_t value_len);
-int ble_att_clt_tx_indicate(struct ble_hs_conn *conn,
+int ble_att_clt_tx_indicate(uint16_t conn_handle,
                             struct ble_att_indicate_req *req,
                             void *value, uint16_t value_len);
 int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 9aa109b..da568c8 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -576,8 +576,6 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct 
os_mbuf **out_txom,
                           uint8_t *att_err)
 {
     struct ble_att_mtu_cmd cmd;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
     struct os_mbuf *txom;
     uint16_t mtu;
     void *dst;
@@ -586,14 +584,8 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct 
os_mbuf **out_txom,
     *att_err = 0; /* Silence unnecessary warning. */
     txom = NULL;
 
-    ble_hs_conn_lock();
-    ble_att_conn_chan_find(conn_handle, &conn, &chan);
-    if (chan != NULL) {
-        mtu = chan->blc_my_mtu;
-    }
-    ble_hs_conn_unlock();
-
-    if (chan == NULL) {
+    mtu = ble_att_mtu(conn_handle);
+    if (mtu == 0) {
         rc = BLE_HS_ENOTCONN;
         goto done;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 f0ac313..03d3696 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -792,30 +792,28 @@ ble_gattc_mtu_kick(struct ble_gattc_proc *proc)
 
     ble_hs_conn_lock();
 
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-        assert(chan != NULL);
-
-        if (chan->blc_flags & BLE_L2CAP_CHAN_F_TXED_MTU) {
-            rc = BLE_HS_EALREADY;
-        } else {
-            req.bamc_mtu = chan->blc_my_mtu;
-            rc = ble_att_clt_tx_mtu(conn, &req);
-        }
+    rc = ble_att_conn_chan_find(proc->fsm_proc.conn_handle, &conn, &chan);
+    if (rc == 0) {
+        req.bamc_mtu = chan->blc_my_mtu;
     }
 
     ble_hs_conn_unlock();
 
-    if (rc == 0) {
-        return 0;
-    } else {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
-        }
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_att_clt_tx_mtu(proc->fsm_proc.conn_handle, &req);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return 0;
 
+err:
+    if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
+        return BLE_HS_EAGAIN;
+    } else {
         ble_gattc_mtu_cb(proc, rc, 0, 0);
         return BLE_HS_EDONE;
     }
@@ -926,36 +924,27 @@ static int
 ble_gattc_disc_all_svcs_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_read_group_type_req req;
-    struct ble_hs_conn *conn;
     uint8_t uuid128[16];
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        rc = ble_uuid_16_to_128(BLE_ATT_UUID_PRIMARY_SERVICE, uuid128);
-        assert(rc == 0);
+    rc = ble_uuid_16_to_128(BLE_ATT_UUID_PRIMARY_SERVICE, uuid128);
+    assert(rc == 0);
 
-        req.bagq_start_handle = proc->disc_all_svcs.prev_handle + 1;
-        req.bagq_end_handle = 0xffff;
-        rc = ble_att_clt_tx_read_group_type(conn, &req, uuid128);
-    }
+    req.bagq_start_handle = proc->disc_all_svcs.prev_handle + 1;
+    req.bagq_end_handle = 0xffff;
+    rc = ble_att_clt_tx_read_group_type(proc->fsm_proc.conn_handle, &req,
+                                        uuid128);
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_disc_all_svcs_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_disc_all_svcs_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -1134,36 +1123,24 @@ static int
 ble_gattc_disc_svc_uuid_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_find_type_value_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        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;
-
-        rc = ble_att_clt_tx_find_type_value(conn, &req,
-                                            proc->disc_svc_uuid.service_uuid,
-                                            16);
-    }
+    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;
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    rc = ble_att_clt_tx_find_type_value(proc->fsm_proc.conn_handle, &req,
+                                        proc->disc_svc_uuid.service_uuid, 16);
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_disc_svc_uuid_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_disc_svc_uuid_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -1327,45 +1304,36 @@ ble_gattc_find_inc_svcs_kick(struct ble_gattc_proc 
*proc)
 {
     struct ble_att_read_type_req read_type_req;
     struct ble_att_read_req read_req;
-    struct ble_hs_conn *conn;
     uint8_t uuid128[16];
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        if (proc->find_inc_svcs.cur_start == 0) {
-            /* Find the next included service. */
-            read_type_req.batq_start_handle =
-                proc->find_inc_svcs.prev_handle + 1;
-            read_type_req.batq_end_handle = proc->find_inc_svcs.end_handle;
+    if (proc->find_inc_svcs.cur_start == 0) {
+        /* Find the next included service. */
+        read_type_req.batq_start_handle =
+            proc->find_inc_svcs.prev_handle + 1;
+        read_type_req.batq_end_handle = proc->find_inc_svcs.end_handle;
 
-            rc = ble_uuid_16_to_128(BLE_ATT_UUID_INCLUDE, uuid128);
-            assert(rc == 0);
+        rc = ble_uuid_16_to_128(BLE_ATT_UUID_INCLUDE, uuid128);
+        assert(rc == 0);
 
-            rc = ble_att_clt_tx_read_type(conn, &read_type_req, uuid128);
-        } else {
-            /* Read the UUID of the previously found service. */
-            read_req.barq_handle = proc->find_inc_svcs.cur_start;
-            rc = ble_att_clt_tx_read(conn, &read_req);
-        }
+        rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle,
+                                      &read_type_req, uuid128);
+    } else {
+        /* Read the UUID of the previously found service. */
+        read_req.barq_handle = proc->find_inc_svcs.cur_start;
+        rc = ble_att_clt_tx_read(proc->fsm_proc.conn_handle, &read_req);
     }
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
             return BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_find_inc_svcs_cb(proc, rc, 0, NULL);
+            return BLE_HS_EDONE;
         }
-
-        ble_gattc_find_inc_svcs_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -1618,37 +1586,27 @@ static int
 ble_gattc_disc_all_chrs_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_read_type_req req;
-    struct ble_hs_conn *conn;
     uint8_t uuid128[16];
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
-        assert(rc == 0);
-
-        req.batq_start_handle = proc->disc_all_chrs.prev_handle + 1;
-        req.batq_end_handle = proc->disc_all_chrs.end_handle;
+    rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
+    assert(rc == 0);
 
-        rc = ble_att_clt_tx_read_type(conn, &req, uuid128);
-    }
+    req.batq_start_handle = proc->disc_all_chrs.prev_handle + 1;
+    req.batq_end_handle = proc->disc_all_chrs.end_handle;
 
-    ble_hs_conn_unlock();
+    rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle, &req, uuid128);
 
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_disc_all_chrs_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_disc_all_chrs_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -1839,37 +1797,27 @@ static int
 ble_gattc_disc_chr_uuid_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_read_type_req req;
-    struct ble_hs_conn *conn;
     uint8_t uuid128[16];
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
-        assert(rc == 0);
+    rc = ble_uuid_16_to_128(BLE_ATT_UUID_CHARACTERISTIC, uuid128);
+    assert(rc == 0);
 
-        req.batq_start_handle = proc->disc_chr_uuid.prev_handle + 1;
-        req.batq_end_handle = proc->disc_chr_uuid.end_handle;
+    req.batq_start_handle = proc->disc_chr_uuid.prev_handle + 1;
+    req.batq_end_handle = proc->disc_chr_uuid.end_handle;
 
-        rc = ble_att_clt_tx_read_type(conn, &req, uuid128);
-    }
+    rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle, &req, uuid128);
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_disc_chr_uuid_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_disc_chr_uuid_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -2068,34 +2016,22 @@ static int
 ble_gattc_disc_all_dscs_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_find_info_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
+    req.bafq_start_handle = proc->disc_all_dscs.prev_handle + 1;
+    req.bafq_end_handle = proc->disc_all_dscs.end_handle;
 
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-
-        req.bafq_start_handle = proc->disc_all_dscs.prev_handle + 1;
-        req.bafq_end_handle = proc->disc_all_dscs.end_handle;
-
-        rc = ble_att_clt_tx_find_info(conn, &req);
-    }
-
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    rc = ble_att_clt_tx_find_info(proc->fsm_proc.conn_handle, &req);
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_disc_all_dscs_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_disc_all_dscs_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -2263,31 +2199,20 @@ static int
 ble_gattc_read_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_read_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        req.barq_handle = proc->read.handle;
-        rc = ble_att_clt_tx_read(conn, &req);
-    }
-
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    req.barq_handle = proc->read.handle;
+    rc = ble_att_clt_tx_read(proc->fsm_proc.conn_handle, &req);
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_read_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_read_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -2410,32 +2335,23 @@ static int
 ble_gattc_read_uuid_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_read_type_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        req.batq_start_handle = proc->read_uuid.prev_handle + 1;
-        req.batq_end_handle = proc->read_uuid.end_handle;
-        rc = ble_att_clt_tx_read_type(conn, &req, proc->read_uuid.uuid128);
-    }
+    req.batq_start_handle = proc->read_uuid.prev_handle + 1;
+    req.batq_end_handle = proc->read_uuid.end_handle;
+    rc = ble_att_clt_tx_read_type(proc->fsm_proc.conn_handle, &req,
+                                  proc->read_uuid.uuid128);
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_read_uuid_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_read_uuid_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -2596,37 +2512,27 @@ ble_gattc_read_long_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_read_blob_req blob_req;
     struct ble_att_read_req read_req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
+    if (proc->read_long.offset == 0) {
+        read_req.barq_handle = proc->read_long.handle;
+        rc = ble_att_clt_tx_read(proc->fsm_proc.conn_handle, &read_req);
     } else {
-        if (proc->read_long.offset == 0) {
-            read_req.barq_handle = proc->read_long.handle;
-            rc = ble_att_clt_tx_read(conn, &read_req);
-        } else {
-            blob_req.babq_handle = proc->read_long.handle;
-            blob_req.babq_offset = proc->read_long.offset;
-            rc = ble_att_clt_tx_read_blob(conn, &blob_req);
-        }
+        blob_req.babq_handle = proc->read_long.handle;
+        blob_req.babq_offset = proc->read_long.offset;
+        rc = ble_att_clt_tx_read_blob(proc->fsm_proc.conn_handle, &blob_req);
     }
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_read_long_cb(proc, rc, 0, NULL);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_read_long_cb(proc, rc, 0, NULL);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -2783,31 +2689,22 @@ ble_gattc_read_mult_cb(struct ble_gattc_proc *proc, int 
status,
 static int
 ble_gattc_read_mult_kick(struct ble_gattc_proc *proc)
 {
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        rc = ble_att_clt_tx_read_mult(conn, proc->read_mult.handles,
-                                      proc->read_mult.num_handles);
-    }
+    rc = ble_att_clt_tx_read_mult(proc->fsm_proc.conn_handle,
+                                  proc->read_mult.handles,
+                                  proc->read_mult.num_handles);
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_read_mult_cb(proc, rc, 0, NULL, 0);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_read_mult_cb(proc, rc, 0, NULL, 0);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -2927,36 +2824,24 @@ static int
 ble_gattc_write_no_rsp_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_write_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
+    req.bawq_handle = proc->write.attr.handle;
+    rc = ble_att_clt_tx_write_cmd(proc->fsm_proc.conn_handle, &req,
+                                  proc->write.attr.value,
+                                  proc->write.attr.value_len);
 
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
+    if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
+        rc = BLE_HS_EAGAIN;
     } else {
-        req.bawq_handle = proc->write.attr.handle;
-        rc = ble_att_clt_tx_write_cmd(conn, &req, proc->write.attr.value,
-                                      proc->write.attr.value_len);
-    }
-
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
         /* No response expected; call callback immediately and return 'done' to
          * indicate the proc should be freed.
          */
-        ble_gattc_write_cb(proc, 0, 0);
-        return BLE_HS_EDONE;
-    } else {
-        if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
-        }
-
         ble_gattc_write_cb(proc, rc, 0);
-        return BLE_HS_EDONE;
+        rc = BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -3018,32 +2903,23 @@ static int
 ble_gattc_write_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_write_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        req.bawq_handle = proc->write.attr.handle;
-        rc = ble_att_clt_tx_write_req(conn, &req, proc->write.attr.value,
-                                      proc->write.attr.value_len);
-    }
+    req.bawq_handle = proc->write.attr.handle;
+    rc = ble_att_clt_tx_write_req(proc->fsm_proc.conn_handle, &req,
+                                  proc->write.attr.value,
+                                  proc->write.attr.value_len);
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_write_cb(proc, rc, 0);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_write_cb(proc, rc, 0);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -3166,22 +3042,17 @@ ble_gattc_write_long_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_prep_write_cmd prep_req;
     struct ble_att_exec_write_req exec_req;
-    struct ble_l2cap_chan *chan;
-    struct ble_hs_conn *conn;
+    void *value;
     int max_sz;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
-        if (proc->write_long.attr.offset < proc->write_long.attr.value_len) {
-            chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
-            assert(chan != NULL);
-
-            max_sz = ble_l2cap_chan_mtu(chan) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ;
+    if (proc->write_long.attr.offset < proc->write_long.attr.value_len) {
+        max_sz = ble_att_mtu(proc->fsm_proc.conn_handle) -
+                 BLE_ATT_PREP_WRITE_CMD_BASE_SZ;
+        if (max_sz == 0) {
+            /* Not connected. */
+            rc = BLE_HS_ENOTCONN;
+        } else {
             if (proc->write_long.attr.offset + max_sz >
                 proc->write_long.attr.value_len) {
 
@@ -3193,28 +3064,26 @@ ble_gattc_write_long_kick(struct ble_gattc_proc *proc)
 
             prep_req.bapc_handle = proc->write_long.attr.handle;
             prep_req.bapc_offset = proc->write_long.attr.offset;
-            rc = ble_att_clt_tx_prep_write(conn, &prep_req,
-                                           proc->write_long.attr.value +
-                                               proc->write_long.attr.offset,
+            value = proc->write_long.attr.value + proc->write_long.attr.offset;
+            rc = ble_att_clt_tx_prep_write(proc->fsm_proc.conn_handle,
+                                           &prep_req, value,
                                            proc->write_long.length);
-        } else {
-            exec_req.baeq_flags = BLE_ATT_EXEC_WRITE_F_CONFIRM;
-            rc = ble_att_clt_tx_exec_write(conn, &exec_req);
         }
+    } else {
+        exec_req.baeq_flags = BLE_ATT_EXEC_WRITE_F_CONFIRM;
+        rc = ble_att_clt_tx_exec_write(proc->fsm_proc.conn_handle, &exec_req);
     }
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_write_long_cb(proc, rc, 0);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_write_long_cb(proc, rc, 0);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -3391,41 +3260,31 @@ ble_gattc_write_reliable_kick(struct ble_gattc_proc 
*proc)
     struct ble_att_prep_write_cmd prep_req;
     struct ble_att_exec_write_req exec_req;
     struct ble_gatt_attr *attr;
-    struct ble_hs_conn *conn;
     int attr_idx;
     int rc;
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
+    attr_idx = proc->write_reliable.cur_attr;
+    if (attr_idx < proc->write_reliable.num_attrs) {
+        attr = proc->write_reliable.attrs + attr_idx;
+        prep_req.bapc_handle = attr->handle;
+        prep_req.bapc_offset = 0;
+        rc = ble_att_clt_tx_prep_write(proc->fsm_proc.conn_handle, &prep_req,
+                                       attr->value, attr->value_len);
     } else {
-        attr_idx = proc->write_reliable.cur_attr;
-        if (attr_idx < proc->write_reliable.num_attrs) {
-            attr = proc->write_reliable.attrs + attr_idx;
-            prep_req.bapc_handle = attr->handle;
-            prep_req.bapc_offset = 0;
-            rc = ble_att_clt_tx_prep_write(conn, &prep_req, attr->value,
-                                           attr->value_len);
-        } else {
-            exec_req.baeq_flags = BLE_ATT_EXEC_WRITE_F_CONFIRM;
-            rc = ble_att_clt_tx_exec_write(conn, &exec_req);
-        }
+        exec_req.baeq_flags = BLE_ATT_EXEC_WRITE_F_CONFIRM;
+        rc = ble_att_clt_tx_exec_write(proc->fsm_proc.conn_handle, &exec_req);
     }
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_write_reliable_cb(proc, rc, 0);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_write_reliable_cb(proc, rc, 0);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -3572,7 +3431,6 @@ ble_gattc_notify_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_svr_access_ctxt ctxt;
     struct ble_att_notify_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
     if (proc->notify.attr.value == NULL) {
@@ -3581,35 +3439,32 @@ ble_gattc_notify_kick(struct ble_gattc_proc *proc)
                                      NULL);
         if (rc != 0) {
             /* Fatal error; application disallowed attribute read. */
-            return BLE_HS_EDONE;
+            rc = BLE_HS_EAPP;
         }
     } else {
+        rc = 0;
         ctxt.attr_data = proc->notify.attr.value;
         ctxt.data_len = proc->notify.attr.value_len;
         ctxt.offset = 0;
     }
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
+    if (rc == 0) {
         proc->notify.attr.value = ctxt.attr_data;
         proc->notify.attr.value_len = ctxt.data_len;
 
         req.banq_handle = proc->notify.attr.handle;
-        rc = ble_att_clt_tx_notify(conn, &req, proc->notify.attr.value,
+        rc = ble_att_clt_tx_notify(proc->fsm_proc.conn_handle, &req,
+                                   proc->notify.attr.value,
                                    proc->notify.attr.value_len);
     }
 
-    ble_hs_conn_unlock();
-
     if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-        return BLE_HS_EAGAIN;
+        rc = BLE_HS_EAGAIN;
     } else {
-        return BLE_HS_EDONE;
+        rc = BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**
@@ -3712,7 +3567,6 @@ ble_gattc_indicate_kick(struct ble_gattc_proc *proc)
 {
     struct ble_att_svr_access_ctxt ctxt;
     struct ble_att_indicate_req req;
-    struct ble_hs_conn *conn;
     int rc;
 
     if (proc->indicate.attr.value == NULL) {
@@ -3721,40 +3575,35 @@ ble_gattc_indicate_kick(struct ble_gattc_proc *proc)
                                      NULL);
         if (rc != 0) {
             /* Fatal error; application disallowed attribute read. */
-            return BLE_HS_EDONE;
+            rc = BLE_HS_EAPP;
         }
     } else {
+        rc = 0;
         ctxt.attr_data = proc->indicate.attr.value;
         ctxt.data_len = proc->indicate.attr.value_len;
         ctxt.offset = 0;
     }
 
-    ble_hs_conn_lock();
-
-    conn = ble_hs_conn_find(proc->fsm_proc.conn_handle);
-    if (conn == NULL) {
-        rc = BLE_HS_ENOTCONN;
-    } else {
+    if (rc == 0) {
         proc->indicate.attr.value = ctxt.attr_data;
         proc->indicate.attr.value_len = ctxt.data_len;
 
         req.baiq_handle = proc->indicate.attr.handle;
-        rc = ble_att_clt_tx_indicate(conn, &req, proc->indicate.attr.value,
+        rc = ble_att_clt_tx_indicate(proc->fsm_proc.conn_handle, &req,
+                                     proc->indicate.attr.value,
                                      proc->indicate.attr.value_len);
     }
 
-    ble_hs_conn_unlock();
-
-    if (rc == 0) {
-        return 0;
-    } else {
+    if (rc != 0) {
         if (ble_fsm_tx_postpone_chk(&proc->fsm_proc, rc)) {
-            return BLE_HS_EAGAIN;
+            rc = BLE_HS_EAGAIN;
+        } else {
+            ble_gattc_indicate_cb(proc, rc, 0);
+            rc = BLE_HS_EDONE;
         }
-
-        ble_gattc_indicate_cb(proc, rc, 0);
-        return BLE_HS_EDONE;
     }
+
+    return rc;
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_misc.c 
b/net/nimble/host/src/ble_hs_misc.c
index 1ae8f79..c988bb9 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -117,3 +117,57 @@ ble_hs_misc_pullup_base(struct os_mbuf **om, int base_len)
 
     return 0;
 }
+
+int
+ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid,
+                           struct ble_hs_conn **out_conn,
+                           struct ble_l2cap_chan **out_chan)
+{
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    conn = ble_hs_conn_find(conn_handle);
+    if (conn == NULL) {
+        chan = NULL;
+        rc = BLE_HS_ENOTCONN;
+    } else {
+        chan = ble_hs_conn_chan_find(conn, cid);
+        if (chan == NULL) {
+            rc = BLE_HS_ENOTCONN;
+        } else {
+            rc = 0;
+        }
+    }
+
+    if (out_conn != NULL) {
+        *out_conn = conn;
+    }
+    if (out_chan != NULL) {
+        *out_chan = chan;
+    }
+
+    return rc;
+}
+
+int
+ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
+                                struct ble_hs_conn **out_conn,
+                                struct ble_l2cap_chan **out_chan)
+{
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    int rc;
+
+    rc = ble_hs_misc_conn_chan_find(conn_handle, cid, &conn, &chan);
+    assert(conn == NULL || chan != NULL);
+
+    if (out_conn != NULL) {
+        *out_conn = conn;
+    }
+    if (out_chan != NULL) {
+        *out_chan = chan;
+    }
+
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 d06b59b..990b127 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -27,6 +27,8 @@
 #include "host/ble_hs.h"
 struct os_mbuf;
 struct os_mempool;
+struct ble_hs_conn;
+struct ble_l2cap_chan;
 
 #define BLE_HOST_HCI_EVENT_CTLR_EVENT   (OS_EVENT_T_PERUSER + 0)
 #define BLE_HS_KICK_HCI_EVENT           (OS_EVENT_T_PERUSER + 1)
@@ -51,6 +53,12 @@ int ble_hs_misc_malloc_mempool(void **mem, struct os_mempool 
*pool,
                                int num_entries, int entry_size, char *name);
 void ble_hs_misc_log_mbuf(struct os_mbuf *om);
 void ble_hs_misc_log_flat_buf(void *data, int len);
+int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid,
+                               struct ble_hs_conn **out_conn,
+                               struct ble_l2cap_chan **out_chan);
+int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
+                                    struct ble_hs_conn **out_conn,
+                                    struct ble_l2cap_chan **out_chan);
 
 void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 039cd9f..91a50e0 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -157,28 +157,18 @@ ble_l2cap_sig_proc_kick(struct ble_fsm_proc *proc)
 
 /**
  * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
+ *     o Caller locks ble_hs_conn.
  */
 static int
 ble_l2cap_sig_conn_chan_find(uint16_t conn_handle,
                              struct ble_hs_conn **out_conn,
                              struct ble_l2cap_chan **out_chan)
 {
-    ble_hs_conn_lock();
-
-    *out_conn = ble_hs_conn_find(conn_handle);
-    if (*out_conn != NULL) {
-        *out_chan = ble_hs_conn_chan_find(*out_conn, BLE_L2CAP_CID_SIG);
-        assert(*out_chan != NULL);
-    }
-
-    ble_hs_conn_unlock();
+    int rc;
 
-    if (*out_conn == NULL) {
-        return BLE_HS_ENOTCONN;
-    } else {
-        return 0;
-    }
+    rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
+                                         out_conn, out_chan);
+    return rc;
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5bdd4af0/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 a53f777..910b433 100644
--- a/net/nimble/host/src/test/ble_att_clt_test.c
+++ b/net/nimble/host/src/test/ble_att_clt_test.c
@@ -68,16 +68,16 @@ ble_att_clt_test_misc_verify_tx_write(uint16_t handle_id, 
void *value,
 }
 
 static void
-ble_att_clt_test_tx_write_req_or_cmd(struct ble_hs_conn *conn,
+ble_att_clt_test_tx_write_req_or_cmd(uint16_t conn_handle,
                                      struct ble_att_write_req *req,
                                      void *value, int value_len, int is_req)
 {
     int rc;
 
     if (is_req) {
-        rc = ble_att_clt_tx_write_req(conn, req, value, value_len);
+        rc = ble_att_clt_tx_write_req(conn_handle, req, value, value_len);
     } else {
-        rc = ble_att_clt_tx_write_cmd(conn, req, value, value_len);
+        rc = ble_att_clt_tx_write_cmd(conn_handle, req, value, value_len);
     }
     TEST_ASSERT(rc == 0);
 }
@@ -94,25 +94,25 @@ TEST_CASE(ble_att_clt_test_tx_find_info)
     /*** Success. */
     req.bafq_start_handle = 1;
     req.bafq_end_handle = 0xffff;
-    rc = ble_att_clt_tx_find_info(conn, &req);
+    rc = ble_att_clt_tx_find_info(conn->bhc_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, &req);
+    rc = ble_att_clt_tx_find_info(conn->bhc_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, &req);
+    rc = ble_att_clt_tx_find_info(conn->bhc_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, &req);
+    rc = ble_att_clt_tx_find_info(conn->bhc_handle, &req);
     TEST_ASSERT(rc == 0);
 }
 
@@ -195,16 +195,16 @@ ble_att_clt_test_case_tx_write_req_or_cmd(int is_req)
 
     /*** 5-byte write. */
     req.bawq_handle = 0x1234;
-    ble_att_clt_test_tx_write_req_or_cmd(conn, &req, value5, sizeof value5,
-                                         is_req);
+    ble_att_clt_test_tx_write_req_or_cmd(conn->bhc_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,
                                           is_req);
 
     /*** Overlong write; verify command truncated to ATT MTU. */
     req.bawq_handle = 0xab83;
-    ble_att_clt_test_tx_write_req_or_cmd(conn, &req, value300, sizeof value300,
-                                         is_req);
+    ble_att_clt_test_tx_write_req_or_cmd(conn->bhc_handle, &req, value300,
+                                         sizeof value300, is_req);
     ble_hs_test_util_tx_all();
     ble_att_clt_test_misc_verify_tx_write(0xab83, value300,
                                           BLE_ATT_MTU_DFLT - 3, is_req);
@@ -225,7 +225,8 @@ ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t 
offset,
 
     req.bapc_handle = handle;
     req.bapc_offset = offset;
-    rc = ble_att_clt_tx_prep_write(conn, &req, attr_data, attr_data_len);
+    rc = ble_att_clt_tx_prep_write(conn->bhc_handle, &req, attr_data,
+                                   attr_data_len);
     TEST_ASSERT(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -258,7 +259,7 @@ ble_att_clt_test_misc_exec_good(uint8_t flags)
     ble_att_clt_test_misc_init(&conn, &chan);
 
     req.baeq_flags = flags;
-    rc = ble_att_clt_tx_exec_write(conn, &req);
+    rc = ble_att_clt_tx_exec_write(conn->bhc_handle, &req);
     TEST_ASSERT(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -288,7 +289,8 @@ ble_att_clt_test_misc_prep_bad(uint16_t handle, uint16_t 
offset,
 
     req.bapc_handle = handle;
     req.bapc_offset = offset;
-    rc = ble_att_clt_tx_prep_write(conn, &req, attr_data, attr_data_len);
+    rc = ble_att_clt_tx_prep_write(conn->bhc_handle, &req, attr_data,
+                                   attr_data_len);
     TEST_ASSERT(rc == status);
 }
 
@@ -309,12 +311,12 @@ TEST_CASE(ble_att_clt_test_tx_read)
 
     /*** Success. */
     req.barq_handle = 1;
-    rc = ble_att_clt_tx_read(conn, &req);
+    rc = ble_att_clt_tx_read(conn->bhc_handle, &req);
     TEST_ASSERT(rc == 0);
 
     /*** Error: handle of 0. */
     req.barq_handle = 0;
-    rc = ble_att_clt_tx_read(conn, &req);
+    rc = ble_att_clt_tx_read(conn->bhc_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 
@@ -354,13 +356,13 @@ TEST_CASE(ble_att_clt_test_tx_read_blob)
     /*** Success. */
     req.babq_handle = 1;
     req.babq_offset = 0;
-    rc = ble_att_clt_tx_read_blob(conn, &req);
+    rc = ble_att_clt_tx_read_blob(conn->bhc_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, &req);
+    rc = ble_att_clt_tx_read_blob(conn->bhc_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 
@@ -398,7 +400,7 @@ TEST_CASE(ble_att_clt_test_tx_read_mult)
     ble_att_clt_test_misc_init(&conn, &chan);
 
     /*** Success. */
-    rc = ble_att_clt_tx_read_mult(conn, ((uint16_t[]){ 1, 2 }), 2);
+    rc = ble_att_clt_tx_read_mult(conn->bhc_handle, ((uint16_t[]){ 1, 2 }), 2);
     TEST_ASSERT(rc == 0);
 
     ble_hs_test_util_tx_all();
@@ -415,7 +417,7 @@ 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, NULL, 0);
+    rc = ble_att_clt_tx_read_mult(conn->bhc_handle, NULL, 0);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 
@@ -526,7 +528,7 @@ TEST_CASE(ble_att_clt_test_tx_exec_write)
     /*** Error: invalid flags value. */
     ble_att_clt_test_misc_init(&conn, &chan);
     req.baeq_flags = 0x02;
-    rc = ble_att_clt_tx_exec_write(conn, &req);
+    rc = ble_att_clt_tx_exec_write(conn->bhc_handle, &req);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 }
 

Reply via email to