OSDN Git Service

[automerger] DO NOT MERGE SDP: Fix the param_len recalculation am: 7b2d711d9e am...
authorAndroid Build Merger (Role) <noreply-android-build-merger@google.com>
Fri, 20 Jul 2018 17:17:22 +0000 (17:17 +0000)
committerAndroid Build Merger (Role) <noreply-android-build-merger@google.com>
Fri, 20 Jul 2018 17:17:22 +0000 (17:17 +0000)
Change-Id: I53e95354ae4b588f11e57fc6e5aef741177becfe

41 files changed:
EventLogTags.logtags
bta/ag/bta_ag_api.c
bta/ag/bta_ag_cmd.c
bta/ag/bta_ag_int.h
bta/ag/bta_ag_main.c
bta/ag/bta_ag_sco.c
bta/dm/bta_dm_act.c
bta/dm/bta_dm_api.c
bta/dm/bta_dm_int.h
bta/gatt/bta_gattc_act.c
bta/gatt/bta_gattc_cache.c
bta/hf_client/bta_hf_client_sco.c
bta/hh/bta_hh_le.c
bta/include/bta_ag_api.h
bta/include/bta_api.h
bta/include/bta_gatt_api.h
btif/Android.mk
btif/co/bta_dm_co.c
btif/include/btif_debug_l2c.h [new file with mode: 0644]
btif/include/btif_storage.h
btif/src/bluetooth.c
btif/src/btif_core.c
btif/src/btif_debug_l2c.c [new file with mode: 0644]
btif/src/btif_dm.c
btif/src/btif_gatt_client.c
btif/src/btif_hf.c
btif/src/btif_media_task.c
btif/src/btif_storage.c
btif/src/stack_manager.c
device/include/interop.h
device/include/interop_database.h
device/src/interop.c
hci/src/btsnoop.c
include/bt_target.h
stack/avdt/avdt_l2c.c
stack/gatt/gatt_main.c
stack/include/l2c_api.h
stack/l2cap/l2c_ble.c
stack/l2cap/l2c_int.h
stack/l2cap/l2c_link.c
stack/l2cap/l2c_utils.c

index dc1d239..79f49e7 100644 (file)
@@ -36,3 +36,4 @@
 1010000 bt_hci_timeout (opcode|1)
 1010001 bt_config_source (opcode|1)
 1010002 bt_hci_unknown_type (hci_type|1)
+1010003 bt_conn_param_update_status (status|1)
index f3415be..872e71d 100644 (file)
@@ -287,3 +287,14 @@ void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec)
 
     bta_sys_sendmsg(p_buf);
 }
+
+void BTA_AgSetScoAllowed(bool value)
+{
+    tBTA_AG_API_SET_SCO_ALLOWED *p_buf =
+        (tBTA_AG_API_SET_SCO_ALLOWED *)osi_malloc(sizeof(tBTA_AG_API_SET_SCO_ALLOWED));
+
+    p_buf->hdr.event = BTA_AG_API_SET_SCO_ALLOWED_EVT;
+    p_buf->value = value;
+
+    bta_sys_sendmsg(p_buf);
+}
index ce22f87..1e9af0d 100644 (file)
@@ -923,6 +923,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
     APPL_TRACE_DEBUG("HFP AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
                       int_arg, p_arg);
 
+    memset(&val, 0, sizeof(tBTA_AG_VAL));
     val.hdr.handle = bta_ag_scb_to_idx(p_scb);
     val.hdr.app_id = p_scb->app_id;
     val.hdr.status = BTA_AG_SUCCESS;
index c1e685f..5048677 100644 (file)
@@ -101,7 +101,8 @@ enum
 
     /* these events are handled outside of the state machine */
     BTA_AG_API_ENABLE_EVT,
-    BTA_AG_API_DISABLE_EVT
+    BTA_AG_API_DISABLE_EVT,
+    BTA_AG_API_SET_SCO_ALLOWED_EVT
 };
 
 /* Actions to perform after a SCO event */
@@ -181,6 +182,13 @@ typedef struct
     tBTA_AG_PEER_CODEC  codec;
 } tBTA_AG_API_SETCODEC;
 
+/* data type for BTA_AG_API_SET_SCO_ALLOWED_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    bool                value;
+} tBTA_AG_API_SET_SCO_ALLOWED;
+
 /* data type for BTA_AG_DISC_RESULT_EVT */
 typedef struct
 {
@@ -423,4 +431,5 @@ extern void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
 extern void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param);
 extern void bta_ag_ci_rx_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
 extern void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
+extern void bta_ag_set_sco_allowed(tBTA_AG_DATA *p_data);
 #endif /* BTA_AG_INT_H */
index 3abd1ef..d6cc556 100644 (file)
@@ -906,6 +906,10 @@ BOOLEAN bta_ag_hdl_event(BT_HDR *p_msg)
             bta_ag_api_result((tBTA_AG_DATA *) p_msg);
             break;
 
+        case BTA_AG_API_SET_SCO_ALLOWED_EVT:
+            bta_ag_set_sco_allowed((tBTA_AG_DATA *) p_msg);
+            break;
+
         /* all others reference scb by handle */
         default:
             if ((p_scb = bta_ag_scb_by_idx(p_msg->layer_specific)) != NULL)
index 89e6f6c..3399e69 100644 (file)
@@ -50,6 +50,8 @@ static char *bta_ag_sco_evt_str(UINT8 event);
 static char *bta_ag_sco_state_str(UINT8 state);
 #endif
 
+static bool sco_allowed = true;
+
 #define BTA_AG_NO_EDR_ESCO  (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | \
                              BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | \
                              BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \
@@ -1348,6 +1350,12 @@ void bta_ag_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
     UINT8 event;
     UNUSED(p_data);
 
+    if (!sco_allowed)
+    {
+        APPL_TRACE_DEBUG("%s not opening sco, by policy", __func__);
+        return;
+    }
+
     /* if another scb using sco, this is a transfer */
     if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb)
     {
@@ -1672,6 +1680,12 @@ void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param)
     }
 }
 
+void bta_ag_set_sco_allowed(tBTA_AG_DATA *p_data)
+{
+    sco_allowed = ((tBTA_AG_API_SET_SCO_ALLOWED *) p_data)->value;
+    APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
+}
+
 /*******************************************************************************
 **  Debugging functions
 *******************************************************************************/
index 3bf6c06..12caa12 100644 (file)
@@ -4666,10 +4666,11 @@ void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
 {
     if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
-                                 p_data->ble_update_conn_params.min_int,
-                                 p_data->ble_update_conn_params.max_int,
-                                 p_data->ble_update_conn_params.latency,
-                                 p_data->ble_update_conn_params.timeout))
+                                  p_data->ble_update_conn_params.min_int,
+                                  p_data->ble_update_conn_params.max_int,
+                                  p_data->ble_update_conn_params.latency,
+                                  p_data->ble_update_conn_params.timeout,
+                                  p_data->ble_update_conn_params.p_conn_param_update_cback))
     {
         APPL_TRACE_ERROR("Update connection parameters failed!");
     }
index 82dd8b2..323e58e 100644 (file)
@@ -1311,39 +1311,6 @@ void BTA_DmSearchExt(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK_EXT *p_services, t
     UNUSED(p_cback);
 #endif
 }
