1 /*
2 * Copyright 2022 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 #include "metrics/chromeos/metrics_event.h"
17
18 #include <android-base/parseint.h>
19 #include <base/files/file_path.h>
20 #include <base/files/file_util.h>
21 #include <base/strings/pattern.h>
22 #include <base/strings/string_number_conversions.h>
23 #include <base/strings/string_util.h>
24 #include <base/strings/stringprintf.h>
25
26 #include <map>
27 #include <utility>
28
29 #include "hci/hci_packets.h"
30 #include "include/hardware/bluetooth.h"
31 #include "include/hardware/bt_av.h"
32 #include "include/hardware/bt_hf.h"
33 #include "include/hardware/bt_hh.h"
34 #include "stack/include/hci_error_code.h"
35
36 extern int GetAdapterIndex();
37
38 namespace bluetooth {
39 namespace metrics {
40
41 namespace {
42 // these consts path below are for getting the chipset info
43 constexpr char kChipsetInfoWlanDirPath[] = "/sys/class/net/wlan0/device";
44 constexpr char kChipsetInfoMlanDirPath[] = "/sys/class/net/mlan0/device";
45 constexpr char kChipsetInfoModaliasPath[] = "/sys/class/bluetooth/hci%d/device/modalias";
46 constexpr char kChipInfoModuleDirPath[] = "/sys/class/bluetooth/hci%d/device/driver/module";
47 } // namespace
48
49 // topshim::btif::BtBondState is a copy of hardware/bluetooth.h:bt_bond_state_t
50 typedef bt_bond_state_t BtBondState;
51 // topshim::btif::BtAclState is a copy of hardware/bluetooth.h:bt_acl_state_t
52 typedef bt_acl_state_t BtAclState;
53 // topshim::btif::BtConnectionDirection is a copy of hardware/bluetooth.h:bt_conn_direction_t
54 typedef bt_conn_direction_t BtConnectionDirection;
55 // topshim::btif::BtStatus is a copy of hardware/bluetooth.h:bt_status_t
56 typedef bt_status_t BtStatus;
57 // topshim::profile::a2dp::BtavConnectionState is a copy of hardware/bt_av.h:btav_connection_state_t
58 typedef btav_connection_state_t BtavConnectionState;
59 // topshim::profile::hid_host::BthhConnectionState is a copy of
60 // hardware/bt_hh.h:bthh_connection_state_t
61 typedef bthh_connection_state_t BthhConnectionState;
62 // topshim::profile::hid_host::BthfConnectionState is a copy of
63 // hardware/bt_hh.h:bthf_connection_state_t
64 typedef headset::bthf_connection_state_t BthfConnectionState;
65
66 // A copy of topshim::btif::BtDeviceType
67 enum class BtDeviceType {
68 Unknown = 0,
69 Bredr,
70 Ble,
71 Dual,
72 };
73
74 // A normalized connection state ENUM definition all profiles
75 enum class ProfilesConnectionState {
76 DISCONNECTED = 0,
77 CONNECTING,
78 CONNECTED,
79 DISCONNECTING,
80 UNKNOWN,
81 };
82
83 // ENUM definition for Bluetooth profiles in sync with ::uuid::Profiles
84 enum class ProfilesFloss {
85 A2dpSink = 0,
86 A2dpSource,
87 AdvAudioDist,
88 Bas,
89 Dis,
90 Hsp,
91 HspAg,
92 Hfp,
93 HfpAg,
94 AvrcpController,
95 AvrcpTarget,
96 ObexObjectPush,
97 Hid,
98 Hogp,
99 Panu,
100 Nap,
101 Bnep,
102 PbapPce,
103 PbapPse,
104 Map,
105 Mns,
106 Mas,
107 Sap,
108 HearingAid,
109 LeAudio,
110 Dip,
111 VolumeControl,
112 GenericMediaControl,
113 MediaControl,
114 CoordinatedSet,
115 };
116
StatusToPairingState(uint32_t status)117 static PairingState StatusToPairingState(uint32_t status) {
118 switch ((BtStatus)status) {
119 case BtStatus::BT_STATUS_SUCCESS:
120 return PairingState::PAIR_SUCCEED;
121 case BtStatus::BT_STATUS_FAIL:
122 return PairingState::PAIR_FAIL_FAILED;
123 case BtStatus::BT_STATUS_NOMEM:
124 return PairingState::PAIR_FAIL_NO_RESOURCES;
125 case BtStatus::BT_STATUS_BUSY:
126 return PairingState::PAIR_FAIL_BUSY;
127 case BtStatus::BT_STATUS_UNSUPPORTED:
128 return PairingState::PAIR_FAIL_NOT_SUPPORTED;
129 case BtStatus::BT_STATUS_PARM_INVALID:
130 return PairingState::PAIR_FAIL_INVALID_PARAMS;
131 case BtStatus::BT_STATUS_AUTH_FAILURE:
132 return PairingState::PAIR_FAIL_AUTH_FAILED;
133 case BtStatus::BT_STATUS_RMT_DEV_DOWN:
134 return PairingState::PAIR_FAIL_ESTABLISH_CONN;
135 case BtStatus::BT_STATUS_AUTH_REJECTED:
136 return PairingState::PAIR_FAIL_AUTH_FAILED;
137 case BtStatus::BT_STATUS_NOT_READY:
138 case BtStatus::BT_STATUS_DONE:
139 case BtStatus::BT_STATUS_UNHANDLED:
140 default:
141 return PairingState::PAIR_FAIL_UNKNOWN;
142 }
143 }
144
FailReasonToPairingState(int32_t fail_reason)145 static PairingState FailReasonToPairingState(int32_t fail_reason) {
146 switch ((hci::ErrorCode)fail_reason) {
147 case hci::ErrorCode::SUCCESS:
148 return PairingState::PAIR_SUCCEED;
149 case hci::ErrorCode::UNKNOWN_HCI_COMMAND:
150 return PairingState::PAIR_FAIL_UNKNOWN_COMMAND;
151 case hci::ErrorCode::UNKNOWN_CONNECTION:
152 return PairingState::PAIR_FAIL_INVALID_PARAMS;
153 case hci::ErrorCode::HARDWARE_FAILURE:
154 return PairingState::PAIR_FAIL_FAILED;
155 case hci::ErrorCode::PAGE_TIMEOUT:
156 return PairingState::PAIR_FAIL_ESTABLISH_CONN;
157 case hci::ErrorCode::AUTHENTICATION_FAILURE:
158 return PairingState::PAIR_FAIL_AUTH_FAILED;
159 case hci::ErrorCode::PIN_OR_KEY_MISSING:
160 return PairingState::PAIR_FAIL_AUTH_FAILED;
161 case hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED:
162 return PairingState::PAIR_FAIL_NO_RESOURCES;
163 case hci::ErrorCode::CONNECTION_TIMEOUT:
164 return PairingState::PAIR_FAIL_ESTABLISH_CONN;
165 case hci::ErrorCode::CONNECTION_LIMIT_EXCEEDED:
166 return PairingState::PAIR_FAIL_NO_RESOURCES;
167 case hci::ErrorCode::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED:
168 return PairingState::PAIR_FAIL_NO_RESOURCES;
169 case hci::ErrorCode::CONNECTION_ALREADY_EXISTS:
170 return PairingState::PAIR_FAIL_ALREADY_PAIRED;
171 case hci::ErrorCode::COMMAND_DISALLOWED:
172 return PairingState::PAIR_FAIL_FAILED;
173 case hci::ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES:
174 return PairingState::PAIR_FAIL_NO_RESOURCES;
175 case hci::ErrorCode::CONNECTION_REJECTED_SECURITY_REASONS:
176 return PairingState::PAIR_FAIL_AUTH_FAILED;
177 case hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR:
178 return PairingState::PAIR_FAIL_INVALID_PARAMS;
179 case hci::ErrorCode::CONNECTION_ACCEPT_TIMEOUT:
180 return PairingState::PAIR_FAIL_ESTABLISH_CONN;
181 case hci::ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE:
182 return PairingState::PAIR_FAIL_NOT_SUPPORTED;
183 case hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS:
184 return PairingState::PAIR_FAIL_INVALID_PARAMS;
185 case hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION:
186 return PairingState::PAIR_FAIL_DISCONNECTED;
187 case hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES:
188 return PairingState::PAIR_FAIL_DISCONNECTED;
189 case hci::ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF:
190 return PairingState::PAIR_FAIL_DISCONNECTED;
191 case hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST:
192 return PairingState::PAIR_FAIL_DISCONNECTED;
193 case hci::ErrorCode::REPEATED_ATTEMPTS:
194 return PairingState::PAIR_FAIL_BUSY;
195 case hci::ErrorCode::PAIRING_NOT_ALLOWED:
196 return PairingState::PAIR_FAIL_FAILED;
197 case hci::ErrorCode::UNKNOWN_LMP_PDU:
198 return PairingState::PAIR_FAIL_FAILED;
199 case hci::ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE:
200 return PairingState::PAIR_FAIL_NOT_SUPPORTED;
201 case hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS:
202 return PairingState::PAIR_FAIL_INVALID_PARAMS;
203 case hci::ErrorCode::UNSPECIFIED_ERROR:
204 return PairingState::PAIR_FAIL_UNKNOWN;
205 case hci::ErrorCode::UNSUPPORTED_LMP_OR_LL_PARAMETER:
206 return PairingState::PAIR_FAIL_NOT_SUPPORTED;
207 case hci::ErrorCode::ROLE_CHANGE_NOT_ALLOWED:
208 return PairingState::PAIR_FAIL_FAILED;
209 case hci::ErrorCode::TRANSACTION_RESPONSE_TIMEOUT:
210 return PairingState::PAIR_FAIL_TIMEOUT;
211 case hci::ErrorCode::LINK_LAYER_COLLISION:
212 return PairingState::PAIR_FAIL_FAILED;
213 case hci::ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE:
214 return PairingState::PAIR_FAIL_AUTH_FAILED;
215 case hci::ErrorCode::ROLE_SWITCH_FAILED:
216 return PairingState::PAIR_FAIL_FAILED;
217 case hci::ErrorCode::HOST_BUSY_PAIRING:
218 return PairingState::PAIR_FAIL_BUSY;
219 case hci::ErrorCode::CONTROLLER_BUSY:
220 return PairingState::PAIR_FAIL_BUSY;
221 case hci::ErrorCode::CONNECTION_FAILED_ESTABLISHMENT:
222 return PairingState::PAIR_FAIL_ESTABLISH_CONN;
223 case hci::ErrorCode::LIMIT_REACHED:
224 return PairingState::PAIR_FAIL_NO_RESOURCES;
225 case hci::ErrorCode::PACKET_TOO_LONG:
226 return PairingState::PAIR_FAIL_INVALID_PARAMS;
227 case hci::ErrorCode::SCO_OFFSET_REJECTED:
228 case hci::ErrorCode::SCO_INTERVAL_REJECTED:
229 case hci::ErrorCode::SCO_AIR_MODE_REJECTED:
230 case hci::ErrorCode::ADVERTISING_TIMEOUT:
231 case hci::ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER:
232 case hci::ErrorCode::STATUS_UNKNOWN:
233 return PairingState::PAIR_FAIL_UNKNOWN;
234 default:
235 return PairingState::PAIR_FAIL_UNKNOWN;
236 }
237 }
238
ToAdapterState(uint32_t state)239 AdapterState ToAdapterState(uint32_t state) {
240 return state == 1 ? AdapterState::ON : AdapterState::OFF;
241 }
242
ToSuspendIdState(uint32_t state)243 SuspendIdState ToSuspendIdState(uint32_t state) {
244 return state == 1 ? SuspendIdState::Recorded : SuspendIdState::NoRecord;
245 }
246
ToPairingDeviceType(std::string addr,uint32_t device_type)247 ConnectionType ToPairingDeviceType(std::string addr, uint32_t device_type) {
248 // A map stores the pending ConnectionType used to match a pairing event with unknown type.
249 // map<address, type>
250 static std::map<std::string, ConnectionType> pending_type;
251
252 switch ((BtDeviceType)device_type) {
253 case BtDeviceType::Ble:
254 pending_type[addr] = ConnectionType::CONN_TYPE_LE;
255 return ConnectionType::CONN_TYPE_LE;
256 case BtDeviceType::Bredr:
257 pending_type[addr] = ConnectionType::CONN_TYPE_BREDR;
258 return ConnectionType::CONN_TYPE_BREDR;
259 case BtDeviceType::Dual:
260 case BtDeviceType::Unknown:
261 if (pending_type.find(addr) != pending_type.end()) {
262 return pending_type[addr];
263 } else {
264 return ConnectionType::CONN_TYPE_UNKNOWN;
265 }
266 }
267 }
268
ToPairingState(uint32_t status,uint32_t bond_state,int32_t fail_reason)269 PairingState ToPairingState(uint32_t status, uint32_t bond_state, int32_t fail_reason) {
270 PairingState pairing_state = PairingState::PAIR_FAIL_UNKNOWN;
271
272 // The Bonding is a transitional state during the pairing process. Ignore it by returning the
273 // starting again.
274 if ((BtBondState)bond_state == BtBondState::BT_BOND_STATE_BONDING) {
275 return PairingState::PAIR_STARTING;
276 }
277
278 if ((BtStatus)status == BtStatus::BT_STATUS_SUCCESS &&
279 (hci::ErrorCode)fail_reason == hci::ErrorCode::SUCCESS) {
280 if ((BtBondState)bond_state == BtBondState::BT_BOND_STATE_BONDED) {
281 return PairingState::PAIR_SUCCEED;
282 } else { // must be BtBondState::BT_BOND_STATE_NONE as BT_BOND_STATE_BONDING case has been
283 // checked early
284 // This implies the event is from forgetting a device. Return an absurd value to let caller
285 // know.
286 return PairingState::PAIR_FAIL_END;
287 }
288 }
289
290 // TODO(b/287392029): Translate cases of bond cancelled into PairingState:PAIR_FAIL_CANCELLED
291
292 // When both status and fail reason are provided and disagree with each other, overwrite status
293 // with the fail reason as fail reason is generated closer to the HCI and provides a more accurate
294 // description.
295 if (status) {
296 pairing_state = StatusToPairingState(status);
297 }
298 if (fail_reason) {
299 pairing_state = FailReasonToPairingState(fail_reason);
300 }
301
302 return pairing_state;
303 }
304
StatusToProfileConnectionState(uint32_t status,StateChangeType type)305 int64_t StatusToProfileConnectionState(uint32_t status, StateChangeType type) {
306 int64_t state;
307 if (StateChangeType::STATE_CHANGE_TYPE_CONNECT == type) {
308 switch ((BtStatus)status) {
309 case BtStatus::BT_STATUS_SUCCESS:
310 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_SUCCEED;
311 break;
312 case BtStatus::BT_STATUS_BUSY:
313 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_BUSY_CONNECTING;
314 break;
315 case BtStatus::BT_STATUS_DONE:
316 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_ALREADY_CONNECTED;
317 break;
318 case BtStatus::BT_STATUS_UNSUPPORTED:
319 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_PROFILE_NOT_SUPPORTED;
320 break;
321 case BtStatus::BT_STATUS_PARM_INVALID:
322 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_UNKNOWN_ERROR;
323 break;
324 case BtStatus::BT_STATUS_AUTH_FAILURE:
325 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_CONNECTION_REFUSED;
326 break;
327 case BtStatus::BT_STATUS_RMT_DEV_DOWN:
328 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_REMOTE_UNAVAILABLE;
329 break;
330 case BtStatus::BT_STATUS_AUTH_REJECTED:
331 case BtStatus::BT_STATUS_FAIL:
332 case BtStatus::BT_STATUS_NOT_READY:
333 case BtStatus::BT_STATUS_NOMEM:
334 case BtStatus::BT_STATUS_UNHANDLED:
335 default:
336 state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_UNKNOWN_ERROR;
337 break;
338 }
339 } else {
340 switch ((BtStatus)status) {
341 case BtStatus::BT_STATUS_SUCCESS:
342 state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_SUCCEED;
343 break;
344 case BtStatus::BT_STATUS_BUSY:
345 state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_BUSY_DISCONNECTING;
346 break;
347 case BtStatus::BT_STATUS_DONE:
348 state = (int64_t)
349 MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_ALREADY_DISCONNECTED;
350 break;
351 case BtStatus::BT_STATUS_UNSUPPORTED:
352 state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_UNKNOWN_ERROR;
353 break;
354 case BtStatus::BT_STATUS_PARM_INVALID:
355 state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_INVALID_PARAMS;
356 break;
357 case BtStatus::BT_STATUS_AUTH_FAILURE:
358 state = (int64_t)
359 MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_DISCONNECTION_REFUSED;
360 break;
361 case BtStatus::BT_STATUS_RMT_DEV_DOWN:
362 state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_UNKNOWN_ERROR;
363 break;
364 case BtStatus::BT_STATUS_AUTH_REJECTED:
365 state = (int64_t)
366 MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_DISCONNECTION_REFUSED;
367 break;
368 case BtStatus::BT_STATUS_FAIL:
369 case BtStatus::BT_STATUS_NOT_READY:
370 case BtStatus::BT_STATUS_NOMEM:
371 case BtStatus::BT_STATUS_UNHANDLED:
372 default:
373 state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_UNKNOWN_ERROR;
374 break;
375 }
376 }
377
378 return state;
379 }
380
ToProfileConnectionState(uint32_t profile,uint32_t state)381 static std::pair<uint32_t, uint32_t> ToProfileConnectionState(uint32_t profile, uint32_t state) {
382 std::pair<uint32_t, uint32_t> output;
383
384 switch ((ProfilesFloss)profile) {
385 case ProfilesFloss::A2dpSink:
386 output.first = (uint32_t)Profile::A2DP;
387 switch ((BtavConnectionState)state) {
388 case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTED:
389 output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
390 break;
391 case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTING:
392 output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
393 break;
394 case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTED:
395 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
396 break;
397 case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTING:
398 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
399 break;
400 default:
401 output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
402 break;
403 }
404 break;
405 // case ProfilesFloss::A2dpSource:
406 // case ProfilesFloss::AdvAudioDist:
407 // case ProfilesFloss::Hsp:
408 // case ProfilesFloss::HspAg:
409 case ProfilesFloss::Hfp:
410 output.first = (uint32_t)Profile::HFP;
411 switch ((BthfConnectionState)state) {
412 case BthfConnectionState::BTHF_CONNECTION_STATE_DISCONNECTED:
413 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
414 break;
415 case BthfConnectionState::BTHF_CONNECTION_STATE_CONNECTING:
416 output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
417 break;
418 case BthfConnectionState::BTHF_CONNECTION_STATE_CONNECTED:
419 case BthfConnectionState::BTHF_CONNECTION_STATE_SLC_CONNECTED:
420 output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
421 break;
422 case BthfConnectionState::BTHF_CONNECTION_STATE_DISCONNECTING:
423 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
424 break;
425 default:
426 output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
427 break;
428 }
429 break;
430 // case ProfilesFloss::HfpAg:
431 case ProfilesFloss::AvrcpController:
432 output.first = (uint32_t)Profile::AVRCP;
433 switch ((BtavConnectionState)state) {
434 case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTED:
435 output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
436 break;
437 case BtavConnectionState::BTAV_CONNECTION_STATE_CONNECTING:
438 output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
439 break;
440 case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTED:
441 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
442 break;
443 case BtavConnectionState::BTAV_CONNECTION_STATE_DISCONNECTING:
444 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
445 break;
446 default:
447 output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
448 break;
449 }
450 break;
451 // case ProfilesFloss::AvrcpTarget:
452 // case ProfilesFloss::ObexObjectPush:
453 case ProfilesFloss::Hid:
454 case ProfilesFloss::Hogp:
455 output.first = (uint32_t)Profile::HID;
456 switch ((BthhConnectionState)state) {
457 case BthhConnectionState::BTHH_CONN_STATE_CONNECTED:
458 output.second = (uint32_t)ProfilesConnectionState::CONNECTED;
459 break;
460 case BthhConnectionState::BTHH_CONN_STATE_CONNECTING:
461 output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
462 break;
463 case BthhConnectionState::BTHH_CONN_STATE_DISCONNECTED:
464 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTED;
465 break;
466 case BthhConnectionState::BTHH_CONN_STATE_DISCONNECTING:
467 output.second = (uint32_t)ProfilesConnectionState::DISCONNECTING;
468 break;
469 case BthhConnectionState::BTHH_CONN_STATE_ACCEPTING:
470 // For metric purpose, we map accepting to connecting.
471 output.second = (uint32_t)ProfilesConnectionState::CONNECTING;
472 break;
473 case BthhConnectionState::BTHH_CONN_STATE_UNKNOWN:
474 output.second = (uint32_t)ProfilesConnectionState::UNKNOWN;
475 break;
476 }
477 break;
478 // case ProfilesFloss::Panu:
479 // case ProfilesFloss::Nap:
480 // case ProfilesFloss::Bnep:
481 // case ProfilesFloss::PbapPce:
482 // case ProfilesFloss::PbapPse:
483 // case ProfilesFloss::Map:
484 // case ProfilesFloss::Mns:
485 // case ProfilesFloss::Mas:
486 // case ProfilesFloss::Sap:
487 // case ProfilesFloss::HearingAid:
488 // case ProfilesFloss::LeAudio:
489 // case ProfilesFloss::Dip:
490 // case ProfilesFloss::VolumeControl:
491 // case ProfilesFloss::GenericMediaControl:
492 // case ProfilesFloss::MediaControl:
493 // case ProfilesFloss::CoordinatedSet:
494 default:
495 output = std::make_pair((uint32_t)Profile::UNKNOWN, state);
496 break;
497 }
498
499 return output;
500 }
501
ToProfileConnectionEvent(std::string addr,uint32_t profile,uint32_t status,uint32_t state)502 ProfileConnectionEvent ToProfileConnectionEvent(std::string addr, uint32_t profile, uint32_t status,
503 uint32_t state) {
504 ProfileConnectionEvent event;
505 // A map stores the pending StateChangeType used to match a (dis)connection event with unknown
506 // type. map<std::pair<address, profile>, type>
507 static std::map<std::pair<std::string, uint32_t>, StateChangeType> pending_type;
508
509 auto profile_state_pair = ToProfileConnectionState(profile, state);
510 auto key = std::make_pair(addr, profile_state_pair.first);
511 event.profile = (int64_t)profile_state_pair.first;
512
513 switch ((ProfilesConnectionState)profile_state_pair.second) {
514 case ProfilesConnectionState::CONNECTED:
515 event.type = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
516 event.state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_SUCCEED;
517 pending_type.erase(key);
518 break;
519 case ProfilesConnectionState::CONNECTING:
520 event.type = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
521 event.state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_STARTING;
522 pending_type[key] = StateChangeType::STATE_CHANGE_TYPE_CONNECT;
523 break;
524 case ProfilesConnectionState::DISCONNECTED:
525 event.type = pending_type.find(key) != pending_type.end()
526 ? (int64_t)pending_type[key]
527 : (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
528 // If the profile successfully disconnected for a connect intent, i.e., a connection is
529 // attempted but received a disconnection state update. Report this as an unknown error.
530 if (StateChangeType::STATE_CHANGE_TYPE_CONNECT == (StateChangeType)event.type &&
531 BtStatus::BT_STATUS_SUCCESS == (BtStatus)status) {
532 event.state = (int64_t)MetricProfileConnectionStatus::PROFILE_CONN_STATE_UNKNOWN_ERROR;
533 } else {
534 event.state = StatusToProfileConnectionState(status, (StateChangeType)event.type);
535 }
536 pending_type.erase(key);
537 break;
538 case ProfilesConnectionState::DISCONNECTING:
539 event.type = (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
540 event.state = (int64_t)MetricProfileDisconnectionStatus::PROFILE_DISCONN_STATE_STARTING;
541 pending_type[key] = StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
542 break;
543 default:
544 event.profile = (int64_t)Profile::UNKNOWN;
545 break;
546 }
547
548 return event;
549 }
550
ToAclConnectionStatus(uint32_t status,StateChangeType type,uint32_t hci_reason)551 static int64_t ToAclConnectionStatus(uint32_t status, StateChangeType type, uint32_t hci_reason) {
552 int64_t state;
553 if (StateChangeType::STATE_CHANGE_TYPE_CONNECT == type) {
554 switch ((BtStatus)status) {
555 case BtStatus::BT_STATUS_SUCCESS:
556 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_SUCCEED;
557 break;
558 case BtStatus::BT_STATUS_BUSY:
559 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_BUSY;
560 break;
561 case BtStatus::BT_STATUS_DONE:
562 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_ALREADY;
563 break;
564 case BtStatus::BT_STATUS_UNSUPPORTED:
565 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_NOT_SUPPORTED;
566 break;
567 case BtStatus::BT_STATUS_PARM_INVALID:
568 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_INVALID_PARAMS;
569 break;
570 case BtStatus::BT_STATUS_AUTH_FAILURE:
571 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_AUTH_FAILED;
572 break;
573 case BtStatus::BT_STATUS_RMT_DEV_DOWN:
574 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_DISCONNECTED;
575 break;
576 case BtStatus::BT_STATUS_AUTH_REJECTED:
577 case BtStatus::BT_STATUS_FAIL:
578 case BtStatus::BT_STATUS_NOT_READY:
579 case BtStatus::BT_STATUS_NOMEM:
580 case BtStatus::BT_STATUS_UNHANDLED:
581 default:
582 state = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_UNKNOWN;
583 break;
584 }
585 } else {
586 switch (hci_reason) {
587 case HCI_ERR_CONNECTION_TOUT:
588 state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_TIMEOUT;
589 break;
590 case HCI_ERR_PEER_USER:
591 case HCI_ERR_REMOTE_LOW_RESOURCE:
592 case HCI_ERR_REMOTE_POWER_OFF:
593 state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_REMOTE;
594 break;
595 case HCI_ERR_CONN_CAUSE_LOCAL_HOST:
596 state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_LOCAL_HOST;
597 // TODO: distinguish from ACL_DISCONN_STATE_LOCAL_HOST_SUSPEND
598 break;
599 case HCI_ERR_AUTH_FAILURE:
600 case HCI_ERR_KEY_MISSING:
601 case HCI_ERR_HOST_REJECT_SECURITY:
602 state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_AUTH_FAILURE;
603 break;
604 default:
605 state = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_UNKNOWN;
606 break;
607 }
608 }
609
610 return state;
611 }
612
613 // pending acl conn event is map<addr, pair<state, time>>
614 static std::map<std::string, std::pair<uint32_t, int64_t>> pending_acl_events;
615
PendingAclConnectAttemptEvent(std::string addr,int64_t time,uint32_t acl_state)616 void PendingAclConnectAttemptEvent(std::string addr, int64_t time, uint32_t acl_state) {
617 pending_acl_events[addr] = std::make_pair(acl_state, time);
618 }
619
ToAclConnectionEvent(std::string addr,int64_t time,uint32_t acl_status,uint32_t acl_state,uint32_t direction,uint32_t hci_reason)620 AclConnectionEvent ToAclConnectionEvent(std::string addr, int64_t time, uint32_t acl_status,
621 uint32_t acl_state, uint32_t direction,
622 uint32_t hci_reason) {
623 AclConnectionEvent event;
624
625 if (pending_acl_events.find(addr) == pending_acl_events.end()) {
626 // No attempt found! Assume initiated by system.
627 event.initiator = (int64_t)MetricAclConnectionInitiator::ACL_CONNECTION_INITIATOR_SYSTEM;
628 event.direction = direction;
629 event.start_time = time;
630
631 // There is no failed disconnection. Therefore on failure, assume it's a connection attempt.
632 if (acl_state == (uint32_t)BtAclState::BT_ACL_STATE_CONNECTED ||
633 acl_status != (uint32_t)BtStatus::BT_STATUS_SUCCESS) {
634 event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
635 } else {
636 event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
637 }
638 } else {
639 // connection attempt found. Assume initiated by client.
640 std::pair<uint32_t, int64_t> pending_event = pending_acl_events[addr];
641 pending_acl_events.erase(addr);
642 event.initiator = (int64_t)MetricAclConnectionInitiator::ACL_CONNECTION_INITIATOR_CLIENT;
643 event.direction = (int64_t)MetricAclConnectionDirection::ACL_CONNECTION_OUTGOING;
644 event.start_time = pending_event.second;
645
646 if (pending_event.first == (uint32_t)BtAclState::BT_ACL_STATE_CONNECTED) {
647 event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT;
648 } else {
649 event.state = (int64_t)StateChangeType::STATE_CHANGE_TYPE_DISCONNECT;
650 }
651 }
652
653 if (event.state == (int64_t)StateChangeType::STATE_CHANGE_TYPE_CONNECT) {
654 event.start_status = (int64_t)MetricAclConnectionStatus::ACL_CONN_STATE_STARTING;
655 } else {
656 event.start_status = (int64_t)MetricAclDisconnectionStatus::ACL_DISCONN_STATE_STARTING;
657 }
658
659 event.status = ToAclConnectionStatus(acl_status, (StateChangeType)event.state, hci_reason);
660
661 return event;
662 }
663
GetChipsetInfoId(const char * path,const char * file)664 static int64_t GetChipsetInfoId(const char* path, const char* file) {
665 std::string content;
666 int64_t id;
667
668 if (base::ReadFileToString(base::FilePath(path).Append(file), &content)) {
669 if (android::base::ParseInt(base::CollapseWhitespaceASCII(content, false), &id)) {
670 return id;
671 }
672 }
673 return 0;
674 }
675
GetChipsetInfoModuleName()676 static std::string GetChipsetInfoModuleName() {
677 std::string module;
678 int adapter_index = GetAdapterIndex();
679 std::string path = base::StringPrintf(kChipsetInfoModaliasPath, adapter_index);
680
681 if (base::ReadFileToString(base::FilePath(path), &module)) {
682 return base::CollapseWhitespaceASCII(module, false);
683 }
684 return "";
685 }
686
GetChipsetInfoTransport(void)687 static MetricTransportType GetChipsetInfoTransport(void) {
688 MetricTransportType transport = MetricTransportType::TRANSPORT_TYPE_UNKNOWN;
689 base::FilePath module_realpath;
690 std::string module_name;
691 int adapter_index = GetAdapterIndex();
692 std::string path = base::StringPrintf(kChipInfoModuleDirPath, adapter_index);
693
694 // examples of module_realpath: /sys/module/btusb and /sys/module/hci_uart
695 module_realpath = base::MakeAbsoluteFilePath(base::FilePath(path));
696 if (module_realpath.empty()) {
697 return transport;
698 }
699
700 module_name = module_realpath.BaseName().value();
701 if (base::MatchPattern(module_name, "*usb*")) {
702 transport = MetricTransportType::TRANSPORT_TYPE_USB;
703 } else if (base::MatchPattern(module_name, "*uart*")) {
704 transport = MetricTransportType::TRANSPORT_TYPE_UART;
705 } else if (base::MatchPattern(module_name, "*sdio*")) {
706 transport = MetricTransportType::TRANSPORT_TYPE_SDIO;
707 }
708
709 return transport;
710 }
711
GetMetricsChipsetInfo()712 MetricsChipsetInfo GetMetricsChipsetInfo() {
713 MetricsChipsetInfo info;
714
715 info.vid = GetChipsetInfoId(kChipsetInfoWlanDirPath, "vendor");
716 info.pid = GetChipsetInfoId(kChipsetInfoWlanDirPath, "device");
717
718 if (!info.vid || !info.pid) {
719 info.vid = GetChipsetInfoId(kChipsetInfoMlanDirPath, "vendor");
720 info.pid = GetChipsetInfoId(kChipsetInfoMlanDirPath, "device");
721 }
722
723 if (!info.vid || !info.pid) {
724 info.chipset_string = GetChipsetInfoModuleName();
725 }
726
727 info.transport = (int)GetChipsetInfoTransport();
728 return info;
729 }
730
731 } // namespace metrics
732 } // namespace bluetooth
733