You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/28 02:14:22 UTC

[23/50] [abbrv] incubator-mynewt-core git commit: ble host - clarify locking restrictions.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c
index 99f7d64..2460048 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -17,6 +17,31 @@
  * under the License.
  */
 
+/**
+ * L2CAP Security Manager (channel ID = 6).
+ *
+ * Design overview:
+ *
+ * L2CAP sm 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_sm_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"
@@ -245,9 +270,6 @@ ble_l2cap_sm_proc_set_timer(struct ble_l2cap_sm_proc *proc)
     proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SM_TIMEOUT_OS_TICKS;
 }
 
-/**
- * Lock restrictions: None.
- */
 static ble_l2cap_sm_rx_fn *
 ble_l2cap_sm_dispatch_get(uint8_t state)
 {
@@ -261,8 +283,6 @@ ble_l2cap_sm_dispatch_get(uint8_t state)
 /**
  * Allocates a proc entry.
  *
- * Lock restrictions: None.
- *
  * @return                      An entry on success; null on failure.
  */
 static struct ble_l2cap_sm_proc *
@@ -280,8 +300,6 @@ ble_l2cap_sm_proc_alloc(void)
 
 /**
  * Frees the specified proc entry.  No-state if passed a null pointer.
- *
- * Lock restrictions: None.
  */
 static void
 ble_l2cap_sm_proc_free(struct ble_l2cap_sm_proc *proc)
@@ -644,6 +662,8 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
 {
     struct ble_hs_conn *conn;
 
+    ble_hs_lock();
+
     conn = ble_hs_conn_find(proc->conn_handle);
     if (conn != NULL) {
         if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
@@ -661,6 +681,8 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc,
         }
     }
 
+    ble_hs_unlock();
+
     if (conn == NULL) {
         return BLE_HS_ENOTCONN;
     }
@@ -1047,10 +1069,6 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
     ble_l2cap_sm_proc_free(proc);
 }
 
-/**
- * Lock restrictions:
- *     o Caller unlocks ble_hs_conn.
- */
 static int
 ble_l2cap_sm_rx(uint16_t conn_handle, struct os_mbuf **om)
 {
@@ -1136,9 +1154,6 @@ ble_l2cap_sm_initiate(uint16_t conn_handle)
     return rc;
 }
 
-/**
- * Lock restrictions: None.
- */
 struct ble_l2cap_chan *
 ble_l2cap_sm_create_chan(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/61458e37/net/nimble/host/src/test/ble_os_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_os_test.c b/net/nimble/host/src/test/ble_os_test.c
index e95e567..8e370fb 100644
--- a/net/nimble/host/src/test/ble_os_test.c
+++ b/net/nimble/host/src/test/ble_os_test.c
@@ -76,6 +76,24 @@ ble_os_test_misc_init(void)
 }
 
 static int
+ble_os_test_misc_conn_exists(uint16_t conn_handle)
+{
+    struct ble_hs_conn *conn;
+
+    ble_hs_lock();
+
+    if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
+        conn = ble_hs_conn_first();
+    } else {
+        conn = ble_hs_conn_find(conn_handle);
+    }
+
+    ble_hs_unlock();
+
+    return conn != NULL;
+}
+
+static int
 ble_gap_direct_connect_test_connect_cb(int event, int status,
                                        struct ble_gap_conn_ctxt *ctxt,
                                        void *arg)
@@ -110,13 +128,13 @@ ble_gap_direct_connect_test_task_handler(void *arg)
     /* Make sure there are no created connections and no connections in
      * progress.
      */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
 
     /* Initiate a direct connection. */
     ble_hs_test_util_conn_initiate(0, addr, NULL,
                                    ble_gap_direct_connect_test_connect_cb,
                                    &cb_called, 0);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!cb_called);
 
     /* Receive an HCI connection-complete event. */
@@ -129,7 +147,7 @@ ble_gap_direct_connect_test_task_handler(void *arg)
     TEST_ASSERT(rc == 0);
 
     /* The connection should now be created. */
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(ble_os_test_misc_conn_exists(2));
     TEST_ASSERT(cb_called);
 
     tu_restart();
@@ -180,7 +198,7 @@ ble_gap_gen_disc_test_task_handler(void *arg)
     /* Make sure there are no created connections and no connections in
      * progress.
      */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!ble_gap_master_in_progress());
 
     /* Initiate the general discovery procedure with a 200 ms timeout. */
@@ -190,18 +208,18 @@ ble_gap_gen_disc_test_task_handler(void *arg)
                                ble_gap_gen_disc_test_connect_cb,
                                &cb_called, 0, 0);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
     /* Receive acks from the controller. */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
     /* Wait 100 ms; verify scan still in progress. */
     os_time_delay(100 * OS_TICKS_PER_SEC / 1000);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(ble_gap_master_in_progress());
     TEST_ASSERT(!cb_called);
 
@@ -211,7 +229,7 @@ ble_gap_gen_disc_test_task_handler(void *arg)
 
     /* Wait 250 more ms; verify scan completed. */
     os_time_delay(250 * OS_TICKS_PER_SEC / 1000);
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!ble_gap_master_in_progress());
     TEST_ASSERT(cb_called);
 
@@ -272,7 +290,7 @@ ble_gap_terminate_test_task_handler(void *arg)
     /* Make sure there are no created connections and no connections in
      * progress.
      */
-    TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!ble_os_test_misc_conn_exists(BLE_HS_CONN_HANDLE_NONE));
     TEST_ASSERT(!ble_gap_master_in_progress());
 
     /* Create two direct connections. */
@@ -296,8 +314,8 @@ ble_gap_terminate_test_task_handler(void *arg)
     rc = ble_gap_rx_conn_complete(&conn_evt);
     TEST_ASSERT(rc == 0);
 
-    TEST_ASSERT_FATAL(ble_hs_conn_find(1) != NULL);
-    TEST_ASSERT_FATAL(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(1));
+    TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(2));
 
     /* Terminate the first one. */
     rc = ble_hs_test_util_conn_terminate(1, 0);
@@ -307,8 +325,8 @@ ble_gap_terminate_test_task_handler(void *arg)
     disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
     ble_gap_rx_disconn_complete(&disconn_evt);
     TEST_ASSERT(disconn_handle == 1);
-    TEST_ASSERT(ble_hs_conn_find(1) == NULL);
-    TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(1));
+    TEST_ASSERT_FATAL(ble_os_test_misc_conn_exists(2));
 
     /* Terminate the second one. */
     rc = ble_hs_test_util_conn_terminate(2, 0);
@@ -318,8 +336,8 @@ ble_gap_terminate_test_task_handler(void *arg)
     disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
     ble_gap_rx_disconn_complete(&disconn_evt);
     TEST_ASSERT(disconn_handle == 2);
-    TEST_ASSERT(ble_hs_conn_find(1) == NULL);
-    TEST_ASSERT(ble_hs_conn_find(2) == NULL);
+    TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(1));
+    TEST_ASSERT_FATAL(!ble_os_test_misc_conn_exists(2));
 
     tu_restart();
 }