Fleshed out packet receipt

This commit is contained in:
Jonah Dahlquist 2019-09-10 20:43:26 -05:00 committed by Jonah Dahlquist
commit 423d2f6401
4 changed files with 68 additions and 46 deletions

View file

@ -46,6 +46,11 @@ pub mod socketn {
pub enum Protocol { pub enum Protocol {
Udp = 0b10u8, Udp = 0b10u8,
} }
pub const COMMAND: u16 = 0x01;
#[repr(u8)]
pub enum Command {
Receive = 0x40,
}
pub const INTERRUPT: u16 = 0x02; pub const INTERRUPT: u16 = 0x02;
#[repr(u8)] #[repr(u8)]
@ -62,5 +67,6 @@ pub mod socketn {
pub const RECEIVED_SIZE: u16 = 0x26; 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;
} }

View file

@ -46,14 +46,28 @@ pub trait Socket {
Ok(data[0] & socketn::interrupt_mask::RECEIVE != 0) Ok(data[0] & socketn::interrupt_mask::RECEIVE != 0)
} }
fn get_packet_address<SpiBus: ActiveBus>( fn get_rx_read_pointer<SpiBus: ActiveBus>(
&self, &self,
bus: &mut SpiBus, bus: &mut SpiBus,
) -> Result<u16, SpiBus::Error> { ) -> Result<u16, SpiBus::Error> {
let mut data = [0u8; 2]; 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)) Ok(BigEndian::read_u16(&data))
} }
fn set_rx_read_pointer<SpiBus: ActiveBus>(&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<SpiBus: ActiveBus>(&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 = ( pub type OwnedSockets = (

View file

@ -1,16 +1,13 @@
mod inactive_udp_socket; mod inactive_udp_socket;
mod packet; mod packet;
use byteorder::{BigEndian, ByteOrder};
use crate::IpAddress;
use crate::bus::ActiveBus; use crate::bus::ActiveBus;
use crate::network::Network; use crate::network::Network;
use crate::socket::OwnedSockets; use crate::socket::{Socket, OwnedSockets};
use crate::socket::Socket;
use crate::udp::inactive_udp_socket::InactiveUdpSocket; use crate::udp::inactive_udp_socket::InactiveUdpSocket;
use crate::w5500::W5500;
use crate::udp::packet::UdpPacket; 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> { pub struct UdpSocket<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> {
bus: SpiBus, bus: SpiBus,
@ -51,18 +48,6 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
} }
} }
fn block_until_receive_size_known(&mut self) -> Result<u16, SpiBus::Error> {
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 // /// Sends a UDP packet to the specified IP and port, and blocks until it is sent
// fn blocking_send( // fn blocking_send(
// &mut self, // &mut self,

View file

@ -1,34 +1,35 @@
use byteorder::{BigEndian, ByteOrder};
use crate::udp::UdpSocket; use crate::udp::UdpSocket;
use crate::network::Network; use crate::network::Network;
use crate::bus::ActiveBus; use crate::bus::ActiveBus;
use crate::socket::Socket; use crate::socket::Socket;
use crate::IpAddress; use crate::IpAddress;
use byteorder::{BigEndian, ByteOrder}; use crate::register::socketn;
pub struct UdpPacket<UdpSocket> { pub struct UdpPacket<UdpSocket> {
udp_socket: UdpSocket, udp_socket: UdpSocket,
address: IpAddress, address: IpAddress,
remote_port: u16, remote_port: u16,
size: u16,
read_pointer: u16, read_pointer: u16,
write_pointer: u16,
} }
impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>> impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>>
{ {
pub fn new(mut udp_socket: UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result<Self, SpiBus::Error> { pub fn new(mut udp_socket: UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result<Self, SpiBus::Error> {
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 -->| // |<-- read_pointer read_pointer + received_size -->|
// |Destination IP Address | Destination Port | Byte Size of DATA | Actual DATA ... | // |Destination IP Address | Destination Port | Byte Size of DATA | Actual DATA ... |
// | --- 4 Bytes --- | --- 2 Bytes --- | --- 2 Bytes --- | .... | // | --- 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]; let mut header = [0u8; 8];
block!(udp_socket.bus.transfer_frame(udp_socket.socket.rx_buffer(), read_pointer, false, &mut header))?; block!(udp_socket.bus.transfer_frame(udp_socket.socket.rx_buffer(), read_pointer, false, &mut header))?;
Ok(UdpPacket { Ok(UdpPacket {
udp_socket, udp_socket,
address: IpAddress::new(header[0], header[1], header[2], header[3]), address: IpAddress::new(header[0], header[1], header[2], header[3]),
remote_port: BigEndian::read_u16(&header[4..5]), remote_port: BigEndian::read_u16(&header[4..5]),
size: receive_size, read_pointer: read_pointer + 8,
read_pointer, write_pointer: read_pointer + receive_size,
}) })
} }
@ -40,27 +41,43 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket<
self.address self.address
} }
pub fn read(&self) { pub fn read(&mut self) -> Result<u8, SpiBus::Error> {
// TODO read a byte upon every invocation let mut buffer = [0u8];
// w5500.read_from( block!(self.udp_socket.bus.transfer_frame(self.udp_socket.socket.rx_buffer(), self.read_pointer, false, &mut buffer))?;
// socket.rx_register_at(read_pointer + 8), Ok(buffer[0])
// &mut destination[..data_length],
// )?;
} }
pub fn close(self) -> UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl> { pub fn done(mut self) -> Result<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>, SpiBus::Error> {
// TODO reset read pointer etc 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 fn block_until_receive_size_known(udp_socket: &mut UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result<u16, SpiBus::Error> {
// w5500.write_u16( loop {
// socket.at(SocketRegister::RxReadPointer), let mut sample_0 = [0u8; 2];
// read_pointer + receive_size as u16, block!(udp_socket.bus.transfer_frame(udp_socket.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_0))?;
// )?; let mut sample_1 = [0u8; 2];
// w5500.write_u8( block!(udp_socket.bus.transfer_frame(udp_socket.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_1))?;
// socket.at(SocketRegister::Command), if sample_0 == sample_1 && sample_0[0] >= 8 {
// SocketCommand::Recv as u8, break Ok(BigEndian::read_u16(&sample_0));
// )?; }
// TODO return Socket }
self.udp_socket }
}
impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> Iterator for UdpPacket<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>> {
type Item = Result<u8, SpiBus::Error>;
fn next(&mut self) -> Option<Self::Item> {
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)),
}
} }
} }