• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "bluetooth_event.h"
17 
18 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
19 
20 #include "bta/include/bta_hfp_api.h"
21 #include "main/shim/helpers.h"
22 #include "os/metrics.h"
23 #include "stack/include/btm_api_types.h"
24 
25 namespace bluetooth {
26 namespace metrics {
27 
28 using android::bluetooth::EventType;
29 using android::bluetooth::State;
30 using hci::ErrorCode;
31 
MapErrorCodeToState(ErrorCode reason)32 State MapErrorCodeToState(ErrorCode reason) {
33   switch (reason) {
34     case ErrorCode::SUCCESS:
35       return State::SUCCESS;
36     case ErrorCode::UNKNOWN_HCI_COMMAND:
37       return State::UNKNOWN_HCI_COMMAND;
38     case ErrorCode::UNKNOWN_CONNECTION:
39       return State::NO_CONNECTION;
40     case ErrorCode::HARDWARE_FAILURE:
41       return State::HARDWARE_FAILURE;
42     case ErrorCode::PAGE_TIMEOUT:
43       return State::PAGE_TIMEOUT;
44     case ErrorCode::AUTHENTICATION_FAILURE:
45       return State::AUTH_FAILURE;
46     case ErrorCode::PIN_OR_KEY_MISSING:
47       return State::KEY_MISSING;
48     case ErrorCode::MEMORY_CAPACITY_EXCEEDED:
49       return State::MEMORY_CAPACITY_EXCEEDED;
50     case ErrorCode::CONNECTION_TIMEOUT:
51       return State::CONNECTION_TIMEOUT;
52     case ErrorCode::CONNECTION_LIMIT_EXCEEDED:
53       return State::CONNECTION_LIMIT_EXCEEDED;
54     case ErrorCode::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED:
55       return State::SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED;
56     case ErrorCode::CONNECTION_ALREADY_EXISTS:
57       return State::ALREADY_CONNECTED;
58     case ErrorCode::COMMAND_DISALLOWED:
59       return State::COMMAND_DISALLOWED;
60     case ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES:
61       return State::RESOURCES_EXCEEDED;
62     case ErrorCode::CONNECTION_REJECTED_SECURITY_REASONS:
63       return State::CONNECTION_REJECTED_SECURITY_REASONS;
64     case ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR:
65       return State::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR;
66     case ErrorCode::CONNECTION_ACCEPT_TIMEOUT:
67       return State::CONNECTION_ACCEPT_TIMEOUT;
68     case ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE:
69       return State::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
70     case ErrorCode::INVALID_HCI_COMMAND_PARAMETERS:
71       return State::INVALID_HCI_COMMAND_PARAMETERS;
72     case ErrorCode::REMOTE_USER_TERMINATED_CONNECTION:
73       return State::REMOTE_USER_TERMINATED_CONNECTION;
74     case ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES:
75       return State::REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES;
76     case ErrorCode::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF:
77       return State::REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF;
78     case ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST:
79       return State::CONNECTION_TERMINATED_BY_LOCAL_HOST;
80     case ErrorCode::REPEATED_ATTEMPTS:
81       return State::REPEATED_ATTEMPTS;
82     case ErrorCode::PAIRING_NOT_ALLOWED:
83       return State::PAIRING_NOT_ALLOWED;
84     case ErrorCode::UNKNOWN_LMP_PDU:
85       return State::UNKNOWN_LMP_PDU;
86     case ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE:
87       return State::UNSUPPORTED_REMOTE_OR_LMP_FEATURE;
88     case ErrorCode::SCO_OFFSET_REJECTED:
89       return State::SCO_OFFSET_REJECTED;
90     case ErrorCode::SCO_INTERVAL_REJECTED:
91       return State::SCO_INTERVAL_REJECTED;
92     case ErrorCode::SCO_AIR_MODE_REJECTED:
93       return State::SCO_AIR_MODE_REJECTED;
94     case ErrorCode::INVALID_LMP_OR_LL_PARAMETERS:
95       return State::INVALID_LMP_OR_LL_PARAMETERS;
96     case ErrorCode::UNSPECIFIED_ERROR:
97       return State::UNSPECIFIED_ERROR;
98     case ErrorCode::UNSUPPORTED_LMP_OR_LL_PARAMETER:
99       return State::UNSUPPORTED_LMP_OR_LL_PARAMETER;
100     case ErrorCode::ROLE_CHANGE_NOT_ALLOWED:
101       return State::ROLE_CHANGE_NOT_ALLOWED;
102     case ErrorCode::TRANSACTION_RESPONSE_TIMEOUT:
103       return State::TRANSACTION_RESPONSE_TIMEOUT;
104     case ErrorCode::LINK_LAYER_COLLISION:
105       return State::LINK_LAYER_COLLISION;
106     case ErrorCode::LMP_PDU_NOT_ALLOWED:
107       return State::LMP_PDU_NOT_ALLOWED;
108     case ErrorCode::ENCRYPTION_MODE_NOT_ACCEPTABLE:
109       return State::ENCRYPTION_MODE_NOT_ACCEPTABLE;
110     case ErrorCode::LINK_KEY_CANNOT_BE_CHANGED:
111       return State::LINK_KEY_CANNOT_BE_CHANGED;
112     case ErrorCode::REQUESTED_QOS_NOT_SUPPORTED:
113       return State::REQUESTED_QOS_NOT_SUPPORTED;
114     case ErrorCode::INSTANT_PASSED:
115       return State::INSTANT_PASSED;
116     case ErrorCode::PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED:
117       return State::PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED;
118     case ErrorCode::DIFFERENT_TRANSACTION_COLLISION:
119       return State::DIFFERENT_TRANSACTION_COLLISION;
120     case ErrorCode::QOS_UNACCEPTABLE_PARAMETERS:
121       return State::QOS_UNACCEPTABLE_PARAMETERS;
122     case ErrorCode::QOS_REJECTED:
123       return State::QOS_REJECTED;
124     case ErrorCode::CHANNEL_ASSESSMENT_NOT_SUPPORTED:
125       return State::CHANNEL_ASSESSMENT_NOT_SUPPORTED;
126     case ErrorCode::INSUFFICIENT_SECURITY:
127       return State::INSUFFICIENT_SECURITY;
128     case ErrorCode::PARAMETER_OUT_OF_MANDATORY_RANGE:
129       return State::PARAMETER_OUT_OF_MANDATORY_RANGE;
130     case ErrorCode::ROLE_SWITCH_PENDING:
131       return State::ROLE_SWITCH_PENDING;
132     case ErrorCode::RESERVED_SLOT_VIOLATION:
133       return State::RESERVED_SLOT_VIOLATION;
134     case ErrorCode::ROLE_SWITCH_FAILED:
135       return State::ROLE_SWITCH_FAILED;
136     case ErrorCode::EXTENDED_INQUIRY_RESPONSE_TOO_LARGE:
137       return State::EXTENDED_INQUIRY_RESPONSE_TOO_LARGE;
138     case ErrorCode::SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST:
139       return State::SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST;
140     case ErrorCode::HOST_BUSY_PAIRING:
141       return State::HOST_BUSY_PAIRING;
142     case ErrorCode::CONNECTION_REJECTED_NO_SUITABLE_CHANNEL_FOUND:
143       return State::CONNECTION_REJECTED_NO_SUITABLE_CHANNEL_FOUND;
144     case ErrorCode::CONTROLLER_BUSY:
145       return State::CONTROLLER_BUSY;
146     case ErrorCode::UNACCEPTABLE_CONNECTION_PARAMETERS:
147       return State::UNACCEPTABLE_CONNECTION_PARAMETERS;
148     case ErrorCode::ADVERTISING_TIMEOUT:
149       return State::ADVERTISING_TIMEOUT;
150     case ErrorCode::CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE:
151       return State::CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE;
152     case ErrorCode::CONNECTION_FAILED_ESTABLISHMENT:
153       return State::CONNECTION_FAILED_ESTABLISHMENT;
154     case ErrorCode::COARSE_CLOCK_ADJUSTMENT_REJECTED:
155       return State::COARSE_CLOCK_ADJUSTMENT_REJECTED;
156     case ErrorCode::TYPE0_SUBMAP_NOT_DEFINED:
157       return State::TYPE0_SUBMAP_NOT_DEFINED;
158     case ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER:
159       return State::UNKNOWN_ADVERTISING_IDENTIFIER;
160     case ErrorCode::LIMIT_REACHED:
161       return State::LIMIT_REACHED;
162     case ErrorCode::OPERATION_CANCELLED_BY_HOST:
163       return State::OPERATION_CANCELLED_BY_HOST;
164     case ErrorCode::PACKET_TOO_LONG:
165       return State::PACKET_TOO_LONG;
166     default:
167       return State::STATE_UNKNOWN;
168   }
169 }
170 
MapHCIStatusToState(tHCI_STATUS status)171 static State MapHCIStatusToState(tHCI_STATUS status) {
172   switch (status) {
173     case tHCI_STATUS::HCI_SUCCESS:
174       return State::SUCCESS;
175     case tHCI_STATUS::HCI_ERR_ILLEGAL_COMMAND:
176       return State::ILLEGAL_COMMAND;
177     case tHCI_STATUS::HCI_ERR_NO_CONNECTION:
178       return State::NO_CONNECTION;
179     case tHCI_STATUS::HCI_ERR_HW_FAILURE:
180       return State::HW_FAILURE;
181     case tHCI_STATUS::HCI_ERR_PAGE_TIMEOUT:
182       return State::PAGE_TIMEOUT;
183     case tHCI_STATUS::HCI_ERR_AUTH_FAILURE:
184       return State::AUTH_FAILURE;
185     case tHCI_STATUS::HCI_ERR_KEY_MISSING:
186       return State::KEY_MISSING;
187     case tHCI_STATUS::HCI_ERR_MEMORY_FULL:
188       return State::MEMORY_FULL;
189     case tHCI_STATUS::HCI_ERR_CONNECTION_TOUT:
190       return State::CONNECTION_TIMEOUT;
191     case tHCI_STATUS::HCI_ERR_MAX_NUM_OF_CONNECTIONS:
192       return State::MAX_NUMBER_OF_CONNECTIONS;
193     case tHCI_STATUS::HCI_ERR_MAX_NUM_OF_SCOS:
194       return State::MAX_NUM_OF_SCOS;
195     case tHCI_STATUS::HCI_ERR_CONNECTION_EXISTS:
196       return State::ALREADY_CONNECTED;
197     case tHCI_STATUS::HCI_ERR_COMMAND_DISALLOWED:
198       return State::COMMAND_DISALLOWED;
199     case tHCI_STATUS::HCI_ERR_HOST_REJECT_RESOURCES:
200       return State::HOST_REJECT_RESOURCES;
201     case tHCI_STATUS::HCI_ERR_HOST_REJECT_SECURITY:
202       return State::HOST_REJECT_SECURITY;
203     case tHCI_STATUS::HCI_ERR_HOST_REJECT_DEVICE:
204       return State::HOST_REJECT_DEVICE;
205     case tHCI_STATUS::HCI_ERR_HOST_TIMEOUT:
206       return State::CONNECTION_ACCEPT_TIMEOUT;
207     case tHCI_STATUS::HCI_ERR_ILLEGAL_PARAMETER_FMT:
208       return State::ILLEGAL_PARAMETER_FMT;
209     case tHCI_STATUS::HCI_ERR_PEER_USER:
210       return State::PEER_USER;
211     case tHCI_STATUS::HCI_ERR_REMOTE_LOW_RESOURCE:
212       return State::REMOTE_LOW_RESOURCE;
213     case tHCI_STATUS::HCI_ERR_REMOTE_POWER_OFF:
214       return State::REMOTE_POWER_OFF;
215     case tHCI_STATUS::HCI_ERR_CONN_CAUSE_LOCAL_HOST:
216       return State::CONN_CAUSE_LOCAL_HOST;
217     case tHCI_STATUS::HCI_ERR_REPEATED_ATTEMPTS:
218       return State::REPEATED_ATTEMPTS;
219     case tHCI_STATUS::HCI_ERR_PAIRING_NOT_ALLOWED:
220       return State::PAIRING_NOT_ALLOWED;
221     case tHCI_STATUS::HCI_ERR_UNSUPPORTED_REM_FEATURE:
222       return State::UNSUPPORTED_REM_FEATURE;
223     case tHCI_STATUS::HCI_ERR_UNSPECIFIED:
224       return State::UNSPECIFIED;
225     case tHCI_STATUS::HCI_ERR_LMP_RESPONSE_TIMEOUT:
226       return State::TRANSACTION_RESPONSE_TIMEOUT;
227     case tHCI_STATUS::HCI_ERR_LMP_ERR_TRANS_COLLISION:
228       return State::LMP_ERR_TRANS_COLLISION;
229     case tHCI_STATUS::HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE:
230       return State::ENCRYPTION_MODE_NOT_ACCEPTABLE;
231     case tHCI_STATUS::HCI_ERR_UNIT_KEY_USED:
232       return State::UNIT_KEY_USED;
233     case tHCI_STATUS::HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED:
234       return State::PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED;
235     case tHCI_STATUS::HCI_ERR_DIFF_TRANSACTION_COLLISION:
236       return State::DIFF_TRANSACTION_COLLISION;
237     case tHCI_STATUS::HCI_ERR_INSUFFCIENT_SECURITY:
238       return State::INSUFFICIENT_SECURITY;
239     case tHCI_STATUS::HCI_ERR_ROLE_SWITCH_PENDING:
240       return State::ROLE_SWITCH_PENDING;
241     case tHCI_STATUS::HCI_ERR_ROLE_SWITCH_FAILED:
242       return State::ROLE_SWITCH_FAILED;
243     case tHCI_STATUS::HCI_ERR_HOST_BUSY_PAIRING:
244       return State::HOST_BUSY_PAIRING;
245     case tHCI_STATUS::HCI_ERR_UNACCEPT_CONN_INTERVAL:
246       return State::UNACCEPT_CONN_INTERVAL;
247     case tHCI_STATUS::HCI_ERR_ADVERTISING_TIMEOUT:
248       return State::ADVERTISING_TIMEOUT;
249     case tHCI_STATUS::HCI_ERR_CONN_FAILED_ESTABLISHMENT:
250       return State::CONNECTION_FAILED_ESTABLISHMENT;
251     case tHCI_STATUS::HCI_ERR_LIMIT_REACHED:
252       return State::LIMIT_REACHED;
253     case tHCI_STATUS::HCI_ERR_CANCELLED_BY_LOCAL_HOST:
254       return State::CANCELLED_BY_LOCAL_HOST;
255     case tHCI_STATUS::HCI_ERR_UNDEFINED:
256       return State::UNDEFINED;
257     default:
258       return State::STATE_UNKNOWN;
259   }
260 }
261 
MapSmpStatusCodeToState(tSMP_STATUS status)262 static State MapSmpStatusCodeToState(tSMP_STATUS status) {
263   switch (status) {
264     case tSMP_STATUS::SMP_SUCCESS:
265       return State::SUCCESS;
266     case tSMP_STATUS::SMP_PASSKEY_ENTRY_FAIL:
267       return State::PASSKEY_ENTRY_FAIL;
268     case tSMP_STATUS::SMP_OOB_FAIL:
269       return State::OOB_FAIL;
270     case tSMP_STATUS::SMP_PAIR_AUTH_FAIL:
271       return State::AUTH_FAILURE;
272     case tSMP_STATUS::SMP_CONFIRM_VALUE_ERR:
273       return State::CONFIRM_VALUE_ERROR;
274     case tSMP_STATUS::SMP_PAIR_NOT_SUPPORT:
275       return State::PAIRING_NOT_ALLOWED;
276     case tSMP_STATUS::SMP_ENC_KEY_SIZE:
277       return State::ENC_KEY_SIZE;
278     case tSMP_STATUS::SMP_INVALID_CMD:
279       return State::INVALID_CMD;
280     case tSMP_STATUS::SMP_PAIR_FAIL_UNKNOWN:
281       return State::STATE_UNKNOWN;  // Assuming this maps to the default
282     case tSMP_STATUS::SMP_REPEATED_ATTEMPTS:
283       return State::REPEATED_ATTEMPTS;
284     case tSMP_STATUS::SMP_INVALID_PARAMETERS:
285       return State::INVALID_PARAMETERS;
286     case tSMP_STATUS::SMP_DHKEY_CHK_FAIL:
287       return State::DHKEY_CHK_FAIL;
288     case tSMP_STATUS::SMP_NUMERIC_COMPAR_FAIL:
289       return State::NUMERIC_COMPARISON_FAIL;
290     case tSMP_STATUS::SMP_BR_PARING_IN_PROGR:
291       return State::BR_PAIRING_IN_PROGRESS;
292     case tSMP_STATUS::SMP_XTRANS_DERIVE_NOT_ALLOW:
293       return State::CROSS_TRANSPORT_NOT_ALLOWED;
294     case tSMP_STATUS::SMP_PAIR_INTERNAL_ERR:
295       return State::INTERNAL_ERROR;
296     case tSMP_STATUS::SMP_UNKNOWN_IO_CAP:
297       return State::UNKNOWN_IO_CAP;
298     case tSMP_STATUS::SMP_BUSY:
299       return State::BUSY_PAIRING;
300     case tSMP_STATUS::SMP_ENC_FAIL:
301       return State::ENCRYPTION_FAIL;
302     case tSMP_STATUS::SMP_STARTED:
303       return State::STATE_UNKNOWN;  // Assuming this maps to the default
304     case tSMP_STATUS::SMP_RSP_TIMEOUT:
305       return State::RESPONSE_TIMEOUT;
306     case tSMP_STATUS::SMP_FAIL:
307       return State::FAIL;
308     case tSMP_STATUS::SMP_CONN_TOUT:
309       return State::CONNECTION_TIMEOUT;
310     case tSMP_STATUS::SMP_SIRK_DEVICE_INVALID:
311       return State::SIRK_DEVICE_INVALID;
312     case tSMP_STATUS::SMP_USER_CANCELLED:
313       return State::USER_CANCELLATION;
314     default:
315       return State::STATE_UNKNOWN;
316   }
317 }
318 
MapHfpVersionToState(uint16_t version)319 State MapHfpVersionToState(uint16_t version) {
320   switch (version) {
321     case HSP_VERSION_1_0:
322       return State::VERSION_1_0;
323     case HFP_VERSION_1_1:
324       return State::VERSION_1_1;
325     case HSP_VERSION_1_2:
326       return State::VERSION_1_2;
327     case HFP_VERSION_1_5:
328       return State::VERSION_1_5;
329     case HFP_VERSION_1_6:
330       return State::VERSION_1_6;
331     case HFP_VERSION_1_7:
332       return State::VERSION_1_7;
333     case HFP_VERSION_1_8:
334       return State::VERSION_1_8;
335     case HFP_VERSION_1_9:
336       return State::VERSION_1_9;
337     default:
338       return State::VERSION_UNKNOWN;
339   }
340 }
341 
MapScoCodecToState(uint16_t codec)342 State MapScoCodecToState(uint16_t codec) {
343   switch (codec) {
344     case BTM_SCO_CODEC_CVSD:
345       return State::CODEC_CVSD;
346     case BTM_SCO_CODEC_MSBC:
347       return State::CODEC_MSBC;
348     case BTM_SCO_CODEC_LC3:
349       return State::CODEC_LC3;
350     case BTA_AG_SCO_APTX_SWB_SETTINGS_Q0_MASK:
351       return State::CODEC_APTX_SWB_SETTINGS_Q0_MASK;
352     case BTA_AG_SCO_APTX_SWB_SETTINGS_Q1_MASK:
353       return State::CODEC_APTX_SWB_SETTINGS_Q1_MASK;
354     case BTA_AG_SCO_APTX_SWB_SETTINGS_Q2_MASK:
355       return State::CODEC_APTX_SWB_SETTINGS_Q2_MASK;
356     case BTA_AG_SCO_APTX_SWB_SETTINGS_Q3_MASK:
357       return State::CODEC_APTX_SWB_SETTINGS_Q3_MASK;
358     default:
359       return State::CODEC_UNKNOWN;
360   }
361 }
362 
LogIncomingAclStartEvent(const hci::Address & address)363 void LogIncomingAclStartEvent(const hci::Address& address) {
364   bluetooth::os::LogMetricBluetoothEvent(address, EventType::ACL_CONNECTION_RESPONDER,
365                                          State::START);
366 }
367 
LogAclCompletionEvent(const hci::Address & address,ErrorCode reason,bool is_locally_initiated)368 void LogAclCompletionEvent(const hci::Address& address, ErrorCode reason,
369                            bool is_locally_initiated) {
370   bluetooth::os::LogMetricBluetoothEvent(address,
371                                          is_locally_initiated ? EventType::ACL_CONNECTION_INITIATOR
372                                                               : EventType::ACL_CONNECTION_RESPONDER,
373                                          MapErrorCodeToState(reason));
374 }
375 
LogRemoteNameRequestCompletion(const RawAddress & raw_address,tHCI_STATUS hci_status)376 void LogRemoteNameRequestCompletion(const RawAddress& raw_address, tHCI_STATUS hci_status) {
377   hci::Address address = bluetooth::ToGdAddress(raw_address);
378   bluetooth::os::LogMetricBluetoothEvent(
379           address, EventType::REMOTE_NAME_REQUEST,
380           MapHCIStatusToState(hci_status));
381 }
382 
LogAclDisconnectionEvent(const hci::Address & address,ErrorCode reason,bool is_locally_initiated)383 void LogAclDisconnectionEvent(const hci::Address& address, ErrorCode reason,
384                               bool is_locally_initiated) {
385   bluetooth::os::LogMetricBluetoothEvent(address,
386                                          is_locally_initiated
387                                                  ? EventType::ACL_DISCONNECTION_INITIATOR
388                                                  : EventType::ACL_DISCONNECTION_RESPONDER,
389                                          MapErrorCodeToState(reason));
390 }
391 
LogAclAfterRemoteNameRequest(const RawAddress & raw_address,tBTM_STATUS status)392 void LogAclAfterRemoteNameRequest(const RawAddress& raw_address, tBTM_STATUS status) {
393   hci::Address address = bluetooth::ToGdAddress(raw_address);
394 
395   switch (status) {
396     case tBTM_STATUS::BTM_SUCCESS:
397       bluetooth::os::LogMetricBluetoothEvent(address, EventType::ACL_CONNECTION_INITIATOR,
398                                              State::ALREADY_CONNECTED);
399       break;
400     case tBTM_STATUS::BTM_NO_RESOURCES:
401       bluetooth::os::LogMetricBluetoothEvent(
402               address, EventType::ACL_CONNECTION_INITIATOR,
403               MapErrorCodeToState(ErrorCode::CONNECTION_REJECTED_LIMITED_RESOURCES));
404       break;
405     default:
406       break;
407   }
408 }
409 
LogAuthenticationComplete(const RawAddress & raw_address,tHCI_STATUS hci_status)410 void LogAuthenticationComplete(const RawAddress& raw_address, tHCI_STATUS hci_status) {
411   hci::Address address = bluetooth::ToGdAddress(raw_address);
412   bluetooth::os::LogMetricBluetoothEvent(address,
413                                          hci_status == tHCI_STATUS::HCI_SUCCESS
414                                                  ? EventType::AUTHENTICATION_COMPLETE
415                                                  : EventType::AUTHENTICATION_COMPLETE_FAIL,
416                                          MapHCIStatusToState(hci_status));
417 }
418 
LogSDPComplete(const RawAddress & raw_address,tBTA_STATUS status)419 void LogSDPComplete(const RawAddress& raw_address, tBTA_STATUS status) {
420   hci::Address address = bluetooth::ToGdAddress(raw_address);
421   bluetooth::os::LogMetricBluetoothEvent(
422           address, EventType::SERVICE_DISCOVERY,
423           status == tBTA_STATUS::BTA_SUCCESS ? State::SUCCESS : State::FAIL);
424 }
425 
LogLeAclCompletionEvent(const hci::Address & address,hci::ErrorCode reason,bool is_locally_initiated)426 void LogLeAclCompletionEvent(const hci::Address& address, hci::ErrorCode reason,
427                              bool is_locally_initiated) {
428   bluetooth::os::LogMetricBluetoothEvent(address,
429                                          is_locally_initiated
430                                                  ? EventType::LE_ACL_CONNECTION_INITIATOR
431                                                  : EventType::LE_ACL_CONNECTION_RESPONDER,
432                                          MapErrorCodeToState(reason));
433 }
434 
LogLePairingFail(const RawAddress & raw_address,uint8_t failure_reason,bool is_outgoing)435 void LogLePairingFail(const RawAddress& raw_address, uint8_t failure_reason, bool is_outgoing) {
436   hci::Address address = bluetooth::ToGdAddress(raw_address);
437   bluetooth::os::LogMetricBluetoothEvent(
438           address, is_outgoing ? EventType::SMP_PAIRING_OUTGOING : EventType::SMP_PAIRING_INCOMING,
439           MapSmpStatusCodeToState(static_cast<tSMP_STATUS>(failure_reason)));
440 }
441 
442 }  // namespace metrics
443 }  // namespace bluetooth
444