fix(icom): wait out the rig's session cleanup before redialling
The capture shows the spiral: a session goes deaf on CI-V (28 unanswered commands, transport alive), the fast-fail rebuilds it, the new session answers for one second — one state read got through — and is then strangled when the rig purges the half-open old one. Twenty seconds a lap, no audio throughout, and only the third or fourth session survives. When the previous session died less than 90 s after connecting, the redial now pauses 20 s so the purge happens BEFORE the new session, not on top of it. A long-lived session still reconnects immediately.
This commit is contained in:
+23
-1
@@ -56,6 +56,15 @@ func NewIcomNet(host, user, pass string, civAddr int, digitalDefault string, aud
|
||||
model: "Icom",
|
||||
scopeFixed: true,
|
||||
}
|
||||
// lastNetConnect is when the previous session came up, and it drives a
|
||||
// deliberate pause: on a real IC-7760 a session sometimes goes deaf on CI-V
|
||||
// while the rig still holds it half-open, and a session dialled straight
|
||||
// back in answers for a second and is then strangled when the rig finally
|
||||
// purges the old one — reconnect, die, reconnect, die, twenty seconds a
|
||||
// lap and no audio the whole time. When the last session died YOUNG, wait
|
||||
// out the rig's cleanup before dialling again; a session that lived long
|
||||
// reconnects immediately, as ever.
|
||||
var lastNetConnect time.Time
|
||||
b.open = func() (civTransport, error) {
|
||||
if strings.TrimSpace(host) == "" {
|
||||
return nil, fmt.Errorf("no rig host configured")
|
||||
@@ -63,7 +72,20 @@ func NewIcomNet(host, user, pass string, civAddr int, digitalDefault string, aud
|
||||
b.dialMu.Lock()
|
||||
cancel := b.dialCancel
|
||||
b.dialMu.Unlock()
|
||||
return dialIcomNet(host, user, pass, "OpsLog", b.rigAddr, cancel, audioSink)
|
||||
if !lastNetConnect.IsZero() && time.Since(lastNetConnect) < 90*time.Second {
|
||||
debugLog.Printf("icom net: the last session died young — pausing 20 s before redialling so the rig can purge it first")
|
||||
for i := 0; i < 40; i++ {
|
||||
if icnCanceled(cancel) {
|
||||
return nil, errDialCanceled
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
tr, err := dialIcomNet(host, user, pass, "OpsLog", b.rigAddr, cancel, audioSink)
|
||||
if err == nil {
|
||||
lastNetConnect = time.Now()
|
||||
}
|
||||
return tr, err
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user