1
0
forked from M-Labs/kirdy

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:
linuswck 2024-09-04 15:24:03 +08:00
parent b763350a8b
commit 0b5fda2cd9
3 changed files with 86 additions and 5 deletions

View File

@ -1,7 +1,7 @@
#![cfg_attr(not(test), no_main)] #![cfg_attr(not(test), no_main)]
#![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_std)]
use core::marker::PhantomData; use core::{marker::PhantomData, u32};
use cortex_m_rt::entry; use cortex_m_rt::entry;
use log::{debug, info}; 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 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 { loop {
wd.feed(); wd.feed();
@ -183,6 +185,10 @@ fn main() -> ! {
thermostat.start_tec_readings_conversion(); 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| { 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_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) { 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::SaveLdThermostatSettings => {
// State Transition // State Transition

View File

@ -31,6 +31,7 @@ pub enum ResponseEnum {
InvalidDatatype, InvalidDatatype,
InvalidCmd, InvalidCmd,
HardReset, HardReset,
ConnectionClose,
} }
pub type MsgType = Option<&'static str>; pub type MsgType = Option<&'static str>;

View File

@ -47,6 +47,7 @@ pub struct ServerHandle {
dma: EthernetDMA<'static, 'static>, dma: EthernetDMA<'static, 'static>,
phy: EthernetPhy<EthernetMACWithMii<Pin<'A', 2, Alternate<11>>, Pin<'C', 1, Alternate<11>>>>, phy: EthernetPhy<EthernetMACWithMii<Pin<'A', 2, Alternate<11>>, Pin<'C', 1, Alternate<11>>>>,
link_was_up: bool, 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 type EthernetPins = EthPins<PA1<Input>, PA7<Input>, PB11<Input>, PB12<Input>, PB13<Input>, PC4<Input>, PC5<Input>>;
pub struct EthernetMgmtPins { pub struct EthernetMgmtPins {
@ -55,7 +56,7 @@ pub struct EthernetMgmtPins {
} }
pub type EthInterface = Interface; 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; const TCP_BUFFER_SIZE: usize = 4096;
static mut RX_RING: Option<[RxRingEntry; 8]> = None; static mut RX_RING: Option<[RxRingEntry; 8]> = None;
static mut TX_RING: Option<[TxRingEntry; 8]> = None; static mut TX_RING: Option<[TxRingEntry; 8]> = None;
@ -138,7 +139,7 @@ impl ServerHandle {
let tcp_handles = { let tcp_handles = {
// Do not use NUM_OF_SOCKETS to define array size to // Do not use NUM_OF_SOCKETS to define array size to
// remind developers to create/remove tcp_handles accordingly after changing NUM_OF_SOCKETS // 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 { macro_rules! create_tcp_handle {
($rx_storage:ident, $tx_storage:ident, $handle:expr) => { ($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_STORAGE1, TX_STORAGE1, tcp_handles[1]);
create_tcp_handle!(RX_STORAGE2, TX_STORAGE2, tcp_handles[2]); create_tcp_handle!(RX_STORAGE2, TX_STORAGE2, tcp_handles[2]);
create_tcp_handle!(RX_STORAGE3, TX_STORAGE3, tcp_handles[3]); 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 { for i in 0..NUM_OF_SOCKETS {
@ -189,6 +191,7 @@ impl ServerHandle {
dma: dma, dma: dma,
phy: phy, phy: phy,
link_was_up: false, link_was_up: false,
data_sent: true,
}; };
unsafe { unsafe {
@ -249,6 +252,7 @@ impl ServerHandle {
cortex_m::interrupt::free(|_| { cortex_m::interrupt::free(|_| {
match socket.send_slice(&buffer[..num_bytes]) { match socket.send_slice(&buffer[..num_bytes]) {
Ok(_) => { Ok(_) => {
self.data_sent = false;
info!("Enqueued {} bytes.", num_bytes); info!("Enqueued {} bytes.", num_bytes);
} }
Err(err) => { 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) { pub fn for_each<F: FnMut(SocketHandle, usize)>(mut callback: F) {
unsafe { unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE { if let Some(ref mut server_handle) = SERVER_HANDLE {
@ -521,6 +565,9 @@ fn ETH() {
if interrupt_reason.rx { if interrupt_reason.rx {
eth_poll_iface(); eth_poll_iface();
} }
if interrupt_reason.tx {
eth_set_data_sent(true);
}
debug!("Ethernet Interrupt{:?}", interrupt_reason); debug!("Ethernet Interrupt{:?}", interrupt_reason);
} }