Skip to main content

GBX Protocol Description

gbx is a binary serialization format for data handling within GSS (GRID Software Suite) and related software (PpRx). The gbx format defines the binary representation of several reports (sometimes referred to as messages). gbx.

Table of Contents

  1. Conventions
  2. Numeric Data Types
  3. GBX File/Stream Structure
  4. GBX Report Structure
  5. GBX Stream Structure
  6. Deserialization techniques and recommendations
  7. Example Program for Processing GBX Data
  8. The Report Types
  9. Protobuf Message Definitions

Conventions

The following conventions shall apply throughout this document:

  • All numerals with prefix '0x' are in base-16 (hexadecimal) notation.
  • All numerals without a prefix are in base-10 (decimal) notation.
  • value < m > represents bit m in value, where bit 0 is the least significant bit.
  • value < m : n > represents the (m - n + 1)-bit bitfield from bit m down to bit n.

Numeric Data Types

All multi-byte fields are stored in little-endian byte order. All signed integers are stored in twos-complement representation.

TypeDescription
u8unsigned 8-bit integer
s8signed 8-bit integer
u16unsigned 16-bit integer
s16signed 16-bit integer
u32unsigned 32-bit integer
s32signed 32-bit integer
u64unsigned 64-bit integer
s64signed 64-bit integer
f32single-precision IEEE-754 floating point value
f64double-precision IEEE-754 floating point value
bNN-bit bitfield

GBX File/Stream Structure

A properly structured gbx file is simply a file which contains one or several gbx reports (and nothing else). For example, a gbx file which contains 2 reports, each being 10 bytes in length, is exactly 20 bytes in length. This means that there are not any separate headers at the beginning of a gbx file which might be used, for example, to specify the origins of the file. As such, it is recommended that you track the origins of your gbx files separately (perhaps with a similarly named .txt file) to stay organized. The recommended file extension for a gbx file is .gbx.

GBX Report Structure

gbx reports are composed of a header, payload, and footer (in that order). As will be seen, the header has a fixed size of 8 bytes, the payload varies with report type, and the footer has a fixed size of 2 bytes. A payload size of 0 is valid and, as an example, such a payload would be serialized into a gbx report totaling 10 bytes in length.

OffsetTypeName/ValueDescription
0u80x55First synchronization byte
1u80x54Second synchronization byte
2u8reportTypeReport type
3u8streamIdStream identifier
4u32reportSizeReport payload size

The fixed size of the header is 8 bytes.

Synchronization Bytes

Protocol-specific values which should always be verified during deserialization. Earlier versions of the gbx format are similar in report structure but had different values for synchronization bytes. This change was deliberate to prevent confusion.

Report Type (reportType)

Specifies the type of report; that is, the nature and structure of data to be found in the payload. A discussion of common report types is found here.

Stream Identifier (streamId)

Allows for multiple logical streams to be multiplexed into a single gbx report stream. Each specific logical stream (e.g., a particular GPS receiver) shall be assigned a unique streamId value. For a gbx report stream containing only one logical stream, this value will normally be 0. In the case where a second logical stream is included (e.g., a reference GNSS receiver for RTK), this second stream should be assigned a value of 1.

Using any other values with the standard set of GSS tools may result in ignoring the stream. At worst, it will result in undefined behavior.

Report Size (reportSize)

Specifies the size of the payload (in bytes). This value does not include the additional length of the header and footer.

Payload

Structure varies dependent on the specified reportType. The size of the payload is specified (in bytes) by the reportSize field of the header. The payload of every report type is actually a Google Protobuf 3 binary buffer. The developer's guide for proto3 is available here. Message definition files can be found in the gss repository under the gss/gbxframework/messages directory.

OffsetTypeName/ValueDescription
0u16checksumFletcher-16 checksum

The fixed size of the footer is 2 bytes. During report deserialization, the Fletcher-16 checksum should be calculated locally for the received header and payload. This calculated checksum should then be compared against the received checksum. If the calculated and received checksums do not match then the report shall be considered corrupt and discarded. The Fletcher-16 checksum value is for the header and payload and can be calculated with the following algorithm (C implementation):

