Bug Summary

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