• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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