• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2025 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/connection.h"
16 
17 namespace pw::bluetooth_sapphire::internal {
18 
19 namespace {
20 // This lock has to be global rather than a member variable so that dispatcher
21 // tasks can lock the mutex before dereferencing their weak pointers.
22 pw::sync::Mutex g_connection_lock;
23 }  // namespace
24 
lock()25 pw::sync::Mutex& Connection::lock() { return g_connection_lock; }
26 
Connection(bt::PeerId peer_id,std::unique_ptr<bt::gap::LowEnergyConnectionHandle> handle,pw::async::Dispatcher & dispatcher)27 Connection::Connection(
28     bt::PeerId peer_id,
29     std::unique_ptr<bt::gap::LowEnergyConnectionHandle> handle,
30     pw::async::Dispatcher& dispatcher)
31     : peer_id_(peer_id), dispatcher_(dispatcher), handle_(std::move(handle)) {
32   // This is safe because the constructor is only called on the Bluetooth
33   // thread.
34   handle_->set_closed_callback([self = self_]() PW_NO_LOCK_SAFETY_ANALYSIS {
35     std::lock_guard guard(g_connection_lock);
36     if (!self.is_alive()) {
37       return;
38     }
39     // TODO: https://pwbug.dev/396449684 - Update set_closed_callback with
40     // disconnect reason.
41     self->disconnect_reason_ = DisconnectReason::kFailure;
42     std::move(self->waker_).Wake();
43   });
44 }
45 
~Connection()46 Connection::~Connection() {
47   std::lock_guard guard(lock());
48   // This will destroy handle_ on the Bluetooth thread.
49   Status post_status =
50       dispatcher_.Post([handle = std::move(handle_)](auto, auto) {});
51   PW_CHECK_OK(post_status);
52 
53   weak_factory_.InvalidatePtrs();
54 }
55 
56 async2::Poll<pw::bluetooth::low_energy::Connection2::DisconnectReason>
PendDisconnect(async2::Context & cx)57 Connection::PendDisconnect(async2::Context& cx) {
58   std::lock_guard guard(lock());
59   if (disconnect_reason_) {
60     return async2::Ready(*disconnect_reason_);
61   }
62   PW_ASYNC_STORE_WAKER(cx, waker_, "bt-disconnect");
63   return async2::Pending();
64 }
65 
GattClient()66 pw::bluetooth::gatt::Client2* Connection::GattClient() {
67   // TODO: https://pwbug.dev/396449684 - Return Client2
68   return nullptr;
69 }
70 
AttMtu()71 uint16_t Connection::AttMtu() {
72   // TODO: https://pwbug.dev/396449684 - Return actual MTU
73   return 0u;
74 }
75 
PendAttMtuChange(async2::Context &)76 async2::Poll<uint16_t> Connection::PendAttMtuChange(async2::Context&) {
77   // TODO: https://pwbug.dev/396449684 - Wire up MTU change logic.
78   return async2::Pending();
79 }
80 
81 pw::bluetooth::low_energy::Connection2::ConnectionParameters
Parameters()82 Connection::Parameters() {
83   // TODO: https://pwbug.dev/396449684 - Get the actual connection parameters.
84   return pw::bluetooth::low_energy::Connection2::ConnectionParameters();
85 }
86 
87 async2::OnceReceiver<pw::expected<
88     void,
89     pw::bluetooth::low_energy::Connection2::ConnectionParameterUpdateError>>
RequestParameterUpdate(RequestedConnectionParameters)90 Connection::RequestParameterUpdate(RequestedConnectionParameters) {
91   // TODO: https://pwbug.dev/396449684 - Update the parameters.
92   return async2::OnceReceiver<
93       pw::expected<void,
94                    pw::bluetooth::low_energy::Connection2::
95                        ConnectionParameterUpdateError>>();
96 }
97 
98 async2::OnceReceiver<pw::Result<pw::bluetooth::low_energy::Channel::Ptr>>
ConnectL2cap(ConnectL2capParameters)99 Connection::ConnectL2cap(ConnectL2capParameters) {
100   // TODO: https://pwbug.dev/396449684 - Open an L2CAP channel.
101   return async2::OnceReceiver<
102       pw::Result<pw::bluetooth::low_energy::Channel::Ptr>>(
103       pw::Status::Unimplemented());
104 }
105 
106 }  // namespace pw::bluetooth_sapphire::internal
107