fix: Kenwood split read from FR/FT when the status frame omits it
Reported from a Flex in Kenwood CAT mode: frequency read perfectly, split never appeared. Not every rig speaking this dialect fills IF's split bit. Rather than guess which column that firmware populates, ask the question that DEFINES split — is the transmit VFO a different VFO from the receive one — which is exactly what FR and FT answer, and the same rule the Yaesu backend settled on after several wrong turns. FR is also trusted over IF for which VFO is in use: they are asked in the same breath, and a rig vague about the split bit may be just as vague about the VFO field. Cost is bounded: a rig that rejects FR/FT answers "?;" once and is never asked again, so this is two short commands per poll only where it works. Both paths are tested against the emulator — split found through FR/FT with IF silent, and IF-reported split still working on a rig that refuses FR/FT without re-asking. Also extends the CAT wire trace to the Kenwood backend, ASCII quoted so an empty reply is visible as such: "" and ";" look identical unquoted, and telling them apart is the whole question when a rig half-supports a command. If this fix is not the whole story on real hardware, the trace is what will say so.
This commit is contained in:
+34
-18
@@ -75,37 +75,53 @@ func DebugLogPath() string {
|
||||
return filepath.Join(base, "OpsLog", "cat.log")
|
||||
}
|
||||
|
||||
// ── CI-V byte trace ────────────────────────────────────────────────────────
|
||||
// ── CAT wire trace ─────────────────────────────────────────
|
||||
//
|
||||
// Opt-in, off by default. Turning it on logs every CI-V frame sent and received
|
||||
// as hex, exactly like the WinKeyer protocol trace.
|
||||
// Opt-in, off by default. Turning it on logs every frame sent and received —
|
||||
// CI-V as hex, the ASCII backends (Kenwood, Yaesu) as the text they exchange.
|
||||
//
|
||||
// That trace exists because a fault nobody could reason about — "the keyer sends
|
||||
// one element then stalls" — was settled in one line the moment the actual bytes
|
||||
// were visible. The CI-V link has now produced the same class of report: a MOX
|
||||
// button that sets split instead of transmitting, on a rig whose PTT command is
|
||||
// demonstrably correct in the source. Guessing at that from the command table
|
||||
// has already cost this project a wrong fix; the bytes will say what the rig was
|
||||
// really asked.
|
||||
var civTrace atomic.Bool
|
||||
// It exists because a fault nobody could reason about — "the keyer sends one
|
||||
// element then stalls" — was settled in one line the moment the actual bytes
|
||||
// were visible, and the CAT links have since produced the same class of report:
|
||||
// a MOX button that sets split instead of transmitting, and a split the Kenwood
|
||||
// backend does not recognise on a rig whose frequency it reads perfectly.
|
||||
//
|
||||
// Both are questions about what the RIG actually said. Guessing at that from a
|
||||
// protocol document has already cost this project a wrong fix that broke the
|
||||
// case which already worked.
|
||||
var catTrace atomic.Bool
|
||||
|
||||
// SetCIVTrace turns the CI-V byte trace on or off.
|
||||
// SetCIVTrace turns the CAT wire trace on or off. Named for the CI-V link it
|
||||
// was written for; it now covers the text backends too.
|
||||
func SetCIVTrace(on bool) {
|
||||
civTrace.Store(on)
|
||||
catTrace.Store(on)
|
||||
if on {
|
||||
debugLog.Printf("civ trace ON — every CI-V frame to and from the rig is logged")
|
||||
debugLog.Printf("wire trace ON — every CAT frame to and from the rig is logged")
|
||||
} else {
|
||||
debugLog.Printf("civ trace OFF")
|
||||
debugLog.Printf("wire trace OFF")
|
||||
}
|
||||
}
|
||||
|
||||
// CIVTraceEnabled reports whether the trace is running (for the settings UI).
|
||||
func CIVTraceEnabled() bool { return civTrace.Load() }
|
||||
func CIVTraceEnabled() bool { return catTrace.Load() }
|
||||
|
||||
// traceCIV logs one frame. dir is "TX" (to the rig) or "RX" (from it).
|
||||
// traceCIV logs one CI-V frame. dir is "TX" (to the rig) or "RX" (from it).
|
||||
func traceCIV(dir string, b []byte) {
|
||||
if !civTrace.Load() || len(b) == 0 {
|
||||
if !catTrace.Load() || len(b) == 0 {
|
||||
return
|
||||
}
|
||||
debugLog.Printf("civ %s % X", dir, b)
|
||||
}
|
||||
|
||||
// traceText logs one ASCII exchange, for the Kenwood and Yaesu backends.
|
||||
//
|
||||
// The text is QUOTED. A truncated or empty reply must be visible as such
|
||||
// rather than vanish into the line: "" and ";" look identical unquoted, and
|
||||
// telling them apart is the whole question when a rig answers a command it
|
||||
// does not really support.
|
||||
func traceText(backend, dir, s string) {
|
||||
if !catTrace.Load() || s == "" {
|
||||
return
|
||||
}
|
||||
debugLog.Printf("%s %s %q", backend, dir, s)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user