C/C++ API Reference
Loading...
Searching...
No Matches
central.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/central2.h"
19#include "pw_bluetooth_sapphire/internal/connection.h"
20#include "pw_bluetooth_sapphire/internal/host/gap/adapter.h"
21#include "pw_multibuf/allocator.h"
22
25
27
30 public:
31 // The maximum number of scan results to queue in each ScanHandle
32 static constexpr uint8_t kMaxScanResultsQueueSize = 10;
33
34 // TODO: https://pwbug.dev/377301546 - Don't expose Adapter in public API.
37 Central(bt::gap::Adapter::WeakPtr adapter,
38 pw::async::Dispatcher& dispatcher,
39 pw::multibuf::MultiBufAllocator& allocator);
40 ~Central() override;
41
43 pw::bluetooth::PeerId peer_id,
45 PW_LOCKS_EXCLUDED(lock());
46
48 const ScanOptions& options) override PW_LOCKS_EXCLUDED(lock());
49
50 static pw::sync::Mutex& lock();
51
52 private:
53 class ScanHandleImpl final : public ScanHandle {
54 public:
55 explicit ScanHandleImpl(uint16_t scan_id, Central* central)
56 : scan_id_(scan_id), central_(central) {}
57
58 // Synchronously clears ScanState's pointer to this object and
59 // asynchronously stops the scan procedure.
60 ~ScanHandleImpl() override;
61
62 void QueueScanResultLocked(ScanResult&& result)
64
65 void WakeLocked() PW_EXCLUSIVE_LOCKS_REQUIRED(lock()) { waker_.Wake(); }
66
67 void OnScanErrorLocked() PW_EXCLUSIVE_LOCKS_REQUIRED(lock()) {
68 central_ = nullptr;
69 WakeLocked();
70 }
71
72 private:
73 async2::PollResult<ScanResult> PendResult(async2::Context& cx) override;
74
75 // std::unique_ptr custom Deleter
76 void Release() override { delete this; }
77
78 const uint16_t scan_id_;
79
80 // Set to null when Central is destroyed or scanning has stopped.
81 Central* central_ PW_GUARDED_BY(lock());
82
83 // PendResult() waker. Set when Pending was returned.
84 async2::Waker waker_ PW_GUARDED_BY(lock());
85 std::queue<ScanResult> results_ PW_GUARDED_BY(lock());
86 };
87
88 // Created and destroyed on the Bluetooth thread.
89 class ScanState {
90 public:
91 // Must be run on Bluetooth thread. Not thread safe.
92 explicit ScanState(
93 std::unique_ptr<bt::gap::LowEnergyDiscoverySession> session,
94 ScanHandleImpl* scan_handle,
95 uint16_t scan_id,
96 Central* central);
97
98 ~ScanState();
99
100 void OnScanHandleDestroyedLocked() PW_EXCLUSIVE_LOCKS_REQUIRED(lock()) {
101 scan_handle_ = nullptr;
102 }
103
104 private:
105 // Must be run on Bluetooth thread. Not thread safe.
106 void OnScanResult(const bt::gap::Peer& peer) PW_LOCKS_EXCLUDED(lock());
107
108 // Must be run on Bluetooth thread. Not thread safe.
109 void OnError() PW_LOCKS_EXCLUDED(lock());
110
111 const uint16_t scan_id_;
112
113 // Set to null synchronously when ScanHandleImpl is destroyed.
114 ScanHandleImpl* scan_handle_ PW_GUARDED_BY(lock());
115
116 // Members must only be accessed on Bluetooth thread.
117 Central* const central_;
118 std::unique_ptr<bt::gap::LowEnergyDiscoverySession> session_;
119 };
120
121 // Asynchronously stops the scan corresponding to `scan_id` and synchronously
122 // clears `ScanState.scan_handle_`.
123 void StopScanLocked(uint16_t scan_id) PW_EXCLUSIVE_LOCKS_REQUIRED(lock());
124
125 void OnConnectionResult(
126 bt::PeerId peer_id,
127 bt::gap::Adapter::LowEnergy::ConnectionResult result,
128 async2::OptionalValueProvider<ConnectResult> result_provider)
129 PW_LOCKS_EXCLUDED(lock());
130
131 std::unordered_map<uint16_t, ScanState> scans_ PW_GUARDED_BY(lock());
132
133 // Must only be used on the Bluetooth thread.
134 bt::gap::Adapter::WeakPtr adapter_;
135
136 // Dispatcher for Bluetooth thread. Thread safe.
137 pw::async::Dispatcher& dispatcher_;
138 pw::async::HeapDispatcher heap_dispatcher_;
139
140 pw::multibuf::MultiBufAllocator& allocator_;
141
142 // Must only be used on the Bluetooth thread.
143 WeakSelf<Central> weak_factory_{this};
144
145 // Thread safe to copy and destroy, but WeakPtr should only be used
146 // or dereferenced on the Bluetooth thread (WeakRef is not thread safe).
147 WeakSelf<Central>::WeakPtr self_{weak_factory_.GetWeakPtr()};
148};
149
150} // namespace pw::bluetooth_sapphire
Definition: value_future.h:47
Definition: dispatcher.h:48
Represents an ongoing LE scan.
Definition: central2.h:148
Represents the LE central role. Used to scan and connect to peripherals.
Definition: central2.h:31
Must only be constructed and destroyed on the Bluetooth thread.
Definition: central.h:29
Definition: mutex.h:40
async2::OptionalValueFuture< ScanStartResult > Scan(const ScanOptions &options) override
Central(bt::gap::Adapter::WeakPtr adapter, pw::async::Dispatcher &dispatcher, pw::multibuf::MultiBufAllocator &allocator)
pw::expected< Connection2::Ptr, ConnectError > ConnectResult
The result type returned by Connect().
Definition: central2.h:200
#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
The Pigweed namespace.
Definition: alignment.h:27
Parameters used during a scan.
Definition: central2.h:89
Represents parameters that are set on a per-connection basis.
Definition: connection2.h:112