1 /******************************************************************************
2  *
3  *  Copyright 2021 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 <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
22 #include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h>
23 #include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h>
24 
25 #include <vector>
26 
27 #include "hci/address.h"
28 
29 namespace bluetooth {
30 
31 namespace os {
32 /**
33  * Unknown connection handle for metrics purpose
34  */
35 static const uint32_t kUnknownConnectionHandle = 0xFFFF;
36 
37 /**
38  * Log link layer connection event
39  *
40  * @param address Stack wide consistent Bluetooth address of this event,
41  *                nullptr if unknown
42  * @param connection_handle connection handle of this event,
43  *                          {@link kUnknownConnectionHandle} if unknown
44  * @param direction direction of this connection
45  * @param link_type type of the link
46  * @param hci_cmd HCI command opecode associated with this event, if any
47  * @param hci_event HCI event code associated with this event, if any
48  * @param hci_ble_event HCI BLE event code associated with this event, if any
49  * @param cmd_status Command status associated with this event, if any
50  * @param reason_code Reason code associated with this event, if any
51  */
52 void LogMetricLinkLayerConnectionEvent(
53     const hci::Address* address,
54     uint32_t connection_handle,
55     android::bluetooth::DirectionEnum direction,
56     uint16_t link_type,
57     uint32_t hci_cmd,
58     uint16_t hci_event,
59     uint16_t hci_ble_event,
60     uint16_t cmd_status,
61     uint16_t reason_code);
62 
63 /**
64  * Logs when Bluetooth controller failed to reply with command status within
65  * a timeout period after receiving an HCI command from the host
66  *
67  * @param hci_cmd opcode of HCI command that caused this timeout
68  */
69 void LogMetricHciTimeoutEvent(uint32_t hci_cmd);
70 
71 /**
72  * Logs when we receive Bluetooth Read Remote Version Information Complete
73  * Event from the remote device, as documented by the Bluetooth Core HCI
74  * specification
75  *
76  * Reference: 5.0 Core Specification, Vol 2, Part E, Page 1118
77  *
78  * @param handle handle of associated ACL connection
79  * @param status HCI command status of this event
80  * @param version version code from read remote version complete event
81  * @param manufacturer_name manufacturer code from read remote version complete
82  *                          event
83  * @param subversion subversion code from read remote version complete event
84  */
85 void LogMetricRemoteVersionInfo(
86     uint16_t handle, uint8_t status, uint8_t version, uint16_t manufacturer_name, uint16_t subversion);
87 
88 /**
89  * Log A2DP audio buffer underrun event
90  *
91  * @param address A2DP device associated with this event
92  * @param encoding_interval_millis encoding interval in milliseconds
93  * @param num_missing_pcm_bytes number of PCM bytes that cannot be read from
94  *                              the source
95  */
96 void LogMetricA2dpAudioUnderrunEvent(
97     const hci::Address& address, uint64_t encoding_interval_millis, int num_missing_pcm_bytes);
98 
99 /**
100  * Log A2DP audio buffer overrun event
101  *
102  * @param address A2DP device associated with this event
103  * @param encoding_interval_millis encoding interval in milliseconds
104  * @param num_dropped_buffers number of encoded buffers dropped from Tx queue
105  * @param num_dropped_encoded_frames number of encoded frames dropped from Tx
106  *                                   queue
107  * @param num_dropped_encoded_bytes number of encoded bytes dropped from Tx
108  *                                  queue
109  */
110 void LogMetricA2dpAudioOverrunEvent(
111     const hci::Address& address,
112     uint64_t encoding_interval_millis,
113     int num_dropped_buffers,
114     int num_dropped_encoded_frames,
115     int num_dropped_encoded_bytes);
116 
117 /**
118  * Log A2DP audio playback state changed event
119  *
120  * @param address A2DP device associated with this event
121  * @param playback_state A2DP audio playback state, on/off
122  * @param audio_coding_mode A2DP audio codec encoding mode, hw/sw
123  */
124 void LogMetricA2dpPlaybackEvent(
125     const hci::Address& address, int playback_state, int audio_coding_mode);
126 
127 /**
128  * Log A2DP audio session metrics
129  *
130  * @param address A2DP device associated with this session
131  * @param audio_duration_ms duration of the A2DP session
132  * @param media_timer_min_ms min time interval for the media timer
133  * @param media_timer_max_ms max time interval for the media timer
134  * @param media_timer_avg_ms avg time interval for the media timer
135  * @param total_scheduling_count total scheduling count
136  * @param buffer_overruns_max_count max count of Tx queue messages dropped
137                                     caused by buffer overruns
138  * @param buffer_overruns_total total count of Tx queue messages dropped
139                                 caused by buffer overruns
140  * @param buffer_underruns_average  avg number of bytes short in buffer
141                                     underruns
142  * @param buffer_underruns_count count of buffer underruns
143  * @param codec_index A2DP codec index (SBC=0, AAC=1, etc...)
144  * @param is_a2dp_offload if A2DP is offload
145  */
146 void LogMetricA2dpSessionMetricsEvent(
147     const hci::Address& address,
148     int64_t audio_duration_ms,
149     int media_timer_min_ms,
150     int media_timer_max_ms,
151     int media_timer_avg_ms,
152     int total_scheduling_count,
153     int buffer_overruns_max_count,
154     int buffer_overruns_total,
155     float buffer_underruns_average,
156     int buffer_underruns_count,
157     int64_t codec_index,
158     bool is_a2dp_offload);
159 
160 /**
161  * Log HFP audio capture packet loss statistics
162  *
163  * @param address HFP device associated with this stats
164  * @param num_decoded_frames number of decoded frames
165  * @param packet_loss_ratio ratio of packet loss frames
166  * @param codec_id codec ID of the packet (mSBC=2, LC3=3)
167  */
168 void LogMetricHfpPacketLossStats(
169     const hci::Address& address,
170     int num_decoded_frames,
171     double packet_loss_ratio,
172     uint16_t codec_id);
173 
174 /**
175  * Log Mmc transcode round-trip time statistics
176  *
177  * @param maximum_rtt maximum round-trip time in this session
178  * @param mean_rtt the average of round-trip time in this session
179  * @param num_requests the number of transcoding requests in the session
180  * @param codec_type codec type used in this session
181  */
182 void LogMetricMmcTranscodeRttStats(
183     int maximum_rtt, double mean_rtt, int num_requests, int codec_type);
184 
185 /**
186  * Log read RSSI result
187  *
188  * @param address device associated with this event
189  * @param handle connection handle of this event,
190  *               {@link kUnknownConnectionHandle} if unknown
191  * @param cmd_status command status from read RSSI command
192  * @param rssi rssi value in dBm
193  */
194 void LogMetricReadRssiResult(const hci::Address& address, uint16_t handle, uint32_t cmd_status, int8_t rssi);
195 
196 /**
197  * Log failed contact counter report
198  *
199  * @param address device associated with this event
200  * @param handle connection handle of this event,
201  *               {@link kUnknownConnectionHandle} if unknown
202  * @param cmd_status command status from read failed contact counter command
203  * @param failed_contact_counter Number of consecutive failed contacts for a
204  *                               connection corresponding to the Handle
205  */
206 void LogMetricReadFailedContactCounterResult(
207     const hci::Address& address, uint16_t handle, uint32_t cmd_status, int32_t failed_contact_counter);
208 
209 /**
210  * Log transmit power level for a particular device after read
211  *
212  * @param address device associated with this event
213  * @param handle connection handle of this event,
214  *               {@link kUnknownConnectionHandle} if unknown
215  * @param cmd_status command status from read failed contact counter command
216  * @param transmit_power_level transmit power level for connection to this
217  *                             device
218  */
219 void LogMetricReadTxPowerLevelResult(
220     const hci::Address& address, uint16_t handle, uint32_t cmd_status, int32_t transmit_power_level);
221 
222 /**
223  * Logs when there is an event related to Bluetooth Security Manager Protocol
224  *
225  * @param address address of associated device
226  * @param smp_cmd SMP command code associated with this event
227  * @param direction direction of this SMP command
228  * @param smp_fail_reason SMP pairing failure reason code from SMP spec
229  */
230 void LogMetricSmpPairingEvent(
231     const hci::Address& address,
232     uint16_t smp_cmd,
233     android::bluetooth::DirectionEnum direction,
234     uint16_t smp_fail_reason);
235 
236 /**
237  * Logs there is an event related Bluetooth classic pairing
238  *
239  * @param address address of associated device
240  * @param handle connection handle of this event,
241  *               {@link kUnknownConnectionHandle} if unknown
242  * @param hci_cmd HCI command associated with this event
243  * @param hci_event HCI event associated with this event
244  * @param cmd_status Command status associated with this event
245  * @param reason_code Reason code associated with this event
246  * @param event_value A status value related to this specific event
247  */
248 void LogMetricClassicPairingEvent(
249     const hci::Address& address,
250     uint16_t handle,
251     uint32_t hci_cmd,
252     uint16_t hci_event,
253     uint16_t cmd_status,
254     uint16_t reason_code,
255     int64_t event_value);
256 
257 /**
258  * Logs when certain Bluetooth SDP attributes are discovered
259  *
260  * @param address address of associated device
261  * @param protocol_uuid 16 bit protocol UUID from Bluetooth Assigned Numbers
262  * @param attribute_id 16 bit attribute ID from Bluetooth Assigned Numbers
263  * @param attribute_size size of this attribute
264  * @param attribute_value pointer to the attribute data, must be larger than
265  *                        attribute_size
266  */
267 void LogMetricSdpAttribute(
268     const hci::Address& address,
269     uint16_t protocol_uuid,
270     uint16_t attribute_id,
271     size_t attribute_size,
272     const char* attribute_value);
273 
274 /**
275  * Logs when there is a change in Bluetooth socket connection state
276  *
277  * @param address address of associated device, empty if this is a server port
278  * @param port port of this socket connection
279  * @param type type of socket
280  * @param connection_state socket connection state
281  * @param tx_bytes number of bytes transmitted
282  * @param rx_bytes number of bytes received
283  * @param server_port server port of this socket, if any. When both
284  *        |server_port| and |port| fields are populated, |port| must be spawned
285  *        by |server_port|
286  * @param socket_role role of this socket, server or connection
287  * @param uid socket owner's uid
288  */
289 void LogMetricSocketConnectionState(
290     const hci::Address& address,
291     int port,
292     int type,
293     android::bluetooth::SocketConnectionstateEnum connection_state,
294     int64_t tx_bytes,
295     int64_t rx_bytes,
296     int uid,
297     int server_port,
298     android::bluetooth::SocketRoleEnum socket_role);
299 
300 /**
301  * Logs when a Bluetooth device's manufacturer information is learnt
302  *
303  * @param address address of associated device
304  * @param source_type where is this device info obtained from
305  * @param source_name name of the data source, internal or external
306  * @param manufacturer name of the manufacturer of this device
307  * @param model model of this device
308  * @param hardware_version hardware version of this device
309  * @param software_version software version of this device
310  */
311 void LogMetricManufacturerInfo(
312     const hci::Address& address,
313     android::bluetooth::AddressTypeEnum address_type,
314     android::bluetooth::DeviceInfoSrcEnum source_type,
315     const std::string& source_name,
316     const std::string& manufacturer,
317     const std::string& model,
318     const std::string& hardware_version,
319     const std::string& software_version);
320 
321 /**
322  * Logs when received Bluetooth HAL crash reason report.
323  *
324  * @param address current connected address.
325  * @param error_code the crash reason from bluetooth hal
326  * @param vendor_error_code the vendor crash reason from bluetooth firmware
327  */
328 void LogMetricBluetoothHalCrashReason(
329     const hci::Address& address,
330     uint32_t error_code,
331     uint32_t vendor_error_code);
332 
333 void LogMetricBluetoothLocalSupportedFeatures(uint32_t page_num, uint64_t features);
334 
335 void LogMetricBluetoothLocalVersions(
336     uint32_t lmp_manufacturer_name,
337     uint8_t lmp_version,
338     uint32_t lmp_subversion,
339     uint8_t hci_version,
340     uint32_t hci_revision);
341 
342 void LogMetricBluetoothDisconnectionReasonReported(
343     uint32_t reason, const hci::Address& address, uint32_t connection_handle);
344 
345 void LogMetricBluetoothRemoteSupportedFeatures(
346     const hci::Address& address, uint32_t page, uint64_t features, uint32_t connection_handle);
347 
348 void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count);
349 
350 using android::bluetooth::le::LeAclConnectionState;
351 using android::bluetooth::le::LeConnectionOriginType;
352 using android::bluetooth::le::LeConnectionType;
353 using android::bluetooth::le::LeConnectionState;
354 // Adding options
355 struct LEConnectionSessionOptions {
356   // Contains the state of the LE-ACL Connection
357   LeAclConnectionState acl_connection_state = LeAclConnectionState::LE_ACL_UNSPECIFIED;
358   // Origin of the transaction
359   LeConnectionOriginType origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED;
360   // Connection Type
361   LeConnectionType transaction_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED;
362   // Transaction State
363   LeConnectionState transaction_state = LeConnectionState::STATE_UNSPECIFIED;
364   // Latency of the entire transaction
365   int64_t latency = 0;
366   // Address of the remote device
367   hci::Address remote_address = hci::Address::kEmpty;
368   // UID associated with the device
369   int app_uid = 0;
370   // Latency of the ACL Transaction
371   int64_t acl_latency = 0;
372   // Contains the error code associated with the ACL Connection if failed
373   android::bluetooth::hci::StatusEnum status = android::bluetooth::hci::StatusEnum::STATUS_UNKNOWN;
374   // Cancelled connection
375   bool is_cancelled = false;
376 };
377 
378 // Argument Type
379 enum ArgumentType { GATT_IF, L2CAP_PSM, L2CAP_CID, APP_UID, ACL_STATUS_CODE };
380 void LogMetricBluetoothLEConnectionMetricEvent(
381     const hci::Address& address,
382     LeConnectionOriginType origin_type,
383     LeConnectionType connection_type,
384     LeConnectionState transaction_state,
385     std::vector<std::pair<os::ArgumentType, int>>& argument_list);
386 
387 // Upload LE Session
388 void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options);
389 
390 }  // namespace os
391    //
392 }  // namespace bluetooth
393