-/*******************************************************************************
-**
-** Function         BTA_DmBleUpdateConnectionParam
-**
-** Description      Update connection parameters, can only be used when connection is up.
-**
-** Parameters:      bd_addr          - BD address of the peer
-**                  min_int   -     minimum connection interval, [0x0004~ 0x4000]
-**                  max_int   -     maximum connection interval, [0x0004~ 0x4000]
-**                  latency   -     slave latency [0 ~ 500]
-**                  timeout   -     supervision timeout [0x000a ~ 0xc80]
-**
-** Returns          void
-**
-*******************************************************************************/
-void BTA_DmBleUpdateConnectionParam(BD_ADDR bd_addr, UINT16 min_int,
-                                    UINT16 max_int, UINT16 latency,
-                                    UINT16 timeout)
-{
-#if BLE_INCLUDED == TRUE
-    tBTA_DM_API_UPDATE_CONN_PARAM *p_msg =
-        (tBTA_DM_API_UPDATE_CONN_PARAM *)osi_calloc(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
-
-    p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT;
-    bdcpy(p_msg->bd_addr, bd_addr);
-    p_msg->min_int = min_int;
-    p_msg->max_int = max_int;
-    p_msg->latency = latency;
-    p_msg->timeout = timeout;
-
-    bta_sys_sendmsg(p_msg);
-#endif
-}
 
 /*******************************************************************************
 **
@@ -1746,17 +1713,19 @@ void BTA_DmEnableScanFilter(UINT8 action, tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cb
 **
 ** Description      Update connection parameters, can only be used when connection is up.
 **
-** Parameters:      bd_addr   - BD address of the peer
+** Parameters:      bd_addr   -     BD address of the peer
 **                  min_int   -     minimum connection interval, [0x0004~ 0x4000]
 **                  max_int   -     maximum connection interval, [0x0004~ 0x4000]
 **                  latency   -     slave latency [0 ~ 500]
 **                  timeout   -     supervision timeout [0x000a ~ 0xc80]
+                    p_cback   -     callback on connection parameters updated
 **
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
-                                    UINT16 latency, UINT16 timeout)
+void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int,
+                                     UINT16 max_int, UINT16 latency, UINT16 timeout,
+                                     tBTA_DM_BLE_CONN_PARAM_CBACK *p_cback)
 {
     tBTA_DM_API_UPDATE_CONN_PARAM *p_msg =
         (tBTA_DM_API_UPDATE_CONN_PARAM *)osi_calloc(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
@@ -1767,6 +1736,7 @@ void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max
     p_msg->max_int = max_int;
     p_msg->latency = latency;
     p_msg->timeout = timeout;
+    p_msg->p_conn_param_update_cback = p_cback;
 
     bta_sys_sendmsg(p_msg);
 }
index a5fe0ad..796d4a5 100644 (file)
@@ -436,7 +436,6 @@ typedef struct
     UINT16                  conn_int_max;
     UINT16                  supervision_tout;
     UINT16                  slave_latency;
-
 }tBTA_DM_API_BLE_CONN_PARAMS;
 
 typedef struct
@@ -611,6 +610,8 @@ typedef struct
     tBTA_DM_LINK_TYPE link_type;
 
 } tBTA_DM_API_REMOVE_ALL_ACL;
+
+/* data type for BTA_DM_API_UPDATE_CONN_PARAM_EVT */
 typedef struct
 {
     BT_HDR      hdr;
@@ -619,7 +620,8 @@ typedef struct
     UINT16      max_int;
     UINT16      latency;
     UINT16      timeout;
-}tBTA_DM_API_UPDATE_CONN_PARAM;
+    tBTA_DM_BLE_CONN_PARAM_CBACK *p_conn_param_update_cback;
+} tBTA_DM_API_UPDATE_CONN_PARAM;
 
 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
 typedef struct
index 3390b94..69f8ecf 100644 (file)
@@ -1396,8 +1396,10 @@ void  bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
             return;
         }
 
-        /* discard responses if service change indication is received before operation completed */
-        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg)
+        /* Except for MTU configuration, discard responses if service change indication is
+         * received before operation completed */
+        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg &&
+            op != GATTC_OPTYPE_CONFIG)
         {
             APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
             p_data->op_cmpl.status = GATT_ERROR;
index d283b38..62b4d81 100644 (file)
@@ -1517,6 +1517,12 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
 *******************************************************************************/
 bool bta_gattc_cache_load(tBTA_GATTC_CLCB *p_clcb)
 {
+
+#if (defined WEAR_DISABLE_GATT_CACHE && WEAR_DISABLE_GATT_CACHE == TRUE)
+    LOG_WARN(LOG_TAG, "%s GATT cache not used.", __func__);
+    return false;
+#endif
+
     char fname[255] = {0};
     bta_gattc_generate_cache_file_name(fname, p_clcb->p_srcb->server_bda);
 
index 129dc9e..1be82a5 100644 (file)
@@ -231,7 +231,7 @@ static void bta_hf_client_sco_conn_cback(UINT16 sco_idx)
     /* no match found; disconnect sco, init sco variables */
     else
     {
-        bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
+        /* should not force the sco state to shutdown state here */
         BTM_RemoveSco(sco_idx);
     }
 }
index b538470..a21df35 100644 (file)
@@ -1804,8 +1804,8 @@ void bta_hh_w4_le_read_char_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_buf)
         if (tout < BTM_BLE_CONN_TIMEOUT_MIN_DEF)
             tout = BTM_BLE_CONN_TIMEOUT_MIN_DEF;
 
-        BTM_BleSetPrefConnParams (p_dev_cb->addr, min, max, latency, tout);
-        L2CA_UpdateBleConnParams(p_dev_cb->addr, min, max, latency, tout);
+        BTM_BleSetPrefConnParams(p_dev_cb->addr, min, max, latency, tout);
+        L2CA_UpdateBleConnParams(p_dev_cb->addr, min, max, latency, tout, NULL);
     }
     else
     {
index e281fb1..899461a 100644 (file)
@@ -580,6 +580,8 @@ void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data);
 *******************************************************************************/
 void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec);
 
+void BTA_AgSetScoAllowed(bool value);
+
 #ifdef __cplusplus
 }
 #endif
index b20c271..8fdd6ec 100644 (file)
@@ -933,6 +933,9 @@ typedef void (tBTA_DM_BLE_PF_PARAM_CBACK) (UINT8 action_type, tBTA_DM_BLE_PF_AVB
 typedef void (tBTA_DM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTA_STATUS status,
                                             tBTA_DM_BLE_REF_VALUE ref_value);
 
+/* Connection update callback */
+typedef void (tBTA_DM_BLE_CONN_PARAM_CBACK) (BD_ADDR bd_addr, UINT16 interval, UINT16 latency,
+                                             UINT16 timeout, tBTA_STATUS status);
 
 #define BTA_DM_BLE_PF_BRDCAST_ADDR_FILT  1
 #define BTA_DM_BLE_PF_SERV_DATA_CHG_FILT 2
@@ -2110,7 +2113,7 @@ extern void BTA_BleDisableAdvInstance(UINT8 inst_id);
 **
 ** Description      Update connection parameters, can only be used when connection is up.
 **
-** Parameters:      bd_addr   - BD address of the peer
+** Parameters:      bd_addr   -     BD address of the peer
 **                  min_int   -     minimum connection interval, [0x0004~ 0x4000]
 **                  max_int   -     maximum connection interval, [0x0004~ 0x4000]
 **                  latency   -     slave latency [0 ~ 500]
@@ -2119,8 +2122,9 @@ extern void BTA_BleDisableAdvInstance(UINT8 inst_id);
 ** Returns          void
 **
 *******************************************************************************/
-extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int,
-                                   UINT16 max_int, UINT16 latency, UINT16 timeout);
+extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
+                                            UINT16 latency, UINT16 timeout,
+                                            tBTA_DM_BLE_CONN_PARAM_CBACK p_cback);
 
 /*******************************************************************************
 **
index 4c9f76c..0d0a1fc 100644 (file)
@@ -146,6 +146,7 @@ typedef UINT8 tBTA_GATT_STATUS;
 #define BTA_GATTC_SCAN_FLT_PARAM_EVT 32 /* Param filter event */
 #define BTA_GATTC_SCAN_FLT_STATUS_EVT 33 /* Filter status event */
 #define BTA_GATTC_ADV_VSC_EVT         34 /* ADV VSC event */
+#define BTA_GATTC_CONN_PARAM_UPD_EVT 35 /* Connection parameter update event */
 
 typedef UINT8 tBTA_GATTC_EVT;
 
index eee76b9..d6b934d 100644 (file)
@@ -36,6 +36,7 @@ btifCommonSrc += \
   src/btif_debug.c \
   src/btif_debug_btsnoop.c \
   src/btif_debug_conn.c \
+  src/btif_debug_l2c.c \
   src/btif_dm.c \
   src/btif_gatt.c \
   src/btif_gatt_client.c \
index 343010f..55b2f86 100644 (file)
@@ -24,6 +24,9 @@
 #include "bta_dm_ci.h"
 #include "bt_utils.h"
 #include "btif_dm.h"
+#if (defined WEAR_LE_IO_CAP_OVERRIDE && WEAR_LE_IO_CAP_OVERRIDE == TRUE)
+#include "btif_storage.h"
+#endif
 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
 #include "bte_appl.h"
 
