Check CCB state before executing channel state machine events

Use Case:
When a disconnect response is being executed, a timeout may
occur and timeout event gets enqueued in BTU process. When
processing of the disconnect event completes, timout event is received
at csm and is executed. However, by this time the Channel
Control Block is already released during previous event causing
errors.

Steps:
Various connection/disconnection scenario.

Failure:
If ccb is already released while processing of
previous event, the occurance of new enqueued event causes
crash.

Root cause:
Disconnection response event has already released
ccb and set lcb for this channel to null. The occurance of
timer event after this results in crash because lcb is
dereferenced while header creation to send disc response to
peer device.

Fix:
Added check for ccb state for whether it is currently in
use or released before executing events in csm.

Change-Id: I9110e6dd5273fa162b51c8aa15bd0030567d664b
diff --git a/stack/l2cap/l2c_csm.c b/stack/l2cap/l2c_csm.c
index dedffc8..9eac5d5 100644
--- a/stack/l2cap/l2c_csm.c
+++ b/stack/l2cap/l2c_csm.c
@@ -67,6 +67,11 @@
 *******************************************************************************/
 void l2c_csm_execute (tL2C_CCB *p_ccb, UINT16 event, void *p_data)
 {
+    if (!l2cu_is_ccb_active(p_ccb)) {
+        L2CAP_TRACE_WARNING("%s CCB not in use, event (%d) cannot be processed", __func__, event);
+        return;
+    }
+
     switch (p_ccb->chnl_state)
     {
     case CST_CLOSED:
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index fab7e8f..9c6bf8a 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -639,6 +639,7 @@
 extern BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr);
 extern void    l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb);
 extern void    l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb);
+extern BOOLEAN l2cu_is_ccb_active (tL2C_CCB *p_ccb);
 
 /* Functions provided by l2c_ucd.c
 ************************************
diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c
index ff6461f..af87c2a 100644
--- a/stack/l2cap/l2c_utils.c
+++ b/stack/l2cap/l2c_utils.c
@@ -3824,3 +3824,17 @@
     }
 }
 
+/*******************************************************************************
+**
+** Function         l2cu_is_ccb_active
+**
+** Description      Check if Channel Control Block is in use or released
+**
+** Returns          BOOLEAN - TRUE if Channel Control Block is in use
+**                            FALSE if p_ccb is null or is released.
+**
+*******************************************************************************/
+BOOLEAN l2cu_is_ccb_active (tL2C_CCB *p_ccb)
+{
+    return (p_ccb && p_ccb->in_use);
+}