diff --git a/controlstream.go b/controlstream.go index 5d4aaca..ef328ef 100644 --- a/controlstream.go +++ b/controlstream.go @@ -21,8 +21,12 @@ type controlStream struct { authInnerSendSeq uint16 authID [6]byte + gotAuthID bool + authOk bool + + a8replyID [16]byte + gotA8ReplyID bool - gotAuthID bool serialAndAudioStreamOpened bool deinitializing bool @@ -103,8 +107,8 @@ func (s *controlStream) sendRequestSerialAndAudio() error { byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID), 0x00, 0x00, 0x00, 0x80, 0x01, 0x03, 0x00, byte(s.authInnerSendSeq), byte(s.authInnerSendSeq >> 8), 0x00, s.authID[0], s.authID[1], s.authID[2], s.authID[3], s.authID[4], s.authID[5], - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 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 + s.a8replyID[0], s.a8replyID[1], s.a8replyID[2], s.a8replyID[3], s.a8replyID[4], s.a8replyID[5], s.a8replyID[6], s.a8replyID[7], + s.a8replyID[8], s.a8replyID[9], s.a8replyID[10], s.a8replyID[11], s.a8replyID[12], s.a8replyID[13], s.a8replyID[14], s.a8replyID[15], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x43, 0x2d, 0x37, 0x30, 0x35, 0x00, 0x00, // IC-705 in plain text @@ -127,8 +131,45 @@ func (s *controlStream) sendRequestSerialAndAudio() error { return nil } +func (s *controlStream) sendRequestSerialAndAudioIfPossible() { + if !s.serialAndAudioStreamOpened && s.authOk && s.gotA8ReplyID { + time.AfterFunc(time.Second, func() { + if err := s.sendRequestSerialAndAudio(); err != nil { + reportError(err) + } + }) + } +} + func (s *controlStream) handleRead(r []byte) error { switch len(r) { + case 168: + if bytes.Equal(r[:6], []byte{0xa8, 0x00, 0x00, 0x00, 0x00, 0x00}) { + // Example answer from radio: + // 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + // 0x01, 0x13, 0x11, 0x18, 0x38, 0xff, 0x55, 0x7d, + // 0x00, 0x00, 0x00, 0x98, 0x02, 0x02, 0x00, 0x07, + // 0x00, 0x00, 0x7f, 0x91, 0x00, 0x00, 0x4f, 0x0d, + // 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, + // 0x00, 0x01, 0x93, 0x8a, 0x01, 0x24, 0x17, 0x64, + // 0xbc, 0x4b, 0xa3, 0xa0, 0x13, 0x58, 0x41, 0x04, + // 0x58, 0x2d, 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, 0x49, 0x43, 0x4f, 0x4d, 0x5f, 0x56, + // 0x41, 0x55, 0x44, 0x49, 0x4f, 0x00, 0x00, 0x00, + // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x00, 0x00, 0x3f, 0x3f, 0xa4, 0x01, 0xff, 0x01, + // 0xff, 0x01, 0x01, 0x01, 0x00, 0x00, 0x4b, 0x00, + // 0x01, 0x50, 0x00, 0xb8, 0x0b, 0x00, 0x00, 0x00 + copy(s.a8replyID[:], r[66:82]) + s.gotA8ReplyID = true + } case 64: if bytes.Equal(r[:6], []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00}) { // Example answer from radio: 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, @@ -144,14 +185,10 @@ func (s *controlStream) handleRead(r []byte) error { log.Debug("auth ok") - if r[21] == 0x05 && !s.serialAndAudioStreamOpened { // Answer for our second auth? + if r[21] == 0x05 { // Answer for our second auth? + s.authOk = true s.secondAuthTimer.Stop() - - time.AfterFunc(time.Second, func() { - if err := s.sendRequestSerialAndAudio(); err != nil { - reportError(err) - } - }) + s.sendRequestSerialAndAudioIfPossible() } } case 80: