Skip to content

docs/JAMULUS_PROTOCOL.md: message reference, directory flows, small fixes#3794

Open
mcfnord wants to merge 7 commits into
jamulussoftware:mainfrom
mcfnord:enhance-protocol-doc
Open

docs/JAMULUS_PROTOCOL.md: message reference, directory flows, small fixes#3794
mcfnord wants to merge 7 commits into
jamulussoftware:mainfrom
mcfnord:enhance-protocol-doc

Conversation

@mcfnord

@mcfnord mcfnord commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

One file. Fills the main gaps in the protocol doc, verified against src/protocol.cpp / src/socket.cpp / src/serverlist.cpp on current main:

  • How a receiver tells protocol packets from audio packets (they share one port; parse-or-audio in CSocket::ProcessPacket()), the CRC parameters, and how acknowledge/retransmit actually works — previously the doc said only "must be acknowledged".
  • A complete message-ID reference table for both message classes, with the legacy IDs called out. This is the piece a Wireshark user or protocol reader currently has to reconstruct from protocol.h.
  • A new section on directories: registration and refresh/timeout intervals, server-list responses (why both reduced and full lists are sent), and the CLM_SEND_EMPTY_MESSAGE/CLM_EMPTY_MESSAGE NAT hole-punch flow — previously undocumented here despite being a third of the connectionless messages.
  • Fixes message names that drifted from protocol.h (REQ_CHANNEL_INFOS, CHANNEL_INFOS, REQ_CONN_CLIENTS_LIST).

CHANGELOG: SKIP

🤖 Generated with Claude Code

…ixes

- Explain how receivers classify datagrams (protocol frame vs audio)
  and specify the CRC and the acknowledge/retransmit mechanism
- Add a complete message-ID reference for connection-based and
  connectionless messages
- Add a section on directory registration, server lists and NAT hole
  punching (registration refresh/timeout intervals, CLM message flows)
- Fix message names to match protocol.h (REQ_CHANNEL_INFOS,
  CHANNEL_INFOS, REQ_CONN_CLIENTS_LIST)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ann0see
ann0see self-requested a review July 17, 2026 22:08
Comment thread docs/JAMULUS_PROTOCOL.md Outdated
| 34 | `REQ_SPLIT_MESS_SUPPORT` | Request split-message support |
| 35 | `SPLIT_MESS_SUPPORTED` | Split messages are supported |
| 36 | `RAWAUDIO_SUPPORTED` | Raw (uncompressed) audio is supported |
| 2001 | `SPECIAL_SPLIT_MESSAGE` | Container for split messages |

@pljones pljones Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without commentary, this looks peculiar.

2001 is a different type of message from the (other) connection-oriented messages. I'd not put it in the same table.

Comment thread docs/JAMULUS_PROTOCOL.md Outdated

## Directory Registration and Server Lists

A directory is a Jamulus server acting as a registry (implemented in `src/serverlist.cpp`, both roles). All directory traffic uses connectionless messages:

@pljones pljones Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check through and make sure the following adhere to the style guide:

  • Client
  • Server
  • Directory

all always capitalised when referring to Jamulus "running as a...". The style guide covers a few other things.

Probably applies to the other docs as well.

Comment thread docs/JAMULUS_PROTOCOL.md Outdated
mcfnord and others added 3 commits July 18, 2026 12:46
Co-authored-by: Peter L Jones <pljones@users.noreply.github.com>
Per review: Client, Server and Directory capitalised when referring to
Jamulus in that role, per https://jamulus.io/contribute/Style-and-Tone.
Also applies the guide's other defined terms present here (Channel,
Jitter Buffer), sentence-case headings, and unit spacing (48 kHz).
Code identifiers, message names and file paths unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… unregister wording

