maeqtt/mqtt/packets/Disconnect.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)
}