esp8266_wifi_serial/
network_session.rs1use core::format_args;
2
3use embedded_hal::serial;
4use heapless::Vec;
5use simple_clock::SimpleClock;
6
7use crate::{
8 module::{CarretCondition, Module, OkCondition},
9 net::{IpAddr, SocketAddr},
10 parser::CommandResponse,
11 reader_part::{ReadData, ReaderPart},
12 Error,
13};
14
15#[derive(Debug, PartialEq, Eq)]
17pub struct SessionInfo {
18 pub softap_address: Option<IpAddr>,
19 pub listen_address: Option<IpAddr>,
20}
21
22#[derive(Debug)]
24pub struct NetworkSession<Rx, Tx, C, const N: usize>
25where
26 Rx: serial::Read<u8> + 'static,
27 Tx: serial::Write<u8> + 'static,
28 C: SimpleClock,
29{
30 module: Module<Rx, Tx, C, N>,
31}
32
33impl<Rx, Tx, C, const N: usize> NetworkSession<Rx, Tx, C, N>
34where
35 Rx: serial::Read<u8> + 'static,
36 Tx: serial::Write<u8> + 'static,
37 C: SimpleClock,
38{
39 pub(crate) fn new(module: Module<Rx, Tx, C, N>) -> Self {
40 Self { module }
41 }
42
43 pub fn listen(&mut self, port: u16) -> crate::Result<()> {
45 self.module
47 .send_at_command(format_args!("AT+CIPSERVER=1,{}", port))?
48 .expect("Malformed command");
49
50 Ok(())
51 }
52
53 pub fn connect(&mut self, link_id: usize, address: SocketAddr) -> crate::Result<()> {
57 self.module
58 .send_at_command(format_args!(
59 "AT+CIPSTART={},\"{}\",\"{}\",{}",
60 link_id,
61 "TCP",
62 address.ip(),
63 address.port(),
64 ))?
65 .expect("Malformed command");
66
67 Ok(())
68 }
69
70 pub fn poll_network_event(&mut self) -> nb::Result<NetworkEvent<'_, N>, Error> {
72 let reader = self.reader_mut();
73
74 let response =
75 CommandResponse::parse(reader.buf()).map(|(remainder, event)| (remainder.len(), event));
76
77 if let Some((remaining_bytes, response)) = response {
78 let pos = reader.buf().len() - remaining_bytes;
79 truncate_buf(reader.buf_mut(), pos);
80
81 let event = match response {
82 CommandResponse::Connected { link_id } => NetworkEvent::Connected { link_id },
83 CommandResponse::Closed { link_id } => NetworkEvent::Closed { link_id },
84 CommandResponse::DataAvailable { link_id, size } => {
85 let current_pos = reader.buf().len();
86 for _ in current_pos..size as usize {
87 let byte = nb::block!(reader.read_byte())?;
88 reader.buf_mut().push(byte).map_err(|_| Error::BufferFull)?;
89 }
90
91 NetworkEvent::DataAvailable {
92 link_id,
93 data: ReadData::new(reader.buf_mut()),
94 }
95 }
96 CommandResponse::WifiDisconnect => return Err(nb::Error::WouldBlock),
97 };
98
99 return Ok(event);
100 }
101
102 reader.read_bytes()?;
103 Err(nb::Error::WouldBlock)
104 }
105
106 pub fn send<I>(&mut self, link_id: usize, bytes: I) -> crate::Result<()>
112 where
113 I: Iterator<Item = u8> + ExactSizeIterator,
114 {
115 let bytes_len = bytes.len();
116 assert!(
118 bytes_len < 2048,
119 "Total packet size should not be greater than the 2048 bytes"
120 );
121 assert!(self.reader().buf().is_empty());
122
123 self.module
124 .write_command_fmt(format_args!("AT+CIPSEND={},{}", link_id, bytes_len))?;
125 self.module.read_until(CarretCondition)?;
126
127 for byte in bytes {
128 nb::block!(self.module.writer.write_byte(byte))?;
129 }
130
131 self.module
132 .read_until(OkCondition)?
133 .expect("Malformed command");
134 Ok(())
135 }
136
137 pub fn get_info(&mut self) -> crate::Result<SessionInfo> {
139 let info = self.module.get_network_info()?;
140 Ok(SessionInfo {
141 softap_address: info.ap_ip,
142 listen_address: info.sta_ip,
143 })
144 }
145
146 pub fn clock(&self) -> &C {
148 &self.module.clock
149 }
150
151 pub fn timeout(&self) -> Option<u64> {
153 self.module.timeout
154 }
155
156 fn reader(&self) -> &ReaderPart<Rx, N> {
157 &self.module.reader
158 }
159
160 fn reader_mut(&mut self) -> &mut ReaderPart<Rx, N> {
161 &mut self.module.reader
162 }
163}
164
165#[derive(Debug)]
167pub enum NetworkEvent<'a, const N: usize> {
168 Connected {
170 link_id: u16,
172 },
173 Closed {
175 link_id: u16,
177 },
178 DataAvailable {
180 link_id: u16,
182 data: ReadData<'a, N>,
184 },
185}
186
187fn truncate_buf<const N: usize>(buf: &mut Vec<u8, N>, at: usize) {
189 let buf_len = buf.len();
190
191 assert!(at <= buf_len);
192
193 for from in at..buf_len {
194 let to = from - at;
195 buf[to] = buf[from];
196 }
197
198 unsafe {
201 buf.set_len(buf_len - at);
202 }
203}