@@ -402,7 +405,24 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr,  tBTA_IO_CAP *p_io_cap,
                           tBTA_LE_KEY_TYPE  *p_resp_key )
 {
     UNUSED(bd_addr);
-    /* Retrieve the properties from file system if possible */
+
+
+#if (defined WEAR_LE_IO_CAP_OVERRIDE && WEAR_LE_IO_CAP_OVERRIDE == TRUE)
+    /*
+     * Note: This is a Wear-specific feature for iOS pairing.
+     *
+     * Set WearLeIoCap config to force local IO capability to be BTM_IO_CAP_NONE
+     * (No input, no output) for the first bond creation, that indirectly
+     * triggers Just Works pairing.
+     */
+    if (btif_storage_get_num_bonded_devices() == 0)
+        bte_appl_cfg.ble_io_cap = BTM_IO_CAP_NONE;
+#endif
+
+    /* For certification testing purpose, LE IO capability can also be specified with
+     * "PTS_SmpOptions" in the BT stack configuration file (i.e. bt_stack.conf).
+     * Note that if "PTS_SmpOptions" is set, it could override IO capability set above.
+     */
     tBTE_APPL_CFG nv_config;
     if(btif_dm_get_smp_config(&nv_config))
         bte_appl_cfg = nv_config;
diff --git a/btif/include/btif_debug_l2c.h b/btif/include/btif_debug_l2c.h
new file mode 100644 (file)
index 0000000..b77c49b
--- /dev/null
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2016 Google Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <stdint.h>
+
+#include <hardware/bluetooth.h>
+
+// Captures a BLE connection parameter update request (Section 4.20 of
+// Bluetooth Core V4.2 specification):
+//
+// |min_interval| and |max_interval| define the minimum and maximum values for
+// the connection event interval (in units of 1.25ms and should be in the
+// [6, 3200] range).
+// |slave_latency_param| is the slave latency parameter for the connection in
+// number of connection events (unitless and should be less than 500).
+// |timeout_multiplier| is the connection timeout parameter (in units of 10ms
+// and should be in the [10, 3200] range).
+void btif_debug_ble_connection_update_request(bt_bdaddr_t bda,
+    uint16_t min_interval, uint16_t max_interval, uint16_t slave_latency_param,
+    uint16_t timeout_multiplier);
+
+// Captures a BLE connection parameter update response ((Section 4.21 of
+// Bluetooth Core V4.2 specification):
+//
+// |interval| defines the minimum and maximum values for the
+// connection event interval (in units of 1.25ms and should be in the
+// [6, 3200] range).
+// |slave_latency_param| is the slave latency parameter for the connection in
+// number of connection events (unitless and should be less than 500).
+// |timeout_multiplier| is the connection timeout parameter (in units of 10ms
+// and should be in the [10, 3200] range).
+void btif_debug_ble_connection_update_response(bt_bdaddr_t bda, uint8_t status,
+    uint16_t interval, uint16_t slave_latency_param,
+    uint16_t timeout_multiplier);
+
+// Dumps captured L2C information.
+void btif_debug_l2c_dump(int fd);
index bc1060c..5309ce0 100644 (file)
@@ -274,6 +274,16 @@ bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr);
 *******************************************************************************/
 BOOLEAN btif_storage_is_restricted_device(const bt_bdaddr_t *remote_bd_addr);
 
+/*******************************************************************************
+**
+** Function         btif_storage_get_num_bonded_devices
+**
+** Description      BTIF storage API - Gets the number of bonded devices
+**
+** Returns          the number of bonded devices
+**
+*******************************************************************************/
+int btif_storage_get_num_bonded_devices(void);
 #if (BLE_INCLUDED == TRUE)
 bt_status_t btif_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr,
                                               char *key,
index 1414138..6be1d19 100644 (file)
@@ -62,6 +62,7 @@
 #include "btif_storage.h"
 #include "btif/include/btif_debug_btsnoop.h"
 #include "btif/include/btif_debug_conn.h"
+#include "btif/include/btif_debug_l2c.h"
 #include "btif/include/btif_media.h"
 
 /************************************************************************************
@@ -353,6 +354,7 @@ static void dump(int fd, const char **arguments)
     btif_debug_conn_dump(fd);
     btif_debug_bond_event_dump(fd);
     btif_debug_a2dp_dump(fd);
+    btif_debug_l2c_dump(fd);
     btif_debug_config_dump(fd);
     wakelock_debug_dump(fd);
     alarm_debug_dump(fd);
index c74c6dd..7dc93c4 100644 (file)
@@ -709,13 +709,18 @@ static bt_status_t btif_in_get_adapter_properties(void)
     uint32_t disc_timeout;
     bt_bdaddr_t bonded_devices[BTM_SEC_MAX_DEVICE_RECORDS];
     bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
+    bt_status_t status;
     num_props = 0;
 
     /* BD_ADDR */
     BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDADDR,
                                sizeof(addr), &addr);
-    btif_storage_get_adapter_property(&properties[num_props]);
-    num_props++;
+    status = btif_storage_get_adapter_property(&properties[num_props]);
+    // Add BT_PROPERTY_BDADDR property into list only when successful.
+    // Otherwise, skip this property entry.
+    if (status == BT_STATUS_SUCCESS) {
+        num_props++;
+    }
 
     /* BD_NAME */
     BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDNAME,
