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/hci/fake_local_address_delegate.h"
16
17 #include <lib/fit/result.h>
18 #include <pw_assert/check.h>
19
20 #include "pw_bluetooth_sapphire/internal/host/common/host_error.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/log.h"
22
23 namespace bt::hci {
24
EnablePrivacy(bool enabled)25 void FakeLocalAddressDelegate::EnablePrivacy(bool enabled) {
26 privacy_enabled_ = enabled;
27
28 if (!enabled && random_.has_value()) {
29 random_.reset();
30
31 // Notify the callback about the change in address.
32 if (address_changed_callback_) {
33 address_changed_callback_();
34 }
35 }
36 }
37
EnsureLocalAddress(std::optional<DeviceAddress::Type> address_type,AddressCallback callback)38 void FakeLocalAddressDelegate::EnsureLocalAddress(
39 std::optional<DeviceAddress::Type> address_type, AddressCallback callback) {
40 PW_DCHECK(callback);
41
42 if (!privacy_enabled_ && address_type.has_value() &&
43 address_type.value() == DeviceAddress::Type::kLERandom) {
44 bt_log(WARN,
45 "hci-le",
46 "Cannot advertise a random address while privacy is disabled");
47 callback(fit::error(HostError::kInvalidParameters));
48 return;
49 }
50
51 DeviceAddress address = local_address_;
52 if (address_type == DeviceAddress::Type::kLEPublic || !privacy_enabled_) {
53 address = identity_address_;
54 }
55
56 if (privacy_enabled_) {
57 random_ = local_address_;
58 }
59
60 if (!async_) {
61 callback(fit::ok(address));
62 return;
63 }
64
65 (void)heap_dispatcher_.Post(
66 [cb = std::move(callback), addr = std::move(address)](
67 pw::async::Context /*ctx*/, pw::Status status) {
68 if (status.ok()) {
69 cb(fit::ok(addr));
70 }
71 });
72 }
73
UpdateRandomAddress(DeviceAddress & address)74 void FakeLocalAddressDelegate::UpdateRandomAddress(DeviceAddress& address) {
75 random_ = address;
76
77 // Notify the callback about the change in address.
78 if (address_changed_callback_) {
79 address_changed_callback_();
80 }
81 }
82 } // namespace bt::hci
83