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/06 02:37:27 UTC
[6/6] incubator-mynewt-core git commit: ble host: cancel sm proc when
connection broken.
ble host: cancel sm proc when connection broken.
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/655d0239
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/655d0239
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/655d0239
Branch: refs/heads/develop
Commit: 655d02396b4c5302df067e7f3eb43ead1a72995a
Parents: 6e099aa
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Apr 5 17:34:23 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Tue Apr 5 17:36:32 2016 -0700
----------------------------------------------------------------------
net/nimble/host/include/host/ble_l2cap.h | 1 +
net/nimble/host/src/ble_gap.c | 1 +
net/nimble/host/src/ble_l2cap_sm.c | 83 ++++++++++++++++++++++++++-
3 files changed, 83 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/655d0239/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 76c838b..01e25a6 100644
--- a/net/nimble/host/include/host/ble_l2cap.h
+++ b/net/nimble/host/include/host/ble_l2cap.h
@@ -100,5 +100,6 @@ int ble_l2cap_sig_update(uint16_t conn_handle,
int ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk);
+void ble_l2cap_sm_connection_broken(uint16_t conn_handle);
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/655d0239/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 3cfe4b0..4342103 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -772,6 +772,7 @@ ble_gap_conn_broken(uint16_t conn_handle)
ble_gap_unlock();
ble_gattc_connection_broken(conn_handle);
+ ble_l2cap_sm_connection_broken(conn_handle);
STATS_INC(ble_gap_stats, disconnect);
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/655d0239/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 6d89466..15d654e 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -283,6 +283,29 @@ ble_l2cap_sm_dispatch_get(uint8_t op)
return ble_l2cap_sm_dispatch[op];
}
+/* Indicates the handle of the specified proc's unserviced HCI reservation, if
+ * any. If there is no such handle associated with the proc,
+ * BLE_HCI_SCHED_HANDLE_NONE is returned.
+ *
+ * Lock restrictions: None.
+ *
+ * @param proc The proc object to query.
+ *
+ * @return The HCI handle, or BLE_HCI_SCHED_HANDLE_NONE.
+ */
+static uint8_t
+ble_l2cap_sm_proc_outstanding_hci_handle(struct ble_l2cap_sm_proc *proc)
+{
+ switch (proc->fsm_proc.op) {
+ case BLE_L2CAP_SM_PROC_OP_LTK:
+ case BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED:
+ return proc->hci.handle;
+
+ default:
+ return BLE_HCI_SCHED_HANDLE_NONE;
+ }
+}
+
/**
* Allocates a proc entry.
*
@@ -311,9 +334,22 @@ ble_l2cap_sm_proc_alloc(void)
static void
ble_l2cap_sm_proc_free(struct ble_fsm_proc *proc)
{
+ struct ble_l2cap_sm_proc *sm_proc;
+ uint8_t hci_handle;
int rc;
if (proc != NULL) {
+ sm_proc = (struct ble_l2cap_sm_proc *)proc;
+
+ /* If this proc has an unserviced HCI reservation, cancel it before
+ * freeing the proc.
+ */
+ hci_handle = ble_l2cap_sm_proc_outstanding_hci_handle(sm_proc);
+ if (hci_handle != BLE_HCI_SCHED_HANDLE_NONE) {
+ rc = ble_hci_sched_cancel(hci_handle);
+ BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+ }
+
rc = os_memblock_put(&ble_l2cap_sm_proc_pool, proc);
BLE_HS_DBG_ASSERT_EVAL(rc == 0);
}
@@ -687,6 +723,7 @@ ble_l2cap_sm_random_kick(struct ble_l2cap_sm_proc *proc)
}
if (!(proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR)) {
+ proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_LTK;
}
@@ -781,6 +818,11 @@ ble_l2cap_sm_lt_key_req_reply_tx(void *arg)
BLE_HS_DBG_ASSERT(proc->fsm_proc.op == BLE_L2CAP_SM_PROC_OP_LTK_TXED);
+ /* Indicate that the HCI reservation has been serviced. If there is a
+ * failure, we shouldn't try to cancel the reservation.
+ */
+ proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
+
cmd.conn_handle = proc->fsm_proc.conn_handle;
memcpy(cmd.long_term_key, proc->hci.key, 16);
@@ -837,7 +879,13 @@ ble_l2cap_sm_start_encrypt_tx(void *arg)
proc = arg;
- BLE_HS_DBG_ASSERT(proc->fsm_proc.op == BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED);
+ BLE_HS_DBG_ASSERT(proc->fsm_proc.op ==
+ BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED);
+
+ /* Indicate that the HCI reservation has been serviced. If there is a
+ * failure, we shouldn't try to cancel the reservation.
+ */
+ proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
cmd.connection_handle = proc->fsm_proc.conn_handle;
cmd.encrypted_diversifier = ble_l2cap_sm_gen_ediv();
@@ -862,6 +910,7 @@ ble_l2cap_sm_start_encrypt_kick(struct ble_l2cap_sm_proc *proc)
return BLE_HS_EDONE;
}
+ proc->hci.handle = BLE_HCI_SCHED_HANDLE_NONE;
proc->fsm_proc.op = BLE_L2CAP_SM_PROC_OP_START_ENCRYPT_TXED;
return 0;
@@ -1239,7 +1288,7 @@ ble_l2cap_sm_heartbeat(void)
ble_l2cap_sm_proc_extract_expired_cb, NULL);
/* Notify application of each failure and free the corresponding procedure
- * objects.
+ * object.
*/
while ((fsm_proc = STAILQ_FIRST(&exp_list)) != NULL) {
proc = (struct ble_l2cap_sm_proc *)fsm_proc;
@@ -1327,6 +1376,36 @@ ble_l2cap_sm_set_tk(uint16_t conn_handle, uint8_t *tk)
return 0;
}
+void
+ble_l2cap_sm_connection_broken(uint16_t conn_handle)
+{
+ struct ble_fsm_proc_list list;
+ struct ble_l2cap_sm_proc *proc;
+ struct ble_fsm_proc *fsm_proc;
+
+ /* Extract all procs associated with the broken connection and insert them
+ * into the temporary list.
+ */
+ ble_fsm_proc_extract_list(
+ &ble_l2cap_sm_fsm, &list, ble_l2cap_sm_proc_extract_cb,
+ &(struct ble_l2cap_sm_extract_arg) {
+ .conn_handle = conn_handle,
+ .op = BLE_L2CAP_SM_PROC_OP_NONE,
+ .initiator = -1,
+ }
+ );
+
+ /* Free each affected procedure object. There is no need to notify the
+ * application, as it has already been notified of the connection failure.
+ */
+ while ((fsm_proc = STAILQ_FIRST(&list)) != NULL) {
+ proc = (struct ble_l2cap_sm_proc *)fsm_proc;
+
+ STAILQ_REMOVE_HEAD(&list, next);
+ ble_l2cap_sm_proc_free(&proc->fsm_proc);
+ }
+}
+
/**
* Lock restrictions:
* o Caller unlocks ble_hs_conn.