1 /* packet-ubx-galileo_e1b_inav.c
2 * Dissection of Galileo E1-B I/NAV navigation messages
3 * (as provided by UBX-RXM-SFRBX).
5 * By Timo Warns <timo.warns@gmail.com>
6 * Copyright 2023 Timo Warns
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@unicom.net>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
19 #include <wsutil/array.h>
20 #include <wsutil/pint.h>
21 #include <wsutil/utf8_entities.h>
23 #include "packet-ubx.h"
26 * Dissects Galileo E1-B I/NAV navigation messages
27 * as encoded by UBX (in UBX-RXM-SFRBX messages).
28 * Based on Galileo OS SIS ICD Issue 2.1
31 // Initialize the protocol and registered fields
32 static int proto_ubx_gal_inav
;
34 static int hf_ubx_gal_inav_even_odd
;
35 static int hf_ubx_gal_inav_page_type
;
36 static int hf_ubx_gal_inav_type
;
37 static int hf_ubx_gal_inav_data_122_67
;
38 static int hf_ubx_gal_inav_data_66_17
;
39 static int hf_ubx_gal_inav_data_16_1
;
40 static int hf_ubx_gal_inav_osnma
;
41 static int hf_ubx_gal_inav_sar_start_bit
;
42 static int hf_ubx_gal_inav_sar_long_rlm
;
43 static int hf_ubx_gal_inav_sar_beacon_1
;
44 static int hf_ubx_gal_inav_sar_rlm_data
;
45 static int hf_ubx_gal_inav_spare
;
46 static int hf_ubx_gal_inav_ssp
;
47 static int hf_ubx_gal_inav_crc
;
48 static int hf_ubx_gal_inav_tail
;
49 static int hf_ubx_gal_inav_pad
;
50 static int hf_ubx_gal_inav_reserved_1
;
52 static int hf_ubx_gal_inav_word_type
;
54 static int hf_ubx_gal_inav_word0
;
55 static int hf_ubx_gal_inav_word0_time
;
56 static int hf_ubx_gal_inav_word0_spare
;
57 static int hf_ubx_gal_inav_word0_wn
;
58 static int hf_ubx_gal_inav_word0_tow
;
60 static int hf_ubx_gal_inav_word1
;
61 static int hf_ubx_gal_inav_word1_iodnav
;
62 static int hf_ubx_gal_inav_word1_t0e
;
63 static int hf_ubx_gal_inav_word1_m0
;
64 static int hf_ubx_gal_inav_word1_e
;
65 static int hf_ubx_gal_inav_word1_sqrta
;
66 static int hf_ubx_gal_inav_word1_reserved
;
68 static int hf_ubx_gal_inav_word2
;
69 static int hf_ubx_gal_inav_word2_iodnav
;
70 static int hf_ubx_gal_inav_word2_omega0
;
71 static int hf_ubx_gal_inav_word2_i0
;
72 static int hf_ubx_gal_inav_word2_omega
;
73 static int hf_ubx_gal_inav_word2_incl_angle_rate
;
74 static int hf_ubx_gal_inav_word2_reserved
;
76 static int hf_ubx_gal_inav_word3
;
77 static int hf_ubx_gal_inav_word3_iodnav
;
78 static int hf_ubx_gal_inav_word3_omega_rate
;
79 static int hf_ubx_gal_inav_word3_delta_n
;
80 static int hf_ubx_gal_inav_word3_c_uc
;
81 static int hf_ubx_gal_inav_word3_c_us
;
82 static int hf_ubx_gal_inav_word3_c_rc
;
83 static int hf_ubx_gal_inav_word3_c_rs
;
84 static int hf_ubx_gal_inav_word3_sisa_e1_e5b
;
86 static int hf_ubx_gal_inav_word4
;
87 static int hf_ubx_gal_inav_word4_iodnav
;
88 static int hf_ubx_gal_inav_word4_svid
;
89 static int hf_ubx_gal_inav_word4_c_ic
;
90 static int hf_ubx_gal_inav_word4_c_is
;
91 static int hf_ubx_gal_inav_word4_t_0c
;
92 static int hf_ubx_gal_inav_word4_a_f0
;
93 static int hf_ubx_gal_inav_word4_a_f1
;
94 static int hf_ubx_gal_inav_word4_a_f2
;
95 static int hf_ubx_gal_inav_word4_spare
;
97 static dissector_table_t ubx_gal_inav_word_dissector_table
;
99 static int ett_ubx_gal_inav
;
100 static int ett_ubx_gal_inav_word0
;
101 static int ett_ubx_gal_inav_word1
;
102 static int ett_ubx_gal_inav_word2
;
103 static int ett_ubx_gal_inav_word3
;
104 static int ett_ubx_gal_inav_word4
;
105 static int ett_ubx_gal_inav_sar
;
107 static const value_string GAL_PAGE_TYPE
[] = {
113 static const value_string GAL_SSP
[] = {
120 /* Format clock correction (with scale factor 60) for
123 static void fmt_clk_correction(char *label
, uint32_t c
) {
124 snprintf(label
, ITEM_LABEL_LENGTH
, "%u s", 60 * c
);
127 /* Format radians (with 2^-29 scale factor) for
128 * amplitude of harmonic correction terms
130 static void fmt_lat_correction(char *label
, int16_t c
) {
131 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-29 radians", c
);
134 /* Format meters (with 2^-5 scale factor) for
135 * amplitude of orbit correction terms
137 static void fmt_orbit_correction(char *label
, int16_t c
) {
138 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-5 m", c
);
141 /* Format semi-circles (with 2^-31 scale factor) for
142 * - mean anomaly at reference time
143 * - longitude of ascending node of orbital plane at weekly epoch
144 * - inclination angle at reference time
145 * - argument of perigee
147 static void fmt_semi_circles(char *label
, int32_t c
) {
148 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-31 semi-circles", c
);
151 /* Format rate of semi-circles (with 2^-43 scale factor) for
152 * - inclination angle
154 * - mean motion difference
156 static void fmt_semi_circles_rate(char *label
, int16_t c
) {
157 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-43 semi-circles/s", c
);
161 static void fmt_sisa(char *label
, uint8_t i
) {
163 // 0 cm to 49 cm with 1 cm resolution
164 snprintf(label
, ITEM_LABEL_LENGTH
, "%u cm", i
);
167 // 50 cm to 98 cm with 2 cm resolution
168 snprintf(label
, ITEM_LABEL_LENGTH
, "%u cm", 50 + ((i
- 50) * 2));
171 // 100 cm to 196 cm with 4 cm resolution
172 snprintf(label
, ITEM_LABEL_LENGTH
, "%u cm", 100 + ((i
- 75) * 4));
175 // 200 cm to 600 cm with 16 cm resolution
176 snprintf(label
, ITEM_LABEL_LENGTH
, "%u cm", 200 + ((i
- 100) * 16));
180 snprintf(label
, ITEM_LABEL_LENGTH
, "Spare");
183 snprintf(label
, ITEM_LABEL_LENGTH
, "No Accuracy Prediction Available (NAPA)");
187 /* Format SV clock bias (with 2^-34 scale factor) for
190 static void fmt_sv_clk_bias(char *label
, int32_t c
) {
191 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-34 s", c
);
194 /* Format SV clock drift (with 2^-46 scale factor) for
197 static void fmt_sv_clk_drift(char *label
, int32_t c
) {
198 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-46 s/s", c
);
201 /* Format SV clock drift rate (with 2^-59 scale factor) for
204 static void fmt_sv_clk_drift_rate(char *label
, int32_t c
) {
205 snprintf(label
, ITEM_LABEL_LENGTH
, "%d * 2^-59 s/s" UTF8_SUPERSCRIPT_TWO
, c
);
208 /* Format eccentricity */
209 static void fmt_e(char *label
, uint64_t c
) {
210 snprintf(label
, ITEM_LABEL_LENGTH
, "%" PRIu64
" * 2^-33", c
);
213 /* Format square root of the semi-major axis */
214 static void fmt_sqrt_a(char *label
, uint64_t c
) {
215 snprintf(label
, ITEM_LABEL_LENGTH
, "%" PRIu64
" * 2^-19 " UTF8_SQUARE_ROOT
"m", c
);
218 /* Format ephemeris reference time */
219 static void fmt_t0e(char *label
, uint32_t c
) {
221 snprintf(label
, ITEM_LABEL_LENGTH
, "%ds", c
);
224 /* Dissect Galileo E1-B I/NAV navigation message */
225 static int dissect_ubx_gal_inav(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
228 bool sar_start
, sar_long_rlm
;
229 uint32_t inav_type
= 0, even_page_type
, odd_page_type
;
230 uint64_t data_122_67
= 0, data_66_17
= 0, data_16_1
= 0;
233 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Galileo E1-B I/NAV");
234 col_clear(pinfo
->cinfo
, COL_INFO
);
236 proto_tree
*gal_inav_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 32, ett_ubx_gal_inav
, NULL
, "Galileo E1-B I/NAV");
239 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_even_odd
, tvb
, 0, 1, ENC_NA
);
240 proto_tree_add_item_ret_uint(gal_inav_tree
, hf_ubx_gal_inav_page_type
, tvb
, 0, 1, ENC_NA
, &even_page_type
);
242 if (even_page_type
== 1) { // alert page
243 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_reserved_1
, tvb
, 0, 15, ENC_NA
);
245 else if (even_page_type
== 0) { // nominal page
246 proto_tree_add_item_ret_uint(gal_inav_tree
, hf_ubx_gal_inav_type
, tvb
, 0, 1, ENC_NA
, &inav_type
);
247 proto_tree_add_item_ret_uint64(gal_inav_tree
, hf_ubx_gal_inav_data_122_67
, tvb
, 0, 8, ENC_BIG_ENDIAN
, &data_122_67
);
248 proto_tree_add_item_ret_uint64(gal_inav_tree
, hf_ubx_gal_inav_data_66_17
, tvb
, 8, 8, ENC_BIG_ENDIAN
, &data_66_17
);
251 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_tail
, tvb
, 14, 1, ENC_NA
);
252 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_pad
, tvb
, 15, 1, ENC_NA
);
256 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_even_odd
, tvb
, 16, 1, ENC_NA
);
257 proto_tree_add_item_ret_uint(gal_inav_tree
, hf_ubx_gal_inav_page_type
, tvb
, 16, 1, ENC_NA
, &odd_page_type
);
259 if (odd_page_type
== 1) { // alert page
260 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_reserved_1
, tvb
, 16, 11, ENC_NA
);
262 else if (odd_page_type
== 0) { // nominal page
263 proto_tree_add_item_ret_uint64(gal_inav_tree
, hf_ubx_gal_inav_data_16_1
, tvb
, 16, 8, ENC_BIG_ENDIAN
, &data_16_1
);
264 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_osnma
, tvb
, 16, 8, ENC_BIG_ENDIAN
);
266 proto_tree
*sar_tree
= proto_tree_add_subtree(gal_inav_tree
, tvb
, 23, 4, ett_ubx_gal_inav_sar
, NULL
, "SAR");
267 proto_tree_add_item_ret_boolean(sar_tree
, hf_ubx_gal_inav_sar_start_bit
, tvb
, 23, 4, ENC_BIG_ENDIAN
, &sar_start
);
268 proto_tree_add_item_ret_boolean(sar_tree
, hf_ubx_gal_inav_sar_long_rlm
, tvb
, 23, 4, ENC_BIG_ENDIAN
, &sar_long_rlm
);
270 proto_tree_add_item(sar_tree
, hf_ubx_gal_inav_sar_beacon_1
, tvb
, 23, 4, ENC_BIG_ENDIAN
);
273 // TODO: add more elaborate dissection for subsequent RLM data (requiring state tracking)
274 proto_tree_add_item(sar_tree
, hf_ubx_gal_inav_sar_rlm_data
, tvb
, 23, 4, ENC_BIG_ENDIAN
);
277 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_spare
, tvb
, 26, 1, ENC_NA
);
281 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_crc
, tvb
, 26, 4, ENC_BIG_ENDIAN
);
283 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_ssp
, tvb
, 28, 4, ENC_BIG_ENDIAN
);
284 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_tail
, tvb
, 30, 1, ENC_NA
);
285 proto_tree_add_item(gal_inav_tree
, hf_ubx_gal_inav_pad
, tvb
, 31, 1, ENC_NA
);
287 // handoff the data word of a nominal page
288 if (even_page_type
== 0 && odd_page_type
== 0) {
289 // create new tvb with the data word
290 word
= wmem_alloc(pinfo
->pool
, 16);
291 phton16(word
+ 14, (uint16_t)data_16_1
);
292 phton64(word
+ 6, data_66_17
);
293 phton64(word
, (((uint64_t) inav_type
) << 58) | (data_122_67
<< 2) | (data_66_17
>> 48));
295 next_tvb
= tvb_new_child_real_data(tvb
, (uint8_t *)word
, 16, 16);
296 add_new_data_source(pinfo
, next_tvb
, "Galileo I/NAV Word");
298 // handoff to appropriate dissector
299 if (!dissector_try_uint(ubx_gal_inav_word_dissector_table
, inav_type
, next_tvb
, pinfo
, tree
)) {
300 call_data_dissector(next_tvb
, pinfo
, tree
);
304 return tvb_captured_length(tvb
);
307 /* Dissect word 0 - I/NAV Spare Word */
308 static int dissect_ubx_gal_inav_word0(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
) {
309 col_append_str(pinfo
->cinfo
, COL_INFO
, "Word 0 (Spare Word)");
311 proto_item
*ti
= proto_tree_add_item(tree
, hf_ubx_gal_inav_word0
, tvb
, 0, 16, ENC_NA
);
312 proto_tree
*word_tree
= proto_item_add_subtree(ti
, ett_ubx_gal_inav_word0
);
314 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word_type
, tvb
, 0, 1, ENC_NA
);
315 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word0_time
, tvb
, 0, 1, ENC_NA
);
316 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word0_spare
, tvb
, 1, 11, ENC_NA
);
317 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word0_wn
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
318 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word0_tow
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
320 return tvb_captured_length(tvb
);
323 /* Dissect word 1 - Ephemeris (1/4) */
324 static int dissect_ubx_gal_inav_word1(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
) {
325 col_append_str(pinfo
->cinfo
, COL_INFO
, "Word 1 (Ephemeris (1/4))");
327 proto_item
*ti
= proto_tree_add_item(tree
, hf_ubx_gal_inav_word1
, tvb
, 0, 16, ENC_NA
);
328 proto_tree
*word_tree
= proto_item_add_subtree(ti
, ett_ubx_gal_inav_word1
);
330 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word_type
, tvb
, 0, 1, ENC_NA
);
331 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word1_iodnav
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
332 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word1_t0e
, tvb
, 2, 2, ENC_BIG_ENDIAN
);
333 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word1_m0
, tvb
, 3, 8, ENC_BIG_ENDIAN
);
334 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word1_e
, tvb
, 7, 8, ENC_BIG_ENDIAN
);
335 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word1_sqrta
, tvb
, 8, 8, ENC_BIG_ENDIAN
);
336 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word1_reserved
, tvb
, 15, 1, ENC_NA
);
338 return tvb_captured_length(tvb
);
341 /* Dissect word 2 - Ephemeris (2/4) */
342 static int dissect_ubx_gal_inav_word2(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
) {
343 col_append_str(pinfo
->cinfo
, COL_INFO
, "Word 2 (Ephemeris (2/4))");
345 proto_item
*ti
= proto_tree_add_item(tree
, hf_ubx_gal_inav_word2
, tvb
, 0, 16, ENC_NA
);
346 proto_tree
*word_tree
= proto_item_add_subtree(ti
, ett_ubx_gal_inav_word2
);
348 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word_type
, tvb
, 0, 1, ENC_NA
);
349 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word2_iodnav
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
350 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word2_omega0
, tvb
, 2, 4, ENC_BIG_ENDIAN
);
351 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word2_i0
, tvb
, 6, 4, ENC_BIG_ENDIAN
);
352 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word2_omega
, tvb
, 10, 4, ENC_BIG_ENDIAN
);
353 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word2_incl_angle_rate
, tvb
, 14, 2, ENC_BIG_ENDIAN
);
354 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word2_reserved
, tvb
, 15, 1, ENC_NA
);
356 return tvb_captured_length(tvb
);
359 /* Dissect word 3 - Ephemeris (3/4) */
360 static int dissect_ubx_gal_inav_word3(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
) {
361 col_append_str(pinfo
->cinfo
, COL_INFO
, "Word 3 (Ephemeris (3/4))");
363 proto_item
*ti
= proto_tree_add_item(tree
, hf_ubx_gal_inav_word3
, tvb
, 0, 16, ENC_NA
);
364 proto_tree
*word_tree
= proto_item_add_subtree(ti
, ett_ubx_gal_inav_word3
);
366 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word_type
, tvb
, 0, 1, ENC_NA
);
367 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_iodnav
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
368 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_omega_rate
, tvb
, 2, 4, ENC_BIG_ENDIAN
);
369 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_delta_n
, tvb
, 5, 2, ENC_BIG_ENDIAN
);
370 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_c_uc
, tvb
, 7, 2, ENC_BIG_ENDIAN
);
371 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_c_us
, tvb
, 9, 2, ENC_BIG_ENDIAN
);
372 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_c_rc
, tvb
, 11, 2, ENC_BIG_ENDIAN
);
373 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_c_rs
, tvb
, 13, 2, ENC_BIG_ENDIAN
);
374 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word3_sisa_e1_e5b
, tvb
, 15, 1, ENC_NA
);
376 return tvb_captured_length(tvb
);
379 /* Dissect word 4 - Ephemeris (4/4) */
380 static int dissect_ubx_gal_inav_word4(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
) {
381 col_append_str(pinfo
->cinfo
, COL_INFO
, "Word 4 (Ephemeris (4/4))");
383 proto_item
*ti
= proto_tree_add_item(tree
, hf_ubx_gal_inav_word4
, tvb
, 0, 16, ENC_NA
);
384 proto_tree
*word_tree
= proto_item_add_subtree(ti
, ett_ubx_gal_inav_word4
);
386 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word_type
, tvb
, 0, 1, ENC_NA
);
387 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_iodnav
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
388 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_svid
, tvb
, 2, 1, ENC_NA
);
389 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_c_ic
, tvb
, 2, 4, ENC_BIG_ENDIAN
);
390 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_c_is
, tvb
, 4, 4, ENC_BIG_ENDIAN
);
391 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_t_0c
, tvb
, 6, 4, ENC_BIG_ENDIAN
);
392 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_a_f0
, tvb
, 8, 8, ENC_BIG_ENDIAN
);
393 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_a_f1
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
394 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_a_f2
, tvb
, 12, 4, ENC_BIG_ENDIAN
);
395 proto_tree_add_item(word_tree
, hf_ubx_gal_inav_word4_spare
, tvb
, 15, 1, ENC_NA
);
397 return tvb_captured_length(tvb
);
400 void proto_register_ubx_gal_inav(void) {
402 static hf_register_info hf
[] = {
403 {&hf_ubx_gal_inav_even_odd
, {"Even/Odd", "gal_inav.even_odd", FT_BOOLEAN
, 8, TFS(&tfs_odd_even
), 0x80, NULL
, HFILL
}},
404 {&hf_ubx_gal_inav_page_type
, {"Page Type", "gal_inav.page_type", FT_UINT8
, BASE_DEC
, VALS(GAL_PAGE_TYPE
), 0x40, NULL
, HFILL
}},
405 {&hf_ubx_gal_inav_type
, {"Type", "gal_inav.type", FT_UINT8
, BASE_DEC
, NULL
, 0x3f, NULL
, HFILL
}},
406 {&hf_ubx_gal_inav_data_122_67
, {"Data (122-67)", "gal_inav.data_122_67", FT_UINT64
, BASE_HEX
, NULL
, 0x00ffffffffffffff, NULL
, HFILL
}},
407 {&hf_ubx_gal_inav_data_66_17
, {"Data (66-17)", "gal_inav.data_66_17", FT_UINT64
, BASE_HEX
, NULL
, 0xffffffffffffc000, NULL
, HFILL
}},
408 {&hf_ubx_gal_inav_data_16_1
, {"Data (16-1)", "gal_inav.data_16_1", FT_UINT64
, BASE_HEX
, NULL
, 0x3fffc00000000000, NULL
, HFILL
}},
409 {&hf_ubx_gal_inav_osnma
, {"OSNMA", "gal_inav.osnma", FT_UINT64
, BASE_HEX
, NULL
, 0x00003fffffffffc0, NULL
, HFILL
}},
410 {&hf_ubx_gal_inav_sar_start_bit
, {"Start bit", "gal_inav.sar.start_bit", FT_BOOLEAN
, 32, NULL
, 0x20000000, NULL
, HFILL
}},
411 {&hf_ubx_gal_inav_sar_long_rlm
, {"Long RLM", "gal_inav.sar.long_rlm", FT_BOOLEAN
, 32, NULL
, 0x10000000, NULL
, HFILL
}},
412 {&hf_ubx_gal_inav_sar_beacon_1
, {"Beacon (1/3)", "gal_inav.sar.beacon_1", FT_UINT32
, BASE_HEX
, NULL
, 0x0fffff00, NULL
, HFILL
}},
413 {&hf_ubx_gal_inav_sar_rlm_data
, {"RLM data", "gal_inav.sar.rlm_data", FT_UINT32
, BASE_HEX
, NULL
, 0x0fffff00, NULL
, HFILL
}},
414 {&hf_ubx_gal_inav_spare
, {"Spare", "gal_inav.spare", FT_UINT8
, BASE_HEX
, NULL
, 0xc0, NULL
, HFILL
}},
415 {&hf_ubx_gal_inav_reserved_1
, {"Reserved 1", "gal_inav.reserved_1", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
416 {&hf_ubx_gal_inav_crc
, {"CRC", "gal_inav.crc", FT_UINT32
, BASE_HEX
, NULL
, 0x3fffffc0, NULL
, HFILL
}},
417 {&hf_ubx_gal_inav_ssp
, {"SSP", "gal_inav.ssp", FT_UINT32
, BASE_HEX
, VALS(GAL_SSP
), 0x003fc000, NULL
, HFILL
}},
418 {&hf_ubx_gal_inav_tail
, {"Tail", "gal_inav.tail", FT_UINT8
, BASE_HEX
, NULL
, 0x3f, NULL
, HFILL
}},
419 {&hf_ubx_gal_inav_pad
, {"Pad", "gal_inav.pad", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
422 {&hf_ubx_gal_inav_word_type
, {"Type", "gal_inav.word.type", FT_UINT8
, BASE_DEC
, NULL
, 0xfc, NULL
, HFILL
}},
425 {&hf_ubx_gal_inav_word0
, {"Word 0 (Spare Word)", "gal_inav.word0", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
426 {&hf_ubx_gal_inav_word0_time
, {"Time", "gal_inav.word0.time", FT_UINT8
, BASE_HEX
, NULL
, 0x03, NULL
, HFILL
}},
427 {&hf_ubx_gal_inav_word0_spare
, {"Spare", "gal_inav.word0.spare", FT_BYTES
, BASE_NONE
|SEP_SPACE
, NULL
, 0x0, NULL
, HFILL
}},
428 {&hf_ubx_gal_inav_word0_wn
, {"Week Number", "gal_inav.word0.wn", FT_UINT32
, BASE_DEC
, NULL
, 0xfff00000, NULL
, HFILL
}},
429 {&hf_ubx_gal_inav_word0_tow
, {"Time of Week", "gal_inav.word0.tow", FT_UINT32
, BASE_DEC
, NULL
, 0x000fffff, NULL
, HFILL
}},
432 {&hf_ubx_gal_inav_word1
, {"Word 1 (Ephemeris (1/4))", "gal_inav.word1", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
433 {&hf_ubx_gal_inav_word1_iodnav
, {"IOD_nav", "gal_inav.word1.iod_nav", FT_UINT16
, BASE_DEC
, NULL
, 0x03ff, NULL
, HFILL
}},
434 {&hf_ubx_gal_inav_word1_t0e
, {"Ephemeris reference time (t_0e)", "gal_inav.word1.t_0e", FT_UINT16
, BASE_CUSTOM
, CF_FUNC(&fmt_t0e
), 0xfffc, NULL
, HFILL
}},
435 {&hf_ubx_gal_inav_word1_m0
, {"Mean anomaly at reference time (M" UTF8_SUBSCRIPT_ZERO
")", "gal_inav.word1.m_0", FT_INT64
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles
), 0x03fffffffc000000, NULL
, HFILL
}},
436 {&hf_ubx_gal_inav_word1_e
, {"Eccentricity (e)", "gal_inav.word1.e", FT_UINT64
, BASE_CUSTOM
, CF_FUNC(&fmt_e
), 0x03fffffffc000000, NULL
, HFILL
}},
437 {&hf_ubx_gal_inav_word1_sqrta
, {"Square root of the semi-major axis (" UTF8_SQUARE_ROOT
"a)", "gal_inav.word1.sqrt_a", FT_UINT64
, BASE_CUSTOM
, CF_FUNC(&fmt_sqrt_a
), 0x00000003fffffffc, NULL
, HFILL
}},
438 {&hf_ubx_gal_inav_word1_reserved
,{"Reserved", "gal_inav.word1.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0x03, NULL
, HFILL
}},
441 {&hf_ubx_gal_inav_word2
, {"Word 2 (Ephemeris (2/4))", "gal_inav.word2", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
442 {&hf_ubx_gal_inav_word2_iodnav
, {"IOD_nav", "gal_inav.word2.iod_nav", FT_UINT16
, BASE_DEC
, NULL
, 0x03ff, NULL
, HFILL
}},
443 {&hf_ubx_gal_inav_word2_omega0
, {"Longitude of ascending node of orbital plane at weekly epoch (" UTF8_CAPITAL_OMEGA UTF8_SUBSCRIPT_ZERO
")", "gal_inav.word2.omega_0", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles
), 0xffffffff, NULL
, HFILL
}},
444 {&hf_ubx_gal_inav_word2_i0
, {"Inclination angle at reference time (i" UTF8_SUBSCRIPT_ZERO
")", "gal_inav.word2.i_0", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles
), 0xffffffff, NULL
, HFILL
}},
445 {&hf_ubx_gal_inav_word2_omega
, {"Argument of perigee (" UTF8_OMEGA
")", "gal_inav.word2.omega", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles
), 0xffffffff, NULL
, HFILL
}},
446 {&hf_ubx_gal_inav_word2_incl_angle_rate
, {"Rate of change of inclination angle (di)", "gal_inav.word2.di", FT_INT16
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles_rate
), 0xfffc, NULL
, HFILL
}},
447 {&hf_ubx_gal_inav_word2_reserved
, {"Reserved", "gal_inav.word2.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0x03, NULL
, HFILL
}},
450 {&hf_ubx_gal_inav_word3
, {"Word 3 (Ephemeris (3/4))", "gal_inav.word3", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
451 {&hf_ubx_gal_inav_word3_iodnav
, {"IOD_nav", "gal_inav.word3.iod_nav", FT_UINT16
, BASE_DEC
, NULL
, 0x03ff, NULL
, HFILL
}},
452 {&hf_ubx_gal_inav_word3_omega_rate
, {"Rate of change of right ascension (dot " UTF8_CAPITAL_OMEGA
")", "gal_inav.word3.omega_rate", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles_rate
), 0xffffff00, NULL
, HFILL
}},
453 {&hf_ubx_gal_inav_word3_delta_n
, {"Mean motion difference from computed value (" UTF8_CAPITAL_DELTA
"n)", "gal_inav.word3.delta_n", FT_INT16
, BASE_CUSTOM
, CF_FUNC(&fmt_semi_circles_rate
), 0xffff, NULL
, HFILL
}},
454 {&hf_ubx_gal_inav_word3_c_uc
, {"Amplitude of the cosine harmonic correction term to the argument of latitude (C_UC)", "gal_inav.word3.c_uc", FT_INT16
, BASE_CUSTOM
, CF_FUNC(&fmt_lat_correction
), 0xffff, NULL
, HFILL
}},
455 {&hf_ubx_gal_inav_word3_c_us
, {"Amplitude of the sine harmonic correction term to the argument of latitude (C_US)", "gal_inav.word3.c_us", FT_INT16
, BASE_CUSTOM
, CF_FUNC(&fmt_lat_correction
), 0xffff, NULL
, HFILL
}},
456 {&hf_ubx_gal_inav_word3_c_rc
, {"Amplitude of the cosine harmonic correction term to the orbit radius (C_RC)", "gal_inav.word3.c_rc", FT_INT16
, BASE_CUSTOM
, CF_FUNC(&fmt_orbit_correction
), 0xffff, NULL
, HFILL
}},
457 {&hf_ubx_gal_inav_word3_c_rs
, {"Amplitude of the sine harmonic correction term to the orbit radius (C_RS)", "gal_inav.word3.c_rs", FT_INT16
, BASE_CUSTOM
, CF_FUNC(&fmt_orbit_correction
), 0xffff, NULL
, HFILL
}},
458 {&hf_ubx_gal_inav_word3_sisa_e1_e5b
, {"Signal-in-Space Accuracy (SISA(E1,E5b))", "gal_inav.word3.sisa_e1_e5b", FT_UINT8
, BASE_CUSTOM
, CF_FUNC(&fmt_sisa
), 0xff, NULL
, HFILL
}},
461 {&hf_ubx_gal_inav_word4
, {"Word 4 (Ephemeris (4/4))", "gal_inav.word4", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
462 {&hf_ubx_gal_inav_word4_iodnav
, {"IOD_nav", "gal_inav.word4.iod_nav", FT_UINT16
, BASE_DEC
, NULL
, 0x03ff, NULL
, HFILL
}},
463 {&hf_ubx_gal_inav_word4_svid
, {"SVID", "gal_inav.word4.svid", FT_UINT8
, BASE_DEC
, NULL
, 0xfc, NULL
, HFILL
}},
464 {&hf_ubx_gal_inav_word4_c_ic
, {"Amplitude of the cosine harmonic correction term to the angle of inclination (C_IC)", "gal_inav.word4.c_ic", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_lat_correction
), 0x03fffc00, NULL
, HFILL
}},
465 {&hf_ubx_gal_inav_word4_c_is
, {"Amplitude of the sine harmonic correction term to the angle of inclination (C_IS)", "gal_inav.word4.c_is", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_lat_correction
), 0x03fffc00, NULL
, HFILL
}},
466 {&hf_ubx_gal_inav_word4_t_0c
, {"Clock correction data reference Time of Week (t_0c)", "gal_inav.word4.t_0c", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(&fmt_clk_correction
), 0x03fff000, NULL
, HFILL
}},
467 {&hf_ubx_gal_inav_word4_a_f0
, {"SV clock bias correction coefficient (a_f0)", "gal_inav.word4.a_f0", FT_INT64
, BASE_CUSTOM
, CF_FUNC(&fmt_sv_clk_bias
), 0x0fffffffe0000000, NULL
, HFILL
}},
468 {&hf_ubx_gal_inav_word4_a_f1
, {"SV clock drift correction coefficient (a_f1)", "gal_inav.word4.a_f1", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_sv_clk_drift
), 0x1fffff00, NULL
, HFILL
}},
469 {&hf_ubx_gal_inav_word4_a_f2
, {"SV clock drift rate correction coefficient (a_f2)", "gal_inav.word4.a_f2", FT_INT32
, BASE_CUSTOM
, CF_FUNC(&fmt_sv_clk_drift_rate
), 0x000000fc, NULL
, HFILL
}},
470 {&hf_ubx_gal_inav_word4_spare
, {"Spare", "gal_inav.word4.spare", FT_UINT8
, BASE_HEX
, NULL
, 0x03, NULL
, HFILL
}},
473 static int *ett
[] = {
475 &ett_ubx_gal_inav_word0
,
476 &ett_ubx_gal_inav_word1
,
477 &ett_ubx_gal_inav_word2
,
478 &ett_ubx_gal_inav_word3
,
479 &ett_ubx_gal_inav_word4
,
480 &ett_ubx_gal_inav_sar
,
483 proto_ubx_gal_inav
= proto_register_protocol("Galileo E1-B I/NAV Navigation Message", "Galileo I/NAV", "gal_inav");
485 proto_register_field_array(proto_ubx_gal_inav
, hf
, array_length(hf
));
486 proto_register_subtree_array(ett
, array_length(ett
));
488 register_dissector("ubx_gal_inav", dissect_ubx_gal_inav
, proto_ubx_gal_inav
);
490 ubx_gal_inav_word_dissector_table
= register_dissector_table("ubx.rxm.sfrbx.gal_inav.word",
491 "Galileo I/NAV Word", proto_ubx_gal_inav
, FT_UINT8
, BASE_DEC
);
494 void proto_reg_handoff_ubx_gal_inav(void) {
495 dissector_add_uint("ubx.rxm.sfrbx.gnssid", GNSS_ID_GALILEO
, create_dissector_handle(dissect_ubx_gal_inav
, proto_ubx_gal_inav
));
497 dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 0, create_dissector_handle(dissect_ubx_gal_inav_word0
, proto_ubx_gal_inav
));
498 dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 1, create_dissector_handle(dissect_ubx_gal_inav_word1
, proto_ubx_gal_inav
));
499 dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 2, create_dissector_handle(dissect_ubx_gal_inav_word2
, proto_ubx_gal_inav
));
500 dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 3, create_dissector_handle(dissect_ubx_gal_inav_word3
, proto_ubx_gal_inav
));
501 dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 4, create_dissector_handle(dissect_ubx_gal_inav_word4
, proto_ubx_gal_inav
));