Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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