debug(icom): the quiet detector watches CI-V DATA, not transport chatter

The first detector counted any packet and never fired: pings and idles keep
flowing while the rig stops answering CI-V commands — which is what the 7760's
recurring silence turns out to be. Now it fires on 10 s without a CI-V payload
and reports the ages of the transport, the last scope frame and the last
socket error, so the next occurrence says exactly what the rig was still
sending.
This commit is contained in:
2026-08-29 16:54:37 +02:00
parent 1fba7d2d57
commit a2b019b280
+12 -3
View File
@@ -365,6 +365,8 @@ func (n *icomNet) civPump() {
// and a rig that stopped talking are different repairs, and the 30 s
// watchdog that follows cannot tell them apart from where it sits.
lastPkt := time.Now()
lastData := time.Now() // CI-V payload packets (replies + transceive)
lastScope := time.Time{} // scope frames within those
var lastErr error
quietSaid := false
for {
@@ -382,7 +384,7 @@ func (n *icomNet) civPump() {
}
if err == nil && k >= 16 {
if quietSaid {
debugLog.Printf("icom net: CI-V stream is talking again after %s of silence", time.Since(lastPkt).Round(time.Second))
debugLog.Printf("icom net: CI-V replies are back after %s", time.Since(lastData).Round(time.Second))
quietSaid = false
}
lastPkt = time.Now()
@@ -398,6 +400,7 @@ 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
lastData = time.Now()
n.trackRxSeq(icnLE.Uint16(buf[6:])) // note gaps for retransmit
civBytes := buf[0x15:k]
cp := append([]byte(nil), civBytes...)
@@ -407,6 +410,7 @@ func (n *icomNet) civPump() {
// feeder in IcomSerial picks them up. Everything else is a control
// reply → rx → Read.
if len(civBytes) >= 5 && civBytes[4] == 0x27 {
lastScope = time.Now()
icnEnqueueDrop(n.scopeRx, cp)
break
}
@@ -429,9 +433,14 @@ func (n *icomNet) civPump() {
}
}
}
if !quietSaid && time.Since(lastPkt) > 10*time.Second {
if !quietSaid && time.Since(lastData) > 10*time.Second {
quietSaid = true
debugLog.Printf("icom net: CI-V stream quiet for 10 s (control link still alive; last socket error: %v; missing-seq backlog: %d) — idles and retransmit requests are still being sent", lastErr, len(n.rxMissing))
scopeAge := "never"
if !lastScope.IsZero() {
scopeAge = time.Since(lastScope).Round(time.Second).String()
}
debugLog.Printf("icom net: no CI-V DATA for 10 s (transport last heard %s ago; last scope frame %s ago; last socket error: %v; missing-seq backlog: %d)",
time.Since(lastPkt).Round(time.Second), scopeAge, lastErr, len(n.rxMissing))
}
if time.Since(lastIdle) > 150*time.Millisecond {
_, _ = n.civ.Write(icnCtrl(0x00, 0, n.vID, n.vRemote))