You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/05/09 04:54:03 UTC

[1/4] incubator-mynewt-core git commit: BLE host - whitespace fix.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 264a67b95 -> e76defb04


BLE host - whitespace fix.


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

Branch: refs/heads/develop
Commit: ee13afed061a8b06fe9b6adbb5207cbe6045128f
Parents: 264a67b
Author: Christopher Collins <cc...@apache.org>
Authored: Sat May 7 12:07:33 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sat May 7 12:07:33 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap_sm.c | 50 ++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ee13afed/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 aca9260..ff620ec 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -209,31 +209,31 @@ ble_l2cap_sm_dbg_num_procs(void)
  * $misc                                                                     *
  *****************************************************************************/
 
- static void
- ble_l2cap_build_rx_key_exchange_state(struct ble_l2cap_sm_proc *proc)
- {
-     uint8_t rx_key_dist;
-
-     /* if we are intiating we are waiting for the responders keys */
-     if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-         rx_key_dist = proc->pair_rsp.resp_key_dist;
-     } else {
-         rx_key_dist = proc->pair_rsp.init_key_dist;
-     }
-     proc->rx_key_flags = 0;
-
-     if (rx_key_dist & KEY_DIST_ENC_KEY) {
-         proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_ENC_INFO |
-                               BLE_L2CAP_SM_KE_F_MASTER_IDEN;
-     }
-     if (rx_key_dist & KEY_DIST_ID_KEY) {
-         proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_IDEN_INFO |
-                               BLE_L2CAP_SM_KE_F_ADDR_INFO;
-     }
-     if (rx_key_dist & KEY_DIST_SIGN) {
-         proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_SIGN_INFO;
-     }
- }
+static void
+ble_l2cap_build_rx_key_exchange_state(struct ble_l2cap_sm_proc *proc)
+{
+    uint8_t rx_key_dist;
+
+    /* if we are intiating we are waiting for the responders keys */
+    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+        rx_key_dist = proc->pair_rsp.resp_key_dist;
+    } else {
+        rx_key_dist = proc->pair_rsp.init_key_dist;
+    }
+    proc->rx_key_flags = 0;
+
+    if (rx_key_dist & KEY_DIST_ENC_KEY) {
+        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_ENC_INFO |
+                              BLE_L2CAP_SM_KE_F_MASTER_IDEN;
+    }
+    if (rx_key_dist & KEY_DIST_ID_KEY) {
+        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_IDEN_INFO |
+                              BLE_L2CAP_SM_KE_F_ADDR_INFO;
+    }
+    if (rx_key_dist & KEY_DIST_SIGN) {
+        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_SIGN_INFO;
+    }
+}
 
 static int
 ble_l2cap_sm_gen_pair_rand(uint8_t *pair_rand)


[4/4] incubator-mynewt-core git commit: BLE host - remove ble_l2cap_sm_process_status().

Posted by cc...@apache.org.
BLE host - remove ble_l2cap_sm_process_status().

This function was ill-conceived.


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

Branch: refs/heads/develop
Commit: e76defb0437e1811dffe3f630405627eb6b3bf2a
Parents: 2a6cf99
Author: Christopher Collins <cc...@apache.org>
Authored: Sun May 8 21:33:32 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sun May 8 21:53:50 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap_sm.c           | 120 ++---
 net/nimble/host/src/test/ble_l2cap_sm_test.c | 578 +++++++++++++++-------
 2 files changed, 463 insertions(+), 235 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e76defb0/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 60cbae8..376b2f8 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -403,30 +403,6 @@ ble_l2cap_sm_gap_event(struct ble_l2cap_sm_proc *proc, int status,
     ble_gap_security_event(proc->conn_handle, status, &sec_state);
 }
 
-/* We must call this function when the host is unlocked because in
- * failure conditions it will transmit which requires that we lock it
-  */
-static int
-ble_l2cap_sm_process_status(struct ble_l2cap_sm_proc *proc, int status,
-                            uint8_t sm_status, int call_cb, int tx_fail)
-{
-    if (proc == NULL) {
-        status = BLE_HS_ENOENT;
-    } else if (status != 0) {
-        if (tx_fail) {
-            ble_hs_lock();
-            ble_l2cap_sm_pair_fail_tx(proc->conn_handle, sm_status);
-            ble_hs_unlock();
-        }
-        if (call_cb) {
-            ble_l2cap_sm_gap_event(proc, status, 0);
-        }
-        ble_l2cap_sm_proc_free(proc);
-    }
-
-    return status;
-}
-
 static int
 ble_l2cap_sm_proc_matches(struct ble_l2cap_sm_proc *proc, uint16_t conn_handle,
                           uint8_t state, int is_initiator)
@@ -1037,7 +1013,7 @@ ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
     }
     if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
         *out_sm_status = BLE_L2CAP_SM_ERR_CMD_NOT_SUPP;
-        return BLE_HS_EROLE;
+        return BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_CMD_NOT_SUPP);
     }
 
     if (!ble_l2cap_sm_pair_cmd_is_valid(req)) {
@@ -1310,20 +1286,22 @@ ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
             ble_l2cap_sm_signing_info_handle(proc, &u.signing_info);
             break;
         }
-    }
 
-    /* did we finish RX keys */
-    rc = 0;
-    if (!proc->rx_key_flags) {
-        if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-            /* time for us to send our keys */
-            rc = ble_l2cap_sm_key_exchange_go(proc, &sm_status);
+        /* did we finish RX keys */
+        rc = 0;
+        if (!proc->rx_key_flags) {
+            if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+                /* time for us to send our keys */
+                rc = ble_l2cap_sm_key_exchange_go(proc, &sm_status);
+            }
+            sm_end = 1;
         }
-        sm_end = 1;
-    }
 
-    if (rc != 0 || sm_end) {
-        ble_l2cap_sm_proc_remove(proc, prev);
+        if (rc != 0 || sm_end) {
+            ble_l2cap_sm_proc_remove(proc, prev);
+        }
+    } else {
+        rc = BLE_HS_ENOENT;
     }
 
     ble_hs_unlock();
@@ -1331,14 +1309,15 @@ ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
     /* a successful ending of the link */
     if (rc == 0) {
         if (sm_end) {
-            /* TODO put error code here */
             ble_l2cap_sm_gap_event(proc, 0, 1);
             ble_l2cap_sm_key_exchange_events(proc);
             ble_l2cap_sm_proc_free(proc);
         }
     } else {
-        rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
+        ble_l2cap_sm_gap_event(proc, sm_status, 0);
+        ble_l2cap_sm_proc_free(proc);
     }
+
     return rc;
 }
 
@@ -1400,14 +1379,20 @@ ble_l2cap_sm_rx_pair_req(uint16_t conn_handle, uint8_t op,
         }
     }
 
+    if (rc != 0) {
+        ble_l2cap_sm_pair_fail_tx(proc->conn_handle, sm_status);
+    }
+
     ble_hs_unlock();
 
