Files
NixMsg/test/load/connect.go
T

154 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package load
import (
"bytes"
"fmt"
"io"
"github.com/mochi-mqtt/server/v2/packets"
)
const (
mqttProtocolLevel5 = 5
mqttKeepaliveSec = 30
)
// encodeConnect 按 DEVELOPMENT §5 生成 MQTT 5 CONNECT:
// ClientID=Username=端编号、CleanStart、心跳 30、会话过期间隔缺省为 0(Clean Start 时即为 0)。
// 不声明 Receive Maximum,避免踩 mochi 发送配额路径。
func encodeConnect(endpointID, password string) ([]byte, error) {
pk := packets.Packet{
FixedHeader: packets.FixedHeader{Type: packets.Connect},
ProtocolVersion: mqttProtocolLevel5,
Connect: packets.ConnectParams{
ProtocolName: []byte("MQTT"),
Clean: true,
ClientIdentifier: endpointID,
Keepalive: mqttKeepaliveSec,
UsernameFlag: true,
Username: []byte(endpointID),
PasswordFlag: true,
Password: []byte(password),
},
}
var buf bytes.Buffer
if err := pk.ConnectEncode(&buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func encodeSubscribe(packetID uint16, endpointID string) ([]byte, error) {
pk := packets.Packet{
FixedHeader: packets.FixedHeader{Type: packets.Subscribe, Qos: 1},
ProtocolVersion: mqttProtocolLevel5,
PacketID: packetID,
Filters: packets.Subscriptions{
{Filter: downTopic(endpointID), Qos: 1},
},
}
var buf bytes.Buffer
if err := pk.SubscribeEncode(&buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func encodePublish(packetID uint16, endpointID string, payload []byte) ([]byte, error) {
pk := packets.Packet{
FixedHeader: packets.FixedHeader{Type: packets.Publish, Qos: 1},
ProtocolVersion: mqttProtocolLevel5,
TopicName: upTopic(endpointID),
PacketID: packetID,
Payload: payload,
}
var buf bytes.Buffer
if err := pk.PublishEncode(&buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func encodePuback(packetID uint16) ([]byte, error) {
pk := packets.Packet{
FixedHeader: packets.FixedHeader{Type: packets.Puback},
ProtocolVersion: mqttProtocolLevel5,
PacketID: packetID,
}
var buf bytes.Buffer
if err := pk.PubackEncode(&buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func encodePingreq() []byte {
return []byte{0xC0, 0x00}
}
func downTopic(id string) string { return "nix/c/" + id + "/down" }
func upTopic(id string) string { return "nix/c/" + id + "/up" }
func connackReason(raw []byte) (byte, error) {
if len(raw) < 2 || raw[0]>>4 != packets.Connack {
return 0, fmt.Errorf("不是 CONNACK:type=0x%02x len=%d", byteAt(raw, 0), len(raw))
}
rem, n, err := decodeRemainingLength(raw[1:])
if err != nil {
return 0, err
}
body := raw[1+n:]
if rem < 2 || len(body) < 2 {
return 0, fmt.Errorf("CONNACK 过短 remaining=%d body=%d", rem, len(body))
}
return body[1], nil
}
func decodePublish(raw []byte) (payload []byte, packetID uint16, qos byte, err error) {
if len(raw) < 2 {
return nil, 0, 0, io.ErrUnexpectedEOF
}
qos = (raw[0] >> 1) & 0x3
rem, n, err := decodeRemainingLength(raw[1:])
if err != nil {
return nil, 0, 0, err
}
body := raw[1+n:]
if len(body) != rem {
return nil, 0, 0, io.ErrUnexpectedEOF
}
pk := packets.Packet{
ProtocolVersion: mqttProtocolLevel5,
FixedHeader: packets.FixedHeader{
Type: packets.Publish,
Remaining: rem,
Qos: qos,
},
}
if err := pk.PublishDecode(body); err != nil {
return nil, 0, qos, err
}
return pk.Payload, pk.PacketID, qos, nil
}
func decodeRemainingLength(b []byte) (value int, n int, err error) {
var mul uint32 = 1
var v uint32
for i := 0; i < len(b) && i < 4; i++ {
v += uint32(b[i]&127) * mul
n++
if b[i]&128 == 0 {
return int(v), n, nil
}
mul *= 128
}
return 0, 0, io.ErrUnexpectedEOF
}
func byteAt(b []byte, i int) byte {
if i < 0 || i >= len(b) {
return 0
}
return b[i]
}