xref: /aosp_15_r20/external/pigweed/pw_bluetooth/public/pw_bluetooth/low_energy/channel.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 #pragma once
15 
16 #include "pw_async2/dispatcher.h"
17 #include "pw_async2/once_sender.h"
18 #include "pw_bluetooth/internal/raii_ptr.h"
19 #include "pw_channel/channel.h"
20 #include "pw_result/result.h"
21 
22 namespace pw::bluetooth::low_energy {
23 
24 /// An identifier for a service that accepts connection-oriented channel
25 /// connections. Referred to as a (simplified) protocol/service multiplexer
26 /// in the Bluetooth specification.
27 enum class Psm : uint16_t {};
28 
29 /// The authentication an encryption requirements for a channel.
30 struct SecurityRequirements {
31   /// If true, the link must be authenticated with on-path attacker protection.
32   /// If false, authentication is not required.
33   bool authentication_required;
34 
35   /// If true, the link must be encrypted with a Secure Connections key.
36   bool secure_connections_required;
37 };
38 
39 /// A duplex datagram channel that models the lifetime of a connection-oriented
40 /// channel. Closing or destroying `Channel` will close the underlying channel.
41 class Channel : public pw::channel::ReliableDatagramReaderWriter {
42  public:
43   virtual ~Channel() = default;
44 
45   /// Maximum payload size (SDU) that the peer supports receiving.
46   virtual uint16_t max_transmit_size() = 0;
47 
48   /// Maximum payload size (SDU) that this channel supports receiving.
49   virtual uint16_t max_receive_size() = 0;
50 
51  private:
52   virtual void Release() = 0;
53 
54  public:
55   using Ptr = internal::RaiiPtr<Channel, &Channel::Release>;
56 };
57 
58 /// Represents a service or protocol that accepts incoming channels for a PSM.
59 /// Destroying this object will cease accepting any incoming channels, but
60 /// existing established channels will not be affected. Additionally, once
61 /// this object is destroyed the implementation is free to reuse the PSM that
62 /// was previously assigned for this instance.
63 class ChannelListener {
64  public:
65   virtual ~ChannelListener() = default;
66 
67   /// Poll to receive incoming channels.
68   virtual async2::Poll<Channel::Ptr> PendChannel(async2::Waker&& waker) = 0;
69 
70   /// The protocol/service multiplexer for this listener.
71   virtual Psm psm() = 0;
72 
73  private:
74   /// Custom deleter called when `ChannelListener::Ptr` is destroyed. The
75   /// implementation should free or clean up the memory used by this
76   /// object. This enables the use of smart pointer semantics while leaving
77   /// memory management up to the implementation. Calling the virtual destructor
78   /// or not is up to the implementation.
79   virtual void Release() = 0;
80 
81  public:
82   using Ptr = internal::RaiiPtr<ChannelListener, &ChannelListener::Release>;
83 };
84 
85 class ChannelListenerRegistry {
86  public:
87   /// The parameters to use for incoming channels.
88   struct ListenParameters {
89     /// Maximum supported payload size (SDU) for receiving.
90     uint16_t max_receive_size;
91     /// The security requirements that must be met before data is exchanged on
92     /// the channel. If the requirements cannot be met, channel establishment
93     /// will fail.
94     SecurityRequirements security_requirements;
95   };
96 
97   virtual ~ChannelListenerRegistry() = default;
98 
99   /// Register a listener for incoming channels. The registry will assign a
100   /// protocol/service multiplexer value that is unique for the local device, as
101   /// well as create a `ChannelListener` for accepting incoming channels. In the
102   /// unlikely event that all PSMs have been assigned, this call will fail with
103   /// `RESOURCE_EXHAUSTED`.
104   ///
105   /// Note that the method of service discovery or advertising is defined by
106   /// the service or protocol, so it is the responsibility of the caller to
107   /// update the GATT database or other service discovery mechanism.
108   ///
109   /// @param parameters Parameters for the local side of the channel.
110   /// @return The result of starting the listener. On success, contains a
111   /// `ChannelListener` that can be used to receive new channels.
112   virtual async2::OnceReceiver<pw::Result<ChannelListener::Ptr>> ListenL2cap(
113       ListenParameters parameters) = 0;
114 };
115 
116 }  // namespace pw::bluetooth::low_energy
117