• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 =
__anon1efff76f0102() 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     uint16_t opcode = hal_->getMsftOpcode();
60     if (opcode == 0) {
61       log::info("MSFT extension is not supported.");
62       return;
63     }
64     msft_.opcode = opcode;
65     log::info("MSFT opcode 0x{:04x}", msft_.opcode.value());
66 
67     /*
68      * The vendor prefix is required to distinguish among the vendor events
69      * of different vendor specifications. Read the supported features to
70      * derive the vendor prefix as well as other supported features.
71      */
72     hci_layer_->EnqueueCommand(
73             MsftReadSupportedFeaturesBuilder::Create(static_cast<OpCode>(msft_.opcode.value())),
74             module_handler_->BindOnceOn(this, &impl::on_msft_read_supported_features_complete));
75   }
76 
stopbluetooth::hci::MsftExtensionManager::impl77   void stop() { log::info("MsftExtensionManager stop()"); }
78 
handle_rssi_eventbluetooth::hci::MsftExtensionManager::impl79   void handle_rssi_event(MsftRssiEventPayloadView /* view */) {
80     log::warn("The Microsoft MSFT_RSSI_EVENT is not supported yet.");
81   }
82 
handle_le_monitor_device_eventbluetooth::hci::MsftExtensionManager::impl83   void handle_le_monitor_device_event(MsftLeMonitorDeviceEventPayloadView view) {
84     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
85 
86     // The monitor state is 0x00 when the controller stops monitoring the device.
87     if (view.GetMonitorState() == 0x00 || view.GetMonitorState() == 0x01) {
88       AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info;
89       on_found_on_lost_info.advertiser_address_type = view.GetAddressType();
90       on_found_on_lost_info.advertiser_address = view.GetBdAddr();
91       on_found_on_lost_info.advertiser_state = view.GetMonitorState();
92       on_found_on_lost_info.monitor_handle = view.GetMonitorHandle();
93       scanning_callbacks_->OnTrackAdvFoundLost(on_found_on_lost_info);
94     } else {
95       log::warn("The Microsoft vendor event monitor state is invalid.");
96       return;
97     }
98   }
99 
handle_msft_eventsbluetooth::hci::MsftExtensionManager::impl100   void handle_msft_events(VendorSpecificEventView view) {
101     auto payload = view.GetPayload();
102     for (size_t i = 0; i < msft_.prefix.size() - 1; i++) {
103       if (msft_.prefix[i + 1] != payload[i]) {
104         log::warn("The Microsoft vendor event prefix does not match.");
105         return;
106       }
107     }
108 
109     auto msft_view = MsftEventPayloadView::Create(
110             payload.GetLittleEndianSubview(msft_.prefix.size() - 1, payload.size()));
111     log::assert_that(msft_view.IsValid(), "assert failed: msft_view.IsValid()");
112 
113     MsftEventCode ev_code = msft_view.GetMsftEventCode();
114     switch (ev_code) {
115       case MsftEventCode::MSFT_RSSI_EVENT:
116         handle_rssi_event(MsftRssiEventPayloadView::Create(msft_view));
117         break;
118       case MsftEventCode::MSFT_LE_MONITOR_DEVICE_EVENT:
119         handle_le_monitor_device_event(MsftLeMonitorDeviceEventPayloadView::Create(msft_view));
120         break;
121       default:
122         log::warn("Unknown MSFT event code {}", ev_code);
123         break;
124     }
125   }
126 
supports_msft_extensionsbluetooth::hci::MsftExtensionManager::impl127   bool supports_msft_extensions() { return msft_.opcode.has_value(); }
128 
msft_adv_monitor_addbluetooth::hci::MsftExtensionManager::impl129   void msft_adv_monitor_add(const MsftAdvMonitor& monitor, MsftAdvMonitorAddCallback cb) {
130     if (!supports_msft_extensions()) {
131       log::warn("Disallowed as MSFT extension is not supported.");
132       return;
133     }
134 
135     if (com::android::bluetooth::flags::msft_addr_tracking_quirk()) {
136       if (monitor.condition_type != MSFT_CONDITION_TYPE_ADDRESS &&
137           monitor.condition_type != MSFT_CONDITION_TYPE_PATTERNS) {
138         log::warn("Disallowed as MSFT condition type {} is not supported.", monitor.condition_type);
139         return;
140       }
141 
142       if (monitor.condition_type == MSFT_CONDITION_TYPE_ADDRESS) {
143         msft_adv_monitor_add_cb_ = cb;
144         Address addr;
145         Address::FromString(monitor.addr_info.bd_addr.ToString(), addr);
146         hci_layer_->EnqueueCommand(
147                 MsftLeMonitorAdvConditionAddressBuilder::Create(
148                         static_cast<OpCode>(msft_.opcode.value()), monitor.rssi_threshold_high,
149                         monitor.rssi_threshold_low, monitor.rssi_threshold_low_time_interval,
150                         monitor.rssi_sampling_period, monitor.addr_info.addr_type, addr),
151                 module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_add_complete));
152         return;
153       }
154     }
155 
156     std::vector<MsftLeMonitorAdvConditionPattern> patterns;
157     MsftLeMonitorAdvConditionPattern pattern;
158     // The Microsoft Extension specifies 1 octet for the number of patterns.
159     // However, the max number of patters should not exceed 61.
160     // (255 - 1 (packet type) - 2 (OGF/OCF) - 1 (length) - 7 (MSFT command parameters)) /
161     // 4 (min size of a pattern) = 61
162     if (monitor.patterns.size() > 61) {
163       log::error("Number of MSFT patterns {} is too large", monitor.patterns.size());
164       return;
165     }
166     for (auto& p : monitor.patterns) {
167       pattern.ad_type_ = p.ad_type;
168       pattern.start_of_pattern_ = p.start_byte;
169       pattern.pattern_ = p.pattern;
170       patterns.push_back(pattern);
171     }
172 
173     msft_adv_monitor_add_cb_ = cb;
174     hci_layer_->EnqueueCommand(
175             MsftLeMonitorAdvConditionPatternsBuilder::Create(
176                     static_cast<OpCode>(msft_.opcode.value()), monitor.rssi_threshold_high,
177                     monitor.rssi_threshold_low, monitor.rssi_threshold_low_time_interval,
178                     monitor.rssi_sampling_period, patterns),
179             module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_add_complete));
180   }
181 
msft_adv_monitor_removebluetooth::hci::MsftExtensionManager::impl182   void msft_adv_monitor_remove(uint8_t monitor_handle, MsftAdvMonitorRemoveCallback cb) {
183     if (!supports_msft_extensions()) {
184       log::warn("Disallowed as MSFT extension is not supported.");
185       return;
186     }
187 
188     msft_adv_monitor_remove_cb_ = cb;
189     hci_layer_->EnqueueCommand(
190             MsftLeCancelMonitorAdvBuilder::Create(static_cast<OpCode>(msft_.opcode.value()),
191                                                   monitor_handle),
192             module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_remove_complete));
193   }
194 
msft_adv_monitor_enablebluetooth::hci::MsftExtensionManager::impl195   void msft_adv_monitor_enable(bool enable, MsftAdvMonitorEnableCallback cb) {
196     if (!supports_msft_extensions()) {
197       log::warn("Disallowed as MSFT extension is not supported.");
198       return;
199     }
200 
201     msft_adv_monitor_enable_cb_ = cb;
202     hci_layer_->EnqueueCommand(
203             MsftLeSetAdvFilterEnableBuilder::Create(static_cast<OpCode>(msft_.opcode.value()),
204                                                     enable),
205             module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_enable_complete));
206   }
207 
set_scanning_callbackbluetooth::hci::MsftExtensionManager::impl208   void set_scanning_callback(ScanningCallback* callbacks) { scanning_callbacks_ = callbacks; }
209 
210   /*
211    * Get the event prefix from the packet for configuring MSFT's
212    * Vendor Specific events. Also get the MSFT supported features.
213    */
on_msft_read_supported_features_completebluetooth::hci::MsftExtensionManager::impl214   void on_msft_read_supported_features_complete(CommandCompleteView view) {
215     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
216     auto status_view = MsftReadSupportedFeaturesCommandCompleteView::Create(
217             MsftCommandCompleteView::Create(view));
218     if (!status_view.IsValid()) {
219       log::error("MSFT Read supported features failed");
220       msft_.opcode = std::nullopt;
221       return;
222     }
223 
224     if (status_view.GetStatus() != ErrorCode::SUCCESS) {
225       log::warn("MSFT Command complete status {}", ErrorCodeText(status_view.GetStatus()));
226       return;
227     }
228 
229     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
230     if (sub_opcode != MsftSubcommandOpcode::MSFT_READ_SUPPORTED_FEATURES) {
231       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
232       return;
233     }
234 
235     msft_.features = status_view.GetSupportedFeatures();
236 
237     // Save the vendor prefix to distinguish upcoming MSFT vendor events.
238     auto prefix = status_view.GetPrefix();
239     msft_.prefix.assign(prefix.begin(), prefix.end());
240 
241     if (prefix.size() > kMsftEventPrefixLengthMax) {
242       log::warn("The MSFT prefix length {} is too large", (unsigned int)prefix.size());
243     }
244 
245     log::info("MSFT features 0x{:016x} prefix length {}", msft_.features, prefix.size());
246 
247     // We are here because Microsoft Extension is supported. Hence, register the
248     // first octet of the vendor prefix so that the vendor specific event manager
249     // can dispatch the event correctly.
250     // Note: registration of the first octet of the vendor prefix is sufficient
251     //       because each vendor controller should ensure that the first octet
252     //       is unique within the vendor's events.
253     hci_layer_->RegisterVendorSpecificEventHandler(
254             static_cast<VseSubeventCode>(msft_.prefix[0]),
255             module_handler_->BindOn(this, &impl::handle_msft_events));
256   }
257 
on_msft_adv_monitor_add_completebluetooth::hci::MsftExtensionManager::impl258   void on_msft_adv_monitor_add_complete(CommandCompleteView view) {
259     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
260     auto status_view =
261             MsftLeMonitorAdvCommandCompleteView::Create(MsftCommandCompleteView::Create(view));
262     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
263 
264     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
265     if (sub_opcode != MsftSubcommandOpcode::MSFT_LE_MONITOR_ADV) {
266       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
267       return;
268     }
269 
270     msft_adv_monitor_add_cb_.Run(status_view.GetMonitorHandle(), status_view.GetStatus());
271   }
272 
on_msft_adv_monitor_remove_completebluetooth::hci::MsftExtensionManager::impl273   void on_msft_adv_monitor_remove_complete(CommandCompleteView view) {
274     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
275     auto status_view = MsftLeCancelMonitorAdvCommandCompleteView::Create(
276             MsftCommandCompleteView::Create(view));
277     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
278 
279     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
280     if (sub_opcode != MsftSubcommandOpcode::MSFT_LE_CANCEL_MONITOR_ADV) {
281       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
282       return;
283     }
284 
285     msft_adv_monitor_remove_cb_.Run(status_view.GetStatus());
286   }
287 
on_msft_adv_monitor_enable_completebluetooth::hci::MsftExtensionManager::impl288   void on_msft_adv_monitor_enable_complete(CommandCompleteView view) {
289     log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
290     auto status_view = MsftLeSetAdvFilterEnableCommandCompleteView::Create(
291             MsftCommandCompleteView::Create(view));
292     log::assert_that(status_view.IsValid(), "assert failed: status_view.IsValid()");
293 
294     MsftSubcommandOpcode sub_opcode = status_view.GetSubcommandOpcode();
295     if (sub_opcode != MsftSubcommandOpcode::MSFT_LE_SET_ADV_FILTER_ENABLE) {
296       log::warn("Wrong MSFT subcommand opcode {} returned", sub_opcode);
297       return;
298     }
299 
300     msft_adv_monitor_enable_cb_.Run(status_view.GetStatus());
301   }
302 
303   Module* module_;
304   os::Handler* module_handler_;
305   hal::HciHal* hal_;
306   hci::HciLayer* hci_layer_;
307   Msft msft_;
308   MsftAdvMonitorAddCallback msft_adv_monitor_add_cb_;
309   MsftAdvMonitorRemoveCallback msft_adv_monitor_remove_cb_;
310   MsftAdvMonitorEnableCallback msft_adv_monitor_enable_cb_;
311   ScanningCallback* scanning_callbacks_;
312 };
313 
MsftExtensionManager()314 MsftExtensionManager::MsftExtensionManager() {
315   log::info("MsftExtensionManager()");
316   pimpl_ = std::make_unique<impl>(this);
317 }
318 
ListDependencies(ModuleList * list) const319 void MsftExtensionManager::ListDependencies(ModuleList* list) const {
320   list->add<hal::HciHal>();
321   list->add<hci::HciLayer>();
322 }
323 
Start()324 void MsftExtensionManager::Start() {
325   pimpl_->start(GetHandler(), GetDependency<hal::HciHal>(), GetDependency<hci::HciLayer>());
326 }
327 
Stop()328 void MsftExtensionManager::Stop() { pimpl_->stop(); }
329 
ToString() const330 std::string MsftExtensionManager::ToString() const { return "Microsoft Extension Manager"; }
331 
SupportsMsftExtensions()332 bool MsftExtensionManager::SupportsMsftExtensions() { return pimpl_->supports_msft_extensions(); }
333 
MsftAdvMonitorAdd(const MsftAdvMonitor & monitor,MsftAdvMonitorAddCallback cb)334 void MsftExtensionManager::MsftAdvMonitorAdd(const MsftAdvMonitor& monitor,
335                                              MsftAdvMonitorAddCallback cb) {
336   CallOn(pimpl_.get(), &impl::msft_adv_monitor_add, monitor, cb);
337 }
338 
MsftAdvMonitorRemove(uint8_t monitor_handle,MsftAdvMonitorRemoveCallback cb)339 void MsftExtensionManager::MsftAdvMonitorRemove(uint8_t monitor_handle,
340                                                 MsftAdvMonitorRemoveCallback cb) {
341   CallOn(pimpl_.get(), &impl::msft_adv_monitor_remove, monitor_handle, cb);
342 }
343 
MsftAdvMonitorEnable(bool enable,MsftAdvMonitorEnableCallback cb)344 void MsftExtensionManager::MsftAdvMonitorEnable(bool enable, MsftAdvMonitorEnableCallback cb) {
345   CallOn(pimpl_.get(), &impl::msft_adv_monitor_enable, enable, cb);
346 }
347 
SetScanningCallback(ScanningCallback * callbacks)348 void MsftExtensionManager::SetScanningCallback(ScanningCallback* callbacks) {
349   CallOn(pimpl_.get(), &impl::set_scanning_callback, callbacks);
350 }
351 
352 }  // namespace hci
353 }  // namespace bluetooth
354