Add keepalive command and sequence handling to new protocol

This commit is contained in:
seydx
2026-01-12 10:34:05 +01:00
parent 3dcb6dfc48
commit c5311cdd94
2 changed files with 44 additions and 27 deletions
+34 -20
View File
@@ -49,6 +49,7 @@ type Conn struct {
seq uint16
seqCmd uint16
avSeq uint32
kaSeq uint32
// DTLS
main *dtls.Conn
@@ -317,8 +318,6 @@ func (c *Conn) WriteAndWait(req []byte, timeout time.Duration, ok func(res []byt
func (c *Conn) WriteAndWaitIOCtrl(cmd uint16, payload []byte, expectCmd uint16, timeout time.Duration) ([]byte, error) {
frame := c.buildIOCtrlFrame(payload)
// Retry send every second
var t *time.Timer
t = time.AfterFunc(1, func() {
if _, err := c.main.Write(frame); err == nil && t != nil {
@@ -588,15 +587,23 @@ func (c *Conn) reader() {
}
// NEW protocol (0xCC51)
if c.newProto && n >= NewHeaderSize+NewAuthSize && binary.LittleEndian.Uint16(buf[:2]) == MagicNewProto {
if binary.LittleEndian.Uint16(buf[4:]) == CmdNewDTLS {
ch := byte(binary.LittleEndian.Uint16(buf[12:]) >> 8)
dtls := buf[NewHeaderSize : n-NewAuthSize]
switch ch {
case IOTCChannelMain:
c.queue(c.mainBuf, dtls)
case IOTCChannelBack:
c.queue(c.speakBuf, dtls)
if c.newProto && n >= 12 && binary.LittleEndian.Uint16(buf[:2]) == MagicNewProto {
cmd := binary.LittleEndian.Uint16(buf[4:])
switch cmd {
case CmdNewKeepalive:
if n >= NewKeepaliveSize {
_ = c.Write(c.buildNewKeepalive())
}
case CmdNewDTLS:
if n >= NewHeaderSize+NewAuthSize {
ch := byte(binary.LittleEndian.Uint16(buf[12:]) >> 8)
dtls := buf[NewHeaderSize : n-NewAuthSize]
switch ch {
case IOTCChannelMain:
c.queue(c.mainBuf, dtls)
case IOTCChannelBack:
c.queue(c.speakBuf, dtls)
}
}
}
continue
@@ -696,7 +703,6 @@ func (c *Conn) buildDisco(stage byte) []byte {
binary.LittleEndian.PutUint16(b[4:], OldDiscoBodySize) // body size
binary.LittleEndian.PutUint16(b[8:], CmdDiscoReq) // 0x0601
binary.LittleEndian.PutUint16(b[10:], 0x0021) // flags
body := b[OldHeaderSize:]
copy(body[:UIDSize], c.uid)
copy(body[36:], "\x01\x01\x02\x04") // unknown
@@ -720,8 +726,6 @@ func (c *Conn) buildNewDisco(seq, ticket uint16, isResponse bool) []byte {
binary.LittleEndian.PutUint16(b[14:], ticket)
copy(b[16:24], c.sid)
copy(b[24:32], "\x00\x08\x03\x04\x1d\x00\x00\x00") // SDK 4.3.8.0
// HMAC-SHA1(UID+AuthKey, header)
authKey := crypto.CalculateAuthKey(c.enr, c.mac)
h := hmac.New(sha1.New, append([]byte(c.uid), authKey...))
h.Write(b[:32])
@@ -729,13 +733,27 @@ func (c *Conn) buildNewDisco(seq, ticket uint16, isResponse bool) []byte {
return b
}
func (c *Conn) buildNewKeepalive() []byte {
c.kaSeq += 2
b := make([]byte, NewKeepaliveSize)
binary.LittleEndian.PutUint16(b[0:], MagicNewProto) // 0xCC51
binary.LittleEndian.PutUint16(b[4:], CmdNewKeepalive) // 0x1202
binary.LittleEndian.PutUint16(b[6:], 0x0024) // 36 bytes payload
binary.LittleEndian.PutUint32(b[16:], c.kaSeq) // counter
copy(b[20:28], c.sid) // session ID
authKey := crypto.CalculateAuthKey(c.enr, c.mac)
h := hmac.New(sha1.New, append([]byte(c.uid), authKey...))
h.Write(b[:28])
copy(b[28:48], h.Sum(nil))
return b
}
func (c *Conn) buildSession() []byte {
b := make([]byte, OldSessionSize)
copy(b, "\x04\x02\x1a\x02") // marker + mode
binary.LittleEndian.PutUint16(b[4:], OldSessionBody) // body size
binary.LittleEndian.PutUint16(b[8:], CmdSessionReq) // 0x0402
binary.LittleEndian.PutUint16(b[10:], 0x0033) // flags
body := b[OldHeaderSize:]
copy(body[:UIDSize], c.uid)
copy(body[UIDSize:], c.rid)
@@ -805,9 +823,7 @@ func (c *Conn) buildAudioFrame(payload []byte, timestampUS uint32, codec uint16,
binary.LittleEndian.PutUint32(b[24:], uint32(totalPayload))
binary.LittleEndian.PutUint32(b[28:], prevFrame)
binary.LittleEndian.PutUint32(b[32:], c.audioFrame)
// Payload + FrameInfo
copy(b[36:], payload)
copy(b[36:], payload) // Payload + FrameInfo
fi := b[36+len(payload):]
binary.LittleEndian.PutUint16(fi, codec)
fi[2] = BuildAudioFlags(sampleRate, true, channels == 2)
@@ -845,8 +861,6 @@ func (c *Conn) buildNewTxData(payload []byte, channel byte) []byte {
copy(b[16:24], c.sid)
binary.LittleEndian.PutUint32(b[24:], 1) // const
copy(b[NewHeaderSize:], payload)
// HMAC-SHA1(UID+AuthKey, header)
authKey := crypto.CalculateAuthKey(c.enr, c.mac)
h := hmac.New(sha1.New, append([]byte(c.uid), authKey...))
h.Write(b[:NewHeaderSize])
+10 -7
View File
@@ -138,13 +138,16 @@ const (
// NEW Protocol (0xCC51)
const (
MagicNewProto uint16 = 0xCC51
CmdNewDisco uint16 = 0x1002
CmdNewDTLS uint16 = 0x1502
NewPayloadSize uint16 = 0x0028
NewPacketSize = 52
NewHeaderSize = 28
NewAuthSize = 20
MagicNewProto uint16 = 0xCC51
CmdNewDisco uint16 = 0x1002
CmdNewKeepalive uint16 = 0x1202
CmdNewClose uint16 = 0x1302
CmdNewDTLS uint16 = 0x1502
NewPayloadSize uint16 = 0x0028
NewPacketSize = 52
NewHeaderSize = 28
NewAuthSize = 20
NewKeepaliveSize = 48
)
const (