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