NMEA: remove deprecated type talker_id
[marnav.git] / src / marnav / nmea / mob.cpp
blobfde33c3ce4be8ca0193f5742945f1660595845cf
1 #include <marnav/nmea/mob.hpp>
2 #include <marnav/nmea/io.hpp>
3 #include "convert.hpp"
4 #include <algorithm>
5 #include <stdexcept>
7 namespace marnav
9 namespace nmea
11 namespace
13 static mob::mob_status mob_status_mapping(
14 typename std::underlying_type<mob::mob_status>::type value)
16 switch (value) {
17 case 'A':
18 return mob::mob_status::mob_activated;
19 case 'T':
20 return mob::mob_status::test_mode;
21 case 'M':
22 return mob::mob_status::manual_button;
23 case 'V':
24 return mob::mob_status::mob_not_in_use;
25 case 'E':
26 return mob::mob_status::error;
28 throw std::invalid_argument{"invaild value for conversion to mob::mob_status"};
31 static mob::mob_position_source mob_position_source_mapping(
32 typename std::underlying_type<mob::mob_position_source>::type value)
34 switch (value) {
35 case 0:
36 return mob::mob_position_source::position_estimated;
37 case 1:
38 return mob::mob_position_source::position_reported;
39 case 2:
40 case 3:
41 case 4:
42 case 5:
43 return mob::mob_position_source::reserved;
44 case 6:
45 return mob::mob_position_source::error;
47 throw std::invalid_argument{"invaild value for conversion to mob::mob_position_source"};
50 static mob::battery_status battery_status_mapping(
51 typename std::underlying_type<mob::battery_status>::type value)
53 switch (value) {
54 case 0:
55 return mob::battery_status::good;
56 case 1:
57 return mob::battery_status::low;
58 case 2:
59 case 3:
60 case 4:
61 case 5:
62 return mob::battery_status::reserved;
63 case 6:
64 return mob::battery_status::error;
66 throw std::invalid_argument{"invaild value for conversion to mob::battery_status"};
70 std::string to_string(mob::mob_status value)
72 switch (value) {
73 case mob::mob_status::mob_activated:
74 return "A";
75 case mob::mob_status::test_mode:
76 return "T";
77 case mob::mob_status::manual_button:
78 return "M";
79 case mob::mob_status::mob_not_in_use:
80 return "V";
81 case mob::mob_status::error:
82 return "E";
84 throw std::invalid_argument{"invaild value for conversion of mob::mob_status"};
87 std::string to_string(mob::mob_position_source value)
89 switch (value) {
90 case mob::mob_position_source::position_estimated:
91 return "0";
92 case mob::mob_position_source::position_reported:
93 return "1";
94 case mob::mob_position_source::reserved:
95 return "2";
96 case mob::mob_position_source::error:
97 return "6";
99 throw std::invalid_argument{"invaild value for conversion of mob::mob_position_source"};
102 std::string to_string(mob::battery_status value)
104 switch (value) {
105 case mob::battery_status::good:
106 return "0";
107 case mob::battery_status::low:
108 return "1";
109 case mob::battery_status::reserved:
110 return "2";
111 case mob::battery_status::error:
112 return "6";
114 throw std::invalid_argument{"invaild value for conversion of mob::battery_status"};
117 constexpr sentence_id mob::ID;
118 constexpr const char * mob::TAG;
120 mob::mob()
121 : sentence(ID, TAG, talker::integrated_navigation)
125 mob::mob(talker talk, fields::const_iterator first, fields::const_iterator last)
126 : sentence(ID, TAG, talk)
128 if (std::distance(first, last) != 14)
129 throw std::invalid_argument{"invalid number of fields in mob"};
131 read(*(first + 0), emitter_id_);
132 read(*(first + 1), mob_status_, mob_status_mapping);
133 read(*(first + 2), mob_activation_utc_);
134 read(*(first + 3), mob_position_source_, mob_position_source_mapping);
135 read(*(first + 4), position_date_);
136 read(*(first + 5), position_utc_);
137 read(*(first + 6), lat_);
138 read(*(first + 7), lat_hem_);
139 read(*(first + 8), lon_);
140 read(*(first + 9), lon_hem_);
141 read(*(first + 10), cog_);
142 read(*(first + 11), sog_);
143 read(*(first + 12), mmsi_);
144 read(*(first + 13), battery_status_, battery_status_mapping);
146 // instead of reading data into temporary lat/lon, let's correct values afterwards
147 lat_ = correct_hemisphere(lat_, lat_hem_);
148 lon_ = correct_hemisphere(lon_, lon_hem_);
151 void mob::append_data_to(std::string & s) const
153 append(s, to_string(emitter_id_));
154 append(s, to_string(mob_status_));
155 append(s, to_string(mob_activation_utc_));
156 append(s, to_string(mob_position_source_));
157 append(s, to_string(position_date_));
158 append(s, to_string(position_utc_));
159 append(s, to_string(lat_));
160 append(s, to_string(lat_hem_));
161 append(s, to_string(lon_));
162 append(s, to_string(lon_hem_));
163 append(s, to_string(cog_));
164 append(s, to_string(sog_));
165 append(s, format(mmsi_, 9));
166 append(s, to_string(battery_status_));
169 geo::latitude mob::get_lat() const
171 return lat_;
174 geo::longitude mob::get_lon() const
176 return lon_;
179 utils::mmsi mob::get_mmsi() const
181 return utils::mmsi{static_cast<utils::mmsi::value_type>(mmsi_)};
184 void mob::set_emitter_id(const std::string & t)
186 if (t.empty()) {
187 emitter_id_.reset();
188 return;
191 if (t.size() > emitter_id_max)
192 throw std::invalid_argument("emitter id max 5 digits");
193 if (t.find_first_not_of("0123456789abcdefABCDEF") != std::string::npos)
194 throw std::invalid_argument("emitter id only hex digits allowed");
196 emitter_id_ = std::string(emitter_id_max, '0');
197 std::transform(begin(t), end(t), next(begin(*emitter_id_), emitter_id_max - t.size()),
198 [](std::string::value_type c) -> std::string::value_type { return std::toupper(c); });
201 void mob::set_lat(const geo::latitude & t)
203 lat_ = t;
204 lat_hem_ = convert_hemisphere(t);
207 void mob::set_lon(const geo::longitude & t)
209 lon_ = t;
210 lon_hem_ = convert_hemisphere(t);
213 void mob::set_mmsi(const utils::mmsi & t)
215 mmsi_ = t;