Wiki / Protocols

GNSS signals and the navigation message

GPS, Galileo, GLONASS and BeiDou: how a satellite broadcasts a ranging code plus a navigation message, and why that message is a plain unsigned broadcast that anyone in range can imitate.

GPS L1 C/A navigation message
Frame, 1500 bits, 30 s
Subframe 1: clock
10 words x 30 bits
24 data + 6 parity
Subframes 2 to 3: ephemeris
Word 1 = TLM, preamble 0x8B
Word 2 = HOW, subframe id
Subframes 4 to 5: almanac
25 pages, 12.5 min cycle
At 50 bit/s a 300-bit subframe takes exactly 6 seconds and a five-subframe frame takes 30 seconds, which is why a cold receiver needs about half a minute to fix. Every 30-bit word carries only 24 bits of payload; the last 6 are parity computed over those 24 plus two bits carried from the previous word, so words cannot be edited independently.

GNSS (Global Navigation Satellite System) is the umbrella term for GPS, Galileo, GLONASS and BeiDou. Each is a constellation of satellites broadcasting, from medium Earth orbit, a signal a receiver uses for two things at once: measure how long the signal took to arrive, and read the message that says where the satellite was when it sent it. A position fix is the intersection of four of those measurements.

What it is

Every GNSS signal has two layers stacked on one carrier.

  • A ranging code, a long pseudo-random sequence the receiver correlates against its own copy. The correlation peak gives the time of arrival, and time of arrival times the speed of light gives the pseudorange. This is the measurement.
  • A navigation message, a very slow data stream modulated on top, carrying the satellite's clock correction, its ephemeris (its own precise orbit), and an almanac (coarse orbits for the whole constellation). This is what turns four timings into a position.

GPS L1 C/A sits at 1575.42 MHz and carries 50 bit/s of navigation data. Galileo E1 shares that band; GLONASS legacy signals use FDMA around 1602 MHz; BeiDou B1 sits nearby. The important structural point is that both layers are public. The C/A code is published, the message format is published, and neither is signed.

The GPS L1 C/A message structure

The stream is a rigid grid, which is exactly what lets you parse it without a receiver:

Unit Size Duration
Word 30 bits (24 data + 6 parity) 0.6 s
Subframe 10 words, 300 bits 6 s
Frame 5 subframes 30 s
Almanac cycle 25 frames 12.5 min

Word 1 of every subframe is the Telemetry word, whose first 8 bits are the fixed preamble 0x8B (10001011). Word 2 is the Handover Word, which carries a 17-bit time-of-week and the 3-bit subframe id. Subframes 1 to 3 carry the transmitting satellite's own clock and ephemeris; subframes 4 and 5 page out almanac and constellation data.

Finding a frame start is not "search for 0x8B". An 8-bit pattern turns up by chance roughly every 256 bits, so the test that works is recurrence: a real preamble has another preamble exactly 300 bits later, on the subframe grid.

Why it matters

GNSS is a timing utility as much as a navigation one. Cellular base stations, power-grid phasor measurement, broadcast, and financial timestamping all discipline their clocks to it, so a GNSS failure is rarely just a wrong map. And the exposure is structural: the civil signal is a public format broadcast at roughly minus 130 dBm at the ground, weaker than the thermal noise floor, which makes it cheap to overpower.

Three distinct attacks, worth keeping separate:

  • Jamming floods the band; the receiver simply loses lock and reports no fix. Loud and obvious.
  • Spoofing transmits a plausible fake constellation so the receiver computes a wrong fix while reporting a healthy one. Quiet and much worse.
  • Meaconing rebroadcasts the genuine signal with a delay. No bits are forged, so nothing in the data is false, yet the arrival time, which is the entire measurement, is wrong.

Assessing it

Receiving is easy and legal. An RTL-SDR reaches L1 at 1575.42 MHz, but you need an active GNSS antenna and a bias tee to power it, because the signal is below the noise floor and the dongle's own noise figure is poor; expect this to be at the edge of what the hardware can do. GNSS-SDR is the open-source software receiver that takes it from I/Q to a fix and can dump the decoded navigation message.

Transmitting is a different matter. gps-sdr-sim generates a baseband I/Q file from a broadcast ephemeris file and a chosen position:

gps-sdr-sim -e brdc3540.14n -l 30.286502,120.032669,100 -b 8
hackrf_transfer -t gpssim.bin -f 1575420000 -s 2600000 -a 1 -x 0

Do that over the air and you are transmitting on a protected aeronautical radionavigation band, which is illegal essentially everywhere and dangerous near anything that navigates. The only defensible bench setup is a shielded enclosure or a direct cabled path with fixed attenuators, into a receiver you own.

Pitfalls

  • The parity is not a checksum you can ignore. Each word's 6 parity bits are computed from its 24 data bits plus the last two bits of the previous word, and two of those data bits are transmitted inverted when the previous word's parity says so (the D30* fold). Flip a payload bit and the word no longer validates; recompute the parity and you still have to thread the carry through the whole subframe.
  • Ephemeris and almanac are not interchangeable. The ephemeris is precise and valid for a few hours; the almanac is coarse and valid for weeks. A receiver with only an almanac gets a slow, rough fix.
  • A healthy fix is not an authentic fix. Nothing in the legacy message answers "did this come from the ground segment", which is precisely the gap Wiki: osnma exists to close, and OSNMA closes it only for the data, not for the ranging signal.
  • GLONASS legacy is FDMA, one frequency per satellite, not CDMA like the rest, so tooling written for GPS does not simply retarget.

Further reading