Skip to content

About

Android bridge: WSJT-X UDP (Xiegu X6100 FT8) -> online loggers

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

HAMLogBridge

An Android app that sits between your radio and your online logbooks. It listens for the WSJT-X UDP protocol (the same stream GridTracker, JTAlert and Log4OM read), saves every QSO the radio logs, and uploads it to Cloudlog/Wavelog, QRZ.com, Club Log, HRDLog.net, eQSL.cc or your own webhook. A copy always goes to a local ADIF file.

It was built for the Xiegu X6100 with FT8 firmware that sends WSJT-X packets over Wi-Fi or Bluetooth, but any sender of the protocol works, including WSJT-X and JTDX on a PC.

   Radio (X6100 FT8, WSJT-X, JTDX)
        β”‚  Wi-Fi UDP :2237   or   Bluetooth SPP
        β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  HAMLogBridge on the phone    │──── relay, byte for byte ───► GridTracker / Log4OM on a PC
   β”‚  Β· live decodes and rig state β”‚
   β”‚  Β· QSO log + local .adi file  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚ upload queue with retries
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β–Ό             β–Ό             β–Ό           β–Ό          β–Ό          β–Ό
 Cloudlog /    QRZ.com       Club Log    HRDLog.net   eQSL.cc    webhook
 Wavelog       Logbook

Contents


Install

  1. Download the newest HAMLogBridge-vX.Y.Z.apk from Releases.
  2. Install it on Android 8.0 or newer. You may need to allow installing apps from this source.
  3. Allow notifications when asked. The app runs as a foreground service and shows a notification while it is listening.
  4. Turn off battery optimization for the app: Settings β†’ Apps β†’ HAMLogBridge β†’ Battery β†’ Unrestricted. Without this, many phones (Xiaomi, Samsung, Huawei and others) put the network socket to sleep and packets stop arriving.

New versions install over old ones and keep your log and settings.

Quick start

  1. Setup β†’ Station: enter your callsign and grid square. Optionally fill in operator, TX power, rig and antenna (see station defaults).
  2. Setup β†’ Connection: pick how the radio connects (Wi-Fi, Bluetooth or both) and follow what the card tells you. For Wi-Fi it shows the exact address and port to type into the radio.
  3. Setup β†’ Loggers: switch on the services you use, fill in their keys and tap Check connection.
  4. Tap Start listening (on Monitor or in Setup β†’ Connection).
  5. Make a QSO. It appears in LogBook within a second or two, and the upload status of each logger is shown under it.

Connecting the radio

Wi-Fi (UDP)

The phone and the radio must be able to reach each other:

  • Same network: both on your home or field Wi-Fi, or
  • Phone hotspot: turn on the phone's hotspot and connect the radio to it. No router is needed, which is handy portable.

Then set the radio's UDP output to the address and port shown in Setup β†’ Connection β†’ "Set in the radio's UDP output". The default port is 2237, the same as WSJT-X. The app picks the phone's Wi-Fi or hotspot address and ignores the mobile-data address. If the phone has no Wi-Fi address, the card says so in red.

Other options:

  • Broadcast (e.g. 192.168.1.255) works too; the app listens on all interfaces.
  • Multicast: if the radio sends to a multicast group (e.g. 239.255.0.1), enter that group in Setup β†’ Receive β†’ Multicast group. The app then joins the group on the Wi-Fi interface, also when the phone is the hotspot.
  • Different port: change it in Setup β†’ Receive β†’ UDP port.

For WSJT-X or JTDX on a PC: Settings β†’ Reporting β†’ UDP Server, enter the phone's address and port.

Bluetooth

For X6100 firmware that sends the WSJT-X packets over Bluetooth SPP:

  1. Pair the radio in Android's Bluetooth settings. It pairs without a PIN. The card has an Open Bluetooth settings shortcut.
  2. Back in Setup β†’ Connection, choose Bluetooth and tap Choose radio, then pick it from the list of paired devices.
  3. Start listening. The card and the Monitor tab show connecting / connected.

The phone connects out to the radio and reconnects automatically if the link drops (1 s, then doubling up to 30 s between attempts). Each packet travels with a 4-byte length prefix; the app finds the right RFCOMM channel on its own, for both older firmware and v1.0.2+, where channel 1 is taken by CAT.

Both

Listens on Wi-Fi and Bluetooth at the same time. A packet that arrives over both links within 4 seconds is processed once, so nothing is logged or relayed twice.

The four tabs

Monitor

  • Rig panel: dial frequency, mode, your call and grid, the station you are working, and whether the radio is transmitting. Shows listening :port, BT connected, transmitting or error, plus a packet counter and the time of the last packet.
  • Start / Stop listening.
  • Band activity: live decodes, newest on top, with UTC time, SNR (number and bar), DT, audio offset in Hz and the message. CQ calls are highlighted green, lines with your callsign blue. Tap a line to open that station's QRZ.com page inside the app (with a button to open it in the browser).

Decodes are only shown; they are never logged. A decode is not a contact.

LogBook

