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 #if TARGET_FLOSS
17 #include "hci/msft.h"
18 
19 #include <bluetooth/log.h>
20 #include <com_android_bluetooth_flags.h>
21 #include <hardware/bt_common_types.h>
22 
23 #include "hal/hci_hal.h"
24 #include "hci/hci_layer.h"
25 #include "hci/hci_packets.h"
26 
27 namespace bluetooth {
28 namespace hci {
29 
30 // https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/
31 //         microsoft-defined-bluetooth-hci-commands-and-events
32 constexpr uint8_t kMsftEventPrefixLengthMax = 0x20;
33 
34 struct Msft {
35   // MSFT opcode needs to be configured from Bluetooth driver.
36   std::optional<uint16_t> opcode;
37   uint64_t features{0};
38   std::vector<uint8_t> prefix;
39 };
40 
__anon5145fdb90102() 41 const ModuleFactory MsftExtensionManager::Factory = ModuleFactory([]() { return new MsftExtensionManager(); });
42 
43 struct MsftExtensionManager::impl {
implbluetooth::hci::MsftExtensionManager::impl44   impl(Module* module) : module_(module){};
45 
~implbluetooth::hci::MsftExtensionManager::impl46   ~impl() {}
47 
startbluetooth::hci::MsftExtensionManager::impl48   void start(os::Handler* handler, hal::HciHal* hal, hci::HciLayer* hci_layer) {
49     log::info("MsftExtensionManager start()");
50     module_handler_ = handler;
51     hal_ = hal;
52     hci_layer_ = hci_layer;
53 
54     /*
55      * The MSFT opcode is assigned by Bluetooth controller vendors.
56      * Query the kernel/drivers to derive the MSFT opcode so that
57      * we can issue MSFT vendor specific commands.
58      */
59     if (!supports_msft_extensions()) {
60       log::info("MSFT extension is not supported.");
61       return;
62     }
63 
64     /*
65      * The vendor prefix is required to distinguish among the vendor events
66      * of different vendor specifications. Read the supported features to
67      * derive the vendor prefix as well as other supported features.
68      */
69     hci_layer_->EnqueueCommand(
70         MsftReadSupportedFeaturesBuilder::Create(static_cast<OpCode>(msft_.opcode.value())),
71         module_handler_->BindOnceOn(this, &impl::on_msft_read_supported_features_complete));
72   }
73 
stopbluetooth::hci::MsftExtensionManager::impl74   void stop() {
75     log::info("MsftExtensionManager stop()");
76   }
77 
handle_rssi_eventbluetooth::hci::MsftExtensionManager::impl78   void handle_rssi_event(MsftRssiEventPayloadView /* view */) {
79     log::warn("The Microsoft MSFT_RSSI_EVENT is not supported yet.");
80   }
81 
handle_le_monitor_device_eventbluetooth::hci::MsftExtensionManager::impl82   void handle_le_monitor_device_event(MsftLeMonitorDeviceEventPayloadView view) {
83     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
84 
85     // The monitor state is 0x00 when the controller stops monitoring the device.
86     if (view.GetMonitorState() == 0x00 || view.GetMonitorState() == 0x01) {
87       AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info;
88       on_found_on_lost_info.advertiser_address_type = view.GetAddressType();
89       on_found_on_lost_info.advertiser_address = view.GetBdAddr();
90       on_found_on_lost_info.advertiser_state = view.GetMonitorState();
91       on_found_on_lost_info.monitor_handle = view.GetMonitorHandle();
92       scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
93     } else {
94       log::warn("The Microsoft vendor event monitor state is invalid.");
95       return;
96     }
97   }
98 
handle_msft_eventsbluetooth::hci::MsftExtensionManager::impl99   void handle_msft_events(VendorSpecificEventView view) {
100     auto payload = view.GetPayload();
101     for (size_t i = 0; i < msft_.prefix.size() - 1; i++) {
102       if (msft_.prefix[i + 1] != payload[i]) {
103         log::warn("The Microsoft vendor event prefix does not match.");
104         return;
105       }
106     }
107 
108     auto msft_view = MsftEventPayloadView::Create(
109         payload.GetLittleEndianSubview(msft_.prefix.size() - 1, payload.size()));
110     log::assert_that(msft_view.IsValid(), "assert failed: msft_view.IsValid()");
111 
112     MsftEventCode ev_code = msft_view.GetMsftEventCode();
113     switch (ev_code) {
114       case MsftEventCode::MSFT_RSSI_EVENT:
115         handle_rssi_event(MsftRssiEventPayloadView::Create(msft_view));
116         break;
117       case MsftEventCode::MSFT_LE_MONITOR_DEVICE_EVENT:
118         handle_le_monitor_device_event(MsftLeMonitorDeviceEventPayloadView::Create(msft_view));
119         break;
120       default:
121         log::warn("Unknown MSFT event code {}", ev_code);
122         break;
123     }
124   }
125 
supports_msft_extensionsbluetooth::hci::MsftExtensionManager::impl126   bool supports_msft_extensions() {
127     if (msft_.opcode.has_value()) return true;
128 
129     uint16_t opcode = hal_->getMsftOpcode();
130     if (opcode == 0) return false;
131 
132     msft_.opcode = opcode;
133     log::info("MSFT opcode 0x{:04x}", msft_.opcode.value());
134     return true;
135   }
136 
msft_adv_monitor_addbluetooth::hci::MsftExtensionManager::impl137   void msft_adv_monitor_add(const MsftAdvMonitor& monitor, MsftAdvMonitorAddCallback cb) {
138     if (!supports_msft_extensions()) {
139       log::warn("Disallowed as MSFT extension is not supported.");
140       return;
141     }
142 
143     if (com::android::bluetooth::flags::msft_addr_tracking_quirk()) {
144       if (monitor.condition_type != MSFT_CONDITION_TYPE_ADDRESS &&
145           monitor.condition_type != MSFT_CONDITION_TYPE_PATTERNS) {
146         log::warn("Disallowed as MSFT condition type {} is not supported.", monitor.condition_type);
147         return;
148       }
149 
150       if (monitor.condition_type == MSFT_CONDITION_TYPE_ADDRESS) {
151         msft_adv_monitor_add_cb_ = cb;
152         Address addr;
153         Address::FromString(monitor.addr_info.bd_addr.ToString(), addr);
154         hci_layer_->EnqueueCommand(
155             MsftLeMonitorAdvConditionAddressBuilder::Create(
156                 static_cast<OpCode>(msft_.opcode.value()),
157                 monitor.rssi_threshold_high,
158                 monitor.rssi_threshold_low,
159                 monitor.rssi_threshold_low_time_interval,
160                 monitor.rssi_sampling_period,
161                 monitor.addr_info.addr_type,
162                 addr),
163             module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_add_complete));
164         return;
165       }
166     }
167 
168     std::vector<MsftLeMonitorAdvConditionPattern> patterns;
169     MsftLeMonitorAdvConditionPattern pattern;
170     // The Microsoft Extension specifies 1 octet for the number of patterns.
171     // However, the max number of patters should not exceed 61.
172     // (255 - 1 (packet type) - 2 (OGF/OCF) - 1 (length) - 7 (MSFT command parameters)) /
173     // 4 (min size of a pattern) = 61
174     if (monitor.patterns.size() > 61) {
175       log::error("Number of MSFT patterns {} is too large", monitor.patterns.size());
176       return;
177     }
178     for (auto& p : monitor.patterns) {
179       pattern.ad_type_ = p.ad_type;
180       pattern.start_of_pattern_ = p.start_byte;
181       pattern.pattern_ = p.pattern;
182       patterns.push_back(pattern);
183     }
184 
185     msft_adv_monitor_add_cb_ = cb;
186     hci_layer_->EnqueueCommand(
187         MsftLeMonitorAdvConditionPatternsBuilder::Create(
188             static_cast<OpCode>(msft_.opcode.value()),
189             monitor.rssi_threshold_high,
190             monitor.rssi_threshold_low,
191             monitor.rssi_threshold_low_time_interval,
192             monitor.rssi_sampling_period,
193             patterns),
194         module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_add_complete));
195   }
196 
msft_adv_monitor_removebluetooth::hci::MsftExtensionManager::impl197   void msft_adv_monitor_remove(uint8_t monitor_handle, MsftAdvMonitorRemoveCallback cb) {
198     if (!supports_msft_extensions()) {
199       log::warn("Disallowed as MSFT extension is not supported.");
200       return;
201     }
202 
203     msft_adv_monitor_remove_cb_ = cb;
204     hci_layer_->EnqueueCommand(
205         MsftLeCancelMonitorAdvBuilder::Create(
206             static_cast<OpCode>(msft_.opcode.value()), monitor_handle),
207         module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_remove_complete));
208   }
209 
msft_adv_monitor_enablebluetooth::hci::MsftExtensionManager::impl210   void msft_adv_monitor_enable(bool enable, MsftAdvMonitorEnableCallback cb) {
211     if (!supports_msft_extensions()) {
212       log::warn("Disallowed as MSFT extension is not supported.");
213       return;
214     }
215 
216     msft_adv_monitor_enable_cb_ = cb;
217     hci_layer_->EnqueueCommand(
218         MsftLeSetAdvFilterEnableBuilder::Create(static_cast<OpCode>(msft_.opcode.value()), enable),
219         module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_enable_complete));
220   }
221 
set_scanning_callbackbluetooth::hci::MsftExtensionManager::impl222   void set_scanning_callback(ScanningCallback* callbacks) {
223     scanning_callbacks_ = callbacks;
224   }
225 
226   /*
227    * Get the event prefix from the packet for configuring MSFT's
228    * Vendor Specific events. Also get the MSFT supported features.
229    */
on_msft_read_supported_features_completebluetooth::hci::MsftExtensionManager::impl230   void on_msft_read_supported_features_complete(CommandCompleteView view) {
231     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
232     auto status_view = MsftReadSupportedFeaturesCommandCompleteView::Create(MsftCommandCompleteView::Create(view));
233     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
234 
235     if (status_view.GetStatus() != ErrorCode::SUCCESS) {
236       log::warn("MSFT Command complete status {}", ErrorCodeText(status_view.GetStatus()));
237       return;
238     }
239 
240     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
241     if (sub_opcode != MsftSubcommandOpcode::MSFT_READ_SUPPORTED_FEATURES) {
242       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
243       return;
244     }
245 
246     msft_.features = status_view.GetSupportedFeatures();
247 
248     // Save the vendor prefix to distinguish upcoming MSFT vendor events.
249     auto prefix = status_view.GetPrefix();
250     msft_.prefix.assign(prefix.begin(), prefix.end());
251 
252     if (prefix.size() > kMsftEventPrefixLengthMax)
253       log::warn("The MSFT prefix length {} is too large", (unsigned int)prefix.size());
254 
255     log::info("MSFT features 0x{:016x} prefix length {}", msft_.features, prefix.size());
256 
257     // We are here because Microsoft Extension is supported. Hence, register the
258     // first octet of the vendor prefix so that the vendor specific event manager
259     // can dispatch the event correctly.
260     // Note: registration of the first octet of the vendor prefix is sufficient
261     //       because each vendor controller should ensure that the first octet
262     //       is unique within the vendor's events.
263     hci_layer_->RegisterVendorSpecificEventHandler(
264         static_cast<VseSubeventCode>(msft_.prefix[0]),
265         module_handler_->BindOn(this, &impl::handle_msft_events));
266   }
267 
on_msft_adv_monitor_add_completebluetooth::hci::MsftExtensionManager::impl268   void on_msft_adv_monitor_add_complete(CommandCompleteView view) {
269     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
270     auto status_view =
271         MsftLeMonitorAdvCommandCompleteView::Create(MsftCommandCompleteView::Create(view));
272     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
273 
274     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
275     if (sub_opcode != MsftSubcommandOpcode::MSFT_LE_MONITOR_ADV) {
276       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
277       return;
278     }
279 
280     msft_adv_monitor_add_cb_.Run(status_view.GetMonitorHandle(), status_view.GetStatus());
281   }
282 
on_msft_adv_monitor_remove_completebluetooth::hci::MsftExtensionManager::impl283   void on_msft_adv_monitor_remove_complete(CommandCompleteView view) {
284     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
285     auto status_view =
286         MsftLeCancelMonitorAdvCommandCompleteView::Create(MsftCommandCompleteView::Create(view));
287     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
288 
289     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
290     if (sub_opcode != MsftSubcommandOpcode::MSFT_LE_CANCEL_MONITOR_ADV) {
291       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
292       return;
293     }
294 
295     msft_adv_monitor_remove_cb_.Run(status_view.GetStatus());
296   }
297 
on_msft_adv_monitor_enable_completebluetooth::hci::MsftExtensionManager::impl298   void on_msft_adv_monitor_enable_complete(CommandCompleteView view) {
299     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
300     auto status_view =
301         MsftLeSetAdvFilterEnableCommandCompleteView::Create(MsftCommandCompleteView::Create(view));
302     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
303 
304     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
305     if (sub_opcode != MsftSubcommandOpcode::MSFT_LE_SET_ADV_FILTER_ENABLE) {
306       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
307       return;
308     }
309 
310     msft_adv_monitor_enable_cb_.Run(status_view.GetStatus());
311   }
312 
313   Module* module_;
314   os::Handler* module_handler_;
315   hal::HciHal* hal_;
316   hci::HciLayer* hci_layer_;
317   Msft msft_;
318   MsftAdvMonitorAddCallback msft_adv_monitor_add_cb_;
319   MsftAdvMonitorRemoveCallback msft_adv_monitor_remove_cb_;
320   MsftAdvMonitorEnableCallback msft_adv_monitor_enable_cb_;
321   ScanningCallback* scanning_callbacks_;
322 };
323 
MsftExtensionManager()324 MsftExtensionManager::MsftExtensionManager() {
325   log::info("MsftExtensionManager()");
326   pimpl_ = std::make_unique<impl>(this);
327 }
328 
ListDependencies(ModuleList * list) const329 void MsftExtensionManager::ListDependencies(ModuleList* list) const {
330   list->add<hal::HciHal>();
331   list->add<hci::HciLayer>();
332 }
333 
Start()334 void MsftExtensionManager::Start() {
335   pimpl_->start(GetHandler(), GetDependency<hal::HciHal>(), GetDependency<hci::HciLayer>());
336 }
337 
Stop()338 void MsftExtensionManager::Stop() {
339   pimpl_->stop();
340 }
341 
ToString() const342 std::string MsftExtensionManager::ToString() const {
343   return "Microsoft Extension Manager";
344 }
345 
SupportsMsftExtensions()346 bool MsftExtensionManager::SupportsMsftExtensions() {
347   return pimpl_->supports_msft_extensions();
348 }
349 
MsftAdvMonitorAdd(const MsftAdvMonitor & monitor,MsftAdvMonitorAddCallback cb)350 void MsftExtensionManager::MsftAdvMonitorAdd(
351     const MsftAdvMonitor& monitor, MsftAdvMonitorAddCallback cb) {
352   CallOn(pimpl_.get(), &impl::msft_adv_monitor_add, monitor, cb);
353 }
354 
MsftAdvMonitorRemove(uint8_t monitor_handle,MsftAdvMonitorRemoveCallback cb)355 void MsftExtensionManager::MsftAdvMonitorRemove(
356     uint8_t monitor_handle, MsftAdvMonitorRemoveCallback cb) {
357   CallOn(pimpl_.get(), &impl::msft_adv_monitor_remove, monitor_handle, cb);
358 }
359 
MsftAdvMonitorEnable(bool enable,MsftAdvMonitorEnableCallback cb)360 void MsftExtensionManager::MsftAdvMonitorEnable(bool enable, MsftAdvMonitorEnableCallback cb) {
361   CallOn(pimpl_.get(), &impl::msft_adv_monitor_enable, enable, cb);
362 }
363 
SetScanningCallback(ScanningCallback * callbacks)364 void MsftExtensionManager::SetScanningCallback(ScanningCallback* callbacks) {
365   CallOn(pimpl_.get(), &impl::set_scanning_callback, callbacks);
366 }
367 
368 }  // namespace hci
369 }  // namespace bluetooth
370 #endif
371