-    /* This has to be done after the unlock */
-    if (passkey_action != BLE_GAP_PKACT_NONE) {
-        ble_gap_passkey_event(proc->conn_handle,sm_status, passkey_action);
+    if (rc == 0) {
+        if (passkey_action != BLE_GAP_PKACT_NONE) {
+            ble_gap_passkey_event(conn_handle, sm_status, passkey_action);
+        }
+    } else {
+        ble_l2cap_sm_proc_free(proc);
     }
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 0, 1);
     return rc;
 }
 
@@ -1443,16 +1428,19 @@ ble_l2cap_sm_rx_pair_rsp(uint16_t conn_handle, uint8_t op,
                                           &passkey_action);
         if (rc != 0) {
             ble_l2cap_sm_proc_remove(proc, prev);
+            ble_l2cap_sm_pair_fail_tx(conn_handle, sm_status);
         }
     }
+
     ble_hs_unlock();
 
-    /* The GAP callback can only be executed after the unlock. */
-    if (passkey_action != BLE_GAP_PKACT_NONE) {
-        ble_gap_passkey_event(proc->conn_handle,sm_status, passkey_action);
+    if (rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    } else if (passkey_action != BLE_GAP_PKACT_NONE) {
+        ble_gap_passkey_event(conn_handle, sm_status, passkey_action);
     }
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
     return rc;
 }
 
@@ -1482,11 +1470,16 @@ ble_l2cap_sm_rx_pair_confirm(uint16_t conn_handle, uint8_t op,
         rc = ble_l2cap_sm_confirm_handle(proc, &cmd, &sm_status);
         if (rc != 0) {
             ble_l2cap_sm_proc_remove(proc, prev);
+            ble_l2cap_sm_pair_fail_tx(conn_handle, sm_status);
         }
     }
     ble_hs_unlock();
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
+    if (rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    }
+
     return rc;
 }
 
@@ -1518,11 +1511,16 @@ ble_l2cap_sm_rx_pair_random(uint16_t conn_handle, uint8_t op,
         rc = ble_l2cap_sm_random_handle(proc, &cmd, &sm_status);
         if (rc != 0) {
             ble_l2cap_sm_proc_remove(proc, prev);
+            ble_l2cap_sm_pair_fail_tx(conn_handle, sm_status);
         }
     }
     ble_hs_unlock();
 
-    rc = ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
+    if (rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    }
+
     return rc;
 }
 
@@ -1552,9 +1550,14 @@ ble_l2cap_sm_rx_pair_fail(uint16_t conn_handle, uint8_t op,
     }
     ble_hs_unlock();
 
-    rc = ble_l2cap_sm_process_status(proc, BLE_HS_SM_THEM_ERR(cmd.reason),
-                                     0, 1, 0);
-    return rc;
+    if (proc == NULL) {
+        return BLE_HS_ENOENT;
+    }
+
+    ble_l2cap_sm_gap_event(proc, BLE_HS_SM_THEM_ERR(cmd.reason), 0);
+    ble_l2cap_sm_proc_free(proc);
+
+    return 0;
 }
 
 static int
@@ -1666,7 +1669,10 @@ ble_l2cap_sm_rx_lt_key_req(struct hci_le_lt_key_req *evt)
             rc = ble_l2cap_sm_lt_key_req_ltk_handle(evt);
         }
     } else if (proc != NULL) {
-        rc = ble_l2cap_sm_process_status(proc, rc, 0, 1, 0);
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
+    } else {
+        rc = BLE_HS_ENOENT;
     }
 
     return rc;
@@ -1707,12 +1713,10 @@ ble_l2cap_sm_rx_encryption_change(struct hci_encrypt_change *evt)
 
     ble_hs_unlock();
 
-    if (proc != NULL && do_key_exchange == 0 && rc == 0) {
+    if (rc != 0 || (proc != NULL && do_key_exchange == 0)) {
         /* The pairing procedure is now complete. */
         ble_l2cap_sm_gap_event(proc, BLE_HS_HCI_ERR(evt->status), enc_enabled);
         ble_l2cap_sm_proc_free(proc);
-    } else if (rc) {
-        ble_l2cap_sm_process_status(proc, rc, sm_status, 1, 1);
     }
 }
 
@@ -1960,12 +1964,14 @@ ble_l2cap_sm_set_tk(uint16_t conn_handle, struct passkey_action *pkey)
 set_tk_return:
     if (proc != NULL && rc != 0) {
         ble_l2cap_sm_proc_remove(proc, prev);
+        ble_l2cap_sm_pair_fail_tx(conn_handle, sm_error);
     }
 
     ble_hs_unlock();
 
-    if (rc != 0) {
-        rc = ble_l2cap_sm_process_status(proc, rc, sm_error, 1, 1);
+    if (proc != NULL && rc != 0) {
+        ble_l2cap_sm_gap_event(proc, rc, 0);
+        ble_l2cap_sm_proc_free(proc);
     }
 
     return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e76defb0/net/nimble/host/src/test/ble_l2cap_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_sm_test.c b/net/nimble/host/src/test/ble_l2cap_sm_test.c
index dd22a73..22077c1 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -66,14 +66,13 @@ ble_l2cap_sm_test_util_conn_cb(int event, int status,
                                struct ble_gap_conn_ctxt *ctxt, void *arg)
 {
     struct ble_l2cap_sm_test_ltk_info *ltk_info;
-
-    ble_l2cap_sm_test_gap_event = event;
-    ble_l2cap_sm_test_gap_status = status;
+    int rc;
 
     switch (event) {
     case BLE_GAP_EVENT_SECURITY:
         ble_l2cap_sm_test_sec_state = ctxt->desc->sec_state;
-        return 0;
+        rc = 0;
+        break;
 
     case BLE_GAP_EVENT_LTK_REQUEST:
         ltk_info = arg;
@@ -88,19 +87,26 @@ ble_l2cap_sm_test_util_conn_cb(int event, int status,
 
         ble_l2cap_sm_test_ltk_params = *ctxt->ltk_params;
         if (ltk_info == NULL) {
-            return -1;
+            rc = -1;
         } else {
-            return 0;
+            rc = 0;
         }
+        break;
 
     default:
         return 0;
     }
+
+    ble_l2cap_sm_test_gap_event = event;
+    ble_l2cap_sm_test_gap_status = status;
+
+    return rc;
 }
 
 static void
 ble_l2cap_sm_test_util_rx_pair_cmd(struct ble_hs_conn *conn, uint8_t op,
-                                   struct ble_l2cap_sm_pair_cmd *cmd)
+                                   struct ble_l2cap_sm_pair_cmd *cmd,
+                                   int rx_status)
 {
     struct hci_data_hdr hci_hdr;
     struct os_mbuf *om;
@@ -125,21 +131,25 @@ ble_l2cap_sm_test_util_rx_pair_cmd(struct ble_hs_conn *conn, uint8_t op,
 
     rc = ble_hs_test_util_l2cap_rx_first_frag(conn, BLE_L2CAP_CID_SM, &hci_hdr,
                                               om);
-    TEST_ASSERT_FATAL(rc == 0);
+    TEST_ASSERT(rc == rx_status);
 }
 
 static void
 ble_l2cap_sm_test_util_rx_pair_req(struct ble_hs_conn *conn,
-                                   struct ble_l2cap_sm_pair_cmd *req)
+                                   struct ble_l2cap_sm_pair_cmd *req,
+                                   int rx_status)
 {
-    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_REQ, req);
+    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_REQ, req,
+                                       rx_status);
 }
 
 static void
 ble_l2cap_sm_test_util_rx_pair_rsp(struct ble_hs_conn *conn,
-                                   struct ble_l2cap_sm_pair_cmd *rsp)
+                                   struct ble_l2cap_sm_pair_cmd *rsp,
+                                   int rx_status)
 {
-    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_RSP, rsp);
+    ble_l2cap_sm_test_util_rx_pair_cmd(conn, BLE_L2CAP_SM_OP_PAIR_RSP, rsp,
+                                       rx_status);
 }
 
 static void
