nmea_kit/ais/messages/
position_b.rs1use crate::ais::armor::{extract_i32, extract_u32};
4
5use super::common::AisClass;
6use super::position_a::PositionReport;
7use super::utils::{decode_cog, decode_heading, decode_latitude, decode_longitude, decode_sog};
8
9impl PositionReport {
10 pub fn decode_class_b(bits: &[u8]) -> Option<Self> {
12 if bits.len() < 168 {
13 return None;
14 }
15
16 let msg_type = extract_u32(bits, 0, 6)? as u8;
17 let mmsi = extract_u32(bits, 8, 30)?;
18 let sog_raw = extract_u32(bits, 46, 10)?;
19 let accuracy = extract_u32(bits, 56, 1)? == 1;
20 let lon_raw = extract_i32(bits, 57, 28)?;
21 let lat_raw = extract_i32(bits, 85, 27)?;
22 let cog_raw = extract_u32(bits, 112, 12)?;
23 let hdg_raw = extract_u32(bits, 124, 9)?;
24 let ts_raw = extract_u32(bits, 133, 6)? as u8;
25
26 Some(Self {
27 msg_type,
28 mmsi,
29 nav_status: None,
30 rate_of_turn: None,
31 sog: decode_sog(sog_raw),
32 position_accuracy: accuracy,
33 longitude: decode_longitude(lon_raw),
34 latitude: decode_latitude(lat_raw),
35 cog: decode_cog(cog_raw),
36 heading: decode_heading(hdg_raw),
37 timestamp: if ts_raw < 60 { Some(ts_raw) } else { None },
38 ais_class: AisClass::B,
39 })
40 }
41}