#![allow(non_camel_case_types, unused)]
use crate::{as_bytes, as_bytes_mut};
use libc::{c_char, c_uint};
use neli::{
consts::rtnl::{RtaType, RtaTypeWrapper},
err::{DeError, SerError},
impl_trait, neli_enum, FromBytes, Size, ToBytes,
};
use std::{
io::{self, Cursor, Read, Write},
mem,
mem::size_of,
};
pub const EXT_FILTER_VF: c_uint = 1 << 0;
pub const EXT_FILTER_BRVLAN: c_uint = 1 << 1;
pub const EXT_FILTER_BRVLAN_COMPRESSED: c_uint = 1 << 2;
pub const EXT_FILTER_SKIP_STATS: c_uint = 1 << 3;
pub const EXT_FILTER_MRP: c_uint = 1 << 4;
pub const EXT_FILTER_CFM_CONFIG: c_uint = 1 << 5;
pub const EXT_FILTER_CFM_STATUS: c_uint = 1 << 6;
pub const EXT_FILTER_MST: c_uint = 1 << 7;
#[repr(C)]
#[derive(Debug, Default, Clone, Copy, FromBytes, ToBytes, Size)]
pub struct can_bittiming {
pub bitrate: u32, pub sample_point: u32, pub tq: u32, pub prop_seg: u32, pub phase_seg1: u32, pub phase_seg2: u32, pub sjw: u32, pub brp: u32, }
#[repr(C)]
#[derive(Debug, Default, Clone, Copy)]
pub struct can_bittiming_const {
pub name: [c_char; 16], pub tseg1_min: u32, pub tseg1_max: u32,
pub tseg2_min: u32, pub tseg2_max: u32,
pub sjw_max: u32, pub brp_min: u32, pub brp_max: u32,
pub brp_inc: u32,
}
impl ToBytes for can_bittiming_const {
fn to_bytes(&self, buf: &mut Cursor<Vec<u8>>) -> Result<(), SerError> {
buf.write_all(as_bytes(self))?;
Ok(())
}
}
impl<'a> FromBytes<'a> for can_bittiming_const {
fn from_bytes(buf: &mut Cursor<&'a [u8]>) -> Result<Self, DeError> {
let mut timing_const: can_bittiming_const = unsafe { mem::zeroed() };
buf.read_exact(as_bytes_mut(&mut timing_const))?;
Ok(timing_const)
}
}
impl Size for can_bittiming_const {
fn unpadded_size(&self) -> usize {
size_of::<can_bittiming_const>()
}
}
#[repr(C)]
#[derive(Debug, Default, Clone, Copy, FromBytes, ToBytes, Size)]
pub struct can_clock {
pub freq: u32, }
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CanState {
ErrorActive,
ErrorWarning,
ErrorPassive,
BusOff,
Stopped,
Sleeping,
}
impl TryFrom<u32> for CanState {
type Error = io::Error;
fn try_from(val: u32) -> Result<Self, Self::Error> {
use CanState::*;
match val {
0 => Ok(ErrorActive),
1 => Ok(ErrorWarning),
2 => Ok(ErrorPassive),
3 => Ok(BusOff),
4 => Ok(Stopped),
5 => Ok(Sleeping),
_ => Err(io::Error::from(io::ErrorKind::InvalidData)),
}
}
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, FromBytes, ToBytes, Size)]
pub struct can_berr_counter {
pub txerr: u16,
pub rxerr: u16,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, FromBytes, ToBytes, Size)]
pub struct can_ctrlmode {
pub mask: u32,
pub flags: u32,
}
pub const CAN_CTRLMODE_LOOPBACK: u32 = 0x01;
pub const CAN_CTRLMODE_LISTENONLY: u32 = 0x02;
pub const CAN_CTRLMODE_3_SAMPLES: u32 = 0x04;
pub const CAN_CTRLMODE_ONE_SHOT: u32 = 0x08;
pub const CAN_CTRLMODE_BERR_REPORTING: u32 = 0x10;
pub const CAN_CTRLMODE_FD: u32 = 0x20;
pub const CAN_CTRLMODE_PRESUME_ACK: u32 = 0x40;
pub const CAN_CTRLMODE_FD_NON_ISO: u32 = 0x80;
pub const CAN_CTRLMODE_CC_LEN8_DLC: u32 = 0x100;
pub const CAN_TERMINATION_DISABLED: u32 = 0;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, FromBytes)]
pub struct can_device_stats {
pub bus_error: u32, pub error_warning: u32, pub error_passive: u32, pub bus_off: u32, pub arbitration_lost: u32, pub restarts: u32, }
pub const IFLA_CAN_UNSPEC: u16 = 0;
pub const IFLA_CAN_BITTIMING: u16 = 1;
pub const IFLA_CAN_BITTIMING_CONST: u16 = 2;
pub const IFLA_CAN_CLOCK: u16 = 3;
pub const IFLA_CAN_STATE: u16 = 4;
pub const IFLA_CAN_CTRLMODE: u16 = 5;
pub const IFLA_CAN_RESTART_MS: u16 = 6;
pub const IFLA_CAN_RESTART: u16 = 7;
pub const IFLA_CAN_BERR_COUNTER: u16 = 8;
pub const IFLA_CAN_DATA_BITTIMING: u16 = 9;
pub const IFLA_CAN_DATA_BITTIMING_CONST: u16 = 10;
pub const IFLA_CAN_TERMINATION: u16 = 11;
pub const IFLA_CAN_TERMINATION_CONST: u16 = 12;
pub const IFLA_CAN_BITRATE_CONST: u16 = 13;
pub const IFLA_CAN_DATA_BITRATE_CONST: u16 = 14;
pub const IFLA_CAN_BITRATE_MAX: u16 = 15;
pub const IFLA_CAN_TDC: u16 = 16;
pub const IFLA_CAN_CTRLMODE_EXT: u16 = 17;
#[neli_enum(serialized_type = "libc::c_ushort")]
pub enum IflaCan {
Unspec = IFLA_CAN_UNSPEC,
BitTiming = IFLA_CAN_BITTIMING,
BitTimingConst = IFLA_CAN_BITTIMING_CONST,
Clock = IFLA_CAN_CLOCK,
State = IFLA_CAN_STATE,
CtrlMode = IFLA_CAN_CTRLMODE,
RestartMs = IFLA_CAN_RESTART_MS,
Restart = IFLA_CAN_RESTART,
BerrCounter = IFLA_CAN_BERR_COUNTER,
DataBitTiming = IFLA_CAN_DATA_BITTIMING,
DataBitTimingConst = IFLA_CAN_DATA_BITTIMING_CONST,
Termination = IFLA_CAN_TERMINATION,
TerminationConst = IFLA_CAN_TERMINATION_CONST,
BitRateConst = IFLA_CAN_BITRATE_CONST,
DataBitRateConst = IFLA_CAN_DATA_BITRATE_CONST,
BitRateMax = IFLA_CAN_BITRATE_MAX,
Tdc = IFLA_CAN_TDC,
CtrlModeExt = IFLA_CAN_CTRLMODE_EXT,
}
impl RtaType for IflaCan {}
#[cfg(test)]
pub mod tests {
use super::*;
#[test]
fn test_as_bytes() {
let bitrate = 500000;
let sample_point = 750;
let timing = can_bittiming {
bitrate,
sample_point,
..can_bittiming::default()
};
assert_eq!(
unsafe {
std::slice::from_raw_parts::<'_, u8>(
&timing as *const _ as *const u8,
size_of::<can_bittiming>(),
)
},
as_bytes(&timing)
);
}
}