diff --git a/btif/src/btif_debug_l2c.c b/btif/src/btif_debug_l2c.c
new file mode 100644 (file)
index 0000000..5a04135
--- /dev/null
@@ -0,0 +1,159 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2016 Google Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+
+#include "btcore/include/bdaddr.h"
+#include "btif/include/btif_debug.h"
+#include "btif/include/btif_debug_l2c.h"
+
+#define NUM_UPDATE_REQUESTS 5
+#define NUM_UPDATE_RESPONSES 5
+
+#define INTERVAL_1_25_MS_MULTIPLIER 1.25f
+#define TIMEOUT_10_MS_MULTIPLIER 10
+
+typedef enum {
+  BTIF_DEBUG_CONNECTION_UPDATE_REQUEST,
+  BTIF_DEBUG_CONNECTION_UPDATE_RESPONSE,
+} btif_debug_ble_conn_update_t;
+
+/* Shared Connection update record for both request and response. */
+typedef struct ble_conn_update_t {
+  uint64_t timestamp_ms;
+  bt_bdaddr_t bda;
+  btif_debug_ble_conn_update_t type;
+  uint8_t status;         /* Not populated for request. */
+  uint16_t min_interval;  /* Not populated for response. */
+  uint16_t max_interval;
+  uint16_t latency;
+  uint16_t timeout;
+} ble_conn_update_t;
+
+static int update_request_index;
+static int update_response_index;
+static ble_conn_update_t last_ble_conn_update_requests[NUM_UPDATE_REQUESTS];
+static ble_conn_update_t last_ble_conn_update_responses[NUM_UPDATE_RESPONSES];
+
+static int dump_connection_update(int fd, const ble_conn_update_t *update) {
+  if (!update || update->timestamp_ms == 0) {
+    return -1;
+  }
+
+  /* Format timestamp */
+  const uint64_t msecs = update->timestamp_ms / 1000;
+  const time_t secs = msecs / 1000;
+  struct tm *ptm = localtime(&secs);
+  char time_buf[20] = {0};
+  strftime(time_buf, sizeof(time_buf), "%m-%d %H:%M:%S", ptm);
+  snprintf(time_buf, sizeof(time_buf), "%s.%03u", time_buf,
+      (uint16_t)(msecs % 1000));
+
+  /* Format address */
+  char addr_buf[18] = {0};
+  bdaddr_to_string(&update->bda, addr_buf, sizeof(addr_buf));
+
+  if (update->type == BTIF_DEBUG_CONNECTION_UPDATE_REQUEST) {
+    dprintf(fd,
+        "  %s %s min interval=%d (%.2fms) max interval=%d (%.2fms) "
+        "latency parameter=%d timeout multiplier=%d (%dms)\n",
+        time_buf, addr_buf, update->min_interval,
+        (float)update->min_interval * INTERVAL_1_25_MS_MULTIPLIER,
+        update->max_interval,
+        (float)update->max_interval * INTERVAL_1_25_MS_MULTIPLIER,
+        update->latency, update->timeout,
+        update->timeout * TIMEOUT_10_MS_MULTIPLIER);
+  } else {
+    dprintf(fd,
+        "  %s %s status=%d interval=%d (%.2fms) latency parameter=%d "
+        "timeout multiplier=%d (%dms)\n", time_buf,
+        addr_buf, update->status, update->max_interval,
+        (float)update->max_interval * INTERVAL_1_25_MS_MULTIPLIER,
+        update->latency, update->timeout,
+        update->timeout * TIMEOUT_10_MS_MULTIPLIER);
+  }
+
+  return 0;
+}
+
+static void record_connection_update(bt_bdaddr_t bda, uint8_t status,
+    uint16_t min_interval, uint16_t max_interval, uint16_t latency,
+    uint16_t timeout, btif_debug_ble_conn_update_t type,
+    ble_conn_update_t* update) {
+
+  memcpy(&update->bda, &bda, sizeof(bt_bdaddr_t));
+  update->type = type;
+  update->timestamp_ms = btif_debug_ts();
+  update->min_interval = min_interval;
+  update->max_interval = max_interval;
+  update->latency = latency;
+  update->timeout = timeout;
+  update->status = 0;
+}
+
+void btif_debug_ble_connection_update_request(bt_bdaddr_t bda,
+    uint16_t min_interval, uint16_t max_interval, uint16_t slave_latency_param,
+    uint16_t timeout_multiplier) {
+  ble_conn_update_t *request =
+      &last_ble_conn_update_requests[update_request_index];
+
+  record_connection_update(bda, 0, min_interval, max_interval, slave_latency_param,
+      timeout_multiplier, BTIF_DEBUG_CONNECTION_UPDATE_REQUEST, request);
+
+  update_request_index = (update_request_index == NUM_UPDATE_REQUESTS - 1) ?
+      0 : update_request_index + 1;
+}
+
+void btif_debug_ble_connection_update_response(bt_bdaddr_t bda, uint8_t status,
+    uint16_t interval, uint16_t slave_latency_param,
+    uint16_t timeout_multiplier) {
+  ble_conn_update_t *response =
+      &last_ble_conn_update_responses[update_response_index];
+
+  record_connection_update(bda, status, 0, interval, slave_latency_param,
+      timeout_multiplier, BTIF_DEBUG_CONNECTION_UPDATE_RESPONSE, response);
+
+  update_response_index = (update_response_index == NUM_UPDATE_RESPONSES - 1) ?
+      0 : update_response_index + 1;
+}
+
+void btif_debug_l2c_dump(int fd) {
+  dprintf(fd, "\nLE Connection Parameter Updates:\n");
+
+  int i;
+  dprintf(fd, "  Last %d Request(s):\n", NUM_UPDATE_REQUESTS);
+  for (i = 0; i < NUM_UPDATE_REQUESTS; ++i) {
+    if (dump_connection_update(fd, &last_ble_conn_update_requests[i]) < 0 &&
+        i == 0) {
+      dprintf(fd, "  None\n");
+      break;
+    }
+  }
+
+  dprintf(fd, "\n  Last %d Response(s):\n", NUM_UPDATE_RESPONSES);
+  for (i = 0; i < NUM_UPDATE_RESPONSES; ++i) {
+    if (dump_connection_update(fd, &last_ble_conn_update_responses[i]) < 0 &&
+        i == 0) {
+      dprintf(fd, "  None\n");
+      break;
+    }
+  }
+}
index f70e4fa..74ba174 100644 (file)
@@ -3078,6 +3078,18 @@ static void btif_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
             btif_storage_remove_bonded_device(&bdaddr);
             state = BT_BOND_STATE_NONE;
         } else {
+            /*
+             * Note: This is a Wear-specific feature for iOS pairing.
+             * Store the address of the first bonded device that is also of type LE to
+             * enable auto connection parameter update.
+             */
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+            if (btif_storage_get_num_bonded_devices() == 0) {
+                bdstr_t bdstr;
+                bdaddr_to_string(&bdaddr, bdstr, sizeof(bdstr));
+                btif_config_set_str("Adapter", "AutoConnParamUpdateAddr", bdstr);
+            }
+#endif
             btif_dm_save_ble_bonding_keys();
             BTA_GATTC_Refresh(bd_addr.address);
             btif_dm_get_remote_services_by_transport(&bd_addr, BTA_GATT_TRANSPORT_LE);
index 7ad4f08..f27f4bd 100644 (file)
@@ -50,8 +50,9 @@
 #include "btif_gatt_multi_adv_util.h"
 #include "btif_gatt_util.h"
 #include "btif_storage.h"
-#include "btif_storage.h"
 #include "osi/include/log.h"
+#include "osi/include/alarm.h"
+#include "stack/include/gatt_api.h"
 #include "vendor_api.h"
 
 /*******************************************************************************
@@ -69,6 +70,7 @@
 #define BLE_RESOLVE_ADDR_MSB                 0x40   /* bit7, bit6 is 01 to be resolvable random */
 #define BLE_RESOLVE_ADDR_MASK                0xc0   /* bit 6, and bit7 */
 #define BTM_BLE_IS_RESOLVE_BDA(x)           ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
+#define BT_CONN_PARAM_UPDATE_STATUS          1010003
 
 typedef enum {
     BTIF_GATTC_REGISTER_APP = 1000,
@@ -206,12 +208,15 @@ typedef struct
 
 typedef struct
 {
+    uint8_t     client_if;
     bt_bdaddr_t bd_addr;
-    uint16_t    min_interval;
-    uint16_t    max_interval;
+    uint16_t    requested_min_interval;
+    uint16_t    requested_max_interval;
+    uint16_t    configured_interval;
     uint16_t    timeout;
     uint16_t    latency;
-} btif_conn_param_cb_t;
+    uint8_t     status;
+}__attribute__((packed)) btif_conn_param_cb_t;
 
 typedef struct
 {
@@ -236,6 +241,138 @@ static btif_gattc_dev_cb_t  *p_dev_cb = &btif_gattc_dev_cb;
 static uint8_t rssi_request_client_if;
 
 /*******************************************************************************
+**  Auto Connection Parameter Update
+**
+**  Feature is enabled when WEAR_AUTO_CONN_PARAM_UPDATE build config is set to
+**  TRUE.  It looks for a whitelisted address in the configuration file and
+**  automatically applies a connection interval parameter update
+**  (WEAR_AUTO_CONN_IDLE_INTERVAL_1_25_MS) when the connection is idle for a
+**  specific period of time (WEAR_AUTO_CONN_IDLE_TIMEOUT_MS).
+********************************************************************************/
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+typedef struct
+{
+    bt_bdaddr_t device_address;
+    uint16_t    min_interval;
+    uint16_t    max_interval;
+    uint16_t    timeout;
+    uint16_t    latency;
+    bool        is_auto_update_address_known;
+    bool        is_auto_update_enabled;
+    bool        is_updating;
+    alarm_t     *check_idle_alarm;
+} btgatt_auto_connection_param_update_cb_t;
+
+static btgatt_auto_connection_param_update_cb_t auto_conn_param_update_cb;
+
+static bt_status_t btif_gattc_conn_parameter_update_internal(const bt_bdaddr_t *bd_addr, int min_interval,
+             int max_interval, int latency, int timeout);
+
+static void auto_connection_param_update_idle_cb(UNUSED_ATTR void *data)
+{
+    btgatt_auto_connection_param_update_cb_t *auto_update_cb =
+        (btgatt_auto_connection_param_update_cb_t *)data;
+
+    if (auto_conn_param_update_cb.is_updating)
+    {
+        LOG_WARN(LOG_TAG, "%s another connection update in progress", __FUNCTION__);
+        return;
+    }
+
+    btif_gattc_conn_parameter_update_internal(&auto_update_cb->device_address,
+        WEAR_AUTO_CONN_IDLE_INTERVAL_1_25_MS, WEAR_AUTO_CONN_IDLE_INTERVAL_1_25_MS, 0, 2000);
+    LOG_INFO(LOG_TAG, "%s auto adjust connection interval to %dms", __FUNCTION__,
+             (int)(WEAR_AUTO_CONN_IDLE_INTERVAL_1_25_MS * 1.25f));
+}
+
+static void maybe_set_connection_param_update_in_progress(const bt_bdaddr_t *bd_addr, bool in_progress)
+{
+    if (auto_conn_param_update_cb.is_auto_update_enabled &&
+        bdcmp(auto_conn_param_update_cb.device_address.address, bd_addr->address) == 0)
+    {
+        auto_conn_param_update_cb.is_updating = in_progress;
+    }
+}
+
+static void maybe_enable_auto_connection_param_update(const bt_bdaddr_t *bd_addr, int min_interval,
+                                                      int max_interval, int latency, int timeout)
+{
+    /* First check if there is a whitelisted address to enable auto connection param update */
+    if (!auto_conn_param_update_cb.is_auto_update_address_known)
+    {
+        bdstr_t bdstr;
+        int bdstr_size = sizeof(bdstr);
+        /*
+         * If AutoConnParamUpdateAddr is not set from bonding, infer the first LE address performing
+         * connection parameter update as the companion.
+         */
+        if (!btif_config_get_str("Adapter", "AutoConnParamUpdateAddr", bdstr, &bdstr_size)) {
+            bdaddr_to_string(bd_addr, bdstr, bdstr_size);
+            btif_config_set_str("Adapter", "AutoConnParamUpdateAddr", bdstr);
+            LOG_INFO(LOG_TAG, "%s force set AutoConnParamUpdateAddr: %s", __FUNCTION__, bdstr);
+        }
+
+        bdcpy(auto_conn_param_update_cb.device_address.address, bd_addr->address);
+        auto_conn_param_update_cb.is_auto_update_address_known = true;
+        LOG_INFO(LOG_TAG, "%s auto connection param update for address: %s", __FUNCTION__, bdstr);
+    }
+
+    /* If the address matches the auto update address, store the connection parameter value */
+    if (bdcmp(auto_conn_param_update_cb.device_address.address, bd_addr->address) == 0)
+    {
+        auto_conn_param_update_cb.min_interval = min_interval;
+        auto_conn_param_update_cb.max_interval = max_interval;
+        auto_conn_param_update_cb.timeout = timeout;
+        auto_conn_param_update_cb.latency = latency;
+        auto_conn_param_update_cb.is_auto_update_enabled = true;
+    }
+}
+
+static void maybe_restore_connection_parameters(BD_ADDR address) {
+    /*
+     * Will not perform auto connection parameter update if:
+     *
+     * - feature not enabled (yet)
+     * - address doesn't match auto update address
+     * - connection parameter update is in progress
+     */
+    if (!auto_conn_param_update_cb.is_auto_update_enabled ||
+        (bdcmp(auto_conn_param_update_cb.device_address.address, address) != 0) ||
+        auto_conn_param_update_cb.is_updating)
+    {
+        return;
+    }
+
+    if (alarm_is_scheduled(auto_conn_param_update_cb.check_idle_alarm))
+    {
+        /* Idle alarm is scheduled, reschedule it */
+        alarm_cancel(auto_conn_param_update_cb.check_idle_alarm);
+    }
+    else
+    {
+        /* No idle alarm and no update in progress, restore specified connection parameters */
+        btif_gattc_conn_parameter_update_internal(&auto_conn_param_update_cb.device_address,
+                                                  auto_conn_param_update_cb.min_interval,
+                                                  auto_conn_param_update_cb.max_interval,
+                                                  auto_conn_param_update_cb.latency,
+                                                  auto_conn_param_update_cb.timeout);
+        LOG_VERBOSE(LOG_TAG, "%s restore connection parameters", __FUNCTION__);
+    }
+
+    /* Schedule idle alarm */
+    if (!auto_conn_param_update_cb.check_idle_alarm)
+    {
+        auto_conn_param_update_cb.check_idle_alarm =
+            alarm_new("gatt_client.auto_conn_param_update_idle_alarm");
+    }
+    alarm_set(auto_conn_param_update_cb.check_idle_alarm, WEAR_AUTO_CONN_IDLE_TIMEOUT_MS,
+              auto_connection_param_update_idle_cb, &auto_conn_param_update_cb);
+
+    return;
+}
+#endif
+
+/*******************************************************************************
 **  Static functions
 ********************************************************************************/
 
@@ -536,6 +673,10 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
             if (p_data->notify.is_notify == FALSE)
                 BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);
 
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+            maybe_restore_connection_parameters(data.bda.address);
+#endif
+
             break;
         }
 
