From 1b746f24529a03bf5ad38de41d5b08a5aa4978ad Mon Sep 17 00:00:00 2001 From: rouggy Date: Sun, 30 Aug 2026 03:08:59 +0200 Subject: [PATCH] fix(icom): CI-V idles carry real sequence numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every idle went out with seq 0, seven a second, interleaved with properly-numbered data — where RS-BA1 and wfview draw idle sequence numbers from the same counter as everything else. A rig that follows the sequence tolerates the zeros for a minute or so and then stops serving CI-V data on the stream: the shape of every dropout the loaner IC-7760 has shown, with the scope and the TX path both since eliminated as causes. Idles now take the next tracked seq and sit in the retransmit buffer like any other packet. --- internal/cat/icomnet.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/internal/cat/icomnet.go b/internal/cat/icomnet.go index 5f79529..958a17c 100644 --- a/internal/cat/icomnet.go +++ b/internal/cat/icomnet.go @@ -510,7 +510,23 @@ func (n *icomNet) civPump() { debugLog.Printf("icom net: the reopen did not bring CI-V back — forcing a fresh session") } if time.Since(lastIdle) > 150*time.Millisecond { - _, _ = n.civ.Write(icnCtrl(0x00, 0, n.vID, n.vRemote)) + // Idles carry a REAL sequence number, drawn from the same counter as + // the data packets, and sit in the retransmit buffer like them — + // which is how RS-BA1 and wfview number theirs. Ours used seq 0 on + // every idle, seven a second, interleaved with properly-numbered + // data; a rig that follows the sequence tolerates that for a minute + // or so and then stops serving CI-V data on the stream — which is + // the shape of every dropout this loaner IC-7760 has shown, with + // the scope and the TX path both since eliminated. + n.seqMu.Lock() + iseq := n.vTracked + n.vTracked++ + n.seqMu.Unlock() + ipkt := icnCtrl(0x00, iseq, n.vID, n.vRemote) + n.sentMu.Lock() + n.sentBuf[iseq] = ipkt + n.sentMu.Unlock() + _, _ = n.civ.Write(ipkt) lastIdle = time.Now() } if time.Since(lastReq) > 100*time.Millisecond {