Every logged QSO: callsign, band, mode, grid, time (UTC) and reports, with a coloured pill per logger (green = uploaded, amber = waiting, red = failed).

  • The header shows how many QSOs are logged, how many uploads are queued, and a Retry N button when some failed.
  • Tap a QSO to expand it: the last message from each logger (e.g. Duplicate, already in log or Bad API key), the full ADIF record, and Send again to enabled loggers.

Events

The event trace, newest first, in UTC: every packet type received and from where, every rejected packet (Ignored 14B from 10.0.0.5 (not WSJT-X)), socket and Bluetooth state changes, logged QSOs and duplicates. Keeps the last 200 entries; Clear empties it. This is the first place to look when the radio is transmitting but nothing shows up.

Setup

  • Station: callsign, grid, operator, TX power, rig, antenna.
  • Connection: live status (Connected to X6100 from 192.168.1.50, last packet 5s ago, Waiting for the radio, No packets for 2m, Not listening), connection mode, what to enter in the radio, and the Bluetooth radio picker.
  • Receive: UDP port, multicast group, relay targets, Start with the phone.
  • Loggers: one card per service with an on/off switch, its fields and Check connection.
  • Local copy: where the ADIF file is, Share ADIF file, Clear log.

The β“˜ button at the top shows a short how-to-connect guide and the version. The exit button stops listening and closes the app completely.

How QSOs are logged

Sources

Only two message types create a QSO:

Type Name What happens
5 QSO Logged The app builds an ADIF record from the fields and saves the QSO.
12 Logged ADIF A ready ADIF record from the sender. If it is the same QSO as a type 5 just received, it updates that entry (it usually carries more fields) instead of adding a second one.

Other types are used for display only:

Type Name Used for
0 Heartbeat detecting the sender
1 Status frequency, mode, DE/DX call, TX state on Monitor
2 Decode Band activity on Monitor
3 Clear clears Band activity
6 Close end of session
10 WSPR Decode read, not used yet

The reader is tolerant: firmware that sends only part of the fields (the X6100 often fills only the first few Status fields) is accepted. Anything that is not a WSJT-X packet is ignored and listed in Events.

Packets are processed one at a time, in the order they arrive.

Duplicates

A QSO is identified by callsign + start time to the minute (UTC) + band. WSJT-X sends each contact twice (types 5 and 12), and a radio may resend a packet; neither creates a second entry. Minute resolution is deliberate: the radio's and the phone's clocks may be a few seconds apart.

Station defaults

The radio usually sends only your callsign and grid. Whatever it leaves empty is filled in from Setup β†’ Station: station callsign, grid, operator, TX power, rig (MY_RIG), antenna (MY_ANTENNA). Values sent by the radio always win.

ADIF

Records follow ADIF 3.1.4. FT4, JS8 and Q65 are written as mode MFSK with the right submode; FT8 stays FT8. Frequency is always written with a dot (14.074000), whatever the phone's language. Field lengths are counted in bytes, so names with letters such as Ε‚, ΓΆ or Γ© are stored correctly.

Online loggers

Switch on as many as you like; every QSO goes to each enabled one.

Logger What you need Notes
Cloudlog / Wavelog Base URL, API key (read/write), station profile id Works with http:// addresses in your LAN, e.g. http://192.168.1.50/cloudlog. Check connection tests the key.
QRZ.com Logbook Logbook API key (QRZ Logbook β†’ Settings) Optional Replace duplicates (0/1). Check connection tests the key and shows how many QSOs the logbook has.
Club Log Account e-mail, password, logged callsign, API key (clublog.org/api) Real-time upload.
HRDLog.net Callsign, upload code (from your HRDLog account page)
eQSL.cc eQSL user, password; optional QTH nickname and QSL message The nickname is only needed if you have several QTHs.
Custom webhook Endpoint URL; optional format (adif or json) and extra headers, one per line adif POSTs the raw record. json POSTs call, band, mode, freq_hz, rst_sent, rst_rcvd, time_on, time_off (epoch ms), my_call, my_grid, grid and adif.

For services without a read-only test endpoint, Check connection only checks that the required fields are filled in; the credentials are then verified on the first QSO. Nothing is ever written to a remote log by a check.

Upload queue and errors

Each QSO gets one upload job per enabled logger, kept in the app's database and sent by Android's WorkManager whenever the phone has network. They survive app restarts and reboots.

Results fall into three groups:

  • Uploaded (green): accepted by the server. A server reply of duplicate also counts as uploaded, because the QSO is already in that log.
  • Temporary problem (amber): no network, server error (5xx), rate limit (429). Retried automatically with growing pauses (from 30 s), up to 12 attempts. After a temporary error, the rest of that logger's queue waits for the next attempt without using up its tries.
  • Permanent problem (red): wrong key or password, 401/403, record rejected. Not retried. After the first such error, the remaining QSOs for that logger are not sent in the same run either and are marked Not sent, an earlier QSO failed. This way 50 queued QSOs with a wrong password mean one failed login, not 50. That matters, because repeated failed logins can get an account blocked on QRZ or Club Log.

Fix the setting and tap Retry in LogBook to requeue everything that failed. Send again to enabled loggers on a single QSO re-sends it even if it was uploaded.

Local ADIF file

Every QSO is appended to an ADIF file right away, whether or not uploads work:

Android/data/pl.hamlogbridge/files/Documents/HamLogBridge/hamlogbridge-<year>.adi

One file per year (UTC). It is reachable over USB (MTP) from a PC, and Setup β†’ Local copy β†’ Share ADIF file sends it to e-mail, Drive or any other app. Clear log removes QSOs and upload history from the app, but leaves this file alone.

Android deletes this folder when the app is uninstalled. Share or copy the file before uninstalling.

Relay to a PC

Setup β†’ Receive β†’ Relay datagrams to forwards every packet received from the radio, unchanged, to one or more host:port targets, separated by commas:

192.168.1.10:2237, 192.168.1.10:2238

To the PC it looks as if WSJT-X were sending on the network, so GridTracker, JTAlert, Log4OM and similar programs keep working while the phone does the logging. Notes:

  • The relay sends only while the app is listening; packets are not stored for later.
  • Two programs on the same PC cannot listen on the same port; give each its own.
  • Do not relay to a broadcast address or to the phone itself on its listening port, or the phone will receive its own packets in a loop.

Running in the background

Listening runs in a foreground service with a permanent notification, so it keeps going with the screen off. It holds a Wi-Fi lock, a multicast lock and a partial wake lock; all three are needed on many phones even to receive broadcast packets.

  • Start with the phone (Setup β†’ Receive) starts listening after a reboot.
  • Battery optimization must still be off (see Install).
  • Stop with Stop listening, or close the app completely with the exit button.

Troubleshooting

Start with Setup β†’ Connection (is anything connected?) and then Events (what arrives, and from where?).

Symptom Likely cause
Waiting for the radio, nothing in Events The radio sends to a different address or port. Compare with Setup β†’ Connection. On a hotspot, check that the radio is really connected to it.
Worked for a while, then stopped with the screen off Battery optimization is still on for the app.
Events shows Ignored … (not WSJT-X) Something else sends to this port. Check the radio's output format or move to another port.
no Wi-Fi in red on the Connection card The phone is not on Wi-Fi and the hotspot is off.
Bluetooth stays at connecting Radio off or out of range, or its Bluetooth output is disabled. Re-pair if the firmware was just updated.
QSO in LogBook, red pill for a logger Expand the QSO to read the server's message, fix the setting, tap Retry.
QSO in LogBook, amber pill for a long time No internet, or the service is down. It retries on its own.

Not supported

  • LoTW. Uploading requires signing each record with the private key of a TQSL certificate, which cannot be done sensibly and safely on a phone. Share the ADIF file and sign it with TQSL on a PC, or let Cloudlog/Wavelog sync with LoTW.
  • Transmitting or controlling the radio. The app only listens; it never sends replies, halt-TX or free text to the radio.
  • Maps, DXCC tracking, worked/confirmed, alerts. Use GridTracker or JTAlert on a PC through the relay.

Security and privacy

  • Passwords and API keys are stored unencrypted in the app's private storage, and are included in Android's cloud backup of the app.
  • Plain http:// is allowed so that Cloudlog/Wavelog on a home server works; public services use HTTPS anyway.
  • The app sends data only to the loggers you enable, to relay targets you enter, and to qrz.com when you tap a decode.

Building from source

Requirements: JDK 17 and the Android SDK (or Android Studio). Without Android Studio, create local.properties with sdk.dir=... (see local.properties.example).

./gradlew test            # unit tests: protocol decoder and ADIF, no device needed
./gradlew assembleDebug   # APK: app/build/outputs/apk/debug/HAMLogBridge-v<version>.apk

Kotlin 2.0, Jetpack Compose, Room, WorkManager, OkHttp. minSdk 26, targetSdk 35.

app/src/main/java/pl/hamlogbridge/
β”œβ”€β”€ wsjtx/     WSJT-X protocol reader (plain Kotlin, no Android)
β”œβ”€β”€ adif/      building and parsing ADIF records (plain Kotlin, no Android)
β”œβ”€β”€ net/       UDP listener, Bluetooth source, relay, Wi-Fi/BT de-duplication
β”œβ”€β”€ data/      Room database, settings, Repository (ties everything together)
β”œβ”€β”€ upload/    one class per logger, upload worker, local ADIF writer
β”œβ”€β”€ service/   foreground service, start on boot
└── ui/        Monitor, LogBook, Events, Setup (Compose)

Adding a logger: implement LogTarget and add it to Targets.all. Its settings card, queue and retries work automatically.

Test status: the protocol reader and ADIF code have unit tests. The upload request formats follow each service's API documentation but have not all been tried against the live services yet; if an upload fails, the server's reply is shown on the QSO in LogBook.


Author: Kris, SP2KMO

About

Android bridge: WSJT-X UDP (Xiegu X6100 FT8) -> online loggers

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages