sim_pb/driving/
network.rs

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use crate::driving::SimRobot;
use async_std::io::{ReadExt, WriteExt};
use async_std::net::{TcpListener, TcpStream};
use async_std::task::sleep;
use bevy::prelude::{error, info};
use core_pb::driving::network::{NetworkScanInfo, RobotNetworkBehavior};
use core_pb::names::RobotName;
use embedded_io_async::{ErrorType, Read, ReadExactError, Write};
use std::io;
use std::io::ErrorKind;
use std::net::Shutdown;
use std::sync::{Arc, RwLock};
use std::time::Duration;

pub struct SimNetwork {
    name: RobotName,
    sim_robot: Arc<RwLock<SimRobot>>,
    network_connected: bool,

    firmware_swapped: bool,
}

impl SimNetwork {
    pub fn new(name: RobotName, firmware_swapped: bool, sim_robot: Arc<RwLock<SimRobot>>) -> Self {
        Self {
            name,
            sim_robot,
            network_connected: false,
            firmware_swapped,
        }
    }
}

#[derive(Debug)]
pub enum SimNetworkError {
    TcpAcceptFailed,
}

pub struct TcpStreamReadWrite(TcpStream);

impl ErrorType for TcpStreamReadWrite {
    type Error = io::Error;
}

impl Read for TcpStreamReadWrite {
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
        self.0.read(buf).await
    }

    async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError<Self::Error>> {
        self.0
            .read_exact(buf)
            .await
            .map_err(|_| ReadExactError::Other(io::Error::new(ErrorKind::Other, "")))
    }
}

impl Write for TcpStreamReadWrite {
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
        self.0.write(buf).await
    }
}

impl RobotNetworkBehavior for SimNetwork {
    type Error = SimNetworkError;
    type Socket<'a>
        = TcpStreamReadWrite
    where
        Self: 'a;

    async fn mac_address(&mut self) -> [u8; 6] {
        self.name.mac_address()
    }

    async fn wifi_is_connected(&self) -> Option<[u8; 4]> {
        if self.network_connected {
            Some([127, 0, 0, 1])
        } else {
            None
        }
    }

    async fn list_networks<const C: usize>(&mut self) -> heapless::Vec<NetworkScanInfo, C> {
        heapless::Vec::new()
    }

    async fn connect_wifi(
        &mut self,
        _network: &str,
        _password: Option<&str>,
    ) -> Result<(), <Self as RobotNetworkBehavior>::Error> {
        self.network_connected = true;
        sleep(Duration::from_secs(1)).await;
        Ok(())
    }

    async fn disconnect_wifi(&mut self) {
        self.network_connected = false;
    }

    async fn tcp_accept<'a>(
        &mut self,
        port: u16,
        _tx: &'a mut [u8; 5192],
        _rx: &'a mut [u8; 5192],
    ) -> Result<Self::Socket<'a>, <Self as RobotNetworkBehavior>::Error>
    where
        Self: 'a,
    {
        // simulate robot delay
        sleep(Duration::from_secs(1)).await;
        info!("{} listening on {port}!", self.name);
        match TcpListener::bind(format!("0.0.0.0:{port}")).await {
            Ok(listener) => match listener.accept().await {
                Err(e) => {
                    error!("Error accepting socket: {e:?}")
                }
                Ok((stream, addr)) => {
                    info!("Client connected to a {} from {addr}", self.name);
                    return Ok(TcpStreamReadWrite(stream));
                }
            },
            Err(e) => {
                error!("Error binding listener: {e:?}");
            }
        }
        Err(SimNetworkError::TcpAcceptFailed)
    }

    async fn tcp_close<'a>(&mut self, socket: &mut Self::Socket<'a>) {
        socket.0.shutdown(Shutdown::Both).unwrap()
    }

    async fn prepare_firmware_update(&mut self) {}

    async fn write_firmware(&mut self, _offset: usize, _data: &[u8]) -> Result<(), Self::Error> {
        sleep(Duration::from_millis(50)).await;
        Ok(())
    }

    async fn hash_firmware(&mut self, _update_len: u32, _output: &mut [u8; 32]) {
        sleep(Duration::from_millis(50)).await;
    }

    async fn mark_firmware_updated(&mut self) {
        self.sim_robot.write().unwrap().firmware_updated = true;
    }

    async fn firmware_swapped(&mut self) -> bool {
        self.firmware_swapped
    }

    async fn reboot(&mut self) {
        self.sim_robot.write().unwrap().reboot = true;
        sleep(Duration::from_secs(99999)).await
    }

    async fn mark_firmware_booted(&mut self) {
        self.firmware_swapped = false;
    }
}