• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/bt


Commit MetaInfo

Revisione7bec445b8d20e153fcf7cb46c0da6020d1c96fd (tree)
Zeit2017-04-14 17:47:18
AutorLinux Build Service Account <lnxbuild@loca...>
CommiterLinux Build Service Account

Log Message

Promotion of bt.lnx.2.1.c1-00046.

CRs Change ID Subject


Ia79483c72d3b0cfc1e339f9f4ac65295e68e8e5d Add dumpsys support for LE connection parameter updates
I3c165843bb76c372b76bdc18a7d9226345d39037 Fix incorrect check for empty out-of-band pairing data
Iaf1b1dd746dd52ab7e50b870efacde2b8dd0bed6 DO NOT MERGE ANYWHERE Fix the timestamp in btsnoop forma
I73ad281437760e1d61dd4e504401b270eb77e3e6 DO NOT MERGE ANYWHERE LE Connection Parameter Update Cal
I1732be86dd888586c603112fb6c3010974b54a13 DO NOT MERGE ANYWHERE Add Wear-specific feature to overr
I7f8a052e78706c8c72c5102b38cfe9ce200ae0d9 Remove position dependent lookup tables in AT command pa
Ibd9301a990f12a94e8043b9c29a480f068251ba8 Fix how LE connection parameters are set after connectin
Ibd8f8b85eb59be8bfbb8a7c83b5935802624a748 Move btsnoop_hci.log to /data/misc/bluetooth/logs
Iea2a997c4ea074687a5d50860e9229f0e1b82659 Fix A2DP metrics session duration
Ic96205b5c304acb44eab53f4e2cb150726643bda Serialize stack shutdown, state change callback and clea
If2ca53c7b22a346e7236514ea7b461695c923f74 Cleanup GATT cache when remote device is disconnected
Ibe500e332dba8f44485b44bcac32d11be52520a6 Add extra logs by default inside sdp_copy_raw_data()
I27619098df33a641cb089b82cf4d4ffd3c6e6aea Fix NPE when discovering invalid GATT datatbase
I28cf4f6d5dcfb7a0bfb6aa652d939e16fbdcdcde DO NOT MERGE ANYWHERE Auto Connection Parameter Update f
I4bb3fb02cffdcc5b1273f8ace281826eccce6639 Improve HOGP input report error handling
Ide9dee819e1db24a39c05b086cd4c0b558ca23ef [DO NOT MERGE] Remove incorrect assert in btm_read_rssi_
I2cc6f9304725938b63b211d615eb1941eac60edf Fix A2DP Metrics Logging Capacity
I10984920afd4d77f07a5ac75736f8dcd69b13af8 Corrected default value assignments in Bluetooth A2DP Me
I216142090fe99b25ef7697fceceb278b761a182b Add LE Secure Connection data parsing (3/4)
I61f06a9d878dd72154d6621eb094dcea5f701cbc Assign pairing code to bta_dm_cb before device name reso
I683eccd53d40e79ec03545166b18ffa1922f0fb2 Fix HFP AT command BIA failures
Iac8684bdfd02b18cce260bedefb829e8f7285361 Mask out HFP 1.7 feature bits if peer version is <1.7
I7f8a052e78706c8c72c5102b38cfe9ce200ae0d9 Remove position dependent lookup tables in AT command pa
I51cb73666ac58e4792d9cba0d6f16dad30a0ff39 Add LeakyBondedQueue to libosi
Idc0315e9e3f9e17c3cf56fa483c8e21eb3590f01 BLE OOB Pairing - parse address type (1/5)
I4540230c792490f79e4cca24cb4b34a1c383422f DO NOT MERGE ANYWHERE Do not update sco_state when no ma

Change-Id: Iad5b862b89b66ceb0345caf8f5a3c0bf44b0c21c

Ändern Zusammenfassung

Diff

