nmea_parser/ais/
vdm_t20.rs

1/*
2Copyright 2020 Timo Saarinen
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17use super::*;
18
19// -------------------------------------------------------------------------------------------------
20
21/// Type 20: Data Link Management Message
22#[derive(Clone, Debug, PartialEq)]
23pub struct DataLinkManagementMessage {
24    /// True if the data is about own vessel, false if about other.
25    pub own_vessel: bool,
26
27    /// AIS station type.
28    pub station: Station,
29
30    /// Interrogation case based on data length
31    pub case: InterrogationCase,
32
33    /// Source MMSI (30 bits)
34    pub mmsi: u32,
35
36    /// Offset number 1 (12 bits)
37    pub offset1: u16,
38
39    /// Reserved offset number (4)
40    pub number1: u8,
41
42    /// Allocation timeout in munites (4 bits)
43    pub timeout1: u8,
44
45    /// Repeat increment (11 bits)
46    pub increment1: u8,
47
48    /// Offset number 2 (12 bits)
49    pub offset2: u16,
50
51    /// Reserved offset number (4)
52    pub number2: u8,
53
54    /// Allocation timeout in munites (4 bits)
55    pub timeout2: u8,
56
57    /// Repeat increment (11 bits)
58    pub increment2: u8,
59
60    /// Offset number 3 (12 bits)
61    pub offset3: u16,
62
63    /// Reserved offset number (4)
64    pub number3: u8,
65
66    /// Allocation timeout in munites (4 bits)
67    pub timeout3: u8,
68
69    /// Repeat increment (11 bits)
70    pub increment3: u8,
71
72    /// Offset number 4 (12 bits)
73    pub offset4: u16,
74
75    /// Reserved offset number (4)
76    pub number4: u8,
77
78    /// Allocation timeout in munites (4 bits)
79    pub timeout4: u8,
80
81    /// Repeat increment (11 bits)
82    pub increment4: u8,
83}
84
85// -------------------------------------------------------------------------------------------------
86
87/// AIS VDM/VDO type 20: Data Link Management Message
88pub(crate) fn handle(
89    bv: &BitVec,
90    station: Station,
91    own_vessel: bool,
92) -> Result<ParsedMessage, ParseError> {
93    let case = InterrogationCase::new(bv);
94    Ok(ParsedMessage::DataLinkManagementMessage(
95        DataLinkManagementMessage {
96            own_vessel,
97            station,
98            case,
99            mmsi: { pick_u64(bv, 8, 30) as u32 },
100            offset1: { pick_u64(bv, 40, 12) as u16 },
101            number1: { pick_u64(bv, 52, 4) as u8 },
102            timeout1: { pick_u64(bv, 56, 3) as u8 },
103            increment1: { pick_u64(bv, 59, 11) as u8 },
104            offset2: { pick_u64(bv, 70, 12) as u16 },
105            number2: { pick_u64(bv, 82, 4) as u8 },
106            timeout2: { pick_u64(bv, 86, 3) as u8 },
107            increment2: { pick_u64(bv, 89, 11) as u8 },
108            offset3: { pick_u64(bv, 100, 12) as u16 },
109            number3: { pick_u64(bv, 112, 4) as u8 },
110            timeout3: { pick_u64(bv, 116, 3) as u8 },
111            increment3: { pick_u64(bv, 119, 11) as u8 },
112            offset4: { pick_u64(bv, 130, 12) as u16 },
113            number4: { pick_u64(bv, 142, 4) as u8 },
114            timeout4: { pick_u64(bv, 146, 3) as u8 },
115            increment4: { pick_u64(bv, 149, 11) as u8 },
116        },
117    ))
118}
119
120// -------------------------------------------------------------------------------------------------
121
122#[cfg(test)]
123mod test {
124    use super::*;
125
126    #[test]
127    fn test_parse_vdm_type20() {
128        let mut p = NmeaParser::new();
129        match p.parse_sentence("!AIVDM,1,1,,A,Dh3OvjB8IN>4,0*1D") {
130            Ok(ps) => {
131                match ps {
132                    // The expected result
133                    ParsedMessage::DataLinkManagementMessage(dlmm) => {
134                        assert_eq!(dlmm.mmsi, 3669705);
135                        assert_eq!(dlmm.offset1, 2182);
136                        assert_eq!(dlmm.number1, 5);
137                        assert_eq!(dlmm.timeout1, 7);
138                        assert_eq!(dlmm.increment1, 225);
139                    }
140                    ParsedMessage::Incomplete => {
141                        assert!(false);
142                    }
143                    _ => {
144                        assert!(false);
145                    }
146                }
147            }
148            Err(e) => {
149                assert_eq!(e.to_string(), "OK");
150            }
151        }
152    }
153}