OSDN Git Service

BLE stack doesn't handle multiple l2cap_conn_update requests
authorZhihai Xu <zhihaixu@google.com>
Wed, 18 Dec 2013 04:33:09 +0000 (20:33 -0800)
committerZhihai Xu <zhihaixu@google.com>
Wed, 18 Dec 2013 17:41:41 +0000 (09:41 -0800)
we can define 4 bits as flags:
1. L2C_BLE_CONN_UPDATE_DISABLE:
if set it means disable update connection parameter. otherwise enable
2.L2C_BLE_NEW_CONN_PARAM:
if set, it means we have new connection parameter which is needed to be configured
if possible(after update done or enable).
3.L2C_BLE_UPDATE_PENDING:
if set, it means waiting for connection parameter update finished.
this flag will be cleared in btu_ble_ll_conn_param_upd_evt.
will be set when we call btsnd_hcic_ble_upd_ll_conn_params
4.L2C_BLE_NOT_DEFAULT_PARAM:
if set, it means we don't use the default connection parameter.
so when we disable update,
we need to configure default connection parameter.
with these 4 flags, we can replace all these states:
UPD_ENABLED, UPD_DISABLED, UPD_PENDING and UPD_UPDATED.
so we can cover all the corner cases which aren't handled
by original code.

bug:11450715
Change-Id: I6673d4783a8063bf9e8a213c6669800f86e67945

stack/btu/btu_hcif.c
stack/include/l2c_api.h
stack/l2cap/l2c_ble.c
stack/l2cap/l2c_int.h

index 69b3882..bd7c9ff 100644 (file)
@@ -2266,7 +2266,16 @@ static void btu_ble_ll_conn_complete_evt ( UINT8 *p, UINT16 evt_len)
 
 static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len)
 {
-/* This is empty until an upper layer cares about returning event */
+    /* LE connection update has completed successfully as a master. */
+    /* We can enable the update request if the result is a success. */
+    /* extract the HCI handle first */
+    UINT8   status;
+    UINT16  handle;
+    BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, "btu_ble_ll_conn_param_upd_evt");
+
+    STREAM_TO_UINT8  (status, p);
+    STREAM_TO_UINT16 (handle, p);
+    L2CA_HandleConnUpdateEvent(handle, status);
 }
 
 static void btu_ble_read_remote_feat_evt (UINT8 *p, UINT16 evt_len)
