### Bug Summary

File: | epan/dissectors/packet-nmea0183.c
Warning: | line 1783, column 5 Value stored to 'offset' is never read

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-nmea0183.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-11-27-100330-3583-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-nmea0183.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* packet-nmea0183.c
2 | * Routines for NMEA 0183 protocol dissection
3 | * Copyright 2024 Casper Meijn <casper@meijn.net>
4 | *
5 | * Wireshark - Network traffic analyzer
6 | * By Gerald Combs <gerald@wireshark.org>
7 | * Copyright 1998 Gerald Combs
8 | *
9 | * SPDX-License-Identifier: GPL-2.0-or-later
10 | */
11 |
12 | #include "config.h"
13 | #include <epan/packet.h>
14 | #include <epan/expert.h>
15 |
16 |
17 | /*
18 | * null-terminated sentence prefix string "UdPbC"
19 | */
20 | #define UDPBC"UdPbC" "UdPbC"
21 |
22 | static int hf_nmea0183_talker_id;
23 | static int hf_nmea0183_sentence_id;
24 | static int hf_nmea0183_unknown_field;
25 | static int hf_nmea0183_checksum;
26 | static int hf_nmea0183_checksum_calculated;
27 |
28 | static int hf_nmea0183_dpt_depth;
29 | static int hf_nmea0183_dpt_offset;
30 | static int hf_nmea0183_dpt_max_range;
31 |
32 | static int hf_nmea0183_hdt_heading;
33 | static int hf_nmea0183_hdt_unit;
34 |
35 | static int hf_nmea0183_alr_time;
36 | static int hf_nmea0183_alr_time_hour;
37 | static int hf_nmea0183_alr_time_minute;
38 | static int hf_nmea0183_alr_time_second;
39 | static int hf_nmea0183_alr_alarm_id;
40 | static int hf_nmea0183_alr_alarm_cond;
41 | static int hf_nmea0183_alr_alarm_ack_st;
42 | static int hf_nmea0183_alr_alarm_desc_txt;
43 |
44 | static int hf_nmea0183_gga_time;
45 | static int hf_nmea0183_gga_time_hour;
46 | static int hf_nmea0183_gga_time_minute;
47 | static int hf_nmea0183_gga_time_second;
48 | static int hf_nmea0183_gga_latitude;
49 | static int hf_nmea0183_gga_latitude_degree;
50 | static int hf_nmea0183_gga_latitude_minute;
51 | static int hf_nmea0183_gga_latitude_direction;
52 | static int hf_nmea0183_gga_longitude;
53 | static int hf_nmea0183_gga_longitude_degree;
54 | static int hf_nmea0183_gga_longitude_minute;
55 | static int hf_nmea0183_gga_longitude_direction;
56 | static int hf_nmea0183_gga_quality;
57 | static int hf_nmea0183_gga_number_satellites;
58 | static int hf_nmea0183_gga_horizontal_dilution;
59 | static int hf_nmea0183_gga_altitude;
60 | static int hf_nmea0183_gga_altitude_unit;
61 | static int hf_nmea0183_gga_geoidal_separation;
62 | static int hf_nmea0183_gga_geoidal_separation_unit;
63 | static int hf_nmea0183_gga_age_dgps;
64 | static int hf_nmea0183_gga_dgps_station;
65 |
66 | static int hf_nmea0183_gll_latitude;
67 | static int hf_nmea0183_gll_latitude_degree;
68 | static int hf_nmea0183_gll_latitude_minute;
69 | static int hf_nmea0183_gll_latitude_direction;
70 | static int hf_nmea0183_gll_longitude;
71 | static int hf_nmea0183_gll_longitude_degree;
72 | static int hf_nmea0183_gll_longitude_minute;
73 | static int hf_nmea0183_gll_longitude_direction;
74 | static int hf_nmea0183_gll_time;
75 | static int hf_nmea0183_gll_time_hour;
76 | static int hf_nmea0183_gll_time_minute;
77 | static int hf_nmea0183_gll_time_second;
78 | static int hf_nmea0183_gll_status;
79 | static int hf_nmea0183_gll_mode;
80 |
81 | static int hf_nmea0183_gst_time;
82 | static int hf_nmea0183_gst_time_hour;
83 | static int hf_nmea0183_gst_time_minute;
84 | static int hf_nmea0183_gst_time_second;
85 | static int hf_nmea0183_gst_rms_total_sd;
86 | static int hf_nmea0183_gst_ellipse_major_sd;
87 | static int hf_nmea0183_gst_ellipse_minor_sd;
88 | static int hf_nmea0183_gst_ellipse_orientation;
89 | static int hf_nmea0183_gst_latitude_sd;
90 | static int hf_nmea0183_gst_longitude_sd;
91 | static int hf_nmea0183_gst_altitude_sd;
92 |
93 | static int hf_nmea0183_rot_rate_of_turn;
94 | static int hf_nmea0183_rot_valid;
95 | static int hf_nmea0183_txt_num;
96 | static int hf_nmea0183_txt_sent_num;
97 | static int hf_nmea0183_txt_id;
98 | static int hf_nmea0183_txt_msg;
99 |
100 | static int hf_nmea0183_vbw_water_speed_longitudinal;
101 | static int hf_nmea0183_vbw_water_speed_transverse;
102 | static int hf_nmea0183_vbw_water_speed_valid;
103 | static int hf_nmea0183_vbw_ground_speed_longitudinal;
104 | static int hf_nmea0183_vbw_ground_speed_transverse;
105 | static int hf_nmea0183_vbw_ground_speed_valid;
106 | static int hf_nmea0183_vbw_stern_water_speed;
107 | static int hf_nmea0183_vbw_stern_water_speed_valid;
108 | static int hf_nmea0183_vbw_stern_ground_speed;
109 | static int hf_nmea0183_vbw_stern_ground_speed_valid;
110 |
111 | static int hf_nmea0183_vhw_true_heading;
112 | static int hf_nmea0183_vhw_true_heading_unit;
113 | static int hf_nmea0183_vhw_magnetic_heading;
114 | static int hf_nmea0183_vhw_magnetic_heading_unit;
115 | static int hf_nmea0183_vhw_water_speed_knot;
116 | static int hf_nmea0183_vhw_water_speed_knot_unit;
117 | static int hf_nmea0183_vhw_water_speed_kilometer;
118 | static int hf_nmea0183_vhw_water_speed_kilometer_unit;
119 |
120 | static int hf_nmea0183_vlw_cumulative_water;
121 | static int hf_nmea0183_vlw_cumulative_water_unit;
122 | static int hf_nmea0183_vlw_trip_water;
123 | static int hf_nmea0183_vlw_trip_water_unit;
124 | static int hf_nmea0183_vlw_cumulative_ground;
125 | static int hf_nmea0183_vlw_cumulative_ground_unit;
126 | static int hf_nmea0183_vlw_trip_ground;
127 | static int hf_nmea0183_vlw_trip_ground_unit;
128 |
129 | static int hf_nmea0183_vtg_true_course;
130 | static int hf_nmea0183_vtg_true_course_unit;
131 | static int hf_nmea0183_vtg_magnetic_course;
132 | static int hf_nmea0183_vtg_magnetic_course_unit;
133 | static int hf_nmea0183_vtg_ground_speed_knot;
134 | static int hf_nmea0183_vtg_ground_speed_knot_unit;
135 | static int hf_nmea0183_vtg_ground_speed_kilometer;
136 | static int hf_nmea0183_vtg_ground_speed_kilometer_unit;
137 | static int hf_nmea0183_vtg_mode;
138 |
139 | static int hf_nmea0183_zda_time;
140 | static int hf_nmea0183_zda_time_hour;
141 | static int hf_nmea0183_zda_time_minute;
142 | static int hf_nmea0183_zda_time_second;
143 | static int hf_nmea0183_zda_date_day;
144 | static int hf_nmea0183_zda_date_month;
145 | static int hf_nmea0183_zda_date_year;
146 | static int hf_nmea0183_zda_local_zone_hour;
147 | static int hf_nmea0183_zda_local_zone_minute;
148 |
149 | static int hf_nmea0183_sentence_prefix;
150 | static int hf_nmea0183_tag_block;
151 |
152 | static int ett_nmea0183;
153 | static int ett_nmea0183_checksum;
154 | static int ett_nmea0183_sentence;
155 | static int ett_nmea0183_zda_time;
156 | static int ett_nmea0183_alr_time;
157 | static int ett_nmea0183_gga_time;
158 | static int ett_nmea0183_gga_latitude;
159 | static int ett_nmea0183_gga_longitude;
160 | static int ett_nmea0183_gll_time;
161 | static int ett_nmea0183_gll_latitude;
162 | static int ett_nmea0183_gll_longitude;
163 | static int ett_nmea0183_gst_time;
164 | static int ett_nmea0183_tag_block;
165 |
166 | static expert_field ei_nmea0183_invalid_first_character;
167 | static expert_field ei_nmea0183_missing_checksum_character;
168 | static expert_field ei_nmea0183_invalid_end_of_line;
169 | static expert_field ei_nmea0183_checksum_incorrect;
170 | static expert_field ei_nmea0183_sentence_too_long;
171 | static expert_field ei_nmea0183_field_time_too_short;
172 | static expert_field ei_nmea0183_field_latitude_too_short;
173 | static expert_field ei_nmea0183_field_longitude_too_short;
174 | static expert_field ei_nmea0183_field_missing;
175 | static expert_field ei_nmea0183_gga_altitude_unit_incorrect;
176 | static expert_field ei_nmea0183_gga_geoidal_separation_unit_incorrect;
177 | static expert_field ei_nmea0183_hdt_unit_incorrect;
178 | static expert_field ei_nmea0183_vhw_true_heading_unit_incorrect;
179 | static expert_field ei_nmea0183_vhw_magnetic_heading_unit_incorrect;
180 | static expert_field ei_nmea0183_vhw_water_speed_knot_unit_incorrect;
181 | static expert_field ei_nmea0183_vhw_water_speed_kilometer_unit_incorrect;
182 | static expert_field ei_nmea0183_vlw_cumulative_water_unit_incorrect;
183 | static expert_field ei_nmea0183_vlw_trip_water_unit_incorrect;
184 | static expert_field ei_nmea0183_vlw_cumulative_ground_unit_incorrect;
185 | static expert_field ei_nmea0183_vlw_trip_ground_unit_incorrect;
186 | static expert_field ei_nmea0183_vtg_true_course_unit_incorrect;
187 | static expert_field ei_nmea0183_vtg_magnetic_course_unit_incorrect;
188 | static expert_field ei_nmea0183_vtg_ground_speed_knot_unit_incorrect;
189 | static expert_field ei_nmea0183_vtg_ground_speed_kilometer_unit_incorrect;
190 |
191 | static int proto_nmea0183;
192 |
193 | static dissector_handle_t nmea0183_handle;
194 |
195 | // List of known Talker IDs (Source: NMEA Revealed by Eric S. Raymond, https://gpsd.gitlab.io/gpsd/NMEA.html, retrieved 2023-01-26)
196 | static const string_string known_talker_ids[] = {
197 | {"AB", "Independent AIS Base Station"},
198 | {"AD", "Dependent AIS Base Station"},
199 | {"AG", "Autopilot - General"},
200 | {"AI", "Mobile AIS Station"},
201 | {"AN", "AIS Aid to Navigation"},
202 | {"AP", "Autopilot - Magnetic"},
203 | {"AR", "AIS Receiving Station"},
204 | {"AT", "AIS Transmitting Station"},
205 | {"AX", "AIS Simplex Repeater"},
206 | {"BD", "BeiDou (China)"},
207 | {"BI", "Bilge System"},
208 | {"BN", "Bridge navigational watch alarm system"},
209 | {"BS", "Base AIS Station"},
210 | {"CA", "Central Alarm"},
211 | {"CC", "Computer - Programmed Calculator (obsolete)"},
212 | {"CD", "Communications - Digital Selective Calling (DSC)"},
213 | {"CM", "Computer - Memory Data (obsolete)"},
214 | {"CR", "Communications - Data Receiver"},
215 | {"CS", "Communications - Satellite"},
216 | {"CT", "Communications - Radio-Telephone (MF/HF)"},
217 | {"CV", "Communications - Radio-Telephone (VHF)"},
218 | {"CX", "Communications - Scanning Receiver"},
219 | {"DE", "DECCA Navigation (obsolete)"},
220 | {"DF", "Direction Finder"},
221 | {"DM", "Velocity Sensor, Speed Log, Water, Magnetic"},
222 | {"DP", "Dynamiv Position"},
223 | {"DU", "Duplex repeater station"},
224 | {"EC", "Electronic Chart System (ECS)"},
225 | {"EI", "Electronic Chart Display & Information System (ECDIS)"},
226 | {"EP", "Emergency Position Indicating Beacon (EPIRB)"},
227 | {"ER", "Engine Room Monitoring Systems"},
228 | {"FD", "Fire Door"},
229 | {"FE", "Fire Extinguisher System"},
230 | {"FR", "Fire Detection System"},
231 | {"FS", "Fire Sprinkler"},
232 | {"GA", "Galileo Positioning System"},
233 | {"GB", "BeiDou (China)"},
234 | {"GI", "NavIC, IRNSS (India)"},
235 | {"GL", "GLONASS, according to IEIC 61162-1"},
236 | {"GN", "Combination of multiple satellite systems (NMEA 1083)"},
237 | {"GP", "Global Positioning System receiver"},
238 | {"GQ", "QZSS regional GPS augmentation system (Japan)"},
239 | {"HC", "Heading - Magnetic Compass"},
240 | {"HD", "Hull Door"},
241 | {"HE", "Heading - North Seeking Gyro"},
242 | {"HF", "Heading - Fluxgate"},
243 | {"HN", "Heading - Non North Seeking Gyro"},
244 | {"HS", "Hull Stress"},
245 | {"II", "Integrated Instrumentation"},
246 | {"IN", "Integrated Navigation"},
247 | {"JA", "Alarm and Monitoring"},
248 | {"JB", "Water Monitoring"},
249 | {"JC", "Power Management"},
250 | {"JD", "Propulsion Control"},
251 | {"JE", "Engine Control"},
252 | {"JF", "Propulsion Boiler"},
253 | {"JG", "Aux Boiler"},
254 | {"JH", "Engine Governor"},
255 | {"LA", "Loran A (obsolete)"},
256 | {"LC", "Loran C (obsolete)"},
257 | {"MP", "Microwave Positioning System (obsolete)"},
258 | {"MX", "Multiplexer"},
259 | {"NL", "Navigation light controller"},
260 | {"NV", "Night Vision"},
261 | {"OM", "OMEGA Navigation System (obsolete)"},
262 | {"OS", "Distress Alarm System (obsolete)"},
263 | {"P ", "Vendor specific"},
264 | {"QZ", "QZSS regional GPS augmentation system (Japan)"},
265 | {"RA", "RADAR and/or ARPA"},
266 | {"RB", "Record Book"},
267 | {"RC", "Propulsion Machinery including Remote Control"},
268 | {"RI", "Rudder Angle Indicator"},
269 | {"SA", "Physical Shore AUS Station"},
270 | {"SC", "Steering Control System/Device"},
271 | {"SD", "Depth Sounder"},
272 | {"SG", "Steering Gear"},
273 | {"SN", "Electronic Positioning System, other/general"},
274 | {"SS", "Scanning Sounder"},
275 | {"ST", "Skytraq debug output"},
276 | {"TC", "Track Control"},
277 | {"TI", "Turn Rate Indicator"},
278 | {"TR", "TRANSIT Navigation System"},
279 | {"U0", "User Configured 0"},
280 | {"U1", "User Configured 1"},
281 | {"U2", "User Configured 2"},
282 | {"U3", "User Configured 3"},
283 | {"U4", "User Configured 4"},
284 | {"U5", "User Configured 5"},
285 | {"U6", "User Configured 6"},
286 | {"U7", "User Configured 7"},
287 | {"U8", "User Configured 8"},
288 | {"U9", "User Configured 9"},
289 | {"UP", "Microprocessor controller"},
290 | {"VA", "VHF Data Exchange System (VDES), ASM"},
291 | {"VD", "Velocity Sensor, Doppler, other/general"},
292 | {"VM", "Velocity Sensor, Speed Log, Water, Magnetic"},
293 | {"VR", "Voyage Data recorder"},
294 | {"VS", "VHF Data Exchange System (VDES), Satellite"},
295 | {"VT", "VHF Data Exchange System (VDES), Terrestrial"},
296 | {"VW", "Velocity Sensor, Speed Log, Water, Mechanical"},
297 | {"WD", "Watertight Door"},
298 | {"WI", "Weather Instruments"},
299 | {"WL", "Water Level"},
300 | {"YC", "Transducer - Temperature (obsolete)"},
301 | {"YD", "Transducer - Displacement, Angular or Linear (obsolete)"},
302 | {"YF", "Transducer - Frequency (obsolete)"},
303 | {"YL", "Transducer - Level (obsolete)"},
304 | {"YP", "Transducer - Pressure (obsolete)"},
305 | {"YR", "Transducer - Flow Rate (obsolete)"},
306 | {"YT", "Transducer - Tachometer (obsolete)"},
307 | {"YV", "Transducer - Volume (obsolete)"},
308 | {"YX", "Transducer"},
309 | {"ZA", "Timekeeper - Atomic Clock"},
310 | {"ZC", "Timekeeper - Chronometer"},
311 | {"ZQ", "Timekeeper - Quartz"},
312 | {"ZV", "Timekeeper - Radio Update, WWV or WWVH"},
313 | {NULL((void*)0), NULL((void*)0)}};
314 |
315 | // List of known Sentence IDs (Source: NMEA Revealed by Eric S. Raymond, https://gpsd.gitlab.io/gpsd/NMEA.html, retrieved 2023-01-26)
316 | static const string_string known_sentence_ids[] = {
317 | {"AAM", "Waypoint Arrival Alarm"},
318 | {"ABK", "UAIS Addressed and Binary Broadcast Acknowledgement"},
319 | {"ACA", "UAIS Regional Channel Assignment Message"},
320 | {"ACF", "General AtoN Station Configuration Command"},
321 | {"ACG", "Extended General AtoN Station Configuration Command"},
322 | {"ACK", "Alarm Acknowledgement"},
323 | {"ACM", "Preparation and Initiation of an AIS Base Station Addressed Channel Management Message (Message 22)"},
324 | {"ACS", "UAIS Channel Management Information Source"},
325 | {"ADS", "Automatic Device Status"},
326 | {"AFB", "AtoN Forced Broadcast Command"},
327 | {"AGA", "Preparation and Initiation of an AIS Base Station Broadcast of a Group Assignment Message (Message 23)"},
328 | {"AID", "AtoN Identification Configuration Command"},
329 | {"AIR", "UAIS Interrogation Request"},
330 | {"AKD", "Acknowledge Detail Alarm Condition"},
331 | {"ALA", "Set Detail Alarm Condition"},
332 | {"ALM", "GPS Almanac Data"},
333 | {"ALR", "Set Alarm State"},
334 | {"ARC", "Alert Command Refused"},
335 | {"APA", "Autopilot Sentence A"},
336 | {"APB", "Autopilot Sentence B"},
337 | {"ASD", "Autopilot System Data"},
338 | {"ASN", "Preparation and Initiation of an AIS Base Station Broadcast of Assignment VDL (Message 16)"},
339 | {"BBM", "AIS Broadcast BinaryMessage"},
340 | {"BCG", "Base Station Configuration, General Command"},
341 | {"BCL", "Base Station Configuration, Location Command"},
342 | {"BEC", "Bearing & Distance to Waypoint - Dead Reckoning"},
343 | {"BER", "Bearing & Distance to Waypoint, Dead Reckoning, Rhumb Line"},
344 | {"BOD", "Bearing - Waypoint to Waypoint"},
345 | {"BPI", "Bearing & Distance to Point of Interest"},
346 | {"BWC", "Bearing & Distance to Waypoint - Great Circle"},
347 | {"BWR", "Bearing and Distance to Waypoint - Rhumb Line"},
348 | {"BWW", "Bearing - Waypoint to Waypoint"},
349 | {"CBR", "Configure Broadcast Rates for AIS AtoN Station Message Command"},
350 | {"CEK", "Configure Encryption Key Command"},
351 | {"COP", "Configure the Operational Period, Command"},
352 | {"CPC", "Configure Parameter-Code for UNIX Time Parameter (c)"},
353 | {"CPD", "Configure Parameter-Code for Destination-Identification Parameter (d)"},
354 | {"CPG", "Configure Parameter-Code for the Sentence-Grouping Parameter (g)"},
355 | {"CPN", "Configure Parameter-Code for the Line-Count Parameter (n)"},
356 | {"CPR", "Configure Parameter-Code for Relative Time Parameter (r)"},
357 | {"CPS", "Configure Parameter-Code for the Source-Identification Parameter (s)"},
358 | {"CPT", "Configure Parameter-Code for General Alphanumeric String Parameter (t)"},
359 | {"CUR", "Water Current Layer"},
360 | {"DBK", "Echosounder - Depth Below Keel"},
361 | {"DBS", "Echosounder - Depth Below Surface"},
362 | {"DBT", "Echosounder - Depth Below Transducer"},
363 | {"DCN", "DECCA Position"},
364 | {"DCR", "Device Capability Report"},
365 | {"DDC", "Display Dimming Control"},
366 | {"DLM", "Data Link Management Slot Allocations for Base Station"},
367 | {"DOR", "Door Status Detection"},
368 | {"DPT", "Depth of Water"},
369 | {"DRU", "Dual Doppler Auxiliary Data"},
370 | {"DSC", "Digital Selective Calling Information"},
371 | {"DSE", "Extended DSC"},
372 | {"DSI", "DSC Transponder Initiate"},
373 | {"DSR", "DSC Transponder Response"},
374 | {"DTM", "Datum Reference"},
375 | {"ECB", "Configure Broadcast Rates for Base Station Messages with Epoch Planning Support"},
376 | {"ETL", "Engine Telegraph Operation Status"},
377 | {"EVE", "General Event Message"},
378 | {"FIR", "Fire Detection"},
379 | {"FSI", "Frequency Set Information"},
380 | {"FSR", "Frame Summary of AIS Reception"},
381 | {"GAL", "Galileo Almanac Data"},
382 | {"GBS", "GPS Satellite Fault Detection"},
383 | {"GDA", "Dead Reckoning Positions"},
384 | {"GEN", "Generic Binary/Status Information"},
385 | {"GFA", "GNSS Fix Accuracy and Integrity"},
386 | {"GGA", "Global Positioning System Fix Data"},
387 | {"GLA", "Loran-C Positions"},
388 | {"GLC", "Geographic Position, Loran-C"},
389 | {"GLL", "Geographic Position - Latitude/Longitude"},
390 | {"GMP", "GNSS Map Projection Fix Data"},
391 | {"GNS", "GNSS Fix data"},
392 | {"GOA", "OMEGA Positions"},
393 | {"GRS", "GNSS Range Residuals"},
394 | {"GSA", "GNSS DOP and Active Satellites"},
395 | {"GST", "GNSS Pseudorange Noise Statistics"},
396 | {"GSV", "GNSS Satellites in View"},
397 | {"GTD", "Geographic Location in Time Differences"},
398 | {"GXA", "TRANSIT Position"},
399 | {"HBT", "Heartbeat Supervision Report"},
400 | {"HCC", "Compass Heading"},
401 | {"HCD", "Heading and Deviation"},
402 | {"HDG", "Heading - Deviation & Variation"},
403 | {"HDM", "Heading - Magnetic"},
404 | {"HDT", "Heading - True"},
405 | {"HFB", "Trawl Headrope to Footrope and Bottom"},
406 | {"HMR", "Heading, Monitor Receive"},
407 | {"HMS", "Heading, Monitor Set"},
408 | {"HSC", "Heading Steering Command"},
409 | {"HSS", "Hull Stress Surveillance Systems"},
410 | {"HTC", "Heading/Track Control Command"},
411 | {"HTD", "Heading/Track Control Data"},
412 | {"HVD", "Magnetic Variation, Automatic"},
413 | {"HVM", "Magnetic Variation, Manually Set"},
414 | {"IMA", "Vessel Identification"},
415 | {"ITS", "Trawl Door Spread 2 Distance"},
416 | {"LCD", "Loran-C Signal Data"},
417 | {"LR1", "UAIS Long-range Reply Sentence 1"},
418 | {"LR2", "UAIS Long-range Reply Sentence 2"},
419 | {"LR3", "UAIS Long-range Reply Sentence 3"},
420 | {"LRF", "UAIS Long-Range Function"},
421 | {"LRI", "UAIS Long-Range Interrogation"},
422 | {"LTI", "UAIS Long-Range Interrogation"},
423 | {"MDA", "Meteorological Composite"},
424 | {"MEB", "Message Input for Broadcast, Command"},
425 | {"MHU", "Humidity"},
426 | {"MLA", "GLONASS Almanac Data"},
427 | {"MMB", "Barometer"},
428 | {"MSK", "Control for a Beacon Receiver"},
429 | {"MSS", "Beacon Receiver Status"},
430 | {"MTA", "Air Temperature"},
431 | {"MTW", "Mean Temperature of Water"},
432 | {"MWD", "Wind Direction & Speed"},
433 | {"MWH", "Wave Height"},
434 | {"MWS", "Wind & Sea State"},
435 | {"MWV", "Wind Speed and Angle"},
436 | {"NAK", "Negative Acknowledgement"},
437 | {"NRM", "NAVTEX Receiver Mask"},
438 | {"NRX", "NAVTEX Received Message"},
439 | {"ODC", "Echosounder - ODEC DPT Format"},
440 | {"OLN", "Omega Lane Numbers"},
441 | {"OLW", "Omega Lane Width"},
442 | {"OMP", "Omega Position"},
443 | {"OSD", "Own Ship Data"},
444 | {"OZN", "Omega Zone Number"},
445 | {"POS", "Device Position and Ship Dimensions Report or Configuration Command"},
446 | {"PRC", "Propulsion Remote Control Status"},
447 | {"R00", "Waypoints in active route"},
448 | {"RLM", "Return Link Message"},
449 | {"RMA", "Recommended Minimum Specific Loran-C Data"},
450 | {"RMB", "Recommended Minimum Navigation Information"},
451 | {"RMC", "Recommended Minimum Specific GNSS Data"},
452 | {"RNN", "Routes"},
453 | {"ROO", "Waypoints in Active Route"},
454 | {"ROR", "Rudder Order Status"},
455 | {"ROT", "Rate Of Turn"},
456 | {"RPM", "Revolutions"},
457 | {"RSA", "Rudder Sensor Angle"},
458 | {"RSD", "RADAR System Data"},
459 | {"RST", "Equipment Reset Command"},
460 | {"RTE", "Routes"},
461 | {"SBK", "Loran-C Blink Status"},
462 | {"SCD", "Loran-C ECDs"},
463 | {"SCY", "Loran-C Cycle Lock Status"},
464 | {"SDB", "Loran-C Signal Strength"},
465 | {"SFI", "Scanning Frequency Information"},
466 | {"SGD", "Position Accuracy Estimate"},
467 | {"SGR", "Loran-C Chain Identifier"},
468 | {"SID", "Set an Equipment's Identification, Command"},
469 | {"SIU", "Loran-C Stations in Use"},
470 | {"SLC", "Loran-C Status"},
471 | {"SPO", "Select AIS Device's Processing and Output"},
472 | {"SNC", "Navigation Calculation Basis"},
473 | {"SNU", "Loran-C SNR Status"},
474 | {"SPO", "Select AIS Device's Processing and Output"},
475 | {"SPS", "Loran-C Predicted Signal Strength"},
476 | {"SSD", "UAIS Ship Static Data"},
477 | {"SSF", "Position Correction Offset"},
478 | {"STC", "Time Constant"},
479 | {"STN", "Multiple Data ID"},
480 | {"STR", "Tracking Reference"},
481 | {"SYS", "Hybrid System Configuration"},
482 | {"TBR", "TAG Block Report"},
483 | {"TBS", "TAG Block Listener Source-Identification Configuration Command"},
484 | {"TDS", "Trawl Door Spread Distance"},
485 | {"TEC", "TRANSIT Satellite Error Code & Doppler Count"},
486 | {"TEP", "TRANSIT Satellite Predicted Elevation"},
487 | {"TFI", "Trawl Filling Indicator"},
488 | {"TFR", "Transmit Feedback Report"},
489 | {"TGA", "TRANSIT Satellite Antenna & Geoidal Heights"},
490 | {"THS", "True Heading and Status"},
491 | {"TIF", "TRANSIT Satellite Initial Flag"},
492 | {"TLB", "Target Label"},
493 | {"TLL", "Target Latitude and Longitude"},
494 | {"TPC", "Trawl Position Cartesian Coordinates"},
495 | {"TPR", "Trawl Position Relative Vessel"},
496 | {"TPT", "Trawl Position True"},
497 | {"TRC", "Thruster Control Data"},
498 | {"TRD", "Thruster Response Data"},
499 | {"TRF", "TRANSIT Fix Data"},
500 | {"TRP", "TRANSIT Satellite Predicted Direction of Rise"},
501 | {"TRS", "TRANSIT Satellite Operating Status"},
502 | {"TSA", "Transmit Slot Assignment"},
503 | {"TSP", "Transmit Slot Prohibit"},
504 | {"TSR", "Transmit Slot Prohibit - Status Report"},
505 | {"TTD", "Tracked Target Data"},
506 | {"TTM", "Tracked Target Message"},
507 | {"TUT", "Transmission of Multi-Language Text"},
508 | {"TXT", "Text Transmission"},
509 | {"UID", "User Identification Code Transmission"},
510 | {"VBW", "Dual Ground/Water Speed"},
511 | {"VCD", "Current at Selected Depth"},
512 | {"VDR", "Set and Drift"},
513 | {"VER", "Version"},
514 | {"VHW", "Water Speed and Heading"},
515 | {"VLW", "Distance Traveled through Water"},
516 | {"VPE", "Speed, Dead Reckoned Parallel to True Wind"},
517 | {"VPW", "Speed, Measured Parallel to Wind"},
518 | {"VSD", "UAIS Voyage Static Data"},
519 | {"VSI", "VDL Signal Information"},
520 | {"VTA", "Actual Track"},
521 | {"VTG", "Track made good and Ground speed"},
522 | {"VTI", "Intended Track"},
523 | {"VWE", "Wind Track Efficiency"},
524 | {"VWR", "Relative Wind Speed and Angle"},
525 | {"VWT", "True Wind Speed and Angle"},
526 | {"WAT", "Water Level Detection"},
527 | {"WCV", "Waypoint Closure Velocity"},
528 | {"WDC", "Distance to Waypoint - Great Circle"},
529 | {"WDR", "Distance to Waypoint - Rhumb Line"},
530 | {"WFM", "Route Following Mode"},
531 | {"WNC", "Distance - Waypoint to Waypoint"},
532 | {"WNR", "Waypoint-to-Waypoint Distance, Rhumb Line"},
533 | {"WPL", "Waypoint Location"},
534 | {"XDR", "Transducer Measurement"},
535 | {"XTE", "Cross-Track Error, Measured"},
536 | {"XTR", "Cross Track Error - Dead Reckoning"},
537 | {"YWP", "Water Propagation Speed"},
538 | {"YWS", "Water Profile"},
539 | {"ZAA", "Time, Elapsed/Estimated"},
540 | {"ZCD", "Timer"},
541 | {"ZDA", "Time & Date - UTC, day, month, year and local time zone"},
542 | {"ZDL", "Time and Distance to Variable Point"},
543 | {"ZEV", "Event Timer"},
544 | {"ZFO", "UTC & Time from origin Waypoint"},
545 | {"ZLZ", "Time of Day"},
546 | {"ZTG", "UTC & Time to Destination Waypoint"},
547 | {"ZZU", "Time, UTC"},
548 | {NULL((void*)0), NULL((void*)0)}};
549 |
550 | /* Proprietary Manufacturer Mnemonic Coder lookup table */
551 | /* https://web.nmea.org/External/WCPages/WCWebContent/webcontentpage.aspx?ContentID=364 */
552 | static const string_string manufacturer_vals[] = {
553 | {"3SN", "3-S Navigation"},
554 | {"AAB", "ASM Selective Addressed Message (Reserved for Future Use)"},
555 | {"AAR", "Asian American Resources"},
556 | {"ABB", "ASM Broadcast Message (Reserved for Future Use)"},
557 | {"ACE", "Auto-Comm Engineering Corporation"},
558 | {"ACR", "ACR Electronics, Inc."},
559 | {"ACS", "Arco Solar Inc."},
560 | {"ACT", "Advanced Control Technology"},
561 | {"ADI", "Aditel"},
562 | {"ADM", "ASM VHF Data-Link Message (Reserved for Future Use)"},
563 | {"ADN", "AD Navigation"},
564 | {"ADO", "ASM VHF Data-Link Own-Vessel Report (Reserved for Future Use"},
565 | {"AGB", "ASM Geographical Multicast Message (Reserved for Future Use"},
566 | {"AGI", "Airguide Instrument Co."},
567 | {"AGL", "Alert Group List (Reserved for Future Use)"},
568 | {"AHA", "Autohelm of America"},
569 | {"AIP", "AIPHONE Corporation"},
570 | {"ALD", "Alden Electronics, Inc."},
571 | {"AMB", "Ambarella, Inc. "},
572 | {"AMC", "AllTek Marine Electronics Corp."},
573 | {"AMI", "Advanced Marine Instrumentation, Ltd."},
574 | {"AMK", "ASM Addressed and Broadcast Message Acknowledgement (Reserved for Future Use)"},
575 | {"AMM", "Aquametro Oil & Marine"},
576 | {"AMR", "AMR Systems"},
577 | {"AMT", "Airmar Technology Corporation"},
578 | {"AND", "Andrew Corporation"},
579 | {"ANI", "Autonautic Instrumental Sl. (Spain)"},
580 | {"ANS", "Antenna Specialists"},
581 | {"ANX", "Analytyx Electronic Systems"},
582 | {"ANZ", "Anschutz of America"},
583 | {"AOB", "Aerobytes, Ltd."},
584 | {"APC", "Apelco Electronics & Navigation"},
585 | {"APN", "American Pioneer, Inc."},
586 | {"APO", "Automated Procedure Options (Reserved for Future Use)"},
587 | {"APW", "Pharos Marine Automatic Power"},
588 | {"APX", "Amperex, Inc."},
589 | {"AQC", "Aqua-Chem, Inc."},
590 | {"AQD", "AquaDynamics, Inc."},
591 | {"AQM", "Aqua Meter Instrument Corp."},
592 | {"ARL", "Active Research, Ltd."},
593 | {"ART", "Arlt Technologies, GmbH (Germany)"},
594 | {"ARV", "Arvento Mobile Systems"},
595 | {"ASH", "Ashtech"},
596 | {"ASP", "American Solar Power"},
597 | {"ATC", "Advanced C Technology, Ltd."},
598 | {"ATE", "Aetna Engineering"},
599 | {"ATM", "Atlantic Marketing Company"},
600 | {"ATR", "Airtron"},
601 | {"ATV", "Activation, Inc."},
602 | {"AUC", "Automated Procedure Control (Reserved for Future Use)"},
603 | {"AUP", "Automated Procedure Query (Reserved for Future Use)"},
604 | {"AUS", "Automated Procedure Status (Reserved for Future Use)"},
605 | {"AVN", "Advanced Navigation, Inc."},
606 | {"AWA", "Awa New Zealand, Ltd."},
607 | {"AXN", "Axiom Navigation, Inc."},
608 | {"BBG", "BBG, Inc."},
609 | {"BBL", "BBL Industries, Inc."},
610 | {"BBR", "BBR and Associates"},
611 | {"BDV", "Brisson Development, Inc."},
612 | {"BEC", "Boat Electric Corporation"},
613 | {"BFA", "Blueflow Americas"},
614 | {"BGG", "Bodensee Gravitymeter Geo-Systems (BGS)"},
615 | {"BGS", "Barringer Geoservice"},
616 | {"BGT", "Brookes and Gatehouse, Inc."},
617 | {"BHE", "BH Electronics"},
618 | {"BHR", "Bahr Technologies, Inc."},
619 | {"BLB", "Bay Laboratories"},
620 | {"BMC", "BMC"},
621 | {"BME", "Bartel Marine Electronics"},
622 | {"BMS", "Becker Marine Systems"},
623 | {"BMT", "Aventics GmbH (formerly Bosch Rexroth AG Marine Technique) (Germany)"},
624 | {"BNI", "Neil Brown Instrument Systems"},
625 | {"BNS", "Bowditch Navigation Systems"},
626 | {"BRM", "Mel Barr Company"},
627 | {"BRO", "Broadgate, Ltd."},
628 | {"BRY", "Byrd Industries"},
629 | {"BTH", "Benthos, Inc."},
630 | {"BTK", "Baltek Corporation"},
631 | {"BTS", "Boat Sentry, Inc."},
632 | {"BVE", "BV Engineering"},
633 | {"BXA", "Bendix-Avalex, Inc."},
634 | {"CAI", "Cambridge Aero Instruments"},
635 | {"CAT", "Catel"},
636 | {"CBN", "Cybernet Marine Products"},
637 | {"CCA", "Copal Corporation of America"},
638 | {"CCC", "Coastel Communications Company"},
639 | {"CCL", "Coastal Climate Company"},
640 | {"CCM", "Coastal Communications"},
641 | {"CDC", "Cordic Company"},
642 | {"CDI", "Chetco Digital Instruments"},
643 | {"CDL", "Teledyne CDL (CDLTD), Inc."},
644 | {"CDS", "Central Dimming Set (Reserved for Future Use)"},
645 | {"CEC", "Ceco Communications, Inc."},
646 | {"CEI", "Cambridge Engineering, Inc."},
647 | {"CFS", "Carlisle and Finch Company"},
648 | {"CHI", "Charles Industries, Ltd."},
649 | {"CIN", "Canadian Automotive Instruments"},
650 | {"CKM", "Cinkel Marine Electronics"},
651 | {"CLR", "Colorlight AB"},
652 | {"CMA", "Soc Nouvelle D'equip Calvados"},
653 | {"CMC", "Coe Manufacturing Company"},
654 | {"CME", "Cushman Electronics, Inc."},
655 | {"CML", "CML Microsystems PLC"},
656 | {"CMN", "ComNav Marine, Ltd."},
657 | {"CMP", "C-MAP, s.r.l. (Italy)"},
658 | {"CMS", "Coastal Marine Sales Company"},
659 | {"CMV", "Coursemaster USA, Inc."},
660 | {"CNI", "Continental Instruments"},
661 | {"CNS", "CNS Systems AB (Sweden)"},
662 | {"CNV", "Coastal Navigator"},
663 | {"CNX", "Cynex Manufacturing Company"},
664 | {"CPL", "Computrol, Inc."},
665 | {"CPN", "CompuNav"},
666 | {"CPS", "Columbus Positioning, Ltd."},
667 | {"CPT", "CPT, Inc."},
668 | {"CRE", "Crystal Electronics, Ltd."},
669 | {"CRO", "The Caro Group"},
670 | {"CRY", "Crystek Crystals Corporation"},
671 | {"CSI", "Communication Systems International"},
672 | {"CSM", "COMSAT Maritime Services"},
673 | {"CSR", "CSR Stockholm"},
674 | {"CSS", "CNS, Inc."},
675 | {"CST", "CAST, Inc."},
676 | {"CSV", "Combined Services"},
677 | {"CTA", "Current Alternatives"},
678 | {"CTB", "Cetec Benmar"},
679 | {"CTC", "Cell-Tech Communications"},
680 | {"CTE", "Castle Electronics"},
681 | {"CTL", "C-Tech, Ltd."},
682 | {"CTS", "C-Tech Systems"},
683 | {"CUL", "Cyclic Procedure List (Reserved for Future Use)"},
684 | {"CUS", "Customware"},
685 | {"CWD", "Cubic Western Data"},
686 | {"CWF", "Hamilton Jet"},
687 | {"CWV", "Celwave RF, Inc."},
688 | {"CYL", "Cyclic Procedure List (Reserved for Future Use)"},
689 | {"CYZ", "CYZ, Inc."},
690 | {"DAN", "Danelec Marine A/S (Denmark)"},
691 | {"DAS", "Dassault Sercel Navigation-Positioning"},
692 | {"DBM", "Deep Blue Marine"},
693 | {"DCC", "Dolphin Components Corporation"},
694 | {"DEB", "Debeg GmbH (Germany)"},
695 | {"DEC", "Decca Division, Litton Marine Systems BV"},
696 | {"DFI", "Defender Industries, Inc."},
697 | {"DGC", "Digicourse, Inc."},
698 | {"DGY", "Digital Yacht, Ltd."},
699 | {"DGP", "Digpilot A/S (Norway)"},
700 | {"DME", "Delorme"},
701 | {"DMI", "Datamarine International"},
702 | {"DNS", "Dornier System"},
703 | {"DNT", "Del Norte Technology, Inc."},
704 | {"DOI", "Digital Oceans, Inc."},
705 | {"DPC", "Data Panel Corporation"},
706 | {"DPS", "Danaplus, Inc."},
707 | {"DRL", "RL Drake Company"},
708 | {"DSC", "Dynascan Corporation"},
709 | {"DTN", "Dytechna, Ltd."},
710 | {"DYN", "Dynamote Corporation"},
711 | {"DYT", "Dytek Laboratories, Inc."},
712 | {"EAN", "EuroAvionics Navigation Systems GmbH (Germany)"},
713 | {"EBC", "Emergency Beacon Corporation"},
714 | {"ECI", "Enhanced Selective Calling Information (Reserved for Future Use)"},
715 | {"ECR", "Escort, Inc."},
716 | {"ECT", "Echotec, Inc."},
717 | {"EDO", "EDO Corporation, Electroacoustics Division"},
718 | {"EEL", "Electronica Eutimio Sl. (Spain)"},
719 | {"EEV", "EEV, Inc."},
720 | {"EFC", "Efcom Communication Systems"},
721 | {"EKC", "Eastman Kodak"},
722 | {"ELA", "Wartsila Elac Nautik GmbH (Germany)"},
723 | {"ELD", "Electronic Devices, Inc."},
724 | {"ELM", "ELMAN, s.r.l. (Italy)"},
725 | {"EMC", "Electric Motion Company"},
726 | {"EMK", "E-Marine Company, Ltd."},
727 | {"EMR", "EMRI A/S (Denmark)"},
728 | {"EMS", "Electro Marine Systems, Inc."},
729 | {"ENA", "Energy Analysts, Inc."},
730 | {"ENC", "Encron, Inc."},
731 | {"EPM", "EPSCO Marine"},
732 | {"EPT", "Eastprint, Inc."},
733 | {"ERC", "The Ericsson Corporation"},
734 | {"ERD", "eRide, Inc."},
735 | {"ESA", "European Space Agency"},
736 | {"ESC", "Electronics Emporium Division of ESC Products"},
737 | {"ESY", "E-Systems ECI Division"},
738 | {"FDN", "FluiDyne"},
739 | {"FEC", "Furuno Electric Company"},
740 | {"FHE", "Fish Hawk Electronics"},
741 | {"FJN", "Jon Fluke Company"},
742 | {"FLA", "Flarm Technology GmbH (Germany)"},
743 | {"FLO", "Floscan, Inc."},
744 | {"FMM", "First Mate Marine Autopilots"},
745 | {"FMS", "Fugro Seastar A/S (MarineStar)"},
746 | {"FNT", "Franklin Net and Twine, Ltd."},
747 | {"FRC", "The Fredericks Company"},
748 | {"FSS", "Frequency Selection (Reserved for Future Use)"},
749 | {"FST", "Fastrax OY (Switzerland)"},
750 | {"FTG", "Thomas G Faria Corporation"},
751 | {"FTT", "FT-TEC"},
752 | {"FUG", "Fugro Intersite BV (Netherlands)"},
753 | {"FUJ", "Fujitsu Ten Corporation of America"},
754 | {"FUR", "Furuno USA, Inc."},
755 | {"FWG", "Forschungsbereich Wasserchall and Geophysik WTD 71 (German Armed Forces Research Institute) (Germany)"},
756 | {"GAM", "GRE America, Inc."},
757 | {"GCA", "Gulf Cellular Associates"},
758 | {"GDC", "GNSS Differential Correction (Reserved for Future Use)"},
759 | {"GEC", "GEC Plessey Semiconductors"},
760 | {"GES", "Geostar Corporation"},
761 | {"GFC", "Graphic Controls Corporation"},
762 | {"GFV", "GFV Marine, Ltd."},
763 | {"GIL", "Gill Instruments Limited"},
764 | {"GIS", "Galax Integrated Systems"},
765 | {"GNV", "Geonav International"},
766 | {"GPI", "Global Positioning Instrument Corporation"},
767 | {"GPP", "GEO++ GmbH (Germany)"},
768 | {"GPR", "Global Positioning System Joint Program Office (Rockwell Collins)"},
769 | {"GRF", "Grafinta (Spain)"},
770 | {"GRM", "Garmin Corporation"},
771 | {"GSC", "Gold Star Company, Ltd."},
772 | {"GTI", "Genesis Technology International, Ltd."},
773 | {"GTO", "GRO Electronics"},
774 | {"GVE", "Guest Corporation"},
775 | {"GVT", "Great Valley Technology"},
776 | {"HAI", "Hydragraphic Associates, Ltd."},
777 | {"HAL", "HAL Communications Corporation"},
778 | {"HAR", "Harris Corporation"},
779 | {"HHS", "Hydel Hellas Skaltsaris, Ltd. (Shanghai)"},
780 | {"HIG", "Hy-Gain"},
781 | {"HIL", "Philips Navigation A/S (Denmark)"},
782 | {"HIT", "Hi-Tec"},
783 | {"HMS", "Hyde Marine Systems, Inc."},
784 | {"HOM", "Hoppe Marine GmbH (Germany)"},
785 | {"HPK", "Hewlett-Packard"},
786 | {"HRC", "Harco Manufacturing Company"},
787 | {"HRM", "[Unnamed]"},
788 | {"HRT", "Hart Systems, Inc."},
789 | {"HTI", "Heart Interface, Inc."},
790 | {"HUL", "Hull Electronics Company"},
791 | {"HWM", "Honeywell Marine Systems"},
792 | {"IBM", "IBM Microelectronics"},
793 | {"ICO", "Icom of America, Inc."},
794 | {"ICG", "Initiative Computing USA, Inc. / Initiative Computing AG"},
795 | {"IDS", "ICAN Marine (Canada)"},
796 | {"IFD", "International Fishing Devices"},
797 | {"IFI", "Instruments for Industry"},
798 | {"ILS", "Ideal Teknoloji Bilisim Cozumleri A/S (Turkey)"},
799 | {"IME", "Imperial Marine Equipment"},
800 | {"IMI", "International Marine Instruments"},
801 | {"IMM", "ITT Mackay Marine"},
802 | {"IMP", "Impulse Manufacturing, Inc."},
803 | {"IMR", "Ideal Technologies, Inc."},
804 | {"IMT", "International Marketing and Trading, Inc."},
805 | {"INM", "Inmar Electronics and Sales"},
806 | {"INT", "Intech, Inc."},
807 | {"IRT", "Intera Technologies, Ltd."},
808 | {"IST", "Innerspace Technology, Inc."},
809 | {"ITM", "Intermarine Electronics, Inc."},
810 | {"ITR", "Itera, Ltd."},
811 | {"IWW", "Inland Waterways (Germany)"},
812 | {"IXB", "iXblue"},
813 | {"JAN", "Jan Crystals"},
814 | {"JAS", "Jasco Research, Ltd."},
815 | {"JFR", "Ray Jefferson"},
816 | {"JLD", "Jargoon Limited"},
817 | {"JMT", "Japan Marine Telecommunications"},
818 | {"JPI", "JP Instruments"},
819 | {"JRC", "Japan Radio Company, Ltd."},
820 | {"JRI", "J-R Industries, Inc."},
821 | {"JTC", "J-Tech Associates, Inc."},
822 | {"JTR", "Jotron Radiosearch, Ltd."},
823 | {"KBE", "KB Electronics, Ltd."},
824 | {"KBM", "Kennebec Marine Company"},
825 | {"KEL", "Knudsen Engineering, Ltd."},
826 | {"KHU", "Kelvin Hughes, Ltd."},
827 | {"KLA", "Klein Associates, Inc."},
828 | {"KME", "Kyushu Matsushita Electric"},
829 | {"KML", "Kongsberg Mesotech, Ltd. (Canada)"},
830 | {"KMO", "Kongsberg Maritime A/S (Norway)"},
831 | {"KMR", "King Marine Radio Corporation"},
832 | {"KMS", "Kongsberg Maritime Subsea (Norway)"},
833 | {"KNC", "Kongsberg Norcontrols (Norway)"},
834 | {"KNG", "King Radio Corporation"},
835 | {"KOD", "Koden Electronics Company, Ltd."},
836 | {"KRA", "EDV Krajka (Germany)"},
837 | {"KRP", "Krupp International, Inc."},
838 | {"KST", "Kongsberg Seatex A/S (Norway)"},
839 | {"KVH", "KVH Company"},
840 | {"KYI", "Kyocera International, Inc."},
841 | {"L3A", "L3 Communications Recorders Division"},
842 | {"LAT", "Latitude Corporation"},
843 | {"L3I", "L-3 Interstate Electronics Corporation"},
844 | {"LCI", "Lasercraft, Inc."},
845 | {"LEC", "Lorain Electronics Corporation"},
846 | {"LEI", "Leica Geosystems Pty, Ltd."},
847 | {"LIT", "Litton Laser Systems"},
848 | {"LMM", "Lamarche Manufacturing Company"},
849 | {"LRD", "Lorad"},
850 | {"LSE", "Littlemore Scientific (ELSEC) Engineering"},
851 | {"LSP", "Laser Plot, Inc."},
852 | {"LST", "Lite Systems Engineering"},
853 | {"LTH", "Lars Thrane A/S (Denmark)"},
854 | {"LTF", "Littlefuse, Inc."},
855 | {"LTI", "Laser Technology, Inc."},
856 | {"LWR", "Lowrance Electronics Corporation"},
857 | {"MCA", "Canadian Marconi Company"},
858 | {"MCI", "Matsushita Communications (Japan)"},
859 | {"MCL", "Micrologic, Inc."},
860 | {"MDL", "Medallion Instruments, Inc."},
861 | {"MDS", "Marine Data Systems"},
862 | {"MEC", "Marine Engine Center, Inc."},
863 | {"MEG", "Maritec Engineering GmbH (Germany)"},
864 | {"MES", "Marine Electronics Services, Inc."},
865 | {"MEW", "Matsushita Electric Works (Japan)"},
866 | {"MFR", "Modern Products, Ltd."},
867 | {"MFW", "Frank W. Murphy Manufacturing"},
868 | {"MGN", "Magellen Systems Corporation"},
869 | {"MGS", "MG Electronic Sales Corporation"},
870 | {"MIE", "Mieco, Inc."},
871 | {"MIK", "Mikrolab GmbH (Germany)"},
872 | {"MIR", "Miros A/S (Norway)"},
873 | {"MIM", "Marconi International Marine"},
874 | {"MLE", "Martha Lake Electronics"},
875 | {"MLN", "Matlin Company"},
876 | {"MLP", "Marlin Products"},
877 | {"MLT", "Miller Technologies"},
878 | {"MMB", "Marsh-McBirney, Inc."},
879 | {"MME", "Marks Marine Engineering"},
880 | {"MMI", "Microwave Monolithics"},
881 | {"MMM", "Madman Marine"},
882 | {"MMP", "Metal Marine Pilot, Inc."},
883 | {"MMS", "Mars Marine Systems"},
884 | {"MMT", "Micro Modular Technologies"},
885 | {"MNI", "Micro-Now Instrument Company"},
886 | {"MNT", "Marine Technology"},
887 | {"MNX", "Marinex"},
888 | {"MOT", "Motorola Communications & Electronics"},
889 | {"MPI", "Megapulse, Inc."},
890 | {"MPN", "Memphis Net and Twine Company, Inc."},
891 | {"MQS", "Marquis Industries, Inc."},
892 | {"MRC", "Marinecomp, Inc."},
893 | {"MRE", "Morad Electronics Corporation"},
894 | {"MRP", "Mooring Products of New England"},
895 | {"MRR", "II Morrow, Inc."},
896 | {"MRS", "Marine Radio Service"},
897 | {"MSB", "Mitsubishi Electric Company, Ltd."},
898 | {"MSE", "Master Electronics"},
899 | {"MSF", "Microsoft Corporation"},
900 | {"MSM", "Master Mariner, Inc."},
901 | {"MST", "Mesotech Systems, Ltd."},
902 | {"MTA", "Marine Technical Associates"},
903 | {"MTD", "Maritel Data Services"},
904 | {"MTG", "Marine Technical Assistance Group"},
905 | {"MTI", "Mobile Telesystems, Inc."},
906 | {"MTK", "Martech, Inc."},
907 | {"MTL", "Marine Technologies, LLC"},
908 | {"MTR", "The MITRE Corporation"},
909 | {"MTS", "Mets, Inc."},
910 | {"MUR", "Murata Erie North America"},
911 | {"MVX", "Magnavox Advanced Products and Systems Company"},
912 | {"MXS", "Maxsea International"},
913 | {"MXX", "Maxxima Marine"},
914 | {"MYS", "Marine Electronics Company (South Korea)"},
915 | {"NAG", "Noris Automation GmbH (Germany)"},
916 | {"NAT", "Nautech, Ltd."},
917 | {"NAU", "Nauticast (a.k.a. Nauticall)"},
918 | {"NAV", "Navtec, Inc."},
919 | {"NCG", "Navcert, GmbH (Germany)"},
920 | {"NCT", "Navcom Technology, Inc."},
921 | {"NEC", "NEC Corporation"},
922 | {"NEF", "New England Fishing Gear"},
923 | {"NGC", "Northrop Grumman Maritime Systems"},
924 | {"NGS", "Navigation Sciences, Inc."},
925 | {"NIX", "L-3 Nautronix"},
926 | {"NLS", "Navigation Light Status (Reserved for Future Use)"},
927 | {"NMR", "Newmar"},
928 | {"NMX", "Nanometrics"},
929 | {"NOM", "Nav-Com, Inc."},
930 | {"NOR", "Nortech Surveys (Canada)"},
931 | {"NOS", "Northern Solutions A/S (Norway)"},
932 | {"NOV", "NovAtel Communications, Ltd."},
933 | {"NSI", "Noregon Systems, Inc."},
934 | {"NSL", "Navitron Systems, Ltd."},
935 | {"NSM", "Northstar Marine"},
936 | {"NTI", "Northstar Technologies, Inc."},
937 | {"NTK", "Novatech Designs, Ltd."},
938 | {"NTS", "Navtech Systems"},
939 | {"NUT", "Nautitech Pty, Ltd."},
940 | {"NVC", "Navico"},
941 | {"NVG", "NVS Technologies AG (Switzerland)"},
942 | {"NVL", "Navelec Marine Systems Sl. (Spain)"},
943 | {"NVO", "Navionics, s.p.a. (Italy)"},
944 | {"NVS", "Navstar"},
945 | {"NVT", "Novariant, Inc."},
946 | {"NWC", "Naval Warfare Center"},
947 | {"OAR", "On-Line Applications Research (OAR) Corporation"},
948 | {"OBS", "Observator Instruments"},
949 | {"OCC", "Occupation Control (Reserved for Future Use)"},
950 | {"ODE", "Ocean Data Equipment Corporation"},
951 | {"ODN", "Odin Electronics, Inc."},
952 | {"OHB", "OHB Systems"},
953 | {"OIN", "Ocean Instruments, Inc."},
954 | {"OKI", "Oki Electric Industry Company, Ltd."},
955 | {"OLY", "Navstard, Ltd. (Polytechnic Electronics)"},
956 | {"OMN", "Omnetics Corporation"},
957 | {"OMT", "Omnitech A/S (Norway)"},
958 | {"ONI", "Omskiy Nauchno Issledovatelskiy Institut Priborostroeniya (Russia)"},
959 | {"ORB", "Orbcomm"},
960 | {"ORE", "Ocean Research"},
961 | {"OSG", "Ocean Signal, Ltd."},
962 | {"OSI", "OSI Maritime Systems (was Offshore Systems International)"},
963 | {"OSL", "OSI Maritime Systems (was Offshore Systems, Ltd.)"},
964 | {"OSS", "Ocean Solution Systems"},
965 | {"OTK", "Ocean Technology"},
966 | {"PCE", "Pace"},
967 | {"PCM", "P-Sea Marine Systems"},
968 | {"PDC", "Pan Delta Controls, Ltd."},
969 | {"PDM", "Prodelco Marine Systems"},
970 | {"PLA", "Plath C Division of Litton Industries"},
971 | {"PLI", "Pilot Instruments"},
972 | {"PMI", "Pernicka Marine Instruments"},
973 | {"PMP", "Pacific Marine Products"},
974 | {"PNI", "PNI Sensors, Inc."},
975 | {"PNL", "Points North, Ltd."},
976 | {"POM", "POMS Engineering"},
977 | {"PPL", "Pamarine Private, Ltd."},
978 | {"PRK", "Perko, Inc."},
979 | {"PSM", "Pearce-Simpson, Inc."},
980 | {"PST", "Pointstar A/S (Denmark)"},
981 | {"PTC", "Petro-Com"},
982 | {"PTG", "PTI/Guest"},
983 | {"PTH", "Pathcom, Inc."},
984 | {"PVS", "Planevision Systems"},
985 | {"QNQ", "QinetiQ (United Kingdom)"},
986 | {"QRC", "QinetiQ (United Kingdom)"},
987 | {"QWE", "Qwerty Elektronik AB (Sweden)"},
988 | {"QZM", "[Unnamed]"},
989 | {"Q2N", "QQN Navigation ABS"},
990 | {"RAC", "Racal Marine, Inc."},
991 | {"RAE", "RCA Astro-Electronics"},
992 | {"RAF", "Robins Air Force (USAF)"},
993 | {"RAK", "Rockson Automation Kiel"},
994 | {"RAY", "Raytheon Marine Company"},
995 | {"RCA", "RCA Service Company"},
996 | {"RCH", "Roach Engineering"},
997 | {"RCI", "Rochester Instruments, Inc."},
998 | {"RCQ", "QinetiQ (United Kingdom)"},
999 | {"RDC", "U.S. Coast Guard Research & Development Center"},
1000 | {"RDI", "Radar Devices"},
1001 | {"RDM", "Ray-Dar Manufacturing Company"},
1002 | {"REC", "Ross Engineering Company"},
1003 | {"RFP", "Rolfite Products, Inc."},
1004 | {"RGC", "RCA Global Communications"},
1005 | {"RGL", "Riegl Laser Measurement Systems"},
1006 | {"RGY", "Regency Electronics, Inc."},
1007 | {"RHO", "Rhotheta Elektronik GmbH (Germany)"},
1008 | {"RHM", "RH Marine"},
1009 | {"RLK", "Reelektronika NL (Netherlands)"},
1010 | {"RME", "Racal Marine Electronics"},
1011 | {"RMR", "RCA Missile and Radar"},
1012 | {"RSL", "Ross Laboratories, Inc."},
1013 | {"RSM", "Robertson-Shipmate USA"},
1014 | {"RTH", "Parthus"},
1015 | {"RTN", "Robertson Tritech Nyaskaien (Norway)"},
1016 | {"RWC", "Rockwell Collins"},
1017 | {"RWI", "Rockwell International"},
1018 | {"SAA", "Satronika Sl. (Spain)"},
1019 | {"SAB", "VDE Satellite Selective Addressed Binary and Safety Related Message (Reserved for Future Use)"},
1020 | {"SAE", "STN Atlas Elektronik GmbH (Germany)"},
1021 | {"SAF", "Safemine"},
1022 | {"SAI", "SAIT, Inc."},
1023 | {"SAJ", "SAJ Instrument AB (Finland)"},
1024 | {"SAM", "SAM Electronics GmbH (Germany)"},
1025 | {"SAL", "Consilium Marine AB (Sweden)"},
1026 | {"SAP", "Systems Engineering & Assessment, Ltd."},
1027 | {"SAT", "Satloc"},
1028 | {"SBB", "VDE Satellite Broadcast Binary Message (Reserved for Future Use)"},
1029 | {"SBG", "SBG Systems"},
1030 | {"SBR", "Sea-Bird Electronics, Inc."},
1031 | {"SCL", "Sokkia Company, Ltd."},
1032 | {"SCM", "Scandinavian Microsystems A/S (Norway)"},
1033 | {"SCO", "Simoco Telecommunications, Ltd."},
1034 | {"SCR", "Signalcrafters, Inc."},
1035 | {"SDM", "VDE Satellite VHF Data-Link Message (Reserved for Future Use)"},
1036 | {"SDN", "Sapien Design"},
1037 | {"SDO", "VDE Satellite VHF Data-Link Own-Vessel Report (Reserved for Future Use)"},
1038 | {"SEA", "Sea, Inc."},
1039 | {"SEC", "Sercel Electronics of Canada"},
1040 | {"SEE", "Seetrac (a.k.a. Global Marine Tracking)"},
1041 | {"SEL", "Selection Report (Reserved for Future Use)"},
1042 | {"SEM", "Semtech, Ltd."},
1043 | {"SEP", "Steel and Engine Products"},
1044 | {"SER", "Sercel France"},
1045 | {"SFN", "Seafarer Navigation International"},
1046 | {"SGB", "VDE Satellite Geographical Addressed Binary and Safety Message (Reserved for Future Use)"},
1047 | {"SGC", "SGC, Inc."},
1048 | {"SGN", "Signav"},
1049 | {"SHI", "Shine Micro, Inc."},
1050 | {"SIG", "Signet, Inc."},
1051 | {"SIM", "Simrad, Inc."},
1052 | {"SKA", "Skantek Corporation"},
1053 | {"SKP", "Skipper Electronics A/S (Norway)"},
1054 | {"SLI", "Starlink, Inc."},
1055 | {"SLM", "Steering Location Mode (Reserved for Future Use)"},
1056 | {"SMC", "Solis Marine Consultants"},
1057 | {"SMD", "ShipModul Customware (Netherlands)"},
1058 | {"SME", "Shakespeare Marine Electronics"},
1059 | {"SMF", "Seattle Marine and Fishing Supply Company"},
1060 | {"SMI", "Sperry Marine, Inc."},
1061 | {"SMK", "VDE Satellite Addressed and Broadcast Message Acknowledgement (Reserved for Future Use)"},
1062 | {"SML", "Simerl Instruments"},
1063 | {"SMT", "SRT Marine Technology, Ltd. (United Kingdom)"},
1064 | {"SMV", "SafetyNet Message Vessel (Reserved for Future Use)"},
1065 | {"SNP", "Science Applications International Corporation"},
1066 | {"SNV", "STARNAV Corporation (Canada)"},
1067 | {"SNY", "Sony Corporation - Mobile Electronics"},
1068 | {"SOM", "Sound Marine Electronics"},
1069 | {"SON", "Sonardyne International, Ltd. (United Kingdom)"},
1070 | {"SOV", "Sell Overseas America"},
1071 | {"SPL", "Spelmar"},
1072 | {"SPT", "Sound Powered Telephone"},
1073 | {"SRC", "Stellar Research Group"},
1074 | {"SRD", "SRD Labs"},
1075 | {"SRF", "SIRF Technology, Inc."},
1076 | {"SRP", "System Function ID Resolution Protocol (Reserved for Future Use)"},
1077 | {"SRS", "Scientific Radio Systems, Inc."},
1078 | {"SRT", "Standard Radio and Telefon AB (Sweden)"},
1079 | {"SRV", "(Reserved for Future Use)"},
1080 | {"SSA", "(Reserved for Future Use)"},
1081 | {"SSC", "Swedish Space Corporation"},
1082 | {"SSD", "Saab AB, Security & Defense Solutions, Command and Control Systems Division (Sweden)"},
1083 | {"SSE", "Seven Star Electronics"},
1084 | {"SSI", "Sea Scout Industries"},
1085 | {"SSN", "Septentrio"},
1086 | {"STC", "Standard Communications"},
1087 | {"STI", "Sea-Temp Instrument Corporation"},
1088 | {"STK", "Seatechnik, Ltd. (a.k.a. Trelleborg Marine Systems) (United Kingdom)"},
1089 | {"STL", "Streamline Technology, Ltd."},
1090 | {"STM", "SI-TEX Marine Electronics"},
1091 | {"STO", "Stowe Marine Electronics"},
1092 | {"STT", "Saab TransponderTech AB (Sweden)"},
1093 | {"SVY", "Savoy Electronics"},
1094 | {"SWI", "Swoffer Marine Instruments"},
1095 | {"SWT", "Swift Navigation, Inc."},
1096 | {"SYE", "Samyung ENC Company, Ltd. (South Korea)"},
1097 | {"SYN", "Synergy Systems, LLC"},
1098 | {"TAB", "VDE Terrestrial Selective Addressed Binary and Safety Related Message (Reserved for Future Use)"},
1099 | {"TBB", "Thompson Brothers Boat Manufacturing"},
1100 | {"TBM", "VDE Terrestrial Broadcast Binary Message (Reserved for Future Use)"},
1101 | {"TCN", "Trade Commission of Norway"},
1102 | {"TDI", "Teledyne RD Instruments, Inc."},
1103 | {"TDL", "Tideland Signal"},
1104 | {"TDM", "VDE Terrestrial VHF Data-Link Message (Reserved for Future Use)"},
1105 | {"TDO", "VDE Terrestrial VHF Data-Link Own-Vessel Report (Reserved for Future Use)"},
1106 | {"TEL", "Plessey Tellumat (South Africa)"},
1107 | {"TES", "Thales Electronic Systems GmbH (Germany)"},
1108 | {"TGB", "VDE Terrestrial Geographical Addressed Binary and Safety Message (Reserved for Future Use)"},
1109 | {"THR", "Thrane and Thrane A/A (Denmark)"},
1110 | {"TKI", "Tokyo Keiki, Inc. (Japan)"},
1111 | {"TLS", "Telesystems"},
1112 | {"TMK", "VDE Terrestrial Addressed and Broadcast Message Acknowledgement (Reserved for Future Use)"},
1113 | {"TMS", "Trelleborg Marine Systems"},
1114 | {"TMT", "Tamtech, Ltd."},
1115 | {"TNL", "Trimble Navigation, Inc."},
1116 | {"TOP", "Topcon Positioning Systems, Inc."},
1117 | {"TPL", "Totem Plus, Ltd."},
1118 | {"TRC", "Tracor, Inc."},
1119 | {"TRS", "Travroute Software"},
1120 | {"TSG", "(Reserved for Future Use)"},
1121 | {"TSI", "Techsonic Industries, Inc."},
1122 | {"TSS", "Teledyne TSS, Ltd. (United Kingdom)"},
1123 | {"TTK", "Talon Technology Corporation"},
1124 | {"TTS", "Transtector Systems, Inc."},
1125 | {"TYC", "Vincotech GmbH (formerly Tyco Electronics) (Germany)"},
1126 | {"TWC", "Transworld Communications"},
1127 | {"TWS", "Telit Location Solutions, a Division of Telit Wireless Solutions"},
1128 | {"TXI", "Texas Instruments, Inc."},
1129 | {"UBX", "u-blox AG (Switzerland)"},
1130 | {"UCG", "United States Coast Guard"},
1131 | {"UEL", "Ultra Electronics, Ltd."},
1132 | {"UME", "UMEC"},
1133 | {"UNF", "Uniforce Electronics Company"},
1134 | {"UNI", "Uniden Corporation of America"},
1135 | {"UNP", "Unipas, Inc."},
1136 | {"URS", "UrsaNav, Inc."},
1137 | {"VAN", "Vanner, Inc."},
1138 | {"VAR", "Varian Eimac Associates"},
1139 | {"VBC", "Docking Speed Log (Reserved for Future Use)"},
1140 | {"VCM", "Videocom"},
1141 | {"VDB", "Bertold Vandenbergh"},
1142 | {"VEA", "Vard Electro A/S (Norway)"},
1143 | {"VEC", "Vectron International"},
1144 | {"VEX", "Vexilar"},
1145 | {"VIS", "Vessel Information Systems"},
1146 | {"VMR", "Vast Marketing Corporation"},
1147 | {"VSP", "Vesper Marine"},
1148 | {"VXS", "Vertex Standard"},
1149 | {"WAL", "Walport USA"},
1150 | {"WBE", "Wamblee, s.r.l. (Italy)"},
1151 | {"WBG", "Westberg Manufacturing"},
1152 | {"WBR", "Wesbar Corporation"},
1153 | {"WEC", "Westinghouse Electric Corporation"},
1154 | {"WEI", "Weidmueller Interface GmbH (Germany)"},
1155 | {"WCI", "Wi-Sys Communications"},
1156 | {"WDC", "Weatherdock Corporation"},
1157 | {"WHA", "W-H Autopilots, Inc."},
1158 | {"WMM", "Wait Manufacturing and Marine Sales Company"},
1159 | {"WMR", "Wesmar Electronics"},
1160 | {"WNG", "Winegard Company"},
1161 | {"WOE", "Woosung Engineering Company, Ltd. (South Korea)"},
1162 | {"WSE", "Wilson Electronics Corporation"},
1163 | {"WST", "West Electronics, Ltd."},
1164 | {"WTC", "Watercom"},
1165 | {"XEL", "3XEL Electronics and Navigation Systems, s.r.l. (Italy)"},
1166 | {"YAS", "Yaesu Electronics (Japan)"},
1167 | {"YDK", "Yokogawa Denshikiki Company, Ltd. (Japan)"},
1168 | {"YSH", "Standard Horizon Yaesu"},
1169 | {"ZNS", "Zinnos, Inc. (South Korea)"},
1170 | {NULL((void*)0), NULL((void*)0)}};
1171 |
1172 | // List of GPS Quality Indicator (Source: NMEA Revealed by Eric S. Raymond, https://gpsd.gitlab.io/gpsd/NMEA.html, retrieved 2023-01-26)
1173 | static const string_string known_gps_quality_indicators[] = {
1174 | {"0", "Fix not available"},
1175 | {"1", "GPS fix"},
1176 | {"2", "Differential GPS fix"},
1177 | {"3", "PPS fix"},
1178 | {"4", "Real Time Kinematic"},
1179 | {"5", "Float Real Time Kinematic"},
1180 | {"6", "Estimated (dead reckoning)"},
1181 | {"7", "Manual input mode"},
1182 | {"8", "Simulation mode"},
1183 | {NULL((void*)0), NULL((void*)0)}};
1184 |
1185 | // List of status indicators (Source: NMEA Revealed by Eric S. Raymond, https://gpsd.gitlab.io/gpsd/NMEA.html, retrieved 2024-04-19)
1186 | static const string_string known_status_indicators[] = {
1187 | {"A", "Valid/Active"},
1188 | {"V", "Invalid/Void"},
1189 | {NULL((void*)0), NULL((void*)0)}};
1190 |
1191 | // List of FAA Mode Indicator (Source: NMEA Revealed by Eric S. Raymond, https://gpsd.gitlab.io/gpsd/NMEA.html, retrieved 2024-04-19)
1192 | static const string_string known_faa_mode_indicators[] = {
1193 | {"A", "Autonomous mode"},
1194 | {"C", "Quectel Querk, Caution"},
1195 | {"D", "Differential Mode"},
1196 | {"E", "Estimated (dead-reckoning) mode"},
1197 | {"F", "RTK Float mode"},
1198 | {"M", "Manual Input Mode"},
1199 | {"N", "Data Not Valid"},
1200 | {"P", "Precise"},
1201 | {"R", "RTK Integer mode"},
1202 | {"S", "Simulated Mode"},
1203 | {"U", "Quectel Querk, Unsafe"},
1204 | {NULL((void*)0), NULL((void*)0)}};
1205 |
1206 | static uint8_t calculate_checksum(tvbuff_t *tvb, const int start, const int length)
1207 | {
1208 | uint8_t checksum = 0;
1209 | for (int i = start; i < start + length; i++)
1210 | {
1211 | checksum ^= tvb_get_uint8(tvb, i);
1212 | }
1213 | return checksum;
1214 | }
1215 |
1216 | /* Find first occurrence of a field separator in tvbuff, starting at offset. Searches
1217 | * to end of tvbuff.
1218 | * Returns the offset of the found separator.
1219 | * If separator is not found, return the offset of end of tvbuff.
1220 | * If offset is out of bounds, return the offset of end of tvbuff.
1221 | **/
1222 | static int
1223 | tvb_find_end_of_nmea0183_field(tvbuff_t *tvb, const int offset)
1224 | {
1225 | if (tvb_captured_length_remaining(tvb, offset) == 0)
1226 | {
1227 | return tvb_captured_length(tvb);
1228 | }
1229 |
1230 | int end_of_field_offset = tvb_find_uint8(tvb, offset, -1, ',');
1231 | if (end_of_field_offset == -1)
1232 | {
1233 | return tvb_captured_length(tvb);
1234 | }
1235 | return end_of_field_offset;
1236 | }
1237 |
1238 | /* Add a zero length item which indicates an expected but missing field */
1239 | static proto_item *
1240 | proto_tree_add_missing_field(proto_tree *tree, packet_info *pinfo, int hf, tvbuff_t *tvb,
1241 | const int offset)
1242 | {
1243 | proto_item *ti = NULL((void*)0);
1244 | ti = proto_tree_add_item(tree, hf, tvb, offset, 0, ENC_ASCII0x00000000);
1245 | proto_item_append_text(ti, "[missing]");
1246 | expert_add_info(pinfo, ti, &ei_nmea0183_field_missing);
1247 | return ti;
1248 | }
1249 |
1250 | /* Dissect a time field. The field is split into a tree with hour, minute and second elements.
1251 | * Returns length including separator
1252 | **/
1253 | static int
1254 | dissect_nmea0183_field_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1255 | int hf_time, int hf_hour, int hf_minute, int hf_second, int ett_time)
1256 | {
1257 | if (offset > (int)tvb_captured_length(tvb))
1258 | {
1259 | proto_tree_add_missing_field(tree, pinfo, hf_time, tvb, tvb_captured_length(tvb));
1260 | return 0;
1261 | }
1262 |
1263 | proto_item *ti = NULL((void*)0);
1264 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1265 | ti = proto_tree_add_item(tree, hf_time, tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000);
1266 | if (end_of_field_offset - offset == 0)
1267 | {
1268 | proto_item_append_text(ti, ": [empty]");
1269 | }
1270 | else if (end_of_field_offset - offset >= 6)
1271 | {
1272 | const uint8_t *hour = NULL((void*)0);
1273 | const uint8_t *minute = NULL((void*)0);
1274 | const uint8_t *second = NULL((void*)0);
1275 | proto_tree *time_subtree = proto_item_add_subtree(ti, ett_time);
1276 |
1277 | proto_tree_add_item_ret_string(time_subtree, hf_hour,
1278 | tvb, offset, 2, ENC_ASCII0x00000000,
1279 | pinfo->pool, &hour);
1280 |
1281 | proto_tree_add_item_ret_string(time_subtree, hf_minute,
1282 | tvb, offset + 2, 2, ENC_ASCII0x00000000,
1283 | pinfo->pool, &minute);
1284 |
1285 | proto_tree_add_item_ret_string(time_subtree, hf_second,
1286 | tvb, offset + 4, end_of_field_offset - offset - 4,
1287 | ENC_ASCII0x00000000, pinfo->pool, &second);
1288 |
1289 | proto_item_append_text(ti, ": %s:%s:%s", hour, minute, second);
1290 | }
1291 | else
1292 | {
1293 | expert_add_info(pinfo, ti, &ei_nmea0183_field_time_too_short);
1294 | }
1295 | return end_of_field_offset - offset + 1;
1296 | }
1297 |
1298 | /* Dissect a single field containing a dimensionless value. Returns length including separator */
1299 | static int
1300 | dissect_nmea0183_field(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf, const char *suffix, const string_string *str_str)
1301 | {
1302 | const uint8_t* field_str = NULL((void*)0);
1303 |
1304 | if (offset > (int)tvb_captured_length(tvb))
1305 | {
1306 | proto_tree_add_missing_field(tree, pinfo, hf, tvb, tvb_captured_length(tvb));
1307 | return 0;
1308 | }
1309 |
1310 | proto_item *ti = NULL((void*)0);
1311 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1312 | ti = proto_tree_add_item_ret_string(tree, hf, tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000, pinfo->pool, &field_str);
1313 | if (end_of_field_offset - offset == 0)
1314 | {
1315 | proto_item_append_text(ti, "[empty]");
1316 | }
1317 | else if (suffix != NULL((void*)0))
1318 | {
1319 | proto_item_append_text(ti, " %s", suffix);
1320 | }
1321 | if ((str_str)&&(field_str)) {
1322 | proto_item_append_text(ti, " - %s", str_to_str_wmem(pinfo->pool, field_str, str_str, " "));
1323 | }
1324 | return end_of_field_offset - offset + 1;
1325 | }
1326 |
1327 | /* Dissect a latitude/longitude direction field.
1328 | * Returns length including separator
1329 | **/
1330 | static int
1331 | dissect_nmea0183_field_latlong_direction(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1332 | int offset, int hf,
1333 | wmem_allocator_t *scope, const uint8_t **retval)
1334 | {
1335 | if (offset > (int)tvb_captured_length(tvb))
1336 | {
1337 | proto_tree_add_missing_field(tree, pinfo, hf, tvb, tvb_captured_length(tvb));
1338 | return 0;
1339 | }
1340 |
1341 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1342 | proto_item *ti = proto_tree_add_item_ret_string(tree, hf,
1343 | tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000,
1344 | scope, retval);
1345 | if (end_of_field_offset - offset == 0)
1346 | {
1347 | if (retval == NULL((void*)0))
1348 | {
1349 | proto_item_append_text(ti, "[empty]");
1350 | }
1351 | else
1352 | {
1353 | proto_item_append_text(ti, "[missing]");
1354 | expert_add_info(pinfo, ti, &ei_nmea0183_field_missing);
1355 | }
1356 | }
1357 | return end_of_field_offset - offset + 1;
1358 | }
1359 |
1360 | /* Dissect a latitude field + direction field. The fields are split into a tree with degree, minute and direction elements.
1361 | * Returns length including separator
1362 | **/
1363 | static int
1364 | dissect_nmea0183_field_latitude(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1365 | int hf_latitude, int hf_degree, int hf_minute, int hf_direction, int ett_latitude)
1366 | {
1367 | if (offset > (int)tvb_captured_length(tvb))
1368 | {
1369 | proto_tree_add_missing_field(tree, pinfo, hf_latitude, tvb, tvb_captured_length(tvb));
1370 | return 0;
1371 | }
1372 |
1373 | proto_item *ti = NULL((void*)0);
1374 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1375 | ti = proto_tree_add_item(tree, hf_latitude, tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000);
1376 | if (end_of_field_offset - offset == 0)
1377 | {
1378 | proto_item_append_text(ti, ": [empty]");
1379 |
1380 | end_of_field_offset += dissect_nmea0183_field_latlong_direction(tvb, pinfo, tree, end_of_field_offset + 1, hf_direction, NULL((void*)0), NULL((void*)0));
1381 | }
1382 | else if (end_of_field_offset - offset >= 4)
1383 | {
1384 | const uint8_t *degree = NULL((void*)0);
1385 | const uint8_t *minute = NULL((void*)0);
1386 | const uint8_t *direction = NULL((void*)0);
1387 | proto_tree *latitude_subtree = proto_item_add_subtree(ti, ett_latitude);
1388 |
1389 | proto_tree_add_item_ret_string(latitude_subtree, hf_degree,
1390 | tvb, offset, 2,
1391 | ENC_ASCII0x00000000, pinfo->pool, &degree);
1392 |
1393 | proto_tree_add_item_ret_string(latitude_subtree, hf_minute,
1394 | tvb, offset + 2, end_of_field_offset - offset - 2,
1395 | ENC_ASCII0x00000000, pinfo->pool, &minute);
1396 |
1397 | end_of_field_offset += dissect_nmea0183_field_latlong_direction(tvb, pinfo, latitude_subtree, end_of_field_offset + 1, hf_direction, pinfo->pool, &direction);
1398 |
1399 | proto_item_append_text(ti, ": %s° %s' %s", degree, minute, direction);
1400 | }
1401 | else
1402 | {
1403 | expert_add_info(pinfo, ti, &ei_nmea0183_field_latitude_too_short);
1404 |
1405 | end_of_field_offset += dissect_nmea0183_field_latlong_direction(tvb, pinfo, tree, end_of_field_offset + 1, hf_direction, NULL((void*)0), NULL((void*)0));
1406 | }
1407 | return end_of_field_offset - offset + 1;
1408 | }
1409 |
1410 | /* Dissect a longitude field + direction field. The fields are split into a tree with degree, minute and direction elements.
1411 | * Returns length including separator
1412 | **/
1413 | static int
1414 | dissect_nmea0183_field_longitude(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
1415 | int hf_longitude, int hf_degree, int hf_minute, int hf_direction, int ett_latitude)
1416 | {
1417 | if (offset > (int)tvb_captured_length(tvb))
1418 | {
1419 | proto_tree_add_missing_field(tree, pinfo, hf_longitude, tvb, tvb_captured_length(tvb));
1420 | return 0;
1421 | }
1422 |
1423 | proto_item *ti = NULL((void*)0);
1424 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1425 | ti = proto_tree_add_item(tree, hf_longitude, tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000);
1426 | if (end_of_field_offset - offset == 0)
1427 | {
1428 | proto_item_append_text(ti, ": [empty]");
1429 |
1430 | end_of_field_offset += dissect_nmea0183_field_latlong_direction(tvb, pinfo, tree, end_of_field_offset + 1, hf_direction, NULL((void*)0), NULL((void*)0));
1431 | }
1432 | else if (end_of_field_offset - offset >= 5)
1433 | {
1434 | const uint8_t *degree = NULL((void*)0);
1435 | const uint8_t *minute = NULL((void*)0);
1436 | const uint8_t *direction = NULL((void*)0);
1437 | proto_tree *longitude_subtree = proto_item_add_subtree(ti, ett_latitude);
1438 |
1439 | proto_tree_add_item_ret_string(longitude_subtree, hf_degree,
1440 | tvb, offset, 3,
1441 | ENC_ASCII0x00000000, pinfo->pool, &degree);
1442 |
1443 | proto_tree_add_item_ret_string(longitude_subtree, hf_minute,
1444 | tvb, offset + 3, end_of_field_offset - offset - 3,
1445 | ENC_ASCII0x00000000, pinfo->pool, &minute);
1446 |
1447 | end_of_field_offset += dissect_nmea0183_field_latlong_direction(tvb, pinfo, longitude_subtree, end_of_field_offset + 1, hf_direction, pinfo->pool, &direction);
1448 |
1449 | proto_item_append_text(ti, ": %s° %s' %s", degree, minute, direction);
1450 | }
1451 | else
1452 | {
1453 | expert_add_info(pinfo, ti, &ei_nmea0183_field_longitude_too_short);
1454 |
1455 | end_of_field_offset += dissect_nmea0183_field_latlong_direction(tvb, pinfo, tree, end_of_field_offset + 1, hf_direction, NULL((void*)0), NULL((void*)0));
1456 | }
1457 | return end_of_field_offset - offset + 1;
1458 | }
1459 |
1460 | /* Dissect a required gps quality field. Returns length including separator */
1461 | static int
1462 | dissect_nmea0183_field_gps_quality(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf)
1463 | {
1464 | if (offset > (int)tvb_captured_length(tvb))
1465 | {
1466 | proto_tree_add_missing_field(tree, pinfo, hf, tvb, tvb_captured_length(tvb));
1467 | return 0;
1468 | }
1469 |
1470 | proto_item *ti = NULL((void*)0);
1471 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1472 | const uint8_t *quality = NULL((void*)0);
1473 | ti = proto_tree_add_item_ret_string(tree, hf,
1474 | tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000,
1475 | pinfo->pool, &quality);
1476 | if (end_of_field_offset - offset == 0)
1477 | {
1478 | proto_item_append_text(ti, "[missing]");
1479 | expert_add_info(pinfo, ti, &ei_nmea0183_field_missing);
1480 | }
1481 | else
1482 | {
1483 | proto_item_append_text(ti, " (%s)", str_to_str_wmem(pinfo->pool, quality, known_gps_quality_indicators, "Unknown quality"));
1484 | }
1485 | return end_of_field_offset - offset + 1;
1486 | }
1487 |
1488 | /* Dissect a single field containing a fixed text.
1489 | The text of the field must match the `expected_text` or expert info `invalid_ei` is
1490 | added to the field. An empty field is allowed. Returns length including separator */
1491 | static int
1492 | dissect_nmea0183_field_fixed_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf,
1493 | const uint8_t *expected_text, expert_field *invalid_ei)
1494 | {
1495 | if (offset > (int)tvb_captured_length(tvb))
1496 | {
1497 | proto_tree_add_missing_field(tree, pinfo, hf, tvb, tvb_captured_length(tvb));
1498 | return 0;
1499 | }
1500 |
1501 | proto_item *ti = NULL((void*)0);
1502 | const uint8_t *text = NULL((void*)0);
1503 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1504 | ti = proto_tree_add_item_ret_string(tree, hf,
1505 | tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000,
1506 | pinfo->pool, &text);
1507 | if (end_of_field_offset - offset == 0)
1508 | {
1509 | proto_item_append_text(ti, "[empty]");
1510 | }
1511 | else if (g_ascii_strcasecmp(text, expected_text) != 0)
1512 | {
1513 | expert_add_info(pinfo, ti, invalid_ei);
1514 | }
1515 | return end_of_field_offset - offset + 1;
1516 | }
1517 |
1518 | /* Dissect a optional FAA mode indicator field. Returns length including separator */
1519 | static int
1520 | dissect_nmea0183_field_faa_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf)
1521 | {
1522 | if (offset > (int)tvb_captured_length(tvb))
1523 | {
1524 | proto_tree_add_missing_field(tree, pinfo, hf, tvb, tvb_captured_length(tvb));
1525 | return 0;
1526 | }
1527 |
1528 | proto_item *ti = NULL((void*)0);
1529 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1530 | const uint8_t *mode = NULL((void*)0);
1531 | ti = proto_tree_add_item_ret_string(tree, hf,
1532 | tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000,
1533 | pinfo->pool, &mode);
1534 | if (end_of_field_offset - offset == 0)
1535 | {
1536 | proto_item_append_text(ti, "[empty]");
1537 | }
1538 | else
1539 | {
1540 | proto_item_append_text(ti, " (%s)", str_to_str_wmem(pinfo->pool, mode, known_faa_mode_indicators, "Unknown FAA mode"));
1541 | }
1542 | return end_of_field_offset - offset + 1;
1543 | }
1544 |
1545 | /* Dissect a optional A/V status field. Returns length including separator */
1546 | static int
1547 | dissect_nmea0183_field_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf)
1548 | {
1549 | if (offset > (int)tvb_captured_length(tvb))
1550 | {
1551 | proto_tree_add_missing_field(tree, pinfo, hf, tvb, tvb_captured_length(tvb));
1552 | return 0;
1553 | }
1554 |
1555 | proto_item *ti = NULL((void*)0);
1556 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1557 | const uint8_t *mode = NULL((void*)0);
1558 | ti = proto_tree_add_item_ret_string(tree, hf,
1559 | tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000,
1560 | pinfo->pool, &mode);
1561 | if (end_of_field_offset - offset == 0)
1562 | {
1563 | proto_item_append_text(ti, "[empty]");
1564 | }
1565 | else
1566 | {
1567 | proto_item_append_text(ti, " (%s)", str_to_str_wmem(pinfo->pool, mode, known_status_indicators, "Unknown status"));
1568 | }
1569 | return end_of_field_offset - offset + 1;
1570 | }
1571 |
1572 | /* Dissect a ALR sentence. */
1573 | /*
1574 | * $--ALR,hhmmss.ss,xxx,A,A,c--c*hh<CR><LF>
1575 | */
1576 | static const string_string alarm_condition_str[] = {
1577 | {"A", "Threshold exceeded"},
1578 | {"V", "Threshold not exceeded"},
1579 | { NULL((void*)0), NULL((void*)0)},
1580 | };
1581 |
1582 | static const string_string alarm_ack_state_str[] = {
1583 | {"A", "Acknowledged"},
1584 | {"V", "Unacknowledged"},
1585 | { NULL((void*)0), NULL((void*)0)},
1586 | };
1587 |
1588 | static int
1589 | dissect_nmea0183_sentence_alr(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree)
1590 | {
1591 | int offset = 0;
1592 |
1593 | proto_tree* subtree = proto_tree_add_subtree(tree, tvb, offset,
1594 | tvb_captured_length(tvb), ett_nmea0183_sentence, NULL((void*)0), "ALR sentence - Set Alarm State");
1595 |
1596 | /* hhmmss.ss */
1597 | offset += dissect_nmea0183_field_time(tvb, pinfo, subtree, offset, hf_nmea0183_alr_time,
1598 | hf_nmea0183_alr_time_hour, hf_nmea0183_alr_time_minute,
1599 | hf_nmea0183_alr_time_second, ett_nmea0183_alr_time);
1600 | /* xxx Unique alarm number (identifier) at alarm source */
1601 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_alr_alarm_id, NULL((void*)0), NULL((void*)0));
1602 | /* Alarm condition (A = threshold exceeded, V = not exceeded) */
1603 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_alr_alarm_cond, NULL((void*)0), alarm_condition_str);
1604 | /* Alarm’s acknowledge state, A= acknowledged, V= unacknowledged*/
1605 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_alr_alarm_ack_st, NULL((void*)0), alarm_ack_state_str);
1606 | /* c--c Alarm’s description text*/
1607 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_alr_alarm_desc_txt, NULL((void*)0), NULL((void*)0));
1608 |
1609 | return tvb_captured_length(tvb);
1610 | }
1611 |
1612 | /* Dissect a DPT sentence. */
1613 | static int
1614 | dissect_nmea0183_sentence_dpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1615 | {
1616 | int offset = 0;
1617 |
1618 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1619 | tvb_captured_length(tvb), ett_nmea0183_sentence, NULL((void*)0), "DPT sentence - Depth of Water");
1620 |
1621 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_dpt_depth, "meter", NULL((void*)0));
1622 |
1623 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_dpt_offset, "meter", NULL((void*)0));
1624 |
1625 | dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_dpt_max_range, "meter", NULL((void*)0));
1626 |
1627 | return tvb_captured_length(tvb);
1628 | }
1629 |
1630 | /* Dissect a GGA sentence. The time, latitude and longitude fields is split into individual parts. */
1631 | static int
1632 | dissect_nmea0183_sentence_gga(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1633 | {
1634 | int offset = 0;
1635 |
1636 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1637 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1638 | NULL((void*)0), "GGA sentence - Global Positioning System Fix");
1639 |
1640 | offset += dissect_nmea0183_field_time(tvb, pinfo, subtree, offset, hf_nmea0183_gga_time,
1641 | hf_nmea0183_gga_time_hour, hf_nmea0183_gga_time_minute,
1642 | hf_nmea0183_gga_time_second, ett_nmea0183_gga_time);
1643 |
1644 | offset += dissect_nmea0183_field_latitude(tvb, pinfo, subtree, offset, hf_nmea0183_gga_latitude,
1645 | hf_nmea0183_gga_latitude_degree, hf_nmea0183_gga_latitude_minute,
1646 | hf_nmea0183_gga_latitude_direction, ett_nmea0183_gga_latitude);
1647 |
1648 | offset += dissect_nmea0183_field_longitude(tvb, pinfo, subtree, offset, hf_nmea0183_gga_longitude,
1649 | hf_nmea0183_gga_longitude_degree, hf_nmea0183_gga_longitude_minute,
1650 | hf_nmea0183_gga_longitude_direction, ett_nmea0183_gga_longitude);
1651 |
1652 | offset += dissect_nmea0183_field_gps_quality(tvb, pinfo, subtree, offset, hf_nmea0183_gga_quality);
1653 |
1654 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gga_number_satellites, NULL((void*)0), NULL((void*)0));
1655 |
1656 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gga_horizontal_dilution, "meter", NULL((void*)0));
1657 |
1658 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gga_altitude, "meter", NULL((void*)0));
1659 |
1660 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_gga_altitude_unit,
1661 | "M", &ei_nmea0183_gga_altitude_unit_incorrect);
1662 |
1663 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gga_geoidal_separation, "meter", NULL((void*)0));
1664 |
1665 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_gga_geoidal_separation_unit,
1666 | "M", &ei_nmea0183_gga_geoidal_separation_unit_incorrect);
1667 |
1668 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gga_age_dgps, "second", NULL((void*)0));
1669 |
1670 | dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gga_dgps_station, NULL((void*)0), NULL((void*)0));
1671 |
1672 | return tvb_captured_length(tvb);
1673 | }
1674 |
1675 | /* Dissect a GLL sentence. The latitude, longitude and time fields is split into individual parts. */
1676 | static int
1677 | dissect_nmea0183_sentence_gll(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1678 | {
1679 | int offset = 0;
1680 |
1681 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1682 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1683 | NULL((void*)0), "GLL sentence - Geographic Position");
1684 |
1685 | offset += dissect_nmea0183_field_latitude(tvb, pinfo, subtree, offset, hf_nmea0183_gll_latitude,
1686 | hf_nmea0183_gll_latitude_degree, hf_nmea0183_gll_latitude_minute,
1687 | hf_nmea0183_gll_latitude_direction, ett_nmea0183_gll_latitude);
1688 |
1689 | offset += dissect_nmea0183_field_longitude(tvb, pinfo, subtree, offset, hf_nmea0183_gll_longitude,
1690 | hf_nmea0183_gll_longitude_degree, hf_nmea0183_gll_longitude_minute,
1691 | hf_nmea0183_gll_longitude_direction, ett_nmea0183_gll_longitude);
1692 |
1693 | offset += dissect_nmea0183_field_time(tvb, pinfo, subtree, offset, hf_nmea0183_gll_time,
1694 | hf_nmea0183_gll_time_hour, hf_nmea0183_gll_time_minute,
1695 | hf_nmea0183_gll_time_second, ett_nmea0183_gll_time);
1696 |
1697 | offset += dissect_nmea0183_field_status(tvb, pinfo, subtree, offset, hf_nmea0183_gll_status);
1698 |
1699 | dissect_nmea0183_field_faa_mode(tvb, pinfo, subtree, offset, hf_nmea0183_gll_mode);
1700 |
1701 | return tvb_captured_length(tvb);
1702 | }
1703 |
1704 | /* Dissect a GST sentence. The time field is split into individual parts. */
1705 | static int
1706 | dissect_nmea0183_sentence_gst(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1707 | {
1708 | int offset = 0;
1709 |
1710 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1711 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1712 | NULL((void*)0), "GST sentence - GPS Pseudorange Noise Statistics");
1713 |
1714 | offset += dissect_nmea0183_field_time(tvb, pinfo, subtree, offset, hf_nmea0183_gst_time,
1715 | hf_nmea0183_gst_time_hour, hf_nmea0183_gst_time_minute,
1716 | hf_nmea0183_gst_time_second, ett_nmea0183_gst_time);
1717 |
1718 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_rms_total_sd, NULL((void*)0), NULL((void*)0));
1719 |
1720 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_ellipse_major_sd, "meter", NULL((void*)0));
1721 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_ellipse_minor_sd, "meter", NULL((void*)0));
1722 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_ellipse_orientation, "degree (true north)", NULL((void*)0));
1723 |
1724 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_latitude_sd, "meter", NULL((void*)0));
1725 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_longitude_sd, "meter", NULL((void*)0));
1726 | dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_gst_altitude_sd, "meter", NULL((void*)0));
1727 |
1728 | return tvb_captured_length(tvb);
1729 | }
1730 |
1731 | /* Dissect a HDT sentence. */
1732 | static int
1733 | dissect_nmea0183_sentence_hdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1734 | {
1735 | int offset = 0;
1736 |
1737 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1738 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1739 | NULL((void*)0), "HDT sentence - True Heading");
1740 |
1741 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_hdt_heading, "degree", NULL((void*)0));
1742 |
1743 | dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_hdt_unit,
1744 | "T", &ei_nmea0183_hdt_unit_incorrect);
1745 |
1746 | return tvb_captured_length(tvb);
1747 | }
1748 |
1749 | /* Dissect a ROT sentence. */
1750 | static int
1751 | dissect_nmea0183_sentence_rot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1752 | {
1753 | int offset = 0;
1754 |
1755 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1756 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1757 | NULL((void*)0), "ROT sentence - Rate Of Turn");
1758 |
1759 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_rot_rate_of_turn, "degree per minute", NULL((void*)0));
1760 |
1761 | dissect_nmea0183_field_status(tvb, pinfo, subtree, offset, hf_nmea0183_rot_valid);
1762 |
1763 | return tvb_captured_length(tvb);
1764 | }
1765 |
1766 | /* Dissect a TXT sentence */
1767 | static int
1768 | dissect_nmea0183_sentence_txt(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree)
1769 | {
1770 | int offset = 0;
1771 |
1772 | proto_tree* subtree = proto_tree_add_subtree(tree, tvb, offset,
1773 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1774 | NULL((void*)0), "TXT sentence - Text Transmission");
1775 |
1776 | /* Total number of sentences, 01 to 99 */
1777 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_txt_num, NULL((void*)0), NULL((void*)0));
1778 | /* Sentence number */
1779 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_txt_sent_num, NULL((void*)0), NULL((void*)0));
1780 | /* Text identifier */
1781 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_txt_id, NULL((void*)0), NULL((void*)0));
1782 | /* Text message */
1783 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_txt_msg, NULL((void*)0), NULL((void*)0));
| Value stored to 'offset' is never read
1784 |
1785 | return tvb_captured_length(tvb);
1786 | }
1787 |
1788 |
1789 | /* Dissect a VHW sentence. */
1790 | static int
1791 | dissect_nmea0183_sentence_vhw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1792 | {
1793 | int offset = 0;
1794 |
1795 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1796 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1797 | NULL((void*)0), "VHW sentence - Water speed and heading");
1798 |
1799 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_true_heading, "degree", NULL((void*)0));
1800 |
1801 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_true_heading_unit,
1802 | "T", &ei_nmea0183_vhw_true_heading_unit_incorrect);
1803 |
1804 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_magnetic_heading, "degree", NULL((void*)0));
1805 |
1806 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_magnetic_heading_unit,
1807 | "M", &ei_nmea0183_vhw_magnetic_heading_unit_incorrect);
1808 |
1809 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_water_speed_knot, "knot", NULL((void*)0));
1810 |
1811 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_water_speed_knot_unit,
1812 | "N", &ei_nmea0183_vhw_water_speed_knot_unit_incorrect);
1813 |
1814 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_water_speed_kilometer, "kilometer per hour", NULL((void*)0));
1815 |
1816 | dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vhw_water_speed_kilometer_unit,
1817 | "K", &ei_nmea0183_vhw_water_speed_kilometer_unit_incorrect);
1818 |
1819 | return tvb_captured_length(tvb);
1820 | }
1821 |
1822 | /* Dissect a VBW sentence. */
1823 | static int
1824 | dissect_nmea0183_sentence_vbw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1825 | {
1826 | int offset = 0;
1827 |
1828 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1829 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1830 | NULL((void*)0), "VBW sentence - Dual Ground/Water Speed");
1831 |
1832 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_water_speed_longitudinal, "knot", NULL((void*)0));
1833 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_water_speed_transverse, "knot", NULL((void*)0));
1834 | offset += dissect_nmea0183_field_status(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_water_speed_valid);
1835 |
1836 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_ground_speed_longitudinal, "knot", NULL((void*)0));
1837 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_ground_speed_transverse, "knot", NULL((void*)0));
1838 | offset += dissect_nmea0183_field_status(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_ground_speed_valid);
1839 |
1840 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_stern_water_speed, "knot", NULL((void*)0));
1841 | offset += dissect_nmea0183_field_status(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_stern_water_speed_valid);
1842 |
1843 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_stern_ground_speed, "knot", NULL((void*)0));
1844 | dissect_nmea0183_field_status(tvb, pinfo, subtree, offset, hf_nmea0183_vbw_stern_ground_speed_valid);
1845 |
1846 | return tvb_captured_length(tvb);
1847 | }
1848 |
1849 | /* Dissect a VLW sentence. */
1850 | static int
1851 | dissect_nmea0183_sentence_vlw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1852 | {
1853 | int offset = 0;
1854 |
1855 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1856 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1857 | NULL((void*)0), "VLW sentence - Distance Traveled through Water");
1858 |
1859 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_cumulative_water, "nautical miles", NULL((void*)0));
1860 |
1861 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_cumulative_water_unit,
1862 | "N", &ei_nmea0183_vlw_cumulative_water_unit_incorrect);
1863 |
1864 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_trip_water, "nautical miles", NULL((void*)0));
1865 |
1866 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_trip_water_unit,
1867 | "N", &ei_nmea0183_vlw_trip_water_unit_incorrect);
1868 |
1869 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_cumulative_ground, "nautical miles", NULL((void*)0));
1870 |
1871 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_cumulative_ground_unit,
1872 | "N", &ei_nmea0183_vlw_cumulative_ground_unit_incorrect);
1873 |
1874 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_trip_ground, "nautical miles", NULL((void*)0));
1875 |
1876 | dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vlw_trip_ground_unit,
1877 | "N", &ei_nmea0183_vlw_trip_ground_unit_incorrect);
1878 |
1879 | return tvb_captured_length(tvb);
1880 | }
1881 |
1882 | /* Dissect a VTG sentence. */
1883 | static int
1884 | dissect_nmea0183_sentence_vtg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1885 | {
1886 | int offset = 0;
1887 |
1888 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1889 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1890 | NULL((void*)0), "VTG sentence - Track made good and Ground speed");
1891 |
1892 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_true_course, "degree", NULL((void*)0));
1893 |
1894 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_true_course_unit,
1895 | "T", &ei_nmea0183_vtg_true_course_unit_incorrect);
1896 |
1897 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_magnetic_course, "degree", NULL((void*)0));
1898 |
1899 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_magnetic_course_unit,
1900 | "M", &ei_nmea0183_vtg_magnetic_course_unit_incorrect);
1901 |
1902 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_ground_speed_knot, "knot", NULL((void*)0));
1903 |
1904 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_ground_speed_knot_unit,
1905 | "N", &ei_nmea0183_vtg_ground_speed_knot_unit_incorrect);
1906 |
1907 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_ground_speed_kilometer, "kilometer per hour", NULL((void*)0));
1908 |
1909 | offset += dissect_nmea0183_field_fixed_text(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_ground_speed_kilometer_unit,
1910 | "K", &ei_nmea0183_vtg_ground_speed_kilometer_unit_incorrect);
1911 |
1912 | dissect_nmea0183_field_faa_mode(tvb, pinfo, subtree, offset, hf_nmea0183_vtg_mode);
1913 |
1914 | return tvb_captured_length(tvb);
1915 | }
1916 |
1917 | /* Dissect a ZDA (Time & Date) sentence. The time field is split into individual parts. */
1918 | static int
1919 | dissect_nmea0183_sentence_zda(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1920 | {
1921 | int offset = 0;
1922 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1923 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1924 | NULL((void*)0), "ZDA sentence - Time & Date");
1925 |
1926 | offset += dissect_nmea0183_field_time(tvb, pinfo, subtree, offset, hf_nmea0183_zda_time,
1927 | hf_nmea0183_zda_time_hour, hf_nmea0183_zda_time_minute,
1928 | hf_nmea0183_zda_time_second, ett_nmea0183_zda_time);
1929 |
1930 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_zda_date_day, NULL((void*)0), NULL((void*)0));
1931 |
1932 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_zda_date_month, NULL((void*)0), NULL((void*)0));
1933 |
1934 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_zda_date_year, NULL((void*)0), NULL((void*)0));
1935 |
1936 | offset += dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_zda_local_zone_hour, NULL((void*)0), NULL((void*)0));
1937 |
1938 | dissect_nmea0183_field(tvb, pinfo, subtree, offset, hf_nmea0183_zda_local_zone_minute, NULL((void*)0), NULL((void*)0));
1939 |
1940 | return tvb_captured_length(tvb);
1941 | }
1942 |
1943 | /* Dissect a sentence where the sentence id is unknown. Each field is shown as an generic field. */
1944 | static int
1945 | dissect_nmea0183_sentence_unknown(tvbuff_t *tvb, packet_info *pinfo _U___attribute__((unused)), proto_tree *tree)
1946 | {
1947 | int offset = 0;
1948 |
1949 | proto_tree *subtree = proto_tree_add_subtree(tree, tvb, offset,
1950 | tvb_captured_length(tvb), ett_nmea0183_sentence,
1951 | NULL((void*)0), "Unknown sentence");
1952 |
1953 | /* In an unknown sentence, the name of each field is unknown. Find all field by splitting at a comma. */
1954 | while (tvb_captured_length_remaining(tvb, offset) > 0)
1955 | {
1956 | int end_of_field_offset = tvb_find_end_of_nmea0183_field(tvb, offset);
1957 | proto_item *ti = proto_tree_add_item(subtree, hf_nmea0183_unknown_field,
1958 | tvb, offset, end_of_field_offset - offset, ENC_ASCII0x00000000);
1959 | if (end_of_field_offset - offset == 0)
1960 | {
1961 | proto_item_append_text(ti, "[empty]");
1962 | }
1963 | offset = end_of_field_offset + 1;
1964 | }
1965 | return tvb_captured_length(tvb);
1966 | }
1967 |
1968 |
1969 | /* <tag block 1>,<tagblock2>, … <tagblock n>*<tagblocks CS> */
1970 | //static void
1971 | //dissect_nmea0183_tag_block(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree)
1972 | //{
1973 | // int offset = 0, chk_sum_off, comma_off;
1974 | //
1975 | // chk_sum_off = tvb_find_uint8(tvb, offset, -1, '*');
1976 | // if (chk_sum_off == -1) {
1977 | // /* No checksum ??*/
1978 | // return;
1979 | // }
1980 | // while (offset < chk_sum_off) {
1981 | // comma_off = tvb_find_uint8(tvb, offset, -1, ',');
1982 | // if (comma_off == -1) {
1983 | //
1984 | // }
1985 | //
1986 | // }
1987 | //
1988 | //}
1989 |
1990 | static int
1991 | dissect_nmea0183(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused)))
1992 | {
1993 | int offset = 0;
1994 | int start_offset;
1995 | int start_checksum_offset = 0;
1996 | const uint8_t *talker_id = NULL((void*)0);
1997 | const uint8_t *sentence_id = NULL((void*)0);
1998 | const uint8_t *checksum = NULL((void*)0);
1999 | uint8_t start_delimiter;
2000 |
2001 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "NMEA 0183");
2002 | /* Clear the info column */
2003 | col_clear(pinfo->cinfo, COL_INFO);
2004 |
2005 | proto_item *ti = proto_tree_add_item(tree, proto_nmea0183, tvb, 0, -1, ENC_NA0x00000000);
2006 | proto_tree *nmea0183_tree = proto_item_add_subtree(ti, ett_nmea0183);
2007 |
2008 | /* UdPbC\<tag block 1>,<tagblock2>, … <tagblock n>*<tagblocks CS>\<NMEA message>*/
2009 | if (tvb_memeql(tvb, 0, UDPBC"UdPbC", sizeof(UDPBC"UdPbC")) == 0) {
2010 | proto_tree_add_item(nmea0183_tree, hf_nmea0183_sentence_prefix, tvb, offset, 6, ENC_ASCII0x00000000);
2011 | offset += 6;
2012 | start_offset = offset;
2013 | offset = tvb_find_uint8(tvb, offset, -1, '$');
2014 | if (offset == -1) {
2015 | offset = tvb_find_uint8(tvb, offset, -1, '!');
2016 | }if (offset == -1) {
2017 | offset = start_offset;
2018 | } else {
2019 | /* TAG block as defined in NMEA 0183 V.4.0. ????*/
2020 | /*ti = */proto_tree_add_item(nmea0183_tree, hf_nmea0183_tag_block, tvb, start_offset, offset-start_offset, ENC_ASCII0x00000000);
2021 | //proto_tree* nmea0183_tree = proto_item_add_subtree(ti, ett_nmea0183_tag_block);
2022 | ///* look for "\" */
2023 | //start_delimiter = tvb_get_uint8(tvb, start_offset);
2024 | //if (start_delimiter == '\\') {
2025 | // start_offset++;
2026 | // int end_offset = tvb_find_uint8(tvb, start_offset, -1, '\\');
2027 | // if (end_offset != -1) {
2028 | // tvbuff_t* new_tvb = tvb_new_subset_length(tvb, start_offset, end_offset - start_offset);
2029 | // dissect_nmea0183_tag_block(new_tvb, pinfo, nmea0183_tree);
2030 | // }
2031 | //}
2032 | }
2033 | }
2034 | /* Start delimiter */
2035 | start_delimiter = tvb_get_uint8(tvb, offset);
2036 | if ((start_delimiter != '$') && (start_delimiter != '!'))
2037 | {
2038 | expert_add_info(pinfo, nmea0183_tree, &ei_nmea0183_invalid_first_character);
2039 | }
2040 | offset += 1;
2041 | start_offset = offset;
2042 | /* Talker id */
2043 | ti = proto_tree_add_item_ret_string(nmea0183_tree, hf_nmea0183_talker_id,
2044 | tvb, offset, 2, ENC_ASCII0x00000000,
2045 | pinfo->pool, &talker_id);
2046 |
2047 | proto_item_append_text(ti, " (%s)", str_to_str_wmem(pinfo->pool, talker_id, known_talker_ids, "Unknown talker ID"));
2048 |
2049 | col_append_fstr(pinfo->cinfo, COL_INFO, "Talker %s", str_to_str_wmem(pinfo->pool, talker_id, known_talker_ids, "Unknown talker ID"));
2050 |
2051 | offset += 2;
2052 |
2053 | /* Sentence id */
2054 | ti = proto_tree_add_item_ret_string(nmea0183_tree, hf_nmea0183_sentence_id,
2055 | tvb, offset, 3, ENC_ASCII0x00000000,
2056 | pinfo->pool, &sentence_id);
2057 |
2058 | proto_item_append_text(ti, " (%s)", str_to_str_wmem(pinfo->pool, sentence_id, known_sentence_ids, "Unknown sentence ID"));
2059 |
2060 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Sentence %s", str_to_str_wmem(pinfo->pool, sentence_id, known_sentence_ids, "Unknown sentence ID"));
2061 |
2062 | offset += 3;
2063 |
2064 | /* Start of checksum */
2065 | start_checksum_offset = tvb_find_uint8(tvb, offset, -1, '*');
2066 | if (start_checksum_offset == -1)
2067 | {
2068 | expert_add_info(pinfo, nmea0183_tree, &ei_nmea0183_missing_checksum_character);
2069 | return tvb_captured_length(tvb);
2070 | }
2071 |
2072 | /* Data */
2073 | offset += 1;
2074 | tvbuff_t *data_tvb = tvb_new_subset_length(tvb, offset, start_checksum_offset - offset);
2075 | if (g_ascii_strcasecmp(sentence_id, "ALR") == 0)
2076 | {
2077 | offset += dissect_nmea0183_sentence_alr(data_tvb, pinfo, nmea0183_tree);
2078 | }
2079 | else if (g_ascii_strcasecmp(sentence_id, "DPT") == 0)
2080 | {
2081 | offset += dissect_nmea0183_sentence_dpt(data_tvb, pinfo, nmea0183_tree);
2082 | }
2083 | else if (g_ascii_strcasecmp(sentence_id, "GGA") == 0)
2084 | {
2085 | offset += dissect_nmea0183_sentence_gga(data_tvb, pinfo, nmea0183_tree);
2086 | }
2087 | else if (g_ascii_strcasecmp(sentence_id, "GLL") == 0)
2088 | {
2089 | offset += dissect_nmea0183_sentence_gll(data_tvb, pinfo, nmea0183_tree);
2090 | }
2091 | else if (g_ascii_strcasecmp(sentence_id, "GST") == 0)
2092 | {
2093 | offset += dissect_nmea0183_sentence_gst(data_tvb, pinfo, nmea0183_tree);
2094 | }
2095 | else if (g_ascii_strcasecmp(sentence_id, "HDT") == 0)
2096 | {
2097 | offset += dissect_nmea0183_sentence_hdt(data_tvb, pinfo, nmea0183_tree);
2098 | }
2099 | else if (g_ascii_strcasecmp(sentence_id, "ROT") == 0)
2100 | {
2101 | offset += dissect_nmea0183_sentence_rot(data_tvb, pinfo, nmea0183_tree);
2102 | }
2103 | else if (g_ascii_strcasecmp(sentence_id, "TXT") == 0)
2104 | {
2105 | offset += dissect_nmea0183_sentence_txt(data_tvb, pinfo, nmea0183_tree);
2106 | }
2107 | else if (g_ascii_strcasecmp(sentence_id, "VBW") == 0)
2108 | {
2109 | offset += dissect_nmea0183_sentence_vbw(data_tvb, pinfo, nmea0183_tree);
2110 | }
2111 | else if (g_ascii_strcasecmp(sentence_id, "VHW") == 0)
2112 | {
2113 | offset += dissect_nmea0183_sentence_vhw(data_tvb, pinfo, nmea0183_tree);
2114 | }
2115 | else if (g_ascii_strcasecmp(sentence_id, "VLW") == 0)
2116 | {
2117 | offset += dissect_nmea0183_sentence_vlw(data_tvb, pinfo, nmea0183_tree);
2118 | }
2119 | else if (g_ascii_strcasecmp(sentence_id, "VTG") == 0)
2120 | {
2121 | offset += dissect_nmea0183_sentence_vtg(data_tvb, pinfo, nmea0183_tree);
2122 | }
2123 | else if (g_ascii_strcasecmp(sentence_id, "ZDA") == 0)
2124 | {
2125 | offset += dissect_nmea0183_sentence_zda(data_tvb, pinfo, nmea0183_tree);
2126 | }
2127 | else
2128 | {
2129 | offset += dissect_nmea0183_sentence_unknown(data_tvb, pinfo, nmea0183_tree);
2130 | }
2131 |
2132 | /* Checksum */
2133 | offset += 1;
2134 | ti = proto_tree_add_item_ret_string(nmea0183_tree, hf_nmea0183_checksum,
2135 | tvb, offset, 2, ENC_ASCII0x00000000,
2136 | pinfo->pool, &checksum);
2137 |
2138 | uint8_t received_checksum = (uint8_t)strtol(checksum, NULL((void*)0), 16);
2139 | uint8_t calculated_checksum;
2140 |
2141 | //calculated_checksum = calculate_checksum(tvb, 1, offset - 2);
2142 | calculated_checksum = calculate_checksum(tvb, start_offset, (offset - start_offset-1));
2143 |
2144 | if (received_checksum == calculated_checksum)
2145 | {
2146 | proto_item_append_text(ti, " [correct]");
2147 | }
2148 | else
2149 | {
2150 | proto_item_append_text(ti, " [INCORRECT]");
2151 | expert_add_info(pinfo, ti, &ei_nmea0183_checksum_incorrect);
2152 | }
2153 |
2154 | // Calculated checksum highlights 2 bytes, which is the ascii hex value of a 1 byte checksum
2155 | proto_item *checksum_tree = proto_item_add_subtree(ti, ett_nmea0183_checksum);
2156 | ti = proto_tree_add_uint(checksum_tree, hf_nmea0183_checksum_calculated,
2157 | tvb, offset, 2, calculated_checksum);
2158 |
2159 | proto_item_set_generated(ti);
2160 |
2161 | offset += 2;
2162 |
2163 | /* End of line */
2164 | if (tvb_captured_length_remaining(tvb, offset) < 2 ||
2165 | tvb_get_uint8(tvb, offset) != '\r' ||
2166 | tvb_get_uint8(tvb, offset + 1) != '\n')
2167 | {
2168 | expert_add_info(pinfo, nmea0183_tree, &ei_nmea0183_invalid_end_of_line);
2169 | }
2170 | offset += 2;
2171 |
2172 | /* Check sentence length */
2173 | if (offset > 82)
2174 | {
2175 | expert_add_info(pinfo, nmea0183_tree, &ei_nmea0183_sentence_too_long);
2176 | }
2177 |
2178 | return tvb_captured_length(tvb);
2179 | }
2180 |
2181 | /* Try to detect NMEA 0183 heuristically */
2182 | static bool_Bool dissect_nmea0183_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused)))
2183 | {
2184 | char *sent_type;
2185 | const char *talker, *t_val, *p_val, *m_val, *manuf;
2186 |
2187 | /* Have to have at least 11 bytes:
2188 | * 1-byte sentence type character ('!' or '$')
2189 | * 2-byte TALKER lookup value
2190 | * 2-byte TALKER (for Query sentences) or 3-byte FORMATTER
2191 | * variable number of bytes for delimiters and data fields (minimum would be a single ',' byte)
2192 | * '*' delimeter byte, 2-bytes for checksum, and 2-bytes for EOM "\r\n" */
2193 | if(tvb_reported_length(tvb) < 11 || tvb_captured_length(tvb) < 5){
2194 | return false0;
2195 | }
2196 | /* See if we have a UDP brodcast message */
2197 | if (tvb_memeql(tvb, 0, UDPBC"UdPbC", sizeof(UDPBC"UdPbC")) == 0) {
2198 | return true1;
2199 | }
2200 | /* Grab the first byte and check the first character */
2201 | sent_type = tvb_get_string_enc(pinfo->pool, tvb, 0, 1, ENC_ASCII0x00000000);
2202 |
2203 | /* Sentence type character ('!' or '$') */
2204 | if( (sent_type[0] != '!') && (sent_type[0] != '$') ){
2205 | return false0;
2206 | }
2207 |
2208 | /* We either have a 'P' and corresponding manufacturer 3-byte value OR
2209 | * we have a non-proprietary 2-byte TALKER field */
2210 | //TODO: Implement encapsulation and proprietary message parsing
2211 |
2212 | /* Do a lookup for the 2-byte TALKER field */
2213 | t_val = tvb_get_string_enc(pinfo->pool, tvb, 1, 2, ENC_ASCII0x00000000);
2214 | talker = try_str_to_str(t_val, known_talker_ids);
2215 |
2216 | /* Do a lookup for the 3-byte manufacturer if the 2nd byte in the PDU is 'P' */
2217 | p_val = tvb_get_string_enc(pinfo->pool, tvb, 1, 1, ENC_ASCII0x00000000);
2218 | m_val = tvb_get_string_enc(pinfo->pool, tvb, 2, 3, ENC_ASCII0x00000000);
2219 | manuf = try_str_to_str(m_val, manufacturer_vals);
2220 |
2221 | /* If one of the two conditions are true then try to dissect NMEA 0183 */
2222 | if( ((p_val[0] == 'P') && (manuf != NULL((void*)0))) ||
2223 | (talker != NULL((void*)0)) ){
2224 | /* Looks like NMEA 0183 so let's give it a try */
2225 | return (dissect_nmea0183(tvb, pinfo, tree, data) != 0);
2226 | }
2227 | /* If neither conditions are met then we return false */
2228 | else{
2229 | return false0;
2230 | }
2231 | }
2232 |
2233 | void proto_register_nmea0183(void)
2234 | {
2235 | expert_module_t *expert_nmea0183;
2236 |
2237 | static hf_register_info hf[] = {
2238 | {&hf_nmea0183_talker_id,
2239 | {"Talker ID", "nmea0183.talker",
2240 | FT_STRING, BASE_NONE,
2241 | NULL((void*)0), 0x0,
2242 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2243 | {&hf_nmea0183_sentence_id,
2244 | {"Sentence ID", "nmea0183.sentence",
2245 | FT_STRING, BASE_NONE,
2246 | NULL((void*)0), 0x0,
2247 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2248 | {&hf_nmea0183_unknown_field,
2249 | {"Field", "nmea0183.unknown_field",
2250 | FT_STRING, BASE_NONE,
2251 | NULL((void*)0), 0x0,
2252 | "NMEA 0183 Unknown field", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2253 | {&hf_nmea0183_checksum,
2254 | {"Checksum", "nmea0183.checksum",
2255 | FT_STRING, BASE_NONE,
2256 | NULL((void*)0), 0x0,
2257 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2258 | {&hf_nmea0183_checksum_calculated,
2259 | {"Calculated checksum", "nmea0183.checksum_calculated",
2260 | FT_UINT8, BASE_HEX,
2261 | NULL((void*)0), 0x0,
2262 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2263 | {&hf_nmea0183_dpt_depth,
2264 | {"Water depth", "nmea0183.dpt_depth",
2265 | FT_STRING, BASE_NONE,
2266 | NULL((void*)0), 0x0,
2267 | "NMEA 0183 DPT Water depth relative to transducer", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2268 | {&hf_nmea0183_dpt_offset,
2269 | {"Offset", "nmea0183.dpt_offset",
2270 | FT_STRING, BASE_NONE,
2271 | NULL((void*)0), 0x0,
2272 | "NMEA 0183 DPT Offset from transducer, positive means distance from transducer to water line, negative means distance from transducer to keel", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2273 | {&hf_nmea0183_dpt_max_range,
2274 | {"Maximum range", "nmea0183.dpt_max_range",
2275 | FT_STRING, BASE_NONE,
2276 | NULL((void*)0), 0x0,
2277 | "NMEA 0183 DPT Maximum range scale in use (NMEA 3.0 and above)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2278 | {&hf_nmea0183_alr_time,
2279 | {"UTC Time of alarm condition change", "nmea0183.alr_time",
2280 | FT_NONE, BASE_NONE,
2281 | NULL((void*)0), 0x0,
2282 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2283 | {&hf_nmea0183_alr_time_hour,
2284 | {"Hour", "nmea0183.alr_time_hour",
2285 | FT_STRING, BASE_NONE,
2286 | NULL((void*)0), 0x0,
2287 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2288 | {&hf_nmea0183_alr_time_minute,
2289 | {"Minute", "nmea0183.alr_time_minute",
2290 | FT_STRING, BASE_NONE,
2291 | NULL((void*)0), 0x0,
2292 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2293 | {&hf_nmea0183_alr_time_second,
2294 | {"Second", "nmea0183.alr_time_second",
2295 | FT_STRING, BASE_NONE,
2296 | NULL((void*)0), 0x0,
2297 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2298 | {&hf_nmea0183_alr_alarm_id,
2299 | {"Alarm id", "nmea0183.alr_id",
2300 | FT_STRING, BASE_NONE,
2301 | NULL((void*)0), 0x0,
2302 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2303 | {&hf_nmea0183_alr_alarm_cond,
2304 | {"Alarm condition", "nmea0183.alr_alarm_cond",
2305 | FT_STRING, BASE_NONE,
2306 | NULL((void*)0), 0x0,
2307 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2308 | {&hf_nmea0183_alr_alarm_ack_st,
2309 | {"Alarm’s acknowledge state", "nmea0183.alr_alarm_ack_st",
2310 | FT_STRING, BASE_NONE,
2311 | NULL((void*)0), 0x0,
2312 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2313 | {&hf_nmea0183_alr_alarm_desc_txt,
2314 | {"Alarm’s description text", "nmea0183.alr_alarm_desc_txt",
2315 | FT_STRING, BASE_NONE,
2316 | NULL((void*)0), 0x0,
2317 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2318 | {&hf_nmea0183_gga_time,
2319 | {"UTC Time of position", "nmea0183.gga_time",
2320 | FT_NONE, BASE_NONE,
2321 | NULL((void*)0), 0x0,
2322 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2323 | {&hf_nmea0183_gga_time_hour,
2324 | {"Hour", "nmea0183.gga_time_hour",
2325 | FT_STRING, BASE_NONE,
2326 | NULL((void*)0), 0x0,
2327 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2328 | {&hf_nmea0183_gga_time_minute,
2329 | {"Minute", "nmea0183.gga_time_minute",
2330 | FT_STRING, BASE_NONE,
2331 | NULL((void*)0), 0x0,
2332 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2333 | {&hf_nmea0183_gga_time_second,
2334 | {"Second", "nmea0183.gga_time_second",
2335 | FT_STRING, BASE_NONE,
2336 | NULL((void*)0), 0x0,
2337 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2338 | {&hf_nmea0183_gga_latitude,
2339 | {"Latitude", "nmea0183.gga_latitude",
2340 | FT_NONE, BASE_NONE,
2341 | NULL((void*)0), 0x0,
2342 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2343 | {&hf_nmea0183_gga_latitude_degree,
2344 | {"Degree", "nmea0183.gga_latitude_degree",
2345 | FT_STRING, BASE_NONE,
2346 | NULL((void*)0), 0x0,
2347 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2348 | {&hf_nmea0183_gga_latitude_minute,
2349 | {"Minute", "nmea0183.gga_latitude_minute",
2350 | FT_STRING, BASE_NONE,
2351 | NULL((void*)0), 0x0,
2352 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2353 | {&hf_nmea0183_gga_latitude_direction,
2354 | {"Direction", "nmea0183.gga_latitude_direction",
2355 | FT_STRING, BASE_NONE,
2356 | NULL((void*)0), 0x0,
2357 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2358 | {&hf_nmea0183_gga_longitude,
2359 | {"Longitude", "nmea0183.gga_longitude",
2360 | FT_NONE, BASE_NONE,
2361 | NULL((void*)0), 0x0,
2362 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2363 | {&hf_nmea0183_gga_longitude_degree,
2364 | {"Degree", "nmea0183.gga_longitude_degree",
2365 | FT_STRING, BASE_NONE,
2366 | NULL((void*)0), 0x0,
2367 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2368 | {&hf_nmea0183_gga_longitude_minute,
2369 | {"Minute", "nmea0183.gga_longitude_minute",
2370 | FT_STRING, BASE_NONE,
2371 | NULL((void*)0), 0x0,
2372 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2373 | {&hf_nmea0183_gga_longitude_direction,
2374 | {"Direction", "nmea0183.gga_longitude_direction",
2375 | FT_STRING, BASE_NONE,
2376 | NULL((void*)0), 0x0,
2377 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2378 | {&hf_nmea0183_gga_quality,
2379 | {"Quality indicator", "nmea0183.gga_quality",
2380 | FT_STRING, BASE_NONE,
2381 | NULL((void*)0), 0x0,
2382 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2383 | {&hf_nmea0183_gga_number_satellites,
2384 | {"Number of satellites", "nmea0183.gga_number_satellites",
2385 | FT_STRING, BASE_NONE,
2386 | NULL((void*)0), 0x0,
2387 | "NMEA 0183 GGA Number of satellites in use", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2388 | {&hf_nmea0183_gga_horizontal_dilution,
2389 | {"Horizontal Dilution", "nmea0183.gga_horizontal_dilution",
2390 | FT_STRING, BASE_NONE,
2391 | NULL((void*)0), 0x0,
2392 | "NMEA 0183 GGA Horizontal Dilution of precision", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2393 | {&hf_nmea0183_gga_altitude,
2394 | {"Altitude", "nmea0183.gga_altitude",
2395 | FT_STRING, BASE_NONE,
2396 | NULL((void*)0), 0x0,
2397 | "NMEA 0183 GGA Antenna Altitude above mean-sea-level", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2398 | {&hf_nmea0183_gga_altitude_unit,
2399 | {"Altitude unit", "nmea0183.gga_altitude_unit",
2400 | FT_STRING, BASE_NONE,
2401 | NULL((void*)0), 0x0,
2402 | "NMEA 0183 GGA Units of antenna altitude", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2403 | {&hf_nmea0183_gga_geoidal_separation,
2404 | {"Geoidal separation", "nmea0183.gga_geoidal_separation",
2405 | FT_STRING, BASE_NONE,
2406 | NULL((void*)0), 0x0,
2407 | "NMEA 0183 GGA Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2408 | {&hf_nmea0183_gga_geoidal_separation_unit,
2409 | {"Geoidal separation unit", "nmea0183.gga_geoidal_separation_unit",
2410 | FT_STRING, BASE_NONE,
2411 | NULL((void*)0), 0x0,
2412 | "NMEA 0183 GGA Units of geoidal separation, meters", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2413 | {&hf_nmea0183_gga_age_dgps,
2414 | {"Age of differential GPS", "nmea0183.gga_age_dgps",
2415 | FT_STRING, BASE_NONE,
2416 | NULL((void*)0), 0x0,
2417 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2418 | {&hf_nmea0183_gga_dgps_station,
2419 | {"Differential GPS station id", "nmea0183.gga_dgps_station",
2420 | FT_STRING, BASE_NONE,
2421 | NULL((void*)0), 0x0,
2422 | "NMEA 0183 GGA Differential reference station ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2423 | {&hf_nmea0183_gll_latitude,
2424 | {"Latitude", "nmea0183.gll_latitude",
2425 | FT_NONE, BASE_NONE,
2426 | NULL((void*)0), 0x0,
2427 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2428 | {&hf_nmea0183_gll_latitude_degree,
2429 | {"Degree", "nmea0183.gll_latitude_degree",
2430 | FT_STRING, BASE_NONE,
2431 | NULL((void*)0), 0x0,
2432 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2433 | {&hf_nmea0183_gll_latitude_minute,
2434 | {"Minute", "nmea0183.gll_latitude_minute",
2435 | FT_STRING, BASE_NONE,
2436 | NULL((void*)0), 0x0,
2437 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2438 | {&hf_nmea0183_gll_latitude_direction,
2439 | {"Direction", "nmea0183.gll_latitude_direction",
2440 | FT_STRING, BASE_NONE,
2441 | NULL((void*)0), 0x0,
2442 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2443 | {&hf_nmea0183_gll_longitude,
2444 | {"Longitude", "nmea0183.gll_longitude",
2445 | FT_NONE, BASE_NONE,
2446 | NULL((void*)0), 0x0,
2447 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2448 | {&hf_nmea0183_gll_longitude_degree,
2449 | {"Degree", "nmea0183.gll_longitude_degree",
2450 | FT_STRING, BASE_NONE,
2451 | NULL((void*)0), 0x0,
2452 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2453 | {&hf_nmea0183_gll_longitude_minute,
2454 | {"Minute", "nmea0183.gll_longitude_minute",
2455 | FT_STRING, BASE_NONE,
2456 | NULL((void*)0), 0x0,
2457 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2458 | {&hf_nmea0183_gll_longitude_direction,
2459 | {"Direction", "nmea0183.gll_longitude_direction",
2460 | FT_STRING, BASE_NONE,
2461 | NULL((void*)0), 0x0,
2462 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2463 | {&hf_nmea0183_gll_time,
2464 | {"UTC Time of position", "nmea0183.gll_time",
2465 | FT_NONE, BASE_NONE,
2466 | NULL((void*)0), 0x0,
2467 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2468 | {&hf_nmea0183_gll_time_hour,
2469 | {"Hour", "nmea0183.gll_time_hour",
2470 | FT_STRING, BASE_NONE,
2471 | NULL((void*)0), 0x0,
2472 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2473 | {&hf_nmea0183_gll_time_minute,
2474 | {"Minute", "nmea0183.gll_time_minute",
2475 | FT_STRING, BASE_NONE,
2476 | NULL((void*)0), 0x0,
2477 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2478 | {&hf_nmea0183_gll_time_second,
2479 | {"Second", "nmea0183.gll_time_second",
2480 | FT_STRING, BASE_NONE,
2481 | NULL((void*)0), 0x0,
2482 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2483 | {&hf_nmea0183_gll_status,
2484 | {"Status", "nmea0183.gll_status",
2485 | FT_STRING, BASE_NONE,
2486 | NULL((void*)0), 0x0,
2487 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2488 | {&hf_nmea0183_gll_mode,
2489 | {"FAA mode", "nmea0183.gll_mode",
2490 | FT_STRING, BASE_NONE,
2491 | NULL((void*)0), 0x0,
2492 | "NMEA 0183 GLL FAA mode indicator (NMEA 2.3 and later)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2493 | {&hf_nmea0183_gst_time,
2494 | {"UTC Time of position", "nmea0183.gst_time",
2495 | FT_NONE, BASE_NONE,
2496 | NULL((void*)0), 0x0,
2497 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2498 | {&hf_nmea0183_gst_time_hour,
2499 | {"Hour", "nmea0183.gst_time_hour",
2500 | FT_STRING, BASE_NONE,
2501 | NULL((void*)0), 0x0,
2502 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2503 | {&hf_nmea0183_gst_time_minute,
2504 | {"Minute", "nmea0183.gst_time_minute",
2505 | FT_STRING, BASE_NONE,
2506 | NULL((void*)0), 0x0,
2507 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2508 | {&hf_nmea0183_gst_time_second,
2509 | {"Second", "nmea0183.gst_time_second",
2510 | FT_STRING, BASE_NONE,
2511 | NULL((void*)0), 0x0,
2512 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2513 | {&hf_nmea0183_gst_rms_total_sd,
2514 | {"Total RMS standard deviation", "nmea0183.gst_sd_rms_total",
2515 | FT_STRING, BASE_NONE,
2516 | NULL((void*)0), 0x0,
2517 | "NMEA 0183 GST Total RMS standard deviation of ranges inputs to the navigation solution", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2518 | {&hf_nmea0183_gst_ellipse_major_sd,
2519 | {"Standard deviation of semi-major axis of error", "nmea0183.gst_ellipse_major_sd",
2520 | FT_STRING, BASE_NONE,
2521 | NULL((void*)0), 0x0,
2522 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2523 | {&hf_nmea0183_gst_ellipse_minor_sd,
2524 | {"Standard deviation of semi-minor axis of error ellipse", "nmea0183.gst_ellipse_minor_sd",
2525 | FT_STRING, BASE_NONE,
2526 | NULL((void*)0), 0x0,
2527 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2528 | {&hf_nmea0183_gst_ellipse_orientation,
2529 | {"Orientation of semi-major axis of error ellipse", "nmea0183.gst_ellipse_orientation",
2530 | FT_STRING, BASE_NONE,
2531 | NULL((void*)0), 0x0,
2532 | "NMEA 0183 GST Orientation of semi-major axis of error ellipse (true north degrees)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2533 | {&hf_nmea0183_gst_latitude_sd,
2534 | {"Standard deviation of latitude error", "nmea0183.gst_sd_latitude",
2535 | FT_STRING, BASE_NONE,
2536 | NULL((void*)0), 0x0,
2537 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2538 | {&hf_nmea0183_gst_longitude_sd,
2539 | {"Standard deviation of longitude error", "nmea0183.gst_sd_longitude",
2540 | FT_STRING, BASE_NONE,
2541 | NULL((void*)0), 0x0,
2542 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2543 | {&hf_nmea0183_gst_altitude_sd,
2544 | {"Standard deviation of altitude error", "nmea0183.gst_sd_altitude",
2545 | FT_STRING, BASE_NONE,
2546 | NULL((void*)0), 0x0,
2547 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2548 | {&hf_nmea0183_hdt_heading,
2549 | {"True heading", "nmea0183.hdt_heading",
2550 | FT_STRING, BASE_NONE,
2551 | NULL((void*)0), 0x0,
2552 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2553 | {&hf_nmea0183_hdt_unit,
2554 | {"Heading unit", "nmea0183.hdt_unit",
2555 | FT_STRING, BASE_NONE,
2556 | NULL((void*)0), 0x0,
2557 | "NMEA 0183 HDT Heading unit, must be T", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2558 | {&hf_nmea0183_rot_rate_of_turn,
2559 | {"Rate of turn", "nmea0183.rot_rate_of_turn",
2560 | FT_STRING, BASE_NONE,
2561 | NULL((void*)0), 0x0,
2562 | "NMEA 0183 ROT Rate Of Turn, degrees per minute, negative value means bow turns to port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2563 | { &hf_nmea0183_txt_num,
2564 | {"Total number of sentences", "nmea0183.txt.num",
2565 | FT_STRING, BASE_NONE,
2566 | NULL((void*)0), 0x0,
2567 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)} },
2568 | { &hf_nmea0183_txt_sent_num,
2569 | {"Sentence number", "nmea0183.txt.sent_num",
2570 | FT_STRING, BASE_NONE,
2571 | NULL((void*)0), 0x0,
2572 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)} },
2573 | { &hf_nmea0183_txt_id,
2574 | {"Text identifier", "nmea0183.txt.id",
2575 | FT_STRING, BASE_NONE,
2576 | NULL((void*)0), 0x0,
2577 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)} },
2578 | { &hf_nmea0183_txt_msg,
2579 | {"Text message", "nmea0183.txt.msg",
2580 | FT_STRING, BASE_NONE,
2581 | NULL((void*)0), 0x0,
2582 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)} },
2583 | {&hf_nmea0183_rot_valid,
2584 | {"Validity", "nmea0183.rot_valid",
2585 | FT_STRING, BASE_NONE,
2586 | NULL((void*)0), 0x0,
2587 | "NMEA 0183 ROT Status, A means data is valid", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2588 | {&hf_nmea0183_vbw_water_speed_longitudinal,
2589 | {"Longitudinal water speed", "nmea0183.vbw_water_speed_longitudinal",
2590 | FT_STRING, BASE_NONE,
2591 | NULL((void*)0), 0x0,
2592 | "NMEA 0183 VBW Longitudinal water speed, negative value means astern, knots", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2593 | {&hf_nmea0183_vbw_water_speed_transverse,
2594 | {"Transverse water speed", "nmea0183.vbw_water_speed_transverse",
2595 | FT_STRING, BASE_NONE,
2596 | NULL((void*)0), 0x0,
2597 | "NMEA 0183 VBW Transverse water speed, negative value means port, knots", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2598 | {&hf_nmea0183_vbw_water_speed_valid,
2599 | {"Water speed validity", "nmea0183.vbw_water_speed_valid",
2600 | FT_STRING, BASE_NONE,
2601 | NULL((void*)0), 0x0,
2602 | "NMEA 0183 VBW Water speed status, A means data is valid", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2603 | {&hf_nmea0183_vbw_ground_speed_longitudinal,
2604 | {"Longitudinal ground speed", "nmea0183.vbw_ground_speed_longitudinal",
2605 | FT_STRING, BASE_NONE,
2606 | NULL((void*)0), 0x0,
2607 | "NMEA 0183 VBW Longitudinal ground speed, negative value means astern, knots", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2608 | {&hf_nmea0183_vbw_ground_speed_transverse,
2609 | {"Transverse ground speed", "nmea0183.vbw_ground_speed_transverse",
2610 | FT_STRING, BASE_NONE,
2611 | NULL((void*)0), 0x0,
2612 | "NMEA 0183 VBW Transverse ground speed, negative value means port, knots", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2613 | {&hf_nmea0183_vbw_ground_speed_valid,
2614 | {"Ground speed validity", "nmea0183.vbw_ground_speed_valid",
2615 | FT_STRING, BASE_NONE,
2616 | NULL((void*)0), 0x0,
2617 | "NMEA 0183 VBW Ground speed status, A means data is valid", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2618 | {&hf_nmea0183_vbw_stern_water_speed,
2619 | {"Stern water speed", "nmea0183.vbw_stern_water_speed",
2620 | FT_STRING, BASE_NONE,
2621 | NULL((void*)0), 0x0,
2622 | "NMEA 0183 VBW Stern traverse water ground speed, negative value means port, knots", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2623 | {&hf_nmea0183_vbw_stern_water_speed_valid,
2624 | {"Stern water speed validity", "nmea0183.vbw_stern_water_speed_valid",
2625 | FT_STRING, BASE_NONE,
2626 | NULL((void*)0), 0x0,
2627 | "NMEA 0183 VBW Stern traverse water speed status, A means data is valid", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2628 | {&hf_nmea0183_vbw_stern_ground_speed,
2629 | {"Stern ground speed", "nmea0183.vbw_stern_ground_speed",
2630 | FT_STRING, BASE_NONE,
2631 | NULL((void*)0), 0x0,
2632 | "NMEA 0183 VBW Stern traverse ground ground speed, negative value means port, knots", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2633 | {&hf_nmea0183_vbw_stern_ground_speed_valid,
2634 | {"Stern ground speed validity", "nmea0183.vbw_stern_ground_speed_valid",
2635 | FT_STRING, BASE_NONE,
2636 | NULL((void*)0), 0x0,
2637 | "NMEA 0183 VBW Stern traverse ground speed status, A means data is valid", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2638 | {&hf_nmea0183_vhw_true_heading,
2639 | {"True heading", "nmea0183.vhw_true_heading",
2640 | FT_STRING, BASE_NONE,
2641 | NULL((void*)0), 0x0,
2642 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2643 | {&hf_nmea0183_vhw_true_heading_unit,
2644 | {"Heading unit", "nmea0183.vhw_true_heading_unit",
2645 | FT_STRING, BASE_NONE,
2646 | NULL((void*)0), 0x0,
2647 | "NMEA 0183 VHW Heading unit, must be T", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2648 | {&hf_nmea0183_vhw_magnetic_heading,
2649 | {"Magnetic heading", "nmea0183.vhw_magnetic_heading",
2650 | FT_STRING, BASE_NONE,
2651 | NULL((void*)0), 0x0,
2652 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2653 | {&hf_nmea0183_vhw_magnetic_heading_unit,
2654 | {"Heading unit", "nmea0183.vhw_magnetic_heading_unit",
2655 | FT_STRING, BASE_NONE,
2656 | NULL((void*)0), 0x0,
2657 | "NMEA 0183 VHW Heading unit, must be M", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2658 | {&hf_nmea0183_vhw_water_speed_knot,
2659 | {"Water speed", "nmea0183.vhw_water_speed_knot",
2660 | FT_STRING, BASE_NONE,
2661 | NULL((void*)0), 0x0,
2662 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2663 | {&hf_nmea0183_vhw_water_speed_knot_unit,
2664 | {"Speed unit", "nmea0183.vhw_water_speed_knot_unit",
2665 | FT_STRING, BASE_NONE,
2666 | NULL((void*)0), 0x0,
2667 | "NMEA 0183 VHW Water speed unit, must be N", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2668 | {&hf_nmea0183_vhw_water_speed_kilometer,
2669 | {"Water speed", "nmea0183.vhw_water_speed_kilometer",
2670 | FT_STRING, BASE_NONE,
2671 | NULL((void*)0), 0x0,
2672 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2673 | {&hf_nmea0183_vhw_water_speed_kilometer_unit,
2674 | {"Speed unit", "nmea0183.vhw_water_speed_kilometer_unit",
2675 | FT_STRING, BASE_NONE,
2676 | NULL((void*)0), 0x0,
2677 | "NMEA 0183 VHW Water speed unit, must be K", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2678 | {&hf_nmea0183_vlw_cumulative_water,
2679 | {"Cumulative water distance", "nmea0183.vlw_hf_nmea0183_vlw_cumulative_water",
2680 | FT_STRING, BASE_NONE,
2681 | NULL((void*)0), 0x0,
2682 | "NMEA 0183 VLW Total cumulative water distance, nautical miles", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2683 | {&hf_nmea0183_vlw_cumulative_water_unit,
2684 | {"Distance unit", "nmea0183.vlw_cumulative_water_unit",
2685 | FT_STRING, BASE_NONE,
2686 | NULL((void*)0), 0x0,
2687 | "NMEA 0183 VLW Distance unit, must be N", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2688 | {&hf_nmea0183_vlw_trip_water,
2689 | {"Trip water distance", "nmea0183.vlw_hf_nmea0183_vlw_trip_water",
2690 | FT_STRING, BASE_NONE,
2691 | NULL((void*)0), 0x0,
2692 | "NMEA 0183 VLW Water distance since Reset, nautical miles", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2693 | {&hf_nmea0183_vlw_trip_water_unit,
2694 | {"Distance unit", "nmea0183.vlw_trip_water_unit",
2695 | FT_STRING, BASE_NONE,
2696 | NULL((void*)0), 0x0,
2697 | "NMEA 0183 VLW Distance unit, must be N", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2698 | {&hf_nmea0183_vlw_cumulative_ground,
2699 | {"Cumulative ground distance", "nmea0183.vlw_hf_nmea0183_vlw_cumulative_ground",
2700 | FT_STRING, BASE_NONE,
2701 | NULL((void*)0), 0x0,
2702 | "NMEA 0183 VLW Total cumulative ground distance, nautical miles (NMEA 3 and above)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2703 | {&hf_nmea0183_vlw_cumulative_ground_unit,
2704 | {"Distance unit", "nmea0183.vlw_cumulative_ground_unit",
2705 | FT_STRING, BASE_NONE,
2706 | NULL((void*)0), 0x0,
2707 | "NMEA 0183 VLW Distance unit, must be N", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2708 | {&hf_nmea0183_vlw_trip_ground,
2709 | {"Trip ground distance", "nmea0183.vlw_hf_nmea0183_vlw_trip_ground",
2710 | FT_STRING, BASE_NONE,
2711 | NULL((void*)0), 0x0,
2712 | "NMEA 0183 VLW Ground distance since Reset, nautical miles (NMEA 3 and above)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2713 | {&hf_nmea0183_vlw_trip_ground_unit,
2714 | {"Distance unit", "nmea0183.vlw_trip_ground_unit",
2715 | FT_STRING, BASE_NONE,
2716 | NULL((void*)0), 0x0,
2717 | "NMEA 0183 VLW Distance unit, must be N", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2718 | {&hf_nmea0183_vtg_true_course,
2719 | {"True course over ground", "nmea0183.vtg_true_course",
2720 | FT_STRING, BASE_NONE,
2721 | NULL((void*)0), 0x0,
2722 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2723 | {&hf_nmea0183_vtg_true_course_unit,
2724 | {"Course unit", "nmea0183.vtg_true_course_unit",
2725 | FT_STRING, BASE_NONE,
2726 | NULL((void*)0), 0x0,
2727 | "NMEA 0183 VTG Course unit, must be T", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2728 | {&hf_nmea0183_vtg_magnetic_course,
2729 | {"Magnetic course over ground", "nmea0183.vtg_magnetic_course",
2730 | FT_STRING, BASE_NONE,
2731 | NULL((void*)0), 0x0,
2732 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2733 | {&hf_nmea0183_vtg_magnetic_course_unit,
2734 | {"Course unit", "nmea0183.vtg_magnetic_course_unit",
2735 | FT_STRING, BASE_NONE,
2736 | NULL((void*)0), 0x0,
2737 | "NMEA 0183 VTG Course unit, must be M", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2738 | {&hf_nmea0183_vtg_ground_speed_knot,
2739 | {"Speed over ground", "nmea0183.vtg_ground_speed_knot",
2740 | FT_STRING, BASE_NONE,
2741 | NULL((void*)0), 0x0,
2742 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2743 | {&hf_nmea0183_vtg_ground_speed_knot_unit,
2744 | {"Speed unit", "nmea0183.vtg_ground_speed_knot_unit",
2745 | FT_STRING, BASE_NONE,
2746 | NULL((void*)0), 0x0,
2747 | "NMEA 0183 VTG Ground speed unit, must be N", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2748 | {&hf_nmea0183_vtg_ground_speed_kilometer,
2749 | {"Speed over ground", "nmea0183.vtg_ground_speed_kilometer",
2750 | FT_STRING, BASE_NONE,
2751 | NULL((void*)0), 0x0,
2752 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2753 | {&hf_nmea0183_vtg_ground_speed_kilometer_unit,
2754 | {"Speed unit", "nmea0183.vtg_ground_speed_kilometer_unit",
2755 | FT_STRING, BASE_NONE,
2756 | NULL((void*)0), 0x0,
2757 | "NMEA 0183 VTG Ground speed unit, must be K", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2758 | {&hf_nmea0183_vtg_mode,
2759 | {"FAA mode", "nmea0183.vtg_mode",
2760 | FT_STRING, BASE_NONE,
2761 | NULL((void*)0), 0x0,
2762 | "NMEA 0183 VTG FAA mode indicator (NMEA 2.3 and later)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2763 | {&hf_nmea0183_zda_time,
2764 | {"UTC Time", "nmea0183.zda_time",
2765 | FT_NONE, BASE_NONE,
2766 | NULL((void*)0), 0x0,
2767 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2768 | {&hf_nmea0183_zda_time_hour,
2769 | {"Hour", "nmea0183.zda_time_hour",
2770 | FT_STRING, BASE_NONE,
2771 | NULL((void*)0), 0x0,
2772 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2773 | {&hf_nmea0183_zda_time_minute,
2774 | {"Minute", "nmea0183.zda_time_minute",
2775 | FT_STRING, BASE_NONE,
2776 | NULL((void*)0), 0x0,
2777 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2778 | {&hf_nmea0183_zda_time_second,
2779 | {"Second", "nmea0183.zda_time_second",
2780 | FT_STRING, BASE_NONE,
2781 | NULL((void*)0), 0x0,
2782 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2783 | {&hf_nmea0183_zda_date_day,
2784 | {"Day", "nmea0183.zda_date_day",
2785 | FT_STRING, BASE_NONE,
2786 | NULL((void*)0), 0x0,
2787 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2788 | {&hf_nmea0183_zda_date_month,
2789 | {"Month", "nmea0183.zda_date_month",
2790 | FT_STRING, BASE_NONE,
2791 | NULL((void*)0), 0x0,
2792 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2793 | {&hf_nmea0183_zda_date_year,
2794 | {"Year", "nmea0183.zda_date_year",
2795 | FT_STRING, BASE_NONE,
2796 | NULL((void*)0), 0x0,
2797 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2798 | {&hf_nmea0183_zda_local_zone_hour,
2799 | {"Local zone hour", "nmea0183.zda_local_zone_hour",
2800 | FT_STRING, BASE_NONE,
2801 | NULL((void*)0), 0x0,
2802 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2803 | { &hf_nmea0183_zda_local_zone_minute,
2804 | {"Local zone minute", "nmea0183.zda_local_zone_minute",
2805 | FT_STRING, BASE_NONE,
2806 | NULL((void*)0), 0x0,
2807 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2808 | { &hf_nmea0183_sentence_prefix,
2809 | { "Sentence prefix", "nmea0183.sentence_prefix",
2810 | FT_STRING, BASE_NONE,
2811 | NULL((void*)0), 0x0,
2812 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2813 | { &hf_nmea0183_tag_block,
2814 | { "Tag block", "nmea0183.tag_block",
2815 | FT_STRING, BASE_NONE,
2816 | NULL((void*)0), 0x0,
2817 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
2818 | },
2819 | };
2820 |
2821 | /* Setup protocol subtree array */
2822 | static int *ett[] = {
2823 | &ett_nmea0183,
2824 | &ett_nmea0183_checksum,
2825 | &ett_nmea0183_sentence,
2826 | &ett_nmea0183_zda_time,
2827 | &ett_nmea0183_alr_time,
2828 | &ett_nmea0183_gga_time,
2829 | &ett_nmea0183_gga_latitude,
2830 | &ett_nmea0183_gga_longitude,
2831 | &ett_nmea0183_gll_time,
2832 | &ett_nmea0183_gll_latitude,
2833 | &ett_nmea0183_gll_longitude,
2834 | &ett_nmea0183_gst_time,
2835 | &ett_nmea0183_tag_block
2836 | };
2837 |
2838 | static ei_register_info ei[] = {
2839 | {&ei_nmea0183_invalid_first_character,
2840 | {"nmea0183.invalid_first_character", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2841 | "First character should be '$'", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2842 | {&ei_nmea0183_missing_checksum_character,
2843 | {"nmea0183.missing_checksum_character", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
2844 | "Missing begin of checksum character '*'", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2845 | {&ei_nmea0183_invalid_end_of_line,
2846 | {"nmea0183.invalid_end_of_line", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2847 | "Sentence should end with <CR><LF>", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2848 | {&ei_nmea0183_checksum_incorrect,
2849 | {"nmea0183.checksum_incorrect", PI_CHECKSUM0x01000000, PI_WARN0x00600000,
2850 | "Incorrect checksum", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2851 | {&ei_nmea0183_sentence_too_long,
2852 | {"nmea0183.sentence_too_long", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2853 | "Sentence is too long. Maximum is 82 bytes including $ and <CR><LF>", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2854 | {&ei_nmea0183_field_time_too_short,
2855 | {"nmea0183.field_time_too_short", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2856 | "Field containing time is too short. Field should be at least 6 characters", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2857 | {&ei_nmea0183_field_latitude_too_short,
2858 | {"nmea0183.field_latitude_too_short", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2859 | "Field containing latitude is too short. Field should be at least 4 characters", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2860 | {&ei_nmea0183_field_longitude_too_short,
2861 | {"nmea0183.field_longitude_too_short", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2862 | "Field containing longitude is too short. Field should be at least 5 characters", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2863 | {&ei_nmea0183_field_missing,
2864 | {"nmea0183.field_missing", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2865 | "Field expected, but not found", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2866 | {&ei_nmea0183_gga_altitude_unit_incorrect,
2867 | {"nmea0183.gga_altitude_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2868 | "Incorrect altitude unit (should be 'M')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2869 | {&ei_nmea0183_gga_geoidal_separation_unit_incorrect,
2870 | {"nmea0183.gga_geoidal_separation_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2871 | "Incorrect geoidal separation unit (should be 'M')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2872 | {&ei_nmea0183_hdt_unit_incorrect,
2873 | {"nmea0183.hdt_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2874 | "Incorrect heading unit (should be 'T')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2875 | {&ei_nmea0183_vhw_true_heading_unit_incorrect,
2876 | {"nmea0183.vhw_true_heading_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2877 | "Incorrect heading unit (should be 'T')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2878 | {&ei_nmea0183_vhw_magnetic_heading_unit_incorrect,
2879 | {"nmea0183.vhw_magnetic_heading_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2880 | "Incorrect heading unit (should be 'M')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2881 | {&ei_nmea0183_vhw_water_speed_knot_unit_incorrect,
2882 | {"nmea0183.vhw_water_speed_knot_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2883 | "Incorrect speed unit (should be 'N')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2884 | {&ei_nmea0183_vhw_water_speed_kilometer_unit_incorrect,
2885 | {"nmea0183.vhw_water_speed_kilometer_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2886 | "Incorrect speed unit (should be 'K')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2887 | {&ei_nmea0183_vlw_cumulative_water_unit_incorrect,
2888 | {"nmea0183.vlw_cumulative_water_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2889 | "Incorrect distance unit (should be 'N')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2890 | {&ei_nmea0183_vlw_trip_water_unit_incorrect,
2891 | {"nmea0183.vlw_trip_water_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2892 | "Incorrect distance unit (should be 'N')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2893 | {&ei_nmea0183_vlw_cumulative_ground_unit_incorrect,
2894 | {"nmea0183.vlw_cumulative_ground_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2895 | "Incorrect distance unit (should be 'N')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2896 | {&ei_nmea0183_vlw_trip_ground_unit_incorrect,
2897 | {"nmea0183.vlw_trip_ground_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2898 | "Incorrect distance unit (should be 'N')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2899 | {&ei_nmea0183_vtg_true_course_unit_incorrect,
2900 | {"nmea0183.vtg_true_course_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2901 | "Incorrect course unit (should be 'T')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2902 | {&ei_nmea0183_vtg_magnetic_course_unit_incorrect,
2903 | {"nmea0183.vtg_magnetic_course_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2904 | "Incorrect course unit (should be 'M')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2905 | {&ei_nmea0183_vtg_ground_speed_knot_unit_incorrect,
2906 | {"nmea0183.vtg_ground_speed_knot_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2907 | "Incorrect speed unit (should be 'N')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
2908 | {&ei_nmea0183_vtg_ground_speed_kilometer_unit_incorrect,
2909 | {"nmea0183.vtg_ground_speed_kilometer_unit_incorrect", PI_PROTOCOL0x09000000, PI_WARN0x00600000,
2910 | "Incorrect speed unit (should be 'K')", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}}};
2911 |
2912 | proto_nmea0183 = proto_register_protocol("NMEA 0183 protocol", "NMEA 0183", "nmea0183");
2913 |
2914 | proto_register_field_array(proto_nmea0183, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
2915 | proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
2916 | expert_nmea0183 = expert_register_protocol(proto_nmea0183);
2917 | expert_register_field_array(expert_nmea0183, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
2918 |
2919 | nmea0183_handle = register_dissector("nmea0183", dissect_nmea0183, proto_nmea0183);
2920 | }
2921 |
2922 | void proto_reg_handoff_nmea0183(void)
2923 | {
2924 | /* Register the UDP PDU NMEA0183 handle for heuristic dissection */
2925 | heur_dissector_add("udp", dissect_nmea0183_heur, "NMEA0183 over UDP",
2926 | "nmea0183_udp", proto_nmea0183, HEURISTIC_DISABLE);
2927 | dissector_add_for_decode_as_with_preference("udp.port", nmea0183_handle);
2928 | }