net: close oldest sock if available socks run out
- By default, smoltcp by default reset any new connections if there is no available socket
This commit is contained in:
parent
b763350a8b
commit
0b5fda2cd9
37
src/main.rs
37
src/main.rs
@ -1,7 +1,7 @@
|
||||
#![cfg_attr(not(test), no_main)]
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::{marker::PhantomData, u32};
|
||||
|
||||
use cortex_m_rt::entry;
|
||||
use log::{debug, info};
|
||||
@ -82,6 +82,8 @@ fn main() -> ! {
|
||||
|
||||
let eth_data_buffer = unsafe { addr_of_mut!(ETH_DATA_BUFFER).as_mut().unwrap() };
|
||||
|
||||
let mut sock_ts: [u32; net::net::NUM_OF_SOCKETS] = [0; net::net::NUM_OF_SOCKETS];
|
||||
|
||||
loop {
|
||||
wd.feed();
|
||||
|
||||
@ -183,6 +185,10 @@ fn main() -> ! {
|
||||
thermostat.start_tec_readings_conversion();
|
||||
}
|
||||
|
||||
let mut num_of_connected_sock: u8 = 0;
|
||||
let mut oldest_connected_sock_ts: u32 = u32::MAX;
|
||||
let mut oldest_connected_sock_id: usize = 0;
|
||||
|
||||
net::net::for_each(|mut socket, id| {
|
||||
if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) {
|
||||
if net::net::eth_can_sock_recv(socket) && net::net::eth_can_sock_send(socket) {
|
||||
@ -204,8 +210,35 @@ fn main() -> ! {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
num_of_connected_sock += 1;
|
||||
|
||||
if sock_ts[id] == 0 {
|
||||
sock_ts[id] = sys_timer::now();
|
||||
}
|
||||
if oldest_connected_sock_ts > sock_ts[id] {
|
||||
oldest_connected_sock_ts = sock_ts[id];
|
||||
oldest_connected_sock_id = id;
|
||||
}
|
||||
} else {
|
||||
sock_ts[id] = 0;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if num_of_connected_sock == net::net::NUM_OF_SOCKETS as u8 {
|
||||
let mut sock_handle = net::net::eth_get_sock_handle(oldest_connected_sock_id);
|
||||
net::cmd_handler::send_response(
|
||||
eth_data_buffer,
|
||||
net::cmd_handler::ResponseEnum::ConnectionClose,
|
||||
None,
|
||||
&mut sock_handle,
|
||||
);
|
||||
net::net::eth_poll_iface();
|
||||
debug!("Waiting for ConnectionClose msg to be sent");
|
||||
while !net::net::eth_is_data_sent() { }
|
||||
net::net::eth_close_socket_by_id(oldest_connected_sock_id);
|
||||
debug!("Closing socket id: {:?}", oldest_connected_sock_id);
|
||||
}
|
||||
}
|
||||
State::SaveLdThermostatSettings => {
|
||||
// State Transition
|
||||
|
@ -31,6 +31,7 @@ pub enum ResponseEnum {
|
||||
InvalidDatatype,
|
||||
InvalidCmd,
|
||||
HardReset,
|
||||
ConnectionClose,
|
||||
}
|
||||
|
||||
pub type MsgType = Option<&'static str>;
|
||||
|
@ -47,6 +47,7 @@ pub struct ServerHandle {
|
||||
dma: EthernetDMA<'static, 'static>,
|
||||
phy: EthernetPhy<EthernetMACWithMii<Pin<'A', 2, Alternate<11>>, Pin<'C', 1, Alternate<11>>>>,
|
||||
link_was_up: bool,
|
||||
data_sent: bool,
|
||||
}
|
||||
pub type EthernetPins = EthPins<PA1<Input>, PA7<Input>, PB11<Input>, PB12<Input>, PB13<Input>, PC4<Input>, PC5<Input>>;
|
||||
pub struct EthernetMgmtPins {
|
||||
@ -55,7 +56,7 @@ pub struct EthernetMgmtPins {
|
||||
}
|
||||
pub type EthInterface = Interface;
|
||||
|
||||
pub const NUM_OF_SOCKETS: usize = 4;
|
||||
pub const NUM_OF_SOCKETS: usize = 4 + 1;
|
||||
const TCP_BUFFER_SIZE: usize = 4096;
|
||||
static mut RX_RING: Option<[RxRingEntry; 8]> = None;
|
||||
static mut TX_RING: Option<[TxRingEntry; 8]> = None;
|
||||
@ -138,7 +139,7 @@ impl ServerHandle {
|
||||
let tcp_handles = {
|
||||
// Do not use NUM_OF_SOCKETS to define array size to
|
||||
// remind developers to create/remove tcp_handles accordingly after changing NUM_OF_SOCKETS
|
||||
let mut tcp_handles: [MaybeUninit<SocketHandle>; 4] = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
let mut tcp_handles: [MaybeUninit<SocketHandle>; 5] = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
macro_rules! create_tcp_handle {
|
||||
($rx_storage:ident, $tx_storage:ident, $handle:expr) => {
|
||||
@ -155,8 +156,9 @@ impl ServerHandle {
|
||||
create_tcp_handle!(RX_STORAGE1, TX_STORAGE1, tcp_handles[1]);
|
||||
create_tcp_handle!(RX_STORAGE2, TX_STORAGE2, tcp_handles[2]);
|
||||
create_tcp_handle!(RX_STORAGE3, TX_STORAGE3, tcp_handles[3]);
|
||||
create_tcp_handle!(RX_STORAGE4, TX_STORAGE4, tcp_handles[4]);
|
||||
|
||||
unsafe { mem::transmute::<_, [SocketHandle; 4]>(tcp_handles) }
|
||||
unsafe { mem::transmute::<_, [SocketHandle; 5]>(tcp_handles) }
|
||||
};
|
||||
|
||||
for i in 0..NUM_OF_SOCKETS {
|
||||
@ -189,6 +191,7 @@ impl ServerHandle {
|
||||
dma: dma,
|
||||
phy: phy,
|
||||
link_was_up: false,
|
||||
data_sent: true,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
@ -249,6 +252,7 @@ impl ServerHandle {
|
||||
cortex_m::interrupt::free(|_| {
|
||||
match socket.send_slice(&buffer[..num_bytes]) {
|
||||
Ok(_) => {
|
||||
self.data_sent = false;
|
||||
info!("Enqueued {} bytes.", num_bytes);
|
||||
}
|
||||
Err(err) => {
|
||||
@ -501,6 +505,46 @@ pub fn eth_close_socket(socket_handles: SocketHandle) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eth_get_sock_handle(id: usize) -> SocketHandle {
|
||||
unsafe {
|
||||
if let Some(ref mut server_handle) = SERVER_HANDLE {
|
||||
server_handle.socket_handles[id]
|
||||
} else {
|
||||
panic!("eth_get_sock_handle is called before init");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eth_close_socket_by_id(id: usize) {
|
||||
unsafe {
|
||||
if let Some(ref mut server_handle) = SERVER_HANDLE {
|
||||
server_handle.close_socket(server_handle.socket_handles[id])
|
||||
} else {
|
||||
panic!("eth_close_socket_by_id is called before init");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eth_is_data_sent() -> bool {
|
||||
unsafe {
|
||||
if let Some(ref mut server_handle) = SERVER_HANDLE {
|
||||
server_handle.data_sent
|
||||
} else {
|
||||
panic!("eth_is_data_sent is called before init");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eth_set_data_sent(val: bool) {
|
||||
unsafe {
|
||||
if let Some(ref mut server_handle) = SERVER_HANDLE {
|
||||
server_handle.data_sent = val;
|
||||
} else {
|
||||
panic!("eth_is_data_sent is called before init");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_each<F: FnMut(SocketHandle, usize)>(mut callback: F) {
|
||||
unsafe {
|
||||
if let Some(ref mut server_handle) = SERVER_HANDLE {
|
||||
@ -521,6 +565,9 @@ fn ETH() {
|
||||
if interrupt_reason.rx {
|
||||
eth_poll_iface();
|
||||
}
|
||||
if interrupt_reason.tx {
|
||||
eth_set_data_sent(true);
|
||||
}
|
||||
debug!("Ethernet Interrupt{:?}", interrupt_reason);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user