u16 fletcher16(const u8* data, u32 bytes) {
u16 sum1 = 0xff, sum2 = 0xff;
u32 tlen;
while (bytes) {
tlen = ((bytes >= 20) ? 20 : bytes);
bytes -= tlen;
do {
sum2 += sum1 += *data++;
tlen--;
} while (tlen);
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
}
/* Second reduction step to reduce sums to 8 bits */
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
return (sum2 << 8) | sum1;
}

NOTE: Variations of the Fletcher-16 checksum implementation may provide different checksum values for a particular input. If using different implementations (by algorithm or language), it is recommended that you compare their output against the provided algorithm.

Sample Report

A valid and complete gbx report: 55 54 14 00 03 00 00 00 08 82 01 4C DD (hexadecimal byte values, left byte first)

The first 8 bytes represent the header and communicate the following:

  • This is a gbx report (0x55 0x54),
  • of report type CODA (see The Report Types),
  • multiplexed on streamId 0,
  • with a payload that is 3 bytes in length (note Little-Endian byte ordering of a u32)

The 3 byte payload contains: 0x08 0x82 0x01

And the Fletcher-16 checksum (the 2 byte footer) of the first 11 bytes is 0x4C 0xDD, the Little-Endian representation of the value 0xDD4C.

GBX Stream Structure

With few exceptions, each individual report is entirely self-contained; that is, it contains all relevant information required to use all other information contained in the report. Where reports are found in the stream relative to other reports is generally irrelevant (other than to infer relative timing). Reports can generally be encountered in any order. This is the rule. The exceptions are to follow.

The Epoch

The epoch represents a set of reports whose mutual information is applicable to the same instant in time (the epoch). The epoch is the periodic output (say, 5Hz) of the GNSS receiver, PpRx. Every epoch begins with a report of type OBSERVABLES_MEASUREMENT_TIME and ends with a report of type CODA. Any OBSERVABLES_MEASUREMENT_TIME (or CODA) report encountered without an associated CODA (or OBSERVABLES_MEASUREMENT_TIME ) shall be considered to represent a corrupt stream or incomplete epoch. The following report types represent the epoch produced by PpRx:

  1. GNSS_OBSERVABLES
  2. STANDARD_NAVIGATION_SOLUTION
  3. TRANSMITTER_INFO
  4. IQ_METADATA
  5. IONOSPHERE
  6. SCINTILLATION_PARAMETERS

Note that other applications (e.g., another PpRx instance or an RTK application) operating on a PpRx-produced gbx stream may add other reports to the epoch, or may remove PpRx-emplaced reports.

The epoch has two primary purposes:

  1. The first purpose is to allow proper interpretation of individually incomplete reports (e.g., due to not storing an applicable timestamp). Any timestamp associated with one epoch-associated report is applicable to all epoch-associated reports.
  2. The second purpose is to facilitate robust, low-latency stream processing. The end of the epoch (the CODA report) serves as an explicit signal that no other reports associated with this epoch will be received in the future. Without the benefit of this explicit signal, a processing node could only infer the completion of one epoch by the beginning of the next epoch (with resultant substantial latency).

Not all epoch-associated report types may be present in any given epoch; in fact, a valid epoch may contain no epoch-associated report types. Some epoch-associated report types may be repeated multiple times.

If any other report types have an associated timestamp which is exactly coincident to that of the epoch (by design and not mere coincidence) then they shall also be members of that epoch. For example, the result of any measurement update using GNSS observables of the epoch is, by design, coincident with the epoch and is a member of that epoch.

A stream is considered ill-formed if any epoch-associated report is encountered outside of an associated pairing of OBSERVABLES_MEASUREMENT_TIME and CODA reports; undefined behavior may result. It is not required that the recipient ignore these misplaced reports. Rather, the producer shall assume that they will be ignored.