@@ -799,6 +940,20 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
             break;
         }
 
+        case BTA_GATTC_CONN_PARAM_UPD_EVT:
+        {
+            btif_conn_param_cb_t *p_btif_cb = (btif_conn_param_cb_t *)p_param;
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+            maybe_set_connection_param_update_in_progress(&p_btif_cb->bd_addr, false);
+#endif
+            /* Log update failures */
+            if (p_btif_cb->status != 0)
+            {
+                LOG_EVENT_INT(BT_CONN_PARAM_UPDATE_STATUS, p_btif_cb->status);
+            }
+            break;
+        }
+
         case BTIF_GATTC_SCAN_PARAM_EVT:
         {
             btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t *)p_param;
@@ -1092,6 +1247,20 @@ static void bta_scan_filt_status_cb(UINT8 action, tBTA_STATUS status,
                           (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
 }
 
+static void bta_gattc_conn_param_update_cback(BD_ADDR bd_addr, UINT16 interval,
+                                              UINT16 latency, UINT16 timeout, tBTA_STATUS status)
+{
+    btif_conn_param_cb_t btif_cb;
+
+    bdcpy(btif_cb.bd_addr.address, bd_addr);
+    btif_cb.configured_interval = interval;
+    btif_cb.latency = latency;
+    btif_cb.timeout = timeout;
+    btif_cb.status = status;
+    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_CONN_PARAM_UPD_EVT,
+                          (char*) &btif_cb, sizeof(btif_conn_param_cb_t), NULL);
+}
+
 static void btgattc_free_event_data(UINT16 event, char *event_data)
 {
     switch (event)
@@ -1254,9 +1423,21 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
             break;
 
         case BTIF_GATTC_WRITE_CHAR:
+        {
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+            /* TODO(jackyc): find a cleaner way to get address from connection id */
+            tGATT_IF gatt_if;
+            BD_ADDR bd_addr;
+            tBT_TRANSPORT transport;
+            if (GATT_GetConnectionInfor(p_cb->conn_id, &gatt_if, bd_addr, &transport) == TRUE)
+            {
+                maybe_restore_connection_parameters(bd_addr);
+            }
+#endif
             BTA_GATTC_WriteCharValue(p_cb->conn_id, p_cb->handle, p_cb->write_type,
                                      p_cb->len, p_cb->value, p_cb->auth_req);
             break;
+        }
 
         case BTIF_GATTC_WRITE_CHAR_DESCR:
             descr_val.len = p_cb->len;
@@ -1553,11 +1734,14 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
             if (BTA_DmGetConnectionState(p_conn_param_cb->bd_addr.address))
             {
                 BTA_DmBleUpdateConnectionParams(p_conn_param_cb->bd_addr.address,
-                               p_conn_param_cb->min_interval, p_conn_param_cb->max_interval,
-                               p_conn_param_cb->latency, p_conn_param_cb->timeout);
+                               p_conn_param_cb->requested_min_interval,
+                               p_conn_param_cb->requested_max_interval,
+                               p_conn_param_cb->latency, p_conn_param_cb->timeout,
+                               bta_gattc_conn_param_update_cback);
             } else {
                 BTA_DmSetBlePrefConnParams(p_conn_param_cb->bd_addr.address,
-                               p_conn_param_cb->min_interval, p_conn_param_cb->max_interval,
+                               p_conn_param_cb->requested_min_interval,
+                               p_conn_param_cb->requested_max_interval,
                                p_conn_param_cb->latency, p_conn_param_cb->timeout);
             }
             break;
@@ -1873,13 +2057,16 @@ static bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu)
                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
 }
 
-static bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t *bd_addr, int min_interval,
-                    int max_interval, int latency, int timeout)
+static bt_status_t btif_gattc_conn_parameter_update_internal(const bt_bdaddr_t *bd_addr, int min_interval,
+                                                    int max_interval, int latency, int timeout)
 {
     CHECK_BTGATT_INIT();
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+    maybe_set_connection_param_update_in_progress(bd_addr, true);
+#endif
     btif_conn_param_cb_t btif_cb;
-    btif_cb.min_interval = min_interval;
-    btif_cb.max_interval = max_interval;
+    btif_cb.requested_min_interval = min_interval;
+    btif_cb.requested_max_interval = max_interval;
     btif_cb.latency = latency;
     btif_cb.timeout = timeout;
     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
@@ -1887,6 +2074,16 @@ static bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t *bd_addr,
                                  (char*) &btif_cb, sizeof(btif_conn_param_cb_t), NULL);
 }
 
