gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/ipc/cgo/smp/packet.go (about)

     1  package smp
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  )
     7  
     8  const (
     9  	minPacketLength = 16
    10  	maxPacketLength = 32
    11  )
    12  
    13  const magicCode = 0x20230805
    14  
    15  type Command uint16
    16  
    17  const (
    18  	CommandAllocRequest = Command(iota) + 1
    19  )
    20  
    21  const (
    22  	CommandAllocResponse = Command(iota) + 1<<15
    23  )
    24  
    25  type (
    26  	InvalidPacketLength  int
    27  	InvalidPacketMagic   uint64
    28  	InvalidPacketCommand Command
    29  )
    30  
    31  func (e InvalidPacketLength) Error() string {
    32  	return fmt.Sprintf("invalid packet length: %d", int(e))
    33  }
    34  
    35  func (e InvalidPacketMagic) Error() string {
    36  	return fmt.Sprintf("invalid packet magic code: %08x", uint32(e))
    37  }
    38  
    39  func (e InvalidPacketCommand) Error() string {
    40  	return fmt.Sprintf("invalid packet command: %d", uint16(e))
    41  }
    42  
    43  type BasePacket struct {
    44  	magic   uint32
    45  	command Command
    46  	seq     uint16
    47  }
    48  
    49  func (p *BasePacket) Unmarshal(data []byte) (error, ErrType) {
    50  	if len(data) < minPacketLength || len(data) > maxPacketLength {
    51  		return InvalidPacketLength(len(data)), ErrTypePacketInvalidLength
    52  	}
    53  	p.magic = binary.BigEndian.Uint32(data)
    54  	if p.magic != magicCode {
    55  		return InvalidPacketMagic(p.magic), ErrTypePacketInvalidMagic
    56  	}
    57  	p.command = Command(binary.BigEndian.Uint16(data[4:]))
    58  	if p.command < CommandAllocRequest || (p.command > CommandAllocRequest &&
    59  		p.command < CommandAllocResponse) || p.command > CommandAllocResponse {
    60  		return InvalidPacketCommand(p.command), ErrTypePacketInvalidCommand
    61  	}
    62  	p.seq = binary.BigEndian.Uint16(data[6:])
    63  	return nil, 0
    64  }
    65  
    66  type AllocRequest struct {
    67  	BasePacket
    68  	flags uint32
    69  	size  uint32
    70  }
    71  
    72  func (r *AllocRequest) Unmarshal(data []byte) (error, ErrType) {
    73  	if len(data) < minPacketLength+8 {
    74  		return InvalidPacketLength(len(data)), ErrTypePacketInvalidLength
    75  	}
    76  	r.flags = binary.BigEndian.Uint32(data[minPacketLength:])
    77  	r.size = binary.BigEndian.Uint32(data[minPacketLength+4:])
    78  	return nil, 0
    79  }
    80  
    81  func (r *AllocRequest) Reuse() bool {
    82  	return r.flags&1 != 0
    83  }
    84  
    85  func (r *AllocRequest) Size() uint32 {
    86  	return r.size
    87  }
    88  
    89  const (
    90  	ResponseOk = 0
    91  )
    92  
    93  type BaseResponse struct {
    94  	BasePacket
    95  	status uint32
    96  }
    97  
    98  func (r *AllocResponse) Unmarshal(data []byte) (error, ErrType) {
    99  	if len(data) < minPacketLength+4 {
   100  		return InvalidPacketLength(len(data)), ErrTypePacketInvalidLength
   101  	}
   102  	r.status = binary.BigEndian.Uint32(data[minPacketLength:])
   103  	return nil, 0
   104  }
   105  
   106  func (r *BaseResponse) Status() uint32 {
   107  	return r.status
   108  }
   109  
   110  type AllocResponse struct {
   111  	BaseResponse
   112  }