### Bug Summary

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