drogue_esp8266/
network.rs

1use crate::adapter::{Adapter, AdapterError};
2use embedded_hal::serial::Write;
3
4use core::cell::RefCell;
5use drogue_network::addr::{
6    HostAddr,
7    HostSocketAddr,
8    IpAddr
9};
10use drogue_network::tcp::{
11    Mode,
12    TcpStack,
13    TcpError,
14    TcpImplError,
15};
16use core::fmt::Debug;
17use nom::lib::std::fmt::Formatter;
18use heapless::{
19    String,
20    consts::{
21        U256,
22    },
23};
24use drogue_network::IpNetworkDriver;
25use drogue_network::dns::{Dns, DnsError, AddrType};
26/// Network driver based on the ESP8266 board
27pub struct Esp8266IpNetworkDriver<'a, Tx>
28    where
29        Tx: Write<u8>,
30{
31    adapter: RefCell<Adapter<'a, Tx>>,
32}
33
34
35impl<'a, Tx> Debug for Esp8266IpNetworkDriver<'a, Tx>
36    where
37        Tx: Write<u8>,
38{
39    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
40        f.debug_tuple( "Esp8266IpNetworkDriver").finish()
41    }
42}
43
44impl<'a, Tx> Esp8266IpNetworkDriver<'a, Tx>
45    where
46        Tx: Write<u8>,
47{
48    pub(crate) fn new(adapter: Adapter<'a, Tx>) -> Self {
49        Self {
50            adapter: RefCell::new(adapter),
51        }
52    }
53}
54
55impl<'a, Tx> IpNetworkDriver for Esp8266IpNetworkDriver<'a, Tx>
56    where
57        Tx: Write<u8>,
58{
59    type TcpSocket = TcpSocket;
60    type TcpError = TcpError;
61    type DnsError = DnsError;
62
63    fn tcp(&self) -> &dyn TcpStack<TcpSocket=Self::TcpSocket, Error=Self::TcpError> {
64        self as &dyn TcpStack<TcpSocket = Self::TcpSocket, Error = Self::TcpError>
65    }
66
67    fn dns(&self) -> &dyn Dns<Error=Self::DnsError> {
68        self as &dyn Dns<Error = Self::DnsError>
69    }
70}
71
72/// Handle to a socket.
73pub struct TcpSocket {
74    link_id: usize,
75    mode: Mode,
76}
77
78impl Debug for TcpSocket {
79    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
80        f.debug_struct("TcpSocket")
81            .field("link_id", &self.link_id)
82            .field("mode",
83                   &match self.mode {
84                       Mode::Blocking => {
85                           "blocking"
86                       }
87                       Mode::NonBlocking => {
88                           "non-blocking"
89                       }
90                       Mode::Timeout(_t) => {
91                           "timeout"
92                       }
93                   },
94            )
95            .finish()
96    }
97}
98
99/*
100impl Into<TcpError> for AdapterError {
101    fn into(self) -> TcpError {
102        match self {
103            AdapterError::Timeout => {
104                TcpError::Timeout
105            },
106            AdapterError::WriteError => {
107                TcpError::WriteError
108            },
109            AdapterError::InvalidSocket => {
110                TcpError::SocketNotOpen
111            },
112            _ => {
113                TcpError::Impl(TcpImplError::Unknown)
114            },
115        }
116    }
117}
118 */
119
120impl From<AdapterError> for TcpError {
121    fn from(error: AdapterError) -> Self {
122        match error {
123            AdapterError::Timeout => {
124                TcpError::Timeout
125            }
126            AdapterError::WriteError => {
127                TcpError::WriteError
128            }
129            AdapterError::ReadError => {
130                TcpError::ReadError
131            }
132            AdapterError::InvalidSocket => {
133                TcpError::SocketNotOpen
134            }
135            _ => {
136                TcpError::Impl(TcpImplError::Unknown)
137            }
138        }
139    }
140}
141
142impl<'a, Tx> TcpStack for Esp8266IpNetworkDriver<'a, Tx>
143    where
144        Tx: Write<u8>,
145{
146    type TcpSocket = TcpSocket;
147    type Error = TcpError;
148
149    fn open(&self, mode: Mode) -> Result<Self::TcpSocket, Self::Error> {
150        let mut adapter = self.adapter.borrow_mut();
151        Ok(TcpSocket {
152            link_id: adapter.open()?,
153            mode,
154        })
155    }
156
157    fn connect(
158        &self,
159        socket: Self::TcpSocket,
160        remote: HostSocketAddr,
161    ) -> Result<Self::TcpSocket, Self::Error> {
162        let mut adapter = self.adapter.borrow_mut();
163
164        adapter.connect_tcp(socket.link_id, remote)?;
165        Ok(socket)
166    }
167
168    fn is_connected(&self, socket: &Self::TcpSocket) -> Result<bool, Self::Error> {
169        let adapter = self.adapter.borrow();
170        adapter.is_connected(socket.link_id).map_err(TcpError::from)
171    }
172
173    fn write(&self, socket: &mut Self::TcpSocket, buffer: &[u8]) -> nb::Result<usize, Self::Error> {
174        let mut adapter = self.adapter.borrow_mut();
175
176        Ok(adapter
177            .write(socket.link_id, buffer)
178            .map_err(|e| { e.map(TcpError::from) })?)
179    }
180
181    fn read(
182        &self,
183        socket: &mut Self::TcpSocket,
184        buffer: &mut [u8],
185    ) -> nb::Result<usize, Self::Error> {
186        let mut adapter = self.adapter.borrow_mut();
187
188        match socket.mode {
189            Mode::Blocking => {
190                nb::block!(
191                adapter.read(socket.link_id, buffer))
192                    .map_err(|e|
193                        nb::Error::from(TcpError::from(e))
194                    )
195            }
196            Mode::NonBlocking => {
197                adapter.read(socket.link_id, buffer)
198                    .map_err(|e|
199                        e.map(TcpError::from)
200                    )
201            }
202            Mode::Timeout(_) => unimplemented!(),
203        }
204    }
205
206    fn close(&self, socket: Self::TcpSocket) -> Result<(), Self::Error> {
207        let mut adapter = self.adapter.borrow_mut();
208        adapter.close(socket.link_id).map_err(|e| e.into())
209    }
210}
211
212impl<'a, Tx> Dns for Esp8266IpNetworkDriver<'a, Tx>
213    where
214        Tx: Write<u8>,
215{
216    type Error = DnsError;
217
218    fn gethostbyname(&self, hostname: &str, addr_type: AddrType) -> Result<HostAddr, Self::Error> {
219        match addr_type {
220            AddrType::IPv6 => {
221                Err(DnsError::UnsupportedAddressType)
222            },
223            _ => {
224                let mut adapter = self.adapter.borrow_mut();
225                adapter.get_host_by_name(hostname)
226            }
227        }
228    }
229
230    fn gethostbyaddr(&self, _addr: IpAddr) -> Result<String<U256>, Self::Error> {
231        unimplemented!()
232    }
233}
234