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