Configure (message 15), mode field only, every other field sent as no-change: an FT4 spot clicked while WSJT-X sits in FT8 lands the operator ready to decode instead of staring at gibberish. Sent to every instance heard this session — one already in the right mode treats it as a no-op — and only for modes the decoder actually speaks (FT8/FT4/JT65/JT9/MSK144/ Q65/FST4); CW and SSB are none of its business. Toggle in the Connections panel, on by default.
48 lines
2.1 KiB
Go
48 lines
2.1 KiB
Go
package udp
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
|
|
"hamlog/internal/applog"
|
|
)
|
|
|
|
// WSJT-X Configure (message 15) — change the decoder's settings remotely. Used
|
|
// for ONE thing here: clicking an FT4 spot while the decoder sits in FT8
|
|
// switches its mode too, so the operator lands ready to decode instead of
|
|
// staring at a band of gibberish. Every other field is sent as "no change"
|
|
// (empty strings, max-quint32), per the protocol.
|
|
const wsjtMsgConfigure = 15
|
|
|
|
// EncodeConfigureMode builds a Configure datagram that changes only the mode.
|
|
func EncodeConfigureMode(programID, mode string) []byte {
|
|
const noChange32 = ^uint32(0)
|
|
var b bytes.Buffer
|
|
_ = binary.Write(&b, binary.BigEndian, uint32(wsjtMagic))
|
|
_ = binary.Write(&b, binary.BigEndian, uint32(2))
|
|
_ = binary.Write(&b, binary.BigEndian, uint32(wsjtMsgConfigure))
|
|
writeQString(&b, programID)
|
|
writeQString(&b, mode) // Mode
|
|
_ = binary.Write(&b, binary.BigEndian, noChange32) // Frequency Tolerance — no change
|
|
writeQString(&b, "") // Submode — no change
|
|
_ = binary.Write(&b, binary.BigEndian, uint8(0)) // Fast Mode — off (right for every HF mode)
|
|
_ = binary.Write(&b, binary.BigEndian, noChange32) // T/R Period — no change
|
|
_ = binary.Write(&b, binary.BigEndian, noChange32) // Rx DF — no change
|
|
writeQString(&b, "") // DX Call — no change
|
|
writeQString(&b, "") // DX Grid — no change
|
|
_ = binary.Write(&b, binary.BigEndian, uint8(0)) // Generate Messages — no
|
|
return b.Bytes()
|
|
}
|
|
|
|
// SendConfigureMode asks every decoder heard this session to switch mode.
|
|
// Sent to all instances rather than one: the spot click does not say which
|
|
// decoder the operator is looking at, and a second instance already in the
|
|
// right mode treats the message as a no-op.
|
|
func (m *Manager) SendConfigureMode(mode string) {
|
|
for _, inst := range m.Instances() {
|
|
if err := m.sendToInstance(inst, EncodeConfigureMode(inst, mode), "configure-mode"); err == nil {
|
|
applog.Printf("udp: asked %q to switch to %s", inst, mode)
|
|
}
|
|
}
|
|
}
|