fix(decodes): a decode's mode is a marker, not a mode name
Every station on an already-worked band was flagged NEW MODE. A WSJT-X Decode does not carry the mode's name. It carries the one-character marker from the decode line - "~" for FT8, "+" for FT4 - and that character was passed straight through as though it were a mode. The status resolver then compared "~" against the modes worked for the entity, matched nothing, and concluded the mode had never been worked. Same cause put "~ -07" in the comment of every decode spot pushed to the FlexRadio panadapter, which nobody had traced back. Resolved through a marker table, with the mode from the sender's last Status as the fallback - Status is the message that carries the real name. So an unlisted or future marker degrades to correct rather than to nonsense, and a sender that puts the name in the field directly is believed as-is. With neither available the mode is left empty, which makes the resolver answer "worked": the safe side, since a wrong mode invents a new-mode flag exactly as the marker did.
This commit is contained in:
@@ -453,3 +453,50 @@ func readQString(r *bytes.Reader) (string, error) {
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
// decodeModeChar maps the single character WSJT-X puts in a Decode's mode field
|
||||
// to the mode it stands for.
|
||||
//
|
||||
// A Decode does NOT carry the mode's name. It carries the one-character marker
|
||||
// that appears in the decode line and in ALL.TXT — "~" for FT8, "+" for FT4 —
|
||||
// and that character was being passed straight through as if it were a mode.
|
||||
// Everything downstream then compared "~" against the modes in the log, matched
|
||||
// nothing, and called every station on an already-worked band a new MODE.
|
||||
//
|
||||
// The table covers what is common; anything missing falls back to the mode from
|
||||
// the sender's last Status, which carries the real name — so an unlisted or
|
||||
// future marker degrades to correct rather than to nonsense.
|
||||
var decodeModeChar = map[string]string{
|
||||
"~": "FT8",
|
||||
"+": "FT4",
|
||||
"#": "JT65",
|
||||
"@": "JT9",
|
||||
"&": "MSK144",
|
||||
":": "Q65",
|
||||
"`": "FST4",
|
||||
}
|
||||
|
||||
// DecodeModeName resolves a Decode's mode field to a real mode name. statusMode
|
||||
// is the mode from the same program's last Status, used when the field is a
|
||||
// marker we do not know, or empty.
|
||||
func DecodeModeName(raw, statusMode string) string {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if m, ok := decodeModeChar[raw]; ok {
|
||||
return m
|
||||
}
|
||||
// A mode name is at least two alphanumeric characters ("FT8", "JS8", "Q65").
|
||||
// Anything shorter, or carrying punctuation, is a marker rather than a name.
|
||||
if len(raw) >= 2 {
|
||||
named := true
|
||||
for _, r := range raw {
|
||||
if !(r >= 'A' && r <= 'Z') && !(r >= 'a' && r <= 'z') && !(r >= '0' && r <= '9') {
|
||||
named = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if named {
|
||||
return strings.ToUpper(raw)
|
||||
}
|
||||
}
|
||||
return strings.ToUpper(strings.TrimSpace(statusMode))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user