mirror of
https://github.com/fhmq/hmq.git
synced 2026-04-27 03:58:33 +00:00
169 lines
4.0 KiB
Go
Executable File
169 lines
4.0 KiB
Go
Executable File
// Copyright (c) 2014 The SurgeMQ Authors. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package message
|
|
|
|
import "fmt"
|
|
|
|
// The CONNACK Packet is the packet sent by the Server in response to a CONNECT Packet
|
|
// received from a Client. The first packet sent from the Server to the Client MUST
|
|
// be a CONNACK Packet [MQTT-3.2.0-1].
|
|
//
|
|
// If the Client does not receive a CONNACK Packet from the Server within a reasonable
|
|
// amount of time, the Client SHOULD close the Network Connection. A "reasonable" amount
|
|
// of time depends on the type of application and the communications infrastructure.
|
|
type ConnackMessage struct {
|
|
header
|
|
|
|
sessionPresent bool
|
|
returnCode ConnackCode
|
|
}
|
|
|
|
var _ Message = (*ConnackMessage)(nil)
|
|
|
|
// NewConnackMessage creates a new CONNACK message
|
|
func NewConnackMessage() *ConnackMessage {
|
|
msg := &ConnackMessage{}
|
|
msg.SetType(CONNACK)
|
|
|
|
return msg
|
|
}
|
|
|
|
// String returns a string representation of the CONNACK message
|
|
func (this ConnackMessage) String() string {
|
|
return fmt.Sprintf("%s, Session Present=%t, Return code=%q\n", this.header, this.sessionPresent, this.returnCode)
|
|
}
|
|
|
|
// SessionPresent returns the session present flag value
|
|
func (this *ConnackMessage) SessionPresent() bool {
|
|
return this.sessionPresent
|
|
}
|
|
|
|
// SetSessionPresent sets the value of the session present flag
|
|
func (this *ConnackMessage) SetSessionPresent(v bool) {
|
|
if v {
|
|
this.sessionPresent = true
|
|
} else {
|
|
this.sessionPresent = false
|
|
}
|
|
|
|
this.dirty = true
|
|
}
|
|
|
|
// ReturnCode returns the return code received for the CONNECT message. The return
|
|
// type is an error
|
|
func (this *ConnackMessage) ReturnCode() ConnackCode {
|
|
return this.returnCode
|
|
}
|
|
|
|
func (this *ConnackMessage) SetReturnCode(ret ConnackCode) {
|
|
this.returnCode = ret
|
|
this.dirty = true
|
|
}
|
|
|
|
func (this *ConnackMessage) Len() int {
|
|
if !this.dirty {
|
|
return len(this.dbuf)
|
|
}
|
|
|
|
ml := this.msglen()
|
|
|
|
if err := this.SetRemainingLength(int32(ml)); err != nil {
|
|
return 0
|
|
}
|
|
|
|
return this.header.msglen() + ml
|
|
}
|
|
|
|
func (this *ConnackMessage) Decode(src []byte) (int, error) {
|
|
total := 0
|
|
|
|
n, err := this.header.decode(src)
|
|
total += n
|
|
if err != nil {
|
|
return total, err
|
|
}
|
|
|
|
b := src[total]
|
|
|
|
if b&254 != 0 {
|
|
return 0, fmt.Errorf("connack/Decode: Bits 7-1 in Connack Acknowledge Flags byte (1) are not 0")
|
|
}
|
|
|
|
this.sessionPresent = b&0x1 == 1
|
|
total++
|
|
|
|
b = src[total]
|
|
|
|
// Read return code
|
|
if b > 5 {
|
|
return 0, fmt.Errorf("connack/Decode: Invalid CONNACK return code (%d)", b)
|
|
}
|
|
|
|
this.returnCode = ConnackCode(b)
|
|
total++
|
|
|
|
this.dirty = false
|
|
|
|
return total, nil
|
|
}
|
|
|
|
func (this *ConnackMessage) Encode(dst []byte) (int, error) {
|
|
if !this.dirty {
|
|
if len(dst) < len(this.dbuf) {
|
|
return 0, fmt.Errorf("connack/Encode: Insufficient buffer size. Expecting %d, got %d.", len(this.dbuf), len(dst))
|
|
}
|
|
|
|
return copy(dst, this.dbuf), nil
|
|
}
|
|
|
|
// CONNACK remaining length fixed at 2 bytes
|
|
hl := this.header.msglen()
|
|
ml := this.msglen()
|
|
|
|
if len(dst) < hl+ml {
|
|
return 0, fmt.Errorf("connack/Encode: Insufficient buffer size. Expecting %d, got %d.", hl+ml, len(dst))
|
|
}
|
|
|
|
if err := this.SetRemainingLength(int32(ml)); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
total := 0
|
|
|
|
n, err := this.header.encode(dst[total:])
|
|
total += n
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if this.sessionPresent {
|
|
dst[total] = 1
|
|
}
|
|
total++
|
|
|
|
if this.returnCode > 5 {
|
|
return total, fmt.Errorf("connack/Encode: Invalid CONNACK return code (%d)", this.returnCode)
|
|
}
|
|
|
|
dst[total] = this.returnCode.Value()
|
|
total++
|
|
|
|
return total, nil
|
|
}
|
|
|
|
func (this *ConnackMessage) msglen() int {
|
|
return 2
|
|
}
|