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