--- a/bta/ag/bta_ag_cmd.c
+++ b/bta/ag/bta_ag_cmd.c
@@ -177,7 +177,7 @@ enum
177177 BTA_AG_RES_FMT_STR /* string argument */
178178 };
179179
180-/* enumeration of AT result codes, matches constant table */
180+/* Local AT command result codes not defined in bta_ag_api.h */
181181 enum
182182 {
183183 BTA_AG_RES_OK,
@@ -207,7 +207,7 @@ enum
207207 #if defined(BTA_HSP_RESULT_REPLACE_COLON) && (BTA_HSP_RESULT_REPLACE_COLON == TRUE)
208208 #define COLON_IDX_4_VGSVGM 4
209209 #endif
210-/* AT result code constant table (Indexed by result code) */
210+/* AT result code constant table */
211211 const tBTA_AG_RESULT bta_ag_result_tbl[] =
212212 {
213213 {"OK", BTA_AG_RES_FMT_NONE},
@@ -234,6 +234,7 @@ const tBTA_AG_RESULT bta_ag_result_tbl[] =
234234 {"+BIND: ", BTA_AG_RES_FMT_STR},
235235 };
236236
237+
237238 const tBTA_AG_AT_CMD *bta_ag_at_tbl[BTA_AG_NUM_IDX] =
238239 {
239240 bta_ag_hsp_cmd,
@@ -350,10 +351,10 @@ const UINT8 bta_ag_callsetup_ind_tbl[] =
350351 static void bta_ag_send_result(tBTA_AG_SCB *p_scb, UINT8 code, char *p_arg,
351352 INT16 int_arg)
352353 {
353- char buf[BTA_AG_AT_MAX_LEN + 16];
354- char *p = buf;
355- UINT16 len;
356354
355+ char buf[BTA_AG_AT_MAX_LEN + 16];
356+ char *p = buf;
357+ UINT16 len;
357358 #if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
358359 memset(buf, NULL, sizeof(buf));
359360 #endif
@@ -364,7 +365,7 @@ static void bta_ag_send_result(tBTA_AG_SCB *p_scb, UINT8 code, char *p_arg,
364365 /* copy result code string */
365366 strlcpy(p, bta_ag_result_tbl[code].p_res, sizeof(buf) - 2);
366367 #if defined(BTA_HSP_RESULT_REPLACE_COLON) && (BTA_HSP_RESULT_REPLACE_COLON == TRUE)
367- if(p_scb->conn_service == BTA_AG_HSP)
368+ if (p_scb->conn_service == BTA_AG_HSP)
368369 {
369370 /* If HSP then ":"symbol should be changed as "=" for HSP compatibility */
370371 switch(code)
@@ -972,7 +973,6 @@ void bta_ag_at_hsp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
972973 char *p_arg, INT16 int_arg)
973974 {
974975 tBTA_AG_VAL val;
975-
976976 APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
977977 int_arg, p_arg);
978978
@@ -987,7 +987,6 @@ void bta_ag_at_hsp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
987987 /* call callback with event */
988988 (*bta_ag_cb.p_cback)(bta_ag_hsp_cb_evt[cmd], (tBTA_AG *) &val);
989989 }
990-
991990 /*******************************************************************************
992991 **
993992 ** Function bta_ag_at_hfp_cback
@@ -1368,6 +1367,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
13681367
13691368 case BTA_AG_HF_CMD_CNUM:
13701369 break;
1370+
13711371 case BTA_AG_HF_CMD_CLCC:
13721372 if(!(p_scb->features & BTA_AG_FEAT_ECS))
13731373 {
@@ -1562,7 +1562,6 @@ void bta_ag_at_err_cback(tBTA_AG_SCB *p_scb, BOOLEAN unknown, char *p_arg)
15621562 void bta_ag_hsp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
15631563 {
15641564 UINT8 code = bta_ag_trans_result[p_result->result];
1565-
15661565 APPL_TRACE_DEBUG("bta_ag_hsp_result : res = %d", p_result->result);
15671566
15681567 switch(p_result->result)
--- a/bta/ag/bta_ag_int.h
+++ b/bta/ag/bta_ag_int.h
@@ -28,6 +28,7 @@
2828 #include "bta_api.h"
2929 #include "bta_ag_api.h"
3030 #include "bta_ag_at.h"
31+#include "osi/include/log.h"
3132
3233 /* Send RING & CLIP in one AT cmd */
3334 #ifndef BTA_AG_MULTI_RESULT_INCLUDED
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -2952,6 +2952,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
29522952 /*case BTM_SP_KEY_REQ_EVT: */
29532953 case BTM_SP_KEY_NOTIF_EVT:
29542954 #endif
2955+ bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
2956+
29552957 if(BTM_SP_CFM_REQ_EVT == event)
29562958 {
29572959 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
@@ -2982,7 +2984,6 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
29822984 }
29832985 }
29842986
2985- bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
29862987 if (BTM_SP_KEY_NOTIF_EVT == event)
29872988 {
29882989 /* If the device name is not known, save bdaddr and devclass
@@ -4482,6 +4483,11 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
44824483 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
44834484 break;
44844485
4486+ case BTM_LE_SC_OOB_REQ_EVT:
4487+ bdcpy(sec_event.ble_req.bd_addr, bda);
4488+ bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event);
4489+ break;
4490+
44854491 case BTM_LE_KEY_EVT:
44864492 bdcpy(sec_event.ble_key.bd_addr, bda);
44874493 sec_event.ble_key.key_type = p_data->key.key_type;
--- a/bta/gatt/bta_gattc_cache.c
+++ b/bta/gatt/bta_gattc_cache.c
@@ -326,7 +326,8 @@ static tBTA_GATT_STATUS bta_gattc_add_attr_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
326326 descriptor->handle = handle;
327327 memcpy(&descriptor->uuid, p_uuid, sizeof(tBT_UUID));
328328
329- if (service->characteristics == NULL) {
329+ if (service->characteristics == NULL ||
330+ list_is_empty(service->characteristics)) {
330331 APPL_TRACE_ERROR("%s: Illegal action to add descriptor before adding a characteristic!",
331332 __func__);
332333 osi_free(descriptor);
--- a/bta/gatt/bta_gattc_utils.c
+++ b/bta/gatt/bta_gattc_utils.c
@@ -302,6 +302,12 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
302302 p_srcb->connected = FALSE;
303303 p_srcb->state = BTA_GATTC_SERV_IDLE;
304304 p_srcb->mtu = 0;
305+
306+ /* clean up cache */
307+ if (p_srcb->p_srvc_cache) {
308+ list_free(p_srcb->p_srvc_cache);
309+ p_srcb->p_srvc_cache = NULL;
310+ }
305311 }
306312
307313 osi_free_and_reset((void **)&p_clcb->p_q_cmd);
--- a/bta/hh/bta_hh_le.c
+++ b/bta/hh/bta_hh_le.c
@@ -2182,12 +2182,19 @@ void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY *p_data)
21822182
21832183 if (p_dev_cb == NULL)
21842184 {
2185- APPL_TRACE_ERROR("notification received from Unknown device");
2185+ APPL_TRACE_ERROR("%s: notification received from Unknown device, conn_id: 0x%04x",
2186+ __func__, p_data->conn_id);
21862187 return;
21872188 }
21882189
21892190 const tBTA_GATTC_CHARACTERISTIC *p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id,
21902191 p_data->handle);
2192+ if (p_char == NULL)
2193+ {
2194+ APPL_TRACE_ERROR("%s: notification received for Unknown Characteristic, conn_id: 0x%04x, handle: 0x%04x",
2195+ __func__, p_dev_cb->conn_id, p_data->handle);
2196+ return;
2197+ }
21912198
21922199 if (p_char == NULL) {
21932200 APPL_TRACE_ERROR("%s: notification received for Unknown Characteristic,handle: 0x%04x",
@@ -2208,7 +2215,8 @@ void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY *p_data)
22082215 p_char->handle);
22092216 if (p_rpt == NULL)
22102217 {
2211- APPL_TRACE_ERROR("notification received for Unknown Report");
2218+ APPL_TRACE_ERROR("%s: notification received for Unknown Report, uuid: 0x%04x, handle: 0x%04x",
2219+ __func__, p_char->uuid.uu.uuid16, p_char->handle);
22122220 return;
22132221 }
22142222
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -593,7 +593,8 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
593593 #define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */
594594 #define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */
595595 #define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
596-typedef UINT8 tBTA_DM_SEC_EVT;
596+#define BTA_DM_BLE_SC_OOB_REQ_EVT 29 /* SMP SC OOB request event */
597+typedef uint8_t tBTA_DM_SEC_EVT;
597598
598599 /* Structure associated with BTA_DM_ENABLE_EVT */
599600 typedef struct
--- a/btif/Android.mk
+++ b/btif/Android.mk
@@ -36,6 +36,7 @@ btifCommonSrc += \
3636 src/btif_debug.c \
3737 src/btif_debug_btsnoop.c \
3838 src/btif_debug_conn.c \
39+ src/btif_debug_l2c.c \
3940 src/btif_dm.c \
4041 src/btif_gatt.c \
4142 src/btif_gatt_client.c \
--- a/btif/co/bta_dm_co.c
+++ b/btif/co/bta_dm_co.c
@@ -24,6 +24,9 @@
2424 #include "bta_dm_ci.h"
2525 #include "bt_utils.h"
2626 #include "btif_dm.h"
27+#if (defined WEAR_LE_IO_CAP_OVERRIDE && WEAR_LE_IO_CAP_OVERRIDE == TRUE)
28+#include "btif_storage.h"
29+#endif
2730 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
2831 #include "bte_appl.h"
2932
@@ -408,7 +411,24 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
408411 tBTA_LE_KEY_TYPE *p_resp_key )
409412 {
410413 UNUSED(bd_addr);
411- /* Retrieve the properties from file system if possible */
414+
415+
416+#if (defined WEAR_LE_IO_CAP_OVERRIDE && WEAR_LE_IO_CAP_OVERRIDE == TRUE)
417+ /*
418+ * Note: This is a Wear-specific feature for iOS pairing.
419+ *
420+ * Set WearLeIoCap config to force local IO capability to be BTM_IO_CAP_NONE
421+ * (No input, no output) for the first bond creation, that indirectly
422+ * triggers Just Works pairing.
423+ */
424+ if (btif_storage_get_num_bonded_devices() == 0)
425+ bte_appl_cfg.ble_io_cap = BTM_IO_CAP_NONE;
426+#endif
427+
428+ /* For certification testing purpose, LE IO capability can also be specified with
429+ * "PTS_SmpOptions" in the BT stack configuration file (i.e. bt_stack.conf).
430+ * Note that if "PTS_SmpOptions" is set, it could override IO capability set above.
431+ */
412432 tBTE_APPL_CFG nv_config;
413433 if(btif_dm_get_smp_config(&nv_config))
414434 bte_appl_cfg = nv_config;
--- /dev/null
+++ b/btif/include/btif_debug_l2c.h
@@ -0,0 +1,54 @@
1+/******************************************************************************
2+ *
3+ * Copyright (C) 2016 Google Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+
19+#pragma once
20+
21+#include <stdint.h>
22+
23+#include <hardware/bluetooth.h>
24+
25+// Captures a BLE connection parameter update request (Section 4.20 of
26+// Bluetooth Core V4.2 specification):
27+//
28+// |min_interval| and |max_interval| define the minimum and maximum values for
29+// the connection event interval (in units of 1.25ms and should be in the
30+// [6, 3200] range).
31+// |slave_latency_param| is the slave latency parameter for the connection in
32+// number of connection events (unitless and should be less than 500).
33+// |timeout_multiplier| is the connection timeout parameter (in units of 10ms
34+// and should be in the [10, 3200] range).
35+void btif_debug_ble_connection_update_request(bt_bdaddr_t bda,
36+ uint16_t min_interval, uint16_t max_interval, uint16_t slave_latency_param,
37+ uint16_t timeout_multiplier);
38+
39+// Captures a BLE connection parameter update response ((Section 4.21 of
40+// Bluetooth Core V4.2 specification):
41+//
42+// |interval| defines the minimum and maximum values for the
43+// connection event interval (in units of 1.25ms and should be in the
44+// [6, 3200] range).
45+// |slave_latency_param| is the slave latency parameter for the connection in
46+// number of connection events (unitless and should be less than 500).
47+// |timeout_multiplier| is the connection timeout parameter (in units of 10ms
48+// and should be in the [10, 3200] range).
49+void btif_debug_ble_connection_update_response(bt_bdaddr_t bda, uint8_t status,
50+ uint16_t interval, uint16_t slave_latency_param,
51+ uint16_t timeout_multiplier);
52+
53+// Dumps captured L2C information.
54+void btif_debug_l2c_dump(int fd);
--- a/btif/include/btif_storage.h
+++ b/btif/include/btif_storage.h
@@ -286,6 +286,16 @@ bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr);
286286 *******************************************************************************/
287287 BOOLEAN btif_storage_is_restricted_device(const bt_bdaddr_t *remote_bd_addr);
288288
289+/*******************************************************************************
290+**
291+** Function btif_storage_get_num_bonded_devices
292+**
293+** Description BTIF storage API - Gets the number of bonded devices
294+**
295+** Returns the number of bonded devices
296+**
297+*******************************************************************************/
298+int btif_storage_get_num_bonded_devices(void);
289299 #if (BLE_INCLUDED == TRUE)
290300 bt_status_t btif_storage_add_ble_bonding_key( bt_bdaddr_t *remote_bd_addr,
291301 char *key,
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -68,6 +68,7 @@
6868 #include "btif_storage.h"
6969 #include "btif/include/btif_debug_btsnoop.h"
7070 #include "btif/include/btif_debug_conn.h"
71+#include "btif/include/btif_debug_l2c.h"
7172 #include "btif/include/btif_media.h"
7273 #include "l2cdefs.h"
7374 #include "l2c_api.h"
@@ -392,20 +393,15 @@ static int read_energy_info()
392393 static void dump(int fd, const char **arguments)
393394 {
394395 if (arguments != NULL && arguments[0] != NULL) {
395- if (strncmp(arguments[0], "--proto-text", 12) == 0) {
396- btif_update_a2dp_metrics();
397- metrics_print(fd, true);
398- return;
399- }
400396 if (strncmp(arguments[0], "--proto-bin", 11) == 0) {
401- btif_update_a2dp_metrics();
402- metrics_write(fd, true);
397+ metrics_write_base64(fd, true);
403398 return;
404399 }
405400 }
406401 btif_debug_conn_dump(fd);
407402 btif_debug_bond_event_dump(fd);
408403 btif_debug_a2dp_dump(fd);
404+ btif_debug_l2c_dump(fd);
409405 btif_debug_config_dump(fd);
410406 wakelock_debug_dump(fd);
411407 alarm_debug_dump(fd);
--- /dev/null
+++ b/btif/src/btif_debug_l2c.c
@@ -0,0 +1,159 @@
1+/******************************************************************************
2+ *
3+ * Copyright (C) 2016 Google Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+
19+#include <stdio.h>
20+#include <stdint.h>
21+#include <string.h>
22+#include <time.h>
23+
24+#include "btcore/include/bdaddr.h"
25+#include "btif/include/btif_debug.h"
26+#include "btif/include/btif_debug_l2c.h"
27+
28+#define NUM_UPDATE_REQUESTS 5
29+#define NUM_UPDATE_RESPONSES 5
30+
31+#define INTERVAL_1_25_MS_MULTIPLIER 1.25f
32+#define TIMEOUT_10_MS_MULTIPLIER 10
33+
34+typedef enum {
35+ BTIF_DEBUG_CONNECTION_UPDATE_REQUEST,
36+ BTIF_DEBUG_CONNECTION_UPDATE_RESPONSE,
37+} btif_debug_ble_conn_update_t;
38+
39+/* Shared Connection update record for both request and response. */
40+typedef struct ble_conn_update_t {
41+ uint64_t timestamp_ms;
42+ bt_bdaddr_t bda;
43+ btif_debug_ble_conn_update_t type;
44+ uint8_t status; /* Not populated for request. */
45+ uint16_t min_interval; /* Not populated for response. */
46+ uint16_t max_interval;
47+ uint16_t latency;
48+ uint16_t timeout;
49+} ble_conn_update_t;
50+
51+static int update_request_index;
52+static int update_response_index;
53+static ble_conn_update_t last_ble_conn_update_requests[NUM_UPDATE_REQUESTS];
54+static ble_conn_update_t last_ble_conn_update_responses[NUM_UPDATE_RESPONSES];
55+
56+static int dump_connection_update(int fd, const ble_conn_update_t *update) {
57+ if (!update || update->timestamp_ms == 0) {
58+ return -1;
59+ }
60+
61+ /* Format timestamp */
62+ const uint64_t msecs = update->timestamp_ms / 1000;
63+ const time_t secs = msecs / 1000;
64+ struct tm *ptm = localtime(&secs);
65+ char time_buf[20] = {0};
66+ strftime(time_buf, sizeof(time_buf), "%m-%d %H:%M:%S", ptm);
67+ snprintf(time_buf, sizeof(time_buf), "%s.%03u", time_buf,
68+ (uint16_t)(msecs % 1000));
69+
70+ /* Format address */
71+ char addr_buf[18] = {0};
72+ bdaddr_to_string(&update->bda, addr_buf, sizeof(addr_buf));
73+
74+ if (update->type == BTIF_DEBUG_CONNECTION_UPDATE_REQUEST) {
75+ dprintf(fd,
76+ " %s %s min interval=%d (%.2fms) max interval=%d (%.2fms) "
77+ "latency parameter=%d timeout multiplier=%d (%dms)\n",
78+ time_buf, addr_buf, update->min_interval,
79+ (float)update->min_interval * INTERVAL_1_25_MS_MULTIPLIER,
80+ update->max_interval,
81+ (float)update->max_interval * INTERVAL_1_25_MS_MULTIPLIER,
82+ update->latency, update->timeout,
83+ update->timeout * TIMEOUT_10_MS_MULTIPLIER);
84+ } else {
85+ dprintf(fd,
86+ " %s %s status=%d interval=%d (%.2fms) latency parameter=%d "
87+ "timeout multiplier=%d (%dms)\n", time_buf,
88+ addr_buf, update->status, update->max_interval,
89+ (float)update->max_interval * INTERVAL_1_25_MS_MULTIPLIER,
90+ update->latency, update->timeout,
91+ update->timeout * TIMEOUT_10_MS_MULTIPLIER);
92+ }
93+
94+ return 0;
95+}
96+
97+static void record_connection_update(bt_bdaddr_t bda, uint8_t status,
98+ uint16_t min_interval, uint16_t max_interval, uint16_t latency,
99+ uint16_t timeout, btif_debug_ble_conn_update_t type,
100+ ble_conn_update_t* update) {
101+
102+ memcpy(&update->bda, &bda, sizeof(bt_bdaddr_t));
103+ update->type = type;
104+ update->timestamp_ms = btif_debug_ts();
105+ update->min_interval = min_interval;
106+ update->max_interval = max_interval;
107+ update->latency = latency;
108+ update->timeout = timeout;
109+ update->status = 0;
110+}
111+
112+void btif_debug_ble_connection_update_request(bt_bdaddr_t bda,
113+ uint16_t min_interval, uint16_t max_interval, uint16_t slave_latency_param,
114+ uint16_t timeout_multiplier) {
115+ ble_conn_update_t *request =
116+ &last_ble_conn_update_requests[update_request_index];
117+
118+ record_connection_update(bda, 0, min_interval, max_interval, slave_latency_param,
119+ timeout_multiplier, BTIF_DEBUG_CONNECTION_UPDATE_REQUEST, request);
120+
121+ update_request_index = (update_request_index == NUM_UPDATE_REQUESTS - 1) ?
122+ 0 : update_request_index + 1;
123+}
124+
125+void btif_debug_ble_connection_update_response(bt_bdaddr_t bda, uint8_t status,
126+ uint16_t interval, uint16_t slave_latency_param,
127+ uint16_t timeout_multiplier) {
128+ ble_conn_update_t *response =
129+ &last_ble_conn_update_responses[update_response_index];
130+
131+ record_connection_update(bda, status, 0, interval, slave_latency_param,
132+ timeout_multiplier, BTIF_DEBUG_CONNECTION_UPDATE_RESPONSE, response);
133+
134+ update_response_index = (update_response_index == NUM_UPDATE_RESPONSES - 1) ?
135+ 0 : update_response_index + 1;
136+}
137+
138+void btif_debug_l2c_dump(int fd) {
139+ dprintf(fd, "\nLE Connection Parameter Updates:\n");
140+
141+ int i;
142+ dprintf(fd, " Last %d Request(s):\n", NUM_UPDATE_REQUESTS);
143+ for (i = 0; i < NUM_UPDATE_REQUESTS; ++i) {
144+ if (dump_connection_update(fd, &last_ble_conn_update_requests[i]) < 0 &&
145+ i == 0) {
146+ dprintf(fd, " None\n");
147+ break;
148+ }
149+ }
150+
151+ dprintf(fd, "\n Last %d Response(s):\n", NUM_UPDATE_RESPONSES);
152+ for (i = 0; i < NUM_UPDATE_RESPONSES; ++i) {
153+ if (dump_connection_update(fd, &last_ble_conn_update_responses[i]) < 0 &&
154+ i == 0) {
155+ dprintf(fd, " None\n");
156+ break;
157+ }
158+ }
159+}
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -230,6 +230,7 @@ static void btif_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl);
230230 static void btif_dm_ble_passkey_req_evt(tBTA_DM_PIN_REQ *p_pin_req);
231231 static void btif_dm_ble_key_nc_req_evt(tBTA_DM_SP_KEY_NOTIF *p_notif_req) ;
232232 static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB *req_oob_type);
233+static void btif_dm_ble_sc_oob_req_evt(tBTA_DM_SP_RMT_OOB *req_oob_type);
233234 #endif
234235
235236 static void bte_scan_filt_param_cfg_evt(UINT8 action_type,
@@ -818,7 +819,15 @@ static void btif_dm_cb_create_bond(bt_bdaddr_t *bd_addr, tBTA_TRANSPORT transpor
818819 }
819820 if (btif_storage_get_remote_addr_type(bd_addr, &addr_type) != BT_STATUS_SUCCESS)
820821 {
821- btif_storage_set_remote_addr_type(bd_addr, BLE_ADDR_PUBLIC);
822+
823+ // Try to read address type. OOB pairing might have set it earlier, but
824+ // didn't store it, it defaults to BLE_ADDR_PUBLIC
825+ uint8_t tmp_dev_type;
826+ uint8_t tmp_addr_type;
827+ BTM_ReadDevInfo(bd_addr->address, &tmp_dev_type, &tmp_addr_type);
828+ addr_type = tmp_addr_type;
829+
830+ btif_storage_set_remote_addr_type(bd_addr, addr_type);
822831 }
823832 }
824833 if((btif_config_get_int((char const *)&bdstr,"DevType", &device_type) &&
@@ -1878,7 +1887,7 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
18781887 uint32_t i;
18791888 bt_bdaddr_t bd_addr;
18801889
1881- BTIF_TRACE_EVENT("btif_dm_upstreams_cback ev: %s", dump_dm_event(event));
1890+ BTIF_TRACE_EVENT("%s: ev: %s", __func__, dump_dm_event(event));
18821891
18831892 switch (event)
18841893 {
@@ -2162,6 +2171,10 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
21622171 BTIF_TRACE_DEBUG("BTA_DM_BLE_OOB_REQ_EVT. ");
21632172 btif_dm_ble_oob_req_evt(&p_data->rmt_oob);
21642173 break;
2174+ case BTA_DM_BLE_SC_OOB_REQ_EVT:
2175+ BTIF_TRACE_DEBUG("BTA_DM_BLE_SC_OOB_REQ_EVT. ");
2176+ btif_dm_ble_sc_oob_req_evt(&p_data->rmt_oob);
2177+ break;
21652178 case BTA_DM_BLE_LOCAL_IR_EVT:
21662179 BTIF_TRACE_DEBUG("BTA_DM_BLE_LOCAL_IR_EVT. ");
21672180 ble_local_key_cb.is_id_keys_rcvd = TRUE;
@@ -2630,6 +2643,19 @@ bt_status_t btif_dm_create_bond_out_of_band(const bt_bdaddr_t *bd_addr, int tran
26302643 bdcpy(oob_cb.bdaddr, bd_addr->address);
26312644 memcpy(&oob_cb.oob_data, oob_data, sizeof(bt_out_of_band_data_t));
26322645
2646+ uint8_t empty[] = {0, 0, 0, 0, 0, 0, 0};
2647+ // If LE Bluetooth Device Address is provided, use provided address type
2648+ // value.
2649+ if (memcmp(oob_data->le_bt_dev_addr, empty, 7) != 0) {
2650+ /* byte no 7 is address type in LE Bluetooth Address OOB data */
2651+ uint8_t address_type = oob_data->le_bt_dev_addr[6];
2652+ if (address_type == BLE_ADDR_PUBLIC || address_type == BLE_ADDR_RANDOM) {
2653+ // bd_addr->address is already reversed, so use it instead of
2654+ // oob_data->le_bt_dev_addr
2655+ BTM_SecAddBleDevice(bd_addr->address, NULL, BT_DEVICE_TYPE_BLE, address_type);
2656+ }
2657+ }
2658+
26332659 bdstr_t bdstr;
26342660 BTIF_TRACE_EVENT("%s: bd_addr=%s, transport=%d", __FUNCTION__, bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)), transport);
26352661 return btif_dm_create_bond(bd_addr, transport);
@@ -3102,29 +3128,36 @@ void btif_dm_set_oob_for_le_io_req(BD_ADDR bd_addr, tBTA_OOB_DATA *p_has_oob_da
31023128 tBTA_LE_AUTH_REQ *p_auth_req)
31033129 {
31043130
3105- /* We currently support only Security Manager TK as OOB data for LE transport.
3106- If it's not present mark no OOB data.
3107- */
3108- if (!is_empty_128bit(oob_cb.oob_data.sm_tk))
3109- {
3131+ if (!is_empty_128bit(oob_cb.oob_data.le_sc_c) &&
3132+ !is_empty_128bit(oob_cb.oob_data.le_sc_r)) {
3133+ /* We have LE SC OOB data */
3134+
3135+ /* make sure OOB data is for this particular device */
3136+ if (memcmp(bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) == 0) {
3137+ *p_auth_req = ((*p_auth_req) | BTM_LE_AUTH_REQ_SC_ONLY);
3138+ *p_has_oob_data = true;
3139+ } else {
3140+ *p_has_oob_data = false;
3141+ BTIF_TRACE_WARNING("%s: remote address didn't match OOB data address",
3142+ __func__);
3143+ }
3144+ } else if (!is_empty_128bit(oob_cb.oob_data.sm_tk)) {
3145+ /* We have security manager TK */
3146+
31103147 /* make sure OOB data is for this particular device */
31113148 if (memcmp(bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) == 0) {
31123149 // When using OOB with TK, SC Secure Connections bit must be disabled.
31133150 tBTA_LE_AUTH_REQ mask = ~BTM_LE_AUTH_REQ_SC_ONLY;
31143151 *p_auth_req = ((*p_auth_req) & mask);
31153152
3116- *p_has_oob_data = TRUE;
3117- }
3118- else
3119- {
3120- *p_has_oob_data = FALSE;
3153+ *p_has_oob_data = true;
3154+ } else {
3155+ *p_has_oob_data = false;
31213156 BTIF_TRACE_WARNING("%s: remote address didn't match OOB data address",
31223157 __func__);
31233158 }
3124- }
3125- else
3126- {
3127- *p_has_oob_data = FALSE;
3159+ } else {
3160+ *p_has_oob_data = false;
31283161 }
31293162 BTIF_TRACE_DEBUG("%s *p_has_oob_data=%d", __func__, *p_has_oob_data);
31303163 }
@@ -3625,10 +3658,9 @@ static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB *req_oob_type)
36253658
36263659 bt_bdaddr_t bd_addr;
36273660 bdcpy(bd_addr.address, req_oob_type->bd_addr);
3628-
3629- /* We currently support only Security Manager TK as OOB data. We already
3630- * checked if it's present in btif_dm_set_oob_for_le_io_req, but check here
3631- * again. If it's not present do nothing, pairing will timeout.
3661+ /* We already checked if OOB data is present in
3662+ * btif_dm_set_oob_for_le_io_req, but check here again. If it's not present
3663+ * do nothing, pairing will timeout.
36323664 */
36333665 if (is_empty_128bit(oob_cb.oob_data.sm_tk)) {
36343666 return;
@@ -3652,6 +3684,44 @@ static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB *req_oob_type)
36523684 BTM_BleOobDataReply(req_oob_type->bd_addr, 0, 16, oob_cb.oob_data.sm_tk);
36533685 }
36543686
3687+
3688+static void btif_dm_ble_sc_oob_req_evt(tBTA_DM_SP_RMT_OOB *req_oob_type)
3689+{
3690+ BTIF_TRACE_DEBUG("%s", __func__);
3691+
3692+ bt_bdaddr_t bd_addr;
3693+ bdcpy(bd_addr.address, req_oob_type->bd_addr);
3694+
3695+ /* We already checked if OOB data is present in
3696+ * btif_dm_set_oob_for_le_io_req, but check here again. If it's not present
3697+ * do nothing, pairing will timeout.
3698+ */
3699+ if (is_empty_128bit(oob_cb.oob_data.le_sc_c) &&
3700+ is_empty_128bit(oob_cb.oob_data.le_sc_r)) {
3701+ BTIF_TRACE_WARNING("%s: LE SC OOB data is empty", __func__);
3702+ return;
3703+ }
3704+
3705+ /* make sure OOB data is for this particular device */
3706+ if (memcmp(req_oob_type->bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) != 0) {
3707+ BTIF_TRACE_WARNING("%s: remote address didn't match OOB data address", __func__);
3708+ return;
3709+ }
3710+
3711+ /* Remote name update */
3712+ btif_update_remote_properties(req_oob_type->bd_addr , req_oob_type->bd_name,
3713+ NULL, BT_DEVICE_TYPE_BLE);
3714+
3715+ bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
3716+ pairing_cb.is_ssp = false;
3717+ pairing_cb.is_le_only = true; //TODO: we can derive classic pairing from this one
3718+ pairing_cb.is_le_nc = false;
3719+
3720+ BTM_BleSecureConnectionOobDataReply(req_oob_type->bd_addr,
3721+ oob_cb.oob_data.le_sc_c,
3722+ oob_cb.oob_data.le_sc_r);
3723+}
3724+
36553725 void btif_dm_update_ble_remote_properties( BD_ADDR bd_addr, BD_NAME bd_name,
36563726 tBT_DEVICE_TYPE dev_type)
36573727 {
@@ -3797,7 +3867,7 @@ static void btif_stats_add_bond_event(const bt_bdaddr_t *bd_addr,
37973867 uint32_t cod = get_cod(bd_addr);
37983868 uint64_t ts = event->timestamp.tv_sec * 1000 +
37993869 event->timestamp.tv_nsec / 1000000;
3800- metrics_pair_event(0, ts, cod, device_type);
3870+ metrics_log_pair_event(0, ts, cod, device_type);
38013871
38023872 pthread_mutex_unlock(&bond_event_lock);
38033873 }
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -305,6 +305,7 @@ typedef struct {
305305
306306 typedef struct {
307307 uint64_t session_start_us;
308+ uint64_t session_end_us;
308309
309310 scheduling_stats_t tx_queue_enqueue_stats;
310311 scheduling_stats_t tx_queue_dequeue_stats;
@@ -322,6 +323,7 @@ typedef struct {
322323 uint64_t tx_queue_last_flushed_us;
323324
324325 size_t tx_queue_total_dropped_messages;
326+ size_t tx_queue_max_dropped_messages;
325327 size_t tx_queue_dropouts;
326328 uint64_t tx_queue_last_dropouts_us;
327329
@@ -410,6 +412,7 @@ typedef struct
410412 BOOLEAN tx_enc_update_initiated;
411413 //#endif
412414
415+ btif_media_stats_t accumulated_stats;
413416 #endif
414417 } tBTIF_MEDIA_CB;
415418
@@ -532,6 +535,68 @@ static uint8_t multicast_query = FALSE;
532535 /*****************************************************************************
533536 ** Misc helper functions
534537 *****************************************************************************/
538+void btif_a2dp_source_accumulate_scheduling_stats(scheduling_stats_t* src,
539+ scheduling_stats_t* dst) {
540+ dst->total_updates += src->total_updates;
541+ dst->last_update_us = src->last_update_us;
542+ dst->overdue_scheduling_count += src->overdue_scheduling_count;
543+ dst->total_overdue_scheduling_delta_us += src->total_overdue_scheduling_delta_us;
544+ if (src->max_overdue_scheduling_delta_us > dst->max_overdue_scheduling_delta_us) {
545+ dst->max_overdue_scheduling_delta_us = src->max_overdue_scheduling_delta_us;
546+ }
547+ dst->premature_scheduling_count += src->premature_scheduling_count;
548+ dst->total_premature_scheduling_delta_us += src->total_premature_scheduling_delta_us;
549+ if (src->max_premature_scheduling_delta_us > dst->max_premature_scheduling_delta_us) {
550+ dst->max_premature_scheduling_delta_us = src->max_premature_scheduling_delta_us;
551+ }
552+ dst->exact_scheduling_count += src->exact_scheduling_count;
553+ dst->total_scheduling_time_us += src->total_scheduling_time_us;
554+}
555+
556+void btif_a2dp_source_accumulate_stats(btif_media_stats_t* src,
557+ btif_media_stats_t* dst) {
558+ dst->tx_queue_total_frames += src->tx_queue_total_frames;
559+ if (src->tx_queue_max_frames_per_packet > dst->tx_queue_max_frames_per_packet) {
560+ dst->tx_queue_max_frames_per_packet = src->tx_queue_max_frames_per_packet;
561+ }
562+ dst->tx_queue_total_queueing_time_us += src->tx_queue_total_queueing_time_us;
563+ if (src->tx_queue_max_queueing_time_us > dst->tx_queue_max_queueing_time_us) {
564+ dst->tx_queue_max_queueing_time_us = src->tx_queue_max_queueing_time_us;
565+ }
566+ dst->tx_queue_total_readbuf_calls += src->tx_queue_total_readbuf_calls;
567+ dst->tx_queue_last_readbuf_us = src->tx_queue_last_readbuf_us;
568+ dst->tx_queue_total_flushed_messages += src->tx_queue_total_flushed_messages;
569+ dst->tx_queue_last_flushed_us = src->tx_queue_last_flushed_us;
570+ dst->tx_queue_total_dropped_messages += src->tx_queue_total_dropped_messages;
571+ if (src->tx_queue_max_dropped_messages > dst->tx_queue_max_dropped_messages) {
572+ dst->tx_queue_max_dropped_messages = src->tx_queue_max_dropped_messages;
573+ }
574+ dst->tx_queue_dropouts += src->tx_queue_dropouts;
575+ dst->tx_queue_last_dropouts_us = src->tx_queue_last_dropouts_us;
576+ dst->media_read_total_underflow_bytes +=
577+ src->media_read_total_underflow_bytes;
578+ dst->media_read_total_underflow_count +=
579+ src->media_read_total_underflow_count;
580+ dst->media_read_last_underflow_us = src->media_read_last_underflow_us;
581+ dst->media_read_total_underrun_bytes += src->media_read_total_underrun_bytes;
582+ dst->media_read_total_underflow_count += src->media_read_total_underrun_count;
583+ dst->media_read_last_underrun_us = src->media_read_last_underrun_us;
584+ dst->media_read_total_expected_frames += src->media_read_total_expected_frames;
585+ if (src->media_read_max_expected_frames > dst->media_read_max_expected_frames) {
586+ dst->media_read_max_expected_frames = src->media_read_max_expected_frames;
587+ }
588+ dst->media_read_expected_count += src->media_read_expected_count;
589+ dst->media_read_total_limited_frames += src->media_read_total_limited_frames;
590+ if (src->media_read_max_limited_frames > dst->media_read_max_limited_frames) {
591+ dst->media_read_max_limited_frames = src->media_read_max_limited_frames;
592+ }
593+ dst->media_read_limited_count += src->media_read_limited_count;
594+ btif_a2dp_source_accumulate_scheduling_stats(&src->tx_queue_enqueue_stats,
595+ &dst->tx_queue_enqueue_stats);
596+ btif_a2dp_source_accumulate_scheduling_stats(&src->tx_queue_dequeue_stats,
597+ &dst->tx_queue_dequeue_stats);
598+ memset(src, 0, sizeof(btif_media_stats_t));
599+}
535600
536601 static void update_scheduling_stats(scheduling_stats_t *stats,
537602 uint64_t now_us, uint64_t expected_delta)
@@ -629,7 +694,11 @@ UNUSED_ATTR static const char *dump_media_event(UINT16 event)
629694
630695 static void btm_read_rssi_cb(void *data)
631696 {
632- assert(data);
697+ if (data == NULL)
698+ {
699+ LOG_ERROR(LOG_TAG, "%s RSSI request timed out", __func__);
700+ return;
701+ }
633702
634703 tBTM_RSSI_RESULTS *result = (tBTM_RSSI_RESULTS*)data;
635704 if (result->status != BTM_SUCCESS)
@@ -2027,6 +2096,9 @@ static void btif_media_task_aa_handle_timer(UNUSED_ATTR void *context)
20272096 if (alarm_is_scheduled(btif_media_cb.media_alarm))
20282097 {
20292098 btif_media_send_aa_frame(timestamp_us);
2099+ update_scheduling_stats(&btif_media_cb.stats.tx_queue_enqueue_stats,
2100+ timestamp_us,
2101+ BTIF_SINK_MEDIA_TIME_TICK_MS * 1000);
20302102 }
20312103 else
20322104 {
@@ -2054,7 +2126,6 @@ static void btif_media_thread_init(UNUSED_ATTR void *context) {
20542126
20552127 APPL_TRACE_IMP(" btif_media_thread_init");
20562128 memset(&btif_media_cb, 0, sizeof(btif_media_cb));
2057- btif_media_cb.stats.session_start_us = time_now_us();
20582129
20592130 UIPC_Init(NULL);
20602131
@@ -2067,6 +2138,7 @@ static void btif_media_thread_init(UNUSED_ATTR void *context) {
20672138 raise_priority_a2dp(TASK_HIGH_MEDIA);
20682139 media_task_running = MEDIA_TASK_STATE_ON;
20692140 APPL_TRACE_DEBUG(" btif_media_thread_init complete");
2141+ metrics_log_bluetooth_session_start(CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
20702142 }
20712143
20722144 static void btif_media_thread_cleanup(UNUSED_ATTR void *context) {
@@ -2085,6 +2157,7 @@ static void btif_media_thread_cleanup(UNUSED_ATTR void *context) {
20852157 /* Clear media task flag */
20862158 media_task_running = MEDIA_TASK_STATE_OFF;
20872159 APPL_TRACE_DEBUG(" btif_media_thread_cleanup complete");
2160+ metrics_log_bluetooth_session_end(DISCONNECT_REASON_UNKNOWN, 0);
20882161 }
20892162
20902163 /*******************************************************************************
@@ -2440,6 +2513,14 @@ BOOLEAN btif_media_task_start_aa_req(void)
24402513
24412514 if (btif_media_cmd_msg_queue != NULL)
24422515 fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
2516+ memset(&btif_media_cb.stats, 0, sizeof(btif_media_stats_t));
2517+ // Assign session_start_us to 1 when time_now_us() is 0 to indicate
2518+ // btif_media_task_start_aa_req() has been called
2519+ btif_media_cb.stats.session_start_us = time_now_us();
2520+ if (btif_media_cb.stats.session_start_us == 0) {
2521+ btif_media_cb.stats.session_start_us = 1;
2522+ }
2523+ btif_media_cb.stats.session_end_us = 0;
24432524 return TRUE;
24442525 }
24452526
@@ -2468,8 +2549,14 @@ BOOLEAN btif_media_task_stop_aa_req(void)
24682549 * the "cleanup() -> btif_a2dp_stop_media_task()" processing during
24692550 * the shutdown of the Bluetooth stack.
24702551 */
2471- if (btif_media_cmd_msg_queue != NULL)
2552+ if (btif_media_cmd_msg_queue != NULL) {
24722553 fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
2554+ }
2555+
2556+ btif_media_cb.stats.session_end_us = time_now_us();
2557+ btif_update_a2dp_metrics();
2558+ btif_a2dp_source_accumulate_stats(&btif_media_cb.stats,
2559+ &btif_media_cb.accumulated_stats);
24732560
24742561 return TRUE;
24752562 }
@@ -4223,9 +4310,6 @@ static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame,
42234310 }
42244311
42254312 /* Enqueue the encoded SBC frame in AA Tx Queue */
4226- update_scheduling_stats(&btif_media_cb.stats.tx_queue_enqueue_stats,
4227- timestamp_us,
4228- BTIF_SINK_MEDIA_TIME_TICK_MS * 1000);
42294313 uint8_t done_nb_frame = remain_nb_frame - nb_frame;
42304314 remain_nb_frame = nb_frame;
42314315 btif_media_cb.stats.tx_queue_total_frames += done_nb_frame;
@@ -4268,6 +4352,10 @@ static void btif_media_aa_prep_2_send(UINT8 nb_frame, uint64_t timestamp_us)
42684352 btif_media_cb.stats.tx_queue_last_dropouts_us = timestamp_us;
42694353
42704354 // Flush all queued buffers...
4355+ size_t drop_n = fixed_queue_length(btif_media_cb.TxAaQ);
4356+ if (drop_n > btif_media_cb.stats.tx_queue_max_dropped_messages) {
4357+ btif_media_cb.stats.tx_queue_max_dropped_messages = drop_n;
4358+ }
42714359 while (fixed_queue_length(btif_media_cb.TxAaQ)) {
42724360 btif_media_cb.stats.tx_queue_total_dropped_messages++;
42734361 osi_free(fixed_queue_try_dequeue(btif_media_cb.TxAaQ));
@@ -4945,8 +5033,10 @@ void dump_codec_info(unsigned char *p_codec)
49455033
49465034 void btif_debug_a2dp_dump(int fd)
49475035 {
5036+ btif_a2dp_source_accumulate_stats(&btif_media_cb.stats,
5037+ &btif_media_cb.accumulated_stats);
49485038 uint64_t now_us = time_now_us();
4949- btif_media_stats_t *stats = &btif_media_cb.stats;
5039+ btif_media_stats_t *stats = &btif_media_cb.accumulated_stats;
49505040 scheduling_stats_t *enqueue_stats = &stats->tx_queue_enqueue_stats;
49515041 scheduling_stats_t *dequeue_stats = &stats->tx_queue_dequeue_stats;
49525042 size_t ave_size;
@@ -5080,52 +5170,51 @@ void btif_debug_a2dp_dump(int fd)
50805170
50815171 void btif_update_a2dp_metrics(void)
50825172 {
5083- uint64_t now_us = time_now_us();
5084- btif_media_stats_t *stats = &btif_media_cb.stats;
5085- scheduling_stats_t *dequeue_stats = &stats->tx_queue_dequeue_stats;
5086- int32_t media_timer_min_ms = 0;
5087- int32_t media_timer_max_ms = 0;
5088- int32_t media_timer_avg_ms = 0;
5089- int32_t buffer_overruns_max_count = 0;
5090- int32_t buffer_overruns_total = 0;
5091- float buffer_underruns_average = 0.0;
5092- int32_t buffer_underruns_count = 0;
5093-
5094- int64_t session_duration_sec =
5095- (now_us - stats->session_start_us) / (1000 * 1000);
5096-
5097- /* NOTE: Disconnect reason is unused */
5098- const char *disconnect_reason = NULL;
5099- uint32_t device_class = BTM_COD_MAJOR_AUDIO;
5100-
5101- if (dequeue_stats->total_updates > 1) {
5102- media_timer_min_ms = BTIF_SINK_MEDIA_TIME_TICK_MS -
5103- (dequeue_stats->max_premature_scheduling_delta_us / 1000);
5104- media_timer_max_ms = BTIF_SINK_MEDIA_TIME_TICK_MS +
5105- (dequeue_stats->max_overdue_scheduling_delta_us / 1000);
5106-
5107- uint64_t total_scheduling_count =
5108- dequeue_stats->overdue_scheduling_count +
5109- dequeue_stats->premature_scheduling_count +
5110- dequeue_stats->exact_scheduling_count;
5111- if (total_scheduling_count > 0) {
5112- media_timer_avg_ms = dequeue_stats->total_scheduling_time_us /
5113- (1000 * total_scheduling_count);
5173+ btif_media_stats_t* stats = &btif_media_cb.stats;
5174+ scheduling_stats_t* enqueue_stats = &stats->tx_queue_enqueue_stats;
5175+ A2dpSessionMetrics_t metrics;
5176+ metrics.media_timer_min_ms = -1;
5177+ metrics.media_timer_max_ms = -1;
5178+ metrics.media_timer_avg_ms = -1;
5179+ metrics.total_scheduling_count = -1;
5180+ metrics.buffer_overruns_max_count = -1;
5181+ metrics.buffer_overruns_total = -1;
5182+ metrics.buffer_underruns_average = -1.0;
5183+ metrics.buffer_underruns_count = -1;
5184+ metrics.audio_duration_ms = -1;
5185+ // session_start_us is 0 when btif_media_task_start_aa_req() is not called
5186+ // mark the metric duration as invalid (-1) in this case
5187+ if (stats->session_start_us != 0) {
5188+ int64_t session_end_us = stats->session_end_us == 0
5189+ ? time_now_us()
5190+ : stats->session_end_us;
5191+ metrics.audio_duration_ms = (session_end_us - stats->session_start_us) / 1000;
5192+ }
5193+ if (enqueue_stats->total_updates > 1) {
5194+ metrics.media_timer_min_ms = BTIF_SINK_MEDIA_TIME_TICK_MS -
5195+ (enqueue_stats->max_premature_scheduling_delta_us / 1000);
5196+ metrics.media_timer_max_ms = BTIF_SINK_MEDIA_TIME_TICK_MS +
5197+ (enqueue_stats->max_overdue_scheduling_delta_us / 1000);
5198+ metrics.total_scheduling_count
5199+ = enqueue_stats->overdue_scheduling_count +
5200+ enqueue_stats->premature_scheduling_count +
5201+ enqueue_stats->exact_scheduling_count;
5202+ if (metrics.total_scheduling_count > 0) {
5203+ metrics.media_timer_avg_ms = enqueue_stats->total_scheduling_time_us /
5204+ (1000 * metrics.total_scheduling_count);
51145205 }
5115-
5116- buffer_overruns_max_count = stats->media_read_max_expected_frames;
5117- buffer_overruns_total = stats->tx_queue_total_dropped_messages;
5118- buffer_underruns_count = stats->media_read_total_underflow_count +
5119- stats->media_read_total_underrun_count;
5120- if (buffer_underruns_count > 0) {
5121- buffer_underruns_average =
5122- (stats->media_read_total_underflow_bytes + stats->media_read_total_underrun_bytes) / buffer_underruns_count;
5206+ metrics.buffer_overruns_max_count = stats->tx_queue_max_dropped_messages;
5207+ metrics.buffer_overruns_total = stats->tx_queue_total_dropped_messages;
5208+ metrics.buffer_underruns_count =
5209+ stats->media_read_total_underflow_count +
5210+ stats->media_read_total_underrun_count;
5211+ metrics.buffer_underruns_average = 0;
5212+ if (metrics.buffer_underruns_count > 0) {
5213+ metrics.buffer_underruns_average =
5214+ (stats->media_read_total_underflow_bytes +
5215+ stats->media_read_total_underrun_bytes) /
5216+ metrics.buffer_underruns_count;
51235217 }
51245218 }
5125-
5126- metrics_a2dp_session(session_duration_sec, disconnect_reason, device_class,
5127- media_timer_min_ms, media_timer_max_ms,
5128- media_timer_avg_ms, buffer_overruns_max_count,
5129- buffer_overruns_total, buffer_underruns_average,
5130- buffer_underruns_count);
5219+ metrics_log_a2dp_session(&metrics);
51315220 }
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -1447,6 +1447,21 @@ bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr)
14471447
14481448 /*******************************************************************************
14491449 **
1450+** Function btif_storage_get_num_bonded_devices
1451+**
1452+** Description BTIF storage API - Gets the number of bonded devices
1453+**
1454+** Returns the number of bonded devices
1455+**
1456+*******************************************************************************/
1457+int btif_storage_get_num_bonded_devices(void) {
1458+ btif_bonded_devices_t bonded_devices;
1459+ btif_in_fetch_bonded_devices(&bonded_devices, 0);
1460+ return bonded_devices.num_devices;
1461+}
1462+
1463+/*******************************************************************************
1464+**
14501465 ** Function btif_storage_read_hl_apps_cb
14511466 **
14521467 ** Description BTIF storage API - Read HL application control block from NVRAM
--- a/conf/bt_stack.conf
+++ b/conf/bt_stack.conf
@@ -9,7 +9,7 @@ BtSnoopLogOutput=false
99 BtSnoopExtDump=false
1010
1111 # BtSnoop log output file
12-BtSnoopFileName=/sdcard/btsnoop_hci.log
12+BtSnoopFileName=/data/misc/bluetooth/logs/btsnoop_hci.log
1313
1414 # Preserve existing BtSnoop log before overwriting
1515 BtSnoopSaveLog=false
--- a/hci/src/btsnoop.c
+++ b/hci/src/btsnoop.c
@@ -205,12 +205,15 @@ static void update_logging() {
205205 LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__, log_path, last_log_path, strerror(errno));
206206 }
207207
208+ mode_t prevmask = umask(0);
208209 logfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
209210 if (logfile_fd == INVALID_FD) {
210211 LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, log_path, strerror(errno));
211212 is_logging = false;
213+ umask(prevmask);
212214 return;
213215 }
216+ umask(prevmask);
214217
215218 write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
216219 } else {
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -1684,4 +1684,15 @@ The maximum number of payload octets that the local device can receive in a sing
16841684
16851685 #include "bt_trace.h"
16861686
1687+/******************************************************************************
1688+**
1689+** Wear
1690+**
1691+******************************************************************************/
1692+
1693+/* Enable/disable LE IO capability overriding to no-input-no-output on first bond */
1694+#ifndef WEAR_LE_IO_CAP_OVERRIDE
1695+#define WEAR_LE_IO_CAP_OVERRIDE FALSE
1696+#endif
1697+
16871698 #endif /* BT_TARGET_H */
--- a/main/stack_config.c
+++ b/main/stack_config.c
@@ -82,7 +82,8 @@ EXPORT_SYMBOL const module_t stack_config_module = {
8282 // Interface functions
8383
8484 static const char *get_btsnoop_log_path(void) {
85- return config_get_string(config, CONFIG_DEFAULT_SECTION, BTSNOOP_LOG_PATH_KEY, "/data/misc/bluedroid/btsnoop_hci.log");
85+ return config_get_string(config, CONFIG_DEFAULT_SECTION, BTSNOOP_LOG_PATH_KEY,
86+ "/data/misc/bluetooth/logs/btsnoop_hci.log");
8687 }
8788
8889 static bool get_btsnoop_turned_on(void) {
--- a/osi/Android.mk
+++ b/osi/Android.mk
@@ -68,7 +68,9 @@ btosiCommonTestSrc := \
6868 ./test/future_test.cpp \
6969 ./test/hash_map_test.cpp \
7070 ./test/hash_map_utils_test.cpp \
71+ ./test/leaky_bonded_queue_test.cpp \
7172 ./test/list_test.cpp \
73+ ./test/metrics_test.cpp \
7274 ./test/properties_test.cpp \
7375 ./test/rand_test.cpp \
7476 ./test/reactor_test.cpp \
@@ -79,6 +81,7 @@ btosiCommonTestSrc := \
7981
8082 btosiCommonIncludes := \
8183 $(LOCAL_PATH)/.. \
84+ $(LOCAL_PATH)/../include \
8285 $(LOCAL_PATH)/../utils/include \
8386 $(LOCAL_PATH)/../stack/include \
8487 $(bluetooth_C_INCLUDES)
@@ -167,7 +170,7 @@ LOCAL_SRC_FILES := $(btosiCommonTestSrc)
167170 LOCAL_MODULE := net_test_osi
168171 LOCAL_MODULE_TAGS := tests
169172 LOCAL_SHARED_LIBRARIES := libc liblog libprotobuf-cpp-full libchrome libcutils
170-LOCAL_STATIC_LIBRARIES := libosi libbt-protos
173+LOCAL_STATIC_LIBRARIES := libosi libbt-protos libgmock
171174
172175 LOCAL_CFLAGS += $(bluetooth_CFLAGS)
173176 LOCAL_CONLYFLAGS += $(bluetooth_CONLYFLAGS)
@@ -185,7 +188,7 @@ LOCAL_LDLIBS := -lrt -lpthread
185188 LOCAL_MODULE := net_test_osi
186189 LOCAL_MODULE_TAGS := tests
187190 LOCAL_SHARED_LIBRARIES := liblog libprotobuf-cpp-full libchrome
188-LOCAL_STATIC_LIBRARIES := libosi-host libbt-protos
191+LOCAL_STATIC_LIBRARIES := libosi-host libbt-protos libgmock_host
189192
190193 LOCAL_CFLAGS += $(bluetooth_CFLAGS) -DOS_GENERIC
191194 LOCAL_CONLYFLAGS += $(bluetooth_CONLYFLAGS)
--- a/osi/BUILD.gn
+++ b/osi/BUILD.gn
@@ -71,7 +71,9 @@ executable("net_test_osi") {
7171 "test/future_test.cpp",
7272 "test/hash_map_test.cpp",
7373 "test/hash_map_utils_test.cpp",
74+ "test/leaky_bonded_queue_test.cpp",
7475 "test/list_test.cpp",
76+ "test/metrics_test.cpp",
7577 "test/properties_test.cpp",
7678 "test/rand_test.cpp",
7779 "test/reactor_test.cpp",
@@ -88,6 +90,8 @@ executable("net_test_osi") {
8890 deps = [
8991 "//osi",
9092 "//third_party/googletest:gtest_main",
93+ "//third_party/googletest:gmock_main",
94+ "//third_party/libchrome:base",
9195 ]
9296
9397 libs = [
--- /dev/null
+++ b/osi/include/leaky_bonded_queue.h
@@ -0,0 +1,158 @@
1+/******************************************************************************
2+ *
3+ * Copyright (C) 2016 Google, Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+#pragma once
19+
20+#include <memory>
21+#include <mutex>
22+#include <queue>
23+
24+namespace system_bt_osi {
25+
26+/*
27+ * LeakyBondedQueue<T>
28+ *
29+ * - LeakyLondedQueue<T> is a fixed size queue that leaks oldest item when
30+ * reaching its capacity. This is useful in creating memory bonded data
31+ * structure where freshness is more important than full coverage.
32+ * - The queue is protected by a simple mutex and is thread-safe, although
33+ * improvements could be made to lock enqueue and dequeue separately, it
34+ * is not implemented at this moment due to lack of demand
35+ * - The queue uses unique_ptr to automatically free its content when it is
36+ * destructed. It is the user's responsibility to implement T's destructor
37+ * correctly.
38+ *
39+ */
40+template <class T>
41+class LeakyBondedQueue {
42+ public:
43+ LeakyBondedQueue(size_t capacity);
44+ /* Default destructor
45+ *
46+ * Call Clear() and free the queue structure itself
47+ */
48+ ~LeakyBondedQueue();
49+ /*
50+ * Add item NEW_ITEM to the underlining queue. If the queue is full, pop
51+ * the oldest item
52+ */
53+ void Enqueue(T* new_item);
54+ /*
55+ * Add item NEW_ITEM to the underlining queue. If the queue is full, dequeue
56+ * the oldest item and returns it to the caller. Return nullptr otherwise.
57+ */
58+ T* EnqueueWithPop(T* new_item);
59+ /*
60+ * Dequeues the oldest item from the queue. Return nullptr if queue is empty
61+ */
62+ T* Dequeue();
63+ /*
64+ * Returns the length of queue
65+ */
66+ size_t Length();
67+ /*
68+ * Returns the defined capacity of the queue
69+ */
70+ size_t Capacity();
71+ /*
72+ * Returns whether the queue is empty
73+ */
74+ bool Empty();
75+ /*
76+ * Pops all items from the queue
77+ */
78+ void Clear();
79+
80+ private:
81+ // Put item in unique_ptr so that they get freed automatically when poped or
82+ // when queue_ is freed
83+ std::queue<std::unique_ptr<T>> queue_;
84+ std::mutex lock_;
85+ size_t capacity_;
86+};
87+
88+/*
89+* Definitions must be in the header for template classes
90+*/
91+
92+template <class T>
93+LeakyBondedQueue<T>::LeakyBondedQueue(size_t capacity) {
94+ capacity_ = capacity;
95+}
96+
97+template <class T>
98+LeakyBondedQueue<T>::~LeakyBondedQueue() {}
99+
100+template <class T>
101+void LeakyBondedQueue<T>::Enqueue(T* new_item) {
102+ std::lock_guard<std::mutex> lock(lock_);
103+ if ((queue_.size() + 1) > capacity_) {
104+ queue_.pop();
105+ }
106+ std::unique_ptr<T> item_ptr(new_item);
107+ queue_.push(std::move(item_ptr));
108+}
109+
110+template <class T>
111+T* LeakyBondedQueue<T>::EnqueueWithPop(T* new_item) {
112+ std::lock_guard<std::mutex> lock(lock_);
113+ T* old_item = nullptr;
114+ if ((queue_.size() + 1) > capacity_) {
115+ std::unique_ptr<T> item = std::move(queue_.front());
116+ queue_.pop();
117+ old_item = item.release();
118+ }
119+ std::unique_ptr<T> item_ptr(new_item);
120+ queue_.push(std::move(item_ptr));
121+ return old_item;
122+}
123+
124+template <class T>
125+T* LeakyBondedQueue<T>::Dequeue() {
126+ std::lock_guard<std::mutex> lock(lock_);
127+ std::unique_ptr<T> item = std::move(queue_.front());
128+ queue_.pop();
129+ return item.release();
130+}
131+
132+template <class T>
133+void LeakyBondedQueue<T>::Clear() {
134+ std::lock_guard<std::mutex> lock(lock_);
135+ while (!queue_.empty()) {
136+ // unique_ptr does not need to be freed
137+ queue_.pop();
138+ }
139+}
140+
141+template <class T>
142+size_t LeakyBondedQueue<T>::Length() {
143+ std::lock_guard<std::mutex> lock(lock_);
144+ return queue_.size();
145+}
146+
147+template <class T>
148+size_t LeakyBondedQueue<T>::Capacity() {
149+ return capacity_;
150+}
151+
152+template <class T>
153+bool LeakyBondedQueue<T>::Empty() {
154+ std::lock_guard<std::mutex> lock(lock_);
155+ return queue_.empty();
156+}
157+
158+} // namespace system_bt_osi
--- a/osi/include/metrics.h
+++ b/osi/include/metrics.h
@@ -20,6 +20,11 @@
2020
2121 #include <stdint.h>
2222
23+#ifdef __cplusplus
24+extern "C" {
25+#endif
26+// Typedefs to hide protobuf definition to the rest of stack
27+
2328 typedef enum {
2429 DEVICE_TYPE_UNKNOWN,
2530 DEVICE_TYPE_BREDR,
@@ -27,26 +32,12 @@ typedef enum {
2732 DEVICE_TYPE_DUMO,
2833 } device_type_t;
2934
30-// Record a pairing event at Unix epoch time |timestamp_ms|
31-// |device_class| and |device_type| denote the type of device paired.
32-// |disconnect_reason| is the HCI reason for pairing disconnection,
33-// see stack/include/hcidefs.h
34-void metrics_pair_event(uint32_t disconnect_reason, uint64_t timestamp_ms,
35- uint32_t device_class, device_type_t device_type);
36-
3735 typedef enum {
3836 WAKE_EVENT_UNKNOWN,
3937 WAKE_EVENT_ACQUIRED,
4038 WAKE_EVENT_RELEASED,
4139 } wake_event_type_t;
4240
43-// Record a wake event at Unix epoch time |timestamp_ms|.
44-// |type| specifies whether it was acquired or relased,
45-// |requestor| if provided is the service requesting the wake lock.
46-// |name| is the name of the wake lock held.
47-void metrics_wake_event(wake_event_type_t type, const char *requestor,
48- const char *name, uint64_t timestamp_ms);
49-
5041 typedef enum {
5142 SCAN_TYPE_UNKNOWN,
5243 SCAN_TECH_TYPE_LE,
@@ -54,44 +45,52 @@ typedef enum {
5445 SCAN_TECH_TYPE_BOTH,
5546 } scan_tech_t;
5647
57-// Record a scan event at Unix epoch time |timestamp_ms|.
58-// |start| is true if this is the beginning of the scan.
59-// |initiator| is a unique ID identifying the app starting the scan.
60-// |type| is whether the scan reports BR/EDR, LE, or both.
61-// |results| is the number of results to be reported.
62-void metrics_scan_event(bool start, const char *initator, scan_tech_t type,
63- uint32_t results, uint64_t timestamp_ms);
64-
65-// Record A2DP session information.
66-// |session_duration_sec| is the session duration (in seconds).
67-// |device_class| is the device class of the paired device.
68-// |media_timer_min_ms| is the minimum scheduled time (in milliseconds)
69-// of the media timer.
70-// |media_timer_max_ms| is the maximum scheduled time (in milliseconds)
71-// of the media timer.
72-// |media_timer_avg_ms| is the average scheduled time (in milliseconds)
73-// of the media timer.
74-// |buffer_overruns_max_count| - TODO - not clear what this is.
75-// |buffer_overruns_total| is the number of times the media buffer with
76-// audio data has overrun.
77-// |buffer_underruns_average| - TODO - not clear what this is.
78-// |buffer_underruns_count| is the number of times there was no enough
79-// audio data to add to the media buffer.
80-void metrics_a2dp_session(int64_t session_duration_sec,
81- const char *disconnect_reason,
82- uint32_t device_class,
83- int32_t media_timer_min_ms,
84- int32_t media_timer_max_ms,
85- int32_t media_timer_avg_ms,
86- int32_t buffer_overruns_max_count,
87- int32_t buffer_overruns_total,
88- float buffer_underruns_average,
89- int32_t buffer_underruns_count);
90-
91-// Writes the metrics, in packed protobuf format, into the descriptor |fd|.
92-// If |clear| is true, metrics events are cleared afterwards.
93-void metrics_write(int fd, bool clear);
94-
95-// Writes the metrics, in human-readable protobuf format, into the descriptor
96-// |fd|. If |clear| is true, metrics events are cleared afterwards.
97-void metrics_print(int fd, bool clear);
48+typedef enum {
49+ CONNECTION_TECHNOLOGY_TYPE_UNKNOWN,
50+ CONNECTION_TECHNOLOGY_TYPE_LE,
51+ CONNECTION_TECHNOLOGY_TYPE_BREDR,
52+} connection_tech_t;
53+
54+typedef enum {
55+ DISCONNECT_REASON_UNKNOWN,
56+ DISCONNECT_REASON_METRICS_DUMP,
57+ DISCONNECT_REASON_NEXT_START_WITHOUT_END_PREVIOUS,
58+} disconnect_reason_t;
59+
60+typedef struct {
61+ int64_t audio_duration_ms;
62+ int32_t media_timer_min_ms;
63+ int32_t media_timer_max_ms;
64+ int32_t media_timer_avg_ms;
65+ int64_t total_scheduling_count;
66+ int32_t buffer_overruns_max_count;
67+ int32_t buffer_overruns_total;
68+ float buffer_underruns_average;
69+ int32_t buffer_underruns_count;
70+} A2dpSessionMetrics_t;
71+
72+void metrics_log_pair_event(uint32_t disconnect_reason, uint64_t timestamp_ms,
73+ uint32_t device_class, device_type_t device_type);
74+
75+void metrics_log_wake_event(wake_event_type_t type, const char* requestor,
76+ const char* name, uint64_t timestamp_ms);
77+
78+void metrics_log_scan_event(bool start, const char* initator, scan_tech_t type,
79+ uint32_t results, uint64_t timestamp_ms);
80+
81+void metrics_log_bluetooth_session_start(connection_tech_t connection_tech_type,
82+ uint64_t timestamp_ms);
83+
84+void metrics_log_bluetooth_session_end(disconnect_reason_t disconnect_reason,
85+ uint64_t timestamp_ms);
86+
87+void metrics_log_bluetooth_session_device_info(uint32_t device_class,
88+ device_type_t device_type);
89+
90+void metrics_log_a2dp_session(A2dpSessionMetrics_t* metrics);
91+
92+void metrics_write_base64(int fd, bool clear);
93+
94+#ifdef __cplusplus
95+}
96+#endif
--- /dev/null
+++ b/osi/include/metrics_cpp.h
@@ -0,0 +1,230 @@
1+/******************************************************************************
2+ *
3+ * Copyright (C) 2016 Google, Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+#include <stdint.h>
19+#include <memory>
20+#include <string>
21+
22+namespace system_bt_osi {
23+
24+/* Values of A2DP metrics that we care about
25+ *
26+ * audio_duration_ms : sum of audio duration (in milliseconds).
27+ * device_class: device class of the paired device.
28+ * media_timer_min_ms : minimum scheduled time (in milliseconds)
29+ * of the media timer.
30+ * media_timer_max_ms: maximum scheduled time (in milliseconds)
31+ * of the media timer.
32+ * media_timer_avg_ms: average scheduled time (in milliseconds)
33+ * of the media timer.
34+ * buffer_overruns_max_count: TODO - not clear what this is.
35+ * buffer_overruns_total : number of times the media buffer with
36+ * audio data has overrun
37+ * buffer_underruns_average: TODO - not clear what this is.
38+ * buffer_underruns_count: number of times there was no enough
39+ * audio data to add to the media buffer.
40+ * NOTE: Negative values are invalid
41+*/
42+class A2dpSessionMetrics {
43+ public:
44+ A2dpSessionMetrics() {}
45+
46+ /*
47+ * Update the metrics value in the current metrics object using the metrics
48+ * objects supplied
49+ */
50+ void Update(const A2dpSessionMetrics& metrics);
51+
52+ /*
53+ * Compare whether two metrics objects are equal
54+ */
55+ bool operator==(const A2dpSessionMetrics& rhs) const;
56+
57+ /*
58+ * Initialize all values to -1 which is invalid in order to make a distinction
59+ * between 0 and invalid values
60+ */
61+ int64_t audio_duration_ms = -1;
62+ int32_t media_timer_min_ms = -1;
63+ int32_t media_timer_max_ms = -1;
64+ int32_t media_timer_avg_ms = -1;
65+ int64_t total_scheduling_count = -1;
66+ int32_t buffer_overruns_max_count = -1;
67+ int32_t buffer_overruns_total = -1;
68+ float buffer_underruns_average = -1;
69+ int32_t buffer_underruns_count = -1;
70+};
71+
72+class BluetoothMetricsLogger {
73+ public:
74+ static BluetoothMetricsLogger* GetInstance() {
75+ static BluetoothMetricsLogger* instance = new BluetoothMetricsLogger();
76+ return instance;
77+ }
78+
79+ /*
80+ * Record a pairing event
81+ *
82+ * Parameters:
83+ * timestamp_ms: Unix epoch time in milliseconds
84+ * device_class: class of remote device
85+ * device_type: type of remote device
86+ * disconnect_reason: HCI reason for pairing disconnection.
87+ * See: stack/include/hcidefs.h
88+ */
89+ void LogPairEvent(uint32_t disconnect_reason, uint64_t timestamp_ms,
90+ uint32_t device_class, device_type_t device_type);
91+
92+ /*
93+ * Record a wake event
94+ *
95+ * Parameters:
96+ * timestamp_ms: Unix epoch time in milliseconds
97+ * type: whether it was acquired or released
98+ * requestor: if provided is the service requesting the wake lock
99+ * name: the name of the wake lock held
100+ */
101+ void LogWakeEvent(wake_event_type_t type, const std::string& requestor,
102+ const std::string& name, uint64_t timestamp_ms);
103+
104+ /*
105+ * Record a scan event
106+ *
107+ * Parameters
108+ * timestamp_ms : Unix epoch time in milliseconds
109+ * start : true if this is the beginning of the scan
110+ * initiator: a unique ID identifying the app starting the scan
111+ * type: whether the scan reports BR/EDR, LE, or both.
112+ * results: number of results to be reported.
113+ */
114+ void LogScanEvent(bool start, const std::string& initator, scan_tech_t type,
115+ uint32_t results, uint64_t timestamp_ms);
116+
117+ /*
118+ * Start logging a Bluetooth session
119+ *
120+ * A Bluetooth session is defined a a connection between this device and
121+ * another remote device which may include multiple profiles and protocols
122+ *
123+ * Only one Bluetooth session can exist at one time. Calling this method twice
124+ * without LogBluetoothSessionEnd will result in logging a premature end of
125+ * current Bluetooth session
126+ *
127+ * Parameters:
128+ * connection_tech_type : type of connection technology
129+ * timestamp_ms : the timestamp for session start, 0 means now
130+ *
131+ */
132+ void LogBluetoothSessionStart(connection_tech_t connection_tech_type,
133+ uint64_t timestamp_ms);
134+
135+ /*
136+ * Stop logging a Bluetooth session and pushes it to the log queue
137+ *
138+ * If no Bluetooth session exist, this method exits immediately
139+ *
140+ * Parameters:
141+ * disconnect_reason : A string representation of disconnect reason
142+ * timestamp_ms : the timestamp of session end, 0 means now
143+ *
144+ */
145+ void LogBluetoothSessionEnd(disconnect_reason_t disconnect_reason,
146+ uint64_t timestamp_ms);
147+
148+ /*
149+ * Log information about remote device in a current Bluetooth session
150+ *
151+ * If a Bluetooth session does not exist, create one with default parameter
152+ * and timestamp now
153+ *
154+ * Parameters:
155+ * device_class : device_class defined in btm_api_types.h
156+ * device_type : type of remote device
157+ */
158+ void LogBluetoothSessionDeviceInfo(uint32_t device_class,
159+ device_type_t device_type);
160+
161+ /*
162+ * Log A2DP Audio Session Information
163+ *
164+ * - Repeated calls to this method will override previous metrics if in the
165+ * same Bluetooth connection
166+ * - If a Bluetooth session does not exist, create one with default parameter
167+ * and timestamp now
168+ *
169+ * Parameters:
170+ * a2dp_session_metrics - pointer to struct holding a2dp stats
171+ *
172+ */
173+ void LogA2dpSession(const A2dpSessionMetrics& a2dp_session_metrics);
174+
175+ /*
176+ * Writes the metrics, in base64 protobuf format, into the descriptor FD
177+ * If CLEAR is true, metrics events are cleared afterwards.
178+ */
179+ void WriteBase64(int fd, bool clear);
180+ void WriteBase64String(std::string* serialized, bool clear);
181+ void WriteString(std::string* serialized, bool clear);
182+
183+ /*
184+ * Reset the metrics logger by cleaning up its staging queues and existing
185+ * protobuf objects.
186+ */
187+ void Reset();
188+
189+ /*
190+ * Maximum number of log entries for each session or event
191+ */
192+ static const size_t kMaxNumBluetoothSession = 50;
193+ static const size_t kMaxNumPairEvent = 50;
194+ static const size_t kMaxNumWakeEvent = 1000;
195+ static const size_t kMaxNumScanEvent = 50;
196+
197+ private:
198+ BluetoothMetricsLogger();
199+
200+ /*
201+ * When a Bluetooth session is on and the user initiates a metrics dump, we
202+ * need to be able to upload whatever we have first. This method breaks the
203+ * ongoing Bluetooth session into two sessions with the previous one labeled
204+ * as "METRICS_DUMP" for the disconnect reason.
205+ */
206+ void CutoffSession();
207+
208+ /*
209+ * Build the internal metrics object using information gathered
210+ */
211+ void Build();
212+
213+ /*
214+ * Reset objects related to current Bluetooth session
215+ */
216+ void ResetSession();
217+
218+ /*
219+ * Reset the underlining BluetoothLog object
220+ */
221+ void ResetLog();
222+
223+ /*
224+ * PIMPL style implementation to hide internal dependencies
225+ */
226+ struct impl;
227+ std::unique_ptr<impl> const pimpl_;
228+};
229+
230+} // namespace system_bt_osi
--- a/osi/src/metrics.cpp
+++ b/osi/src/metrics.cpp
@@ -15,28 +15,37 @@
1515 * limitations under the License.
1616 *
1717 ******************************************************************************/
18-
19-
2018 #define LOG_TAG "bt_osi_metrics"
2119
22-extern "C" {
23-#include "osi/include/metrics.h"
20+#include <unistd.h>
21+#include <algorithm>
22+#include <cerrno>
23+#include <chrono>
24+#include <cstdint>
25+#include <cstring>
26+#include <memory>
27+#include <mutex>
2428
25-#include <errno.h>
29+#include <base/base64.h>
30+#include <base/logging.h>
2631
32+#include "osi/include/leaky_bonded_queue.h"
2733 #include "osi/include/log.h"
2834 #include "osi/include/osi.h"
29-}
35+#include "stack/include/btm_api.h"
3036
3137 #include "osi/src/protos/bluetooth.pb.h"
3238
33-#include <base/base64.h>
34-#include <google/protobuf/text_format.h>
35-#include <mutex>
39+#include "osi/include/metrics.h"
40+#include "osi/include/metrics_cpp.h"
41+
42+namespace system_bt_osi {
3643
3744 using clearcut::connectivity::A2DPSession;
3845 using clearcut::connectivity::BluetoothLog;
3946 using clearcut::connectivity::BluetoothSession;
47+using clearcut::connectivity::BluetoothSession_ConnectionTechnologyType;
48+using clearcut::connectivity::BluetoothSession_DisconnectReasonType;
4049 using clearcut::connectivity::DeviceInfo;
4150 using clearcut::connectivity::DeviceInfo_DeviceType;
4251 using clearcut::connectivity::PairEvent;
@@ -46,156 +55,378 @@ using clearcut::connectivity::ScanEvent_ScanEventType;
4655 using clearcut::connectivity::WakeEvent;
4756 using clearcut::connectivity::WakeEvent_WakeEventType;
4857
49-BluetoothLog *pending;
50-std::mutex log_lock;
58+uint64_t metrics_time_get_os_boottime_us(void) {
59+ struct timespec ts_now;
60+ clock_gettime(CLOCK_BOOTTIME, &ts_now);
5161
52-static void lazy_initialize(void) {
53- if (pending == nullptr) {
54- pending = BluetoothLog::default_instance().New();
55- }
62+ return ((uint64_t)ts_now.tv_sec * 1000000L) +
63+ ((uint64_t)ts_now.tv_nsec / 1000);
5664 }
5765
58-void metrics_pair_event(uint32_t disconnect_reason, uint64_t timestamp_ms,
59- uint32_t device_class, device_type_t device_type) {
60- std::lock_guard<std::mutex> lock(log_lock);
61- lazy_initialize();
62-
63- PairEvent *event = pending->add_pair_event();
64-
65- DeviceInfo *info = event->mutable_device_paired_with();
66-
67- info->set_device_class(device_class);
68-
69- DeviceInfo_DeviceType type = DeviceInfo::DEVICE_TYPE_UNKNOWN;
70-
71- if (device_type == DEVICE_TYPE_BREDR)
72- type = DeviceInfo::DEVICE_TYPE_BREDR;
73- if (device_type == DEVICE_TYPE_LE)
74- type = DeviceInfo::DEVICE_TYPE_LE;
75- if (device_type == DEVICE_TYPE_DUMO)
76- type = DeviceInfo::DEVICE_TYPE_DUMO;
66+/*
67+ * Get current OS boot time in millisecond
68+ */
69+static int64_t time_get_os_boottime_ms(void) {
70+ return metrics_time_get_os_boottime_us() / 1000;
71+}
7772
78- info->set_device_type(type);
73+static float combine_averages(float avg_a, int64_t ct_a, float avg_b,
74+ int64_t ct_b) {
75+ if (ct_a > 0 && ct_b > 0) {
76+ return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b);
77+ } else if (ct_b > 0) {
78+ return avg_b;
79+ } else {
80+ return avg_a;
81+ }
82+}
7983
80- event->set_disconnect_reason(disconnect_reason);
84+static int32_t combine_averages(int32_t avg_a, int64_t ct_a, int32_t avg_b,
85+ int64_t ct_b) {
86+ if (ct_a > 0 && ct_b > 0) {
87+ return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b);
88+ } else if (ct_b > 0) {
89+ return avg_b;
90+ } else {
91+ return avg_a;
92+ }
93+}
8194
82- event->set_event_time_millis(timestamp_ms);
95+void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
96+ if (metrics.audio_duration_ms >= 0) {
97+ audio_duration_ms = std::max(static_cast<int64_t>(0), audio_duration_ms);
98+ audio_duration_ms += metrics.audio_duration_ms;
99+ }
100+ if (metrics.media_timer_min_ms >= 0) {
101+ if (media_timer_min_ms < 0) {
102+ media_timer_min_ms = metrics.media_timer_min_ms;
103+ } else {
104+ media_timer_min_ms =
105+ std::min(media_timer_min_ms, metrics.media_timer_min_ms);
106+ }
107+ }
108+ if (metrics.media_timer_max_ms >= 0) {
109+ media_timer_max_ms =
110+ std::max(media_timer_max_ms, metrics.media_timer_max_ms);
111+ }
112+ if (metrics.media_timer_avg_ms >= 0 && metrics.total_scheduling_count >= 0) {
113+ if (media_timer_avg_ms < 0 || total_scheduling_count < 0) {
114+ media_timer_avg_ms = metrics.media_timer_avg_ms;
115+ total_scheduling_count = metrics.total_scheduling_count;
116+ } else {
117+ media_timer_avg_ms = combine_averages(
118+ media_timer_avg_ms, total_scheduling_count,
119+ metrics.media_timer_avg_ms, metrics.total_scheduling_count);
120+ total_scheduling_count += metrics.total_scheduling_count;
121+ }
122+ }
123+ if (metrics.buffer_overruns_max_count >= 0) {
124+ buffer_overruns_max_count =
125+ std::max(buffer_overruns_max_count, metrics.buffer_overruns_max_count);
126+ }
127+ if (metrics.buffer_overruns_total >= 0) {
128+ buffer_overruns_total =
129+ std::max(static_cast<int32_t>(0), buffer_overruns_total);
130+ buffer_overruns_total += metrics.buffer_overruns_total;
131+ }
132+ if (metrics.buffer_underruns_average >= 0 &&
133+ metrics.buffer_underruns_count >= 0) {
134+ if (buffer_underruns_average < 0 || buffer_underruns_count < 0) {
135+ buffer_underruns_average = metrics.buffer_underruns_average;
136+ buffer_underruns_count = metrics.buffer_underruns_count;
137+ } else {
138+ buffer_underruns_average = combine_averages(
139+ buffer_underruns_average, buffer_underruns_count,
140+ metrics.buffer_underruns_average, metrics.buffer_underruns_count);
141+ buffer_underruns_count += metrics.buffer_underruns_count;
142+ }
143+ }
83144 }
84145
85-void metrics_wake_event(wake_event_type_t type, const char *requestor,
86- const char *name, uint64_t timestamp_ms) {
87- std::lock_guard<std::mutex> lock(log_lock);
88- lazy_initialize();
146+bool A2dpSessionMetrics::operator==(const A2dpSessionMetrics& rhs) const {
147+ return audio_duration_ms == rhs.audio_duration_ms &&
148+ media_timer_min_ms == rhs.media_timer_min_ms &&
149+ media_timer_max_ms == rhs.media_timer_max_ms &&
150+ media_timer_avg_ms == rhs.media_timer_avg_ms &&
151+ total_scheduling_count == rhs.total_scheduling_count &&
152+ buffer_overruns_max_count == rhs.buffer_overruns_max_count &&
153+ buffer_overruns_total == rhs.buffer_overruns_total &&
154+ buffer_underruns_average == rhs.buffer_underruns_average &&
155+ buffer_underruns_count == rhs.buffer_underruns_count;
156+}
89157
90- WakeEvent *event = pending->add_wake_event();
158+static DeviceInfo_DeviceType get_device_type(device_type_t type) {
159+ switch (type) {
160+ case DEVICE_TYPE_BREDR:
161+ return DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR;
162+ case DEVICE_TYPE_LE:
163+ return DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_LE;
164+ case DEVICE_TYPE_DUMO:
165+ return DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_DUMO;
166+ case DEVICE_TYPE_UNKNOWN:
167+ default:
168+ return DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_UNKNOWN;
169+ }
170+}
91171
92- WakeEvent_WakeEventType waketype = WakeEvent::UNKNOWN;
172+static BluetoothSession_ConnectionTechnologyType get_connection_tech_type(
173+ connection_tech_t type) {
174+ switch (type) {
175+ case CONNECTION_TECHNOLOGY_TYPE_LE:
176+ return BluetoothSession_ConnectionTechnologyType::
177+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_LE;
178+ case CONNECTION_TECHNOLOGY_TYPE_BREDR:
179+ return BluetoothSession_ConnectionTechnologyType::
180+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR;
181+ case CONNECTION_TECHNOLOGY_TYPE_UNKNOWN:
182+ default:
183+ return BluetoothSession_ConnectionTechnologyType::
184+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_UNKNOWN;
185+ }
186+}
93187
94- if (type == WAKE_EVENT_ACQUIRED)
95- waketype = WakeEvent::ACQUIRED;
96- if (type == WAKE_EVENT_RELEASED)
97- waketype = WakeEvent::RELEASED;
188+static ScanEvent_ScanTechnologyType get_scan_tech_type(scan_tech_t type) {
189+ switch (type) {
190+ case SCAN_TECH_TYPE_LE:
191+ return ScanEvent_ScanTechnologyType::
192+ ScanEvent_ScanTechnologyType_SCAN_TECH_TYPE_LE;
193+ case SCAN_TECH_TYPE_BREDR:
194+ return ScanEvent_ScanTechnologyType::
195+ ScanEvent_ScanTechnologyType_SCAN_TECH_TYPE_BREDR;
196+ case SCAN_TECH_TYPE_BOTH:
197+ return ScanEvent_ScanTechnologyType::
198+ ScanEvent_ScanTechnologyType_SCAN_TECH_TYPE_BOTH;
199+ case SCAN_TYPE_UNKNOWN:
200+ default:
201+ return ScanEvent_ScanTechnologyType::
202+ ScanEvent_ScanTechnologyType_SCAN_TYPE_UNKNOWN;
203+ }
204+}
98205
99- event->set_wake_event_type(waketype);
206+static WakeEvent_WakeEventType get_wake_event_type(wake_event_type_t type) {
207+ switch (type) {
208+ case WAKE_EVENT_ACQUIRED:
209+ return WakeEvent_WakeEventType::WakeEvent_WakeEventType_ACQUIRED;
210+ case WAKE_EVENT_RELEASED:
211+ return WakeEvent_WakeEventType::WakeEvent_WakeEventType_RELEASED;
212+ case WAKE_EVENT_UNKNOWN:
213+ default:
214+ return WakeEvent_WakeEventType::WakeEvent_WakeEventType_UNKNOWN;
215+ }
216+}
100217
101- if (requestor)
102- event->set_requestor(requestor);
218+static BluetoothSession_DisconnectReasonType get_disconnect_reason_type(
219+ disconnect_reason_t type) {
220+ switch (type) {
221+ case DISCONNECT_REASON_METRICS_DUMP:
222+ return BluetoothSession_DisconnectReasonType::
223+ BluetoothSession_DisconnectReasonType_METRICS_DUMP;
224+ case DISCONNECT_REASON_NEXT_START_WITHOUT_END_PREVIOUS:
225+ return BluetoothSession_DisconnectReasonType::
226+ BluetoothSession_DisconnectReasonType_NEXT_START_WITHOUT_END_PREVIOUS;
227+ case DISCONNECT_REASON_UNKNOWN:
228+ default:
229+ return BluetoothSession_DisconnectReasonType::
230+ BluetoothSession_DisconnectReasonType_UNKNOWN;
231+ }
232+}
103233
104- if (name)
105- event->set_name(name);
234+struct BluetoothMetricsLogger::impl {
235+ impl(size_t max_bluetooth_session, size_t max_pair_event,
236+ size_t max_wake_event, size_t max_scan_event)
237+ : bt_session_queue_(
238+ new LeakyBondedQueue<BluetoothSession>(max_bluetooth_session)),
239+ pair_event_queue_(new LeakyBondedQueue<PairEvent>(max_pair_event)),
240+ wake_event_queue_(new LeakyBondedQueue<WakeEvent>(max_wake_event)),
241+ scan_event_queue_(new LeakyBondedQueue<ScanEvent>(max_scan_event)) {
242+ bluetooth_log_ = BluetoothLog::default_instance().New();
243+ bluetooth_session_ = nullptr;
244+ bluetooth_session_start_time_ms_ = 0;
245+ a2dp_session_metrics_ = A2dpSessionMetrics();
246+ }
106247
248+ /* Bluetooth log lock protected */
249+ BluetoothLog* bluetooth_log_;
250+ std::recursive_mutex bluetooth_log_lock_;
251+ /* End Bluetooth log lock protected */
252+ /* Bluetooth session lock protected */
253+ BluetoothSession* bluetooth_session_;
254+ uint64_t bluetooth_session_start_time_ms_;
255+ A2dpSessionMetrics a2dp_session_metrics_;
256+ std::recursive_mutex bluetooth_session_lock_;
257+ /* End bluetooth session lock protected */
258+ std::unique_ptr<LeakyBondedQueue<BluetoothSession>> bt_session_queue_;
259+ std::unique_ptr<LeakyBondedQueue<PairEvent>> pair_event_queue_;
260+ std::unique_ptr<LeakyBondedQueue<WakeEvent>> wake_event_queue_;
261+ std::unique_ptr<LeakyBondedQueue<ScanEvent>> scan_event_queue_;
262+};
263+
264+BluetoothMetricsLogger::BluetoothMetricsLogger()
265+ : pimpl_(new impl(kMaxNumBluetoothSession, kMaxNumPairEvent,
266+ kMaxNumWakeEvent, kMaxNumScanEvent)) {}
267+
268+void BluetoothMetricsLogger::LogPairEvent(uint32_t disconnect_reason,
269+ uint64_t timestamp_ms,
270+ uint32_t device_class,
271+ device_type_t device_type) {
272+ PairEvent* event = new PairEvent();
273+ DeviceInfo* info = event->mutable_device_paired_with();
274+ info->set_device_class(device_class);
275+ info->set_device_type(get_device_type(device_type));
276+ event->set_disconnect_reason(disconnect_reason);
107277 event->set_event_time_millis(timestamp_ms);
278+ pimpl_->pair_event_queue_->Enqueue(event);
279+ {
280+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_log_lock_);
281+ pimpl_->bluetooth_log_->set_num_pair_event(
282+ pimpl_->bluetooth_log_->num_pair_event() + 1);
283+ }
108284 }
109285
110-void metrics_scan_event(bool start, const char *initator, scan_tech_t type,
111- uint32_t results, uint64_t timestamp_ms) {
112- std::lock_guard<std::mutex> lock(log_lock);
113- lazy_initialize();
114-
115- ScanEvent *event = pending->add_scan_event();
286+void BluetoothMetricsLogger::LogWakeEvent(wake_event_type_t type,
287+ const std::string& requestor,
288+ const std::string& name,
289+ uint64_t timestamp_ms) {
290+ WakeEvent* event = new WakeEvent();
291+ event->set_wake_event_type(get_wake_event_type(type));
292+ event->set_requestor(requestor);
293+ event->set_name(name);
294+ event->set_event_time_millis(timestamp_ms);
295+ pimpl_->wake_event_queue_->Enqueue(event);
296+ {
297+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_log_lock_);
298+ pimpl_->bluetooth_log_->set_num_wake_event(
299+ pimpl_->bluetooth_log_->num_wake_event() + 1);
300+ }
301+}
116302
117- if (start)
303+void BluetoothMetricsLogger::LogScanEvent(bool start,
304+ const std::string& initator,
305+ scan_tech_t type, uint32_t results,
306+ uint64_t timestamp_ms) {
307+ ScanEvent* event = new ScanEvent();
308+ if (start) {
118309 event->set_scan_event_type(ScanEvent::SCAN_EVENT_START);
119- else
310+ } else {
120311 event->set_scan_event_type(ScanEvent::SCAN_EVENT_STOP);
121-
122- if (initator)
123- event->set_initiator(initator);
124-
125- ScanEvent::ScanTechnologyType scantype = ScanEvent::SCAN_TYPE_UNKNOWN;
126-
127- if (type == SCAN_TECH_TYPE_LE)
128- scantype = ScanEvent::SCAN_TECH_TYPE_LE;
129- if (type == SCAN_TECH_TYPE_BREDR)
130- scantype = ScanEvent::SCAN_TECH_TYPE_BREDR;
131- if (type == SCAN_TECH_TYPE_BOTH)
132- scantype = ScanEvent::SCAN_TECH_TYPE_BOTH;
133-
134- event->set_scan_technology_type(scantype);
135-
312+ }
313+ event->set_initiator(initator);
314+ event->set_scan_technology_type(get_scan_tech_type(type));
136315 event->set_number_results(results);
137-
138316 event->set_event_time_millis(timestamp_ms);
317+ pimpl_->scan_event_queue_->Enqueue(event);
318+ {
319+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_log_lock_);
320+ pimpl_->bluetooth_log_->set_num_scan_event(
321+ pimpl_->bluetooth_log_->num_scan_event() + 1);
322+ }
323+}
324+
325+void BluetoothMetricsLogger::LogBluetoothSessionStart(
326+ connection_tech_t connection_tech_type, uint64_t timestamp_ms) {
327+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_session_lock_);
328+ if (pimpl_->bluetooth_session_ != nullptr) {
329+ LogBluetoothSessionEnd(DISCONNECT_REASON_NEXT_START_WITHOUT_END_PREVIOUS,
330+ 0);
331+ }
332+ if (timestamp_ms == 0) {
333+ timestamp_ms = time_get_os_boottime_ms();
334+ }
335+ pimpl_->bluetooth_session_start_time_ms_ = timestamp_ms;
336+ pimpl_->bluetooth_session_ = new BluetoothSession();
337+ pimpl_->bluetooth_session_->set_connection_technology_type(
338+ get_connection_tech_type(connection_tech_type));
339+}
340+
341+void BluetoothMetricsLogger::LogBluetoothSessionEnd(
342+ disconnect_reason_t disconnect_reason, uint64_t timestamp_ms) {
343+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_session_lock_);
344+ if (pimpl_->bluetooth_session_ == nullptr) {
345+ return;
346+ }
347+ if (timestamp_ms == 0) {
348+ timestamp_ms = time_get_os_boottime_ms();
349+ }
350+ int64_t session_duration_sec =
351+ (timestamp_ms - pimpl_->bluetooth_session_start_time_ms_) / 1000;
352+ pimpl_->bluetooth_session_->set_session_duration_sec(session_duration_sec);
353+ pimpl_->bluetooth_session_->set_disconnect_reason_type(
354+ get_disconnect_reason_type(disconnect_reason));
355+ pimpl_->bt_session_queue_->Enqueue(pimpl_->bluetooth_session_);
356+ pimpl_->bluetooth_session_ = nullptr;
357+ {
358+ std::lock_guard<std::recursive_mutex> log_lock(pimpl_->bluetooth_log_lock_);
359+ pimpl_->bluetooth_log_->set_num_bluetooth_session(
360+ pimpl_->bluetooth_log_->num_bluetooth_session() + 1);
361+ }
139362 }
140363
141-void metrics_a2dp_session(int64_t session_duration_sec,
142- const char *disconnect_reason,
143- uint32_t device_class,
144- int32_t media_timer_min_ms,
145- int32_t media_timer_max_ms,
146- int32_t media_timer_avg_ms,
147- int32_t buffer_overruns_max_count,
148- int32_t buffer_overruns_total,
149- float buffer_underruns_average,
150- int32_t buffer_underruns_count) {
151- std::lock_guard<std::mutex> lock(log_lock);
152- lazy_initialize();
153-
154- BluetoothSession *bt_session = pending->add_session();
155-
156- // Set connection type: for A2DP it is always BR/EDR
157- BluetoothSession::ConnectionTechnologyType conn_type =
158- BluetoothSession::CONNECTION_TECHNOLOGY_TYPE_BREDR;
159- bt_session->set_connection_technology_type(conn_type);
160-
161- bt_session->set_session_duration_sec(session_duration_sec);
162- if (disconnect_reason != NULL)
163- bt_session->set_disconnect_reason(disconnect_reason);
164-
165- // Set device: class and type are pre-defined
166- DeviceInfo *info = bt_session->mutable_device_connected_to();
364+void BluetoothMetricsLogger::LogBluetoothSessionDeviceInfo(
365+ uint32_t device_class, device_type_t device_type) {
366+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_session_lock_);
367+ if (pimpl_->bluetooth_session_ == nullptr) {
368+ LogBluetoothSessionStart(CONNECTION_TECHNOLOGY_TYPE_UNKNOWN, 0);
369+ }
370+ DeviceInfo* info = pimpl_->bluetooth_session_->mutable_device_connected_to();
167371 info->set_device_class(device_class);
168372 info->set_device_type(DeviceInfo::DEVICE_TYPE_BREDR);
373+}
169374
170- A2DPSession *a2dp_session = bt_session->mutable_a2dp_session();
171- a2dp_session->set_media_timer_min_millis(media_timer_min_ms);
172- a2dp_session->set_media_timer_max_millis(media_timer_max_ms);
173- a2dp_session->set_media_timer_avg_millis(media_timer_avg_ms);
174- a2dp_session->set_buffer_overruns_max_count(buffer_overruns_max_count);
175- a2dp_session->set_buffer_overruns_total(buffer_overruns_total);
176- a2dp_session->set_buffer_underruns_average(buffer_underruns_average);
177- a2dp_session->set_buffer_underruns_count(buffer_underruns_count);
375+void BluetoothMetricsLogger::LogA2dpSession(
376+ const A2dpSessionMetrics& a2dp_session_metrics) {
377+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_session_lock_);
378+ if (pimpl_->bluetooth_session_ == nullptr) {
379+ // When no bluetooth session exist, create one on system's behalf
380+ // Set connection type: for A2DP it is always BR/EDR
381+ LogBluetoothSessionStart(CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
382+ LogBluetoothSessionDeviceInfo(BTM_COD_MAJOR_AUDIO, DEVICE_TYPE_BREDR);
383+ }
384+ // Accumulate metrics
385+ pimpl_->a2dp_session_metrics_.Update(a2dp_session_metrics);
386+ // Get or allocate new A2DP session object
387+ A2DPSession* a2dp_session =
388+ pimpl_->bluetooth_session_->mutable_a2dp_session();
389+ a2dp_session->set_audio_duration_millis(
390+ pimpl_->a2dp_session_metrics_.audio_duration_ms);
391+ a2dp_session->set_media_timer_min_millis(
392+ pimpl_->a2dp_session_metrics_.media_timer_min_ms);
393+ a2dp_session->set_media_timer_max_millis(
394+ pimpl_->a2dp_session_metrics_.media_timer_max_ms);
395+ a2dp_session->set_media_timer_avg_millis(
396+ pimpl_->a2dp_session_metrics_.media_timer_avg_ms);
397+ a2dp_session->set_buffer_overruns_max_count(
398+ pimpl_->a2dp_session_metrics_.buffer_overruns_max_count);
399+ a2dp_session->set_buffer_overruns_total(
400+ pimpl_->a2dp_session_metrics_.buffer_overruns_total);
401+ a2dp_session->set_buffer_underruns_average(
402+ pimpl_->a2dp_session_metrics_.buffer_underruns_average);
403+ a2dp_session->set_buffer_underruns_count(
404+ pimpl_->a2dp_session_metrics_.buffer_underruns_count);
178405 }
179406
180-void metrics_write(int fd, bool clear) {
181- log_lock.lock();
407+void BluetoothMetricsLogger::WriteString(std::string* serialized, bool clear) {
408+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_log_lock_);
409+ LOG_DEBUG(LOG_TAG, "%s building metrics", __func__);
410+ Build();
182411 LOG_DEBUG(LOG_TAG, "%s serializing metrics", __func__);
183- lazy_initialize();
184-
185- std::string serialized;
186- if (!pending->SerializeToString(&serialized)) {
412+ if (!pimpl_->bluetooth_log_->SerializeToString(serialized)) {
187413 LOG_ERROR(LOG_TAG, "%s: error serializing metrics", __func__);
188414 return;
189415 }
190-
191416 if (clear) {
192- pending->Clear();
417+ pimpl_->bluetooth_log_->Clear();
193418 }
194- log_lock.unlock();
419+}
195420
196- std::string protoBase64;
197- base::Base64Encode(serialized, &protoBase64);
421+void BluetoothMetricsLogger::WriteBase64String(std::string* serialized,
422+ bool clear) {
423+ this->WriteString(serialized, clear);
424+ base::Base64Encode(*serialized, serialized);
425+}
198426
427+void BluetoothMetricsLogger::WriteBase64(int fd, bool clear) {
428+ std::string protoBase64;
429+ this->WriteBase64String(&protoBase64, clear);
199430 ssize_t ret;
200431 OSI_NO_INTR(ret = write(fd, protoBase64.c_str(), protoBase64.size()));
201432 if (ret == -1) {
@@ -204,23 +435,137 @@ void metrics_write(int fd, bool clear) {
204435 }
205436 }
206437
207-void metrics_print(int fd, bool clear) {
208- log_lock.lock();
209- LOG_DEBUG(LOG_TAG, "%s printing metrics", __func__);
210- lazy_initialize();
211-
212- std::string pretty_output;
213- google::protobuf::TextFormat::PrintToString(*pending, &pretty_output);
438+void BluetoothMetricsLogger::CutoffSession() {
439+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_session_lock_);
440+ if (pimpl_->bluetooth_session_ != nullptr) {
441+ BluetoothSession* new_bt_session =
442+ new BluetoothSession(*pimpl_->bluetooth_session_);
443+ new_bt_session->clear_a2dp_session();
444+ new_bt_session->clear_rfcomm_session();
445+ LogBluetoothSessionEnd(DISCONNECT_REASON_METRICS_DUMP, 0);
446+ pimpl_->bluetooth_session_ = new_bt_session;
447+ pimpl_->bluetooth_session_start_time_ms_ = time_get_os_boottime_ms();
448+ pimpl_->a2dp_session_metrics_ = A2dpSessionMetrics();
449+ }
450+}
214451
215- if (clear) {
216- pending->Clear();
452+void BluetoothMetricsLogger::Build() {
453+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_log_lock_);
454+ CutoffSession();
455+ BluetoothLog* bluetooth_log = pimpl_->bluetooth_log_;
456+ while (!pimpl_->bt_session_queue_->Empty() &&
457+ static_cast<size_t>(bluetooth_log->session_size()) <=
458+ pimpl_->bt_session_queue_->Capacity()) {
459+ bluetooth_log->mutable_session()->AddAllocated(
460+ pimpl_->bt_session_queue_->Dequeue());
461+ }
462+ while (!pimpl_->pair_event_queue_->Empty() &&
463+ static_cast<size_t>(bluetooth_log->pair_event_size()) <=
464+ pimpl_->pair_event_queue_->Capacity()) {
465+ bluetooth_log->mutable_pair_event()->AddAllocated(
466+ pimpl_->pair_event_queue_->Dequeue());
467+ }
468+ while (!pimpl_->scan_event_queue_->Empty() &&
469+ static_cast<size_t>(bluetooth_log->scan_event_size()) <=
470+ pimpl_->scan_event_queue_->Capacity()) {
471+ bluetooth_log->mutable_scan_event()->AddAllocated(
472+ pimpl_->scan_event_queue_->Dequeue());
473+ }
474+ while (!pimpl_->wake_event_queue_->Empty() &&
475+ static_cast<size_t>(bluetooth_log->wake_event_size()) <=
476+ pimpl_->wake_event_queue_->Capacity()) {
477+ bluetooth_log->mutable_wake_event()->AddAllocated(
478+ pimpl_->wake_event_queue_->Dequeue());
217479 }
218- log_lock.unlock();
480+ while (!pimpl_->bt_session_queue_->Empty() &&
481+ static_cast<size_t>(bluetooth_log->wake_event_size()) <=
482+ pimpl_->wake_event_queue_->Capacity()) {
483+ bluetooth_log->mutable_wake_event()->AddAllocated(
484+ pimpl_->wake_event_queue_->Dequeue());
485+ }
486+}
219487
220- ssize_t ret;
221- OSI_NO_INTR(ret = write(fd, pretty_output.c_str(), pretty_output.size()));
222- if (ret == -1) {
223- LOG_ERROR(LOG_TAG, "%s: error writing to dumpsys fd: %s (%d)", __func__,
224- strerror(errno), errno);
488+void BluetoothMetricsLogger::ResetSession() {
489+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_session_lock_);
490+ if (pimpl_->bluetooth_session_ != nullptr) {
491+ delete pimpl_->bluetooth_session_;
492+ pimpl_->bluetooth_session_ = nullptr;
225493 }
494+ pimpl_->bluetooth_session_start_time_ms_ = 0;
495+ pimpl_->a2dp_session_metrics_ = A2dpSessionMetrics();
496+}
497+
498+void BluetoothMetricsLogger::ResetLog() {
499+ std::lock_guard<std::recursive_mutex> lock(pimpl_->bluetooth_log_lock_);
500+ pimpl_->bluetooth_log_->Clear();
501+}
502+
503+void BluetoothMetricsLogger::Reset() {
504+ ResetSession();
505+ ResetLog();
506+ pimpl_->bt_session_queue_->Clear();
507+ pimpl_->pair_event_queue_->Clear();
508+ pimpl_->wake_event_queue_->Clear();
509+ pimpl_->scan_event_queue_->Clear();
510+}
511+
512+} // namespace system_bt_osi
513+
514+using system_bt_osi::BluetoothMetricsLogger;
515+
516+void metrics_log_pair_event(uint32_t disconnect_reason, uint64_t timestamp_ms,
517+ uint32_t device_class, device_type_t device_type) {
518+ BluetoothMetricsLogger::GetInstance()->LogPairEvent(disconnect_reason,
519+ timestamp_ms, device_class, device_type);
520+}
521+
522+void metrics_log_wake_event(wake_event_type_t type, const char* requestor,
523+ const char* name, uint64_t timestamp_ms) {
524+ std::string requestor_str(requestor);
525+ std::string name_str(name);
526+ BluetoothMetricsLogger::GetInstance()->LogWakeEvent(type, requestor_str,
527+ name_str, timestamp_ms);
528+}
529+
530+void metrics_log_scan_event(bool start, const char* initator, scan_tech_t type,
531+ uint32_t results, uint64_t timestamp_ms) {
532+ std::string initator_str(initator);
533+ BluetoothMetricsLogger::GetInstance()->LogScanEvent(start, initator_str, type,
534+ results, timestamp_ms);
535+}
536+
537+void metrics_log_bluetooth_session_start(connection_tech_t connection_tech_type,
538+ uint64_t timestamp_ms) {
539+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
540+ connection_tech_type, 0);
541+}
542+
543+void metrics_log_bluetooth_session_end(disconnect_reason_t disconnect_reason,
544+ uint64_t timestamp_ms) {
545+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
546+ disconnect_reason, timestamp_ms);
547+}
548+
549+void metrics_log_bluetooth_session_device_info(uint32_t device_class,
550+ device_type_t device_type) {
551+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionDeviceInfo(
552+ device_class, device_type);
553+}
554+
555+void metrics_log_a2dp_session(A2dpSessionMetrics_t* metrics) {
556+ system_bt_osi::A2dpSessionMetrics metrics_obj;
557+ metrics_obj.audio_duration_ms = metrics->audio_duration_ms;
558+ metrics_obj.media_timer_min_ms = metrics->media_timer_min_ms;
559+ metrics_obj.media_timer_max_ms = metrics->media_timer_max_ms;
560+ metrics_obj.media_timer_avg_ms = metrics->media_timer_avg_ms;
561+ metrics_obj.total_scheduling_count = metrics->total_scheduling_count;
562+ metrics_obj.buffer_overruns_max_count = metrics->buffer_overruns_max_count;
563+ metrics_obj.buffer_overruns_total = metrics->buffer_overruns_total;
564+ metrics_obj.buffer_underruns_average = metrics->buffer_underruns_average;
565+ metrics_obj.buffer_underruns_count = metrics->buffer_underruns_count;
566+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics_obj);
567+}
568+
569+void metrics_write_base64(int fd, bool clear) {
570+ BluetoothMetricsLogger::GetInstance()->WriteBase64(fd, clear);
226571 }
--- a/osi/src/metrics_linux.cpp
+++ b/osi/src/metrics_linux.cpp
@@ -15,46 +15,230 @@
1515 * limitations under the License.
1616 *
1717 ******************************************************************************/
18+#define LOG_TAG "bt_osi_metrics"
1819
20+#include <unistd.h>
21+#include <algorithm>
22+#include <cerrno>
23+#include <chrono>
24+#include <cstdint>
25+#include <cstring>
26+#include <memory>
27+#include <mutex>
1928
20-#define LOG_TAG "bt_osi_metrics"
29+#include <base/base64.h>
30+#include <base/logging.h>
31+
32+#include "osi/include/leaky_bonded_queue.h"
33+#include "osi/include/log.h"
34+#include "osi/include/osi.h"
35+#include "osi/include/time.h"
2136
22-extern "C" {
2337 #include "osi/include/metrics.h"
38+#include "osi/include/metrics_cpp.h"
39+
40+
41+namespace system_bt_osi {
42+
43+// Maximum number of log entries for each repeated field
44+#define MAX_NUM_BLUETOOTH_SESSION 50
45+#define MAX_NUM_PAIR_EVENT 50
46+#define MAX_NUM_WAKE_EVENT 50
47+#define MAX_NUM_SCAN_EVENT 50
48+
49+static float combine_averages(float avg_a, int64_t ct_a, float avg_b,
50+ int64_t ct_b) {
51+ if (ct_a > 0 && ct_b > 0) {
52+ return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b);
53+ } else if (ct_b > 0) {
54+ return avg_b;
55+ } else {
56+ return avg_a;
57+ }
58+}
59+
60+static int32_t combine_averages(int32_t avg_a, int64_t ct_a, int32_t avg_b,
61+ int64_t ct_b) {
62+ if (ct_a > 0 && ct_b > 0) {
63+ return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b);
64+ } else if (ct_b > 0) {
65+ return avg_b;
66+ } else {
67+ return avg_a;
68+ }
69+}
70+
71+void A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) {
72+ if (metrics.audio_duration_ms > 0) {
73+ audio_duration_ms = std::max(static_cast<int64_t>(0), audio_duration_ms);
74+ audio_duration_ms += metrics.audio_duration_ms;
75+ }
76+ if (metrics.media_timer_min_ms > 0) {
77+ if (media_timer_min_ms < 0) {
78+ media_timer_min_ms = metrics.media_timer_min_ms;
79+ } else {
80+ media_timer_min_ms =
81+ std::min(media_timer_min_ms, metrics.media_timer_min_ms);
82+ }
83+ }
84+ if (metrics.media_timer_max_ms > 0) {
85+ media_timer_max_ms =
86+ std::max(media_timer_max_ms, metrics.media_timer_max_ms);
87+ }
88+ if (metrics.media_timer_avg_ms > 0 && metrics.total_scheduling_count > 0) {
89+ if (media_timer_avg_ms < 0 || total_scheduling_count < 0) {
90+ media_timer_avg_ms = metrics.media_timer_avg_ms;
91+ total_scheduling_count = metrics.total_scheduling_count;
92+ } else {
93+ media_timer_avg_ms = combine_averages(
94+ media_timer_avg_ms, total_scheduling_count,
95+ metrics.media_timer_avg_ms, metrics.total_scheduling_count);
96+ total_scheduling_count += metrics.total_scheduling_count;
97+ }
98+ }
99+ if (metrics.buffer_overruns_max_count > 0) {
100+ buffer_overruns_max_count =
101+ std::max(buffer_overruns_max_count, metrics.buffer_overruns_max_count);
102+ }
103+ if (metrics.buffer_overruns_total > 0) {
104+ buffer_overruns_total =
105+ std::max(static_cast<int32_t>(0), buffer_overruns_total);
106+ buffer_overruns_total += metrics.buffer_overruns_total;
107+ }
108+ if (metrics.buffer_underruns_average > 0 &&
109+ metrics.buffer_underruns_count > 0) {
110+ if (buffer_underruns_average < 0 || buffer_underruns_count < 0) {
111+ buffer_underruns_average = metrics.buffer_underruns_average;
112+ buffer_underruns_count = metrics.buffer_underruns_count;
113+ } else {
114+ buffer_underruns_average = combine_averages(
115+ metrics.buffer_underruns_average, metrics.buffer_underruns_count,
116+ buffer_underruns_average, buffer_underruns_count);
117+ buffer_underruns_count += metrics.buffer_underruns_count;
118+ }
119+ }
120+}
121+
122+bool A2dpSessionMetrics::operator==(const A2dpSessionMetrics& rhs) const {
123+ return audio_duration_ms == rhs.audio_duration_ms &&
124+ media_timer_min_ms == rhs.media_timer_min_ms &&
125+ media_timer_max_ms == rhs.media_timer_max_ms &&
126+ media_timer_avg_ms == rhs.media_timer_avg_ms &&
127+ total_scheduling_count == rhs.total_scheduling_count &&
128+ buffer_overruns_max_count == rhs.buffer_overruns_max_count &&
129+ buffer_overruns_total == rhs.buffer_overruns_total &&
130+ buffer_underruns_average == rhs.buffer_underruns_average &&
131+ buffer_underruns_count == rhs.buffer_underruns_count;
132+}
133+
134+struct BluetoothMetricsLogger::impl {
135+ // TODO(siyuanh): Implement for linux
136+};
137+
138+BluetoothMetricsLogger::BluetoothMetricsLogger() : pimpl_(new impl) {}
139+
140+void BluetoothMetricsLogger::LogPairEvent(uint32_t disconnect_reason,
141+ uint64_t timestamp_ms,
142+ uint32_t device_class,
143+ device_type_t device_type) {
144+ // TODO(siyuanh): Implement for linux
145+}
146+
147+void BluetoothMetricsLogger::LogWakeEvent(wake_event_type_t type,
148+ const std::string& requestor,
149+ const std::string& name,
150+ uint64_t timestamp_ms) {
151+ // TODO(siyuanh): Implement for linux
152+}
153+
154+void BluetoothMetricsLogger::LogScanEvent(bool start,
155+ const std::string& initator,
156+ scan_tech_t type, uint32_t results,
157+ uint64_t timestamp_ms) {
158+ // TODO(siyuanh): Implement for linux
159+}
160+
161+void BluetoothMetricsLogger::LogBluetoothSessionStart(
162+ connection_tech_t connection_tech_type, uint64_t timestamp_ms) {
163+ // TODO(siyuanh): Implement for linux
164+}
165+
166+void BluetoothMetricsLogger::LogBluetoothSessionEnd(
167+ const std::string& disconnect_reason, uint64_t timestamp_ms) {
168+ // TODO(siyuanh): Implement for linux
169+}
170+
171+void BluetoothMetricsLogger::LogBluetoothSessionDeviceInfo(
172+ uint32_t device_class, device_type_t device_type) {
173+ // TODO(siyuanh): Implement for linux
174+}
175+
176+void BluetoothMetricsLogger::LogA2dpSession(
177+ const A2dpSessionMetrics& a2dp_session_metrics) {
178+ // TODO(siyuanh): Implement for linux
179+}
180+
181+void BluetoothMetricsLogger::WriteString(std::string* serialized, bool clear) {
182+ // TODO(siyuanh): Implement for linux
183+}
184+
185+void BluetoothMetricsLogger::WriteBase64String(std::string* serialized,
186+ bool clear) {
187+ // TODO(siyuanh): Implement for linux
188+}
189+
190+void BluetoothMetricsLogger::WriteBase64(int fd, bool clear) {
191+ // TODO(siyuanh): Implement for linux
192+}
193+
194+void BluetoothMetricsLogger::CutoffSession() {
195+ // TODO(siyuanh): Implement for linux
196+}
197+
198+void BluetoothMetricsLogger::Build() {
199+ // TODO(siyuanh): Implement for linux
200+}
201+
202+void BluetoothMetricsLogger::Reset() {
203+ // TODO(siyuanh): Implement for linux
204+}
205+
206+} // namespace system_bt_osi
207+
208+void metrics_log_pair_event(uint32_t disconnect_reason, uint64_t timestamp_ms,
209+ uint32_t device_class, device_type_t device_type) {
210+ // TODO(siyuanh): Implement for linux
211+}
212+
213+void metrics_log_wake_event(wake_event_type_t type, const char* requestor,
214+ const char* name, uint64_t timestamp_ms) {
215+ // TODO(siyuanh): Implement for linux
24216 }
25217
26-void metrics_pair_event(uint32_t disconnect_reason, uint64_t timestamp_ms,
27- uint32_t device_class, device_type_t device_type) {
28- //TODO(jpawlowski): implement
218+void metrics_log_scan_event(bool start, const char* initator, scan_tech_t type,
219+ uint32_t results, uint64_t timestamp_ms) {
220+ // TODO(siyuanh): Implement for linux
29221 }
30222
31-void metrics_wake_event(wake_event_type_t type, const char *requestor,
32- const char *name, uint64_t timestamp_ms) {
33- //TODO(jpawlowski): implement
223+void metrics_log_bluetooth_session_start(connection_tech_t connection_tech_type,
224+ uint64_t timestamp_ms) {
225+ // TODO(siyuanh): Implement for linux
34226 }
35227
36-void metrics_scan_event(bool start, const char *initator, scan_tech_t type,
37- uint32_t results, uint64_t timestamp_ms) {
38- //TODO(jpawlowski): implement
228+void metrics_log_bluetooth_session_end(const char* disconnect_reason,
229+ uint64_t timestamp_ms) {
230+ // TODO(siyuanh): Implement for linux
39231 }
40232
41-void metrics_a2dp_session(int64_t session_duration_sec,
42- const char *disconnect_reason,
43- uint32_t device_class,
44- int32_t media_timer_min_ms,
45- int32_t media_timer_max_ms,
46- int32_t media_timer_avg_ms,
47- int32_t buffer_overruns_max_count,
48- int32_t buffer_overruns_total,
49- float buffer_underruns_average,
50- int32_t buffer_underruns_count) {
51- //TODO(jpawlowski): implement
233+void metrics_log_bluetooth_session_device_info(uint32_t device_class,
234+ device_type_t device_type) {
235+ // TODO(siyuanh): Implement for linux
52236 }
53237
54-void metrics_write(int fd, bool clear) {
55- //TODO(jpawlowski): implement
238+void metrics_log_a2dp_session(A2dpSessionMetrics_t* metrics) {
239+ // TODO(siyuanh): Implement for linux
56240 }
57241
58-void metrics_print(int fd, bool clear) {
59- //TODO(jpawlowski): implement
242+void metrics_write_base64(int fd, bool clear) {
243+ // TODO(siyuanh): Implement for linux
60244 }
--- a/osi/src/protos/bluetooth.proto
+++ b/osi/src/protos/bluetooth.proto
@@ -24,6 +24,21 @@ message BluetoothLog {
2424
2525 // Scan event information.
2626 repeated ScanEvent scan_event = 4;
27+
28+ // Number of bonded devices.
29+ optional int32 num_bonded_devices = 5;
30+
31+ // Number of BluetoothSession including discarded ones beyond capacity
32+ optional int64 num_bluetooth_session = 6;
33+
34+ // Number of PairEvent including discarded ones beyond capacity
35+ optional int64 num_pair_event = 7;
36+
37+ // Number of WakeEvent including discarded ones beyond capacity
38+ optional int64 num_wake_event = 8;
39+
40+ // Number of ScanEvent including discarded ones beyond capacity
41+ optional int64 num_scan_event = 9;
2742 }
2843
2944 // The information about the device.
@@ -63,6 +78,17 @@ message BluetoothSession {
6378 CONNECTION_TECHNOLOGY_TYPE_BREDR = 2;
6479 }
6580
81+ enum DisconnectReasonType {
82+ UNKNOWN = 0;
83+
84+ // A metrics dump takes a snapshot of current Bluetooth session and thus
85+ // is not a real disconnect, but a discontinuation in metrics logging.
86+ // This enum indicates this situation.
87+ METRICS_DUMP = 1;
88+
89+ NEXT_START_WITHOUT_END_PREVIOUS = 2;
90+ }
91+
6692 // Duration of the session.
6793 optional int64 session_duration_sec = 2;
6894
@@ -70,7 +96,7 @@ message BluetoothSession {
7096 optional ConnectionTechnologyType connection_technology_type = 3;
7197
7298 // Reason for disconnecting.
73- optional string disconnect_reason = 4;
99+ optional string disconnect_reason = 4 [deprecated=true];
74100
75101 // The information about the device which it is connected to.
76102 optional DeviceInfo device_connected_to = 5;
@@ -78,8 +104,11 @@ message BluetoothSession {
78104 // The information about the RFComm session.
79105 optional RFCommSession rfcomm_session = 6;
80106
81- // The information about the A2DP session.
107+ // The information about the A2DP audio session.
82108 optional A2DPSession a2dp_session = 7;
109+
110+ // Numeric reason for disconnecting as defined in metrics.h
111+ optional DisconnectReasonType disconnect_reason_type = 8;
83112 }
84113
85114 message RFCommSession {
@@ -91,7 +120,7 @@ message RFCommSession {
91120 optional int32 tx_bytes = 2;
92121 }
93122
94-// Session information that gets logged for every A2DP session.
123+// Session information that gets logged for A2DP session.
95124 message A2DPSession {
96125
97126 // Media timer in milliseconds.
@@ -114,6 +143,9 @@ message A2DPSession {
114143
115144 // Buffer underruns count.
116145 optional int32 buffer_underruns_count = 7;
146+
147+ // Total audio time in this A2DP session
148+ optional int64 audio_duration_millis = 8;
117149 }
118150
119151 message PairEvent {
--- a/osi/src/wakelock.c
+++ b/osi/src/wakelock.c
@@ -294,7 +294,7 @@ static void update_wakelock_acquired_stats(bt_status_t acquired_status) {
294294
295295 pthread_mutex_unlock(&monitor);
296296
297- metrics_wake_event(WAKE_EVENT_ACQUIRED, NULL, WAKE_LOCK_ID, now_ms);
297+ metrics_log_wake_event(WAKE_EVENT_ACQUIRED, "", "", now_ms);
298298 }
299299
300300 //
@@ -338,7 +338,7 @@ static void update_wakelock_released_stats(bt_status_t released_status) {
338338
339339 pthread_mutex_unlock(&monitor);
340340
341- metrics_wake_event(WAKE_EVENT_RELEASED, NULL, WAKE_LOCK_ID, now_ms);
341+ metrics_log_wake_event(WAKE_EVENT_RELEASED, "", "", now_ms);
342342 }
343343
344344 void wakelock_debug_dump(int fd) {
--- /dev/null
+++ b/osi/test/leaky_bonded_queue_test.cpp
@@ -0,0 +1,242 @@
1+/******************************************************************************
2+ *
3+ * Copyright (C) 2016 Google, Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+#include <gmock/gmock.h>
19+#include <gtest/gtest.h>
20+
21+#include <base/logging.h>
22+
23+#include "osi/include/leaky_bonded_queue.h"
24+
25+namespace testing {
26+
27+using system_bt_osi::LeakyBondedQueue;
28+
29+#define ITEM_EQ(a, b) \
30+ do { \
31+ EXPECT_EQ(a, b); \
32+ EXPECT_EQ(a->index, b->index); \
33+ } while (0)
34+
35+class Item {
36+ public:
37+ Item(int i) { index = i; }
38+ virtual ~Item() {}
39+ int index;
40+};
41+
42+class MockItem : public Item {
43+ public:
44+ MockItem(int i) : Item(i) {}
45+ ~MockItem() { Destruct(); }
46+ MOCK_METHOD0(Destruct, void());
47+};
48+
49+TEST(LeakyBondedQueueTest, TestEnqueueDequeue) {
50+ MockItem* item1 = new MockItem(1);
51+ MockItem* item2 = new MockItem(2);
52+ MockItem* item3 = new MockItem(3);
53+ MockItem* item4 = new MockItem(4);
54+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(3);
55+ EXPECT_EQ(queue->Capacity(), static_cast<size_t>(3));
56+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
57+ queue->Enqueue(item1);
58+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
59+ queue->Enqueue(item2);
60+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
61+ queue->Enqueue(item3);
62+ EXPECT_EQ(queue->Length(), static_cast<size_t>(3));
63+ EXPECT_CALL(*item1, Destruct()).Times(1);
64+ queue->Enqueue(item4);
65+ EXPECT_EQ(queue->Length(), static_cast<size_t>(3));
66+ MockItem* item2_2 = queue->Dequeue();
67+ MockItem* item3_3 = queue->Dequeue();
68+ MockItem* item4_4 = queue->Dequeue();
69+ EXPECT_THAT(item2_2, NotNull());
70+ ITEM_EQ(item2_2, item2);
71+ EXPECT_THAT(item3_3, NotNull());
72+ ITEM_EQ(item3_3, item3);
73+ EXPECT_THAT(item4_4, NotNull());
74+ ITEM_EQ(item4_4, item4);
75+ LOG(INFO) << "All done release items";
76+ EXPECT_CALL(*item2_2, Destruct()).Times(1);
77+ delete item2_2;
78+ EXPECT_CALL(*item3_3, Destruct()).Times(1);
79+ delete item3_3;
80+ EXPECT_CALL(*item4_4, Destruct()).Times(1);
81+ delete item4_4;
82+ delete queue;
83+}
84+
85+TEST(LeakyBondedQueueTest, TestEnqueueDequeue2) {
86+ MockItem* item1 = new MockItem(1);
87+ MockItem* item2 = new MockItem(2);
88+ MockItem* item3 = new MockItem(3);
89+ MockItem* item4 = new MockItem(4);
90+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
91+ EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
92+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
93+ queue->Enqueue(item1);
94+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
95+ MockItem* item1_1 = queue->Dequeue();
96+ ITEM_EQ(item1, item1_1);
97+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
98+ queue->Enqueue(item2);
99+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
100+ queue->Enqueue(item3);
101+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
102+ EXPECT_CALL(*item2, Destruct()).Times(1);
103+ queue->Enqueue(item4);
104+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
105+ EXPECT_CALL(*item3, Destruct()).Times(1);
106+ queue->Enqueue(item1);
107+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
108+ MockItem* item4_4_4 = queue->Dequeue();
109+ MockItem* item1_1_1 = queue->Dequeue();
110+ ITEM_EQ(item4_4_4, item4);
111+ ITEM_EQ(item1_1_1, item1);
112+ EXPECT_CALL(*item1_1_1, Destruct()).Times(1);
113+ delete item1_1_1;
114+ EXPECT_CALL(*item4_4_4, Destruct()).Times(1);
115+ delete item4_4_4;
116+ delete queue;
117+}
118+
119+TEST(LeakyBondedQueueTest, TestEnqueuePop) {
120+ MockItem* item1 = new MockItem(1);
121+ MockItem* item2 = new MockItem(2);
122+ MockItem* item3 = new MockItem(3);
123+ MockItem* item4 = new MockItem(4);
124+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
125+ EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
126+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
127+ queue->Enqueue(item1);
128+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
129+ MockItem* item1_1 = queue->Dequeue();
130+ ITEM_EQ(item1, item1_1);
131+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
132+ queue->Enqueue(item2);
133+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
134+ queue->Enqueue(item3);
135+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
136+ MockItem* item2_2 = queue->EnqueueWithPop(item4);
137+ EXPECT_THAT(item2_2, NotNull());
138+ ITEM_EQ(item2_2, item2);
139+ EXPECT_CALL(*item2, Destruct()).Times(1);
140+ delete item2_2;
141+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
142+ MockItem* item3_3 = queue->EnqueueWithPop(item1);
143+ EXPECT_THAT(item3_3, NotNull());
144+ ITEM_EQ(item3_3, item3);
145+ EXPECT_CALL(*item3, Destruct()).Times(1);
146+ delete item3_3;
147+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
148+ MockItem* item4_4_4 = queue->Dequeue();
149+ MockItem* item1_1_1 = queue->Dequeue();
150+ ITEM_EQ(item4_4_4, item4);
151+ ITEM_EQ(item1_1_1, item1);
152+ EXPECT_CALL(*item1_1_1, Destruct()).Times(1);
153+ delete item1_1_1;
154+ EXPECT_CALL(*item4_4_4, Destruct()).Times(1);
155+ delete item4_4_4;
156+ delete queue;
157+}
158+
159+TEST(LeakyBondedQueueTest, TestQueueClear) {
160+ MockItem* item1 = new MockItem(1);
161+ MockItem* item2 = new MockItem(2);
162+ MockItem* item3 = new MockItem(3);
163+ MockItem* item4 = new MockItem(4);
164+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
165+ EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
166+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
167+ queue->Enqueue(item1);
168+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
169+ MockItem* item1_1 = queue->Dequeue();
170+ ITEM_EQ(item1, item1_1);
171+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
172+ queue->Enqueue(item2);
173+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
174+ queue->Enqueue(item3);
175+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
176+ EXPECT_CALL(*item2, Destruct()).Times(1);
177+ queue->Enqueue(item4);
178+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
179+ EXPECT_CALL(*item3, Destruct()).Times(1);
180+ queue->Enqueue(item1);
181+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
182+ EXPECT_CALL(*item1, Destruct()).Times(1);
183+ EXPECT_CALL(*item4, Destruct()).Times(1);
184+ queue->Clear();
185+ delete queue;
186+}
187+
188+TEST(LeakyBondedQueueTest, TestQueueFree) {
189+ MockItem* item1 = new MockItem(1);
190+ MockItem* item2 = new MockItem(2);
191+ MockItem* item3 = new MockItem(3);
192+ MockItem* item4 = new MockItem(4);
193+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
194+ EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
195+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
196+ queue->Enqueue(item1);
197+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
198+ MockItem* item1_1 = queue->Dequeue();
199+ ITEM_EQ(item1, item1_1);
200+ EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
201+ queue->Enqueue(item2);
202+ EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
203+ queue->Enqueue(item3);
204+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
205+ EXPECT_CALL(*item2, Destruct()).Times(1);
206+ queue->Enqueue(item4);
207+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
208+ EXPECT_CALL(*item3, Destruct()).Times(1);
209+ queue->Enqueue(item1);
210+ EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
211+ EXPECT_CALL(*item1, Destruct()).Times(1);
212+ EXPECT_CALL(*item4, Destruct()).Times(1);
213+ delete queue;
214+}
215+
216+TEST(LeakyBondedQueueTest, TestPushNull) {
217+ MockItem* item1 = nullptr;
218+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
219+ queue->Enqueue(item1);
220+ MockItem* item1_1 = queue->Dequeue();
221+ EXPECT_THAT(item1_1, IsNull());
222+}
223+
224+TEST(LeakyBondedQueueTest, TestPushNullOverflowQueue) {
225+ MockItem* item1 = nullptr;
226+ MockItem* item2 = nullptr;
227+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(1);
228+ queue->Enqueue(item1);
229+ queue->Enqueue(item2);
230+ MockItem* item2_2 = queue->Dequeue();
231+ EXPECT_THAT(item2_2, IsNull());
232+}
233+
234+TEST(LeakyBondedQueueTest, TestPushNullDeleteQueue) {
235+ MockItem* item1 = nullptr;
236+ MockItem* item2 = nullptr;
237+ LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
238+ queue->Enqueue(item1);
239+ queue->Enqueue(item2);
240+ delete queue;
241+}
242+}
--- /dev/null
+++ b/osi/test/metrics_test.cpp
@@ -0,0 +1,805 @@
1+/******************************************************************************
2+ *
3+ * Copyright (C) 2016 Google, Inc.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ ******************************************************************************/
18+#include <chrono>
19+#include <cstdint>
20+#include <string>
21+#include <thread>
22+#include <vector>
23+
24+#include <gmock/gmock.h>
25+#include <gtest/gtest.h>
26+
27+#include <base/logging.h>
28+
29+#include "osi/include/metrics.h"
30+#include "osi/include/metrics_cpp.h"
31+#include "osi/include/time.h"
32+#include "osi/src/protos/bluetooth.pb.h"
33+
34+#define BTM_COD_MAJOR_AUDIO_TEST 0x04
35+
36+namespace testing {
37+
38+using clearcut::connectivity::A2DPSession;
39+using clearcut::connectivity::BluetoothLog;
40+using clearcut::connectivity::BluetoothSession;
41+using clearcut::connectivity::BluetoothSession_ConnectionTechnologyType;
42+using clearcut::connectivity::BluetoothSession_DisconnectReasonType;
43+using clearcut::connectivity::DeviceInfo;
44+using clearcut::connectivity::DeviceInfo_DeviceType;
45+using clearcut::connectivity::PairEvent;
46+using clearcut::connectivity::RFCommSession;
47+using clearcut::connectivity::ScanEvent;
48+using clearcut::connectivity::ScanEvent_ScanTechnologyType;
49+using clearcut::connectivity::ScanEvent_ScanEventType;
50+using clearcut::connectivity::WakeEvent;
51+using clearcut::connectivity::WakeEvent_WakeEventType;
52+using system_bt_osi::BluetoothMetricsLogger;
53+using system_bt_osi::A2dpSessionMetrics;
54+
55+namespace {
56+const size_t kMaxEventGenerationLimit = 5000;
57+}
58+
59+uint64_t metrics_time_get_os_boottime_us(void) {
60+ struct timespec ts_now;
61+ clock_gettime(CLOCK_BOOTTIME, &ts_now);
62+
63+ return ((uint64_t)ts_now.tv_sec * 1000000L) +
64+ ((uint64_t)ts_now.tv_nsec / 1000);
65+}
66+
67+/*
68+ * Get current OS boot time in millisecond
69+ */
70+static int64_t time_get_os_boottime_ms(void) {
71+ return metrics_time_get_os_boottime_us() / 1000;
72+}
73+
74+static void sleep_ms(int64_t t) {
75+ std::this_thread::sleep_for(std::chrono::milliseconds(t));
76+}
77+
78+DeviceInfo* MakeDeviceInfo(int32_t device_class,
79+ DeviceInfo_DeviceType device_type) {
80+ DeviceInfo* info = new DeviceInfo();
81+ info->set_device_class(device_class);
82+ info->set_device_type(device_type);
83+ return info;
84+}
85+
86+PairEvent* MakePairEvent(int32_t disconnect_reason, int64_t timestamp_ms,
87+ DeviceInfo* device_info) {
88+ PairEvent* event = new PairEvent();
89+ event->set_disconnect_reason(disconnect_reason);
90+ event->set_event_time_millis(timestamp_ms);
91+ if (device_info) event->set_allocated_device_paired_with(device_info);
92+ return event;
93+}
94+
95+WakeEvent* MakeWakeEvent(WakeEvent_WakeEventType event_type,
96+ const std::string& requestor, const std::string& name,
97+ int64_t timestamp_ms) {
98+ WakeEvent* event = new WakeEvent();
99+ event->set_wake_event_type(event_type);
100+ event->set_requestor(requestor);
101+ event->set_name(name);
102+ event->set_event_time_millis(timestamp_ms);
103+ return event;
104+}
105+
106+ScanEvent* MakeScanEvent(ScanEvent_ScanEventType event_type,
107+ const std::string& initiator,
108+ ScanEvent_ScanTechnologyType tech_type,
109+ int32_t num_results, int64_t timestamp_ms) {
110+ ScanEvent* event = new ScanEvent();
111+ event->set_scan_event_type(event_type);
112+ event->set_initiator(initiator);
113+ event->set_scan_technology_type(tech_type);
114+ event->set_number_results(num_results);
115+ event->set_event_time_millis(timestamp_ms);
116+ return event;
117+}
118+
119+A2DPSession* MakeA2DPSession(const A2dpSessionMetrics& metrics) {
120+ A2DPSession* session = new A2DPSession();
121+ session->set_media_timer_min_millis(metrics.media_timer_min_ms);
122+ session->set_media_timer_max_millis(metrics.media_timer_max_ms);
123+ session->set_media_timer_avg_millis(metrics.media_timer_avg_ms);
124+ session->set_buffer_overruns_max_count(metrics.buffer_overruns_max_count);
125+ session->set_buffer_overruns_total(metrics.buffer_overruns_total);
126+ session->set_buffer_underruns_average(metrics.buffer_underruns_average);
127+ session->set_buffer_underruns_count(metrics.buffer_underruns_count);
128+ session->set_audio_duration_millis(metrics.audio_duration_ms);
129+ return session;
130+}
131+
132+BluetoothSession* MakeBluetoothSession(
133+ int64_t session_duration_sec,
134+ BluetoothSession_ConnectionTechnologyType conn_type,
135+ BluetoothSession_DisconnectReasonType disconnect_reason,
136+ DeviceInfo* device_info, RFCommSession* rfcomm_session,
137+ A2DPSession* a2dp_session) {
138+ BluetoothSession* session = new BluetoothSession();
139+ if (a2dp_session) session->set_allocated_a2dp_session(a2dp_session);
140+ if (rfcomm_session) session->set_allocated_rfcomm_session(rfcomm_session);
141+ if (device_info) session->set_allocated_device_connected_to(device_info);
142+ session->set_session_duration_sec(session_duration_sec);
143+ session->set_connection_technology_type(conn_type);
144+ session->set_disconnect_reason_type(disconnect_reason);
145+ return session;
146+}
147+
148+BluetoothLog* MakeBluetoothLog(std::vector<BluetoothSession*> bt_sessions,
149+ std::vector<PairEvent*> pair_events,
150+ std::vector<WakeEvent*> wake_events,
151+ std::vector<ScanEvent*> scan_events) {
152+ BluetoothLog* bt_log = new BluetoothLog();
153+ for (BluetoothSession* session : bt_sessions) {
154+ bt_log->mutable_session()->AddAllocated(session);
155+ }
156+ bt_sessions.clear();
157+ for (PairEvent* event : pair_events) {
158+ bt_log->mutable_pair_event()->AddAllocated(event);
159+ }
160+ pair_events.clear();
161+ for (WakeEvent* event : wake_events) {
162+ bt_log->mutable_wake_event()->AddAllocated(event);
163+ }
164+ wake_events.clear();
165+ for (ScanEvent* event : scan_events) {
166+ bt_log->mutable_scan_event()->AddAllocated(event);
167+ }
168+ scan_events.clear();
169+ return bt_log;
170+}
171+
172+void GenerateWakeEvents(size_t start, size_t end,
173+ std::vector<WakeEvent*>* wake_events) {
174+ for (size_t i = start; i < end; ++i) {
175+ wake_events->push_back(MakeWakeEvent(
176+ i % 2 == 0 ? WakeEvent_WakeEventType::WakeEvent_WakeEventType_ACQUIRED
177+ : WakeEvent_WakeEventType::WakeEvent_WakeEventType_RELEASED,
178+ "TEST_REQ", "TEST_NAME", i));
179+ }
180+}
181+
182+#define COMPARE_A2DP_METRICS(a, b) \
183+ do { \
184+ EXPECT_EQ(a.audio_duration_ms, b.audio_duration_ms); \
185+ EXPECT_EQ(a.media_timer_min_ms, b.media_timer_min_ms); \
186+ EXPECT_EQ(a.media_timer_max_ms, b.media_timer_max_ms); \
187+ EXPECT_EQ(a.media_timer_avg_ms, b.media_timer_avg_ms); \
188+ EXPECT_EQ(a.total_scheduling_count, b.total_scheduling_count); \
189+ EXPECT_EQ(a.buffer_overruns_max_count, b.buffer_overruns_max_count); \
190+ EXPECT_EQ(a.buffer_overruns_total, b.buffer_overruns_total); \
191+ EXPECT_THAT(a.buffer_underruns_average, \
192+ FloatNear(b.buffer_underruns_average, 0.01)); \
193+ a.buffer_underruns_average = b.buffer_underruns_average; \
194+ EXPECT_EQ(a.buffer_underruns_count, b.buffer_underruns_count); \
195+ } while (0)
196+
197+/*
198+ * metrics_sum = metrics1 + metrics2
199+ */
200+TEST(BluetoothA2DPSessionMetricsTest, TestUpdateNormal) {
201+ A2dpSessionMetrics metrics1;
202+ A2dpSessionMetrics metrics2;
203+ A2dpSessionMetrics metrics_sum;
204+ metrics1.audio_duration_ms = 10;
205+ metrics2.audio_duration_ms = 25;
206+ metrics_sum.audio_duration_ms = 35;
207+ metrics1.media_timer_min_ms = 10;
208+ metrics2.media_timer_min_ms = 25;
209+ metrics_sum.media_timer_min_ms = 10;
210+ metrics1.media_timer_max_ms = 100;
211+ metrics2.media_timer_max_ms = 200;
212+ metrics_sum.media_timer_max_ms = 200;
213+ metrics1.media_timer_avg_ms = 50;
214+ metrics1.total_scheduling_count = 50;
215+ metrics2.media_timer_avg_ms = 100;
216+ metrics2.total_scheduling_count = 50;
217+ metrics_sum.media_timer_avg_ms = 75;
218+ metrics_sum.total_scheduling_count = 100;
219+ metrics1.buffer_overruns_max_count = 70;
220+ metrics2.buffer_overruns_max_count = 80;
221+ metrics_sum.buffer_overruns_max_count = 80;
222+ metrics1.buffer_underruns_average = 80;
223+ metrics1.buffer_underruns_count = 1200;
224+ metrics2.buffer_underruns_average = 130;
225+ metrics2.buffer_underruns_count = 2400;
226+ metrics_sum.buffer_underruns_average = 113.33333333;
227+ metrics_sum.buffer_underruns_count = 3600;
228+ metrics1.Update(metrics2);
229+ COMPARE_A2DP_METRICS(metrics1, metrics_sum);
230+ EXPECT_TRUE(metrics1 == metrics_sum);
231+ EXPECT_EQ(metrics1, metrics_sum);
232+}
233+
234+TEST(BluetoothA2DPSessionMetricsTest, TestUpdateNew) {
235+ A2dpSessionMetrics metrics1;
236+ A2dpSessionMetrics metrics2;
237+ A2dpSessionMetrics metrics_sum;
238+ metrics2.audio_duration_ms = 25;
239+ metrics_sum.audio_duration_ms = 25;
240+ metrics2.media_timer_min_ms = 25;
241+ metrics_sum.media_timer_min_ms = 25;
242+ metrics2.media_timer_max_ms = 200;
243+ metrics_sum.media_timer_max_ms = 200;
244+ metrics2.media_timer_avg_ms = 100;
245+ metrics2.total_scheduling_count = 50;
246+ metrics_sum.media_timer_avg_ms = 100;
247+ metrics_sum.total_scheduling_count = 50;
248+ metrics2.buffer_overruns_max_count = 80;
249+ metrics_sum.buffer_overruns_max_count = 80;
250+ metrics2.buffer_underruns_average = 130;
251+ metrics2.buffer_underruns_count = 2400;
252+ metrics_sum.buffer_underruns_average = 130;
253+ metrics_sum.buffer_underruns_count = 2400;
254+ metrics1.Update(metrics2);
255+ COMPARE_A2DP_METRICS(metrics1, metrics_sum);
256+ EXPECT_TRUE(metrics1 == metrics_sum);
257+ EXPECT_EQ(metrics1, metrics_sum);
258+}
259+
260+TEST(BluetoothA2DPSessionMetricsTest, TestNullUpdate) {
261+ A2dpSessionMetrics metrics1;
262+ A2dpSessionMetrics metrics2;
263+ A2dpSessionMetrics metrics_sum;
264+ metrics2.audio_duration_ms = 25;
265+ metrics_sum.audio_duration_ms = 25;
266+ metrics2.media_timer_min_ms = 25;
267+ metrics_sum.media_timer_min_ms = 25;
268+ metrics2.media_timer_max_ms = 200;
269+ metrics_sum.media_timer_max_ms = 200;
270+ metrics2.media_timer_avg_ms = 100;
271+ metrics2.total_scheduling_count = 50;
272+ metrics_sum.media_timer_avg_ms = 100;
273+ metrics_sum.total_scheduling_count = 50;
274+ metrics2.buffer_overruns_max_count = 80;
275+ metrics_sum.buffer_overruns_max_count = 80;
276+ metrics2.buffer_underruns_average = 130;
277+ metrics2.buffer_underruns_count = 2400;
278+ metrics_sum.buffer_underruns_average = 130;
279+ metrics_sum.buffer_underruns_count = 2400;
280+ metrics2.Update(metrics1);
281+ COMPARE_A2DP_METRICS(metrics2, metrics_sum);
282+ EXPECT_TRUE(metrics2 == metrics_sum);
283+ EXPECT_EQ(metrics2, metrics_sum);
284+}
285+
286+TEST(BluetoothA2DPSessionMetricsTest, TestPartialUpdate) {
287+ A2dpSessionMetrics metrics1;
288+ A2dpSessionMetrics metrics2;
289+ A2dpSessionMetrics metrics_sum;
290+ metrics1.audio_duration_ms = 10;
291+ metrics2.audio_duration_ms = 25;
292+ metrics_sum.audio_duration_ms = 35;
293+ metrics1.media_timer_min_ms = 10;
294+ metrics_sum.media_timer_min_ms = 10;
295+ metrics1.media_timer_max_ms = 100;
296+ metrics_sum.media_timer_max_ms = 100;
297+ metrics1.media_timer_avg_ms = 50;
298+ metrics1.total_scheduling_count = 50;
299+ metrics2.media_timer_avg_ms = 100;
300+ metrics_sum.media_timer_avg_ms = 50;
301+ metrics_sum.total_scheduling_count = 50;
302+ metrics1.buffer_overruns_max_count = 70;
303+ metrics_sum.buffer_overruns_max_count = 70;
304+ metrics1.buffer_underruns_average = 80;
305+ metrics1.buffer_underruns_count = 1200;
306+ metrics2.buffer_underruns_count = 2400;
307+ metrics_sum.buffer_underruns_average = 80;
308+ metrics_sum.buffer_underruns_count = 1200;
309+ metrics1.Update(metrics2);
310+ COMPARE_A2DP_METRICS(metrics1, metrics_sum);
311+ EXPECT_TRUE(metrics1 == metrics_sum);
312+ EXPECT_EQ(metrics1, metrics_sum);
313+}
314+
315+class BluetoothMetricsLoggerTest : public Test {
316+ protected:
317+ // Use to hold test protos
318+ std::vector<PairEvent*> pair_events_;
319+ std::vector<WakeEvent*> wake_events_;
320+ std::vector<ScanEvent*> scan_events_;
321+ std::vector<BluetoothSession*> bt_sessions_;
322+ int64_t num_pair_event_ = 0;
323+ int64_t num_wake_event_ = 0;
324+ int64_t num_scan_event_ = 0;
325+ int64_t num_bt_session_ = 0;
326+ BluetoothLog* bt_log_;
327+ std::string bt_log_str_;
328+ std::string bt_log_ascii_str_;
329+
330+ void UpdateLog() {
331+ for (BluetoothSession* session : bt_sessions_) {
332+ bt_log_->mutable_session()->AddAllocated(session);
333+ }
334+ if (num_bt_session_ > 0) {
335+ bt_log_->set_num_bluetooth_session(num_bt_session_);
336+ } else if (bt_sessions_.size() > 0) {
337+ bt_log_->set_num_bluetooth_session(bt_sessions_.size());
338+ }
339+ bt_sessions_.clear();
340+ for (PairEvent* event : pair_events_) {
341+ bt_log_->mutable_pair_event()->AddAllocated(event);
342+ }
343+ if (num_pair_event_ > 0) {
344+ bt_log_->set_num_pair_event(num_pair_event_);
345+ } else if (pair_events_.size() > 0) {
346+ bt_log_->set_num_pair_event(pair_events_.size());
347+ }
348+ pair_events_.clear();
349+ for (WakeEvent* event : wake_events_) {
350+ bt_log_->mutable_wake_event()->AddAllocated(event);
351+ }
352+ if (num_wake_event_ > 0) {
353+ bt_log_->set_num_wake_event(num_wake_event_);
354+ } else if (wake_events_.size() > 0) {
355+ bt_log_->set_num_wake_event(wake_events_.size());
356+ }
357+ wake_events_.clear();
358+ for (ScanEvent* event : scan_events_) {
359+ bt_log_->mutable_scan_event()->AddAllocated(event);
360+ }
361+ if (num_scan_event_ > 0) {
362+ bt_log_->set_num_scan_event(num_scan_event_);
363+ } else if (scan_events_.size() > 0) {
364+ bt_log_->set_num_scan_event(scan_events_.size());
365+ }
366+ scan_events_.clear();
367+ bt_log_->SerializeToString(&bt_log_str_);
368+ }
369+
370+ void ClearLog() {
371+ for (BluetoothSession* session : bt_sessions_) {
372+ session->Clear();
373+ delete session;
374+ }
375+ bt_sessions_.clear();
376+ for (PairEvent* event : pair_events_) {
377+ event->Clear();
378+ delete event;
379+ }
380+ pair_events_.clear();
381+ for (WakeEvent* event : wake_events_) {
382+ event->Clear();
383+ delete event;
384+ }
385+ wake_events_.clear();
386+ for (ScanEvent* event : scan_events_) {
387+ event->Clear();
388+ delete event;
389+ }
390+ scan_events_.clear();
391+ bt_log_->Clear();
392+ }
393+
394+ void SetUp() {
395+ bt_log_ = new BluetoothLog();
396+ // Clear existing metrics entries, if any
397+ BluetoothMetricsLogger::GetInstance()->Reset();
398+ }
399+ void TearDown() {
400+ // Clear remaining metrics entries, if any
401+ BluetoothMetricsLogger::GetInstance()->Reset();
402+ ClearLog();
403+ delete bt_log_;
404+ }
405+
406+ public:
407+};
408+
409+TEST_F(BluetoothMetricsLoggerTest, PairEventTest) {
410+ pair_events_.push_back(MakePairEvent(
411+ 35, 12345,
412+ MakeDeviceInfo(
413+ 42, DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR)));
414+ UpdateLog();
415+ BluetoothMetricsLogger::GetInstance()->LogPairEvent(
416+ 35, 12345, 42, DEVICE_TYPE_BREDR);
417+ std::string msg_str;
418+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
419+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
420+}
421+
422+TEST_F(BluetoothMetricsLoggerTest, WakeEventTest) {
423+ wake_events_.push_back(
424+ MakeWakeEvent(WakeEvent_WakeEventType::WakeEvent_WakeEventType_ACQUIRED,
425+ "TEST_REQ", "TEST_NAME", 12345));
426+ UpdateLog();
427+ BluetoothMetricsLogger::GetInstance()->LogWakeEvent(
428+ WAKE_EVENT_ACQUIRED, "TEST_REQ", "TEST_NAME", 12345);
429+ std::string msg_str;
430+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
431+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
432+}
433+
434+TEST_F(BluetoothMetricsLoggerTest, WakeEventOverrunTest) {
435+ GenerateWakeEvents(kMaxEventGenerationLimit -
436+ BluetoothMetricsLogger::kMaxNumWakeEvent,
437+ kMaxEventGenerationLimit, &wake_events_);
438+ num_wake_event_ = kMaxEventGenerationLimit;
439+ UpdateLog();
440+ for (size_t i = 0; i < kMaxEventGenerationLimit; ++i) {
441+ BluetoothMetricsLogger::GetInstance()->LogWakeEvent(
442+ i % 2 == 0 ? WAKE_EVENT_ACQUIRED : WAKE_EVENT_RELEASED,
443+ "TEST_REQ", "TEST_NAME", i);
444+ }
445+ std::string msg_str;
446+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
447+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
448+}
449+
450+TEST_F(BluetoothMetricsLoggerTest, ScanEventTest) {
451+ scan_events_.push_back(MakeScanEvent(
452+ ScanEvent_ScanEventType::ScanEvent_ScanEventType_SCAN_EVENT_STOP,
453+ "TEST_INITIATOR", ScanEvent_ScanTechnologyType::
454+ ScanEvent_ScanTechnologyType_SCAN_TECH_TYPE_BREDR,
455+ 42, 123456));
456+ UpdateLog();
457+ BluetoothMetricsLogger::GetInstance()->LogScanEvent(
458+ false, "TEST_INITIATOR", SCAN_TECH_TYPE_BREDR, 42, 123456);
459+ std::string msg_str;
460+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
461+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
462+}
463+
464+TEST_F(BluetoothMetricsLoggerTest, BluetoothSessionTest) {
465+ bt_sessions_.push_back(MakeBluetoothSession(
466+ 10,
467+ BluetoothSession_ConnectionTechnologyType::
468+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_LE,
469+ BluetoothSession_DisconnectReasonType::
470+ BluetoothSession_DisconnectReasonType_UNKNOWN,
471+ nullptr, nullptr, nullptr));
472+ UpdateLog();
473+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
474+ CONNECTION_TECHNOLOGY_TYPE_LE, 123456);
475+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
476+ DISCONNECT_REASON_UNKNOWN, 133456);
477+ std::string msg_str;
478+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
479+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
480+}
481+
482+TEST_F(BluetoothMetricsLoggerTest, BluetoothSessionDumpBeforeEndTest) {
483+ bt_sessions_.push_back(MakeBluetoothSession(
484+ 1,
485+ BluetoothSession_ConnectionTechnologyType::
486+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_LE,
487+ BluetoothSession_DisconnectReasonType::
488+ BluetoothSession_DisconnectReasonType_METRICS_DUMP,
489+ nullptr, nullptr, nullptr));
490+ UpdateLog();
491+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
492+ CONNECTION_TECHNOLOGY_TYPE_LE, time_get_os_boottime_ms());
493+ sleep_ms(1000);
494+ std::string msg_str;
495+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
496+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
497+}
498+
499+TEST_F(BluetoothMetricsLoggerTest, BluetoothSessionStartBeforeEndTest) {
500+ bt_sessions_.push_back(MakeBluetoothSession(
501+ 1,
502+ BluetoothSession_ConnectionTechnologyType::
503+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_UNKNOWN,
504+ BluetoothSession_DisconnectReasonType::
505+ BluetoothSession_DisconnectReasonType_NEXT_START_WITHOUT_END_PREVIOUS,
506+ nullptr, nullptr, nullptr));
507+ bt_sessions_.push_back(MakeBluetoothSession(
508+ 2,
509+ BluetoothSession_ConnectionTechnologyType::
510+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_LE,
511+ BluetoothSession_DisconnectReasonType::
512+ BluetoothSession_DisconnectReasonType_METRICS_DUMP,
513+ nullptr, nullptr, nullptr));
514+ UpdateLog();
515+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
516+ CONNECTION_TECHNOLOGY_TYPE_UNKNOWN, 0);
517+ sleep_ms(1000);
518+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
519+ CONNECTION_TECHNOLOGY_TYPE_LE, 0);
520+ sleep_ms(2000);
521+ std::string msg_str;
522+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
523+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
524+}
525+
526+/*
527+ * Test Case: A2DPSessionTwoUpdatesTest
528+ *
529+ * 1. Create Instance
530+ * 2. LogBluetoothSessionStart
531+ * 3. LogBluetoothSessionDeviceInfo
532+ * 4. LogA2dpSession
533+ * 5. LogA2dpSession
534+ * 6. LogBluetoothSessionEnd
535+ * 7. WriteString
536+ *
537+ */
538+TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesTest) {
539+ /* Same metrics from BluetoothA2DPSessionMetricsTest.TestUpdateNormal */
540+ A2dpSessionMetrics metrics1;
541+ A2dpSessionMetrics metrics2;
542+ A2dpSessionMetrics metrics_sum;
543+ metrics1.audio_duration_ms = 10;
544+ metrics2.audio_duration_ms = 25;
545+ metrics_sum.audio_duration_ms = 35;
546+ metrics1.media_timer_min_ms = 10;
547+ metrics2.media_timer_min_ms = 25;
548+ metrics_sum.media_timer_min_ms = 10;
549+ metrics1.media_timer_max_ms = 100;
550+ metrics2.media_timer_max_ms = 200;
551+ metrics_sum.media_timer_max_ms = 200;
552+ metrics1.media_timer_avg_ms = 50;
553+ metrics1.total_scheduling_count = 50;
554+ metrics2.media_timer_avg_ms = 100;
555+ metrics2.total_scheduling_count = 50;
556+ metrics_sum.media_timer_avg_ms = 75;
557+ metrics_sum.total_scheduling_count = 100;
558+ metrics1.buffer_overruns_max_count = 70;
559+ metrics2.buffer_overruns_max_count = 80;
560+ metrics_sum.buffer_overruns_max_count = 80;
561+ metrics1.buffer_underruns_average = 80;
562+ metrics1.buffer_underruns_count = 1200;
563+ metrics2.buffer_underruns_average = 130;
564+ metrics2.buffer_underruns_count = 2400;
565+ metrics_sum.buffer_underruns_average = 113.33333333;
566+ metrics_sum.buffer_underruns_count = 3600;
567+ DeviceInfo* info = MakeDeviceInfo(
568+ BTM_COD_MAJOR_AUDIO_TEST,
569+ DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
570+ A2DPSession* session = MakeA2DPSession(metrics_sum);
571+ bt_sessions_.push_back(MakeBluetoothSession(
572+ 10,
573+ BluetoothSession_ConnectionTechnologyType::
574+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
575+ BluetoothSession_DisconnectReasonType::BluetoothSession_DisconnectReasonType_UNKNOWN,
576+ info, nullptr, session));
577+ UpdateLog();
578+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
579+ CONNECTION_TECHNOLOGY_TYPE_BREDR, 123456);
580+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionDeviceInfo(
581+ BTM_COD_MAJOR_AUDIO_TEST, DEVICE_TYPE_BREDR);
582+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics1);
583+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics2);
584+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
585+ DISCONNECT_REASON_UNKNOWN, 133456);
586+ std::string msg_str;
587+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
588+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
589+}
590+
591+/*
592+ * Test Case: A2DPSessionTwoUpdatesSeparatedbyDumpTest
593+ *
594+ * 1. Create Instance
595+ * 2. LogBluetoothSessionStart
596+ * 3. LogBluetoothSessionDeviceInfo
597+ * 4. LogA2dpSession
598+ * 5. WriteString
599+ * 6. LogA2dpSession
600+ * 7. LogBluetoothSessionEnd
601+ * 8. WriteString
602+ *
603+ */
604+TEST_F(BluetoothMetricsLoggerTest, A2DPSessionTwoUpdatesSeparatedbyDumpTest) {
605+ /* Same metrics from BluetoothA2DPSessionMetricsTest.TestUpdateNormal */
606+ A2dpSessionMetrics metrics1;
607+ A2dpSessionMetrics metrics2;
608+ metrics1.audio_duration_ms = 10;
609+ metrics2.audio_duration_ms = 25;
610+ metrics1.media_timer_min_ms = 10;
611+ metrics2.media_timer_min_ms = 25;
612+ metrics1.media_timer_max_ms = 100;
613+ metrics2.media_timer_max_ms = 200;
614+ metrics1.media_timer_avg_ms = 50;
615+ metrics1.total_scheduling_count = 50;
616+ metrics2.media_timer_avg_ms = 100;
617+ metrics2.total_scheduling_count = 50;
618+ metrics1.buffer_overruns_max_count = 70;
619+ metrics2.buffer_overruns_max_count = 80;
620+ metrics1.buffer_underruns_average = 80;
621+ metrics1.buffer_underruns_count = 1200;
622+ metrics2.buffer_underruns_average = 130;
623+ metrics2.buffer_underruns_count = 2400;
624+ DeviceInfo* info = MakeDeviceInfo(
625+ BTM_COD_MAJOR_AUDIO_TEST,
626+ DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
627+ A2DPSession* session = MakeA2DPSession(metrics1);
628+ bt_sessions_.push_back(MakeBluetoothSession(
629+ 1,
630+ BluetoothSession_ConnectionTechnologyType::
631+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
632+ BluetoothSession_DisconnectReasonType::
633+ BluetoothSession_DisconnectReasonType_METRICS_DUMP,
634+ info, nullptr, session));
635+ UpdateLog();
636+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
637+ CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
638+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionDeviceInfo(
639+ BTM_COD_MAJOR_AUDIO_TEST, DEVICE_TYPE_BREDR);
640+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics1);
641+ sleep_ms(1000);
642+ std::string msg_str;
643+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
644+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
645+ ClearLog();
646+ info = MakeDeviceInfo(
647+ BTM_COD_MAJOR_AUDIO_TEST,
648+ DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
649+ session = MakeA2DPSession(metrics2);
650+ bt_sessions_.push_back(MakeBluetoothSession(
651+ 1,
652+ BluetoothSession_ConnectionTechnologyType::
653+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
654+ BluetoothSession_DisconnectReasonType::BluetoothSession_DisconnectReasonType_UNKNOWN,
655+ info, nullptr, session));
656+ UpdateLog();
657+ sleep_ms(1000);
658+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics2);
659+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
660+ DISCONNECT_REASON_UNKNOWN, 0);
661+ msg_str.clear();
662+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
663+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
664+}
665+
666+/*
667+ * Test Case 1: A2DPSessionOnlyTest
668+ *
669+ * 1. Create Instance
670+ * 4. LogA2dpSession
671+ * 5. WriteString
672+ * 6. LogA2dpSession
673+ * 8. WriteString
674+ *
675+ */
676+TEST_F(BluetoothMetricsLoggerTest, A2DPSessionOnlyTest) {
677+ /* Same metrics from BluetoothA2DPSessionMetricsTest.TestUpdateNormal */
678+ A2dpSessionMetrics metrics1;
679+ A2dpSessionMetrics metrics2;
680+ A2dpSessionMetrics metrics_sum;
681+ metrics1.audio_duration_ms = 10;
682+ metrics2.audio_duration_ms = 25;
683+ metrics_sum.audio_duration_ms = 35;
684+ metrics1.media_timer_min_ms = 10;
685+ metrics2.media_timer_min_ms = 25;
686+ metrics_sum.media_timer_min_ms = 10;
687+ metrics1.media_timer_max_ms = 100;
688+ metrics2.media_timer_max_ms = 200;
689+ metrics_sum.media_timer_max_ms = 200;
690+ metrics1.media_timer_avg_ms = 50;
691+ metrics1.total_scheduling_count = 50;
692+ metrics2.media_timer_avg_ms = 100;
693+ metrics2.total_scheduling_count = 50;
694+ metrics_sum.media_timer_avg_ms = 75;
695+ metrics_sum.total_scheduling_count = 100;
696+ metrics1.buffer_overruns_max_count = 70;
697+ metrics2.buffer_overruns_max_count = 80;
698+ metrics_sum.buffer_overruns_max_count = 80;
699+ metrics1.buffer_underruns_average = 80;
700+ metrics1.buffer_underruns_count = 1200;
701+ metrics2.buffer_underruns_average = 130;
702+ metrics2.buffer_underruns_count = 2400;
703+ metrics_sum.buffer_underruns_average = 113.33333333;
704+ metrics_sum.buffer_underruns_count = 3600;
705+ DeviceInfo* info = MakeDeviceInfo(
706+ BTM_COD_MAJOR_AUDIO_TEST,
707+ DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
708+ A2DPSession* session = MakeA2DPSession(metrics_sum);
709+ bt_sessions_.push_back(MakeBluetoothSession(
710+ 1,
711+ BluetoothSession_ConnectionTechnologyType::
712+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
713+ BluetoothSession_DisconnectReasonType::BluetoothSession_DisconnectReasonType_METRICS_DUMP,
714+ info, nullptr, session));
715+ UpdateLog();
716+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics1);
717+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics2);
718+ sleep_ms(1000);
719+ std::string msg_str;
720+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
721+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
722+}
723+
724+/*
725+ * Test Case: A2DPSessionDumpBeforeTwoUpdatesTest
726+ *
727+ * 1. Create Instance
728+ * 2. LogBluetoothSessionStart
729+ * 3. LogBluetoothSessionDeviceInfo
730+ * 5. WriteString
731+ * 6. LogA2dpSession
732+ * 7. LogA2dpSession
733+ * 8. LogBluetoothSessionEnd
734+ * 9. WriteString
735+ *
736+ */
737+TEST_F(BluetoothMetricsLoggerTest, A2DPSessionDumpBeforeTwoUpdatesTest) {
738+ /* Same metrics from BluetoothA2DPSessionMetricsTest.TestUpdateNormal */
739+ A2dpSessionMetrics metrics1;
740+ A2dpSessionMetrics metrics2;
741+ A2dpSessionMetrics metrics_sum;
742+ metrics1.audio_duration_ms = 10;
743+ metrics2.audio_duration_ms = 25;
744+ metrics_sum.audio_duration_ms = 35;
745+ metrics1.media_timer_min_ms = 10;
746+ metrics2.media_timer_min_ms = 25;
747+ metrics_sum.media_timer_min_ms = 10;
748+ metrics1.media_timer_max_ms = 100;
749+ metrics2.media_timer_max_ms = 200;
750+ metrics_sum.media_timer_max_ms = 200;
751+ metrics1.media_timer_avg_ms = 50;
752+ metrics1.total_scheduling_count = 50;
753+ metrics2.media_timer_avg_ms = 100;
754+ metrics2.total_scheduling_count = 50;
755+ metrics_sum.media_timer_avg_ms = 75;
756+ metrics_sum.total_scheduling_count = 100;
757+ metrics1.buffer_overruns_max_count = 70;
758+ metrics2.buffer_overruns_max_count = 80;
759+ metrics_sum.buffer_overruns_max_count = 80;
760+ metrics1.buffer_underruns_average = 80;
761+ metrics1.buffer_underruns_count = 1200;
762+ metrics2.buffer_underruns_average = 130;
763+ metrics2.buffer_underruns_count = 2400;
764+ metrics_sum.buffer_underruns_average = 113.33333333;
765+ metrics_sum.buffer_underruns_count = 3600;
766+ DeviceInfo* info = MakeDeviceInfo(
767+ BTM_COD_MAJOR_AUDIO_TEST,
768+ DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
769+ bt_sessions_.push_back(MakeBluetoothSession(
770+ 1,
771+ BluetoothSession_ConnectionTechnologyType::
772+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
773+ BluetoothSession_DisconnectReasonType::BluetoothSession_DisconnectReasonType_METRICS_DUMP,
774+ info, nullptr, nullptr));
775+ UpdateLog();
776+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
777+ CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
778+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionDeviceInfo(
779+ BTM_COD_MAJOR_AUDIO_TEST, DEVICE_TYPE_BREDR);
780+ sleep_ms(1000);
781+ std::string msg_str;
782+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
783+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
784+ ClearLog();
785+ info = MakeDeviceInfo(
786+ BTM_COD_MAJOR_AUDIO_TEST,
787+ DeviceInfo_DeviceType::DeviceInfo_DeviceType_DEVICE_TYPE_BREDR);
788+ A2DPSession* session = MakeA2DPSession(metrics_sum);
789+ bt_sessions_.push_back(MakeBluetoothSession(
790+ 1,
791+ BluetoothSession_ConnectionTechnologyType::
792+ BluetoothSession_ConnectionTechnologyType_CONNECTION_TECHNOLOGY_TYPE_BREDR,
793+ BluetoothSession_DisconnectReasonType::BluetoothSession_DisconnectReasonType_UNKNOWN,
794+ info, nullptr, session));
795+ UpdateLog();
796+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics1);
797+ BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics2);
798+ sleep_ms(1000);
799+ BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionEnd(
800+ DISCONNECT_REASON_UNKNOWN, 0);
801+ msg_str.clear();
802+ BluetoothMetricsLogger::GetInstance()->WriteString(&msg_str, true);
803+ EXPECT_THAT(msg_str, StrEq(bt_log_str_));
804+}
805+}
--- a/stack/btm/btm_acl.c
+++ b/stack/btm/btm_acl.c
@@ -164,7 +164,7 @@ void btm_acl_init (void)
164164 ** NULL if not found.
165165 **
166166 *******************************************************************************/
167-tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport)
167+tACL_CONN *btm_bda_to_acl (const BD_ADDR bda, tBT_TRANSPORT transport)
168168 {
169169 tACL_CONN *p = &btm_cb.acl_db[0];
170170 UINT16 xx;
@@ -1002,6 +1002,43 @@ void BTM_SetDefaultLinkPolicy (UINT16 settings)
10021002 btsnd_hcic_write_def_policy_set(settings);
10031003 }
10041004
1005+
1006+void btm_use_preferred_conn_params(BD_ADDR bda) {
1007+ tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
1008+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
1009+
1010+ /* If there are any preferred connection parameters, set them now */
1011+ if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
1012+ (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
1013+ (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
1014+ (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
1015+ (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) &&
1016+ (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
1017+ (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
1018+ ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int &&
1019+ p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
1020+ (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) ||
1021+ (p_lcb->latency > p_dev_rec->conn_params.slave_latency) ||
1022+ (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout)))
1023+ {
1024+ BTM_TRACE_DEBUG ("%s: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d", __func__,
1025+ p_lcb->handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
1026+ p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
1027+
1028+ p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int;
1029+ p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int;
1030+ p_lcb->timeout = p_dev_rec->conn_params.supervision_tout;
1031+ p_lcb->latency = p_dev_rec->conn_params.slave_latency;
1032+
1033+ btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
1034+ p_dev_rec->conn_params.min_conn_int,
1035+ p_dev_rec->conn_params.max_conn_int,
1036+ p_dev_rec->conn_params.slave_latency,
1037+ p_dev_rec->conn_params.supervision_tout,
1038+ 0, 0);
1039+ }
1040+}
1041+
10051042 /*******************************************************************************
10061043 **
10071044 ** Function btm_read_remote_version_complete
@@ -1041,8 +1078,9 @@ void btm_read_remote_version_complete (UINT8 *p)
10411078 }
10421079
10431080 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
1044- if (p_acl_cb->transport == BT_TRANSPORT_LE){
1081+ if (p_acl_cb->transport == BT_TRANSPORT_LE) {
10451082 l2cble_notify_le_connection (p_acl_cb->remote_addr);
1083+ btm_use_preferred_conn_params(p_acl_cb->remote_addr);
10461084 }
10471085 #endif // (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
10481086 BTM_TRACE_WARNING ("btm_read_remote_version_complete: BDA: %02x-%02x-%02x-%02x-%02x-%02x",
@@ -1527,7 +1565,7 @@ UINT16 btm_get_acl_disc_reason_code (void)
15271565 ** Returns the handle of the connection, or 0xFFFF if none.
15281566 **
15291567 *******************************************************************************/
1530-UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport)
1568+UINT16 BTM_GetHCIConnHandle (const BD_ADDR remote_bda, tBT_TRANSPORT transport)
15311569 {
15321570 tACL_CONN *p;
15331571 BTM_TRACE_DEBUG ("BTM_GetHCIConnHandle");
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -71,7 +71,7 @@ extern void gatt_notify_enc_cmpl(BD_ADDR bd_addr);
7171 ** Returns TRUE if added OK, else FALSE
7272 **
7373 *******************************************************************************/
74-BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE dev_type,
74+BOOLEAN BTM_SecAddBleDevice (const BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE dev_type,
7575 tBLE_ADDR_TYPE addr_type)
7676 {
7777 BTM_TRACE_DEBUG ("%s: dev_type=0x%x", __func__, dev_type);
@@ -485,11 +485,10 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data)
485485 tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_OOB_FAIL;
486486 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
487487
488- BTM_TRACE_DEBUG ("BTM_BleOobDataReply");
488+ BTM_TRACE_DEBUG ("%s:", __func__);
489489
490- if (p_dev_rec == NULL)
491- {
492- BTM_TRACE_ERROR("BTM_BleOobDataReply() to Unknown device");
490+ if (p_dev_rec == NULL) {
491+ BTM_TRACE_ERROR("%s: Unknown device", __func__);
493492 return;
494493 }
495494
@@ -498,6 +497,47 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data)
498497 #endif
499498 }
500499
500+/*******************************************************************************
501+**
502+** Function BTM_BleSecureConnectionOobDataReply
503+**
504+** Description This function is called to provide the OOB data for
505+** SMP in response to BTM_LE_OOB_REQ_EVT when secure connection
506+** data is available
507+**
508+** Parameters: bd_addr - Address of the peer device
509+** p_c - pointer to Confirmation.
510+** p_r - pointer to Randomizer
511+**
512+*******************************************************************************/
513+void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr,
514+ uint8_t *p_c, uint8_t *p_r)
515+{
516+#if SMP_INCLUDED == TRUE
517+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
518+
519+ BTM_TRACE_DEBUG ("%s:", __func__);
520+
521+ if (p_dev_rec == NULL) {
522+ BTM_TRACE_ERROR("%s: Unknown device", __func__);
523+ return;
524+ }
525+
526+ p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
527+
528+ tSMP_SC_OOB_DATA oob;
529+ memset(&oob, 0, sizeof(tSMP_SC_OOB_DATA));
530+
531+ oob.peer_oob_data.present = true;
532+ memcpy(&oob.peer_oob_data.randomizer, p_r, BT_OCTET16_LEN);
533+ memcpy(&oob.peer_oob_data.commitment, p_c, BT_OCTET16_LEN);
534+ oob.peer_oob_data.addr_rcvd_from.type = p_dev_rec->ble.ble_addr_type;
535+ memcpy(&oob.peer_oob_data.addr_rcvd_from.bda, bd_addr, sizeof(BD_ADDR));
536+
537+ SMP_SecureConnectionOobDataReply((uint8_t*)&oob);
538+#endif
539+}
540+
501541 /******************************************************************************
502542 **
503543 ** Function BTM_BleSetConnScanParams
--- a/stack/btm/btm_dev.c
+++ b/stack/btm/btm_dev.c
@@ -422,12 +422,12 @@ bool is_address_equal(void *data, void *context)
422422 ** Returns Pointer to the record or NULL
423423 **
424424 *******************************************************************************/
425-tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
425+tBTM_SEC_DEV_REC *btm_find_dev(const BD_ADDR bd_addr)
426426 {
427427 if (!bd_addr)
428428 return NULL;
429429
430- list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_address_equal, bd_addr);
430+ list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_address_equal, (void*)bd_addr);
431431 if (n)
432432 return list_node(n);
433433
--- a/stack/btm/btm_inq.c
+++ b/stack/btm/btm_inq.c
@@ -1131,7 +1131,7 @@ tBTM_STATUS BTM_CancelRemoteDeviceName (void)
11311131 ** Returns pointer to entry, or NULL if not found
11321132 **
11331133 *******************************************************************************/
1134-tBTM_INQ_INFO *BTM_InqDbRead (BD_ADDR p_bda)
1134+tBTM_INQ_INFO *BTM_InqDbRead (const BD_ADDR p_bda)
11351135 {
11361136 BTM_TRACE_API ("BTM_InqDbRead: bd addr [%02x%02x%02x%02x%02x%02x]",
11371137 p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
@@ -1538,7 +1538,7 @@ BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda)
15381538 ** Returns pointer to entry, or NULL if not found
15391539 **
15401540 *******************************************************************************/
1541-tINQ_DB_ENT *btm_inq_db_find (BD_ADDR p_bda)
1541+tINQ_DB_ENT *btm_inq_db_find (const BD_ADDR p_bda)
15421542 {
15431543 UINT16 xx;
15441544 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -952,7 +952,7 @@ extern void btm_process_cancel_complete(UINT8 status, UINT8 mode);
952952 extern void btm_event_filter_complete (UINT8 *p);
953953 extern void btm_inq_stop_on_ssp(void);
954954 extern void btm_inq_clear_ssp(void);
955-extern tINQ_DB_ENT *btm_inq_db_find (BD_ADDR p_bda);
955+extern tINQ_DB_ENT *btm_inq_db_find (const BD_ADDR p_bda);
956956 extern BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda);
957957
958958 extern BOOLEAN btm_lookup_eir(BD_ADDR_PTR p_rem_addr);
@@ -999,7 +999,7 @@ extern void btm_establish_continue (tACL_CONN *p_acl_cb);
999999 extern void btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_pkt_type);
10001000 /* Read maximum data packet that can be sent over current connection */
10011001 extern UINT16 btm_get_max_packet_size (BD_ADDR addr);
1002-extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport);
1002+extern tACL_CONN *btm_bda_to_acl (const BD_ADDR bda, tBT_TRANSPORT transport);
10031003 extern BOOLEAN btm_acl_notif_conn_collision (BD_ADDR bda);
10041004
10051005 extern void btm_pm_reset(void);
@@ -1080,7 +1080,7 @@ extern BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr);
10801080 extern tBTM_SEC_DEV_REC *btm_sec_allocate_dev_rec(void);
10811081 extern tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr);
10821082 extern void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec);
1083-extern tBTM_SEC_DEV_REC *btm_find_dev (BD_ADDR bd_addr);
1083+extern tBTM_SEC_DEV_REC *btm_find_dev (const BD_ADDR bd_addr);
10841084 extern tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr);
10851085 extern tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle);
10861086 extern tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr);
--- a/stack/include/btm_api.h
+++ b/stack/include/btm_api.h
@@ -2555,7 +2555,7 @@ extern UINT8 *BTM_ReadAllRemoteFeatures (BD_ADDR addr);
25552555 ** Returns pointer to entry, or NULL if not found
25562556 **
25572557 *******************************************************************************/
2558-extern tBTM_INQ_INFO *BTM_InqDbRead (BD_ADDR p_bda);
2558+extern tBTM_INQ_INFO *BTM_InqDbRead (const BD_ADDR p_bda);
25592559
25602560
25612561 /*******************************************************************************
@@ -3761,7 +3761,7 @@ extern tBTM_STATUS BTM_SetSsrParams (BD_ADDR remote_bda, UINT16 max_lat,
37613761 ** Returns the handle of the connection, or 0xFFFF if none.
37623762 **
37633763 *******************************************************************************/
3764-extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport);
3764+extern UINT16 BTM_GetHCIConnHandle (const BD_ADDR remote_bda, tBT_TRANSPORT transport);
37653765
37663766 /*******************************************************************************
37673767 **
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -917,7 +917,7 @@ extern "C" {
917917 ** Returns TRUE if added OK, else FALSE
918918 **
919919 *******************************************************************************/
920-extern BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name,
920+extern BOOLEAN BTM_SecAddBleDevice (const BD_ADDR bd_addr, BD_NAME bd_name,
921921 tBT_DEVICE_TYPE dev_type, tBLE_ADDR_TYPE addr_type);
922922
923923 /*******************************************************************************
@@ -1241,6 +1241,22 @@ extern void BTM_BleConfirmReply (BD_ADDR bd_addr, UINT8 res);
12411241 *******************************************************************************/
12421242 extern void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data);
12431243
1244+/*******************************************************************************
1245+**
1246+** Function BTM_BleSecureConnectionOobDataReply
1247+**
1248+** Description This function is called to provide the OOB data for
1249+** SMP in response to BTM_LE_OOB_REQ_EVT when secure connection
1250+** data is available
1251+**
1252+** Parameters: bd_addr - Address of the peer device
1253+** p_c - pointer to Confirmation
1254+** p_r - pointer to Randomizer.
1255+**
1256+*******************************************************************************/
1257+extern void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr,
1258+ uint8_t *p_c, uint8_t *p_r);
1259+
12441260
12451261 /*******************************************************************************
12461262 **
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -33,6 +33,7 @@
3333 #include "device/include/controller.h"
3434 #include "device/include/interop.h"
3535 #include "stack_config.h"
36+#include "btif_debug_l2c.h"
3637
3738 #if (BLE_INCLUDED == TRUE)
3839
@@ -234,42 +235,6 @@ UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
234235 return reason;
235236 }
236237
237-void l2cble_use_preferred_conn_params(BD_ADDR bda) {
238- tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
239- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
240-
241- /* If there are any preferred connection parameters, set them now */
242- if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
243- (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
244- (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
245- (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
246- (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) &&
247- (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
248- (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
249- ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int &&
250- p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
251- (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) ||
252- (p_lcb->latency > p_dev_rec->conn_params.slave_latency) ||
253- (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout)))
254- {
255- L2CAP_TRACE_DEBUG ("%s: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d", __func__,
256- p_lcb->handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
257- p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
258-
259- p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int;
260- p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int;
261- p_lcb->timeout = p_dev_rec->conn_params.supervision_tout;
262- p_lcb->latency = p_dev_rec->conn_params.slave_latency;
263-
264- btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
265- p_dev_rec->conn_params.min_conn_int,
266- p_dev_rec->conn_params.max_conn_int,
267- p_dev_rec->conn_params.slave_latency,
268- p_dev_rec->conn_params.supervision_tout,
269- 0, 0);
270- }
271-}
272-
273238 /*******************************************************************************
274239 **
275240 ** Function l2cble_notify_le_connection
@@ -308,7 +273,7 @@ void l2cble_notify_le_connection (BD_ADDR bda)
308273 if (!BTM_GetRemoteDeviceName(bda, bdname) || !*bdname ||
309274 (!interop_match_name(INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS, (const char*) bdname)))
310275 {
311- l2cble_use_preferred_conn_params(bda);
276+ //l2cble_use_preferred_conn_params(bda);
312277 }
313278 }
314279
@@ -578,6 +543,14 @@ static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
578543 p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
579544 }
580545 }
546+
547+ /* Record the BLE connection update request. */
548+ if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) {
549+ bt_bdaddr_t bd_addr;
550+ bdcpy(bd_addr.address, p_lcb->remote_bd_addr);
551+ btif_debug_ble_connection_update_request(bd_addr, min_conn_int, max_conn_int, slave_latency,
552+ supervision_tout);
553+ }
581554 }
582555
583556 /*******************************************************************************
@@ -612,6 +585,12 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status,
612585
613586 l2cble_start_conn_update(p_lcb);
614587
588+ /* Record the BLE connection update response. */
589+ bt_bdaddr_t bd_addr;
590+ bdcpy(bd_addr.address, p_lcb->remote_bd_addr);
591+ btif_debug_ble_connection_update_response(bd_addr, status, interval,
592+ latency, timeout);
593+
615594 L2CAP_TRACE_DEBUG("%s: conn_update_mask=%d", __func__, p_lcb->conn_update_mask);
616595 }
617596
--- a/stack/sdp/sdp_discovery.c
+++ b/stack/sdp/sdp_discovery.c
@@ -384,10 +384,11 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
384384 SDP_TRACE_WARNING("rem_len :%d less than cpy_len:%d", rem_len, cpy_len);
385385 cpy_len = rem_len;
386386 }
387-#if (SDP_DEBUG_RAW == TRUE)
388- SDP_TRACE_WARNING("list_len :%d cpy_len:%d raw_size:%d raw_used:%d",
389- list_len, cpy_len, p_ccb->p_db->raw_size, p_ccb->p_db->raw_used);
390-#endif
387+ SDP_TRACE_WARNING(
388+ "%s: list_len:%d cpy_len:%d p:%p p_ccb:%p p_db:%p raw_size:%d "
389+ "raw_used:%d raw_data:%p",
390+ __func__, list_len, cpy_len, p, p_ccb, p_ccb->p_db,
391+ p_ccb->p_db->raw_size, p_ccb->p_db->raw_used, p_ccb->p_db->raw_data);
391392 memcpy (&p_ccb->p_db->raw_data[p_ccb->p_db->raw_used], p, cpy_len);
392393 p_ccb->p_db->raw_used += cpy_len;
393394 }