kappanhang/main.go

395 lines
15 KiB
Go
Raw Normal View History

2020-10-16 17:13:46 +02:00
package main
import (
"bytes"
2020-10-16 18:22:22 +02:00
"crypto/rand"
2020-10-16 17:13:46 +02:00
"encoding/binary"
"fmt"
"net"
2020-10-16 19:25:02 +02:00
"os"
"os/signal"
"syscall"
2020-10-16 17:13:46 +02:00
"time"
"github.com/nonoo/kappanhang/log"
)
var conn *net.UDPConn
2020-10-16 19:25:02 +02:00
var localSID uint32
var remoteSID uint32
var sendSeq uint16
2020-10-16 23:37:12 +02:00
var authSendSeq uint16
2020-10-17 18:35:55 +02:00
var authInnerSendSeq uint16
2020-10-16 19:25:02 +02:00
var authID [6]byte
2020-10-16 23:37:12 +02:00
var randIDByteForPktSeven [1]byte
var expectedPkt7ReplySeq uint16
2020-10-17 18:35:55 +02:00
var lastReauthAt time.Time
2020-10-16 17:13:46 +02:00
func send(d []byte) {
_, err := conn.Write(d)
if err != nil {
log.Fatal(err)
}
}
func read() ([]byte, error) {
err := conn.SetReadDeadline(time.Now().Add(time.Second))
if err != nil {
log.Fatal(err)
}
b := make([]byte, 1500)
n, _, err := conn.ReadFromUDP(b)
if err != nil {
if err, ok := err.(net.Error); ok && !err.Timeout() {
log.Fatal(err)
}
}
return b[:n], err
}
2020-10-16 19:25:02 +02:00
func setupCloseHandler() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log.Print("disconnecting")
2020-10-16 23:37:12 +02:00
sendDisconnect()
2020-10-16 19:25:02 +02:00
os.Exit(0)
}()
}
2020-10-17 12:15:56 +02:00
func sendPkt7(replyID []byte, seq uint16) {
2020-10-16 23:37:12 +02:00
// Example request from PC: 0x15, 0x00, 0x00, 0x00, 0x07, 0x00, 0x09, 0x00, 0xbe, 0xd9, 0xf2, 0x63, 0xe4, 0x35, 0xdd, 0x72, 0x00, 0x78, 0x40, 0xf6, 0x02
// Example reply from radio: 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x09, 0x00, 0xe4, 0x35, 0xdd, 0x72, 0xbe, 0xd9, 0xf2, 0x63, 0x01, 0x78, 0x40, 0xf6, 0x02
var replyFlag byte
if replyID == nil {
replyID = make([]byte, 4)
var randID [2]byte
_, err := rand.Read(randID[:])
if err != nil {
log.Fatal(err)
}
replyID[0] = randID[0]
replyID[1] = randID[1]
replyID[2] = randIDByteForPktSeven[0]
replyID[3] = 0x03
} else {
replyFlag = 0x01
}
expectedPkt7ReplySeq = sendSeq
2020-10-17 12:15:56 +02:00
send([]byte{0x15, 0x00, 0x00, 0x00, 0x07, 0x00, byte(seq), byte(seq >> 8),
2020-10-16 23:37:12 +02:00
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID),
replyFlag, replyID[0], replyID[1], replyID[2], replyID[3]})
}
func sendPkt3() {
send([]byte{0x10, 0x00, 0x00, 0x00, 0x03, 0x00, byte(sendSeq), byte(sendSeq >> 8),
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID)})
}
func sendPkt6() {
send([]byte{0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00,
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID)})
}
func sendPktLogin() {
2020-10-17 18:35:55 +02:00
// The reply to the login packet will contain a 6 bytes long auth ID with the first 2 bytes set to our randID.
2020-10-16 23:37:12 +02:00
var randID [2]byte
_, err := rand.Read(randID[:])
if err != nil {
log.Fatal(err)
}
send([]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID),
2020-10-17 18:35:55 +02:00
0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, byte(authInnerSendSeq),
byte(authInnerSendSeq >> 8), 0x00, randID[0], randID[1], 0x00, 0x00, 0x00, 0x00,
2020-10-16 23:37:12 +02:00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2b, 0x3f, 0x55, 0x5c, 0x00, 0x00, 0x00, 0x00, // username: beer
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2b, 0x3f, 0x55, 0x5c, 0x3f, 0x25, 0x77, 0x58, // pass: beerbeer
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020-10-17 18:35:55 +02:00
0x69, 0x63, 0x6f, 0x6d, 0x2d, 0x70, 0x63, 0x00, // icom-pc in plain text
2020-10-16 23:37:12 +02:00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
2020-10-17 18:35:55 +02:00
authSendSeq++
authInnerSendSeq++
2020-10-16 23:37:12 +02:00
}
2020-10-17 19:09:53 +02:00
func sendPktReauth(firstReauthSend bool) {
2020-10-17 18:35:55 +02:00
var magic byte
2020-10-17 19:09:53 +02:00
if firstReauthSend {
2020-10-17 18:35:55 +02:00
magic = 0x02
2020-10-17 19:09:53 +02:00
} else {
magic = 0x05
2020-10-17 18:35:55 +02:00
}
2020-10-16 23:37:12 +02:00
// Example request from PC: 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
// 0xbb, 0x41, 0x3f, 0x2b, 0xe6, 0xb2, 0x7b, 0x7b,
// 0x00, 0x00, 0x00, 0x30, 0x01, 0x05, 0x00, 0x02,
// 0x00, 0x00, 0x5d, 0x37, 0x12, 0x82, 0x3b, 0xde,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// Example reply from radio: 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
// 0xe6, 0xb2, 0x7b, 0x7b, 0xbb, 0x41, 0x3f, 0x2b,
// 0x00, 0x00, 0x00, 0x30, 0x02, 0x05, 0x00, 0x02,
// 0x00, 0x00, 0x5d, 0x37, 0x12, 0x82, 0x3b, 0xde,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2020-10-17 18:35:55 +02:00
send([]byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, byte(authSendSeq), byte(authSendSeq >> 8),
2020-10-16 23:37:12 +02:00
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID),
2020-10-17 18:35:55 +02:00
0x00, 0x00, 0x00, 0x30, 0x01, magic, 0x00, byte(authInnerSendSeq),
byte(authInnerSendSeq >> 8), 0x00, authID[0], authID[1], authID[2], authID[3], authID[4], authID[5],
2020-10-16 23:37:12 +02:00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
2020-10-17 18:35:55 +02:00
authSendSeq++
authInnerSendSeq++
lastReauthAt = time.Now()
2020-10-16 23:37:12 +02:00
}
func sendDisconnect() {
send([]byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, byte(sendSeq), byte(sendSeq >> 8),
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID),
2020-10-17 18:35:55 +02:00
0x00, 0x00, 0x00, 0x30, 0x01, 0x01, 0x00, byte(authInnerSendSeq),
byte(authInnerSendSeq >> 8), 0x00, authID[0], authID[1], authID[2], authID[3], authID[4], authID[5],
2020-10-16 23:37:12 +02:00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
send([]byte{0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID),
byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID)})
}
func sendRequestSerialAndAudio() {
2020-10-17 18:35:55 +02:00
log.Print("requesting serial and audio stream")
send([]byte{0x90, 0x00, 0x00, 0x00, 0x00, 0x00, byte(authSendSeq), byte(authSendSeq >> 8),
byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID), byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID),
2020-10-17 18:35:55 +02:00
0x00, 0x00, 0x00, 0x80, 0x01, 0x03, 0x00, byte(authInnerSendSeq),
byte(authInnerSendSeq >> 8), 0x00, authID[0], authID[1], authID[2], authID[3], authID[4], authID[5],
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
2020-10-17 18:35:55 +02:00
0x80, 0x00, 0x00, 0x90, 0xc7, 0x0e, 0x86, 0x01, // The last 5 bytes from this row can be acquired from a reply starting with 0xa8 or 0x90
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020-10-17 18:35:55 +02:00
0x49, 0x43, 0x2d, 0x37, 0x30, 0x35, 0x00, 0x00, // IC-705 in plain text
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2b, 0x3f, 0x55, 0x5c, 0x00, 0x00, 0x00, 0x00, // username: beer
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x04, 0x04, 0x00, 0x00, 0xbb, 0x80,
0x00, 0x00, 0xbb, 0x80, 0x00, 0x00, 0xc3, 0x52,
0x00, 0x00, 0xc3, 0x53, 0x00, 0x00, 0x00, 0x64,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
2020-10-17 18:35:55 +02:00
authSendSeq++
authInnerSendSeq++
}
2020-10-16 17:13:46 +02:00
func main() {
log.Init()
parseArgs()
2020-10-16 19:25:02 +02:00
setupCloseHandler()
2020-10-16 17:13:46 +02:00
2020-10-17 19:09:53 +02:00
hostPort := fmt.Sprint(connectAddress, ":50001")
2020-10-16 17:13:46 +02:00
log.Print("connecting to ", hostPort)
raddr, err := net.ResolveUDPAddr("udp", hostPort)
if err != nil {
log.Fatal(err)
}
2020-10-17 18:35:55 +02:00
laddr := net.UDPAddr{
2020-10-17 19:09:53 +02:00
Port: 50001,
2020-10-17 18:35:55 +02:00
}
conn, err = net.DialUDP("udp", &laddr, raddr)
2020-10-16 17:13:46 +02:00
if err != nil {
log.Fatal(err)
}
2020-10-17 18:35:55 +02:00
localSID = uint32(time.Now().Unix())
2020-10-16 17:13:46 +02:00
log.Debugf("using session id %.8x", localSID)
2020-10-16 23:37:12 +02:00
sendPkt3()
sendSeq = 1
2020-10-17 12:15:56 +02:00
sendPkt7(nil, sendSeq)
2020-10-16 23:37:12 +02:00
sendSeq = 0
sendPkt3()
2020-10-16 17:13:46 +02:00
for {
2020-10-16 23:37:12 +02:00
// Expecting a Pkt4 answer.
2020-10-17 11:05:07 +02:00
// Example answer from radio: 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8c, 0x7d, 0x45, 0x7a, 0x1d, 0xf6, 0xe9, 0x0b
2020-10-16 17:13:46 +02:00
r, _ := read()
2020-10-17 18:35:55 +02:00
if len(r) == 16 && bytes.Equal(r[:8], []byte{0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00}) {
2020-10-16 17:13:46 +02:00
remoteSID = binary.BigEndian.Uint32(r[8:12])
break
}
}
log.Debugf("got remote session id %.8x", remoteSID)
2020-10-16 23:37:12 +02:00
authSendSeq = 1
2020-10-17 18:35:55 +02:00
authInnerSendSeq = 0x50
2020-10-16 23:37:12 +02:00
sendPkt6()
2020-10-17 18:35:55 +02:00
for {
// Expecting a Pkt6 answer.
r, _ := read()
if len(r) == 16 && bytes.Equal(r[:8], []byte{0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00}) {
remoteSID = binary.BigEndian.Uint32(r[8:12])
break
}
}
2020-10-16 23:37:12 +02:00
sendPktLogin()
2020-10-17 18:35:55 +02:00
sendSeq = 5
2020-10-16 17:13:46 +02:00
2020-10-17 19:09:53 +02:00
// Example success auth packet: 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
// 0xe6, 0xb2, 0x7b, 0x7b, 0xbb, 0x41, 0x3f, 0x2b,
// 0x00, 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x5d, 0x37, 0x12, 0x82, 0x3b, 0xde,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x46, 0x54, 0x54, 0x48, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
for {
r, _ := read()
if len(r) == 96 && bytes.Equal(r[:8], []byte{0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}) {
if bytes.Equal(r[48:52], []byte{0xff, 0xff, 0xff, 0xfe}) {
log.Fatal("invalid user/password")
}
copy(authID[:], r[26:32])
log.Print("auth ok")
sendPktReauth(true)
time.AfterFunc(time.Second*2, sendRequestSerialAndAudio)
break
}
}
2020-10-16 17:13:46 +02:00
var lastPingAt time.Time
2020-10-16 23:37:12 +02:00
var lastStatusLog time.Time
2020-10-16 17:13:46 +02:00
var errCount int
2020-10-16 23:37:12 +02:00
_, err = rand.Read(randIDByteForPktSeven[:])
if err != nil {
log.Fatal(err)
}
2020-10-16 17:13:46 +02:00
for {
r, err := read()
if err != nil {
errCount++
if errCount > 5 {
log.Fatal("timeout")
}
log.Error("stream break detected")
}
errCount = 0
2020-10-16 18:22:22 +02:00
if len(r) == 21 && bytes.Equal(r[1:6], []byte{0x00, 0x00, 0x00, 0x07, 0x00}) {
2020-10-17 12:15:56 +02:00
gotSeq := binary.LittleEndian.Uint16(r[6:8])
2020-10-16 23:37:12 +02:00
if r[16] == 0x00 { // This is a pkt7 request from the radio.
// Replying to the radio.
// Example request from radio: 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x1c, 0x0e, 0xe4, 0x35, 0xdd, 0x72, 0xbe, 0xd9, 0xf2, 0x63, 0x00, 0x57, 0x2b, 0x12, 0x00
// Example answer from PC: 0x15, 0x00, 0x00, 0x00, 0x07, 0x00, 0x1c, 0x0e, 0xbe, 0xd9, 0xf2, 0x63, 0xe4, 0x35, 0xdd, 0x72, 0x01, 0x57, 0x2b, 0x12, 0x00
2020-10-17 12:15:56 +02:00
sendPkt7(r[17:21], gotSeq)
2020-10-16 23:37:12 +02:00
} else {
2020-10-17 19:09:53 +02:00
if expectedPkt7ReplySeq != gotSeq { // TODO
2020-10-16 23:37:12 +02:00
var missingPkts int
if gotSeq > expectedPkt7ReplySeq {
missingPkts = int(gotSeq) - int(expectedPkt7ReplySeq)
} else {
missingPkts = int(gotSeq) + 65536 - int(expectedPkt7ReplySeq)
}
if missingPkts < 1000 {
log.Error("lost ", missingPkts, " packets ", gotSeq, " ", expectedPkt7ReplySeq)
}
}
2020-10-16 17:13:46 +02:00
}
2020-10-16 18:22:22 +02:00
}
if len(r) == 16 && bytes.Equal(r[:6], []byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00}) {
// Replying to the radio.
2020-10-16 18:51:22 +02:00
// Example request from radio: 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0xe4, 0x35, 0xdd, 0x72, 0xbe, 0xd9, 0xf2, 0x63
// Example answer from PC: 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0xbe, 0xd9, 0xf2, 0x63, 0xe4, 0x35, 0xdd, 0x72
2020-10-16 19:25:02 +02:00
gotSeq := binary.LittleEndian.Uint16(r[6:8])
2020-10-16 23:37:12 +02:00
send([]byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, byte(gotSeq), byte(gotSeq >> 8), byte(localSID >> 24), byte(localSID >> 16), byte(localSID >> 8), byte(localSID), byte(remoteSID >> 24), byte(remoteSID >> 16), byte(remoteSID >> 8), byte(remoteSID)})
2020-10-16 18:22:22 +02:00
}
2020-10-17 18:35:55 +02:00
if len(r) == 80 && bytes.Equal(r[:6], []byte{0x50, 0x00, 0x00, 0x00, 0x00, 0x00}) && bytes.Equal(r[48:51], []byte{0xff, 0xff, 0xff}) {
// Example answer from radio: 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
// 0x86, 0x1f, 0x2f, 0xcc, 0x03, 0x03, 0x89, 0x29,
// 0x00, 0x00, 0x00, 0x40, 0x02, 0x03, 0x00, 0x52,
// 0x00, 0x00, 0xf8, 0xad, 0x06, 0x8d, 0xda, 0x7b,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
// 0x80, 0x00, 0x00, 0x90, 0xc7, 0x0e, 0x86, 0x01,
// 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
log.Error("reauth failed")
sendDisconnect()
os.Exit(1)
}
2020-10-17 19:09:53 +02:00
if len(r) == 144 && bytes.Equal(r[:6], []byte{0x90, 0x00, 0x00, 0x00, 0x00, 0x00}) && r[96] == 1 {
// Example answer:
// 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00,
// 0xc6, 0x5f, 0x6f, 0x0c, 0x5f, 0x8b, 0x1e, 0x89,
// 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x31, 0x30, 0x31, 0x47, 0x39, 0x07,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
// 0x80, 0x00, 0x00, 0x90, 0xc7, 0x0e, 0x86, 0x01,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x49, 0x43, 0x2d, 0x37, 0x30, 0x35, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x01, 0x00, 0x00, 0x00, 0x69, 0x63, 0x6f, 0x6d,
// 0x2d, 0x70, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x03, 0x03,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
log.Print("serial and audio request success")
go openAudioStream()
}
2020-10-16 17:13:46 +02:00
2020-10-16 18:22:22 +02:00
if time.Since(lastPingAt) >= 100*time.Millisecond {
2020-10-17 12:15:56 +02:00
sendPkt7(nil, sendSeq)
2020-10-16 23:37:12 +02:00
sendPkt3()
2020-10-16 17:13:46 +02:00
sendSeq++
lastPingAt = time.Now()
2020-10-16 18:51:22 +02:00
2020-10-17 19:09:53 +02:00
if time.Since(lastReauthAt) >= 60*time.Second {
sendPktReauth(false)
2020-10-16 23:37:12 +02:00
}
if time.Since(lastStatusLog) >= 10*time.Second {
log.Print("still connected")
lastStatusLog = time.Now()
2020-10-16 18:51:22 +02:00
}
2020-10-16 17:13:46 +02:00
}
}
}