@@ -21,8 +21,50 @@ const MCTP_I2C_HEADER: usize = 4;
2121// bytecount is limited to u8, includes MCTP payload + 1 byte i2c source
2222pub const MCTP_I2C_MAXMTU : usize = u8:: MAX as usize - 1 ;
2323
24- type MctpI2cHeader =
25- libmctp:: smbus_proto:: MCTPSMBusHeader < [ u8 ; MCTP_I2C_HEADER ] > ;
24+ pub struct MctpI2cHeader {
25+ pub dest : u8 ,
26+ pub source : u8 ,
27+ pub byte_count : usize ,
28+ }
29+
30+ impl MctpI2cHeader {
31+ fn encode ( & self ) -> Result < [ u8 ; 4 ] > {
32+ if self . dest > 0x7f || self . source > 0x7f {
33+ return Err ( Error :: BadArgument ) ;
34+ }
35+ if self . byte_count > u8:: MAX as usize {
36+ return Err ( Error :: BadArgument ) ;
37+ }
38+ Ok ( [
39+ self . dest << 1 ,
40+ MCTP_I2C_COMMAND_CODE ,
41+ self . byte_count as u8 ,
42+ self . source << 1 | 1 ,
43+ ] )
44+ }
45+
46+ fn decode ( pkt : & [ u8 ] ) -> Result < Self > {
47+ let [ dest, cmd, byte_count, source] =
48+ pkt. try_into ( ) . map_err ( |_| Error :: BadArgument ) ?;
49+ if dest & 1 != 0 {
50+ trace ! ( "Bad i2c dest write bit" ) ;
51+ return Err ( Error :: InvalidInput ) ;
52+ }
53+ if cmd != MCTP_I2C_COMMAND_CODE {
54+ trace ! ( "Bad i2c command code" ) ;
55+ return Err ( Error :: InvalidInput ) ;
56+ }
57+ if source & 1 != 1 {
58+ trace ! ( "Bad i2c source read bit" ) ;
59+ return Err ( Error :: InvalidInput ) ;
60+ }
61+ Ok ( Self {
62+ dest,
63+ source,
64+ byte_count : byte_count as usize ,
65+ } )
66+ }
67+ }
2668
2769/// Simple packet processing to add/remove the 4 byte MCTP-I2C header.
2870#[ derive( Debug , Clone ) ]
@@ -58,22 +100,13 @@ impl MctpI2cEncap {
58100 }
59101 }
60102
61- if packet. len ( ) < MCTP_I2C_HEADER {
62- return Err ( Error :: InvalidInput ) ;
63- }
64-
65- let ( i2c, packet) = packet. split_at ( MCTP_I2C_HEADER ) ;
66- // OK unwrap, size matches
67- let header = MctpI2cHeader :: new_from_buf ( i2c. try_into ( ) . unwrap ( ) ) ;
103+ let header = MctpI2cHeader :: decode ( packet) ?;
68104 // +1 for i2c source address field
69- if header. byte_count ( ) as usize != packet. len ( ) + 1 {
105+ if header. byte_count != packet. len ( ) + 1 {
70106 return Err ( Error :: InvalidInput ) ;
71107 }
72108
73- if header. command_code ( ) != MCTP_I2C_COMMAND_CODE {
74- return Err ( Error :: InvalidInput ) ;
75- }
76- Ok ( ( packet, header. source_slave_addr ( ) ) )
109+ Ok ( ( & packet[ MCTP_I2C_HEADER ..] , header. source ) )
77110 }
78111
79112 /// Handles a MCTP fragment with the PEC already validated
@@ -120,16 +153,18 @@ impl MctpI2cEncap {
120153 }
121154 } ;
122155
123- // Write the i2c header and return the whole packet
124- let mut header = MctpI2cHeader :: new ( ) ;
125- header. set_dest_slave_addr ( i2c_dest) ;
126- header. set_source_slave_addr ( self . own_addr ) ;
127- header. set_source_read_write ( 1 ) ;
128- header. set_command_code ( MCTP_I2C_COMMAND_CODE ) ;
129156 debug_assert ! ( packet. len( ) <= MCTP_I2C_MAXMTU ) ;
130- header. set_byte_count ( ( packet. len ( ) + 1 ) as u8 ) ;
157+ // Write the i2c header and return the whole packet
158+ let header = MctpI2cHeader {
159+ source : self . own_addr ,
160+ dest : i2c_dest,
161+ byte_count : packet. len ( ) + 1 ,
162+ } ;
131163
132- i2chead. copy_from_slice ( & header. 0 ) ;
164+ match header. encode ( ) {
165+ Ok ( h) => i2chead. copy_from_slice ( & h) ,
166+ Err ( e) => return SendOutput :: failure ( e, fragmenter) ,
167+ }
133168
134169 let out_len = MCTP_I2C_HEADER + packet. len ( ) ;
135170 let out = & mut out[ ..out_len] ;
@@ -153,14 +188,14 @@ impl MctpI2cEncap {
153188 }
154189
155190 let ( i2chead, packet) = out. split_at_mut ( MCTP_I2C_HEADER ) ;
156- let mut header = MctpI2cHeader :: new ( ) ;
157- header. set_dest_slave_addr ( i2c_dest ) ;
158- header . set_source_slave_addr ( self . own_addr ) ;
159- header . set_source_read_write ( 1 ) ;
160- header . set_command_code ( MCTP_I2C_COMMAND_CODE ) ;
161- // Include i2c source address byte in bytecount. No PEC.
162- header . set_byte_count ( ( 1 + inp . len ( ) ) as u8 ) ;
163- i2chead. copy_from_slice ( & header. 0 ) ;
191+ // Write the i2c header and return the whole packet
192+ let header = MctpI2cHeader {
193+ source : self . own_addr ,
194+ dest : i2c_dest ,
195+ // Include i2c source address byte in bytecount. No PEC.
196+ byte_count : inp . len ( ) + 1 ,
197+ } ;
198+ i2chead. copy_from_slice ( & header. encode ( ) ? ) ;
164199 packet[ ..inp. len ( ) ] . copy_from_slice ( inp) ;
165200
166201 if pec {
0 commit comments