41
41
//! is available through the `AsRawFd`, `IntoRawFd` and `FromRawFd`
42
42
//! implementations.
43
43
44
-
45
-
46
44
// clippy: do not warn about things like "SocketCAN" inside the docs
47
45
#![ cfg_attr( feature = "cargo-clippy" , allow( doc_markdown) ) ]
48
46
49
47
extern crate byte_conv;
48
+ extern crate embedded_hal;
50
49
extern crate hex;
51
50
extern crate itertools;
52
51
extern crate libc;
52
+ extern crate nb;
53
53
extern crate neli;
54
54
extern crate nix;
55
55
extern crate try_from;
@@ -63,15 +63,17 @@ mod util;
63
63
#[ cfg( test) ]
64
64
mod tests;
65
65
66
- use libc:: { c_int, c_short, c_void, c_uint, c_ulong, socket, SOCK_RAW , close, bind, sockaddr, read,
67
- write, SOL_SOCKET , SO_RCVTIMEO , timespec, timeval, EINPROGRESS , SO_SNDTIMEO , time_t,
68
- suseconds_t, fcntl, F_GETFL , F_SETFL , O_NONBLOCK } ;
69
66
use itertools:: Itertools ;
67
+ use libc:: {
68
+ bind, c_int, c_short, c_uint, c_ulong, c_void, close, fcntl, read, sockaddr, socket,
69
+ suseconds_t, time_t, timespec, timeval, write, EINPROGRESS , F_GETFL , F_SETFL , O_NONBLOCK ,
70
+ SOCK_RAW , SOL_SOCKET , SO_RCVTIMEO , SO_SNDTIMEO ,
71
+ } ;
70
72
use nix:: net:: if_:: if_nametoindex;
71
73
pub use nl:: CanInterface ;
72
- use std:: { error, fmt, io, time} ;
73
74
use std:: mem:: { size_of, uninitialized} ;
74
75
use std:: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd , RawFd } ;
76
+ use std:: { error, fmt, io, time} ;
75
77
use util:: { set_socket_option, set_socket_option_mult} ;
76
78
77
79
/// Check an error return value for timeouts.
@@ -131,7 +133,6 @@ const CAN_RAW_RECV_OWN_MSGS: c_int = 4;
131
133
// const CAN_RAW_FD_FRAMES: c_int = 5;
132
134
const CAN_RAW_JOIN_FILTERS : c_int = 6 ;
133
135
134
-
135
136
// get timestamp in a struct timeval (us accuracy)
136
137
// const SIOCGSTAMP: c_int = 0x8906;
137
138
@@ -156,7 +157,6 @@ pub const EFF_MASK: u32 = 0x1fffffff;
156
157
/// valid bits in error frame
157
158
pub const ERR_MASK : u32 = 0x1fffffff ;
158
159
159
-
160
160
/// an error mask that will cause SocketCAN to report all errors
161
161
pub const ERR_MASK_ALL : u32 = ERR_MASK ;
162
162
@@ -214,7 +214,6 @@ impl error::Error for CanSocketOpenError {
214
214
}
215
215
}
216
216
217
-
218
217
#[ derive( Debug , Copy , Clone ) ]
219
218
/// Error that occurs when creating CAN packets
220
219
pub enum ConstructionError {
@@ -300,9 +299,11 @@ impl CanSocket {
300
299
let bind_rv;
301
300
unsafe {
302
301
let sockaddr_ptr = & addr as * const CanAddr ;
303
- bind_rv = bind ( sock_fd,
304
- sockaddr_ptr as * const sockaddr ,
305
- size_of :: < CanAddr > ( ) as u32 ) ;
302
+ bind_rv = bind (
303
+ sock_fd,
304
+ sockaddr_ptr as * const sockaddr ,
305
+ size_of :: < CanAddr > ( ) as u32 ,
306
+ ) ;
306
307
}
307
308
308
309
// FIXME: on fail, close socket (do not leak socketfds)
@@ -522,6 +523,23 @@ impl Drop for CanSocket {
522
523
}
523
524
}
524
525
526
+ impl embedded_hal:: can:: Transmitter for CanSocket {
527
+ type Frame = CanFrame ;
528
+ type Error = io:: Error ;
529
+ fn transmit (
530
+ & mut self ,
531
+ frame : & Self :: Frame ,
532
+ ) -> Result < Option < Self :: Frame > , nb:: Error < Self :: Error > > {
533
+ self . write_frame ( frame) . map ( |_| None ) . map_err ( |io_err| {
534
+ if io_err. kind ( ) == io:: ErrorKind :: WouldBlock {
535
+ nb:: Error :: WouldBlock
536
+ } else {
537
+ nb:: Error :: Other ( io_err)
538
+ }
539
+ } )
540
+ }
541
+ }
542
+
525
543
/// CanFrame
526
544
///
527
545
/// Uses the same memory layout as the underlying kernel struct for performance
@@ -565,7 +583,6 @@ impl CanFrame {
565
583
_id |= EFF_FLAG ;
566
584
}
567
585
568
-
569
586
if rtr {
570
587
_id |= RTR_FLAG ;
571
588
}
@@ -582,13 +599,13 @@ impl CanFrame {
582
599
}
583
600
584
601
Ok ( CanFrame {
585
- _id : _id,
586
- _data_len : data. len ( ) as u8 ,
587
- _pad : 0 ,
588
- _res0 : 0 ,
589
- _res1 : 0 ,
590
- _data : full_data,
591
- } )
602
+ _id : _id,
603
+ _data_len : data. len ( ) as u8 ,
604
+ _pad : 0 ,
605
+ _res0 : 0 ,
606
+ _res1 : 0 ,
607
+ _data : full_data,
608
+ } )
592
609
}
593
610
594
611
/// Return the actual CAN ID (without EFF/RTR/ERR flags)
@@ -656,6 +673,33 @@ impl fmt::UpperHex for CanFrame {
656
673
}
657
674
}
658
675
676
+ impl embedded_hal:: can:: Frame for CanFrame {
677
+ fn new_standard ( id : u32 , data : & [ u8 ] ) -> Self {
678
+ CanFrame :: new ( id, data, false , false ) . unwrap ( )
679
+ }
680
+ fn new_extended ( id : u32 , data : & [ u8 ] ) -> Self {
681
+ CanFrame :: new ( id, data, false , false ) . unwrap ( )
682
+ }
683
+ fn with_rtr ( & mut self , dlc : usize ) -> & mut Self {
684
+ unimplemented ! ( )
685
+ }
686
+ fn is_extended ( & self ) -> bool {
687
+ self . is_extended ( )
688
+ }
689
+ fn is_remote_frame ( & self ) -> bool {
690
+ self . is_rtr ( )
691
+ }
692
+ fn id ( & self ) -> u32 {
693
+ self . id ( )
694
+ }
695
+ fn dlc ( & self ) -> usize {
696
+ self . _data_len as usize
697
+ }
698
+ fn data ( & self ) -> & [ u8 ] {
699
+ self . data ( )
700
+ }
701
+ }
702
+
659
703
/// CanFilter
660
704
///
661
705
/// Contains an internal id and mask. Packets are considered to be matched by
@@ -671,8 +715,8 @@ impl CanFilter {
671
715
/// Construct a new CAN filter.
672
716
pub fn new ( id : u32 , mask : u32 ) -> Result < CanFilter , ConstructionError > {
673
717
Ok ( CanFilter {
674
- _id : id,
675
- _mask : mask,
676
- } )
718
+ _id : id,
719
+ _mask : mask,
720
+ } )
677
721
}
678
722
}
0 commit comments