Any and all other report types may be encountered between a pairing of OBSERVABLES_MEASUREMENT_TIME and CODA reports. This is allowable but circumstantial. These other report types are not associated with the epoch.

IMU and IMU Configuration Reports

IMU and IMU_CONFIG are not entirely self-contained and independent. The IMU report contains a partial timestamp (the lower 32-bits of a 64-bit value). The IMU_CONFIG report is periodically published and contains (among other things) a full 64-bit timestamp. The upper 32-bits of the full 64-bit timestamp from the IMU_CONFIG report should be used to disambiguate and recover the full 64-bit timestamp associated with each IMU report. If the need arises to use this fact and further clarification is required, contact the developers.

Deserialization techniques and recommendations

A valid gbx report can be identified in a byte-stream through the following process:

  1. Locate the first occurrence of the two synchronization bytes (0x55 0x54).
  2. Assuming this sequence marks the beginning of a valid gbx report header, extract the payload size. Use the payload size to extract the footer checksum.
  3. Calculate the checksum of the received header and payload and compare against the received checksum found in the footer.
  • If the checksums compare equal then it can be assumed that a valid gbx report has been found.
  • If the checksums do not compare equal then either misalignment or corruption has occurred. In either case, the payload size is suspect and should not be used to attempt to skip forward to the next report. Instead, the next occurrence of 0x55 0x54 should be located and the process repeated.

Undesired reports can be ignored based on report type and/or stream identifier. In these cases, it is not necessary to deserialize their payloads. However, it is recommended to still calculate and compare checksums on ignored reports.

Keep in mind that filtering reports from a stream may impact proper operation of GSS tools. Importantly, if either OBSERVABLES_MEASUREMENT_TIME and/or CODA reports are filtered then the epoch structure of the gbx4 stream will be damaged and all epoch-associated reports will be negatively impacted (and potentially rendered useless). In short, it is best to only filter report types from a stream if you know exactly what you are doing.

Example Program for Processing GBX Data

For worked examples of reading and using GBX data, see the following guides:

The Report Types

The presence of report types in this list does not necessarily imply software capabilities that are available for licensing (or that even exist) at this time. Certain report types might be implemented for future-use or not even fully implemented. All report type values not included in this list shall be considered reserved. Cross-check this list with reporttype.inc to ensure completeness and accuracy.

NameReport Type
DUMMY_REPORT0x00
IQ0x01
GNSS_OBSERVABLES0x02
OBSERVABLES_MEASUREMENT_TIME0x03
ESTIMATOR_INNOVATIONS0x04
ESTIMATOR_STATE0x05
IMU0x06
IMU_CONFIG0x07
TRANSMITTER_INFO0x08
IQ_METADATA0x09
SCINTILLATION_PARAMETERS0x0A
IONOSPHERE0x0B
DIAGNOSTIC_MESSAGE0x0C
ANTENNA_PCV0x0D
POSE_AND_TWIST0x0E
STANDARD_NAVIGATION_SOLUTION0x0F
TRIGGER_TIME0x10
EPHEMERIS0x11
ALMANAC0x12
BITCONTAINER0x13
CODA0x14
SPECTRUM0x15
INFO0x16
STATUS0x17
ATTITUDE_2D0x18
ATTITUDE_3D0x19
SINGLE_BASELINE_RTK0x1A
MULTI_BASELINE_RTK_ATTITUDE_2D0x1B
MULTI_BASELINE_RTK_ATTITUDE_3D0x1C
RADAR0x1D
RADAR_CONFIG0x1E
TIME_CONVERSION0x1F
EPHEMERIS_PARAMETERS0x20
ATMOSPHERIC_PARAMETERS0x21
DIFFERENTIAL_CODE_BIAS0x22
IMAGE0x23
MEASUREMENTS0x24
MEASUREMENTS_BATCH0x25
DIFFERENTIAL_CORRECTIONS0x26
COMMAND0x27
COMMAND_RESPONSE0x28

Protobuf Message Definitions

For GBX stream parser development, contact support@locuslock.com for protobuf message definitions and support.