/* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BTIF_BQR_H_ #define BTIF_BQR_H_ #include "btm_api_types.h" #include "common/leaky_bonded_queue.h" #include "osi/include/osi.h" namespace bluetooth { namespace bqr { // Bluetooth Quality Report (BQR) // // It is a feature to start the mechanism in the Bluetooth controller to report // Bluetooth Quality event to the host and the following options can be enabled: // [Quality Monitoring Mode] // The controller shall periodically send Bluetooth Quality Report sub-event // to the host. // // [Approaching LSTO] // Once no packets are received from the connected Bluetooth device for a // duration longer than the half of LSTO (Link Supervision TimeOut) value, // the controller shall report Approaching LSTO event to the host. // // [A2DP Audio Choppy] // When the controller detects the factors which will cause audio choppy, // the controller shall report A2DP Audio Choppy event to the host. // // [(e)SCO Voice Choppy] // When the controller detects the factors which will cause voice choppy, // the controller shall report (e)SCO Voice Choppy event to the host. // // [Root Inflammation] // When the controller encounters an error it shall report Root Inflammation // event indicating the error code to the host. // // [LMP/LL message trace] // The controller sends the LMP/LL message handshaking with the remote // device to the host. // // [Bluetooth Multi-profile/Coex scheduling trace] // The controller sends its scheduling information on handling the Bluetooth // multiple profiles and wireless coexistence in the 2.4 Ghz band to the // host. // // [Enable the Controller Debug Information mechanism] // After enabling the Controller Debug Information mechanism, the controller // just can autonomously report debug logging information via the Controller // Debug Info sub-event to the host. // // Bit masks for the selected quality event reporting. static constexpr uint32_t kQualityEventMaskAllOff = 0; static constexpr uint32_t kQualityEventMaskMonitorMode = 0x00000001; static constexpr uint32_t kQualityEventMaskApproachLsto = 0x00000002; static constexpr uint32_t kQualityEventMaskA2dpAudioChoppy = 0x00000004; static constexpr uint32_t kQualityEventMaskScoVoiceChoppy = 0x00000008; static constexpr uint32_t kQualityEventMaskRootInflammation = 0x00000010; static constexpr uint32_t kQualityEventMaskLmpMessageTrace = 0x00010000; static constexpr uint32_t kQualityEventMaskBtSchedulingTrace = 0x00020000; static constexpr uint32_t kQualityEventMaskControllerDbgInfo = 0x00040000; static constexpr uint32_t kQualityEventMaskAll = kQualityEventMaskMonitorMode | kQualityEventMaskApproachLsto | kQualityEventMaskA2dpAudioChoppy | kQualityEventMaskScoVoiceChoppy | kQualityEventMaskRootInflammation | kQualityEventMaskLmpMessageTrace | kQualityEventMaskBtSchedulingTrace | kQualityEventMaskControllerDbgInfo; // Define the minimum time interval (in ms) of quality event reporting for the // selected quality event(s). Controller Firmware should not report the next // event within the defined time interval. static constexpr uint16_t kMinReportIntervalNoLimit = 0; static constexpr uint16_t kMinReportIntervalMaxMs = 0xFFFF; // The maximum count of Log Dump related event can be written in the log file. static constexpr uint16_t kLogDumpEventPerFile = 0x00FF; // Total length of all parameters of the link Quality related event except // Vendor Specific Parameters. static constexpr uint8_t kLinkQualityParamTotalLen = 48; // Total length of all parameters of the ROOT_INFLAMMATION event except Vendor // Specific Parameters. static constexpr uint8_t kRootInflammationParamTotalLen = 3; // Total length of all parameters of the Log Dump related event except Vendor // Specific Parameters. static constexpr uint8_t kLogDumpParamTotalLen = 3; // Warning criteria of the RSSI value. static constexpr int8_t kCriWarnRssi = -80; // Warning criteria of the unused AFH channel count. static constexpr uint8_t kCriWarnUnusedCh = 55; // The queue size of recording the BQR events. static constexpr uint8_t kBqrEventQueueSize = 25; // The Property of BQR event mask configuration. static constexpr const char* kpPropertyEventMask = "persist.bluetooth.bqr.event_mask"; // The Property of BQR minimum report interval configuration. static constexpr const char* kpPropertyMinReportIntervalMs = "persist.bluetooth.bqr.min_interval_ms"; // Path of the LMP/LL message trace log file. static constexpr const char* kpLmpLlMessageTraceLogPath = "/data/misc/bluetooth/logs/lmp_ll_message_trace.log"; // Path of the last LMP/LL message trace log file. static constexpr const char* kpLmpLlMessageTraceLastLogPath = "/data/misc/bluetooth/logs/lmp_ll_message_trace.log.last"; // Path of the Bluetooth Multi-profile/Coex scheduling trace log file. static constexpr const char* kpBtSchedulingTraceLogPath = "/data/misc/bluetooth/logs/bt_scheduling_trace.log"; // Path of the last Bluetooth Multi-profile/Coex scheduling trace log file. static constexpr const char* kpBtSchedulingTraceLastLogPath = "/data/misc/bluetooth/logs/bt_scheduling_trace.log.last"; // File Descriptor of LMP/LL message trace log static int LmpLlMessageTraceLogFd = INVALID_FD; // File Descriptor of Bluetooth Multi-profile/Coex scheduling trace log static int BtSchedulingTraceLogFd = INVALID_FD; // Counter of LMP/LL message trace static uint16_t LmpLlMessageTraceCounter = 0; // Counter of Bluetooth Multi-profile/Coex scheduling trace static uint16_t BtSchedulingTraceCounter = 0; // Action definition // // Action to Add, Delete or Clear the reporting of quality event(s). // Delete will clear specific quality event(s) reporting. Clear will clear all // quality events reporting. enum BqrReportAction : uint8_t { REPORT_ACTION_ADD = 0x00, REPORT_ACTION_DELETE = 0x01, REPORT_ACTION_CLEAR = 0x02 }; // Report ID definition enum BqrQualityReportId : uint8_t { QUALITY_REPORT_ID_MONITOR_MODE = 0x01, QUALITY_REPORT_ID_APPROACH_LSTO = 0x02, QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03, QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04, QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05, QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE = 0x11, QUALITY_REPORT_ID_BT_SCHEDULING_TRACE = 0x12, QUALITY_REPORT_ID_CONTROLLER_DBG_INFO = 0x13 }; // Packet Type definition enum BqrPacketType : uint8_t { PACKET_TYPE_ID = 0x01, PACKET_TYPE_NULL, PACKET_TYPE_POLL, PACKET_TYPE_FHS, PACKET_TYPE_HV1, PACKET_TYPE_HV2, PACKET_TYPE_HV3, PACKET_TYPE_DV, PACKET_TYPE_EV3, PACKET_TYPE_EV4, PACKET_TYPE_EV5, PACKET_TYPE_2EV3, PACKET_TYPE_2EV5, PACKET_TYPE_3EV3, PACKET_TYPE_3EV5, PACKET_TYPE_DM1, PACKET_TYPE_DH1, PACKET_TYPE_DM3, PACKET_TYPE_DH3, PACKET_TYPE_DM5, PACKET_TYPE_DH5, PACKET_TYPE_AUX1, PACKET_TYPE_2DH1, PACKET_TYPE_2DH3, PACKET_TYPE_2DH5, PACKET_TYPE_3DH1, PACKET_TYPE_3DH3, PACKET_TYPE_3DH5 }; // Configuration Parameters typedef struct { BqrReportAction report_action; uint32_t quality_event_mask; uint16_t minimum_report_interval_ms; } BqrConfiguration; // Link quality related BQR event typedef struct { // Quality report ID. uint8_t quality_report_id; // Packet type of the connection. uint8_t packet_types; // Connection handle of the connection. uint16_t connection_handle; // Performing Role for the connection. uint8_t connection_role; // Current Transmit Power Level for the connection. This value is the same as // the controller's response to the HCI_Read_Transmit_Power_Level HCI command. int8_t tx_power_level; // Received Signal Strength Indication (RSSI) value for the connection. This // value is an absolute receiver signal strength value. int8_t rssi; // Signal-to-Noise Ratio (SNR) value for the connection. It is the average // SNR of all the channels used by the link currently. uint8_t snr; // Indicates the number of unused channels in AFH_channel_map. uint8_t unused_afh_channel_count; // Indicates the number of the channels which are interfered and quality is // bad but are still selected for AFH. uint8_t afh_select_unideal_channel_count; // Current Link Supervision Timeout Setting. // Unit: N * 0.3125 ms (1 Bluetooth Clock) uint16_t lsto; // Piconet Clock for the specified Connection_Handle. This value is the same // as the controller's response to HCI_Read_Clock HCI command with the // parameter "Which_Clock" of 0x01 (Piconet Clock). // Unit: N * 0.3125 ms (1 Bluetooth Clock) uint32_t connection_piconet_clock; // The count of retransmission. uint32_t retransmission_count; // The count of no RX. uint32_t no_rx_count; // The count of NAK (Negative Acknowledge). uint32_t nak_count; // Timestamp of last TX ACK. // Unit: N * 0.3125 ms (1 Bluetooth Clock) uint32_t last_tx_ack_timestamp; // The count of Flow-off (STOP). uint32_t flow_off_count; // Timestamp of last Flow-on (GO). // Unit: N * 0.3125 ms (1 Bluetooth Clock) uint32_t last_flow_on_timestamp; // Buffer overflow count (how many bytes of TX data are dropped) since the // last event. uint32_t buffer_overflow_bytes; // Buffer underflow count (in byte). uint32_t buffer_underflow_bytes; // For the controller vendor to obtain more vendor specific parameters. uint8_t* vendor_specific_parameter; } BqrLinkQualityEvent; // Log dump related BQR event typedef struct { // Quality report ID. uint8_t quality_report_id; // Connection handle of the connection. uint16_t connection_handle; // For the controller vendor to obtain more vendor specific parameters. uint8_t* vendor_specific_parameter; } BqrLogDumpEvent; // BQR sub-event of Vendor Specific Event class BqrVseSubEvt { public: // Parse the Link Quality related BQR event. // // @param length Total length of all parameters contained in the sub-event. // @param p_param_buf A pointer to the parameters contained in the sub-event. void ParseBqrLinkQualityEvt(uint8_t length, uint8_t* p_param_buf); // Write the LMP/LL message trace to the log file. // // @param fd The File Descriptor of the log file. // @param length Total length of all parameters contained in the sub-event. // @param p_param_buf A pointer to the parameters contained in the sub-event. void WriteLmpLlTraceLogFile(int fd, uint8_t length, uint8_t* p_param_buf); // Write the Bluetooth Multi-profile/Coex scheduling trace to the log file. // // @param fd The File Descriptor of the log file. // @param length Total length of all parameters contained in the sub-event. // @param p_param_buf A pointer to the parameters contained in the sub-event. void WriteBtSchedulingTraceLogFile(int fd, uint8_t length, uint8_t* p_param_buf); // Get a string representation of the Bluetooth Quality event. // // @return a string representation of the Bluetooth Quality event. std::string ToString() const; friend std::ostream& operator<<(std::ostream& os, const BqrVseSubEvt& a) { return os << a.ToString(); } virtual ~BqrVseSubEvt() = default; // Link Quality related BQR event BqrLinkQualityEvent bqr_link_quality_event_ = {}; // Log Dump related BQR event BqrLogDumpEvent bqr_log_dump_event_ = {}; // Local wall clock timestamp of receiving BQR VSE sub-event std::tm tm_timestamp_ = {}; }; // Get a string representation of the Quality Report ID. // // @param quality_report_id The quality report ID to convert. // @return a string representation of the Quality Report ID. std::string QualityReportIdToString(uint8_t quality_report_id); // Get a string representation of the Packet Type. // // @param packet_type The packet type to convert. // @return a string representation of the Packet Type. std::string PacketTypeToString(uint8_t packet_type); // Enable/Disable Bluetooth Quality Report mechanism. // // Which Quality event will be enabled is according to the setting of the // property "persist.bluetooth.bqr.event_mask". // And the minimum time interval of quality event reporting depends on the // setting of property "persist.bluetooth.bqr.min_interval_ms". // // @param is_enable True/False to enable/disable Bluetooth Quality Report // mechanism in the Bluetooth controller. void EnableBtQualityReport(bool is_enable); // Configure Bluetooth Quality Report setting to the Bluetooth controller. // // @param bqr_config The struct of configuration parameters. void ConfigureBqr(const BqrConfiguration& bqr_config); // Callback invoked on completion of vendor specific Bluetooth Quality Report // command. // // @param p_vsc_cmpl_params A pointer to the parameters contained in the vendor // specific command complete event. void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params); // Invoked on completion of Bluetooth Quality Report configuration. Then it will // Register/Unregister for receiving VSE - Bluetooth Quality Report sub-event. // // @param current_evt_mask Indicates current quality event bit mask setting in // the Bluetooth controller. void ConfigureBqrCmpl(uint32_t current_evt_mask); // Categorize the incoming Bluetooth Quality Report. // // @param length Lengths of the quality report sent from the Bluetooth // controller. // @param p_bqr_event A pointer to the BQR VSE sub-event which is sent from the // Bluetooth controller. void CategorizeBqrEvent(uint8_t length, uint8_t* p_bqr_event); // Record a new incoming Link Quality related BQR event in quality event queue. // // @param length Lengths of the Link Quality related BQR event. // @param p_link_quality_event A pointer to the Link Quality related BQR event. void AddLinkQualityEventToQueue(uint8_t length, uint8_t* p_link_quality_event); // Dump the LMP/LL message handshaking with the remote device to a log file. // // @param length Lengths of the LMP/LL message trace event. // @param p_lmp_ll_message_event A pointer to the LMP/LL message trace event. void DumpLmpLlMessage(uint8_t length, uint8_t* p_lmp_ll_message_event); // Open the LMP/LL message trace log file. // // @return a file descriptor of the LMP/LL message trace log file. int OpenLmpLlTraceLogFile(); // Dump the Bluetooth Multi-profile/Coex scheduling information to a log file. // // @param length Lengths of the Bluetooth Multi-profile/Coex scheduling trace // event. // @param p_bt_scheduling_event A pointer to the Bluetooth Multi-profile/Coex // scheduling trace event. void DumpBtScheduling(uint8_t length, uint8_t* p_bt_scheduling_event); // Open the Bluetooth Multi-profile/Coex scheduling trace log file. // // @return a file descriptor of the Bluetooth Multi-profile/Coex scheduling // trace log file. int OpenBtSchedulingTraceLogFile(); // Dump Bluetooth Quality Report information. // // @param fd The file descriptor to use for dumping information. void DebugDump(int fd); } // namespace bqr } // namespace bluetooth #endif // BTIF_BQR_H_