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) }