Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ubx.c
blobbbdfe4c61ff3710eccc8bc18b5e2e90c8131a76f
1 /* packet-ubx.c
2 * u-blox UBX protocol dissection.
4 * By Timo Warns <timo.warns@gmail.com>
5 * Copyright 2023 Timo Warns
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/expert.h>
17 #include <epan/packet.h>
18 #include <epan/unit_strings.h>
19 #include <wsutil/array.h>
20 #include <wsutil/utf8_entities.h>
21 #include <wsutil/pint.h>
23 #include "packet-ubx.h"
24 #include "packet-sbas_l1.h"
27 * Dissects the UBX protocol of u-blox GNSS receivers as defined by the
28 * u-blox 8 / u-blox M8 receiver description.
31 /* mapping from UBX message class / id to mnemonics */
32 static const value_string UBX_MSG_CLASS_ID[] = {
33 {UBX_ACK_ACK, "UBX-ACK-ACK"},
34 {UBX_ACK_NAK, "UBX-ACK-NAK"},
35 {UBX_AID_ALM, "UBX-AID-ALM"},
36 {UBX_AID_AOP, "UBX-AID-AOP"},
37 {UBX_AID_EPH, "UBX-AID-EPH"},
38 {UBX_AID_HUI, "UBX-AID-HUI"},
39 {UBX_AID_INI, "UBX-AID-INI"},
40 {UBX_CFG_ANT, "UBX-CFG-ANT"},
41 {UBX_CFG_BATCH, "UBX-CFG-BATCH"},
42 {UBX_CFG_CFG, "UBX-CFG-CFG"},
43 {UBX_CFG_DAT, "UBX-CFG-DAT"},
44 {UBX_CFG_DGNSS, "UBX-CFG-DGNSS"},
45 {UBX_CFG_DOSC, "UBX-CFG-DOSC"},
46 {UBX_CFG_ESFALG, "UBX-CFG-ESFALG"},
47 {UBX_CFG_ESFA, "UBX-CFG-ESFA"},
48 {UBX_CFG_ESFG, "UBX-CFG-ESFG"},
49 {UBX_CFG_ESFWT, "UBX-CFG-ESFWT"},
50 {UBX_CFG_ESRC, "UBX-CFG-ESRC"},
51 {UBX_CFG_GEOFENCE, "UBX-CFG-GEOFENCE"},
52 {UBX_CFG_GNSS, "UBX-CFG-GNSS"},
53 {UBX_CFG_HNR, "UBX-CFG-HNR"},
54 {UBX_CFG_INF, "UBX-CFG-INF"},
55 {UBX_CFG_ITFM, "UBX-CFG-ITFM"},
56 {UBX_CFG_LOGFILTER, "UBX-CFG-LOGFILTER"},
57 {UBX_CFG_MSG, "UBX-CFG-MSG"},
58 {UBX_CFG_NAV5, "UBX-CFG-NAV5"},
59 {UBX_CFG_NAVX5, "UBX-CFG-NAVX5"},
60 {UBX_CFG_NMEA, "UBX-CFG-NMEA"},
61 {UBX_CFG_ODO, "UBX-CFG-ODO"},
62 {UBX_CFG_PM2, "UBX-CFG-PM2"},
63 {UBX_CFG_PMS, "UBX-CFG-PMS"},
64 {UBX_CFG_PRT, "UBX-CFG-PRT"},
65 {UBX_CFG_PWR, "UBX-CFG-PWR"},
66 {UBX_CFG_RATE, "UBX-CFG-RATE"},
67 {UBX_CFG_RINV, "UBX-CFG-RINV"},
68 {UBX_CFG_RST, "UBX-CFG-RST"},
69 {UBX_CFG_RXM, "UBX-CFG-RXM"},
70 {UBX_CFG_SBAS, "UBX-CFG-SBAS"},
71 {UBX_CFG_SENIF, "UBX-CFG-SENIF"},
72 {UBX_CFG_SLAS, "UBX-CFG-SLAS"},
73 {UBX_CFG_SMGR, "UBX-CFG-SMGR"},
74 {UBX_CFG_SPT, "UBX-CFG-SPT"},
75 {UBX_CFG_TMODE2, "UBX-CFG-TMODE2"},
76 {UBX_CFG_TMODE3, "UBX-CFG-TMODE3"},
77 {UBX_CFG_TP5, "UBX-CFG-TP5"},
78 {UBX_CFG_TXSLOT, "UBX-CFG-TXSLOT"},
79 {UBX_CFG_USB, "UBX-CFG-USB"},
80 {UBX_ESF_ALG, "UBX-ESF-ALG"},
81 {UBX_ESF_INS, "UBX-ESF-INS"},
82 {UBX_ESF_MEAS, "UBX-ESF-MEAS"},
83 {UBX_ESF_RAW, "UBX-ESF-RAW"},
84 {UBX_ESF_STATUS, "UBX-ESF-STATUS"},
85 {UBX_HNR_ATT, "UBX-HNR-ATT"},
86 {UBX_HNR_INS, "UBX-HNR-INS"},
87 {UBX_HNR_PVT, "UBX-HNR-PVT"},
88 {UBX_INF_DEBUG, "UBX-INF-DEBUG"},
89 {UBX_INF_ERROR, "UBX-INF-ERROR"},
90 {UBX_INF_NOTICE, "UBX-INF-NOTICE"},
91 {UBX_INF_TEST, "UBX-INF-TEST"},
92 {UBX_INF_WARNING, "UBX-INF-WARNING"},
93 {UBX_LOG_BATCH, "UBX-LOG-BATCH"},
94 {UBX_LOG_CREATE, "UBX-LOG-CREATE"},
95 {UBX_LOG_ERASE, "UBX-LOG-ERASE"},
96 {UBX_LOG_FINDTIME, "UBX-LOG-FINDTIME"},
97 {UBX_LOG_INFO, "UBX-LOG-INFO"},
98 {UBX_LOG_RETRIEVEBATCH, "UBX-LOG-RETRIEVEBATCH"},
99 {UBX_LOG_RETRIEVEPOSEXTRA, "UBX-LOG-RETRIEVEPOSEXTRA"},
100 {UBX_LOG_RETRIEVEPOS, "UBX-LOG-RETRIEVEPOS"},
101 {UBX_LOG_RETRIEVESTRING, "UBX-LOG-RETRIEVESTRING"},
102 {UBX_LOG_RETRIEVE, "UBX-LOG-RETRIEVE"},
103 {UBX_LOG_STRING, "UBX-LOG-STRING"},
104 {UBX_MGA_ACK_DATA0, "UBX-MGA-ACK-DATA0"},
105 {UBX_MGA_ANO, "UBX-MGA-ANO"},
106 {UBX_MGA_BDS, "UBX-MGA-BDS"},
107 {UBX_MGA_DBD, "UBX-MGA-DBD"},
108 {UBX_MGA_FLASH, "UBX-MGA-FLASH"},
109 {UBX_MGA_GAL, "UBX-MGA-GAL"},
110 {UBX_MGA_GLO, "UBX-MGA-GLO"},
111 {UBX_MGA_GPS, "UBX-MGA-GPS"},
112 {UBX_MGA_INI, "UBX-MGA-INI"},
113 {UBX_MGA_QZSS, "UBX-MGA-QZSS"},
114 {UBX_MON_BATCH, "UBX-MON-BATCH"},
115 {UBX_MON_GNSS, "UBX-MON-GNSS"},
116 {UBX_MON_HW2, "UBX-MON-HW2"},
117 {UBX_MON_HW, "UBX-MON-HW"},
118 {UBX_MON_IO, "UBX-MON-IO"},
119 {UBX_MON_MSGPP, "UBX-MON-MSGPP"},
120 {UBX_MON_PATCH, "UBX-MON-PATCH"},
121 {UBX_MON_RXBUF, "UBX-MON-RXBUF"},
122 {UBX_MON_RXR, "UBX-MON-RXR"},
123 {UBX_MON_SMGR, "UBX-MON-SMGR"},
124 {UBX_MON_SPT, "UBX-MON-SPT"},
125 {UBX_MON_TXBUF, "UBX-MON-TXBUF"},
126 {UBX_MON_VER, "UBX-MON-VER"},
127 {UBX_NAV_AOPSTATUS, "UBX-NAV-AOPSTATUS"},
128 {UBX_NAV_ATT, "UBX-NAV-ATT"},
129 {UBX_NAV_CLOCK, "UBX-NAV-CLOCK"},
130 {UBX_NAV_COV, "UBX-NAV-COV"},
131 {UBX_NAV_DGPS, "UBX-NAV-DGPS"},
132 {UBX_NAV_DOP, "UBX-NAV-DOP"},
133 {UBX_NAV_EELL, "UBX-NAV-EELL"},
134 {UBX_NAV_EOE, "UBX-NAV-EOE"},
135 {UBX_NAV_GEOFENCE, "UBX-NAV-GEOFENCE"},
136 {UBX_NAV_HPPOSECEF, "UBX-NAV-HPPOSECEF"},
137 {UBX_NAV_HPPOSLLH, "UBX-NAV-HPPOSLLH"},
138 {UBX_NAV_NMI, "UBX-NAV-NMI"},
139 {UBX_NAV_ODO, "UBX-NAV-ODO"},
140 {UBX_NAV_ORB, "UBX-NAV-ORB"},
141 {UBX_NAV_POSECEF, "UBX-NAV-POSECEF"},
142 {UBX_NAV_POSLLH, "UBX-NAV-POSLLH"},
143 {UBX_NAV_PVT, "UBX-NAV-PVT"},
144 {UBX_NAV_RELPOSNED, "UBX-NAV-RELPOSNED"},
145 {UBX_NAV_RESETODO, "UBX-NAV-RESETODO"},
146 {UBX_NAV_SAT, "UBX-NAV-SAT"},
147 {UBX_NAV_SBAS, "UBX-NAV-SBAS"},
148 {UBX_NAV_SLAS, "UBX-NAV-SLAS"},
149 {UBX_NAV_SOL, "UBX-NAV-SOL"},
150 {UBX_NAV_STATUS, "UBX-NAV-STATUS"},
151 {UBX_NAV_SVINFO, "UBX-NAV-SVINFO"},
152 {UBX_NAV_SVIN, "UBX-NAV-SVIN"},
153 {UBX_NAV_TIMEBDS, "UBX-NAV-TIMEBDS"},
154 {UBX_NAV_TIMEGAL, "UBX-NAV-TIMEGAL"},
155 {UBX_NAV_TIMEGLO, "UBX-NAV-TIMEGLO"},
156 {UBX_NAV_TIMEGPS, "UBX-NAV-TIMEGPS"},
157 {UBX_NAV_TIMELS, "UBX-NAV-TIMELS"},
158 {UBX_NAV_TIMEUTC, "UBX-NAV-TIMEUTC"},
159 {UBX_NAV_VELECEF, "UBX-NAV-VELECEF"},
160 {UBX_NAV_VELNED, "UBX-NAV-VELNED"},
161 {UBX_RXM_IMES, "UBX-RXM-IMES"},
162 {UBX_RXM_MEASX, "UBX-RXM-MEASX"},
163 {UBX_RXM_PMREQ, "UBX-RXM-PMREQ"},
164 {UBX_RXM_RAWX, "UBX-RXM-RAWX"},
165 {UBX_RXM_RLM, "UBX-RXM-RLM"},
166 {UBX_RXM_RTCM, "UBX-RXM-RTCM"},
167 {UBX_RXM_SFRBX, "UBX-RXM-SFRBX"},
168 {UBX_RXM_SVSI, "UBX-RXM-SVSI"},
169 {UBX_SEC_UNIQID, "UBX-SEC-UNIQID"},
170 {UBX_TIM_DOSC, "UBX-TIM-DOSC"},
171 {UBX_TIM_FCHG, "UBX-TIM-FCHG"},
172 {UBX_TIM_HOC, "UBX-TIM-HOC"},
173 {UBX_TIM_SMEAS, "UBX-TIM-SMEAS"},
174 {UBX_TIM_SVIN, "UBX-TIM-SVIN"},
175 {UBX_TIM_TM2, "UBX-TIM-TM2"},
176 {UBX_TIM_TOS, "UBX-TIM-TOS"},
177 {UBX_TIM_TP, "UBX-TIM-TP"},
178 {UBX_TIM_VCOCAL, "UBX-TIM-VCOCAL"},
179 {UBX_TIM_VRFY, "UBX-TIM-VRFY"},
180 {UBX_UPD_SOS, "UBX-UPD-SOS"},
181 {0, NULL},
184 static const value_string UBX_GNSS_ID[] = {
185 {GNSS_ID_GPS, "GPS"},
186 {GNSS_ID_SBAS, "SBAS"},
187 {GNSS_ID_GALILEO, "Galileo"},
188 {GNSS_ID_BEIDOU, "Beidou"},
189 {GNSS_ID_IMES, "IMES"},
190 {GNSS_ID_QZSS, "QZSS"},
191 {GNSS_ID_GLONASS, "Glonass"},
192 {0, NULL},
195 /* mapping from correction age id to description */
196 static const value_string UBX_LAST_CORRECTION_AGE[] = {
197 {0, "not available"},
198 {1, "age between 0 and 1 second"},
199 {2, "age between 1 (inclusive) and 2 seconds"},
200 {3, "age between 2 (inclusive) and 5 seconds"},
201 {4, "age between 5 (inclusive) and 10 seconds"},
202 {5, "age between 10 (inclusive) and 15 seconds"},
203 {6, "age between 15 (inclusive) and 20 seconds"},
204 {7, "age between 20 (inclusive) and 30 seconds"},
205 {8, "age between 30 (inclusive) and 45 seconds"},
206 {9, "age between 45 (inclusive) and 60 seconds"},
207 {10, "age between 60 (inclusive) and 90 seconds"},
208 {11, "age between 90 (inclusive) and 120 seconds"},
209 {12, "age greater or equal than 120 seconds"},
210 {13, "age greater or equal than 120 seconds"},
211 {14, "age greater or equal than 120 seconds"},
212 {15, "age greater or equal than 120 seconds"},
213 {0, NULL}
216 /* mapping from GNSS fix type id to description */
217 static const value_string UBX_GNSS_FIX_TYPE[] = {
218 {0, "no fix"},
219 {1, "dead reckoning only"},
220 {2, "2D-fix"},
221 {3, "3D-fix"},
222 {4, "GNSS + dead reckoning combined"},
223 {5, "time only fix"},
224 {0, NULL}
227 /* signal quality indicator description */
228 static const value_string UBX_SIGNAL_QUALITY_INDICATOR[] = {
229 {0, "no signal"},
230 {1, "searching signal"},
231 {2, "signal acquired"},
232 {3, "signal detected but unusable"},
233 {4, "code locked and time synchronized"},
234 {5, "code and carrier locked and time synchronized"},
235 {6, "code and carrier locked and time synchronized"},
236 {7, "code and carrier locked and time synchronized"},
237 {0, NULL}
240 /* signal health description */
241 static const value_string UBX_SIGNAL_HEALTH[] = {
242 {0, "unknown"},
243 {1, "healthy"},
244 {2, "unhealthy"},
245 {0, NULL}
248 /* orbit source description */
249 static const value_string UBX_ORBIT_SOURCE[] = {
250 {0, "no orbit information available"},
251 {1, "ephemeris is used"},
252 {2, "almanac is used"},
253 {3, "AssistNow Offline orbit is used"},
254 {4, "AssistNow Autonomous orbit is used"},
255 {5, "other orbit information is used"},
256 {6, "other orbit information is used"},
257 {7, "other orbit information is used"},
258 {0, NULL}
261 /* CFG-GNSS GPS sigCfgMsk */
262 static const value_string UBX_CFG_GNSS_GPS_SIGCFGMASK[] = {
263 {0x01, "GPS L1C/A"},
264 {0x10, "GPS L2C"},
265 {0, NULL}
268 /* CFG-GNSS SBAS sigCfgMsk */
269 static const value_string UBX_CFG_GNSS_SBAS_SIGCFGMASK[] = {
270 {0x01, "SBAS L1C/A"},
271 {0, NULL}
274 /* CFG-GNSS Galileo sigCfgMsk */
275 static const value_string UBX_CFG_GNSS_GAL_SIGCFGMASK[] = {
276 {0x01, "Galileo E1"},
277 {0x20, "Galileo E5b"},
278 {0, NULL}
281 /* CFG-GNSS BeiDou sigCfgMsk */
282 static const value_string UBX_CFG_GNSS_BDS_SIGCFGMASK[] = {
283 {0x01, "BeiDou B1I"},
284 {0x10, "BeiDou B2I"},
285 {0, NULL}
288 /* CFG-GNSS IMES sigCfgMsk */
289 static const value_string UBX_CFG_GNSS_IMES_SIGCFGMASK[] = {
290 {0x01, "IMES L1"},
291 {0, NULL}
294 /* CFG-GNSS QZSS sigCfgMsk */
295 static const value_string UBX_CFG_GNSS_QZSS_SIGCFGMASK[] = {
296 {0x01, "QZSS L1C/A"},
297 {0x04, "QZSS L1S"},
298 {0x10, "QZSS L2C"},
299 {0, NULL}
302 /* CFG-GNSS Glonass sigCfgMsk */
303 static const value_string UBX_CFG_GNSS_GLO_SIGCFGMASK[] = {
304 {0x01, "Glonass L1"},
305 {0x10, "Glonass L2"},
306 {0, NULL}
309 /* UBX-RXM-MEASX Multipath index */
310 static const value_string UBX_RXM_MEASX_MULTIPATH_INDEX[] = {
311 {0x0, "not measured"},
312 {0x1, "low"},
313 {0x2, "medium"},
314 {0x3, "high"},
315 {0, NULL}
318 /* SBAS mode */
319 static const value_string UBX_SBAS_MODE[] = {
320 {0, "Disabled"},
321 {1, "Enabled integrity"},
322 {3, "Enabled test mode"},
323 {0, NULL}
326 /* SBAS system */
327 static const value_string UBX_SBAS_SYSTEM[] = {
328 {-1, "Unknown"},
329 {0, "WAAS"},
330 {1, "EGNOS"},
331 {2, "MSAS"},
332 {3, "GAGAN"},
333 {16, "GPS"},
334 {0, NULL}
337 /* SBAS testbed description */
338 static const value_string UBX_SBAS_TESTBED[] = {
339 {0, "Ignore data when in test mode (SBAS msg 0)"},
340 {1, "Use data anyhow"},
341 {0, NULL}
344 /* UTC standard identifier */
345 static const value_string UBX_UTC_STD_ID[] = {
346 {0, "Information not available"},
347 {1, "Communications Research Laboratory (CRL), Tokyo, Japan"},
348 {2, "National Institute of Standards and Technology (NIST)"},
349 {3, "U.S. Naval Observatory (USNO)"},
350 {4, "International Bureau of Weights and Measures (BIPM)"},
351 {5, "European laboratories"},
352 {6, "Former Soviet Union (SU)"},
353 {7, "National Time Service Center (NTSC), China"},
354 {15, "Unknown"},
355 {0, NULL}
358 /* Initialize the protocol and registered fields */
359 static int proto_ubx;
361 static int hf_ubx_preamble;
362 static int hf_ubx_msg_class_id;
363 static int hf_ubx_payload_len;
364 static int hf_ubx_chksum;
366 static int hf_ubx_ack_ack;
367 static int hf_ubx_ack_ack_msg_class_id;
369 static int hf_ubx_ack_nak;
370 static int hf_ubx_ack_nak_msg_class_id;
372 static int hf_ubx_cfg_gnss;
373 static int hf_ubx_cfg_gnss_version;
374 static int hf_ubx_cfg_gnss_numtrkchhw;
375 static int hf_ubx_cfg_gnss_numtrkchuse;
376 static int hf_ubx_cfg_gnss_numconfigblocks;
377 static int hf_ubx_cfg_gnss_blk_gnssid;
378 static int hf_ubx_cfg_gnss_blk_restrkch;
379 static int hf_ubx_cfg_gnss_blk_maxtrkch;
380 static int hf_ubx_cfg_gnss_blk_reserved1;
381 static int hf_ubx_cfg_gnss_blk_enable;
382 static int hf_ubx_cfg_gnss_blk_sigcfgmask;
383 static int hf_ubx_cfg_gnss_blk_gps_sigcfgmask;
384 static int hf_ubx_cfg_gnss_blk_sbas_sigcfgmask;
385 static int hf_ubx_cfg_gnss_blk_gal_sigcfgmask;
386 static int hf_ubx_cfg_gnss_blk_bds_sigcfgmask;
387 static int hf_ubx_cfg_gnss_blk_imes_sigcfgmask;
388 static int hf_ubx_cfg_gnss_blk_qzss_sigcfgmask;
389 static int hf_ubx_cfg_gnss_blk_glo_sigcfgmask;
391 static int hf_ubx_cfg_sbas;
392 static int hf_ubx_cfg_sbas_mode;
393 static int hf_ubx_cfg_sbas_mode_enabled;
394 static int hf_ubx_cfg_sbas_mode_test;
395 static int hf_ubx_cfg_sbas_usage_range;
396 static int hf_ubx_cfg_sbas_usage_diffcorr;
397 static int hf_ubx_cfg_sbas_usage_integrity;
398 static int hf_ubx_cfg_sbas_max_sbas;
399 static int hf_ubx_cfg_sbas_scanmode_prn158;
400 static int hf_ubx_cfg_sbas_scanmode_prn157;
401 static int hf_ubx_cfg_sbas_scanmode_prn156;
402 static int hf_ubx_cfg_sbas_scanmode_prn155;
403 static int hf_ubx_cfg_sbas_scanmode_prn154;
404 static int hf_ubx_cfg_sbas_scanmode_prn153;
405 static int hf_ubx_cfg_sbas_scanmode_prn152;
406 static int hf_ubx_cfg_sbas_scanmode_prn151;
407 static int hf_ubx_cfg_sbas_scanmode_prn150;
408 static int hf_ubx_cfg_sbas_scanmode_prn149;
409 static int hf_ubx_cfg_sbas_scanmode_prn148;
410 static int hf_ubx_cfg_sbas_scanmode_prn147;
411 static int hf_ubx_cfg_sbas_scanmode_prn146;
412 static int hf_ubx_cfg_sbas_scanmode_prn145;
413 static int hf_ubx_cfg_sbas_scanmode_prn144;
414 static int hf_ubx_cfg_sbas_scanmode_prn143;
415 static int hf_ubx_cfg_sbas_scanmode_prn142;
416 static int hf_ubx_cfg_sbas_scanmode_prn141;
417 static int hf_ubx_cfg_sbas_scanmode_prn140;
418 static int hf_ubx_cfg_sbas_scanmode_prn139;
419 static int hf_ubx_cfg_sbas_scanmode_prn138;
420 static int hf_ubx_cfg_sbas_scanmode_prn137;
421 static int hf_ubx_cfg_sbas_scanmode_prn136;
422 static int hf_ubx_cfg_sbas_scanmode_prn135;
423 static int hf_ubx_cfg_sbas_scanmode_prn134;
424 static int hf_ubx_cfg_sbas_scanmode_prn133;
425 static int hf_ubx_cfg_sbas_scanmode_prn132;
426 static int hf_ubx_cfg_sbas_scanmode_prn131;
427 static int hf_ubx_cfg_sbas_scanmode_prn130;
428 static int hf_ubx_cfg_sbas_scanmode_prn129;
429 static int hf_ubx_cfg_sbas_scanmode_prn128;
430 static int hf_ubx_cfg_sbas_scanmode_prn127;
431 static int hf_ubx_cfg_sbas_scanmode_prn126;
432 static int hf_ubx_cfg_sbas_scanmode_prn125;
433 static int hf_ubx_cfg_sbas_scanmode_prn124;
434 static int hf_ubx_cfg_sbas_scanmode_prn123;
435 static int hf_ubx_cfg_sbas_scanmode_prn122;
436 static int hf_ubx_cfg_sbas_scanmode_prn121;
437 static int hf_ubx_cfg_sbas_scanmode_prn120;
439 static int * const ubx_cfg_sbas_mode_fields[] = {
440 &hf_ubx_cfg_sbas_mode_enabled,
441 &hf_ubx_cfg_sbas_mode_test,
442 NULL
445 static int hf_ubx_nav_dop;
446 static int hf_ubx_nav_dop_itow;
447 static int hf_ubx_nav_dop_gdop;
448 static int hf_ubx_nav_dop_pdop;
449 static int hf_ubx_nav_dop_tdop;
450 static int hf_ubx_nav_dop_vdop;
451 static int hf_ubx_nav_dop_hdop;
452 static int hf_ubx_nav_dop_ndop;
453 static int hf_ubx_nav_dop_edop;
455 static int hf_ubx_nav_eoe;
456 static int hf_ubx_nav_eoe_itow;
458 static int hf_ubx_nav_odo;
459 static int hf_ubx_nav_odo_version;
460 static int hf_ubx_nav_odo_reserved1;
461 static int hf_ubx_nav_odo_itow;
462 static int hf_ubx_nav_odo_distance;
463 static int hf_ubx_nav_odo_totaldistance;
464 static int hf_ubx_nav_odo_distancestd;
466 static int hf_ubx_nav_posecef;
467 static int hf_ubx_nav_posecef_itow;
468 static int hf_ubx_nav_posecef_ecefx;
469 static int hf_ubx_nav_posecef_ecefy;
470 static int hf_ubx_nav_posecef_ecefz;
471 static int hf_ubx_nav_posecef_pacc;
473 static int hf_ubx_nav_pvt;
474 static int hf_ubx_nav_pvt_itow;
475 static int hf_ubx_nav_pvt_year;
476 static int hf_ubx_nav_pvt_month;
477 static int hf_ubx_nav_pvt_day;
478 static int hf_ubx_nav_pvt_hour;
479 static int hf_ubx_nav_pvt_min;
480 static int hf_ubx_nav_pvt_sec;
481 static int hf_ubx_nav_pvt_valid;
482 static int hf_ubx_nav_pvt_validmag;
483 static int hf_ubx_nav_pvt_fullyresolved;
484 static int hf_ubx_nav_pvt_validtime;
485 static int hf_ubx_nav_pvt_validdate;
486 static int hf_ubx_nav_pvt_tacc;
487 static int hf_ubx_nav_pvt_nano;
488 static int hf_ubx_nav_pvt_fixtype;
489 static int hf_ubx_nav_pvt_flags;
490 static int hf_ubx_nav_pvt_headvehvalid;
491 static int hf_ubx_nav_pvt_psmstate;
492 static int hf_ubx_nav_pvt_diffsoln;
493 static int hf_ubx_nav_pvt_gnssfixok;
494 static int hf_ubx_nav_pvt_flags2;
495 static int hf_ubx_nav_pvt_confirmedtime;
496 static int hf_ubx_nav_pvt_confirmeddate;
497 static int hf_ubx_nav_pvt_confirmedavai;
498 static int hf_ubx_nav_pvt_numsv;
499 static int hf_ubx_nav_pvt_lon;
500 static int hf_ubx_nav_pvt_lat;
501 static int hf_ubx_nav_pvt_height;
502 static int hf_ubx_nav_pvt_hmsl;
503 static int hf_ubx_nav_pvt_hacc;
504 static int hf_ubx_nav_pvt_vacc;
505 static int hf_ubx_nav_pvt_veln;
506 static int hf_ubx_nav_pvt_vele;
507 static int hf_ubx_nav_pvt_veld;
508 static int hf_ubx_nav_pvt_gspeed;
509 static int hf_ubx_nav_pvt_headmot;
510 static int hf_ubx_nav_pvt_sacc;
511 static int hf_ubx_nav_pvt_headacc;
512 static int hf_ubx_nav_pvt_pdop;
513 static int hf_ubx_nav_pvt_lastcorrectionage;
514 static int hf_ubx_nav_pvt_invalidllh;
515 static int hf_ubx_nav_pvt_reserved1;
516 static int hf_ubx_nav_pvt_headveh;
517 static int hf_ubx_nav_pvt_magdec;
518 static int hf_ubx_nav_pvt_magacc;
520 static int * const ubx_nav_pvt_valid_fields[] = {
521 &hf_ubx_nav_pvt_validdate,
522 &hf_ubx_nav_pvt_validtime,
523 &hf_ubx_nav_pvt_fullyresolved,
524 &hf_ubx_nav_pvt_validmag,
525 NULL
528 static int * const ubx_nav_pvt_flags_fields[] = {
529 &hf_ubx_nav_pvt_gnssfixok,
530 &hf_ubx_nav_pvt_diffsoln,
531 &hf_ubx_nav_pvt_psmstate,
532 &hf_ubx_nav_pvt_headvehvalid,
533 NULL
536 static int * const ubx_nav_pvt_flags2_fields[] = {
537 &hf_ubx_nav_pvt_confirmedavai,
538 &hf_ubx_nav_pvt_confirmeddate,
539 &hf_ubx_nav_pvt_confirmedtime,
540 NULL
543 static int hf_ubx_nav_sat;
544 static int hf_ubx_nav_sat_itow;
545 static int hf_ubx_nav_sat_version;
546 static int hf_ubx_nav_sat_num_svs;
547 static int hf_ubx_nav_sat_reserved1;
548 static int hf_ubx_nav_sat_gnss_id;
549 static int hf_ubx_nav_sat_sv_id;
550 static int hf_ubx_nav_sat_cn0;
551 static int hf_ubx_nav_sat_elev;
552 static int hf_ubx_nav_sat_azim;
553 static int hf_ubx_nav_sat_pr_res;
554 static int hf_ubx_nav_sat_flags;
555 static int hf_ubx_nav_sat_quality_ind;
556 static int hf_ubx_nav_sat_sv_used;
557 static int hf_ubx_nav_sat_health;
558 static int hf_ubx_nav_sat_diff_corr;
559 static int hf_ubx_nav_sat_smoothed;
560 static int hf_ubx_nav_sat_orbit_src;
561 static int hf_ubx_nav_sat_eph_avail;
562 static int hf_ubx_nav_sat_alm_avail;
563 static int hf_ubx_nav_sat_ano_avail;
564 static int hf_ubx_nav_sat_aop_avail;
565 static int hf_ubx_nav_sat_sbas_corr_used;
566 static int hf_ubx_nav_sat_rtcm_corr_used;
567 static int hf_ubx_nav_sat_slas_corr_used;
568 static int hf_ubx_nav_sat_spartn_corr_used;
569 static int hf_ubx_nav_sat_pr_corr_used;
570 static int hf_ubx_nav_sat_cr_corr_used;
571 static int hf_ubx_nav_sat_do_corr_used;
573 static int * const ubx_nav_sat_flags_fields[] = {
574 &hf_ubx_nav_sat_quality_ind,
575 &hf_ubx_nav_sat_sv_used,
576 &hf_ubx_nav_sat_health,
577 &hf_ubx_nav_sat_diff_corr,
578 &hf_ubx_nav_sat_smoothed,
579 &hf_ubx_nav_sat_orbit_src,
580 &hf_ubx_nav_sat_eph_avail,
581 &hf_ubx_nav_sat_alm_avail,
582 &hf_ubx_nav_sat_ano_avail,
583 &hf_ubx_nav_sat_aop_avail,
584 &hf_ubx_nav_sat_sbas_corr_used,
585 &hf_ubx_nav_sat_rtcm_corr_used,
586 &hf_ubx_nav_sat_slas_corr_used,
587 &hf_ubx_nav_sat_spartn_corr_used,
588 &hf_ubx_nav_sat_pr_corr_used,
589 &hf_ubx_nav_sat_cr_corr_used,
590 &hf_ubx_nav_sat_do_corr_used,
591 NULL
594 static int hf_ubx_nav_sbas;
595 static int hf_ubx_nav_sbas_itow;
596 static int hf_ubx_nav_sbas_geo;
597 static int hf_ubx_nav_sbas_mode;
598 static int hf_ubx_nav_sbas_sys;
599 static int hf_ubx_nav_sbas_service;
600 static int hf_ubx_nav_sbas_service_ranging;
601 static int hf_ubx_nav_sbas_service_corrections;
602 static int hf_ubx_nav_sbas_service_integrity;
603 static int hf_ubx_nav_sbas_service_testmode;
604 static int hf_ubx_nav_sbas_service_bad;
605 static int hf_ubx_nav_sbas_cnt;
606 static int hf_ubx_nav_sbas_reserved1;
607 static int hf_ubx_nav_sbas_sv_id;
608 static int hf_ubx_nav_sbas_flags;
609 static int hf_ubx_nav_sbas_udre;
610 static int hf_ubx_nav_sbas_sv_sys;
611 static int hf_ubx_nav_sbas_sv_service;
612 static int hf_ubx_nav_sbas_reserved2;
613 static int hf_ubx_nav_sbas_prc;
614 static int hf_ubx_nav_sbas_reserved3;
615 static int hf_ubx_nav_sbas_ic;
617 static int * const ubx_nav_sbas_service_fields[] = {
618 &hf_ubx_nav_sbas_service_ranging,
619 &hf_ubx_nav_sbas_service_corrections,
620 &hf_ubx_nav_sbas_service_integrity,
621 &hf_ubx_nav_sbas_service_testmode,
622 &hf_ubx_nav_sbas_service_bad,
623 NULL
626 static int hf_ubx_nav_timegps;
627 static int hf_ubx_nav_timegps_itow;
628 static int hf_ubx_nav_timegps_ftow;
629 static int hf_ubx_nav_timegps_week;
630 static int hf_ubx_nav_timegps_leaps;
631 static int hf_ubx_nav_timegps_valid;
632 static int hf_ubx_nav_timegps_leapsvalid;
633 static int hf_ubx_nav_timegps_weekvalid;
634 static int hf_ubx_nav_timegps_towvalid;
635 static int hf_ubx_nav_timegps_tacc;
637 static int * const ubx_nav_timegps_valid_fields[] = {
638 &hf_ubx_nav_timegps_towvalid,
639 &hf_ubx_nav_timegps_weekvalid,
640 &hf_ubx_nav_timegps_leapsvalid,
641 NULL
644 static int hf_ubx_nav_timeutc;
645 static int hf_ubx_nav_timeutc_itow;
646 static int hf_ubx_nav_timeutc_tacc;
647 static int hf_ubx_nav_timeutc_nano;
648 static int hf_ubx_nav_timeutc_year;
649 static int hf_ubx_nav_timeutc_month;
650 static int hf_ubx_nav_timeutc_day;
651 static int hf_ubx_nav_timeutc_hour;
652 static int hf_ubx_nav_timeutc_min;
653 static int hf_ubx_nav_timeutc_sec;
654 static int hf_ubx_nav_timeutc_valid;
655 static int hf_ubx_nav_timeutc_validtow;
656 static int hf_ubx_nav_timeutc_validwkn;
657 static int hf_ubx_nav_timeutc_validutc;
658 static int hf_ubx_nav_timeutc_utcstandard;
660 static int * const ubx_nav_timeutc_valid_fields[] = {
661 &hf_ubx_nav_timeutc_validtow,
662 &hf_ubx_nav_timeutc_validwkn,
663 &hf_ubx_nav_timeutc_validutc,
664 &hf_ubx_nav_timeutc_utcstandard,
665 NULL
668 static int hf_ubx_nav_velecef;
669 static int hf_ubx_nav_velecef_itow;
670 static int hf_ubx_nav_velecef_ecefvx;
671 static int hf_ubx_nav_velecef_ecefvy;
672 static int hf_ubx_nav_velecef_ecefvz;
673 static int hf_ubx_nav_velecef_sacc;
675 static int hf_ubx_rxm_measx;
676 static int hf_ubx_rxm_measx_version;
677 static int hf_ubx_rxm_measx_reserved1;
678 static int hf_ubx_rxm_measx_gpstow;
679 static int hf_ubx_rxm_measx_glotow;
680 static int hf_ubx_rxm_measx_bdstow;
681 static int hf_ubx_rxm_measx_reserved2;
682 static int hf_ubx_rxm_measx_qzsstow;
683 static int hf_ubx_rxm_measx_gpstowacc;
684 static int hf_ubx_rxm_measx_glotowacc;
685 static int hf_ubx_rxm_measx_bdstowacc;
686 static int hf_ubx_rxm_measx_reserved3;
687 static int hf_ubx_rxm_measx_qzsstowacc;
688 static int hf_ubx_rxm_measx_numsv;
689 static int hf_ubx_rxm_measx_flags_towset;
690 static int hf_ubx_rxm_measx_reserved4;
691 static int hf_ubx_rxm_measx_gnssid;
692 static int hf_ubx_rxm_measx_svid;
693 static int hf_ubx_rxm_measx_cn0;
694 static int hf_ubx_rxm_measx_mpathindic;
695 static int hf_ubx_rxm_measx_dopplerms;
696 static int hf_ubx_rxm_measx_dopplerhz;
697 static int hf_ubx_rxm_measx_wholechips;
698 static int hf_ubx_rxm_measx_fracchips;
699 static int hf_ubx_rxm_measx_codephase;
700 static int hf_ubx_rxm_measx_intcodephase;
701 static int hf_ubx_rxm_measx_pseurangermserr;
702 static int hf_ubx_rxm_measx_reserved5;
704 static int hf_ubx_rxm_rawx;
705 static int hf_ubx_rxm_rawx_rcvtow;
706 static int hf_ubx_rxm_rawx_week;
707 static int hf_ubx_rxm_rawx_leaps;
708 static int hf_ubx_rxm_rawx_nummeas;
709 static int hf_ubx_rxm_rawx_recstat;
710 static int hf_ubx_rxm_rawx_recstat_leapsec;
711 static int hf_ubx_rxm_rawx_recstat_clkreset;
712 static int hf_ubx_rxm_rawx_version;
713 static int hf_ubx_rxm_rawx_reserved1;
714 static int hf_ubx_rxm_rawx_prmes;
715 static int hf_ubx_rxm_rawx_cpmes;
716 static int hf_ubx_rxm_rawx_domes;
717 static int hf_ubx_rxm_rawx_gnssid;
718 static int hf_ubx_rxm_rawx_svid;
719 static int hf_ubx_rxm_rawx_sigid;
720 static int hf_ubx_rxm_rawx_freqid;
721 static int hf_ubx_rxm_rawx_locktime;
722 static int hf_ubx_rxm_rawx_cn0;
723 static int hf_ubx_rxm_rawx_prstdev;
724 static int hf_ubx_rxm_rawx_cpstdev;
725 static int hf_ubx_rxm_rawx_dostdev;
726 static int hf_ubx_rxm_rawx_trkstat;
727 static int hf_ubx_rxm_rawx_trkstat_prvalid;
728 static int hf_ubx_rxm_rawx_trkstat_cpvalid;
729 static int hf_ubx_rxm_rawx_trkstat_halfcyc;
730 static int hf_ubx_rxm_rawx_trkstat_subhalfcyc;
731 static int hf_ubx_rxm_rawx_reserved2;
733 static int * const ubx_rxm_rawx_recstat_fields[] = {
734 &hf_ubx_rxm_rawx_recstat_leapsec,
735 &hf_ubx_rxm_rawx_recstat_clkreset,
736 NULL
739 static int * const ubx_rxm_rawx_trkstat_fields[] = {
740 &hf_ubx_rxm_rawx_trkstat_prvalid,
741 &hf_ubx_rxm_rawx_trkstat_cpvalid,
742 &hf_ubx_rxm_rawx_trkstat_halfcyc,
743 &hf_ubx_rxm_rawx_trkstat_subhalfcyc,
744 NULL
747 static int hf_ubx_rxm_sfrbx;
748 static int hf_ubx_rxm_sfrbx_gnssid;
749 static int hf_ubx_rxm_sfrbx_svid;
750 static int hf_ubx_rxm_sfrbx_sigid;
751 static int hf_ubx_rxm_sfrbx_freqid;
752 static int hf_ubx_rxm_sfrbx_numwords;
753 static int hf_ubx_rxm_sfrbx_chn;
754 static int hf_ubx_rxm_sfrbx_version;
755 static int hf_ubx_rxm_sfrbx_dwrd;
756 static int hf_ubx_rxm_sfrbx_reserved1;
757 static int hf_ubx_rxm_sfrbx_reserved2;
758 static int hf_ubx_rxm_sfrbx_reserved3;
760 static dissector_table_t ubx_class_id_dissector_table;
761 static dissector_table_t ubx_gnssid_dissector_table;
763 static expert_field ei_ubx_chksum;
765 static int ett_ubx;
766 static int ett_ubx_ack_ack;
767 static int ett_ubx_ack_nak;
768 static int ett_ubx_cfg_gnss;
769 static int ett_ubx_cfg_gnss_block[255];
770 static int ett_ubx_cfg_sbas;
771 static int ett_ubx_cfg_sbas_mode;
772 static int ett_ubx_cfg_sbas_scanmode;
773 static int ett_ubx_nav_dop;
774 static int ett_ubx_nav_eoe;
775 static int ett_ubx_nav_odo;
776 static int ett_ubx_nav_posecef;
777 static int ett_ubx_nav_pvt;
778 static int ett_ubx_nav_pvt_datetime;
779 static int ett_ubx_nav_pvt_valid;
780 static int ett_ubx_nav_pvt_flags;
781 static int ett_ubx_nav_pvt_flags2;
782 static int ett_ubx_nav_sat;
783 static int ett_ubx_nav_sat_sv_info[255];
784 static int ett_ubx_nav_sat_flags;
785 static int ett_ubx_nav_sbas;
786 static int ett_ubx_nav_sbas_service;
787 static int ett_ubx_nav_sbas_sv_info[255];
788 static int ett_ubx_nav_timegps;
789 static int ett_ubx_nav_timegps_tow;
790 static int ett_ubx_nav_timegps_valid;
791 static int ett_ubx_nav_timeutc;
792 static int ett_ubx_nav_timeutc_valid;
793 static int ett_ubx_nav_velecef;
794 static int ett_ubx_rxm_measx;
795 static int ett_ubx_rxm_measx_meas[255];
796 static int ett_ubx_rxm_rawx;
797 static int ett_ubx_rxm_rawx_recstat;
798 static int ett_ubx_rxm_rawx_trkstat;
799 static int ett_ubx_rxm_rawx_meas[255];
800 static int ett_ubx_rxm_sfrbx;
802 static dissector_handle_t ubx_handle;
804 /* compute the checksum for a UBX message (Fletcher 8-bit by RFC 1145 */
805 static uint16_t chksum_fletcher_8(const uint8_t *data, const int len) {
806 uint8_t ck_a = 0, ck_b = 0;
807 int i;
809 for (i = 0; i < len; i++) {
810 ck_a += data[i];
811 ck_b += ck_a;
814 return (ck_b << 8) | ck_a;
817 /* Format code phase */
818 static void fmt_codephase(char *label, uint32_t p) {
819 snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-21 ms", p);
822 /* Format carrier phase standard deviation */
823 static void fmt_cpstdev(char *label, uint32_t p) {
824 snprintf(label, ITEM_LABEL_LENGTH, "%d.%03d cycles", (p * 4) / 1000, (p * 4) % 1000);
827 /* Format magnetic declination */
828 static void fmt_decl(char *label, int32_t d) {
829 if (d >= 0) {
830 snprintf(label, ITEM_LABEL_LENGTH, "%d.%02d%s", d / 100, d % 100,
831 UTF8_DEGREE_SIGN);
833 else {
834 snprintf(label, ITEM_LABEL_LENGTH, "-%d.%02d%s", -d / 100, -d % 100,
835 UTF8_DEGREE_SIGN);
839 /* Format magnetic declination accuracy */
840 static void fmt_decl_acc(char *label, uint32_t a) {
841 snprintf(label, ITEM_LABEL_LENGTH, "%d.%02d%s", a / 100,
842 a % 100, UTF8_DEGREE_SIGN);
845 /* Format Dilution of Precision */
846 static void fmt_dop(char *label, uint32_t dop) {
847 snprintf(label, ITEM_LABEL_LENGTH, "%i.%02i", dop / 100, dop % 100);
850 /* Format Doppler measurement in m/s */
851 static void fmt_dopplerms(char *label, int32_t d) {
852 if (d >= 0) {
853 snprintf(label, ITEM_LABEL_LENGTH, "%d.%02d m/s", d * 4 / 100, (d * 4) % 100);
855 else {
856 snprintf(label, ITEM_LABEL_LENGTH, "-%d.%02d m/s", -d * 4 / 100, (-d * 4) % 100);
860 /* Format Doppler measurement in Hz */
861 static void fmt_dopplerhz(char *label, int32_t d) {
862 if (d >= 0) {
863 snprintf(label, ITEM_LABEL_LENGTH, "%d.%01d Hz", d * 2 / 10, (d * 2) % 10);
865 else {
866 snprintf(label, ITEM_LABEL_LENGTH, "-%d.%01d Hz", -d * 2 / 10, (-d * 2) % 10);
870 /* Format Doppler standard deviation */
871 static void fmt_dostdev(char *label, uint32_t p) {
872 snprintf(label, ITEM_LABEL_LENGTH, "%d.%03d Hz", (1 << p) * 2 / 1000, ((1 << p) * 2) % 1000);
875 /* Format heading */
876 static void fmt_heading(char *label, int32_t h) {
877 if (h >= 0) {
878 snprintf(label, ITEM_LABEL_LENGTH, "%d.%05d%s", h / 100000, h % 100000,
879 UTF8_DEGREE_SIGN);
881 else {
882 snprintf(label, ITEM_LABEL_LENGTH, "-%d.%05d%s", -h / 100000,
883 -h % 100000, UTF8_DEGREE_SIGN);
887 /* Format heading accuracy */
888 static void fmt_heading_acc(char *label, uint32_t a) {
889 snprintf(label, ITEM_LABEL_LENGTH, "%d.%05d%s", a / 100000,
890 a % 100000, UTF8_DEGREE_SIGN);
893 /* Format latitude or longitude */
894 static void fmt_lat_lon(char *label, int32_t l) {
895 if (l >= 0) {
896 snprintf(label, ITEM_LABEL_LENGTH, "%d.%07d%s", l / 10000000,
897 l % 10000000, UTF8_DEGREE_SIGN);
899 else {
900 snprintf(label, ITEM_LABEL_LENGTH, "-%d.%07d%s", -l / 10000000,
901 -l % 10000000, UTF8_DEGREE_SIGN);
905 /* Format pseudo-range residuals */
906 static void fmt_pr_res(char *label, int32_t p) {
907 if (p >= 0) {
908 snprintf(label, ITEM_LABEL_LENGTH, "%d.%01dm", p / 10, p % 10);
910 else {
911 snprintf(label, ITEM_LABEL_LENGTH, "-%d.%01dm", -p / 10, -p % 10);
915 /* Format pseudo-range standard deviation */
916 static void fmt_prstdev(char *label, uint32_t p) {
917 snprintf(label, ITEM_LABEL_LENGTH, "%d.%02dm", (1 << p) / 100, (1 << p) % 100);
920 /* Format measurement reference time accuracy */
921 static void fmt_towacc(char *label, uint32_t p) {
922 snprintf(label, ITEM_LABEL_LENGTH, "%d.%04dms", p / 16, (p * 10000 / 16) % 10000);
925 /* Dissect UBX message */
926 static int dissect_ubx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
927 tvbuff_t *next_tvb;
928 uint32_t msg_class_id, payload_len, cmp_chksum;
930 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX");
931 col_clear(pinfo->cinfo, COL_INFO);
933 payload_len = tvb_get_uint16(tvb, 4, ENC_LITTLE_ENDIAN);
935 proto_item *ti = proto_tree_add_item(tree, proto_ubx, tvb, 0,
936 UBX_HEADER_SIZE + payload_len + UBX_CHKSUM_SIZE, ENC_NA);
937 proto_tree *ubx_tree = proto_item_add_subtree(ti, ett_ubx);
939 // dissect the registered fields
940 proto_tree_add_item(ubx_tree, hf_ubx_preamble,
941 tvb, 0, 2, ENC_BIG_ENDIAN);
942 proto_tree_add_item_ret_uint(ubx_tree, hf_ubx_msg_class_id,
943 tvb, 2, 2, ENC_BIG_ENDIAN, &msg_class_id);
944 proto_tree_add_item(ubx_tree, hf_ubx_payload_len,
945 tvb, 4, 2, ENC_LITTLE_ENDIAN);
947 // checksum
948 cmp_chksum = chksum_fletcher_8(
949 (uint8_t *)tvb_memdup(pinfo->pool, tvb, 2, UBX_HEADER_SIZE + payload_len - 2),
950 UBX_HEADER_SIZE + payload_len - 2);
951 proto_tree_add_checksum(ubx_tree,
952 tvb, UBX_HEADER_SIZE + payload_len,
953 hf_ubx_chksum, -1, &ei_ubx_chksum, NULL, cmp_chksum,
954 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
956 // send the payload to the next dissector
957 next_tvb = tvb_new_subset_length(tvb, UBX_HEADER_SIZE, payload_len);
958 if (!dissector_try_uint(ubx_class_id_dissector_table, msg_class_id,
959 next_tvb, pinfo, tree)) {
960 call_data_dissector(next_tvb, pinfo, tree);
963 return tvb_captured_length(tvb);
966 /* Dissect UBX-ACK-ACK message */
967 static int dissect_ubx_ack_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
968 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-ACK-ACK");
969 col_clear(pinfo->cinfo, COL_INFO);
971 proto_item *ti = proto_tree_add_item(tree, hf_ubx_ack_ack, tvb, 0, 2, ENC_NA);
972 proto_tree *ubx_ack_ack_tree = proto_item_add_subtree(ti, ett_ubx_ack_ack);
974 // dissect the registered fields
975 proto_tree_add_item(ubx_ack_ack_tree, hf_ubx_ack_ack_msg_class_id,
976 tvb, 0, 2, ENC_BIG_ENDIAN);
978 return tvb_captured_length(tvb);
981 /* Dissect UBX-ACK-NAK message */
982 static int dissect_ubx_ack_nak(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
983 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-ACK-NAK");
984 col_clear(pinfo->cinfo, COL_INFO);
986 proto_item *ti = proto_tree_add_item(tree, hf_ubx_ack_nak, tvb, 0, 2, ENC_NA);
987 proto_tree *ubx_ack_nak_tree = proto_item_add_subtree(ti, ett_ubx_ack_nak);
989 // dissect the registered fields
990 proto_tree_add_item(ubx_ack_nak_tree, hf_ubx_ack_nak_msg_class_id,
991 tvb, 0, 2, ENC_BIG_ENDIAN);
993 return tvb_captured_length(tvb);
996 /* Dissect UBX-CFG-SBAS message */
997 static int dissect_ubx_cfg_gnss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
998 uint8_t i, num_config_blocks;
1000 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-CFG-GNSS");
1001 col_clear(pinfo->cinfo, COL_INFO);
1003 num_config_blocks = tvb_get_uint8(tvb, 3);
1005 proto_item *ti = proto_tree_add_item(tree, hf_ubx_cfg_gnss,
1006 tvb, 0, 4 + 8 * num_config_blocks, ENC_NA);
1007 proto_tree *ubx_cfg_gnss_tree = proto_item_add_subtree(ti, ett_ubx_cfg_gnss);
1009 // dissect the registered fields
1010 proto_tree_add_item(ubx_cfg_gnss_tree, hf_ubx_cfg_gnss_version,
1011 tvb, 0, 1, ENC_NA);
1012 proto_tree_add_item(ubx_cfg_gnss_tree, hf_ubx_cfg_gnss_numtrkchhw,
1013 tvb, 1, 1, ENC_NA);
1014 proto_tree_add_item(ubx_cfg_gnss_tree, hf_ubx_cfg_gnss_numtrkchuse,
1015 tvb, 2, 1, ENC_NA);
1016 proto_tree_add_item(ubx_cfg_gnss_tree, hf_ubx_cfg_gnss_numconfigblocks,
1017 tvb, 3, 1, ENC_NA);
1019 for (i = 0; i < num_config_blocks; i++) {
1020 const uint8_t gnss_id = tvb_get_uint8(tvb, 4 + 8 * i);
1021 const uint8_t res_trk_ch = tvb_get_uint8(tvb, 5 + 8 * i);
1022 const uint8_t max_trk_ch = tvb_get_uint8(tvb, 6 + 8 * i);
1024 proto_tree *gnss_blk_tree = proto_tree_add_subtree_format(ubx_cfg_gnss_tree,
1025 tvb, 4 + 8 * i, 8, ett_ubx_cfg_gnss_block[i], NULL,
1026 "%-7s (Res Trk Ch %2d, Max Trk Ch %2d)",
1027 val_to_str_const(gnss_id, UBX_GNSS_ID, "Unknown GNSS ID"),
1028 res_trk_ch, max_trk_ch);
1030 proto_tree_add_item(gnss_blk_tree, hf_ubx_cfg_gnss_blk_gnssid,
1031 tvb, 4 + (8 * i), 1, ENC_NA);
1032 proto_tree_add_item(gnss_blk_tree, hf_ubx_cfg_gnss_blk_restrkch,
1033 tvb, 5 + (8 * i), 1, ENC_NA);
1034 proto_tree_add_item(gnss_blk_tree, hf_ubx_cfg_gnss_blk_maxtrkch,
1035 tvb, 6 + (8 * i), 1, ENC_NA);
1036 proto_tree_add_item(gnss_blk_tree, hf_ubx_cfg_gnss_blk_reserved1,
1037 tvb, 7 + (8 * i), 1, ENC_NA);
1038 proto_tree_add_item(gnss_blk_tree, hf_ubx_cfg_gnss_blk_enable,
1039 tvb, 8 + (8 * i), 4, ENC_LITTLE_ENDIAN);
1041 int hf;
1042 switch (gnss_id) {
1043 case GNSS_ID_GPS:
1044 hf = hf_ubx_cfg_gnss_blk_gps_sigcfgmask;
1045 break;
1046 case GNSS_ID_SBAS:
1047 hf = hf_ubx_cfg_gnss_blk_sbas_sigcfgmask;
1048 break;
1049 case GNSS_ID_GALILEO:
1050 hf = hf_ubx_cfg_gnss_blk_gal_sigcfgmask;
1051 break;
1052 case GNSS_ID_BEIDOU:
1053 hf = hf_ubx_cfg_gnss_blk_bds_sigcfgmask;
1054 break;
1055 case GNSS_ID_IMES:
1056 hf = hf_ubx_cfg_gnss_blk_imes_sigcfgmask;
1057 break;
1058 case GNSS_ID_QZSS:
1059 hf = hf_ubx_cfg_gnss_blk_qzss_sigcfgmask;
1060 break;
1061 case GNSS_ID_GLONASS:
1062 hf = hf_ubx_cfg_gnss_blk_glo_sigcfgmask;
1063 break;
1064 default:
1065 hf = hf_ubx_cfg_gnss_blk_sigcfgmask;
1067 proto_tree_add_item(gnss_blk_tree, hf,
1068 tvb, 8 + (8 * i), 4, ENC_LITTLE_ENDIAN);
1071 return tvb_captured_length(tvb);
1074 /* Dissect UBX-CFG-SBAS message */
1075 static int dissect_ubx_cfg_sbas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1076 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-CFG-SBAS");
1077 col_clear(pinfo->cinfo, COL_INFO);
1079 proto_item *ti = proto_tree_add_item(tree, hf_ubx_cfg_sbas, tvb, 0, 2, ENC_NA);
1080 proto_tree *ubx_cfg_sbas_tree = proto_item_add_subtree(ti, ett_ubx_cfg_sbas);
1082 // dissect the registered fields
1083 proto_tree_add_bitmask(ubx_cfg_sbas_tree, tvb, 0, hf_ubx_cfg_sbas_mode,
1084 ett_ubx_cfg_sbas_mode, ubx_cfg_sbas_mode_fields, ENC_NA);
1085 proto_tree_add_item(ubx_cfg_sbas_tree, hf_ubx_cfg_sbas_usage_range,
1086 tvb, 1, 1, ENC_NA);
1087 proto_tree_add_item(ubx_cfg_sbas_tree, hf_ubx_cfg_sbas_usage_diffcorr,
1088 tvb, 1, 1, ENC_NA);
1089 proto_tree_add_item(ubx_cfg_sbas_tree, hf_ubx_cfg_sbas_usage_integrity,
1090 tvb, 1, 1, ENC_NA);
1091 proto_tree_add_item(ubx_cfg_sbas_tree, hf_ubx_cfg_sbas_max_sbas,
1092 tvb, 2, 1, ENC_NA);
1094 // scanmode bitmask
1095 proto_tree *scanmode_tree = proto_tree_add_subtree(ubx_cfg_sbas_tree,
1096 tvb, 3, 5, ett_ubx_cfg_sbas_scanmode, NULL, "Scanmode bitmask");
1097 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn120,
1098 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1099 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn121,
1100 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1101 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn122,
1102 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1103 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn123,
1104 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1105 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn124,
1106 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1107 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn125,
1108 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1109 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn126,
1110 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1111 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn127,
1112 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1113 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn128,
1114 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1115 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn129,
1116 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1117 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn130,
1118 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1119 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn131,
1120 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1121 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn132,
1122 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1123 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn133,
1124 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1125 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn134,
1126 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1127 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn135,
1128 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1129 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn136,
1130 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1131 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn137,
1132 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1133 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn138,
1134 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1135 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn139,
1136 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1137 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn140,
1138 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1139 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn141,
1140 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1141 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn142,
1142 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1143 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn143,
1144 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1145 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn144,
1146 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1147 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn145,
1148 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1149 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn146,
1150 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1151 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn147,
1152 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1153 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn148,
1154 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1155 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn149,
1156 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1157 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn150,
1158 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1159 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn151,
1160 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1161 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn152,
1162 tvb, 3, 1, ENC_NA);
1163 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn153,
1164 tvb, 3, 1, ENC_NA);
1165 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn154,
1166 tvb, 3, 1, ENC_NA);
1167 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn155,
1168 tvb, 3, 1, ENC_NA);
1169 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn156,
1170 tvb, 3, 1, ENC_NA);
1171 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn157,
1172 tvb, 3, 1, ENC_NA);
1173 proto_tree_add_item(scanmode_tree, hf_ubx_cfg_sbas_scanmode_prn158,
1174 tvb, 3, 1, ENC_NA);
1176 return tvb_captured_length(tvb);
1179 /* Dissect UBX-NAV-DOP message */
1180 static int dissect_ubx_nav_dop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1181 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-DOP");
1182 col_clear(pinfo->cinfo, COL_INFO);
1184 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_dop,
1185 tvb, 0, 18, ENC_NA);
1186 proto_tree *ubx_nav_dop_tree = proto_item_add_subtree(ti, ett_ubx_nav_dop);
1188 // dissect the registered fields
1189 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_itow,
1190 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1191 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_gdop, tvb, 4, 2, ENC_LITTLE_ENDIAN);
1192 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_pdop, tvb, 6, 2, ENC_LITTLE_ENDIAN);
1193 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_tdop, tvb, 8, 2, ENC_LITTLE_ENDIAN);
1194 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_vdop, tvb, 10, 2, ENC_LITTLE_ENDIAN);
1195 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_hdop, tvb, 12, 2, ENC_LITTLE_ENDIAN);
1196 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_ndop, tvb, 14, 2, ENC_LITTLE_ENDIAN);
1197 proto_tree_add_item(ubx_nav_dop_tree, hf_ubx_nav_dop_edop, tvb, 16, 2, ENC_LITTLE_ENDIAN);
1199 return tvb_captured_length(tvb);
1202 /* Dissect UBX-NAV-EOE message */
1203 static int dissect_ubx_nav_eoe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1204 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-EOE");
1205 col_clear(pinfo->cinfo, COL_INFO);
1207 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_eoe,
1208 tvb, 0, 4, ENC_NA);
1209 proto_tree *ubx_nav_eoe_tree = proto_item_add_subtree(ti, ett_ubx_nav_eoe);
1211 // dissect the registered fields
1212 proto_tree_add_item(ubx_nav_eoe_tree, hf_ubx_nav_eoe_itow,
1213 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1215 return tvb_captured_length(tvb);
1218 /* Dissect UBX-NAV-ODO message */
1219 static int dissect_ubx_nav_odo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1220 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-ODO");
1221 col_clear(pinfo->cinfo, COL_INFO);
1223 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_odo,
1224 tvb, 0, 20, ENC_NA);
1225 proto_tree *ubx_nav_odo_tree = proto_item_add_subtree(ti, ett_ubx_nav_odo);
1227 // dissect the registered fields
1228 proto_tree_add_item(ubx_nav_odo_tree, hf_ubx_nav_odo_version,
1229 tvb, 0, 1, ENC_NA);
1230 proto_tree_add_item(ubx_nav_odo_tree, hf_ubx_nav_odo_reserved1,
1231 tvb, 1, 3, ENC_LITTLE_ENDIAN);
1232 proto_tree_add_item(ubx_nav_odo_tree, hf_ubx_nav_odo_itow,
1233 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1234 proto_tree_add_item(ubx_nav_odo_tree, hf_ubx_nav_odo_distance,
1235 tvb, 8, 4, ENC_LITTLE_ENDIAN);
1236 proto_tree_add_item(ubx_nav_odo_tree, hf_ubx_nav_odo_totaldistance,
1237 tvb, 12, 4, ENC_LITTLE_ENDIAN);
1238 proto_tree_add_item(ubx_nav_odo_tree, hf_ubx_nav_odo_distancestd,
1239 tvb, 16, 4, ENC_LITTLE_ENDIAN);
1241 return tvb_captured_length(tvb);
1244 /* Dissect UBX-NAV-POSECEF message */
1245 static int dissect_ubx_nav_posecef(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1246 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-POSECEF");
1247 col_clear(pinfo->cinfo, COL_INFO);
1249 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_posecef,
1250 tvb, 0, 20, ENC_NA);
1251 proto_tree *ubx_nav_posecef_tree = proto_item_add_subtree(ti, ett_ubx_nav_posecef);
1253 // dissect the registered fields
1254 proto_tree_add_item(ubx_nav_posecef_tree, hf_ubx_nav_posecef_itow,
1255 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1256 proto_tree_add_item(ubx_nav_posecef_tree, hf_ubx_nav_posecef_ecefx,
1257 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1258 proto_tree_add_item(ubx_nav_posecef_tree, hf_ubx_nav_posecef_ecefy,
1259 tvb, 8, 4, ENC_LITTLE_ENDIAN);
1260 proto_tree_add_item(ubx_nav_posecef_tree, hf_ubx_nav_posecef_ecefz,
1261 tvb, 12, 4, ENC_LITTLE_ENDIAN);
1262 proto_tree_add_item(ubx_nav_posecef_tree, hf_ubx_nav_posecef_pacc,
1263 tvb, 16, 4, ENC_LITTLE_ENDIAN);
1265 return tvb_captured_length(tvb);
1268 /* Dissect UBX-NAV-PVT message */
1269 static int dissect_ubx_nav_pvt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1270 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-PVT");
1271 col_clear(pinfo->cinfo, COL_INFO);
1273 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_pvt,
1274 tvb, 0, 92, ENC_NA);
1275 proto_tree *ubx_nav_pvt_tree = proto_item_add_subtree(ti, ett_ubx_nav_pvt);
1277 // dissect the registered fields
1278 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_itow,
1279 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1281 // dissect date & time
1282 uint16_t year = tvb_get_int16(tvb, 4, ENC_LITTLE_ENDIAN);
1283 uint8_t month = tvb_get_int8(tvb, 6);
1284 uint8_t day = tvb_get_int8(tvb, 7);
1285 uint8_t hour = tvb_get_int8(tvb, 8);
1286 uint8_t min = tvb_get_int8(tvb, 9);
1287 uint8_t sec = tvb_get_int8(tvb, 10);
1288 proto_tree *datetime_tree = proto_tree_add_subtree_format(ubx_nav_pvt_tree,
1289 tvb, 4, 7, ett_ubx_nav_pvt_datetime, NULL,
1290 "Date/time: %04d-%02d-%02d %02d:%02d:%02d",
1291 year, month, day, hour, min, sec);
1292 proto_tree_add_item(datetime_tree, hf_ubx_nav_pvt_year,
1293 tvb, 4, 2, ENC_LITTLE_ENDIAN);
1294 proto_tree_add_item(datetime_tree, hf_ubx_nav_pvt_month,
1295 tvb, 6, 1, ENC_NA);
1296 proto_tree_add_item(datetime_tree, hf_ubx_nav_pvt_day,
1297 tvb, 7, 1, ENC_NA);
1298 proto_tree_add_item(datetime_tree, hf_ubx_nav_pvt_hour,
1299 tvb, 8, 1, ENC_NA);
1300 proto_tree_add_item(datetime_tree, hf_ubx_nav_pvt_min,
1301 tvb, 9, 1, ENC_NA);
1302 proto_tree_add_item(datetime_tree, hf_ubx_nav_pvt_sec,
1303 tvb, 10, 1, ENC_NA);
1305 proto_tree_add_bitmask(ubx_nav_pvt_tree, tvb, 11, hf_ubx_nav_pvt_valid,
1306 ett_ubx_nav_pvt_valid, ubx_nav_pvt_valid_fields, ENC_NA);
1307 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_tacc,
1308 tvb, 12, 4, ENC_LITTLE_ENDIAN);
1309 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_nano,
1310 tvb, 16, 4, ENC_LITTLE_ENDIAN);
1311 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_fixtype,
1312 tvb, 20, 1, ENC_NA);
1313 proto_tree_add_bitmask(ubx_nav_pvt_tree, tvb, 21, hf_ubx_nav_pvt_flags,
1314 ett_ubx_nav_pvt_flags, ubx_nav_pvt_flags_fields, ENC_NA);
1315 proto_tree_add_bitmask(ubx_nav_pvt_tree, tvb, 22, hf_ubx_nav_pvt_flags2,
1316 ett_ubx_nav_pvt_flags2, ubx_nav_pvt_flags2_fields, ENC_NA);
1317 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_numsv,
1318 tvb, 23, 1, ENC_NA);
1319 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_lon,
1320 tvb, 24, 4, ENC_LITTLE_ENDIAN);
1321 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_lat,
1322 tvb, 28, 4, ENC_LITTLE_ENDIAN);
1323 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_height,
1324 tvb, 32, 4, ENC_LITTLE_ENDIAN);
1325 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_hmsl,
1326 tvb, 36, 4, ENC_LITTLE_ENDIAN);
1327 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_hacc,
1328 tvb, 40, 4, ENC_LITTLE_ENDIAN);
1329 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_vacc,
1330 tvb, 44, 4, ENC_LITTLE_ENDIAN);
1331 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_veln,
1332 tvb, 48, 4, ENC_LITTLE_ENDIAN);
1333 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_vele,
1334 tvb, 52, 4, ENC_LITTLE_ENDIAN);
1335 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_veld,
1336 tvb, 56, 4, ENC_LITTLE_ENDIAN);
1337 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_gspeed,
1338 tvb, 60, 4, ENC_LITTLE_ENDIAN);
1339 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_headmot,
1340 tvb, 64, 4, ENC_LITTLE_ENDIAN);
1341 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_sacc,
1342 tvb, 68, 4, ENC_LITTLE_ENDIAN);
1343 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_headacc,
1344 tvb, 72, 4, ENC_LITTLE_ENDIAN);
1345 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_pdop,
1346 tvb, 76, 2, ENC_LITTLE_ENDIAN);
1347 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_invalidllh,
1348 tvb, 78, 2, ENC_LITTLE_ENDIAN);
1349 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_lastcorrectionage,
1350 tvb, 78, 2, ENC_LITTLE_ENDIAN);
1351 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_reserved1,
1352 tvb, 80, 4, ENC_LITTLE_ENDIAN);
1353 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_headveh,
1354 tvb, 84, 4, ENC_LITTLE_ENDIAN);
1355 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_magdec,
1356 tvb, 88, 2, ENC_LITTLE_ENDIAN);
1357 proto_tree_add_item(ubx_nav_pvt_tree, hf_ubx_nav_pvt_magacc,
1358 tvb, 90, 2, ENC_LITTLE_ENDIAN);
1360 return tvb_captured_length(tvb);
1363 /* Dissect UBX-NAV-SAT message */
1364 static int dissect_ubx_nav_sat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1365 uint16_t i;
1366 uint32_t num_svs;
1368 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-SAT");
1369 col_clear(pinfo->cinfo, COL_INFO);
1371 num_svs = tvb_get_uint8(tvb, 5);
1373 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_sat,
1374 tvb, 0, 8 + 12 * num_svs, ENC_NA);
1375 proto_tree *ubx_nav_sat_tree = proto_item_add_subtree(ti, ett_ubx_nav_sat);
1377 // dissect the registered fields
1378 proto_tree_add_item(ubx_nav_sat_tree, hf_ubx_nav_sat_itow,
1379 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1380 proto_tree_add_item(ubx_nav_sat_tree, hf_ubx_nav_sat_version,
1381 tvb, 4, 1, ENC_NA);
1382 proto_tree_add_item(ubx_nav_sat_tree, hf_ubx_nav_sat_num_svs,
1383 tvb, 5, 1, ENC_NA);
1384 proto_tree_add_item(ubx_nav_sat_tree, hf_ubx_nav_sat_reserved1,
1385 tvb, 6, 2, ENC_NA);
1387 for (i = 0; i < num_svs; i++) {
1388 const uint8_t gnss_id = tvb_get_uint8(tvb, 8 + 12 * i);
1389 const uint8_t sv_id = tvb_get_uint8(tvb, 9 + 12 * i);
1390 const uint32_t used = (tvb_get_uint32(tvb, 16 + 12 * i, ENC_LITTLE_ENDIAN) & 0x0008) >> 3;
1392 proto_tree *sv_info_tree = proto_tree_add_subtree_format(ubx_nav_sat_tree,
1393 tvb, 8 + 12 * i, 12, ett_ubx_nav_sat_sv_info[i], NULL,
1394 "%-7s / SV ID %3d, used %d",
1395 val_to_str_const(gnss_id, UBX_GNSS_ID, "Unknown GNSS ID"),
1396 sv_id, used);
1398 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sat_gnss_id,
1399 tvb, 8 + (12 * i), 1, ENC_NA);
1400 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sat_sv_id,
1401 tvb, 9 + (12 * i), 1, ENC_NA);
1402 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sat_cn0,
1403 tvb, 10 + (12 * i), 1, ENC_NA);
1404 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sat_elev,
1405 tvb, 11 + (12 * i), 1, ENC_NA);
1406 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sat_azim,
1407 tvb, 12 + (12 * i), 2, ENC_LITTLE_ENDIAN);
1408 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sat_pr_res,
1409 tvb, 14 + (12 * i), 2, ENC_LITTLE_ENDIAN);
1410 proto_tree_add_bitmask(sv_info_tree,
1411 tvb, 16 + (12 * i),
1412 hf_ubx_nav_sat_flags, ett_ubx_nav_sat_flags,
1413 ubx_nav_sat_flags_fields, ENC_LITTLE_ENDIAN);
1416 return tvb_captured_length(tvb);
1419 /* Dissect UBX-NAV-SBAS message */
1420 static int dissect_ubx_nav_sbas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1421 uint16_t i;
1422 uint32_t num_svs;
1424 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-SBAS");
1425 col_clear(pinfo->cinfo, COL_INFO);
1427 num_svs = tvb_get_uint8(tvb, 8);
1429 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_sbas,
1430 tvb, 0, 12 + 12 * num_svs, ENC_NA);
1431 proto_tree *ubx_nav_sbas_tree = proto_item_add_subtree(ti, ett_ubx_nav_sbas);
1433 proto_tree_add_item(ubx_nav_sbas_tree, hf_ubx_nav_sbas_itow,
1434 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1435 proto_tree_add_item(ubx_nav_sbas_tree, hf_ubx_nav_sbas_geo,
1436 tvb, 4, 1, ENC_NA);
1437 proto_tree_add_item(ubx_nav_sbas_tree, hf_ubx_nav_sbas_mode,
1438 tvb, 5, 1, ENC_NA);
1439 proto_tree_add_item(ubx_nav_sbas_tree, hf_ubx_nav_sbas_sys,
1440 tvb, 6, 1, ENC_NA);
1441 proto_tree_add_bitmask(ubx_nav_sbas_tree, tvb, 7, hf_ubx_nav_sbas_service,
1442 ett_ubx_nav_sbas_service, ubx_nav_sbas_service_fields, ENC_NA);
1443 proto_tree_add_item(ubx_nav_sbas_tree, hf_ubx_nav_sbas_cnt,
1444 tvb, 8, 1, ENC_NA);
1445 proto_tree_add_item(ubx_nav_sbas_tree, hf_ubx_nav_sbas_reserved1,
1446 tvb, 9, 3, ENC_LITTLE_ENDIAN);
1448 for (i = 0; i < num_svs; i++) {
1449 const uint8_t sv_id = tvb_get_uint8(tvb, 12 + 12 * i);
1451 proto_tree *sv_info_tree = proto_tree_add_subtree_format(ubx_nav_sbas_tree,
1452 tvb, 12 + (12 * i), 12, ett_ubx_nav_sbas_sv_info[i], NULL,
1453 "SV ID %3d", sv_id);
1455 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_sv_id,
1456 tvb, 12 + (12 * i), 1, ENC_NA);
1457 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_flags,
1458 tvb, 13 + (12 * i), 1, ENC_NA);
1459 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_udre,
1460 tvb, 14 + (12 * i), 1, ENC_NA);
1461 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_sv_sys,
1462 tvb, 15 + (12 * i), 1, ENC_NA);
1463 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_sv_service,
1464 tvb, 16 + (12 * i), 1, ENC_NA);
1465 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_reserved2,
1466 tvb, 17 + (12 * i), 1, ENC_NA);
1467 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_prc,
1468 tvb, 18 + (12 * i), 2, ENC_LITTLE_ENDIAN);
1469 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_reserved3,
1470 tvb, 20 + (12 * i), 2, ENC_LITTLE_ENDIAN);
1471 proto_tree_add_item(sv_info_tree, hf_ubx_nav_sbas_ic,
1472 tvb, 22 + (12 * i), 2, ENC_LITTLE_ENDIAN);
1475 return tvb_captured_length(tvb);
1478 /* Dissect UBX-NAV-TIMEGPS message */
1479 static int dissect_ubx_nav_timegps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1480 uint32_t itow;
1481 int32_t ftow;
1483 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-TIMEGPS");
1484 col_clear(pinfo->cinfo, COL_INFO);
1486 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_timegps,
1487 tvb, 0, 16, ENC_NA);
1488 proto_tree *ubx_nav_timegps_tree = proto_item_add_subtree(ti, ett_ubx_nav_timegps);
1490 // dissect the registered fields
1491 itow = tvb_get_uint32(tvb, 0, ENC_LITTLE_ENDIAN);
1492 ftow = tvb_get_int32(tvb, 4, ENC_LITTLE_ENDIAN);
1493 ftow = (itow % 1000) * 1000000 + ftow;
1494 itow = itow / 1000;
1495 if (ftow < 0) {
1496 itow = itow - 1;
1497 ftow = 1000000000 + ftow;
1499 proto_tree *tow_tree = proto_tree_add_subtree_format(ubx_nav_timegps_tree,
1500 tvb, 0, 8, ett_ubx_nav_timegps_tow, NULL, "TOW: %d.%09ds", itow, ftow);
1501 proto_tree_add_item(tow_tree, hf_ubx_nav_timegps_itow,
1502 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1503 proto_tree_add_item(tow_tree, hf_ubx_nav_timegps_ftow,
1504 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1506 proto_tree_add_item(ubx_nav_timegps_tree, hf_ubx_nav_timegps_week,
1507 tvb, 8, 2, ENC_LITTLE_ENDIAN);
1508 proto_tree_add_item(ubx_nav_timegps_tree, hf_ubx_nav_timegps_leaps,
1509 tvb, 10, 1, ENC_NA);
1510 proto_tree_add_bitmask(ubx_nav_timegps_tree, tvb, 11,
1511 hf_ubx_nav_timegps_valid, ett_ubx_nav_timegps_valid,
1512 ubx_nav_timegps_valid_fields, ENC_NA);
1513 proto_tree_add_item(ubx_nav_timegps_tree, hf_ubx_nav_timegps_tacc,
1514 tvb, 12, 4, ENC_LITTLE_ENDIAN);
1516 return tvb_captured_length(tvb);
1519 /* Dissect UBX-NAV-TIMEUTC message */
1520 static int dissect_ubx_nav_timeutc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1521 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-TIMEUTC");
1522 col_clear(pinfo->cinfo, COL_INFO);
1524 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_timeutc,
1525 tvb, 0, 20, ENC_NA);
1526 proto_tree *ubx_nav_timeutc_tree = proto_item_add_subtree(ti, ett_ubx_nav_timeutc);
1528 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_itow,
1529 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1530 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_tacc,
1531 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1532 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_nano,
1533 tvb, 8, 4, ENC_LITTLE_ENDIAN);
1534 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_year,
1535 tvb, 12, 2, ENC_LITTLE_ENDIAN);
1536 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_month,
1537 tvb, 14, 1, ENC_NA);
1538 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_day,
1539 tvb, 15, 1, ENC_NA);
1540 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_hour,
1541 tvb, 16, 1, ENC_NA);
1542 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_min,
1543 tvb, 17, 1, ENC_NA);
1544 proto_tree_add_item(ubx_nav_timeutc_tree, hf_ubx_nav_timeutc_sec,
1545 tvb, 18, 1, ENC_NA);
1546 proto_tree_add_bitmask(ubx_nav_timeutc_tree, tvb, 19,
1547 hf_ubx_nav_timeutc_valid, ett_ubx_nav_timeutc_valid,
1548 ubx_nav_timeutc_valid_fields, ENC_NA);
1550 return tvb_captured_length(tvb);
1553 /* Dissect UBX-NAV-VELECEF message */
1554 static int dissect_ubx_nav_velecef(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1555 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-NAV-VELECEF");
1556 col_clear(pinfo->cinfo, COL_INFO);
1558 proto_item *ti = proto_tree_add_item(tree, hf_ubx_nav_velecef,
1559 tvb, 0, 20, ENC_NA);
1560 proto_tree *ubx_nav_velecef_tree = proto_item_add_subtree(ti, ett_ubx_nav_velecef);
1562 // dissect the registered fields
1563 proto_tree_add_item(ubx_nav_velecef_tree, hf_ubx_nav_velecef_itow,
1564 tvb, 0, 4, ENC_LITTLE_ENDIAN);
1565 proto_tree_add_item(ubx_nav_velecef_tree, hf_ubx_nav_velecef_ecefvx,
1566 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1567 proto_tree_add_item(ubx_nav_velecef_tree, hf_ubx_nav_velecef_ecefvy,
1568 tvb, 8, 4, ENC_LITTLE_ENDIAN);
1569 proto_tree_add_item(ubx_nav_velecef_tree, hf_ubx_nav_velecef_ecefvz,
1570 tvb, 12, 4, ENC_LITTLE_ENDIAN);
1571 proto_tree_add_item(ubx_nav_velecef_tree, hf_ubx_nav_velecef_sacc,
1572 tvb, 16, 4, ENC_LITTLE_ENDIAN);
1574 return tvb_captured_length(tvb);
1577 /* Dissect UBX-RXM-MEASX message */
1578 static int dissect_ubx_rxm_measx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1579 uint32_t i, numsv;
1581 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-RXM-MEASX");
1582 col_clear(pinfo->cinfo, COL_INFO);
1584 numsv = tvb_get_uint8(tvb, 34);
1586 proto_item *ti = proto_tree_add_item(tree, hf_ubx_rxm_measx,
1587 tvb, 0, 44 + numsv * 24, ENC_NA);
1588 proto_tree *ubx_rxm_measx_tree = proto_item_add_subtree(ti, ett_ubx_rxm_measx);
1590 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_version,
1591 tvb, 0, 1, ENC_NA);
1592 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_reserved1,
1593 tvb, 1, 3, ENC_LITTLE_ENDIAN);
1594 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_gpstow,
1595 tvb, 4, 4, ENC_LITTLE_ENDIAN);
1596 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_glotow,
1597 tvb, 8, 4, ENC_LITTLE_ENDIAN);
1598 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_bdstow,
1599 tvb, 12, 4, ENC_LITTLE_ENDIAN);
1600 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_reserved2,
1601 tvb, 16, 4, ENC_LITTLE_ENDIAN);
1602 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_qzsstow,
1603 tvb, 20, 4, ENC_LITTLE_ENDIAN);
1604 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_gpstowacc,
1605 tvb, 24, 2, ENC_LITTLE_ENDIAN);
1606 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_glotowacc,
1607 tvb, 26, 2, ENC_LITTLE_ENDIAN);
1608 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_bdstowacc,
1609 tvb, 28, 2, ENC_LITTLE_ENDIAN);
1610 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_reserved3,
1611 tvb, 30, 2, ENC_LITTLE_ENDIAN);
1612 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_qzsstowacc,
1613 tvb, 32, 2, ENC_LITTLE_ENDIAN);
1614 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_numsv,
1615 tvb, 34, 1, ENC_NA);
1616 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_flags_towset,
1617 tvb, 35, 1, ENC_NA);
1618 proto_tree_add_item(ubx_rxm_measx_tree, hf_ubx_rxm_measx_reserved4,
1619 tvb, 36, 8, ENC_LITTLE_ENDIAN);
1621 for (i = 0; i < numsv; i++) {
1622 const uint8_t gnss_id = tvb_get_uint8(tvb, 44 + 24 * i);
1623 const uint8_t sv_id = tvb_get_uint8(tvb, 45 + 24 * i);
1624 const uint8_t cn0 = tvb_get_uint8(tvb, 46 + 24 * i);
1626 proto_tree *meas_tree = proto_tree_add_subtree_format(ubx_rxm_measx_tree,
1627 tvb, 44 + 24 * i, 24, ett_ubx_rxm_measx_meas[i], NULL,
1628 "%-7s / SV ID %3d / C/N0 %d dB-Hz",
1629 val_to_str_const(gnss_id, UBX_GNSS_ID, "Unknown GNSS ID"),
1630 sv_id, cn0);
1632 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_gnssid,
1633 tvb, 44 + 24 * i, 1, ENC_NA);
1634 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_svid,
1635 tvb, 45 + 24 * i, 1, ENC_NA);
1636 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_cn0,
1637 tvb, 46 + 24 * i, 1, ENC_NA);
1638 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_mpathindic,
1639 tvb, 47 + 24 * i, 1, ENC_NA);
1640 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_dopplerms,
1641 tvb, 48 + 24 * i, 4, ENC_LITTLE_ENDIAN);
1642 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_dopplerhz,
1643 tvb, 52 + 24 * i, 4, ENC_LITTLE_ENDIAN);
1644 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_wholechips,
1645 tvb, 56 + 24 * i, 2, ENC_LITTLE_ENDIAN);
1646 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_fracchips,
1647 tvb, 58 + 24 * i, 2, ENC_LITTLE_ENDIAN);
1648 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_codephase,
1649 tvb, 60 + 24 * i, 4, ENC_LITTLE_ENDIAN);
1650 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_intcodephase,
1651 tvb, 64 + 24 * i, 1, ENC_NA);
1652 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_pseurangermserr,
1653 tvb, 65 + 24 * i, 1, ENC_NA);
1654 proto_tree_add_item(meas_tree, hf_ubx_rxm_measx_reserved5,
1655 tvb, 66 + 24 * i, 2, ENC_LITTLE_ENDIAN);
1658 return tvb_captured_length(tvb);
1661 /* Dissect UBX-RXM-RAWX message */
1662 static int dissect_ubx_rxm_rawx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1663 uint32_t i, nummeas;
1665 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-RXM-RAWX");
1666 col_clear(pinfo->cinfo, COL_INFO);
1668 nummeas = tvb_get_uint8(tvb, 11);
1670 proto_item *ti = proto_tree_add_item(tree, hf_ubx_rxm_rawx,
1671 tvb, 0, 16 + nummeas * 32, ENC_NA);
1672 proto_tree *ubx_rxm_rawx_tree = proto_item_add_subtree(ti, ett_ubx_rxm_rawx);
1674 proto_tree_add_item(ubx_rxm_rawx_tree, hf_ubx_rxm_rawx_rcvtow,
1675 tvb, 0, 8, ENC_LITTLE_ENDIAN);
1676 proto_tree_add_item(ubx_rxm_rawx_tree, hf_ubx_rxm_rawx_week,
1677 tvb, 8, 2, ENC_LITTLE_ENDIAN);
1678 proto_tree_add_item(ubx_rxm_rawx_tree, hf_ubx_rxm_rawx_leaps,
1679 tvb, 10, 1, ENC_NA);
1680 proto_tree_add_item(ubx_rxm_rawx_tree, hf_ubx_rxm_rawx_nummeas,
1681 tvb, 11, 1, ENC_NA);
1682 proto_tree_add_bitmask(ubx_rxm_rawx_tree, tvb, 12,
1683 hf_ubx_rxm_rawx_recstat, ett_ubx_rxm_rawx_recstat,
1684 ubx_rxm_rawx_recstat_fields, ENC_NA);
1685 proto_tree_add_item(ubx_rxm_rawx_tree, hf_ubx_rxm_rawx_version,
1686 tvb, 13, 1, ENC_NA);
1687 proto_tree_add_item(ubx_rxm_rawx_tree, hf_ubx_rxm_rawx_reserved1,
1688 tvb, 14, 2, ENC_LITTLE_ENDIAN);
1690 for (i = 0; i < nummeas; i++) {
1691 const uint8_t gnss_id = tvb_get_uint8(tvb, 36 + 32 * i);
1692 const uint8_t sv_id = tvb_get_uint8(tvb, 37 + 32 * i);
1693 const uint8_t cn0 = tvb_get_uint8(tvb, 42 + 32 * i);
1695 proto_tree *meas_tree = proto_tree_add_subtree_format(ubx_rxm_rawx_tree,
1696 tvb, 16 + 32 * i, 32, ett_ubx_rxm_rawx_meas[i], NULL,
1697 "%-7s / SV ID %3d / C/N0 %d dB-Hz",
1698 val_to_str_const(gnss_id, UBX_GNSS_ID, "Unknown GNSS ID"),
1699 sv_id, cn0);
1701 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_prmes,
1702 tvb, 16 + (32 * i), 8, ENC_LITTLE_ENDIAN);
1703 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_cpmes,
1704 tvb, 24 + (32 * i), 8, ENC_LITTLE_ENDIAN);
1705 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_domes,
1706 tvb, 32 + (32 * i), 4, ENC_LITTLE_ENDIAN);
1707 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_gnssid,
1708 tvb, 36 + (32 * i), 1, ENC_NA);
1709 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_svid,
1710 tvb, 37 + (32 * i), 1, ENC_NA);
1711 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_sigid,
1712 tvb, 38 + (32 * i), 1, ENC_NA);
1713 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_freqid,
1714 tvb, 39 + (32 * i), 1, ENC_NA);
1715 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_locktime,
1716 tvb, 40 + (32 * i), 2, ENC_LITTLE_ENDIAN);
1717 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_cn0,
1718 tvb, 42 + (32 * i), 1, ENC_NA);
1719 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_prstdev,
1720 tvb, 43 + (32 * i), 1, ENC_NA);
1721 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_cpstdev,
1722 tvb, 44 + (32 * i), 1, ENC_NA);
1723 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_dostdev,
1724 tvb, 45 + (32 * i), 1, ENC_NA);
1725 proto_tree_add_bitmask(meas_tree,
1726 tvb, 46 + (32 * i),
1727 hf_ubx_rxm_rawx_trkstat, ett_ubx_rxm_rawx_trkstat,
1728 ubx_rxm_rawx_trkstat_fields, ENC_NA);
1729 proto_tree_add_item(meas_tree, hf_ubx_rxm_rawx_reserved2,
1730 tvb, 47 + (32 * i), 1, ENC_NA);
1733 return tvb_captured_length(tvb);
1736 /* Dissect UBX-RXM-SFRBX message */
1737 static int dissect_ubx_rxm_sfrbx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
1738 tvbuff_t *next_tvb;
1739 uint8_t *buf;
1740 uint8_t i;
1741 uint32_t gnssid, numwords, version;
1743 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UBX-RXM-SFRBX");
1744 col_clear(pinfo->cinfo, COL_INFO);
1746 // get length of the payload and protocol version
1747 numwords = tvb_get_uint8(tvb, 4);
1748 version = tvb_get_uint8(tvb, 6);
1750 proto_item *ti = proto_tree_add_item(tree, hf_ubx_rxm_sfrbx,
1751 tvb, 0, 8 + numwords * 4, ENC_NA);
1752 proto_tree *ubx_rxm_sfrbx_tree = proto_item_add_subtree(ti, ett_ubx_rxm_sfrbx);
1754 proto_tree_add_item_ret_uint(ubx_rxm_sfrbx_tree, hf_ubx_rxm_sfrbx_gnssid,
1755 tvb, 0, 1, ENC_NA, &gnssid);
1756 proto_tree_add_item(ubx_rxm_sfrbx_tree, hf_ubx_rxm_sfrbx_svid,
1757 tvb, 1, 1, ENC_NA);
1758 switch(version) {
1759 case 0x01: proto_tree_add_item(ubx_rxm_sfrbx_tree,
1760 hf_ubx_rxm_sfrbx_reserved1, tvb, 2, 1, ENC_NA);
1761 break;
1762 case 0x02: proto_tree_add_item(ubx_rxm_sfrbx_tree,
1763 hf_ubx_rxm_sfrbx_sigid, tvb, 2, 1, ENC_NA);
1764 break;
1766 proto_tree_add_item(ubx_rxm_sfrbx_tree, hf_ubx_rxm_sfrbx_freqid,
1767 tvb, 3, 1, ENC_NA);
1768 proto_tree_add_item(ubx_rxm_sfrbx_tree, hf_ubx_rxm_sfrbx_numwords,
1769 tvb, 4, 1, ENC_NA);
1770 switch(version) {
1771 case 0x01: proto_tree_add_item(ubx_rxm_sfrbx_tree,
1772 hf_ubx_rxm_sfrbx_reserved2, tvb, 5, 1, ENC_NA);
1773 break;
1774 case 0x02: proto_tree_add_item(ubx_rxm_sfrbx_tree,
1775 hf_ubx_rxm_sfrbx_chn, tvb, 5, 1, ENC_NA);
1776 break;
1778 proto_tree_add_item(ubx_rxm_sfrbx_tree, hf_ubx_rxm_sfrbx_version,
1779 tvb, 6, 1, ENC_NA);
1780 switch(version) {
1781 case 0x01: proto_tree_add_item(ubx_rxm_sfrbx_tree,
1782 hf_ubx_rxm_sfrbx_reserved3, tvb, 7, 1, ENC_NA);
1783 break;
1784 case 0x02: proto_tree_add_item(ubx_rxm_sfrbx_tree,
1785 hf_ubx_rxm_sfrbx_reserved1, tvb, 7, 1, ENC_NA);
1786 break;
1788 proto_tree_add_item(ubx_rxm_sfrbx_tree, hf_ubx_rxm_sfrbx_dwrd,
1789 tvb, 8, numwords * 4, ENC_NA);
1791 if (gnssid == GNSS_ID_GPS) {
1792 // send the GPS nav msg (preprocessed by UBX) to the next dissector
1793 next_tvb = tvb_new_subset_length(tvb, 8, 4 * numwords);
1795 else {
1796 // UBX-RXM-SFRBX has the nav msg encoded in little endian. As this is not
1797 // convenient for dissection, map to big endian and add as new data source.
1798 buf = wmem_alloc(pinfo->pool, numwords * 4);
1799 for (i = 0; i < numwords; i++) {
1800 phton32(buf + 4 * i, tvb_get_uint32(tvb, 8 + i * 4, ENC_LITTLE_ENDIAN));
1802 next_tvb = tvb_new_child_real_data(tvb, (uint8_t *)buf, numwords * 4, numwords * 4);
1803 add_new_data_source(pinfo, next_tvb, "GNSS navigation message");
1806 // send the nav msg to the next dissector
1807 if (!dissector_try_uint_with_data(ubx_gnssid_dissector_table, gnssid, next_tvb, pinfo, tree, true, (void *)tvb_get_ptr(tvb, 1, 1))) {
1808 call_data_dissector(next_tvb, pinfo, tree);
1811 return tvb_captured_length(tvb);
1814 void proto_register_ubx(void) {
1815 static hf_register_info hf[] = {
1816 {&hf_ubx_preamble,
1817 {"Preamble", "ubx.preamble",
1818 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1819 {&hf_ubx_msg_class_id,
1820 {"Msg Class & ID", "ubx.msg_class_id",
1821 FT_UINT16, BASE_HEX, VALS(UBX_MSG_CLASS_ID), 0x0, NULL, HFILL}},
1822 {&hf_ubx_payload_len,
1823 {"Payload Length", "ubx.payload_len",
1824 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1825 {&hf_ubx_chksum,
1826 {"Checksum", "ubx.checksum",
1827 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1829 // ACK-ACK
1830 {&hf_ubx_ack_ack,
1831 {"UBX-ACK-ACK", "ubx.ack.ack",
1832 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1833 {&hf_ubx_ack_ack_msg_class_id,
1834 {"Msg Class & ID", "ubx.ack.ack.msg_class_id",
1835 FT_UINT16, BASE_HEX, VALS(UBX_MSG_CLASS_ID), 0x0, NULL, HFILL}},
1837 // ACK-NAK
1838 {&hf_ubx_ack_nak,
1839 {"UBX-ACK-NAK", "ubx.ack.nak",
1840 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1841 {&hf_ubx_ack_nak_msg_class_id,
1842 {"Msg Class & ID", "ubx.ack.nak.msg_class_id",
1843 FT_UINT16, BASE_HEX, VALS(UBX_MSG_CLASS_ID), 0x0, NULL, HFILL}},
1845 // CFG-GNSS
1846 {&hf_ubx_cfg_gnss,
1847 {"UBX-CFG-GNSS", "ubx.cfg.gnss",
1848 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1849 {&hf_ubx_cfg_gnss_version,
1850 {"Version", "ubx.cfg.gnss.version",
1851 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1852 {&hf_ubx_cfg_gnss_numtrkchhw,
1853 {"Number of tracking channels available in hardware", "ubx.cfg.gnss.numtrkchhw",
1854 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1855 {&hf_ubx_cfg_gnss_numtrkchuse,
1856 {"Number of tracking channels to use", "ubx.cfg.gnss.numtrkchuse",
1857 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1858 {&hf_ubx_cfg_gnss_numconfigblocks,
1859 {"Number of configuration blocks following", "ubx.cfg.gnss.numconfigblocks",
1860 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1861 {&hf_ubx_cfg_gnss_blk_gnssid,
1862 {"GNSS ID", "ubx.cfg.gnss.gnssid",
1863 FT_UINT8, BASE_DEC, VALS(UBX_GNSS_ID), 0x0, NULL, HFILL}},
1864 {&hf_ubx_cfg_gnss_blk_restrkch,
1865 {"Number of reserved (minimum) tracking channels", "ubx.cfg.gnss.restrkch",
1866 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1867 {&hf_ubx_cfg_gnss_blk_maxtrkch,
1868 {"Maximum number of tracking channels", "ubx.cfg.gnss.maxtrkch",
1869 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1870 {&hf_ubx_cfg_gnss_blk_reserved1,
1871 {"Reserved", "ubx.cfg.gnss.reserved1",
1872 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1873 {&hf_ubx_cfg_gnss_blk_enable,
1874 {"Enabled", "ubx.cfg.gnss.enabled",
1875 FT_UINT32, BASE_HEX, NULL, 0x00000001, NULL, HFILL}},
1876 {&hf_ubx_cfg_gnss_blk_sigcfgmask,
1877 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1878 FT_UINT32, BASE_HEX, NULL, 0x00ff0000, NULL, HFILL}},
1879 {&hf_ubx_cfg_gnss_blk_gps_sigcfgmask,
1880 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1881 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_GPS_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1882 {&hf_ubx_cfg_gnss_blk_sbas_sigcfgmask,
1883 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1884 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_SBAS_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1885 {&hf_ubx_cfg_gnss_blk_gal_sigcfgmask,
1886 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1887 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_GAL_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1888 {&hf_ubx_cfg_gnss_blk_bds_sigcfgmask,
1889 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1890 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_BDS_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1891 {&hf_ubx_cfg_gnss_blk_imes_sigcfgmask,
1892 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1893 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_IMES_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1894 {&hf_ubx_cfg_gnss_blk_qzss_sigcfgmask,
1895 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1896 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_QZSS_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1897 {&hf_ubx_cfg_gnss_blk_glo_sigcfgmask,
1898 {"Signal configuration mask", "ubx.cfg.gnss.sigcfgmask",
1899 FT_UINT32, BASE_HEX, VALS(UBX_CFG_GNSS_GLO_SIGCFGMASK), 0x00ff0000, NULL, HFILL}},
1901 // CFG-SBAS
1902 {&hf_ubx_cfg_sbas,
1903 {"UBX-CFG-SBAS", "ubx.cfg.sbas",
1904 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1905 {&hf_ubx_cfg_sbas_mode,
1906 {"SBAS mode", "ubx.cfg.sbas.mode",
1907 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1908 {&hf_ubx_cfg_sbas_mode_enabled,
1909 {"SBAS enabled", "ubx.cfg.sbas.mode.enabled",
1910 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
1911 {&hf_ubx_cfg_sbas_mode_test,
1912 {"SBAS testbed", "ubx.cfg.sbas.mode.test",
1913 FT_UINT8, BASE_HEX, VALS(UBX_SBAS_TESTBED), 0x02, NULL, HFILL}},
1914 {&hf_ubx_cfg_sbas_usage_range,
1915 {"Use SBAS GEOs as a ranging source (for navigation)", "ubx.cfg.sbas.usage.range",
1916 FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL}},
1917 {&hf_ubx_cfg_sbas_usage_diffcorr,
1918 {"Use SBAS differential corrections", "ubx.cfg.sbas.usage.diffcorr",
1919 FT_UINT8, BASE_HEX, NULL, 0x02, NULL, HFILL}},
1920 {&hf_ubx_cfg_sbas_usage_integrity,
1921 {"Use SBAS integrity information", "ubx.cfg.sbas.usage.integrity",
1922 FT_UINT8, BASE_HEX, NULL, 0x04, NULL, HFILL}},
1923 {&hf_ubx_cfg_sbas_max_sbas,
1924 {"Maximum number of SBAS prioritized tracking channels to use", "ubx.cfg.sbas.maxsbas",
1925 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1926 {&hf_ubx_cfg_sbas_scanmode_prn158,
1927 {"PRN 158", "ubx.cfg.sbas.scanmode.prn158",
1928 FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL}},
1929 {&hf_ubx_cfg_sbas_scanmode_prn157,
1930 {"PRN 157", "ubx.cfg.sbas.scanmode.prn157",
1931 FT_UINT8, BASE_HEX, NULL, 0x20, NULL, HFILL}},
1932 {&hf_ubx_cfg_sbas_scanmode_prn156,
1933 {"PRN 156", "ubx.cfg.sbas.scanmode.prn156",
1934 FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL}},
1935 {&hf_ubx_cfg_sbas_scanmode_prn155,
1936 {"PRN 155", "ubx.cfg.sbas.scanmode.prn155",
1937 FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL}},
1938 {&hf_ubx_cfg_sbas_scanmode_prn154,
1939 {"PRN 154", "ubx.cfg.sbas.scanmode.prn154",
1940 FT_UINT8, BASE_HEX, NULL, 0x04, NULL, HFILL}},
1941 {&hf_ubx_cfg_sbas_scanmode_prn153,
1942 {"PRN 153", "ubx.cfg.sbas.scanmode.prn153",
1943 FT_UINT8, BASE_HEX, NULL, 0x02, NULL, HFILL}},
1944 {&hf_ubx_cfg_sbas_scanmode_prn152,
1945 {"PRN 152", "ubx.cfg.sbas.scanmode.prn152",
1946 FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL}},
1947 {&hf_ubx_cfg_sbas_scanmode_prn151,
1948 {"PRN 151", "ubx.cfg.sbas.scanmode.prn151",
1949 FT_UINT32, BASE_HEX, NULL, 0x80000000, NULL, HFILL}},
1950 {&hf_ubx_cfg_sbas_scanmode_prn150,
1951 {"PRN 150", "ubx.cfg.sbas.scanmode.prn150",
1952 FT_UINT32, BASE_HEX, NULL, 0x40000000, NULL, HFILL}},
1953 {&hf_ubx_cfg_sbas_scanmode_prn149,
1954 {"PRN 149", "ubx.cfg.sbas.scanmode.prn149",
1955 FT_UINT32, BASE_HEX, NULL, 0x20000000, NULL, HFILL}},
1956 {&hf_ubx_cfg_sbas_scanmode_prn148,
1957 {"PRN 148", "ubx.cfg.sbas.scanmode.prn148",
1958 FT_UINT32, BASE_HEX, NULL, 0x10000000, NULL, HFILL}},
1959 {&hf_ubx_cfg_sbas_scanmode_prn147,
1960 {"PRN 147", "ubx.cfg.sbas.scanmode.prn147",
1961 FT_UINT32, BASE_HEX, NULL, 0x08000000, NULL, HFILL}},
1962 {&hf_ubx_cfg_sbas_scanmode_prn146,
1963 {"PRN 146", "ubx.cfg.sbas.scanmode.prn146",
1964 FT_UINT32, BASE_HEX, NULL, 0x04000000, NULL, HFILL}},
1965 {&hf_ubx_cfg_sbas_scanmode_prn145,
1966 {"PRN 145", "ubx.cfg.sbas.scanmode.prn145",
1967 FT_UINT32, BASE_HEX, NULL, 0x02000000, NULL, HFILL}},
1968 {&hf_ubx_cfg_sbas_scanmode_prn144,
1969 {"PRN 144", "ubx.cfg.sbas.scanmode.prn144",
1970 FT_UINT32, BASE_HEX, NULL, 0x01000000, NULL, HFILL}},
1971 {&hf_ubx_cfg_sbas_scanmode_prn143,
1972 {"PRN 143", "ubx.cfg.sbas.scanmode.prn143",
1973 FT_UINT32, BASE_HEX, NULL, 0x00800000, NULL, HFILL}},
1974 {&hf_ubx_cfg_sbas_scanmode_prn142,
1975 {"PRN 142", "ubx.cfg.sbas.scanmode.prn142",
1976 FT_UINT32, BASE_HEX, NULL, 0x00400000, NULL, HFILL}},
1977 {&hf_ubx_cfg_sbas_scanmode_prn141,
1978 {"PRN 141", "ubx.cfg.sbas.scanmode.prn141",
1979 FT_UINT32, BASE_HEX, NULL, 0x00200000, NULL, HFILL}},
1980 {&hf_ubx_cfg_sbas_scanmode_prn140,
1981 {"PRN 140", "ubx.cfg.sbas.scanmode.prn140",
1982 FT_UINT32, BASE_HEX, NULL, 0x00100000, NULL, HFILL}},
1983 {&hf_ubx_cfg_sbas_scanmode_prn139,
1984 {"PRN 139", "ubx.cfg.sbas.scanmode.prn139",
1985 FT_UINT32, BASE_HEX, NULL, 0x00080000, NULL, HFILL}},
1986 {&hf_ubx_cfg_sbas_scanmode_prn138,
1987 {"PRN 138", "ubx.cfg.sbas.scanmode.prn138",
1988 FT_UINT32, BASE_HEX, NULL, 0x00040000, NULL, HFILL}},
1989 {&hf_ubx_cfg_sbas_scanmode_prn137,
1990 {"PRN 137", "ubx.cfg.sbas.scanmode.prn137",
1991 FT_UINT32, BASE_HEX, NULL, 0x00020000, NULL, HFILL}},
1992 {&hf_ubx_cfg_sbas_scanmode_prn136,
1993 {"PRN 136", "ubx.cfg.sbas.scanmode.prn136",
1994 FT_UINT32, BASE_HEX, NULL, 0x00010000, NULL, HFILL}},
1995 {&hf_ubx_cfg_sbas_scanmode_prn135,
1996 {"PRN 135", "ubx.cfg.sbas.scanmode.prn135",
1997 FT_UINT32, BASE_HEX, NULL, 0x00008000, NULL, HFILL}},
1998 {&hf_ubx_cfg_sbas_scanmode_prn134,
1999 {"PRN 134", "ubx.cfg.sbas.scanmode.prn134",
2000 FT_UINT32, BASE_HEX, NULL, 0x00004000, NULL, HFILL}},
2001 {&hf_ubx_cfg_sbas_scanmode_prn133,
2002 {"PRN 133", "ubx.cfg.sbas.scanmode.prn133",
2003 FT_UINT32, BASE_HEX, NULL, 0x00002000, NULL, HFILL}},
2004 {&hf_ubx_cfg_sbas_scanmode_prn132,
2005 {"PRN 132", "ubx.cfg.sbas.scanmode.prn132",
2006 FT_UINT32, BASE_HEX, NULL, 0x00001000, NULL, HFILL}},
2007 {&hf_ubx_cfg_sbas_scanmode_prn131,
2008 {"PRN 131", "ubx.cfg.sbas.scanmode.prn131",
2009 FT_UINT32, BASE_HEX, NULL, 0x00000800, NULL, HFILL}},
2010 {&hf_ubx_cfg_sbas_scanmode_prn130,
2011 {"PRN 130", "ubx.cfg.sbas.scanmode.prn130",
2012 FT_UINT32, BASE_HEX, NULL, 0x00000400, NULL, HFILL}},
2013 {&hf_ubx_cfg_sbas_scanmode_prn129,
2014 {"PRN 129", "ubx.cfg.sbas.scanmode.prn129",
2015 FT_UINT32, BASE_HEX, NULL, 0x00000200, NULL, HFILL}},
2016 {&hf_ubx_cfg_sbas_scanmode_prn128,
2017 {"PRN 128", "ubx.cfg.sbas.scanmode.prn128",
2018 FT_UINT32, BASE_HEX, NULL, 0x00000100, NULL, HFILL}},
2019 {&hf_ubx_cfg_sbas_scanmode_prn127,
2020 {"PRN 127", "ubx.cfg.sbas.scanmode.prn127",
2021 FT_UINT32, BASE_HEX, NULL, 0x00000080, NULL, HFILL}},
2022 {&hf_ubx_cfg_sbas_scanmode_prn126,
2023 {"PRN 126", "ubx.cfg.sbas.scanmode.prn126",
2024 FT_UINT32, BASE_HEX, NULL, 0x00000040, NULL, HFILL}},
2025 {&hf_ubx_cfg_sbas_scanmode_prn125,
2026 {"PRN 125", "ubx.cfg.sbas.scanmode.prn125",
2027 FT_UINT32, BASE_HEX, NULL, 0x00000020, NULL, HFILL}},
2028 {&hf_ubx_cfg_sbas_scanmode_prn124,
2029 {"PRN 124", "ubx.cfg.sbas.scanmode.prn124",
2030 FT_UINT32, BASE_HEX, NULL, 0x00000010, NULL, HFILL}},
2031 {&hf_ubx_cfg_sbas_scanmode_prn123,
2032 {"PRN 123", "ubx.cfg.sbas.scanmode.prn123",
2033 FT_UINT32, BASE_HEX, NULL, 0x00000008, NULL, HFILL}},
2034 {&hf_ubx_cfg_sbas_scanmode_prn122,
2035 {"PRN 122", "ubx.cfg.sbas.scanmode.prn122",
2036 FT_UINT32, BASE_HEX, NULL, 0x00000004, NULL, HFILL}},
2037 {&hf_ubx_cfg_sbas_scanmode_prn121,
2038 {"PRN 121", "ubx.cfg.sbas.scanmode.prn121",
2039 FT_UINT32, BASE_HEX, NULL, 0x00000002, NULL, HFILL}},
2040 {&hf_ubx_cfg_sbas_scanmode_prn120,
2041 {"PRN 120", "ubx.cfg.sbas.scanmode.prn120",
2042 FT_UINT32, BASE_HEX, NULL, 0x00000001, NULL, HFILL}},
2044 // NAV-DOP
2045 {&hf_ubx_nav_dop,
2046 {"UBX-NAV-DOP", "ubx.nav.dop",
2047 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2048 {&hf_ubx_nav_dop_itow,
2049 {"iTOW", "ubx.nav.dop.itow",
2050 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2051 {&hf_ubx_nav_dop_gdop,
2052 {"Geometric DOP", "ubx.nav.dop.gdop",
2053 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2054 {&hf_ubx_nav_dop_pdop,
2055 {"Position DOP", "ubx.nav.dop.pdop",
2056 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2057 {&hf_ubx_nav_dop_tdop,
2058 {"Time DOP", "ubx.nav.dop.tdop",
2059 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2060 {&hf_ubx_nav_dop_vdop,
2061 {"Vertical DOP", "ubx.nav.dop.vdop",
2062 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2063 {&hf_ubx_nav_dop_hdop,
2064 {"Horizontal DOP", "ubx.nav.dop.hdop",
2065 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2066 {&hf_ubx_nav_dop_ndop,
2067 {"Northing DOP", "ubx.nav.dop.ndop",
2068 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2069 {&hf_ubx_nav_dop_edop,
2070 {"Easting DOP", "ubx.nav.dop.edop",
2071 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2073 // NAV-EOE
2074 {&hf_ubx_nav_eoe,
2075 {"UBX-NAV-EOE", "ubx.nav.eoe",
2076 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2077 {&hf_ubx_nav_eoe_itow,
2078 {"iTOW", "ubx.nav.eoe.itow",
2079 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2081 // NAV-ODO
2082 {&hf_ubx_nav_odo,
2083 {"UBX-NAV-ODO", "ubx.nav.odo",
2084 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2085 {&hf_ubx_nav_odo_version,
2086 {"Version", "ubx.nav.odo.version",
2087 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2088 {&hf_ubx_nav_odo_reserved1,
2089 {"Reserved", "ubx.nav.odo.reserved1",
2090 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2091 {&hf_ubx_nav_odo_itow,
2092 {"iTOW", "ubx.nav.odo.itow",
2093 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2094 {&hf_ubx_nav_odo_distance,
2095 {"Ground distance since last reset", "ubx.nav.odo.distance",
2096 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_meter_meters), 0x0, NULL, HFILL}},
2097 {&hf_ubx_nav_odo_totaldistance,
2098 {"Total cumulative ground distance", "ubx.nav.odo.totaldistance",
2099 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_meter_meters), 0x0, NULL, HFILL}},
2100 {&hf_ubx_nav_odo_distancestd,
2101 {"Ground distance accuracy (1-sigma)", "ubx.nav.odo.distancestd",
2102 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_meter_meters), 0x0, NULL, HFILL}},
2104 // NAV-POSECEF
2105 {&hf_ubx_nav_posecef,
2106 {"UBX-NAV-POSECEF", "ubx.nav.posecef",
2107 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2108 {&hf_ubx_nav_posecef_itow,
2109 {"iTOW", "ubx.nav.posecef.itow",
2110 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2111 {&hf_ubx_nav_posecef_ecefx,
2112 {"ECEF X coordinate", "ubx.nav.posecef.ecefx",
2113 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_centimeters), 0x0, NULL, HFILL}},
2114 {&hf_ubx_nav_posecef_ecefy,
2115 {"ECEF Y coordinate", "ubx.nav.posecef.ecefy",
2116 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_centimeters), 0x0, NULL, HFILL}},
2117 {&hf_ubx_nav_posecef_ecefz,
2118 {"ECEF Z coordinate", "ubx.nav.posecef.ecefz",
2119 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_centimeters), 0x0, NULL, HFILL}},
2120 {&hf_ubx_nav_posecef_pacc,
2121 {"Position accuracy estimate", "ubx.nav.posecef.pacc",
2122 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_centimeters), 0x0, NULL, HFILL}},
2124 // NAV-PVT
2125 {&hf_ubx_nav_pvt,
2126 {"UBX-NAV-PVT", "ubx.nav.pvt",
2127 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2128 {&hf_ubx_nav_pvt_itow,
2129 {"iTOW", "ubx.nav.pvt.itow",
2130 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2131 {&hf_ubx_nav_pvt_year,
2132 {"Year", "ubx.nav.pvt.year",
2133 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2134 {&hf_ubx_nav_pvt_month,
2135 {"Month", "ubx.nav.pvt.month",
2136 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2137 {&hf_ubx_nav_pvt_day,
2138 {"Day", "ubx.nav.pvt.day",
2139 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2140 {&hf_ubx_nav_pvt_hour,
2141 {"Hour", "ubx.nav.pvt.hour",
2142 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2143 {&hf_ubx_nav_pvt_min,
2144 {"Minute", "ubx.nav.pvt.min",
2145 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2146 {&hf_ubx_nav_pvt_sec,
2147 {"Seconds", "ubx.nav.pvt.sec",
2148 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2149 {&hf_ubx_nav_pvt_valid,
2150 {"Validity flags", "ubx.nav.pvt.valid",
2151 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2152 {&hf_ubx_nav_pvt_validmag,
2153 {"Valid magnetic declination", "ubx.nav.pvt.valid.validmag",
2154 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}},
2155 {&hf_ubx_nav_pvt_fullyresolved,
2156 {"UTC time of day fully resolved", "ubx.nav.pvt.valid.fullyresolved",
2157 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}},
2158 {&hf_ubx_nav_pvt_validtime,
2159 {"valid UTC time of day", "ubx.nav.pvt.valid.validtime",
2160 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2161 {&hf_ubx_nav_pvt_validdate,
2162 {"valid UTC date", "ubx.nav.pvt.valid.validdate",
2163 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2164 {&hf_ubx_nav_pvt_tacc,
2165 {"Time accuracy estimate", "ubx.nav.pvt.tacc",
2166 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL}},
2167 {&hf_ubx_nav_pvt_nano,
2168 {"UTC fraction of second", "ubx.nav.pvt.nano",
2169 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL}},
2170 {&hf_ubx_nav_pvt_fixtype,
2171 {"GNSS fix type", "ubx.nav.pvt.fixtype",
2172 FT_UINT8, BASE_DEC, VALS(UBX_GNSS_FIX_TYPE), 0x0, NULL, HFILL}},
2173 {&hf_ubx_nav_pvt_flags,
2174 {"Fix status flags", "ubx.nav.pvt.flags",
2175 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2176 {&hf_ubx_nav_pvt_headvehvalid,
2177 {"heading of vehicle is valid", "ubx.nav.pvt.flags.headvehvalid",
2178 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2179 {&hf_ubx_nav_pvt_psmstate,
2180 {"PSM state", "ubx.nav.pvt.flags.psmstate",
2181 FT_UINT8, BASE_DEC, NULL, 0x1c, NULL, HFILL}},
2182 {&hf_ubx_nav_pvt_diffsoln,
2183 {"differential corrections were applied", "ubx.nav.pvt.flags.diffsoln",
2184 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2185 {&hf_ubx_nav_pvt_gnssfixok,
2186 {"valid fix", "ubx.nav.pvt.flags.gnssfixok",
2187 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2188 {&hf_ubx_nav_pvt_flags2,
2189 {"Additional flags", "ubx.nav.pvt.flags2",
2190 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2191 {&hf_ubx_nav_pvt_confirmedtime,
2192 {"UTC time of day could be confirmed", "ubx.nav.pvt.flags2.confirmedtime",
2193 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2194 {&hf_ubx_nav_pvt_confirmeddate,
2195 {"UTC date could be validated", "ubx.nav.pvt.flags2.confirmeddate",
2196 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}},
2197 {&hf_ubx_nav_pvt_confirmedavai,
2198 {"information about UTC date and time of day validity confirmation is available", "ubx.nav.pvt.flags2.confirmedavai",
2199 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2200 {&hf_ubx_nav_pvt_numsv,
2201 {"Number of satellite vehicles used in Nav solution", "ubx.nav.pvt.numsv",
2202 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2203 {&hf_ubx_nav_pvt_lon,
2204 {"Longitude", "ubx.nav.pvt.lon",
2205 FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_lat_lon), 0x0, NULL, HFILL}},
2206 {&hf_ubx_nav_pvt_lat,
2207 {"Latitude", "ubx.nav.pvt.lat",
2208 FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_lat_lon), 0x0, NULL, HFILL}},
2209 {&hf_ubx_nav_pvt_height,
2210 {"Height above ellipsoid", "ubx.nav.pvt.height",
2211 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_millimeters), 0x0, NULL, HFILL}},
2212 {&hf_ubx_nav_pvt_hmsl,
2213 {"Height above mean sea level", "ubx.nav.pvt.hmsl",
2214 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_millimeters), 0x0, NULL, HFILL}},
2215 {&hf_ubx_nav_pvt_hacc,
2216 {"Horizontal accuracy estimate", "ubx.nav.pvt.hacc",
2217 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_millimeters), 0x0, NULL, HFILL}},
2218 {&hf_ubx_nav_pvt_vacc,
2219 {"Vertical accuracy estimate", "ubx.nav.pvt.vacc",
2220 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_millimeters), 0x0, NULL, HFILL}},
2221 {&hf_ubx_nav_pvt_veln,
2222 {"NED north velocity", "ubx.nav.pvt.veln",
2223 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_mm_s), 0x0, NULL, HFILL}},
2224 {&hf_ubx_nav_pvt_vele,
2225 {"NED east velocity", "ubx.nav.pvt.vele",
2226 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_mm_s), 0x0, NULL, HFILL}},
2227 {&hf_ubx_nav_pvt_veld,
2228 {"NED down velocity", "ubx.nav.pvt.veld",
2229 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_mm_s), 0x0, NULL, HFILL}},
2230 {&hf_ubx_nav_pvt_gspeed,
2231 {"Ground speed (2-D)", "ubx.nav.pvt.gspeed",
2232 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_mm_s), 0x0, NULL, HFILL}},
2233 {&hf_ubx_nav_pvt_headmot,
2234 {"Heading of motion (2-D)", "ubx.nav.pvt.headmot",
2235 FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_heading), 0x0, NULL, HFILL}},
2236 {&hf_ubx_nav_pvt_sacc,
2237 {"Speed accuracy estimate", "ubx.nav.pvt.sacc",
2238 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_mm_s), 0x0, NULL, HFILL}},
2239 {&hf_ubx_nav_pvt_headacc,
2240 {"Heading accuracy estimate", "ubx.nav.pvt.headacc",
2241 FT_UINT32, BASE_CUSTOM, CF_FUNC(&fmt_heading_acc), 0x0, NULL, HFILL}},
2242 {&hf_ubx_nav_pvt_pdop,
2243 {"Position DOP", "ubx.nav.pvt.pdop",
2244 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_dop), 0x0, NULL, HFILL}},
2245 {&hf_ubx_nav_pvt_lastcorrectionage,
2246 {"Age of the most recently received differential correction", "ubx.nav.pvt.lastcorrectionage",
2247 FT_UINT16, BASE_DEC, VALS(UBX_LAST_CORRECTION_AGE), 0x001e, NULL, HFILL}},
2248 {&hf_ubx_nav_pvt_invalidllh,
2249 {"Invalid lon, lat, height, and hMSL", "ubx.nav.pvt.invalidllh",
2250 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL}},
2251 {&hf_ubx_nav_pvt_reserved1,
2252 {"Reserved 1", "ubx.nav.pvt.reserved1",
2253 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2254 {&hf_ubx_nav_pvt_headveh,
2255 {"Heading of vehicle (2-D)", "ubx.nav.pvt.headveh",
2256 FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_heading), 0x0, NULL, HFILL}},
2257 {&hf_ubx_nav_pvt_magdec,
2258 {"Magnetic declination", "ubx.nav.pvt.magdec",
2259 FT_INT16, BASE_CUSTOM, CF_FUNC(&fmt_decl), 0x0, NULL, HFILL}},
2260 {&hf_ubx_nav_pvt_magacc,
2261 {"Magnetic declination accuracy", "ubx.nav.pvt.magacc",
2262 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_decl_acc), 0x0, NULL, HFILL}},
2264 // NAV-SAT
2265 {&hf_ubx_nav_sat,
2266 {"UBX-NAV-SAT", "ubx.nav.sat",
2267 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2268 {&hf_ubx_nav_sat_itow,
2269 {"iTOW", "ubx.nav.sat.itow",
2270 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2271 {&hf_ubx_nav_sat_version,
2272 {"Version", "ubx.nav.sat.version",
2273 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2274 {&hf_ubx_nav_sat_num_svs,
2275 {"Number of satellites", "ubx.nav.sat.num_svs",
2276 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2277 {&hf_ubx_nav_sat_reserved1,
2278 {"Reserved", "ubx.nav.sat.reserved1",
2279 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2280 {&hf_ubx_nav_sat_gnss_id,
2281 {"GNSS ID", "ubx.nav.sat.gnss_id",
2282 FT_UINT8, BASE_DEC, VALS(UBX_GNSS_ID), 0x0, NULL, HFILL}},
2283 {&hf_ubx_nav_sat_sv_id,
2284 {"SV ID", "ubx.nav.sat.sv_id",
2285 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2286 {&hf_ubx_nav_sat_cn0,
2287 {"C/N0", "ubx.nav.sat.cn0",
2288 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_dbhz), 0x0, NULL, HFILL}},
2289 {&hf_ubx_nav_sat_elev,
2290 {"Elevation", "ubx.nav.sat.elev",
2291 FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2292 {&hf_ubx_nav_sat_azim,
2293 {"Azimuth", "ubx.nav.sat.azim",
2294 FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2295 {&hf_ubx_nav_sat_pr_res,
2296 {"Pseudorange residual", "ubx.nav.sat.pr_res",
2297 FT_INT16, BASE_CUSTOM, CF_FUNC(&fmt_pr_res), 0x0, NULL, HFILL}},
2298 {&hf_ubx_nav_sat_flags,
2299 {"Bitmask", "ubx.nav.sat.flags",
2300 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2301 {&hf_ubx_nav_sat_quality_ind,
2302 {"Signal quality indicator", "ubx.nav.sat.flags.quality_ind",
2303 FT_UINT32, BASE_HEX, VALS(UBX_SIGNAL_QUALITY_INDICATOR), 0x00000007, NULL, HFILL}},
2304 {&hf_ubx_nav_sat_sv_used,
2305 {"Signal used for navigation", "ubx.nav.sat.flags.sv_used",
2306 FT_UINT32, BASE_HEX, NULL, 0x00000008, NULL, HFILL}},
2307 {&hf_ubx_nav_sat_health,
2308 {"Signal health", "ubx.nav.sat.flags.health",
2309 FT_UINT32, BASE_HEX, VALS(UBX_SIGNAL_HEALTH), 0x00000030, NULL, HFILL}},
2310 {&hf_ubx_nav_sat_diff_corr,
2311 {"Differential correction available", "ubx.nav.sat.flags.diff_corr",
2312 FT_UINT32, BASE_HEX, NULL, 0x00000040, NULL, HFILL}},
2313 {&hf_ubx_nav_sat_smoothed,
2314 {"Carrier smoothed pseudorange used", "ubx.nav.sat.flags.smoothed",
2315 FT_UINT32, BASE_HEX, NULL, 0x00000080, NULL, HFILL}},
2316 {&hf_ubx_nav_sat_orbit_src,
2317 {"Orbit source", "ubx.nav.sat.flags.orbit_src",
2318 FT_UINT32, BASE_HEX, VALS(UBX_ORBIT_SOURCE), 0x00000700, NULL, HFILL}},
2319 {&hf_ubx_nav_sat_eph_avail,
2320 {"Ephemeris available", "ubx.nav.sat.flags.eph_avail",
2321 FT_UINT32, BASE_HEX, NULL, 0x00000800, NULL, HFILL}},
2322 {&hf_ubx_nav_sat_alm_avail,
2323 {"Almanac available", "ubx.nav.sat.flags.alm_avail",
2324 FT_UINT32, BASE_HEX, NULL, 0x00001000, NULL, HFILL}},
2325 {&hf_ubx_nav_sat_ano_avail,
2326 {"AssistNow Offline data available", "ubx.nav.sat.flags.ano_avail",
2327 FT_UINT32, BASE_HEX, NULL, 0x00002000, NULL, HFILL}},
2328 {&hf_ubx_nav_sat_aop_avail,
2329 {"AssistNow Autonomous data available", "ubx.nav.sat.flags.aop_avail",
2330 FT_UINT32, BASE_HEX, NULL, 0x00004000, NULL, HFILL}},
2331 {&hf_ubx_nav_sat_sbas_corr_used,
2332 {"SBAS corrections used", "ubx.nav.sat.flags.sbas_corr_used",
2333 FT_UINT32, BASE_HEX, NULL, 0x00010000, NULL, HFILL}},
2334 {&hf_ubx_nav_sat_rtcm_corr_used,
2335 {"RTCM corrections used", "ubx.nav.sat.flags.rtcm_corr_used",
2336 FT_UINT32, BASE_HEX, NULL, 0x00020000, NULL, HFILL}},
2337 {&hf_ubx_nav_sat_slas_corr_used,
2338 {"QZSS SLAS corrections used", "ubx.nav.sat.flags.slas_corr_used",
2339 FT_UINT32, BASE_HEX, NULL, 0x00040000, NULL, HFILL}},
2340 {&hf_ubx_nav_sat_spartn_corr_used,
2341 {"SPARTN corrections used", "ubx.nav.sat.flags.spartn_corr_used",
2342 FT_UINT32, BASE_HEX, NULL, 0x00080000, NULL, HFILL}},
2343 {&hf_ubx_nav_sat_pr_corr_used,
2344 {"Pseudorange corrections used", "ubx.nav.sat.flags.pr_corr_used",
2345 FT_UINT32, BASE_HEX, NULL, 0x00100000, NULL, HFILL}},
2346 {&hf_ubx_nav_sat_cr_corr_used,
2347 {"Carrier range corrections used", "ubx.nav.sat.flags.cr_corr_used",
2348 FT_UINT32, BASE_HEX, NULL, 0x00200000, NULL, HFILL}},
2349 {&hf_ubx_nav_sat_do_corr_used,
2350 {"Range rate (Doppler) corrections used", "ubx.nav.sat.flags.do_corr_used",
2351 FT_UINT32, BASE_HEX, NULL, 0x00400000, NULL, HFILL}},
2353 // NAV-SBAS
2354 {&hf_ubx_nav_sbas,
2355 {"UBX-NAV-SBAS", "ubx.nav.sbas",
2356 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2357 {&hf_ubx_nav_sbas_itow,
2358 {"iTOW", "ubx.nav.sbas.itow",
2359 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2360 {&hf_ubx_nav_sbas_geo,
2361 {"GEO PRN", "ubx.nav.sbas.geo",
2362 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2363 {&hf_ubx_nav_sbas_mode,
2364 {"SBAS Mode", "ubx.nav.sbas.mode",
2365 FT_UINT8, BASE_DEC, VALS(UBX_SBAS_MODE), 0x0, NULL, HFILL}},
2366 {&hf_ubx_nav_sbas_sys,
2367 {"SBAS System", "ubx.nav.sbas.sys",
2368 FT_INT8, BASE_DEC, VALS(UBX_SBAS_SYSTEM), 0x0, NULL, HFILL}},
2369 {&hf_ubx_nav_sbas_service,
2370 {"SBAS Services available", "ubx.nav.sbas.service",
2371 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2372 {&hf_ubx_nav_sbas_service_ranging,
2373 {"GEO may be used as ranging source", "ubx.nav.sbas.service.ranging",
2374 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2375 {&hf_ubx_nav_sbas_service_corrections,
2376 {"GEO is providing correction data", "ubx.nav.sbas.service.corrections",
2377 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2378 {&hf_ubx_nav_sbas_service_integrity,
2379 {"GEO is providing integrity", "ubx.nav.sbas.service.integrity",
2380 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}},
2381 {&hf_ubx_nav_sbas_service_testmode,
2382 {"GEO is in test mode", "ubx.nav.sbas.service.testmode",
2383 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}},
2384 {&hf_ubx_nav_sbas_service_bad,
2385 {"Problem with signal or broadcast data indicated", "ubx.nav.sbas.service.bad",
2386 FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}},
2387 {&hf_ubx_nav_sbas_cnt,
2388 {"Number of SV data following", "ubx.nav.sbas.cnt",
2389 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2390 {&hf_ubx_nav_sbas_reserved1,
2391 {"Reserved", "ubx.nav.sbas.reserved1",
2392 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2393 {&hf_ubx_nav_sbas_sv_id,
2394 {"SV ID", "ubx.nav.sbas.sv_id",
2395 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2396 {&hf_ubx_nav_sbas_flags,
2397 {"Flags", "ubx.nav.sbas.flags",
2398 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2399 {&hf_ubx_nav_sbas_udre,
2400 {"Monitoring status", "ubx.nav.sbas.udre",
2401 FT_UINT8, BASE_DEC, VALS(UDREI_EVALUATION), 0x0, NULL, HFILL}},
2402 {&hf_ubx_nav_sbas_sv_sys,
2403 {"System", "ubx.nav.sbas.sv_sys",
2404 FT_INT8, BASE_DEC, VALS(UBX_SBAS_SYSTEM), 0x0, NULL, HFILL}},
2405 {&hf_ubx_nav_sbas_sv_service,
2406 {"Service", "ubx.nav.sbas.sv_service",
2407 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2408 {&hf_ubx_nav_sbas_reserved2,
2409 {"Reserved", "ubx.nav.sbas.reserved2",
2410 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2411 {&hf_ubx_nav_sbas_prc,
2412 {"Pseudo Range correction", "ubx.nav.sbas.prc",
2413 FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_centimeter_centimeters), 0x0, NULL, HFILL}},
2414 {&hf_ubx_nav_sbas_reserved3,
2415 {"Reserved", "ubx.nav.sbas.reserved3",
2416 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2417 {&hf_ubx_nav_sbas_ic,
2418 {"Ionosphere correction", "ubx.nav.sbas.ic",
2419 FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_centimeter_centimeters), 0x0, NULL, HFILL}},
2421 // NAV-TIMEGPS
2422 {&hf_ubx_nav_timegps,
2423 {"UBX-NAV-TIMEGPS", "ubx.nav.timegps",
2424 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2425 {&hf_ubx_nav_timegps_itow,
2426 {"iTOW", "ubx.nav.timegps.itow",
2427 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2428 {&hf_ubx_nav_timegps_ftow,
2429 {"fTOW", "ubx.nav.timegps.ftow",
2430 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL}},
2431 {&hf_ubx_nav_timegps_week,
2432 {"GPS week", "ubx.nav.timegps.week",
2433 FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2434 {&hf_ubx_nav_timegps_leaps,
2435 {"GPS leap seconds", "ubx.nav.timegps.leaps",
2436 FT_INT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL}},
2437 {&hf_ubx_nav_timegps_valid,
2438 {"Validity flags", "ubx.nav.timegps.valid",
2439 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2440 {&hf_ubx_nav_timegps_towvalid,
2441 {"Valid GPS time of week", "ubx.nav.timegps.valid.towvalid",
2442 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2443 {&hf_ubx_nav_timegps_weekvalid,
2444 {"Valid GPS week number", "ubx.nav.timegps.valid.weekvalid",
2445 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2446 {&hf_ubx_nav_timegps_leapsvalid,
2447 {"Valid GPS leap seconds", "ubx.nav.timegps.valid.leapsvalid",
2448 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}},
2449 {&hf_ubx_nav_timegps_tacc,
2450 {"Time accuracy estimate", "ubx.nav.timegps.tacc",
2451 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL}},
2453 // NAV-TIMEUTC
2454 {&hf_ubx_nav_timeutc,
2455 {"UBX-NAV-TIMEUTC", "ubx.nav.timeutc",
2456 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2457 {&hf_ubx_nav_timeutc_itow,
2458 {"iTOW", "ubx.nav.timeutc.itow",
2459 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2460 {&hf_ubx_nav_timeutc_tacc,
2461 {"Time accuracy estimate (UTC)", "ubx.nav.timeutc.tacc",
2462 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL}},
2463 {&hf_ubx_nav_timeutc_nano,
2464 {"Fraction of second (UTC)", "ubx.nav.timeutc.nano",
2465 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_nanoseconds), 0x0, NULL, HFILL}},
2466 {&hf_ubx_nav_timeutc_year,
2467 {"Year", "ubx.nav.timeutc.year",
2468 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2469 {&hf_ubx_nav_timeutc_month,
2470 {"Month", "ubx.nav.timeutc.month",
2471 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2472 {&hf_ubx_nav_timeutc_day,
2473 {"Day", "ubx.nav.timeutc.day",
2474 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2475 {&hf_ubx_nav_timeutc_hour,
2476 {"Hour of day", "ubx.nav.timeutc.hour",
2477 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2478 {&hf_ubx_nav_timeutc_min,
2479 {"Minute of hour", "ubx.nav.timeutc.min",
2480 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2481 {&hf_ubx_nav_timeutc_sec,
2482 {"Seconds of minute", "ubx.nav.timeutc.sec",
2483 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2484 {&hf_ubx_nav_timeutc_valid,
2485 {"Validity flags", "ubx.nav.timeutc.valid",
2486 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2487 {&hf_ubx_nav_timeutc_validtow,
2488 {"Valid Time of Week", "ubx.nav.timeutc.valid.validtow",
2489 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2490 {&hf_ubx_nav_timeutc_validwkn,
2491 {"Valid Week Number", "ubx.nav.timeutc.valid.validwkn",
2492 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2493 {&hf_ubx_nav_timeutc_validutc,
2494 {"Valid UTC Time", "ubx.nav.timeutc.valid.validutc",
2495 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}},
2496 {&hf_ubx_nav_timeutc_utcstandard,
2497 {"utcStandard", "ubx.nav.timeutc.valid.utcstandard",
2498 FT_UINT8, BASE_DEC, VALS(UBX_UTC_STD_ID), 0xf0, NULL, HFILL}},
2500 // NAV-VELECEF
2501 {&hf_ubx_nav_velecef,
2502 {"UBX-NAV-VELECEF", "ubx.nav.velecef",
2503 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2504 {&hf_ubx_nav_velecef_itow,
2505 {"iTOW", "ubx.nav.velecef.itow",
2506 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL}},
2507 {&hf_ubx_nav_velecef_ecefvx,
2508 {"ECEF X velocity", "ubx.nav.velecef.ecefvx",
2509 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_cm_s), 0x0, NULL, HFILL}},
2510 {&hf_ubx_nav_velecef_ecefvy,
2511 {"ECEF Y velocity", "ubx.nav.velecef.ecefvy",
2512 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_cm_s), 0x0, NULL, HFILL}},
2513 {&hf_ubx_nav_velecef_ecefvz,
2514 {"ECEF Z velocity", "ubx.nav.velecef.ecefvz",
2515 FT_INT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_cm_s), 0x0, NULL, HFILL}},
2516 {&hf_ubx_nav_velecef_sacc,
2517 {"Speed accuracy estimate", "ubx.nav.velecef.sacc",
2518 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_cm_s), 0x0, NULL, HFILL}},
2520 // RXM-MEASX
2521 {&hf_ubx_rxm_measx,
2522 {"UBX-RXM-MEASX", "ubx.rxm.measx",
2523 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2524 {&hf_ubx_rxm_measx_version,
2525 {"Message version", "ubx.rxm.measx.version",
2526 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2527 {&hf_ubx_rxm_measx_reserved1,
2528 {"Reserved", "ubx.rxm.measx.reserved1",
2529 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2530 {&hf_ubx_rxm_measx_gpstow,
2531 {"GPS measurement reference time", "ubx.rxm.measx.gpstow",
2532 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2533 {&hf_ubx_rxm_measx_glotow,
2534 {"GLONASS measurement reference time", "ubx.rxm.measx.glotow",
2535 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2536 {&hf_ubx_rxm_measx_bdstow,
2537 {"BeiDou measurement reference time", "ubx.rxm.measx.bdstow",
2538 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2539 {&hf_ubx_rxm_measx_reserved2,
2540 {"Reserved", "ubx.rxm.measx.reserved2",
2541 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2542 {&hf_ubx_rxm_measx_qzsstow,
2543 {"QZSS measurement reference time", "ubx.rxm.measx.qzsstow",
2544 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2545 {&hf_ubx_rxm_measx_gpstowacc,
2546 {"GPS measurement reference time accuracy", "ubx.rxm.measx.gpstowacc",
2547 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_towacc), 0x0, NULL, HFILL}},
2548 {&hf_ubx_rxm_measx_glotowacc,
2549 {"GLONASS measurement reference time accuracy", "ubx.rxm.measx.glotowacc",
2550 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_towacc), 0x0, NULL, HFILL}},
2551 {&hf_ubx_rxm_measx_bdstowacc,
2552 {"BeiDou measurement reference time accuracy", "ubx.rxm.measx.bdstowacc",
2553 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_towacc), 0x0, NULL, HFILL}},
2554 {&hf_ubx_rxm_measx_reserved3,
2555 {"Reserved", "ubx.rxm.measx.reserved3",
2556 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2557 {&hf_ubx_rxm_measx_qzsstowacc,
2558 {"QZSS measurement reference time accuracy", "ubx.rxm.measx.qzsstowacc",
2559 FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_towacc), 0x0, NULL, HFILL}},
2560 {&hf_ubx_rxm_measx_numsv,
2561 {"Number of satellites in repeated block", "ubx.rxm.measx.numsv",
2562 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2563 {&hf_ubx_rxm_measx_flags_towset,
2564 {"TOW set", "ubx.rxm.measx.flags.towset",
2565 FT_BOOLEAN, 8, NULL, 0x03, NULL, HFILL}},
2566 {&hf_ubx_rxm_measx_reserved4,
2567 {"Reserved", "ubx.rxm.measx.reserved4",
2568 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2569 {&hf_ubx_rxm_measx_gnssid,
2570 {"GNSS ID", "ubx.rxm.measx.gnssid",
2571 FT_UINT8, BASE_DEC, VALS(UBX_GNSS_ID), 0x0, NULL, HFILL}},
2572 {&hf_ubx_rxm_measx_svid,
2573 {"Satellite ID", "ubx.rxm.measx.svid",
2574 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2575 {&hf_ubx_rxm_measx_cn0,
2576 {"C/N0", "ubx.rxm.measx.cn0",
2577 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_dbhz), 0x0, NULL, HFILL}},
2578 {&hf_ubx_rxm_measx_mpathindic,
2579 {"multipath index", "ubx.rxm.measx.mpathindic",
2580 FT_UINT8, BASE_DEC, VALS(UBX_RXM_MEASX_MULTIPATH_INDEX), 0x0, NULL, HFILL}},
2581 {&hf_ubx_rxm_measx_dopplerms,
2582 {"Doppler measurement", "ubx.rxm.measx.dopplerms",
2583 FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_dopplerms), 0x0, NULL, HFILL}},
2584 {&hf_ubx_rxm_measx_dopplerhz,
2585 {"Doppler measurement", "ubx.rxm.measx.dopplerhz",
2586 FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_dopplerhz), 0x0, NULL, HFILL}},
2587 {&hf_ubx_rxm_measx_wholechips,
2588 {"whole value of the code phase measurement", "ubx.rxm.measx.wholechips",
2589 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2590 {&hf_ubx_rxm_measx_fracchips,
2591 {"fractional value of the code phase measurement", "ubx.rxm.measx.fracchips",
2592 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2593 {&hf_ubx_rxm_measx_codephase,
2594 {"Code phase", "ubx.rxm.measx.codephase",
2595 FT_UINT32, BASE_CUSTOM, CF_FUNC(&fmt_codephase), 0x0, NULL, HFILL}},
2596 {&hf_ubx_rxm_measx_intcodephase,
2597 {"integer (part of) the code phase", "ubx.rxm.measx.intcodephase",
2598 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2599 {&hf_ubx_rxm_measx_pseurangermserr,
2600 {"pseudorange RMS error index", "ubx.rxm.measx.pseurangermserr",
2601 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2602 {&hf_ubx_rxm_measx_reserved5,
2603 {"Reserved", "ubx.rxm.measx.reserved5",
2604 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2606 // RXM-RAWX
2607 {&hf_ubx_rxm_rawx,
2608 {"UBX-RXM-RAWX", "ubx.rxm.rawx",
2609 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2610 {&hf_ubx_rxm_rawx_rcvtow,
2611 {"Measurement time of week in receiver local time", "ubx.rxm.rawx.rcvtow",
2612 FT_DOUBLE, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL}},
2613 {&hf_ubx_rxm_rawx_week,
2614 {"GPS week number in receiver local time", "ubx.rxm.rawx.week",
2615 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2616 {&hf_ubx_rxm_rawx_leaps,
2617 {"GPS leap seconds", "ubx.rxm.rawx.leaps",
2618 FT_INT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL}},
2619 {&hf_ubx_rxm_rawx_nummeas,
2620 {"Number of measurements to follow", "ubx.rxm.rawx.nummeas",
2621 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2622 {&hf_ubx_rxm_rawx_recstat,
2623 {"Receiver tracking status bitfield", "ubx.rxm.rawx.recstat",
2624 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2625 {&hf_ubx_rxm_rawx_recstat_leapsec,
2626 {"Leap seconds have been determined", "ubx.rxm.rawx.recstat.leapsec",
2627 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2628 {&hf_ubx_rxm_rawx_recstat_clkreset,
2629 {"Clock reset applied", "ubx.rxm.rawx.recstat.clkreset",
2630 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2631 {&hf_ubx_rxm_rawx_version,
2632 {"Message version", "ubx.rxm.rawx.version",
2633 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2634 {&hf_ubx_rxm_rawx_reserved1,
2635 {"Reserved", "ubx.rxm.rawx.reserved1",
2636 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2637 {&hf_ubx_rxm_rawx_prmes,
2638 {"Pseudorange measurement", "ubx.rxm.rawx.prmes",
2639 FT_DOUBLE, BASE_DEC|BASE_UNIT_STRING, UNS(&units_meter_meters), 0x0, NULL, HFILL}},
2640 {&hf_ubx_rxm_rawx_cpmes,
2641 {"Carrier phase measurement", "ubx.rxm.rawx.cpmes",
2642 FT_DOUBLE, BASE_DEC|BASE_UNIT_STRING, UNS(&units_cycle_cycles), 0x0, NULL, HFILL}},
2643 {&hf_ubx_rxm_rawx_domes,
2644 {"Doppler measurement", "ubx.rxm.rawx.domes",
2645 FT_FLOAT, BASE_DEC|BASE_UNIT_STRING, UNS(&units_hz), 0x0, NULL, HFILL}},
2646 {&hf_ubx_rxm_rawx_gnssid,
2647 {"GNSS ID", "ubx.rxm.rawx.gnssid",
2648 FT_UINT8, BASE_DEC, VALS(UBX_GNSS_ID), 0x0, NULL, HFILL}},
2649 {&hf_ubx_rxm_rawx_svid,
2650 {"Satellite ID", "ubx.rxm.rawx.svid",
2651 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2652 {&hf_ubx_rxm_rawx_sigid,
2653 {"Signal ID", "ubx.rxm.rawx.sigid",
2654 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2655 {&hf_ubx_rxm_rawx_freqid,
2656 {"Frequency ID", "ubx.rxm.rawx.freqid",
2657 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2658 {&hf_ubx_rxm_rawx_locktime,
2659 {"Carrier phase locktime counter", "ubx.rxm.rawx.locktime",
2660 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0x0, NULL, HFILL}},
2661 {&hf_ubx_rxm_rawx_cn0,
2662 {"C/N0", "ubx.rxm.rawx.cn0",
2663 FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_dbhz), 0x0, NULL, HFILL}},
2664 {&hf_ubx_rxm_rawx_prstdev,
2665 {"Estimated pseudorange measurement standard deviation", "ubx.rxm.rawx.prstdev",
2666 FT_UINT8, BASE_CUSTOM, CF_FUNC(&fmt_prstdev), 0x0f, NULL, HFILL}},
2667 {&hf_ubx_rxm_rawx_cpstdev,
2668 {"Estimated carrier phase measurement standard deviation", "ubx.rxm.rawx.cpstdev",
2669 FT_UINT8, BASE_CUSTOM, CF_FUNC(&fmt_cpstdev), 0x0f, NULL, HFILL}},
2670 {&hf_ubx_rxm_rawx_dostdev,
2671 {"Estimated Doppler measurement standard deviation", "ubx.rxm.rawx.dostdev",
2672 FT_UINT8, BASE_CUSTOM, CF_FUNC(&fmt_dostdev), 0x0f, NULL, HFILL}},
2673 {&hf_ubx_rxm_rawx_trkstat,
2674 {"Tracking status bitfield", "ubx.rxm.rawx.trkstat",
2675 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL}},
2676 {&hf_ubx_rxm_rawx_trkstat_prvalid,
2677 {"Pseudorange valid", "ubx.rxm.rawx.trkstat.prvalid",
2678 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}},
2679 {&hf_ubx_rxm_rawx_trkstat_cpvalid,
2680 {"Carrier phase valid", "ubx.rxm.rawx.trkstat.cpvalid",
2681 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}},
2682 {&hf_ubx_rxm_rawx_trkstat_halfcyc,
2683 {"Half cycle valid", "ubx.rxm.rawx.trkstat.halfcyc",
2684 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}},
2685 {&hf_ubx_rxm_rawx_trkstat_subhalfcyc,
2686 {"Half cycle subtracted from phase", "ubx.rxm.rawx.trkstat.subhalfcyc",
2687 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}},
2688 {&hf_ubx_rxm_rawx_reserved2,
2689 {"Reserved", "ubx.rxm.rawx.reserved2",
2690 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2692 // RXM-SFRBX
2693 {&hf_ubx_rxm_sfrbx,
2694 {"UBX-RXM-SFRBX", "ubx.rxm.sfrbx",
2695 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2696 {&hf_ubx_rxm_sfrbx_gnssid,
2697 {"GNSS ID", "ubx.rxm.sfrbx.gnssid",
2698 FT_UINT8, BASE_DEC, VALS(UBX_GNSS_ID), 0x0, NULL, HFILL}},
2699 {&hf_ubx_rxm_sfrbx_svid,
2700 {"Satellite ID", "ubx.rxm.sfrbx.svid",
2701 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2702 {&hf_ubx_rxm_sfrbx_sigid,
2703 {"Signal identifier", "ubx.rxm.sfrbx.sigid",
2704 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2705 {&hf_ubx_rxm_sfrbx_freqid,
2706 {"Frequency identifier", "ubx.rxm.sfrbx.freqid",
2707 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2708 {&hf_ubx_rxm_sfrbx_numwords,
2709 {"Number of data words", "ubx.rxm.sfrbx.numwords",
2710 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2711 {&hf_ubx_rxm_sfrbx_chn,
2712 {"Tracking channel number", "ubx.rxm.sfrbx.chn",
2713 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2714 {&hf_ubx_rxm_sfrbx_version,
2715 {"Message version", "ubx.rxm.sfrbx.version",
2716 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2717 {&hf_ubx_rxm_sfrbx_dwrd,
2718 {"Data words (little endian)", "ubx.rxm.sfrbx.dwrd",
2719 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2720 {&hf_ubx_rxm_sfrbx_reserved1,
2721 {"Reserved 1", "ubx.rxm.sfrbx.reserved1",
2722 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2723 {&hf_ubx_rxm_sfrbx_reserved2,
2724 {"Reserved 2", "ubx.rxm.sfrbx.reserved2",
2725 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2726 {&hf_ubx_rxm_sfrbx_reserved3,
2727 {"Reserved 3", "ubx.rxm.sfrbx.reserved3",
2728 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2731 expert_module_t *expert_ubx;
2733 static ei_register_info ei[] = {
2734 {&ei_ubx_chksum, {"ubx.chksum", PI_CHECKSUM, PI_WARN, "Chksum", EXPFILL}},
2737 static int *ett_part[] = {
2738 &ett_ubx,
2739 &ett_ubx_ack_ack,
2740 &ett_ubx_ack_nak,
2741 &ett_ubx_cfg_gnss,
2742 &ett_ubx_cfg_sbas,
2743 &ett_ubx_cfg_sbas_mode,
2744 &ett_ubx_cfg_sbas_scanmode,
2745 &ett_ubx_nav_dop,
2746 &ett_ubx_nav_eoe,
2747 &ett_ubx_nav_odo,
2748 &ett_ubx_nav_posecef,
2749 &ett_ubx_nav_pvt,
2750 &ett_ubx_nav_pvt_datetime,
2751 &ett_ubx_nav_pvt_valid,
2752 &ett_ubx_nav_pvt_flags,
2753 &ett_ubx_nav_pvt_flags2,
2754 &ett_ubx_nav_sat,
2755 &ett_ubx_nav_sat_flags,
2756 &ett_ubx_nav_sbas,
2757 &ett_ubx_nav_sbas_service,
2758 &ett_ubx_nav_timegps,
2759 &ett_ubx_nav_timegps_tow,
2760 &ett_ubx_nav_timegps_valid,
2761 &ett_ubx_nav_timeutc,
2762 &ett_ubx_nav_timeutc_valid,
2763 &ett_ubx_nav_velecef,
2764 &ett_ubx_rxm_measx,
2765 &ett_ubx_rxm_rawx,
2766 &ett_ubx_rxm_rawx_recstat,
2767 &ett_ubx_rxm_rawx_trkstat,
2768 &ett_ubx_rxm_sfrbx,
2771 static int *ett[array_length(ett_part)
2772 + array_length(ett_ubx_nav_sat_sv_info)
2773 + array_length(ett_ubx_cfg_gnss_block)
2774 + array_length(ett_ubx_nav_sbas_sv_info)
2775 + array_length(ett_ubx_rxm_rawx_meas)
2776 + array_length(ett_ubx_rxm_measx_meas)];
2778 // fill ett with elements from ett_part,
2779 // pointers to ett_ubx_nav_sat_sv_info elements,
2780 // pointers to ett_ubx_cfg_gnss_block elements,
2781 // pointers to ett_ubx_nav_sbas_sv_info elements,
2782 // pointers to ett_ubx_rxm_rawx_meas elements, and
2783 // pointers to ett_ubx_rxm_measx_meas elements
2784 uint16_t i;
2785 for (i = 0; i < array_length(ett_part); i++) {
2786 ett[i] = ett_part[i];
2788 for (i = 0; i < array_length(ett_ubx_nav_sat_sv_info); i++) {
2789 ett[i + array_length(ett_part)] = &ett_ubx_nav_sat_sv_info[i];
2791 for (i = 0; i < array_length(ett_ubx_cfg_gnss_block); i++) {
2792 ett[i + array_length(ett_part) + array_length(ett_ubx_nav_sat_sv_info)]
2793 = &ett_ubx_cfg_gnss_block[i];
2795 for (i = 0; i < array_length(ett_ubx_nav_sbas_sv_info); i++) {
2796 ett[i + array_length(ett_part) + array_length(ett_ubx_nav_sat_sv_info)
2797 + array_length(ett_ubx_cfg_gnss_block)]
2798 = &ett_ubx_nav_sbas_sv_info[i];
2800 for (i = 0; i < array_length(ett_ubx_rxm_rawx_meas); i++) {
2801 ett[i + array_length(ett_part) + array_length(ett_ubx_nav_sat_sv_info)
2802 + array_length(ett_ubx_cfg_gnss_block)
2803 + array_length(ett_ubx_nav_sbas_sv_info)]
2804 = &ett_ubx_rxm_rawx_meas[i];
2806 for (i = 0; i < array_length(ett_ubx_rxm_measx_meas); i++) {
2807 ett[i + array_length(ett_part) + array_length(ett_ubx_nav_sat_sv_info)
2808 + array_length(ett_ubx_cfg_gnss_block)
2809 + array_length(ett_ubx_nav_sbas_sv_info)
2810 + array_length(ett_ubx_rxm_rawx_meas)]
2811 = &ett_ubx_rxm_measx_meas[i];
2814 proto_ubx = proto_register_protocol("UBX Protocol", "UBX", "ubx");
2816 ubx_handle = register_dissector("ubx", dissect_ubx, proto_ubx);
2818 proto_register_field_array(proto_ubx, hf, array_length(hf));
2819 proto_register_subtree_array(ett, array_length(ett));
2821 expert_ubx = expert_register_protocol(proto_ubx);
2822 expert_register_field_array(expert_ubx, ei, array_length(ei));
2824 ubx_class_id_dissector_table = register_dissector_table("ubx.msg_class_id",
2825 "UBX Message Class & ID", proto_ubx, FT_UINT16, BASE_HEX);
2826 ubx_gnssid_dissector_table = register_dissector_table("ubx.rxm.sfrbx.gnssid",
2827 "UBX-RXM-SFRBX GNSS Type ID", proto_ubx,
2828 FT_UINT8, BASE_DEC);
2831 void proto_reg_handoff_ubx(void) {
2832 UBX_REGISTER_DISSECTOR(dissect_ubx_ack_ack, UBX_ACK_ACK);
2833 UBX_REGISTER_DISSECTOR(dissect_ubx_ack_nak, UBX_ACK_NAK);
2834 UBX_REGISTER_DISSECTOR(dissect_ubx_cfg_gnss, UBX_CFG_GNSS);
2835 UBX_REGISTER_DISSECTOR(dissect_ubx_cfg_sbas, UBX_CFG_SBAS);
2836 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_dop, UBX_NAV_DOP);
2837 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_eoe, UBX_NAV_EOE);
2838 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_odo, UBX_NAV_ODO);
2839 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_posecef, UBX_NAV_POSECEF);
2840 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_pvt, UBX_NAV_PVT);
2841 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_sat, UBX_NAV_SAT);
2842 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_sbas, UBX_NAV_SBAS);
2843 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_timegps, UBX_NAV_TIMEGPS);
2844 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_timeutc, UBX_NAV_TIMEUTC);
2845 UBX_REGISTER_DISSECTOR(dissect_ubx_nav_velecef, UBX_NAV_VELECEF);
2846 UBX_REGISTER_DISSECTOR(dissect_ubx_rxm_measx, UBX_RXM_MEASX);
2847 UBX_REGISTER_DISSECTOR(dissect_ubx_rxm_rawx, UBX_RXM_RAWX);
2848 UBX_REGISTER_DISSECTOR(dissect_ubx_rxm_sfrbx, UBX_RXM_SFRBX);