Add constructors for network types.
This commit is contained in:
parent
979e750e89
commit
cbb3468893
2 changed files with 166 additions and 81 deletions
103
src/lib.rs
103
src/lib.rs
|
|
@ -4,6 +4,9 @@
|
||||||
#[macro_use(block)]
|
#[macro_use(block)]
|
||||||
extern crate nb;
|
extern crate nb;
|
||||||
|
|
||||||
|
pub mod net;
|
||||||
|
pub use net::{Ipv4Addr, MacAddress};
|
||||||
|
|
||||||
use byteorder::BigEndian;
|
use byteorder::BigEndian;
|
||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
|
|
@ -20,65 +23,6 @@ const FIXED_DATA_LENGTH_2_BYTES: u8 = 0b_10;
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
const FIXED_DATA_LENGTH_4_BYTES: u8 = 0b_11;
|
const FIXED_DATA_LENGTH_4_BYTES: u8 = 0b_11;
|
||||||
|
|
||||||
/// IP Address struct. Represents an IP address as a u8 array of length 4.
|
|
||||||
/// Can be instantiated with [`IpAddress::new`]
|
|
||||||
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Default, Debug)]
|
|
||||||
pub struct IpAddress {
|
|
||||||
pub address: [u8; 4],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IpAddress {
|
|
||||||
/// Instantiate a new IP address with u8s for each address fragment
|
|
||||||
pub fn new(a0: u8, a1: u8, a2: u8, a3: u8) -> IpAddress {
|
|
||||||
IpAddress {
|
|
||||||
address: [a0, a1, a2, a3],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::core::fmt::Display for IpAddress {
|
|
||||||
/// String formatter for IP addresses, useful for debugging output
|
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}.{}.{}.{}",
|
|
||||||
self.address[0], self.address[1], self.address[2], self.address[3],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// MAC address struct. Represents a MAC address as a u8 array of length 6.
|
|
||||||
/// Can be instantiated with [`MacAddress::new`]
|
|
||||||
#[derive(Copy, Clone, PartialOrd, PartialEq, Default, Debug)]
|
|
||||||
pub struct MacAddress {
|
|
||||||
pub address: [u8; 6],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MacAddress {
|
|
||||||
/// Instantiate a new MAC address with u8s for each address fragment
|
|
||||||
pub fn new(a0: u8, a1: u8, a2: u8, a3: u8, a4: u8, a5: u8) -> MacAddress {
|
|
||||||
MacAddress {
|
|
||||||
address: [a0, a1, a2, a3, a4, a5],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::core::fmt::Display for MacAddress {
|
|
||||||
/// String formatter for MAC addresses, useful for debugging output
|
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
|
|
||||||
self.address[0],
|
|
||||||
self.address[1],
|
|
||||||
self.address[2],
|
|
||||||
self.address[3],
|
|
||||||
self.address[4],
|
|
||||||
self.address[5],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error enum that represents the union between SPI hardware errors and digital IO pin errors.
|
/// Error enum that represents the union between SPI hardware errors and digital IO pin errors.
|
||||||
/// Returned as an Error type by many [`ActiveW5500`] operations that talk to the chip
|
/// Returned as an Error type by many [`ActiveW5500`] operations that talk to the chip
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
@ -240,17 +184,17 @@ impl<
|
||||||
/// Sets the IP address of the network gateway (your router's address)
|
/// Sets the IP address of the network gateway (your router's address)
|
||||||
pub fn set_gateway(
|
pub fn set_gateway(
|
||||||
&mut self,
|
&mut self,
|
||||||
gateway: IpAddress,
|
gateway: Ipv4Addr,
|
||||||
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
||||||
self.write_to(Register::CommonRegister(0x00_01_u16), &gateway.address)
|
self.write_to(Register::CommonRegister(0x00_01_u16), &gateway.octets)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the subnet on the network (for example 255.255.255.0 for /24 subnets)
|
/// Sets the subnet on the network (for example 255.255.255.0 for /24 subnets)
|
||||||
pub fn set_subnet(
|
pub fn set_subnet(
|
||||||
&mut self,
|
&mut self,
|
||||||
subnet: IpAddress,
|
subnet: Ipv4Addr,
|
||||||
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
||||||
self.write_to(Register::CommonRegister(0x00_05_u16), &subnet.address)
|
self.write_to(Register::CommonRegister(0x00_05_u16), &subnet.octets)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the MAC address of the W5500 device on the network.
|
/// Sets the MAC address of the W5500 device on the network.
|
||||||
|
|
@ -271,25 +215,22 @@ impl<
|
||||||
&mut self,
|
&mut self,
|
||||||
mac: MacAddress,
|
mac: MacAddress,
|
||||||
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
||||||
self.write_to(Register::CommonRegister(0x00_09_u16), &mac.address)
|
self.write_to(Register::CommonRegister(0x00_09_u16), &mac.octets)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the IP address of the W5500 device. Must be within the range and permitted by the
|
/// Sets the IP address of the W5500 device. Must be within the range and permitted by the
|
||||||
/// gateway or the device will not be accessible.
|
/// gateway or the device will not be accessible.
|
||||||
pub fn set_ip(
|
pub fn set_ip(&mut self, ip: Ipv4Addr) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
||||||
&mut self,
|
self.write_to(Register::CommonRegister(0x00_0F_u16), &ip.octets)
|
||||||
ip: IpAddress,
|
|
||||||
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
|
|
||||||
self.write_to(Register::CommonRegister(0x00_0F_u16), &ip.address)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the 4 bytes from any ip register and returns the value as an [`IpAddress`]
|
/// Reads the 4 bytes from any ip register and returns the value as an [`Ipv4Addr`]
|
||||||
pub fn read_ip(
|
pub fn read_ip(
|
||||||
&mut self,
|
&mut self,
|
||||||
register: Register,
|
register: Register,
|
||||||
) -> Result<IpAddress, TransferError<SpiError, ChipSelectError>> {
|
) -> Result<Ipv4Addr, TransferError<SpiError, ChipSelectError>> {
|
||||||
let mut ip = IpAddress::default();
|
let mut ip = Ipv4Addr::default();
|
||||||
self.read_from(register, &mut ip.address)?;
|
self.read_from(register, &mut ip.octets)?;
|
||||||
Ok(ip)
|
Ok(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,11 +449,11 @@ pub trait Udp {
|
||||||
fn receive(
|
fn receive(
|
||||||
&mut self,
|
&mut self,
|
||||||
target_buffer: &mut [u8],
|
target_buffer: &mut [u8],
|
||||||
) -> Result<Option<(IpAddress, u16, usize)>, Self::Error>;
|
) -> Result<Option<(Ipv4Addr, u16, usize)>, Self::Error>;
|
||||||
|
|
||||||
fn blocking_send(
|
fn blocking_send(
|
||||||
&mut self,
|
&mut self,
|
||||||
host: &IpAddress,
|
host: &Ipv4Addr,
|
||||||
host_port: u16,
|
host_port: u16,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
|
|
@ -528,7 +469,7 @@ impl<ChipSelect: OutputPin, Spi: FullDuplex<u8>> Udp
|
||||||
fn receive(
|
fn receive(
|
||||||
&mut self,
|
&mut self,
|
||||||
destination: &mut [u8],
|
destination: &mut [u8],
|
||||||
) -> Result<Option<(IpAddress, u16, usize)>, Self::Error> {
|
) -> Result<Option<(Ipv4Addr, u16, usize)>, Self::Error> {
|
||||||
let (w5500, UdpSocket(socket)) = self;
|
let (w5500, UdpSocket(socket)) = self;
|
||||||
|
|
||||||
if w5500.read_u8(socket.at(SocketRegister::InterruptMask))? & 0x04 == 0 {
|
if w5500.read_u8(socket.at(SocketRegister::InterruptMask))? & 0x04 == 0 {
|
||||||
|
|
@ -579,7 +520,7 @@ impl<ChipSelect: OutputPin, Spi: FullDuplex<u8>> Udp
|
||||||
/// Sends a UDP packet to the specified IP and port, and blocks until it is fully sent
|
/// Sends a UDP packet to the specified IP and port, and blocks until it is fully sent
|
||||||
fn blocking_send(
|
fn blocking_send(
|
||||||
&mut self,
|
&mut self,
|
||||||
host: &IpAddress,
|
host: &Ipv4Addr,
|
||||||
host_port: u16,
|
host_port: u16,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
|
|
@ -601,10 +542,10 @@ impl<ChipSelect: OutputPin, Spi: FullDuplex<u8>> Udp
|
||||||
0x00,
|
0x00,
|
||||||
0x00,
|
0x00,
|
||||||
0x00, // destination mac
|
0x00, // destination mac
|
||||||
host.address[0],
|
host.octets[0],
|
||||||
host.address[1],
|
host.octets[1],
|
||||||
host.address[2],
|
host.octets[2],
|
||||||
host.address[3], // target IP
|
host.octets[3], // target IP
|
||||||
host_port[0],
|
host_port[0],
|
||||||
host_port[1], // destination port (5354)
|
host_port[1], // destination port (5354)
|
||||||
],
|
],
|
||||||
|
|
|
||||||
144
src/net.rs
Normal file
144
src/net.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
//! Networking data types.
|
||||||
|
//!
|
||||||
|
//! There may a standard for embedded networking in the future, see
|
||||||
|
//! [rust-embedded issue 348] and [RFC 2832]
|
||||||
|
//!
|
||||||
|
//! This is mostly ripped directly from [std::net].
|
||||||
|
//!
|
||||||
|
//! [rust-embedded issue 348]: https://github.com/rust-embedded/wg/issues/348
|
||||||
|
//! [std::net]: https://doc.rust-lang.org/std/net/index.html
|
||||||
|
//! [RFC 2832]: https://github.com/rust-lang/rfcs/pull/2832
|
||||||
|
#![deny(unsafe_code, missing_docs, warnings)]
|
||||||
|
|
||||||
|
/// Ipv4Addr address struct. Can be instantiated with `Ipv4Addr::new`.
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
|
||||||
|
pub struct Ipv4Addr {
|
||||||
|
/// Octets of the Ipv4Addr address.
|
||||||
|
pub octets: [u8; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ipv4Addr {
|
||||||
|
/// Creates a new IPv4 address from four eight-bit octets.
|
||||||
|
///
|
||||||
|
/// The result will represent the IP address `a`.`b`.`c`.`d`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use w5500::net::Ipv4Addr;
|
||||||
|
///
|
||||||
|
/// let addr = Ipv4Addr::new(127, 0, 0, 1);
|
||||||
|
/// ```
|
||||||
|
#[allow(clippy::many_single_char_names)]
|
||||||
|
pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
|
||||||
|
Ipv4Addr {
|
||||||
|
octets: [a, b, c, d],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An IPv4 address with the address pointing to localhost: 127.0.0.1.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use w5500::net::Ipv4Addr;
|
||||||
|
///
|
||||||
|
/// let addr = Ipv4Addr::LOCALHOST;
|
||||||
|
/// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1));
|
||||||
|
/// ```
|
||||||
|
pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
|
||||||
|
|
||||||
|
/// An IPv4 address representing an unspecified address: 0.0.0.0
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use w5500::net::Ipv4Addr;
|
||||||
|
///
|
||||||
|
/// let addr = Ipv4Addr::UNSPECIFIED;
|
||||||
|
/// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0));
|
||||||
|
/// ```
|
||||||
|
pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);
|
||||||
|
|
||||||
|
/// An IPv4 address representing the broadcast address: 255.255.255.255
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use w5500::net::Ipv4Addr;
|
||||||
|
///
|
||||||
|
/// let addr = Ipv4Addr::BROADCAST;
|
||||||
|
/// assert_eq!(addr, Ipv4Addr::new(255, 255, 255, 255));
|
||||||
|
/// ```
|
||||||
|
pub const BROADCAST: Self = Ipv4Addr::new(255, 255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::core::fmt::Display for Ipv4Addr {
|
||||||
|
/// String formatter for Ipv4Addr addresses.
|
||||||
|
fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
|
write!(
|
||||||
|
fmt,
|
||||||
|
"{}.{}.{}.{}",
|
||||||
|
self.octets[0], self.octets[1], self.octets[2], self.octets[3],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MAC address struct. Can be instantiated with `MacAddress::new`.
|
||||||
|
///
|
||||||
|
/// This is an EUI-48 MAC address (previously called MAC-48).
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash, Default)]
|
||||||
|
pub struct MacAddress {
|
||||||
|
/// Octets of the MAC address.
|
||||||
|
pub octets: [u8; 6],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MacAddress {
|
||||||
|
/// Creates a new EUI-48 MAC address from six eight-bit octets.
|
||||||
|
///
|
||||||
|
/// The result will represent the EUI-48 MAC address
|
||||||
|
/// `a`:`b`:`c`:`d`:`e`:`f`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use w5500::net::MacAddress;
|
||||||
|
///
|
||||||
|
/// let addr = MacAddress::new(0x00, 0x00, 0x5E, 0x00, 0x00, 0x00);
|
||||||
|
/// ```
|
||||||
|
#[allow(clippy::many_single_char_names)]
|
||||||
|
pub const fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> MacAddress {
|
||||||
|
MacAddress {
|
||||||
|
octets: [a, b, c, d, e, f],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An EUI-48 MAC address representing an unspecified address:
|
||||||
|
/// 00:00:00:00:00:00
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use w5500::net::MacAddress;
|
||||||
|
///
|
||||||
|
/// let addr = MacAddress::UNSPECIFIED;
|
||||||
|
/// assert_eq!(addr, MacAddress::new(0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
|
||||||
|
/// ```
|
||||||
|
pub const UNSPECIFIED: Self = MacAddress::new(0, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::core::fmt::Display for MacAddress {
|
||||||
|
/// String formatter for MacAddress addresses.
|
||||||
|
fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
|
write!(
|
||||||
|
fmt,
|
||||||
|
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
|
||||||
|
self.octets[0],
|
||||||
|
self.octets[1],
|
||||||
|
self.octets[2],
|
||||||
|
self.octets[3],
|
||||||
|
self.octets[4],
|
||||||
|
self.octets[5],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue