thermostat/src/server.rs

109 lines
3.8 KiB
Rust
Raw Normal View History

2019-03-13 05:52:39 +08:00
use core::fmt;
2020-03-09 06:45:07 +08:00
use core::mem::MaybeUninit;
2019-03-13 05:52:39 +08:00
use smoltcp::{
2019-03-19 03:02:57 +08:00
iface::EthernetInterface,
socket::{SocketSet, SocketHandle, TcpSocket, TcpSocketBuffer},
2019-03-13 05:52:39 +08:00
time::Instant,
};
const TCP_PORT: u16 = 23;
2019-03-19 04:41:51 +08:00
/// Number of server sockets and therefore concurrent client
/// sessions. Many data structures in `Server::run()` correspond to
/// this const.
2019-03-19 03:02:57 +08:00
const SOCKET_COUNT: usize = 8;
2019-03-13 05:52:39 +08:00
2019-03-19 03:02:57 +08:00
const TCP_RX_BUFFER_SIZE: usize = 2048;
const TCP_TX_BUFFER_SIZE: usize = 2048;
2019-03-13 05:52:39 +08:00
2020-03-09 06:45:07 +08:00
macro_rules! create_socket {
($set:ident, $rx_storage:ident, $tx_storage:ident, $target:expr) => {
2019-03-19 03:02:57 +08:00
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
let tcp_rx_buffer = TcpSocketBuffer::new(&mut $rx_storage[..]);
let tcp_tx_buffer = TcpSocketBuffer::new(&mut $tx_storage[..]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
$target = $set.add(tcp_socket);
2020-03-09 06:45:07 +08:00
}
2019-03-13 05:52:39 +08:00
}
/// Contains a number of server sockets that get all sent the same
/// data (through `fmt::Write`).
2019-03-19 03:02:57 +08:00
pub struct Server<'a, 'b> {
net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>,
2020-03-09 06:45:07 +08:00
sockets: SocketSet<'b, 'b, 'b>,
2019-03-13 05:52:39 +08:00
handles: [SocketHandle; SOCKET_COUNT],
}
2019-03-19 03:02:57 +08:00
impl<'a, 'b> Server<'a, 'b> {
/// Run a server with stack-allocated sockets
2019-03-19 03:02:57 +08:00
pub fn run<F>(net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>, f: F)
where
F: FnOnce(&mut Server<'a, '_>),
{
2020-03-09 06:45:07 +08:00
let mut sockets_storage: [_; SOCKET_COUNT] = Default::default();
2019-03-19 03:02:57 +08:00
let mut sockets = SocketSet::new(&mut sockets_storage[..]);
2020-03-09 06:45:07 +08:00
let mut handles: [SocketHandle; SOCKET_COUNT] = unsafe { MaybeUninit::uninit().assume_init() };
2019-03-19 03:02:57 +08:00
create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, handles[0]);
create_socket!(sockets, tcp_rx_storage1, tcp_tx_storage1, handles[1]);
create_socket!(sockets, tcp_rx_storage2, tcp_tx_storage2, handles[2]);
create_socket!(sockets, tcp_rx_storage3, tcp_tx_storage3, handles[3]);
create_socket!(sockets, tcp_rx_storage4, tcp_tx_storage4, handles[4]);
create_socket!(sockets, tcp_rx_storage5, tcp_tx_storage5, handles[5]);
create_socket!(sockets, tcp_rx_storage6, tcp_tx_storage6, handles[6]);
create_socket!(sockets, tcp_rx_storage7, tcp_tx_storage7, handles[7]);
2019-03-13 05:52:39 +08:00
let mut server = Server {
2019-03-19 03:02:57 +08:00
handles,
sockets,
2019-03-13 05:52:39 +08:00
net,
};
2019-03-19 03:02:57 +08:00
f(&mut server);
2019-03-13 05:52:39 +08:00
}
/// Poll the interface and the sockets
pub fn poll(&mut self, now: Instant) -> Result<(), smoltcp::Error> {
// Poll smoltcp EthernetInterface
let mut poll_error = None;
2019-03-19 03:02:57 +08:00
let activity = self.net.poll(&mut self.sockets, now)
.unwrap_or_else(|e| {
poll_error = Some(e);
true
});
2019-03-13 05:52:39 +08:00
if activity {
// Listen on all sockets
for handle in &self.handles {
let mut socket = self.sockets.get::<TcpSocket>(*handle);
if ! socket.is_open() {
let _ = socket.listen(TCP_PORT);
}
2019-03-13 05:52:39 +08:00
}
}
// Pass some smoltcp errors to the caller
match poll_error {
None => Ok(()),
Some(smoltcp::Error::Malformed) => Ok(()),
Some(smoltcp::Error::Unrecognized) => Ok(()),
Some(e) => Err(e),
}
2019-03-13 05:52:39 +08:00
}
}
2019-03-19 04:41:51 +08:00
/// Reusing the `fmt::Write` trait just for `write!()` convenience
2019-03-13 05:52:39 +08:00
impl<'a, 's> fmt::Write for Server<'a, 's> {
/// Write to all connected clients
fn write_str(&mut self, slice: &str) -> fmt::Result {
for handle in &self.handles {
2019-03-19 03:02:57 +08:00
let mut socket = self.sockets.get::<TcpSocket>(*handle);
2019-03-13 05:52:39 +08:00
if socket.can_send() {
// Ignore errors, proceed with next client
let _ = socket.write_str(slice);
}
}
Ok(())
}
}