thermostat/src/server.rs

105 lines
3.7 KiB
Rust
Raw Normal View History

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,
2020-03-14 06:39:22 +08:00
socket::{SocketSet, SocketHandle, TcpSocket, TcpSocketBuffer, SocketRef},
2019-03-13 05:52:39 +08:00
time::Instant,
wire::{IpCidr, Ipv4Address, Ipv4Cidr},
2019-03-13 05:52:39 +08:00
};
2020-03-14 06:39:22 +08:00
pub struct SocketState<S> {
handle: SocketHandle,
state: S,
}
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.
const SOCKET_COUNT: usize = 4;
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
/// Contains a number of server sockets that get all sent the same
/// data (through `fmt::Write`).
2020-03-14 06:39:22 +08:00
pub struct Server<'a, 'b, S> {
2019-03-19 03:02:57 +08:00
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>,
2020-03-14 06:39:22 +08:00
states: [SocketState<S>; SOCKET_COUNT],
2019-03-13 05:52:39 +08:00
}
2020-03-14 06:39:22 +08:00
impl<'a, 'b, S: Default> Server<'a, 'b, S> {
/// 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
2020-03-14 06:39:22 +08:00
F: FnOnce(&mut Server<'a, '_, S>),
2019-03-19 03:02:57 +08:00
{
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-14 06:39:22 +08:00
let mut states: [SocketState<S>; SOCKET_COUNT] = unsafe { MaybeUninit::uninit().assume_init() };
macro_rules! create_socket {
($set:ident, $rx_storage:ident, $tx_storage:ident, $target:expr) => {
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);
}
}
create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, states[0].handle);
create_socket!(sockets, tcp_rx_storage1, tcp_tx_storage1, states[1].handle);
create_socket!(sockets, tcp_rx_storage2, tcp_tx_storage2, states[2].handle);
create_socket!(sockets, tcp_rx_storage3, tcp_tx_storage3, states[3].handle);
for state in &mut states {
state.state = S::default();
}
2019-03-19 03:02:57 +08:00
2019-03-13 05:52:39 +08:00
let mut server = Server {
2020-03-14 06:39:22 +08:00
states,
2019-03-19 03:02:57 +08:00
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> {
2020-03-14 06:39:22 +08:00
// Poll smoltcp EthernetInterface,
// pass only unexpected smoltcp errors to the caller
match self.net.poll(&mut self.sockets, now) {
Ok(_) => Ok(()),
Err(smoltcp::Error::Malformed) => Ok(()),
Err(smoltcp::Error::Unrecognized) => Ok(()),
Err(e) => Err(e),
}
2019-03-13 05:52:39 +08:00
}
2020-03-14 06:39:22 +08:00
/// Iterate over all sockets managed by this server
pub fn for_each<F: FnMut(SocketRef<TcpSocket>, &mut S)>(&mut self, mut callback: F) {
for state in &mut self.states {
let socket = self.sockets.get::<TcpSocket>(state.handle);
callback(socket, &mut state.state);
2019-03-13 05:52:39 +08:00
}
}
pub fn set_ipv4_address(&mut self, ipv4_address: Ipv4Address) {
self.net.update_ip_addrs(|addrs| {
for addr in addrs.iter_mut() {
match addr {
IpCidr::Ipv4(_) => {
*addr = IpCidr::Ipv4(Ipv4Cidr::new(ipv4_address, 0));
// done
break
}
_ => {
// skip
}
}
}
});
}
2019-03-13 05:52:39 +08:00
}