1use bt_hci::controller::{blocking, Controller};
3
4pub use crate::channel_manager::CreditFlowPolicy;
5#[cfg(feature = "channel-metrics")]
6pub use crate::channel_manager::Metrics as ChannelMetrics;
7use crate::channel_manager::{ChannelIndex, ChannelManager};
8use crate::connection::Connection;
9use crate::pdu::Sdu;
10use crate::{BleHostError, Error, PacketPool, Stack};
11
12pub(crate) mod sar;
13
14pub struct L2capChannel<'d, P: PacketPool> {
16 index: ChannelIndex,
17 manager: &'d ChannelManager<'d, P>,
18}
19
20pub struct L2capChannelWriter<'d, P: PacketPool> {
22 index: ChannelIndex,
23 manager: &'d ChannelManager<'d, P>,
24}
25
26pub struct L2capChannelReader<'d, P: PacketPool> {
28 index: ChannelIndex,
29 manager: &'d ChannelManager<'d, P>,
30}
31
32pub struct L2capChannelRef<'d, P: PacketPool> {
34 index: ChannelIndex,
35 manager: &'d ChannelManager<'d, P>,
36}
37
38#[cfg(feature = "defmt")]
39impl<P: PacketPool> defmt::Format for L2capChannel<'_, P> {
40 fn format(&self, f: defmt::Formatter<'_>) {
41 defmt::write!(f, "{}, ", self.index);
42 self.manager.print(self.index, f);
43 }
44}
45
46impl<P: PacketPool> Drop for L2capChannel<'_, P> {
47 fn drop(&mut self) {
48 self.manager.dec_ref(self.index);
49 }
50}
51
52impl<P: PacketPool> Drop for L2capChannelRef<'_, P> {
53 fn drop(&mut self) {
54 self.manager.dec_ref(self.index);
55 }
56}
57
58#[cfg(feature = "defmt")]
59impl<P: PacketPool> defmt::Format for L2capChannelWriter<'_, P> {
60 fn format(&self, f: defmt::Formatter<'_>) {
61 defmt::write!(f, "{}, ", self.index);
62 self.manager.print(self.index, f);
63 }
64}
65
66impl<P: PacketPool> Drop for L2capChannelWriter<'_, P> {
67 fn drop(&mut self) {
68 self.manager.dec_ref(self.index);
69 }
70}
71
72#[cfg(feature = "defmt")]
73impl<P: PacketPool> defmt::Format for L2capChannelReader<'_, P> {
74 fn format(&self, f: defmt::Formatter<'_>) {
75 defmt::write!(f, "{}, ", self.index);
76 self.manager.print(self.index, f);
77 }
78}
79
80impl<P: PacketPool> Drop for L2capChannelReader<'_, P> {
81 fn drop(&mut self) {
82 self.manager.dec_ref(self.index);
83 }
84}
85
86#[derive(Default)]
88pub struct L2capChannelConfig {
89 pub mtu: Option<u16>,
91 pub mps: Option<u16>,
93 pub flow_policy: CreditFlowPolicy,
95 pub initial_credits: Option<u16>,
97}
98
99impl<'d, P: PacketPool> L2capChannel<'d, P> {
100 pub(crate) fn new(index: ChannelIndex, manager: &'d ChannelManager<'d, P>) -> Self {
101 Self { index, manager }
102 }
103
104 pub fn disconnect(&mut self) {
106 self.manager.disconnect(self.index);
107 }
108
109 pub fn psm(&self) -> u16 {
111 self.manager.psm(self.index)
112 }
113
114 pub async fn send<T: Controller>(
121 &mut self,
122 stack: &Stack<'_, T, P>,
123 buf: &[u8],
124 ) -> Result<(), BleHostError<T::Error>> {
125 let mut p_buf = P::allocate().ok_or(Error::OutOfMemory)?;
126 stack
127 .host
128 .channels
129 .send(self.index, buf, p_buf.as_mut(), &stack.host)
130 .await
131 }
132
133 pub fn try_send<T: Controller + blocking::Controller>(
140 &mut self,
141 stack: &Stack<'_, T, P>,
142 buf: &[u8],
143 ) -> Result<(), BleHostError<T::Error>> {
144 let mut p_buf = P::allocate().ok_or(Error::OutOfMemory)?;
145 stack
146 .host
147 .channels
148 .try_send(self.index, buf, p_buf.as_mut(), &stack.host)
149 }
150
151 pub async fn receive<T: Controller>(
155 &mut self,
156 stack: &Stack<'_, T, P>,
157 buf: &mut [u8],
158 ) -> Result<usize, BleHostError<T::Error>> {
159 stack.host.channels.receive(self.index, buf, &stack.host).await
160 }
161
162 pub async fn receive_sdu<T: Controller>(
166 &mut self,
167 stack: &Stack<'_, T, P>,
168 ) -> Result<Sdu<P::Packet>, BleHostError<T::Error>> {
169 stack.host.channels.receive_sdu(self.index, &stack.host).await
170 }
171
172 #[cfg(feature = "channel-metrics")]
174 pub fn metrics<F: FnOnce(&ChannelMetrics) -> R, R>(&self, f: F) -> R {
175 self.manager.metrics(self.index, f)
176 }
177
178 pub async fn accept<T: Controller>(
180 stack: &'d Stack<'d, T, P>,
181 connection: &Connection<'_, P>,
182 psm: &[u16],
183 config: &L2capChannelConfig,
184 ) -> Result<Self, BleHostError<T::Error>> {
185 let handle = connection.handle();
186 stack.host.channels.accept(handle, psm, config, &stack.host).await
187 }
188
189 pub async fn create<T: Controller>(
191 stack: &'d Stack<'d, T, P>,
192 connection: &Connection<'_, P>,
193 psm: u16,
194 config: &L2capChannelConfig,
195 ) -> Result<Self, BleHostError<T::Error>> {
196 stack
197 .host
198 .channels
199 .create(connection.handle(), psm, config, &stack.host)
200 .await
201 }
202
203 pub fn split(self) -> (L2capChannelWriter<'d, P>, L2capChannelReader<'d, P>) {
206 self.manager.inc_ref(self.index);
207 self.manager.inc_ref(self.index);
208 (
209 L2capChannelWriter {
210 index: self.index,
211 manager: self.manager,
212 },
213 L2capChannelReader {
214 index: self.index,
215 manager: self.manager,
216 },
217 )
218 }
219
220 pub fn merge(writer: L2capChannelWriter<'d, P>, reader: L2capChannelReader<'d, P>) -> Self {
224 assert_eq!(writer.index, reader.index);
227
228 let manager = writer.manager;
229 let index = writer.index;
230 manager.inc_ref(index);
231
232 Self { index, manager }
233 }
234}
235
236impl<'d, P: PacketPool> L2capChannelReader<'d, P> {
237 pub fn disconnect(&mut self) {
239 self.manager.disconnect(self.index);
240 }
241
242 pub async fn receive<T: Controller>(
246 &mut self,
247 stack: &Stack<'_, T, P>,
248 buf: &mut [u8],
249 ) -> Result<usize, BleHostError<T::Error>> {
250 stack.host.channels.receive(self.index, buf, &stack.host).await
251 }
252
253 pub async fn receive_sdu<T: Controller>(
257 &mut self,
258 stack: &Stack<'_, T, P>,
259 ) -> Result<Sdu<P::Packet>, BleHostError<T::Error>> {
260 stack.host.channels.receive_sdu(self.index, &stack.host).await
261 }
262
263 #[cfg(feature = "channel-metrics")]
265 pub fn metrics<F: FnOnce(&ChannelMetrics) -> R, R>(&self, f: F) -> R {
266 self.manager.metrics(self.index, f)
267 }
268
269 pub fn channel_ref(&mut self) -> L2capChannelRef<'d, P> {
271 self.manager.inc_ref(self.index);
272 L2capChannelRef {
273 index: self.index,
274 manager: self.manager,
275 }
276 }
277}
278
279impl<'d, P: PacketPool> L2capChannelRef<'d, P> {
280 #[cfg(feature = "channel-metrics")]
281 pub fn metrics<F: FnOnce(&ChannelMetrics) -> R, R>(&self, f: F) -> R {
283 self.manager.metrics(self.index, f)
284 }
285}
286
287impl<'d, P: PacketPool> L2capChannelWriter<'d, P> {
288 pub fn disconnect(&mut self) {
290 self.manager.disconnect(self.index);
291 }
292
293 pub async fn send<T: Controller>(
300 &mut self,
301 stack: &Stack<'_, T, P>,
302 buf: &[u8],
303 ) -> Result<(), BleHostError<T::Error>> {
304 let mut p_buf = P::allocate().ok_or(Error::OutOfMemory)?;
305 stack
306 .host
307 .channels
308 .send(self.index, buf, p_buf.as_mut(), &stack.host)
309 .await
310 }
311
312 pub fn try_send<T: Controller + blocking::Controller>(
319 &mut self,
320 stack: &Stack<'_, T, P>,
321 buf: &[u8],
322 ) -> Result<(), BleHostError<T::Error>> {
323 let mut p_buf = P::allocate().ok_or(Error::OutOfMemory)?;
324 stack
325 .host
326 .channels
327 .try_send(self.index, buf, p_buf.as_mut(), &stack.host)
328 }
329
330 #[cfg(feature = "channel-metrics")]
332 pub fn metrics<F: FnOnce(&ChannelMetrics) -> R, R>(&self, f: F) -> R {
333 self.manager.metrics(self.index, f)
334 }
335
336 pub fn channel_ref(&mut self) -> L2capChannelRef<'d, P> {
338 self.manager.inc_ref(self.index);
339 L2capChannelRef {
340 index: self.index,
341 manager: self.manager,
342 }
343 }
344}