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 <pw_async/dispatcher.h>
18 #include <pw_bluetooth/hci_commands.emb.h>
19 #include <pw_bluetooth/hci_events.emb.h>
20 #include <pw_bytes/endian.h>
21
22 #include <cinttypes>
23
24 #include "pw_bluetooth_sapphire/internal/host/common/assert.h"
25 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
26 #include "pw_bluetooth_sapphire/internal/host/common/metrics.h"
27 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
28 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_connection_manager.h"
29 #include "pw_bluetooth_sapphire/internal/host/gap/bredr_discovery_manager.h"
30 #include "pw_bluetooth_sapphire/internal/host/gap/event_masks.h"
31 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
32 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_address_manager.h"
33 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_advertising_manager.h"
34 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_connection_manager.h"
35 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_discovery_manager.h"
36 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h"
37 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
38 #include "pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
39 #include "pw_bluetooth_sapphire/internal/host/hci-spec/vendor_protocol.h"
40 #include "pw_bluetooth_sapphire/internal/host/hci/android_extended_low_energy_advertiser.h"
41 #include "pw_bluetooth_sapphire/internal/host/hci/extended_low_energy_advertiser.h"
42 #include "pw_bluetooth_sapphire/internal/host/hci/extended_low_energy_scanner.h"
43 #include "pw_bluetooth_sapphire/internal/host/hci/legacy_low_energy_advertiser.h"
44 #include "pw_bluetooth_sapphire/internal/host/hci/legacy_low_energy_scanner.h"
45 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connector.h"
46 #include "pw_bluetooth_sapphire/internal/host/hci/sequential_command_runner.h"
47 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel_manager.h"
48 #include "pw_bluetooth_sapphire/internal/host/sm/security_manager.h"
49 #include "pw_bluetooth_sapphire/internal/host/transport/control_packets.h"
50 #include "pw_bluetooth_sapphire/internal/host/transport/transport.h"
51
52 namespace bt::gap {
53
54 namespace android_hci = hci_spec::vendor::android;
55 namespace android_emb = pw::bluetooth::vendor::android_hci;
56
57 static constexpr const char* kInspectLowEnergyDiscoveryManagerNodeName =
58 "low_energy_discovery_manager";
59 static constexpr const char* kInspectLowEnergyConnectionManagerNodeName =
60 "low_energy_connection_manager";
61 static constexpr const char* kInspectBrEdrConnectionManagerNodeName =
62 "bredr_connection_manager";
63 static constexpr const char* kInspectBrEdrDiscoveryManagerNodeName =
64 "bredr_discovery_manager";
65
66 // All asynchronous callbacks are posted on the Loop on which this Adapter
67 // instance is created.
68 class AdapterImpl final : public Adapter {
69 public:
70 explicit AdapterImpl(pw::async::Dispatcher& pw_dispatcher,
71 hci::Transport::WeakPtr hci,
72 gatt::GATT::WeakPtr gatt,
73 Config config,
74 std::unique_ptr<l2cap::ChannelManager> l2cap);
75 ~AdapterImpl() override;
76
identifier() const77 AdapterId identifier() const override { return identifier_; }
78
79 bool Initialize(InitializeCallback callback,
80 fit::closure transport_error_cb) override;
81
82 void ShutDown() override;
83
IsInitializing() const84 bool IsInitializing() const override {
85 return init_state_ == State::kInitializing;
86 }
87
IsInitialized() const88 bool IsInitialized() const override {
89 return init_state_ == State::kInitialized;
90 }
91
state() const92 const AdapterState& state() const override { return state_; }
93
94 class LowEnergyImpl final : public LowEnergy {
95 public:
LowEnergyImpl(AdapterImpl * adapter)96 explicit LowEnergyImpl(AdapterImpl* adapter) : adapter_(adapter) {}
97
Connect(PeerId peer_id,ConnectionResultCallback callback,LowEnergyConnectionOptions connection_options)98 void Connect(PeerId peer_id,
99 ConnectionResultCallback callback,
100 LowEnergyConnectionOptions connection_options) override {
101 adapter_->le_connection_manager_->Connect(
102 peer_id, std::move(callback), connection_options);
103 adapter_->metrics_.le.outgoing_connection_requests.Add();
104 }
105
Disconnect(PeerId peer_id)106 bool Disconnect(PeerId peer_id) override {
107 return adapter_->le_connection_manager_->Disconnect(peer_id);
108 }
109
OpenL2capChannel(PeerId peer_id,l2cap::Psm psm,l2cap::ChannelParameters params,sm::SecurityLevel security_level,l2cap::ChannelCallback cb)110 void OpenL2capChannel(PeerId peer_id,
111 l2cap::Psm psm,
112 l2cap::ChannelParameters params,
113 sm::SecurityLevel security_level,
114 l2cap::ChannelCallback cb) override {
115 adapter_->le_connection_manager_->OpenL2capChannel(
116 peer_id, psm, params, security_level, std::move(cb));
117 }
118
Pair(PeerId peer_id,sm::SecurityLevel pairing_level,sm::BondableMode bondable_mode,sm::ResultFunction<> cb)119 void Pair(PeerId peer_id,
120 sm::SecurityLevel pairing_level,
121 sm::BondableMode bondable_mode,
122 sm::ResultFunction<> cb) override {
123 adapter_->le_connection_manager_->Pair(
124 peer_id, pairing_level, bondable_mode, std::move(cb));
125 adapter_->metrics_.le.pair_requests.Add();
126 }
127
SetLESecurityMode(LESecurityMode mode)128 void SetLESecurityMode(LESecurityMode mode) override {
129 adapter_->le_connection_manager_->SetSecurityMode(mode);
130 }
131
security_mode() const132 LESecurityMode security_mode() const override {
133 return adapter_->le_connection_manager_->security_mode();
134 }
135
StartAdvertising(AdvertisingData data,AdvertisingData scan_rsp,AdvertisingInterval interval,bool extended_pdu,bool anonymous,bool include_tx_power_level,std::optional<ConnectableAdvertisingParameters> connectable,std::optional<DeviceAddress::Type> address_type,AdvertisingStatusCallback status_callback)136 void StartAdvertising(
137 AdvertisingData data,
138 AdvertisingData scan_rsp,
139 AdvertisingInterval interval,
140 bool extended_pdu,
141 bool anonymous,
142 bool include_tx_power_level,
143 std::optional<ConnectableAdvertisingParameters> connectable,
144 std::optional<DeviceAddress::Type> address_type,
145 AdvertisingStatusCallback status_callback) override {
146 LowEnergyAdvertisingManager::ConnectionCallback advertisement_connect_cb =
147 nullptr;
148 if (connectable) {
149 PW_CHECK(connectable->connection_cb);
150
151 // All advertisement connections are first registered with
152 // LowEnergyConnectionManager before being reported to higher layers.
153 advertisement_connect_cb =
154 [this, connectable_params = std::move(connectable)](
155 AdvertisementId advertisement_id,
156 std::unique_ptr<hci::LowEnergyConnection> link) mutable {
157 auto register_link_cb = [advertisement_id,
158 connection_callback = std::move(
159 connectable_params->connection_cb)](
160 ConnectionResult result) {
161 connection_callback(advertisement_id, std::move(result));
162 };
163
164 adapter_->le_connection_manager_->RegisterRemoteInitiatedLink(
165 std::move(link),
166 connectable_params->bondable_mode,
167 std::move(register_link_cb));
168 };
169 }
170
171 adapter_->le_advertising_manager_->StartAdvertising(
172 std::move(data),
173 std::move(scan_rsp),
174 std::move(advertisement_connect_cb),
175 interval,
176 extended_pdu,
177 anonymous,
178 include_tx_power_level,
179 address_type,
180 std::move(status_callback));
181 adapter_->metrics_.le.start_advertising_events.Add();
182 }
183
StartDiscovery(bool active,SessionCallback callback)184 void StartDiscovery(bool active, SessionCallback callback) override {
185 adapter_->le_discovery_manager_->StartDiscovery(active,
186 std::move(callback));
187 adapter_->metrics_.le.start_discovery_events.Add();
188 }
189
EnablePrivacy(bool enabled)190 void EnablePrivacy(bool enabled) override {
191 adapter_->le_address_manager_->EnablePrivacy(enabled);
192 }
193
PrivacyEnabled() const194 bool PrivacyEnabled() const override {
195 return adapter_->le_address_manager_->PrivacyEnabled();
196 }
197
CurrentAddress() const198 const DeviceAddress CurrentAddress() const override {
199 return adapter_->le_address_manager_->current_address();
200 }
201
register_address_changed_callback(fit::closure callback)202 void register_address_changed_callback(fit::closure callback) override {
203 auto cb = [addr_changed_cb = std::move(callback)](auto) {
204 addr_changed_cb();
205 };
206 adapter_->le_address_manager_->register_address_changed_callback(
207 std::move(cb));
208 }
209
set_irk(const std::optional<UInt128> & irk)210 void set_irk(const std::optional<UInt128>& irk) override {
211 adapter_->le_address_manager_->set_irk(irk);
212 }
213
irk() const214 std::optional<UInt128> irk() const override {
215 return adapter_->le_address_manager_->irk();
216 }
217
set_request_timeout_for_testing(pw::chrono::SystemClock::duration value)218 void set_request_timeout_for_testing(
219 pw::chrono::SystemClock::duration value) override {
220 adapter_->le_connection_manager_->set_request_timeout_for_testing(value);
221 }
222
set_scan_period_for_testing(pw::chrono::SystemClock::duration period)223 void set_scan_period_for_testing(
224 pw::chrono::SystemClock::duration period) override {
225 adapter_->le_discovery_manager_->set_scan_period(period);
226 }
227
228 private:
229 AdapterImpl* adapter_;
230 };
231
le() const232 LowEnergy* le() const override { return low_energy_.get(); }
233
234 class BrEdrImpl final : public BrEdr {
235 public:
BrEdrImpl(AdapterImpl * adapter)236 explicit BrEdrImpl(AdapterImpl* adapter) : adapter_(adapter) {}
237
Connect(PeerId peer_id,ConnectResultCallback callback)238 bool Connect(PeerId peer_id, ConnectResultCallback callback) override {
239 return adapter_->bredr_connection_manager_->Connect(peer_id,
240 std::move(callback));
241 adapter_->metrics_.bredr.outgoing_connection_requests.Add();
242 }
243
Disconnect(PeerId peer_id,DisconnectReason reason)244 bool Disconnect(PeerId peer_id, DisconnectReason reason) override {
245 return adapter_->bredr_connection_manager_->Disconnect(peer_id, reason);
246 }
247
OpenL2capChannel(PeerId peer_id,l2cap::Psm psm,BrEdrSecurityRequirements security_requirements,l2cap::ChannelParameters params,l2cap::ChannelCallback cb)248 void OpenL2capChannel(PeerId peer_id,
249 l2cap::Psm psm,
250 BrEdrSecurityRequirements security_requirements,
251 l2cap::ChannelParameters params,
252 l2cap::ChannelCallback cb) override {
253 adapter_->metrics_.bredr.open_l2cap_channel_requests.Add();
254 adapter_->bredr_connection_manager_->OpenL2capChannel(
255 peer_id, psm, security_requirements, params, std::move(cb));
256 }
257
GetPeerId(hci_spec::ConnectionHandle handle) const258 PeerId GetPeerId(hci_spec::ConnectionHandle handle) const override {
259 return adapter_->bredr_connection_manager_->GetPeerId(handle);
260 }
261
AddServiceSearch(const UUID & uuid,std::unordered_set<sdp::AttributeId> attributes,SearchCallback callback)262 SearchId AddServiceSearch(const UUID& uuid,
263 std::unordered_set<sdp::AttributeId> attributes,
264 SearchCallback callback) override {
265 return adapter_->bredr_connection_manager_->AddServiceSearch(
266 uuid, std::move(attributes), std::move(callback));
267 }
268
RemoveServiceSearch(SearchId id)269 bool RemoveServiceSearch(SearchId id) override {
270 return adapter_->bredr_connection_manager_->RemoveServiceSearch(id);
271 }
272
Pair(PeerId peer_id,BrEdrSecurityRequirements security,hci::ResultFunction<> callback)273 void Pair(PeerId peer_id,
274 BrEdrSecurityRequirements security,
275 hci::ResultFunction<> callback) override {
276 adapter_->bredr_connection_manager_->Pair(
277 peer_id, security, std::move(callback));
278 adapter_->metrics_.bredr.pair_requests.Add();
279 }
280
SetBrEdrSecurityMode(BrEdrSecurityMode mode)281 void SetBrEdrSecurityMode(BrEdrSecurityMode mode) override {
282 adapter_->bredr_connection_manager_->SetSecurityMode(mode);
283 }
284
security_mode() const285 BrEdrSecurityMode security_mode() const override {
286 return adapter_->bredr_connection_manager_->security_mode();
287 }
288
SetConnectable(bool connectable,hci::ResultFunction<> status_cb)289 void SetConnectable(bool connectable,
290 hci::ResultFunction<> status_cb) override {
291 adapter_->bredr_connection_manager_->SetConnectable(connectable,
292 std::move(status_cb));
293 if (connectable) {
294 adapter_->metrics_.bredr.set_connectable_true_events.Add();
295 } else {
296 adapter_->metrics_.bredr.set_connectable_false_events.Add();
297 }
298 }
299
RequestDiscovery(DiscoveryCallback callback)300 void RequestDiscovery(DiscoveryCallback callback) override {
301 adapter_->bredr_discovery_manager_->RequestDiscovery(std::move(callback));
302 }
303
RequestDiscoverable(DiscoverableCallback callback)304 void RequestDiscoverable(DiscoverableCallback callback) override {
305 adapter_->bredr_discovery_manager_->RequestDiscoverable(
306 std::move(callback));
307 }
308
RegisterService(std::vector<sdp::ServiceRecord> records,l2cap::ChannelParameters chan_params,ServiceConnectCallback conn_cb)309 RegistrationHandle RegisterService(
310 std::vector<sdp::ServiceRecord> records,
311 l2cap::ChannelParameters chan_params,
312 ServiceConnectCallback conn_cb) override {
313 return adapter_->sdp_server_->RegisterService(
314 std::move(records), chan_params, std::move(conn_cb));
315 }
316
UnregisterService(RegistrationHandle handle)317 bool UnregisterService(RegistrationHandle handle) override {
318 return adapter_->sdp_server_->UnregisterService(handle);
319 }
320
GetRegisteredServices(RegistrationHandle handle) const321 std::vector<sdp::ServiceRecord> GetRegisteredServices(
322 RegistrationHandle handle) const override {
323 return adapter_->sdp_server_->GetRegisteredServices(handle);
324 }
325
OpenScoConnection(PeerId peer_id,const bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter> & parameters,sco::ScoConnectionManager::OpenConnectionCallback callback)326 std::optional<ScoRequestHandle> OpenScoConnection(
327 PeerId peer_id,
328 const bt::StaticPacket<
329 pw::bluetooth::emboss::SynchronousConnectionParametersWriter>&
330 parameters,
331 sco::ScoConnectionManager::OpenConnectionCallback callback) override {
332 return adapter_->bredr_connection_manager_->OpenScoConnection(
333 peer_id, parameters, std::move(callback));
334 }
AcceptScoConnection(PeerId peer_id,const std::vector<bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>> parameters,sco::ScoConnectionManager::AcceptConnectionCallback callback)335 std::optional<ScoRequestHandle> AcceptScoConnection(
336 PeerId peer_id,
337 const std::vector<bt::StaticPacket<
338 pw::bluetooth::emboss::SynchronousConnectionParametersWriter>>
339 parameters,
340 sco::ScoConnectionManager::AcceptConnectionCallback callback) override {
341 return adapter_->bredr_connection_manager_->AcceptScoConnection(
342 peer_id, std::move(parameters), std::move(callback));
343 }
344
345 private:
346 AdapterImpl* adapter_;
347 };
348
bredr() const349 BrEdr* bredr() const override { return bredr_.get(); }
350
peer_cache()351 PeerCache* peer_cache() override { return &peer_cache_; }
352
353 bool AddBondedPeer(BondingData bonding_data) override;
354
355 void SetPairingDelegate(PairingDelegate::WeakPtr delegate) override;
356
357 bool IsDiscoverable() const override;
358
359 bool IsDiscovering() const override;
360
361 void SetLocalName(std::string name, hci::ResultFunction<> callback) override;
362
local_name() const363 std::string local_name() const override {
364 return bredr_discovery_manager_->local_name();
365 }
366
367 void SetDeviceClass(DeviceClass dev_class,
368 hci::ResultFunction<> callback) override;
369
370 void GetSupportedDelayRange(
371 const bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter>& codec_id,
372 pw::bluetooth::emboss::LogicalTransportType logical_transport_type,
373 pw::bluetooth::emboss::DataPathDirection direction,
374 const std::optional<std::vector<uint8_t>>& codec_configuration,
375 GetSupportedDelayRangeCallback cb) override;
376
set_auto_connect_callback(AutoConnectCallback callback)377 void set_auto_connect_callback(AutoConnectCallback callback) override {
378 auto_conn_cb_ = std::move(callback);
379 }
380
381 void AttachInspect(inspect::Node& parent, std::string name) override;
382
AsWeakPtr()383 WeakSelf<Adapter>::WeakPtr AsWeakPtr() override {
384 return weak_self_adapter_.GetWeakPtr();
385 }
386
387 private:
388 // Called by Initialize() after Transport is initialized.
389 void InitializeStep1();
390
391 // Second step of the initialization sequence. Called by InitializeStep1()
392 // when the first batch of HCI commands have been sent.
393 void InitializeStep2();
394
395 // Third step of the initialization sequence. Called by InitializeStep2() when
396 // the second batch of HCI commands have been sent.
397 void InitializeStep3();
398
399 // Fourth step of the initialization sequence. Called by InitializeStep3()
400 // when the third batch of HCI commands have been sent.
401 void InitializeStep4();
402
403 // Returns true if initialization was completed, or false if initialization is
404 // not in progress.
405 bool CompleteInitialization(bool success);
406
407 // Reads LMP feature mask's bits from |page|
408 void InitQueueReadLMPFeatureMaskPage(uint8_t page);
409
410 // Assigns properties to |adapter_node_| using values discovered during other
411 // initialization steps.
412 void UpdateInspectProperties();
413
414 // Called by ShutDown() and during Initialize() in case of failure. This
415 // synchronously cleans up the transports and resets initialization state.
416 void CleanUp();
417
418 // Called by Transport after it experiences a fatal error.
419 void OnTransportError();
420
421 // Called when a directed connectable advertisement is received from a bonded
422 // LE device. This amounts to a connection request from a bonded peripheral
423 // which is handled by routing the request to |le_connection_manager_| to
424 // initiate a Direct Connection Establishment procedure (Vol 3, Part C,
425 // 9.3.8).
426 void OnLeAutoConnectRequest(Peer* peer);
427
428 // Called by |le_address_manager_| to query whether it is currently allowed to
429 // reconfigure the LE random address.
430 bool IsLeRandomAddressChangeAllowed();
431
432 // Called when we receive an LE Get Vendor Capabilities Command Complete from
433 // the Controller
434 void ParseLEGetVendorCapabilitiesCommandComplete(
435 const hci::EventPacket& event);
436
CreateAdvertiser(bool extended)437 std::unique_ptr<hci::LowEnergyAdvertiser> CreateAdvertiser(bool extended) {
438 if (extended) {
439 return std::make_unique<hci::ExtendedLowEnergyAdvertiser>(
440 hci_, state_.low_energy_state.max_advertising_data_length_);
441 }
442
443 constexpr pw::bluetooth::Controller::FeaturesBits feature =
444 pw::bluetooth::Controller::FeaturesBits::kAndroidVendorExtensions;
445 if (!state().IsControllerFeatureSupported(feature)) {
446 return std::make_unique<hci::LegacyLowEnergyAdvertiser>(hci_);
447 }
448
449 if (!state().android_vendor_capabilities) {
450 bt_log(
451 WARN,
452 "gap",
453 "controller supports android vendor extensions, but failed to parse "
454 "LEGetVendorCapabilitiesCommandComplete, using legacy advertiser");
455 return std::make_unique<hci::LegacyLowEnergyAdvertiser>(hci_);
456 }
457
458 uint8_t max_advt =
459 state().android_vendor_capabilities->max_simultaneous_advertisements();
460 bt_log(INFO,
461 "gap",
462 "controller supports android vendor extensions, max simultaneous "
463 "advertisements: %d",
464 max_advt);
465 return std::make_unique<hci::AndroidExtendedLowEnergyAdvertiser>(hci_,
466 max_advt);
467 }
468
CreateConnector(bool extended)469 std::unique_ptr<hci::LowEnergyConnector> CreateConnector(bool extended) {
470 return std::make_unique<hci::LowEnergyConnector>(
471 hci_,
472 le_address_manager_.get(),
473 dispatcher_,
474 fit::bind_member<&hci::LowEnergyAdvertiser::OnIncomingConnection>(
475 hci_le_advertiser_.get()),
476 extended);
477 }
478
CreateScanner(bool extended)479 std::unique_ptr<hci::LowEnergyScanner> CreateScanner(bool extended) {
480 if (extended) {
481 return std::make_unique<hci::ExtendedLowEnergyScanner>(
482 le_address_manager_.get(), hci_, dispatcher_);
483 }
484
485 return std::make_unique<hci::LegacyLowEnergyScanner>(
486 le_address_manager_.get(), hci_, dispatcher_);
487 }
488
489 // Must be initialized first so that child nodes can be passed to other
490 // constructors.
491 inspect::Node adapter_node_;
492 struct InspectProperties {
493 inspect::StringProperty adapter_id;
494 inspect::StringProperty hci_version;
495 inspect::UintProperty bredr_max_num_packets;
496 inspect::UintProperty bredr_max_data_length;
497 inspect::UintProperty le_max_num_packets;
498 inspect::UintProperty le_max_data_length;
499 inspect::UintProperty sco_max_num_packets;
500 inspect::UintProperty sco_max_data_length;
501 inspect::StringProperty lmp_features;
502 inspect::StringProperty le_features;
503 };
504 InspectProperties inspect_properties_;
505
506 // Metrics properties
507 inspect::Node metrics_node_;
508 inspect::Node metrics_bredr_node_;
509 inspect::Node metrics_le_node_;
510 struct AdapterMetrics {
511 struct LeMetrics {
512 UintMetricCounter outgoing_connection_requests;
513 UintMetricCounter pair_requests;
514 UintMetricCounter start_advertising_events;
515 UintMetricCounter stop_advertising_events;
516 UintMetricCounter start_discovery_events;
517 } le;
518 struct BrEdrMetrics {
519 UintMetricCounter outgoing_connection_requests;
520 UintMetricCounter pair_requests;
521 UintMetricCounter set_connectable_true_events;
522 UintMetricCounter set_connectable_false_events;
523 UintMetricCounter open_l2cap_channel_requests;
524 } bredr;
525 };
526 AdapterMetrics metrics_;
527
528 // Uniquely identifies this adapter on the current system.
529 AdapterId identifier_;
530
531 hci::Transport::WeakPtr hci_;
532
533 // Callback invoked to notify clients when the underlying transport is closed.
534 fit::closure transport_error_cb_;
535
536 // Parameters relevant to the initialization sequence.
537 // TODO(armansito): The Initialize()/ShutDown() pattern has become common
538 // enough in this project that it might be worth considering moving the
539 // init-state-keeping into an abstract base.
540 enum State {
541 kNotInitialized = 0,
542 kInitializing,
543 kInitialized,
544 };
545 std::atomic<State> init_state_;
546 std::unique_ptr<hci::SequentialCommandRunner> init_seq_runner_;
547
548 // The callback passed to Initialize(). Null after initialization completes.
549 InitializeCallback init_cb_;
550
551 // Contains the global adapter state.
552 AdapterState state_;
553
554 // The maximum LMP feature page that we will read.
555 std::optional<size_t> max_lmp_feature_page_index_;
556
557 // Provides access to discovered, connected, and/or bonded remote Bluetooth
558 // devices.
559 PeerCache peer_cache_;
560
561 // L2CAP layer used by GAP. This must be destroyed after the following members
562 // because they raw pointers to this member.
563 std::unique_ptr<l2cap::ChannelManager> l2cap_;
564
565 // The GATT profile. We use this reference to add and remove data bearers and
566 // for service discovery.
567 gatt::GATT::WeakPtr gatt_;
568
569 // Contains feature flags based on the product's configuration
570 Config config_;
571
572 // Objects that abstract the controller for connection and advertising
573 // procedures.
574 std::unique_ptr<hci::LowEnergyAdvertiser> hci_le_advertiser_;
575 std::unique_ptr<hci::LowEnergyConnector> hci_le_connector_;
576 std::unique_ptr<hci::LowEnergyScanner> hci_le_scanner_;
577
578 // Objects that perform LE procedures.
579 std::unique_ptr<LowEnergyAddressManager> le_address_manager_;
580 std::unique_ptr<LowEnergyDiscoveryManager> le_discovery_manager_;
581 std::unique_ptr<LowEnergyConnectionManager> le_connection_manager_;
582 std::unique_ptr<LowEnergyAdvertisingManager> le_advertising_manager_;
583 std::unique_ptr<LowEnergyImpl> low_energy_;
584
585 // Objects that perform BR/EDR procedures.
586 std::unique_ptr<BrEdrConnectionManager> bredr_connection_manager_;
587 std::unique_ptr<BrEdrDiscoveryManager> bredr_discovery_manager_;
588 std::unique_ptr<sdp::Server> sdp_server_;
589 std::unique_ptr<BrEdrImpl> bredr_;
590
591 // Callback to propagate ownership of an auto-connected LE link.
592 AutoConnectCallback auto_conn_cb_;
593
594 pw::async::Dispatcher& dispatcher_;
595
596 // This must remain the last member to make sure that all weak pointers are
597 // invalidating before other members are destroyed.
598 WeakSelf<AdapterImpl> weak_self_;
599 WeakSelf<Adapter> weak_self_adapter_;
600
601 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AdapterImpl);
602 };
603
AdapterImpl(pw::async::Dispatcher & pw_dispatcher,hci::Transport::WeakPtr hci,gatt::GATT::WeakPtr gatt,Config config,std::unique_ptr<l2cap::ChannelManager> l2cap)604 AdapterImpl::AdapterImpl(pw::async::Dispatcher& pw_dispatcher,
605 hci::Transport::WeakPtr hci,
606 gatt::GATT::WeakPtr gatt,
607 Config config,
608 std::unique_ptr<l2cap::ChannelManager> l2cap)
609 : identifier_(Random<AdapterId>()),
610 hci_(std::move(hci)),
611 init_state_(State::kNotInitialized),
612 peer_cache_(pw_dispatcher),
613 l2cap_(std::move(l2cap)),
614 gatt_(std::move(gatt)),
615 config_(config),
616 dispatcher_(pw_dispatcher),
617 weak_self_(this),
618 weak_self_adapter_(this) {
619 PW_DCHECK(hci_.is_alive());
620 PW_DCHECK(gatt_.is_alive());
621
622 auto self = weak_self_.GetWeakPtr();
623 hci_->SetTransportErrorCallback([self] {
624 if (self.is_alive()) {
625 self->OnTransportError();
626 }
627 });
628
629 gatt_->SetPersistServiceChangedCCCCallback(
630 [this](PeerId peer_id, gatt::ServiceChangedCCCPersistedData gatt_data) {
631 Peer* peer = peer_cache_.FindById(peer_id);
632 if (!peer) {
633 bt_log(WARN,
634 "gap",
635 "Unable to find peer %s when storing persisted GATT data.",
636 bt_str(peer_id));
637 } else if (!peer->le()) {
638 bt_log(WARN,
639 "gap",
640 "Tried to store persisted GATT data for non-LE peer %s.",
641 bt_str(peer_id));
642 } else {
643 peer->MutLe().set_service_changed_gatt_data(gatt_data);
644 }
645 });
646
647 gatt_->SetRetrieveServiceChangedCCCCallback([this](PeerId peer_id) {
648 Peer* peer = peer_cache_.FindById(peer_id);
649 if (!peer) {
650 bt_log(WARN,
651 "gap",
652 "Unable to find peer %s when retrieving persisted GATT data.",
653 peer_id.ToString().c_str());
654 return std::optional<gatt::ServiceChangedCCCPersistedData>();
655 }
656
657 if (!peer->le()) {
658 bt_log(WARN,
659 "gap",
660 "Tried to retrieve persisted GATT data for non-LE peer %s.",
661 peer_id.ToString().c_str());
662 return std::optional<gatt::ServiceChangedCCCPersistedData>();
663 }
664
665 return std::optional(peer->le()->get_service_changed_gatt_data());
666 });
667 }
668
~AdapterImpl()669 AdapterImpl::~AdapterImpl() {
670 if (IsInitialized()) {
671 ShutDown();
672 }
673 }
674
Initialize(InitializeCallback callback,fit::closure transport_error_cb)675 bool AdapterImpl::Initialize(InitializeCallback callback,
676 fit::closure transport_error_cb) {
677 PW_DCHECK(callback);
678 PW_DCHECK(transport_error_cb);
679
680 if (IsInitialized()) {
681 bt_log(WARN, "gap", "Adapter already initialized");
682 return false;
683 }
684
685 PW_DCHECK(!IsInitializing());
686 PW_DCHECK(!init_seq_runner_);
687
688 init_state_ = State::kInitializing;
689 init_cb_ = std::move(callback);
690 transport_error_cb_ = std::move(transport_error_cb);
691
692 hci_->Initialize([this](bool success) {
693 if (!success) {
694 bt_log(ERROR, "gap", "Failed to initialize Transport");
695 CompleteInitialization(/*success=*/false);
696 return;
697 }
698 init_seq_runner_ = std::make_unique<hci::SequentialCommandRunner>(
699 hci_->command_channel()->AsWeakPtr());
700
701 InitializeStep1();
702 });
703
704 return true;
705 }
706
ShutDown()707 void AdapterImpl::ShutDown() {
708 bt_log(DEBUG, "gap", "adapter shutting down");
709
710 if (IsInitializing()) {
711 PW_DCHECK(!init_seq_runner_->IsReady());
712 init_seq_runner_->Cancel();
713 }
714
715 CleanUp();
716 }
717
AddBondedPeer(BondingData bonding_data)718 bool AdapterImpl::AddBondedPeer(BondingData bonding_data) {
719 return peer_cache()->AddBondedPeer(bonding_data);
720 }
721
SetPairingDelegate(PairingDelegate::WeakPtr delegate)722 void AdapterImpl::SetPairingDelegate(PairingDelegate::WeakPtr delegate) {
723 le_connection_manager_->SetPairingDelegate(delegate);
724 bredr_connection_manager_->SetPairingDelegate(delegate);
725 }
726
IsDiscoverable() const727 bool AdapterImpl::IsDiscoverable() const {
728 if (bredr_discovery_manager_ && bredr_discovery_manager_->discoverable()) {
729 return true;
730 }
731
732 // If LE Privacy is enabled, then we are not discoverable.
733 // TODO(fxbug.dev/42060496): Make this dependent on whether the LE Public
734 // advertisement is active or not.
735 if (le_address_manager_ && le_address_manager_->PrivacyEnabled()) {
736 return false;
737 }
738
739 return (le_advertising_manager_ && le_advertising_manager_->advertising());
740 }
741
IsDiscovering() const742 bool AdapterImpl::IsDiscovering() const {
743 return (le_discovery_manager_ && le_discovery_manager_->discovering()) ||
744 (bredr_discovery_manager_ && bredr_discovery_manager_->discovering());
745 }
746
SetLocalName(std::string name,hci::ResultFunction<> callback)747 void AdapterImpl::SetLocalName(std::string name,
748 hci::ResultFunction<> callback) {
749 // TODO(fxbug.dev/42116852): set the public LE advertisement name from |name|
750 // If BrEdr is not supported, skip the name update.
751 if (!bredr_discovery_manager_) {
752 callback(ToResult(bt::HostError::kNotSupported));
753 return;
754 }
755
756 // Make a copy of |name| to move separately into the lambda.
757 std::string name_copy(name);
758 bredr_discovery_manager_->UpdateLocalName(
759 std::move(name),
760 [this, cb = std::move(callback), local_name = std::move(name_copy)](
761 auto status) {
762 if (!bt_is_error(status, WARN, "gap", "set local name failed")) {
763 state_.local_name = local_name;
764 }
765 cb(status);
766 });
767 }
768
SetDeviceClass(DeviceClass dev_class,hci::ResultFunction<> callback)769 void AdapterImpl::SetDeviceClass(DeviceClass dev_class,
770 hci::ResultFunction<> callback) {
771 auto write_dev_class = hci::CommandPacket::New<
772 pw::bluetooth::emboss::WriteClassOfDeviceCommandWriter>(
773 hci_spec::kWriteClassOfDevice);
774 write_dev_class.view_t().class_of_device().BackingStorage().WriteUInt(
775 dev_class.to_int());
776 hci_->command_channel()->SendCommand(
777 std::move(write_dev_class),
778 [cb = std::move(callback)](auto, const hci::EventPacket& event) {
779 HCI_IS_ERROR(event, WARN, "gap", "set device class failed");
780 cb(event.ToResult());
781 });
782 }
783
GetSupportedDelayRange(const bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter> & codec_id,pw::bluetooth::emboss::LogicalTransportType logical_transport_type,pw::bluetooth::emboss::DataPathDirection direction,const std::optional<std::vector<uint8_t>> & codec_configuration,GetSupportedDelayRangeCallback cb)784 void AdapterImpl::GetSupportedDelayRange(
785 const bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter>& codec_id,
786 pw::bluetooth::emboss::LogicalTransportType logical_transport_type,
787 pw::bluetooth::emboss::DataPathDirection direction,
788 const std::optional<std::vector<uint8_t>>& codec_configuration,
789 GetSupportedDelayRangeCallback cb) {
790 if (!state_.SupportedCommands()
791 .read_local_supported_controller_delay()
792 .Read()) {
793 bt_log(WARN,
794 "gap",
795 "read local supported controller delay command not supported");
796 cb(PW_STATUS_UNIMPLEMENTED, /*min=*/0, /*max=*/0);
797 return;
798 }
799 bt_log(INFO, "gap", "retrieving controller codec delay");
800 size_t codec_configuration_size = 0;
801 if (codec_configuration.has_value()) {
802 codec_configuration_size = codec_configuration->size();
803 }
804 size_t packet_size =
805 pw::bluetooth::emboss::ReadLocalSupportedControllerDelayCommand::
806 MinSizeInBytes() +
807 codec_configuration_size;
808 auto cmd_packet = hci::CommandPacket::New<
809 pw::bluetooth::emboss::ReadLocalSupportedControllerDelayCommandWriter>(
810 hci_spec::kReadLocalSupportedControllerDelay, packet_size);
811 auto cmd_view = cmd_packet.view_t();
812 cmd_view.codec_id().CopyFrom(
813 const_cast<bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter>&>(
814 codec_id)
815 .view());
816 cmd_view.logical_transport_type().Write(logical_transport_type);
817 cmd_view.direction().Write(direction);
818 cmd_view.codec_configuration_length().Write(codec_configuration_size);
819 if (codec_configuration.has_value()) {
820 std::memcpy(cmd_view.codec_configuration().BackingStorage().data(),
821 codec_configuration->data(),
822 codec_configuration_size);
823 }
824
825 hci_->command_channel()->SendCommand(
826 std::move(cmd_packet),
827 [callback = std::move(cb)](auto /*id*/, const hci::EventPacket& event) {
828 auto view = event.view<
829 pw::bluetooth::emboss::
830 ReadLocalSupportedControllerDelayCommandCompleteEventView>();
831 if (HCI_IS_ERROR(event,
832 WARN,
833 "gap",
834 "read local supported controller delay failed")) {
835 callback(PW_STATUS_UNKNOWN, /*min=*/0, /*max=*/0);
836 return;
837 }
838 bt_log(INFO, "gap", "controller delay read successfully");
839 callback(PW_STATUS_OK,
840 view.min_controller_delay().Read(),
841 view.max_controller_delay().Read());
842 });
843 }
844
AttachInspect(inspect::Node & parent,std::string name)845 void AdapterImpl::AttachInspect(inspect::Node& parent, std::string name) {
846 adapter_node_ = parent.CreateChild(name);
847 UpdateInspectProperties();
848
849 peer_cache_.AttachInspect(adapter_node_);
850
851 metrics_node_ = adapter_node_.CreateChild(kMetricsInspectNodeName);
852
853 metrics_le_node_ = metrics_node_.CreateChild("le");
854 metrics_.le.outgoing_connection_requests.AttachInspect(
855 metrics_le_node_, "outgoing_connection_requests");
856 metrics_.le.pair_requests.AttachInspect(metrics_le_node_, "pair_requests");
857 metrics_.le.start_advertising_events.AttachInspect(
858 metrics_le_node_, "start_advertising_events");
859 metrics_.le.stop_advertising_events.AttachInspect(metrics_le_node_,
860 "stop_advertising_events");
861 metrics_.le.start_discovery_events.AttachInspect(metrics_le_node_,
862 "start_discovery_events");
863
864 metrics_bredr_node_ = metrics_node_.CreateChild("bredr");
865 metrics_.bredr.outgoing_connection_requests.AttachInspect(
866 metrics_bredr_node_, "outgoing_connection_requests");
867 metrics_.bredr.pair_requests.AttachInspect(metrics_bredr_node_,
868 "pair_requests");
869 metrics_.bredr.set_connectable_true_events.AttachInspect(
870 metrics_bredr_node_, "set_connectable_true_events");
871 metrics_.bredr.set_connectable_false_events.AttachInspect(
872 metrics_bredr_node_, "set_connectable_false_events");
873 metrics_.bredr.open_l2cap_channel_requests.AttachInspect(
874 metrics_bredr_node_, "open_l2cap_channel_requests");
875 }
876
ParseLEGetVendorCapabilitiesCommandComplete(const hci::EventPacket & event)877 void AdapterImpl::ParseLEGetVendorCapabilitiesCommandComplete(
878 const hci::EventPacket& event) {
879 // NOTE: There can be various versions of this command complete event
880 // sent by the Controller. As fields are added, the version_supported
881 // field is incremented to signify which fields are available. In a previous
882 // undertaking (pwrev.dev/203950, fxrev.dev/1029396), we attempted to use
883 // Emboss' conditional fields feature to define fields based on the version
884 // they are included in. However, in practice, we've found vendors sometimes
885 // send the wrong number of bytes required for the version they claim to send.
886 // To tolerate these types of errors, we simply define all the fields in
887 // Emboss. If we receive a response smaller than what we expect, we use what
888 // the vendor sends, and fill the rest with zero to disable the feature. If we
889 // receive a response larger than what we expect, we read up to what we
890 // support and drop the rest of the data.
891 StaticPacket<android_emb::LEGetVendorCapabilitiesCommandCompleteEventView>
892 packet;
893 packet.SetToZeros();
894 size_t copy_size = std::min(packet.data().size(), event.size());
895 packet.mutable_data().Write(event.data().data(), copy_size);
896
897 auto params = packet.view();
898 state_.android_vendor_capabilities = AndroidVendorCapabilities::New(params);
899
900 size_t expected_size = 0;
901 uint8_t major = params.version_supported().major_number().Read();
902 uint8_t minor = params.version_supported().minor_number().Read();
903
904 if (major == 0 && minor == 0) {
905 // The version_supported field was only introduced into the command in
906 // Version 0.95. Controllers that use the base version, Version 0.55,
907 // don't have the version_supported field.
908 expected_size = android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
909 version_0_55_size();
910 } else if (major == 0 && minor == 95) {
911 expected_size = android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
912 version_0_95_size();
913 } else if (major == 0 && minor == 96) {
914 expected_size = android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
915 version_0_96_size();
916 } else if (major == 0 && minor == 98) {
917 expected_size = android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
918 version_0_98_size();
919 } else if (major == 1 && minor == 03) {
920 expected_size = android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
921 version_1_03_size();
922 } else if (major == 1 && minor == 04) {
923 expected_size = android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
924 version_1_04_size();
925 }
926
927 if (event.size() != expected_size) {
928 bt_log(WARN,
929 "gap",
930 "LE Get Vendor Capabilities Command Complete, received %zu bytes, "
931 "expected %zu bytes, version: %d.%d",
932 event.size(),
933 expected_size,
934 major,
935 minor);
936 }
937 }
938
InitializeStep1()939 void AdapterImpl::InitializeStep1() {
940 state_.controller_features = hci_->GetFeatures();
941
942 // Start by resetting the controller to a clean state and then send
943 // informational parameter commands that are not specific to LE or BR/EDR. The
944 // commands sent here are mandatory for all LE controllers.
945 //
946 // NOTE: It's safe to pass capture |this| directly in the callbacks as
947 // |init_seq_runner_| will internally invalidate the callbacks if it ever gets
948 // deleted.
949
950 // HCI_Reset
951 auto reset_command =
952 hci::CommandPacket::New<pw::bluetooth::emboss::ResetCommandWriter>(
953 hci_spec::kReset);
954 init_seq_runner_->QueueCommand(std::move(reset_command));
955
956 // HCI_Read_Local_Version_Information
957 init_seq_runner_->QueueCommand(
958 hci::CommandPacket::New<
959 pw::bluetooth::emboss::ReadLocalVersionInformationCommandView>(
960 hci_spec::kReadLocalVersionInfo),
961 [this](const hci::EventPacket& cmd_complete) {
962 if (HCI_IS_ERROR(
963 cmd_complete, WARN, "gap", "read local version info failed")) {
964 return;
965 }
966 auto params =
967 cmd_complete
968 .view<pw::bluetooth::emboss::
969 ReadLocalVersionInfoCommandCompleteEventView>();
970 state_.hci_version = params.hci_version().Read();
971 });
972
973 // HCI_Read_Local_Supported_Commands
974 init_seq_runner_->QueueCommand(
975 hci::CommandPacket::New<
976 pw::bluetooth::emboss::ReadLocalSupportedCommandsCommandView>(
977 hci_spec::kReadLocalSupportedCommands),
978 [this](const hci::EventPacket& cmd_complete) {
979 if (HCI_IS_ERROR(cmd_complete,
980 WARN,
981 "gap",
982 "read local supported commands failed")) {
983 return;
984 }
985 auto view =
986 cmd_complete
987 .view<pw::bluetooth::emboss::
988 ReadLocalSupportedCommandsCommandCompleteEventView>();
989 std::copy(view.supported_commands().BackingStorage().begin(),
990 view.supported_commands().BackingStorage().end(),
991 state_.supported_commands);
992 });
993
994 // HCI_Read_Local_Supported_Features
995 InitQueueReadLMPFeatureMaskPage(0);
996
997 // HCI_Read_BD_ADDR
998 init_seq_runner_->QueueCommand(
999 hci::CommandPacket::New<pw::bluetooth::emboss::ReadBdAddrCommandView>(
1000 hci_spec::kReadBDADDR),
1001 [this](const hci::EventPacket& cmd_complete) {
1002 if (HCI_IS_ERROR(cmd_complete, WARN, "gap", "read BR_ADDR failed")) {
1003 return;
1004 }
1005 auto packet = cmd_complete.view<
1006 pw::bluetooth::emboss::ReadBdAddrCommandCompleteEventView>();
1007 state_.controller_address = DeviceAddressBytes(packet.bd_addr());
1008 });
1009
1010 if (state().IsControllerFeatureSupported(
1011 pw::bluetooth::Controller::FeaturesBits::kAndroidVendorExtensions)) {
1012 bt_log(INFO,
1013 "gap",
1014 "controller supports android hci extensions, querying exact feature "
1015 "set");
1016 init_seq_runner_->QueueCommand(
1017 hci::CommandPacket::New<
1018 android_emb::LEGetVendorCapabilitiesCommandView>(
1019 android_hci::kLEGetVendorCapabilities),
1020 [this](const hci::EventPacket& event) {
1021 if (HCI_IS_ERROR(
1022 event,
1023 WARN,
1024 "gap",
1025 "Failed to query android hci extension capabilities")) {
1026 return;
1027 }
1028
1029 ParseLEGetVendorCapabilitiesCommandComplete(event);
1030 });
1031 }
1032
1033 init_seq_runner_->RunCommands([this](hci::Result<> status) mutable {
1034 if (bt_is_error(status,
1035 ERROR,
1036 "gap",
1037 "Failed to obtain initial controller information: %s",
1038 bt_str(status))) {
1039 CompleteInitialization(/*success=*/false);
1040 return;
1041 }
1042
1043 InitializeStep2();
1044 });
1045 }
1046
InitializeStep2()1047 void AdapterImpl::InitializeStep2() {
1048 PW_DCHECK(IsInitializing());
1049
1050 // Low Energy MUST be supported. We don't support BR/EDR-only controllers.
1051 if (!state_.IsLowEnergySupported()) {
1052 bt_log(ERROR, "gap", "Bluetooth LE not supported by controller");
1053 CompleteInitialization(/*success=*/false);
1054 return;
1055 }
1056
1057 // Check the HCI version. We officially only support 4.2+ only but for now we
1058 // just log a warning message if the version is legacy.
1059 if (state_.hci_version <
1060 pw::bluetooth::emboss::CoreSpecificationVersion::V4_2) {
1061 bt_log(WARN,
1062 "gap",
1063 "controller is using legacy HCI version %s",
1064 hci_spec::HCIVersionToString(state_.hci_version).c_str());
1065 }
1066
1067 PW_DCHECK(init_seq_runner_->IsReady());
1068
1069 // If the controller supports the Read Buffer Size command then send it.
1070 // Otherwise we'll default to 0 when initializing the ACLDataChannel.
1071 if (state_.SupportedCommands().read_buffer_size().Read()) {
1072 // HCI_Read_Buffer_Size
1073 init_seq_runner_->QueueCommand(
1074 hci::CommandPacket::New<
1075 pw::bluetooth::emboss::ReadBufferSizeCommandView>(
1076 hci_spec::kReadBufferSize),
1077 [this](const hci::EventPacket& cmd_complete) {
1078 if (HCI_IS_ERROR(
1079 cmd_complete, WARN, "gap", "read buffer size failed")) {
1080 return;
1081 }
1082 auto packet = cmd_complete.view<
1083 pw::bluetooth::emboss::ReadBufferSizeCommandCompleteEventView>();
1084 uint16_t acl_mtu = packet.acl_data_packet_length().Read();
1085 uint16_t acl_max_count = packet.total_num_acl_data_packets().Read();
1086 if (acl_mtu && acl_max_count) {
1087 state_.bredr_data_buffer_info =
1088 hci::DataBufferInfo(acl_mtu, acl_max_count);
1089 }
1090 // Use UncheckedRead because this field is supposed to
1091 // be 0x01-0xFF, but it is possible and harmless for controllers to
1092 // set to 0x00 if not supported.
1093 uint16_t sco_mtu =
1094 packet.synchronous_data_packet_length().UncheckedRead();
1095 uint16_t sco_max_count =
1096 packet.total_num_synchronous_data_packets().Read();
1097 if (sco_mtu && sco_max_count) {
1098 state_.sco_buffer_info =
1099 hci::DataBufferInfo(sco_mtu, sco_max_count);
1100 }
1101 });
1102 }
1103
1104 // HCI_LE_Read_Local_Supported_Features
1105 init_seq_runner_->QueueCommand(
1106 hci::CommandPacket::New<
1107 pw::bluetooth::emboss::LEReadLocalSupportedFeaturesCommandView>(
1108 hci_spec::kLEReadLocalSupportedFeatures),
1109 [this](const hci::EventPacket& cmd_complete) {
1110 if (HCI_IS_ERROR(cmd_complete,
1111 WARN,
1112 "gap",
1113 "LE read local supported features failed")) {
1114 return;
1115 }
1116 auto packet = cmd_complete.view<
1117 pw::bluetooth::emboss::
1118 LEReadLocalSupportedFeaturesCommandCompleteEventView>();
1119 state_.low_energy_state.supported_features_ =
1120 packet.le_features().BackingStorage().ReadUInt();
1121 });
1122
1123 // HCI_LE_Read_Supported_States
1124 init_seq_runner_->QueueCommand(
1125 hci::CommandPacket::New<
1126 pw::bluetooth::emboss::LEReadSupportedStatesCommandView>(
1127 hci_spec::kLEReadSupportedStates),
1128 [this](const hci::EventPacket& cmd_complete) {
1129 if (HCI_IS_ERROR(cmd_complete,
1130 WARN,
1131 "gap",
1132 "LE read local supported states failed")) {
1133 return;
1134 }
1135 auto packet =
1136 cmd_complete
1137 .view<pw::bluetooth::emboss::
1138 LEReadSupportedStatesCommandCompleteEventView>();
1139 state_.low_energy_state.supported_states_ =
1140 packet.le_states().BackingStorage().ReadLittleEndianUInt<64>();
1141 });
1142
1143 if (state_.SupportedCommands()
1144 .le_read_maximum_advertising_data_length()
1145 .Read()) {
1146 // HCI_LE_Read_Maximum_Advertising_Data_Length
1147 init_seq_runner_->QueueCommand(
1148 hci::CommandPacket::New<
1149 pw::bluetooth::emboss::LEReadMaxAdvertisingDataLengthCommandView>(
1150 hci_spec::kLEReadMaximumAdvertisingDataLength),
1151 [this](const hci::EventPacket& cmd_complete) {
1152 if (HCI_IS_ERROR(cmd_complete,
1153 WARN,
1154 "gap",
1155 "LE read maximum advertising data length failed")) {
1156 return;
1157 }
1158
1159 auto params = cmd_complete.view<
1160 pw::bluetooth::emboss::
1161 LEReadMaximumAdvertisingDataLengthCommandCompleteEventView>();
1162 state_.low_energy_state.max_advertising_data_length_ =
1163 params.max_advertising_data_length().Read();
1164 bt_log(INFO,
1165 "gap",
1166 "maximum advertising data length: %d",
1167 state_.low_energy_state.max_advertising_data_length_);
1168 });
1169 } else {
1170 bt_log(INFO,
1171 "gap",
1172 "LE read maximum advertising data command not supported, "
1173 "defaulting to legacy maximum: %zu",
1174 hci_spec::kMaxLEAdvertisingDataLength);
1175 state_.low_energy_state.max_advertising_data_length_ =
1176 hci_spec::kMaxLEAdvertisingDataLength;
1177 }
1178
1179 if (state_.SupportedCommands().le_read_buffer_size_v2().Read()) {
1180 // HCI_LE_Read_Buffer_Size [v2]
1181 init_seq_runner_->QueueCommand(
1182 hci::CommandPacket::New<
1183 pw::bluetooth::emboss::LEReadBufferSizeCommandV2View>(
1184 hci_spec::kLEReadBufferSizeV2),
1185 [this](const hci::EventPacket& cmd_complete) {
1186 if (HCI_IS_ERROR(cmd_complete,
1187 WARN,
1188 "gap",
1189 "LE read buffer size [v2] failed")) {
1190 return;
1191 }
1192 auto params =
1193 cmd_complete
1194 .view<pw::bluetooth::emboss::
1195 LEReadBufferSizeV2CommandCompleteEventView>();
1196 uint16_t acl_mtu = params.le_acl_data_packet_length().Read();
1197 uint8_t acl_max_count = params.total_num_le_acl_data_packets().Read();
1198 if (acl_mtu && acl_max_count) {
1199 state_.low_energy_state.acl_data_buffer_info_ =
1200 hci::DataBufferInfo(acl_mtu, acl_max_count);
1201 }
1202 uint16_t iso_mtu = params.iso_data_packet_length().Read();
1203 uint8_t iso_max_count = params.total_num_iso_data_packets().Read();
1204 if (iso_mtu && iso_max_count) {
1205 state_.low_energy_state.iso_data_buffer_info_ =
1206 hci::DataBufferInfo(iso_mtu, iso_max_count);
1207 }
1208 });
1209 } else {
1210 // HCI_LE_Read_Buffer_Size [v1]
1211 init_seq_runner_->QueueCommand(
1212 hci::CommandPacket::New<
1213 pw::bluetooth::emboss::LEReadBufferSizeCommandV1View>(
1214 hci_spec::kLEReadBufferSizeV1),
1215 [this](const hci::EventPacket& cmd_complete) {
1216 if (HCI_IS_ERROR(
1217 cmd_complete, WARN, "gap", "LE read buffer size failed")) {
1218 return;
1219 }
1220 auto params =
1221 cmd_complete
1222 .view<pw::bluetooth::emboss::
1223 LEReadBufferSizeV1CommandCompleteEventView>();
1224 uint16_t mtu = params.le_acl_data_packet_length().Read();
1225 uint8_t max_count = params.total_num_le_acl_data_packets().Read();
1226 if (mtu && max_count) {
1227 state_.low_energy_state.acl_data_buffer_info_ =
1228 hci::DataBufferInfo(mtu, max_count);
1229 }
1230 });
1231 }
1232
1233 if (state_.features.HasBit(
1234 /*page=*/0u,
1235 hci_spec::LMPFeature::kSecureSimplePairingControllerSupport)) {
1236 // HCI_Write_Simple_Pairing_Mode
1237 auto write_spm = hci::CommandPacket::New<
1238 pw::bluetooth::emboss::WriteSimplePairingModeCommandWriter>(
1239 hci_spec::kWriteSimplePairingMode);
1240 auto write_ssp_params = write_spm.view_t();
1241 write_ssp_params.simple_pairing_mode().Write(
1242 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1243 init_seq_runner_->QueueCommand(
1244 std::move(write_spm), [](const hci::EventPacket& event) {
1245 // Warn if the command failed
1246 HCI_IS_ERROR(event, WARN, "gap", "write simple pairing mode failed");
1247 });
1248 }
1249
1250 // If there are extended features then try to read the first page of the
1251 // extended features.
1252 if (state_.features.HasBit(/*page=*/0u,
1253 hci_spec::LMPFeature::kExtendedFeatures)) {
1254 // HCI_Write_LE_Host_Support
1255 if (!state_.SupportedCommands().write_le_host_support().Read()) {
1256 bt_log(INFO, "gap", "LE Host is not supported");
1257 } else {
1258 bt_log(INFO, "gap", "LE Host is supported. Enabling LE Host mode");
1259 auto cmd_packet = hci::CommandPacket::New<
1260 pw::bluetooth::emboss::WriteLEHostSupportCommandWriter>(
1261 hci_spec::kWriteLEHostSupport);
1262 auto params = cmd_packet.view_t();
1263 params.le_supported_host().Write(
1264 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1265 init_seq_runner_->QueueCommand(
1266 std::move(cmd_packet), [](const hci::EventPacket& event) {
1267 HCI_IS_ERROR(event, WARN, "gap", "Write LE Host support failed");
1268 });
1269 }
1270
1271 // HCI_Write_Secure_Connections_Host_Support
1272 if (!state_.SupportedCommands()
1273 .write_secure_connections_host_support()
1274 .Read()) {
1275 bt_log(INFO, "gap", "Secure Connections (Host Support) is not supported");
1276 } else {
1277 bt_log(INFO,
1278 "gap",
1279 "Secure Connections (Host Support) is supported. "
1280 "Enabling Secure Connections (Host Support) mode");
1281 auto cmd_packet = hci::CommandPacket::New<
1282 pw::bluetooth::emboss::
1283 WriteSecureConnectionsHostSupportCommandWriter>(
1284 hci_spec::kWriteSecureConnectionsHostSupport);
1285 auto params = cmd_packet.view_t();
1286 params.secure_connections_host_support().Write(
1287 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1288 init_seq_runner_->QueueCommand(
1289 std::move(cmd_packet), [](const hci::EventPacket& event) {
1290 HCI_IS_ERROR(event,
1291 WARN,
1292 "gap",
1293 "Write Secure Connections (Host Support) failed");
1294 });
1295 }
1296
1297 // Read updated page 1 after host support bits enabled.
1298 InitQueueReadLMPFeatureMaskPage(1);
1299 }
1300
1301 init_seq_runner_->RunCommands([this](hci::Result<> status) mutable {
1302 if (bt_is_error(
1303 status,
1304 ERROR,
1305 "gap",
1306 "failed to obtain initial controller information (step 2)")) {
1307 CompleteInitialization(/*success=*/false);
1308 return;
1309 }
1310 InitializeStep3();
1311 });
1312 }
1313
InitializeStep3()1314 void AdapterImpl::InitializeStep3() {
1315 PW_CHECK(IsInitializing());
1316 PW_CHECK(init_seq_runner_->IsReady());
1317 PW_CHECK(!init_seq_runner_->HasQueuedCommands());
1318
1319 if (!state_.bredr_data_buffer_info.IsAvailable() &&
1320 !state_.low_energy_state.acl_data_buffer_info().IsAvailable()) {
1321 bt_log(ERROR, "gap", "Both BR/EDR and LE buffers are unavailable");
1322 CompleteInitialization(/*success=*/false);
1323 return;
1324 }
1325
1326 // Now that we have all the ACL data buffer information it's time to
1327 // initialize the ACLDataChannel.
1328 if (!hci_->InitializeACLDataChannel(
1329 state_.bredr_data_buffer_info,
1330 state_.low_energy_state.acl_data_buffer_info())) {
1331 bt_log(ERROR, "gap", "Failed to initialize ACLDataChannel (step 3)");
1332 CompleteInitialization(/*success=*/false);
1333 return;
1334 }
1335
1336 if (!state_.low_energy_state.IsFeatureSupported(
1337 hci_spec::LESupportedFeature::
1338 kConnectedIsochronousStreamPeripheral)) {
1339 bt_log(INFO, "gap", "CIS Peripheral is not supported");
1340 } else {
1341 bt_log(INFO,
1342 "gap",
1343 "Connected Isochronous Stream Peripheral is supported. "
1344 "Enabling ConnectedIsochronousStream (Host Support)");
1345 auto cmd_packet = hci::CommandPacket::New<
1346 pw::bluetooth::emboss::LESetHostFeatureCommandWriter>(
1347 hci_spec::kLESetHostFeature);
1348 auto params = cmd_packet.view_t();
1349 params.bit_number().Write(
1350 static_cast<uint8_t>(hci_spec::LESupportedFeatureBitPos::
1351 kConnectedIsochronousStreamHostSupport));
1352 params.bit_value().Write(pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1353 init_seq_runner_->QueueCommand(
1354 std::move(cmd_packet), [](const hci::EventPacket& event) {
1355 HCI_IS_ERROR(
1356 event, WARN, "gap", "Set Host Feature (ISO support) failed");
1357 });
1358 }
1359
1360 // The controller may not support SCO flow control (as implied by not
1361 // supporting HCI_Write_Synchronous_Flow_Control_Enable), in which case we
1362 // don't support HCI SCO on this controller yet.
1363 // TODO(fxbug.dev/42171056): Support controllers that don't support
1364 // SCO flow control.
1365 bool sco_flow_control_supported =
1366 state_.SupportedCommands().write_synchronous_flow_control_enable().Read();
1367 if (state_.sco_buffer_info.IsAvailable() && sco_flow_control_supported) {
1368 // Enable SCO flow control.
1369 auto sync_flow_control = hci::CommandPacket::New<
1370 pw::bluetooth::emboss::WriteSynchronousFlowControlEnableCommandWriter>(
1371 hci_spec::kWriteSynchronousFlowControlEnable);
1372 auto flow_control_params = sync_flow_control.view_t();
1373 flow_control_params.synchronous_flow_control_enable().Write(
1374 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
1375 init_seq_runner_->QueueCommand(
1376 std::move(sync_flow_control), [this](const hci::EventPacket& event) {
1377 if (HCI_IS_ERROR(event,
1378 ERROR,
1379 "gap",
1380 "Write synchronous flow control enable failed, "
1381 "proceeding without HCI "
1382 "SCO support")) {
1383 return;
1384 }
1385
1386 if (!hci_->InitializeScoDataChannel(state_.sco_buffer_info)) {
1387 bt_log(WARN,
1388 "gap",
1389 "Failed to initialize ScoDataChannel, proceeding without "
1390 "HCI SCO support");
1391 return;
1392 }
1393 bt_log(DEBUG, "gap", "ScoDataChannel initialized successfully");
1394 });
1395 } else {
1396 bt_log(INFO,
1397 "gap",
1398 "HCI SCO not supported (SCO buffer available: %d, SCO flow control "
1399 "supported: %d)",
1400 state_.sco_buffer_info.IsAvailable(),
1401 sco_flow_control_supported);
1402 }
1403
1404 const hci::DataBufferInfo iso_data_buffer_info =
1405 state_.low_energy_state.iso_data_buffer_info();
1406 if (iso_data_buffer_info.IsAvailable()) {
1407 bt_log(INFO,
1408 "gap",
1409 "ISO data buffer information available (size: %zu, count: %zu)",
1410 iso_data_buffer_info.max_data_length(),
1411 iso_data_buffer_info.max_num_packets());
1412 if (hci_->InitializeIsoDataChannel(iso_data_buffer_info)) {
1413 bt_log(INFO, "gap", "IsoDataChannel initialized successfully");
1414 } else {
1415 bt_log(WARN,
1416 "gap",
1417 "Failed to initialize IsoDataChannel, proceeding without HCI ISO "
1418 "support");
1419 }
1420 } else {
1421 bt_log(
1422 INFO,
1423 "gap",
1424 "No ISO data buffer information available, not starting data channel");
1425 }
1426
1427 hci_->AttachInspect(adapter_node_);
1428
1429 // Create ChannelManager, if we haven't been provided one for testing. Doing
1430 // so here lets us guarantee that AclDataChannel's lifetime is a superset of
1431 // ChannelManager's lifetime.
1432 if (!l2cap_) {
1433 // Initialize ChannelManager to make it available for the next
1434 // initialization step. The AclDataChannel must be initialized before
1435 // creating ChannelManager.
1436 l2cap_ = l2cap::ChannelManager::Create(hci_->acl_data_channel(),
1437 hci_->command_channel(),
1438 /*random_channel_ids=*/true,
1439 dispatcher_);
1440 l2cap_->AttachInspect(adapter_node_,
1441 l2cap::ChannelManager::kInspectNodeName);
1442 }
1443
1444 // HCI_Set_Event_Mask
1445 {
1446 uint64_t event_mask = BuildEventMask();
1447 auto set_event = hci::CommandPacket::New<
1448 pw::bluetooth::emboss::SetEventMaskCommandWriter>(
1449 hci_spec::kSetEventMask);
1450 auto set_event_params = set_event.view_t();
1451 set_event_params.event_mask().Write(event_mask);
1452 init_seq_runner_->QueueCommand(
1453 std::move(set_event), [](const hci::EventPacket& event) {
1454 HCI_IS_ERROR(event, WARN, "gap", "set event mask failed");
1455 });
1456 }
1457
1458 // HCI_LE_Set_Event_Mask
1459 {
1460 uint64_t event_mask = BuildLEEventMask();
1461 auto cmd_packet = hci::CommandPacket::New<
1462 pw::bluetooth::emboss::LESetEventMaskCommandWriter>(
1463 hci_spec::kLESetEventMask);
1464 cmd_packet.view_t().le_event_mask().BackingStorage().WriteUInt(event_mask);
1465 init_seq_runner_->QueueCommand(
1466 std::move(cmd_packet), [](const hci::EventPacket& event) {
1467 HCI_IS_ERROR(event, WARN, "gap", "LE set event mask failed");
1468 });
1469 }
1470
1471 // If page 2 of the extended features bitfield is available, read it
1472 if (max_lmp_feature_page_index_.has_value() &&
1473 max_lmp_feature_page_index_.value() > 1) {
1474 InitQueueReadLMPFeatureMaskPage(2);
1475 }
1476
1477 init_seq_runner_->RunCommands([this](hci::Result<> status) mutable {
1478 if (bt_is_error(
1479 status,
1480 ERROR,
1481 "gap",
1482 "failed to obtain initial controller information (step 3)")) {
1483 CompleteInitialization(/*success=*/false);
1484 return;
1485 }
1486 InitializeStep4();
1487 });
1488 }
1489
InitializeStep4()1490 void AdapterImpl::InitializeStep4() {
1491 // Initialize the scan manager and low energy adapters based on current
1492 // feature support
1493 PW_DCHECK(IsInitializing());
1494
1495 // We use the public controller address as the local LE identity address.
1496 DeviceAddress adapter_identity(DeviceAddress::Type::kLEPublic,
1497 state_.controller_address);
1498
1499 // Initialize the LE local address manager.
1500 le_address_manager_ = std::make_unique<LowEnergyAddressManager>(
1501 adapter_identity,
1502 fit::bind_member<&AdapterImpl::IsLeRandomAddressChangeAllowed>(this),
1503 hci_->command_channel()->AsWeakPtr(),
1504 dispatcher_);
1505
1506 // Initialize the HCI adapters. Note: feature support for extended
1507 // scanning, connections, etc are all grouped under the extended advertising
1508 // feature flag.
1509 bool extended = state().low_energy_state.IsFeatureSupported(
1510 hci_spec::LESupportedFeature::kLEExtendedAdvertising);
1511 bt_log(INFO,
1512 "gap",
1513 "controller support for extended operations: %s",
1514 extended ? "yes" : "no");
1515 hci_le_advertiser_ = CreateAdvertiser(extended);
1516 hci_le_connector_ = CreateConnector(extended);
1517 hci_le_scanner_ = CreateScanner(extended);
1518
1519 // Initialize the LE manager objects
1520 le_discovery_manager_ = std::make_unique<LowEnergyDiscoveryManager>(
1521 hci_le_scanner_.get(), &peer_cache_, dispatcher_);
1522 le_discovery_manager_->AttachInspect(
1523 adapter_node_, kInspectLowEnergyDiscoveryManagerNodeName);
1524 le_discovery_manager_->set_peer_connectable_callback(
1525 fit::bind_member<&AdapterImpl::OnLeAutoConnectRequest>(this));
1526
1527 le_connection_manager_ = std::make_unique<LowEnergyConnectionManager>(
1528 hci_->GetWeakPtr(),
1529 le_address_manager_.get(),
1530 hci_le_connector_.get(),
1531 &peer_cache_,
1532 l2cap_.get(),
1533 gatt_,
1534 le_discovery_manager_->GetWeakPtr(),
1535 sm::SecurityManager::Create,
1536 state(),
1537 dispatcher_);
1538 le_connection_manager_->AttachInspect(
1539 adapter_node_, kInspectLowEnergyConnectionManagerNodeName);
1540
1541 le_advertising_manager_ = std::make_unique<LowEnergyAdvertisingManager>(
1542 hci_le_advertiser_.get(), le_address_manager_.get());
1543 low_energy_ = std::make_unique<LowEnergyImpl>(this);
1544
1545 // Initialize the BR/EDR manager objects if the controller supports BR/EDR.
1546 if (state_.IsBREDRSupported()) {
1547 DeviceAddress local_bredr_address(DeviceAddress::Type::kBREDR,
1548 state_.controller_address);
1549
1550 bredr_connection_manager_ = std::make_unique<BrEdrConnectionManager>(
1551 hci_,
1552 &peer_cache_,
1553 local_bredr_address,
1554 l2cap_.get(),
1555 state_.features.HasBit(/*page=*/0,
1556 hci_spec::LMPFeature::kInterlacedPageScan),
1557 state_.IsLocalSecureConnectionsSupported(),
1558 config_.legacy_pairing_enabled,
1559 dispatcher_);
1560 bredr_connection_manager_->AttachInspect(
1561 adapter_node_, kInspectBrEdrConnectionManagerNodeName);
1562
1563 pw::bluetooth::emboss::InquiryMode mode =
1564 pw::bluetooth::emboss::InquiryMode::STANDARD;
1565 if (state_.features.HasBit(
1566 /*page=*/0, hci_spec::LMPFeature::kExtendedInquiryResponse)) {
1567 mode = pw::bluetooth::emboss::InquiryMode::EXTENDED;
1568 } else if (state_.features.HasBit(
1569 /*page=*/0, hci_spec::LMPFeature::kRSSIwithInquiryResults)) {
1570 mode = pw::bluetooth::emboss::InquiryMode::RSSI;
1571 }
1572
1573 bredr_discovery_manager_ = std::make_unique<BrEdrDiscoveryManager>(
1574 dispatcher_, hci_->command_channel()->AsWeakPtr(), mode, &peer_cache_);
1575 bredr_discovery_manager_->AttachInspect(
1576 adapter_node_, kInspectBrEdrDiscoveryManagerNodeName);
1577
1578 sdp_server_ = std::make_unique<sdp::Server>(l2cap_.get());
1579 sdp_server_->AttachInspect(adapter_node_);
1580
1581 bredr_ = std::make_unique<BrEdrImpl>(this);
1582 }
1583
1584 // Override the current privacy setting and always use the local stable
1585 // identity address (i.e. not a RPA) when initiating connections. This
1586 // improves interoperability with certain Bluetooth peripherals that fail to
1587 // authenticate following a RPA rotation.
1588 //
1589 // The implication here is that the public address is revealed in LL
1590 // connection request PDUs. LE central privacy is still preserved during an
1591 // active scan, i.e. in LL scan request PDUs.
1592 //
1593 // TODO(fxbug.dev/42141593): Remove this temporary fix once we determine the
1594 // root cause for authentication failures.
1595 hci_le_connector_->UseLocalIdentityAddress();
1596
1597 // Update properties before callback called so properties can be verified in
1598 // unit tests.
1599 UpdateInspectProperties();
1600
1601 // Assign a default name and device class before notifying completion.
1602 auto self = weak_self_.GetWeakPtr();
1603 SetLocalName(kDefaultLocalName, [self](auto) mutable {
1604 // Set the default device class - a computer with audio.
1605 // TODO(fxbug.dev/42074312): set this from a platform configuration file
1606 DeviceClass dev_class(DeviceClass::MajorClass::kComputer);
1607 dev_class.SetServiceClasses({DeviceClass::ServiceClass::kAudio});
1608 self->SetDeviceClass(dev_class, [self](const auto&) {
1609 self->CompleteInitialization(/*success=*/true);
1610 });
1611 });
1612 }
1613
CompleteInitialization(bool success)1614 bool AdapterImpl::CompleteInitialization(bool success) {
1615 if (!init_cb_) {
1616 return false;
1617 }
1618
1619 if (success) {
1620 init_state_ = State::kInitialized;
1621 } else {
1622 CleanUp();
1623 }
1624
1625 init_cb_(success);
1626 return true;
1627 }
1628
InitQueueReadLMPFeatureMaskPage(uint8_t page)1629 void AdapterImpl::InitQueueReadLMPFeatureMaskPage(uint8_t page) {
1630 PW_DCHECK(init_seq_runner_);
1631 PW_DCHECK(init_seq_runner_->IsReady());
1632
1633 if (max_lmp_feature_page_index_.has_value() &&
1634 page > max_lmp_feature_page_index_.value()) {
1635 bt_log(WARN,
1636 "gap",
1637 "Maximum value of LMP features mask page is %zu. Received page "
1638 "%" PRIx8,
1639 max_lmp_feature_page_index_.value(),
1640 page);
1641 return;
1642 }
1643
1644 if (page == 0) {
1645 init_seq_runner_->QueueCommand(
1646 hci::CommandPacket::New<
1647 pw::bluetooth::emboss::ReadLocalSupportedFeaturesCommandView>(
1648 hci_spec::kReadLocalSupportedFeatures),
1649 [this, page](const hci::EventPacket& cmd_complete) {
1650 if (HCI_IS_ERROR(cmd_complete,
1651 WARN,
1652 "gap",
1653 "read local supported features failed")) {
1654 return;
1655 }
1656 auto view = cmd_complete.view<
1657 pw::bluetooth::emboss::
1658 ReadLocalSupportedFeaturesCommandCompleteEventView>();
1659 state_.features.SetPage(page, view.lmp_features().Read());
1660 });
1661 return;
1662 }
1663
1664 if (!state_.features.HasBit(/*page=*/0u,
1665 hci_spec::LMPFeature::kExtendedFeatures)) {
1666 bt_log(WARN, "gap", "LMP features mask does not have extended features");
1667 max_lmp_feature_page_index_ = 0;
1668 return;
1669 }
1670
1671 if (!max_lmp_feature_page_index_.has_value() ||
1672 page <= max_lmp_feature_page_index_.value()) {
1673 // HCI_Read_Local_Extended_Features
1674 auto cmd_packet = hci::CommandPacket::New<
1675 pw::bluetooth::emboss::ReadLocalExtendedFeaturesCommandWriter>(
1676 hci_spec::kReadLocalExtendedFeatures);
1677 cmd_packet.view_t().page_number().Write(page); // Try to read |page|
1678
1679 init_seq_runner_->QueueCommand(
1680 std::move(cmd_packet),
1681 [this, page](const hci::EventPacket& cmd_complete) {
1682 if (HCI_IS_ERROR(cmd_complete,
1683 WARN,
1684 "gap",
1685 "read local extended features failed")) {
1686 return;
1687 }
1688 auto view = cmd_complete.view<
1689 pw::bluetooth::emboss::
1690 ReadLocalExtendedFeaturesCommandCompleteEventView>();
1691 state_.features.SetPage(page, view.extended_lmp_features().Read());
1692 max_lmp_feature_page_index_ = view.max_page_number().Read();
1693 });
1694 }
1695 }
1696
UpdateInspectProperties()1697 void AdapterImpl::UpdateInspectProperties() {
1698 inspect_properties_.adapter_id =
1699 adapter_node_.CreateString("adapter_id", identifier_.ToString());
1700 inspect_properties_.hci_version = adapter_node_.CreateString(
1701 "hci_version", hci_spec::HCIVersionToString(state_.hci_version));
1702
1703 inspect_properties_.bredr_max_num_packets = adapter_node_.CreateUint(
1704 "bredr_max_num_packets", state_.bredr_data_buffer_info.max_num_packets());
1705 inspect_properties_.bredr_max_data_length = adapter_node_.CreateUint(
1706 "bredr_max_data_length", state_.bredr_data_buffer_info.max_data_length());
1707
1708 inspect_properties_.le_max_num_packets = adapter_node_.CreateUint(
1709 "le_max_num_packets",
1710 state_.low_energy_state.acl_data_buffer_info().max_num_packets());
1711 inspect_properties_.le_max_data_length = adapter_node_.CreateUint(
1712 "le_max_data_length",
1713 state_.low_energy_state.acl_data_buffer_info().max_data_length());
1714
1715 inspect_properties_.sco_max_num_packets = adapter_node_.CreateUint(
1716 "sco_max_num_packets", state_.sco_buffer_info.max_num_packets());
1717 inspect_properties_.sco_max_data_length = adapter_node_.CreateUint(
1718 "sco_max_data_length", state_.sco_buffer_info.max_data_length());
1719
1720 inspect_properties_.lmp_features =
1721 adapter_node_.CreateString("lmp_features", state_.features.ToString());
1722
1723 auto le_features = bt_lib_cpp_string::StringPrintf(
1724 "0x%016" PRIx64, state_.low_energy_state.supported_features());
1725 inspect_properties_.le_features =
1726 adapter_node_.CreateString("le_features", le_features);
1727 }
1728
CleanUp()1729 void AdapterImpl::CleanUp() {
1730 if (init_state_ == State::kNotInitialized) {
1731 bt_log(DEBUG, "gap", "clean up: not initialized");
1732 return;
1733 }
1734
1735 init_state_ = State::kNotInitialized;
1736 state_ = AdapterState();
1737 transport_error_cb_ = nullptr;
1738
1739 // Destroy objects in reverse order of construction.
1740 low_energy_ = nullptr;
1741 bredr_ = nullptr;
1742 sdp_server_ = nullptr;
1743 bredr_discovery_manager_ = nullptr;
1744 le_advertising_manager_ = nullptr;
1745 le_connection_manager_ = nullptr;
1746 le_discovery_manager_ = nullptr;
1747
1748 hci_le_connector_ = nullptr;
1749 hci_le_advertiser_ = nullptr;
1750 hci_le_scanner_ = nullptr;
1751
1752 le_address_manager_ = nullptr;
1753
1754 l2cap_ = nullptr;
1755
1756 hci_.reset();
1757 }
1758
OnTransportError()1759 void AdapterImpl::OnTransportError() {
1760 bt_log(INFO, "gap", "HCI transport error");
1761 if (CompleteInitialization(/*success=*/false)) {
1762 return;
1763 }
1764 if (transport_error_cb_) {
1765 transport_error_cb_();
1766 }
1767 }
1768
OnLeAutoConnectRequest(Peer * peer)1769 void AdapterImpl::OnLeAutoConnectRequest(Peer* peer) {
1770 PW_DCHECK(le_connection_manager_);
1771 PW_DCHECK(peer);
1772 PW_DCHECK(peer->le());
1773
1774 PeerId peer_id = peer->identifier();
1775
1776 if (!peer->le()->should_auto_connect()) {
1777 bt_log(DEBUG,
1778 "gap",
1779 "ignoring auto-connection (peer->should_auto_connect() is false) "
1780 "(peer: %s)",
1781 bt_str(peer_id));
1782 return;
1783 }
1784
1785 LowEnergyConnectionOptions options{.auto_connect = true};
1786
1787 auto self = weak_self_.GetWeakPtr();
1788 le_connection_manager_->Connect(
1789 peer_id,
1790 [self, peer_id](auto result) {
1791 if (!self.is_alive()) {
1792 bt_log(DEBUG, "gap", "ignoring auto-connection (adapter destroyed)");
1793 return;
1794 }
1795
1796 if (result.is_error()) {
1797 bt_log(INFO,
1798 "gap",
1799 "failed to auto-connect (peer: %s, error: %s)",
1800 bt_str(peer_id),
1801 HostErrorToString(result.error_value()).c_str());
1802 return;
1803 }
1804
1805 auto conn = std::move(result).value();
1806 PW_CHECK(conn);
1807 bt_log(INFO, "gap", "peer auto-connected (peer: %s)", bt_str(peer_id));
1808 if (self->auto_conn_cb_) {
1809 self->auto_conn_cb_(std::move(conn));
1810 }
1811 },
1812 options);
1813 }
1814
IsLeRandomAddressChangeAllowed()1815 bool AdapterImpl::IsLeRandomAddressChangeAllowed() {
1816 return hci_le_advertiser_->AllowsRandomAddressChange() &&
1817 hci_le_scanner_->AllowsRandomAddressChange() &&
1818 hci_le_connector_->AllowsRandomAddressChange();
1819 }
1820
Create(pw::async::Dispatcher & pw_dispatcher,hci::Transport::WeakPtr hci,gatt::GATT::WeakPtr gatt,Config config,std::unique_ptr<l2cap::ChannelManager> l2cap)1821 std::unique_ptr<Adapter> Adapter::Create(
1822 pw::async::Dispatcher& pw_dispatcher,
1823 hci::Transport::WeakPtr hci,
1824 gatt::GATT::WeakPtr gatt,
1825 Config config,
1826 std::unique_ptr<l2cap::ChannelManager> l2cap) {
1827 return std::make_unique<AdapterImpl>(
1828 pw_dispatcher, hci, gatt, config, std::move(l2cap));
1829 }
1830
1831 } // namespace bt::gap
1832