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