diff --git a/audiostream.go b/audiostream.go index 91bbac8..f3dccc9 100644 --- a/audiostream.go +++ b/audiostream.go @@ -138,7 +138,7 @@ func (s *audioStream) loop() { case r := <-s.common.readChan: s.handleRead(r) case <-s.timeoutTimer.C: - reportError(errors.New("audio stream timeout")) + reportError(errors.New("audio stream timeout, try rebooting the radio")) case e := <-s.rxSeqBufEntryChan: s.handleRxSeqBufEntry(e) case d := <-s.audio.rec: diff --git a/controlstream.go b/controlstream.go index 907e504..15e005f 100644 --- a/controlstream.go +++ b/controlstream.go @@ -2,7 +2,6 @@ package main import ( "bytes" - "crypto/rand" "errors" "strings" "time" @@ -31,16 +30,13 @@ type controlStream struct { } func (s *controlStream) sendPktLogin() error { - // The reply to the auth packet will contain a 6 bytes long auth ID with the first 2 bytes set to our randID. - var randID [2]byte - if _, err := rand.Read(randID[:]); err != nil { - return err - } + // The reply to the auth packet will contain a 6 bytes long auth ID with the first 2 bytes set to our ID. + authStartID := []byte{0x63, 0x00} p := []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, byte(s.authSendSeq), byte(s.authSendSeq >> 8), byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID), byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID), 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, byte(s.authInnerSendSeq), - byte(s.authInnerSendSeq >> 8), 0x00, randID[0], randID[1], 0x00, 0x00, 0x00, 0x00, + byte(s.authInnerSendSeq >> 8), 0x00, authStartID[0], authStartID[1], 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, @@ -227,15 +223,17 @@ func (s *controlStream) handleRead(r []byte) error { // 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x03, 0x03, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - if !bytes.Equal(r[26:32], s.authID[:]) { - return errors.New("got serial and audio request success, but not for our auth id") - } + devName := s.parseNullTerminatedString(r[64:]) + log.Print("got serial and audio request success, device name: ", devName) + if !s.serialAndAudioStreamOpenRequested { - return errors.New("got serial and audio request success, but not requested yet") + return errors.New("not requested serial and audio streams yet") } - devName := s.parseNullTerminatedString(r[64:]) - log.Print("serial and audio request success, device name: ", devName) + // The auth ID can change in the meantime because of a previous login... + copy(s.authID[:], r[26:32]) + s.secondAuthTimer.Stop() + if s.requestSerialAndAudioTimeout != nil { s.requestSerialAndAudioTimeout.Stop() s.requestSerialAndAudioTimeout = nil @@ -301,13 +299,8 @@ func (s *controlStream) start() error { return err } - if err := s.common.sendPkt3(); err != nil { - return err - } - s.common.pkt7.sendSeq = 1 - if err := s.common.pkt7.send(&s.common); err != nil { - return err - } + s.common.pkt7.startPeriodicSend(&s.common, 2, false) + if err := s.common.sendPkt3(); err != nil { return err } @@ -353,8 +346,6 @@ func (s *controlStream) start() error { } log.Print("login ok, first auth sent...") - s.common.pkt7.startPeriodicSend(&s.common, 5, false) - s.requestSerialAndAudioTimeout = time.AfterFunc(5*time.Second, func() { reportError(errors.New("login/serial/audio request timeout")) }) diff --git a/main.go b/main.go index 3bc701d..a4466b3 100644 --- a/main.go +++ b/main.go @@ -40,8 +40,10 @@ func runControlStream(osSignal chan os.Signal) (shouldExit bool, exitCode int) { case <-gotErrChan: c.deinit() + // Need to wait before reinit because the IC-705 will disconnect our audio stream eventually if we relogin + // in a too short interval... t := time.NewTicker(time.Second) - for sec := 180; sec > 0; sec-- { + for sec := 65; sec > 0; sec-- { log.Print("waiting ", sec, " seconds...") select { case <-t.C: diff --git a/pkt7.go b/pkt7.go index 3f1b1d4..6667672 100644 --- a/pkt7.go +++ b/pkt7.go @@ -81,7 +81,7 @@ func (p *pkt7Type) sendDo(s *streamCommon, replyID []byte, seq uint16) error { replyID[0] = randID[0] replyID[1] = byte(p.innerSendSeq) replyID[2] = byte(p.innerSendSeq >> 8) - replyID[3] = 0x05 + replyID[3] = 0x06 p.innerSendSeq++ } else { replyFlag = 0x01 diff --git a/streamcommon.go b/streamcommon.go index 6ea7ef5..ab34753 100644 --- a/streamcommon.go +++ b/streamcommon.go @@ -153,14 +153,15 @@ func (s *streamCommon) init(name string, portNumber int) error { return err } - s.conn, err = net.DialUDP("udp", nil, raddr) + s.conn, err = net.DialUDP("udp", &net.UDPAddr{Port: portNumber}, raddr) if err != nil { return err } // Constructing the local session ID by combining the local IP address and port. - laddr := s.conn.LocalAddr().(*net.UDPAddr) - s.localSID = binary.BigEndian.Uint32(laddr.IP[len(laddr.IP)-4:])<<16 | uint32(laddr.Port&0xffff) + // laddr := s.conn.LocalAddr().(*net.UDPAddr) + // s.localSID = binary.BigEndian.Uint32(laddr.IP[len(laddr.IP)-4:])<<16 | uint32(laddr.Port&0xffff) + s.localSID = 0x8aff0539 s.readChan = make(chan []byte) s.readerCloseNeededChan = make(chan bool)