github.com/20yyq/packet@v0.1.4-0.20231013092308-386a004a3baa/can/frame.go (about) 1 // @@ 2 // @ Author : Eacher 3 // @ Date : 2023-09-06 10:48:53 4 // @ LastEditTime : 2023-09-11 08:01:05 5 // @ LastEditors : Eacher 6 // @ --------------------------------------------------------------------------------< 7 // @ Description : 8 // @ --------------------------------------------------------------------------------< 9 // @ FilePath : /20yyq/packet/can/frame.go 10 // @@ 11 package can 12 13 import ( 14 "fmt" 15 "unsafe" 16 ) 17 18 const ( 19 // SocketCAN frame 最大 bytes 长度 20 CanFrameLength = 0x10 21 // SocketCAN frame 数据最大 bytes 长度 22 CanDataLength = 0x08 23 // SocketCANFD frame 最大 bytes 长度 24 CanFDFrameLength= 0x48 25 // SocketCANFD frame 数据最大 bytes 长度 26 CanFDDataLength = 0x40 27 28 FlagExtended= 0x80000000 29 FlagRemote = 0x40000000 30 FlagError = 0x20000000 31 MaxExtended = 0x1FFFFFFF 32 MaxStandard = 0x7FF 33 ) 34 35 func NewCanFrame(b [CanFrameLength]byte) (f Frame) { 36 f = *(*Frame)(unsafe.Pointer(&b[0])) 37 f.initAttr() 38 return 39 } 40 41 func NewCanFDFrame(b [CanFDFrameLength]byte) (f Frame) { 42 f = *(*Frame)(unsafe.Pointer(&b[0])) 43 f.CanFd = true 44 f.initAttr() 45 return 46 } 47 48 // 来源 https://www.kernel.org/doc/Documentation/networking/can.txt 49 // 50 // The struct canfd_frame is defined in include/linux/can.h: 51 52 // struct canfd_frame { 53 // canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ 54 // __u8 len; /* frame payload length in byte (0 .. 64) */ 55 // __u8 flags; /* additional flags for CAN FD */ 56 // __u8 __res0; /* reserved / padding */ 57 // __u8 __res1; /* reserved / padding */ 58 // __u8 data[64] __attribute__((aligned(8))); 59 // }; 60 type Frame struct { 61 id uint32 62 Len uint8 63 Flags uint8 64 Res0 uint8 65 Res1 uint8 66 Data [CanFDDataLength]byte 67 68 CanFd bool 69 Extended bool 70 Remote bool 71 Error bool 72 } 73 74 func (f *Frame) initAttr() { 75 f.Extended = f.id & FlagExtended > 0 76 f.Error = f.id & FlagError > 0 77 f.Remote = f.id & FlagRemote > 0 78 } 79 80 func (f *Frame) SetID(id uint32) error { 81 if id > MaxExtended { 82 return fmt.Errorf("invalid extended Can id: %v does not fit in 29 bits", id) 83 } 84 f.id = id 85 if f.Extended { 86 f.id |= FlagExtended 87 } else if f.id > MaxStandard { 88 return fmt.Errorf("invalid standard Can id: %v does not fit in 11 bits", id) 89 } 90 if f.Error { 91 f.id |= FlagError 92 } 93 if f.Remote { 94 f.id |= FlagRemote 95 } 96 return nil 97 } 98 99 func (f Frame) ID() uint32 { 100 if f.id & FlagExtended > 0 || f.id & FlagRemote > 0 || f.id & FlagError > 0 { 101 return f.id & MaxExtended 102 } 103 return f.id & MaxStandard 104 } 105 106 func (f Frame) WireFormat() []byte { 107 var b [CanFDFrameLength]byte 108 *(*uint32)(unsafe.Pointer(&b[0])) = f.id 109 b[4], b[5], b[6], b[7] = f.Len, f.Flags, f.Res0, f.Res1 110 if f.CanFd { 111 *(*[CanFDDataLength]byte)(b[8:]) = f.Data 112 return b[:] 113 } 114 *(*[CanDataLength]byte)(b[8:]) = ([CanDataLength]byte)(f.Data[:]) 115 return b[:CanFrameLength] 116 } 117 118 func (f Frame) String() string { 119 format := "%d\t%-4X\t[%d]\t% -24X\t%s\t%d\t%d\t%d\n" 120 return fmt.Sprintf(format, f.id, f.ID(), f.Len, f.Data[:f.Len], f.Data[:f.Len], f.Flags, f.Res0, f.Res1) 121 }