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