General: reorganization of header files
[marnav.git] / include / marnav / ais / message.hpp
blobed484c40df215e89611ee69bd3bd2d5ad363c32d
1 #ifndef MARNAV__AIS__MESSAGE__HPP
2 #define MARNAV__AIS__MESSAGE__HPP
4 #include <memory>
5 #include <string>
6 #include <marnav/ais/binary_data.hpp>
8 namespace marnav
10 namespace ais
13 /// All known AIS message IDs.
14 enum class message_id : uint8_t {
15 NONE = 0,
16 position_report_class_a = 1,
17 position_report_class_a_assigned_schedule = 2,
18 position_report_class_a_response_to_interrogation = 3,
19 base_station_report = 4,
20 static_and_voyage_related_data = 5,
21 binary_addressed_message = 6,
22 binary_acknowledge = 7,
23 binary_broadcast_message = 8,
24 standard_sar_aircraft_position_report = 9,
25 utc_and_date_inquiry = 10,
26 utc_and_date_response = 11,
27 addressed_safety_related_message = 12,
28 safety_related_acknowledgement = 13,
29 safety_related_broadcast_message = 14,
30 interrogation = 15,
31 assignment_mode_command = 16,
32 dgnss_binary_broadcast_message = 17,
33 standard_class_b_cs_position_report = 18,
34 extended_class_b_equipment_position_report = 19,
35 data_link_management = 20,
36 aid_to_navigation_report = 21,
37 channel_management = 22,
38 group_assignment_command = 23,
39 static_data_report = 24,
40 single_slot_binary_message = 25,
41 multiple_slot_binary_message_with_communications_state = 26,
42 position_report_for_long_range_applications = 27,
45 enum class navigation_status : uint8_t {
46 under_way_using_engine = 0,
47 at_anchor = 1,
48 not_under_command = 2,
49 restricted_maneuverability = 3,
50 constrained_by_her_draught = 4,
51 moored = 5,
52 aground = 6,
53 engaged_in_Fishing = 7,
54 under_way_sailing = 8,
55 reserved_09 = 9,
56 reserved_10 = 10,
57 reserved_11 = 11,
58 reserved_12 = 12,
59 reserved_13 = 13,
60 ais_sart_is_active = 14,
61 not_defined = 15, // default
64 enum class ship_type : uint8_t {
65 not_available = 0,
66 // 1..19 reserved for future use
67 wing_in_ground = 20,
68 wing_in_ground_hazardous_cat_a = 21,
69 wing_in_ground_hazardous_cat_b = 22,
70 wing_in_ground_hazardous_cat_c = 23,
71 wing_in_ground_hazardous_cat_d = 24,
72 // 25..29 WIG reserved for future use
73 fishing = 30,
74 towing = 31,
75 towing_large = 32, // exceeds 200m length or 25m breadth
76 dredging_or_underwater_ops = 33,
77 diving_ops = 34,
78 military_ops = 35,
79 sailing = 36,
80 pleasure_craft = 37,
81 // 38..39 reserved
82 high_speed_craft = 40,
83 high_speed_craft_hazardous_cat_a = 41,
84 high_speed_craft_hazardous_cat_b = 42,
85 high_speed_craft_hazardous_cat_c = 43,
86 high_speed_craft_hazardous_cat_d = 44,
87 // 45..48 HSC reserved for future use
88 high_speed_craft_no_info = 49,
89 pilot_vessel = 50,
90 search_and_rescue_vessel = 51,
91 tug = 52,
92 port_tender = 53,
93 anti_pollution_equipment = 54,
94 law_enforcement = 55,
95 // 56..57 spare, local vessel
96 medical_transport = 58,
97 noncombatant = 59,
98 passenger = 60,
99 passenger_hazardous_cat_a = 61,
100 passenger_hazardous_cat_b = 62,
101 passenger_hazardous_cat_c = 63,
102 passenger_hazardous_cat_d = 64,
103 // 65..68 Passenger reserved for future use
104 passenger_no_info = 69,
105 cargo = 70,
106 cargo_hazardous_cat_a = 71,
107 cargo_hazardous_cat_b = 72,
108 cargo_hazardous_cat_c = 73,
109 cargo_hazardous_cat_d = 74,
110 // 75..78 Cargo reserved for future use
111 cargo_no_info = 79,
112 tanker = 80,
113 tanker_hazardous_cat_a = 81,
114 tanker_hazardous_cat_b = 82,
115 tanker_hazardous_cat_c = 83,
116 tanker_hazardous_cat_d = 84,
117 // 85..88 Tanker reserved for future use
118 tanker_no_info = 89,
119 other = 90,
120 other_hazardous_cat_a = 91,
121 other_hazardous_cat_b = 92,
122 other_hazardous_cat_c = 93,
123 other_hazardous_cat_d = 94,
124 // 95..98 Other type reserved for future use
125 other_no_info = 99,
128 /// Electronic Position Fixing Device
129 enum class epfd_fix_type : uint8_t {
130 undefined = 0,
131 gps = 1,
132 glonass = 2,
133 combined_gps_glonass = 3,
134 loran_c = 4,
135 chayka = 5,
136 integrated_navigation_system = 6,
137 surveyed = 7,
138 galileo = 8,
141 /// Enumeration of data terminal status.
142 enum class data_terminal : uint8_t { ready = 0, not_ready = 1 };
144 enum class virtual_aid : uint32_t { real_aid = 0, virtual_aid = 1 };
146 enum class off_position_indicator : uint32_t { on_position = 0, off_position = 1 };
148 /// Enumeration of all aid types
149 enum class aid_type_id : uint32_t {
150 /// 0 : Default, Type of Aid to Navigation not specified
151 unspecified = 0,
153 /// 1 : Reference point
154 reference_point = 1,
156 /// 2 : RACON (radar transponder marking a navigation hazard)
157 racon = 2,
159 /// 3 : Fixed structure off shore, such as oil platforms, wind farms, rigs. (Note: This
160 /// code should identify an obstruction that is fitted with an Aid-to-Navigation AIS
161 /// station.)
162 fixed_structure = 3,
164 /// 4 : Spare, Reserved for future use.
165 reserved = 4,
167 /// 5 : Light, without sectors
168 light_no_sectors = 5,
170 /// 6 : Light, with sectors
171 light_sectors = 6,
173 /// 7 : Leading Light Front
174 leading_light_fromt = 7,
176 /// 8 : Leading Light Rear
177 leading_light_rear = 8,
179 /// 9 : Beacon, Cardinal N
180 beacon_cardinal_n = 9,
182 /// 10: Beacon, Cardinal E
183 beacon_cardinal_e = 10,
185 /// 11: Beacon, Cardinal S
186 beacon_cardinal_s = 11,
188 /// 12: Beacon, Cardinal W
189 beacon_cardinal_w = 12,
191 /// 13: Beacon, Port hand
192 beacon_port_hand = 13,
194 /// 14: Beacon, Starboard hand
195 beacon_starboard_hand = 14,
197 /// 15: Beacon, Preferred Channel port hand
198 beacon_preferred_channel_port_hand = 15,
200 ///< 16: Beacon, Preferred Channel starboard hand
201 beacon_preferred_channel_starboard_hand = 16,
203 /// 17: Beacon, Isolated danger
204 beacon_isolated_danger = 17,
206 /// 18: Beacon, Safe water
207 beacon_safe_water = 18,
209 /// 19: Beacon, Special mark
210 beacon_sepcial_mark = 19,
212 /// 20: Cardinal Mark N
213 cardinal_n = 20,
215 /// 21: Cardinal Mark E
216 cardinal_e = 21,
218 /// 22: Cardinal Mark S
219 cardinal_s = 22,
221 /// 23: Cardinal Mark W
222 cardinal_w = 23,
224 /// 24: Port hand Mark
225 mark_port_hand = 24,
227 /// 25: Starboard hand Mark
228 mark_starboard_hand = 25,
230 /// 26: Preferred Channel Port hand
231 preferred_channel_port_hand = 26,
233 /// 27: Preferred Channel Starboard hand
234 preferred_channel_starboard_hand = 27,
236 /// 28: Isolated danger
237 isolated_danger = 28,
239 /// 29: Safe Water
240 safe_water = 29,
242 /// 30: Special Mark
243 special_mark = 30,
245 /// 31: Light Vessel / LANBY / Rigs
246 light_vessel = 31,
250 enum class maneuver_indicator_id : uint32_t { not_available = 0, normal = 1, special = 2 };
252 // AIS data is coded in a binary form. This implies a need for special
253 // value that mark the invalidity of a certain value.
254 /// @{
256 /// Value for a longitude that is not specified.
257 constexpr static const uint32_t longitude_not_available = 0x6791AC0;
259 /// Value for a latitude that is not specified.
260 constexpr static const uint32_t latitude_not_available = 0x3412140;
262 /// Value for a longitude that is not specified, short version.
263 constexpr static const uint32_t longitude_not_available_short = 0x1a838;
265 /// Value for a latitude that is not specified, short version.
266 constexpr static const uint32_t latitude_not_available_short = 0xd548;
268 /// Value for a speed over ground that is not specified.
269 constexpr static const uint32_t sog_not_available = 1023;
271 /// Value for a course over ground that is not specified.
272 constexpr static const uint32_t cog_not_available = 3600;
274 /// Value for a heading that is not specified.
275 constexpr static const uint32_t hdg_not_available = 511;
277 /// Value to indicate the absense of a timestamp.
278 constexpr static const uint8_t timestamp_not_available = 60;
280 /// Value for a year that is not specified.
281 constexpr static const uint32_t year_not_available = 0;
283 /// Value for a month that is not specified.
284 constexpr static const uint32_t month_not_available = 0;
286 /// Value for a day that is not specified.
287 constexpr static const uint32_t day_not_available = 0;
289 /// Value for a hour that is not specified.
290 constexpr static const uint32_t hour_not_available = 24;
292 /// Value for a minute that is not specified.
293 constexpr static const uint32_t minute_not_available = 60;
295 /// Value for a second that is not specified.
296 constexpr static const uint32_t second_not_available = 60;
298 /// @}
300 /// @brief Base class for all AIS messages.
301 class message : public binary_data
303 friend std::vector<std::pair<std::string, uint32_t>> encode_message(const message & msg);
305 public:
306 virtual ~message() = default;
307 message() = delete;
308 message(const message &) = default;
309 message & operator=(const message &) = default;
310 message(message &&) = default;
311 message & operator=(message &&) = default;
313 message_id type() const { return message_type; }
315 protected:
316 explicit message(message_id type)
317 : message_type(type)
321 virtual raw get_data() const = 0;
323 private:
324 message_id message_type;
327 /// @cond DEV
328 namespace detail
330 /// Checks if the specified cast is valid, throws `bad_cast` if not.
331 /// If the pointer is `nullptr`, false returns.
332 template <class T> bool check_cast(const message * s)
334 if (!s)
335 return false;
336 if (s->type() != T::ID)
337 throw std::bad_cast{};
338 return true;
341 class factory
343 public:
344 template <class T,
345 typename std::enable_if<std::is_base_of<message, T>::value, int>::type = 0>
346 static std::unique_ptr<message> parse(const raw & bits)
348 return std::unique_ptr<T>(new T{bits});
352 /// @endcond
354 /// Helper function to parse a specific message, to be used in unit tests.
356 /// @todo This breaks encapsulation.
357 template <class T, typename std::enable_if<std::is_base_of<message, T>::value, int>::type = 0>
358 std::unique_ptr<message> message_parse(const raw & bits)
360 return detail::factory::parse<T>(bits);
363 /// @{
365 /// Casts the specified message to the message given by the template parameter.
366 /// The object converted only if it is valid and of the correct type. It is not
367 /// possible to cast a message into a completley different one.
369 /// @param[in] s The message object to convert.
370 /// @retval nullptr The specified message is invalid.
371 /// @return The converted message.
372 /// @exception std::bad_cast The specified message has the wrong ID.
373 template <class T> T * message_cast(message * s)
375 return detail::check_cast<T>(s) ? static_cast<T *>(s) : nullptr;
378 /// Raw pointer const variant.
380 /// @see message_cast(message * s)
381 template <class T> const T * message_cast(const message * s)
383 return detail::check_cast<T>(s) ? static_cast<const T *>(s) : nullptr;
386 /// `std::unique_ptr` variant. If the cast is possible, the original `unique_ptr<message>`
387 /// will be invalidated and a new `unique_ptr<T>` will be returned. This has implications
388 /// within the calling code.
390 /// @param[in,out] s The message to cast.
391 /// @return The casted message. If the specified sentence was `nullptr`, the function
392 /// also returns `nullptr`.
393 /// @exception bad_cast This exception is thrown if the specified message is
394 /// not castable into the destination type `T`.
396 template <class T> std::unique_ptr<T> message_cast(std::unique_ptr<message> & s)
398 return detail::check_cast<T>(s.get()) ? std::unique_ptr<T>(static_cast<T *>(s.release()))
399 : nullptr;
402 /// `unique_ptr` ref ref variant.
404 /// @see message_cast(std::unique_ptr<message> & s)
405 template <class T> std::unique_ptr<T> message_cast(std::unique_ptr<message> && s)
407 return detail::check_cast<T>(s.get()) ? std::unique_ptr<T>(static_cast<T *>(s.release()))
408 : nullptr;
411 /// @}
415 #endif