1 /******************************************************************************
2 *
3 * Copyright 2021 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "BluetoothMetrics"
20
21 #include "os/metrics.h"
22
23 #include <statslog_bt.h>
24
25 #include "common/audit_log.h"
26 #include "metrics/metrics_state.h"
27 #include "common/metric_id_manager.h"
28 #include "common/strings.h"
29 #include "hci/hci_packets.h"
30 #include "os/log.h"
31
32 namespace bluetooth {
33
34 namespace os {
35
36 using bluetooth::common::MetricIdManager;
37 using bluetooth::hci::Address;
38 using bluetooth::hci::ErrorCode;
39 using bluetooth::hci::EventCode;
40
41 /**
42 * nullptr and size 0 represent missing value for obfuscated_id
43 */
44 static const BytesField byteField(nullptr, 0);
45
LogMetricLinkLayerConnectionEvent(const Address * address,uint32_t connection_handle,android::bluetooth::DirectionEnum direction,uint16_t link_type,uint32_t hci_cmd,uint16_t hci_event,uint16_t hci_ble_event,uint16_t cmd_status,uint16_t reason_code)46 void LogMetricLinkLayerConnectionEvent(
47 const Address* address,
48 uint32_t connection_handle,
49 android::bluetooth::DirectionEnum direction,
50 uint16_t link_type,
51 uint32_t hci_cmd,
52 uint16_t hci_event,
53 uint16_t hci_ble_event,
54 uint16_t cmd_status,
55 uint16_t reason_code) {
56 int metric_id = 0;
57 if (address != nullptr) {
58 metric_id = MetricIdManager::GetInstance().AllocateId(*address);
59 }
60 int ret = stats_write(
61 BLUETOOTH_LINK_LAYER_CONNECTION_EVENT,
62 byteField,
63 connection_handle,
64 direction,
65 link_type,
66 hci_cmd,
67 hci_event,
68 hci_ble_event,
69 cmd_status,
70 reason_code,
71 metric_id);
72 if (ret < 0) {
73 LOG_WARN(
74 "Failed to log status %s , reason %s, from cmd %s, event %s, ble_event %s, for %s, handle %d, type %s, "
75 "error %d",
76 common::ToHexString(cmd_status).c_str(),
77 common::ToHexString(reason_code).c_str(),
78 common::ToHexString(hci_cmd).c_str(),
79 common::ToHexString(hci_event).c_str(),
80 common::ToHexString(hci_ble_event).c_str(),
81 address ? ADDRESS_TO_LOGGABLE_CSTR(*address) : "(NULL)",
82 connection_handle,
83 common::ToHexString(link_type).c_str(),
84 ret);
85 }
86 }
87
LogMetricHciTimeoutEvent(uint32_t hci_cmd)88 void LogMetricHciTimeoutEvent(uint32_t hci_cmd) {
89 int ret = stats_write(BLUETOOTH_HCI_TIMEOUT_REPORTED, static_cast<int64_t>(hci_cmd));
90 if (ret < 0) {
91 LOG_WARN("Failed for opcode %s, error %d", common::ToHexString(hci_cmd).c_str(), ret);
92 }
93 }
94
LogMetricRemoteVersionInfo(uint16_t handle,uint8_t status,uint8_t version,uint16_t manufacturer_name,uint16_t subversion)95 void LogMetricRemoteVersionInfo(
96 uint16_t handle, uint8_t status, uint8_t version, uint16_t manufacturer_name, uint16_t subversion) {
97 int ret = stats_write(BLUETOOTH_REMOTE_VERSION_INFO_REPORTED, handle, status, version, manufacturer_name, subversion);
98 if (ret < 0) {
99 LOG_WARN(
100 "Failed for handle %d, status %s, version %s, manufacturer_name %s, subversion %s, error %d",
101 handle,
102 common::ToHexString(status).c_str(),
103 common::ToHexString(version).c_str(),
104 common::ToHexString(manufacturer_name).c_str(),
105 common::ToHexString(subversion).c_str(),
106 ret);
107 }
108 }
109
LogMetricA2dpAudioUnderrunEvent(const Address & address,uint64_t encoding_interval_millis,int num_missing_pcm_bytes)110 void LogMetricA2dpAudioUnderrunEvent(
111 const Address& address, uint64_t encoding_interval_millis, int num_missing_pcm_bytes) {
112 int metric_id = 0;
113 if (!address.IsEmpty()) {
114 metric_id = MetricIdManager::GetInstance().AllocateId(address);
115 }
116 int64_t encoding_interval_nanos = encoding_interval_millis * 1000000;
117 int ret = stats_write(
118 BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED, byteField, encoding_interval_nanos, num_missing_pcm_bytes, metric_id);
119 if (ret < 0) {
120 LOG_WARN(
121 "Failed for %s, encoding_interval_nanos %s, num_missing_pcm_bytes %d, error %d",
122 ADDRESS_TO_LOGGABLE_CSTR(address),
123 std::to_string(encoding_interval_nanos).c_str(),
124 num_missing_pcm_bytes,
125 ret);
126 }
127 }
128
LogMetricA2dpAudioOverrunEvent(const Address & address,uint64_t encoding_interval_millis,int num_dropped_buffers,int num_dropped_encoded_frames,int num_dropped_encoded_bytes)129 void LogMetricA2dpAudioOverrunEvent(
130 const Address& address,
131 uint64_t encoding_interval_millis,
132 int num_dropped_buffers,
133 int num_dropped_encoded_frames,
134 int num_dropped_encoded_bytes) {
135 int metric_id = 0;
136 if (!address.IsEmpty()) {
137 metric_id = MetricIdManager::GetInstance().AllocateId(address);
138 }
139
140 int64_t encoding_interval_nanos = encoding_interval_millis * 1000000;
141 int ret = stats_write(
142 BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED,
143 byteField,
144 encoding_interval_nanos,
145 num_dropped_buffers,
146 num_dropped_encoded_frames,
147 num_dropped_encoded_bytes,
148 metric_id);
149 if (ret < 0) {
150 LOG_WARN(
151 "Failed to log for %s, encoding_interval_nanos %s, num_dropped_buffers %d, "
152 "num_dropped_encoded_frames %d, num_dropped_encoded_bytes %d, error %d",
153 ADDRESS_TO_LOGGABLE_CSTR(address),
154 std::to_string(encoding_interval_nanos).c_str(),
155 num_dropped_buffers,
156 num_dropped_encoded_frames,
157 num_dropped_encoded_bytes,
158 ret);
159 }
160 }
161
LogMetricA2dpPlaybackEvent(const Address & address,int playback_state,int audio_coding_mode)162 void LogMetricA2dpPlaybackEvent(const Address& address, int playback_state, int audio_coding_mode) {
163 int metric_id = 0;
164 if (!address.IsEmpty()) {
165 metric_id = MetricIdManager::GetInstance().AllocateId(address);
166 }
167
168 int ret = stats_write(BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED, byteField, playback_state, audio_coding_mode, metric_id);
169 if (ret < 0) {
170 LOG_WARN(
171 "Failed to log for %s, playback_state %d, audio_coding_mode %d,error %d",
172 ADDRESS_TO_LOGGABLE_CSTR(address),
173 playback_state,
174 audio_coding_mode,
175 ret);
176 }
177 }
178
LogMetricHfpPacketLossStats(const Address & address,int num_decoded_frames,double packet_loss_ratio)179 void LogMetricHfpPacketLossStats(
180 const Address& address, int num_decoded_frames, double packet_loss_ratio) {}
181
LogMetricReadRssiResult(const Address & address,uint16_t handle,uint32_t cmd_status,int8_t rssi)182 void LogMetricReadRssiResult(const Address& address, uint16_t handle, uint32_t cmd_status, int8_t rssi) {
183 int metric_id = 0;
184 if (!address.IsEmpty()) {
185 metric_id = MetricIdManager::GetInstance().AllocateId(address);
186 }
187 int ret = stats_write(BLUETOOTH_DEVICE_RSSI_REPORTED, byteField, handle, cmd_status, rssi, metric_id);
188 if (ret < 0) {
189 LOG_WARN(
190 "Failed for %s, handle %d, status %s, rssi %d dBm, error %d",
191 ADDRESS_TO_LOGGABLE_CSTR(address),
192 handle,
193 common::ToHexString(cmd_status).c_str(),
194 rssi,
195 ret);
196 }
197 }
198
LogMetricReadFailedContactCounterResult(const Address & address,uint16_t handle,uint32_t cmd_status,int32_t failed_contact_counter)199 void LogMetricReadFailedContactCounterResult(
200 const Address& address, uint16_t handle, uint32_t cmd_status, int32_t failed_contact_counter) {
201 int metric_id = 0;
202 if (!address.IsEmpty()) {
203 metric_id = MetricIdManager::GetInstance().AllocateId(address);
204 }
205 int ret = stats_write(
206 BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED,
207 byteField,
208 handle,
209 cmd_status,
210 failed_contact_counter,
211 metric_id);
212 if (ret < 0) {
213 LOG_WARN(
214 "Failed for %s, handle %d, status %s, failed_contact_counter %d packets, error %d",
215 ADDRESS_TO_LOGGABLE_CSTR(address),
216 handle,
217 common::ToHexString(cmd_status).c_str(),
218 failed_contact_counter,
219 ret);
220 }
221 }
222
LogMetricReadTxPowerLevelResult(const Address & address,uint16_t handle,uint32_t cmd_status,int32_t transmit_power_level)223 void LogMetricReadTxPowerLevelResult(
224 const Address& address, uint16_t handle, uint32_t cmd_status, int32_t transmit_power_level) {
225 int metric_id = 0;
226 if (!address.IsEmpty()) {
227 metric_id = MetricIdManager::GetInstance().AllocateId(address);
228 }
229 int ret = stats_write(
230 BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED, byteField, handle, cmd_status, transmit_power_level, metric_id);
231 if (ret < 0) {
232 LOG_WARN(
233 "Failed for %s, handle %d, status %s, transmit_power_level %d packets, error %d",
234 ADDRESS_TO_LOGGABLE_CSTR(address),
235 handle,
236 common::ToHexString(cmd_status).c_str(),
237 transmit_power_level,
238 ret);
239 }
240 }
241
LogMetricSmpPairingEvent(const Address & address,uint16_t smp_cmd,android::bluetooth::DirectionEnum direction,uint16_t smp_fail_reason)242 void LogMetricSmpPairingEvent(
243 const Address& address, uint16_t smp_cmd, android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason) {
244 int metric_id = 0;
245 if (!address.IsEmpty()) {
246 metric_id = MetricIdManager::GetInstance().AllocateId(address);
247 }
248 int ret =
249 stats_write(BLUETOOTH_SMP_PAIRING_EVENT_REPORTED, byteField, smp_cmd, direction, smp_fail_reason, metric_id);
250 if (ret < 0) {
251 LOG_WARN(
252 "Failed for %s, smp_cmd %s, direction %d, smp_fail_reason %s, error %d",
253 ADDRESS_TO_LOGGABLE_CSTR(address),
254 common::ToHexString(smp_cmd).c_str(),
255 direction,
256 common::ToHexString(smp_fail_reason).c_str(),
257 ret);
258 }
259 }
260
LogMetricClassicPairingEvent(const Address & address,uint16_t handle,uint32_t hci_cmd,uint16_t hci_event,uint16_t cmd_status,uint16_t reason_code,int64_t event_value)261 void LogMetricClassicPairingEvent(
262 const Address& address,
263 uint16_t handle,
264 uint32_t hci_cmd,
265 uint16_t hci_event,
266 uint16_t cmd_status,
267 uint16_t reason_code,
268 int64_t event_value) {
269 int metric_id = 0;
270 if (!address.IsEmpty()) {
271 metric_id = MetricIdManager::GetInstance().AllocateId(address);
272 }
273 int ret = stats_write(
274 BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED,
275 byteField,
276 handle,
277 hci_cmd,
278 hci_event,
279 cmd_status,
280 reason_code,
281 event_value,
282 metric_id);
283 if (ret < 0) {
284 LOG_WARN(
285 "Failed for %s, handle %d, hci_cmd %s, hci_event %s, cmd_status %s, "
286 "reason %s, event_value %s, error %d",
287 ADDRESS_TO_LOGGABLE_CSTR(address),
288 handle,
289 common::ToHexString(hci_cmd).c_str(),
290 common::ToHexString(hci_event).c_str(),
291 common::ToHexString(cmd_status).c_str(),
292 common::ToHexString(reason_code).c_str(),
293 std::to_string(event_value).c_str(),
294 ret);
295 }
296
297 if (static_cast<EventCode>(hci_event) == EventCode::SIMPLE_PAIRING_COMPLETE) {
298 common::LogConnectionAdminAuditEvent("Pairing", address, static_cast<ErrorCode>(cmd_status));
299 }
300 }
301
LogMetricSdpAttribute(const Address & address,uint16_t protocol_uuid,uint16_t attribute_id,size_t attribute_size,const char * attribute_value)302 void LogMetricSdpAttribute(
303 const Address& address,
304 uint16_t protocol_uuid,
305 uint16_t attribute_id,
306 size_t attribute_size,
307 const char* attribute_value) {
308 int metric_id = 0;
309 if (!address.IsEmpty()) {
310 metric_id = MetricIdManager::GetInstance().AllocateId(address);
311 }
312 BytesField attribute_field(attribute_value, attribute_size);
313 int ret =
314 stats_write(BLUETOOTH_SDP_ATTRIBUTE_REPORTED, byteField, protocol_uuid, attribute_id, attribute_field, metric_id);
315 if (ret < 0) {
316 LOG_WARN(
317 "Failed for %s, protocol_uuid %s, attribute_id %s, error %d",
318 ADDRESS_TO_LOGGABLE_CSTR(address),
319 common::ToHexString(protocol_uuid).c_str(),
320 common::ToHexString(attribute_id).c_str(),
321 ret);
322 }
323 }
324
LogMetricSocketConnectionState(const Address & address,int port,int type,android::bluetooth::SocketConnectionstateEnum connection_state,int64_t tx_bytes,int64_t rx_bytes,int uid,int server_port,android::bluetooth::SocketRoleEnum socket_role)325 void LogMetricSocketConnectionState(
326 const Address& address,
327 int port,
328 int type,
329 android::bluetooth::SocketConnectionstateEnum connection_state,
330 int64_t tx_bytes,
331 int64_t rx_bytes,
332 int uid,
333 int server_port,
334 android::bluetooth::SocketRoleEnum socket_role) {
335 int metric_id = 0;
336 if (!address.IsEmpty()) {
337 metric_id = MetricIdManager::GetInstance().AllocateId(address);
338 }
339 int ret = stats_write(
340 BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED,
341 byteField,
342 port,
343 type,
344 connection_state,
345 tx_bytes,
346 rx_bytes,
347 uid,
348 server_port,
349 socket_role,
350 metric_id);
351 if (ret < 0) {
352 LOG_WARN(
353 "Failed for %s, port %d, type %d, state %d, tx_bytes %s, rx_bytes %s, uid %d, server_port %d, "
354 "socket_role %d, error %d",
355 ADDRESS_TO_LOGGABLE_CSTR(address),
356 port,
357 type,
358 connection_state,
359 std::to_string(tx_bytes).c_str(),
360 std::to_string(rx_bytes).c_str(),
361 uid,
362 server_port,
363 socket_role,
364 ret);
365 }
366 }
367
LogMetricManufacturerInfo(const Address & address,android::bluetooth::AddressTypeEnum address_type,android::bluetooth::DeviceInfoSrcEnum source_type,const std::string & source_name,const std::string & manufacturer,const std::string & model,const std::string & hardware_version,const std::string & software_version)368 void LogMetricManufacturerInfo(
369 const Address& address,
370 android::bluetooth::AddressTypeEnum address_type,
371 android::bluetooth::DeviceInfoSrcEnum source_type,
372 const std::string& source_name,
373 const std::string& manufacturer,
374 const std::string& model,
375 const std::string& hardware_version,
376 const std::string& software_version) {
377 int metric_id = 0;
378 if (!address.IsEmpty()) {
379 metric_id = MetricIdManager::GetInstance().AllocateId(address);
380 }
381 int ret = stats_write(
382 BLUETOOTH_DEVICE_INFO_REPORTED,
383 byteField,
384 source_type,
385 source_name.c_str(),
386 manufacturer.c_str(),
387 model.c_str(),
388 hardware_version.c_str(),
389 software_version.c_str(),
390 metric_id,
391 address_type,
392 address.address[5],
393 address.address[4],
394 address.address[3]);
395 if (ret < 0) {
396 LOG_WARN(
397 "Failed for %s, source_type %d, source_name %s, manufacturer %s, model %s, "
398 "hardware_version %s, "
399 "software_version %s, MAC address type %d MAC address prefix %d %d %d, error %d",
400 ADDRESS_TO_LOGGABLE_CSTR(address),
401 source_type,
402 source_name.c_str(),
403 manufacturer.c_str(),
404 model.c_str(),
405 hardware_version.c_str(),
406 software_version.c_str(),
407 address_type,
408 address.address[5],
409 address.address[4],
410 address.address[3],
411 ret);
412 }
413 }
414
LogMetricBluetoothHalCrashReason(const Address & address,uint32_t error_code,uint32_t vendor_error_code)415 void LogMetricBluetoothHalCrashReason(
416 const Address& address,
417 uint32_t error_code,
418 uint32_t vendor_error_code) {
419 int ret =
420 stats_write(BLUETOOTH_HAL_CRASH_REASON_REPORTED, 0 /* metric_id */, byteField, error_code, vendor_error_code);
421 if (ret < 0) {
422 LOG_WARN(
423 "Failed for %s, error_code %s, vendor_error_code %s, error %d",
424 ADDRESS_TO_LOGGABLE_CSTR(address),
425 common::ToHexString(error_code).c_str(),
426 common::ToHexString(vendor_error_code).c_str(),
427 ret);
428 }
429 }
430
LogMetricBluetoothLocalSupportedFeatures(uint32_t page_num,uint64_t features)431 void LogMetricBluetoothLocalSupportedFeatures(uint32_t page_num, uint64_t features) {
432 int ret = stats_write(BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED, page_num, features);
433 if (ret < 0) {
434 LOG_WARN(
435 "Failed for LogMetricBluetoothLocalSupportedFeatures, "
436 "page_num %d, features %s, error %d",
437 page_num,
438 std::to_string(features).c_str(),
439 ret);
440 }
441 }
442
LogMetricBluetoothLocalVersions(uint32_t lmp_manufacturer_name,uint8_t lmp_version,uint32_t lmp_subversion,uint8_t hci_version,uint32_t hci_revision)443 void LogMetricBluetoothLocalVersions(
444 uint32_t lmp_manufacturer_name,
445 uint8_t lmp_version,
446 uint32_t lmp_subversion,
447 uint8_t hci_version,
448 uint32_t hci_revision) {
449 int ret = stats_write(
450 BLUETOOTH_LOCAL_VERSIONS_REPORTED,
451 static_cast<int32_t>(lmp_manufacturer_name),
452 static_cast<int32_t>(lmp_version),
453 static_cast<int32_t>(lmp_subversion),
454 static_cast<int32_t>(hci_version),
455 static_cast<int32_t>(hci_revision));
456 if (ret < 0) {
457 LOG_WARN(
458 "Failed for LogMetricBluetoothLocalVersions, "
459 "lmp_manufacturer_name %d, lmp_version %hhu, lmp_subversion %d, hci_version %hhu, hci_revision %d, error %d",
460 lmp_manufacturer_name,
461 lmp_version,
462 lmp_subversion,
463 hci_version,
464 hci_revision,
465 ret);
466 }
467 }
468
LogMetricBluetoothDisconnectionReasonReported(uint32_t reason,const Address & address,uint32_t connection_handle)469 void LogMetricBluetoothDisconnectionReasonReported(
470 uint32_t reason, const Address& address, uint32_t connection_handle) {
471 int metric_id = 0;
472 if (!address.IsEmpty()) {
473 metric_id = MetricIdManager::GetInstance().AllocateId(address);
474 }
475 int ret = stats_write(BLUETOOTH_DISCONNECTION_REASON_REPORTED, reason, metric_id, connection_handle);
476 if (ret < 0) {
477 LOG_WARN(
478 "Failed for LogMetricBluetoothDisconnectionReasonReported, "
479 "reason %d, metric_id %d, connection_handle %d, error %d",
480 reason,
481 metric_id,
482 connection_handle,
483 ret);
484 }
485 }
486
LogMetricBluetoothRemoteSupportedFeatures(const Address & address,uint32_t page,uint64_t features,uint32_t connection_handle)487 void LogMetricBluetoothRemoteSupportedFeatures(
488 const Address& address, uint32_t page, uint64_t features, uint32_t connection_handle) {
489 int metric_id = 0;
490 if (!address.IsEmpty()) {
491 metric_id = MetricIdManager::GetInstance().AllocateId(address);
492 }
493 int ret = stats_write(BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED, metric_id, page, features, connection_handle);
494 if (ret < 0) {
495 LOG_WARN(
496 "Failed for LogMetricBluetoothRemoteSupportedFeatures, "
497 "metric_id %d, page %d, features %s, connection_handle %d, error %d",
498 metric_id,
499 page,
500 std::to_string(features).c_str(),
501 connection_handle,
502 ret);
503 }
504 }
505
LogMetricBluetoothCodePathCounterMetrics(int32_t key,int64_t count)506 void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) {
507 int ret = stats_write(BLUETOOTH_CODE_PATH_COUNTER, key, count);
508 if (ret < 0) {
509 LOG_WARN(
510 "Failed counter metrics for %d, count %s, error %d",
511 key, std::to_string(count).c_str(), ret);
512 }
513 }
514
LogMetricBluetoothLEConnectionMetricEvent(const Address & address,android::bluetooth::le::LeConnectionOriginType origin_type,android::bluetooth::le::LeConnectionType connection_type,android::bluetooth::le::LeConnectionState transaction_state,std::vector<std::pair<os::ArgumentType,int>> & argument_list)515 void LogMetricBluetoothLEConnectionMetricEvent(
516 const Address& address,
517 android::bluetooth::le::LeConnectionOriginType origin_type,
518 android::bluetooth::le::LeConnectionType connection_type,
519 android::bluetooth::le::LeConnectionState transaction_state,
520 std::vector<std::pair<os::ArgumentType, int>>& argument_list) {
521 bluetooth::metrics::MetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent(
522 address, origin_type, connection_type, transaction_state, argument_list);
523 }
524
LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options)525 void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options) {
526 int metric_id = 0;
527 if (!session_options.remote_address.IsEmpty()) {
528 metric_id = MetricIdManager::GetInstance().AllocateId(session_options.remote_address);
529 }
530 int ret = stats_write(
531 BLUETOOTH_LE_SESSION_CONNECTED,
532 session_options.acl_connection_state,
533 session_options.origin_type,
534 session_options.transaction_type,
535 session_options.transaction_state,
536 session_options.latency,
537 metric_id,
538 session_options.app_uid,
539 session_options.acl_latency,
540 session_options.status,
541 session_options.is_cancelled);
542
543 if (ret < 0) {
544 LOG_WARN(
545 "Failed BluetoothLeSessionConnected - Address: %s, ACL Connection State: %s, Origin Type: "
546 "%s",
547 ADDRESS_TO_LOGGABLE_CSTR(session_options.remote_address),
548 common::ToHexString(session_options.acl_connection_state).c_str(),
549 common::ToHexString(session_options.origin_type).c_str());
550 }
551 }
552
553 } // namespace os
554 } // namespace bluetooth
555
556