use crate::protocol::{
self, ReadBytes, ReadBytesExt, ReadFromBytes, SizeBytes, WriteBytes, WriteBytesExt,
WriteToBytes, LE,
};
use std::ffi::CString;
use std::{io, mem};
pub const OLD_BROADCAST_PORT: u16 = 4810;
pub const MULTICAST_PORT: u16 = 4809;
pub const OLD_MULTICAST_ADDR: [u8; 4] = [224, 0, 0, 180];
pub const MULTICAST_ADDR: [u8; 4] = [239, 224, 0, 180];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Header {
pub citp_header: protocol::Header,
pub content_type: u32,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Message<T> {
pub pinf_header: Header,
pub message: T,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct PNam {
pub name: CString,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct PLoc {
pub listening_tcp_port: u16,
pub kind: CString,
pub name: CString,
pub state: CString,
}
impl Header {
pub const CONTENT_TYPE: &'static [u8; 4] = b"PINF";
}
impl PNam {
pub const CONTENT_TYPE: &'static [u8; 4] = b"PNam";
}
impl PLoc {
pub const CONTENT_TYPE: &'static [u8; 4] = b"PLoc";
}
impl WriteToBytes for Header {
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_bytes(self.citp_header)?;
writer.write_u32::<LE>(self.content_type)?;
Ok(())
}
}
impl<T> WriteToBytes for Message<T>
where
T: WriteToBytes,
{
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_bytes(self.pinf_header)?;
writer.write_bytes(&self.message)?;
Ok(())
}
}
impl WriteToBytes for PNam {
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_bytes(&self.name)?;
Ok(())
}
}
impl WriteToBytes for PLoc {
fn write_to_bytes<W: WriteBytesExt>(&self, mut writer: W) -> io::Result<()> {
writer.write_u16::<LE>(self.listening_tcp_port)?;
writer.write_bytes(&self.kind)?;
writer.write_bytes(&self.name)?;
writer.write_bytes(&self.state)?;
Ok(())
}
}
impl ReadFromBytes for PNam {
fn read_from_bytes<R: ReadBytesExt>(mut reader: R) -> io::Result<Self> {
let name = reader.read_bytes()?;
let pnam = PNam { name };
Ok(pnam)
}
}
impl ReadFromBytes for PLoc {
fn read_from_bytes<R: ReadBytesExt>(mut reader: R) -> io::Result<Self> {
let listening_tcp_port = reader.read_u16::<LE>()?;
let kind = reader.read_bytes()?;
let name = reader.read_bytes()?;
let state = reader.read_bytes()?;
let ploc = PLoc {
listening_tcp_port,
kind,
name,
state,
};
Ok(ploc)
}
}
impl SizeBytes for PNam {
fn size_bytes(&self) -> usize {
self.name.size_bytes()
}
}
impl SizeBytes for PLoc {
fn size_bytes(&self) -> usize {
mem::size_of::<u16>()
+ self.kind.size_bytes()
+ self.name.size_bytes()
+ self.state.size_bytes()
}
}