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/04/21 01:32:25 UTC

[3/7] incubator-mynewt-core git commit: ble host - clarify locking restrictions.

ble host - clarify locking restrictions.


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

Branch: refs/heads/develop
Commit: 61458e37bf166ecb85c292485bd72e095cc46b4d
Parents: 3befe37
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 20 12:27:36 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 20 16:11:45 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_att.c           |  37 ++--
 net/nimble/host/src/ble_att_clt.c       | 180 +------------------
 net/nimble/host/src/ble_att_priv.h      |   3 +-
 net/nimble/host/src/ble_att_svr.c       | 156 ++---------------
 net/nimble/host/src/ble_gap.c           | 248 +++++----------------------
 net/nimble/host/src/ble_gattc.c         |  59 +++++--
 net/nimble/host/src/ble_gatts.c         | 105 ------------
 net/nimble/host/src/ble_hs.c            |  47 +++--
 net/nimble/host/src/ble_hs_adv.c        |   2 -
 net/nimble/host/src/ble_hs_atomic.c     |  21 +++
 net/nimble/host/src/ble_hs_atomic.h     |   5 +
 net/nimble/host/src/ble_hs_conn.c       |  68 +-------
 net/nimble/host/src/ble_hs_conn.h       |   1 -
 net/nimble/host/src/ble_hs_misc.c       |   8 -
 net/nimble/host/src/ble_hs_priv.h       |  12 +-
 net/nimble/host/src/ble_l2cap.c         |  41 -----
 net/nimble/host/src/ble_l2cap_sig.c     |  29 +++-
 net/nimble/host/src/ble_l2cap_sig_cmd.c |   4 -
 net/nimble/host/src/ble_l2cap_sm.c      |  43 +++--
 net/nimble/host/src/test/ble_os_test.c  |  48 ++++--
 20 files changed, 270 insertions(+), 847 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 74679f7..379ed48 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -22,7 +22,7 @@
 #include "bsp/bsp.h"
 #include "ble_hs_priv.h"
 
-bssnz_t uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
+static bssnz_t uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
 
 static uint16_t ble_att_preferred_mtu;
 
@@ -125,9 +125,6 @@ STATS_NAME_START(ble_att_stats)
     STATS_NAME(ble_att_stats, write_cmd_tx)
 STATS_NAME_END(ble_att_stats)
 
-/**
- * Lock restrictions: None.
- */
 static const struct ble_att_rx_dispatch_entry *
 ble_att_rx_dispatch_entry_find(uint8_t op)
 {
@@ -148,9 +145,6 @@ ble_att_rx_dispatch_entry_find(uint8_t op)
     return NULL;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 int
 ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                        struct ble_l2cap_chan **out_chan)
@@ -396,6 +390,17 @@ ble_att_inc_rx_stat(uint8_t att_op)
     }
 }
 
+/**
+ * Retrieves a pointer to the global ATT flat buffer.  This buffer is only used
+ * by the host parent task, so users can assume exclusive access.
+ */
+uint8_t *
+ble_att_get_flat_buf(void)
+{
+    BLE_HS_DBG_ASSERT(ble_hs_is_app_task());
+    return ble_att_flat_buf;
+}
+
 uint16_t
 ble_att_mtu(uint16_t conn_handle)
 {
@@ -417,9 +422,6 @@ ble_att_mtu(uint16_t conn_handle)
     return mtu;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static int
 ble_att_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -447,9 +449,6 @@ ble_att_rx(uint16_t conn_handle, struct os_mbuf **om)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 void
 ble_att_set_notify_cb(ble_att_svr_notify_fn *cb, void *cb_arg)
 {
@@ -457,9 +456,6 @@ ble_att_set_notify_cb(ble_att_svr_notify_fn *cb, void *cb_arg)
     ble_att_svr_notify_cb_arg = cb_arg;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
 {
@@ -470,9 +466,6 @@ ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu)
     chan->blc_peer_mtu = peer_mtu;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_set_preferred_mtu(uint16_t mtu)
 {
@@ -490,9 +483,6 @@ ble_att_set_preferred_mtu(uint16_t mtu)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_att_create_chan(void)
 {
@@ -511,9 +501,6 @@ ble_att_create_chan(void)
     return chan;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 19af956..1a95bdc 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -26,9 +26,6 @@
 #include "host/ble_uuid.h"
 #include "ble_hs_priv.h"
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_init_req(uint16_t initial_sz, struct os_mbuf **out_txom)
 {
@@ -58,10 +55,6 @@ err:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_append_blob(uint16_t conn_handle, struct os_mbuf *txom,
                         void *blob, int blob_len)
@@ -93,13 +86,11 @@ ble_att_clt_append_blob(uint16_t conn_handle, 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)
 {
+    uint8_t *flat_buf;
     uint16_t attr_len;
 
     /* Make sure the attribute value isn't too big. */
@@ -111,8 +102,9 @@ ble_att_clt_copy_attr_to_flatbuf(struct os_mbuf *om, void **out_attr_val,
     }
 
     /* Copy the attribute data into the global ATT flat buffer. */
-    os_mbuf_copydata(om, 0, attr_len, ble_att_flat_buf);
-    *out_attr_val = ble_att_flat_buf;
+    flat_buf = ble_att_get_flat_buf();
+    os_mbuf_copydata(om, 0, attr_len, flat_buf);
+    *out_attr_val = flat_buf;
     *out_attr_len = attr_len;
     return 0;
 }
@@ -145,10 +137,6 @@ ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
  * $error response                                                           *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -170,9 +158,6 @@ ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **om)
  * $mtu exchange                                                             *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_mtu_req(struct ble_att_mtu_cmd *req,
                           struct os_mbuf **out_txom)
@@ -199,10 +184,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req)
 {
@@ -237,10 +218,6 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, struct ble_att_mtu_cmd *req)
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -274,9 +251,6 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
  * $find information                                                         *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_find_info_req(struct ble_att_find_info_req *req,
                                 struct os_mbuf **out_txom)
@@ -295,10 +269,6 @@ ble_att_clt_build_find_info_req(struct ble_att_find_info_req *req,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_find_info(uint16_t conn_handle,
                          struct ble_att_find_info_req *req)
@@ -382,10 +352,6 @@ ble_att_clt_parse_find_info_entry(struct os_mbuf **rxom, uint8_t rsp_format,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -429,9 +395,6 @@ done:
  * $find by type value                                                       *
  *****************************************************************************/
 
-/**
- * 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,
@@ -456,10 +419,6 @@ ble_att_clt_build_find_type_value_req(struct ble_att_find_type_value_req *req,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_find_type_value(uint16_t conn_handle,
                                struct ble_att_find_type_value_req *req,
@@ -492,9 +451,6 @@ ble_att_clt_tx_find_type_value(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_parse_find_type_value_hinfo(
     struct os_mbuf **om, struct ble_att_find_type_value_hinfo *dst)
@@ -512,10 +468,6 @@ ble_att_clt_parse_find_type_value_hinfo(
     return 0;
 }
 
-/**
- * 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)
 {
@@ -554,9 +506,6 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read by type                                                             *
  *****************************************************************************/
 
-/**
- * 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)
@@ -589,10 +538,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read_type(uint16_t conn_handle,
                          struct ble_att_read_type_req *req,
@@ -624,9 +569,6 @@ ble_att_clt_tx_read_type(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_clt_parse_read_type_adata(struct os_mbuf **om, int data_len,
                                   struct ble_att_read_type_adata *adata)
@@ -645,10 +587,6 @@ ble_att_clt_parse_read_type_adata(struct os_mbuf **om, int data_len,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -692,9 +630,6 @@ done:
  * $read                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_req(struct ble_att_read_req *req,
                            struct os_mbuf **out_txom)
@@ -721,10 +656,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read(uint16_t conn_handle, struct ble_att_read_req *req)
 {
@@ -752,10 +683,6 @@ ble_att_clt_tx_read(uint16_t conn_handle, struct ble_att_read_req *req)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -784,9 +711,6 @@ ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read blob                                                                *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_blob_req(struct ble_att_read_blob_req *req,
                                 struct os_mbuf **out_txom)
@@ -813,10 +737,6 @@ done:
     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)
@@ -845,10 +765,6 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -877,9 +793,6 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read multiple                                                            *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_read_mult_req(uint16_t *att_handles, int num_att_handles,
                                 struct os_mbuf **out_txom)
@@ -920,10 +833,6 @@ done:
     return rc;
 }
 
-/**
- * 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)
@@ -952,10 +861,6 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t *att_handles,
     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)
 {
@@ -984,9 +889,6 @@ ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
  * $read by group type                                                       *
  *****************************************************************************/
 
-/**
- * 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)
@@ -1018,10 +920,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_read_group_type(uint16_t conn_handle,
                                struct ble_att_read_group_type_req *req,
@@ -1055,9 +953,6 @@ ble_att_clt_tx_read_group_type(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_clt_parse_read_group_type_adata(
     struct os_mbuf **om, int data_len,
@@ -1082,10 +977,6 @@ ble_att_clt_parse_read_group_type_adata(
     return 0;
 }
 
-/**
- * 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)
 {
@@ -1129,10 +1020,6 @@ done:
  * $write                                                                    *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_att_clt_build_write_req_or_cmd(uint16_t conn_handle,
                                    struct ble_att_write_req *req,
@@ -1170,10 +1057,6 @@ done:
     return rc;
 }
 
-/**
- * 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,
@@ -1197,10 +1080,6 @@ ble_att_clt_tx_write_req_or_cmd(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_write_req(uint16_t conn_handle, struct ble_att_write_req *req,
                          void *value, uint16_t value_len)
@@ -1216,10 +1095,6 @@ ble_att_clt_tx_write_req(uint16_t conn_handle, struct ble_att_write_req *req,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_write_cmd(uint16_t conn_handle,
                          struct ble_att_write_req *req,
@@ -1236,10 +1111,6 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1256,10 +1127,6 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
  * $prepare write request                                                    *
  *****************************************************************************/
 
-/**
- * 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,
@@ -1293,10 +1160,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_prep_write(uint16_t conn_handle,
                           struct ble_att_prep_write_cmd *req,
@@ -1337,10 +1200,6 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1381,9 +1240,6 @@ done:
  * $execute write request                                                    *
  *****************************************************************************/
 
-/**
- * Lock restrictions: none.
- */
 static int
 ble_att_clt_build_exec_write_req(struct ble_att_exec_write_req *req,
                                  struct os_mbuf **out_txom)
@@ -1410,10 +1266,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_exec_write(uint16_t conn_handle,
                           struct ble_att_exec_write_req *req)
@@ -1442,10 +1294,6 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1468,10 +1316,6 @@ ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
  * $handle value notification                                                *
  *****************************************************************************/
 
-/**
- * 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,
@@ -1505,10 +1349,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_notify(uint16_t conn_handle, struct ble_att_notify_req *req,
                       void *value, uint16_t value_len)
@@ -1542,10 +1382,6 @@ ble_att_clt_tx_notify(uint16_t conn_handle, struct ble_att_notify_req *req,
  * $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,
@@ -1579,10 +1415,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 int
 ble_att_clt_tx_indicate(uint16_t conn_handle,
                         struct ble_att_indicate_req *req,
@@ -1613,10 +1445,6 @@ ble_att_clt_tx_indicate(uint16_t conn_handle,
     return 0;
 }
 
-/**
- * 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-core/blob/61458e37/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 3a0bc6d..77b5935 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -141,12 +141,11 @@ SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry);
 
 /*** @gen */
 
-extern uint8_t ble_att_flat_buf[BLE_ATT_ATTR_MAX_LEN];
-
 struct ble_l2cap_chan *ble_att_create_chan(void);
 int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
                            struct ble_l2cap_chan **out_chan);
 void ble_att_inc_tx_stat(uint8_t att_op);
+uint8_t *ble_att_get_flat_buf(void);
 uint16_t ble_att_mtu(uint16_t conn_handle);
 void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
 int ble_att_init(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 8f647e2..c64d6f9 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -37,9 +37,6 @@ static struct os_mempool ble_att_svr_prep_entry_pool;
 ble_att_svr_notify_fn *ble_att_svr_notify_cb;
 void *ble_att_svr_notify_cb_arg;
 
-/**
- * Lock restrictions: None.
- */
 static struct ble_att_svr_entry *
 ble_att_svr_entry_alloc(void)
 {
@@ -56,8 +53,6 @@ ble_att_svr_entry_alloc(void)
 /**
  * Allocate the next handle id and return it.
  *
- * Lock restrictions: None.
- *
  * @return A new 16-bit handle ID.
  */
 static uint16_t
@@ -71,8 +66,6 @@ ble_att_svr_next_id(void)
 /**
  * Register a host attribute with the BLE stack.
  *
- * Lock restrictions: None.
- *
  * @param ha                    A filled out ble_att structure to register
  * @param handle_id             A pointer to a 16-bit handle ID, which will be
  *                                  the handle that is allocated.
@@ -107,9 +100,6 @@ ble_att_svr_register(uint8_t *uuid, uint8_t flags, uint16_t *handle_id,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_svr_register_uuid16(uint16_t uuid16, uint8_t flags,
                             uint16_t *handle_id, ble_att_svr_access_fn *cb,
@@ -131,9 +121,6 @@ ble_att_svr_register_uuid16(uint16_t uuid16, uint8_t flags,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 uint16_t
 ble_att_svr_prev_handle(void)
 {
@@ -143,8 +130,6 @@ ble_att_svr_prev_handle(void)
 /**
  * Find a host attribute by handle id.
  *
- * Lock restrictions: None.
- *
  * @param handle_id             The handle_id to search for
  * @param ha_ptr                On input: Indicates the starting point of the
  *                                  walk; null means start at the beginning of
@@ -176,8 +161,6 @@ ble_att_svr_find_by_handle(uint16_t handle_id)
 /**
  * Find a host attribute by UUID.
  *
- * Lock restrictions: None.
- *
  * @param uuid                  The ble_uuid_t to search for
  * @param ha_ptr                On input: Indicates the starting point of the
  *                                  walk; null means start at the beginning of
@@ -230,9 +213,6 @@ ble_att_svr_pullup_req_base(struct os_mbuf **om, int base_len,
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_read(uint16_t conn_handle, struct ble_att_svr_entry *entry,
                  struct ble_att_svr_access_ctxt *ctxt, uint8_t *out_att_err)
@@ -275,9 +255,6 @@ err:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
                         struct ble_att_svr_access_ctxt *ctxt,
@@ -300,9 +277,6 @@ ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_write(uint16_t conn_handle, struct ble_att_svr_entry *entry,
                   struct ble_att_svr_access_ctxt *ctxt, uint8_t *out_att_err)
@@ -310,7 +284,7 @@ ble_att_svr_write(uint16_t conn_handle, struct ble_att_svr_entry *entry,
     uint8_t att_err;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (conn_handle != BLE_HS_CONN_HANDLE_NONE &&
         !(entry->ha_flags & HA_FLAG_PERM_WRITE)) {
@@ -363,9 +337,6 @@ ble_att_svr_write_handle(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                          uint8_t req_op, uint16_t handle, uint8_t error_code)
@@ -430,7 +401,6 @@ err:
  * @param err_handle            If an error is transmitted, this is the value
  *                                  of the error message's attribute handle
  *                                  field.
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
  */
 static int
 ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
@@ -482,9 +452,6 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *txom,
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **out_txom,
                           uint8_t *att_err)
@@ -535,9 +502,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -583,8 +547,6 @@ done:
  * Fills the supplied mbuf with the variable length Information Data field of a
  * Find Information ATT response.
  *
- * Lock restrictions: None.
- *
  * @param req                   The Find Information request being responded
  *                                  to.
  * @param om                    The destination mbuf where the Information
@@ -678,9 +640,6 @@ done:
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_find_info_rsp(uint16_t conn_handle,
                                 struct ble_att_find_info_req *req,
@@ -737,9 +696,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -796,8 +752,6 @@ done:
  * Processes a single non-matching attribute entry while filling a
  * Find-By-Type-Value-Response.
  *
- * Lock restrictions: None.
- *
  * @param om                    The response mbuf.
  * @param first                 Pointer to the first matching handle ID in the
  *                                  current group of IDs.  0 if there is not a
@@ -858,8 +812,6 @@ ble_att_svr_fill_type_value_no_match(struct os_mbuf *om, uint16_t *first,
  * Processes a single matching attribute entry while filling a
  * Find-By-Type-Value-Response.
  *
- * Lock restrictions: None.
- *
  * @param om                    The response mbuf.
  * @param first                 Pointer to the first matching handle ID in the
  *                                  current group of IDs.  0 if there is not a
@@ -913,8 +865,6 @@ ble_att_svr_fill_type_value_match(struct os_mbuf *om, uint16_t *first,
  * Fills the supplied mbuf with the variable length Handles-Information-List
  * field of a Find-By-Type-Value ATT response.
  *
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- *
  * @param req                   The Find-By-Type-Value-Request being responded
  *                                  to.
  * @param rxom                  The mbuf containing the received request.
@@ -1010,9 +960,6 @@ done:
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle,
                                       struct ble_att_find_type_value_req *req,
@@ -1061,9 +1008,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1119,9 +1063,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_read_type_rsp(uint16_t conn_handle,
                                 struct ble_att_read_type_req *req,
@@ -1248,9 +1189,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1333,8 +1271,6 @@ done:
 }
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -1391,9 +1327,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1445,8 +1378,6 @@ done:
 }
 
 /**
- * Lock restrictions: None.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -1494,9 +1425,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1561,9 +1489,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_build_read_mult_rsp(uint16_t conn_handle,
                                 struct os_mbuf **rxom,
@@ -1658,9 +1583,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -1704,9 +1626,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_svr_is_valid_group_type(uint8_t *uuid128)
 {
@@ -1718,9 +1637,6 @@ ble_att_svr_is_valid_group_type(uint8_t *uuid128)
            uuid16 == BLE_ATT_UUID_SECONDARY_SERVICE;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, uint16_t *uuid16,
                          uint8_t *uuid128)
@@ -1752,9 +1668,6 @@ ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, uint16_t *uuid16,
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu,
                                         uint16_t start_group_handle,
@@ -1791,8 +1704,6 @@ ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu,
 }
 
 /**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- *
  * @return                      0 on success; BLE_HS error code on failure.
  */
 static int
@@ -1975,9 +1886,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2052,9 +1960,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_att_svr_build_write_rsp(struct os_mbuf **out_txom, uint8_t *att_err)
 {
@@ -2085,9 +1990,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2119,7 +2021,7 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_WRITE_REQ_BASE_SZ);
 
-    ctxt.attr_data = ble_att_flat_buf;
+    ctxt.attr_data = ble_att_get_flat_buf();
     ctxt.data_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, ctxt.data_len, ctxt.attr_data);
     rc = ble_att_svr_write_handle(conn_handle, req.bawq_handle, &ctxt,
@@ -2143,9 +2045,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2169,7 +2068,7 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_WRITE_REQ_BASE_SZ);
 
-    ctxt.attr_data = ble_att_flat_buf;
+    ctxt.attr_data = ble_att_get_flat_buf();
     ctxt.data_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, ctxt.data_len, ctxt.attr_data);
     rc = ble_att_svr_write_handle(conn_handle, req.bawq_handle, &ctxt,
@@ -2181,9 +2080,6 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_write_local(uint16_t attr_handle, void *data, uint16_t data_len)
 {
@@ -2200,9 +2096,6 @@ ble_att_svr_write_local(uint16_t attr_handle, void *data, uint16_t data_len)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_att_svr_prep_free(struct ble_att_prep_entry *entry)
 {
@@ -2210,9 +2103,6 @@ ble_att_svr_prep_free(struct ble_att_prep_entry *entry)
     os_memblock_put(&ble_att_svr_prep_entry_pool, entry);
 }
 
-/**
- * Lock restrictions: None.
- */
 static struct ble_att_prep_entry *
 ble_att_svr_prep_alloc(void)
 {
@@ -2233,9 +2123,6 @@ ble_att_svr_prep_alloc(void)
     return entry;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static struct ble_att_prep_entry *
 ble_att_svr_prep_find_prev(struct ble_att_svr_conn *basc, uint16_t handle,
                            uint16_t offset)
@@ -2259,9 +2146,6 @@ ble_att_svr_prep_find_prev(struct ble_att_svr_conn *basc, uint16_t handle,
     return prev;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_att_svr_prep_clear(struct ble_att_svr_conn *basc)
 {
@@ -2274,8 +2158,6 @@ ble_att_svr_prep_clear(struct ble_att_svr_conn *basc)
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- *
  * @return                      0 on success; ATT error code on failure.
  */
 static int
@@ -2316,8 +2198,6 @@ ble_att_svr_prep_validate(struct ble_att_svr_conn *basc, uint16_t *err_handle)
 }
 
 /**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- *
  * @return                      0 on success; ATT error code on failure.
  */
 static int
@@ -2327,6 +2207,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
     struct ble_att_prep_entry *entry;
     struct ble_att_prep_entry *next;
     struct ble_att_svr_entry *attr;
+    uint8_t *flat_buf;
     uint8_t att_err;
     int buf_off;
     int rc;
@@ -2339,6 +2220,8 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
         return rc;
     }
 
+    flat_buf = ble_att_get_flat_buf();
+
     /* Contents are valid; perform the writes. */
     buf_off = 0;
     entry = SLIST_FIRST(&conn->bhc_att_svr.basc_prep_list);
@@ -2347,7 +2230,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
 
         rc = os_mbuf_copydata(entry->bape_value, 0,
                               OS_MBUF_PKTLEN(entry->bape_value),
-                              ble_att_flat_buf + buf_off);
+                              flat_buf + buf_off);
         BLE_HS_DBG_ASSERT_EVAL(rc == 0);
         buf_off += OS_MBUF_PKTLEN(entry->bape_value);
 
@@ -2359,7 +2242,7 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
                 return BLE_ATT_ERR_INVALID_HANDLE;
             }
 
-            ctxt.attr_data = ble_att_flat_buf;
+            ctxt.attr_data = flat_buf;
             ctxt.data_len = buf_off;
             rc = ble_att_svr_write(conn->bhc_handle, attr, &ctxt, &att_err);
             if (rc != 0) {
@@ -2376,9 +2259,6 @@ ble_att_svr_prep_write(struct ble_hs_conn *conn, uint16_t *err_handle)
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2522,8 +2402,6 @@ done:
 }
 
 /**
- * Lock restrictions: None.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -2556,9 +2434,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2619,9 +2494,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2652,7 +2524,7 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_NOTIFY_REQ_BASE_SZ);
 
-    attr_data = ble_att_flat_buf;
+    attr_data = ble_att_get_flat_buf();
     attr_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, attr_len, attr_data);
 
@@ -2669,8 +2541,6 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom)
 }
 
 /**
- * Lock restrictions: None.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
@@ -2701,9 +2571,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 int
 ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
 {
@@ -2740,7 +2607,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
     /* Strip the request base from the front of the mbuf. */
     os_mbuf_adj(*rxom, BLE_ATT_INDICATE_REQ_BASE_SZ);
 
-    attr_data = ble_att_flat_buf;
+    attr_data = ble_att_get_flat_buf();
     attr_len = OS_MBUF_PKTLEN(*rxom);
     os_mbuf_copydata(*rxom, 0, attr_len, attr_data);
 
@@ -2774,9 +2641,6 @@ ble_att_svr_free_mem(void)
     ble_att_svr_entry_mem = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_att_svr_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 5a556d1..33ef101 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -26,11 +26,40 @@
 #include "host/host_hci.h"
 #include "ble_hs_priv.h"
 
-#define BLE_GAP_OP_NULL                                 0
+/**
+ * GAP - Generic Access Profile.
+ *
+ * Design overview:
+ *
+ * GAP procedures are initiated by the application via function calls.  Such
+ * functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 2. Functions called directly by the application never call callbacks.
+ *    Generally, these functions lock the ble_hs mutex at the start, and only
+ *    unlock it at return.
+ * 3. Functions which do call callbacks (receive handlers and timer
+ *    expirations) generally only lock the mutex long enough to modify
+ *    affected state and make copies of data needed for the callback.  A copy
+ *    of various pieces of data is called a "snapshot" (struct
+ *    ble_gap_snapshot).  The sole purpose of snapshots is to allow callbacks
+ *    to be executed after unlocking the mutex.
+ */
 
+/** GAP procedure op codes. */
+#define BLE_GAP_OP_NULL                                 0
 #define BLE_GAP_OP_M_DISC                               1
 #define BLE_GAP_OP_M_CONN                               2
-
 #define BLE_GAP_OP_S_ADV                                1
 
 /**
@@ -234,9 +263,6 @@ ble_gap_log_adv(struct hci_adv_params *adv_params)
  * $snapshot                                                                 *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gap_fill_conn_desc(struct ble_hs_conn *conn,
                        struct ble_gap_conn_desc *desc)
@@ -249,9 +275,6 @@ ble_gap_fill_conn_desc(struct ble_hs_conn *conn,
     desc->supervision_timeout = conn->bhc_supervision_timeout;
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gap_conn_to_snapshot(struct ble_hs_conn *conn,
                          struct ble_gap_snapshot *snap)
@@ -261,10 +284,6 @@ ble_gap_conn_to_snapshot(struct ble_hs_conn *conn,
     snap->cb_arg = conn->bhc_cb_arg;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
 {
@@ -290,17 +309,13 @@ ble_gap_find_snapshot(uint16_t handle, struct ble_gap_snapshot *snap)
  * $misc                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_call_conn_cb(int event, int status, struct ble_gap_conn_ctxt *ctxt,
                      ble_gap_conn_fn *cb, void *cb_arg)
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (cb != NULL) {
         rc = cb(event, status, ctxt, cb_arg);
@@ -315,10 +330,6 @@ ble_gap_call_conn_cb(int event, int status, struct ble_gap_conn_ctxt *ctxt,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static void
 ble_gap_call_slave_cb(int event, int status, int reset_state)
 {
@@ -348,10 +359,6 @@ ble_gap_call_slave_cb(int event, int status, int reset_state)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_call_master_conn_cb(int event, int status, int reset_state)
 {
@@ -388,10 +395,6 @@ ble_gap_call_master_conn_cb(int event, int status, int reset_state)
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static void
 ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
                             struct ble_hs_adv_fields *fields, int reset_state)
@@ -428,16 +431,11 @@ ble_gap_call_master_disc_cb(int event, int status, struct ble_hs_adv *adv,
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks gap.
- */
 int
 ble_gap_update_in_progress(uint16_t conn_handle)
 {
     struct ble_hs_conn *conn;
 
-    /* XXX LOCKING */
     conn = ble_hs_conn_find(conn_handle);
     return conn != NULL && conn->bhc_flags & BLE_HS_CONN_F_UPDATE;
 }
@@ -447,7 +445,6 @@ ble_gap_update_set_flag(uint16_t conn_handle, int val)
 {
     struct ble_hs_conn *conn;
 
-    /* XXX LOCKING */
     conn = ble_hs_conn_find(conn_handle);
     if (conn == NULL) {
         return BLE_HS_ENOTCONN;
@@ -461,10 +458,6 @@ ble_gap_update_set_flag(uint16_t conn_handle, int val)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static void
 ble_gap_update_notify(uint16_t conn_handle, int status)
 {
@@ -495,9 +488,6 @@ ble_gap_master_set_timer(uint32_t ms_from_now)
  * Called when an error is encountered while the master-connection-fsm is
  * active.  Resets the state machine, clears the HCI ack callback, and notifies
  * the host task that the next hci_batch item can be processed.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_gap_master_failed(int status)
@@ -527,10 +517,6 @@ ble_gap_update_failed(uint16_t conn_handle, int status)
     ble_gap_update_notify(conn_handle, status);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks gap.
- */
 static void
 ble_gap_conn_broken(struct ble_gap_snapshot *snap)
 {
@@ -548,10 +534,6 @@ ble_gap_conn_broken(struct ble_gap_snapshot *snap)
     STATS_INC(ble_gap_stats, disconnect);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
 {
@@ -582,10 +564,6 @@ ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt)
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
 {
@@ -597,8 +575,6 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
     struct ble_gap_snapshot snap;
     struct ble_hs_conn *conn;
 
-    ble_hs_misc_assert_not_locked();
-
     STATS_INC(ble_gap_stats, rx_update_complete);
 
     ble_hs_lock();
@@ -628,8 +604,6 @@ ble_gap_rx_update_complete(struct hci_le_conn_upd_complete *evt)
 
 /**
  * Tells you if the BLE host is in the process of creating a master connection.
- *
- * Lock restrictions: None.
  */
 int
 ble_gap_master_in_progress(void)
@@ -639,8 +613,6 @@ ble_gap_master_in_progress(void)
 
 /**
  * Tells you if the BLE host is in the process of creating a slave connection.
- *
- * Lock restrictions: None.
  */
 int
 ble_gap_slave_in_progress(void)
@@ -648,9 +620,6 @@ ble_gap_slave_in_progress(void)
     return ble_gap_slave.op != BLE_GAP_OP_NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gap_currently_advertising(void)
 {
@@ -663,9 +632,6 @@ ble_gap_currently_advertising(void)
  * FSM is in a state that can accept this event, and the peer device address is
  * valid, the master FSM is reset and success is returned.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @param addr_type             The address type of the peer; one of the
  *                                  following values:
  *                                  o    BLE_ADDR_TYPE_PUBLIC
@@ -710,8 +676,6 @@ ble_gap_accept_master_conn(uint8_t addr_type, uint8_t *addr)
  * FSM is in a state that can accept this event, and the peer device address is
  * valid, the master FSM is reset and success is returned.
  *
- * Lock restrictions: None.
- *
  * @param addr_type             The address type of the peer; one of the
  *                                  following values:
  *                                  o    BLE_ADDR_TYPE_PUBLIC
@@ -757,10 +721,6 @@ ble_gap_accept_slave_conn(uint8_t addr_type, uint8_t *addr)
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_adv_report(struct ble_hs_adv *adv)
 {
@@ -795,9 +755,6 @@ ble_gap_rx_adv_report(struct ble_hs_adv *adv)
 
 /**
  * Processes an incoming connection-complete HCI event.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 int
 ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
@@ -875,6 +832,7 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     }
 
     /* We verified that there is a free connection when the procedure began. */
+    /* XXX: Revisit this; ensure this is guaranteed. */
     conn = ble_hs_conn_alloc();
     BLE_HS_DBG_ASSERT(conn != NULL);
 
@@ -905,10 +863,6 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
                             struct ble_gap_upd_params *params)
@@ -917,8 +871,6 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
     struct ble_gap_snapshot snap;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
-
     rc = ble_gap_find_snapshot(conn_handle, &snap);
     if (rc != 0) {
         return rc;
@@ -938,9 +890,6 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle,
 
 /**
  * Called by the ble_hs heartbeat timer.  Handles timed out master procedures.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 void
 ble_gap_heartbeat(void)
@@ -980,9 +929,6 @@ ble_gap_heartbeat(void)
  * $white list                                                               *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gap_wl_busy(void)
 {
@@ -997,10 +943,6 @@ ble_gap_wl_busy(void)
            ble_gap_master.conn.using_wl;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_wl_tx_add(struct ble_gap_white_entry *entry)
 {
@@ -1021,10 +963,6 @@ ble_gap_wl_tx_add(struct ble_gap_white_entry *entry)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_wl_tx_clear(void)
 {
@@ -1040,10 +978,6 @@ ble_gap_wl_tx_clear(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_wl_set(struct ble_gap_white_entry *white_list,
                uint8_t white_list_count)
@@ -1103,10 +1037,6 @@ err:
  * $stop advertise                                                           *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_disable_tx(void)
 {
@@ -1122,10 +1052,6 @@ ble_gap_adv_disable_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_adv_stop(void)
 {
@@ -1163,9 +1089,6 @@ err:
  * $advertise                                                                *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
                   uint16_t *out_itvl_min, uint16_t *out_itvl_max)
@@ -1192,10 +1115,6 @@ ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
     }
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_enable_tx(void)
 {
@@ -1212,10 +1131,6 @@ ble_gap_adv_enable_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_rsp_data_tx(void)
 {
@@ -1237,10 +1152,6 @@ ble_gap_adv_rsp_data_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_data_tx(void)
 {
@@ -1302,10 +1213,6 @@ ble_gap_adv_data_tx(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
 {
@@ -1347,9 +1254,6 @@ ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
  * Enables the specified discoverable mode and connectable mode, and initiates
  * the advertising process.
  *
- * Lock restrictions:
- *     o Caller unlocks gap.
- *
  * @param discoverable_mode     One of the following constants:
  *                                  o BLE_GAP_DISC_MODE_NON
  *                                      (non-discoverable; 3.C.9.2.2).
@@ -1503,9 +1407,6 @@ done:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
 {
@@ -1539,9 +1440,6 @@ ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
 {
@@ -1571,10 +1469,6 @@ ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields)
  * $discovery procedures                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_disc_tx_disable(void)
 {
@@ -1590,10 +1484,6 @@ ble_gap_disc_tx_disable(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_disc_tx_enable(void)
 {
@@ -1609,10 +1499,6 @@ ble_gap_disc_tx_enable(void)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
 {
@@ -1640,9 +1526,6 @@ ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
  * Performs the Limited or General Discovery Procedures, as described in
  * vol. 3, part C, section 9.2.5 / 9.2.6.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      0 on success; nonzero on failure.
  */
 int
@@ -1725,18 +1608,6 @@ done:
  * $connection establishment procedures                                      *
  *****************************************************************************/
 
-/**
- * Processes an HCI acknowledgement (either command status or command complete)
- * while a master connection is being established.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
-
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 static int
 ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
                        struct ble_gap_crt_params *params)
@@ -1790,9 +1661,6 @@ ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
  *                                  o BLE_GAP_ADDR_TYPE_WL
  * @param addr                  The address of the peer to connect to.
  *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- *
  * @return                      0 on success; nonzero on failure.
  */
 int
@@ -1860,10 +1728,6 @@ done:
  * $terminate connection procedure                                           *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_terminate(uint16_t conn_handle)
 {
@@ -1905,10 +1769,6 @@ done:
  * $cancel                                                                   *
  *****************************************************************************/
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 int
 ble_gap_cancel(void)
 {
@@ -1992,10 +1852,6 @@ ble_gap_tx_param_neg_reply(uint16_t conn_handle, uint8_t reject_reason)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
- */
 void
 ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
 {
@@ -2010,14 +1866,12 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     uint8_t reject_reason;
     int rc;
 
-    ble_hs_lock();
-
     reject_reason = 0; /* Silence warning. */
 
     rc = ble_gap_find_snapshot(evt->connection_handle, &snap);
     if (rc != 0) {
         /* We are not connected to the sender. */
-        goto done;;
+        return;
     }
 
     peer_params.itvl_min = evt->itvl_min;
@@ -2027,7 +1881,10 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     peer_params.min_ce_len = 0;
     peer_params.max_ce_len = 0;
 
-    /* By default, the application will just XXX */
+    /* Copy the peer params into the self params to make it easy on the
+     * application.  The application callback will change only the fields which
+     * it finds unsuitable.
+     */
     self_params = peer_params;
 
     memset(&ctxt, 0, sizeof ctxt);
@@ -2050,15 +1907,8 @@ ble_gap_rx_param_req(struct hci_le_conn_param_req *evt)
     } else {
         ble_gap_tx_param_neg_reply(evt->connection_handle, reject_reason);
     }
-
-done:
-    ble_hs_unlock();
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks gap.
- */
 static int
 ble_gap_update_tx(uint16_t conn_handle, struct ble_gap_upd_params *params)
 {
@@ -2087,11 +1937,6 @@ ble_gap_update_tx(uint16_t conn_handle, struct ble_gap_upd_params *params)
     return 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- *     o Caller unlocks gap.
- */
 int
 ble_gap_update_params(uint16_t conn_handle, struct ble_gap_upd_params *params)
 {
@@ -2145,21 +1990,13 @@ int
 ble_gap_security_initiate(uint16_t conn_handle)
 {
     ble_hs_conn_flags_t conn_flags;
-    struct ble_hs_conn *conn;
     int rc;
 
-    ble_hs_lock();
-
-    conn = ble_hs_conn_find(conn_handle);
-    if (conn != NULL) {
-        conn_flags = conn->bhc_flags;
+    rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
+    if (rc != 0) {
+        return rc;
     }
 
-    ble_hs_unlock();
-
-    if (conn == NULL) {
-        return BLE_HS_ENOTCONN;
-    }
     if (!(conn_flags & BLE_HS_CONN_F_MASTER)) {
         return BLE_HS_EROLE;
     }
@@ -2203,9 +2040,6 @@ ble_gap_security_event(uint16_t conn_handle, int status,
  * $init                                                                     *
  *****************************************************************************/
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gap_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 64502f3..bee3c39 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -17,6 +17,31 @@
  * under the License.
  */
 
+/**
+ * GATT client - Generic Attribute Profile; client operations.
+ *
+ * Design overview:
+ *
+ * GATT client procedures are initiated by the application via function calls.
+ * Such functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 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.
+ */
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -840,7 +865,7 @@ ble_gattc_mtu_cb(struct ble_gattc_proc *proc, int status, uint16_t att_handle,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, mtu_fail);
@@ -944,7 +969,7 @@ ble_gattc_disc_all_svcs_cb(struct ble_gattc_proc *proc,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_svcs_fail);
@@ -1141,7 +1166,7 @@ ble_gattc_disc_svc_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_svc_uuid_fail);
@@ -1319,7 +1344,7 @@ ble_gattc_find_inc_svcs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, find_inc_svcs_fail);
@@ -1606,7 +1631,7 @@ ble_gattc_disc_all_chrs_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_chrs_fail);
@@ -1814,12 +1839,12 @@ 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());
+
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_chrs_uuid_fail);
     }
 
-    ble_hs_misc_assert_not_locked();
-
     if (proc->disc_chr_uuid.cb == NULL) {
         rc = 0;
     } else {
@@ -2033,12 +2058,12 @@ 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());
+
     if (status != 0) {
         STATS_INC(ble_gattc_stats, disc_all_dscs_fail);
     }
 
-    ble_hs_misc_assert_not_locked();
-
     if (proc->disc_all_dscs.cb == NULL) {
         rc = 0;
     } else {
@@ -2214,7 +2239,7 @@ ble_gattc_read_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_fail);
@@ -2334,7 +2359,7 @@ ble_gattc_read_uuid_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_uuid_fail);
@@ -2476,7 +2501,7 @@ ble_gattc_read_long_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_long_fail);
@@ -2641,7 +2666,7 @@ ble_gattc_read_mult_cb(struct ble_gattc_proc *proc, int status,
     struct ble_gatt_attr attr;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, read_mult_fail);
@@ -2785,7 +2810,7 @@ ble_gattc_write_cb(struct ble_gattc_proc *proc, int status,
     struct ble_gatt_attr attr;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_fail);
@@ -2889,7 +2914,7 @@ ble_gattc_write_long_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_long_fail);
@@ -3100,7 +3125,7 @@ ble_gattc_write_reliable_cb(struct ble_gattc_proc *proc, int status,
 {
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, write_reliable_fail);
@@ -3376,7 +3401,7 @@ ble_gattc_indicate_cb(struct ble_gattc_proc *proc, int status,
     struct ble_gatt_attr attr;
     int rc;
 
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_gattc_stats, indicate_fail);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 73bee78..4ef5f21 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -64,9 +64,6 @@ STATS_NAME_START(ble_gatts_stats)
     STATS_NAME(ble_gatts_stats, dsc_writes)
 STATS_NAME_END(ble_gatts_stats)
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t op,
@@ -94,9 +91,6 @@ ble_gatts_svc_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t op,
@@ -129,9 +123,6 @@ ble_gatts_inc_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint16_t
 ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
 {
@@ -148,9 +139,6 @@ ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
     return flags;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
 {
@@ -167,9 +155,6 @@ ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
     return att_flags;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_chr_properties(const struct ble_gatt_chr_def *chr)
 {
@@ -207,9 +192,6 @@ ble_gatts_chr_properties(const struct ble_gatt_chr_def *chr)
     return properties;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_chr_def_access(uint16_t conn_handle, uint16_t attr_handle,
                          uint8_t *uuid128, uint8_t op,
@@ -243,9 +225,6 @@ ble_gatts_chr_def_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_chr_is_sane(const struct ble_gatt_chr_def *chr)
 {
@@ -262,9 +241,6 @@ ble_gatts_chr_is_sane(const struct ble_gatt_chr_def *chr)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_chr_op(uint8_t att_op)
 {
@@ -298,9 +274,6 @@ ble_gatts_chr_inc_val_stat(uint8_t gatt_op)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle,
                          uint8_t *uuid128, uint8_t att_op,
@@ -339,9 +312,6 @@ ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_find_svc(const struct ble_gatt_svc_def *svc)
 {
@@ -356,9 +326,6 @@ ble_gatts_find_svc(const struct ble_gatt_svc_def *svc)
     return -1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_incs_satisfied(const struct ble_gatt_svc_def *svc)
 {
@@ -380,9 +347,6 @@ ble_gatts_svc_incs_satisfied(const struct ble_gatt_svc_def *svc)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_inc(struct ble_gatts_svc_entry *entry)
 {
@@ -401,9 +365,6 @@ ble_gatts_register_inc(struct ble_gatts_svc_entry *entry)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static uint8_t
 ble_gatts_dsc_op(uint8_t att_op)
 {
@@ -437,9 +398,6 @@ ble_gatts_dsc_inc_stat(uint8_t gatt_op)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_dsc_access(uint16_t conn_handle, uint16_t attr_handle,
                      uint8_t *uuid128, uint8_t att_op,
@@ -472,9 +430,6 @@ ble_gatts_dsc_access(uint16_t conn_handle, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
 {
@@ -489,9 +444,6 @@ ble_gatts_dsc_is_sane(const struct ble_gatt_dsc_def *dsc)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
                        const struct ble_gatt_chr_def *chr,
@@ -526,9 +478,6 @@ ble_gatts_register_dsc(const struct ble_gatt_dsc_def *dsc,
 
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_clt_cfg_find_idx(struct ble_gatts_clt_cfg *cfgs,
                            uint16_t chr_def_handle)
@@ -546,9 +495,6 @@ ble_gatts_clt_cfg_find_idx(struct ble_gatts_clt_cfg *cfgs,
     return -1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static struct ble_gatts_clt_cfg *
 ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg *cfgs,
                        uint16_t chr_def_handle)
@@ -563,9 +509,6 @@ ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg *cfgs,
     }
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
                                 uint8_t *uuid128, uint8_t att_op,
@@ -627,9 +570,6 @@ ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 static int
 ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
                          uint8_t *uuid128, uint8_t op,
@@ -654,9 +594,6 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
 {
@@ -679,9 +616,6 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_chr(const struct ble_gatt_chr_def *chr,
                        ble_gatt_register_fn *register_cb, void *cb_arg)
@@ -750,9 +684,6 @@ ble_gatts_register_chr(const struct ble_gatt_chr_def *chr,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_type_to_uuid(uint8_t svc_type, uint16_t *out_uuid16)
 {
@@ -770,9 +701,6 @@ ble_gatts_svc_type_to_uuid(uint8_t svc_type, uint16_t *out_uuid16)
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_svc_is_sane(const struct ble_gatt_svc_def *svc)
 {
@@ -789,9 +717,6 @@ ble_gatts_svc_is_sane(const struct ble_gatt_svc_def *svc)
     return 1;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
                        uint16_t *out_handle,
@@ -861,9 +786,6 @@ ble_gatts_register_svc(const struct ble_gatt_svc_def *svc,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_register_round(int *out_num_registered, ble_gatt_register_fn *cb,
                          void *cb_arg)
@@ -907,9 +829,6 @@ ble_gatts_register_round(int *out_num_registered, ble_gatt_register_fn *cb,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
                         ble_gatt_register_fn *cb, void *cb_arg)
@@ -942,9 +861,6 @@ ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 void
 ble_gatts_conn_deinit(struct ble_gatts_conn *gatts_conn)
 {
@@ -958,18 +874,12 @@ ble_gatts_conn_deinit(struct ble_gatts_conn *gatts_conn)
     }
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_clt_cfg_size(void)
 {
     return ble_gatts_num_cfgable_chrs * sizeof (struct ble_gatts_clt_cfg);
 }
 
-/**
- * Lock restrictions: None.
- */
 static int
 ble_gatts_clt_cfg_init(void)
 {
@@ -1037,9 +947,6 @@ ble_gatts_clt_cfg_init(void)
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn)
 {
@@ -1069,9 +976,6 @@ ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn)
     return 0;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_gatts_send_notifications(struct ble_hs_conn *conn)
 {
@@ -1111,9 +1015,6 @@ ble_gatts_send_notifications(struct ble_hs_conn *conn)
     }
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 void
 ble_gatts_chr_updated(uint16_t chr_def_handle)
 {
@@ -1151,9 +1052,6 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
     ble_hs_unlock();
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_gatts_free_mem(void)
 {
@@ -1164,9 +1062,6 @@ ble_gatts_free_mem(void)
     ble_gatts_svc_entries = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_gatts_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 e05a9e9..4d62a94 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -44,7 +44,7 @@ struct log ble_hs_log;
 struct os_mempool g_hci_cmd_pool;
 static void *ble_hs_hci_cmd_buf;
 
-/* XXX: this might be transport layer*/
+/* XXX: this might be transport layer */
 #define HCI_OS_EVENT_BUF_SIZE   (sizeof(struct os_event))
 
 struct os_mempool g_hci_os_event_pool;
@@ -67,6 +67,7 @@ static struct os_callout_func ble_hs_event_co;
 /* Host HCI Task Events */
 static struct os_eventq ble_hs_evq;
 static struct os_eventq *ble_hs_app_evq;
+static struct os_task *ble_hs_app_task;
 
 static struct os_mqueue ble_hs_rx_q;
 static struct os_mqueue ble_hs_tx_q;
@@ -83,16 +84,39 @@ STATS_NAME_START(ble_hs_stats)
     STATS_NAME(ble_hs_stats, hci_unknown_event)
 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;
+
+    owner = ble_hs_mutex.mu_owner;
+    return owner != NULL && owner == os_sched_get_current_task();
+}
+
+int
+ble_hs_thread_safe(void)
+{
+    return !os_started() || ble_hs_locked_by_cur_task();
+}
+
+int
+ble_hs_is_app_task(void)
+{
+    return os_sched_get_current_task() == ble_hs_app_task;
+}
+
 void
 ble_hs_lock(void)
 {
-    struct os_task *owner;
     int rc;
 
-    owner = ble_hs_mutex.mu_owner;
-    if (owner != NULL) {
-        BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
-    }
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     rc = os_mutex_pend(&ble_hs_mutex, 0xffffffff);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
@@ -107,12 +131,6 @@ ble_hs_unlock(void)
     BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
 }
 
-int
-ble_hs_locked(void)
-{
-    return ble_hs_mutex.mu_level > 0;
-}
-
 void
 ble_hs_process_tx_data_queue(void)
 {
@@ -150,9 +168,6 @@ ble_hs_heartbeat_timer_reset(void)
 /**
  * Called once a second by the ble_hs heartbeat timer.  Handles unresponsive
  * timeouts and periodic retries in case of resource shortage.
- *
- * Lock restrictions:
- *     o Caller unlocks all ble_hs mutexes.
  */
 static void
 ble_hs_heartbeat(void *unused)
@@ -218,6 +233,8 @@ ble_hs_start(void)
 {
     int rc;
 
+    ble_hs_app_task = os_sched_get_current_task();
+
     ble_hs_heartbeat_timer_reset();
 
     rc = ble_hs_startup_go();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_adv.c b/net/nimble/host/src/ble_hs_adv.c
index faf63b0..ef038a7 100644
--- a/net/nimble/host/src/ble_hs_adv.c
+++ b/net/nimble/host/src/ble_hs_adv.c
@@ -106,8 +106,6 @@ ble_hs_adv_set_array32(uint8_t type, uint8_t num_elems, uint32_t *elems,
 /**
  * Sets the significant part of the data in outgoing advertisements.
  *
- * Lock restrictions: None.
- *
  * @return                      0 on success;  on failure.
  */
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 4aeabe6..a09eaad 100644
--- a/net/nimble/host/src/ble_hs_atomic.c
+++ b/net/nimble/host/src/ble_hs_atomic.c
@@ -43,3 +43,24 @@ ble_hs_atomic_conn_insert(struct ble_hs_conn *conn)
     ble_hs_conn_insert(conn);
     ble_hs_unlock();
 }
+
+int
+ble_hs_atomic_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
+{
+    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;
+        *out_flags = conn->bhc_flags;
+    }
+
+    ble_hs_unlock();
+
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_atomic.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.h b/net/nimble/host/src/ble_hs_atomic.h
index 5bb3665..29852f8 100644
--- a/net/nimble/host/src/ble_hs_atomic.h
+++ b/net/nimble/host/src/ble_hs_atomic.h
@@ -20,6 +20,11 @@
 #ifndef H_BLE_HS_ATOMIC_
 #define H_BLE_HS_ATOMIC_
 
+#include "ble_hs_conn.h"
+
 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);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 7c505ba..8d22739 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -28,9 +28,6 @@ static struct os_mempool ble_hs_conn_pool;
 
 static os_membuf_t *ble_hs_conn_elem_mem;
 
-/**
- * Lock restrictions: none.
- */
 int
 ble_hs_conn_can_alloc(void)
 {
@@ -41,9 +38,6 @@ ble_hs_conn_can_alloc(void)
     return ble_hs_conn_pool.mp_num_free >= 1;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 struct ble_l2cap_chan *
 ble_hs_conn_chan_find(struct ble_hs_conn *conn, uint16_t cid)
 {
@@ -65,10 +59,6 @@ ble_hs_conn_chan_find(struct ble_hs_conn *conn, uint16_t cid)
     return NULL;
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex if connection has been
- * inserted.
- */
 int
 ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -100,9 +90,6 @@ ble_hs_conn_chan_insert(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     return 0;
 }
 
-/**
- * Lock restrictions: none.
- */
 struct ble_hs_conn *
 ble_hs_conn_alloc(void)
 {
@@ -165,9 +152,6 @@ err:
     return NULL;
 }
 
-/**
- * Lock restrictions: none.
- */
 static void
 ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -179,9 +163,6 @@ ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     ble_l2cap_chan_free(chan);
 }
 
-/**
- * Lock restrictions: none.
- */
 void
 ble_hs_conn_free(struct ble_hs_conn *conn)
 {
@@ -210,9 +191,6 @@ ble_hs_conn_free(struct ble_hs_conn *conn)
     STATS_INC(ble_hs_stats, conn_delete);
 }
 
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
 void
 ble_hs_conn_insert(struct ble_hs_conn *conn)
 {
@@ -220,13 +198,12 @@ ble_hs_conn_insert(struct ble_hs_conn *conn)
     return;
 #endif
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
+
     BLE_HS_DBG_ASSERT_EVAL(ble_hs_conn_find(conn->bhc_handle) == NULL);
     SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 void
 ble_hs_conn_remove(struct ble_hs_conn *conn)
 {
@@ -234,12 +211,11 @@ ble_hs_conn_remove(struct ble_hs_conn *conn)
     return;
 #endif
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
+
     SLIST_REMOVE(&ble_hs_conns, conn, ble_hs_conn, bhc_next);
 }
 
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
 struct ble_hs_conn *
 ble_hs_conn_find(uint16_t conn_handle)
 {
@@ -249,6 +225,8 @@ ble_hs_conn_find(uint16_t conn_handle)
 
     struct ble_hs_conn *conn;
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
+
     SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
         if (conn->bhc_handle == conn_handle) {
             return conn;
@@ -268,34 +246,7 @@ ble_hs_conn_exists(uint16_t conn_handle)
 }
 
 /**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
-int
-ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
-{
-    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;
-        *out_flags = conn->bhc_flags;
-    }
-
-    ble_hs_unlock();
-
-    return rc;
-}
-
-/**
  * Retrieves the first connection in the list.
- *
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
  */
 struct ble_hs_conn *
 ble_hs_conn_first(void)
@@ -304,12 +255,10 @@ ble_hs_conn_first(void)
     return NULL;
 #endif
 
+    BLE_HS_DBG_ASSERT(ble_hs_thread_safe());
     return SLIST_FIRST(&ble_hs_conns);
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_hs_conn_free_mem(void)
 {
@@ -317,9 +266,6 @@ ble_hs_conn_free_mem(void)
     ble_hs_conn_elem_mem = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int 
 ble_hs_conn_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index 0dd7bf6..c470c3d 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -64,7 +64,6 @@ void ble_hs_conn_insert(struct ble_hs_conn *conn);
 void ble_hs_conn_remove(struct ble_hs_conn *conn);
 struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle);
 int ble_hs_conn_exists(uint16_t conn_handle);
-int ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags);
 struct ble_hs_conn *ble_hs_conn_first(void);
 struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
                                              uint16_t cid);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 ab130bb..82941d6 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -67,16 +67,8 @@ ble_hs_misc_log_flat_buf(void *data, int len)
     }
 }
 
-void
-ble_hs_misc_assert_not_locked(void)
-{
-    assert(!ble_hs_locked());
-}
-
 /**
  * Allocates an mbuf for use by the nimble host.
- *
- * Lock restrictions: None.
  */
 struct os_mbuf *
 ble_hs_misc_pkthdr(void)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 9bd3632..23df932 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -26,14 +26,15 @@
 #include "ble_att_priv.h"
 #include "ble_gap_priv.h"
 #include "ble_gatt_priv.h"
+#include "ble_hci_util.h"
 #include "ble_hs_adv_priv.h"
+#include "ble_hs_atomic.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_endian.h"
 #include "ble_hs_startup.h"
 #include "ble_l2cap_priv.h"
 #include "ble_l2cap_sig.h"
 #include "ble_l2cap_sm.h"
-#include "ble_hci_util.h"
 #include "host/ble_hs.h"
 #include "log/log.h"
 #include "nimble/nimble_opt.h"
@@ -92,15 +93,14 @@ 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);
 
-int ble_hs_atomic_conn_delete(uint16_t conn_handle);
-void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
-
 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_app_task(void);
 void ble_hs_lock(void);
 void ble_hs_unlock(void);
-int ble_hs_locked(void);
-void ble_hs_misc_assert_not_locked(void);
 
 struct os_mbuf *ble_hs_misc_pkthdr(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c
index 40bf225..65b3fc2 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -46,9 +46,6 @@ STATS_NAME_START(ble_l2cap_stats)
     STATS_NAME(ble_l2cap_stats, sm_rx)
 STATS_NAME_END(ble_l2cap_stats)
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_l2cap_chan_alloc(void)
 {
@@ -66,9 +63,6 @@ ble_l2cap_chan_alloc(void)
     return chan;
 }
 
-/**
- * Lock restrictions: None.
- */
 void
 ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
 {
@@ -84,10 +78,6 @@ ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
     STATS_INC(ble_l2cap_stats, chan_delete);
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 uint16_t
 ble_l2cap_chan_mtu(struct ble_l2cap_chan *chan)
 {
@@ -109,9 +99,6 @@ ble_l2cap_chan_mtu(struct ble_l2cap_chan *chan)
     return mtu;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
                     struct ble_l2cap_hdr *l2cap_hdr)
@@ -129,9 +116,6 @@ ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
     return 0;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct os_mbuf *
 ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len)
 {
@@ -150,10 +134,6 @@ ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len)
     return om;
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static void
 ble_l2cap_forget_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -162,10 +142,6 @@ ble_l2cap_forget_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     chan->blc_rx_len = 0;
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static void
 ble_l2cap_discard_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
@@ -173,10 +149,6 @@ ble_l2cap_discard_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
     ble_l2cap_forget_rx(conn, chan);
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 static int
 ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                      struct os_mbuf *om,
@@ -211,10 +183,6 @@ ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     return rc;
 }
 
-/**
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- */
 int
 ble_l2cap_rx(struct ble_hs_conn *conn,
              struct hci_data_hdr *hci_hdr,
@@ -288,9 +256,6 @@ err:
  * Transmits the L2CAP payload contained in the specified mbuf.  The supplied
  * mbuf is consumed, regardless of the outcome of the function call.
  * 
- * Lock restrictions:
- *     o Caller locks ble_hs_conn.
- *
  * @param chan                  The L2CAP channel to transmit over.
  * @param om                    The data to transmit.
  *
@@ -324,9 +289,6 @@ err:
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 static void
 ble_l2cap_free_mem(void)
 {
@@ -334,9 +296,6 @@ ble_l2cap_free_mem(void)
     ble_l2cap_chan_mem = NULL;
 }
 
-/**
- * Lock restrictions: None.
- */
 int
 ble_l2cap_init(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/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 2f6b692..ff98426 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -17,6 +17,31 @@
  * under the License.
  */
 
+/**
+ * L2CAP Signaling (channel ID = 5).
+ *
+ * Design overview:
+ *
+ * L2CAP sig procedures are initiated by the application via function calls.
+ * Such functions return when either of the following happens:
+ *
+ * (1) The procedure completes (success or failure).
+ * (2) The procedure cannot proceed until a BLE peer responds.
+ *
+ * For (1), the result of the procedure if fully indicated by the function
+ * return code.
+ * For (2), the procedure result is indicated by an application-configured
+ * callback.  The callback is executed when the procedure completes.
+ *
+ * Notes on thread-safety:
+ * 1. The ble_hs mutex must never be locked when an application callback is
+ *    executed.  A callback is free to initiate additional host procedures.
+ * 2. The only resource protected by the mutex is the list of active procedures
+ *    (ble_l2cap_sig_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.
+ */
+
 #include <string.h>
 #include <errno.h>
 #include "console/console.h"
@@ -241,7 +266,7 @@ ble_l2cap_sig_rx_noop(uint16_t conn_handle,
 static void
 ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status)
 {
-    ble_hs_misc_assert_not_locked();
+    BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task());
 
     if (status != 0) {
         STATS_INC(ble_l2cap_stats, update_fail);
@@ -382,7 +407,7 @@ ble_l2cap_sig_update(uint16_t conn_handle,
 
     STATS_INC(ble_l2cap_stats, update_init);
 
-    rc = ble_hs_conn_flags(conn_handle, &conn_flags);
+    rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index 290dc43..7e12180 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -52,10 +52,6 @@ ble_l2cap_sig_init_cmd(uint8_t op, uint8_t id, uint8_t payload_len,
     return 0;
 }
 
-/**
- * Locking restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
 {