This document specifies the proposed IPSC3 Master Exchange protocol,
identified on the wire as I3MX/1. It is a design specification
for authenticated, real-time exchange of talkgroup voice, private calls,
SMS, radio presence, and position reports between independent IPSC3
servers. The master implementation is running at
api.ipsc3.net:50710/udp. Node-side trunk clients are deployed on
the VK, UK, ZL, and US IPSC3 servers as ipsc3-vkdmr,
ipsc3-uk, ipsc3-zl, and ipsc3-us.
The master is a routing exchange, not another DMR endpoint. DMR timeslots remain local to each IPSC3 server. A participating server advertises its channels, selects remote channels, and maps those channels to its own talkgroup and timeslot policy at the local edge.
pcmu and dmr_ambe2. POC-origin calls publish synchronized variants under one canonical session: native PCMU for POC listeners and derived AMBE for DMR endpoints.I3MX/1.MUST, MUST NOT, SHOULD, and MAY describe protocol requirements.
An IPSC3 server configures the exchange as an IPSC3 Master Exchange
trunk. Only one such trunk may be configured on a server. The trunk stores
the stable certificate-bound server ID, master endpoint, local bind address,
and paths to the client certificate, private key, and master CA certificate.
ipsc3_master as the transport protocol while preserving the bounded source label, such as gps or wifi_cache. They are never republished to APRS-IS by the receiving node.Group voice is not exchanged merely because the trunk is enabled. Local talkgroups must be explicitly enabled for publication, and remote catalogue channels must be explicitly mapped to a local talkgroup, timeslot, and direction. This keeps similarly numbered channels on independent IPSC3 servers separate unless an administrator deliberately connects them.
The initial master includes a lightweight public runtime dashboard at api.ipsc3.net/master/. It has separate views for authenticated server connections and the combined advertised talkgroup catalogue.
POC client -- PCMU --> originating IPSC3 ----+
\
IPSC3 Master ----> remote IPSC3 ----> POC
/ |
DMR endpoint -- AMBE --> originating IPSC3 ---+ +----> remote IPSC3 ----> DMR
|
+----> bounded codec worker
Each IPSC3 server maintains one outbound, authenticated connection to the master. The master owns the network-wide channel floor and fans each accepted media variant to interested servers. A separate bounded codec worker beside the master may create a missing PCMU or AMBE variant once per call. Codec work MUST NOT execute in the master's control or media receive loop.
A source server sends its native codec and MAY also supply a derived variant it already has. The master only requests conversion when a required variant is missing. Receiving IPSC3 servers consume the appropriate variant and do not need to transcode merely to participate in the exchange.
| Plane | Transport | Use |
|---|---|---|
| Connection and control | QUIC v1 with TLS 1.3 | Authentication, catalogue, subscriptions, presence, call control, SMS, position, status, and keepalive. |
| Media | QUIC datagrams on the same authenticated connection | Sequenced PCMU and AMBE media without reliable-stream head-of-line blocking. |
ipsc3-master/1.api.ipsc3.net:50710/udp. The port remains deployment-configurable.server_id. A newer authenticated connection replaces an older connection from the same server instance.
Initial enrollment is operator-assisted: the node creates its private key and
CSR locally, and the master operator signs the CSR after approving the stable
server_id. The private key never leaves the node. The intended
automated enrollment sequence is:
server_id, hostname, and token over HTTPS.server_id.server_id cannot override it.HELLO with software version, boot instance, capabilities, and last known catalogue revision.HELLO_ACK with master identity, connection ID, server time, permissions, and required resynchronisation state.CATALOG_SNAPSHOT, or an accepted delta when both sides share the same base revision.READY before publishing calls or data.
Either side sends PING after 15 seconds without control traffic.
A connection is considered lost after 45 seconds without valid control or
transport activity. Reconnection uses exponential backoff with jitter. After
reconnect, catalogues, subscriptions, and presence are resynchronised; old
voice is never replayed.
{
"type": "CALL_START",
"protocol": "I3MX/1",
"message_id": "0194a1bd-7096-7e80-a161-970c80290001",
"sent_at_ms": 1787468400123,
"origin_server_id": "ipsc3-vkdmr",
"route_path": ["server:ipsc3-vkdmr"],
"body": {}
}
| Field | Type and bound | Meaning |
|---|---|---|
type | ASCII string, 1-64 characters | Control message type. |
protocol | Exact string I3MX/1 | Wire protocol version. |
message_id | UUIDv7 | Idempotency identifier for this control event. |
sent_at_ms | Unsigned 64-bit integer | UTC Unix time in milliseconds. |
origin_server_id | ASCII string, 1-64 characters | Server that first introduced the event. Immutable across forwarding. |
route_path | Array of at most eight bounded strings | Servers and IPSC3-aware exchanges already traversed. |
body | JSON object | Message-specific fields. |
| Message | Direction | Purpose |
|---|---|---|
HELLO, HELLO_ACK, READY | Both | Connection setup and negotiated capabilities. |
PING, PONG | Both | Keepalive and measured round-trip time. |
CATALOG_SNAPSHOT, CATALOG_DELTA | Both | Advertised channel state. |
SUBSCRIBE, UNSUBSCRIBE | Server to master | Remote channels and media profiles required by a server. |
PRESENCE_SNAPSHOT, PRESENCE_UPSERT, PRESENCE_REMOVE | Both | Leased roaming reachability. |
CALL_REQUEST, CALL_GRANT, CALL_DENY | Both | Pre-arranged floor control, primarily for POC-origin calls. |
CALL_START, CALL_ACCEPT, CALL_END | Both | Voice session lifecycle, including unscheduled DMR starts. |
MEDIA_REQUIREMENTS | Master to server | Codec variants currently required for an accepted call. |
SMS_SUBMIT, SMS_STATUS, SMS_ACK | Both | Idempotent SMS transit and delivery status. |
POSITION_REPORT | Server to master | Optional radio position replication. |
ERROR, RESYNC_REQUEST | Both | Bounded error reporting and state recovery. |
A numeric talkgroup is not globally unique. The canonical channel identifier is namespaced by the server that owns its policy:
ipsc3-vkdmr/505
ipsc3-uk/505
The two examples are distinct channels unless an administrator deliberately maps them. Clients MUST NOT infer a relationship from matching numeric talkgroup values.
{
"channel_id": "ipsc3-vkdmr/505",
"owner_server_id": "ipsc3-vkdmr",
"number": 505,
"name": "Australia Call Channel",
"call_type": "group_voice",
"routing_mode": "static",
"media_class": "mixed",
"publish": true,
"directions": ["send", "receive"],
"restrictions": [],
"available_codecs": ["dmr_ambe2", "pcmu"]
}
advertised, publish-enabled, subscribed, and locally mapped are separate states.A subscription identifies a remote channel and direction. The receiving server stores its own local talkgroup and timeslot mapping. Local mapping is deliberately absent from the master channel identity.
{
"type": "SUBSCRIBE",
"protocol": "I3MX/1",
"message_id": "0194a1bd-7096-7e80-a161-970c80290002",
"sent_at_ms": 1787468400220,
"origin_server_id": "ipsc3-uk",
"route_path": ["server:ipsc3-uk"],
"body": {
"channel_id": "ipsc3-vkdmr/505",
"direction": "both",
"accepted_codecs": ["dmr_ambe2", "pcmu"]
}
}
For example, the UK server may locally map the remote channel to TG505/TS1 while VKDMR locally uses TG505/TS2. The master sees one namespaced channel and no timeslot translation.
A server with a send or both mapping may publish into
the remote owner's channel. The channel owner is an implicit receive target
for that publication and does not subscribe to its own channel. Explicit
subscriptions are then added and deduplicated, so the owner receives one copy.
On the owner, the channel resolves through its enabled local trunk link and
the talkgroup's configured default timeslot. An explicit remote mapping still
takes precedence when one exists.
network_session_id.canonical_session_id; normally this is the same UUID as network_session_id.CALL_ACCEPT returns the canonical ID. A separately observed duplicate may be aliased to the first accepted canonical ID.CALL_DENY.
A future POC reservation extension may obtain CALL_GRANT before
the client is finally granted PTT. Version 1 clients currently use
CALL_START. DMR-origin calls cannot wait for a round trip, so
the server sends CALL_START and may immediately send early media.
The master may retain up to 300 ms of bounded early media while validating the
start, preventing the first syllable from being clipped. Denied early media
is discarded.
{
"type": "CALL_START",
"protocol": "I3MX/1",
"message_id": "0194a1bd-7096-7e80-a161-970c80290003",
"sent_at_ms": 1787468401000,
"origin_server_id": "ipsc3-vkdmr",
"route_path": ["server:ipsc3-vkdmr"],
"body": {
"network_session_id": "0194a1bd-7096-7e80-a161-970c80290100",
"channel_id": "ipsc3-vkdmr/505",
"call_type": "group_voice",
"source_radio_id": 5052540,
"source_instance_id": "optional-poc-instance",
"origin_protocol": "POC",
"source_stream_id": "1435003188",
"started_at_ms": 1787468401000,
"native_codec": "pcmu",
"offered_codecs": ["pcmu", "dmr_ambe2"]
}
}
| Codec ID | Name | Payload | Packet duration | Clock |
|---|---|---|---|---|
1 | pcmu | 160 G.711 mu-law bytes | 20 ms | 8000 Hz |
2 | dmr_ambe2 | Three canonical 9-byte AMBE+2 frames, 27 bytes total | 60 ms | 8000 Hz media timeline |
POC-originated audio MUST be available to the exchange before the existing PCMU-to-AMBE encoder. The source POC service applies its normal authenticated RTP validation, sequence recovery, and jitter reordering, then forwards the ordered 160-byte PCMU frames to the master media worker.
| Source | Destination | Master representation | Lossy conversion |
|---|---|---|---|
| POC | POC | Native PCMU | None after the client's PCMU encoding |
| POC | DMR | Derived AMBE | One PCMU-to-AMBE conversion |
| DMR | DMR | Native AMBE | None |
| DMR | POC | Derived PCMU | One AMBE-to-PCMU conversion |
Codec variants are parallel representations of the same call. They are not separate calls. A receiving server that has both DMR and POC listeners may receive both variants and MUST route each variant only to matching local endpoint classes.
(canonical_session_id, codec).CALL_START.All integer fields use network byte order.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | Magic | ASCII I3M1. |
| 4 | 1 | Codec ID | 1 PCMU, 2 DMR AMBE+2. |
| 5 | 1 | Flags | Bit 0 marker/start; remaining bits reserved and zero. |
| 6 | 2 | Header length | Currently 34. |
| 8 | 16 | Network session | Binary UUID bytes for the source network_session_id. The primary accepted source ID is the canonical session ID. |
| 24 | 4 | Sequence | Unsigned sequence number scoped to session and codec. |
| 28 | 4 | Timestamp | Unsigned media timestamp in 8000 Hz sample ticks. |
| 32 | 2 | Payload length | Number of following media bytes. |
| 34 | Variable | Payload | Codec payload described above. |
CALL_END message terminates a session. A datagram end flag is deliberately not required.Deduplication operates at session, codec, packet, and route levels. It MUST remain in bounded memory and MUST NOT perform database access from media handling.
CALL_START with the same network_session_id is idempotent.canonical_session_id.message_id returns the prior disposition without repeating the action.(canonical_session_id, codec_id).(canonical_session_id, codec_id, sequence).
The same DMR call may independently reach two IPSC3 servers through legacy
trunks that do not carry network_session_id. The master therefore
maintains a provisional duplicate detector using:
A second possible copy is held as a shadow ingress and is not fanned out. If the media fingerprint matches, it is attached to the existing canonical session and suppressed. If it does not match, normal floor-collision policy applies. The master MUST NOT merge calls using only Radio ID, talkgroup, and time; doing so could suppress legitimate quick re-keys or separate devices sharing one POC Radio ID.
Version 1 uses the first accepted ingress as the primary path. Automatic mid-call switching to a shadow path is outside version 1 because it could disturb sequence and audio timing.
origin_server_id and network_session_id are immutable.route_path.openbridge:TRUNK_ID or i3mx:MASTER_ID.Participating servers publish coarse, leased reachability rather than private endpoint details. A presence entry contains Radio ID, server ID, endpoint class, capabilities, last activity, and expiry. It does not expose source IP, hotspot password, repeater authentication, or local timeslot configuration.
{
"radio_id": 5052562,
"server_id": "ipsc3-vkdmr",
"client_instance_id": null,
"endpoint_class": "dmr_repeater",
"capabilities": ["private_voice", "sms"],
"last_activity_ms": 1787468400000,
"expires_at_ms": 1787511600000
}
network_session_id while the session is valid.message_id generated by the originating IPSC3 server.message_id.accepted, routed, delivered, failed, and expired.{
"type": "SMS_SUBMIT",
"protocol": "I3MX/1",
"message_id": "0194a1bd-7096-7e80-a161-970c80290300",
"sent_at_ms": 1787468405000,
"origin_server_id": "ipsc3-vkdmr",
"route_path": ["server:ipsc3-vkdmr"],
"body": {
"source_radio_id": 5052540,
"destination_radio_id": 5052562,
"encoding": "utf-8",
"text": "Testing IPSC3 Master SMS",
"expires_at_ms": 1787554805000
}
}
Position exchange is opt-in per server and policy. The master transports position results, not private WiFi fingerprints or radio configuration data.
{
"type": "POSITION_REPORT",
"protocol": "I3MX/1",
"message_id": "0194a1bd-7096-7e80-a161-970c80290400",
"sent_at_ms": 1787468406000,
"origin_server_id": "ipsc3-vkdmr",
"route_path": ["server:ipsc3-vkdmr"],
"body": {
"report_id": "0194a1bd-7096-7e80-a161-970c80290401",
"radio_id": 5052540,
"latitude": -33.874288,
"longitude": 151.220588,
"accuracy_m": 20,
"source": "gps",
"fix_time_ms": 1787468405000,
"fix_age_ms": 1000
}
}
report_id is the primary position dedupe key.Per-packet logging is disabled by default. Counters and periodic summaries are preferred so observability cannot become a media-path load problem.
HELLO.api.ipsc3.net:50710/udp with mandatory certificate authentication.127.0.0.1:8091/health, systemd hardening, UFW policy, certificate renewal restart, and operator CSR signing tools.pcmu and dmr_ambe2. DMR calls retain native AMBE, while POC-origin calls supply native PCMU and the existing derived AMBE variant under one call identity.poc protocol marker is retained through the master and local media gateway, so a remote POC client receives source: "poc" and can display its normal POC- caller indication. DMR-origin calls remain labelled DMR.