@@ -1028,6 +1028,10 @@ impl AsRef<can_frame> for CanErrorFrame {
10281028///
10291029/// This is highly compatible with the `canfd_frame` from libc.
10301030/// ([ref](https://docs.rs/libc/latest/libc/struct.canfd_frame.html))
1031+ ///
1032+ /// Payload data that is greater than 8 bytes and whose data length does
1033+ /// not match a valid CANFD data length is padded with 0 bytes to the
1034+ /// next higher valid CANFD data length.
10311035#[ derive( Clone , Copy ) ]
10321036pub struct CanFdFrame ( canfd_frame ) ;
10331037
@@ -1048,9 +1052,20 @@ impl CanFdFrame {
10481052 nif n <=CANFD_MAX_DLEN =>{
10491053let mut frame =canfd_frame_default ( ) ;
10501054 frame. can_id = can_id;
1051- frame. len = nas u8 ;
10521055 frame. flags = fd_flags. bits ( ) ;
1053- frame. data [ ..n] . copy_from_slice ( data) ;
1056+ if n >8 && !CanFdFrame :: is_valid_data_len ( n) {
1057+ // data must be 0 padded to the next valid DataLength
1058+ let new_len =CanFdFrame :: next_valid_ext_dlen ( n) ;
1059+ let mut padded_data: Vec < u8 > =Vec :: from ( data) ;
1060+ padded_data. resize ( new_len, 0 ) ;
1061+ frame. len = new_lenas u8 ;
1062+ frame. data [ ..new_len] . copy_from_slice ( & padded_data) ;
1063+ } else {
1064+ // payload length is a valid CANFD data length so no padding is required
1065+ frame. len = nas u8 ;
1066+ frame. data [ ..n] . copy_from_slice ( data) ;
1067+ }
1068+
10541069Ok ( Self ( frame) )
10551070}
10561071 _ =>Err ( ConstructionError :: TooMuchData ) ,
@@ -1093,6 +1108,28 @@ impl CanFdFrame {
10931108self . 0 . flags &= !CANFD_ESI as u8 ;
10941109}
10951110}
1111+
1112+ /// Checks whether a given length is a valid CANFD data length.
1113+ ///
1114+ /// Valid values are `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`,
1115+ /// `12`, `16`, `20`, `24`, `32`, `48` or `64`.
1116+ fn is_valid_data_len ( len : usize ) ->bool {
1117+ ( 0 ..=8 ) . contains ( & len) ||[ 12 , 16 , 20 , 24 , 32 , 48 , 64 ] . contains ( & len)
1118+ }
1119+
1120+ /// Returns the next larger valid CANFD extended data length into which the given
1121+ /// length fits, up to a maximum of CANFD_MAX_DLEN.
1122+ fn next_valid_ext_dlen ( len : usize ) ->usize {
1123+ let valid_ext_dlengths: [ usize ; 7 ] =[ 12 , 16 , 20 , 24 , 32 , 48 , 64 ] ;
1124+
1125+ for valid_ext_lenin valid_ext_dlengths{
1126+ if valid_ext_len >= len{
1127+ return valid_ext_len;
1128+ }
1129+ }
1130+ // return CANFD_MAX_DLEN if len > CANFD_MAX_DLEN
1131+ CANFD_MAX_DLEN
1132+ }
10961133}
10971134
10981135impl AsPtr for CanFdFrame {
@@ -1140,7 +1177,19 @@ impl EmbeddedFrame for CanFdFrame {
11401177
11411178/// Data length code
11421179fn dlc ( & self ) ->usize {
1143- self . 0 . len as usize
1180+ match self . 0 . len {
1181+ 0 ..=8 =>self . 0 . len as usize ,
1182+ 12 =>0x09 ,
1183+ 16 =>0x0A ,
1184+ 20 =>0x0B ,
1185+ 24 =>0x0C ,
1186+ 32 =>0x0D ,
1187+ 48 =>0x0E ,
1188+ 64 =>0x0F ,
1189+ // invalid data length, should never occur as the data is
1190+ // padded to a valid CANFD data length on frame creation
1191+ _ =>0x00 ,
1192+ }
11441193}
11451194
11461195/// A slice into the actual data.
@@ -1166,8 +1215,17 @@ impl Frame for CanFdFrame {
11661215fn set_data ( & mut self , data : & [ u8 ] ) ->Result < ( ) , ConstructionError > {
11671216match data. len ( ) {
11681217 nif n <=CANFD_MAX_DLEN =>{
1169- self . 0 . len = nas u8 ;
1170- self . 0 . data [ ..n] . copy_from_slice ( data) ;
1218+ if n >8 && !CanFdFrame :: is_valid_data_len ( n) {
1219+ // data must be 0 padded to the next valid DataLength
1220+ let new_len =CanFdFrame :: next_valid_ext_dlen ( n) ;
1221+ let mut padded_data: Vec < u8 > =Vec :: from ( data) ;
1222+ padded_data. resize ( new_len, 0 ) ;
1223+ self . 0 . len = new_lenas u8 ;
1224+ self . 0 . data [ ..new_len] . copy_from_slice ( & padded_data) ;
1225+ } else {
1226+ self . 0 . len = nas u8 ;
1227+ self . 0 . data [ ..n] . copy_from_slice ( data) ;
1228+ }
11711229Ok ( ( ) )
11721230}
11731231 _ =>Err ( ConstructionError :: TooMuchData ) ,
@@ -1238,6 +1296,16 @@ mod tests {
12381296const DATA : & [ u8 ] =& [ 0 , 1 , 2 , 3 ] ;
12391297const DATA_LEN : usize =DATA . len ( ) ;
12401298
1299+ const EXT_DATA : & [ u8 ] =& [ 0xAB ; 32 ] ;
1300+ const EXT_DATA_DLC : usize =0x0D ;
1301+
1302+ const EXT_DATA_INVALID_DLEN : & [ u8 ] =
1303+ & [ 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xAA ] ;
1304+ const EXT_DATA_PADDED : & [ u8 ] =& [
1305+ 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xAA , 0x00 , 0x00 ,
1306+ ] ;
1307+ const EXT_DATA_PADDED_DLC : usize =0x09 ;
1308+
12411309const EMPTY_DATA : & [ u8 ] =& [ ] ;
12421310const ZERO_DATA : & [ u8 ] =& [ 0u8 ; DATA_LEN ] ;
12431311
@@ -1479,6 +1547,17 @@ mod tests {
14791547assert_eq ! ( EXT_LOW_ID , frame. id( ) ) ;
14801548assert ! ( !frame. is_standard( ) ) ;
14811549assert ! ( frame. is_extended( ) ) ;
1550+
1551+ let mut frame =CanFdFrame :: new ( STD_ID , EXT_DATA ) . unwrap ( ) ;
1552+ assert_eq ! ( frame. dlc( ) , EXT_DATA_DLC ) ;
1553+ assert_eq ! ( frame. data( ) , EXT_DATA ) ;
1554+ frame. set_data ( EXT_DATA_INVALID_DLEN ) . unwrap ( ) ;
1555+ assert_eq ! ( frame. data( ) , EXT_DATA_PADDED ) ;
1556+ assert_eq ! ( frame. dlc( ) , EXT_DATA_PADDED_DLC ) ;
1557+
1558+ let frame =CanFdFrame :: new ( STD_ID , EXT_DATA_INVALID_DLEN ) . unwrap ( ) ;
1559+ assert_eq ! ( frame. data( ) , EXT_DATA_PADDED ) ;
1560+ assert_eq ! ( frame. dlc( ) , EXT_DATA_PADDED_DLC ) ;
14821561}
14831562
14841563#[ test]