contest: reset the qso when the form becomes empty

Users assume that backspacing the form will reset the start time.  Let's not
surprise them.

Note that if the form has whitespace, then it is not considered empty.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
xlua: grid helper script shouldn't use bad QSOs for points & mults

They should, however, be included in all QSOs list.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: move the stdout locking to the top level

This reduces the concurrency slightly, but it guarantees that all output for
a single packet is contiguous.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: dump info announcement CBOR payload

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: improve unknown announcement warning text

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: move hexdumping into a separate function

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: print a warning about received address being longer than xsockaddr

If we get one of these addresses, we print a warning and then NULL-out the
address pointer.  The printing function displays a "???" instead of trying
to use a NULL pointer.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: print source address for each announcement

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: print timestamp for non-announcement packets

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
watch: move timestamp printing to a helper function

This will make it easier to also print the source address.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
rpc: make sure 'all' notification callback is always invoked

Deduplication of 'qso' callbacks shouldn't affect the 'all' notification
callbacks.  We want 'all' to be called for every single announcement packet.
The type-specific callbacks can have their own semantics.  Currently that
means:

 - qso: deduplicated
 - loc, rig: called for each
 - info: no callback

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
rpc: constify announcement message args in tracking code

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
common: add time_set to set a struct time to an arbitrary timestamp

Additionally, this makes time_set_now a trivial wrapper.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
xlua: switch CQ-WW-VHF to grid helper

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
xlua: switch ARRL-VHF-{JAN,JUN,SEP} to grid helper

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
xlua: grid-based contest helper

Contest that use Maidenhead grid squares as the exchange are largely the
same.  They (almost) all have the concept of QSO points and multipliers.
Implementing those rules over and over is tedious and error prone.  This
helper object implements a generic contest with easy-to-use hooks to tweak
behavior based on the specific contest's rules.

Currently unused.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
contest: try to load all QSOs on start up

This invokes the qso-load event for each QSO in the log.  Currently, nothing
implements the load-qso event, so this turns into a big no-op.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
contest: add qso-load event

This event is used to notify the script about a qso entry that was added
outside its knowledge.  This can be used in the future for loading existing
entries on startup or when a new entry appears via wsjtx or announcements.

The big difference between qso-load and qso-done events is that qso-load
gets a read-only qso structure while qso-done gets a read-write qso struct.

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
contest: split startup event into startup and fill-template

The startup event is executed always.  The fill-template event is only
executed when there is a template to fill (i.e., it is not an export).

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
rpc: print a summary of hamlib quirks

Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Next