pub mod common;
mod types;
pub use types::{
Ack, Acknowledge, AidToNavigationReport, Assignment, AssignmentModeCommand, BaseStationReport,
BinaryAddressedMessage, BinaryBroadcastMessage, ChannelManagement, ChannelManagementTarget,
DataLinkManagement, DgnssBroadcastMessage, GroupAssignmentCommand, Interrogation,
LongRangeBroadcast, MessageRequest, MultiSlotBinaryMessage, PositionReportClassA,
PositionReportClassB, PositionReportClassBExtended, SafetyRelatedAddressed,
SafetyRelatedBroadcast, SarAircraftPositionReport, SecondStation, SingleSlotBinaryMessage,
SlotReservation, StaticDataReport, StaticDataReportPartA, StaticDataReportPartB,
StaticVoyageData, UtcDateInquiry,
};
use crate::bits::{BitReader, BitWriter};
use crate::error::{BitError, MessageError};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum AisMessage {
PositionReportClassA(PositionReportClassA),
StaticVoyageData(StaticVoyageData),
PositionReportClassB(PositionReportClassB),
PositionReportClassBExtended(PositionReportClassBExtended),
AidToNavigationReport(AidToNavigationReport),
StaticDataReport(StaticDataReport),
BaseStationReport(BaseStationReport),
SarAircraftPositionReport(SarAircraftPositionReport),
LongRangeBroadcast(LongRangeBroadcast),
BinaryAddressedMessage(BinaryAddressedMessage),
Acknowledge(Acknowledge),
BinaryBroadcastMessage(BinaryBroadcastMessage),
SafetyRelatedAddressed(SafetyRelatedAddressed),
SafetyRelatedBroadcast(SafetyRelatedBroadcast),
SingleSlotBinaryMessage(SingleSlotBinaryMessage),
MultiSlotBinaryMessage(MultiSlotBinaryMessage),
UtcDateInquiry(UtcDateInquiry),
Interrogation(Interrogation),
AssignmentModeCommand(AssignmentModeCommand),
DgnssBroadcastMessage(DgnssBroadcastMessage),
DataLinkManagement(DataLinkManagement),
ChannelManagement(ChannelManagement),
GroupAssignmentCommand(GroupAssignmentCommand),
}
impl AisMessage {
pub fn decode(r: &mut BitReader<'_>) -> Result<Self, MessageError> {
let message_type = r.read_u8(6)?;
match message_type {
1..=3 => Ok(Self::PositionReportClassA(PositionReportClassA::decode(
message_type,
r,
)?)),
5 => Ok(Self::StaticVoyageData(StaticVoyageData::decode(r)?)),
18 => Ok(Self::PositionReportClassB(PositionReportClassB::decode(r)?)),
19 => Ok(Self::PositionReportClassBExtended(
PositionReportClassBExtended::decode(r)?,
)),
21 => Ok(Self::AidToNavigationReport(AidToNavigationReport::decode(
r,
)?)),
24 => Ok(Self::StaticDataReport(StaticDataReport::decode(r)?)),
4 | 11 => Ok(Self::BaseStationReport(BaseStationReport::decode(
message_type,
r,
)?)),
9 => Ok(Self::SarAircraftPositionReport(
SarAircraftPositionReport::decode(r)?,
)),
27 => Ok(Self::LongRangeBroadcast(LongRangeBroadcast::decode(r)?)),
6 => Ok(Self::BinaryAddressedMessage(
BinaryAddressedMessage::decode(r)?,
)),
7 | 13 => Ok(Self::Acknowledge(Acknowledge::decode(message_type, r)?)),
8 => Ok(Self::BinaryBroadcastMessage(
BinaryBroadcastMessage::decode(r)?,
)),
12 => Ok(Self::SafetyRelatedAddressed(
SafetyRelatedAddressed::decode(r)?,
)),
14 => Ok(Self::SafetyRelatedBroadcast(
SafetyRelatedBroadcast::decode(r)?,
)),
25 => Ok(Self::SingleSlotBinaryMessage(
SingleSlotBinaryMessage::decode(r)?,
)),
26 => Ok(Self::MultiSlotBinaryMessage(
MultiSlotBinaryMessage::decode(r)?,
)),
10 => Ok(Self::UtcDateInquiry(UtcDateInquiry::decode(r)?)),
15 => Ok(Self::Interrogation(Interrogation::decode(r)?)),
16 => Ok(Self::AssignmentModeCommand(AssignmentModeCommand::decode(
r,
)?)),
17 => Ok(Self::DgnssBroadcastMessage(DgnssBroadcastMessage::decode(
r,
)?)),
20 => Ok(Self::DataLinkManagement(DataLinkManagement::decode(r)?)),
22 => Ok(Self::ChannelManagement(ChannelManagement::decode(r)?)),
23 => Ok(Self::GroupAssignmentCommand(
GroupAssignmentCommand::decode(r)?,
)),
other => Err(MessageError::UnknownMessageType(other)),
}
}
#[must_use]
pub const fn message_type(&self) -> u8 {
match self {
Self::PositionReportClassA(m) => m.message_type,
Self::StaticVoyageData(_) => 5,
Self::PositionReportClassB(_) => 18,
Self::PositionReportClassBExtended(_) => 19,
Self::AidToNavigationReport(_) => 21,
Self::StaticDataReport(_) => 24,
Self::BaseStationReport(m) => m.message_type,
Self::SarAircraftPositionReport(_) => 9,
Self::LongRangeBroadcast(_) => 27,
Self::BinaryAddressedMessage(_) => 6,
Self::Acknowledge(m) => m.message_type,
Self::BinaryBroadcastMessage(_) => 8,
Self::SafetyRelatedAddressed(_) => 12,
Self::SafetyRelatedBroadcast(_) => 14,
Self::SingleSlotBinaryMessage(_) => 25,
Self::MultiSlotBinaryMessage(_) => 26,
Self::UtcDateInquiry(_) => 10,
Self::Interrogation(_) => 15,
Self::AssignmentModeCommand(_) => 16,
Self::DgnssBroadcastMessage(_) => 17,
Self::DataLinkManagement(_) => 20,
Self::ChannelManagement(_) => 22,
Self::GroupAssignmentCommand(_) => 23,
}
}
pub fn encode(&self, w: &mut BitWriter<'_>) -> Result<(), BitError> {
match self {
Self::PositionReportClassA(m) => m.encode(w),
Self::StaticVoyageData(m) => m.encode(w),
Self::PositionReportClassB(m) => m.encode(w),
Self::PositionReportClassBExtended(m) => m.encode(w),
Self::AidToNavigationReport(m) => m.encode(w),
Self::StaticDataReport(m) => m.encode(w),
Self::BaseStationReport(m) => m.encode(w),
Self::SarAircraftPositionReport(m) => m.encode(w),
Self::LongRangeBroadcast(m) => m.encode(w),
Self::BinaryAddressedMessage(m) => m.encode(w),
Self::Acknowledge(m) => m.encode(w),
Self::BinaryBroadcastMessage(m) => m.encode(w),
Self::SafetyRelatedAddressed(m) => m.encode(w),
Self::SafetyRelatedBroadcast(m) => m.encode(w),
Self::SingleSlotBinaryMessage(m) => m.encode(w),
Self::MultiSlotBinaryMessage(m) => m.encode(w),
Self::UtcDateInquiry(m) => m.encode(w),
Self::Interrogation(m) => m.encode(w),
Self::AssignmentModeCommand(m) => m.encode(w),
Self::DgnssBroadcastMessage(m) => m.encode(w),
Self::DataLinkManagement(m) => m.encode(w),
Self::ChannelManagement(m) => m.encode(w),
Self::GroupAssignmentCommand(m) => m.encode(w),
}
}
}