-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathresponse.go
57 lines (48 loc) · 1.61 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package messagix
import (
"bytes"
"encoding/binary"
"fmt"
"github.com/0xzer/messagix/byter"
"github.com/0xzer/messagix/packets"
)
type ResponseData interface {
Finish() ResponseData
SetIdentifier(identifier int16)
}
type responseHandler func() (ResponseData)
var responseMap = map[uint8]responseHandler{
packets.CONNACK: func() ResponseData {return &Event_Ready{}},
packets.PUBACK: func() ResponseData {return &Event_PublishACK{}},
packets.SUBACK: func() ResponseData {return &Event_SubscribeACK{}},
packets.PUBLISH: func() ResponseData {return &Event_PublishResponse{}},
packets.PINGRESP: func () ResponseData {return &Event_PingResp{}},
}
type Response struct {
PacketByte uint8
RemainingLength uint32 `vlq:"true"`
ResponseData ResponseData
}
func (r *Response) Read(data []byte) error {
reader := byter.NewReader(data)
if err := reader.ReadToStruct(r); err != nil {
return err
}
packetType := r.PacketByte >> 4 // parse the packet type by the leftmost 4 bits
qosLevel := (r.PacketByte >> 1) & 0x03
responseHandlerFunc, ok := responseMap[packetType]
if !ok {
return fmt.Errorf("could not find response func handler for packet type %d", packetType)
}
r.ResponseData = responseHandlerFunc()
bufferBytes := reader.Buff.Bytes()
if packetType == packets.PUBLISH && qosLevel == 1 {
identifierBytes := bufferBytes[10:12]
identifier := binary.BigEndian.Uint16(identifierBytes)
r.ResponseData.SetIdentifier(int16(identifier))
// remove the msg identifier
bufferBytes = append(bufferBytes[:10], bufferBytes[12:]...)
reader.Buff = bytes.NewBuffer(bufferBytes)
}
return reader.ReadToStruct(r.ResponseData)
}