From b82bb92ead603375da149e4db974f4394b185864 Mon Sep 17 00:00:00 2001 From: Jonah Dahlquist Date: Wed, 4 Sep 2019 13:37:59 -0500 Subject: [PATCH] Added inactive UP socket state, added run-time socket ownership checking, added register addresses to sockets --- src/socket/mod.rs | 125 ++++++++++++++++++++++++++++++--- src/udp/inactive_udp_socket.rs | 25 +++++++ src/udp/mod.rs | 37 ++++++++-- src/w5500.rs | 15 +++- 4 files changed, 184 insertions(+), 18 deletions(-) create mode 100644 src/udp/inactive_udp_socket.rs diff --git a/src/socket/mod.rs b/src/socket/mod.rs index bd7eba7..c12160d 100644 --- a/src/socket/mod.rs +++ b/src/socket/mod.rs @@ -1,5 +1,8 @@ pub trait Socket { - // TODO expose method to get address of socket + fn is_owned_by(&self, sockets: OwnedSockets) -> bool; + fn register(&self) -> u8; + fn tx_buffer(&self) -> u8; + fn rx_buffer(&self) -> u8; } pub type OwnedSockets = ( @@ -24,18 +27,122 @@ pub type Sockets<'a> = ( ); pub struct Socket0 {} -impl Socket for Socket0 {} +impl Socket for Socket0 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.0 as *const _ + } + fn register(&self) -> u8 { + 0b000_00001 + } + fn tx_buffer(&self) -> u8 { + 0b000_00010 + } + fn rx_buffer(&self) -> u8 { + 0b000_00011 + } +} pub struct Socket1 {} -impl Socket for Socket1 {} +impl Socket for Socket1 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.1 as *const _ + } + fn register(&self) -> u8 { + 0b000_00101 + } + fn tx_buffer(&self) -> u8 { + 0b000_00110 + } + fn rx_buffer(&self) -> u8 { + 0b000_00111 + } +} pub struct Socket2 {} -impl Socket for Socket2 {} +impl Socket for Socket2 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.2 as *const _ + } + fn register(&self) -> u8 { + 0b000_01001 + } + fn tx_buffer(&self) -> u8 { + 0b000_01010 + } + fn rx_buffer(&self) -> u8 { + 0b000_01011 + } +} pub struct Socket3 {} -impl Socket for Socket3 {} +impl Socket for Socket3 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.3 as *const _ + } + fn register(&self) -> u8 { + 0b000_01101 + } + fn tx_buffer(&self) -> u8 { + 0b000_01110 + } + fn rx_buffer(&self) -> u8 { + 0b000_01111 + } +} pub struct Socket4 {} -impl Socket for Socket4 {} +impl Socket for Socket4 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.4 as *const _ + } + fn register(&self) -> u8 { + 0b000_10001 + } + fn tx_buffer(&self) -> u8 { + 0b000_10010 + } + fn rx_buffer(&self) -> u8 { + 0b000_10011 + } +} pub struct Socket5 {} -impl Socket for Socket5 {} +impl Socket for Socket5 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.5 as *const _ + } + fn register(&self) -> u8 { + 0b000_10101 + } + fn tx_buffer(&self) -> u8 { + 0b000_10110 + } + fn rx_buffer(&self) -> u8 { + 0b000_10111 + } +} pub struct Socket6 {} -impl Socket for Socket6 {} +impl Socket for Socket6 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.6 as *const _ + } + fn register(&self) -> u8 { + 0b000_11001 + } + fn tx_buffer(&self) -> u8 { + 0b000_11010 + } + fn rx_buffer(&self) -> u8 { + 0b000_11011 + } +} pub struct Socket7 {} -impl Socket for Socket7 {} +impl Socket for Socket7 { + fn is_owned_by(&self, sockets: OwnedSockets) -> bool { + self as *const _ == &sockets.7 as *const _ + } + fn register(&self) -> u8 { + 0b000_11101 + } + fn tx_buffer(&self) -> u8 { + 0b000_11110 + } + fn rx_buffer(&self) -> u8 { + 0b000_11111 + } +} diff --git a/src/udp/inactive_udp_socket.rs b/src/udp/inactive_udp_socket.rs new file mode 100644 index 0000000..5776a5e --- /dev/null +++ b/src/udp/inactive_udp_socket.rs @@ -0,0 +1,25 @@ +use crate::socket::Socket; +use crate::w5500::ForeignSocketError; +use crate::udp::UdpSocket; +use crate::w5500::W5500; +use crate::bus::ActiveBus; +use crate::network::Network; + +pub struct InactiveUdpSocket<'a, SocketImpl: Socket> { + socket: &'a mut SocketImpl, +} + +impl<'a, SocketImpl: Socket> InactiveUdpSocket<'a, SocketImpl> { + pub fn new(socket: &'a mut SocketImpl) -> Self { + InactiveUdpSocket { socket } + } + + pub fn activate(self, w5500: W5500) -> Result, ForeignSocketError> { + let (bus, network, sockets) = w5500.release(); + if self.socket.is_owned_by(sockets) { + Ok(UdpSocket::new(bus, network, sockets, self.socket)) + } else { + Err(ForeignSocketError {}) + } + } +} diff --git a/src/udp/mod.rs b/src/udp/mod.rs index 4e882ec..a3d4290 100644 --- a/src/udp/mod.rs +++ b/src/udp/mod.rs @@ -1,12 +1,37 @@ -use crate::socket::Socket; +mod inactive_udp_socket; + +use crate::bus::ActiveBus; +use crate::network::Network; +use crate::socket::Socket; +use crate::w5500::W5500; +use crate::udp::inactive_udp_socket::InactiveUdpSocket; +use crate::socket::OwnedSockets; + +pub struct UdpSocket<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> { + bus: SpiBus, + network: NetworkImpl, + sockets: OwnedSockets, -pub struct UdpSocket<'a, SocketImpl: Socket> { socket: &'a mut SocketImpl, } -impl<'a, SocketImpl: Socket> UdpSocket<'a, SocketImpl> { - pub fn new(socket: &'a mut SocketImpl) -> Self { - // TODO initialize socket for UDP mode - UdpSocket { socket } +impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl> { + pub fn new(bus: SpiBus, network: NetworkImpl, sockets: OwnedSockets, socket: &'a mut SocketImpl) -> Self { + // TODO setup socket in UDP mode + // self.0.reset_interrupt(socket, Interrupt::SendOk)?; + // self.0.write_u16(socket.at(SocketRegister::LocalPort), port)?; + // self.0.write_to( + // socket.at(SocketRegister::Mode), + // &[ + // Protocol::UDP as u8, // Socket Mode Register + // SocketCommand::Open as u8, // Socket Command Register + // ], + // )?; + + UdpSocket { bus, network, sockets, socket } + } + + pub fn deactivate(self) -> (InactiveUdpSocket<'a, SocketImpl>, W5500) { + (InactiveUdpSocket::new(self.socket), W5500::new(self.bus, self.network, self.sockets)) } } diff --git a/src/w5500.rs b/src/w5500.rs index d00ca6e..ae905e8 100644 --- a/src/w5500.rs +++ b/src/w5500.rs @@ -53,9 +53,16 @@ impl W5500 { pub fn open_udp_socket<'a, SocketImpl: Socket>( &self, socket: &'a mut SocketImpl, - ) -> UdpSocket<'a, SocketImpl> { - // TODO compare socket to sockets list - UdpSocket::new(socket) + ) -> Result, ForeignSocketError> { + if socket.is_owned_by(self.sockets) { + Ok(UdpSocket::new(self.bus, self.network, self.sockets, socket)) + } else { + Err(ForeignSocketError {}) + } + } + + pub fn release(self) -> (SpiBus, NetworkImpl, OwnedSockets) { + (self.bus, self.network, self.sockets) } } @@ -74,3 +81,5 @@ impl, NetworkImpl: Network> W5500, Netw (InactiveW5500::new(bus, self.network, self.sockets), spi) } } + +pub struct ForeignSocketError {}