@@ -392,105 +402,217 @@ ble_l2cap_sm_test_util_verify_tx_start_enc(uint16_t conn_handle,
  *****************************************************************************/
 
 static void
-ble_l2cap_sm_test_util_peer_lgcy_good(
+ble_l2cap_sm_test_util_peer_fail_inval(
+    int we_are_master,
     uint8_t *init_addr,
     uint8_t *rsp_addr,
     struct ble_l2cap_sm_pair_cmd *pair_req,
-    struct ble_l2cap_sm_pair_cmd *pair_rsp,
-    struct ble_l2cap_sm_pair_confirm *confirm_req,
-    struct ble_l2cap_sm_pair_confirm *confirm_rsp,
-    struct ble_l2cap_sm_pair_random *random_req,
-    struct ble_l2cap_sm_pair_random *random_rsp,
-    int pair_alg,
-    uint8_t *tk,
-    uint8_t *stk,
-    uint64_t r,
-    uint16_t ediv)
+    struct ble_l2cap_sm_pair_fail *pair_fail)
 {
     struct ble_hs_conn *conn;
 
     ble_l2cap_sm_test_util_init();
     ble_hs_test_util_set_public_addr(rsp_addr);
-    ble_l2cap_sm_dbg_set_next_pair_rand(random_rsp->value);
 
     conn = ble_hs_test_util_create_conn(2, init_addr,
                                         ble_l2cap_sm_test_util_conn_cb,
                                         NULL);
 
-    /* Peer is the initiator so we must be the slave. */
-    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+    if (!we_are_master) {
+        conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+    }
 
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req);
+    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req,
+                                       BLE_HS_SM_US_ERR(pair_fail->reason));
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
-    /* Ensure we sent the expected pair response. */
+    /* Ensure we sent the expected pair fail. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_rsp(pair_rsp);
+    ble_l2cap_sm_test_util_verify_tx_pair_fail(pair_fail);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
-    /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_req);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Verify that security callback was not executed. */
+    TEST_ASSERT(ble_l2cap_sm_test_gap_event == -1);
+    TEST_ASSERT(ble_l2cap_sm_test_gap_status == -1);
 
-    /* Ensure we sent the expected pair confirm. */
-    ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_rsp);
+    /* Verify that connection has correct security state. */
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    TEST_ASSERT(!conn->bhc_sec_state.authenticated);
+}
 
-    /* Receive a pair random from the peer. */
-    ble_l2cap_sm_test_util_rx_random(conn, random_req, 0);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+TEST_CASE(ble_l2cap_sm_test_case_peer_fail_inval)
+{
+    /* Invalid role detected before other arguments. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        1,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x14,
+            .oob_data_flag = 0,
+            .authreq = 0x12,
+            .max_enc_key_size = 20,
+            .init_key_dist = 0x0b,
+            .resp_key_dist = 0x11,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_CMD_NOT_SUPP,
+        } })
+    );
 
-    /* Ensure we sent the expected pair random. */
-    ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_random(random_rsp);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Invalid IO capabiltiies. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x14,
+            .oob_data_flag = 0,
+            .authreq = 0x05,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Receive a long term key request from the controller. */
-    ble_l2cap_sm_test_util_set_lt_key_req_reply_ack(0, 2);
-    ble_l2cap_sm_test_util_rx_lt_key_req(2, r, ediv);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Invalid OOB flag. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 2,
+            .authreq = 0x05,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Ensure we sent the expected long term key request reply command. */
-    ble_l2cap_sm_test_util_verify_tx_lt_key_req_reply(2, stk);
-    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+    /* Invalid authreq - reserved bonding flag. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x2,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Receive an encryption changed event. */
-    ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
+    /* Invalid authreq - reserved other flag. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x20,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Pairing should now be complete. */
-    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+    /* Invalid key size - too small. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 6,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Verify that security callback was executed. */
-    TEST_ASSERT(ble_l2cap_sm_test_gap_event == BLE_GAP_EVENT_SECURITY);
-    TEST_ASSERT(ble_l2cap_sm_test_gap_status == 0);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.pair_alg == pair_alg);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled);
-    TEST_ASSERT(!ble_l2cap_sm_test_sec_state.authenticated);
+    /* Invalid key size - too large. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 17,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 
-    /* Verify that connection has correct security state. */
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.pair_alg ==
-                conn->bhc_sec_state.pair_alg);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled ==
-                conn->bhc_sec_state.enc_enabled);
-    TEST_ASSERT(ble_l2cap_sm_test_sec_state.authenticated ==
-                conn->bhc_sec_state.authenticated);
+    /* Invalid init key dist. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x10,
+            .resp_key_dist = 0x07,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
+
+    /* Invalid resp key dist. */
+    ble_l2cap_sm_test_util_peer_fail_inval(
+        0,
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 0x04,
+            .oob_data_flag = 0,
+            .authreq = 0x5,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x10,
+        } }),
+        ((struct ble_l2cap_sm_pair_fail[1]) { {
+            .reason = BLE_L2CAP_SM_ERR_INVAL,
+        } })
+    );
 }
 
 static void
-ble_l2cap_sm_test_util_peer_lgcy_fail(
+ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
     uint8_t *init_addr,
     uint8_t *rsp_addr,
     struct ble_l2cap_sm_pair_cmd *pair_req,
@@ -517,7 +639,7 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req);
+    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req, 0);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair response. */
@@ -563,65 +685,9 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
                 conn->bhc_sec_state.authenticated);
 }
 
-TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
-{
-    ble_l2cap_sm_test_util_peer_lgcy_good(
-        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
-        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
-        ((struct ble_l2cap_sm_pair_cmd[1]) { {
-            .io_cap = 0x04,
-            .oob_data_flag = 0,
-            .authreq = 0x05,
-            .max_enc_key_size = 16,
-            .init_key_dist = 0x07,
-            .resp_key_dist = 0x07,
-        } }),
-        ((struct ble_l2cap_sm_pair_cmd[1]) { {
-            .io_cap = 3,
-            .oob_data_flag = 0,
-            .authreq = 0,
-            .max_enc_key_size = 16,
-            .init_key_dist = 0,
-            .resp_key_dist = 0,
-        } }),
-        ((struct ble_l2cap_sm_pair_confirm[1]) { {
-            .value = {
-                0x0a, 0xac, 0xa2, 0xae, 0xa6, 0x98, 0xdc, 0x6d,
-                0x65, 0x84, 0x11, 0x69, 0x47, 0x36, 0x8d, 0xa0,
-            },
-        } }),
-        ((struct ble_l2cap_sm_pair_confirm[1]) { {
-            .value = {
-                0x45, 0xd2, 0x2c, 0x38, 0xd8, 0x91, 0x4f, 0x19,
-                0xa2, 0xd4, 0xfc, 0x7d, 0xad, 0x37, 0x79, 0xe0
-            },
-        } }),
-        ((struct ble_l2cap_sm_pair_random[1]) { {
-            .value = {
-                0x2b, 0x3b, 0x69, 0xe4, 0xef, 0xab, 0xcc, 0x48,
-                0x78, 0x20, 0x1a, 0x54, 0x7a, 0x91, 0x5d, 0xfb,
-            },
-        } }),
-        ((struct ble_l2cap_sm_pair_random[1]) { {
-            .value = {
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            },
-        } }),
-        BLE_L2CAP_SM_PAIR_ALG_JW,
-        NULL,
-        ((uint8_t[16]) {
-            0xa4, 0x8e, 0x51, 0x0d, 0x33, 0xe7, 0x8f, 0x38,
-            0x45, 0xf0, 0x67, 0xc3, 0xd4, 0x05, 0xb3, 0xe6,
-        }),
-        0,
-        0
-    );
-}
-
-TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail)
+TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail_confirm)
 {
-    ble_l2cap_sm_test_util_peer_lgcy_fail(
+    ble_l2cap_sm_test_util_peer_lgcy_fail_confirm(
         ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
         ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
         ((struct ble_l2cap_sm_pair_cmd[1]) { {
@@ -670,12 +736,8 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_fail)
     );
 }
 
-/*****************************************************************************
- * $us                                                                       *
- *****************************************************************************/
-
 static void
-ble_l2cap_sm_test_util_us_lgcy_good(
+ble_l2cap_sm_test_util_peer_lgcy_good(
     uint8_t *init_addr,
     uint8_t *rsp_addr,
     struct ble_l2cap_sm_pair_cmd *pair_req,
@@ -691,61 +753,62 @@ ble_l2cap_sm_test_util_us_lgcy_good(
     uint16_t ediv)
 {
     struct ble_hs_conn *conn;
-    int rc;
 
     ble_l2cap_sm_test_util_init();
-    ble_hs_test_util_set_public_addr(init_addr);
-    ble_l2cap_sm_dbg_set_next_pair_rand(random_req->value);
-    ble_l2cap_sm_dbg_set_next_ediv(ediv);
-    ble_l2cap_sm_dbg_set_next_start_rand(r);
+    ble_hs_test_util_set_public_addr(rsp_addr);
+    ble_l2cap_sm_dbg_set_next_pair_rand(random_rsp->value);
 
-    conn = ble_hs_test_util_create_conn(2, rsp_addr,
+    conn = ble_hs_test_util_create_conn(2, init_addr,
                                         ble_l2cap_sm_test_util_conn_cb,
                                         NULL);
 
+    /* Peer is the initiator so we must be the slave. */
+    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
-    /* Initiate the pairing procedure. */
-    rc = ble_hs_test_util_security_initiate(2, 0);
-    TEST_ASSERT_FATAL(rc == 0);
+    /* Receive a pair request from the peer. */
+    ble_l2cap_sm_test_util_rx_pair_req(conn, pair_req, 0);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Ensure we sent the expected pair request. */
+    /* Ensure we sent the expected pair response. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_req(pair_req);
+    ble_l2cap_sm_test_util_verify_tx_pair_rsp(pair_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a pair response from the peer. */
-    ble_l2cap_sm_test_util_rx_pair_rsp(conn, pair_rsp);
+    /* Receive a pair confirm from the peer. */
+    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_req);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair confirm. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_req);
+    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a pair confirm from the peer. */
-    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_rsp);
+    /* Receive a pair random from the peer. */
+    ble_l2cap_sm_test_util_rx_random(conn, random_req, 0);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
     /* Ensure we sent the expected pair random. */
     ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_pair_random(random_req);
+    ble_l2cap_sm_test_util_verify_tx_pair_random(random_rsp);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Receive a pair random from the peer. */
-    ble_l2cap_sm_test_util_rx_random(conn, random_rsp, 0);
+    /* Receive a long term key request from the controller. */
+    ble_l2cap_sm_test_util_set_lt_key_req_reply_ack(0, 2);
+    ble_l2cap_sm_test_util_rx_lt_key_req(2, r, ediv);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
-    /* Ensure we sent the expected start encryption command. */
-    ble_hs_test_util_tx_all();
-    ble_l2cap_sm_test_util_verify_tx_start_enc(2, r, ediv, stk);
+    /* Ensure we sent the expected long term key request reply command. */
+    ble_l2cap_sm_test_util_verify_tx_lt_key_req_reply(2, stk);
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
 
@@ -771,18 +834,18 @@ ble_l2cap_sm_test_util_us_lgcy_good(
                 conn->bhc_sec_state.authenticated);
 }
 
-TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
+TEST_CASE(ble_l2cap_sm_test_case_peer_lgcy_jw_good)
 {
-    ble_l2cap_sm_test_util_us_lgcy_good(
-        ((uint8_t[]){0x06, 0x05, 0x04, 0x03, 0x02, 0x01}),
-        ((uint8_t[]){0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a}),
+    ble_l2cap_sm_test_util_peer_lgcy_good(
+        ((uint8_t[]){0xe1, 0xfc, 0xda, 0xf4, 0xb7, 0x6c}),
+        ((uint8_t[]){0x03, 0x02, 0x01, 0x50, 0x13, 0x00}),
         ((struct ble_l2cap_sm_pair_cmd[1]) { {
-            .io_cap = 3,
+            .io_cap = 0x04,
             .oob_data_flag = 0,
-            .authreq = 0,
+            .authreq = 0x05,
             .max_enc_key_size = 16,
-            .init_key_dist = 0,
-            .resp_key_dist = 0,
+            .init_key_dist = 0x07,
+            .resp_key_dist = 0x07,
         } }),
         ((struct ble_l2cap_sm_pair_cmd[1]) { {
             .io_cap = 3,
@@ -794,20 +857,20 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
         } }),
         ((struct ble_l2cap_sm_pair_confirm[1]) { {
             .value = {
-                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
-                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+                0x0a, 0xac, 0xa2, 0xae, 0xa6, 0x98, 0xdc, 0x6d,
+                0x65, 0x84, 0x11, 0x69, 0x47, 0x36, 0x8d, 0xa0,
             },
         } }),
         ((struct ble_l2cap_sm_pair_confirm[1]) { {
             .value = {
-                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
-                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+                0x45, 0xd2, 0x2c, 0x38, 0xd8, 0x91, 0x4f, 0x19,
+                0xa2, 0xd4, 0xfc, 0x7d, 0xad, 0x37, 0x79, 0xe0
             },
         } }),
         ((struct ble_l2cap_sm_pair_random[1]) { {
             .value = {
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x2b, 0x3b, 0x69, 0xe4, 0xef, 0xab, 0xcc, 0x48,
+                0x78, 0x20, 0x1a, 0x54, 0x7a, 0x91, 0x5d, 0xfb,
             },
         } }),
         ((struct ble_l2cap_sm_pair_random[1]) { {
@@ -819,8 +882,8 @@ TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
         BLE_L2CAP_SM_PAIR_ALG_JW,
         NULL,
         ((uint8_t[16]) {
-            0x2e, 0x2b, 0x34, 0xca, 0x59, 0xfa, 0x4c, 0x88,
-            0x3b, 0x2c, 0x8a, 0xef, 0xd4, 0x4b, 0xe9, 0x66,
+            0xa4, 0x8e, 0x51, 0x0d, 0x33, 0xe7, 0x8f, 0x38,
+            0x45, 0xf0, 0x67, 0xc3, 0xd4, 0x05, 0xb3, 0xe6,
         }),
         0,
         0
@@ -946,10 +1009,168 @@ TEST_CASE(ble_l2cap_sm_test_case_peer_bonding_bad)
     ble_l2cap_sm_test_util_peer_bonding_bad(54325, 65437);
 }
 
+/*****************************************************************************
+ * $us                                                                       *
+ *****************************************************************************/
+
+static void
+ble_l2cap_sm_test_util_us_lgcy_good(
+    uint8_t *init_addr,
+    uint8_t *rsp_addr,
+    struct ble_l2cap_sm_pair_cmd *pair_req,
+    struct ble_l2cap_sm_pair_cmd *pair_rsp,
+    struct ble_l2cap_sm_pair_confirm *confirm_req,
+    struct ble_l2cap_sm_pair_confirm *confirm_rsp,
+    struct ble_l2cap_sm_pair_random *random_req,
+    struct ble_l2cap_sm_pair_random *random_rsp,
+    int pair_alg,
+    uint8_t *tk,
+    uint8_t *stk,
+    uint64_t r,
+    uint16_t ediv)
+{
+    struct ble_hs_conn *conn;
+    int rc;
+
+    ble_l2cap_sm_test_util_init();
+    ble_hs_test_util_set_public_addr(init_addr);
+    ble_l2cap_sm_dbg_set_next_pair_rand(random_req->value);
+    ble_l2cap_sm_dbg_set_next_ediv(ediv);
+    ble_l2cap_sm_dbg_set_next_start_rand(r);
+
+    conn = ble_hs_test_util_create_conn(2, rsp_addr,
+                                        ble_l2cap_sm_test_util_conn_cb,
+                                        NULL);
+
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+    /* Initiate the pairing procedure. */
+    rc = ble_hs_test_util_security_initiate(2, 0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Ensure we sent the expected pair request. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_pair_req(pair_req);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive a pair response from the peer. */
+    ble_l2cap_sm_test_util_rx_pair_rsp(conn, pair_rsp, 0);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Ensure we sent the expected pair confirm. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_pair_confirm(confirm_req);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive a pair confirm from the peer. */
+    ble_l2cap_sm_test_util_rx_confirm(conn, confirm_rsp);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Ensure we sent the expected pair random. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_pair_random(random_req);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive a pair random from the peer. */
+    ble_l2cap_sm_test_util_rx_random(conn, random_rsp, 0);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Ensure we sent the expected start encryption command. */
+    ble_hs_test_util_tx_all();
+    ble_l2cap_sm_test_util_verify_tx_start_enc(2, r, ediv, stk);
+    TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 1);
+
+    /* Receive an encryption changed event. */
+    ble_l2cap_sm_test_util_rx_enc_change(2, 0, 1);
+
+    /* Pairing should now be complete. */
+    TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
+
+    /* Verify that security callback was executed. */
+    TEST_ASSERT(ble_l2cap_sm_test_gap_event == BLE_GAP_EVENT_SECURITY);
+    TEST_ASSERT(ble_l2cap_sm_test_gap_status == 0);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.pair_alg == pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled);
+    TEST_ASSERT(!ble_l2cap_sm_test_sec_state.authenticated);
+
+    /* Verify that connection has correct security state. */
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.pair_alg ==
+                conn->bhc_sec_state.pair_alg);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.enc_enabled ==
+                conn->bhc_sec_state.enc_enabled);
+    TEST_ASSERT(ble_l2cap_sm_test_sec_state.authenticated ==
+                conn->bhc_sec_state.authenticated);
+}
+
+TEST_CASE(ble_l2cap_sm_test_case_us_lgcy_jw_good)
+{
+    ble_l2cap_sm_test_util_us_lgcy_good(
+        ((uint8_t[]){0x06, 0x05, 0x04, 0x03, 0x02, 0x01}),
+        ((uint8_t[]){0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a}),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 3,
+            .oob_data_flag = 0,
+            .authreq = 0,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0,
+            .resp_key_dist = 0,
+        } }),
+        ((struct ble_l2cap_sm_pair_cmd[1]) { {
+            .io_cap = 3,
+            .oob_data_flag = 0,
+            .authreq = 0,
+            .max_enc_key_size = 16,
+            .init_key_dist = 0,
+            .resp_key_dist = 0,
+        } }),
+        ((struct ble_l2cap_sm_pair_confirm[1]) { {
+            .value = {
+                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+            },
+        } }),
+        ((struct ble_l2cap_sm_pair_confirm[1]) { {
+            .value = {
+                0x04, 0x4e, 0xaf, 0xce, 0x30, 0x79, 0x2c, 0x9e,
+                0xa2, 0xeb, 0x53, 0x6a, 0xdf, 0xf7, 0x99, 0xb2,
+            },
+        } }),
+        ((struct ble_l2cap_sm_pair_random[1]) { {
+            .value = {
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            },
+        } }),
+        ((struct ble_l2cap_sm_pair_random[1]) { {
+            .value = {
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            },
+        } }),
+        BLE_L2CAP_SM_PAIR_ALG_JW,
+        NULL,
+        ((uint8_t[16]) {
+            0x2e, 0x2b, 0x34, 0xca, 0x59, 0xfa, 0x4c, 0x88,
+            0x3b, 0x2c, 0x8a, 0xef, 0xd4, 0x4b, 0xe9, 0x66,
+        }),
+        0,
+        0
+    );
+}
+
 TEST_SUITE(ble_l2cap_sm_test_suite)
 {
+    ble_l2cap_sm_test_case_peer_fail_inval();
+    ble_l2cap_sm_test_case_peer_lgcy_fail_confirm();
     ble_l2cap_sm_test_case_peer_lgcy_jw_good();
-    ble_l2cap_sm_test_case_peer_lgcy_fail();
     ble_l2cap_sm_test_case_us_lgcy_jw_good();
     ble_l2cap_sm_test_case_peer_bonding_good();
     ble_l2cap_sm_test_case_peer_bonding_bad();
@@ -962,6 +1183,7 @@ ble_l2cap_sm_test_all(void)
 #if !NIMBLE_OPT_SM
     return 0;
 #else
+    tu_config.tc_system_assert=1;
     ble_l2cap_sm_test_suite();
 
     return tu_any_failed;



[2/4] incubator-mynewt-core git commit: BLE host - Validate pair req/rsp at rx time.

Posted by cc...@apache.org.
BLE host - Validate pair req/rsp at rx time.


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

Branch: refs/heads/develop
Commit: 7a3a9464052c59ddbc4919a881961613564c617c
Parents: ee13afe
Author: Christopher Collins <cc...@apache.org>
Authored: Sat May 7 12:58:55 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sat May 7 13:00:59 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_l2cap.h |  29 ++++++-
 net/nimble/host/src/ble_l2cap_sm.c       | 119 +++++++++++++-------------
 net/nimble/host/src/ble_l2cap_sm_cmd.c   |  33 +++++++
 net/nimble/host/src/ble_l2cap_sm_priv.h  |   8 +-
 net/nimble/include/nimble/ble.h          |   3 +
 5 files changed, 120 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7a3a9464/net/nimble/host/include/host/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_l2cap.h b/net/nimble/host/include/host/ble_l2cap.h
index da26025..26666b2 100644
--- a/net/nimble/host/include/host/ble_l2cap.h
+++ b/net/nimble/host/include/host/ble_l2cap.h
@@ -86,10 +86,31 @@ struct ble_hs_conn;
 #define BLE_L2CAP_SM_PAIR_ALG_PASSKEY       1
 #define BLE_L2CAP_SM_PAIR_ALG_OOB           2
 
-#define BLE_L2CAP_SM_KEY_DIST_ENC           0x01
-#define BLE_L2CAP_SM_KEY_DIST_ID            0x02
-#define BLE_L2CAP_SM_KEY_DIST_SIGN          0x04
-#define BLE_L2CAP_SM_KEY_DIST_LINK          0x08
+#define BLE_L2CAP_SM_PAIR_KEY_DIST_ENC      0x01
+#define BLE_L2CAP_SM_PAIR_KEY_DIST_ID       0x02
+#define BLE_L2CAP_SM_PAIR_KEY_DIST_SIGN     0x04
+#define BLE_L2CAP_SM_PAIR_KEY_DIST_LINK     0x08
+#define BLE_L2CAP_SM_PAIR_KEY_DIST_RESERVED 0xf0
+
+#define BLE_L2CAP_SM_IO_CAP_DISP_ONLY       0x00
+#define BLE_L2CAP_SM_IO_CAP_DISP_YES_NO     0x01
+#define BLE_L2CAP_SM_IO_CAP_KEYBOARD_ONLY   0x02
+#define BLE_L2CAP_SM_IO_CAP_NO_IO           0x03
+#define BLE_L2CAP_SM_IO_CAP_KEYBOARD_DISP   0x04
+#define BLE_L2CAP_SM_IO_CAP_RESERVED        0x05
+
+#define BLE_L2CAP_SM_PAIR_OOB_NO            0x00
+#define BLE_L2CAP_SM_PAIR_OOB_YES           0x01
+#define BLE_L2CAP_SM_PAIR_OOB_RESERVED      0x02
+
+#define BLE_L2CAP_SM_PAIR_AUTHREQ_BOND      0x01
+#define BLE_L2CAP_SM_PAIR_AUTHREQ_MITM      0x04
+#define BLE_L2CAP_SM_PAIR_AUTHREQ_SC        0x08
+#define BLE_L2CAP_SM_PAIR_AUTHREQ_KEYPRESS  0x10
+#define BLE_L2CAP_SM_PAIR_AUTHREQ_RESERVED  0xe2
+
+#define BLE_L2CAP_SM_PAIR_KEY_SZ_MIN        7
+#define BLE_L2CAP_SM_PAIR_KEY_SZ_MAX        16
 
 typedef void ble_l2cap_sig_update_fn(int status, void *arg);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7a3a9464/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 ff620ec..1b2eea0 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -209,32 +209,6 @@ ble_l2cap_sm_dbg_num_procs(void)
  * $misc                                                                     *
  *****************************************************************************/
 
-static void
-ble_l2cap_build_rx_key_exchange_state(struct ble_l2cap_sm_proc *proc)
-{
-    uint8_t rx_key_dist;
-
-    /* if we are intiating we are waiting for the responders keys */
-    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-        rx_key_dist = proc->pair_rsp.resp_key_dist;
-    } else {
-        rx_key_dist = proc->pair_rsp.init_key_dist;
-    }
-    proc->rx_key_flags = 0;
-
-    if (rx_key_dist & KEY_DIST_ENC_KEY) {
-        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_ENC_INFO |
-                              BLE_L2CAP_SM_KE_F_MASTER_IDEN;
-    }
-    if (rx_key_dist & KEY_DIST_ID_KEY) {
-        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_IDEN_INFO |
-                              BLE_L2CAP_SM_KE_F_ADDR_INFO;
-    }
-    if (rx_key_dist & KEY_DIST_SIGN) {
-        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_SIGN_INFO;
-    }
-}
-
 static int
 ble_l2cap_sm_gen_pair_rand(uint8_t *pair_rand)
 {
@@ -415,7 +389,6 @@ ble_l2cap_sm_key_exchange_events(struct ble_l2cap_sm_proc *proc) {
 
     proc->our_keys.is_ours = 1;
     proc->peer_keys.is_ours = 0;
-    /* TODO */
     ble_gap_key_exchange_event(proc->conn_handle, &proc->our_keys);
     ble_gap_key_exchange_event(proc->conn_handle, &proc->peer_keys);
 }
@@ -809,26 +782,18 @@ ble_l2cap_sm_passkey_action(struct ble_l2cap_sm_proc *proc)
 {
     int action;
 
-    /* If both OOB set, then its OOB */
     if (proc->pair_req.oob_data_flag && proc->pair_rsp.oob_data_flag) {
         action = BLE_GAP_PKACT_OOB;
-    }
-    /* If neither MITM is set, then its just works */
-    else if (!((proc->pair_req.authreq | proc->pair_rsp.authreq) & 0x04)) {
-        action = BLE_GAP_PKACT_NONE;
-    }
-    /* What to do if this in in error */
-    /* XXX: Check this during pairing tx/rx. */
-    else if (proc->pair_req.io_cap >= 5 || proc->pair_rsp.io_cap >= 5) {
+    } else if (!(proc->pair_req.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_MITM) ||
+               !(proc->pair_rsp.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_MITM)) {
+
         action = BLE_GAP_PKACT_NONE;
-    }
-    else if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+    } else if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
         action = initiator_pkact[proc->pair_req.io_cap][proc->pair_rsp.io_cap];
     } else {
         action = responder_pkact[proc->pair_req.io_cap][proc->pair_rsp.io_cap];
     }
 
-    /* set some state for the application */
     switch (action) {
     case BLE_GAP_PKACT_NONE:
         proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_JW;
@@ -844,7 +809,12 @@ ble_l2cap_sm_passkey_action(struct ble_l2cap_sm_proc *proc)
         proc->pair_alg = BLE_L2CAP_SM_PAIR_ALG_PASSKEY;
         proc->flags |= BLE_L2CAP_SM_PROC_F_AUTHENTICATED;
         break;
+
+    default:
+        BLE_HS_DBG_ASSERT(0);
+        break;
     }
+
     return action;
 }
 
@@ -986,8 +956,13 @@ ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
         cmd.init_key_dist = ble_hs_cfg.sm_our_key_dist;
         cmd.resp_key_dist = ble_hs_cfg.sm_their_key_dist;
     } else {
-        cmd.init_key_dist = ble_hs_cfg.sm_their_key_dist;
-        cmd.resp_key_dist = ble_hs_cfg.sm_our_key_dist;
+        /* The response's key distribution flags field is the intersection of
+         * the peer's preferences and our capabilities.
+         */
+        cmd.init_key_dist = proc->pair_req.init_key_dist &
+                            ble_hs_cfg.sm_their_key_dist;
+        cmd.resp_key_dist = proc->pair_req.resp_key_dist &
+                            ble_hs_cfg.sm_our_key_dist;
     }
 
     rc = ble_l2cap_sm_pair_cmd_tx(proc->conn_handle, is_req, &cmd);
@@ -1010,21 +985,38 @@ ble_l2cap_sm_pair_go(struct ble_l2cap_sm_proc *proc)
 
     return 0;
 }
-static int
+
+static void
 ble_l2cap_sm_check_key_exchange(struct ble_l2cap_sm_proc *proc)
 {
-    if ((proc->pair_req.authreq & proc->pair_rsp.authreq & 0x3) == 1) {
-        /* The pair response defines what shall be exchanged. */
-        if (proc->pair_rsp.init_key_dist | proc->pair_rsp.resp_key_dist) {
-            proc->flags |= BLE_L2CAP_SM_PROC_F_KEY_EXCHANGE;
-        }
+    uint8_t rx_key_dist;
+
+    if (proc->pair_req.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_BOND &&
+        proc->pair_rsp.authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_BOND &&
+        proc->pair_rsp.init_key_dist                            &&
+        proc->pair_rsp.resp_key_dist) {
+
+        proc->flags |= BLE_L2CAP_SM_PROC_F_KEY_EXCHANGE;
     }
 
-    /* Build the key exchange data. */
-    ble_l2cap_build_rx_key_exchange_state(proc);
+    if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
+        rx_key_dist = proc->pair_rsp.resp_key_dist;
+    } else {
+        rx_key_dist = proc->pair_rsp.init_key_dist;
+    }
 
-    /* XXX: Check for valid combinations. */
-    return 0;
+    proc->rx_key_flags = 0;
+    if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ENC) {
+        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_ENC_INFO |
+                              BLE_L2CAP_SM_KE_F_MASTER_IDEN;
+    }
+    if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ID) {
+        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_IDEN_INFO |
+                              BLE_L2CAP_SM_KE_F_ADDR_INFO;
+    }
+    if (rx_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_SIGN) {
+        proc->rx_key_flags |= BLE_L2CAP_SM_KE_F_SIGN_INFO;
+    }
 }
 
 static int
