fix(icom): give up on the quiet CI-V stream after 15 s, not 30

The capture settled it: the 7760 keeps the transport chatting (pings answered,
no socket error, no loss) while CI-V data simply stops, the in-place reopen is
ignored, and only a fresh session brings it back. So: one reopen attempt at
10 s — kept, it is free and the log will say if a firmware ever honours it —
and at 15 s the link is failed deliberately so the manager rebuilds it,
halving the outage. Also: the recovered-acknowledgement now sits on the DATA
packet, not on any packet — pings were toggling the detector, 160 reopens in
thirty seconds all logged as recoveries that never happened.
This commit is contained in:
2026-08-29 18:35:41 +02:00
parent 2c0158b75c
commit 1c71495446
+14 -4
View File
@@ -372,6 +372,7 @@ func (n *icomNet) civPump() {
lastScope := time.Time{} // scope frames within those
var lastErr error
quietSaid := false
gaveUp := false
for {
select {
case <-n.done:
@@ -386,10 +387,6 @@ func (n *icomNet) civPump() {
}
}
if err == nil && k >= 16 {
if quietSaid {
debugLog.Printf("icom net: CI-V replies are back after %s", time.Since(lastData).Round(time.Second))
quietSaid = false
}
lastPkt = time.Now()
n.markRx()
switch typ := icnLE.Uint16(buf[4:]); {
@@ -403,6 +400,10 @@ func (n *icomNet) civPump() {
n.dead.Store(true) // make Alive() fail now → prompt clean reconnect
debugLog.Printf("icom net: rig sent DISCONNECT on CI-V stream — session dropped by the rig")
case typ == 0x00 && k > 0x15 && buf[0x10] == 0xc1: // CI-V data
if quietSaid {
debugLog.Printf("icom net: CI-V replies are back after %s", time.Since(lastData).Round(time.Second))
quietSaid, gaveUp = false, false
}
lastData = time.Now()
n.trackRxSeq(icnLE.Uint16(buf[6:])) // note gaps for retransmit
civBytes := buf[0x15:k]
@@ -461,6 +462,15 @@ func (n *icomNet) civPump() {
_, _ = n.civ.Write(ocPkt)
debugLog.Printf("icom net: re-sent the CI-V open on the existing stream")
}
// The reopen was given five seconds. On a real IC-7760 it never works —
// the rig ignores it and only a fresh session brings CI-V back — so
// rather than sit out the 30 s watchdog, fail the link NOW and let the
// manager rebuild it: the outage drops from ~35 s to ~15.
if quietSaid && !gaveUp && time.Since(lastData) > 15*time.Second {
gaveUp = true
n.dead.Store(true)
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))
lastIdle = time.Now()