blob: 9d33e1b81fbaa944d2dbecab1ac584427af3b2c8 [file] [log] [blame]
Marie Janssena84a4ee2016-01-15 16:14:14 -08001/******************************************************************************
2 *
Jakub Pawlowski3b10fdd2017-09-18 09:00:20 -07003 * Copyright 2016 Google, Inc.
Marie Janssena84a4ee2016-01-15 16:14:14 -08004 *
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
Jack He7ebb85a2018-04-02 13:04:58 -070021#include <bta/include/bta_api.h>
Jeffrey Huangbb0a3542020-11-20 12:01:19 -080022#include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
23#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
Marie Janssena84a4ee2016-01-15 16:14:14 -080024#include <stdint.h>
Chris Manton2a9d9f22021-09-10 23:05:47 -070025
Jack He777228a2016-12-08 19:29:00 -080026#include <memory>
27#include <string>
Josh Wuc033a162022-05-05 01:29:04 -070028#include <vector>
Jack He777228a2016-12-08 19:29:00 -080029
Chris Manton2a9d9f22021-09-10 23:05:47 -070030#include "types/raw_address.h"
31
Jack He42823982018-08-15 12:38:37 -070032namespace bluetooth {
33
34namespace common {
Jack He777228a2016-12-08 19:29:00 -080035
36// Typedefs to hide protobuf definition to the rest of stack
Marie Janssena84a4ee2016-01-15 16:14:14 -080037
38typedef enum {
39 DEVICE_TYPE_UNKNOWN,
40 DEVICE_TYPE_BREDR,
41 DEVICE_TYPE_LE,
42 DEVICE_TYPE_DUMO,
43} device_type_t;
44
Marie Janssena84a4ee2016-01-15 16:14:14 -080045typedef enum {
46 WAKE_EVENT_UNKNOWN,
47 WAKE_EVENT_ACQUIRED,
48 WAKE_EVENT_RELEASED,
49} wake_event_type_t;
50
Marie Janssena84a4ee2016-01-15 16:14:14 -080051typedef enum {
52 SCAN_TYPE_UNKNOWN,
53 SCAN_TECH_TYPE_LE,
54 SCAN_TECH_TYPE_BREDR,
55 SCAN_TECH_TYPE_BOTH,
56} scan_tech_t;
57
Jack He777228a2016-12-08 19:29:00 -080058typedef enum {
59 CONNECTION_TECHNOLOGY_TYPE_UNKNOWN,
60 CONNECTION_TECHNOLOGY_TYPE_LE,
61 CONNECTION_TECHNOLOGY_TYPE_BREDR,
62} connection_tech_t;
Marie Janssena84a4ee2016-01-15 16:14:14 -080063
Jack He9bebcc02017-01-17 15:41:30 -080064typedef enum {
65 DISCONNECT_REASON_UNKNOWN,
66 DISCONNECT_REASON_METRICS_DUMP,
67 DISCONNECT_REASON_NEXT_START_WITHOUT_END_PREVIOUS,
68} disconnect_reason_t;
69
Jack He777228a2016-12-08 19:29:00 -080070/* Values of A2DP metrics that we care about
71 *
72 * audio_duration_ms : sum of audio duration (in milliseconds).
73 * device_class: device class of the paired device.
74 * media_timer_min_ms : minimum scheduled time (in milliseconds)
75 * of the media timer.
76 * media_timer_max_ms: maximum scheduled time (in milliseconds)
77 * of the media timer.
78 * media_timer_avg_ms: average scheduled time (in milliseconds)
79 * of the media timer.
80 * buffer_overruns_max_count: TODO - not clear what this is.
81 * buffer_overruns_total : number of times the media buffer with
82 * audio data has overrun
83 * buffer_underruns_average: TODO - not clear what this is.
84 * buffer_underruns_count: number of times there was no enough
85 * audio data to add to the media buffer.
86 * NOTE: Negative values are invalid
Jack He42823982018-08-15 12:38:37 -070087 */
Jack He777228a2016-12-08 19:29:00 -080088class A2dpSessionMetrics {
89 public:
90 A2dpSessionMetrics() {}
Pavlin Radoslavov9aa6f122016-02-17 15:42:38 -080091
Jack He777228a2016-12-08 19:29:00 -080092 /*
93 * Update the metrics value in the current metrics object using the metrics
94 * objects supplied
95 */
96 void Update(const A2dpSessionMetrics& metrics);
97
98 /*
99 * Compare whether two metrics objects are equal
100 */
101 bool operator==(const A2dpSessionMetrics& rhs) const;
102
103 /*
104 * Initialize all values to -1 which is invalid in order to make a distinction
105 * between 0 and invalid values
106 */
107 int64_t audio_duration_ms = -1;
108 int32_t media_timer_min_ms = -1;
109 int32_t media_timer_max_ms = -1;
110 int32_t media_timer_avg_ms = -1;
111 int64_t total_scheduling_count = -1;
112 int32_t buffer_overruns_max_count = -1;
113 int32_t buffer_overruns_total = -1;
114 float buffer_underruns_average = -1;
115 int32_t buffer_underruns_count = -1;
Jack Heeeb9f352018-06-08 20:13:23 -0700116 int64_t codec_index = -1;
117 bool is_a2dp_offload = false;
Jack He777228a2016-12-08 19:29:00 -0800118};
119
120class BluetoothMetricsLogger {
121 public:
122 static BluetoothMetricsLogger* GetInstance() {
123 static BluetoothMetricsLogger* instance = new BluetoothMetricsLogger();
124 return instance;
125 }
126
127 /*
128 * Record a pairing event
129 *
130 * Parameters:
131 * timestamp_ms: Unix epoch time in milliseconds
132 * device_class: class of remote device
133 * device_type: type of remote device
134 * disconnect_reason: HCI reason for pairing disconnection.
135 * See: stack/include/hcidefs.h
136 */
137 void LogPairEvent(uint32_t disconnect_reason, uint64_t timestamp_ms,
138 uint32_t device_class, device_type_t device_type);
139
140 /*
141 * Record a wake event
142 *
143 * Parameters:
144 * timestamp_ms: Unix epoch time in milliseconds
145 * type: whether it was acquired or released
146 * requestor: if provided is the service requesting the wake lock
147 * name: the name of the wake lock held
148 */
149 void LogWakeEvent(wake_event_type_t type, const std::string& requestor,
150 const std::string& name, uint64_t timestamp_ms);
151
152 /*
153 * Record a scan event
154 *
155 * Parameters
156 * timestamp_ms : Unix epoch time in milliseconds
157 * start : true if this is the beginning of the scan
158 * initiator: a unique ID identifying the app starting the scan
159 * type: whether the scan reports BR/EDR, LE, or both.
160 * results: number of results to be reported.
161 */
162 void LogScanEvent(bool start, const std::string& initator, scan_tech_t type,
163 uint32_t results, uint64_t timestamp_ms);
164
165 /*
166 * Start logging a Bluetooth session
167 *
168 * A Bluetooth session is defined a a connection between this device and
169 * another remote device which may include multiple profiles and protocols
170 *
171 * Only one Bluetooth session can exist at one time. Calling this method twice
172 * without LogBluetoothSessionEnd will result in logging a premature end of
173 * current Bluetooth session
174 *
175 * Parameters:
176 * connection_tech_type : type of connection technology
177 * timestamp_ms : the timestamp for session start, 0 means now
178 *
179 */
180 void LogBluetoothSessionStart(connection_tech_t connection_tech_type,
181 uint64_t timestamp_ms);
182
183 /*
184 * Stop logging a Bluetooth session and pushes it to the log queue
185 *
186 * If no Bluetooth session exist, this method exits immediately
187 *
188 * Parameters:
189 * disconnect_reason : A string representation of disconnect reason
190 * timestamp_ms : the timestamp of session end, 0 means now
191 *
192 */
Jack He9bebcc02017-01-17 15:41:30 -0800193 void LogBluetoothSessionEnd(disconnect_reason_t disconnect_reason,
Jack He777228a2016-12-08 19:29:00 -0800194 uint64_t timestamp_ms);
195
196 /*
197 * Log information about remote device in a current Bluetooth session
198 *
199 * If a Bluetooth session does not exist, create one with default parameter
200 * and timestamp now
201 *
202 * Parameters:
203 * device_class : device_class defined in btm_api_types.h
204 * device_type : type of remote device
205 */
206 void LogBluetoothSessionDeviceInfo(uint32_t device_class,
207 device_type_t device_type);
208
209 /*
210 * Log A2DP Audio Session Information
211 *
212 * - Repeated calls to this method will override previous metrics if in the
213 * same Bluetooth connection
214 * - If a Bluetooth session does not exist, create one with default parameter
215 * and timestamp now
216 *
217 * Parameters:
218 * a2dp_session_metrics - pointer to struct holding a2dp stats
219 *
220 */
221 void LogA2dpSession(const A2dpSessionMetrics& a2dp_session_metrics);
222
Jack He7ebb85a2018-04-02 13:04:58 -0700223 /**
224 * Log Headset profile RFCOMM connection event
225 *
226 * @param service_id the BTA service ID for this headset connection
Jack He777228a2016-12-08 19:29:00 -0800227 */
Jack He7ebb85a2018-04-02 13:04:58 -0700228 void LogHeadsetProfileRfcConnection(tBTA_SERVICE_ID service_id);
229
230 /*
231 * Writes the metrics, in base64 protobuf format, into the descriptor FD,
232 * metrics events are always cleared after dump
233 */
234 void WriteBase64(int fd);
235 void WriteBase64String(std::string* serialized);
236 void WriteString(std::string* serialized);
Jack He777228a2016-12-08 19:29:00 -0800237
238 /*
239 * Reset the metrics logger by cleaning up its staging queues and existing
240 * protobuf objects.
241 */
242 void Reset();
243
Jack He9bebcc02017-01-17 15:41:30 -0800244 /*
245 * Maximum number of log entries for each session or event
246 */
247 static const size_t kMaxNumBluetoothSession = 50;
248 static const size_t kMaxNumPairEvent = 50;
249 static const size_t kMaxNumWakeEvent = 1000;
250 static const size_t kMaxNumScanEvent = 50;
251
Jack He777228a2016-12-08 19:29:00 -0800252 private:
253 BluetoothMetricsLogger();
254
255 /*
256 * When a Bluetooth session is on and the user initiates a metrics dump, we
257 * need to be able to upload whatever we have first. This method breaks the
258 * ongoing Bluetooth session into two sessions with the previous one labeled
259 * as "METRICS_DUMP" for the disconnect reason.
260 */
261 void CutoffSession();
262
263 /*
264 * Build the internal metrics object using information gathered
265 */
266 void Build();
267
268 /*
269 * Reset objects related to current Bluetooth session
270 */
271 void ResetSession();
272
273 /*
274 * Reset the underlining BluetoothLog object
275 */
276 void ResetLog();
277
278 /*
279 * PIMPL style implementation to hide internal dependencies
280 */
281 struct impl;
282 std::unique_ptr<impl> const pimpl_;
283};
Jack He42823982018-08-15 12:38:37 -0700284
Jack He0d4807d2018-12-20 15:46:17 -0800285/**
286 * Unknown connection handle for metrics purpose
287 */
288static const uint32_t kUnknownConnectionHandle = 0xFFFF;
289
290/**
291 * Log link layer connection event
292 *
293 * @param address Stack wide consistent Bluetooth address of this event,
294 * nullptr if unknown
295 * @param connection_handle connection handle of this event,
296 * {@link kUnknownConnectionHandle} if unknown
297 * @param direction direction of this connection
298 * @param link_type type of the link
299 * @param hci_cmd HCI command opecode associated with this event, if any
300 * @param hci_event HCI event code associated with this event, if any
301 * @param hci_ble_event HCI BLE event code associated with this event, if any
302 * @param cmd_status Command status associated with this event, if any
303 * @param reason_code Reason code associated with this event, if any
304 */
305void LogLinkLayerConnectionEvent(const RawAddress* address,
306 uint32_t connection_handle,
307 android::bluetooth::DirectionEnum direction,
Jack He7a98b402019-02-06 20:24:24 -0800308 uint16_t link_type, uint32_t hci_cmd,
309 uint16_t hci_event, uint16_t hci_ble_event,
310 uint16_t cmd_status, uint16_t reason_code);
Jack He0d4807d2018-12-20 15:46:17 -0800311
Jack He0e818cf2019-01-20 23:16:45 -0800312/**
313 * Logs when Bluetooth controller failed to reply with command status within
314 * a timeout period after receiving an HCI command from the host
315 *
316 * @param hci_cmd opcode of HCI command that caused this timeout
317 */
318void LogHciTimeoutEvent(uint32_t hci_cmd);
319
Jack He078c8a82019-01-29 14:49:34 -0800320/**
321 * Logs when we receive Bluetooth Read Remote Version Information Complete
322 * Event from the remote device, as documented by the Bluetooth Core HCI
323 * specification
324 *
325 * Reference: 5.0 Core Specification, Vol 2, Part E, Page 1118
326 *
327 * @param handle handle of associated ACL connection
328 * @param status HCI command status of this event
329 * @param version version code from read remote version complete event
330 * @param manufacturer_name manufacturer code from read remote version complete
331 * event
332 * @param subversion subversion code from read remote version complete event
333 */
334void LogRemoteVersionInfo(uint16_t handle, uint8_t status, uint8_t version,
335 uint16_t manufacturer_name, uint16_t subversion);
Jack He7d7a8de2019-01-20 21:31:12 -0800336
337/**
338 * Log A2DP audio buffer underrun event
339 *
340 * @param address A2DP device associated with this event
341 * @param encoding_interval_millis encoding interval in milliseconds
342 * @param num_missing_pcm_bytes number of PCM bytes that cannot be read from
343 * the source
344 */
345void LogA2dpAudioUnderrunEvent(const RawAddress& address,
346 uint64_t encoding_interval_millis,
347 int num_missing_pcm_bytes);
348
349/**
350 * Log A2DP audio buffer overrun event
351 *
352 * @param address A2DP device associated with this event
353 * @param encoding_interval_millis encoding interval in milliseconds
354 * @param num_dropped_buffers number of encoded buffers dropped from Tx queue
355 * @param num_dropped_encoded_frames number of encoded frames dropped from Tx
356 * queue
357 * @param num_dropped_encoded_bytes number of encoded bytes dropped from Tx
358 * queue
359 */
360void LogA2dpAudioOverrunEvent(const RawAddress& address,
361 uint64_t encoding_interval_millis,
362 int num_dropped_buffers,
363 int num_dropped_encoded_frames,
364 int num_dropped_encoded_bytes);
365
366/**
Josh Wue9f5c352021-03-24 20:15:43 +0800367 * Log A2DP playback state changed event
368 *
369 * @param address A2DP device associated with this event
370 * @param playback_state audio playback state
371 * @param audio_coding_mode audio codec encoding mode
372 */
373void LogA2dpPlaybackEvent(const RawAddress& address, int playback_state,
374 int audio_coding_mode);
375
376/**
Jack He7d7a8de2019-01-20 21:31:12 -0800377 * Log read RSSI result
378 *
379 * @param address device associated with this event
380 * @param handle connection handle of this event,
381 * {@link kUnknownConnectionHandle} if unknown
382 * @param cmd_status command status from read RSSI command
383 * @param rssi rssi value in dBm
384 */
385void LogReadRssiResult(const RawAddress& address, uint16_t handle,
386 uint32_t cmd_status, int8_t rssi);
387
388/**
389 * Log failed contact counter report
390 *
391 * @param address device associated with this event
392 * @param handle connection handle of this event,
393 * {@link kUnknownConnectionHandle} if unknown
394 * @param cmd_status command status from read failed contact counter command
395 * @param failed_contact_counter Number of consecutive failed contacts for a
396 * connection corresponding to the Handle
397 */
398void LogReadFailedContactCounterResult(const RawAddress& address,
399 uint16_t handle, uint32_t cmd_status,
400 int32_t failed_contact_counter);
401
402/**
403 * Log transmit power level for a particular device after read
404 *
405 * @param address device associated with this event
406 * @param handle connection handle of this event,
407 * {@link kUnknownConnectionHandle} if unknown
408 * @param cmd_status command status from read failed contact counter command
409 * @param transmit_power_level transmit power level for connection to this
410 * device
411 */
412void LogReadTxPowerLevelResult(const RawAddress& address, uint16_t handle,
413 uint32_t cmd_status,
414 int32_t transmit_power_level);
415
Jack Heb75275d2019-01-31 15:17:08 -0800416/**
417 * Logs when there is an event related to Bluetooth Security Manager Protocol
418 *
419 * @param address address of associated device
420 * @param smp_cmd SMP command code associated with this event
421 * @param direction direction of this SMP command
422 * @param smp_fail_reason SMP pairing failure reason code from SMP spec
423 */
424void LogSmpPairingEvent(const RawAddress& address, uint8_t smp_cmd,
425 android::bluetooth::DirectionEnum direction,
426 uint8_t smp_fail_reason);
Jack He0d888e52019-01-31 17:44:46 -0800427
428/**
429 * Logs there is an event related Bluetooth classic pairing
430 *
431 * @param address address of associated device
432 * @param handle connection handle of this event,
433 * {@link kUnknownConnectionHandle} if unknown
434 * @param hci_cmd HCI command associated with this event
435 * @param hci_event HCI event associated with this event
436 * @param cmd_status Command status associated with this event
437 * @param reason_code Reason code associated with this event
Jack He40553162019-03-20 04:04:36 -0700438 * @param event_value A status value related to this specific event
Jack He0d888e52019-01-31 17:44:46 -0800439 */
Jack He40553162019-03-20 04:04:36 -0700440void LogClassicPairingEvent(const RawAddress& address, uint16_t handle, uint32_t hci_cmd, uint16_t hci_event,
441 uint16_t cmd_status, uint16_t reason_code, int64_t event_value);
Jack He3c162a82019-02-01 18:30:21 -0800442
443/**
444 * Logs when certain Bluetooth SDP attributes are discovered
445 *
446 * @param address address of associated device
447 * @param protocol_uuid 16 bit protocol UUID from Bluetooth Assigned Numbers
448 * @param attribute_id 16 bit attribute ID from Bluetooth Assigned Numbers
449 * @param attribute_size size of this attribute
450 * @param attribute_value pointer to the attribute data, must be larger than
451 * attribute_size
452 */
453void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid,
454 uint16_t attribute_id, size_t attribute_size,
455 const char* attribute_value);
Jack He7a98b402019-02-06 20:24:24 -0800456
457/**
458 * Logs when there is a change in Bluetooth socket connection state
459 *
460 * @param address address of associated device, empty if this is a server port
461 * @param port port of this socket connection
462 * @param type type of socket
463 * @param connection_state socket connection state
464 * @param tx_bytes number of bytes transmitted
465 * @param rx_bytes number of bytes received
466 * @param server_port server port of this socket, if any. When both
467 * |server_port| and |port| fields are populated, |port| must be spawned
468 * by |server_port|
469 * @param socket_role role of this socket, server or connection
470 * @param uid socket owner's uid
471 */
472void LogSocketConnectionState(
473 const RawAddress& address, int port, int type,
474 android::bluetooth::SocketConnectionstateEnum connection_state,
475 int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
476 android::bluetooth::SocketRoleEnum socket_role);
Jack He9e026202019-02-06 21:53:41 -0800477
478/**
479 * Logs when a Bluetooth device's manufacturer information is learnt
480 *
481 * @param address address of associated device
482 * @param source_type where is this device info obtained from
483 * @param source_name name of the data source, internal or external
484 * @param manufacturer name of the manufacturer of this device
485 * @param model model of this device
486 * @param hardware_version hardware version of this device
487 * @param software_version software version of this device
488 */
489void LogManufacturerInfo(const RawAddress& address,
Chen Chenc08fc882022-06-02 15:00:20 -0700490 android::bluetooth::AddressTypeEnum address_type,
Jack He9e026202019-02-06 21:53:41 -0800491 android::bluetooth::DeviceInfoSrcEnum source_type,
492 const std::string& source_name,
493 const std::string& manufacturer,
494 const std::string& model,
495 const std::string& hardware_version,
496 const std::string& software_version);
weichinwengc1a2fc92020-12-15 14:56:19 +0800497
498/**
499 * Logs when received Bluetooth HAL crash reason report.
500 *
501 * @param address current connected address.
502 * @param error_code the crash reason from bluetooth hal
503 * @param vendor_error_code the vendor crash reason from bluetooth Firmware
504 */
505void LogBluetoothHalCrashReason(const RawAddress& address, uint32_t error_code,
506 uint32_t vendor_error_code);
Josh Wuc033a162022-05-05 01:29:04 -0700507
508void LogLeAudioConnectionSessionReported(
509 int32_t group_size, int32_t group_metric_id,
510 int64_t connection_duration_nanos,
511 std::vector<int64_t>& device_connecting_offset_nanos,
512 std::vector<int64_t>& device_connected_offset_nanos,
513 std::vector<int64_t>& device_connection_duration_nanos,
514 std::vector<int32_t>& device_connection_status,
515 std::vector<int32_t>& device_disconnection_status,
516 std::vector<RawAddress>& device_address,
517 std::vector<int64_t>& streaming_offset_nanos,
518 std::vector<int64_t>& streaming_duration_nanos,
519 std::vector<int32_t>& streaming_context_type);
520
Jack He42823982018-08-15 12:38:37 -0700521} // namespace common
522
523} // namespace bluetooth