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