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