From 423d2f64018ebab9c4fc9df1337c7528d205db6d Mon Sep 17 00:00:00 2001 From: Jonah Dahlquist Date: Tue, 10 Sep 2019 20:43:26 -0500 Subject: [PATCH] Fleshed out packet receipt --- src/register.rs | 8 +++++- src/socket/mod.rs | 18 +++++++++++-- src/udp/mod.rs | 21 +++------------ src/udp/packet.rs | 67 +++++++++++++++++++++++++++++------------------ 4 files changed, 68 insertions(+), 46 deletions(-) diff --git a/src/register.rs b/src/register.rs index 1a72f20..3421a5d 100644 --- a/src/register.rs +++ b/src/register.rs @@ -46,6 +46,11 @@ pub mod socketn { pub enum Protocol { Udp = 0b10u8, } + pub const COMMAND: u16 = 0x01; + #[repr(u8)] + pub enum Command { + Receive = 0x40, + } pub const INTERRUPT: u16 = 0x02; #[repr(u8)] @@ -62,5 +67,6 @@ pub mod socketn { pub const RECEIVED_SIZE: u16 = 0x26; - pub const RX_DATA_POINTER: u16 = 0x28; + pub const RX_DATA_READ_POINTER: u16 = 0x28; + pub const RX_DATA_WRITE_POINTER: u16 = 0x2A; } diff --git a/src/socket/mod.rs b/src/socket/mod.rs index 48f5c3c..3872ee7 100644 --- a/src/socket/mod.rs +++ b/src/socket/mod.rs @@ -46,14 +46,28 @@ pub trait Socket { Ok(data[0] & socketn::interrupt_mask::RECEIVE != 0) } - fn get_packet_address( + fn get_rx_read_pointer( &self, bus: &mut SpiBus, ) -> Result { let mut data = [0u8; 2]; - block!(bus.transfer_frame(self.register(), socketn::RX_DATA_POINTER, true, &mut data))?; + block!(bus.transfer_frame(self.register(), socketn::RX_DATA_READ_POINTER, true, &mut data))?; Ok(BigEndian::read_u16(&data)) } + + fn set_rx_read_pointer(&self, bus: &mut SpiBus, pointer: u16) -> Result<(), SpiBus::Error> { + let mut data = [0u8; 2]; + BigEndian::write_u16(&mut data, pointer); + block!(bus.transfer_frame(self.register(), socketn::RX_DATA_READ_POINTER, true, &mut data))?; + Ok(()) + } + + fn command(&self, bus: &mut SpiBus, command: socketn::Command) -> Result<(), SpiBus::Error> { + let mut data = [0u8; 2]; + BigEndian::write_u16(&mut data, command as u16); + block!(bus.transfer_frame(self.register(), socketn::COMMAND, true, &mut data))?; + Ok(()) + } } pub type OwnedSockets = ( diff --git a/src/udp/mod.rs b/src/udp/mod.rs index dc9403f..76a8fcb 100644 --- a/src/udp/mod.rs +++ b/src/udp/mod.rs @@ -1,16 +1,13 @@ mod inactive_udp_socket; mod packet; -use byteorder::{BigEndian, ByteOrder}; -use crate::IpAddress; use crate::bus::ActiveBus; use crate::network::Network; -use crate::socket::OwnedSockets; -use crate::socket::Socket; +use crate::socket::{Socket, OwnedSockets}; use crate::udp::inactive_udp_socket::InactiveUdpSocket; -use crate::w5500::W5500; use crate::udp::packet::UdpPacket; -use register::socketn; +use crate::w5500::W5500; +use crate::register::socketn; pub struct UdpSocket<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> { bus: SpiBus, @@ -51,18 +48,6 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> } } - fn block_until_receive_size_known(&mut self) -> Result { - loop { - let mut sample_0 = [0u8; 2]; - block!(self.bus.transfer_frame(self.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_0))?; - let mut sample_1 = [0u8; 2]; - block!(self.bus.transfer_frame(self.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_1))?; - if sample_0 == sample_1 && sample_0[0] >= 8 { - break Ok(BigEndian::read_u16(&sample_0)); - } - } - } - // /// Sends a UDP packet to the specified IP and port, and blocks until it is sent // fn blocking_send( // &mut self, diff --git a/src/udp/packet.rs b/src/udp/packet.rs index 95fd2d0..cf36f6e 100644 --- a/src/udp/packet.rs +++ b/src/udp/packet.rs @@ -1,34 +1,35 @@ +use byteorder::{BigEndian, ByteOrder}; use crate::udp::UdpSocket; use crate::network::Network; use crate::bus::ActiveBus; use crate::socket::Socket; use crate::IpAddress; -use byteorder::{BigEndian, ByteOrder}; +use crate::register::socketn; pub struct UdpPacket { udp_socket: UdpSocket, address: IpAddress, remote_port: u16, - size: u16, read_pointer: u16, + write_pointer: u16, } impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket> { pub fn new(mut udp_socket: UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result { - let receive_size = udp_socket.block_until_receive_size_known()? - 8; + let receive_size = Self::block_until_receive_size_known(&mut udp_socket)?; // |<-- read_pointer read_pointer + received_size -->| // |Destination IP Address | Destination Port | Byte Size of DATA | Actual DATA ... | // | --- 4 Bytes --- | --- 2 Bytes --- | --- 2 Bytes --- | .... | - let read_pointer = udp_socket.socket.get_packet_address(&mut udp_socket.bus)?; + let read_pointer = udp_socket.socket.get_rx_read_pointer(&mut udp_socket.bus)?; let mut header = [0u8; 8]; block!(udp_socket.bus.transfer_frame(udp_socket.socket.rx_buffer(), read_pointer, false, &mut header))?; Ok(UdpPacket { udp_socket, address: IpAddress::new(header[0], header[1], header[2], header[3]), remote_port: BigEndian::read_u16(&header[4..5]), - size: receive_size, - read_pointer, + read_pointer: read_pointer + 8, + write_pointer: read_pointer + receive_size, }) } @@ -40,27 +41,43 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket< self.address } - pub fn read(&self) { - // TODO read a byte upon every invocation - // w5500.read_from( - // socket.rx_register_at(read_pointer + 8), - // &mut destination[..data_length], - // )?; + pub fn read(&mut self) -> Result { + let mut buffer = [0u8]; + block!(self.udp_socket.bus.transfer_frame(self.udp_socket.socket.rx_buffer(), self.read_pointer, false, &mut buffer))?; + Ok(buffer[0]) } - pub fn close(self) -> UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl> { - // TODO reset read pointer etc + pub fn done(mut self) -> Result, SpiBus::Error> { + self.udp_socket.socket.set_rx_read_pointer(&mut self.udp_socket.bus, self.write_pointer)?; + self.udp_socket.socket.command(&mut self.udp_socket.bus, socketn::Command::Receive)?; + Ok(self.udp_socket) + } - // // reset - // w5500.write_u16( - // socket.at(SocketRegister::RxReadPointer), - // read_pointer + receive_size as u16, - // )?; - // w5500.write_u8( - // socket.at(SocketRegister::Command), - // SocketCommand::Recv as u8, - // )?; - // TODO return Socket - self.udp_socket + fn block_until_receive_size_known(udp_socket: &mut UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result { + loop { + let mut sample_0 = [0u8; 2]; + block!(udp_socket.bus.transfer_frame(udp_socket.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_0))?; + let mut sample_1 = [0u8; 2]; + block!(udp_socket.bus.transfer_frame(udp_socket.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_1))?; + if sample_0 == sample_1 && sample_0[0] >= 8 { + break Ok(BigEndian::read_u16(&sample_0)); + } + } + } +} + +impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> Iterator for UdpPacket> { + type Item = Result; + fn next(&mut self) -> Option { + if self.read_pointer > self.write_pointer { + return None; + } + let mut buffer = [0u8]; + let result = block!(self.udp_socket.bus.transfer_frame(self.udp_socket.socket.rx_buffer(), self.read_pointer, false, &mut buffer)); + self.read_pointer += 1; + match result { + Ok(_) => Some(Ok(buffer[0])), + Result::Err(error) => Some(Err(error)), + } } }