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  }