mod api;
mod constant;
mod constants;
mod driver;
mod frame;
pub use self::{constants::*, driver::*, frame::*};
use rs_can::{CanDevice, CanFilter, CanResult, DeviceBuilder};
#[async_trait::async_trait]
impl CanDevice for NiCan {
type Channel = String;
type Frame = NiCanFrame;
fn new(builder: DeviceBuilder<String>) -> CanResult<Self> {
let libpath = builder.get_other::<String>(LIBPATH)?;
let mut device = NiCan::new(libpath.as_deref())?;
builder
.channel_configs()
.iter()
.try_for_each(|(chl, cfg)| {
let filters = cfg
.get_other::<Vec<CanFilter>>(FILTERS)?
.unwrap_or_default();
let bitrate = cfg.nominal_bitrate;
let log_error = cfg.get_other::<bool>(LOG_ERROR)?.unwrap_or_default();
device.open(chl, filters, bitrate, log_error)
})?;
Ok(device)
}
#[inline]
fn is_closed(&self) -> bool {
self.channels.is_empty()
}
#[inline]
fn opened_channels(&self) -> Vec<Self::Channel> {
self.channels.keys().map(|v| v.clone()).collect()
}
#[inline]
async fn transmit(&self, msg: Self::Frame, _: Option<u32>) -> CanResult<()> {
self.transmit_can(msg)
}
#[inline]
async fn receive(
&self,
channel: Self::Channel,
timeout: Option<u32>,
) -> CanResult<Vec<Self::Frame>> {
self.receive_can(channel, timeout)
}
#[inline]
fn shutdown(&mut self) {
self.channels.iter().for_each(|(c, ctx)| {
let ret = unsafe { (self.ncCloseObject)(ctx.handle) };
if let Err(e) = self.check_status(c, ret) {
rsutil::warn!(
"{} error {} when close",
Self::channel_info(c),
self.status_to_str(e)
);
}
});
self.channels.clear();
}
}