fix: CI-V address 00, simplex uploaded as split, and S/F spots
Three field reports. Icom CI-V address 00 could not be kept: zero was read as "not configured" in all three places that validate it, so every save put the rig back to the IC-7610's 0x98 — and the model dropdown followed, since it is derived from the address rather than stored. Picking "Other (custom address)" also had no effect of its own: the list re-derived itself and snapped back to whatever rig matched. It now stays chosen. Cloudlog/Wavelog showed "17m/17m" on ordinary FT8 contacts (OE6CLD). Every QSO is stamped with a receive side equal to the transmit side, and the uploaded record carried it; Wavelog draws band/band_rx whenever both are there. In ADIF an absent BAND_RX means "same as transmit", so the uploaded record now writes the receive side only when it differs. The copy forwarded to another logger over UDP keeps writing it in full — that is why it was stamped in the first place (Log4OM reads BAND_RX) — through its own ForwardRecordADIF. "S/F" in a spot comment joins superfox / sfox / F-H as FT8.
This commit is contained in:
+40
-5
@@ -120,12 +120,36 @@ func (e *Exporter) writeDoc(ctx context.Context, w io.Writer, iter iterator) (in
|
||||
func SingleRecordADIF(q qso.QSO) string {
|
||||
var b strings.Builder
|
||||
bw := bufio.NewWriter(&b)
|
||||
// Uploads target other services — keep it standard (no app-specific tags).
|
||||
// Uploads target other services — keep it standard (no app-specific tags),
|
||||
// and say nothing about the receive side when there is nothing to say: in
|
||||
// ADIF an absent BAND_RX/FREQ_RX means "same as transmit", and a logger
|
||||
// given both draws both. Wavelog reads a simplex FT8 contact uploaded with
|
||||
// BAND_RX filled in as split and shows it as "17m/17m".
|
||||
writeRecord(bw, q, false, nil)
|
||||
bw.Flush()
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// ForwardRecordADIF is the record sent to ANOTHER LOGGER on the UDP link.
|
||||
//
|
||||
// The receive side is written even when it repeats the transmit side, which is
|
||||
// the opposite of the upload rule above and is deliberate: Log4OM reads BAND_RX
|
||||
// and found nothing there for contacts logged by a path that left it blank. A
|
||||
// logger on the same desk is being handed a copy of our record, not published
|
||||
// to a service that will draw conclusions from every tag present.
|
||||
func ForwardRecordADIF(q qso.QSO) string {
|
||||
var b strings.Builder
|
||||
bw := bufio.NewWriter(&b)
|
||||
writeRecord(bw, q, false, nil, keepRX)
|
||||
bw.Flush()
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// keepRX marks a record whose receive side must be written out in full.
|
||||
type rxMode int
|
||||
|
||||
const keepRX rxMode = 1
|
||||
|
||||
// FullRecordADIF serialises one QSO LOSSLESSLY — including the APP_* extras —
|
||||
// so it can be written out and read back with nothing dropped. Used by the
|
||||
// offline queue: a QSO parked in the safety file must come back identical
|
||||
@@ -161,7 +185,18 @@ func BatchRecordsADIF(records []string) string {
|
||||
// Empty fields are omitted. MODE/SUBMODE are massaged so a "promoted"
|
||||
// mode (e.g. FT4 stored without a parent) is exported as the canonical
|
||||
// pair MODE=MFSK SUBMODE=FT4 — round-trips cleanly with strict loggers.
|
||||
func writeRecord(bw *bufio.Writer, q qso.QSO, includeApp bool, allow map[string]bool) {
|
||||
func writeRecord(bw *bufio.Writer, q qso.QSO, includeApp bool, allow map[string]bool, rx ...rxMode) {
|
||||
// The receive side, unless it merely repeats the transmit side. See
|
||||
// SingleRecordADIF and ForwardRecordADIF.
|
||||
bandRX, freqRX := q.BandRX, q.FreqRXHz
|
||||
if len(rx) == 0 || rx[0] != keepRX {
|
||||
if strings.EqualFold(strings.TrimSpace(bandRX), strings.TrimSpace(q.Band)) {
|
||||
bandRX = ""
|
||||
}
|
||||
if freqRX != nil && q.FreqHz != nil && *freqRX == *q.FreqHz {
|
||||
freqRX = nil
|
||||
}
|
||||
}
|
||||
// allow == nil → write every promoted field (standard/full behaviour).
|
||||
// Otherwise a promoted tag is written only when it's in the chosen set.
|
||||
// w/wi/wf wrap the raw writers with that gate so the ~150 field lines below
|
||||
@@ -194,7 +229,7 @@ func writeRecord(bw *bufio.Writer, q qso.QSO, includeApp bool, allow map[string]
|
||||
w("TIME_OFF", q.QSODateOff.UTC().Format("150405"))
|
||||
}
|
||||
w("BAND", q.Band)
|
||||
w("BAND_RX", q.BandRX)
|
||||
w("BAND_RX", bandRX)
|
||||
|
||||
mode, submode := modeForExport(q.Mode, q.Submode)
|
||||
w("MODE", mode)
|
||||
@@ -203,8 +238,8 @@ func writeRecord(bw *bufio.Writer, q qso.QSO, includeApp bool, allow map[string]
|
||||
if q.FreqHz != nil && *q.FreqHz > 0 {
|
||||
w("FREQ", strconv.FormatFloat(float64(*q.FreqHz)/1_000_000, 'f', 6, 64))
|
||||
}
|
||||
if q.FreqRXHz != nil && *q.FreqRXHz > 0 {
|
||||
w("FREQ_RX", strconv.FormatFloat(float64(*q.FreqRXHz)/1_000_000, 'f', 6, 64))
|
||||
if freqRX != nil && *freqRX > 0 {
|
||||
w("FREQ_RX", strconv.FormatFloat(float64(*freqRX)/1_000_000, 'f', 6, 64))
|
||||
}
|
||||
|
||||
w("RST_SENT", q.RSTSent)
|
||||
|
||||
@@ -43,7 +43,7 @@ var icnBE = binary.BigEndian
|
||||
// = CI-V only (the proven default). The audio stream is fully separate from CAT,
|
||||
// so enabling it can't affect freq/mode/DSP control.
|
||||
func NewIcomNet(host, user, pass string, civAddr int, digitalDefault string, audioSink func([]byte)) *IcomSerial {
|
||||
if civAddr <= 0 || civAddr > 0xFF {
|
||||
if civAddr < 0 || civAddr > 0xFF {
|
||||
civAddr = 0x98 // IC-7610
|
||||
}
|
||||
if digitalDefault == "" {
|
||||
|
||||
@@ -172,12 +172,13 @@ const (
|
||||
)
|
||||
|
||||
// NewIcomSerial builds an (unconnected) Icom serial backend. baud defaults to
|
||||
// 115200, rig address to the IC-7610's 0x98 when out of range.
|
||||
// 115200, rig address to the IC-7610's 0x98 when out of range — and 0x00 is in
|
||||
// range: it is a valid CI-V address that some rigs and interfaces are set to.
|
||||
func NewIcomSerial(portName string, baud, civAddr int, digitalDefault string) *IcomSerial {
|
||||
if baud <= 0 {
|
||||
baud = 115200
|
||||
}
|
||||
if civAddr <= 0 || civAddr > 0xFF {
|
||||
if civAddr < 0 || civAddr > 0xFF {
|
||||
civAddr = 0x98 // IC-7610
|
||||
}
|
||||
if digitalDefault == "" {
|
||||
|
||||
Reference in New Issue
Block a user