2019-03-13 05:52:39 +08:00
|
|
|
use core::fmt;
|
|
|
|
use core::mem::uninitialized;
|
|
|
|
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 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
|
|
|
|
2019-03-19 03:02:57 +08:00
|
|
|
macro_rules! create_socket_storage {
|
|
|
|
($rx_storage:ident, $tx_storage:ident) => (
|
|
|
|
let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE];
|
|
|
|
let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE];
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! create_socket {
|
|
|
|
($set:ident, $rx_storage:ident, $tx_storage:ident, $target:expr) => (
|
|
|
|
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);
|
|
|
|
)
|
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>>,
|
|
|
|
sockets: SocketSet<'b, 'b, 'static>,
|
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> {
|
|
|
|
pub fn run<F>(net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>, f: F)
|
|
|
|
where
|
|
|
|
F: FnOnce(&mut Server<'a, '_>),
|
|
|
|
{
|
|
|
|
create_socket_storage!(tcp_rx_storage0, tcp_tx_storage0);
|
|
|
|
create_socket_storage!(tcp_rx_storage1, tcp_tx_storage1);
|
|
|
|
create_socket_storage!(tcp_rx_storage2, tcp_tx_storage2);
|
|
|
|
create_socket_storage!(tcp_rx_storage3, tcp_tx_storage3);
|
|
|
|
create_socket_storage!(tcp_rx_storage4, tcp_tx_storage4);
|
|
|
|
create_socket_storage!(tcp_rx_storage5, tcp_tx_storage5);
|
|
|
|
create_socket_storage!(tcp_rx_storage6, tcp_tx_storage6);
|
|
|
|
create_socket_storage!(tcp_rx_storage7, tcp_tx_storage7);
|
|
|
|
|
|
|
|
let mut sockets_storage = [
|
|
|
|
None, None, None, None,
|
|
|
|
None, None, None, None
|
|
|
|
];
|
|
|
|
let mut sockets = SocketSet::new(&mut sockets_storage[..]);
|
|
|
|
let mut handles: [SocketHandle; SOCKET_COUNT] = unsafe { uninitialized() };
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
pub fn poll(&mut self, now: Instant) {
|
2019-03-19 03:02:57 +08:00
|
|
|
let activity = self.net.poll(&mut self.sockets, now)
|
|
|
|
.unwrap_or(true);
|
2019-03-13 05:52:39 +08:00
|
|
|
if ! activity {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
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.is_open() {
|
|
|
|
socket.listen(TCP_PORT)
|
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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(())
|
|
|
|
}
|
|
|
|
}
|