index 95c44e0..7679d26 100644 (file)
@@ -1146,6 +1146,18 @@ L2C_API extern BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN
 
 /*******************************************************************************
 **
+** Function         L2CA_HandleConnUpdateEvent
+**
+** Description      This function enables the connection update request from remote
+**                  after a successful connection update response is received.
+**
+** Returns          void
+**
+*******************************************************************************/
+L2C_API void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status);
+
+/*******************************************************************************
+**
 ** Function         L2CA_GetBleConnRole
 **
 ** Description      This function returns the connection role.
index 3640687..a440492 100644 (file)
@@ -81,6 +81,56 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
         return(FALSE);
 }
 
+/*******************************************************************************
+**
+**  Function        L2CA_InternalBleConnUpdate
+**
+**  Description     update BLE connection based on status
+**
+**  Parameters:     lcb
+**
+**  Return value:   none
+**
+*******************************************************************************/
+static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb)
+{
+    if (p_lcb->upd_status & L2C_BLE_UPDATE_PENDING) return;
+
+    if (p_lcb->upd_status & L2C_BLE_CONN_UPDATE_DISABLE)
+    {
+        /* application requests to disable parameters update.
+           If parameters are already updated, lets set them
+           up to what has been requested during connection establishement */
+        if (p_lcb->upd_status & L2C_BLE_NOT_DEFAULT_PARAM)
+        {
+            tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
+
+            btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle,
+                (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
+                (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
+                (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
+                (UINT16)((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
+                0, 0);
+            p_lcb->upd_status &= ~L2C_BLE_NOT_DEFAULT_PARAM;
+            p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM);
+        }
+    }
+    else
+    {
+        /* application allows to do update, if we were delaying one do it now */
+        if (p_lcb->upd_status & L2C_BLE_NEW_CONN_PARAM)
+        {
+            btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
+                p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
+            p_lcb->upd_status &= ~L2C_BLE_NEW_CONN_PARAM;
+            p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM);
+        }
+    }
+}
 
 /*******************************************************************************
 **
@@ -116,7 +166,14 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in
     }
 
     if (p_lcb->link_role == HCI_ROLE_MASTER)
-        btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, latency, timeout, 0, 0);
+    {
+        p_lcb->min_interval = min_int;
+        p_lcb->max_interval = max_int;
+        p_lcb->latency = latency;
+        p_lcb->timeout = timeout;
+        p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
+        L2CA_InternalBleConnUpdate(p_lcb);
+    }
     else
         l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
 
@@ -150,8 +207,9 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
         return (FALSE);
     }
 
-    L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d current upd state %d",
-        (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->upd_disabled);
+    L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d upd state %d",
+        (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5],
+        enable, p_lcb->upd_status);
 
     if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER))
     {
@@ -162,42 +220,52 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
 
     if (enable)
     {
-        /* application allows to do update, if we were delaying one do it now, otherwise
-        just mark lcb that updates are enabled */
-        if (p_lcb->upd_disabled == UPD_PENDING)
-        {
-            btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
-                                               p_lcb->latency, p_lcb->timeout, 0, 0);
-            p_lcb->upd_disabled = UPD_UPDATED;
-        }
-        else
-        {
-            p_lcb->upd_disabled = UPD_ENABLED;
-        }
+        p_lcb->upd_status &= ~L2C_BLE_CONN_UPDATE_DISABLE;
     }
     else
     {
-        /* application requests to disable parameters update.  If parameters are already updated, lets set them
-        up to what has been requested during connection establishement */
-        if (p_lcb->upd_disabled == UPD_UPDATED)
-        {
-            tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (rem_bda);
+        p_lcb->upd_status |= L2C_BLE_CONN_UPDATE_DISABLE;
+    }
 
-            btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
-                (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
-                (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
-                (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
-                (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
-                0, 0);
-        }
+    L2CA_InternalBleConnUpdate(p_lcb);
 
-        if (p_lcb->upd_disabled != UPD_PENDING)
-        {
-            p_lcb->upd_disabled = UPD_DISABLED;
-        }
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         L2CA_HandleConnUpdateEvent
+**
+** Description      This function enables the connection update request from remote
+**                  after a successful connection update response is received.
+**
+** Returns          void
+**
+*******************************************************************************/
+void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status)
+{
+    tL2C_LCB *p_lcb;
+
+    L2CAP_TRACE_DEBUG0("L2CA_HandleConnUpdateEvent");
+
+    /* See if we have a link control block for the remote device */
+    p_lcb = l2cu_find_lcb_by_handle(handle);
+    if (!p_lcb)
+    {
+        L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Invalid handle: %d", handle);
+        return;
     }
 
-    return (TRUE);
+    p_lcb->upd_status &= ~L2C_BLE_UPDATE_PENDING;
+
+    if (status != HCI_SUCCESS)
+    {
+        L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Error status: %d", status);
+    }
+
+    L2CA_InternalBleConnUpdate(p_lcb);
+
+    L2CAP_TRACE_DEBUG1("L2CA_HandleConnUpdateEvent: upd_status=%d", p_lcb->upd_status);
 }
 
 /*******************************************************************************
@@ -325,6 +393,7 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
                                            p_dev_rec->conn_params.slave_latency,
                                            p_dev_rec->conn_params.supervision_tout,
                                            0, 0);
+        p_lcb->upd_status |= L2C_BLE_UPDATE_PENDING;
     }
 
     /* Tell BTM Acl management about the link */
@@ -491,18 +560,8 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
                     p_lcb->max_interval = max_interval;
                     p_lcb->latency = latency;
                     p_lcb->timeout = timeout;
-
-                    if (p_lcb->upd_disabled == UPD_ENABLED)
-                    {
-                        btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
-                                                            latency, timeout, 0, 0);
-                        p_lcb->upd_disabled = UPD_UPDATED;
-                    }
-                    else
-                    {
-                        L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
-                        p_lcb->upd_disabled = UPD_PENDING;
-                    }
+                    p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
+                    L2CA_InternalBleConnUpdate(p_lcb);
                 }
             }
             else
index a17c583..72d5544 100644 (file)
@@ -435,11 +435,11 @@ typedef struct t_l2c_linkcb
     BOOLEAN             is_ble_link;
     tBLE_ADDR_TYPE      ble_addr_type;
 
-#define UPD_ENABLED     0  /* If peer requests update, we will change params */
-#define UPD_DISABLED    1  /* application requested not to update */
-#define UPD_PENDING     2  /* while updates are disabled, peer requested new parameters */
-#define UPD_UPDATED     3  /* peer updated connection parameters */
-    UINT8               upd_disabled;
+#define L2C_BLE_CONN_UPDATE_DISABLE 0x1  /* disable update connection parameters */
+#define L2C_BLE_NEW_CONN_PARAM      0x2  /* new connection parameter to be set */
+#define L2C_BLE_UPDATE_PENDING      0x4  /* waiting for connection update finished */
+#define L2C_BLE_NOT_DEFAULT_PARAM   0x8  /* not using default connection parameters */
+    UINT8               upd_status;
 
     UINT16              min_interval; /* parameters as requested by peripheral */
     UINT16              max_interval;