1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef BTIF_BQR_H_
18 #define BTIF_BQR_H_
19 
20 #include <bluetooth/log.h>
21 
22 #include "common/postable_context.h"
23 #include "hci/hci_packets.h"
24 #include "include/hardware/bt_bqr.h"
25 #include "osi/include/osi.h"
26 #include "raw_address.h"
27 
28 namespace bluetooth {
29 namespace bqr {
30 
31 // Bluetooth Quality Report (BQR)
32 //
33 // It is a feature to start the mechanism in the Bluetooth controller to report
34 // Bluetooth Quality event to the host and the following options can be enabled:
35 //   [Quality Monitoring Mode]
36 //     The controller shall periodically send Bluetooth Quality Report sub-event
37 //     to the host.
38 //
39 //   [Approaching LSTO]
40 //     Once no packets are received from the connected Bluetooth device for a
41 //     duration longer than the half of LSTO (Link Supervision TimeOut) value,
42 //     the controller shall report Approaching LSTO event to the host.
43 //
44 //   [A2DP Audio Choppy]
45 //     When the controller detects the factors which will cause audio choppy,
46 //     the controller shall report A2DP Audio Choppy event to the host.
47 //
48 //   [(e)SCO Voice Choppy]
49 //     When the controller detects the factors which will cause voice choppy,
50 //     the controller shall report (e)SCO Voice Choppy event to the host.
51 //
52 //   [Root Inflammation]
53 //     When the controller encounters an error it shall report Root Inflammation
54 //     event indicating the error code to the host.
55 //
56 //   [Vendor Specific Quality]
57 //     Used for the controller vendor to define the vendor proprietary quality
58 //     event(s).
59 //
60 //   [LMP/LL message trace]
61 //     The controller sends the LMP/LL message handshaking with the remote
62 //     device to the host.
63 //
64 //   [Bluetooth Multi-profile/Coex scheduling trace]
65 //     The controller sends its scheduling information on handling the Bluetooth
66 //     multiple profiles and wireless coexistence in the 2.4 Ghz band to the
67 //     host.
68 //
69 //   [Enable the Controller Debug Information mechanism]
70 //     After enabling the Controller Debug Information mechanism, the controller
71 //     just can autonomously report debug logging information via the Controller
72 //     Debug Info sub-event to the host.
73 //
74 //   [Connect Fail]
75 //     When the controller fails to create connection with remote side,
76 //     and remote responds for at least one time, the controller shall report
77 //     connection fail event to the host. However, if remote doesn't respond
78 //     at all(most likely remote is powered off or out of range), controller
79 //     will not report this event.
80 
81 // Bit masks for the selected quality event reporting.
82 static constexpr uint32_t kQualityEventMaskAllOff = 0;
83 static constexpr uint32_t kQualityEventMaskMonitorMode = 0x1 << 0;
84 static constexpr uint32_t kQualityEventMaskApproachLsto = 0x1 << 1;
85 static constexpr uint32_t kQualityEventMaskA2dpAudioChoppy = 0x1 << 2;
86 static constexpr uint32_t kQualityEventMaskScoVoiceChoppy = 0x1 << 3;
87 static constexpr uint32_t kQualityEventMaskRootInflammation = 0x1 << 4;
88 static constexpr uint32_t kQualityEventMaskEnergyMonitoring = 0x1 << 5;
89 static constexpr uint32_t kQualityEventMaskLeAudioChoppy = 0x1 << 6;
90 static constexpr uint32_t kQualityEventMaskConnectFail = 0x1 << 7;
91 static constexpr uint32_t kQualityEventMaskAdvRFStatsEvent = 0x1 << 8;
92 static constexpr uint32_t kQualityEventMaskAdvRFStatsMonitor = 0x1 << 9;
93 static constexpr uint32_t kQualityEventMaskVendorSpecificQuality = 0x1 << 15;
94 static constexpr uint32_t kQualityEventMaskLmpMessageTrace = 0x1 << 16;
95 static constexpr uint32_t kQualityEventMaskBtSchedulingTrace = 0x1 << 17;
96 static constexpr uint32_t kQualityEventMaskControllerDbgInfo = 0x1 << 18;
97 static constexpr uint32_t kQualityEventMaskVendorSpecificTrace = 0x1 << 31;
98 static constexpr uint32_t kQualityEventMaskAll =
99     kQualityEventMaskMonitorMode | kQualityEventMaskApproachLsto |
100     kQualityEventMaskA2dpAudioChoppy | kQualityEventMaskScoVoiceChoppy |
101     kQualityEventMaskRootInflammation | kQualityEventMaskEnergyMonitoring |
102     kQualityEventMaskLeAudioChoppy | kQualityEventMaskConnectFail |
103     kQualityEventMaskAdvRFStatsEvent | kQualityEventMaskAdvRFStatsMonitor |
104     kQualityEventMaskVendorSpecificQuality | kQualityEventMaskLmpMessageTrace |
105     kQualityEventMaskBtSchedulingTrace | kQualityEventMaskControllerDbgInfo |
106     kQualityEventMaskVendorSpecificTrace;
107 // Define the minimum time interval (in ms) of quality event reporting for the
108 // selected quality event(s). Controller Firmware should not report the next
109 // event within the defined Minimum Report Interval * Report Interval
110 // Multiple.
111 static constexpr uint16_t kMinReportIntervalNoLimit = 0;
112 static constexpr uint16_t kMinReportIntervalMaxMs = 0xFFFF;
113 // Define the Report Interval Multiple of quality event reporting for the
114 // selected quality event(s). Controller Firmware should not report the next
115 // event within interval: Minimum Report interval * Report Interval Multiple.
116 // When Report Interval Multiple set to 0 is equal set to 1
117 static constexpr uint32_t kReportIntervalMultipleNoLimit = 0;
118 static constexpr uint32_t kReportIntervalMultipleMax = 0xFFFFFFFF;
119 // The maximum count of Log Dump related event can be written in the log file.
120 static constexpr uint16_t kLogDumpEventPerFile = 0x00FF;
121 // Total length of all parameters of the link Quality related event except
122 // Vendor Specific Parameters.
123 static constexpr uint8_t kLinkQualityParamTotalLen = 48;
124 // 7.8.116 LE Read ISO Link Quality command
125 static constexpr uint8_t kISOLinkQualityParamTotalLen = 24;
126 // Total length of all parameters of the ROOT_INFLAMMATION event except Vendor
127 // Specific Parameters.
128 static constexpr uint8_t kRootInflammationParamTotalLen = 3;
129 // Total length of all parameters of the Log Dump related event except Vendor
130 // Specific Parameters.
131 static constexpr uint8_t kLogDumpParamTotalLen = 3;
132 // Remote address and calibration failure count parameters len
133 // Added in BQR V5.0
134 static constexpr uint8_t kVersion5_0ParamsTotalLen = 7;
135 // Added in BQR V6.0
136 static constexpr uint8_t kVersion6_0ParamsTotalLen = 6;
137 // Warning criteria of the RSSI value.
138 static constexpr int8_t kCriWarnRssi = -80;
139 // Warning criteria of the unused AFH channel count.
140 static constexpr uint8_t kCriWarnUnusedCh = 55;
141 // The queue size of recording the BQR events.
142 static constexpr uint8_t kBqrEventQueueSize = 25;
143 // The Property of BQR event mask configuration.
144 static constexpr const char* kpPropertyEventMask =
145     "persist.bluetooth.bqr.event_mask";
146 // The Property of BQR Vendor Quality configuration.
147 static constexpr const char* kpPropertyVndQualityMask =
148     "persist.bluetooth.bqr.vnd_quality_mask";
149 // The Property of BQR Vendor Trace configuration.
150 static constexpr const char* kpPropertyVndTraceMask =
151     "persist.bluetooth.bqr.vnd_trace_mask";
152 // The Property of BQR minimum report interval configuration.
153 static constexpr const char* kpPropertyMinReportIntervalMs =
154     "persist.bluetooth.bqr.min_interval_ms";
155 // The Property of BQR minimum report interval multiple.
156 static constexpr const char* kpPropertyIntervalMultiple =
157     "persist.bluetooth.bqr.interval_multiple";
158 // Path of the LMP/LL message trace log file.
159 static constexpr const char* kpLmpLlMessageTraceLogPath =
160     "/data/misc/bluetooth/logs/lmp_ll_message_trace.log";
161 // Path of the last LMP/LL message trace log file.
162 static constexpr const char* kpLmpLlMessageTraceLastLogPath =
163     "/data/misc/bluetooth/logs/lmp_ll_message_trace.log.last";
164 // Path of the Bluetooth Multi-profile/Coex scheduling trace log file.
165 static constexpr const char* kpBtSchedulingTraceLogPath =
166     "/data/misc/bluetooth/logs/bt_scheduling_trace.log";
167 // Path of the last Bluetooth Multi-profile/Coex scheduling trace log file.
168 static constexpr const char* kpBtSchedulingTraceLastLogPath =
169     "/data/misc/bluetooth/logs/bt_scheduling_trace.log.last";
170 // The Property of BQR a2dp choppy report and sco choppy report thresholds.
171 // A2dp choppy will be reported only when a2dp choppy times is >=
172 // a2dp_choppy_threshold. The default value in firmware side is 1. It is same
173 // for sco choppy. Value format is a2dp_choppy_threshold,sco_choppy_threshold
174 static constexpr const char* kpPropertyChoppyThreshold =
175     "persist.bluetooth.bqr.choppy_threshold";
176 
177 // File Descriptor of LMP/LL message trace log
178 static int LmpLlMessageTraceLogFd = INVALID_FD;
179 // File Descriptor of Bluetooth Multi-profile/Coex scheduling trace log
180 static int BtSchedulingTraceLogFd = INVALID_FD;
181 // Counter of LMP/LL message trace
182 static uint16_t LmpLlMessageTraceCounter = 0;
183 // Counter of Bluetooth Multi-profile/Coex scheduling trace
184 static uint16_t BtSchedulingTraceCounter = 0;
185 // The version supports ISO packets start from v1.01(257)
186 static constexpr uint16_t kBqrIsoVersion = 0x101;
187 // The version supports vendor quality and trace log starting v1.02(258)
188 static constexpr uint16_t kBqrVndLogVersion = 0x102;
189 // The version supports remote address info and calibration failure count
190 // start from v1.03(259)
191 static constexpr uint16_t kBqrVersion5_0 = 0x103;
192 // The REPORT_ACTION_QUERY and BQR_Report_interval starting v1.04(260)
193 static constexpr uint16_t kBqrVersion6_0 = 0x104;
194 
195 // Action definition
196 //
197 // Action to Add, Delete or Clear the reporting of quality event(s).
198 // Delete will clear specific quality event(s) reporting. Clear will clear all
199 // quality events reporting.
200 enum BqrReportAction : uint8_t {
201   REPORT_ACTION_ADD = 0x00,
202   REPORT_ACTION_DELETE = 0x01,
203   REPORT_ACTION_CLEAR = 0x02,
204   REPORT_ACTION_QUERY = 0x03
205 };
206 
207 // Report ID definition
208 enum BqrQualityReportId : uint8_t {
209   QUALITY_REPORT_ID_MONITOR_MODE = 0x01,
210   QUALITY_REPORT_ID_APPROACH_LSTO = 0x02,
211   QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03,
212   QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04,
213   QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05,
214   QUALITY_REPORT_ID_LE_AUDIO_CHOPPY = 0x07,
215   QUALITY_REPORT_ID_CONNECT_FAIL = 0x08,
216   QUALITY_REPORT_ID_VENDOR_SPECIFIC_QUALITY = 0x10,
217   QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE = 0x11,
218   QUALITY_REPORT_ID_BT_SCHEDULING_TRACE = 0x12,
219   QUALITY_REPORT_ID_CONTROLLER_DBG_INFO = 0x13,
220   QUALITY_REPORT_ID_VENDOR_SPECIFIC_TRACE = 0x20,
221 };
222 
223 // Packet Type definition
224 enum BqrPacketType : uint8_t {
225   PACKET_TYPE_ID = 0x01,
226   PACKET_TYPE_NULL,
227   PACKET_TYPE_POLL,
228   PACKET_TYPE_FHS,
229   PACKET_TYPE_HV1,
230   PACKET_TYPE_HV2,
231   PACKET_TYPE_HV3,
232   PACKET_TYPE_DV,
233   PACKET_TYPE_EV3,
234   PACKET_TYPE_EV4,
235   PACKET_TYPE_EV5,
236   PACKET_TYPE_2EV3,
237   PACKET_TYPE_2EV5,
238   PACKET_TYPE_3EV3,
239   PACKET_TYPE_3EV5,
240   PACKET_TYPE_DM1,
241   PACKET_TYPE_DH1,
242   PACKET_TYPE_DM3,
243   PACKET_TYPE_DH3,
244   PACKET_TYPE_DM5,
245   PACKET_TYPE_DH5,
246   PACKET_TYPE_AUX1,
247   PACKET_TYPE_2DH1,
248   PACKET_TYPE_2DH3,
249   PACKET_TYPE_2DH5,
250   PACKET_TYPE_3DH1,
251   PACKET_TYPE_3DH3,
252   PACKET_TYPE_3DH5,
253   PACKET_TYPE_ISO = 0x51
254 };
255 
256 // Configuration Parameters
257 typedef struct {
258   BqrReportAction report_action;
259   uint32_t quality_event_mask;
260   uint16_t minimum_report_interval_ms;
261   uint32_t vnd_quality_mask;
262   uint32_t vnd_trace_mask;
263   uint32_t report_interval_multiple;
264 } BqrConfiguration;
265 
266 // Link quality related BQR event
267 typedef struct {
268   // Quality report ID.
269   uint8_t quality_report_id;
270   // Packet type of the connection.
271   uint8_t packet_types;
272   // Connection handle of the connection.
273   uint16_t connection_handle;
274   // Performing Role for the connection.
275   uint8_t connection_role;
276   // Current Transmit Power Level for the connection. This value is the same as
277   // the controller's response to the HCI_Read_Transmit_Power_Level HCI command.
278   int8_t tx_power_level;
279   // Received Signal Strength Indication (RSSI) value for the connection. This
280   // value is an absolute receiver signal strength value.
281   int8_t rssi;
282   // Signal-to-Noise Ratio (SNR) value for the connection. It is the average
283   // SNR of all the channels used by the link currently.
284   uint8_t snr;
285   // Indicates the number of unused channels in AFH_channel_map.
286   uint8_t unused_afh_channel_count;
287   // Indicates the number of the channels which are interfered and quality is
288   // bad but are still selected for AFH.
289   uint8_t afh_select_unideal_channel_count;
290   // Current Link Supervision Timeout Setting.
291   // Unit: N * 0.3125 ms (1 Bluetooth Clock)
292   uint16_t lsto;
293   // Piconet Clock for the specified Connection_Handle. This value is the same
294   // as the controller's response to HCI_Read_Clock HCI command with the
295   // parameter "Which_Clock" of 0x01 (Piconet Clock).
296   // Unit: N * 0.3125 ms (1 Bluetooth Clock)
297   uint32_t connection_piconet_clock;
298   // The count of retransmission.
299   uint32_t retransmission_count;
300   // The count of no RX.
301   uint32_t no_rx_count;
302   // The count of NAK (Negative Acknowledge).
303   uint32_t nak_count;
304   // Timestamp of last TX ACK.
305   // Unit: N * 0.3125 ms (1 Bluetooth Clock)
306   uint32_t last_tx_ack_timestamp;
307   // The count of Flow-off (STOP).
308   uint32_t flow_off_count;
309   // Timestamp of last Flow-on (GO).
310   // Unit: N * 0.3125 ms (1 Bluetooth Clock)
311   uint32_t last_flow_on_timestamp;
312   // Buffer overflow count (how many bytes of TX data are dropped) since the
313   // last event.
314   uint32_t buffer_overflow_bytes;
315   // Buffer underflow count (in byte).
316   uint32_t buffer_underflow_bytes;
317   // Remote device address
318   RawAddress bdaddr;
319   // The count of calibration failed items
320   uint8_t cal_failed_item_count;
321   // The number of packets that are sent out.
322   uint32_t tx_total_packets;
323   // The number of packets that don't receive an acknowledgment.
324   uint32_t tx_unacked_packets;
325   // The number of packets that are not sent out by its flush point.
326   uint32_t tx_flushed_packets;
327   // The number of packets that Link Layer transmits a CIS Data PDU in the last
328   // subevent of a CIS event.
329   uint32_t tx_last_subevent_packets;
330   // The number of received packages with CRC error since the last event.
331   uint32_t crc_error_packets;
332   // The number of duplicate(retransmission) packages that are received since
333   // the last event.
334   uint32_t rx_duplicate_packets;
335   // The number of unreceived packets is the same as the parameter of LE Read
336   // ISO Link Quality command.
337   uint32_t rx_unreceived_packets;
338   // Bitmask to indicate various coex related information
339   uint16_t coex_info_mask;
340   // For the controller vendor to obtain more vendor specific parameters.
341   const uint8_t* vendor_specific_parameter;
342 } BqrLinkQualityEvent;
343 
344 // Log dump related BQR event
345 typedef struct {
346   // Quality report ID.
347   uint8_t quality_report_id;
348   // Connection handle of the connection.
349   uint16_t connection_handle;
350   // For the controller vendor to obtain more vendor specific parameters.
351   const uint8_t* vendor_specific_parameter;
352 } BqrLogDumpEvent;
353 
354 // BQR sub-event of Vendor Specific Event
355 class BqrVseSubEvt {
356  public:
357   // Parse the Link Quality related BQR event.
358   //
359   // @param length Total length of all parameters contained in the sub-event.
360   // @param p_param_buf A pointer to the parameters contained in the sub-event.
361   void ParseBqrLinkQualityEvt(uint8_t length, const uint8_t* p_param_buf);
362   // Write the LMP/LL message trace to the log file.
363   //
364   // @param fd The File Descriptor of the log file.
365   // @param length Total length of all parameters contained in the sub-event.
366   // @param p_param_buf A pointer to the parameters contained in the sub-event.
367   void WriteLmpLlTraceLogFile(int fd, uint8_t length,
368                               const uint8_t* p_param_buf);
369   // Write the Bluetooth Multi-profile/Coex scheduling trace to the log file.
370   //
371   // @param fd The File Descriptor of the log file.
372   // @param length Total length of all parameters contained in the sub-event.
373   // @param p_param_buf A pointer to the parameters contained in the sub-event.
374   void WriteBtSchedulingTraceLogFile(int fd, uint8_t length,
375                                      const uint8_t* p_param_buf);
376   // Get a string representation of the Bluetooth Quality event.
377   //
378   // @return a string representation of the Bluetooth Quality event.
379   std::string ToString() const;
380 
381   friend std::ostream& operator<<(std::ostream& os, const BqrVseSubEvt& a) {
382     return os << a.ToString();
383   }
384 
385   virtual ~BqrVseSubEvt() = default;
386   // Link Quality related BQR event
387   BqrLinkQualityEvent bqr_link_quality_event_ = {};
388   // Log Dump related BQR event
389   BqrLogDumpEvent bqr_log_dump_event_ = {};
390   // Local wall clock timestamp of receiving BQR VSE sub-event
391   std::tm tm_timestamp_ = {};
392 };
393 
394 BluetoothQualityReportInterface* getBluetoothQualityReportInterface();
395 
396 // Enable/Disable Bluetooth Quality Report mechanism.
397 //
398 // Which Quality event will be enabled is according to the setting of the
399 // property "persist.bluetooth.bqr.event_mask".
400 // And the minimum time interval of quality event reporting depends on the
401 // setting of property "persist.bluetooth.bqr.min_interval_ms".
402 //
403 // @param to_bind gives the postable for the callback, or null if disabling.
404 void EnableBtQualityReport(common::PostableContext* to_bind);
405 
406 // Dump Bluetooth Quality Report information.
407 //
408 // @param fd The file descriptor to use for dumping information.
409 void DebugDump(int fd);
410 
411 }  // namespace bqr
412 }  // namespace bluetooth
413 
414 namespace fmt {
415 template <>
416 struct formatter<bluetooth::bqr::BqrReportAction>
417     : enum_formatter<bluetooth::bqr::BqrReportAction> {};
418 template <>
419 struct formatter<bluetooth::bqr::BqrVseSubEvt> : ostream_formatter {};
420 }  // namespace fmt
421 
422 #endif  // BTIF_BQR_H_
423