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 #define LOG_TAG "BluetoothMetrics"
17
18 #include "metrics/metrics.h"
19
20 #include <bluetooth/log.h>
21 #include <metrics/structured_events.h>
22
23 #include "common/time_util.h"
24 #include "metrics/chromeos/metrics_allowlist.h"
25 #include "metrics/chromeos/metrics_event.h"
26 #include "metrics/utils.h"
27 #include "os/log.h"
28
29 namespace bluetooth {
30 namespace metrics {
31
32 static constexpr uint32_t DEVICE_MAJOR_CLASS_MASK = 0x1F00;
33 static constexpr uint32_t DEVICE_MAJOR_CLASS_BIT_OFFSET = 8;
34 static constexpr uint32_t DEVICE_CATEGORY_MASK = 0xFFC0;
35 static constexpr uint32_t DEVICE_CATEGORY_BIT_OFFSET = 6;
36
LogMetricsAdapterStateChanged(uint32_t state)37 void LogMetricsAdapterStateChanged(uint32_t state) {
38 int64_t adapter_state;
39 int64_t boot_time;
40 std::string boot_id;
41
42 if (!GetBootId(&boot_id)) return;
43
44 adapter_state = (int64_t)ToAdapterState(state);
45 boot_time = bluetooth::common::time_get_os_boottime_us();
46
47 log::debug("AdapterStateChanged: {}, {}, {}", boot_id, boot_time, adapter_state);
48
49 ::metrics::structured::events::bluetooth::BluetoothAdapterStateChanged()
50 .SetBootId(boot_id)
51 .SetSystemTime(boot_time)
52 .SetIsFloss(true)
53 .SetAdapterState(adapter_state)
54 .Record();
55
56 LogMetricsChipsetInfoReport();
57 }
58
LogMetricsBondCreateAttempt(RawAddress * addr,uint32_t device_type)59 void LogMetricsBondCreateAttempt(RawAddress* addr, uint32_t device_type) {
60 ConnectionType connection_type;
61 int64_t boot_time;
62 std::string addr_string;
63 std::string boot_id;
64
65 if (!GetBootId(&boot_id)) return;
66
67 addr_string = addr->ToString();
68 boot_time = bluetooth::common::time_get_os_boottime_us();
69 connection_type = ToPairingDeviceType(addr_string, device_type);
70
71 log::debug(
72 "PairingStateChanged: {}, {}, {}, {}, {}",
73 boot_id,
74 (int)boot_time,
75 *addr,
76 (int)connection_type,
77 (int)PairingState::PAIR_STARTING);
78
79 ::metrics::structured::events::bluetooth::BluetoothPairingStateChanged()
80 .SetBootId(boot_id)
81 .SetSystemTime(boot_time)
82 .SetDeviceId(addr_string)
83 .SetDeviceType((int64_t)connection_type)
84 .SetPairingState((int64_t)PairingState::PAIR_STARTING)
85 .Record();
86 }
87
LogMetricsBondStateChanged(RawAddress * addr,uint32_t device_type,uint32_t status,uint32_t bond_state,int32_t fail_reason)88 void LogMetricsBondStateChanged(
89 RawAddress* addr, uint32_t device_type, uint32_t status, uint32_t bond_state, int32_t fail_reason) {
90 ConnectionType connection_type;
91 int64_t boot_time;
92 PairingState pairing_state;
93 std::string addr_string;
94 std::string boot_id;
95
96 if (!GetBootId(&boot_id)) return;
97
98 addr_string = addr->ToString();
99 boot_time = bluetooth::common::time_get_os_boottime_us();
100 connection_type = ToPairingDeviceType(addr_string, device_type);
101 pairing_state = ToPairingState(status, bond_state, fail_reason);
102
103 // Ignore the start of pairing event as its logged separated above.
104 if (pairing_state == PairingState::PAIR_STARTING) return;
105
106 // Ignore absurd state.
107 if (pairing_state == PairingState::PAIR_FAIL_END) return;
108
109 log::debug(
110 "PairingStateChanged: {}, {}, {}, {}, {}",
111 boot_id,
112 (int)boot_time,
113 *addr,
114 (int)connection_type,
115 (int)pairing_state);
116
117 ::metrics::structured::events::bluetooth::BluetoothPairingStateChanged()
118 .SetBootId(boot_id)
119 .SetSystemTime(boot_time)
120 .SetDeviceId(addr_string)
121 .SetDeviceType((int64_t)connection_type)
122 .SetPairingState((int64_t)pairing_state)
123 .Record();
124 }
125
LogMetricsDeviceInfoReport(RawAddress * addr,uint32_t device_type,uint32_t class_of_device,uint32_t appearance,uint32_t vendor_id,uint32_t vendor_id_src,uint32_t product_id,uint32_t version)126 void LogMetricsDeviceInfoReport(
127 RawAddress* addr,
128 uint32_t device_type,
129 uint32_t class_of_device,
130 uint32_t appearance,
131 uint32_t vendor_id,
132 uint32_t vendor_id_src,
133 uint32_t product_id,
134 uint32_t version) {
135 int64_t boot_time;
136 std::string addr_string;
137 std::string boot_id;
138 uint32_t major_class;
139 uint32_t category;
140
141 if (!GetBootId(&boot_id)) return;
142
143 addr_string = addr->ToString();
144 boot_time = bluetooth::common::time_get_os_boottime_us();
145
146 major_class = (class_of_device & DEVICE_MAJOR_CLASS_MASK) >> DEVICE_MAJOR_CLASS_BIT_OFFSET;
147 category = (appearance & DEVICE_CATEGORY_MASK) >> DEVICE_CATEGORY_BIT_OFFSET;
148
149 log::debug(
150 "DeviceInfoReport {} {} {} {} {} {} {} {} {} {}",
151 boot_id,
152 (int)boot_time,
153 *addr,
154 (int)device_type,
155 (int)major_class,
156 (int)category,
157 (int)vendor_id,
158 (int)vendor_id_src,
159 (int)product_id,
160 (int)version);
161
162 if (!IsDeviceInfoInAllowlist(vendor_id_src, vendor_id, product_id)) {
163 vendor_id_src = 0;
164 vendor_id = 0;
165 product_id = 0;
166 version = 0;
167 }
168
169 ::metrics::structured::events::bluetooth::BluetoothDeviceInfoReport()
170 .SetBootId(boot_id)
171 .SetSystemTime(boot_time)
172 .SetDeviceId(addr_string)
173 .SetDeviceType(device_type)
174 .SetDeviceClass(major_class)
175 .SetDeviceCategory(category)
176 .SetVendorId(vendor_id)
177 .SetVendorIdSource(vendor_id_src)
178 .SetProductId(product_id)
179 .SetProductVersion(version)
180 .Record();
181 }
182
LogMetricsProfileConnectionStateChanged(RawAddress * addr,uint32_t profile,uint32_t status,uint32_t state)183 void LogMetricsProfileConnectionStateChanged(RawAddress* addr, uint32_t profile, uint32_t status, uint32_t state) {
184 int64_t boot_time;
185 std::string addr_string;
186 std::string boot_id;
187
188 if (!GetBootId(&boot_id)) return;
189
190 addr_string = addr->ToString();
191 boot_time = bluetooth::common::time_get_os_boottime_us();
192
193 ProfileConnectionEvent event = ToProfileConnectionEvent(addr_string, profile, status, state);
194
195 if (Profile::UNKNOWN == (Profile)event.profile) return;
196
197 log::debug(
198 "ProfileConnectionStateChanged: {}, {}, {}, {}, {}, {}",
199 boot_id,
200 (int)boot_time,
201 *addr,
202 (int)event.type,
203 (int)event.profile,
204 (int)event.state);
205
206 ::metrics::structured::events::bluetooth::BluetoothProfileConnectionStateChanged()
207 .SetBootId(boot_id)
208 .SetSystemTime(boot_time)
209 .SetDeviceId(addr_string)
210 .SetStateChangeType((int64_t)event.type)
211 .SetProfile((int64_t)event.profile)
212 .SetProfileConnectionState((int64_t)event.state)
213 .Record();
214 }
215
LogMetricsAclConnectAttempt(RawAddress * addr,uint32_t acl_state)216 void LogMetricsAclConnectAttempt(RawAddress* addr, uint32_t acl_state) {
217 int64_t boot_time = bluetooth::common::time_get_os_boottime_us();
218 std::string addr_string = addr->ToString();
219
220 // At this time we don't know the transport layer, therefore pending on sending the event
221 PendingAclConnectAttemptEvent(addr_string, boot_time, acl_state);
222 }
223
LogMetricsAclConnectionStateChanged(RawAddress * addr,uint32_t transport,uint32_t acl_status,uint32_t acl_state,uint32_t direction,uint32_t hci_reason)224 void LogMetricsAclConnectionStateChanged(
225 RawAddress* addr,
226 uint32_t transport,
227 uint32_t acl_status,
228 uint32_t acl_state,
229 uint32_t direction,
230 uint32_t hci_reason) {
231 int64_t boot_time;
232 std::string addr_string;
233 std::string boot_id;
234 bool attempt_found;
235 AclConnectionEvent event;
236
237 boot_time = bluetooth::common::time_get_os_boottime_us();
238 addr_string = addr->ToString();
239
240 event = ToAclConnectionEvent(addr_string, boot_time, acl_status, acl_state, direction, hci_reason);
241
242 if (!GetBootId(&boot_id)) {
243 return;
244 }
245
246 log::debug(
247 "AclConnectionStateChanged: {}, {}, {}, {}, {}, {}, {}, {}",
248 boot_id,
249 (int)event.start_time,
250 *addr,
251 (int)transport,
252 (int)event.direction,
253 (int)event.initiator,
254 (int)event.state,
255 (int)event.start_status);
256
257 ::metrics::structured::events::bluetooth::BluetoothAclConnectionStateChanged()
258 .SetBootId(boot_id)
259 .SetSystemTime(event.start_time)
260 .SetIsFloss(true)
261 .SetDeviceId(addr_string)
262 .SetDeviceType(transport)
263 .SetConnectionDirection(event.direction)
264 .SetConnectionInitiator(event.initiator)
265 .SetStateChangeType(event.state)
266 .SetAclConnectionState(event.start_status)
267 .Record();
268
269 log::debug(
270 "AclConnectionStateChanged: {}, {}, {}, {}, {}, {}, {}, {}",
271 boot_id,
272 (int)boot_time,
273 *addr,
274 (int)transport,
275 (int)event.direction,
276 (int)event.initiator,
277 (int)event.state,
278 (int)event.status);
279
280 ::metrics::structured::events::bluetooth::BluetoothAclConnectionStateChanged()
281 .SetBootId(boot_id)
282 .SetSystemTime(boot_time)
283 .SetIsFloss(true)
284 .SetDeviceId(addr_string)
285 .SetDeviceType(transport)
286 .SetConnectionDirection(event.direction)
287 .SetConnectionInitiator(event.initiator)
288 .SetStateChangeType(event.state)
289 .SetAclConnectionState(event.status)
290 .Record();
291
292 LogMetricsChipsetInfoReport();
293 }
294
LogMetricsChipsetInfoReport()295 void LogMetricsChipsetInfoReport() {
296 static MetricsChipsetInfo* info = NULL;
297 uint64_t chipset_string_hval = 0;
298 std::string boot_id;
299
300 if (!info) {
301 info = (MetricsChipsetInfo*)calloc(1, sizeof(MetricsChipsetInfo));
302 *info = GetMetricsChipsetInfo();
303 }
304
305 if (!GetBootId(&boot_id)) {
306 return;
307 }
308
309 log::debug(
310 "ChipsetInfoReport: 0x{:x} 0x{:x} {} {}",
311 info->vid,
312 info->pid,
313 info->transport,
314 info->chipset_string);
315
316 if (IsChipsetInfoInAllowList(
317 info->vid, info->pid, info->transport, info->chipset_string.c_str(), &chipset_string_hval)) {
318 ::metrics::structured::events::bluetooth::BluetoothChipsetInfoReport()
319 .SetBootId(boot_id.c_str())
320 .SetVendorId(info->vid)
321 .SetProductId(info->pid)
322 .SetTransport(info->transport)
323 .SetChipsetStringHashValue(chipset_string_hval);
324 }
325 }
326
LogMetricsSuspendIdState(uint32_t state)327 void LogMetricsSuspendIdState(uint32_t state) {
328 int64_t suspend_id_state = 0;
329 int64_t boot_time;
330 std::string boot_id;
331
332 if (!GetBootId(&boot_id)) return;
333
334 boot_time = bluetooth::common::time_get_os_boottime_us();
335
336 suspend_id_state = (int64_t)ToSuspendIdState(state);
337 log::debug("SuspendIdState: {}, {}, {}", boot_id, boot_time, suspend_id_state);
338
339 ::metrics::structured::events::bluetooth::BluetoothSuspendIdStateChanged()
340 .SetBootId(boot_id)
341 .SetSystemTime(boot_time)
342 .SetSuspendIdState(suspend_id_state)
343 .Record();
344 }
345
346 } // namespace metrics
347 } // namespace bluetooth
348