fix(rigctld): stop refusing two commands JTDX sends in Fake It
From a user's log, repeating throughout the session: rigctld: split off failed: cat: this radio's backend cannot set split rigctld: unimplemented command "X PKTUSB -1" Both are answered with an error, and JTDX treats a rig-control error as fatal: it abandoned a transmission 0.86 seconds into a 13.8-second frame. "S 0" — split OFF. Fake It uses no split, and JTDX still sends this to be sure. A backend that cannot SET split was refusing a request that was ALREADY satisfied. It now succeeds when the rig is simplex, without touching the rig at all. Arming still fails loudly: there the request is real and unmet, and a client that believes it transmits up the band while the radio sits on the DX's frequency is exactly what that refusal exists to prevent. "X <mode>" — set_split_mode. Sent during ordinary setup, Fake It included, where there is no second VFO to give a mode to. Accepted now: applied when a split is in force, and a plain success otherwise, because the transmit VFO already has that mode — it is the same VFO. get_split_mode answers to match. Both regressions fail without the fix with the exact codes from that log, RPRT -9 and RPRT -11.
This commit is contained in:
@@ -421,6 +421,17 @@ func (s *Server) handle(line string) (resp string, quit bool) {
|
||||
return rprt(0), false
|
||||
}
|
||||
s.splitWanted.Store(false)
|
||||
// Already simplex? Then there is nothing to do and the request is
|
||||
// satisfied. Reporting a failure here is what broke JTDX in "Fake It":
|
||||
// Fake It uses no split, JTDX still sends "S 0" to be sure, and a backend
|
||||
// that cannot SET split answered an error to a request that was already
|
||||
// true. JTDX read that as rig control failing and abandoned the
|
||||
// transmission a second into the frame.
|
||||
//
|
||||
// A refusal is only honest when something actually needed doing.
|
||||
if on, _ := s.rig.Split(); !on {
|
||||
return rprt(0), false
|
||||
}
|
||||
if err := s.rig.SetSplit(false, 0); err != nil {
|
||||
s.log("rigctld: split off failed: %v", err)
|
||||
return rprt(-9), false
|
||||
@@ -450,6 +461,34 @@ func (s *Server) handle(line string) (resp string, quit bool) {
|
||||
s.log("rigctld: split ON, TX %.0f Hz", hz)
|
||||
return rprt(0), false
|
||||
|
||||
case "X", "\\set_split_mode":
|
||||
// "X <mode> <passband>" — the mode of the TRANSMIT VFO.
|
||||
//
|
||||
// Accepted rather than refused. WSJT-X and JTDX send it as part of their
|
||||
// normal setup even in "Fake It", where there is no split and therefore no
|
||||
// second VFO to give a mode to; answering "not implemented" made JTDX give
|
||||
// up on rig control mid-transmission.
|
||||
//
|
||||
// The mode is applied when there IS a split — the transmit VFO is a real
|
||||
// one then. Without split the request has no target and succeeding is the
|
||||
// honest answer: the transmit VFO already has that mode, because it is the
|
||||
// same VFO.
|
||||
if len(args) < 1 {
|
||||
return rprt(-1), false
|
||||
}
|
||||
if on, _ := s.rig.Split(); !on {
|
||||
return rprt(0), false
|
||||
}
|
||||
if err := s.rig.SetMode(args[0]); err != nil {
|
||||
s.log("rigctld: split mode %q failed: %v", args[0], err)
|
||||
return rprt(-9), false
|
||||
}
|
||||
return rprt(0), false
|
||||
case "x", "\\get_split_mode":
|
||||
// Mirrors X: the transmit VFO's mode and passband. Without split that is
|
||||
// simply the current mode.
|
||||
return s.rig.Mode() + "\n2400\n", false
|
||||
|
||||
default:
|
||||
// A frame ending in ';' is not a rigctl command at all — it is raw rig
|
||||
// dialect (Kenwood/Elecraft/Yaesu), which means the client is configured
|
||||
|
||||
Reference in New Issue
Block a user