use super::*;
#[derive(Clone, Debug, PartialEq)]
pub struct Interrogation {
pub own_vessel: bool,
pub station: Station,
pub case: InterrogationCase,
pub mmsi: u32,
pub mmsi1: u32,
pub type1_1: u8,
pub offset1_1: u16,
pub type1_2: Option<u8>,
pub offset1_2: Option<u16>,
pub mmsi2: Option<u32>,
pub type2_1: Option<u8>,
pub offset2_1: Option<u16>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum InterrogationCase {
Case1,
Case2,
Case3,
Case4,
}
impl InterrogationCase {
pub fn new(bv: &BitVec) -> InterrogationCase {
let len = bv.len();
if len >= 160 {
if pick_u64(bv, 90, 18) == 0 {
InterrogationCase::Case3
} else {
InterrogationCase::Case4
}
} else if len >= 110 {
InterrogationCase::Case2
} else {
InterrogationCase::Case1
}
}
}
pub(crate) fn handle(
bv: &BitVec,
station: Station,
own_vessel: bool,
) -> Result<ParsedMessage, ParseError> {
let case = InterrogationCase::new(bv);
Ok(ParsedMessage::Interrogation(Interrogation {
own_vessel,
station,
case,
mmsi: { pick_u64(bv, 8, 30) as u32 },
mmsi1: { pick_u64(bv, 40, 30) as u32 },
type1_1: { pick_u64(bv, 70, 6) as u8 },
offset1_1: { pick_u64(bv, 76, 12) as u16 },
type1_2: match case {
InterrogationCase::Case2 | InterrogationCase::Case4 => Some(pick_u64(bv, 90, 6) as u8),
_ => None,
},
offset1_2: match case {
InterrogationCase::Case2 | InterrogationCase::Case4 => {
Some(pick_u64(bv, 96, 12) as u16)
}
_ => None,
},
mmsi2: match case {
InterrogationCase::Case3 | InterrogationCase::Case4 => {
Some(pick_u64(bv, 110, 30) as u32)
}
_ => None,
},
type2_1: match case {
InterrogationCase::Case4 => Some(pick_u64(bv, 140, 6) as u8),
_ => None,
},
offset2_1: match case {
InterrogationCase::Case4 => Some(pick_u64(bv, 146, 12) as u16),
_ => None,
},
}))
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_parse_vdm_type15() {
let mut p = NmeaParser::new();
match p.parse_sentence("!AIVDM,1,1,,B,?h3Ovn1GP<K0<P@59a0,2*04") {
Ok(ps) => {
match ps {
ParsedMessage::Interrogation(i) => {
assert_eq!(i.mmsi, 3669720);
assert_eq!(i.mmsi1, 367014320);
assert_eq!(i.type1_1, 3);
assert_eq!(i.offset1_1, 516);
assert_eq!(i.type1_2, Some(5));
assert_eq!(i.offset1_2, Some(617));
assert_eq!(i.mmsi2, None);
assert_eq!(i.type2_1, None);
assert_eq!(i.offset2_1, None);
}
ParsedMessage::Incomplete => {
assert!(false);
}
_ => {
assert!(false);
}
}
}
Err(e) => {
assert_eq!(e.to_string(), "OK");
}
}
}
}