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 }