SimTX API v24/Data types
This page defines the primitive types and shared structures used in the SimTX API game protocol. Every packet layout in the reference is written in terms of these types.
Byte order
All multi-byte values are big-endian (network byte order). This matches Java's DataOutputStream, which the reference implementation uses, and Python's struct format prefix >.
Primitive types
| Type | Size | Description | Python struct
|
|---|---|---|---|
u8 |
1 | Unsigned 8-bit integer. | B
|
i8 |
1 | Signed 8-bit integer. | b
|
bool |
1 | 0 is false; any other value is read as true. Writers must send 0 or 1. |
?
|
u16 |
2 | Unsigned 16-bit integer. | H
|
i16 |
2 | Signed 16-bit two's-complement integer. | h
|
i32 |
4 | Signed 32-bit two's-complement integer. | i
|
i64 |
8 | Signed 64-bit two's-complement integer. | q
|
f32 |
4 | IEEE 754 binary32 floating point. | f
|
f64 |
8 | IEEE 754 binary64 floating point. | d
|
Unless a field description says otherwise, floating-point values must be finite. A NaN or infinity in a request field usually causes the server to close the connection.
Strings
The protocol has two string encodings. Using the wrong one is the most common cause of a connection that closes for no visible reason.
UTF
UTF is Java's modified UTF-8 as written by DataOutputStream.writeUTF:
u16 byteLength number of bytes that follow (not characters)
u8[...] bytes modified UTF-8
Modified UTF-8 differs from standard UTF-8 in two ways:
- The character U+0000 is encoded as the two bytes
C0 80, never as a single00byte. - Characters outside the Basic Multilingual Plane (U+10000 and above, which includes most emoji) are encoded as a UTF-16 surrogate pair, each surrogate written as a separate three-byte sequence. A four-byte UTF-8 sequence is invalid.
For text consisting only of characters in U+0001 to U+FFFF, modified UTF-8 is byte-for-byte identical to standard UTF-8. Clients that restrict callsigns and other text to the BMP and reject control characters can use an ordinary UTF-8 encoder. The maximum length is 65,535 bytes; most fields impose a much smaller limit.
UTF-8 bytes
Fields of the TransmitterSessionRequest TLV list, and the NEC deck inside AntennaConfig, carry standard UTF-8 with an explicit i32 length supplied by the surrounding structure. These are marked UTF-8 in layouts.
Enumerations
Enumerated values are sent as strings containing the constant name, for example "USB". Matching is case-sensitive. An unknown name in a request closes the connection.
Modulation
| Name | Description | Typical bandwidth |
|---|---|---|
AM_DSB_FC |
AM, double sideband, full carrier | 10 kHz |
AM_DSB_SC |
AM, double sideband, suppressed carrier | 6 kHz |
USB |
Upper sideband | 2.7 kHz |
LSB |
Lower sideband | 2.7 kHz |
CW |
Continuous wave (Morse) | 150 Hz |
NFM |
Narrow FM | 12.5 kHz |
WFM |
Wide FM | 180 kHz |
IQ |
External complex baseband supplied by the client | As declared |
WSPR |
Weak Signal Propagation Reporter | 6 Hz |
FT8 |
FT8 | 50 Hz |
See Modulation Modes for how each mode behaves on air.
TransmissionSourceType
| Name | Meaning |
|---|---|
AUDIO_STREAM |
Mono audio streamed by the client, for example a file or a network stream. |
MICROPHONE |
Mono audio from a microphone. Identical to AUDIO_STREAM on the wire.
|
PIPEWIRE |
Mono audio from a desktop audio graph. Identical to AUDIO_STREAM on the wire.
|
GNU_RADIO_IQ |
Complex baseband streamed by the client. Use with modulation IQ.
|
WHITE_NOISE |
Generated by the server. Only valid for role TX_GENERATED.
|
The three audio types differ only in how they are labelled. A third-party client normally uses AUDIO_STREAM or GNU_RADIO_IQ.
AntennaType
DIPOLE, VERTICAL, YAGI_3EL, YAGI_5EL, LOOP, BEVERAGE, LONGWIRE, INVERTED_V, EFHW_32M_49_1. Each is described in Antenna System and its linked pages.
WeatherMapType
See WeatherMapRequest.
CatalogType
See CatalogList.
GeoPoint
A position on the WGS 84 ellipsoid. 24 bytes.
| Field | Type | Description |
|---|---|---|
latitudeDeg |
f64 |
Latitude in degrees, −90 to 90. North is positive. |
longitudeDeg |
f64 |
Longitude in degrees, −180 to 180. East is positive. |
altitudeMeters |
f64 |
Height of the station site in metres. Antenna height is given separately in AntennaConfig. |
AntennaConfig
Describes a station's antenna. Variable length; at least 26 bytes.
| Field | Type | Description |
|---|---|---|
type |
UTF |
An AntennaType name. |
heightMeters |
f32 |
Height of the antenna above ground, ≥ 0. |
azimuthDeg |
f32 |
Bearing of the main lobe or of the wire, in degrees from true north. |
feedlineLossDb |
f32 |
Feed line loss in dB, ≥ 0. |
wireLengthMeters |
f32 |
Wire or element length in metres, ≥ 0. |
necDeckLength |
i32 |
Length of the following deck in bytes, 0 to 262,144. |
necDeck |
u8[necDeckLength] |
A NEC-2 card deck in standard UTF-8, or empty. |
When necDeck is not empty it replaces the built-in antenna model: the server solves the geometry itself and derives feed-point impedance, SWR and radiation pattern from it. The type field must still contain a valid name. Supported cards and limits are described in NEC File Import. An invalid deck closes the session. There is no way to upload a precomputed radiation pattern.
Example: a 20 m dipole at 10 m with no deck.
00 06 44 49 50 4F 4C 45 UTF "DIPOLE"
41 20 00 00 heightMeters 10.0
00 00 00 00 azimuthDeg 0.0
00 00 00 00 feedlineLossDb 0.0
41 A0 00 00 wireLengthMeters 20.0
00 00 00 00 necDeckLength 0
Callsign
A callsign identifies a station in station lists. It is trimmed of surrounding whitespace and must contain 1 to 64 characters with no control characters. In a transmitter request it is limited to 64 bytes of UTF-8. SimTX does not check callsigns against any licensing database.
Station UUID
Stations are identified by a UUID in its canonical 36-character text form, for example 3f2504e0-4f89-11d3-9a0c-0305e82c3301, carried as UTF. The server assigns it when a session starts.
TLV field list
Some packets carry a list of tagged fields, so that fields can be added without breaking older clients:
u8 count
count × {
u8 fieldId
i32 length number of payload bytes
u8[length] payload
}
Numeric payloads are a single f32 or i32 (length 4). String payloads are standard UTF-8 without a further length prefix. A reader skips fields whose ID it does not know. See TransmitterSessionRequest and TxUpdate.
Layout notation
Packet pages describe layouts as tables in wire order. Repeated groups are written count × { … }. A field shown as u8[n] is exactly n raw bytes. Packet bodies never contain padding or alignment bytes.