Skip to content

Commit

Permalink
can-rs: explicitly check number of received can bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
TheButlah committed May 7, 2024
1 parent ce6dc8d commit be23237
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
34 changes: 21 additions & 13 deletions can/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,23 +143,23 @@ impl<const N: usize> FrameStream<N> {
self.recv(&mut frame, flags).map(|_| frame)
}

pub fn recv(&self, frame: &mut Frame<N>, flags: c_int) -> io::Result<usize> {
pub fn recv(&self, frame: &mut Frame<N>, flags: c_int) -> io::Result<()> {
let mut raw = RawFrame::empty();
let size = imp::recv_from(self.as_raw_fd(), &mut raw, flags, Empty)?;
imp::recv_from(self.as_raw_fd(), &mut raw, flags, Empty)?;
let _ = std::mem::replace(frame, raw.into());
Ok(size)
Ok(())
}

pub fn recv_from(
&self,
frame: &mut Frame<N>,
flags: c_int,
src_addr: &mut CanAddr,
) -> io::Result<usize> {
) -> io::Result<()> {
let mut raw = RawFrame::empty();
let size = imp::recv_from(self.as_raw_fd(), &mut raw, flags, SetMut(src_addr))?;
imp::recv_from(self.as_raw_fd(), &mut raw, flags, SetMut(src_addr))?;
let _ = std::mem::replace(frame, raw.into());
Ok(size)
Ok(())
}

pub fn send(&self, frame: &Frame<N>, flags: c_int) -> io::Result<usize> {
Expand Down Expand Up @@ -354,7 +354,7 @@ mod imp {
}

impl<const N: usize> RawFrame<N> {
pub(crate) fn empty() -> Self {
pub(crate) const fn empty() -> Self {
Self {
id: 0,
len: 0,
Expand Down Expand Up @@ -416,21 +416,29 @@ mod imp {
frame: &mut RawFrame<N>,
flags: libc::c_int,
src_addr: T,
) -> io::Result<usize> {
) -> io::Result<()> {
let (addr, addrlen) = src_addr.to_recv_from_arguments();
let ret = unsafe {
let nbytes = unsafe {
libc::recvfrom(
fd.as_raw_fd(),
(frame as *mut RawFrame<N>) as *mut libc::c_void,
std::mem::size_of::<RawFrame<N>>(),
std::ptr::from_mut(frame).cast::<libc::c_void>(),
std::mem::size_of::<RawFrame<{ N }>>(),
flags,
addr,
addrlen,
)
};
if ret < 0 {
if nbytes < 0 {
return Err(io::Error::last_os_error());
} else if nbytes as usize != std::mem::size_of::<RawFrame<{ N }>>() {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
format!(
"the number of bytes read was {nbytes}, but we expected {}",
std::mem::size_of::<RawFrame<{ N }>>()
),
));
}
Ok(ret as usize)
Ok(())
}
}
10 changes: 4 additions & 6 deletions can/tests/integration/frame_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn send_and_receive_check_identical_can_frame() -> Result<(), Error> {
.bind(can_address())?;

let mut frame = Frame::empty();
let size = stream.recv(&mut frame, 0)?;
stream.recv(&mut frame, 0)?;
tx.send((frame, size)).unwrap();
Ok(())
});
Expand All @@ -62,7 +62,7 @@ fn send_and_receive_check_identical_can_frame() -> Result<(), Error> {
};

let stream = FrameStream::<CAN_DATA_LEN>::build().bind(can_address())?;
let size = stream.send(&frame, 0)?;
stream.send(&frame, 0)?;

thread::sleep(std::time::Duration::from_millis(1));

Expand All @@ -71,7 +71,6 @@ fn send_and_receive_check_identical_can_frame() -> Result<(), Error> {
assert_eq!(frame, recv_frame);
assert_eq!(frame.len, CAN_DATA_LEN as u8);
assert_eq!(frame.id, Id::Standard(id));
assert_eq!(size, recv_size);

receiving_thread.join().unwrap()?;
Ok(())
Expand All @@ -91,7 +90,7 @@ fn send_and_receive_check_identical_canfd_frame() -> Result<(), Error> {
.bind(canfd_address())?;

let mut frame = Frame::empty();
let size = stream.recv(&mut frame, 0)?;
stream.recv(&mut frame, 0)?;
tx.send((frame, size)).unwrap();
Ok(())
});
Expand All @@ -106,7 +105,7 @@ fn send_and_receive_check_identical_canfd_frame() -> Result<(), Error> {
data: [16u8; CANFD_DATA_LEN],
};
let stream = FrameStream::<CANFD_DATA_LEN>::build().bind(canfd_address())?;
let size = stream.send(&frame, 0)?;
stream.send(&frame, 0)?;

thread::sleep(std::time::Duration::from_millis(1));

Expand All @@ -115,7 +114,6 @@ fn send_and_receive_check_identical_canfd_frame() -> Result<(), Error> {
assert_eq!(frame, recv_frame);
assert_eq!(frame.len, CANFD_DATA_LEN as u8);
assert_eq!(frame.id, Id::Standard(id));
assert_eq!(size, recv_size);

receiving_thread.join().unwrap()?;
Ok(())
Expand Down

0 comments on commit be23237

Please sign in to comment.