Skip to main content

nmea_kit/ais/messages/
group_assignment.rs

1//! AIS Type 23 — Group assignment command.
2
3use crate::ais::armor::{extract_i32, extract_u32};
4
5/// AIS Type 23 group assignment command.
6#[derive(Debug, Clone, PartialEq)]
7pub struct GroupAssignment {
8    pub repeat_indicator: u8,
9    pub mmsi: u32,
10    pub northeast_longitude: Option<f64>,
11    pub northeast_latitude: Option<f64>,
12    pub southwest_longitude: Option<f64>,
13    pub southwest_latitude: Option<f64>,
14    pub station_type: u8,
15    pub ship_type: u8,
16    pub tx_rx_mode: u8,
17    pub reporting_interval: u8,
18    pub quiet_time: u8,
19}
20
21impl GroupAssignment {
22    pub(crate) fn decode(bits: &[u8]) -> Option<Self> {
23        if bits.len() < 160 {
24            return None;
25        }
26        Some(Self {
27            repeat_indicator: extract_u32(bits, 6, 2)? as u8,
28            mmsi: extract_u32(bits, 8, 30)?,
29            northeast_longitude: decode_longitude(extract_i32(bits, 40, 18)?),
30            northeast_latitude: decode_latitude(extract_i32(bits, 58, 17)?),
31            southwest_longitude: decode_longitude(extract_i32(bits, 75, 18)?),
32            southwest_latitude: decode_latitude(extract_i32(bits, 93, 17)?),
33            station_type: extract_u32(bits, 110, 4)? as u8,
34            ship_type: extract_u32(bits, 114, 8)? as u8,
35            tx_rx_mode: extract_u32(bits, 144, 2)? as u8,
36            reporting_interval: extract_u32(bits, 146, 4)? as u8,
37            quiet_time: extract_u32(bits, 150, 4)? as u8,
38        })
39    }
40}
41
42fn decode_longitude(value: i32) -> Option<f64> {
43    let value = f64::from(value) / 600.0;
44    (-180.0..=180.0).contains(&value).then_some(value)
45}
46
47fn decode_latitude(value: i32) -> Option<f64> {
48    let value = f64::from(value) / 600.0;
49    (-90.0..=90.0).contains(&value).then_some(value)
50}