1use embedded_hal::{digital::v2::OutputPin, serial::Read, serial::Write};
2
3use crate::protocol::{Command, ConnectionType, FirmwareInfo, IpAddresses, Response, WifiConnectionFailure, WiFiMode, ResolverAddresses};
4
5use heapless::{consts::{U16, U2}, spsc::{Consumer, Queue}, String};
6
7use log::info;
8
9use crate::adapter::AdapterError::UnableToInitialize;
10use crate::ingress::Ingress;
11use crate::network::Esp8266IpNetworkDriver;
12use core::fmt::Debug;
13use nom::lib::std::fmt::Formatter;
14use crate::protocol::Response::IpAddress;
15use drogue_network::dns::DnsError;
16use drogue_network::addr::{Ipv4Addr, HostAddr, HostSocketAddr};
17
18#[derive(Debug)]
19pub enum AdapterError {
20 UnableToInitialize,
21 NoAvailableSockets,
22 Timeout,
23 UnableToOpen,
24 UnableToClose,
25 WriteError,
26 ReadError,
27 InvalidSocket,
28}
29
30#[derive(Debug)]
31enum SocketState {
32 HalfClosed,
33 Closed,
34 Open,
35 Connected,
36}
37
38type Initialized<'a, Tx, Rx> = (Adapter<'a, Tx>, Ingress<'a, Rx>);
39
40pub fn initialize<'a, Tx, Rx, EnablePin, ResetPin>(
49 mut tx: Tx,
50 mut rx: Rx,
51 enable_pin: &mut EnablePin,
52 reset_pin: &mut ResetPin,
53 response_queue: &'a mut Queue<Response, U2>,
54 notification_queue: &'a mut Queue<Response, U16>,
55) -> Result<Initialized<'a, Tx, Rx>, AdapterError>
56 where
57 Tx: Write<u8>,
58 Rx: Read<u8>,
59 EnablePin: OutputPin,
60 ResetPin: OutputPin,
61{
62 let mut buffer: [u8; 1024] = [0; 1024];
63 let mut pos = 0;
64
65 const READY: [u8; 7] = *b"ready\r\n";
66
67 let mut counter = 0;
68
69 enable_pin
70 .set_high()
71 .map_err(|_| AdapterError::UnableToInitialize)?;
72 reset_pin
73 .set_high()
74 .map_err(|_| AdapterError::UnableToInitialize)?;
75
76 log::debug!("waiting for adapter to become ready");
77
78 loop {
79 let result = rx.read();
80 match result {
81 Ok(c) => {
82 buffer[pos] = c;
83 pos += 1;
84 if pos >= READY.len() && buffer[pos - READY.len()..pos] == READY {
85 log::debug!("adapter is ready");
86 disable_echo(&mut tx, &mut rx)?;
87 enable_mux(&mut tx, &mut rx)?;
88 set_recv_mode(&mut tx, &mut rx)?;
89 return Ok(build_adapter_and_ingress(
90 tx,
91 rx,
92 response_queue,
93 notification_queue,
94 ));
95 }
96 }
97 Err(nb::Error::WouldBlock) => {
98 continue;
99 }
100 Err(_) if counter > 10_000 => {
101 break;
102 }
103 Err(_) => {
104 counter += 1;
105 }
106 }
107 }
108
109 Err(AdapterError::UnableToInitialize)
110}
111
112fn build_adapter_and_ingress<'a, Tx, Rx>(
113 tx: Tx,
114 rx: Rx,
115 response_queue: &'a mut Queue<Response, U2>,
116 notification_queue: &'a mut Queue<Response, U16>,
117) -> Initialized<'a, Tx, Rx>
118 where
119 Tx: Write<u8>,
120 Rx: Read<u8>,
121{
122 let (response_producer, response_consumer) = response_queue.split();
123 let (notification_producer, notification_consumer) = notification_queue.split();
124 (
125 Adapter {
126 tx,
127 response_consumer,
128 notification_consumer,
129 sockets: initialize_sockets(),
130 },
131 Ingress::new(rx, response_producer, notification_producer),
132 )
133}
134
135fn initialize_sockets() -> [Socket; 5] {
136 [
137 Socket::new(),
138 Socket::new(),
139 Socket::new(),
140 Socket::new(),
141 Socket::new(),
142 ]
143}
144
145fn write_command<Tx>(tx: &mut Tx, cmd: &[u8]) -> Result<(), Tx::Error>
146 where
147 Tx: Write<u8>,
148{
149 for b in cmd.iter() {
150 nb::block!(tx.write(*b))?;
151 }
152 Ok(())
153}
154
155fn disable_echo<Tx, Rx>(tx: &mut Tx, rx: &mut Rx) -> Result<(), AdapterError>
156 where
157 Tx: Write<u8>,
158 Rx: Read<u8>,
159{
160 write_command(tx, b"ATE0\r\n").map_err(|_| UnableToInitialize)?;
161 Ok(wait_for_ok(rx).map_err(|_| UnableToInitialize)?)
162}
163
164fn enable_mux<Tx, Rx>(tx: &mut Tx, rx: &mut Rx) -> Result<(), AdapterError>
165 where
166 Tx: Write<u8>,
167 Rx: Read<u8>,
168{
169 write_command(tx, b"AT+CIPMUX=1\r\n").map_err(|_| UnableToInitialize)?;
170 Ok(wait_for_ok(rx).map_err(|_| UnableToInitialize)?)
171}
172
173fn set_recv_mode<Tx, Rx>(tx: &mut Tx, rx: &mut Rx) -> Result<(), AdapterError>
174 where
175 Tx: Write<u8>,
176 Rx: Read<u8>,
177{
178 write_command(tx, b"AT+CIPRECVMODE=1\r\n").map_err(|_| UnableToInitialize)?;
179 Ok(wait_for_ok(rx).map_err(|_| UnableToInitialize)?)
180}
181
182fn wait_for_ok<Rx>(rx: &mut Rx) -> Result<(), Rx::Error>
183 where
184 Rx: Read<u8>,
185{
186 let mut buf: [u8; 64] = [0; 64];
187 let mut pos = 0;
188
189 loop {
190 let b = nb::block!(rx.read())?;
191 buf[pos] = b;
192 pos += 1;
193 if buf[0..pos].ends_with(b"OK\r\n") {
194 return Ok(());
195 }
196 }
197}
198
199struct Socket {
200 state: SocketState,
201 available: usize,
202}
203
204impl Socket {
205 fn new() -> Self {
206 Self {
207 state: SocketState::Closed,
208 available: 0,
209 }
210 }
211
212 #[allow(dead_code)]
213 pub fn is_closed(&self) -> bool {
214 matches!(self.state, SocketState::Closed)
215 }
216
217 #[allow(dead_code)]
218 pub fn is_half_closed(&self) -> bool {
219 matches!(self.state, SocketState::HalfClosed)
220 }
221
222 #[allow(dead_code)]
223 pub fn is_open(&self) -> bool {
224 matches!(self.state, SocketState::Open)
225 }
226
227 #[allow(dead_code)]
228 pub fn is_connected(&self) -> bool {
229 matches!(self.state, SocketState::Connected)
230 }
231}
232
233pub struct Adapter<'a, Tx>
234 where
235 Tx: Write<u8>,
236{
237 tx: Tx,
238 response_consumer: Consumer<'a, Response, U2>,
239 notification_consumer: Consumer<'a, Response, U16>,
240 sockets: [Socket; 5],
241}
242
243impl<'a, Tx> Debug for Adapter<'a, Tx>
244 where
245 Tx: Write<u8>,
246{
247 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
248 f.debug_struct("Adapter")
249 .finish()
250 }
251}
252
253impl<'a, Tx> Adapter<'a, Tx>
254 where
255 Tx: Write<u8>,
256{
257 fn send<'c>(&mut self, command: Command<'c>) -> Result<Response, AdapterError> {
258 let bytes = command.as_bytes();
259
260 info!(
261 "writing command {}",
262 core::str::from_utf8(bytes.as_bytes()).unwrap()
263 );
264 for b in bytes.as_bytes().iter() {
265 nb::block!(self.tx.write(*b)).map_err(|_| AdapterError::WriteError)?;
266 }
267 nb::block!(self.tx.write(b'\r')).map_err(|_| AdapterError::WriteError)?;
268 nb::block!(self.tx.write(b'\n')).map_err(|_| AdapterError::WriteError)?;
269 self.wait_for_response()
270 }
271
272 fn wait_for_response(&mut self) -> Result<Response, AdapterError> {
273 loop {
274 if let Some(response) = self.response_consumer.dequeue() {
276 return Ok(response);
277 }
278 }
279 }
280
281 pub fn get_firmware_info(&mut self) -> Result<FirmwareInfo, ()> {
283 let command = Command::QueryFirmwareInfo;
284
285 if let Ok(Response::FirmwareInfo(info)) = self.send(command) {
286 return Ok(info);
287 }
288
289 Err(())
290 }
291
292 pub fn get_ip_address(&mut self) -> Result<IpAddresses, ()> {
294 let command = Command::QueryIpAddress;
295
296 if let Ok(Response::IpAddresses(addresses)) = self.send(command) {
297 return Ok(addresses);
298 }
299
300 Err(())
301 }
302
303 pub fn set_mode(&mut self, mode: WiFiMode) -> Result<(), ()> {
307 let command = Command::SetMode(mode);
308
309 match self.send(command) {
310 Ok(Response::Ok) => Ok(()),
311 _ => Err(()),
312 }
313 }
314
315 pub fn join<'c>(
322 &mut self,
323 ssid: &'c str,
324 password: &'c str,
325 ) -> Result<(), WifiConnectionFailure> {
326 let command = Command::JoinAp { ssid, password };
327
328 match self.send(command) {
329 Ok(Response::Ok) => {
330 Ok(())
331 }
332 Ok(Response::WifiConnectionFailure(reason)) => {
333 Err(reason)
334 }
335 _ => {
336 Err(WifiConnectionFailure::ConnectionFailed)
337 }
338 }
339 }
340
341 pub fn query_dns_resolvers(&mut self) -> Result<ResolverAddresses, ()> {
342 let command = Command::QueryDnsResolvers;
343 if let Ok(Response::Resolvers(resolvers)) = self.send(command) {
344 Ok(resolvers)
345 } else {
346 Err(())
347 }
348 }
349
350 pub fn set_dns_resolvers(&mut self, resolver1: Ipv4Addr, resolver2: Option<Ipv4Addr>) -> Result<(), ()> {
351 let command = Command::SetDnsResolvers(
352 ResolverAddresses {
353 resolver1,
354 resolver2
355 }
356 );
357
358 if let Ok(Response::Ok) = self.send(command) {
359 Ok(())
360 } else {
361 Err(())
362 }
363 }
364
365 pub fn into_network_stack(self) -> Esp8266IpNetworkDriver<'a, Tx> {
367 Esp8266IpNetworkDriver::new(self)
368 }
369
370 fn process_notifications(&mut self) {
375 while let Some(response) = self.notification_consumer.dequeue() {
376 match response {
377 Response::DataAvailable { link_id, len } => {
378 self.sockets[link_id].available += len;
379 }
380 Response::Connect(_) => {}
381 Response::Closed(link_id) => {
382 match self.sockets[link_id].state {
383 SocketState::HalfClosed => {
384 self.sockets[link_id].state = SocketState::Closed;
385 }
386 SocketState::Open | SocketState::Connected => {
387 self.sockets[link_id].state = SocketState::HalfClosed;
388 }
389 SocketState::Closed => {
390 }
392 }
393 }
394 _ => { }
395 }
396 }
397 }
398
399 pub(crate) fn open(&mut self) -> Result<usize, AdapterError> {
400 if let Some((index, socket)) = self
401 .sockets
402 .iter_mut()
403 .enumerate()
404 .find(|(_, e)| e.is_closed())
405 {
406 socket.state = SocketState::Open;
407 return Ok(index);
408 }
409
410 Err(AdapterError::NoAvailableSockets)
411 }
412
413 pub(crate) fn close(&mut self, link_id: usize) -> Result<(), AdapterError> {
414 let command = Command::CloseConnection(link_id);
415 match self.send(command) {
416 Ok(Response::Ok) | Ok(Response::UnlinkFail) => {
417 self.sockets[link_id].state = SocketState::Closed;
418 Ok(())
419 },
420 _=> Err(AdapterError::UnableToClose),
421 }
422 }
423
424 pub(crate) fn connect_tcp(
425 &mut self,
426 link_id: usize,
427 remote: HostSocketAddr,
428 ) -> Result<(), AdapterError> {
429 let command = Command::StartConnection(link_id, ConnectionType::TCP, remote.as_socket_addr());
430 if let Ok(Response::Connect(..)) = self.send(command) {
431 self.sockets[link_id].state = SocketState::Connected;
432 return Ok(());
433 }
434
435 Err(AdapterError::UnableToOpen)
436 }
437
438 pub(crate) fn write(
439 &mut self,
440 link_id: usize,
441 buffer: &[u8],
442 ) -> nb::Result<usize, AdapterError> {
443 self.process_notifications();
444
445 let command = Command::Send {
446 link_id,
447 len: buffer.len(),
448 };
449
450 if let Ok(response) = self.send(command) {
451 if let Response::Ok = response {
452 if let Ok(response) = self.wait_for_response() {
453 if let Response::ReadyForData = response {
454 for b in buffer.iter() {
455 nb::block!(self.tx.write(*b))
456 .map_err(|_| nb::Error::from(AdapterError::WriteError))?;
457 }
458 let mut data_sent: Option<usize> = None;
459 loop {
460 match self.wait_for_response() {
461 Ok(Response::ReceivedDataToSend(len)) => {
462 data_sent.replace(len);
463 }
464 Ok(Response::SendOk) => {
465 return Ok(data_sent.unwrap_or_default());
466 }
467 _ => {
468 break; }
470 }
471 }
472 }
473 }
474 }
475 }
476 Err(nb::Error::from(AdapterError::WriteError))
477 }
478
479 pub(crate) fn read(
480 &mut self,
481 link_id: usize,
482 buffer: &mut [u8],
483 ) -> nb::Result<usize, AdapterError> {
484 self.process_notifications();
485
486 if matches!( self.sockets[link_id].state, SocketState::Closed ) {
487 return Err(nb::Error::Other(AdapterError::InvalidSocket));
488 }
489
490 if self.sockets[link_id].available == 0 {
491 if matches!( self.sockets[link_id].state, SocketState::HalfClosed ) {
492 return Err(nb::Error::Other(AdapterError::InvalidSocket));
493 } else {
494 return Err(nb::Error::WouldBlock);
495 }
496 }
497
498 let mut actual_len = buffer.len();
499 if actual_len > crate::BUFFER_LEN {
500 actual_len = crate::BUFFER_LEN;
501 }
502
503 let command = Command::Receive {
504 link_id,
505 len: actual_len,
506 };
507
508 match self.send(command) {
509 Ok(Response::DataReceived(inbound, len)) => {
510 for (i, b) in inbound[0..len].iter().enumerate() {
511 buffer[i] = *b;
512 }
513 self.sockets[link_id].available -= len;
514 Ok(len)
515 }
516 Ok(Response::Ok) => Err(nb::Error::WouldBlock),
517 _=> Err(nb::Error::Other(AdapterError::ReadError)),
518 }
519 }
520
521 pub(crate) fn is_connected(&self, link_id: usize) -> Result<bool, AdapterError> {
522 Ok(match self.sockets[link_id].state {
523 SocketState::HalfClosed => {
524 self.sockets[link_id].available > 0
525 }
526 SocketState::Closed => {
527 false
528 }
529 SocketState::Open => {
530 false
531 }
532 SocketState::Connected => {
533 true
534 }
535 })
536 }
537
538 pub(crate) fn get_host_by_name(&mut self, hostname: &str) -> Result<HostAddr, DnsError> {
543 let command = Command::GetHostByName {
544 hostname
545 };
546
547 if let Ok(IpAddress(ip_addr)) = self.send(command) {
548 Ok(
549 HostAddr::new(ip_addr, Some(String::from(hostname)))
550 )
551 } else {
552 Err(DnsError::NoSuchHost)
553 }
554 }
555}