SPECIAL_SPLIT_MESSAGE (2001) moved out of the connection-based table
into its own paragraph explaining it is a transport container, not a
message type, though each fragment frame is acknowledged/retransmitted
(per CProtocol::ParseMessageBody). Connectionless range stated as
1000-1999. Unregister line takes pljones's suggested wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ann0see ann0see added the AI AI generated or potentially AI generated label Jul 21, 2026
Comment thread docs/JAMULUS_PROTOCOL.md

The CRC is 16 bits, generator polynomial x¹⁶ + x¹² + x⁵ + 1 (CCITT), initial state all ones, calculated over the entire message and transmitted inverted.

Audio and protocol messages share one UDP port. A receiver classifies every incoming datagram by attempting to parse it as a protocol frame — zero TAG bytes, consistent length, valid CRC. Anything that fails this parse is treated as an audio packet (see `CSocket::ProcessPacket()` in `src/socket.cpp`).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will probably change soon since we have TCP support then. Probably worth thinking about rephrasing this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the TCP PR, we can add a sentence or paragraph here explaining that certain messages can arrive over TCP, but any that don't parse correctly are dropped and not treated as audio.

Comment thread docs/JAMULUS_PROTOCOL.md

Connection-based messages (acknowledged; `PROTMESSID_` prefix omitted). Full payload layouts are in the header comment of `src/protocol.cpp`.

| ID | Name | Purpose |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thing is that this may get out of date. Maybe it's better to just link the source file. It should already have descriptions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to have as part of this document. Once a message has been defined and merged to main, it is set in stone and will not change. The only out-of-date-ness would be if a new message was defined and didn't get added here. We can always add a comment in protocol.h reminding to update this file too.

@ann0see
ann0see requested a review from softins July 23, 2026 09:17

@softins softins left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. Just a few comments and suggested changes.

Comment thread docs/JAMULUS_PROTOCOL.md

Connection-based messages (acknowledged; `PROTMESSID_` prefix omitted). Full payload layouts are in the header comment of `src/protocol.cpp`.

| ID | Name | Purpose |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to have as part of this document. Once a message has been defined and merged to main, it is set in stone and will not change. The only out-of-date-ness would be if a new message was defined and didn't get added here. We can always add a comment in protocol.h reminding to update this file too.

Comment thread docs/JAMULUS_PROTOCOL.md

The CRC is 16 bits, generator polynomial x¹⁶ + x¹² + x⁵ + 1 (CCITT), initial state all ones, calculated over the entire message and transmitted inverted.

Audio and protocol messages share one UDP port. A receiver classifies every incoming datagram by attempting to parse it as a protocol frame — zero TAG bytes, consistent length, valid CRC. Anything that fails this parse is treated as an audio packet (see `CSocket::ProcessPacket()` in `src/socket.cpp`).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the TCP PR, we can add a sentence or paragraph here explaining that certain messages can arrive over TCP, but any that don't parse correctly are dropped and not treated as audio.

Comment thread docs/JAMULUS_PROTOCOL.md Outdated
Comment thread docs/JAMULUS_PROTOCOL.md Outdated
Comment thread docs/JAMULUS_PROTOCOL.md Outdated
Comment thread docs/JAMULUS_PROTOCOL.md
The OPUS codec is used to compress the audio over the network and the packets are documented [here](https://datatracker.ietf.org/doc/html/rfc6716).

Jamulus uses a custom OPUS encoder / decoder, giving some different frame sizes, but always uses a 48kHz sample rate. OPUS and OPUS64 codecs are the only supported options currently.
Jamulus uses a custom OPUS encoder / decoder, giving some different frame sizes, but always uses a 48 kHz sample rate. OPUS and OPUS64 codecs are the only supported options currently.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we should mention the new raw audio option here now.

mcfnord and others added 3 commits July 23, 2026 10:00
Co-authored-by: Tony Mountifield <tony@mountifield.org>
Co-authored-by: Tony Mountifield <tony@mountifield.org>
Co-authored-by: Tony Mountifield <tony@mountifield.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI AI generated or potentially AI generated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants