105 lines
3.8 KiB
Go
105 lines
3.8 KiB
Go
|
package packets
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"bytes"
|
||
|
"errors"
|
||
|
"io"
|
||
|
|
||
|
"badat.dev/maeqtt/v2/mqtt/properties"
|
||
|
)
|
||
|
|
||
|
type DisconnectReasonCode byte
|
||
|
|
||
|
const (
|
||
|
DisconnectReasonCodeNormal DisconnectReasonCode = 0
|
||
|
DisconnectReasonCodeWithWill DisconnectReasonCode = 0
|
||
|
DisconnectReasonCodeUnspecified = 128
|
||
|
DisconnectReasonCodeMalformedPacket = 129
|
||
|
DisconnectReasonCodeProtocolError = 130
|
||
|
DisconnectReasonCodeImplErorr = 131
|
||
|
DisconnectReasonCodeNotAuthorized = 135
|
||
|
DisconnectReasonCodeServerBusy = 137
|
||
|
DisconnectReasonServerShuttingDown = 139
|
||
|
DisconnectReasonCodeKeepAliveTimeout = 141
|
||
|
DisconnectReasonCodeSessionTakenOver = 142
|
||
|
DisconnectReasonCodeTopicFilterInvalid = 143
|
||
|
DisconnectReasonCodeTopicNameInvalid = 144
|
||
|
DisconnectReasonCodeReceiveMaxiumExceeded = 147
|
||
|
DisconnectReasonCodeTopicAliasInvalid = 148
|
||
|
DisconnectReasonCodePacketTooLarge = 149
|
||
|
DisconnectReasonCodeMessageRateTooHigh = 150
|
||
|
DisconnectReasonCodeQuotaExceeded = 151
|
||
|
DisconnectReasonCodeAdminiAction = 152
|
||
|
DisconnectReasonCodePayloadFormatInvalid = 153
|
||
|
DisconnectReasonCodeRetainNotSupported = 154
|
||
|
DisconnectReasonCodeQoSNotSupported = 155
|
||
|
DisconnectReasonCodeUseAnotherServer = 156
|
||
|
DisconnectReasonCodeServerMoved = 157
|
||
|
DisconnectReasonCodeSharedSubscriptionNotSupported = 158
|
||
|
DisconnectReasonCodeConnectionRateExceeded = 159
|
||
|
DisconnectReasonCodeMaximumConnectTime = 160
|
||
|
DisconnectReasonCodeSubscriptionIdNotSupported = 161
|
||
|
DisconnectReasonCodeWildcardSubscriptionNotSupported = 162
|
||
|
)
|
||
|
|
||
|
type DisconnectPacket struct {
|
||
|
ReasonCode DisconnectReasonCode
|
||
|
Properties properties.DisconnectPacketProperties
|
||
|
}
|
||
|
|
||
|
func parseDisconnectPacket(control controlPacket) (DisconnectPacket, error) {
|
||
|
packet := DisconnectPacket{}
|
||
|
|
||
|
if control.packetType != PacketTypeDisconnect {
|
||
|
panic("Wrong packet type for parseDisconnect")
|
||
|
}
|
||
|
if control.flags != 0 {
|
||
|
return packet, errors.New("Malformed disconnect packet")
|
||
|
}
|
||
|
|
||
|
r := bufio.NewReader(control.reader)
|
||
|
|
||
|
|
||
|
// If there is less then a byte in the reader assume the reason code == 0
|
||
|
reason,err := r.ReadByte()
|
||
|
if err == io.EOF {
|
||
|
reason = 0
|
||
|
} else if err != nil {
|
||
|
return packet, err
|
||
|
}
|
||
|
packet.ReasonCode = DisconnectReasonCode(reason)
|
||
|
|
||
|
// If there are less than 2 bytes remaining in the reader assume that the packet has no properties
|
||
|
_, err = r.Peek(2)
|
||
|
if err == nil {
|
||
|
err = properties.ParseProperties(r,packet.Properties.ArrayOf())
|
||
|
} else if err != io.EOF {
|
||
|
return packet, err
|
||
|
} else if err == io.EOF {
|
||
|
err = nil
|
||
|
}
|
||
|
|
||
|
return packet, err
|
||
|
}
|
||
|
|
||
|
func (p DisconnectPacket) Write(w io.Writer) error {
|
||
|
buf := bytes.NewBuffer([]byte{})
|
||
|
buf.WriteByte(byte(p.ReasonCode))
|
||
|
err := properties.WriteProps(w, p.Properties.ArrayOf())
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
control := controlPacket {
|
||
|
packetType: PacketTypeDisconnect,
|
||
|
flags: 0,
|
||
|
reader: buf,
|
||
|
}
|
||
|
return control.write(w)
|
||
|
}
|
||
|
|
||
|
func (p DisconnectPacket) visit(v PacketVisitor) {
|
||
|
v.visitDisconnect(p)
|
||
|
}
|