1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! TCP stack implementation of [`Sink`] and [`Source`].

use crate::{Request, ResponseHandler, Sink, Source};
use core::str::from_utf8;
use drogue_network::tcp::TcpStack;
use heapless::ArrayLength;

pub struct TcpSocketSinkSource<'tcp, T>
where
    T: TcpStack,
{
    stack: &'tcp mut T,
    socket: &'tcp mut T::TcpSocket,
}

impl<'tcp, T> TcpSocketSinkSource<'tcp, T>
where
    T: TcpStack,
{
    pub fn from(stack: &'tcp mut T, socket: &'tcp mut T::TcpSocket) -> Self {
        TcpSocketSinkSource { stack, socket }
    }
}

impl<'tcp, T> Source for TcpSocketSinkSource<'tcp, T>
where
    T: TcpStack,
{
    type Error = T::Error;

    fn pipe_data<IN, R>(&mut self, request: &mut Request<IN, R>) -> Result<(), Self::Error>
    where
        IN: ArrayLength<u8>,
        R: ResponseHandler,
    {
        let mut buffer = [0u8; 512];
        while !request.is_complete() {
            match self.stack.read(self.socket, &mut buffer) {
                Ok(len) => {
                    request.push_data(&buffer[0..len]);
                }
                Err(nb::Error::WouldBlock) => {}
                Err(nb::Error::Other(e)) => return Err(e),
            }
        }
        Ok(())
    }
}

impl<'tcp, T> Sink for TcpSocketSinkSource<'tcp, T>
where
    T: TcpStack,
{
    fn send(&mut self, data: &[u8]) -> Result<usize, ()> {
        log::info!("Sending: {:?}", from_utf8(data));
        self.stack.write(self.socket, data).map_err(|_| ())
    }
}