+static bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t *bd_addr, int min_interval,
+                                                    int max_interval, int latency, int timeout)
+{
+#if (defined(WEAR_AUTO_CONN_PARAM_UPDATE) && (WEAR_AUTO_CONN_PARAM_UPDATE == TRUE))
+    maybe_enable_auto_connection_param_update(bd_addr, min_interval, max_interval, latency, timeout);
+#endif
+
+    return btif_gattc_conn_parameter_update_internal(bd_addr, min_interval, max_interval, latency, timeout);
+}
+
 static bt_status_t btif_gattc_scan_filter_param_setup(btgatt_filt_param_setup_t
                                                       filt_param)
 {
index 9d963d1..4e23f3f 100644 (file)
@@ -1152,6 +1152,14 @@ static bt_status_t bind_response(bthf_hf_ind_type_t ind_id, bthf_hf_ind_status_t
     return BT_STATUS_SUCCESS;
 }
 
+static bt_status_t set_sco_allowed(bool value)
+{
+    CHECK_BTHF_INIT();
+
+    BTA_AgSetScoAllowed(value);
+    return BT_STATUS_SUCCESS;
+}
+
 /*******************************************************************************
 **
 ** Function         formatted_at_response
@@ -1643,6 +1651,7 @@ static const bthf_interface_t bthfInterface = {
     cleanup,
     configure_wbs,
     bind_response,
+    set_sco_allowed,
 };
 
 /*******************************************************************************
index 262bc53..ef3d4fb 100644 (file)
@@ -494,7 +494,11 @@ UNUSED_ATTR static const char *dump_media_event(UINT16 event)
 
 static void btm_read_rssi_cb(void *data)
 {
-    assert(data);
+    if (data == NULL)
+    {
+        LOG_ERROR(LOG_TAG, "%s RSSI request timed out", __func__);
+        return;
+    }
 
     tBTM_RSSI_RESULTS *result = (tBTM_RSSI_RESULTS*)data;
     if (result->status != BTM_SUCCESS)
index 5221b8c..535f203 100644 (file)
@@ -52,6 +52,8 @@
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
 
+#include "device/include/controller.h"
+
 /************************************************************************************
 **  Constants & Macros
 ************************************************************************************/
 /* This is a local property to add a device found */
 #define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF
 
-#define BTIF_STORAGE_GET_ADAPTER_PROP(t,v,l,p) \
-      {p.type=t;p.val=v;p.len=l; btif_storage_get_adapter_property(&p);}
+// TODO: This macro should be converted to a function
+#define BTIF_STORAGE_GET_ADAPTER_PROP(s, t,v,l,p) \
+      {p.type=t;p.val=v;p.len=l; s = btif_storage_get_adapter_property(&p);}
 
+// TODO: This macro should be converted to a function
 #define BTIF_STORAGE_GET_REMOTE_PROP(b,t,v,l,p) \
       {p.type=t;p.val=v;p.len=l;btif_storage_get_remote_device_property(b,&p);}
 
@@ -587,8 +591,17 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
     if (property->type == BT_PROPERTY_BDADDR)
     {
         bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)property->val;
-        /* This has been cached in btif. Just fetch it from there */
-        memcpy(bd_addr, &btif_local_bd_addr, sizeof(bt_bdaddr_t));
+        /* Fetch the local BD ADDR */
+        const controller_t* controller = controller_get_interface();
+        if (controller->get_is_ready() == false) {
+          BTIF_TRACE_DEBUG("%s: Controller not ready! Unable to return Bluetooth Address",
+                    __FUNCTION__);
+          memset(bd_addr, 0, sizeof(bt_bdaddr_t));
+          return BT_STATUS_FAIL;
+        } else {
+          BTIF_TRACE_DEBUG("%s: Controller ready!", __FUNCTION__);
+          memcpy(bd_addr, controller->get_address(), sizeof(bt_bdaddr_t));
+        }
         property->len = sizeof(bt_bdaddr_t);
         return BT_STATUS_SUCCESS;
     }
@@ -858,6 +871,7 @@ bt_status_t btif_storage_load_bonded_devices(void)
     uint32_t disc_timeout;
     bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
     bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS];
+    bt_status_t status;
 
     btif_in_fetch_bonded_devices(&bonded_devices, 1);
 
@@ -866,12 +880,16 @@ bt_status_t btif_storage_load_bonded_devices(void)
         memset(adapter_props, 0, sizeof(adapter_props));
 
         /* BD_ADDR */
-        BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_BDADDR, &addr, sizeof(addr),
+        BTIF_STORAGE_GET_ADAPTER_PROP(status, BT_PROPERTY_BDADDR, &addr, sizeof(addr),
                                       adapter_props[num_props]);
-        num_props++;
+        // Add BT_PROPERTY_BDADDR property into list only when successful.
+        // Otherwise, skip this property entry.
+        if (status == BT_STATUS_SUCCESS) {
+          num_props++;
+        }
 
         /* BD_NAME */
-        BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_BDNAME, &name, sizeof(name),
+        BTIF_STORAGE_GET_ADAPTER_PROP(status, BT_PROPERTY_BDNAME, &name, sizeof(name),
                                       adapter_props[num_props]);
         num_props++;
 
@@ -887,7 +905,7 @@ bt_status_t btif_storage_load_bonded_devices(void)
         num_props++;
 
         /* DISC_TIMEOUT */
-        BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+        BTIF_STORAGE_GET_ADAPTER_PROP(status, BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
                                       &disc_timeout, sizeof(disc_timeout),
                                       adapter_props[num_props]);
         num_props++;
@@ -905,7 +923,7 @@ bt_status_t btif_storage_load_bonded_devices(void)
         num_props++;
 
         /* LOCAL UUIDs */
-        BTIF_STORAGE_GET_ADAPTER_PROP(BT_PROPERTY_UUIDS,
+        BTIF_STORAGE_GET_ADAPTER_PROP(status, BT_PROPERTY_UUIDS,
                                       local_uuids, sizeof(local_uuids),
                                       adapter_props[num_props]);
         num_props++;
@@ -1426,6 +1444,21 @@ bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr)
 
 /*******************************************************************************
 **
+** Function         btif_storage_get_num_bonded_devices
+**
+** Description      BTIF storage API - Gets the number of bonded devices
+**
+** Returns          the number of bonded devices
+**
+*******************************************************************************/
+int btif_storage_get_num_bonded_devices(void) {
+    btif_bonded_devices_t bonded_devices;
+    btif_in_fetch_bonded_devices(&bonded_devices, 0);
+    return bonded_devices.num_devices;
+}
+
+/*******************************************************************************
+**
 ** Function         btif_storage_read_hl_apps_cb
 **
 ** Description      BTIF storage API - Read HL application control block from NVRAM
index e132221..288f697 100644 (file)
@@ -178,7 +178,9 @@ static void event_shut_down_stack(UNUSED_ATTR void *context) {
   module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just puts it in a restartable state
 
   LOG_INFO(LOG_TAG, "%s finished", __func__);
+  hack_future = future_new();
   btif_thread_post(event_signal_stack_down, NULL);
+  future_await(hack_future);
 }
 
 static void ensure_stack_is_not_running(void) {
@@ -224,6 +226,7 @@ static void event_signal_stack_up(UNUSED_ATTR void *context) {
 
 static void event_signal_stack_down(UNUSED_ATTR void *context) {
   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
+  future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
 }
 
 static void ensure_manager_initialized(void) {
index 05778a8..76a83fc 100644 (file)
@@ -54,16 +54,7 @@ typedef enum {
   // Keyboards should use a variable pin at all times. However, some keyboards
   // require a fixed pin of all 0000. This workaround enables auto pairing for
   // those keyboards.
-  INTEROP_KEYBOARD_REQUIRES_FIXED_PIN,
-
-  // Some headsets have audio jitter issues because of increased re-transmissions as the
-  // 3 Mbps packets have a lower link margin, and are more prone to interference. We can
-  // disable 3DH packets (use only 2DH packets) for the ACL link to improve sensitivity
-  // when streaming A2DP audio to the headset. Air sniffer logs show reduced
-  // re-transmissions after switching to 2DH packets.
-  //
-  // Disable 3Mbps packets and use only 2Mbps packets for ACL links when streaming audio.
-  INTEROP_2MBPS_LINK_ONLY
+  INTEROP_KEYBOARD_REQUIRES_FIXED_PIN
 } interop_feature_t;
 
 // Check if a given |addr| matches a known interoperability workaround as identified
index 49cb8a5..77e0450 100644 (file)
@@ -55,9 +55,6 @@ static const interop_addr_entry_t interop_addr_database[] = {
   {{{0x44, 0x5e, 0xf3,      0,0,0}}, 3, INTEROP_DISABLE_ABSOLUTE_VOLUME},
   {{{0xd4, 0x9c, 0x28,      0,0,0}}, 3, INTEROP_DISABLE_ABSOLUTE_VOLUME},
 
-  // JayBird Family
-  {{{0x00, 0x18, 0x91,      0,0,0}}, 3, INTEROP_2MBPS_LINK_ONLY},
-
   // LG Tone HBS-730 - unacceptably loud volume
   {{{0x00, 0x18, 0x6b,      0,0,0}}, 3, INTEROP_DISABLE_ABSOLUTE_VOLUME},
   {{{0xb8, 0xad, 0x3e,      0,0,0}}, 3, INTEROP_DISABLE_ABSOLUTE_VOLUME},
index 50020f7..8e59394 100644 (file)
@@ -114,7 +114,6 @@ static const char* interop_feature_string_(const interop_feature_t feature) {
     CASE_RETURN_STR(INTEROP_DISABLE_ABSOLUTE_VOLUME)
     CASE_RETURN_STR(INTEROP_DISABLE_AUTO_PAIRING)
     CASE_RETURN_STR(INTEROP_KEYBOARD_REQUIRES_FIXED_PIN)
-    CASE_RETURN_STR(INTEROP_2MBPS_LINK_ONLY)
   }
 
   return "UNKNOWN";
index 50df910..9e53b61 100644 (file)
@@ -143,7 +143,8 @@ static uint64_t btsnoop_timestamp(void) {
   gettimeofday(&tv, NULL);
 
   // Timestamp is in microseconds.
-  uint64_t timestamp = tv.tv_sec * 1000 * 1000LL;
+  uint64_t timestamp = tv.tv_sec;
+  timestamp *= (uint64_t)1000000ULL;
   timestamp += tv.tv_usec;
   timestamp += BTSNOOP_EPOCH_DELTA;
   return timestamp;
index 45e2e78..c339d9f 100644 (file)
@@ -1555,4 +1555,49 @@ The maximum number of payload octets that the local device can receive in a sing
 
 #include "bt_trace.h"
 
+/******************************************************************************
+**
+** Wear
+**
+******************************************************************************/
+
+/* Enable/disable LE IO capability overriding to no-input-no-output on first bond */
+#ifndef WEAR_LE_IO_CAP_OVERRIDE
+#define WEAR_LE_IO_CAP_OVERRIDE               FALSE
+#endif
+
+/*
+ * Enable/disable LE auto connection parameter update.
+ * When enabled, the first bonded device that is also of type LE will be whitelisted
+ * to use auto connection parameter update.
+ */
+#ifndef WEAR_AUTO_CONN_PARAM_UPDATE
+#define WEAR_AUTO_CONN_PARAM_UPDATE           FALSE
+#endif
+
+/*
+ * Idle timeout period in milliseconds for auto connection parameter update.
+ * Only used when WEAR_AUTO_CONN_PARAM_UPDATE is enabled.
+ */
+#ifndef WEAR_AUTO_CONN_IDLE_TIMEOUT_MS
+#define WEAR_AUTO_CONN_IDLE_TIMEOUT_MS        10000
+#endif
+
+/*
+ * Connection interval parameter applied when the connection is detected to be idle for
+ * WEAR_AUTO_CONN_IDLE_TIMEOUT_MS of time.
+ * Only used when WEAR_AUTO_CONN_PARAM_UPDATE is enabled.
+ */
+#ifndef WEAR_AUTO_CONN_IDLE_INTERVAL_1_25_MS
+#define WEAR_AUTO_CONN_IDLE_INTERVAL_1_25_MS  72
+#endif
+
+/*
+ * Disable the use of local GATT cache.  This forces service discovery on connection
+ * establishment.
+ */
+#ifndef WEAR_DISABLE_GATT_CACHE
+#define WEAR_DISABLE_GATT_CACHE               TRUE
+#endif
+
 #endif /* BT_TARGET_H */
