-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cd0cd1c
commit 0fa5300
Showing
6 changed files
with
167 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "ais" | ||
version = "0.7.0" | ||
version = "0.8.0" | ||
authors = ["Kevin Rauwolf <[email protected]>"] | ||
description = "An AIS parser library" | ||
homepage = "https://github.com/squidpickles/ais" | ||
|
@@ -10,11 +10,11 @@ readme = "README.md" | |
keywords = ["ais", "nmea"] | ||
categories = ["parser-implementations"] | ||
license = "Apache-2.0" | ||
edition = "2018" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
thiserror = "1" | ||
nom = "6.1" | ||
nom = "7" | ||
|
||
[badges] | ||
travis-ci = { repository = "squidpickles/ais", branch = "master" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
//! ExtendedClass B Position Report (type 19) | ||
use super::navigation::*; | ||
use super::parsers::*; | ||
use super::types::AssignedMode; | ||
use super::types::Dte; | ||
use super::types::EpfdType; | ||
use super::AisMessageType; | ||
use crate::errors::Result; | ||
use crate::messages::types::ShipType; | ||
use nom::bits::{bits, complete::take as take_bits}; | ||
use nom::combinator::map; | ||
use nom::IResult; | ||
|
||
#[derive(Debug, PartialEq)] | ||
pub struct ExtendedClassBPositionReport { | ||
pub message_type: u8, | ||
pub repeat_indicator: u8, | ||
pub mmsi: u32, | ||
pub speed_over_ground: Option<f32>, | ||
pub position_accuracy: Accuracy, | ||
pub longitude: Option<f32>, | ||
pub latitude: Option<f32>, | ||
pub course_over_ground: Option<f32>, | ||
pub true_heading: Option<u16>, | ||
pub timestamp: u8, | ||
pub name: String, | ||
pub type_of_ship_and_cargo: Option<ShipType>, | ||
pub dimension_to_bow: u16, | ||
pub dimension_to_stern: u16, | ||
pub dimension_to_port: u16, | ||
pub dimension_to_starboard: u16, | ||
pub epfd_type: Option<EpfdType>, | ||
pub raim: bool, | ||
pub dte: Dte, | ||
pub assigned_mode: AssignedMode, | ||
} | ||
|
||
impl<'a> AisMessageType<'a> for ExtendedClassBPositionReport { | ||
fn name(&self) -> &'static str { | ||
"Extended Class B Position Report" | ||
} | ||
|
||
fn parse(data: &[u8]) -> Result<Self> { | ||
let (_, report) = parse_base(data)?; | ||
Ok(report) | ||
} | ||
} | ||
|
||
fn parse_base(data: &[u8]) -> IResult<&[u8], ExtendedClassBPositionReport> { | ||
bits(move |data| -> IResult<_, _> { | ||
let (data, message_type) = take_bits(6u8)(data)?; | ||
let (data, repeat_indicator) = take_bits(2u8)(data)?; | ||
let (data, mmsi) = take_bits(30u32)(data)?; | ||
let (data, _regional_reserved) = take_bits::<_, u8, _, _>(8u8)(data)?; | ||
let (data, speed_over_ground) = map(take_bits(10u16), parse_speed_over_ground)(data)?; | ||
let (data, position_accuracy) = map(take_bits(1u8), Accuracy::parse)(data)?; | ||
let (data, longitude) = map(|data| signed_i32(data, 28), parse_longitude)(data)?; | ||
let (data, latitude) = map(|data| signed_i32(data, 27), parse_latitude)(data)?; | ||
let (data, course_over_ground) = map(take_bits(12u16), parse_cog)(data)?; | ||
let (data, true_heading) = map(take_bits(9u16), parse_heading)(data)?; | ||
let (data, timestamp) = take_bits(6u8)(data)?; | ||
let (data, _regional_reserved) = take_bits::<_, u8, _, _>(4u8)(data)?; | ||
let (data, name) = parse_6bit_ascii(data, 120)?; | ||
let (data, type_of_ship_and_cargo) = map(take_bits(8u8), ShipType::parse)(data)?; | ||
let (data, dimension_to_bow) = take_bits(9u16)(data)?; | ||
let (data, dimension_to_stern) = take_bits(9u16)(data)?; | ||
let (data, dimension_to_port) = take_bits(6u16)(data)?; | ||
let (data, dimension_to_starboard) = take_bits(6u16)(data)?; | ||
let (data, epfd_type) = map(take_bits(4u8), EpfdType::parse)(data)?; | ||
let (data, raim) = map(take_bits(1u8), u8_to_bool)(data)?; | ||
let (data, dte) = map(take_bits::<_, u8, _, _>(1u8), Into::into)(data)?; | ||
let (data, assigned_mode) = map(take_bits(1u8), AssignedMode::parse)(data)?; | ||
let (data, _spare) = take_bits::<_, u8, _, _>(4u8)(data)?; | ||
Ok(( | ||
data, | ||
ExtendedClassBPositionReport { | ||
message_type, | ||
repeat_indicator, | ||
mmsi, | ||
speed_over_ground, | ||
position_accuracy, | ||
longitude, | ||
latitude, | ||
course_over_ground, | ||
true_heading, | ||
timestamp, | ||
name, | ||
type_of_ship_and_cargo, | ||
dimension_to_bow, | ||
dimension_to_stern, | ||
dimension_to_port, | ||
dimension_to_starboard, | ||
epfd_type, | ||
raim, | ||
dte, | ||
assigned_mode, | ||
}, | ||
)) | ||
})(data) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#![allow(clippy::unreadable_literal)] | ||
use super::*; | ||
use crate::test_helpers::*; | ||
|
||
#[test] | ||
fn test_position() { | ||
let bytestream = b"C6:ijoP00:9NNF4TEspILDN0Vc0jNc1WWV0000000000S2<6R20P"; | ||
let bitstream = crate::messages::unarmor(bytestream, 0).unwrap(); | ||
let report = ExtendedClassBPositionReport::parse(&bitstream).unwrap(); | ||
assert_eq!(report.message_type, 19); | ||
assert_eq!(report.repeat_indicator, 0); | ||
assert_eq!(report.mmsi, 413954782); | ||
assert_eq!(report.speed_over_ground, Some(0.0)); | ||
assert_eq!(report.position_accuracy, Accuracy::DGPS); | ||
f32_equal_naive(report.longitude.unwrap(), 120.12851); | ||
f32_equal_naive(report.latitude.unwrap(), 31.931623); | ||
assert_eq!(report.course_over_ground, Some(40.7)); | ||
assert_eq!(report.true_heading, Some(40)); | ||
assert_eq!(report.timestamp, 60); | ||
assert_eq!(report.name, "SU YOU 333"); | ||
assert_eq!(report.type_of_ship_and_cargo, Some(ShipType::Cargo)); | ||
assert_eq!(report.dimension_to_bow, 35); | ||
assert_eq!(report.dimension_to_stern, 13); | ||
assert_eq!(report.dimension_to_port, 4); | ||
assert_eq!(report.dimension_to_starboard, 4); | ||
assert_eq!(report.epfd_type, None); | ||
assert_eq!(report.raim, false); | ||
assert_eq!(report.dte, Dte::NotReady); | ||
assert_eq!(report.assigned_mode, AssignedMode::Autonomous); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters