#radio #ais #maritime #decoder #nmea

rs162

NMEA AIS Message Parser and Decoder with deku-based AIS message structures

5 releases

0.1.4 Apr 30, 2026
0.1.3 Jan 26, 2026
0.1.2 Jan 20, 2026
0.1.1 Nov 24, 2025
0.1.0 Nov 24, 2025

#1943 in Parser implementations


Used in ship162

MIT license

5MB
9K SLoC

AIS Message Parser and Decoder

This library provides functionality to:

  • demodulate AIS messages from I/Q samples
  • parse NMEA AIVDM/AIVDO messages

and to convert them to binary u8 data, then decode them to structured AIS messages.

Feature Flags

  • rtlsdr: Enables the RtlSdrReceiver source for reading directly from USB RTL-SDR dongles.
  • mqtt: Enables the MqttReceiver source for connecting to AIS data streams over MQTT (e.g. Digitraffic). Disabled by default.

ship162

ship162 is a lightweight maritime AIS receiver and decoder, the maritime equivalent of jet1090 for aviation.

It decodes AIS (Automatic Identification System) messages from SDR hardware, TCP feeds, WebSocket streams, and MQTT brokers, and can display them in a real-time terminal dashboard.

ship162 TUI displaying real-time AIS messages

Installation

Pre-built binaries for Linux, macOS, and Windows are available on the GitHub Releases page.

Shell installer (Linux and macOS):

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/xoolive/ship162/releases/latest/download/ship162-installer.sh | sh

Homebrew (macOS):

brew install xoolive/homebrew/ship162

Cargo:

cargo install ship162

Arch OS (AUR):

yay -S ship162-bin

Building from source

The default build includes RTL-SDR, Airspy, HackRF, and SSH support:

cargo install --git https://github.com/xoolive/ship162

MQTT support requires an extra C build dependency (paho-mqtt) and must be opted into explicitly:

cargo install ship162 --features mqtt

Linux: detach the kernel DVB driver

The RTL-SDR, Airspy, and HackRF backends use a pure-Rust USB driver (nusb) that talks directly to the USB subsystem. On Linux you need to unload the kernel DVB modules first so they do not hold the device:

sudo modprobe -r dvb_usb_rtl28xxu rtl2832

To make this permanent, blacklist the module:

echo 'blacklist dvb_usb_rtl28xxu' | sudo tee /etc/modprobe.d/rtlsdr.conf

Usage

Run ship162 --help for the full list of options. The most common invocations:

# Interactive TUI with an RTL-SDR dongle
ship162 --interactive rtlsdr://

# JSON output from the Norwegian Coastal Administration free feed
ship162 --verbose tcp://153.44.253.27:5631

# Write to a file while also displaying the TUI
ship162 --interactive --output ais.jsonl rtlsdr://

Configuration file

Settings and sources can be stored in a TOML file. ship162 looks for configuration in order:

  1. $SHIP162_CONFIG (environment variable)
  2. $XDG_CONFIG_HOME/ship162/config.toml
  3. ~/.config/ship162/config.toml
interactive = true

[[sources]]
rtlsdr = { device = 0 }
gain = 49.6

[[sources]]
tcp = "153.44.253.27:5631"

See config.toml.example for the full reference with all sources and options.

Sources

SDR hardware

All SDR sources accept gain, sample_rate, and bias_tee at the source level:

# RTL-SDR (default gain 49.6 dB)
[[sources]]
rtlsdr = { device = 0 }
gain = 49.6
bias_tee = false

# Airspy R2 or Mini (default gain 50, sensitivity mode)
[[sources]]
airspy = { device = 0 }
gain = 50
sample_rate = 6000000

# HackRF (default LNA=40 dB, VGA=55 dB)
[[sources]]
hackrf = { device = 0, amp_enable = true }

# Airspy Mini via SoapySDR at 3 MS/s
[[sources]]
soapy = "driver=airspy"
sample_rate = 3000000
gain = 49.6

TCP

[[sources]]
tcp = "153.44.253.27:5631"

# With SSH tunnel (built-in, no openssh needed)
[[sources]]
tcp = { host = "remote-host", port = 5631, jump = "jumphost" }

WebSocket

[[sources]]
ws = "ws://remote-host:88888"

MQTT

Requires building with --features mqtt. Connects to the Finnish Digitraffic broker by default:

[[sources]]
mqtt = "mqtt://mqtt.digitraffic.fi"

Output

Decoded messages are emitted as JSON on stdout (--verbose), written to a file (--output), or published to Redis (--redis-url). The application can also re-broadcast decoded NMEA sentences to downstream consumers:

# Serve NMEA over TCP for other applications (e.g. OpenCPN)
ship162 --serve-tcp 0.0.0.0:5631 rtlsdr://

# Forward to a UDP endpoint
ship162 --serve-udp 0.0.0.0:5632 rtlsdr://

Free AIS data sources

Source Address Notes
Norwegian Coastal Administration tcp://153.44.253.27:5631 IEC 61162-1 NMEA with timestamps
Finnish Digitraffic mqtt://mqtt.digitraffic.fi Requires --features mqtt

Similar projects

License

MIT — see license.md.

Dependencies

~14–29MB
~484K SLoC