fix: the Yaesu keyer refused to send — a status reply we read too strictly
"the keyer buffer stayed full for 4s" and nothing keyed, on a rig whose CAT is working. The buffer was not full: the check demanded the reply be exactly "KY0;" with the digit at byte 2, so anything the FTDX10 phrases differently — a space before the digit, another command's reply arriving first — read as "still full" on every poll until the deadline. The test is now asymmetric on purpose: only a clear "1" holds the send back. Anything unrecognised goes ahead. Refusing to transmit because a status line was phrased unexpectedly is the worse failure — the operator gets silence with no explanation, where at worst sending early truncates a long message, which the chunk loop then recovers from. The reply is also logged once per run, since we have no verified sample of it — that line is what turns the next surprise into a fact instead of a theory.
This commit is contained in:
@@ -27,6 +27,10 @@ import (
|
||||
// split and fed as the rig drains its buffer.
|
||||
const yaesuCWChunk = 24
|
||||
|
||||
// cwStatusLogged makes the KY status reply appear in the log once per run: it
|
||||
// is a line we have no verified sample of, so the first one is worth keeping.
|
||||
var cwStatusLogged bool
|
||||
|
||||
// yaesuCWAllowed is what the rig's keyer can actually send. Anything else is
|
||||
// dropped rather than passed through: an unsupported byte can abort the whole
|
||||
// buffer, losing the rest of the message with no error anywhere.
|
||||
@@ -97,16 +101,57 @@ func (y *Yaesu) waitCWBuffer(within time.Duration) error {
|
||||
debugLog.Printf("yaesu cw: KY status query failed (%v) — sending anyway", err)
|
||||
return nil
|
||||
}
|
||||
if len(r) >= 3 && r[2] == '0' {
|
||||
return nil // room in the buffer
|
||||
// Only an explicit "full" holds us back.
|
||||
//
|
||||
// The first version required the reply to be exactly "KY0;" at byte 2, and
|
||||
// on a real FTDX10 that refused to send at all: anything the rig phrases
|
||||
// differently — a space before the digit, a longer status — read as "still
|
||||
// full" and the send died after four seconds having keyed nothing. The rig
|
||||
// is the one that knows; when its answer is not a clear "1", the right move
|
||||
// is to go ahead rather than to sit and time out.
|
||||
// Log the shape once per session: this is a reply we have no verified
|
||||
// sample of, and the log is what turns the next surprise into a fact.
|
||||
if !cwStatusLogged {
|
||||
cwStatusLogged = true
|
||||
debugLog.Printf("yaesu cw: KY status reply is %q (full=%v)", r, yaesuCWBufferFull(r))
|
||||
}
|
||||
if !yaesuCWBufferFull(r) {
|
||||
return nil
|
||||
}
|
||||
if time.Now().After(deadline) {
|
||||
return fmt.Errorf("yaesu: the keyer buffer stayed full for %s", within)
|
||||
return fmt.Errorf("yaesu: the keyer buffer stayed full for %s (last reply %q)", within, r)
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// yaesuCWBufferFull reads the KY status reply.
|
||||
//
|
||||
// Deliberately asymmetric: only a clear "1" means full. Anything else — an
|
||||
// unexpected shape, a reply from another command that arrived first, an empty
|
||||
// string — is treated as "go ahead". Refusing to send because a status line was
|
||||
// phrased unexpectedly is the worse failure: the operator gets silence with no
|
||||
// explanation, where at worst sending early truncates a long message.
|
||||
func yaesuCWBufferFull(reply string) bool {
|
||||
r := strings.TrimSpace(reply)
|
||||
if !strings.HasPrefix(strings.ToUpper(r), "KY") {
|
||||
return false
|
||||
}
|
||||
for _, c := range r[2:] {
|
||||
switch c {
|
||||
case '0':
|
||||
return false
|
||||
case '1':
|
||||
return true
|
||||
case ' ', ';':
|
||||
continue
|
||||
default:
|
||||
return false // not a status digit — don't block on it
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// filterYaesuCW upper-cases and strips what the keyer cannot send.
|
||||
func filterYaesuCW(text string) string {
|
||||
var b strings.Builder
|
||||
|
||||
Reference in New Issue
Block a user