mirror of
https://github.com/zhaojh329/rttys.git
synced 2026-02-27 09:53:21 +08:00
refactor: parse device messages using TLV.
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
This commit is contained in:
@@ -41,6 +41,17 @@ const (
|
||||
msgTypeFileAbort
|
||||
)
|
||||
|
||||
const (
|
||||
msgRegAttrHeartbeat = iota
|
||||
msgRegAttrDevid
|
||||
msgRegAttrDescription
|
||||
msgRegAttrToken
|
||||
)
|
||||
|
||||
const (
|
||||
msgHeartbeatAttrUptime = iota
|
||||
)
|
||||
|
||||
// Minimum protocol version requirements of rtty
|
||||
const rttyProtoRequired uint8 = 3
|
||||
|
||||
@@ -153,24 +164,36 @@ func (dev *device) Close() {
|
||||
}
|
||||
|
||||
func parseDeviceInfo(dev *device, b []byte) bool {
|
||||
if len(b) < 2 {
|
||||
if len(b) < 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
dev.proto = b[0]
|
||||
|
||||
if dev.proto > 4 {
|
||||
if len(b) < 4 {
|
||||
attrs := parseTLV(b[1:])
|
||||
if attrs == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
dev.heartbeat = time.Duration(binary.BigEndian.Uint16(b[1:3])) * time.Second
|
||||
b = b[3:]
|
||||
} else {
|
||||
for typ, val := range attrs {
|
||||
switch typ {
|
||||
case msgRegAttrHeartbeat:
|
||||
dev.heartbeat = time.Duration(val[0]) * time.Second
|
||||
case msgRegAttrDevid:
|
||||
dev.id = string(val)
|
||||
case msgRegAttrDescription:
|
||||
dev.desc = string(val)
|
||||
case msgRegAttrToken:
|
||||
dev.token = string(val)
|
||||
}
|
||||
}
|
||||
|
||||
b = b[1:]
|
||||
return true
|
||||
}
|
||||
|
||||
b = b[1:]
|
||||
|
||||
fields := bytes.Split(b, []byte{0})
|
||||
|
||||
if len(fields) < 3 {
|
||||
@@ -184,8 +207,27 @@ func parseDeviceInfo(dev *device, b []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func parseHeartbeat(dev *device, b []byte) {
|
||||
dev.uptime = binary.BigEndian.Uint32(b[:4])
|
||||
func parseHeartbeat(dev *device, b []byte) bool {
|
||||
if dev.proto > 4 {
|
||||
attrs := parseTLV(b)
|
||||
if attrs == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for typ, val := range attrs {
|
||||
switch typ {
|
||||
case msgHeartbeatAttrUptime:
|
||||
dev.uptime = binary.BigEndian.Uint32(val)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(b) < 4 {
|
||||
return false
|
||||
}
|
||||
dev.uptime = binary.BigEndian.Uint32(b[:4])
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func msgTypeName(typ byte) string {
|
||||
@@ -327,11 +369,10 @@ func (dev *device) readLoop() {
|
||||
dev.br.httpResp <- &httpResp{b, dev}
|
||||
|
||||
case msgTypeHeartbeat:
|
||||
if msgLen < 4 {
|
||||
if !parseHeartbeat(dev, b) {
|
||||
log.Error().Msgf("%s: msgTypeHeartbeat: invalid", logPrefix)
|
||||
return
|
||||
}
|
||||
parseHeartbeat(dev, b)
|
||||
dev.br.heartbeat <- dev.id
|
||||
default:
|
||||
log.Error().Msgf("%s: invalid msg type: %d", logPrefix, typ)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
func parseTLV(data []byte) map[uint8][]byte {
|
||||
if len(data) < 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
tlvs := map[uint8][]byte{}
|
||||
|
||||
reader := bytes.NewReader(data)
|
||||
|
||||
for reader.Len() > 0 {
|
||||
typ, _ := reader.ReadByte()
|
||||
|
||||
var length uint16
|
||||
err := binary.Read(reader, binary.BigEndian, &length)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
value := make([]byte, length)
|
||||
|
||||
_, err = io.ReadFull(reader, value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
tlvs[typ] = value
|
||||
}
|
||||
|
||||
return tlvs
|
||||
}
|
||||
Reference in New Issue
Block a user