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 #include <bluetooth/log.h>
18 #include <com_android_bluetooth_flags.h>
19 #include <fcntl.h>
20 #ifdef __ANDROID__
21 #include <statslog_bt.h>
22 #endif
23 #include <sys/stat.h>
24 
25 #include <cerrno>
26 #include <cstdint>
27 
28 #include "btif/include/btif_bqr.h"
29 #include "btif/include/btif_common.h"
30 #include "btif/include/btif_storage.h"
31 #include "btif/include/core_callbacks.h"
32 #include "btif/include/stack_manager_t.h"
33 #include "common/leaky_bonded_queue.h"
34 #include "common/postable_context.h"
35 #include "common/time_util.h"
36 #include "hardware/bluetooth.h"
37 #include "hci/hci_interface.h"
38 #include "hci/hci_packets.h"
39 #include "internal_include/bt_trace.h"
40 #include "main/shim/entry.h"
41 #include "osi/include/properties.h"
42 #include "packet/raw_builder.h"
43 #include "stack/btm/btm_dev.h"
44 #include "stack/include/bt_types.h"
45 #include "stack/include/btm_ble_api.h"
46 #include "stack/include/btm_client_interface.h"
47 #include "types/raw_address.h"
48 
49 namespace bluetooth {
50 namespace bqr {
51 
52 using bluetooth::common::LeakyBondedQueue;
53 using std::chrono::system_clock;
54 
55 // The instance of BQR event queue
56 static LeakyBondedQueue<BqrVseSubEvt> kpBqrEventQueue{kBqrEventQueueSize};
57 
58 static uint16_t vendor_cap_supported_version;
59 
60 // File Descriptor of LMP/LL message trace log
61 static int LmpLlMessageTraceLogFd = INVALID_FD;
62 // File Descriptor of Bluetooth Multi-profile/Coex scheduling trace log
63 static int BtSchedulingTraceLogFd = INVALID_FD;
64 // Counter of LMP/LL message trace
65 static uint16_t LmpLlMessageTraceCounter = 0;
66 // Counter of Bluetooth Multi-profile/Coex scheduling trace
67 static uint16_t BtSchedulingTraceCounter = 0;
68 
69 class BluetoothQualityReportInterfaceImpl;
70 std::unique_ptr<BluetoothQualityReportInterface> bluetoothQualityReportInstance;
71 
72 namespace {
73 static std::recursive_mutex life_cycle_guard_;
74 static common::PostableContext* to_bind_ = nullptr;
75 }
76 
ParseBqrLinkQualityEvt(uint8_t length,const uint8_t * p_param_buf)77 void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length, const uint8_t* p_param_buf) {
78   if (length < kLinkQualityParamTotalLen) {
79     log::fatal(
80             "Parameter total length: {} is abnormal. It shall be not shorter than: "
81             "{}",
82             length, kLinkQualityParamTotalLen);
83     return;
84   }
85 
86   STREAM_TO_UINT8(bqr_link_quality_event_.quality_report_id, p_param_buf);
87   STREAM_TO_UINT8(bqr_link_quality_event_.packet_types, p_param_buf);
88   STREAM_TO_UINT16(bqr_link_quality_event_.connection_handle, p_param_buf);
89   STREAM_TO_UINT8(bqr_link_quality_event_.connection_role, p_param_buf);
90   STREAM_TO_INT8(bqr_link_quality_event_.tx_power_level, p_param_buf);
91   STREAM_TO_INT8(bqr_link_quality_event_.rssi, p_param_buf);
92   STREAM_TO_UINT8(bqr_link_quality_event_.snr, p_param_buf);
93   STREAM_TO_UINT8(bqr_link_quality_event_.unused_afh_channel_count, p_param_buf);
94   STREAM_TO_UINT8(bqr_link_quality_event_.afh_select_unideal_channel_count, p_param_buf);
95   STREAM_TO_UINT16(bqr_link_quality_event_.lsto, p_param_buf);
96   STREAM_TO_UINT32(bqr_link_quality_event_.connection_piconet_clock, p_param_buf);
97   STREAM_TO_UINT32(bqr_link_quality_event_.retransmission_count, p_param_buf);
98   STREAM_TO_UINT32(bqr_link_quality_event_.no_rx_count, p_param_buf);
99   STREAM_TO_UINT32(bqr_link_quality_event_.nak_count, p_param_buf);
100   STREAM_TO_UINT32(bqr_link_quality_event_.last_tx_ack_timestamp, p_param_buf);
101   STREAM_TO_UINT32(bqr_link_quality_event_.flow_off_count, p_param_buf);
102   STREAM_TO_UINT32(bqr_link_quality_event_.last_flow_on_timestamp, p_param_buf);
103   STREAM_TO_UINT32(bqr_link_quality_event_.buffer_overflow_bytes, p_param_buf);
104   STREAM_TO_UINT32(bqr_link_quality_event_.buffer_underflow_bytes, p_param_buf);
105 
106   if (vendor_cap_supported_version >= kBqrVersion5_0) {
107     if (length <
108         kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen + kVersion5_0ParamsTotalLen) {
109       log::warn(
110               "Parameter total length: {} is abnormal. "
111               "vendor_cap_supported_version: {}  (>= kBqrVersion5_0={}), It should "
112               "not be shorter than: {}",
113               length, vendor_cap_supported_version, kBqrVersion5_0,
114               kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen + kVersion5_0ParamsTotalLen);
115     } else {
116       STREAM_TO_BDADDR(bqr_link_quality_event_.bdaddr, p_param_buf);
117       STREAM_TO_UINT8(bqr_link_quality_event_.cal_failed_item_count, p_param_buf);
118     }
119   }
120 
121   if (vendor_cap_supported_version >= kBqrIsoVersion) {
122     if (length < kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen) {
123       log::warn(
124               "Parameter total length: {} is abnormal. "
125               "vendor_cap_supported_version: {}  (>= kBqrIsoVersion={}), It should "
126               "not be shorter than: {}",
127               length, vendor_cap_supported_version, kBqrIsoVersion,
128               kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen);
129     } else {
130       STREAM_TO_UINT32(bqr_link_quality_event_.tx_total_packets, p_param_buf);
131       STREAM_TO_UINT32(bqr_link_quality_event_.tx_unacked_packets, p_param_buf);
132       STREAM_TO_UINT32(bqr_link_quality_event_.tx_flushed_packets, p_param_buf);
133       STREAM_TO_UINT32(bqr_link_quality_event_.tx_last_subevent_packets, p_param_buf);
134       STREAM_TO_UINT32(bqr_link_quality_event_.crc_error_packets, p_param_buf);
135       STREAM_TO_UINT32(bqr_link_quality_event_.rx_duplicate_packets, p_param_buf);
136     }
137   }
138 
139   if (vendor_cap_supported_version >= kBqrVersion6_0) {
140     if (length < kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen +
141                          kVersion5_0ParamsTotalLen + kVersion6_0ParamsTotalLen) {
142       log::warn(
143               "Parameter total length: {} is abnormal. "
144               "vendor_cap_supported_version: {}  (>= kBqrVersion6_0={}), It should "
145               "not be shorter than: {}",
146               length, vendor_cap_supported_version, kBqrVersion6_0,
147               kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen + kVersion5_0ParamsTotalLen +
148                       kVersion6_0ParamsTotalLen);
149     } else {
150       STREAM_TO_UINT32(bqr_link_quality_event_.rx_unreceived_packets, p_param_buf);
151       STREAM_TO_UINT16(bqr_link_quality_event_.coex_info_mask, p_param_buf);
152     }
153   }
154 
155   const auto now = system_clock::to_time_t(system_clock::now());
156   localtime_r(&now, &tm_timestamp_);
157 }
158 
ParseBqrEnergyMonitorEvt(uint8_t length,const uint8_t * p_param_buf)159 bool BqrVseSubEvt::ParseBqrEnergyMonitorEvt(uint8_t length, const uint8_t* p_param_buf) {
160   if (length < kEnergyMonitorParamTotalLen) {
161     log::fatal(
162             "Parameter total length: {} is abnormal. It shall be not shorter than: "
163             "{}",
164             length, kEnergyMonitorParamTotalLen);
165     return false;
166   }
167 
168   STREAM_TO_UINT8(bqr_energy_monitor_event_.quality_report_id, p_param_buf);
169   bqr_link_quality_event_.quality_report_id = bqr_energy_monitor_event_.quality_report_id;
170   STREAM_TO_UINT16(bqr_energy_monitor_event_.avg_current_consume, p_param_buf);
171   STREAM_TO_UINT32(bqr_energy_monitor_event_.idle_total_time, p_param_buf);
172   STREAM_TO_UINT32(bqr_energy_monitor_event_.idle_state_enter_count, p_param_buf);
173   STREAM_TO_UINT32(bqr_energy_monitor_event_.active_total_time, p_param_buf);
174   STREAM_TO_UINT32(bqr_energy_monitor_event_.active_state_enter_count, p_param_buf);
175   STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_tx_total_time, p_param_buf);
176   STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_tx_state_enter_count, p_param_buf);
177   STREAM_TO_UINT8(bqr_energy_monitor_event_.bredr_tx_avg_power_lv, p_param_buf);
178   STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_rx_total_time, p_param_buf);
179   STREAM_TO_UINT32(bqr_energy_monitor_event_.bredr_rx_state_enter_count, p_param_buf);
180   STREAM_TO_UINT32(bqr_energy_monitor_event_.le_tx_total_time, p_param_buf);
181   STREAM_TO_UINT32(bqr_energy_monitor_event_.le_tx_state_enter_count, p_param_buf);
182   STREAM_TO_UINT8(bqr_energy_monitor_event_.le_tx_avg_power_lv, p_param_buf);
183   STREAM_TO_UINT32(bqr_energy_monitor_event_.le_rx_total_time, p_param_buf);
184   STREAM_TO_UINT32(bqr_energy_monitor_event_.le_rx_state_enter_count, p_param_buf);
185   STREAM_TO_UINT32(bqr_energy_monitor_event_.tm_period, p_param_buf);
186   STREAM_TO_UINT32(bqr_energy_monitor_event_.rx_active_one_chain_time, p_param_buf);
187   STREAM_TO_UINT32(bqr_energy_monitor_event_.rx_active_two_chain_time, p_param_buf);
188   STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_ipa_active_one_chain_time, p_param_buf);
189   STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_ipa_active_two_chain_time, p_param_buf);
190   STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_epa_active_one_chain_time, p_param_buf);
191   STREAM_TO_UINT32(bqr_energy_monitor_event_.tx_epa_active_two_chain_time, p_param_buf);
192   return true;
193 }
194 
ParseBqrRFStatsEvt(uint8_t length,const uint8_t * p_param_buf)195 bool BqrVseSubEvt::ParseBqrRFStatsEvt(uint8_t length, const uint8_t* p_param_buf) {
196   if (length < kRFStatsParamTotalLen) {
197     log::fatal(
198             "Parameter total length: {} is abnormal. It shall be not shorter than: "
199             "{}",
200             length, kRFStatsParamTotalLen);
201     return false;
202   }
203 
204   STREAM_TO_UINT8(bqr_rf_stats_event_.quality_report_id, p_param_buf);
205   bqr_link_quality_event_.quality_report_id = bqr_rf_stats_event_.quality_report_id;
206   STREAM_TO_UINT8(bqr_rf_stats_event_.ext_info, p_param_buf);
207   STREAM_TO_UINT32(bqr_rf_stats_event_.tm_period, p_param_buf);
208   STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_ipa_bf, p_param_buf);
209   STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_epa_bf, p_param_buf);
210   STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_ipa_div, p_param_buf);
211   STREAM_TO_UINT32(bqr_rf_stats_event_.tx_pw_epa_div, p_param_buf);
212 
213   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_50, p_param_buf);
214   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_50_55, p_param_buf);
215   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_55_60, p_param_buf);
216   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_60_65, p_param_buf);
217   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_65_70, p_param_buf);
218   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_70_75, p_param_buf);
219   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_75_80, p_param_buf);
220   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_80_85, p_param_buf);
221   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_85_90, p_param_buf);
222   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_ch_90, p_param_buf);
223 
224   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_2_down, p_param_buf);
225   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_2_5, p_param_buf);
226   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_5_8, p_param_buf);
227   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_8_11, p_param_buf);
228   STREAM_TO_UINT32(bqr_rf_stats_event_.rssi_delta_11_up, p_param_buf);
229   return true;
230 }
231 
WriteLmpLlTraceLogFile(int fd,uint8_t length,const uint8_t * p_param_buf)232 void BqrVseSubEvt::WriteLmpLlTraceLogFile(int fd, uint8_t length, const uint8_t* p_param_buf) {
233   const auto now = system_clock::to_time_t(system_clock::now());
234   localtime_r(&now, &tm_timestamp_);
235 
236   STREAM_TO_UINT8(bqr_log_dump_event_.quality_report_id, p_param_buf);
237   STREAM_TO_UINT16(bqr_log_dump_event_.connection_handle, p_param_buf);
238   length -= kLogDumpParamTotalLen;
239   bqr_log_dump_event_.vendor_specific_parameter = p_param_buf;
240 
241   std::stringstream ss_log;
242   ss_log << "\n"
243          << std::put_time(&tm_timestamp_, "%m-%d %H:%M:%S ")
244          << "Handle: " << loghex(bqr_log_dump_event_.connection_handle) << " VSP: ";
245 
246   TEMP_FAILURE_RETRY(write(fd, ss_log.str().c_str(), ss_log.str().size()));
247   TEMP_FAILURE_RETRY(write(fd, bqr_log_dump_event_.vendor_specific_parameter, length));
248   LmpLlMessageTraceCounter++;
249 }
250 
WriteBtSchedulingTraceLogFile(int fd,uint8_t length,const uint8_t * p_param_buf)251 void BqrVseSubEvt::WriteBtSchedulingTraceLogFile(int fd, uint8_t length,
252                                                  const uint8_t* p_param_buf) {
253   const auto now = system_clock::to_time_t(system_clock::now());
254   localtime_r(&now, &tm_timestamp_);
255 
256   STREAM_TO_UINT8(bqr_log_dump_event_.quality_report_id, p_param_buf);
257   STREAM_TO_UINT16(bqr_log_dump_event_.connection_handle, p_param_buf);
258   length -= kLogDumpParamTotalLen;
259   bqr_log_dump_event_.vendor_specific_parameter = p_param_buf;
260 
261   std::stringstream ss_log;
262   ss_log << "\n"
263          << std::put_time(&tm_timestamp_, "%m-%d %H:%M:%S ")
264          << "Handle: " << loghex(bqr_log_dump_event_.connection_handle) << " VSP: ";
265 
266   TEMP_FAILURE_RETRY(write(fd, ss_log.str().c_str(), ss_log.str().size()));
267   TEMP_FAILURE_RETRY(write(fd, bqr_log_dump_event_.vendor_specific_parameter, length));
268   BtSchedulingTraceCounter++;
269 }
270 
271 static std::string QualityReportIdToString(uint8_t quality_report_id);
272 static std::string PacketTypeToString(uint8_t packet_type);
273 
ToString() const274 std::string BqrVseSubEvt::ToString() const {
275   std::stringstream ss;
276   ss << QualityReportIdToString(bqr_link_quality_event_.quality_report_id)
277      << ", Handle: " << loghex(bqr_link_quality_event_.connection_handle) << ", "
278      << PacketTypeToString(bqr_link_quality_event_.packet_types) << ", "
279      << ((bqr_link_quality_event_.connection_role == 0) ? "Central" : "Peripheral ")
280      << ", PwLv: " << std::to_string(bqr_link_quality_event_.tx_power_level)
281      << ", RSSI: " << std::to_string(bqr_link_quality_event_.rssi)
282      << ", SNR: " << std::to_string(bqr_link_quality_event_.snr)
283      << ", UnusedCh: " << std::to_string(bqr_link_quality_event_.unused_afh_channel_count)
284      << ", UnidealCh: " << std::to_string(bqr_link_quality_event_.afh_select_unideal_channel_count)
285      << ", ReTx: " << std::to_string(bqr_link_quality_event_.retransmission_count)
286      << ", NoRX: " << std::to_string(bqr_link_quality_event_.no_rx_count)
287      << ", NAK: " << std::to_string(bqr_link_quality_event_.nak_count)
288      << ", FlowOff: " << std::to_string(bqr_link_quality_event_.flow_off_count)
289      << ", OverFlow: " << std::to_string(bqr_link_quality_event_.buffer_overflow_bytes)
290      << ", UndFlow: " << std::to_string(bqr_link_quality_event_.buffer_underflow_bytes);
291   if (vendor_cap_supported_version >= kBqrVersion5_0) {
292     ss << ", RemoteDevAddr: " << bqr_link_quality_event_.bdaddr.ToColonSepHexString()
293        << ", CalFailedItems: " << std::to_string(bqr_link_quality_event_.cal_failed_item_count);
294   }
295   if (vendor_cap_supported_version >= kBqrIsoVersion) {
296     ss << ", TxTotal: " << std::to_string(bqr_link_quality_event_.tx_total_packets)
297        << ", TxUnAcked: " << std::to_string(bqr_link_quality_event_.tx_unacked_packets)
298        << ", TxFlushed: " << std::to_string(bqr_link_quality_event_.tx_flushed_packets)
299        << ", TxLastSubEvent: " << std::to_string(bqr_link_quality_event_.tx_last_subevent_packets)
300        << ", CRCError: " << std::to_string(bqr_link_quality_event_.crc_error_packets)
301        << ", RxDuplicate: " << std::to_string(bqr_link_quality_event_.rx_duplicate_packets);
302   }
303   if (QUALITY_REPORT_ID_ENERGY_MONITOR == bqr_link_quality_event_.quality_report_id) {
304     ss << ", TotalTime: " << std::to_string(bqr_energy_monitor_event_.tm_period)
305        << ", ActiveTime: " << std::to_string(bqr_energy_monitor_event_.active_total_time)
306        << ", IdleTime: " << std::to_string(bqr_energy_monitor_event_.idle_total_time)
307        << ", AvgCurrent: " << std::to_string(bqr_energy_monitor_event_.avg_current_consume);
308   }
309   if (QUALITY_REPORT_ID_RF_STATS == bqr_link_quality_event_.quality_report_id) {
310     ss << ", TotalTime: " << std::to_string(bqr_rf_stats_event_.tm_period)
311        << ", TxiPABF: " << std::to_string(bqr_rf_stats_event_.tx_pw_ipa_bf)
312        << ", TxePABF: " << std::to_string(bqr_rf_stats_event_.tx_pw_epa_bf)
313        << ", TxiPADiv: " << std::to_string(bqr_rf_stats_event_.tx_pw_ipa_div)
314        << ", TxePADiv: " << std::to_string(bqr_rf_stats_event_.tx_pw_epa_div);
315   }
316   return ss.str();
317 }
318 
319 // Get a string representation of the Quality Report ID.
320 //
321 // @param quality_report_id The quality report ID to convert.
322 // @return a string representation of the Quality Report ID.
QualityReportIdToString(uint8_t quality_report_id)323 static std::string QualityReportIdToString(uint8_t quality_report_id) {
324   switch (quality_report_id) {
325     case QUALITY_REPORT_ID_MONITOR_MODE:
326       return "Monitoring";
327     case QUALITY_REPORT_ID_APPROACH_LSTO:
328       return "Approach LSTO";
329     case QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY:
330       return "A2DP Choppy";
331     case QUALITY_REPORT_ID_SCO_VOICE_CHOPPY:
332       return "SCO Choppy";
333     case QUALITY_REPORT_ID_LE_AUDIO_CHOPPY:
334       return "LE Audio Choppy";
335     case QUALITY_REPORT_ID_CONNECT_FAIL:
336       return "Connect Fail";
337     case QUALITY_REPORT_ID_ENERGY_MONITOR:
338       return "Energy Monitor";
339     case QUALITY_REPORT_ID_RF_STATS:
340       return "RF Stats";
341     default:
342       return "Invalid";
343   }
344 }
345 
346 // Get a string representation of the Packet Type.
347 //
348 // @param packet_type The packet type to convert.
349 // @return a string representation of the Packet Type.
PacketTypeToString(uint8_t packet_type)350 static std::string PacketTypeToString(uint8_t packet_type) {
351   switch (packet_type) {
352     case PACKET_TYPE_ID:
353       return "ID";
354     case PACKET_TYPE_NULL:
355       return "NULL";
356     case PACKET_TYPE_POLL:
357       return "POLL";
358     case PACKET_TYPE_FHS:
359       return "FHS";
360     case PACKET_TYPE_HV1:
361       return "HV1";
362     case PACKET_TYPE_HV2:
363       return "HV2";
364     case PACKET_TYPE_HV3:
365       return "HV3";
366     case PACKET_TYPE_DV:
367       return "DV";
368     case PACKET_TYPE_EV3:
369       return "EV3";
370     case PACKET_TYPE_EV4:
371       return "EV4";
372     case PACKET_TYPE_EV5:
373       return "EV5";
374     case PACKET_TYPE_2EV3:
375       return "2EV3";
376     case PACKET_TYPE_2EV5:
377       return "2EV5";
378     case PACKET_TYPE_3EV3:
379       return "3EV3";
380     case PACKET_TYPE_3EV5:
381       return "3EV5";
382     case PACKET_TYPE_DM1:
383       return "DM1";
384     case PACKET_TYPE_DH1:
385       return "DH1";
386     case PACKET_TYPE_DM3:
387       return "DM3";
388     case PACKET_TYPE_DH3:
389       return "DH3";
390     case PACKET_TYPE_DM5:
391       return "DM5";
392     case PACKET_TYPE_DH5:
393       return "DH5";
394     case PACKET_TYPE_AUX1:
395       return "AUX1";
396     case PACKET_TYPE_2DH1:
397       return "2DH1";
398     case PACKET_TYPE_2DH3:
399       return "2DH3";
400     case PACKET_TYPE_2DH5:
401       return "2DH5";
402     case PACKET_TYPE_3DH1:
403       return "3DH1";
404     case PACKET_TYPE_3DH3:
405       return "3DH3";
406     case PACKET_TYPE_3DH5:
407       return "3DH5";
408     case PACKET_TYPE_ISO:
409       return "ISO";
410     default:
411       return "UnKnown ";
412   }
413 }
414 
415 void register_vse();
416 void unregister_vse();
417 
418 static void ConfigureBqr(const BqrConfiguration& bqr_config);
419 
EnableDisableBtQualityReport(bool enable)420 static void EnableDisableBtQualityReport(bool enable) {
421   char bqr_prop_evtmask[PROPERTY_VALUE_MAX] = {0};
422   char bqr_prop_interval_ms[PROPERTY_VALUE_MAX] = {0};
423   char bqr_prop_vnd_quality_mask[PROPERTY_VALUE_MAX] = {0};
424   char bqr_prop_vnd_trace_mask[PROPERTY_VALUE_MAX] = {0};
425   char bqr_prop_interval_multiple[PROPERTY_VALUE_MAX] = {0};
426   osi_property_get(kpPropertyEventMask, bqr_prop_evtmask, "");
427   osi_property_get(kpPropertyMinReportIntervalMs, bqr_prop_interval_ms, "");
428   osi_property_get(kpPropertyVndQualityMask, bqr_prop_vnd_quality_mask, "");
429   osi_property_get(kpPropertyVndTraceMask, bqr_prop_vnd_trace_mask, "");
430   osi_property_get(kpPropertyIntervalMultiple, bqr_prop_interval_multiple, "");
431 
432   if (strlen(bqr_prop_evtmask) == 0 || strlen(bqr_prop_interval_ms) == 0) {
433     log::warn(
434             "Bluetooth Quality Report is disabled. bqr_prop_evtmask: {}, "
435             "bqr_prop_interval_ms: {}",
436             bqr_prop_evtmask, bqr_prop_interval_ms);
437     return;
438   }
439 
440   BqrConfiguration bqr_config = {};
441 
442   if (enable) {
443     bqr_config.report_action = REPORT_ACTION_ADD;
444     bqr_config.quality_event_mask = static_cast<uint32_t>(atoi(bqr_prop_evtmask));
445     bqr_config.minimum_report_interval_ms = static_cast<uint16_t>(atoi(bqr_prop_interval_ms));
446     bqr_config.vnd_quality_mask = static_cast<uint32_t>(atoi(bqr_prop_vnd_quality_mask));
447     bqr_config.vnd_trace_mask = static_cast<uint32_t>(atoi(bqr_prop_vnd_trace_mask));
448     bqr_config.report_interval_multiple = static_cast<uint32_t>(atoi(bqr_prop_interval_multiple));
449     register_vse();
450     kpBqrEventQueue.Clear();
451   } else {
452     bqr_config.report_action = REPORT_ACTION_CLEAR;
453     bqr_config.quality_event_mask = kQualityEventMaskAllOff;
454     bqr_config.minimum_report_interval_ms = kMinReportIntervalNoLimit;
455     bqr_config.vnd_quality_mask = 0;
456     bqr_config.vnd_trace_mask = 0;
457     bqr_config.report_interval_multiple = 0;
458     unregister_vse();
459   }
460 
461   tBTM_BLE_VSC_CB cmn_vsc_cb;
462   BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
463   vendor_cap_supported_version = cmn_vsc_cb.version_supported;
464 
465   log::info("Event Mask: 0x{:x}, Interval: {}, Multiple: {}, vendor_cap_supported_version: {}",
466             bqr_config.quality_event_mask, bqr_config.minimum_report_interval_ms,
467             bqr_config.report_interval_multiple, vendor_cap_supported_version);
468   ConfigureBqr(bqr_config);
469 }
470 
EnableBtQualityReport(common::PostableContext * to_bind)471 void EnableBtQualityReport(common::PostableContext* to_bind) {
472   log::info("");
473   to_bind_ = to_bind;
474   EnableDisableBtQualityReport(true);
475 }
476 
DisableBtQualityReport()477 void DisableBtQualityReport() {
478   log::info("");
479   std::unique_lock<std::recursive_mutex> lock(life_cycle_guard_);
480   if (to_bind_ == nullptr) {
481     log::warn("Skipping second call (Lifecycle issue).");
482     return;
483   }
484   EnableDisableBtQualityReport(false);
485   to_bind_ = nullptr;
486 }
487 
488 static void BqrVscCompleteCallback(hci::CommandCompleteView complete);
489 
490 // Configure Bluetooth Quality Report setting to the Bluetooth controller.
491 //
492 // @param bqr_config The struct of configuration parameters.
ConfigureBqr(const BqrConfiguration & bqr_config)493 void ConfigureBqr(const BqrConfiguration& bqr_config) {
494   if (vendor_cap_supported_version >= kBqrVersion6_0) {
495     if (bqr_config.report_action > REPORT_ACTION_QUERY ||
496         bqr_config.quality_event_mask > kQualityEventMaskAll ||
497         bqr_config.minimum_report_interval_ms > kMinReportIntervalMaxMs) {
498       log::fatal(
499               "Invalid Parameter, Action: {}, Mask: 0x{:x}, Interval: {} Multiple: "
500               "{}",
501               bqr_config.report_action, bqr_config.quality_event_mask,
502               bqr_config.minimum_report_interval_ms, bqr_config.report_interval_multiple);
503       return;
504     } else {
505       if (bqr_config.report_action > REPORT_ACTION_CLEAR ||
506           bqr_config.quality_event_mask > kQualityEventMaskAll ||
507           bqr_config.minimum_report_interval_ms > kMinReportIntervalMaxMs) {
508         log::fatal("Invalid Parameter, Action: {}, Mask: 0x{:x}, Interval: {}",
509                    bqr_config.report_action, bqr_config.quality_event_mask,
510                    bqr_config.minimum_report_interval_ms);
511         return;
512       }
513     }
514   }
515 
516   log::info("Action: 0x{:x}, Mask: 0x{:x}, Interval: {} Multiple: {}",
517             static_cast<uint8_t>(bqr_config.report_action), bqr_config.quality_event_mask,
518             bqr_config.minimum_report_interval_ms, bqr_config.report_interval_multiple);
519 
520   auto payload = std::make_unique<packet::RawBuilder>();
521   payload->AddOctets1(bqr_config.report_action);
522   payload->AddOctets4(bqr_config.quality_event_mask);
523   payload->AddOctets2(bqr_config.minimum_report_interval_ms);
524   if (vendor_cap_supported_version >= kBqrVndLogVersion) {
525     payload->AddOctets4(bqr_config.vnd_quality_mask);
526     payload->AddOctets4(bqr_config.vnd_trace_mask);
527   }
528   if (vendor_cap_supported_version >= kBqrVersion6_0) {
529     payload->AddOctets4(bqr_config.report_interval_multiple);
530   }
531 
532   shim::GetHciLayer()->EnqueueCommand(
533           hci::CommandBuilder::Create(hci::OpCode::CONTROLLER_BQR, std::move(payload)),
534           to_bind_->BindOnce(BqrVscCompleteCallback));
535 }
536 
537 static void ConfigureBqrCmpl(uint32_t current_evt_mask);
538 
539 // Callback invoked on completion of vendor specific Bluetooth Quality Report
540 // command.
541 //
542 // @param p_vsc_cmpl_params A pointer to the parameters contained in the vendor
543 //   specific command complete event.
BqrVscCompleteCallback(hci::CommandCompleteView complete)544 static void BqrVscCompleteCallback(hci::CommandCompleteView complete) {
545   std::vector<uint8_t> payload_vector{complete.GetPayload().begin(), complete.GetPayload().end()};
546   tBTM_VSC_CMPL vsc_cmpl_params = {.opcode = static_cast<uint16_t>(complete.GetCommandOpCode()),
547                                    .param_len = static_cast<uint16_t>(payload_vector.size()),
548                                    .p_param_buf = payload_vector.data()};
549   tBTM_VSC_CMPL* p_vsc_cmpl_params = &vsc_cmpl_params;
550 
551   if (p_vsc_cmpl_params->param_len < 1) {
552     log::error("The length of returned parameters is less than 1");
553     return;
554   }
555 
556   uint8_t* p_event_param_buf = p_vsc_cmpl_params->p_param_buf;
557   uint8_t status = 0xff;
558   uint8_t command_complete_param_len = 5;
559   uint32_t current_vnd_quality_mask = 0;
560   uint32_t current_vnd_trace_mask = 0;
561   uint32_t bqr_report_interval = 0;
562   // [Return Parameter]         | [Size]   | [Purpose]
563   // Status                     | 1 octet  | Command complete status
564   // Current_Quality_Event_Mask | 4 octets | Indicates current bit mask setting
565   // Vendor_Specific_Quality_Mask | 4 octets | vendor quality bit mask setting
566   // Vendor_Specific_Trace_Mask | 4 octets | vendor trace bit mask setting
567   // bqr_report_interval | 4 octets | report interval from controller setting
568 
569   STREAM_TO_UINT8(status, p_event_param_buf);
570   if (status != HCI_SUCCESS) {
571     log::error("Fail to configure BQR. status: 0x{:x}", status);
572     return;
573   }
574 
575   {
576     // `DisableBtQualityReport()` set `to_bind_` at nullptr, after sending the command that clear
577     // reporting. When disabled, we don't want to continue and use nulled `to_bind_` (b/365653608).
578     std::unique_lock<std::recursive_mutex> lock(life_cycle_guard_);
579     if (to_bind_ == nullptr) {
580       log::info("Disabled");
581       return;
582     }
583   }
584 
585   if (vendor_cap_supported_version >= kBqrVndLogVersion) {
586     command_complete_param_len = 13;
587   }
588 
589   if (vendor_cap_supported_version >= kBqrVersion6_0) {
590     command_complete_param_len = 17;
591   }
592 
593   if (p_vsc_cmpl_params->param_len != command_complete_param_len) {
594     log::fatal("The length of returned parameters is incorrect: {}", p_vsc_cmpl_params->param_len);
595     return;
596   }
597 
598   uint32_t current_quality_event_mask = kQualityEventMaskAllOff;
599   STREAM_TO_UINT32(current_quality_event_mask, p_event_param_buf);
600 
601   if (vendor_cap_supported_version >= kBqrVndLogVersion) {
602     STREAM_TO_UINT32(current_vnd_quality_mask, p_event_param_buf);
603     STREAM_TO_UINT32(current_vnd_trace_mask, p_event_param_buf);
604   }
605 
606   if (vendor_cap_supported_version >= kBqrVersion6_0) {
607     STREAM_TO_UINT32(bqr_report_interval, p_event_param_buf);
608   }
609 
610   log::info(
611           "current event mask: 0x{:x}, vendor quality: 0x{:x}, vendor trace: "
612           "0x{:x}, report interval: 0x{:x}",
613           current_quality_event_mask, current_vnd_quality_mask, current_vnd_trace_mask,
614           bqr_report_interval);
615 
616   ConfigureBqrCmpl(current_quality_event_mask);
617 }
618 
ConfigBqrA2dpScoThreshold()619 static void ConfigBqrA2dpScoThreshold() {
620   uint8_t sub_opcode = 0x16;
621   uint16_t a2dp_choppy_threshold = 0;
622   uint16_t sco_choppy_threshold = 0;
623 
624   char bqr_prop_threshold[PROPERTY_VALUE_MAX] = {0};
625   osi_property_get(kpPropertyChoppyThreshold, bqr_prop_threshold, "");
626 
627   sscanf(bqr_prop_threshold, "%hu,%hu", &a2dp_choppy_threshold, &sco_choppy_threshold);
628 
629   log::info("a2dp_choppy_threshold: {}, sco_choppy_threshold: {}", a2dp_choppy_threshold,
630             sco_choppy_threshold);
631 
632   auto payload = std::make_unique<packet::RawBuilder>();
633   payload->AddOctets1(sub_opcode);
634 
635   // A2dp glitch ID
636   payload->AddOctets1(QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY);
637   // A2dp glitch config data length
638   payload->AddOctets1(2);
639   // A2dp glitch threshold
640   payload->AddOctets2(a2dp_choppy_threshold == 0 ? 1 : a2dp_choppy_threshold);
641 
642   // Sco glitch ID
643   payload->AddOctets1(QUALITY_REPORT_ID_SCO_VOICE_CHOPPY);
644   // Sco glitch config data length
645   payload->AddOctets1(2);
646   // Sco glitch threshold
647   payload->AddOctets2(sco_choppy_threshold == 0 ? 1 : sco_choppy_threshold);
648 
649   shim::GetHciLayer()->EnqueueCommand(
650           hci::CommandBuilder::Create(static_cast<hci::OpCode>(HCI_VS_HOST_LOG_OPCODE),
651                                       std::move(payload)),
652           to_bind_->BindOnce([](hci::CommandCompleteView) {}));
653 }
654 
655 // Invoked on completion of Bluetooth Quality Report configuration. Then it will
656 // Register/Unregister for receiving VSE - Bluetooth Quality Report sub-event.
657 //
658 // @param current_evt_mask Indicates current quality event bit mask setting in
659 //   the Bluetooth controller.
ConfigureBqrCmpl(uint32_t current_evt_mask)660 static void ConfigureBqrCmpl(uint32_t current_evt_mask) {
661   log::info("current_evt_mask: 0x{:x}", current_evt_mask);
662 
663   if (current_evt_mask > kQualityEventMaskAllOff) {
664     ConfigBqrA2dpScoThreshold();
665   }
666 
667   if (LmpLlMessageTraceLogFd != INVALID_FD &&
668       (current_evt_mask & kQualityEventMaskLmpMessageTrace) == 0) {
669     log::info("Closing LMP/LL log file.");
670     close(LmpLlMessageTraceLogFd);
671     LmpLlMessageTraceLogFd = INVALID_FD;
672   }
673   if (BtSchedulingTraceLogFd != INVALID_FD &&
674       (current_evt_mask & kQualityEventMaskBtSchedulingTrace) == 0) {
675     log::info("Closing Scheduling log file.");
676     close(BtSchedulingTraceLogFd);
677     BtSchedulingTraceLogFd = INVALID_FD;
678   }
679 }
680 
681 static void AddLinkQualityEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
682 static void AddEnergyMonitorEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
683 static void AddRFStatsEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
684 static void AddLinkQualityEventToQueue(uint8_t length, const uint8_t* p_link_quality_event);
685 // Categorize the incoming Bluetooth Quality Report.
686 //
687 // @param length Lengths of the quality report sent from the Bluetooth
688 //   controller.
689 // @param p_bqr_event A pointer to the BQR VSE sub-event which is sent from the
690 //   Bluetooth controller.
CategorizeBqrEvent(uint8_t length,const uint8_t * p_bqr_event)691 static void CategorizeBqrEvent(uint8_t length, const uint8_t* p_bqr_event) {
692   if (length == 0) {
693     log::warn("Lengths of all of the parameters are zero.");
694     return;
695   }
696 
697   uint8_t quality_report_id = p_bqr_event[0];
698   switch (quality_report_id) {
699     case QUALITY_REPORT_ID_MONITOR_MODE:
700     case QUALITY_REPORT_ID_APPROACH_LSTO:
701     case QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY:
702     case QUALITY_REPORT_ID_SCO_VOICE_CHOPPY:
703     case QUALITY_REPORT_ID_LE_AUDIO_CHOPPY:
704     case QUALITY_REPORT_ID_CONNECT_FAIL:
705       if (length < kLinkQualityParamTotalLen) {
706         log::fatal(
707                 "Parameter total length: {} is abnormal. It shall be not shorter "
708                 "than: {}",
709                 length, kLinkQualityParamTotalLen);
710         return;
711       }
712 
713       AddLinkQualityEventToQueue(length, p_bqr_event);
714       break;
715 
716     // The Root Inflammation and Log Dump related event should be handled and
717     // intercepted already.
718     case QUALITY_REPORT_ID_VENDOR_SPECIFIC_QUALITY:
719     case QUALITY_REPORT_ID_ROOT_INFLAMMATION:
720     case QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE:
721     case QUALITY_REPORT_ID_BT_SCHEDULING_TRACE:
722     case QUALITY_REPORT_ID_CONTROLLER_DBG_INFO:
723     case QUALITY_REPORT_ID_VENDOR_SPECIFIC_TRACE:
724       log::warn("Unexpected ID: 0x{:x}", quality_report_id);
725       break;
726 
727     case QUALITY_REPORT_ID_ENERGY_MONITOR:
728       if (length < kEnergyMonitorParamTotalLen) {
729         log::fatal(
730                 "Parameter total length: {} is abnormal. It shall be not shorter "
731                 "than: {}",
732                 length, kEnergyMonitorParamTotalLen);
733         return;
734       }
735 
736       if (com::android::bluetooth::flags::support_bluetooth_quality_report_v6()) {
737         AddEnergyMonitorEventToQueue(length, p_bqr_event);
738       }
739       break;
740 
741     case QUALITY_REPORT_ID_RF_STATS:
742       if (length < kRFStatsParamTotalLen) {
743         log::fatal(
744                 "Parameter total length: {} is abnormal. It shall be not shorter "
745                 "than: {}",
746                 length, kRFStatsParamTotalLen);
747         return;
748       }
749 
750       if (com::android::bluetooth::flags::support_bluetooth_quality_report_v6()) {
751         AddRFStatsEventToQueue(length, p_bqr_event);
752       }
753       break;
754 
755     default:
756       log::warn("Unknown ID: 0x{:x}", quality_report_id);
757       break;
758   }
759 }
760 
761 // Record a new incoming Link Quality related BQR event in quality event queue.
762 //
763 // @param length Lengths of the Link Quality related BQR event.
764 // @param p_link_quality_event A pointer to the Link Quality related BQR event.
AddLinkQualityEventToQueue(uint8_t length,const uint8_t * p_link_quality_event)765 static void AddLinkQualityEventToQueue(uint8_t length, const uint8_t* p_link_quality_event) {
766   std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
767   RawAddress bd_addr;
768 
769   p_bqr_event->ParseBqrLinkQualityEvt(length, p_link_quality_event);
770 
771   GetInterfaceToProfiles()->events->invoke_link_quality_report_cb(
772           bluetooth::common::time_get_os_boottime_ms(),
773           p_bqr_event->bqr_link_quality_event_.quality_report_id,
774           p_bqr_event->bqr_link_quality_event_.rssi, p_bqr_event->bqr_link_quality_event_.snr,
775           p_bqr_event->bqr_link_quality_event_.retransmission_count,
776           p_bqr_event->bqr_link_quality_event_.no_rx_count,
777           p_bqr_event->bqr_link_quality_event_.nak_count);
778 
779 #ifdef __ANDROID__
780   int ret = stats_write(
781           BLUETOOTH_QUALITY_REPORT_REPORTED, p_bqr_event->bqr_link_quality_event_.quality_report_id,
782           p_bqr_event->bqr_link_quality_event_.packet_types,
783           p_bqr_event->bqr_link_quality_event_.connection_handle,
784           p_bqr_event->bqr_link_quality_event_.connection_role,
785           p_bqr_event->bqr_link_quality_event_.tx_power_level,
786           p_bqr_event->bqr_link_quality_event_.rssi, p_bqr_event->bqr_link_quality_event_.snr,
787           p_bqr_event->bqr_link_quality_event_.unused_afh_channel_count,
788           p_bqr_event->bqr_link_quality_event_.afh_select_unideal_channel_count,
789           p_bqr_event->bqr_link_quality_event_.lsto,
790           p_bqr_event->bqr_link_quality_event_.connection_piconet_clock,
791           p_bqr_event->bqr_link_quality_event_.retransmission_count,
792           p_bqr_event->bqr_link_quality_event_.no_rx_count,
793           p_bqr_event->bqr_link_quality_event_.nak_count,
794           p_bqr_event->bqr_link_quality_event_.last_tx_ack_timestamp,
795           p_bqr_event->bqr_link_quality_event_.flow_off_count,
796           p_bqr_event->bqr_link_quality_event_.last_flow_on_timestamp,
797           p_bqr_event->bqr_link_quality_event_.buffer_overflow_bytes,
798           p_bqr_event->bqr_link_quality_event_.buffer_underflow_bytes);
799   if (ret < 0) {
800     log::warn("failed to log BQR event to statsd, error {}", ret);
801   }
802 #else
803   // TODO(abps) Metrics for non-Android build
804 #endif
805   BluetoothQualityReportInterface* bqrItf = getBluetoothQualityReportInterface();
806 
807   if (bqrItf != NULL) {
808     bd_addr = p_bqr_event->bqr_link_quality_event_.bdaddr;
809     if (bd_addr.IsEmpty()) {
810       tBTM_SEC_DEV_REC* dev =
811               btm_find_dev_by_handle(p_bqr_event->bqr_link_quality_event_.connection_handle);
812       if (dev != NULL) {
813         bd_addr = dev->RemoteAddress();
814       }
815     }
816 
817     if (!bd_addr.IsEmpty()) {
818       bqrItf->bqr_delivery_event(bd_addr, p_link_quality_event, length);
819     } else {
820       log::warn("failed to deliver BQR, bdaddr is empty");
821     }
822   } else {
823     log::warn("failed to deliver BQR, bqrItf is NULL");
824   }
825 
826   kpBqrEventQueue.Enqueue(p_bqr_event.release());
827 }
828 
AddEnergyMonitorEventToQueue(uint8_t length,const uint8_t * p_energy_monitor_event)829 static void AddEnergyMonitorEventToQueue(uint8_t length, const uint8_t* p_energy_monitor_event) {
830   std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
831 
832   if (!p_bqr_event->ParseBqrEnergyMonitorEvt(length, p_energy_monitor_event)) {
833     log::warn("failed to parse BQR energy monitor event");
834     return;
835   }
836 
837   BluetoothQualityReportInterface* bqrItf = getBluetoothQualityReportInterface();
838 
839   if (bqrItf == NULL) {
840     log::warn("failed to deliver BQR, bqrItf is NULL");
841     return;
842   }
843 
844   bqrItf->bqr_delivery_event(RawAddress::kAny, p_energy_monitor_event, length);
845 }
846 
AddRFStatsEventToQueue(uint8_t length,const uint8_t * p_rf_stats_event)847 static void AddRFStatsEventToQueue(uint8_t length, const uint8_t* p_rf_stats_event) {
848   std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
849 
850   if (!p_bqr_event->ParseBqrRFStatsEvt(length, p_rf_stats_event)) {
851     log::warn("failed to parse BQR RF stats event");
852     return;
853   }
854 
855   BluetoothQualityReportInterface* bqrItf = getBluetoothQualityReportInterface();
856 
857   if (bqrItf == NULL) {
858     log::warn("failed to deliver BQR, bqrItf is NULL");
859     return;
860   }
861 
862   bqrItf->bqr_delivery_event(RawAddress::kAny, p_rf_stats_event, length);
863 }
864 
865 static int OpenLmpLlTraceLogFile();
866 
867 // Dump the LMP/LL message handshaking with the remote device to a log file.
868 //
869 // @param length Lengths of the LMP/LL message trace event.
870 // @param p_lmp_ll_message_event A pointer to the LMP/LL message trace event.
DumpLmpLlMessage(uint8_t length,const uint8_t * p_lmp_ll_message_event)871 static void DumpLmpLlMessage(uint8_t length, const uint8_t* p_lmp_ll_message_event) {
872   std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
873 
874   if (LmpLlMessageTraceLogFd == INVALID_FD || LmpLlMessageTraceCounter >= kLogDumpEventPerFile) {
875     LmpLlMessageTraceLogFd = OpenLmpLlTraceLogFile();
876   }
877   if (LmpLlMessageTraceLogFd != INVALID_FD) {
878     p_bqr_event->WriteLmpLlTraceLogFile(LmpLlMessageTraceLogFd, length, p_lmp_ll_message_event);
879   }
880 }
881 
882 // Open the LMP/LL message trace log file.
883 //
884 // @return a file descriptor of the LMP/LL message trace log file.
OpenLmpLlTraceLogFile()885 static int OpenLmpLlTraceLogFile() {
886   if (rename(kpLmpLlMessageTraceLogPath, kpLmpLlMessageTraceLastLogPath) != 0 && errno != ENOENT) {
887     log::error("Unable to rename '{}' to '{}' : {}", kpLmpLlMessageTraceLogPath,
888                kpLmpLlMessageTraceLastLogPath, strerror(errno));
889   }
890 
891   mode_t prevmask = umask(0);
892   int logfile_fd = open(kpLmpLlMessageTraceLogPath, O_WRONLY | O_CREAT | O_TRUNC,
893                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
894   umask(prevmask);
895   if (logfile_fd == INVALID_FD) {
896     log::error("Unable to open '{}' : {}", kpLmpLlMessageTraceLogPath, strerror(errno));
897   } else {
898     LmpLlMessageTraceCounter = 0;
899   }
900   return logfile_fd;
901 }
902 
903 static int OpenBtSchedulingTraceLogFile();
904 
905 // Dump the Bluetooth Multi-profile/Coex scheduling information to a log file.
906 //
907 // @param length Lengths of the Bluetooth Multi-profile/Coex scheduling trace
908 //   event.
909 // @param p_bt_scheduling_event A pointer to the Bluetooth Multi-profile/Coex
910 //   scheduling trace event.
DumpBtScheduling(uint8_t length,const uint8_t * p_bt_scheduling_event)911 static void DumpBtScheduling(uint8_t length, const uint8_t* p_bt_scheduling_event) {
912   std::unique_ptr<BqrVseSubEvt> p_bqr_event = std::make_unique<BqrVseSubEvt>();
913 
914   if (BtSchedulingTraceLogFd == INVALID_FD || BtSchedulingTraceCounter == kLogDumpEventPerFile) {
915     BtSchedulingTraceLogFd = OpenBtSchedulingTraceLogFile();
916   }
917   if (BtSchedulingTraceLogFd != INVALID_FD) {
918     p_bqr_event->WriteBtSchedulingTraceLogFile(BtSchedulingTraceLogFd, length,
919                                                p_bt_scheduling_event);
920   }
921 }
922 
923 // Open the Bluetooth Multi-profile/Coex scheduling trace log file.
924 //
925 // @return a file descriptor of the Bluetooth Multi-profile/Coex scheduling
926 //   trace log file.
OpenBtSchedulingTraceLogFile()927 static int OpenBtSchedulingTraceLogFile() {
928   if (rename(kpBtSchedulingTraceLogPath, kpBtSchedulingTraceLastLogPath) != 0 && errno != ENOENT) {
929     log::error("Unable to rename '{}' to '{}' : {}", kpBtSchedulingTraceLogPath,
930                kpBtSchedulingTraceLastLogPath, strerror(errno));
931   }
932 
933   mode_t prevmask = umask(0);
934   int logfile_fd = open(kpBtSchedulingTraceLogPath, O_WRONLY | O_CREAT | O_TRUNC,
935                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
936   umask(prevmask);
937   if (logfile_fd == INVALID_FD) {
938     log::error("Unable to open '{}' : {}", kpBtSchedulingTraceLogPath, strerror(errno));
939   } else {
940     BtSchedulingTraceCounter = 0;
941   }
942   return logfile_fd;
943 }
944 
DebugDump(int fd)945 void DebugDump(int fd) {
946   dprintf(fd, "\nBT Quality Report Events: \n");
947 
948   if (kpBqrEventQueue.Empty()) {
949     dprintf(fd, "Event queue is empty.\n");
950     return;
951   }
952 
953   while (!kpBqrEventQueue.Empty()) {
954     std::unique_ptr<BqrVseSubEvt> p_event(kpBqrEventQueue.Dequeue());
955 
956     bool warning = (p_event->bqr_link_quality_event_.rssi < kCriWarnRssi ||
957                     p_event->bqr_link_quality_event_.unused_afh_channel_count > kCriWarnUnusedCh);
958 
959     std::stringstream ss_timestamp;
960     ss_timestamp << std::put_time(&p_event->tm_timestamp_, "%m-%d %H:%M:%S");
961 
962     dprintf(fd, "%c  %s %s\n", warning ? '*' : ' ', ss_timestamp.str().c_str(),
963             p_event->ToString().c_str());
964   }
965 
966   dprintf(fd, "\n");
967 }
968 
btif_get_remote_version(const RawAddress & bd_addr)969 static bt_remote_version_t btif_get_remote_version(const RawAddress& bd_addr) {
970   uint8_t tmp_lmp_ver = 0;
971   uint16_t tmp_manufacturer = 0;
972   uint16_t tmp_lmp_subver = 0;
973 
974   const bool status = get_btm_client_interface().peer.BTM_ReadRemoteVersion(
975           bd_addr, &tmp_lmp_ver, &tmp_manufacturer, &tmp_lmp_subver);
976   if (status && (tmp_lmp_ver || tmp_manufacturer || tmp_lmp_subver)) {
977     return {
978             .version = tmp_lmp_ver,
979             .sub_ver = tmp_lmp_subver,
980             .manufacturer = tmp_manufacturer,
981     };
982   }
983 
984   bt_remote_version_t info{};
985   bt_property_t prop{
986           .type = BT_PROPERTY_REMOTE_VERSION_INFO,
987           .len = sizeof(bt_remote_version_t),
988           .val = reinterpret_cast<void*>(&info),
989   };
990 
991   if (btif_storage_get_remote_device_property(&bd_addr, &prop) == BT_STATUS_SUCCESS) {
992     return info;
993   }
994   return {};
995 }
996 
997 class BluetoothQualityReportInterfaceImpl : public bluetooth::bqr::BluetoothQualityReportInterface {
998   ~BluetoothQualityReportInterfaceImpl() override = default;
999 
init(BluetoothQualityReportCallbacks * callbacks)1000   void init(BluetoothQualityReportCallbacks* callbacks) override {
1001     log::info("BluetoothQualityReportInterfaceImpl");
1002     this->callbacks = callbacks;
1003   }
1004 
bqr_delivery_event(const RawAddress & bd_addr,const uint8_t * bqr_raw_data,uint32_t bqr_raw_data_len)1005   void bqr_delivery_event(const RawAddress& bd_addr, const uint8_t* bqr_raw_data,
1006                           uint32_t bqr_raw_data_len) override {
1007     if (bqr_raw_data == NULL) {
1008       log::error("bqr data is null");
1009       return;
1010     }
1011 
1012     std::vector<uint8_t> raw_data;
1013     raw_data.insert(raw_data.begin(), bqr_raw_data, bqr_raw_data + bqr_raw_data_len);
1014 
1015     if (vendor_cap_supported_version < kBqrVersion5_0 &&
1016         bqr_raw_data_len < kLinkQualityParamTotalLen + kVersion5_0ParamsTotalLen) {
1017       std::vector<uint8_t>::iterator it = raw_data.begin() + kLinkQualityParamTotalLen;
1018       /**
1019        * Insert zeros as remote address and calibration count
1020        * for BQR 5.0 incompatible devices
1021        */
1022       raw_data.insert(it, kVersion5_0ParamsTotalLen, 0);
1023     }
1024 
1025     bt_remote_version_t info = btif_get_remote_version(bd_addr);
1026 
1027     log::info("len: {}, addr: {}, lmp_ver: {}, manufacturer_id: {}, lmp_subver: {}",
1028               bqr_raw_data_len, bd_addr, info.version, info.manufacturer, info.sub_ver);
1029 
1030     if (callbacks == nullptr) {
1031       log::error("callbacks is nullptr");
1032       return;
1033     }
1034 
1035     do_in_jni_thread(
1036             base::BindOnce(&bluetooth::bqr::BluetoothQualityReportCallbacks::bqr_delivery_callback,
1037                            base::Unretained(callbacks), bd_addr, info.version, info.sub_ver,
1038                            info.manufacturer, std::move(raw_data)));
1039   }
1040 
1041 private:
1042   BluetoothQualityReportCallbacks* callbacks = nullptr;
1043 };
1044 
getBluetoothQualityReportInterface()1045 BluetoothQualityReportInterface* getBluetoothQualityReportInterface() {
1046   if (!bluetoothQualityReportInstance) {
1047     bluetoothQualityReportInstance.reset(new BluetoothQualityReportInterfaceImpl());
1048   }
1049 
1050   return bluetoothQualityReportInstance.get();
1051 }
1052 
vendor_specific_event_callback(hci::VendorSpecificEventView vendor_specific_event_view)1053 static void vendor_specific_event_callback(
1054         hci::VendorSpecificEventView vendor_specific_event_view) {
1055   auto bqr = hci::BqrEventView::CreateOptional(vendor_specific_event_view);
1056   if (!bqr) {
1057     return;
1058   }
1059   auto payload = vendor_specific_event_view.GetPayload();
1060   std::vector<uint8_t> bytes{payload.begin(), payload.end()};
1061 
1062   uint8_t quality_report_id = static_cast<uint8_t>(bqr->GetQualityReportId());
1063   uint8_t bqr_parameter_length = bytes.size();
1064   const uint8_t* p_bqr_event = bytes.data();
1065 
1066   // The stream currently points to the BQR sub-event parameters
1067   switch (quality_report_id) {
1068     case bluetooth::bqr::QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE: {
1069       auto lmp_view = hci::BqrLogDumpEventView::Create(*bqr);
1070     }
1071       if (bqr_parameter_length >= bluetooth::bqr::kLogDumpParamTotalLen) {
1072         bluetooth::bqr::DumpLmpLlMessage(bqr_parameter_length, p_bqr_event);
1073       } else {
1074         log::info("Malformed LMP event of length {}", bqr_parameter_length);
1075       }
1076 
1077       break;
1078 
1079     case bluetooth::bqr::QUALITY_REPORT_ID_BT_SCHEDULING_TRACE:
1080       if (bqr_parameter_length >= bluetooth::bqr::kLogDumpParamTotalLen) {
1081         bluetooth::bqr::DumpBtScheduling(bqr_parameter_length, p_bqr_event);
1082       } else {
1083         log::info("Malformed TRACE event of length {}", bqr_parameter_length);
1084       }
1085       break;
1086 
1087     default:
1088       log::info("Unhandled BQR subevent 0x{:02x}", quality_report_id);
1089   }
1090 
1091   CategorizeBqrEvent(bytes.size(), bytes.data());
1092 }
1093 
register_vse()1094 void register_vse() {
1095   bluetooth::shim::GetHciLayer()->RegisterVendorSpecificEventHandler(
1096           hci::VseSubeventCode::BQR_EVENT, to_bind_->Bind(vendor_specific_event_callback));
1097 }
1098 
unregister_vse()1099 void unregister_vse() {
1100   bluetooth::shim::GetHciLayer()->UnregisterVendorSpecificEventHandler(
1101           hci::VseSubeventCode::BQR_EVENT);
1102 }
1103 
SetLmpLlMessageTraceLogFd(int fd)1104 void SetLmpLlMessageTraceLogFd(int fd) { LmpLlMessageTraceLogFd = fd; }
1105 
1106 }  // namespace bqr
1107 }  // namespace bluetooth
1108