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