1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_sapphire/internal/host/gap/adapter.h"
16
17 #include <endian.h>
18 #include <pw_async/dispatcher.h>
19 #include <pw_bluetooth/hci_commands.emb.h>
20
21 #include "pw_bluetooth_sapphire/internal/host/common/assert.h"
22 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
23 #include "pw_bluetooth_sapphire/internal/host/common/metrics.h"
24 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
25 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_connection_manager.h"
26 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_discovery_manager.h"
27 #include "pw_bluetooth_sapphire/internal/host/gap/event_masks.h"
28 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
29 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_address_manager.h"
30 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_advertising_manager.h"
31 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_connection_manager.h"
32 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_discovery_manager.h"
33 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h"
34 #include "pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
35 #include "pw_bluetooth_sapphire/internal/host/hci-spec/vendor_protocol.h"
36 #include "pw_bluetooth_sapphire/internal/host/hci/android_extended_low_energy_advertiser.h"
37 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
38 #include "pw_bluetooth_sapphire/internal/host/hci/extended_low_energy_advertiser.h"
39 #include "pw_bluetooth_sapphire/internal/host/hci/legacy_low_energy_advertiser.h"
40 #include "pw_bluetooth_sapphire/internal/host/hci/legacy_low_energy_scanner.h"
41 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connector.h"
42 #include "pw_bluetooth_sapphire/internal/host/hci/sequential_command_runner.h"
43 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel_manager.h"
44 #include "pw_bluetooth_sapphire/internal/host/transport/emboss_control_packets.h"
45 #include "pw_bluetooth_sapphire/internal/host/transport/transport.h"
46
47 namespace bt::gap {
48
49 namespace hci_android = hci_spec::vendor::android;
50
51 static constexpr const char* kInspectLowEnergyDiscoveryManagerNodeName =
52 "low_energy_discovery_manager";
53 static constexpr const char* kInspectLowEnergyConnectionManagerNodeName =
54 "low_energy_connection_manager";
55 static constexpr const char* kInspectBrEdrConnectionManagerNodeName =
56 "bredr_connection_manager";
57 static constexpr const char* kInspectBrEdrDiscoveryManagerNodeName =
58 "bredr_discovery_manager";
59
60 // All asynchronous callbacks are posted on the Loop on which this Adapter
61 // instance is created.
62 class AdapterImpl final : public Adapter {
63 public:
64 explicit AdapterImpl(pw::async::Dispatcher& pw_dispatcher,
65 hci::Transport::WeakPtr hci,
66 gatt::GATT::WeakPtr gatt,
67 std::unique_ptr<l2cap::ChannelManager> l2cap);
68 ~AdapterImpl() override;
69
identifier() const70 AdapterId identifier() const override { return identifier_; }
71
72 bool Initialize(InitializeCallback callback,
73 fit::closure transport_error_cb) override;
74
75 void ShutDown() override;
76
IsInitializing() const77 bool IsInitializing() const override {
78 return init_state_ == State::kInitializing;
79 }
80
IsInitialized() const81 bool IsInitialized() const override {
82 return init_state_ == State::kInitialized;
83 }
84
state() const85 const AdapterState& state() const override { return state_; }
86
87 class LowEnergyImpl final : public LowEnergy {
88 public:
LowEnergyImpl(AdapterImpl * adapter)89 explicit LowEnergyImpl(AdapterImpl* adapter) : adapter_(adapter) {}
90
Connect(PeerId peer_id,ConnectionResultCallback callback,LowEnergyConnectionOptions connection_options)91 void Connect(PeerId peer_id,
92 ConnectionResultCallback callback,
93 LowEnergyConnectionOptions connection_options) override {
94 adapter_->le_connection_manager_->Connect(
95 peer_id, std::move(callback), connection_options);
96 adapter_->metrics_.le.outgoing_connection_requests.Add();
97 }
98
Disconnect(PeerId peer_id)99 bool Disconnect(PeerId peer_id) override {
100 return adapter_->le_connection_manager_->Disconnect(peer_id);
101 }
102
Pair(PeerId peer_id,sm::SecurityLevel pairing_level,sm::BondableMode bondable_mode,sm::ResultFunction<> cb)103 void Pair(PeerId peer_id,
104 sm::SecurityLevel pairing_level,
105 sm::BondableMode bondable_mode,
106 sm::ResultFunction<> cb) override {
107 adapter_->le_connection_manager_->Pair(
108 peer_id, pairing_level, bondable_mode, std::move(cb));
109 adapter_->metrics_.le.pair_requests.Add();
110 }
111
SetLESecurityMode(LESecurityMode mode)112 void SetLESecurityMode(LESecurityMode mode) override {
113 adapter_->le_connection_manager_->SetSecurityMode(mode);
114 }
115
security_mode() const116 LESecurityMode security_mode() const override {
117 return adapter_->le_connection_manager_->security_mode();
118 }
119
StartAdvertising(AdvertisingData data,AdvertisingData scan_rsp,AdvertisingInterval interval,bool anonymous,bool include_tx_power_level,std::optional<ConnectableAdvertisingParameters> connectable,AdvertisingStatusCallback status_callback)120 void StartAdvertising(
121 AdvertisingData data,
122 AdvertisingData scan_rsp,
123 AdvertisingInterval interval,
124 bool anonymous,
125 bool include_tx_power_level,
126 std::optional<ConnectableAdvertisingParameters> connectable,
127 AdvertisingStatusCallback status_callback) override {
128 LowEnergyAdvertisingManager::ConnectionCallback advertisement_connect_cb =
129 nullptr;
130 if (connectable) {
131 BT_ASSERT(connectable->connection_cb);
132
133 // All advertisement connections are first registered with
134 // LowEnergyConnectionManager before being reported to higher layers.
135 advertisement_connect_cb =
136 [this, connectable = std::move(connectable)](
137 AdvertisementId advertisement_id,
138 std::unique_ptr<hci::LowEnergyConnection> link) mutable {
139 auto register_link_cb =
140 [advertisement_id,
141 connection_callback = std::move(connectable->connection_cb)](
142 ConnectionResult result) {
143 connection_callback(advertisement_id, std::move(result));
144 };
145
146 adapter_->le_connection_manager_->RegisterRemoteInitiatedLink(
147 std::move(link),
148 connectable->bondable_mode,
149 std::move(register_link_cb));
150 };
151 }
152
153 adapter_->le_advertising_manager_->StartAdvertising(
154 std::move(data),
155 std::move(scan_rsp),
156 std::move(advertisement_connect_cb),
157 interval,
158 anonymous,
159 include_tx_power_level,
160 std::move(status_callback));
161 adapter_->metrics_.le.start_advertising_events.Add();
162 }
163
StopAdvertising(AdvertisementId advertisement_id)164 void StopAdvertising(AdvertisementId advertisement_id) override {
165 adapter_->le_advertising_manager_->StopAdvertising(advertisement_id);
166 adapter_->metrics_.le.stop_advertising_events.Add();
167 }
168
StartDiscovery(bool active,SessionCallback callback)169 void StartDiscovery(bool active, SessionCallback callback) override {
170 adapter_->le_discovery_manager_->StartDiscovery(active,
171 std::move(callback));
172 adapter_->metrics_.le.start_discovery_events.Add();
173 }
174
EnablePrivacy(bool enabled)175 void EnablePrivacy(bool enabled) override {
176 adapter_->le_address_manager_->EnablePrivacy(enabled);
177 }
178
PrivacyEnabled() const179 bool PrivacyEnabled() const override {
180 return adapter_->le_address_manager_->PrivacyEnabled();
181 }
182
CurrentAddress() const183 const DeviceAddress& CurrentAddress() const override {
184 return adapter_->le_address_manager_->current_address();
185 }
186
register_address_changed_callback(fit::closure callback)187 void register_address_changed_callback(fit::closure callback) override {
188 auto cb = [cb = std::move(callback)](auto) { cb(); };
189 adapter_->le_address_manager_->register_address_changed_callback(
190 std::move(cb));
191 }
192
set_irk(const std::optional<UInt128> & irk)193 void set_irk(const std::optional<UInt128>& irk) override {
194 adapter_->le_address_manager_->set_irk(irk);
195 }
196
irk() const197 std::optional<UInt128> irk() const override {
198 return adapter_->le_address_manager_->irk();
199 }
200
set_request_timeout_for_testing(pw::chrono::SystemClock::duration value)201 void set_request_timeout_for_testing(
202 pw::chrono::SystemClock::duration value) override {
203 adapter_->le_connection_manager_->set_request_timeout_for_testing(value);
204 }
205
set_scan_period_for_testing(pw::chrono::SystemClock::duration period)206 void set_scan_period_for_testing(
207 pw::chrono::SystemClock::duration period) override {
208 adapter_->le_discovery_manager_->set_scan_period(period);
209 }
210
211 private:
212 AdapterImpl* adapter_;
213 };
214
le() const215 LowEnergy* le() const override { return low_energy_.get(); }
216
217 class BrEdrImpl final : public BrEdr {
218 public:
BrEdrImpl(AdapterImpl * adapter)219 explicit BrEdrImpl(AdapterImpl* adapter) : adapter_(adapter) {}
220
Connect(PeerId peer_id,ConnectResultCallback callback)221 bool Connect(PeerId peer_id, ConnectResultCallback callback) override {
222 return adapter_->bredr_connection_manager_->Connect(peer_id,
223 std::move(callback));
224 adapter_->metrics_.bredr.outgoing_connection_requests.Add();
225 }
226
Disconnect(PeerId peer_id,DisconnectReason reason)227 bool Disconnect(PeerId peer_id, DisconnectReason reason) override {
228 return adapter_->bredr_connection_manager_->Disconnect(peer_id, reason);
229 }
230
OpenL2capChannel(PeerId peer_id,l2cap::Psm psm,BrEdrSecurityRequirements security_requirements,l2cap::ChannelParameters params,l2cap::ChannelCallback cb)231 void OpenL2capChannel(PeerId peer_id,
232 l2cap::Psm psm,
233 BrEdrSecurityRequirements security_requirements,
234 l2cap::ChannelParameters params,
235 l2cap::ChannelCallback cb) override {
236 adapter_->metrics_.bredr.open_l2cap_channel_requests.Add();
237 adapter_->bredr_connection_manager_->OpenL2capChannel(
238 peer_id, psm, security_requirements, params, std::move(cb));
239 }
240
GetPeerId(hci_spec::ConnectionHandle handle) const241 PeerId GetPeerId(hci_spec::ConnectionHandle handle) const override {
242 return adapter_->bredr_connection_manager_->GetPeerId(handle);
243 }
244
AddServiceSearch(const UUID & uuid,std::unordered_set<sdp::AttributeId> attributes,SearchCallback callback)245 SearchId AddServiceSearch(const UUID& uuid,
246 std::unordered_set<sdp::AttributeId> attributes,
247 SearchCallback callback) override {
248 return adapter_->bredr_connection_manager_->AddServiceSearch(
249 uuid, std::move(attributes), std::move(callback));
250 }
251
RemoveServiceSearch(SearchId id)252 bool RemoveServiceSearch(SearchId id) override {
253 return adapter_->bredr_connection_manager_->RemoveServiceSearch(id);
254 }
255
Pair(PeerId peer_id,BrEdrSecurityRequirements security,hci::ResultFunction<> callback)256 void Pair(PeerId peer_id,
257 BrEdrSecurityRequirements security,
258 hci::ResultFunction<> callback) override {
259 adapter_->bredr_connection_manager_->Pair(
260 peer_id, security, std::move(callback));
261 adapter_->metrics_.bredr.pair_requests.Add();
262 }
263
SetBrEdrSecurityMode(BrEdrSecurityMode mode)264 void SetBrEdrSecurityMode(BrEdrSecurityMode mode) override {
265 adapter_->bredr_connection_manager_->SetSecurityMode(mode);
266 }
267
security_mode() const268 BrEdrSecurityMode security_mode() const override {
269 return adapter_->bredr_connection_manager_->security_mode();
270 }
271
SetConnectable(bool connectable,hci::ResultFunction<> status_cb)272 void SetConnectable(bool connectable,
273 hci::ResultFunction<> status_cb) override {
274 adapter_->bredr_connection_manager_->SetConnectable(connectable,
275 std::move(status_cb));
276 if (connectable) {
277 adapter_->metrics_.bredr.set_connectable_true_events.Add();
278 } else {
279 adapter_->metrics_.bredr.set_connectable_false_events.Add();
280 }
281 }
282
RequestDiscovery(DiscoveryCallback callback)283 void RequestDiscovery(DiscoveryCallback callback) override {
284 adapter_->bredr_discovery_manager_->RequestDiscovery(std::move(callback));
285 adapter_->metrics_.bredr.request_discovery_events.Add();
286 }
287
RequestDiscoverable(DiscoverableCallback callback)288 void RequestDiscoverable(DiscoverableCallback callback) override {
289 adapter_->bredr_discovery_manager_->RequestDiscoverable(
290 std::move(callback));
291 adapter_->metrics_.bredr.request_discoverable_events.Add();
292 }
293
RegisterService(std::vector<sdp::ServiceRecord> records,l2cap::ChannelParameters chan_params,ServiceConnectCallback conn_cb)294 RegistrationHandle RegisterService(
295 std::vector<sdp::ServiceRecord> records,
296 l2cap::ChannelParameters chan_params,
297 ServiceConnectCallback conn_cb) override {
298 return adapter_->sdp_server_->RegisterService(
299 std::move(records), chan_params, std::move(conn_cb));
300 }
301
UnregisterService(RegistrationHandle handle)302 bool UnregisterService(RegistrationHandle handle) override {
303 return adapter_->sdp_server_->UnregisterService(handle);
304 }
305
OpenScoConnection(PeerId peer_id,const bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter> & parameters,sco::ScoConnectionManager::OpenConnectionCallback callback)306 std::optional<ScoRequestHandle> OpenScoConnection(
307 PeerId peer_id,
308 const bt::StaticPacket<
309 pw::bluetooth::emboss::SynchronousConnectionParametersWriter>&
310 parameters,
311 sco::ScoConnectionManager::OpenConnectionCallback callback) override {
312 return adapter_->bredr_connection_manager_->OpenScoConnection(
313 peer_id, parameters, std::move(callback));
314 }
AcceptScoConnection(PeerId peer_id,const std::vector<bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>> parameters,sco::ScoConnectionManager::AcceptConnectionCallback callback)315 std::optional<ScoRequestHandle> AcceptScoConnection(
316 PeerId peer_id,
317 const std::vector<bt::StaticPacket<
318 pw::bluetooth::emboss::SynchronousConnectionParametersWriter>>
319 parameters,
320 sco::ScoConnectionManager::AcceptConnectionCallback callback) override {
321 return adapter_->bredr_connection_manager_->AcceptScoConnection(
322 peer_id, std::move(parameters), std::move(callback));
323 }
324
325 private:
326 AdapterImpl* adapter_;
327 };
328
bredr() const329 BrEdr* bredr() const override { return bredr_.get(); }
330
peer_cache()331 PeerCache* peer_cache() override { return &peer_cache_; }
332
333 bool AddBondedPeer(BondingData bonding_data) override;
334
335 void SetPairingDelegate(PairingDelegate::WeakPtr delegate) override;
336
337 bool IsDiscoverable() const override;
338
339 bool IsDiscovering() const override;
340
341 void SetLocalName(std::string name, hci::ResultFunction<> callback) override;
342
local_name() const343 std::string local_name() const override {
344 return bredr_discovery_manager_->local_name();
345 }
346
347 void SetDeviceClass(DeviceClass dev_class,
348 hci::ResultFunction<> callback) override;
349
set_auto_connect_callback(AutoConnectCallback callback)350 void set_auto_connect_callback(AutoConnectCallback callback) override {
351 auto_conn_cb_ = std::move(callback);
352 }
353
354 void AttachInspect(inspect::Node& parent, std::string name) override;
355
AsWeakPtr()356 WeakSelf<Adapter>::WeakPtr AsWeakPtr() override {
357 return weak_self_adapter_.GetWeakPtr();
358 }
359
360 private:
361 // Called by Initialize() after Transport is initialized.
362 void InitializeStep1();
363
364 // Second step of the initialization sequence. Called by InitializeStep1()
365 // when the first batch of HCI commands have been sent.
366 void InitializeStep2();
367
368 // Third step of the initialization sequence. Called by InitializeStep2() when
369 // the second batch of HCI commands have been sent.
370 void InitializeStep3();
371
372 // Fourth step of the initialization sequence. Called by InitializeStep3()
373 // when the third batch of HCI commands have been sent.
374 void InitializeStep4();
375
376 // Returns true if initialization was completed, or false if initialization is
377 // not in progress.
378 bool CompleteInitialization(bool success);
379
380 // Reads LMP feature mask's bits from |page|
381 void InitQueueReadLMPFeatureMaskPage(uint8_t page);
382
383 // Assigns properties to |adapter_node_| using values discovered during other
384 // initialization steps.
385 void UpdateInspectProperties();
386
387 // Called by ShutDown() and during Initialize() in case of failure. This
388 // synchronously cleans up the transports and resets initialization state.
389 void CleanUp();
390
391 // Called by Transport after it experiences a fatal error.
392 void OnTransportError();
393
394 // Called when a directed connectable advertisement is received from a bonded
395 // LE device. This amounts to a connection request from a bonded peripheral
396 // which is handled by routing the request to |le_connection_manager_| to
397 // initiate a Direct Connection Establishment procedure (Vol 3, Part C,
398 // 9.3.8).
399 void OnLeAutoConnectRequest(Peer* peer);
400
401 // Called by |le_address_manager_| to query whether it is currently allowed to
402 // reconfigure the LE random address.
403 bool IsLeRandomAddressChangeAllowed();
404
CreateAdvertiser()405 std::unique_ptr<hci::LowEnergyAdvertiser> CreateAdvertiser() {
406 constexpr hci_spec::LESupportedFeature feature =
407 hci_spec::LESupportedFeature::kLEExtendedAdvertising;
408 if (state().low_energy_state.IsFeatureSupported(feature)) {
409 bt_log(INFO,
410 "gap",
411 "controller supports extended advertising, using extended LE "
412 "advertiser");
413 return std::make_unique<hci::ExtendedLowEnergyAdvertiser>(hci_);
414 }
415
416 if (state().IsControllerFeatureSupported(
417 pw::bluetooth::Controller::FeaturesBits::
418 kAndroidVendorExtensions)) {
419 uint8_t max_advt =
420 state().android_vendor_capabilities.max_simultaneous_advertisements();
421 bt_log(INFO,
422 "gap",
423 "controller supports android vendor extensions, max simultaneous "
424 "advertisements: %d",
425 max_advt);
426 return std::make_unique<hci::AndroidExtendedLowEnergyAdvertiser>(
427 hci_, max_advt);
428 }
429
430 bt_log(INFO,
431 "gap",
432 "controller supports only legacy advertising, using legacy LE "
433 "advertiser");
434 return std::make_unique<hci::LegacyLowEnergyAdvertiser>(hci_);
435 }
436
437 // Must be initialized first so that child nodes can be passed to other
438 // constructors.
439 inspect::Node adapter_node_;
440 struct InspectProperties {
441 inspect::StringProperty adapter_id;
442 inspect::StringProperty hci_version;
443 inspect::UintProperty bredr_max_num_packets;
444 inspect::UintProperty bredr_max_data_length;
445 inspect::UintProperty le_max_num_packets;
446 inspect::UintProperty le_max_data_length;
447 inspect::UintProperty sco_max_num_packets;
448 inspect::UintProperty sco_max_data_length;
449 inspect::StringProperty lmp_features;
450 inspect::StringProperty le_features;
451 };
452 InspectProperties inspect_properties_;
453
454 // Metrics properties
455 inspect::Node metrics_node_;
456 inspect::Node metrics_bredr_node_;
457 inspect::Node metrics_le_node_;
458 struct AdapterMetrics {
459 struct LeMetrics {
460 UintMetricCounter outgoing_connection_requests;
461 UintMetricCounter pair_requests;
462 UintMetricCounter start_advertising_events;
463 UintMetricCounter stop_advertising_events;
464 UintMetricCounter start_discovery_events;
465 } le;
466 struct BrEdrMetrics {
467 UintMetricCounter outgoing_connection_requests;
468 UintMetricCounter pair_requests;
469 UintMetricCounter set_connectable_true_events;
470 UintMetricCounter set_connectable_false_events;
471 UintMetricCounter request_discovery_events;
472 UintMetricCounter request_discoverable_events;
473 UintMetricCounter open_l2cap_channel_requests;
474 } bredr;
475 };
476 AdapterMetrics metrics_;
477
478 // Uniquely identifies this adapter on the current system.
479 AdapterId identifier_;
480
481 hci::Transport::WeakPtr hci_;
482
483 // Callback invoked to notify clients when the underlying transport is closed.
484 fit::closure transport_error_cb_;
485
486 // Parameters relevant to the initialization sequence.
487 // TODO(armansito): The Initialize()/ShutDown() pattern has become common
488 // enough in this project that it might be worth considering moving the
489 // init-state-keeping into an abstract base.
490 enum State {
491 kNotInitialized = 0,
492 kInitializing,
493 kInitialized,
494 };
495 std::atomic<State> init_state_;
496 std::unique_ptr<hci::SequentialCommandRunner> init_seq_runner_;
497
498 // The callback passed to Initialize(). Null after initialization completes.
499 InitializeCallback init_cb_;
500
501 // Contains the global adapter state.
502 AdapterState state_;
503
504 // The maximum LMP feature page that we will read.
505 std::optional<size_t> max_lmp_feature_page_index_;
506
507 // Provides access to discovered, connected, and/or bonded remote Bluetooth
508 // devices.
509 PeerCache peer_cache_;
510
511 // L2CAP layer used by GAP. This must be destroyed after the following members
512 // because they raw pointers to this member.
513 std::unique_ptr<l2cap::ChannelManager> l2cap_;
514
515 // The GATT profile. We use this reference to add and remove data bearers and
516 // for service discovery.
517 gatt::GATT::WeakPtr gatt_;
518
519 // Objects that abstract the controller for connection and advertising
520 // procedures.
521 std::unique_ptr<hci::LowEnergyAdvertiser> hci_le_advertiser_;
522 std::unique_ptr<hci::LowEnergyConnector> hci_le_connector_;
523 std::unique_ptr<hci::LowEnergyScanner> hci_le_scanner_;
524
525 // Objects that perform LE procedures.
526 std::unique_ptr<LowEnergyAddressManager> le_address_manager_;
527 std::unique_ptr<LowEnergyDiscoveryManager> le_discovery_manager_;
528 std::unique_ptr<LowEnergyConnectionManager> le_connection_manager_;
529 std::unique_ptr<LowEnergyAdvertisingManager> le_advertising_manager_;
530 std::unique_ptr<LowEnergyImpl> low_energy_;
531
532 // Objects that perform BR/EDR procedures.
533 std::unique_ptr<BrEdrConnectionManager> bredr_connection_manager_;
534 std::unique_ptr<BrEdrDiscoveryManager> bredr_discovery_manager_;
535 std::unique_ptr<sdp::Server> sdp_server_;
536 std::unique_ptr<BrEdrImpl> bredr_;
537
538 // Callback to propagate ownership of an auto-connected LE link.
539 AutoConnectCallback auto_conn_cb_;
540
541 pw::async::Dispatcher& dispatcher_;
542
543 // This must remain the last member to make sure that all weak pointers are
544 // invalidating before other members are destroyed.
545 WeakSelf<AdapterImpl> weak_self_;
546 WeakSelf<Adapter> weak_self_adapter_;
547
548 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AdapterImpl);
549 };
550
AdapterImpl(pw::async::Dispatcher & pw_dispatcher,hci::Transport::WeakPtr hci,gatt::GATT::WeakPtr gatt,std::unique_ptr<l2cap::ChannelManager> l2cap)551 AdapterImpl::AdapterImpl(pw::async::Dispatcher& pw_dispatcher,
552 hci::Transport::WeakPtr hci,
553 gatt::GATT::WeakPtr gatt,
554 std::unique_ptr<l2cap::ChannelManager> l2cap)
555 : identifier_(Random<AdapterId>()),
556 hci_(std::move(hci)),
557 init_state_(State::kNotInitialized),
558 peer_cache_(pw_dispatcher),
559 l2cap_(std::move(l2cap)),
560 gatt_(std::move(gatt)),
561 dispatcher_(pw_dispatcher),
562 weak_self_(this),
563 weak_self_adapter_(this) {
564 BT_DEBUG_ASSERT(hci_.is_alive());
565 BT_DEBUG_ASSERT(gatt_.is_alive());
566
567 auto self = weak_self_.GetWeakPtr();
568 hci_->SetTransportErrorCallback([self] {
569 if (self.is_alive()) {
570 self->OnTransportError();
571 }
572 });
573
574 gatt_->SetPersistServiceChangedCCCCallback(
575 [this](PeerId peer_id, gatt::ServiceChangedCCCPersistedData gatt_data) {
576 Peer* peer = peer_cache_.FindById(peer_id);
577 if (!peer) {
578 bt_log(WARN,
579 "gap",
580 "Unable to find peer %s when storing persisted GATT data.",
581 bt_str(peer_id));
582 } else if (!peer->le()) {
583 bt_log(WARN,
584 "gap",
585 "Tried to store persisted GATT data for non-LE peer %s.",
586 bt_str(peer_id));
587 } else {
588 peer->MutLe().set_service_changed_gatt_data(gatt_data);
589 }
590 });
591
592 gatt_->SetRetrieveServiceChangedCCCCallback([this](PeerId peer_id) {
593 Peer* peer = peer_cache_.FindById(peer_id);
594 if (!peer) {
595 bt_log(WARN,
596 "gap",
597 "Unable to find peer %s when retrieving persisted GATT data.",
598 peer_id.ToString().c_str());
599 return std::optional<gatt::ServiceChangedCCCPersistedData>();
600 }
601
602 if (!peer->le()) {
603 bt_log(WARN,
604 "gap",
605 "Tried to retrieve persisted GATT data for non-LE peer %s.",
606 peer_id.ToString().c_str());
607 return std::optional<gatt::ServiceChangedCCCPersistedData>();
608 }
609
610 return std::optional(peer->le()->get_service_changed_gatt_data());
611 });
612 }
613
~AdapterImpl()614 AdapterImpl::~AdapterImpl() {
615 if (IsInitialized()) {
616 ShutDown();
617 }
618 }
619
Initialize(InitializeCallback callback,fit::closure transport_error_cb)620 bool AdapterImpl::Initialize(InitializeCallback callback,
621 fit::closure transport_error_cb) {
622 BT_DEBUG_ASSERT(callback);
623 BT_DEBUG_ASSERT(transport_error_cb);
624
625 if (IsInitialized()) {
626 bt_log(WARN, "gap", "Adapter already initialized");
627 return false;
628 }
629
630 BT_DEBUG_ASSERT(!IsInitializing());
631 BT_DEBUG_ASSERT(!init_seq_runner_);
632
633 init_state_ = State::kInitializing;
634 init_cb_ = std::move(callback);
635 transport_error_cb_ = std::move(transport_error_cb);
636
637 hci_->Initialize([this](bool success) {
638 if (!success) {
639 bt_log(ERROR, "gap", "Failed to initialize Transport");
640 CompleteInitialization(/*success=*/false);
641 return;
642 }
643 init_seq_runner_ = std::make_unique<hci::SequentialCommandRunner>(
644 hci_->command_channel()->AsWeakPtr());
645
646 InitializeStep1();
647 });
648
649 return true;
650 }
651
ShutDown()652 void AdapterImpl::ShutDown() {
653 bt_log(DEBUG, "gap", "adapter shutting down");
654
655 if (IsInitializing()) {
656 BT_DEBUG_ASSERT(!init_seq_runner_->IsReady());
657 init_seq_runner_->Cancel();
658 }
659
660 CleanUp();
661 }
662
AddBondedPeer(BondingData bonding_data)663 bool AdapterImpl::AddBondedPeer(BondingData bonding_data) {
664 return peer_cache()->AddBondedPeer(bonding_data);
665 }
666
SetPairingDelegate(PairingDelegate::WeakPtr delegate)667 void AdapterImpl::SetPairingDelegate(PairingDelegate::WeakPtr delegate) {
668 le_connection_manager_->SetPairingDelegate(delegate);
669 bredr_connection_manager_->SetPairingDelegate(delegate);
670 }
671
IsDiscoverable() const672 bool AdapterImpl::IsDiscoverable() const {
673 if (bredr_discovery_manager_ && bredr_discovery_manager_->discoverable()) {
674 return true;
675 }
676
677 // If LE Privacy is enabled, then we are not discoverable.
678 // TODO(fxbug.dev/42060496): Make this dependent on whether the LE Public
679 // advertisement is active or not.
680 if (le_address_manager_ && le_address_manager_->PrivacyEnabled()) {
681 return false;
682 }
683
684 return (le_advertising_manager_ && le_advertising_manager_->advertising());
685 }
686
IsDiscovering() const687 bool AdapterImpl::IsDiscovering() const {
688 return (le_discovery_manager_ && le_discovery_manager_->discovering()) ||
689 (bredr_discovery_manager_ && bredr_discovery_manager_->discovering());
690 }
691
SetLocalName(std::string name,hci::ResultFunction<> callback)692 void AdapterImpl::SetLocalName(std::string name,
693 hci::ResultFunction<> callback) {
694 // TODO(fxbug.dev/42116852): set the public LE advertisement name from |name|
695 // If BrEdr is not supported, skip the name update.
696 if (!bredr_discovery_manager_) {
697 callback(ToResult(bt::HostError::kNotSupported));
698 return;
699 }
700
701 // Make a copy of |name| to move separately into the lambda.
702 std::string name_copy(name);
703 bredr_discovery_manager_->UpdateLocalName(
704 std::move(name),
705 [this, cb = std::move(callback), local_name = std::move(name_copy)](
706 auto status) {
707 if (!bt_is_error(status, WARN, "gap", "set local name failed")) {
708 state_.local_name = local_name;
709 }
710 cb(status);
711 });
712 }
713
SetDeviceClass(DeviceClass dev_class,hci::ResultFunction<> callback)714 void AdapterImpl::SetDeviceClass(DeviceClass dev_class,
715 hci::ResultFunction<> callback) {
716 auto write_dev_class = hci::EmbossCommandPacket::New<
717 pw::bluetooth::emboss::WriteClassOfDeviceCommandWriter>(
718 hci_spec::kWriteClassOfDevice);
719 write_dev_class.view_t().class_of_device().BackingStorage().WriteUInt(
720 dev_class.to_int());
721 hci_->command_channel()->SendCommand(
722 std::move(write_dev_class),
723 [cb = std::move(callback)](auto, const hci::EventPacket& event) {
724 hci_is_error(event, WARN, "gap", "set device class failed");
725 cb(event.ToResult());
726 });
727 }
728
AttachInspect(inspect::Node & parent,std::string name)729 void AdapterImpl::AttachInspect(inspect::Node& parent, std::string name) {
730 adapter_node_ = parent.CreateChild(name);
731 UpdateInspectProperties();
732
733 peer_cache_.AttachInspect(adapter_node_);
734
735 metrics_node_ = adapter_node_.CreateChild(kMetricsInspectNodeName);
736
737 metrics_le_node_ = metrics_node_.CreateChild("le");
738 metrics_.le.outgoing_connection_requests.AttachInspect(
739 metrics_le_node_, "outgoing_connection_requests");
740 metrics_.le.pair_requests.AttachInspect(metrics_le_node_, "pair_requests");
741 metrics_.le.start_advertising_events.AttachInspect(
742 metrics_le_node_, "start_advertising_events");
743 metrics_.le.stop_advertising_events.AttachInspect(metrics_le_node_,
744 "stop_advertising_events");
745 metrics_.le.start_discovery_events.AttachInspect(metrics_le_node_,
746 "start_discovery_events");
747
748 metrics_bredr_node_ = metrics_node_.CreateChild("bredr");
749 metrics_.bredr.outgoing_connection_requests.AttachInspect(
750 metrics_bredr_node_, "outgoing_connection_requests");
751 metrics_.bredr.pair_requests.AttachInspect(metrics_bredr_node_,
752 "pair_requests");
753 metrics_.bredr.set_connectable_true_events.AttachInspect(
754 metrics_bredr_node_, "set_connectable_true_events");
755 metrics_.bredr.set_connectable_false_events.AttachInspect(
756 metrics_bredr_node_, "set_connectable_false_events");
757 metrics_.bredr.request_discovery_events.AttachInspect(
758 metrics_bredr_node_, "request_discovery_events");
759 metrics_.bredr.request_discoverable_events.AttachInspect(
760 metrics_bredr_node_, "request_discoverable_events");
761 metrics_.bredr.open_l2cap_channel_requests.AttachInspect(
762 metrics_bredr_node_, "open_l2cap_channel_requests");
763 }
764
InitializeStep1()765 void AdapterImpl::InitializeStep1() {
766 state_.controller_features = hci_->GetFeatures();
767
768 // Start by resetting the controller to a clean state and then send
769 // informational parameter commands that are not specific to LE or BR/EDR. The
770 // commands sent here are mandatory for all LE controllers.
771 //
772 // NOTE: It's safe to pass capture |this| directly in the callbacks as
773 // |init_seq_runner_| will internally invalidate the callbacks if it ever gets
774 // deleted.
775
776 // HCI_Reset
777 auto reset_command =
778 hci::EmbossCommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(
779 hci_spec::kReset);
780 init_seq_runner_->QueueCommand(std::move(reset_command));
781
782 // HCI_Read_Local_Version_Information
783 init_seq_runner_->QueueCommand(
784 hci::EmbossCommandPacket::New<
785 pw::bluetooth::emboss::ReadLocalVersionInformationCommandView>(
786 hci_spec::kReadLocalVersionInfo),
787 [this](const hci::EventPacket& cmd_complete) {
788 if (hci_is_error(
789 cmd_complete, WARN, "gap", "read local version info failed")) {
790 return;
791 }
792 auto params =
793 cmd_complete
794 .return_params<hci_spec::ReadLocalVersionInfoReturnParams>();
795 state_.hci_version = params->hci_version;
796 });
797
798 // HCI_Read_Local_Supported_Commands
799 init_seq_runner_->QueueCommand(
800 hci::EmbossCommandPacket::New<
801 pw::bluetooth::emboss::ReadLocalSupportedCommandsCommandView>(
802 hci_spec::kReadLocalSupportedCommands),
803 [this](const hci::EventPacket& cmd_complete) {
804 if (hci_is_error(cmd_complete,
805 WARN,
806 "gap",
807 "read local supported commands failed")) {
808 return;
809 }
810 auto params = cmd_complete.return_params<
811 hci_spec::ReadLocalSupportedCommandsReturnParams>();
812 std::memcpy(state_.supported_commands,
813 params->supported_commands,
814 sizeof(params->supported_commands));
815 });
816
817 // HCI_Read_Local_Supported_Features
818 InitQueueReadLMPFeatureMaskPage(0);
819
820 // HCI_Read_BD_ADDR
821 init_seq_runner_->QueueCommand(
822 hci::EmbossCommandPacket::New<
823 pw::bluetooth::emboss::ReadBdAddrCommandView>(hci_spec::kReadBDADDR),
824 [this](const hci::EventPacket& cmd_complete) {
825 if (hci_is_error(cmd_complete, WARN, "gap", "read BR_ADDR failed")) {
826 return;
827 }
828 auto params =
829 cmd_complete.return_params<hci_spec::ReadBDADDRReturnParams>();
830 state_.controller_address = params->bd_addr;
831 });
832
833 if (state().IsControllerFeatureSupported(
834 pw::bluetooth::Controller::FeaturesBits::kAndroidVendorExtensions)) {
835 bt_log(INFO,
836 "gap",
837 "controller supports android hci extensions, querying exact feature "
838 "set");
839 init_seq_runner_->QueueCommand(
840 hci::EmbossCommandPacket::New<pw::bluetooth::vendor::android_hci::
841 LEGetVendorCapabilitiesCommandView>(
842 hci_android::kLEGetVendorCapabilities),
843 [this](const hci::EmbossEventPacket& event) {
844 if (hci_is_error(
845 event,
846 WARN,
847 "gap",
848 "Failed to query android hci extension capabilities")) {
849 return;
850 }
851
852 auto params =
853 event.view<pw::bluetooth::vendor::android_hci::
854 LEGetVendorCapabilitiesCommandCompleteEventView>();
855 state_.android_vendor_capabilities.Initialize(params);
856 });
857 }
858
859 init_seq_runner_->RunCommands([this](hci::Result<> status) mutable {
860 if (bt_is_error(status,
861 ERROR,
862 "gap",
863 "Failed to obtain initial controller information: %s",
864 bt_str(status))) {
865 CompleteInitialization(/*success=*/false);
866 return;
867 }
868
869 InitializeStep2();
870 });
871 }
872
InitializeStep2()873 void AdapterImpl::InitializeStep2() {
874 BT_DEBUG_ASSERT(IsInitializing());
875
876 // Low Energy MUST be supported. We don't support BR/EDR-only controllers.
877 if (!state_.IsLowEnergySupported()) {
878 bt_log(ERROR, "gap", "Bluetooth LE not supported by controller");
879 CompleteInitialization(/*success=*/false);
880 return;
881 }
882
883 // Check the HCI version. We officially only support 4.2+ only but for now we
884 // just log a warning message if the version is legacy.
885 if (state_.hci_version <
886 pw::bluetooth::emboss::CoreSpecificationVersion::V4_2) {
887 bt_log(WARN,
888 "gap",
889 "controller is using legacy HCI version %s",
890 hci_spec::HCIVersionToString(state_.hci_version).c_str());
891 }
892
893 BT_DEBUG_ASSERT(init_seq_runner_->IsReady());
894
895 // If the controller supports the Read Buffer Size command then send it.
896 // Otherwise we'll default to 0 when initializing the ACLDataChannel.
897 if (state_.IsCommandSupported(/*octet=*/14,
898 hci_spec::SupportedCommand::kReadBufferSize)) {
899 // HCI_Read_Buffer_Size
900 init_seq_runner_->QueueCommand(
901 hci::EmbossCommandPacket::New<
902 pw::bluetooth::emboss::ReadBufferSizeCommandView>(
903 hci_spec::kReadBufferSize),
904 [this](const hci::EventPacket& cmd_complete) {
905 if (hci_is_error(
906 cmd_complete, WARN, "gap", "read buffer size failed")) {
907 return;
908 }
909 auto params =
910 cmd_complete
911 .return_params<hci_spec::ReadBufferSizeReturnParams>();
912 uint16_t acl_mtu = le16toh(params->hc_acl_data_packet_length);
913 uint16_t acl_max_count =
914 le16toh(params->hc_total_num_acl_data_packets);
915 if (acl_mtu && acl_max_count) {
916 state_.bredr_data_buffer_info =
917 hci::DataBufferInfo(acl_mtu, acl_max_count);
918 }
919 uint16_t sco_mtu = le16toh(params->hc_synchronous_data_packet_length);
920 uint16_t sco_max_count =
921 le16toh(params->hc_total_num_synchronous_data_packets);
922 if (sco_mtu && sco_max_count) {
923 state_.sco_buffer_info =
924 hci::DataBufferInfo(sco_mtu, sco_max_count);
925 }
926 });
927 }
928
929 // HCI_LE_Read_Local_Supported_Features
930 init_seq_runner_->QueueCommand(
931 hci::EmbossCommandPacket::New<
932 pw::bluetooth::emboss::LEReadLocalSupportedFeaturesCommandView>(
933 hci_spec::kLEReadLocalSupportedFeatures),
934 [this](const hci::EventPacket& cmd_complete) {
935 if (hci_is_error(cmd_complete,
936 WARN,
937 "gap",
938 "LE read local supported features failed")) {
939 return;
940 }
941 auto params = cmd_complete.return_params<
942 hci_spec::LEReadLocalSupportedFeaturesReturnParams>();
943 state_.low_energy_state.supported_features_ =
944 le64toh(params->le_features);
945 });
946
947 // HCI_LE_Read_Supported_States
948 init_seq_runner_->QueueCommand(
949 hci::EmbossCommandPacket::New<
950 pw::bluetooth::emboss::LEReadSupportedStatesCommandView>(
951 hci_spec::kLEReadSupportedStates),
952 [this](const hci::EventPacket& cmd_complete) {
953 if (hci_is_error(cmd_complete,
954 WARN,
955 "gap",
956 "LE read local supported states failed")) {
957 return;
958 }
959 auto params =
960 cmd_complete
961 .return_params<hci_spec::LEReadSupportedStatesReturnParams>();
962 state_.low_energy_state.supported_states_ = le64toh(params->le_states);
963 });
964
965 if (state_.IsCommandSupported(
966 /*octet=*/41, hci_spec::SupportedCommand::kLEReadBufferSizeV2)) {
967 // HCI_LE_Read_Buffer_Size [v2]
968 init_seq_runner_->QueueCommand(
969 hci::EmbossCommandPacket::New<
970 pw::bluetooth::emboss::LEReadBufferSizeCommandV2View>(
971 hci_spec::kLEReadBufferSizeV2),
972 [this](const hci::EmbossEventPacket& cmd_complete) {
973 if (hci_is_error(cmd_complete,
974 WARN,
975 "gap",
976 "LE read buffer size [v2] failed")) {
977 return;
978 }
979 auto params =
980 cmd_complete
981 .view<pw::bluetooth::emboss::
982 LEReadBufferSizeV2CommandCompleteEventView>();
983 uint16_t acl_mtu = params.le_acl_data_packet_length().Read();
984 uint8_t acl_max_count = params.total_num_le_acl_data_packets().Read();
985 if (acl_mtu && acl_max_count) {
986 state_.low_energy_state.acl_data_buffer_info_ =
987 hci::DataBufferInfo(acl_mtu, acl_max_count);
988 }
989 uint16_t iso_mtu = params.iso_data_packet_length().Read();
990 uint8_t iso_max_count = params.total_num_iso_data_packets().Read();
991 if (iso_mtu && iso_max_count) {
992 state_.low_energy_state.iso_data_buffer_info_ =
993 hci::DataBufferInfo(iso_mtu, iso_max_count);
994 }
995 });
996 } else {
997 // HCI_LE_Read_Buffer_Size [v1]
998 init_seq_runner_->QueueCommand(
999 hci::EmbossCommandPacket::New<
1000 pw::bluetooth::emboss::LEReadBufferSizeCommandV1View>(
1001 hci_spec::kLEReadBufferSizeV1),
1002 [this](const hci::EventPacket& cmd_complete) {
1003 if (hci_is_error(
1004 cmd_complete, WARN, "gap", "LE read buffer size failed")) {
1005 return;
1006 }
1007 auto params =
1008 cmd_complete
1009 .return_params<hci_spec::LEReadBufferSizeV1ReturnParams>();
1010 uint16_t mtu = le16toh(params->hc_le_acl_data_packet_length);
1011 uint8_t max_count = params->hc_total_num_le_acl_data_packets;
1012 if (mtu && max_count) {
1013 state_.low_energy_state.acl_data_buffer_info_ =
1014 hci::DataBufferInfo(mtu, max_count);
1015 }
1016 });
1017 }
1018
1019 if (state_.features.HasBit(
1020 /*page=*/0u,
1021 hci_spec::LMPFeature::kSecureSimplePairingControllerSupport)) {
1022 // HCI_Write_Simple_Pairing_Mode
1023 auto write_spm = hci::EmbossCommandPacket::New<
1024 pw::bluetooth::emboss::WriteSimplePairingModeCommandWriter>(
1025 hci_spec::kWriteSimplePairingMode);
1026 auto write_ssp_params = write_spm.view_t();
1027 write_ssp_params.simple_pairing_mode().Write(
1028 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1029 init_seq_runner_->QueueCommand(
1030 std::move(write_spm), [](const hci::EventPacket& event) {
1031 // Warn if the command failed
1032 hci_is_error(event, WARN, "gap", "write simple pairing mode failed");
1033 });
1034 }
1035
1036 // If there are extended features then try to read the first page of the
1037 // extended features.
1038 if (state_.features.HasBit(/*page=*/0u,
1039 hci_spec::LMPFeature::kExtendedFeatures)) {
1040 // HCI_Write_LE_Host_Support
1041 if (!state_.IsCommandSupported(
1042 /*octet=*/24, hci_spec::SupportedCommand::kWriteLEHostSupport)) {
1043 bt_log(INFO, "gap", "LE Host is not supported");
1044 } else {
1045 bt_log(INFO, "gap", "LE Host is supported. Enabling LE Host mode");
1046 auto cmd_packet = hci::EmbossCommandPacket::New<
1047 pw::bluetooth::emboss::WriteLEHostSupportCommandWriter>(
1048 hci_spec::kWriteLEHostSupport);
1049 auto params = cmd_packet.view_t();
1050 params.le_supported_host().Write(
1051 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1052 init_seq_runner_->QueueCommand(
1053 std::move(cmd_packet), [](const hci::EventPacket& event) {
1054 hci_is_error(event, WARN, "gap", "Write LE Host support failed");
1055 });
1056 }
1057
1058 // HCI_Write_Secure_Connections_Host_Support
1059 if (!state_.IsCommandSupported(
1060 /*octet=*/32,
1061 hci_spec::SupportedCommand::kWriteSecureConnectionsHostSupport)) {
1062 bt_log(INFO, "gap", "Secure Connections (Host Support) is not supported");
1063 } else {
1064 bt_log(INFO,
1065 "gap",
1066 "Secure Connections (Host Support) is supported. "
1067 "Enabling Secure Connections (Host Support) mode");
1068 auto cmd_packet = hci::EmbossCommandPacket::New<
1069 pw::bluetooth::emboss::
1070 WriteSecureConnectionsHostSupportCommandWriter>(
1071 hci_spec::kWriteSecureConnectionsHostSupport);
1072 auto params = cmd_packet.view_t();
1073 params.secure_connections_host_support().Write(
1074 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1075 init_seq_runner_->QueueCommand(
1076 std::move(cmd_packet), [](const hci::EventPacket& event) {
1077 hci_is_error(event,
1078 WARN,
1079 "gap",
1080 "Write Secure Connections (Host Support) failed");
1081 });
1082 }
1083
1084 // Read updated page 1 after host support bits enabled.
1085 InitQueueReadLMPFeatureMaskPage(1);
1086 }
1087
1088 init_seq_runner_->RunCommands([this](hci::Result<> status) mutable {
1089 if (bt_is_error(
1090 status,
1091 ERROR,
1092 "gap",
1093 "failed to obtain initial controller information (step 2)")) {
1094 CompleteInitialization(/*success=*/false);
1095 return;
1096 }
1097 InitializeStep3();
1098 });
1099 }
1100
InitializeStep3()1101 void AdapterImpl::InitializeStep3() {
1102 BT_ASSERT(IsInitializing());
1103 BT_ASSERT(init_seq_runner_->IsReady());
1104 BT_ASSERT(!init_seq_runner_->HasQueuedCommands());
1105
1106 if (!state_.bredr_data_buffer_info.IsAvailable() &&
1107 !state_.low_energy_state.acl_data_buffer_info().IsAvailable()) {
1108 bt_log(ERROR, "gap", "Both BR/EDR and LE buffers are unavailable");
1109 CompleteInitialization(/*success=*/false);
1110 return;
1111 }
1112
1113 // Now that we have all the ACL data buffer information it's time to
1114 // initialize the ACLDataChannel.
1115 if (!hci_->InitializeACLDataChannel(
1116 state_.bredr_data_buffer_info,
1117 state_.low_energy_state.acl_data_buffer_info())) {
1118 bt_log(ERROR, "gap", "Failed to initialize ACLDataChannel (step 3)");
1119 CompleteInitialization(/*success=*/false);
1120 return;
1121 }
1122
1123 // The controller may not support SCO flow control (as implied by not
1124 // supporting HCI_Write_Synchronous_Flow_Control_Enable), in which case we
1125 // don't support HCI SCO on this controller yet.
1126 // TODO(fxbug.dev/42171056): Support controllers that don't support SCO flow
1127 // control.
1128 bool sco_flow_control_supported = state_.IsCommandSupported(
1129 /*octet=*/10,
1130 hci_spec::SupportedCommand::kWriteSynchronousFlowControlEnable);
1131 if (state_.sco_buffer_info.IsAvailable() && sco_flow_control_supported) {
1132 // Enable SCO flow control.
1133 auto sync_flow_control = hci::EmbossCommandPacket::New<
1134 pw::bluetooth::emboss::WriteSynchronousFlowControlEnableCommandWriter>(
1135 hci_spec::kWriteSynchronousFlowControlEnable);
1136 auto flow_control_params = sync_flow_control.view_t();
1137 flow_control_params.synchronous_flow_control_enable().Write(
1138 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1139 init_seq_runner_->QueueCommand(
1140 std::move(sync_flow_control), [this](const hci::EventPacket& event) {
1141 if (hci_is_error(event,
1142 ERROR,
1143 "gap",
1144 "Write synchronous flow control enable failed, "
1145 "proceeding without HCI "
1146 "SCO support")) {
1147 return;
1148 }
1149
1150 if (!hci_->InitializeScoDataChannel(state_.sco_buffer_info)) {
1151 bt_log(WARN,
1152 "gap",
1153 "Failed to initialize ScoDataChannel, proceeding without "
1154 "HCI SCO support");
1155 return;
1156 }
1157 bt_log(DEBUG, "gap", "ScoDataChannel initialized successfully");
1158 });
1159 } else {
1160 bt_log(INFO,
1161 "gap",
1162 "HCI SCO not supported (SCO buffer available: %d, SCO flow control "
1163 "supported: %d)",
1164 state_.sco_buffer_info.IsAvailable(),
1165 sco_flow_control_supported);
1166 }
1167
1168 hci_->AttachInspect(adapter_node_);
1169
1170 // Create ChannelManager, if we haven't been provided one for testing. Doing
1171 // so here lets us guarantee that AclDataChannel's lifetime is a superset of
1172 // ChannelManager's lifetime.
1173 if (!l2cap_) {
1174 // Initialize ChannelManager to make it available for the next
1175 // initialization step. The AclDataChannel must be initialized before
1176 // creating ChannelManager.
1177 l2cap_ = l2cap::ChannelManager::Create(hci_->acl_data_channel(),
1178 hci_->command_channel(),
1179 /*random_channel_ids=*/true,
1180 dispatcher_);
1181 l2cap_->AttachInspect(adapter_node_,
1182 l2cap::ChannelManager::kInspectNodeName);
1183 }
1184
1185 // HCI_Set_Event_Mask
1186 {
1187 uint64_t event_mask = BuildEventMask();
1188 auto set_event = hci::EmbossCommandPacket::New<
1189 pw::bluetooth::emboss::SetEventMaskCommandWriter>(
1190 hci_spec::kSetEventMask);
1191 auto set_event_params = set_event.view_t();
1192 set_event_params.event_mask().Write(event_mask);
1193 init_seq_runner_->QueueCommand(
1194 std::move(set_event), [](const hci::EventPacket& event) {
1195 hci_is_error(event, WARN, "gap", "set event mask failed");
1196 });
1197 }
1198
1199 // HCI_LE_Set_Event_Mask
1200 {
1201 uint64_t event_mask = BuildLEEventMask();
1202 auto cmd_packet = hci::EmbossCommandPacket::New<
1203 pw::bluetooth::emboss::LESetEventMaskCommandWriter>(
1204 hci_spec::kLESetEventMask);
1205 cmd_packet.view_t().le_event_mask().BackingStorage().WriteUInt(event_mask);
1206 init_seq_runner_->QueueCommand(
1207 std::move(cmd_packet), [](const hci::EventPacket& event) {
1208 hci_is_error(event, WARN, "gap", "LE set event mask failed");
1209 });
1210 }
1211
1212 // If page 2 of the extended features bitfield is available, read it
1213 if (max_lmp_feature_page_index_.has_value() &&
1214 max_lmp_feature_page_index_.value() > 1) {
1215 InitQueueReadLMPFeatureMaskPage(2);
1216 }
1217
1218 init_seq_runner_->RunCommands([this](hci::Result<> status) mutable {
1219 if (bt_is_error(
1220 status,
1221 ERROR,
1222 "gap",
1223 "failed to obtain initial controller information (step 3)")) {
1224 CompleteInitialization(/*success=*/false);
1225 return;
1226 }
1227 InitializeStep4();
1228 });
1229 }
1230
InitializeStep4()1231 void AdapterImpl::InitializeStep4() {
1232 // Initialize the scan manager and low energy adapters based on current
1233 // feature support
1234 BT_DEBUG_ASSERT(IsInitializing());
1235
1236 // We use the public controller address as the local LE identity address.
1237 DeviceAddress adapter_identity(DeviceAddress::Type::kLEPublic,
1238 state_.controller_address);
1239
1240 // Initialize the LE local address manager.
1241 le_address_manager_ = std::make_unique<LowEnergyAddressManager>(
1242 adapter_identity,
1243 fit::bind_member<&AdapterImpl::IsLeRandomAddressChangeAllowed>(this),
1244 hci_->command_channel()->AsWeakPtr(),
1245 dispatcher_);
1246
1247 // Initialize the HCI adapters.
1248 hci_le_advertiser_ = CreateAdvertiser();
1249 hci_le_connector_ = std::make_unique<hci::LowEnergyConnector>(
1250 hci_,
1251 le_address_manager_.get(),
1252 dispatcher_,
1253 fit::bind_member<&hci::LowEnergyAdvertiser::OnIncomingConnection>(
1254 hci_le_advertiser_.get()));
1255 hci_le_scanner_ = std::make_unique<hci::LegacyLowEnergyScanner>(
1256 le_address_manager_.get(), hci_, dispatcher_);
1257
1258 // Initialize the LE manager objects
1259 le_discovery_manager_ = std::make_unique<LowEnergyDiscoveryManager>(
1260 hci_le_scanner_.get(), &peer_cache_, dispatcher_);
1261 le_discovery_manager_->AttachInspect(
1262 adapter_node_, kInspectLowEnergyDiscoveryManagerNodeName);
1263 le_discovery_manager_->set_peer_connectable_callback(
1264 fit::bind_member<&AdapterImpl::OnLeAutoConnectRequest>(this));
1265
1266 le_connection_manager_ = std::make_unique<LowEnergyConnectionManager>(
1267 hci_->command_channel()->AsWeakPtr(),
1268 le_address_manager_.get(),
1269 hci_le_connector_.get(),
1270 &peer_cache_,
1271 l2cap_.get(),
1272 gatt_,
1273 le_discovery_manager_->GetWeakPtr(),
1274 sm::SecurityManager::Create,
1275 dispatcher_);
1276 le_connection_manager_->AttachInspect(
1277 adapter_node_, kInspectLowEnergyConnectionManagerNodeName);
1278
1279 le_advertising_manager_ = std::make_unique<LowEnergyAdvertisingManager>(
1280 hci_le_advertiser_.get(), le_address_manager_.get());
1281 low_energy_ = std::make_unique<LowEnergyImpl>(this);
1282
1283 // Initialize the BR/EDR manager objects if the controller supports BR/EDR.
1284 if (state_.IsBREDRSupported()) {
1285 DeviceAddress local_bredr_address(DeviceAddress::Type::kBREDR,
1286 state_.controller_address);
1287
1288 bredr_connection_manager_ = std::make_unique<BrEdrConnectionManager>(
1289 hci_,
1290 &peer_cache_,
1291 local_bredr_address,
1292 l2cap_.get(),
1293 state_.features.HasBit(/*page=*/0,
1294 hci_spec::LMPFeature::kInterlacedPageScan),
1295 state_.IsLocalSecureConnectionsSupported(),
1296 dispatcher_);
1297 bredr_connection_manager_->AttachInspect(
1298 adapter_node_, kInspectBrEdrConnectionManagerNodeName);
1299
1300 pw::bluetooth::emboss::InquiryMode mode =
1301 pw::bluetooth::emboss::InquiryMode::STANDARD;
1302 if (state_.features.HasBit(
1303 /*page=*/0, hci_spec::LMPFeature::kExtendedInquiryResponse)) {
1304 mode = pw::bluetooth::emboss::InquiryMode::EXTENDED;
1305 } else if (state_.features.HasBit(
1306 /*page=*/0, hci_spec::LMPFeature::kRSSIwithInquiryResults)) {
1307 mode = pw::bluetooth::emboss::InquiryMode::RSSI;
1308 }
1309
1310 bredr_discovery_manager_ = std::make_unique<BrEdrDiscoveryManager>(
1311 dispatcher_, hci_->command_channel()->AsWeakPtr(), mode, &peer_cache_);
1312 bredr_discovery_manager_->AttachInspect(
1313 adapter_node_, kInspectBrEdrDiscoveryManagerNodeName);
1314
1315 sdp_server_ = std::make_unique<sdp::Server>(l2cap_.get());
1316 sdp_server_->AttachInspect(adapter_node_);
1317
1318 bredr_ = std::make_unique<BrEdrImpl>(this);
1319 }
1320
1321 // Override the current privacy setting and always use the local stable
1322 // identity address (i.e. not a RPA) when initiating connections. This
1323 // improves interoperability with certain Bluetooth peripherals that fail to
1324 // authenticate following a RPA rotation.
1325 //
1326 // The implication here is that the public address is revealed in LL
1327 // connection request PDUs. LE central privacy is still preserved during an
1328 // active scan, i.e. in LL scan request PDUs.
1329 //
1330 // TODO(fxbug.dev/42141593): Remove this temporary fix once we determine the
1331 // root cause for authentication failures.
1332 hci_le_connector_->UseLocalIdentityAddress();
1333
1334 // Update properties before callback called so properties can be verified in
1335 // unit tests.
1336 UpdateInspectProperties();
1337
1338 // Assign a default name and device class before notifying completion.
1339 auto self = weak_self_.GetWeakPtr();
1340 SetLocalName(kDefaultLocalName, [self](auto status) mutable {
1341 // Set the default device class - a computer with audio.
1342 // TODO(fxbug.dev/42074312): set this from a platform configuration file
1343 DeviceClass dev_class(DeviceClass::MajorClass::kComputer);
1344 dev_class.SetServiceClasses({DeviceClass::ServiceClass::kAudio});
1345 self->SetDeviceClass(dev_class, [self](const auto&) {
1346 self->CompleteInitialization(/*success=*/true);
1347 });
1348 });
1349 }
1350
CompleteInitialization(bool success)1351 bool AdapterImpl::CompleteInitialization(bool success) {
1352 if (!init_cb_) {
1353 return false;
1354 }
1355
1356 if (success) {
1357 init_state_ = State::kInitialized;
1358 } else {
1359 CleanUp();
1360 }
1361
1362 init_cb_(success);
1363 return true;
1364 }
1365
InitQueueReadLMPFeatureMaskPage(uint8_t page)1366 void AdapterImpl::InitQueueReadLMPFeatureMaskPage(uint8_t page) {
1367 BT_DEBUG_ASSERT(init_seq_runner_);
1368 BT_DEBUG_ASSERT(init_seq_runner_->IsReady());
1369
1370 if (max_lmp_feature_page_index_.has_value() &&
1371 page > max_lmp_feature_page_index_.value()) {
1372 bt_log(WARN,
1373 "gap",
1374 "Maximum value of LMP features mask page is %lu. Received page %hu",
1375 max_lmp_feature_page_index_.value(),
1376 page);
1377 return;
1378 }
1379
1380 if (page == 0) {
1381 init_seq_runner_->QueueCommand(
1382 hci::EmbossCommandPacket::New<
1383 pw::bluetooth::emboss::ReadLocalSupportedFeaturesCommandView>(
1384 hci_spec::kReadLocalSupportedFeatures),
1385 [this, page](const hci::EventPacket& cmd_complete) {
1386 if (hci_is_error(cmd_complete,
1387 WARN,
1388 "gap",
1389 "read local supported features failed")) {
1390 return;
1391 }
1392 auto params = cmd_complete.return_params<
1393 hci_spec::ReadLocalSupportedFeaturesReturnParams>();
1394 state_.features.SetPage(page, le64toh(params->lmp_features));
1395 });
1396 return;
1397 }
1398
1399 if (!state_.features.HasBit(/*page=*/0u,
1400 hci_spec::LMPFeature::kExtendedFeatures)) {
1401 bt_log(WARN, "gap", "LMP features mask does not have extended features");
1402 max_lmp_feature_page_index_ = 0;
1403 return;
1404 }
1405
1406 if (!max_lmp_feature_page_index_.has_value() ||
1407 page <= max_lmp_feature_page_index_.value()) {
1408 // HCI_Read_Local_Extended_Features
1409 auto cmd_packet = hci::EmbossCommandPacket::New<
1410 pw::bluetooth::emboss::ReadLocalExtendedFeaturesCommandWriter>(
1411 hci_spec::kReadLocalExtendedFeatures);
1412 cmd_packet.view_t().page_number().Write(page); // Try to read |page|
1413
1414 init_seq_runner_->QueueCommand(
1415 std::move(cmd_packet),
1416 [this, page](const hci::EventPacket& cmd_complete) {
1417 if (hci_is_error(cmd_complete,
1418 WARN,
1419 "gap",
1420 "read local extended features failed")) {
1421 return;
1422 }
1423 auto params = cmd_complete.return_params<
1424 hci_spec::ReadLocalExtendedFeaturesReturnParams>();
1425 state_.features.SetPage(page, le64toh(params->extended_lmp_features));
1426 max_lmp_feature_page_index_ = params->maximum_page_number;
1427 });
1428 }
1429 }
1430
UpdateInspectProperties()1431 void AdapterImpl::UpdateInspectProperties() {
1432 inspect_properties_.adapter_id =
1433 adapter_node_.CreateString("adapter_id", identifier_.ToString());
1434 inspect_properties_.hci_version = adapter_node_.CreateString(
1435 "hci_version", hci_spec::HCIVersionToString(state_.hci_version));
1436
1437 inspect_properties_.bredr_max_num_packets = adapter_node_.CreateUint(
1438 "bredr_max_num_packets", state_.bredr_data_buffer_info.max_num_packets());
1439 inspect_properties_.bredr_max_data_length = adapter_node_.CreateUint(
1440 "bredr_max_data_length", state_.bredr_data_buffer_info.max_data_length());
1441
1442 inspect_properties_.le_max_num_packets = adapter_node_.CreateUint(
1443 "le_max_num_packets",
1444 state_.low_energy_state.acl_data_buffer_info().max_num_packets());
1445 inspect_properties_.le_max_data_length = adapter_node_.CreateUint(
1446 "le_max_data_length",
1447 state_.low_energy_state.acl_data_buffer_info().max_data_length());
1448
1449 inspect_properties_.sco_max_num_packets = adapter_node_.CreateUint(
1450 "sco_max_num_packets", state_.sco_buffer_info.max_num_packets());
1451 inspect_properties_.sco_max_data_length = adapter_node_.CreateUint(
1452 "sco_max_data_length", state_.sco_buffer_info.max_data_length());
1453
1454 inspect_properties_.lmp_features =
1455 adapter_node_.CreateString("lmp_features", state_.features.ToString());
1456
1457 auto le_features = bt_lib_cpp_string::StringPrintf(
1458 "0x%016lx", state_.low_energy_state.supported_features());
1459 inspect_properties_.le_features =
1460 adapter_node_.CreateString("le_features", le_features);
1461 }
1462
CleanUp()1463 void AdapterImpl::CleanUp() {
1464 if (init_state_ == State::kNotInitialized) {
1465 bt_log(DEBUG, "gap", "clean up: not initialized");
1466 return;
1467 }
1468
1469 init_state_ = State::kNotInitialized;
1470 state_ = AdapterState();
1471 transport_error_cb_ = nullptr;
1472
1473 // Destroy objects in reverse order of construction.
1474 low_energy_ = nullptr;
1475 bredr_ = nullptr;
1476 sdp_server_ = nullptr;
1477 bredr_discovery_manager_ = nullptr;
1478 le_advertising_manager_ = nullptr;
1479 le_connection_manager_ = nullptr;
1480 le_discovery_manager_ = nullptr;
1481
1482 hci_le_connector_ = nullptr;
1483 hci_le_advertiser_ = nullptr;
1484 hci_le_scanner_ = nullptr;
1485
1486 le_address_manager_ = nullptr;
1487
1488 l2cap_ = nullptr;
1489
1490 hci_.reset();
1491 }
1492
OnTransportError()1493 void AdapterImpl::OnTransportError() {
1494 bt_log(INFO, "gap", "HCI transport error");
1495 if (CompleteInitialization(/*success=*/false)) {
1496 return;
1497 }
1498 if (transport_error_cb_) {
1499 transport_error_cb_();
1500 }
1501 }
1502
OnLeAutoConnectRequest(Peer * peer)1503 void AdapterImpl::OnLeAutoConnectRequest(Peer* peer) {
1504 BT_DEBUG_ASSERT(le_connection_manager_);
1505 BT_DEBUG_ASSERT(peer);
1506 BT_DEBUG_ASSERT(peer->le());
1507
1508 PeerId peer_id = peer->identifier();
1509
1510 if (!peer->le()->should_auto_connect()) {
1511 bt_log(DEBUG,
1512 "gap",
1513 "ignoring auto-connection (peer->should_auto_connect() is false) "
1514 "(peer: %s)",
1515 bt_str(peer_id));
1516 return;
1517 }
1518
1519 LowEnergyConnectionOptions options{.auto_connect = true};
1520
1521 auto self = weak_self_.GetWeakPtr();
1522 le_connection_manager_->Connect(
1523 peer_id,
1524 [self, peer_id](auto result) {
1525 if (!self.is_alive()) {
1526 bt_log(DEBUG, "gap", "ignoring auto-connection (adapter destroyed)");
1527 return;
1528 }
1529
1530 if (result.is_error()) {
1531 bt_log(INFO,
1532 "gap",
1533 "failed to auto-connect (peer: %s, error: %s)",
1534 bt_str(peer_id),
1535 HostErrorToString(result.error_value()).c_str());
1536 return;
1537 }
1538
1539 auto conn = std::move(result).value();
1540 BT_ASSERT(conn);
1541 bt_log(INFO, "gap", "peer auto-connected (peer: %s)", bt_str(peer_id));
1542 if (self->auto_conn_cb_) {
1543 self->auto_conn_cb_(std::move(conn));
1544 }
1545 },
1546 options);
1547 }
1548
IsLeRandomAddressChangeAllowed()1549 bool AdapterImpl::IsLeRandomAddressChangeAllowed() {
1550 return hci_le_advertiser_->AllowsRandomAddressChange() &&
1551 hci_le_scanner_->AllowsRandomAddressChange() &&
1552 hci_le_connector_->AllowsRandomAddressChange();
1553 }
1554
Create(pw::async::Dispatcher & pw_dispatcher,hci::Transport::WeakPtr hci,gatt::GATT::WeakPtr gatt,std::unique_ptr<l2cap::ChannelManager> l2cap)1555 std::unique_ptr<Adapter> Adapter::Create(
1556 pw::async::Dispatcher& pw_dispatcher,
1557 hci::Transport::WeakPtr hci,
1558 gatt::GATT::WeakPtr gatt,
1559 std::unique_ptr<l2cap::ChannelManager> l2cap) {
1560 return std::make_unique<AdapterImpl>(
1561 pw_dispatcher, hci, gatt, std::move(l2cap));
1562 }
1563
1564 } // namespace bt::gap
1565