index 87c7ad9..26e6258 100644 (file)
@@ -33,7 +33,7 @@
 #include "l2cdefs.h"
 #include "btm_api.h"
 #include "btm_int.h"
-#include "device/include/interop.h"
+
 
 /* callback function declarations */
 void avdt_l2c_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id);
@@ -202,14 +202,12 @@ void avdt_l2c_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8
             p_tbl->state = AVDT_AD_ST_SEC_ACP;
             p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_ACP;
 
-            if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY, (const bt_bdaddr_t *)&bd_addr)) {
-                // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
-                tACL_CONN *p_acl_cb = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR);
-                btm_set_packet_types(p_acl_cb, (btm_cb.btm_acl_pkt_types_supported |
-                                                HCI_PKT_TYPES_MASK_NO_3_DH1 |
-                                                HCI_PKT_TYPES_MASK_NO_3_DH3 |
-                                                HCI_PKT_TYPES_MASK_NO_3_DH5));
-            }
+            // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
+            tACL_CONN *p_acl_cb = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR);
+            btm_set_packet_types(p_acl_cb, (btm_cb.btm_acl_pkt_types_supported |
+                                            HCI_PKT_TYPES_MASK_NO_3_DH1 |
+                                            HCI_PKT_TYPES_MASK_NO_3_DH3 |
+                                            HCI_PKT_TYPES_MASK_NO_3_DH5));
 
             /* Check the security */
             rc = btm_sec_mx_access_request (bd_addr, AVDT_PSM,
@@ -330,14 +328,12 @@ void avdt_l2c_connect_cfm_cback(UINT16 lcid, UINT16 result)
                         p_tbl->lcid = lcid;
                         p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_INT;
 
-                        if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY, (const bt_bdaddr_t *) &p_ccb->peer_addr)) {
-                            // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
-                            tACL_CONN *p_acl_cb = btm_bda_to_acl(p_ccb->peer_addr, BT_TRANSPORT_BR_EDR);
-                            btm_set_packet_types(p_acl_cb, (btm_cb.btm_acl_pkt_types_supported |
-                                                            HCI_PKT_TYPES_MASK_NO_3_DH1 |
-                                                            HCI_PKT_TYPES_MASK_NO_3_DH3 |
-                                                            HCI_PKT_TYPES_MASK_NO_3_DH5));
-                        }
+                        // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
+                        tACL_CONN *p_acl_cb = btm_bda_to_acl(p_ccb->peer_addr, BT_TRANSPORT_BR_EDR);
+                        btm_set_packet_types(p_acl_cb, (btm_cb.btm_acl_pkt_types_supported |
+                                                        HCI_PKT_TYPES_MASK_NO_3_DH1 |
+                                                        HCI_PKT_TYPES_MASK_NO_3_DH3 |
+                                                        HCI_PKT_TYPES_MASK_NO_3_DH5));
 
                         /* Check the security */
                         btm_sec_mx_access_request (p_ccb->peer_addr, AVDT_PSM,
index 4f1568a..d8251da 100644 (file)
@@ -398,7 +398,7 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr,
     if (ret)
     {
         if (!opportunistic)
-            gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, FALSE);
+            gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE);
         else
             GATT_TRACE_DEBUG("%s: connection is opportunistic, not updating app usage",
                             __func__);
index e8b21fe..3175a50 100644 (file)
@@ -29,6 +29,7 @@
 #include "bt_target.h"
 #include "l2cdefs.h"
 #include "hcidefs.h"
+#include "bta_api.h"
 
 /*****************************************************************************
 **  Constants
@@ -1188,8 +1189,9 @@ extern BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda);
 **  Return value:   TRUE if update started
 **
 *******************************************************************************/
-extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int,
-                                         UINT16 max_int, UINT16 latency, UINT16 timeout);
+extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int, UINT16 max_int,
+                                         UINT16 latency, UINT16 timeout,
+                                         tBTA_DM_BLE_CONN_PARAM_CBACK *p_cback);
 
 /*******************************************************************************
 **
index aa855cc..3a421c3 100644 (file)
@@ -32,6 +32,7 @@
 #include "hcimsgs.h"
 #include "device/include/controller.h"
 #include "stack_config.h"
+#include "btif_debug_l2c.h"
 #include "log/log.h"
 
 #if (BLE_INCLUDED == TRUE)
@@ -102,8 +103,9 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
 **  Return value:   TRUE if update started
 **
 *******************************************************************************/
-BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
-                                            UINT16 latency, UINT16 timeout)
+BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int,
+                                  UINT16 max_int, UINT16 latency, UINT16 timeout,
+                                  tBTA_DM_BLE_CONN_PARAM_CBACK *p_callback)
 {
     tL2C_LCB            *p_lcb;
     tACL_CONN           *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
@@ -133,6 +135,7 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in
     p_lcb->latency = latency;
     p_lcb->timeout = timeout;
     p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
+    p_lcb->p_conn_param_update_cb = p_callback;
 
     l2cble_start_conn_update(p_lcb);
 
@@ -502,7 +505,6 @@ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE typ
 *******************************************************************************/
 static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
 {
-    UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
     tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
 
     // TODO(armansito): The return value of this call wasn't being used but the
@@ -514,6 +516,7 @@ static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
 
     if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE)
     {
+        UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
         /* application requests to disable parameters update.
            If parameters are already updated, lets set them
            up to what has been requested during connection establishement */
@@ -562,6 +565,12 @@ static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
                 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->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
+
+                /* Record the BLE connection update request if the role is master device */
+                bt_bdaddr_t bd_addr;
+                bdcpy(bd_addr.address, p_lcb->remote_bd_addr);
+                btif_debug_ble_connection_update_request(bd_addr, p_lcb->min_interval, p_lcb->max_interval,
+                    p_lcb->latency, p_lcb->timeout);
             }
             else
             {
@@ -570,8 +579,10 @@ static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
             }
             p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
             p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
-        }
+
+       }
     }
+
 }
 
 /*******************************************************************************
@@ -606,6 +617,18 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status,
 
     l2cble_start_conn_update(p_lcb);
 
+    /* Callback to upper layer */
+    if (p_lcb->p_conn_param_update_cb) {
+        p_lcb->p_conn_param_update_cb(p_lcb->remote_bd_addr, interval, latency,
+                                      timeout, status);
+    }
+
+    /* Record the BLE connection update response. */
+    bt_bdaddr_t bd_addr;
+    bdcpy(bd_addr.address, p_lcb->remote_bd_addr);
+    btif_debug_ble_connection_update_response(bd_addr, status, interval,
+        latency, timeout);
+
     L2CAP_TRACE_DEBUG("%s: conn_update_mask=%d", __func__, p_lcb->conn_update_mask);
 }
 
@@ -863,10 +886,6 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
 
         case L2CAP_CMD_DISC_REQ:
-            if (p + 4 >= p_pkt_end) {
-              android_errorWriteLog(0x534e4554, "63146237");
-              return;
-            }
             STREAM_TO_UINT16 (lcid, p);
             STREAM_TO_UINT16 (rcid, p);
 
index 8af47d7..0390be7 100644 (file)
@@ -441,6 +441,7 @@ typedef struct t_l2c_linkcb
     UINT16              latency;
     UINT16              timeout;
 
+    tBTA_DM_BLE_CONN_PARAM_CBACK *p_conn_param_update_cb;
 #endif
 
 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
@@ -682,7 +683,7 @@ extern BOOLEAN  l2cu_lcb_disconnecting (void);
 
 extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport);
 extern BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb);
-extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb);
+extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb, UINT16 *fixed_cid);
 extern void    l2cu_resubmit_pending_sec_req (BD_ADDR p_bda);
 extern void    l2cu_initialize_amp_ccb (tL2C_LCB *p_lcb);
 extern void    l2cu_adjust_out_mps (tL2C_CCB *p_ccb);
index 2fefd13..7a50eb2 100644 (file)
@@ -45,7 +45,7 @@
 
 extern fixed_queue_t *btu_general_alarm_queue;
 
-static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf);
+static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf, UINT16 fixed_cid);
 
 /*******************************************************************************
 **
@@ -1065,6 +1065,7 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
 {
     int         xx;
     BOOLEAN     single_write = FALSE;
+    UINT16    fixed_cid;
 
     /* Save the channel ID for faster counting */
     if (p_buf)
@@ -1110,24 +1111,31 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
         /* Loop through, starting at the next */
         for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
         {
+            /* Check for wraparound */
+            if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS])
+                p_lcb = &l2cb.lcb_pool[0];
+
             /* If controller window is full, nothing to do */
-            if (((l2cb.controller_xmit_window == 0 ||
-                  (l2cb.round_robin_unacked >= l2cb.round_robin_quota))
+            if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
+                (l2cb.controller_xmit_window == 0 ||
+                 l2cb.round_robin_unacked >= l2cb.round_robin_quota))
+            {
 #if (BLE_INCLUDED == TRUE)
-                && (p_lcb->transport == BT_TRANSPORT_BR_EDR)
-                )
-              || (p_lcb->transport == BT_TRANSPORT_LE &&
-                 (l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota ||
-                  l2cb.controller_le_xmit_window == 0 )))
+                continue;
 #else
-                ))
+                /* No more quota and only BR/EDR supported, so nothing more to do*/
+                break;
 #endif
-            break;
-
+            }
 
-            /* Check for wraparound */
-            if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS])
-                p_lcb = &l2cb.lcb_pool[0];
+#if (BLE_INCLUDED == TRUE)
+            if (p_lcb->transport == BT_TRANSPORT_LE &&
+                (l2cb.controller_le_xmit_window == 0 ||
+                 l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota))
+            {
+                continue;
+            }
+#endif
 
             if ( (!p_lcb->in_use)
                || (p_lcb->partial_segment_being_sent)
@@ -1140,7 +1148,7 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
             if (!list_is_empty(p_lcb->link_xmit_data_q)) {
                 p_buf = (BT_HDR *)list_front(p_lcb->link_xmit_data_q);
                 list_remove(p_lcb->link_xmit_data_q, p_buf);
-                l2c_link_send_to_lower (p_lcb, p_buf);
+                l2c_link_send_to_lower (p_lcb, p_buf, 0);
             }
             else if (single_write)
             {
@@ -1148,9 +1156,9 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
                 break;
             }
             /* If nothing on the link queue, check the channel queue */
-            else if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) != NULL)
+            else if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb, &fixed_cid)) != NULL)
             {
-                l2c_link_send_to_lower (p_lcb, p_buf);
+                l2c_link_send_to_lower (p_lcb, p_buf, fixed_cid);
             }
         }
 
@@ -1193,7 +1201,7 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
 
             p_buf = (BT_HDR *)list_front(p_lcb->link_xmit_data_q);
             list_remove(p_lcb->link_xmit_data_q, p_buf);
-            if (!l2c_link_send_to_lower (p_lcb, p_buf))
+            if (!l2c_link_send_to_lower (p_lcb, p_buf, 0))
                 break;
         }
 
@@ -1208,10 +1216,10 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
             while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
 #endif
             {
-                if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) == NULL)
+                if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb, &fixed_cid)) == NULL)
                     break;
 
-                if (!l2c_link_send_to_lower (p_lcb, p_buf))
+                if (!l2c_link_send_to_lower (p_lcb, p_buf, fixed_cid))
                     break;
             }
         }
@@ -1237,7 +1245,7 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
 ** Returns          TRUE for success, FALSE for fail
 **
 *******************************************************************************/
-static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
+static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf, UINT16 fixed_cid)
 {
     UINT16      num_segs;
     UINT16      xmit_window, acl_data_size;
@@ -1368,6 +1376,15 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
     }
 #endif
 
+    if (fixed_cid != 0)
+    {
+        L2CAP_TRACE_DEBUG("%s: fixed_cid = %d, send tx complete", __func__, fixed_cid);
+        /* send tx complete */
+        if (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedTxComplete_Cb)
+        {
+            (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedTxComplete_Cb)(fixed_cid, 1);
+        }
+    }
     return TRUE;
 }
 
index 58ac4b0..185aa76 100644 (file)
@@ -1745,6 +1745,12 @@ void l2cu_release_ccb (tL2C_CCB *p_ccb)
     {
         if (!p_lcb->ccb_queue.p_first_ccb)
         {
+            // Closing a security channel on LE device should not start connection
+            // timeout
+            if (p_lcb->transport == BT_TRANSPORT_LE &&
+                p_ccb->local_cid == L2CAP_SMP_CID)
+                return;
+
             l2cu_no_dynamic_ccbs (p_lcb);
         }
         else
@@ -3532,7 +3538,7 @@ static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
 ** Returns          pointer to buffer or NULL
 **
 *******************************************************************************/
-BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
+BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb, UINT16 *fixed_cid)
 {
     tL2C_CCB    *p_ccb;
     BT_HDR      *p_buf;
@@ -3541,6 +3547,7 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
     int         xx;
 
+    *fixed_cid = 0;
     for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
     {
         if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
@@ -3580,9 +3587,11 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
                     L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
                     return (NULL);
                 }
-                /* send tx complete */
-                if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)
-                    (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1);
+                if (fixed_cid != NULL)
+                {
+                    *fixed_cid = p_ccb->local_cid;
+                    L2CAP_TRACE_DEBUG("l2cu_get_buffer_to_send: fixed_cid = %d", *fixed_cid);
+                }
 
                 l2cu_check_channel_congestion (p_ccb);
                 l2cu_set_acl_hci_header (p_buf, p_ccb);