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