1use core::future::Future;
4
5use embassy_sync::blocking_mutex::raw::RawMutex;
6use embassy_sync::mutex::Mutex;
7use embedded_io::{ErrorType, ReadExactError};
8
9use crate::controller::blocking::TryError;
10use crate::{ControllerToHostPacket, FromHciBytesError, HostToControllerPacket, ReadHci, ReadHciError, WriteHci};
11
12pub trait Transport: embedded_io::ErrorType {
14 fn read<'a>(&self, rx: &'a mut [u8]) -> impl Future<Output = Result<ControllerToHostPacket<'a>, Self::Error>>;
16 fn write<T: HostToControllerPacket>(&self, val: &T) -> impl Future<Output = Result<(), Self::Error>>;
18}
19
20pub struct SerialTransport<M: RawMutex, R, W> {
22 reader: Mutex<M, R>,
23 writer: Mutex<M, W>,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub enum Error<E: embedded_io::Error> {
30 Read(ReadHciError<E>),
32 Write(E),
34}
35
36impl<E: embedded_io::Error> embedded_io::Error for Error<E> {
37 fn kind(&self) -> embedded_io::ErrorKind {
38 match self {
39 Self::Read(e) => e.kind(),
40 Self::Write(e) => e.kind(),
41 }
42 }
43}
44
45impl<E: embedded_io::Error> From<E> for Error<E> {
46 fn from(e: E) -> Self {
47 Self::Write(e)
48 }
49}
50
51impl<E: embedded_io::Error> From<ReadHciError<E>> for Error<E> {
52 fn from(e: ReadHciError<E>) -> Self {
53 Self::Read(e)
54 }
55}
56
57impl<E: embedded_io::Error> From<ReadExactError<E>> for Error<E> {
58 fn from(e: ReadExactError<E>) -> Self {
59 Self::Read(e.into())
60 }
61}
62
63impl<E: embedded_io::Error> From<FromHciBytesError> for Error<E> {
64 fn from(e: FromHciBytesError) -> Self {
65 Self::Read(e.into())
66 }
67}
68
69impl<M: RawMutex, R: embedded_io_async::Read, W: embedded_io_async::Write> SerialTransport<M, R, W> {
70 pub fn new(reader: R, writer: W) -> Self {
72 Self {
73 reader: Mutex::new(reader),
74 writer: Mutex::new(writer),
75 }
76 }
77}
78
79impl<
80 M: RawMutex,
81 R: embedded_io::ErrorType<Error = E>,
82 W: embedded_io::ErrorType<Error = E>,
83 E: embedded_io::Error,
84 > ErrorType for SerialTransport<M, R, W>
85{
86 type Error = Error<E>;
87}
88
89impl<
90 M: RawMutex,
91 R: embedded_io_async::Read<Error = E>,
92 W: embedded_io_async::Write<Error = E>,
93 E: embedded_io::Error,
94 > Transport for SerialTransport<M, R, W>
95{
96 async fn read<'a>(&self, rx: &'a mut [u8]) -> Result<ControllerToHostPacket<'a>, Self::Error> {
97 let mut r = self.reader.lock().await;
98 ControllerToHostPacket::read_hci_async(&mut *r, rx)
99 .await
100 .map_err(Error::Read)
101 }
102
103 async fn write<T: HostToControllerPacket>(&self, tx: &T) -> Result<(), Self::Error> {
104 let mut w = self.writer.lock().await;
105 WithIndicator(tx)
106 .write_hci_async(&mut *w)
107 .await
108 .map_err(|e| Error::Write(e))
109 }
110}
111
112impl<M: RawMutex, R: embedded_io::Read<Error = E>, W: embedded_io::Write<Error = E>, E: embedded_io::Error>
113 blocking::Transport for SerialTransport<M, R, W>
114{
115 fn read<'a>(&self, rx: &'a mut [u8]) -> Result<ControllerToHostPacket<'a>, TryError<Self::Error>> {
116 let mut r = self.reader.try_lock().map_err(|_| TryError::Busy)?;
117 ControllerToHostPacket::read_hci(&mut *r, rx)
118 .map_err(Error::Read)
119 .map_err(TryError::Error)
120 }
121
122 fn write<T: HostToControllerPacket>(&self, tx: &T) -> Result<(), TryError<Self::Error>> {
123 let mut w = self.writer.try_lock().map_err(|_| TryError::Busy)?;
124 WithIndicator(tx)
125 .write_hci(&mut *w)
126 .map_err(|e| Error::Write(e))
127 .map_err(TryError::Error)
128 }
129}
130
131pub struct WithIndicator<'a, T: HostToControllerPacket>(&'a T);
136
137impl<'a, T: HostToControllerPacket> WithIndicator<'a, T> {
138 pub fn new(pkt: &'a T) -> Self {
140 Self(pkt)
141 }
142}
143
144impl<T: HostToControllerPacket> WriteHci for WithIndicator<'_, T> {
145 #[inline(always)]
146 fn size(&self) -> usize {
147 1 + self.0.size()
148 }
149
150 #[inline(always)]
151 fn write_hci<W: embedded_io::Write>(&self, mut writer: W) -> Result<(), W::Error> {
152 T::KIND.write_hci(&mut writer)?;
153 self.0.write_hci(writer)
154 }
155
156 #[inline(always)]
157 async fn write_hci_async<W: embedded_io_async::Write>(&self, mut writer: W) -> Result<(), W::Error> {
158 T::KIND.write_hci_async(&mut writer).await?;
159 self.0.write_hci_async(writer).await
160 }
161}
162
163pub mod blocking {
164 use super::*;
166 use crate::controller::blocking::TryError;
167
168 pub trait Transport: embedded_io::ErrorType {
170 fn read<'a>(&self, rx: &'a mut [u8]) -> Result<ControllerToHostPacket<'a>, TryError<Self::Error>>;
172 fn write<T: HostToControllerPacket>(&self, val: &T) -> Result<(), TryError<Self::Error>>;
174 }
175}