# JG.25 Native Digital Link Specification **Document status:** Experimental Draft v0.2 **Date:** 2026-08-16 **Scope:** Clean-sheet amateur-radio digital link and service protocol for the OpenJSQ/JG waveform family. **Interoperability status:** Not frozen. This draft records the current simulated design so implementations can be built and real-radio tests can begin. > **Important:** Numerical SNR thresholds, exact payload-tone plans, acquisition sequences, FEC puncturing, and adaptation parameters in this document are the current simulation-derived profile. They MUST be treated as provisional until validated over real radios, particularly the FT-8800 → RF → VR-N76 path. ## 1. Purpose and design goals JG.25 is a native packet protocol designed for a family of voice-band 4-FSK waveforms rather than as an extension of AX.25. Its goals are: 1. High delivered goodput through ordinary amateur FM voice radios. 2. Graceful operation from weak links through strong local links. 3. Fast interactive chat plus efficient files, mail, presence, actions, and relaying. 4. Selective-repeat reliability rather than stop-and-wait or go-back-N. 5. Independent adjacent-link reliability and end-to-end message semantics. 6. Safe custodial store-and-forward semantics for emergency communications. 7. Efficient multi-frame bursts with independent recovery of every frame. 8. A waveform and decoder practical on PCs, sound-card/DigiRig interfaces, and embedded TNC-class hardware such as a future custom Mobilinkd implementation. 9. Automatic adaptation based on delivered goodput rather than nominal raw bit rate. Normative terms **MUST**, **SHOULD**, and **MAY** have their usual requirements-language meanings within this experimental draft. ## 2. Protocol architecture ```text Application Services Chat / Presence / Mail / Files / Actions / Groups | End-to-End Service Envelope stable Message ID / origin / final destination / receipts / custody | JG.25 Link Layer sessions / next hop / selective ARQ / fragmentation / priority / bursts | JG PHY Family JG1200 ... JG2400 / F0 ... F3 | FM voice-band radio channel ``` JG.25 is independent of AX.25. OpenJSQ MAY support AX.25/Bell-202 separately for APRS/KISS interoperability. ## 3. PHY terminology and common conventions ### 3.1 Symbols and bit mapping All native JG payload modes use 4-FSK and carry two coded bits per symbol. Symbol-to-tone mapping uses Gray coding: | Dibit | Symbol index | Tone | |---|---:|---| | `00` | 0 | lowest tone | | `01` | 1 | second tone | | `11` | 2 | third tone | | `10` | 3 | highest tone | The simulation baseline is **continuous-phase 4-FSK (CPFSK)**: phase remains continuous while the selected instantaneous frequency changes at symbol boundaries. Gaussian shaping has not been adopted. ### 3.2 Sampling Reference PC audio I/O is 48 kHz mono PCM. A receiver MAY resample to a lower internal rate; the simulations commonly used 12 kHz internally. Wire behavior is defined by tone frequencies and symbol timing, not by a required ADC sample rate. ### 3.3 Byte and bit order Unless a field explicitly states otherwise: - Multi-byte integers are transmitted most-significant byte first. - Within an octet, bit 7 is transmitted before bit 0 before FEC/interleaving. - Symbol digits `0`–`3` in sequence definitions refer to the Gray-mapped tone indices above. ## 4. Native JG waveform family The provisional family is: | Mode ID | Name | Baud | Raw bit/s | Current payload tones (Hz) | Intended role | |---:|---|---:|---:|---|---| | `000` | JG1200 | 600 | 1200 | 500 / 1100 / 1700 / 2300 | extreme robustness | | `001` | JG1400 | 700 | 1400 | 725 / 1275 / 1825 / 2375 | weak link | | `010` | JG1600 | 800 | 1600 | 775 / 1325 / 1875 / 2425 | weak/normal | | `011` | JG1800 | 900 | 1800 | 475 / 1125 / 1775 / 2425 | normal | | `100` | JG2000 | 1000 | 2000 | 525 / 1175 / 1825 / 2475 | good link | | `101` | JG2200 | 1100 | 2200 | 475 / 1125 / 1775 / 2425 | strong link | | `110` | JG2400 | 1200 | 2400 | 500 / 1200 / 1900 / 2600 | very strong link | | `111` | reserved | — | — | — | future mode | The names equal the raw bit rate. Tone plans are **not yet frozen** and MUST be rechecked on real radios. ## 5. Initial acquisition JG uses a nested two-length acquisition structure followed by a common robust PHY header. ### 5.1 Acquisition tones and rate - Modulation: 4-FSK CPFSK - Baud: **600** - Tones: **500 / 1100 / 1700 / 2300 Hz** ### 5.2 NORMAL acquisition profile - Preamble: **48 symbols** - Sync: **20 symbols** - Preamble airtime: 80.0 ms - Sync airtime: 33.33 ms Preamble sequence, base-4 symbol digits: ```text 221002203312213231310103230210301122001311233030 ``` Sync sequence: ```text 00223310112132013023 ``` ### 5.3 ROBUST acquisition profile ROBUST begins with the exact same 48-symbol prefix and then adds a 48-symbol extension before the same sync word. 96-symbol preamble: ```text 221002203312213231310103230210301122001311233030021031131323120323022321131300203323201201020011 ``` Sync sequence: ```text 00223310112132013023 ``` Because the profiles are nested, the receiver can test for sync after the 48-symbol prefix and continue listening for the robust extension if sync does not appear. ### 5.4 Profile selection A sender SHOULD use NORMAL for ordinary links and ROBUST for weak links, important custody/mail transfers, acquisition recovery, or after repeated acquisition failures. The adaptation controller MAY select ROBUST whenever the negotiated/estimated link is in the lower JG modes or weak SNR region. ## 6. Universal PHY header The header is intentionally slower and more robust than any payload mode. ### 6.1 Header waveform - Modulation: 4-FSK CPFSK - Baud: **350** - Tones: **950 / 1350 / 1750 / 2150 Hz** - Uncoded information: 16 bits - Header CRC: 16 bits - FEC: K=7 rate-1/2 convolutional code - Tail: six zero termination bits - Encoded length: 76 coded bits - Header interleaver: provisional 8-row bit interleaver - 4-FSK symbols: 38 - Airtime: **108.57 ms** ### 6.2 Header information word The 16-bit information word is: ```text 15 13 12 11 10 0 +--------------+----------+----------------------------+ | PHY mode (3) | FEC (2) | decoded frame length (11) | +--------------+----------+----------------------------+ ``` - **PHY mode:** values in Section 4. - **FEC:** values in Section 7. - **frame length:** 0–2047 octets. It is the number of decoded JG.25 frame-body octets following the PHY header, **including the JG.25 CRC-32C**. ### 6.3 Header CRC-16 Current simulation profile: - CRC: CRC-16/CCITT polynomial `0x1021` - Initial value: `0xFFFF` - No final XOR in the current simulation profile - CRC is calculated over the two information octets and appended most-significant byte first. The resulting 32 bits are convolutionally encoded. ### 6.4 Header convolutional code Current baseline: - Constraint length K=7 - Generators: octal `(171, 133)` - Mother rate: 1/2 - Encoder starts in state 0 and is terminated by six zero input bits. - Receiver SHOULD use soft-decision Viterbi decoding. ## 7. Payload FEC profiles The FEC field is: | FEC ID | Name | Nominal rate | Current definition | |---:|---|---:|---| | `00` | F0 | 1 | no body FEC | | `01` | F1 | ~3/4 | K=7 `(171,133)`, puncture pattern `111001` over mother-code output | | `10` | F2 | ~2/3 | K=7 `(171,133)`, puncture pattern `1110` | | `11` | F3 | 1/2 | unpunctured K=7 mother code | The current body interleaver is a **provisional 32-row bit interleaver** for coded profiles. Exact rectangular ordering/padding MUST be frozen before interoperable release. F0 carries no convolutional redundancy but still uses the normal JG.25 CRC-32C. ## 8. Payload frame coding pipeline The current transmitter pipeline is: ```text JG.25 frame header + extensions + service payload ↓ CRC-32C appended ↓ (optional future whitening — currently disabled/TBD) ↓ F0/F1/F2/F3 coding ↓ body interleaver for coded profiles ↓ Gray dibit mapping ↓ selected JG 4-FSK waveform ``` The receiver applies the inverse process and MUST accept a reliable frame only after CRC-32C validation. **Whitening is not yet part of the frozen simulation profile.** A polynomial/reset rule may be added after targeted testing. ## 9. Receiver acquisition, timing, and frequency recovery A practical receiver SHOULD use the following architecture: ```text continuous audio ↓ preamble correlation / multiple timing hypotheses ↓ sync confirmation ↓ coarse packet start + common frequency-offset estimate ↓ 350-baud universal header decode ↓ mode / FEC / length known ↓ buffer payload frame ↓ block/non-data-aided sample-clock search ↓ ISI-aware soft 4-FSK likelihoods ↓ deinterleave ↓ soft FEC decode ↓ CRC-32C ``` Simulation showed that a naive per-symbol timing loop can chase ISI at high baud rates; block clock estimation is the preferred baseline. ## 10. JG.25 link-layer frame ### 10.1 Fixed base header Every JG.25 link frame begins with a **5-octet base header**: ```text Octet 0 Control Octets 1–2 Context ID Octets 3–4 Sequence ``` ### 10.2 Control octet ```text 7 6 5 3 2 1 0 +--------+------------+-+-+-+ | ver(2) | class (3) |E|A|P| +--------+------------+-+-+-+ ``` - `ver`: link format version. Initial experimental value `00`. - `class`: frame class. - `E`: extension area present. - `A`: ACK requested. - `P`: priority/urgent indication. ### 10.3 Frame classes | class | Name | Purpose | |---:|---|---| | `000` | BEACON | presence/discovery | | `001` | OPEN | establish link/session context | | `010` | DATA | reliable session data | | `011` | DATAGRAM | connectionless message | | `100` | ACK | selective acknowledgement | | `101` | CONTROL | link control/management | | `110` | CUSTODY | custody/store-and-forward control | | `111` | EXTENDED | future/extended class | ### 10.4 Context ID The 16-bit Context ID identifies an established adjacent-link session. It is local to the peer/session and is not globally unique. Context ID zero SHOULD be reserved for connectionless/control usage. OPEN negotiation MUST prevent a stale pre-restart context from being mistaken for a current one. The exact session nonce/epoch field is still TBD. ### 10.5 Sequence The 16-bit Sequence field is the link-frame sequence number within a reliable context. Modular arithmetic MUST be used. The initial selective-repeat receive window is **32 frames**. ## 11. Extensions If `E=1`, the base header is followed by one octet containing the total extension-area length, then compact TLVs. TLV header: ```text 7 4 3 0 +------------+------------+ | type (4) | length (4) | +------------+------------+ ``` `length` is the value length in octets, 0–15. A future escape type MAY support longer values. Current provisional type registry: | Type | Name | Notes | |---:|---|---| | `0x0` | SOURCE | compact station address | | `0x1` | DESTINATION | compact station address | | `0x2` | SERVICE | application service ID | | `0x3` | SACK | selective ACK data when not using compact ACK body | | `0x4` | FRAGMENT | object/block fragmentation | | `0x5` | MESSAGE_ID | stable end-to-end ID | | `0x6` | PRIORITY | service/object priority | | `0x7` | CAPABILITIES | station/modem/service capabilities | | `0x8` | ROUTE | relay/routing information | | `0x9` | TIMESTAMP | optional timestamp | | `0xA` | SESSION_NONCE | proposed restart/stale-context protection | | `0xB` | BURST_INFO | proposed burst metadata | | `0xC–0xE` | reserved | future standard use | | `0xF` | ESCAPE | extended/private format | Types `0xA` and `0xB` are architectural placeholders and are not yet wire-frozen. ## 12. Compact station addressing Normal amateur station addresses use five octets with no hash collisions for six-character normalized callsigns. ### 12.1 Normal format Normalize the base callsign to six characters using the alphabet: ```text space A B ... Z 0 1 ... 9 ``` Values are: - space = 0 - A–Z = 1–26 - 0–9 = 27–36 Encode six base-37 digits into a 32-bit unsigned integer: ```text value = d0·37^5 + d1·37^4 + ... + d5 ``` Append one format/SSID octet: ```text high nibble = address format low nibble = SSID 0–15 ``` Initial format `0x0` is the normal six-character base-37 address. Format `0xF` is reserved to indicate an extended address representation carried by an extension. All five octets `0xFF` are reserved for broadcast. ## 13. Session establishment An OPEN frame establishes a Context ID and carries, directly or by extension: - source station - destination station - service - capabilities as needed - session nonce/epoch Once the context is established, normal DATA frames SHOULD omit source/destination/service information already known from the context. This is a major JG.25 efficiency mechanism. ## 14. Selective-repeat ARQ Reliable sessions use selective repeat. - Initial receive window: **32 frames**. - Receiver ACKs a base sequence and a 32-bit bitmap. - A set bit indicates the corresponding frame is held correctly. - Sender retransmits only missing frames. - Go-back-N is not used. - ACK information MAY be piggybacked on outbound DATA. ### 14.1 Compact ACK frame The current efficient ACK model is: ```text 5-byte JG.25 base header 4-byte receive bitmap 4-byte CRC-32C ``` The ACK frame's Sequence field is the SACK base sequence; bitmap bit `i` refers to `base + i` modulo 65536. ### 14.2 Fast turnaround ACK After a known burst transaction, the receiver SHOULD use a short reverse synchronization marker and compact ACK rather than paying full initial acquisition/header overhead again. The current simulation baseline used a short mode-rate reverse sync; the exact final ACK marker sequence is TBD. ## 15. Multi-frame bursts JG.25 SHOULD support multiple independent frames under one PTT assertion. ```text full acquisition + PHY header frame N short resync frame N+1 short resync frame N+2 ... PTT off fast SACK ``` Every frame retains its own sequence, FEC result, and CRC-32C. Loss of one frame MUST NOT invalidate later frames in the same burst. ### 15.1 Provisional inter-frame resync lengths The marker uses the **same tones and baud rate as the current payload mode**. | Mode | Marker symbols | Airtime | |---|---:|---:| | JG1200 | 32 | 53.3 ms | | JG1400 | 32 | 45.7 ms | | JG1600 | 20 | 25.0 ms | | JG1800 | 16 | 17.8 ms | | JG2000 | 16 | 16.0 ms | | JG2200 | 12 | 10.9 ms | | JG2400 | 12 | 10.0 ms | Current optimized marker candidates include: ```text 12 symbols: 232110313020 16 symbols: 3123013120310202 ``` The 20- and 32-symbol sequences MUST be frozen after real-radio sequence testing. ### 15.2 Burst airtime policy Burst length is an **airtime budget**, not a fixed frame count. Initial controller targets: | Channel state | Target | |---|---:| | quiet | ~8 s | | normal shared channel | ~6 s | | busy/collision-prone | ~3 s | | absolute initial cap | 10 s | At 128-byte payloads and a ~6 s cap, simulations produced approximately 4 frames/burst at JG1200–1600, 6 at JG1800–2000, and 8 at JG2200–2400. ## 16. Link adaptation The controller jointly selects: ```text PHY rate × FEC × frame payload size × burst airtime ``` The controller MUST optimize expected delivered goodput, not merely choose the highest nominal PHY rate. ### 16.1 Provisional PHY/FEC ladder These thresholds are **simulation calibration values, not protocol constants**: | Enter at/above estimated SNR | State | |---:|---| | below −7.4 dB | JG1200-F3 | | −7.4 dB | JG1200-F2 | | −6.5 dB | JG1400-F2 | | −5.5 dB | JG1600-F2 | | −4.5 dB | JG1800-F2 | | −3.5 dB | JG2000-F2 | | −2.5 dB | JG2000-F1 | | −1.8 dB | JG2200-F2 | | −1.2 dB | JG2200-F1 | | −0.4 dB | JG2400-F1 | | +4.4 dB | JG2000-F0 | | +6.2 dB | JG2200-F0 | | +6.9 dB | JG2400-F0 | The apparent transition from JG2400-F1 to JG2000-F0 is intentional: uncoded JG2000 can have greater delivered information rate than 3/4-coded JG2400 on a clean link. ### 16.2 Hysteresis Initial implementation guidance: - EWMA SNR: approximately 50% prior estimate / 50% newest measurement. - Apply about 0.2 dB normal conservatism. - If the previous burst delivered <55% of frames, apply about 0.55 dB additional pessimism. - If <25% delivered, apply about 1.1 dB additional pessimism. - Downshift immediately when evidence becomes bad. - Upgrade only after two consecutive recommendations, at least ~0.25 dB beyond the next threshold, and recent frame success ≥70%. These rules are local implementation policy and do not alter the on-air frame format. ### 16.3 Frame payload size Provisional adaptation: | Predicted FER | Payload target | |---:|---:| | >16% | 64 B | | 5.5–16% | 128 B | | ≤5.5% | 256 B | | very clean F0, <0.8% | 512 B | 256 B is the current default candidate for normal reliable DATA. ## 17. Channel access JG.25 MUST respect carrier activity and SHOULD avoid transmitting into a busy channel. Collision/random-backoff details have not yet been frozen. Repeated collisions SHOULD cause shorter bursts and randomized delay before retry. ## 18. Service IDs and application services Initial service categories are: - Chat - Presence - Mail - File - Station Action - Group Message - Routing/Discovery - future standardized/private ranges Exact numeric SERVICE IDs are not frozen in this draft. ## 19. Presence and capabilities Presence uses compact connectionless BEACON frames. A beacon SHOULD carry: - source - sequence - capability bits - status flags - optional locator/status Capabilities SHOULD advertise supported JG modes, FEC profiles, file/mail/custody/relay functionality, and other service features. The CAPABILITY_RESPONSE `capability_flags` word (u16) as allocated by the OpenJSQ implementation, permanent once merged: | Bit | Name | Meaning | |---:|---|---| | 0 | verified chat | Verified (ARQ) chat is bound. | | 1 | station actions | The station-action service is bound. | | 2 | files | The reliable file service is bound. | | 3 | mail custody | Custodial mail is bound. | | 4 | delivery receipts | JSQ delivery receipts are generated. | | 5 | application relay | The station will carry for others (follows consent, live). | | 6 | heard lists | Heard requests are answered. | | 7 | mailbox | The mailbox actions are served. | | 8 | shared library | The station UNDERSTANDS `library_list` / `library_fetch`; says nothing about whether anything is offered. | | 9 | shared files available | VOLATILE, per recipient: shared files are currently available to the station this response is addressed to, under the sender's access policy. Decided as the response is built; withdrawn by a later response without it. The JSQ capability `file.shared` maps to this bit, never to bit 8. | A beacon (0x03) carries the presence policy flags only, not this word; whether a capability word should ride the beacon is a separate decision. ## 20. End-to-end durable objects Mail, files, and other durable relayed objects MUST preserve stable end-to-end identity independent of adjacent-link sessions. A durable object requires at minimum: - version/service - flags - stable random **64-bit Message ID** (current recommendation) - immutable origin - immutable final destination - object length - payload and optional metadata A relay MUST NOT replace origin, final destination, or Message ID with its own identity. The exact compact service-envelope wire layout remains TBD. ## 21. Custodial mail semantics JG.25 distinguishes three acknowledgements: 1. **Link ACK:** an adjacent radio frame was received. 2. **Custody ACK:** the complete durable object was validated, durably stored, indexed, and queued for forwarding. 3. **Delivery receipt:** the final destination accepted the object. An origin MUST NOT mark mail as parked merely because adjacent frames were ACKed. Example: ```text W4IJG → KK4IB → N4UZZ ``` KK4IB MAY send CUSTODY ACCEPT only after durable storage and forwarding-queue insertion. Only then may W4IJG mark the object `PARKED_AT(KK4IB)`. Provisional custody operations: - OFFER - ACCEPT - REJECT - STATUS - RELEASE - DELIVERED Provisional durable states: - CREATED - QUEUED - TRANSFERRING - PARKED_AT - FORWARDING - DELIVERED - EXPIRED - FAILED Crash/restart behavior MUST preserve accepted custody. ## 22. File transfer and fragmentation Files are end-to-end objects transported as resumable blocks across JG.25 frames. - Missing one link frame MUST NOT invalidate the whole file. - Resume SHOULD occur at block granularity. - Final file integrity SHOULD be verified with SHA-256. - Link fragmentation and end-to-end object/block segmentation MUST remain separate concepts. Exact block sizes and FRAGMENT extension layout remain TBD. ## 23. Priority The base header provides a one-bit priority indication. Services MAY also carry a richer PRIORITY extension. Channel scheduling MUST avoid starvation of normal traffic; exact priority queues are TBD. ## 24. AX.25 and KISS coexistence JG.25 is not AX.25 and does not fit through an ordinary radio's internal AX.25 KISS TNC unless that device implements JG natively. OpenJSQ MAY expose separate backends: - AX.25/Bell-202 via conventional KISS for interoperability. - JG.25 via PC audio/DigiRig. - JG.25 via a future native modem API on devices such as custom Mobilinkd firmware. A native modem API should expose at least mode, FEC, frame bytes, receive confidence/SNR, frequency offset, and decode status. ## 25. Items deliberately not frozen The following MUST remain experimental until further testing: 1. Final payload tone frequencies on real radio paths. 2. Exact 20- and 32-symbol inter-frame marker sequences. 3. Body interleaver serialization/padding rules. 4. Whitening polynomial/reset behavior, if whitening is retained. 5. Session nonce/epoch exact wire layout. 6. BURST_INFO exact wire layout. 7. Numeric service IDs. 8. Durable service-envelope exact byte format. 9. Fragment/block exact byte format. 10. Channel-access/backoff constants. 11. Real-radio SNR calibration and all adaptation thresholds. 12. Whether short LDPC or another code should replace/augment the K=7 convolutional baseline. 13. The ACTION_RESPONSE status vocabulary. The wire byte has seven values (ok, not_found, disabled, refused, unsupported, busy, error), so the shared-folder answers `stale_reference`, `too_large` and `invalid` fold into `error` and `refused` and a requester cannot tell a stale listing from a failure. Widening it to carry those values distinctly is a wire change that requires a protocol/schema bump and is deferred until after Bench B; until then the requester treats an `error` answering a fetch as "the list may have changed" (frozen in the desktop tests). ## 26. Required real-radio validation before wire freeze The next validation stage SHOULD use at least the available FT-8800/DigiRig and VR-N76 path and measure: 1. Audio passband and level versus frequency. 2. Every JG mode's packet FER versus received level/SNR. 3. NORMAL and ROBUST acquisition false/miss rates. 4. 350-baud header reliability. 5. Frequency-offset estimates and sample-clock estimates. 6. F0–F3 coding under real correlated errors. 7. 64/128/256/512-byte frame goodput. 8. Inter-frame resync after intentionally corrupted frames. 9. Fast SACK turnaround. 10. Adaptive-controller behavior under changing RF conditions. Only after those tests should numeric tone plans and controller thresholds be declared stable. ## Appendix A — Current acquisition sequences ### NORMAL 48-symbol preamble ```text 221002203312213231310103230210301122001311233030 ``` ### ROBUST 96-symbol preamble ```text 221002203312213231310103230210301122001311233030021031131323120323022321131300203323201201020011 ``` ### Shared 20-symbol sync ```text 00223310112132013023 ``` ## Appendix B — Current wire-format summary ```text NORMAL acquisition: 48 symbols @ 600 baud 4-FSK 20 sync symbols @ 600 baud ROBUST acquisition: 96 symbols @ 600 baud 4-FSK 20 sync symbols @ 600 baud Universal PHY header: 16 info bits = mode(3) | FEC(2) | frame_length(11) + CRC-16 = 32 bits K=7 rate-1/2 + 6 tail bits -> 76 coded bits 8-row provisional interleaver 38 symbols @ 350 baud 4-FSK Payload: JG1200 ... JG2400 F0 ... F3 JG.25 frame body CRC-32C Reliable burst: independent frames + mode-rate resync markers fast reverse SACK selective retransmission only ```