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