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