use std::{error::Error, fmt};
use byteorder::{ByteOrder, NativeEndian};
use netlink_packet_core::{
NetlinkDeserializable, NetlinkHeader, NetlinkPayload,
NetlinkSerializable,
};
#[cfg(test)]
mod test;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ConnectorId {
idx: u32,
value: u32
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ConnectorMessage {
id: ConnectorId,
seq: u32,
ack: u32,
flags: u16,
data: Vec<u8>,
}
impl ConnectorMessage {
pub fn new(idx: u32, value: u32, seq: u32, ack: u32, flags: u16, data: Vec<u8>) -> Self {
ConnectorMessage {
id: ConnectorId { idx, value },
seq,
ack,
flags,
data,
}
}
pub fn idx(&self) -> u32 {
self.id.idx
}
pub fn value(&self) -> u32 {
self.id.value
}
pub fn seq(&self) -> u32 {
self.seq
}
pub fn ack(&self) -> u32 {
self.ack
}
pub fn flags(&self) -> u16 {
self.flags
}
pub fn data(&self) -> &[u8] {
&self.data
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DeserializeError(&'static str);
impl Error for DeserializeError {
fn description(&self) -> &str {
self.0
}
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
impl fmt::Display for DeserializeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl NetlinkDeserializable for ConnectorMessage {
type Error = DeserializeError;
fn deserialize(
_header: &NetlinkHeader,
payload: &[u8],
) -> Result<Self, Self::Error> {
let idx: u32 = NativeEndian::read_u32(&payload[0..4]);
let value: u32 = NativeEndian::read_u32(&payload[4..8]);
let seq: u32 = NativeEndian::read_u32(&payload[8..12]);
let ack: u32 = NativeEndian::read_u32(&payload[12..16]);
let len: u16 = NativeEndian::read_u16(&payload[16..18]);
let flags: u16 = NativeEndian::read_u16(&payload[18..20]);
let data = &payload[20..];
if (data.len() as i16 - len as i16) < 0 || (data.len() as u16 - len) > 4 {
return Err(DeserializeError("Invalid data length"));
}
Ok(ConnectorMessage {
id: ConnectorId { idx, value },
seq,
ack,
flags,
data: data[0..len as usize].to_vec(),
})
}
}
impl NetlinkSerializable for ConnectorMessage {
fn message_type(&self) -> u16 {
0
}
fn buffer_len(&self) -> usize {
20 + self.data.len()
}
fn serialize(&self, buffer: &mut [u8]) {
NativeEndian::write_u32(&mut buffer[0..4], self.id.idx);
NativeEndian::write_u32(&mut buffer[4..8], self.id.value);
NativeEndian::write_u32(&mut buffer[8..12], self.seq);
NativeEndian::write_u32(&mut buffer[12..16], self.ack);
NativeEndian::write_u16(&mut buffer[16..18], self.data.len() as u16);
NativeEndian::write_u16(&mut buffer[18..20], self.flags);
buffer[20..].copy_from_slice(&self.data);
}
}
impl From<ConnectorMessage> for NetlinkPayload<ConnectorMessage> {
fn from(message: ConnectorMessage) -> Self {
NetlinkPayload::InnerMessage(message)
}
}