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:24 UTC
[2/7] 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();
}