summaryrefslogtreecommitdiff
path: root/system/btif/include/btif_bqr.h
blob: 1c723125516da94613fb089331424e2c089fc920 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
/*
 * 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;
// The version supports ISO packets start from v1.01(257)
static constexpr uint16_t kBqrIsoVersion = 257;

// 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_LE_AUDIO_CHOPPY = 0x07,
  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,
  PACKET_TYPE_ISO = 0x51
};

// 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;
  // The number of packets that are sent out.
  uint32_t tx_total_packets;
  // The number of packets that don't receive an acknowledgment.
  uint32_t tx_unacked_packets;
  // The number of packets that are not sent out by its flush point.
  uint32_t tx_flushed_packets;
  // The number of packets that Link Layer transmits a CIS Data PDU in the last
  // subevent of a CIS event.
  uint32_t tx_last_subevent_packets;
  // The number of received packages with CRC error since the last event.
  uint32_t crc_error_packets;
  // The number of duplicate(retransmission) packages that are received since
  // the last event.
  uint32_t rx_duplicate_packets;
  // For the controller vendor to obtain more vendor specific parameters.
  const 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.
  const 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, const 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,
                              const 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,
                                     const 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, const 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,
                                const 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, const 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, const 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_