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