ais 0.6.0

An AIS parser library
Documentation

AIS parser

Build Status This is the beginning of a parser for AIS messages, written in Rust.

Documentation

API documentation is available at https://docs.rs/ais

Try it out

If you just want to take a bunch of AIS NMEA sentences and see what they mean, you can try running this as a (very rough) command-line utility.

If your NMEA source is sending UDP packets to port 4722, for example:

nc -u -l 4722 | cargo run

You should start seeing messages stream in:

AidToNavigationReport(AidToNavigationReport { message_type: 21, repeat_indicator: 1, mmsi: 993692016, aid_type: Some(ReferencePoint), name: "6W", accuracy: Unaugmented, longitude: Some(-122.80445), latitude: Some(37.705833), dimension_to_bow: 0, dimension_to_stern: 0, dimension_to_port: 0, dimension_to_starboard: 0, epfd_type: Some(Surveyed), utc_second: 61, off_position: false, regional_reserved: 0, raim: false, virtual_aid: false, assigned_mode: false })
BaseStationReport(BaseStationReport { message_type: 4, repeat_indicator: 0, mmsi: 3669710, year: Some(2020), month: Some(4), day: Some(18), hour: Some(8), minute: Some(46), second: Some(40), fix_quality: DGPS, longitude: Some(-122.42347), latitude: Some(37.96206), epfd_type: None, raim: true, radio_status: Sotdma(SotdmaMessage { sync_state: UtcDirect, slot_timeout: 0, sub_message: SlotOffset(2250) }) })
PositionReport(PositionReport { message_type: 1, repeat_indicator: 0, mmsi: 367625810, navigation_status: Some(UnderWayUsingEngine), rate_of_turn: Some(RateOfTurn { raw: 0 }), speed_over_ground: Some(0.1), position_accuracy: DGPS, longitude: Some(-122.398), latitude: Some(37.80256), course_over_ground: Some(343.8), true_heading: Some(55), timestamp: 41, maneuver_indicator: None, raim: false, radio_status: Sotdma(SotdmaMessage { sync_state: UtcDirect, slot_timeout: 2, sub_message: SlotNumber(1524) }) })
BaseStationReport(BaseStationReport { message_type: 4, repeat_indicator: 0, mmsi: 3669145, year: Some(2020), month: Some(4), day: Some(18), hour: Some(8), minute: Some(46), second: Some(41), fix_quality: DGPS, longitude: Some(-122.46484), latitude: Some(37.794273), epfd_type: None, raim: true, radio_status: Sotdma(SotdmaMessage { sync_state: UtcDirect, slot_timeout: 3, sub_message: ReceivedStations(187) }) })

Use it as a library

Here's an example that parses a single NMEA sentence. In this case, it contains an Aid to Navigation Report:

use ais::{AisFragments, AisParser};
use ais::messages::AisMessage;

// The line below is an NMEA sentence, much as you'd see coming out of an AIS decoder.
let line = b"!AIVDM,1,1,,B,E>kb9O9aS@7PUh10dh19@;0Tah2cWrfP:l?M`00003vP100,0*01";

let mut parser = AisParser::new();
if let AisFragments::Complete(sentence) = parser.parse(line, true)? {
   // This sentence is complete, ie unfragmented
   assert_eq!(sentence.num_fragments, 1);
   // The data was transmitted on AIS channel B
   assert_eq!(sentence.channel, Some('B'));

   if let Some(message) = sentence.message {
       match message {
           AisMessage::AidToNavigationReport(report) => {
               assert_eq!(report.mmsi, 993692028);
               assert_eq!(report.name, "SF OAK BAY BR VAIS E");
               // There are a ton more fields available here
           },
           _ => panic!("Unexpected message type"),
       }
   }
}
# Ok::<(), ais::errors::Error>(())

Supported message types

Right now, only a few common types are supported. They are:

  • Position Report (types 1-3)
  • Base Station Report (type 4)
  • Static and Voyage Related Data (type 5)
  • Binary Broadcast Message (type 8)
  • Interrogation (type 15)
  • Data Link Management Message (type 20)
  • Aid to Navigation Report (type 21)
  • Static Data Report (type 24)

Others to come soon, I hope!