123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package packets
- import (
- "bytes"
- "fmt"
- "github.com/pborman/uuid"
- "io"
- )
- //ConnectPacket is an internal representation of the fields of the
- //Connect MQTT packet
- type ConnectPacket struct {
- FixedHeader
- ProtocolName string
- ProtocolVersion byte
- CleanSession bool
- WillFlag bool
- WillQos byte
- WillRetain bool
- UsernameFlag bool
- PasswordFlag bool
- ReservedBit byte
- KeepaliveTimer uint16
- ClientIdentifier string
- WillTopic string
- WillMessage []byte
- Username string
- Password []byte
- uuid uuid.UUID
- }
- func (c *ConnectPacket) String() string {
- str := fmt.Sprintf("%s\n", c.FixedHeader)
- str += fmt.Sprintf("protocolversion: %d protocolname: %s cleansession: %t willflag: %t WillQos: %d WillRetain: %t Usernameflag: %t Passwordflag: %t keepalivetimer: %d\nclientId: %s\nwilltopic: %s\nwillmessage: %s\nUsername: %s\nPassword: %s\n", c.ProtocolVersion, c.ProtocolName, c.CleanSession, c.WillFlag, c.WillQos, c.WillRetain, c.UsernameFlag, c.PasswordFlag, c.KeepaliveTimer, c.ClientIdentifier, c.WillTopic, c.WillMessage, c.Username, c.Password)
- return str
- }
- func (c *ConnectPacket) Write(w io.Writer) error {
- var body bytes.Buffer
- var err error
- body.Write(encodeString(c.ProtocolName))
- body.WriteByte(c.ProtocolVersion)
- body.WriteByte(boolToByte(c.CleanSession)<<1 | boolToByte(c.WillFlag)<<2 | c.WillQos<<3 | boolToByte(c.WillRetain)<<5 | boolToByte(c.PasswordFlag)<<6 | boolToByte(c.UsernameFlag)<<7)
- body.Write(encodeUint16(c.KeepaliveTimer))
- body.Write(encodeString(c.ClientIdentifier))
- if c.WillFlag {
- body.Write(encodeString(c.WillTopic))
- body.Write(encodeBytes(c.WillMessage))
- }
- if c.UsernameFlag {
- body.Write(encodeString(c.Username))
- }
- if c.PasswordFlag {
- body.Write(encodeBytes(c.Password))
- }
- c.FixedHeader.RemainingLength = body.Len()
- packet := c.FixedHeader.pack()
- packet.Write(body.Bytes())
- _, err = packet.WriteTo(w)
- return err
- }
- //Unpack decodes the details of a ControlPacket after the fixed
- //header has been read
- func (c *ConnectPacket) Unpack(b io.Reader) {
- c.ProtocolName = decodeString(b)
- c.ProtocolVersion = decodeByte(b)
- options := decodeByte(b)
- c.ReservedBit = 1 & options
- c.CleanSession = 1&(options>>1) > 0
- c.WillFlag = 1&(options>>2) > 0
- c.WillQos = 3 & (options >> 3)
- c.WillRetain = 1&(options>>5) > 0
- c.PasswordFlag = 1&(options>>6) > 0
- c.UsernameFlag = 1&(options>>7) > 0
- c.KeepaliveTimer = decodeUint16(b)
- c.ClientIdentifier = decodeString(b)
- if c.WillFlag {
- c.WillTopic = decodeString(b)
- c.WillMessage = decodeBytes(b)
- }
- if c.UsernameFlag {
- c.Username = decodeString(b)
- }
- if c.PasswordFlag {
- c.Password = decodeBytes(b)
- }
- }
- //Validate performs validation of the fields of a Connect packet
- func (c *ConnectPacket) Validate() byte {
- if c.PasswordFlag && !c.UsernameFlag {
- return ErrRefusedBadUsernameOrPassword
- }
- if c.ReservedBit != 0 {
- //Bad reserved bit
- return ErrProtocolViolation
- }
- if (c.ProtocolName == "MQIsdp" && c.ProtocolVersion != 3) || (c.ProtocolName == "MQTT" && c.ProtocolVersion != 4) {
- //Mismatched or unsupported protocol version
- return ErrRefusedBadProtocolVersion
- }
- if c.ProtocolName != "MQIsdp" && c.ProtocolName != "MQTT" {
- //Bad protocol name
- return ErrProtocolViolation
- }
- if len(c.ClientIdentifier) > 65535 || len(c.Username) > 65535 || len(c.Password) > 65535 {
- //Bad size field
- return ErrProtocolViolation
- }
- return Accepted
- }
- //Details returns a Details struct containing the Qos and
- //MessageID of this ControlPacket
- func (c *ConnectPacket) Details() Details {
- return Details{Qos: 0, MessageID: 0}
- }
- //UUID returns the unique ID assigned to the ControlPacket when
- //it was originally received. Note: this is not related to the
- //MessageID field for MQTT packets
- func (c *ConnectPacket) UUID() uuid.UUID {
- return c.uuid
- }
|