2021-08-26 15:08:24 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2021-09-28 12:30:32 +02:00
|
|
|
func (p DisconnectPacket) Visit(v PacketVisitor) {
|
|
|
|
v.VisitDisconnect(p)
|
2021-08-26 15:08:24 +02:00
|
|
|
}
|