C/C++ API Reference
Loading...
Searching...
No Matches
peripheral.h
1// Copyright 2024 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#pragma once
16
17#include "pw_bluetooth/low_energy/peripheral2.h"
18#include "pw_bluetooth_sapphire/internal/host/gap/adapter.h"
19
20namespace pw::bluetooth_sapphire {
21
23
26 public:
27 // TODO: https://pwbug.dev/377301546 - Don't expose Adapter in public API.
29 Peripheral(bt::gap::Adapter::WeakPtr adapter,
30 pw::async::Dispatcher& dispatcher);
31
33 ~Peripheral() override;
34
38 const AdvertisingParameters& parameters) override
39 PW_LOCKS_EXCLUDED(lock());
40
41 static pw::sync::Mutex& lock();
42
43 private:
44 class Advertisement;
45
46 // Thin client handle for an active advertisement.
47 // Thread safe.
48 class AdvertisedPeripheralImpl final
50 public:
51 AdvertisedPeripheralImpl(bt::gap::AdvertisementId id,
52 Peripheral* peripheral)
53 : id_(id), peripheral_(peripheral) {}
54 ~AdvertisedPeripheralImpl() override {
55 std::lock_guard lock(Peripheral::lock());
56 if (peripheral_) {
57 peripheral_->OnAdvertisedPeripheralDestroyedLocked(id_);
58 }
59 }
60
61 // AdvertisedPeripheral2 overrides:
62 async2::Poll<pw::bluetooth::low_energy::Connection2::Ptr> PendConnection(
63 [[maybe_unused]] async2::Context& cx) override {
64 // TODO: https://pwbug.dev/377301546 - Implement connection handling.
65 return async2::Pending();
66 }
67 void StopAdvertising() override;
68 async2::Poll<pw::Status> PendStop(async2::Context& cx) override;
69 void Release() override { delete this; }
70
71 private:
72 friend class Advertisement;
73
74 const bt::gap::AdvertisementId id_;
75
76 // Set to null if the advertisement is stopped or Peripheral is destroyed.
77 Peripheral* peripheral_ PW_GUARDED_BY(lock());
78
79 std::optional<pw::Status> stop_status_ PW_GUARDED_BY(lock());
80
81 // Waker shared by PendConnection() and PendStop().
82 async2::Waker waker_ PW_GUARDED_BY(lock());
83 };
84
85 // Active advertisement state. Must only be destroyed on the Bluetooth thread.
86 class Advertisement final {
87 public:
88 Advertisement(bt::gap::AdvertisementInstance&& instance,
89 AdvertisedPeripheralImpl* advertised_peripheral)
90 : advertised_peripheral_(advertised_peripheral),
91 instance_(std::move(instance)) {}
92
93 // Must only be destroyed on Bluetooth thread.
94 ~Advertisement();
95
96 void OnAdvertisedPeripheralDestroyedLocked()
98 advertised_peripheral_ = nullptr;
99 }
100
101 void OnStopLocked(pw::Status status) PW_EXCLUSIVE_LOCKS_REQUIRED(lock());
102
103 private:
104 friend class AdvertisedPeripheralImpl;
105
106 AdvertisedPeripheralImpl* advertised_peripheral_;
107
108 // Must only be modified/destroyed on the Bluetooth thread.
109 bt::gap::AdvertisementInstance instance_;
110 };
111
112 // Thread safe.
113 void OnAdvertisedPeripheralDestroyedLocked(
114 bt::gap::AdvertisementId advertisement_id)
116
117 // Thread safe. The lock may be held when calling this function as the stop
118 // message is immediately posted to the Bluetooth thread.
119 void StopAdvertising(bt::gap::AdvertisementId advertisement_id);
120
121 // Always called on Bluetooth thread.
122 void OnAdvertiseResult(bt::gap::AdvertisementInstance instance,
123 bt::hci::Result<> result,
124 async2::OnceSender<AdvertiseResult> result_sender);
125
126 // Always called on Bluetooth thread.
127 void OnConnection(bt::gap::AdvertisementId advertisement_id,
128 bt::gap::Adapter::LowEnergy::ConnectionResult result);
129
130 // Dispatcher for Bluetooth thread. Thread safe.
131 pw::async::HeapDispatcher dispatcher_;
132
133 // Must only be used on the Bluetooth thread.
134 bt::gap::Adapter::WeakPtr adapter_;
135
136 std::unordered_map<bt::gap::AdvertisementId, Advertisement> advertisements_
137 PW_GUARDED_BY(lock());
138
139 // Must only be used on the Bluetooth thread.
140 WeakSelf<Peripheral> weak_factory_{this};
141
142 // Thread safe to copy and destroy, but WeakPtr should only be used
143 // or dereferenced on the Bluetooth thread (WeakRef is not thread safe).
144 WeakSelf<Peripheral>::WeakPtr self_{weak_factory_.GetWeakPtr()};
145};
146
147} // namespace pw::bluetooth_sapphire
Definition: status.h:86
Definition: once_sender.h:43
Definition: dispatcher.h:48
Definition: heap_dispatcher.h:25
AdvertisedPeripheral instances are valid for the duration of advertising.
Definition: peripheral2.h:34
Represents the LE Peripheral role, which advertises and is connected to.
Definition: peripheral2.h:93
Must only be constructed and destroyed on the Bluetooth thread.
Definition: peripheral.h:25
Definition: mutex.h:40
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:271
async2::OnceReceiver< AdvertiseResult > Advertise(const AdvertisingParameters &parameters) override
~Peripheral() override
Must only be destroyed on the Bluetooth thread.
Peripheral(bt::gap::Adapter::WeakPtr adapter, pw::async::Dispatcher &dispatcher)
Must only be constructed on the Bluetooth thread.
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146
#define PW_LOCKS_EXCLUDED(...)
Definition: lock_annotations.h:176
Dual-mode Bluetooth host stack.
Definition: central.h:23
Represents the parameters for configuring advertisements.
Definition: peripheral2.h:163