Skip to main content

nmea_kit/ais/messages/
binary_ack.rs

1//! AIS Types 7/13 — Binary / Safety Acknowledge.
2
3use crate::ais::armor::extract_u32;
4
5/// A single acknowledgement entry (MMSI + sequence number).
6#[derive(Debug, Clone, PartialEq)]
7pub struct AckEntry {
8    pub mmsi: u32,
9    pub sequence: u8,
10}
11
12/// AIS Types 7/13 — Binary / Safety Acknowledge.
13///
14/// Acknowledges receipt of Type 6 (binary) or Type 12 (safety) messages.
15/// Contains up to 4 acknowledgement entries.
16#[derive(Debug, Clone, PartialEq)]
17pub struct BinaryAck {
18    pub msg_type: u8,
19    pub mmsi: u32,
20    /// Up to 4 acknowledgement entries.
21    pub acks: Vec<AckEntry>,
22}
23
24impl BinaryAck {
25    pub(crate) fn decode(bits: &[u8]) -> Option<Self> {
26        if bits.len() < 72 {
27            return None;
28        }
29        let msg_type = extract_u32(bits, 0, 6)? as u8;
30        let mmsi = extract_u32(bits, 8, 30)?;
31        let mut acks = Vec::new();
32        // Each ack entry is 32 bits (30 MMSI + 2 sequence), starting at bit 40
33        let mut offset = 40;
34        while offset + 32 <= bits.len() && acks.len() < 4 {
35            let ack_mmsi = extract_u32(bits, offset, 30)?;
36            let seq = extract_u32(bits, offset + 30, 2)? as u8;
37            acks.push(AckEntry {
38                mmsi: ack_mmsi,
39                sequence: seq,
40            });
41            offset += 32;
42        }
43        Some(Self {
44            msg_type,
45            mmsi,
46            acks,
47        })
48    }
49}