@@ -1037,6 +1029,11 @@ ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
 
     proc->pair_req = *req;
 
+    if (!ble_l2cap_sm_pair_cmd_is_valid(req)) {
+        *out_sm_status = BLE_L2CAP_SM_ERR_INVAL;
+        return BLE_HS_EBADDATA;
+    }
+
     rc = ble_l2cap_sm_pair_go(proc);
 
     if (rc != 0) {
@@ -1044,12 +1041,7 @@ ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
         return rc;
     }
 
-    rc = ble_l2cap_sm_check_key_exchange(proc);
-    if (rc != 0) {
-        *out_sm_status = BLE_L2CAP_SM_ERR_INVAL;
-        return rc;
-    }
-
+    ble_l2cap_sm_check_key_exchange(proc);
     proc->state = BLE_L2CAP_SM_PROC_STATE_CONFIRM;
 
     /* Get the passkey action for querying the application. */
@@ -1068,11 +1060,12 @@ ble_l2cap_sm_pair_rsp_handle(struct ble_l2cap_sm_proc *proc,
 
     proc->pair_rsp = *rsp;
 
-    rc = ble_l2cap_sm_check_key_exchange(proc);
-    if (rc != 0) {
+    if (!ble_l2cap_sm_pair_cmd_is_valid(rsp)) {
         *out_sm_status = BLE_L2CAP_SM_ERR_INVAL;
-        return rc;
+        return BLE_HS_EBADDATA;
     }
+
+    ble_l2cap_sm_check_key_exchange(proc);
     proc->state = BLE_L2CAP_SM_PROC_STATE_CONFIRM;
 
     /* If there is no passkey action to take, just continue with confirm. */
@@ -1163,7 +1156,7 @@ ble_l2cap_sm_key_exchange_go(struct ble_l2cap_sm_proc *proc,
         our_key_dist = proc->pair_rsp.resp_key_dist;
     }
 
-    if (our_key_dist & BLE_L2CAP_SM_KEY_DIST_ENC) {
+    if (our_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ENC) {
         /* Send encryption information. */
         rc = ble_l2cap_sm_gen_ltk(proc, enc_info.ltk_le);
         if (rc != 0) {
@@ -1370,7 +1363,11 @@ ble_l2cap_sm_rx_pair_req(uint16_t conn_handle, uint8_t op,
                req.max_enc_key_size, req.init_key_dist, req.resp_key_dist);
 
     ble_hs_lock();
+
     /* XXX: Check connection state; reject if not appropriate. */
+    /* XXX: Ensure enough time has passed since the previous failed pairing
+     * attempt.
+     */
     proc = ble_l2cap_sm_proc_find(conn_handle, BLE_L2CAP_SM_PROC_STATE_NONE,
                                   -1, &prev);
     if (proc != NULL) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7a3a9464/net/nimble/host/src/ble_l2cap_sm_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_cmd.c b/net/nimble/host/src/ble_l2cap_sm_cmd.c
index 8f4766d..62149e6 100644
--- a/net/nimble/host/src/ble_l2cap_sm_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sm_cmd.c
@@ -92,6 +92,38 @@ ble_l2cap_sm_pair_cmd_parse(void *payload, int len,
     cmd->resp_key_dist = u8ptr[5];
 }
 
+int
+ble_l2cap_sm_pair_cmd_is_valid(struct ble_l2cap_sm_pair_cmd *cmd)
+{
+    if (cmd->io_cap >= BLE_L2CAP_SM_IO_CAP_RESERVED) {
+        return 0;
+    }
+
+    if (cmd->oob_data_flag >= BLE_L2CAP_SM_PAIR_OOB_RESERVED) {
+        return 0;
+    }
+
+    if (cmd->authreq & BLE_L2CAP_SM_PAIR_AUTHREQ_RESERVED) {
+        return 0;
+    }
+
+    if (cmd->max_enc_key_size < BLE_L2CAP_SM_PAIR_KEY_SZ_MIN ||
+        cmd->max_enc_key_size > BLE_L2CAP_SM_PAIR_KEY_SZ_MAX) {
+
+        return 0;
+    }
+
+    if (cmd->init_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_RESERVED) {
+        return 0;
+    }
+
+    if (cmd->resp_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_RESERVED) {
+        return 0;
+    }
+
+    return 1;
+}
+
 void
 ble_l2cap_sm_pair_cmd_write(void *payload, int len, int is_req,
                             struct ble_l2cap_sm_pair_cmd *cmd)
@@ -124,6 +156,7 @@ ble_l2cap_sm_pair_cmd_tx(uint16_t conn_handle, int is_req,
     }
 
     ble_l2cap_sm_pair_cmd_write(txom->om_data, txom->om_len, is_req, cmd);
+    BLE_HS_DBG_ASSERT(ble_l2cap_sm_pair_cmd_is_valid(cmd));
 
     rc = ble_l2cap_sm_tx(conn_handle, txom);
     txom = NULL;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7a3a9464/net/nimble/host/src/ble_l2cap_sm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm_priv.h b/net/nimble/host/src/ble_l2cap_sm_priv.h
index 2552ace..2e3b98b 100644
--- a/net/nimble/host/src/ble_l2cap_sm_priv.h
+++ b/net/nimble/host/src/ble_l2cap_sm_priv.h
@@ -48,13 +48,6 @@ struct ble_l2cap_sm_pair_cmd {
     uint8_t resp_key_dist;
 };
 
-/* defines for the bitgs in  init_key_dist and resp_key_dist */
-#define KEY_DIST_ENC_KEY    (0x01)
-#define KEY_DIST_ID_KEY     (0x02)
-#define KEY_DIST_SIGN       (0x04)
-#define KEY_DIST_LINK       (0x08)
-#define KEY_DIST_RESERVED   (0xf0)
-
 /**
  * | Parameter                          | Size (octets)     |
  * +------------------------------------+-------------------+
@@ -180,6 +173,7 @@ int ble_l2cap_sm_pair_random_tx(uint16_t conn_handle,
                                 struct ble_l2cap_sm_pair_random *cmd);
 void ble_l2cap_sm_pair_fail_parse(void *payload, int len,
                                   struct ble_l2cap_sm_pair_fail *cmd);
+int ble_l2cap_sm_pair_cmd_is_valid(struct ble_l2cap_sm_pair_cmd *cmd);
 void ble_l2cap_sm_pair_fail_write(void *payload, int len,
                                   struct ble_l2cap_sm_pair_fail *cmd);
 int ble_l2cap_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7a3a9464/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index 9081b8c..c58a095 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -130,6 +130,9 @@ extern uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
 #undef htobe16
 #undef htobe32
 #undef htobe64
+#undef be16toh
+#undef be32toh
+#undef be64toh
 void htole16(void *buf, uint16_t x);
 void htole32(void *buf, uint32_t x);
 void htole64(void *buf, uint64_t x);


[3/4] incubator-mynewt-core git commit: BLE host - Ensure pair-req sender is master.

Posted by cc...@apache.org.
BLE host - Ensure pair-req sender is master.


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

Branch: refs/heads/develop
Commit: 2a6cf9936308255fa76bcba744cd461781628fda
Parents: 7a3a946
Author: Christopher Collins <cc...@apache.org>
Authored: Sat May 7 13:12:58 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sun May 8 21:53:49 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_l2cap_sm.c           | 14 ++++++++++++--
 net/nimble/host/src/test/ble_l2cap_sm_test.c |  6 ++++++
 2 files changed, 18 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2a6cf993/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 1b2eea0..60cbae8 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -1025,17 +1025,27 @@ ble_l2cap_sm_pair_req_handle(struct ble_l2cap_sm_proc *proc,
                              uint8_t *out_sm_status,
                              uint8_t *passkey_action)
 {
+    struct ble_hs_conn *conn;
     int rc;
 
     proc->pair_req = *req;
 
+    conn = ble_hs_conn_find(proc->conn_handle);
+    if (conn == NULL) {
+        *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+        return BLE_HS_ENOTCONN;
+    }
+    if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) {
+        *out_sm_status = BLE_L2CAP_SM_ERR_CMD_NOT_SUPP;
+        return BLE_HS_EROLE;
+    }
+
     if (!ble_l2cap_sm_pair_cmd_is_valid(req)) {
         *out_sm_status = BLE_L2CAP_SM_ERR_INVAL;
-        return BLE_HS_EBADDATA;
+        return BLE_HS_SM_US_ERR(BLE_L2CAP_SM_ERR_INVAL);
     }
 
     rc = ble_l2cap_sm_pair_go(proc);
-
     if (rc != 0) {
         *out_sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
         return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2a6cf993/net/nimble/host/src/test/ble_l2cap_sm_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_sm_test.c b/net/nimble/host/src/test/ble_l2cap_sm_test.c
index 409cfc9..dd22a73 100644
--- a/net/nimble/host/src/test/ble_l2cap_sm_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_sm_test.c
@@ -417,6 +417,9 @@ ble_l2cap_sm_test_util_peer_lgcy_good(
                                         ble_l2cap_sm_test_util_conn_cb,
                                         NULL);
 
+    /* Peer is the initiator so we must be the slave. */
+    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+
     TEST_ASSERT(!conn->bhc_sec_state.enc_enabled);
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
@@ -508,6 +511,9 @@ ble_l2cap_sm_test_util_peer_lgcy_fail(
                                         ble_l2cap_sm_test_util_conn_cb,
                                         NULL);
 
+    /* Peer is the initiator so we must be the slave. */
+    conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
+
     TEST_ASSERT(ble_l2cap_sm_dbg_num_procs() == 0);
 
     /* Receive a pair request from the peer. */