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:
+4
-2
@@ -19,7 +19,8 @@
|
|||||||
"QSO recorder: a manual take on a network Icom records the network RX stream, not the “From radio” sound card (which captured another radio’s DAX on a mixed station).",
|
"QSO recorder: a manual take on a network Icom records the network RX stream, not the “From radio” sound card (which captured another radio’s DAX on a mixed station).",
|
||||||
"Icom network audio: duplicate and late-retransmitted packets no longer reach the recorder — recordings came out longer than the QSO, slowed and stuttering, while the speakers played fine.",
|
"Icom network audio: duplicate and late-retransmitted packets no longer reach the recorder — recordings came out longer than the QSO, slowed and stuttering, while the speakers played fine.",
|
||||||
"Icom network audio: it now starts with the app — launching OpsLog connected with audio silently off, and the option had to be unticked and re-saved to hear anything.",
|
"Icom network audio: it now starts with the app — launching OpsLog connected with audio silently off, and the option had to be unticked and re-saved to hear anything.",
|
||||||
"Icom network: when the rig goes quiet on CI-V while the session stays up (seen on the IC-7760), the CI-V flow is re-opened on the spot — recovery in seconds instead of the 35-second full reconnect."
|
"Icom network: when the rig goes quiet on CI-V while the session stays up (seen on the IC-7760), the CI-V flow is re-opened on the spot — recovery in seconds instead of the 35-second full reconnect.",
|
||||||
|
"Icom network: after a session dies young, the redial waits 20 s so the rig can purge the old session first — stops the reconnect-die-reconnect spiral seen on the IC-7760, where each fresh session answered for a second and was then strangled by the previous one’s cleanup."
|
||||||
],
|
],
|
||||||
"fr": [
|
"fr": [
|
||||||
"Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à l’affichage de la radio (il lisait environ deux points S trop bas).",
|
"Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à l’affichage de la radio (il lisait environ deux points S trop bas).",
|
||||||
@@ -38,7 +39,8 @@
|
|||||||
"Enregistreur de QSO : une prise manuelle sur un Icom réseau enregistre le flux RX réseau, pas la carte son « From Radio » (qui capturait le DAX d’une autre radio sur une station mixte).",
|
"Enregistreur de QSO : une prise manuelle sur un Icom réseau enregistre le flux RX réseau, pas la carte son « From Radio » (qui capturait le DAX d’une autre radio sur une station mixte).",
|
||||||
"Audio réseau Icom : les paquets dupliqués ou retransmis en retard n’atteignent plus l’enregistreur — les enregistrements sortaient plus longs que le QSO, ralentis et hachés, alors que les haut-parleurs jouaient bien.",
|
"Audio réseau Icom : les paquets dupliqués ou retransmis en retard n’atteignent plus l’enregistreur — les enregistrements sortaient plus longs que le QSO, ralentis et hachés, alors que les haut-parleurs jouaient bien.",
|
||||||
"Audio réseau Icom : il démarre maintenant avec l’application — au lancement, la connexion se faisait audio coupé, et il fallait décocher/recocher l’option pour entendre quelque chose.",
|
"Audio réseau Icom : il démarre maintenant avec l’application — au lancement, la connexion se faisait audio coupé, et il fallait décocher/recocher l’option pour entendre quelque chose.",
|
||||||
"Réseau Icom : quand la radio se tait sur le CI-V alors que la session tient (constaté sur l’IC-7760), le flux CI-V est rouvert immédiatement — récupération en quelques secondes au lieu des 35 secondes de reconnexion complète."
|
"Réseau Icom : quand la radio se tait sur le CI-V alors que la session tient (constaté sur l’IC-7760), le flux CI-V est rouvert immédiatement — récupération en quelques secondes au lieu des 35 secondes de reconnexion complète.",
|
||||||
|
"Réseau Icom : après une session morte jeune, la renumérotation attend 20 s pour que la radio purge d’abord l’ancienne session — stoppe la spirale reconnexion-mort-reconnexion vue sur l’IC-7760, où chaque session neuve répondait une seconde avant d’être étranglée par le nettoyage de la précédente."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+23
-1
@@ -56,6 +56,15 @@ func NewIcomNet(host, user, pass string, civAddr int, digitalDefault string, aud
|
|||||||
model: "Icom",
|
model: "Icom",
|
||||||
scopeFixed: true,
|
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) {
|
b.open = func() (civTransport, error) {
|
||||||
if strings.TrimSpace(host) == "" {
|
if strings.TrimSpace(host) == "" {
|
||||||
return nil, fmt.Errorf("no rig host configured")
|
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()
|
b.dialMu.Lock()
|
||||||
cancel := b.dialCancel
|
cancel := b.dialCancel
|
||||||
b.dialMu.Unlock()
|
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
|
return b
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user