Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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