/src/wireshark/epan/dissectors/packet-ubx-galileo_e1b_inav.c
Line | Count | Source |
1 | | /* packet-ubx-galileo_e1b_inav.c |
2 | | * Dissection of Galileo E1-B I/NAV navigation messages |
3 | | * (as provided by UBX-RXM-SFRBX). |
4 | | * |
5 | | * By Timo Warns <timo.warns@gmail.com> |
6 | | * Copyright 2023 Timo Warns |
7 | | * |
8 | | * Wireshark - Network traffic analyzer |
9 | | * By Gerald Combs <gerald@unicom.net> |
10 | | * Copyright 1998 Gerald Combs |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/conversation.h> |
18 | | #include <epan/packet.h> |
19 | | #include <epan/tfs.h> |
20 | | #include <epan/unit_strings.h> |
21 | | #include <proto.h> |
22 | | #include <wmem_scopes.h> |
23 | | #include <wsutil/array.h> |
24 | | #include <wsutil/pint.h> |
25 | | #include <wsutil/utf8_entities.h> |
26 | | |
27 | | #include "packet-ubx.h" |
28 | | #include "wsutil/wmem/wmem_core.h" |
29 | | |
30 | | /* |
31 | | * Dissects Galileo E1-B I/NAV navigation messages |
32 | | * as encoded by UBX (in UBX-RXM-SFRBX messages). |
33 | | * Based on Galileo OS SIS ICD Issue 2.1 |
34 | | */ |
35 | | |
36 | | const value_string DAY_NUMBER[] = { |
37 | | {0, "not defined"}, |
38 | | {1, "Sunday"}, |
39 | | {2, "Monday"}, |
40 | | {3, "Tuesday"}, |
41 | | {4, "Wednesday"}, |
42 | | {5, "Thursday"}, |
43 | | {6, "Friday"}, |
44 | | {7, "Saturday"}, |
45 | | {0, NULL}, |
46 | | }; |
47 | | |
48 | | static const value_string GAL_OSNMA_NMAS_CODE[] = { |
49 | | { 0, "Reserved"}, |
50 | | { 1, "Test"}, |
51 | | { 2, "Operational"}, |
52 | | { 3, "Don't use"}, |
53 | | { 0, NULL}, |
54 | | }; |
55 | | |
56 | | static const value_string GAL_OSNMA_CPKS_CODE[] = { |
57 | | { 0, "Reserved"}, |
58 | | { 1, "Nominal"}, |
59 | | { 2, "End of Chain (EOC)"}, |
60 | | { 3, "Chain Revoked (CREV)"}, |
61 | | { 4, "New Public Key (NPK)"}, |
62 | | { 5, "Public Key Revoked (PKREV)"}, |
63 | | { 6, "New Merkle Tree (NMT)"}, |
64 | | { 7, "Alert Message (AM)"}, |
65 | | { 0, NULL}, |
66 | | }; |
67 | | |
68 | | static const value_string GAL_OSNMA_NB_DP_CODE[] = { |
69 | | { 0, "Reserved"}, |
70 | | { 1, "Reserved"}, |
71 | | { 2, "Reserved"}, |
72 | | { 3, "Reserved"}, |
73 | | { 4, "Reserved"}, |
74 | | { 5, "Reserved"}, |
75 | | { 6, "Reserved"}, |
76 | | { 7, "13"}, |
77 | | { 8, "14"}, |
78 | | { 9, "15"}, |
79 | | {10, "16"}, |
80 | | {11, "Reserved"}, |
81 | | {12, "Reserved"}, |
82 | | {13, "Reserved"}, |
83 | | {14, "Reserved"}, |
84 | | {15, "Reserved"}, |
85 | | { 0, NULL}, |
86 | | }; |
87 | | |
88 | | static const value_string GAL_OSNMA_NB_DK_CODE[] = { |
89 | | { 0, "Reserved"}, |
90 | | { 1, "7"}, |
91 | | { 2, "8"}, |
92 | | { 3, "9"}, |
93 | | { 4, "10"}, |
94 | | { 5, "11"}, |
95 | | { 6, "12"}, |
96 | | { 7, "13"}, |
97 | | { 8, "14"}, |
98 | | { 9, "Reserved"}, |
99 | | {10, "Reserved"}, |
100 | | {11, "Reserved"}, |
101 | | {12, "Reserved"}, |
102 | | {13, "Reserved"}, |
103 | | {14, "Reserved"}, |
104 | | {15, "Reserved"}, |
105 | | { 0, NULL}, |
106 | | }; |
107 | | |
108 | | static const value_string GAL_OSNMA_NPKT_CODE[] = { |
109 | | { 0, "Reserved"}, |
110 | | { 1, "ECDSA P-256"}, |
111 | | { 2, "Reserved"}, |
112 | | { 3, "ECDSA P-521"}, |
113 | | { 4, "OSNMA Alert Message (OAM)"}, |
114 | | { 5, "Reserved"}, |
115 | | { 6, "Reserved"}, |
116 | | { 7, "Reserved"}, |
117 | | { 8, "Reserved"}, |
118 | | { 9, "Reserved"}, |
119 | | {10, "Reserved"}, |
120 | | {11, "Reserved"}, |
121 | | {12, "Reserved"}, |
122 | | {13, "Reserved"}, |
123 | | {14, "Reserved"}, |
124 | | {15, "Reserved"}, |
125 | | { 0, NULL}, |
126 | | }; |
127 | | |
128 | | static const value_string GAL_OSNMA_HF_CODE[] = { |
129 | | { 0, "SHA-256"}, |
130 | | { 1, "Reserved"}, |
131 | | { 2, "SHA3-256"}, |
132 | | { 3, "Reserved"}, |
133 | | { 0, NULL}, |
134 | | }; |
135 | | |
136 | | static const value_string GAL_OSNMA_MF_CODE[] = { |
137 | | { 0, "HMAC-SHA-256"}, |
138 | | { 1, "CMAC-AES"}, |
139 | | { 2, "Reserved"}, |
140 | | { 3, "Reserved"}, |
141 | | { 0, NULL}, |
142 | | }; |
143 | | |
144 | | static const value_string GAL_OSNMA_KS_CODE[] = { |
145 | | { 0, "96 bits"}, |
146 | | { 1, "104 bits"}, |
147 | | { 2, "112 bits"}, |
148 | | { 3, "120 bits"}, |
149 | | { 4, "128 bits"}, |
150 | | { 5, "160 bits"}, |
151 | | { 6, "192 bits"}, |
152 | | { 7, "224 bits"}, |
153 | | { 8, "256 bits"}, |
154 | | { 9, "Reserved"}, |
155 | | {10, "Reserved"}, |
156 | | {11, "Reserved"}, |
157 | | {12, "Reserved"}, |
158 | | {13, "Reserved"}, |
159 | | {14, "Reserved"}, |
160 | | {15, "Reserved"}, |
161 | | { 0, NULL}, |
162 | | }; |
163 | 0 | static uint32_t ks2len(uint32_t ks) { |
164 | 0 | if (ks <= 4) { |
165 | 0 | return 12 + ks; |
166 | 0 | } |
167 | 0 | else if (ks <= 8) { |
168 | 0 | return 20 + (ks-5) * 4; |
169 | 0 | } |
170 | 0 | else { |
171 | 0 | return 0; |
172 | 0 | } |
173 | 0 | } |
174 | | |
175 | | static const value_string GAL_OSNMA_TS_CODE[] = { |
176 | | { 0, "Reserved"}, |
177 | | { 1, "Reserved"}, |
178 | | { 2, "Reserved"}, |
179 | | { 3, "Reserved"}, |
180 | | { 4, "Reserved"}, |
181 | | { 5, "20 bits"}, |
182 | | { 6, "24 bits"}, |
183 | | { 7, "28 bits"}, |
184 | | { 8, "32 bits"}, |
185 | | { 9, "40 bits"}, |
186 | | {10, "Reserved"}, |
187 | | {11, "Reserved"}, |
188 | | {12, "Reserved"}, |
189 | | {13, "Reserved"}, |
190 | | {14, "Reserved"}, |
191 | | {15, "Reserved"}, |
192 | | { 0, NULL}, |
193 | | }; |
194 | | |
195 | | static const value_string GAL_SAR_SHORT_RLM_MSG_CODE[] = { |
196 | | { 0, "Spare"}, |
197 | | { 1, "Acknowledgement Service"}, |
198 | | { 2, "Spare"}, |
199 | | { 3, "Spare"}, |
200 | | { 4, "Spare"}, |
201 | | { 5, "Spare"}, |
202 | | { 6, "Spare"}, |
203 | | { 7, "Spare"}, |
204 | | { 8, "Spare"}, |
205 | | { 9, "Spare"}, |
206 | | {10, "Spare"}, |
207 | | {11, "Spare"}, |
208 | | {12, "Spare"}, |
209 | | {13, "Spare"}, |
210 | | {14, "Spare"}, |
211 | | {15, "Test Service"}, |
212 | | { 0, NULL}, |
213 | | }; |
214 | | |
215 | 0 | #define CONVERSATION_SAR_RLM 1 |
216 | 0 | #define CONVERSATION_OSNMA_HKROOT_MACK 2 |
217 | 0 | #define CONVERSATION_OSNMA_DSM 3 |
218 | | |
219 | | // Initialize the protocol and registered fields |
220 | | static int proto_ubx_gal_inav; |
221 | | |
222 | | static int hf_ubx_gal_inav_even_odd; |
223 | | static int hf_ubx_gal_inav_page_type; |
224 | | static int hf_ubx_gal_inav_type; |
225 | | static int hf_ubx_gal_inav_data_122_67; |
226 | | static int hf_ubx_gal_inav_data_66_17; |
227 | | static int hf_ubx_gal_inav_data_16_1; |
228 | | |
229 | | static int hf_ubx_gal_inav_osnma_hkroot; |
230 | | static int hf_ubx_gal_inav_osnma_mack; |
231 | | static int hf_ubx_gal_inav_osnma_nmas; |
232 | | static int hf_ubx_gal_inav_osnma_cid; |
233 | | static int hf_ubx_gal_inav_osnma_cpks; |
234 | | static int hf_ubx_gal_inav_osnma_reserved; |
235 | | static int hf_ubx_gal_inav_osnma_dsm_id; |
236 | | static int hf_ubx_gal_inav_osnma_dsm_blk_id; |
237 | | static int hf_ubx_gal_inav_osnma_dsm_blk; |
238 | | static int hf_ubx_gal_inav_osnma_tag0; |
239 | | static int hf_ubx_gal_inav_osnma_macseq; |
240 | | static int hf_ubx_gal_inav_osnma_cop; |
241 | | static int hf_ubx_gal_inav_osnma_tag; |
242 | | static int hf_ubx_gal_inav_osnma_prn_d; |
243 | | static int hf_ubx_gal_inav_osnma_adkd; |
244 | | static int hf_ubx_gal_inav_osnma_key; |
245 | | static int hf_ubx_gal_inav_osnma_padding; |
246 | | static int hf_ubx_gal_inav_osnma_dsm_nb_dk; |
247 | | static int hf_ubx_gal_inav_osnma_dsm_pkid; |
248 | | static int hf_ubx_gal_inav_osnma_dsm_cidkr; |
249 | | static int hf_ubx_gal_inav_osnma_dsm_reserved1; |
250 | | static int hf_ubx_gal_inav_osnma_dsm_hf; |
251 | | static int hf_ubx_gal_inav_osnma_dsm_mf; |
252 | | static int hf_ubx_gal_inav_osnma_dsm_ks; |
253 | | static int hf_ubx_gal_inav_osnma_dsm_ts; |
254 | | static int hf_ubx_gal_inav_osnma_dsm_maclt; |
255 | | static int hf_ubx_gal_inav_osnma_dsm_reserved2; |
256 | | static int hf_ubx_gal_inav_osnma_dsm_wn_k; |
257 | | static int hf_ubx_gal_inav_osnma_dsm_towh_k; |
258 | | static int hf_ubx_gal_inav_osnma_dsm_alpha; |
259 | | static int hf_ubx_gal_inav_osnma_dsm_kroot; |
260 | | static int hf_ubx_gal_inav_osnma_dsm_ds; |
261 | | static int hf_ubx_gal_inav_osnma_dsm_p_dk; |
262 | | static int hf_ubx_gal_inav_osnma_dsm_nb_dp; |
263 | | static int hf_ubx_gal_inav_osnma_dsm_mid; |
264 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_0; |
265 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_1; |
266 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_2; |
267 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_3; |
268 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_4; |
269 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_5; |
270 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_6; |
271 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_7; |
272 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_8; |
273 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_9; |
274 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_10; |
275 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_11; |
276 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_12; |
277 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_13; |
278 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_14; |
279 | | static int hf_ubx_gal_inav_osnma_dsm_x_0_15; |
280 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_0; |
281 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_1; |
282 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_2; |
283 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_3; |
284 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_4; |
285 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_5; |
286 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_6; |
287 | | static int hf_ubx_gal_inav_osnma_dsm_x_1_7; |
288 | | static int hf_ubx_gal_inav_osnma_dsm_x_2_0; |
289 | | static int hf_ubx_gal_inav_osnma_dsm_x_2_1; |
290 | | static int hf_ubx_gal_inav_osnma_dsm_x_2_2; |
291 | | static int hf_ubx_gal_inav_osnma_dsm_x_2_3; |
292 | | static int hf_ubx_gal_inav_osnma_dsm_x_3_0; |
293 | | static int hf_ubx_gal_inav_osnma_dsm_x_3_1; |
294 | | static int hf_ubx_gal_inav_osnma_dsm_npkt; |
295 | | static int hf_ubx_gal_inav_osnma_dsm_npkid; |
296 | | static int hf_ubx_gal_inav_osnma_dsm_npk; |
297 | | static int hf_ubx_gal_inav_osnma_dsm_p_dp; |
298 | | |
299 | | static int hf_ubx_gal_inav_sar_start_bit; |
300 | | static int hf_ubx_gal_inav_sar_long_rlm; |
301 | | static int hf_ubx_gal_inav_sar_rlm_data; |
302 | | static int hf_ubx_gal_inav_sar_beacon_id; |
303 | | static int hf_ubx_gal_inav_sar_msg_code; |
304 | | |
305 | | static int hf_ubx_gal_inav_spare; |
306 | | static int hf_ubx_gal_inav_ssp; |
307 | | static int hf_ubx_gal_inav_crc; |
308 | | static int hf_ubx_gal_inav_tail; |
309 | | static int hf_ubx_gal_inav_pad; |
310 | | static int hf_ubx_gal_inav_reserved_1; |
311 | | |
312 | | static int hf_ubx_gal_inav_word_type; |
313 | | |
314 | | static int hf_ubx_gal_inav_word0; |
315 | | static int hf_ubx_gal_inav_word0_time; |
316 | | static int hf_ubx_gal_inav_word0_spare; |
317 | | static int hf_ubx_gal_inav_word0_wn; |
318 | | static int hf_ubx_gal_inav_word0_tow; |
319 | | |
320 | | static int hf_ubx_gal_inav_word1; |
321 | | static int hf_ubx_gal_inav_word1_iodnav; |
322 | | static int hf_ubx_gal_inav_word1_t0e; |
323 | | static int hf_ubx_gal_inav_word1_m0; |
324 | | static int hf_ubx_gal_inav_word1_e; |
325 | | static int hf_ubx_gal_inav_word1_sqrta; |
326 | | static int hf_ubx_gal_inav_word1_reserved; |
327 | | |
328 | | static int hf_ubx_gal_inav_word2; |
329 | | static int hf_ubx_gal_inav_word2_iodnav; |
330 | | static int hf_ubx_gal_inav_word2_omega0; |
331 | | static int hf_ubx_gal_inav_word2_i0; |
332 | | static int hf_ubx_gal_inav_word2_omega; |
333 | | static int hf_ubx_gal_inav_word2_incl_angle_rate; |
334 | | static int hf_ubx_gal_inav_word2_reserved; |
335 | | |
336 | | static int hf_ubx_gal_inav_word3; |
337 | | static int hf_ubx_gal_inav_word3_iodnav; |
338 | | static int hf_ubx_gal_inav_word3_omega_rate; |
339 | | static int hf_ubx_gal_inav_word3_delta_n; |
340 | | static int hf_ubx_gal_inav_word3_c_uc; |
341 | | static int hf_ubx_gal_inav_word3_c_us; |
342 | | static int hf_ubx_gal_inav_word3_c_rc; |
343 | | static int hf_ubx_gal_inav_word3_c_rs; |
344 | | static int hf_ubx_gal_inav_word3_sisa_e1_e5b; |
345 | | |
346 | | static int hf_ubx_gal_inav_word4; |
347 | | static int hf_ubx_gal_inav_word4_iodnav; |
348 | | static int hf_ubx_gal_inav_word4_svid; |
349 | | static int hf_ubx_gal_inav_word4_c_ic; |
350 | | static int hf_ubx_gal_inav_word4_c_is; |
351 | | static int hf_ubx_gal_inav_word4_t_0c; |
352 | | static int hf_ubx_gal_inav_word4_a_f0; |
353 | | static int hf_ubx_gal_inav_word4_a_f1; |
354 | | static int hf_ubx_gal_inav_word4_a_f2; |
355 | | static int hf_ubx_gal_inav_word4_spare; |
356 | | |
357 | | static int hf_ubx_gal_inav_word6; |
358 | | static int hf_ubx_gal_inav_word6_a0; |
359 | | static int hf_ubx_gal_inav_word6_a1; |
360 | | static int hf_ubx_gal_inav_word6_delta_t_ls; |
361 | | static int hf_ubx_gal_inav_word6_t_0t; |
362 | | static int hf_ubx_gal_inav_word6_wn_0t; |
363 | | static int hf_ubx_gal_inav_word6_wn_lsf; |
364 | | static int hf_ubx_gal_inav_word6_dn; |
365 | | static int hf_ubx_gal_inav_word6_delta_t_lsf; |
366 | | static int hf_ubx_gal_inav_word6_tow; |
367 | | static int hf_ubx_gal_inav_word6_spare; |
368 | | |
369 | | static dissector_table_t ubx_gal_inav_word_dissector_table; |
370 | | |
371 | | static int ett_ubx_gal_inav; |
372 | | static int ett_ubx_gal_inav_word0; |
373 | | static int ett_ubx_gal_inav_word1; |
374 | | static int ett_ubx_gal_inav_word2; |
375 | | static int ett_ubx_gal_inav_word3; |
376 | | static int ett_ubx_gal_inav_word4; |
377 | | static int ett_ubx_gal_inav_word6; |
378 | | static int ett_ubx_gal_inav_osnma; |
379 | | static int ett_ubx_gal_inav_osnma_hkroot_msg; |
380 | | static int ett_ubx_gal_inav_osnma_mack_msg; |
381 | | static int ett_ubx_gal_inav_osnma_mack_tag[9]; |
382 | | static int ett_ubx_gal_inav_osnma_dsm; |
383 | | static int ett_ubx_gal_inav_sar; |
384 | | static int ett_ubx_gal_inav_sar_rlm; |
385 | | |
386 | | static const value_string GAL_PAGE_TYPE[] = { |
387 | | {0, "nominal"}, |
388 | | {1, "alert"}, |
389 | | {0, NULL}, |
390 | | }; |
391 | | |
392 | | static const value_string GAL_SSP[] = { |
393 | | {0x04, "SSP 1"}, |
394 | | {0x2b, "SSP 2"}, |
395 | | {0x2f, "SSP 3"}, |
396 | | {0, NULL}, |
397 | | }; |
398 | | |
399 | 0 | #define OSNMA_HKROOT_MACK_MSG_PARTS_NUM 15 |
400 | 0 | #define OSNMA_HKROOT_MSG_LENGTH OSNMA_HKROOT_MACK_MSG_PARTS_NUM * 8 / 8 |
401 | 0 | #define OSNMA_MACK_MSG_LENGTH OSNMA_HKROOT_MACK_MSG_PARTS_NUM * 32 / 8 |
402 | | |
403 | | typedef struct osnma_hkroot_mack_msg_part { |
404 | | uint32_t frame; |
405 | | uint8_t hkroot; |
406 | | uint32_t mack; |
407 | | } osnma_hkroot_mack_msg_part; |
408 | | |
409 | 0 | #define OSNMA_DSM_BLK_LENGTH 13 |
410 | 0 | #define OSNMA_DSM_BLK_NUM 15 |
411 | | |
412 | | typedef struct osnma_dsm_blk { |
413 | | bool set; |
414 | | uint8_t blk[OSNMA_DSM_BLK_LENGTH]; |
415 | | } osnma_dsm_blk; |
416 | | |
417 | 0 | #define SAR_LONG_RLM_PARTS_NUM 8 |
418 | | #define SAR_LONG_RLM_LENGTH (SAR_LONG_RLM_PARTS_NUM * 20 / 8) |
419 | 0 | #define SAR_SHORT_RLM_PARTS_NUM 4 |
420 | 0 | #define SAR_SHORT_RLM_LENGTH (SAR_SHORT_RLM_PARTS_NUM * 20 / 8) |
421 | | |
422 | | typedef struct sar_rlm_part { |
423 | | uint32_t frame; |
424 | | bool long_rlm; |
425 | | uint32_t rlm_data; |
426 | | } sar_rlm_part; |
427 | | |
428 | | /* Format A_0 for GST-UTC Conversion with 2^-30s resolution */ |
429 | 0 | void fmt_a0(char *label, int64_t c) { |
430 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%" PRId64 " * 2^-30s", c); |
431 | 0 | } |
432 | | |
433 | | /* Format A_1 for GST-UTC Conversion with 2^-50s/s resolution */ |
434 | 0 | void fmt_a1(char *label, int32_t c) { |
435 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-50s/s", c); |
436 | 0 | } |
437 | | |
438 | | /* Format t_0t for GST-UTC Conversion with 3600s resolution */ |
439 | 0 | static void fmt_t_0t(char *label, uint32_t c) { |
440 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%us", c * 3600); |
441 | 0 | } |
442 | | |
443 | | /* Format clock correction (with scale factor 60) for |
444 | | * t_0c |
445 | | */ |
446 | 0 | static void fmt_clk_correction(char *label, uint32_t c) { |
447 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%u s", 60 * c); |
448 | 0 | } |
449 | | |
450 | | /* Format radians (with 2^-29 scale factor) for |
451 | | * amplitude of harmonic correction terms |
452 | | */ |
453 | 0 | void fmt_lat_correction(char *label, int32_t c) { |
454 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-29 radians", c); |
455 | 0 | } |
456 | | |
457 | | /* Format meters (with 2^-5 scale factor) for |
458 | | * amplitude of orbit correction terms |
459 | | */ |
460 | 0 | static void fmt_orbit_correction(char *label, int16_t c) { |
461 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-5 m", c); |
462 | 0 | } |
463 | | |
464 | | /* Format semi-circles (with 2^-31 scale factor) for |
465 | | * - mean anomaly at reference time |
466 | | * - longitude of ascending node of orbital plane at weekly epoch |
467 | | * - inclination angle at reference time |
468 | | * - argument of perigee |
469 | | */ |
470 | 0 | static void fmt_semi_circles(char *label, int32_t c) { |
471 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-31 semi-circles", c); |
472 | 0 | } |
473 | | |
474 | | /* Format rate of semi-circles (with 2^-43 scale factor) for |
475 | | * - inclination angle |
476 | | * - right ascension |
477 | | * - mean motion difference |
478 | | */ |
479 | 0 | void fmt_semi_circles_rate(char *label, int32_t c) { |
480 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-43 semi-circles/s", c); |
481 | 0 | } |
482 | | |
483 | | /* Format SISA */ |
484 | 0 | static void fmt_sisa(char *label, uint8_t i) { |
485 | 0 | if (i <= 49) { |
486 | | // 0 cm to 49 cm with 1 cm resolution |
487 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%u cm", i); |
488 | 0 | } |
489 | 0 | else if (i <= 74) { |
490 | | // 50 cm to 98 cm with 2 cm resolution |
491 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%u cm", 50 + ((i - 50) * 2)); |
492 | 0 | } |
493 | 0 | else if (i <= 99) { |
494 | | // 100 cm to 196 cm with 4 cm resolution |
495 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%u cm", 100 + ((i - 75) * 4)); |
496 | 0 | } |
497 | 0 | else if (i <= 125) { |
498 | | // 200 cm to 600 cm with 16 cm resolution |
499 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%u cm", 200 + ((i - 100) * 16)); |
500 | 0 | } |
501 | 0 | else if (i <= 254) { |
502 | | // Spare |
503 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "Spare"); |
504 | 0 | } |
505 | 0 | else { // i == 255 |
506 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "No Accuracy Prediction Available (NAPA)"); |
507 | 0 | } |
508 | 0 | } |
509 | | |
510 | | /* Format SV clock bias (with 2^-34 scale factor) for |
511 | | * a_f0 |
512 | | */ |
513 | 0 | static void fmt_sv_clk_bias(char *label, int32_t c) { |
514 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-34 s", c); |
515 | 0 | } |
516 | | |
517 | | /* Format SV clock drift (with 2^-46 scale factor) for |
518 | | * a_f1 |
519 | | */ |
520 | 0 | static void fmt_sv_clk_drift(char *label, int32_t c) { |
521 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-46 s/s", c); |
522 | 0 | } |
523 | | |
524 | | /* Format SV clock drift rate (with 2^-59 scale factor) for |
525 | | * a_f1 |
526 | | */ |
527 | 0 | static void fmt_sv_clk_drift_rate(char *label, int32_t c) { |
528 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%d * 2^-59 s/s" UTF8_SUPERSCRIPT_TWO, c); |
529 | 0 | } |
530 | | |
531 | | /* Format eccentricity */ |
532 | 0 | static void fmt_e(char *label, uint64_t c) { |
533 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%" PRIu64 " * 2^-33", c); |
534 | 0 | } |
535 | | |
536 | | /* Format square root of the semi-major axis */ |
537 | 0 | static void fmt_sqrt_a(char *label, uint64_t c) { |
538 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%" PRIu64 " * 2^-19 " UTF8_SQUARE_ROOT "m", c); |
539 | 0 | } |
540 | | |
541 | | /* Format ephemeris reference time */ |
542 | 0 | static void fmt_t0e(char *label, uint32_t c) { |
543 | 0 | c = c * 60; |
544 | 0 | snprintf(label, ITEM_LABEL_LENGTH, "%ds", c); |
545 | 0 | } |
546 | | |
547 | | /* Dissect Galileo E1-B I/NAV navigation message */ |
548 | 0 | static int dissect_ubx_gal_inav(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { |
549 | 0 | tvbuff_t *next_tvb; |
550 | |
|
551 | 0 | bool complete_hkroot_mack = false; |
552 | 0 | bool sar_start, sar_long_rlm; |
553 | 0 | uint32_t inav_type = 0, even_page_type, odd_page_type, hkroot, sar_rlm_data; |
554 | 0 | uint64_t mack; |
555 | 0 | uint32_t dsm_id, dsm_blk_id, dsm_ks; |
556 | 0 | uint64_t data_122_67 = 0, data_66_17 = 0, data_16_1 = 0; |
557 | 0 | uint8_t *word, *hkroot_msg, *dsm_buf, *mack_msg; |
558 | 0 | osnma_hkroot_mack_msg_part *osnma_hkroot_mack_msg_parts = NULL; |
559 | 0 | osnma_dsm_blk *osnma_dsm_blks = NULL; |
560 | 0 | sar_rlm_part *sar_rlm_parts = NULL; |
561 | 0 | size_t i; |
562 | |
|
563 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Galileo E1-B I/NAV"); |
564 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
565 | |
|
566 | 0 | proto_tree *gal_inav_tree = proto_tree_add_subtree(tree, tvb, 0, 32, ett_ubx_gal_inav, NULL, "Galileo E1-B I/NAV"); |
567 | | |
568 | | // even page |
569 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_even_odd, tvb, 0, 1, ENC_NA); |
570 | 0 | proto_tree_add_item_ret_uint(gal_inav_tree, hf_ubx_gal_inav_page_type, tvb, 0, 1, ENC_NA, &even_page_type); |
571 | |
|
572 | 0 | if (even_page_type == 1) { // alert page |
573 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_reserved_1, tvb, 0, 15, ENC_NA); |
574 | 0 | } |
575 | 0 | else if (even_page_type == 0) { // nominal page |
576 | 0 | proto_tree_add_item_ret_uint(gal_inav_tree, hf_ubx_gal_inav_type, tvb, 0, 1, ENC_NA, &inav_type); |
577 | 0 | 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); |
578 | 0 | 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); |
579 | 0 | } |
580 | |
|
581 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_tail, tvb, 14, 1, ENC_NA); |
582 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_pad, tvb, 15, 1, ENC_NA); |
583 | | |
584 | | |
585 | | // odd page |
586 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_even_odd, tvb, 16, 1, ENC_NA); |
587 | 0 | proto_tree_add_item_ret_uint(gal_inav_tree, hf_ubx_gal_inav_page_type, tvb, 16, 1, ENC_NA, &odd_page_type); |
588 | |
|
589 | 0 | if (odd_page_type == 1) { // alert page |
590 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_reserved_1, tvb, 16, 11, ENC_NA); |
591 | 0 | } |
592 | 0 | else if (odd_page_type == 0) { // nominal page |
593 | 0 | uint8_t *svid = (uint8_t *) data; |
594 | |
|
595 | 0 | 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); |
596 | |
|
597 | 0 | proto_tree *osnma_tree = proto_tree_add_subtree(gal_inav_tree, tvb, 18, 6, ett_ubx_gal_inav_osnma, NULL, "OSNMA"); |
598 | 0 | proto_tree_add_item_ret_uint(osnma_tree, hf_ubx_gal_inav_osnma_hkroot, tvb, 18, 4, ENC_BIG_ENDIAN, &hkroot); |
599 | 0 | proto_tree_add_item_ret_uint64(osnma_tree, hf_ubx_gal_inav_osnma_mack, tvb, 18, 8, ENC_BIG_ENDIAN, &mack); |
600 | | |
601 | | // manage OSNMA HKROOT & MACK messages via conversations |
602 | 0 | if (svid != NULL && even_page_type == 0 && (hkroot != 0 || mack != 0)) { |
603 | | // try to find already existing conversation |
604 | 0 | conversation_element_t constellation = {.type = CE_INT, .int_val = GNSS_ID_GALILEO}; |
605 | 0 | conversation_element_t type = {.type = CE_INT, .int_val = CONVERSATION_OSNMA_HKROOT_MACK}; |
606 | 0 | conversation_element_t prn = {.type = CE_INT, .int_val = *svid}; |
607 | 0 | conversation_element_t end = {.type = CE_CONVERSATION_TYPE, .conversation_type_val = CONVERSATION_GNSS}; |
608 | 0 | conversation_element_t ce[4] = {constellation, type, prn, end}; |
609 | 0 | conversation_t *c = find_conversation_full(pinfo->num, ce); |
610 | |
|
611 | 0 | if (c == NULL && inav_type == 2) { |
612 | | // No conversation found, but the current Word Type is 2. |
613 | | // As Word Type 2 nominally starts a sub-frame, start a new conversation. |
614 | | // TODO: Detect a new sub-frame based on GST (or, at least, cross-check against GST). |
615 | 0 | c = conversation_new_full(pinfo->num, ce); |
616 | |
|
617 | 0 | osnma_hkroot_mack_msg_parts = (osnma_hkroot_mack_msg_part *) wmem_alloc0_array(wmem_file_scope(), osnma_hkroot_mack_msg_part, OSNMA_HKROOT_MACK_MSG_PARTS_NUM); |
618 | |
|
619 | 0 | osnma_hkroot_mack_msg_parts[0].frame = pinfo->num; |
620 | 0 | osnma_hkroot_mack_msg_parts[0].hkroot = hkroot; |
621 | 0 | osnma_hkroot_mack_msg_parts[0].mack = (uint32_t) mack; |
622 | |
|
623 | 0 | conversation_add_proto_data(c, proto_ubx_gal_inav, osnma_hkroot_mack_msg_parts); |
624 | 0 | } |
625 | 0 | else if (c != NULL && inav_type == 2) { |
626 | | // Check whether the conversation found starts at the current frame. |
627 | | // (If not, a new conversation needs to be created as the Word Type is 2, which nominally indicates a new sub-frame.) |
628 | | // TODO: Detect a new sub-frame based on GST (or, at least, cross-check against GST). |
629 | 0 | osnma_hkroot_mack_msg_parts = (osnma_hkroot_mack_msg_part *) conversation_get_proto_data(c, proto_ubx_gal_inav); |
630 | |
|
631 | 0 | if (osnma_hkroot_mack_msg_parts != NULL && osnma_hkroot_mack_msg_parts[0].frame != pinfo->num) { |
632 | | // Separate conversation found, start a new one. |
633 | 0 | c = conversation_new_full(pinfo->num, ce); |
634 | |
|
635 | 0 | osnma_hkroot_mack_msg_parts = (osnma_hkroot_mack_msg_part *) wmem_alloc0_array(wmem_file_scope(), osnma_hkroot_mack_msg_part, OSNMA_HKROOT_MACK_MSG_PARTS_NUM); |
636 | |
|
637 | 0 | osnma_hkroot_mack_msg_parts[0].frame = pinfo->num; |
638 | 0 | osnma_hkroot_mack_msg_parts[0].hkroot = hkroot; |
639 | 0 | osnma_hkroot_mack_msg_parts[0].mack = (uint32_t) mack; |
640 | |
|
641 | 0 | conversation_add_proto_data(c, proto_ubx_gal_inav, osnma_hkroot_mack_msg_parts); |
642 | 0 | } |
643 | 0 | } |
644 | 0 | else if (c != NULL) { |
645 | | // Check whether packet data still needs to be added to the conversation. |
646 | 0 | osnma_hkroot_mack_msg_parts = (osnma_hkroot_mack_msg_part *) conversation_get_proto_data(c, proto_ubx_gal_inav); |
647 | |
|
648 | 0 | if (osnma_hkroot_mack_msg_parts) { |
649 | | // TODO: Detecting the slot of the HKROOT/MACK part should be based on GST. |
650 | | // TODO: Cross-check whether identified slot matches nominal Word Type schedule. |
651 | 0 | for (i = 0; i < OSNMA_HKROOT_MACK_MSG_PARTS_NUM; i++) { |
652 | 0 | if (osnma_hkroot_mack_msg_parts[i].frame == 0) { |
653 | 0 | osnma_hkroot_mack_msg_parts[i].frame = pinfo->num; |
654 | 0 | osnma_hkroot_mack_msg_parts[i].hkroot = hkroot; |
655 | 0 | osnma_hkroot_mack_msg_parts[i].mack = (uint32_t) mack; |
656 | 0 | break; |
657 | 0 | } |
658 | 0 | else if (osnma_hkroot_mack_msg_parts[i].frame == pinfo->num) { |
659 | 0 | break; |
660 | 0 | } |
661 | 0 | } |
662 | 0 | } |
663 | 0 | } |
664 | | |
665 | | // display OSNMA HKROOT and MACK message if all parts are available |
666 | 0 | if (c != NULL && osnma_hkroot_mack_msg_parts != NULL) { |
667 | 0 | for (i = 0; i < OSNMA_HKROOT_MACK_MSG_PARTS_NUM; i++) { |
668 | 0 | if (osnma_hkroot_mack_msg_parts[i].frame == 0) { |
669 | 0 | break; |
670 | 0 | } |
671 | 0 | } |
672 | |
|
673 | 0 | if (i == OSNMA_HKROOT_MACK_MSG_PARTS_NUM) { |
674 | | // All parts of an OSNMA HKROOT & MACK message are available in the conversation. |
675 | 0 | complete_hkroot_mack = true; |
676 | | |
677 | | // Now dissect them. |
678 | | |
679 | | // reserve buffer for OSNMA HKROOT message |
680 | 0 | hkroot_msg = wmem_alloc(pinfo->pool, OSNMA_HKROOT_MSG_LENGTH); |
681 | | |
682 | | // fill buffer with OSNMA HKROOT parts |
683 | 0 | for (i = 0; i < OSNMA_HKROOT_MACK_MSG_PARTS_NUM; i++) { |
684 | 0 | hkroot_msg[i] = osnma_hkroot_mack_msg_parts[i].hkroot; |
685 | 0 | } |
686 | |
|
687 | 0 | tvbuff_t *osnma_hkroot_msg_tvb = tvb_new_child_real_data(tvb, (uint8_t *)hkroot_msg, OSNMA_HKROOT_MSG_LENGTH, OSNMA_HKROOT_MSG_LENGTH); |
688 | 0 | add_new_data_source(pinfo, osnma_hkroot_msg_tvb, "Galileo E1-B I/NAV OSNMA HKROOT Message"); |
689 | | |
690 | | // dissect OSNMA HKROOT message |
691 | 0 | proto_tree *osnma_hkroot_msg_tree = proto_tree_add_subtree(osnma_tree, osnma_hkroot_msg_tvb, 0, OSNMA_HKROOT_MSG_LENGTH, ett_ubx_gal_inav_osnma_hkroot_msg, NULL, "HKROOT Message (re-assembled)"); |
692 | |
|
693 | 0 | proto_tree_add_item(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_nmas, osnma_hkroot_msg_tvb, 0, 1, ENC_NA); |
694 | 0 | proto_tree_add_item(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_cid, osnma_hkroot_msg_tvb, 0, 1, ENC_NA); |
695 | 0 | proto_tree_add_item(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_cpks, osnma_hkroot_msg_tvb, 0, 1, ENC_NA); |
696 | 0 | proto_tree_add_item(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_reserved, osnma_hkroot_msg_tvb, 0, 1, ENC_NA); |
697 | 0 | proto_tree_add_item_ret_uint(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_dsm_id, osnma_hkroot_msg_tvb, 1, 1, ENC_NA, &dsm_id); |
698 | 0 | proto_tree_add_item_ret_uint(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_dsm_blk_id, osnma_hkroot_msg_tvb, 1, 1, ENC_NA, &dsm_blk_id); |
699 | 0 | proto_tree_add_item(osnma_hkroot_msg_tree, hf_ubx_gal_inav_osnma_dsm_blk, osnma_hkroot_msg_tvb, 2, 13, ENC_NA); |
700 | | |
701 | | |
702 | | // reserve buffer for OSNMA MACK message |
703 | 0 | mack_msg = wmem_alloc(pinfo->pool, OSNMA_MACK_MSG_LENGTH); |
704 | | |
705 | | // fill buffer with OSNMA MACK parts |
706 | 0 | for (i = 0; i < OSNMA_HKROOT_MACK_MSG_PARTS_NUM; i++) { |
707 | 0 | phtonu32(&mack_msg[i * 4], osnma_hkroot_mack_msg_parts[i].mack); |
708 | 0 | } |
709 | |
|
710 | 0 | tvbuff_t *osnma_mack_msg_tvb = tvb_new_child_real_data(tvb, (uint8_t *)mack_msg, OSNMA_MACK_MSG_LENGTH, OSNMA_MACK_MSG_LENGTH); |
711 | 0 | add_new_data_source(pinfo, osnma_mack_msg_tvb, "Galileo E1-B I/NAV OSNMA MACK Message"); |
712 | | |
713 | | // dissect OSNMA MACK message |
714 | 0 | proto_tree *osnma_mack_msg_tree = proto_tree_add_subtree(osnma_tree, osnma_mack_msg_tvb, 0, OSNMA_MACK_MSG_LENGTH, ett_ubx_gal_inav_osnma_mack_msg, NULL, "MACK Message (re-assembled)"); |
715 | | |
716 | | // TODO: The key and tag size should be determined based on DSM-KROOT. |
717 | | // Assuming key size of 128 bits and tag size of 40 bits for now (being the sizes used by GAL). |
718 | 0 | uint32_t key_size = 128; |
719 | 0 | uint32_t tag_size = 40; |
720 | 0 | proto_tree_add_item(osnma_mack_msg_tree, hf_ubx_gal_inav_osnma_tag0, osnma_mack_msg_tvb, 0, tag_size/8, ENC_NA); |
721 | 0 | proto_tree_add_item(osnma_mack_msg_tree, hf_ubx_gal_inav_osnma_macseq, osnma_mack_msg_tvb, tag_size/8, 2, ENC_BIG_ENDIAN); |
722 | 0 | proto_tree_add_item(osnma_mack_msg_tree, hf_ubx_gal_inav_osnma_cop, osnma_mack_msg_tvb, tag_size/8 + 1, 1, ENC_NA); |
723 | |
|
724 | 0 | uint32_t no_tags = (480 - key_size) / (tag_size + 16); |
725 | 0 | for (i = 0; i < no_tags - 1; i++) { |
726 | 0 | proto_tree *osnma_mack_tag_tree = proto_tree_add_subtree(osnma_mack_msg_tree, osnma_mack_msg_tvb, (((uint32_t)i + 1) * (tag_size + 16))/8, (tag_size + 16) / 8, ett_ubx_gal_inav_osnma_mack_tag[i], NULL, "MACK Tag"); |
727 | 0 | proto_tree_add_item(osnma_mack_tag_tree, hf_ubx_gal_inav_osnma_tag, osnma_mack_msg_tvb, (((uint32_t)i + 1) * (tag_size + 16))/8, tag_size/8, ENC_NA); |
728 | 0 | proto_tree_add_item(osnma_mack_tag_tree, hf_ubx_gal_inav_osnma_prn_d, osnma_mack_msg_tvb, (((uint32_t)i + 1) * (tag_size + 16) + tag_size)/8, 1, ENC_NA); |
729 | 0 | proto_tree_add_item(osnma_mack_tag_tree, hf_ubx_gal_inav_osnma_adkd, osnma_mack_msg_tvb, (((uint32_t)i + 1) * (tag_size + 16) + tag_size)/8 + 1, 1, ENC_NA); |
730 | 0 | proto_tree_add_item(osnma_mack_tag_tree, hf_ubx_gal_inav_osnma_cop, osnma_mack_msg_tvb, (((uint32_t)i + 1) * (tag_size + 16) + tag_size)/8 + 1, 1, ENC_NA); |
731 | 0 | } |
732 | |
|
733 | 0 | proto_tree_add_item(osnma_mack_msg_tree, hf_ubx_gal_inav_osnma_key, osnma_mack_msg_tvb, (no_tags * (tag_size + 16))/8, key_size/8, ENC_NA); |
734 | 0 | proto_tree_add_item(osnma_mack_msg_tree, hf_ubx_gal_inav_osnma_padding, osnma_mack_msg_tvb, (no_tags * (tag_size + 16) + key_size)/8, OSNMA_MACK_MSG_LENGTH - (no_tags * (tag_size + 16) + key_size)/8, ENC_NA); |
735 | 0 | } |
736 | 0 | } |
737 | 0 | } |
738 | | |
739 | | // manage OSNMA DSM via conversations (if a HKROOT message was re-assembled) |
740 | 0 | if (complete_hkroot_mack) { |
741 | | // try to find already existing conversation |
742 | 0 | conversation_element_t constellation = {.type = CE_INT, .int_val = GNSS_ID_GALILEO}; |
743 | 0 | conversation_element_t type = {.type = CE_INT, .int_val = CONVERSATION_OSNMA_DSM}; |
744 | 0 | conversation_element_t dsm = {.type = CE_INT, .int_val = dsm_id}; |
745 | 0 | conversation_element_t end = {.type = CE_CONVERSATION_TYPE, .conversation_type_val = CONVERSATION_GNSS}; |
746 | 0 | conversation_element_t ce[4] = {constellation, type, dsm, end}; |
747 | 0 | conversation_t *c = find_conversation_full(pinfo->num, ce); |
748 | | |
749 | | // TODO: Add logic to detect and manage DSM ID roll-over |
750 | 0 | if (c == NULL) { |
751 | | // No conversation found. Start a new one. |
752 | 0 | c = conversation_new_full(pinfo->num, ce); |
753 | |
|
754 | 0 | osnma_dsm_blks = (osnma_dsm_blk *) wmem_alloc0_array(wmem_file_scope(), osnma_dsm_blk, OSNMA_DSM_BLK_NUM); |
755 | |
|
756 | 0 | conversation_add_proto_data(c, proto_ubx_gal_inav, osnma_dsm_blks); |
757 | 0 | } |
758 | 0 | else { |
759 | 0 | osnma_dsm_blks = (osnma_dsm_blk *) conversation_get_proto_data(c, proto_ubx_gal_inav); |
760 | 0 | } |
761 | |
|
762 | 0 | if (osnma_dsm_blks != NULL) { |
763 | | |
764 | | // store block |
765 | 0 | osnma_dsm_blks[dsm_blk_id].set = true; |
766 | 0 | memcpy(osnma_dsm_blks[dsm_blk_id].blk, &hkroot_msg[2], OSNMA_DSM_BLK_LENGTH); |
767 | | |
768 | | // If first block of a DSM has been received, continue processing. |
769 | 0 | if (osnma_dsm_blks[0].set && 0 < osnma_dsm_blks[0].blk[0]) { |
770 | | |
771 | | // Count the number of sequential blocks received. |
772 | 0 | uint8_t dsm_blk_count = 0; |
773 | 0 | for (i = 0; i < OSNMA_DSM_BLK_NUM; i++) { |
774 | 0 | if (osnma_dsm_blks[i].set) { |
775 | 0 | dsm_blk_count++; |
776 | 0 | } |
777 | 0 | else { |
778 | 0 | break; |
779 | 0 | } |
780 | 0 | } |
781 | | |
782 | | // Compare number of received blocks against NB_DP / NB_DK in block 0. |
783 | 0 | if (dsm_blk_count == (osnma_dsm_blks[0].blk[0] >> 4) + 6) { |
784 | | // All blocks for a DSM have been received. |
785 | | // Now dissect it. |
786 | |
|
787 | 0 | dsm_buf = wmem_alloc(pinfo->pool, dsm_blk_count * OSNMA_DSM_BLK_LENGTH); |
788 | 0 | for (i = 0; i < dsm_blk_count; i++) { |
789 | 0 | memcpy(&dsm_buf[i * OSNMA_DSM_BLK_LENGTH], osnma_dsm_blks[i].blk, OSNMA_DSM_BLK_LENGTH); |
790 | 0 | } |
791 | 0 | tvbuff_t *osnma_dsm_tvb = tvb_new_child_real_data(tvb, (uint8_t *)dsm_buf, dsm_blk_count * OSNMA_DSM_BLK_LENGTH, dsm_blk_count * OSNMA_DSM_BLK_LENGTH); |
792 | 0 | add_new_data_source(pinfo, osnma_dsm_tvb, "Galileo E1-B I/NAV OSNMA DSM"); |
793 | | |
794 | |
|
795 | 0 | if (dsm_id < 12) { |
796 | | // dissect DSM-KROOT |
797 | 0 | uint32_t dk_len = dsm_blk_count * OSNMA_DSM_BLK_LENGTH; |
798 | |
|
799 | 0 | proto_tree *osnma_dsm_tree = proto_tree_add_subtree(osnma_tree, osnma_dsm_tvb, 0, dk_len, ett_ubx_gal_inav_osnma_dsm, NULL, "DSM-KROOT (re-assembled)"); |
800 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_nb_dk, osnma_dsm_tvb, 0, 1, ENC_NA); |
801 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_pkid, osnma_dsm_tvb, 0, 1, ENC_NA); |
802 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_cidkr, osnma_dsm_tvb, 1, 1, ENC_NA); |
803 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_reserved1, osnma_dsm_tvb, 1, 1, ENC_NA); |
804 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_hf, osnma_dsm_tvb, 1, 1, ENC_NA); |
805 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_mf, osnma_dsm_tvb, 1, 1, ENC_NA); |
806 | 0 | proto_tree_add_item_ret_uint(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_ks, osnma_dsm_tvb, 2, 1, ENC_NA, &dsm_ks); |
807 | 0 | uint32_t ks_len = ks2len(dsm_ks); |
808 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_ts, osnma_dsm_tvb, 2, 1, ENC_NA); |
809 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_maclt, osnma_dsm_tvb, 3, 1, ENC_NA); |
810 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_reserved2, osnma_dsm_tvb, 4, 1, ENC_NA); |
811 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_wn_k, osnma_dsm_tvb, 4, 2, ENC_BIG_ENDIAN); |
812 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_towh_k, osnma_dsm_tvb, 6, 1, ENC_NA); |
813 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_alpha, osnma_dsm_tvb, 7, 6, ENC_NA); |
814 | 0 | if (ks_len > 0) { |
815 | | // TODO: The length of the digital signature should be derived from the DSM-PKR NPKT with matching PKID. |
816 | 0 | uint32_t ds_len = 64; |
817 | 0 | uint32_t p_dk_len = dk_len - 13 - ks_len - ds_len; |
818 | |
|
819 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_kroot, osnma_dsm_tvb, 13, ks_len, ENC_NA); |
820 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_ds, osnma_dsm_tvb, 13 + ks_len, ds_len, ENC_NA); |
821 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_p_dk, osnma_dsm_tvb, 13 + ks_len + ds_len, p_dk_len, ENC_NA); |
822 | 0 | } |
823 | 0 | } |
824 | 0 | else { |
825 | | // dissect DSM-PKR |
826 | 0 | uint32_t dsm_nb_dp, dsm_mid, dsm_npkt, l_npk, l_pdp; |
827 | |
|
828 | 0 | proto_tree *osnma_dsm_tree = proto_tree_add_subtree(osnma_tree, osnma_dsm_tvb, 0, dsm_blk_count * OSNMA_DSM_BLK_LENGTH, ett_ubx_gal_inav_osnma_dsm, NULL, "DSM-PKR (re-assembled)"); |
829 | 0 | proto_tree_add_item_ret_uint(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_nb_dp, osnma_dsm_tvb, 0, 1, ENC_NA, &dsm_nb_dp); |
830 | 0 | proto_tree_add_item_ret_uint(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_mid, osnma_dsm_tvb, 0, 1, ENC_NA, &dsm_mid); |
831 | |
|
832 | 0 | switch (dsm_mid) { |
833 | 0 | case 0: |
834 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_1, osnma_dsm_tvb, 1, 32, ENC_NA); |
835 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_1, osnma_dsm_tvb, 33, 32, ENC_NA); |
836 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_1, osnma_dsm_tvb, 65, 32, ENC_NA); |
837 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
838 | 0 | break; |
839 | 0 | case 1: |
840 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_0, osnma_dsm_tvb, 1, 32, ENC_NA); |
841 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_1, osnma_dsm_tvb, 33, 32, ENC_NA); |
842 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_1, osnma_dsm_tvb, 65, 32, ENC_NA); |
843 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
844 | 0 | break; |
845 | 0 | case 2: |
846 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_3, osnma_dsm_tvb, 1, 32, ENC_NA); |
847 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_0, osnma_dsm_tvb, 33, 32, ENC_NA); |
848 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_1, osnma_dsm_tvb, 65, 32, ENC_NA); |
849 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
850 | 0 | break; |
851 | 0 | case 3: |
852 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_2, osnma_dsm_tvb, 1, 32, ENC_NA); |
853 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_0, osnma_dsm_tvb, 33, 32, ENC_NA); |
854 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_1, osnma_dsm_tvb, 65, 32, ENC_NA); |
855 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
856 | 0 | break; |
857 | 0 | case 4: |
858 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_5, osnma_dsm_tvb, 1, 32, ENC_NA); |
859 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_3, osnma_dsm_tvb, 33, 32, ENC_NA); |
860 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_0, osnma_dsm_tvb, 65, 32, ENC_NA); |
861 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
862 | 0 | break; |
863 | 0 | case 5: |
864 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_4, osnma_dsm_tvb, 1, 32, ENC_NA); |
865 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_3, osnma_dsm_tvb, 33, 32, ENC_NA); |
866 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_0, osnma_dsm_tvb, 65, 32, ENC_NA); |
867 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
868 | 0 | break; |
869 | 0 | case 6: |
870 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_7, osnma_dsm_tvb, 1, 32, ENC_NA); |
871 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_2, osnma_dsm_tvb, 33, 32, ENC_NA); |
872 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_0, osnma_dsm_tvb, 65, 32, ENC_NA); |
873 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
874 | 0 | break; |
875 | 0 | case 7: |
876 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_6, osnma_dsm_tvb, 1, 32, ENC_NA); |
877 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_2, osnma_dsm_tvb, 33, 32, ENC_NA); |
878 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_0, osnma_dsm_tvb, 65, 32, ENC_NA); |
879 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_1, osnma_dsm_tvb, 97, 32, ENC_NA); |
880 | 0 | break; |
881 | 0 | case 8: |
882 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_9, osnma_dsm_tvb, 1, 32, ENC_NA); |
883 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_5, osnma_dsm_tvb, 33, 32, ENC_NA); |
884 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_3, osnma_dsm_tvb, 65, 32, ENC_NA); |
885 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
886 | 0 | break; |
887 | 0 | case 9: |
888 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_8, osnma_dsm_tvb, 1, 32, ENC_NA); |
889 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_5, osnma_dsm_tvb, 33, 32, ENC_NA); |
890 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_3, osnma_dsm_tvb, 65, 32, ENC_NA); |
891 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
892 | 0 | break; |
893 | 0 | case 10: |
894 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_11, osnma_dsm_tvb, 1, 32, ENC_NA); |
895 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_4, osnma_dsm_tvb, 33, 32, ENC_NA); |
896 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_3, osnma_dsm_tvb, 65, 32, ENC_NA); |
897 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
898 | 0 | break; |
899 | 0 | case 11: |
900 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_10, osnma_dsm_tvb, 1, 32, ENC_NA); |
901 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_4, osnma_dsm_tvb, 33, 32, ENC_NA); |
902 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_3, osnma_dsm_tvb, 65, 32, ENC_NA); |
903 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
904 | 0 | break; |
905 | 0 | case 12: |
906 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_13, osnma_dsm_tvb, 1, 32, ENC_NA); |
907 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_7, osnma_dsm_tvb, 33, 32, ENC_NA); |
908 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_2, osnma_dsm_tvb, 65, 32, ENC_NA); |
909 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
910 | 0 | break; |
911 | 0 | case 13: |
912 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_12, osnma_dsm_tvb, 1, 32, ENC_NA); |
913 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_7, osnma_dsm_tvb, 33, 32, ENC_NA); |
914 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_2, osnma_dsm_tvb, 65, 32, ENC_NA); |
915 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
916 | 0 | break; |
917 | 0 | case 14: |
918 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_15, osnma_dsm_tvb, 1, 32, ENC_NA); |
919 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_6, osnma_dsm_tvb, 33, 32, ENC_NA); |
920 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_2, osnma_dsm_tvb, 65, 32, ENC_NA); |
921 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
922 | 0 | break; |
923 | 0 | case 15: |
924 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_0_14, osnma_dsm_tvb, 1, 32, ENC_NA); |
925 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_1_6, osnma_dsm_tvb, 33, 32, ENC_NA); |
926 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_2_2, osnma_dsm_tvb, 65, 32, ENC_NA); |
927 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_x_3_0, osnma_dsm_tvb, 97, 32, ENC_NA); |
928 | 0 | break; |
929 | 0 | default: |
930 | 0 | break; |
931 | 0 | } |
932 | | |
933 | 0 | proto_tree_add_item_ret_uint(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_npkt, osnma_dsm_tvb, 129, 1, ENC_NA, &dsm_npkt); |
934 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_npkid, osnma_dsm_tvb, 129, 1, ENC_NA); |
935 | | |
936 | | // compute field lengths |
937 | 0 | if (7 <= dsm_nb_dp && dsm_nb_dp <= 10 && (dsm_npkt == 1 || dsm_npkt == 3 || dsm_npkt == 4)) { |
938 | 0 | if (dsm_npkt == 1) { // ECDSA P-256 |
939 | 0 | l_npk = 264; |
940 | 0 | } |
941 | 0 | else if (dsm_npkt == 4) { // ECDSA P-521 |
942 | 0 | l_npk = 536; |
943 | 0 | } |
944 | 0 | else { // OSNMA Alert Message |
945 | 0 | l_npk = ((dsm_nb_dp + 6) * 104) - 1040; // = l_PK_OAM |
946 | 0 | } |
947 | |
|
948 | 0 | l_pdp = ((dsm_nb_dp + 6) * 104) - 1040 - l_npk; |
949 | |
|
950 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_npk, osnma_dsm_tvb, 130, l_npk / 8, ENC_NA); |
951 | 0 | proto_tree_add_item(osnma_dsm_tree, hf_ubx_gal_inav_osnma_dsm_p_dp, osnma_dsm_tvb, 130 + (l_npk / 8), l_pdp / 8, ENC_NA); |
952 | 0 | } |
953 | 0 | } |
954 | 0 | } |
955 | 0 | } |
956 | 0 | } |
957 | 0 | } |
958 | | |
959 | 0 | proto_tree *sar_tree = proto_tree_add_subtree(gal_inav_tree, tvb, 23, 4, ett_ubx_gal_inav_sar, NULL, "SAR"); |
960 | 0 | proto_tree_add_item_ret_boolean(sar_tree, hf_ubx_gal_inav_sar_start_bit, tvb, 23, 4, ENC_BIG_ENDIAN, &sar_start); |
961 | 0 | proto_tree_add_item_ret_boolean(sar_tree, hf_ubx_gal_inav_sar_long_rlm, tvb, 23, 4, ENC_BIG_ENDIAN, &sar_long_rlm); |
962 | 0 | proto_tree_add_item_ret_uint(sar_tree, hf_ubx_gal_inav_sar_rlm_data, tvb, 23, 4, ENC_BIG_ENDIAN, &sar_rlm_data); |
963 | | |
964 | | // manage SAR RLM parts via conversations |
965 | 0 | if (svid != NULL) { |
966 | | |
967 | | // try to find already existing conversation |
968 | 0 | conversation_element_t constellation = {.type = CE_INT, .int_val = GNSS_ID_GALILEO}; |
969 | 0 | conversation_element_t type = {.type = CE_INT, .int_val = CONVERSATION_SAR_RLM}; |
970 | 0 | conversation_element_t prn = {.type = CE_INT, .int_val = *svid}; |
971 | 0 | conversation_element_t end = {.type = CE_CONVERSATION_TYPE, .conversation_type_val = CONVERSATION_GNSS}; |
972 | 0 | conversation_element_t ce[4] = {constellation, type, prn, end}; |
973 | 0 | conversation_t *c = find_conversation_full(pinfo->num, ce); |
974 | |
|
975 | 0 | if (c == NULL && sar_start) { |
976 | | // No conversation found. As the start bit is set, start a new one. |
977 | 0 | c = conversation_new_full(pinfo->num, ce); |
978 | |
|
979 | 0 | sar_rlm_parts = (sar_rlm_part *) wmem_alloc0_array(wmem_file_scope(), sar_rlm_part, sar_long_rlm ? SAR_LONG_RLM_PARTS_NUM : SAR_SHORT_RLM_PARTS_NUM); |
980 | |
|
981 | 0 | sar_rlm_parts[0].frame = pinfo->num; |
982 | 0 | sar_rlm_parts[0].long_rlm = sar_long_rlm; |
983 | 0 | sar_rlm_parts[0].rlm_data = sar_rlm_data; |
984 | |
|
985 | 0 | conversation_add_proto_data(c, proto_ubx_gal_inav, sar_rlm_parts); |
986 | 0 | } |
987 | 0 | else if (c != NULL && sar_start) { |
988 | | // Check whether the conversation found starts at the |
989 | | // current frame. (If not, a new conversation needs to be |
990 | | // created as the start bit is set. |
991 | 0 | sar_rlm_parts = (sar_rlm_part *) conversation_get_proto_data(c, proto_ubx_gal_inav); |
992 | |
|
993 | 0 | if (sar_rlm_parts != NULL && sar_rlm_parts[0].frame != pinfo->num) { |
994 | | // Separate conversation found, start a new one. |
995 | 0 | c = conversation_new_full(pinfo->num, ce); |
996 | |
|
997 | 0 | sar_rlm_parts = (sar_rlm_part *) wmem_alloc0_array(wmem_file_scope(), sar_rlm_part, sar_long_rlm ? SAR_LONG_RLM_PARTS_NUM : SAR_SHORT_RLM_PARTS_NUM); |
998 | |
|
999 | 0 | sar_rlm_parts[0].frame = pinfo->num; |
1000 | 0 | sar_rlm_parts[0].long_rlm = sar_long_rlm; |
1001 | 0 | sar_rlm_parts[0].rlm_data = sar_rlm_data; |
1002 | |
|
1003 | 0 | conversation_add_proto_data(c, proto_ubx_gal_inav, sar_rlm_parts); |
1004 | 0 | } |
1005 | |
|
1006 | 0 | } |
1007 | 0 | else if (c != NULL) { |
1008 | | // Check whether packet data still needs to be added to the conversation. |
1009 | 0 | sar_rlm_parts = (sar_rlm_part *) conversation_get_proto_data(c, proto_ubx_gal_inav); |
1010 | |
|
1011 | 0 | if (sar_rlm_parts != NULL && sar_rlm_parts[0].long_rlm == sar_long_rlm) { |
1012 | 0 | for (i = 0; i < (sar_long_rlm ? SAR_LONG_RLM_PARTS_NUM : SAR_SHORT_RLM_PARTS_NUM); i++) { |
1013 | 0 | if (sar_rlm_parts[i].frame == 0) { |
1014 | 0 | sar_rlm_parts[i].frame = pinfo->num; |
1015 | 0 | sar_rlm_parts[i].long_rlm = sar_long_rlm; |
1016 | 0 | sar_rlm_parts[i].rlm_data = sar_rlm_data; |
1017 | 0 | break; |
1018 | 0 | } |
1019 | 0 | else if (sar_rlm_parts[i].frame == pinfo->num) { |
1020 | 0 | break; |
1021 | 0 | } |
1022 | 0 | } |
1023 | 0 | } |
1024 | 0 | } |
1025 | | |
1026 | | // display SAR RLM if all parts are available |
1027 | 0 | if (c != NULL && sar_rlm_parts != NULL) { |
1028 | 0 | for (i = 0; i < (sar_long_rlm ? SAR_LONG_RLM_PARTS_NUM : SAR_SHORT_RLM_PARTS_NUM); i++) { |
1029 | 0 | if (sar_rlm_parts[i].frame == 0) { |
1030 | 0 | break; |
1031 | 0 | } |
1032 | 0 | } |
1033 | |
|
1034 | 0 | if (!sar_long_rlm && i == SAR_SHORT_RLM_PARTS_NUM) { |
1035 | | // All parts of a Short-RLM are available in the conversation. |
1036 | | // Now dissect it. |
1037 | | |
1038 | | // reserve buffer for short RLM |
1039 | 0 | uint8_t *buf = wmem_alloc(pinfo->pool, SAR_SHORT_RLM_LENGTH); |
1040 | | |
1041 | | // fill buffer with RLM parts |
1042 | 0 | phtonu32(buf, (sar_rlm_parts[0].rlm_data << 12) | (sar_rlm_parts[1].rlm_data >> 8)); |
1043 | 0 | phtonu32(buf + 4, (sar_rlm_parts[1].rlm_data << 24) | (sar_rlm_parts[2].rlm_data << 4) | (sar_rlm_parts[3].rlm_data >> 16)); |
1044 | 0 | phtonu16(buf + 8, (sar_rlm_parts[3].rlm_data & 0xffff)); |
1045 | |
|
1046 | 0 | tvbuff_t *rlm_tvb = tvb_new_child_real_data(tvb, (uint8_t *)buf, SAR_SHORT_RLM_LENGTH, SAR_SHORT_RLM_LENGTH); |
1047 | 0 | add_new_data_source(pinfo, rlm_tvb, "Galileo E1-B I/NAV SAR Short-RLM"); |
1048 | | |
1049 | | // dissect RLM |
1050 | 0 | proto_tree *sar_rlm_tree = proto_tree_add_subtree(sar_tree, rlm_tvb, 0, SAR_SHORT_RLM_LENGTH, ett_ubx_gal_inav_sar_rlm, NULL, "Short-RLM (re-assembled)"); |
1051 | |
|
1052 | 0 | proto_tree_add_item(sar_rlm_tree, hf_ubx_gal_inav_sar_beacon_id, rlm_tvb, 0, 8, ENC_BIG_ENDIAN); |
1053 | 0 | proto_tree_add_item(sar_rlm_tree, hf_ubx_gal_inav_sar_msg_code, rlm_tvb, 6, 4, ENC_BIG_ENDIAN); |
1054 | 0 | } |
1055 | 0 | else if (sar_long_rlm && i == SAR_LONG_RLM_PARTS_NUM) { |
1056 | | // All parts of a Long-RLM are available in the conversation. |
1057 | | // TODO: Now dissect it. |
1058 | 0 | } |
1059 | 0 | } |
1060 | 0 | } |
1061 | |
|
1062 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_spare, tvb, 26, 1, ENC_NA); |
1063 | 0 | } |
1064 | | |
1065 | | // TODO: check CRC |
1066 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_crc, tvb, 26, 4, ENC_BIG_ENDIAN); |
1067 | |
|
1068 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_ssp, tvb, 28, 4, ENC_BIG_ENDIAN); |
1069 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_tail, tvb, 30, 1, ENC_NA); |
1070 | 0 | proto_tree_add_item(gal_inav_tree, hf_ubx_gal_inav_pad, tvb, 31, 1, ENC_NA); |
1071 | | |
1072 | | // handoff the data word of a nominal page |
1073 | 0 | if (even_page_type == 0 && odd_page_type == 0) { |
1074 | | // create new tvb with the data word |
1075 | 0 | word = wmem_alloc(pinfo->pool, 16); |
1076 | 0 | phtonu16(word + 14, (uint16_t)data_16_1); |
1077 | 0 | phtonu64(word + 6, data_66_17); |
1078 | 0 | phtonu64(word, (((uint64_t) inav_type) << 58) | (data_122_67 << 2) | (data_66_17 >> 48)); |
1079 | |
|
1080 | 0 | next_tvb = tvb_new_child_real_data(tvb, (uint8_t *)word, 16, 16); |
1081 | 0 | add_new_data_source(pinfo, next_tvb, "Galileo I/NAV Word"); |
1082 | | |
1083 | | // handoff to appropriate dissector |
1084 | 0 | if (!dissector_try_uint(ubx_gal_inav_word_dissector_table, inav_type, next_tvb, pinfo, tree)) { |
1085 | 0 | call_data_dissector(next_tvb, pinfo, tree); |
1086 | 0 | } |
1087 | 0 | } |
1088 | |
|
1089 | 0 | return tvb_captured_length(tvb); |
1090 | 0 | } |
1091 | | |
1092 | | /* Dissect word 0 - I/NAV Spare Word */ |
1093 | 0 | static int dissect_ubx_gal_inav_word0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { |
1094 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "Word 0 (Spare Word)"); |
1095 | |
|
1096 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_ubx_gal_inav_word0, tvb, 0, 16, ENC_NA); |
1097 | 0 | proto_tree *word_tree = proto_item_add_subtree(ti, ett_ubx_gal_inav_word0); |
1098 | |
|
1099 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word_type, tvb, 0, 1, ENC_NA); |
1100 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word0_time, tvb, 0, 1, ENC_NA); |
1101 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word0_spare, tvb, 1, 11, ENC_NA); |
1102 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word0_wn, tvb, 12, 4, ENC_BIG_ENDIAN); |
1103 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word0_tow, tvb, 12, 4, ENC_BIG_ENDIAN); |
1104 | |
|
1105 | 0 | return tvb_captured_length(tvb); |
1106 | 0 | } |
1107 | | |
1108 | | /* Dissect word 1 - Ephemeris (1/4) */ |
1109 | 0 | static int dissect_ubx_gal_inav_word1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { |
1110 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "Word 1 (Ephemeris (1/4))"); |
1111 | |
|
1112 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_ubx_gal_inav_word1, tvb, 0, 16, ENC_NA); |
1113 | 0 | proto_tree *word_tree = proto_item_add_subtree(ti, ett_ubx_gal_inav_word1); |
1114 | |
|
1115 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word_type, tvb, 0, 1, ENC_NA); |
1116 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word1_iodnav, tvb, 0, 2, ENC_BIG_ENDIAN); |
1117 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word1_t0e, tvb, 2, 2, ENC_BIG_ENDIAN); |
1118 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word1_m0, tvb, 3, 8, ENC_BIG_ENDIAN); |
1119 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word1_e, tvb, 7, 8, ENC_BIG_ENDIAN); |
1120 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word1_sqrta, tvb, 8, 8, ENC_BIG_ENDIAN); |
1121 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word1_reserved, tvb, 15, 1, ENC_NA); |
1122 | |
|
1123 | 0 | return tvb_captured_length(tvb); |
1124 | 0 | } |
1125 | | |
1126 | | /* Dissect word 2 - Ephemeris (2/4) */ |
1127 | 0 | static int dissect_ubx_gal_inav_word2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { |
1128 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "Word 2 (Ephemeris (2/4))"); |
1129 | |
|
1130 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_ubx_gal_inav_word2, tvb, 0, 16, ENC_NA); |
1131 | 0 | proto_tree *word_tree = proto_item_add_subtree(ti, ett_ubx_gal_inav_word2); |
1132 | |
|
1133 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word_type, tvb, 0, 1, ENC_NA); |
1134 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word2_iodnav, tvb, 0, 2, ENC_BIG_ENDIAN); |
1135 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word2_omega0, tvb, 2, 4, ENC_BIG_ENDIAN); |
1136 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word2_i0, tvb, 6, 4, ENC_BIG_ENDIAN); |
1137 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word2_omega, tvb, 10, 4, ENC_BIG_ENDIAN); |
1138 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word2_incl_angle_rate, tvb, 14, 2, ENC_BIG_ENDIAN); |
1139 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word2_reserved, tvb, 15, 1, ENC_NA); |
1140 | |
|
1141 | 0 | return tvb_captured_length(tvb); |
1142 | 0 | } |
1143 | | |
1144 | | /* Dissect word 3 - Ephemeris (3/4) */ |
1145 | 0 | static int dissect_ubx_gal_inav_word3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { |
1146 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "Word 3 (Ephemeris (3/4))"); |
1147 | |
|
1148 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_ubx_gal_inav_word3, tvb, 0, 16, ENC_NA); |
1149 | 0 | proto_tree *word_tree = proto_item_add_subtree(ti, ett_ubx_gal_inav_word3); |
1150 | |
|
1151 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word_type, tvb, 0, 1, ENC_NA); |
1152 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_iodnav, tvb, 0, 2, ENC_BIG_ENDIAN); |
1153 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_omega_rate, tvb, 2, 4, ENC_BIG_ENDIAN); |
1154 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_delta_n, tvb, 5, 2, ENC_BIG_ENDIAN); |
1155 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_c_uc, tvb, 7, 2, ENC_BIG_ENDIAN); |
1156 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_c_us, tvb, 9, 2, ENC_BIG_ENDIAN); |
1157 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_c_rc, tvb, 11, 2, ENC_BIG_ENDIAN); |
1158 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_c_rs, tvb, 13, 2, ENC_BIG_ENDIAN); |
1159 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word3_sisa_e1_e5b, tvb, 15, 1, ENC_NA); |
1160 | |
|
1161 | 0 | return tvb_captured_length(tvb); |
1162 | 0 | } |
1163 | | |
1164 | | /* Dissect word 4 - Ephemeris (4/4) */ |
1165 | 0 | static int dissect_ubx_gal_inav_word4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { |
1166 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "Word 4 (Ephemeris (4/4))"); |
1167 | |
|
1168 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_ubx_gal_inav_word4, tvb, 0, 16, ENC_NA); |
1169 | 0 | proto_tree *word_tree = proto_item_add_subtree(ti, ett_ubx_gal_inav_word4); |
1170 | |
|
1171 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word_type, tvb, 0, 1, ENC_NA); |
1172 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_iodnav, tvb, 0, 2, ENC_BIG_ENDIAN); |
1173 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_svid, tvb, 2, 1, ENC_NA); |
1174 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_c_ic, tvb, 2, 4, ENC_BIG_ENDIAN); |
1175 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_c_is, tvb, 4, 4, ENC_BIG_ENDIAN); |
1176 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_t_0c, tvb, 6, 4, ENC_BIG_ENDIAN); |
1177 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_a_f0, tvb, 8, 8, ENC_BIG_ENDIAN); |
1178 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_a_f1, tvb, 12, 4, ENC_BIG_ENDIAN); |
1179 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_a_f2, tvb, 12, 4, ENC_BIG_ENDIAN); |
1180 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word4_spare, tvb, 15, 1, ENC_NA); |
1181 | |
|
1182 | 0 | return tvb_captured_length(tvb); |
1183 | 0 | } |
1184 | | |
1185 | | /* Dissect word 6 - GST-UTC conversion parameters */ |
1186 | 0 | static int dissect_ubx_gal_inav_word6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { |
1187 | 0 | col_append_str(pinfo->cinfo, COL_INFO, "Word 6 (GST-UTC conversion parameters)"); |
1188 | |
|
1189 | 0 | proto_item *ti = proto_tree_add_item(tree, hf_ubx_gal_inav_word6, tvb, 0, 16, ENC_NA); |
1190 | 0 | proto_tree *word_tree = proto_item_add_subtree(ti, ett_ubx_gal_inav_word6); |
1191 | |
|
1192 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word_type, tvb, 0, 1, ENC_NA); |
1193 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_a0, tvb, 0, 8, ENC_BIG_ENDIAN); |
1194 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_a1, tvb, 4, 4, ENC_BIG_ENDIAN); |
1195 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_delta_t_ls, tvb, 7, 2, ENC_BIG_ENDIAN); |
1196 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_t_0t, tvb, 8, 2, ENC_BIG_ENDIAN); |
1197 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_wn_0t, tvb, 9, 2, ENC_BIG_ENDIAN); |
1198 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_wn_lsf, tvb, 10, 2, ENC_BIG_ENDIAN); |
1199 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_dn, tvb, 11, 2, ENC_BIG_ENDIAN); |
1200 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_delta_t_lsf, tvb, 12, 2, ENC_BIG_ENDIAN); |
1201 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_tow, tvb, 12, 4, ENC_BIG_ENDIAN); |
1202 | 0 | proto_tree_add_item(word_tree, hf_ubx_gal_inav_word6_spare, tvb, 15, 1, ENC_NA); |
1203 | |
|
1204 | 0 | return tvb_captured_length(tvb); |
1205 | 0 | } |
1206 | | |
1207 | 15 | void proto_register_ubx_gal_inav(void) { |
1208 | | |
1209 | 15 | static hf_register_info hf[] = { |
1210 | 15 | {&hf_ubx_gal_inav_even_odd, {"Even/Odd", "gal_inav.even_odd", FT_BOOLEAN, 8, TFS(&tfs_odd_even), 0x80, NULL, HFILL}}, |
1211 | 15 | {&hf_ubx_gal_inav_page_type, {"Page Type", "gal_inav.page_type", FT_UINT8, BASE_DEC, VALS(GAL_PAGE_TYPE), 0x40, NULL, HFILL}}, |
1212 | 15 | {&hf_ubx_gal_inav_type, {"Type", "gal_inav.type", FT_UINT8, BASE_DEC, NULL, 0x3f, NULL, HFILL}}, |
1213 | 15 | {&hf_ubx_gal_inav_data_122_67, {"Data (122-67)", "gal_inav.data_122_67", FT_UINT64, BASE_HEX, NULL, UINT64_C(0x00ffffffffffffff), NULL, HFILL}}, |
1214 | 15 | {&hf_ubx_gal_inav_data_66_17, {"Data (66-17)", "gal_inav.data_66_17", FT_UINT64, BASE_HEX, NULL, UINT64_C(0xffffffffffffc000), NULL, HFILL}}, |
1215 | 15 | {&hf_ubx_gal_inav_data_16_1, {"Data (16-1)", "gal_inav.data_16_1", FT_UINT64, BASE_HEX, NULL, UINT64_C(0x3fffc00000000000), NULL, HFILL}}, |
1216 | | |
1217 | | // OSNMA |
1218 | 15 | {&hf_ubx_gal_inav_osnma_hkroot, {"HKROOT", "gal_inav.osnma.hkroot", FT_UINT32, BASE_HEX, NULL, 0x3fc00000, NULL, HFILL}}, |
1219 | 15 | {&hf_ubx_gal_inav_osnma_mack, {"MACK", "gal_inav.osnma.mack", FT_UINT64, BASE_HEX, NULL, UINT64_C(0x003fffffffc00000), NULL, HFILL}}, |
1220 | 15 | {&hf_ubx_gal_inav_osnma_nmas, {"NMA Status (NMAS)", "gal_inav.osnma.nmas", FT_UINT8, BASE_HEX, VALS(GAL_OSNMA_NMAS_CODE), 0xc0, NULL, HFILL}}, |
1221 | 15 | {&hf_ubx_gal_inav_osnma_cid, {"Chain ID (CID)", "gal_inav.osnma.cid", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL}}, |
1222 | 15 | {&hf_ubx_gal_inav_osnma_cpks, {"Chain and Public Key Status (CPKS)", "gal_inav.osnma.cpks", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_CPKS_CODE), 0x0e, NULL, HFILL}}, |
1223 | 15 | {&hf_ubx_gal_inav_osnma_reserved, {"Reserved", "gal_inav.osnma.reserved", FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL}}, |
1224 | 15 | {&hf_ubx_gal_inav_osnma_dsm_id, {"DSM ID", "gal_inav.osnma.dsm_id", FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL}}, |
1225 | 15 | {&hf_ubx_gal_inav_osnma_dsm_blk_id, {"DSM Block ID", "gal_inav.osnma.dsm_blk_id", FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL}}, |
1226 | 15 | {&hf_ubx_gal_inav_osnma_dsm_blk, {"DSM Block", "gal_inav.osnma.dsm_blk", FT_BYTES, BASE_NONE|SEP_COLON, NULL, 0x0, NULL, HFILL}}, |
1227 | 15 | {&hf_ubx_gal_inav_osnma_tag0, {"Tag 0", "gal_inav.osnma.tag0", FT_BYTES, BASE_NONE|SEP_COLON, NULL, 0x0, NULL, HFILL}}, |
1228 | 15 | {&hf_ubx_gal_inav_osnma_macseq, {"MACSEQ", "gal_inav.osnma.macseq", FT_UINT16, BASE_DEC, NULL, 0xfff0, NULL, HFILL}}, |
1229 | 15 | {&hf_ubx_gal_inav_osnma_cop, {"Data Cut-Off Point (COP)", "gal_inav.osnma.cop", FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL}}, |
1230 | 15 | {&hf_ubx_gal_inav_osnma_tag, {"Tag", "gal_inav.osnma.tag", FT_BYTES, BASE_NONE|SEP_COLON, NULL, 0x0, NULL, HFILL}}, |
1231 | 15 | {&hf_ubx_gal_inav_osnma_prn_d, {"PRN_D", "gal_inav.osnma.prn_d", FT_UINT8, BASE_DEC, NULL, 0xff, NULL, HFILL}}, |
1232 | 15 | {&hf_ubx_gal_inav_osnma_adkd, {"Authentication Data and Key Delay (ADKD)", "gal_inav.osnma.adkd", FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL}}, |
1233 | 15 | {&hf_ubx_gal_inav_osnma_key, {"TESLA Chain Key", "gal_inav.osnma.key", FT_BYTES, BASE_NONE|SEP_COLON, NULL, 0x0, NULL, HFILL}}, |
1234 | 15 | {&hf_ubx_gal_inav_osnma_padding, {"MACK Padding", "gal_inav.osnma.mack_padding", FT_BYTES, BASE_NONE|SEP_COLON, NULL, 0x0, NULL, HFILL}}, |
1235 | 15 | {&hf_ubx_gal_inav_osnma_dsm_nb_dk, {"Number of DSM-KROOT Blocks (NB_DK)", "gal_inav.osnma.dsm.nb_dk", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_NB_DK_CODE), 0xf0, NULL, HFILL}}, |
1236 | 15 | {&hf_ubx_gal_inav_osnma_dsm_pkid, {"Public Key ID (PKID)", "gal_inav.osnma.dsm.pkid", FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL}}, |
1237 | 15 | {&hf_ubx_gal_inav_osnma_dsm_cidkr, {"KROOT Chain ID (CIDKR)", "gal_inav.osnma.dsm.cidkr", FT_UINT8, BASE_DEC, NULL, 0xc0, NULL, HFILL}}, |
1238 | 15 | {&hf_ubx_gal_inav_osnma_dsm_reserved1, {"Reserved 1", "gal_inav.osnma.dsm.reserved1", FT_UINT8, BASE_HEX, NULL, 0x30, NULL, HFILL}}, |
1239 | 15 | {&hf_ubx_gal_inav_osnma_dsm_hf, {"Hash Function (HF)", "gal_inav.osnma.dsm.hf", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_HF_CODE), 0x0c, NULL, HFILL}}, |
1240 | 15 | {&hf_ubx_gal_inav_osnma_dsm_mf, {"MAC Function (MF)", "gal_inav.osnma.dsm.mf", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_MF_CODE), 0x03, NULL, HFILL}}, |
1241 | 15 | {&hf_ubx_gal_inav_osnma_dsm_ks, {"Key Size (KS)", "gal_inav.osnma.dsm.ks", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_KS_CODE), 0xf0, NULL, HFILL}}, |
1242 | 15 | {&hf_ubx_gal_inav_osnma_dsm_ts, {"Tag Size (TS)", "gal_inav.osnma.dsm.ts", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_TS_CODE), 0x0f, NULL, HFILL}}, |
1243 | | // TODO: show the meaning of MACLT entries |
1244 | 15 | {&hf_ubx_gal_inav_osnma_dsm_maclt, {"MAC Look-up Table (MACLT)", "gal_inav.osnma.dsm.maclt", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
1245 | 15 | {&hf_ubx_gal_inav_osnma_dsm_reserved2, {"Reserved 2", "gal_inav.osnma.dsm.reserved2", FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL}}, |
1246 | 15 | {&hf_ubx_gal_inav_osnma_dsm_wn_k, {"KROOT Week Number (WN_K)", "gal_inav.osnma.dsm.wn_k", FT_UINT16, BASE_DEC, NULL, 0x0fff, NULL, HFILL}}, |
1247 | 15 | {&hf_ubx_gal_inav_osnma_dsm_towh_k, {"KROOT Time of Week (TOWH_K)", "gal_inav.osnma.dsm.towh_k", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_hours), 0xff, NULL, HFILL}}, |
1248 | 15 | {&hf_ubx_gal_inav_osnma_dsm_alpha, {"Random Pattern (α)", "gal_inav.osnma.dsm.alpha", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1249 | 15 | {&hf_ubx_gal_inav_osnma_dsm_kroot, {"KROOT", "gal_inav.osnma.dsm.kroot", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1250 | 15 | {&hf_ubx_gal_inav_osnma_dsm_ds, {"Digital Signature (DS)", "gal_inav.osnma.dsm.ds", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1251 | 15 | {&hf_ubx_gal_inav_osnma_dsm_p_dk, {"DSM-KROOT Padding (P_DK)", "gal_inav.osnma.dsm.p_dk", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1252 | 15 | {&hf_ubx_gal_inav_osnma_dsm_nb_dp, {"Number of DSM-PKR Blocks (NB_DP)", "gal_inav.osnma.dsm.nb_dp", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_NB_DP_CODE), 0xf0, NULL, HFILL}}, |
1253 | 15 | {&hf_ubx_gal_inav_osnma_dsm_mid, {"Message ID (MID)", "gal_inav.osnma.dsm.mid", FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL}}, |
1254 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_0, {"x_0_0", "gal_inav.osnma.dsm.x_0_0", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1255 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_1, {"x_0_1", "gal_inav.osnma.dsm.x_0_1", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1256 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_2, {"x_0_2", "gal_inav.osnma.dsm.x_0_2", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1257 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_3, {"x_0_3", "gal_inav.osnma.dsm.x_0_3", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1258 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_4, {"x_0_4", "gal_inav.osnma.dsm.x_0_4", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1259 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_5, {"x_0_5", "gal_inav.osnma.dsm.x_0_5", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1260 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_6, {"x_0_6", "gal_inav.osnma.dsm.x_0_6", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1261 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_7, {"x_0_7", "gal_inav.osnma.dsm.x_0_7", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1262 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_8, {"x_0_8", "gal_inav.osnma.dsm.x_0_8", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1263 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_9, {"x_0_9", "gal_inav.osnma.dsm.x_0_9", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1264 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_10, {"x_0_10", "gal_inav.osnma.dsm.x_0_10", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1265 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_11, {"x_0_11", "gal_inav.osnma.dsm.x_0_11", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1266 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_12, {"x_0_12", "gal_inav.osnma.dsm.x_0_12", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1267 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_13, {"x_0_13", "gal_inav.osnma.dsm.x_0_13", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1268 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_14, {"x_0_14", "gal_inav.osnma.dsm.x_0_14", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1269 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_0_15, {"x_0_15", "gal_inav.osnma.dsm.x_0_15", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1270 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_0, {"x_1_0", "gal_inav.osnma.dsm.x_1_0", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1271 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_1, {"x_1_1", "gal_inav.osnma.dsm.x_1_1", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1272 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_2, {"x_1_2", "gal_inav.osnma.dsm.x_1_2", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1273 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_3, {"x_1_3", "gal_inav.osnma.dsm.x_1_3", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1274 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_4, {"x_1_4", "gal_inav.osnma.dsm.x_1_4", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1275 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_5, {"x_1_5", "gal_inav.osnma.dsm.x_1_5", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1276 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_6, {"x_1_6", "gal_inav.osnma.dsm.x_1_6", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1277 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_1_7, {"x_1_7", "gal_inav.osnma.dsm.x_1_7", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1278 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_2_0, {"x_2_0", "gal_inav.osnma.dsm.x_2_0", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1279 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_2_1, {"x_2_1", "gal_inav.osnma.dsm.x_2_1", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1280 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_2_2, {"x_2_2", "gal_inav.osnma.dsm.x_2_2", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1281 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_2_3, {"x_2_3", "gal_inav.osnma.dsm.x_2_3", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1282 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_3_0, {"x_3_0", "gal_inav.osnma.dsm.x_3_0", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1283 | 15 | {&hf_ubx_gal_inav_osnma_dsm_x_3_1, {"x_3_1", "gal_inav.osnma.dsm.x_3_1", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1284 | 15 | {&hf_ubx_gal_inav_osnma_dsm_npkt, {"New Public Key Type (NPKT)", "gal_inav.osnma.dsm.npkt", FT_UINT8, BASE_DEC, VALS(GAL_OSNMA_NPKT_CODE), 0xf0, NULL, HFILL}}, |
1285 | 15 | {&hf_ubx_gal_inav_osnma_dsm_npkid, {"New Public Key ID (NPKID)", "gal_inav.osnma.dsm.npkid", FT_UINT8, BASE_DEC, NULL, 0x0f, NULL, HFILL}}, |
1286 | 15 | {&hf_ubx_gal_inav_osnma_dsm_npk, {"New Public Key (NPK)", "gal_inav.osnma.dsm.npk", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1287 | 15 | {&hf_ubx_gal_inav_osnma_dsm_p_dp, {"DSM-PKR Padding (P_DP)", "gal_inav.osnma.dsm.p_dp", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1288 | | |
1289 | | // SAR |
1290 | 15 | {&hf_ubx_gal_inav_sar_start_bit, {"Start bit", "gal_inav.sar.start_bit", FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL}}, |
1291 | 15 | {&hf_ubx_gal_inav_sar_long_rlm, {"Long RLM", "gal_inav.sar.long_rlm", FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL}}, |
1292 | 15 | {&hf_ubx_gal_inav_sar_rlm_data, {"RLM data", "gal_inav.sar.rlm_data", FT_UINT32, BASE_HEX, NULL, 0x0fffff00, NULL, HFILL}}, |
1293 | 15 | {&hf_ubx_gal_inav_sar_beacon_id, {"Beacon ID", "gal_inav.sar.beacon_id", FT_UINT64, BASE_HEX, NULL, UINT64_C(0xfffffffffffffff0), NULL, HFILL}}, |
1294 | 15 | {&hf_ubx_gal_inav_sar_msg_code, {"Message code", "gal_inav.sar.msg_code", FT_UINT32, BASE_HEX, VALS(GAL_SAR_SHORT_RLM_MSG_CODE), 0x000f0000, NULL, HFILL}}, |
1295 | | |
1296 | 15 | {&hf_ubx_gal_inav_spare, {"Spare", "gal_inav.spare", FT_UINT8, BASE_HEX, NULL, 0xc0, NULL, HFILL}}, |
1297 | 15 | {&hf_ubx_gal_inav_reserved_1, {"Reserved 1", "gal_inav.reserved_1", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1298 | 15 | {&hf_ubx_gal_inav_crc, {"CRC", "gal_inav.crc", FT_UINT32, BASE_HEX, NULL, 0x3fffffc0, NULL, HFILL}}, |
1299 | 15 | {&hf_ubx_gal_inav_ssp, {"SSP", "gal_inav.ssp", FT_UINT32, BASE_HEX, VALS(GAL_SSP), 0x003fc000, NULL, HFILL}}, |
1300 | 15 | {&hf_ubx_gal_inav_tail, {"Tail", "gal_inav.tail", FT_UINT8, BASE_HEX, NULL, 0x3f, NULL, HFILL}}, |
1301 | 15 | {&hf_ubx_gal_inav_pad, {"Pad", "gal_inav.pad", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, |
1302 | | |
1303 | | // Data words |
1304 | 15 | {&hf_ubx_gal_inav_word_type, {"Type", "gal_inav.word.type", FT_UINT8, BASE_DEC, NULL, 0xfc, NULL, HFILL}}, |
1305 | | |
1306 | | // Word 0 |
1307 | 15 | {&hf_ubx_gal_inav_word0, {"Word 0 (Spare Word)", "gal_inav.word0", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1308 | 15 | {&hf_ubx_gal_inav_word0_time, {"Time", "gal_inav.word0.time", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL}}, |
1309 | 15 | {&hf_ubx_gal_inav_word0_spare, {"Spare", "gal_inav.word0.spare", FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, NULL, HFILL}}, |
1310 | 15 | {&hf_ubx_gal_inav_word0_wn, {"Week Number", "gal_inav.word0.wn", FT_UINT32, BASE_DEC, NULL, 0xfff00000, NULL, HFILL}}, |
1311 | 15 | {&hf_ubx_gal_inav_word0_tow, {"Time of Week", "gal_inav.word0.tow", FT_UINT32, BASE_DEC, NULL, 0x000fffff, NULL, HFILL}}, |
1312 | | |
1313 | | // Word 1 |
1314 | 15 | {&hf_ubx_gal_inav_word1, {"Word 1 (Ephemeris (1/4))", "gal_inav.word1", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1315 | 15 | {&hf_ubx_gal_inav_word1_iodnav, {"IOD_nav", "gal_inav.word1.iod_nav", FT_UINT16, BASE_DEC, NULL, 0x03ff, NULL, HFILL}}, |
1316 | 15 | {&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}}, |
1317 | 15 | {&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), UINT64_C(0x03fffffffc000000), NULL, HFILL}}, |
1318 | 15 | {&hf_ubx_gal_inav_word1_e, {"Eccentricity (e)", "gal_inav.word1.e", FT_UINT64, BASE_CUSTOM, CF_FUNC(&fmt_e), UINT64_C(0x03fffffffc000000), NULL, HFILL}}, |
1319 | 15 | {&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), UINT64_C(0x00000003fffffffc), NULL, HFILL}}, |
1320 | 15 | {&hf_ubx_gal_inav_word1_reserved,{"Reserved", "gal_inav.word1.reserved", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL}}, |
1321 | | |
1322 | | // Word 2 |
1323 | 15 | {&hf_ubx_gal_inav_word2, {"Word 2 (Ephemeris (2/4))", "gal_inav.word2", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1324 | 15 | {&hf_ubx_gal_inav_word2_iodnav, {"IOD_nav", "gal_inav.word2.iod_nav", FT_UINT16, BASE_DEC, NULL, 0x03ff, NULL, HFILL}}, |
1325 | 15 | {&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}}, |
1326 | 15 | {&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}}, |
1327 | 15 | {&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}}, |
1328 | 15 | {&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}}, |
1329 | 15 | {&hf_ubx_gal_inav_word2_reserved, {"Reserved", "gal_inav.word2.reserved", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL}}, |
1330 | | |
1331 | | // Word 3 |
1332 | 15 | {&hf_ubx_gal_inav_word3, {"Word 3 (Ephemeris (3/4))", "gal_inav.word3", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1333 | 15 | {&hf_ubx_gal_inav_word3_iodnav, {"IOD_nav", "gal_inav.word3.iod_nav", FT_UINT16, BASE_DEC, NULL, 0x03ff, NULL, HFILL}}, |
1334 | 15 | {&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}}, |
1335 | 15 | {&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}}, |
1336 | 15 | {&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}}, |
1337 | 15 | {&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}}, |
1338 | 15 | {&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}}, |
1339 | 15 | {&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}}, |
1340 | 15 | {&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}}, |
1341 | | |
1342 | | // Word 4 |
1343 | 15 | {&hf_ubx_gal_inav_word4, {"Word 4 (Ephemeris (4/4))", "gal_inav.word4", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1344 | 15 | {&hf_ubx_gal_inav_word4_iodnav, {"IOD_nav", "gal_inav.word4.iod_nav", FT_UINT16, BASE_DEC, NULL, 0x03ff, NULL, HFILL}}, |
1345 | 15 | {&hf_ubx_gal_inav_word4_svid, {"SVID", "gal_inav.word4.svid", FT_UINT8, BASE_DEC, NULL, 0xfc, NULL, HFILL}}, |
1346 | 15 | {&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}}, |
1347 | 15 | {&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}}, |
1348 | 15 | {&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}}, |
1349 | 15 | {&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}}, |
1350 | 15 | {&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}}, |
1351 | 15 | {&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}}, |
1352 | 15 | {&hf_ubx_gal_inav_word4_spare, {"Spare", "gal_inav.word4.spare", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL}}, |
1353 | | |
1354 | | // Word 6 |
1355 | 15 | {&hf_ubx_gal_inav_word6, {"Word 6 (GST-UTC conversion parameters)", "gal_inav.word6", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1356 | 15 | {&hf_ubx_gal_inav_word6_a0, {"Constant term of polynomial (A_0)", "gal_inav.word6.a_0", FT_INT64, BASE_CUSTOM, CF_FUNC(&fmt_a0), 0x03fffffffc000000, NULL, HFILL}}, |
1357 | 15 | {&hf_ubx_gal_inav_word6_a1, {"1st order term of polynomial (A_1)", "gal_inav.word6.a_1", FT_INT32, BASE_CUSTOM, CF_FUNC(&fmt_a1), 0x03fffffc, NULL, HFILL}}, |
1358 | 15 | {&hf_ubx_gal_inav_word6_delta_t_ls, {"Leap Second count before leap second adjustment (" UTF8_CAPITAL_DELTA "t_LS)", "gal_inav.word6.delta_t_ls", FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_second_seconds), 0x03fc, NULL, HFILL}}, |
1359 | 15 | {&hf_ubx_gal_inav_word6_t_0t, {"UTC data reference Time of Week (t_0t)", "gal_inav.word6.t_0t", FT_UINT16, BASE_CUSTOM, CF_FUNC(&fmt_t_0t), 0x03fc, NULL, HFILL}}, |
1360 | 15 | {&hf_ubx_gal_inav_word6_wn_0t, {"UTC data reference Week Number (WN_0t)", "gal_inav.word6.wn_0t", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_week_weeks), 0x03fc, NULL, HFILL}}, |
1361 | 15 | {&hf_ubx_gal_inav_word6_wn_lsf, {"Week Number of leap second adjustment (WN_LSF)", "gal_inav.word6.wn_lsf", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_week_weeks), 0x03fc, NULL, HFILL}}, |
1362 | 15 | {&hf_ubx_gal_inav_word6_dn, {"Day Number at the end of which a leap second adjustment becomes effective (DN)", "gal_inav.word6.dn", FT_UINT16, BASE_DEC, VALS(DAY_NUMBER), 0x0380, NULL, HFILL}}, |
1363 | 15 | {&hf_ubx_gal_inav_word6_delta_t_lsf, {"Leap Second count after leap second adjustment (" UTF8_CAPITAL_DELTA "t_LSF)", "gal_inav.word6.delta_t_lsf", FT_INT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_second_seconds), 0x7f80, NULL, HFILL}}, |
1364 | 15 | {&hf_ubx_gal_inav_word6_tow, {"Time of Week (TOW)", "gal_inav.word6.tow", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_second_seconds), 0x007ffff8, NULL, HFILL}}, |
1365 | 15 | {&hf_ubx_gal_inav_word6_spare, {"Spare", "gal_inav.word6.spare", FT_UINT8, BASE_HEX, NULL, 0x07, NULL, HFILL}}, |
1366 | 15 | }; |
1367 | | |
1368 | 15 | static int *ett[] = { |
1369 | 15 | &ett_ubx_gal_inav, |
1370 | 15 | &ett_ubx_gal_inav_word0, |
1371 | 15 | &ett_ubx_gal_inav_word1, |
1372 | 15 | &ett_ubx_gal_inav_word2, |
1373 | 15 | &ett_ubx_gal_inav_word3, |
1374 | 15 | &ett_ubx_gal_inav_word4, |
1375 | 15 | &ett_ubx_gal_inav_word6, |
1376 | 15 | &ett_ubx_gal_inav_osnma, |
1377 | 15 | &ett_ubx_gal_inav_osnma_hkroot_msg, |
1378 | 15 | &ett_ubx_gal_inav_osnma_mack_msg, |
1379 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[0], |
1380 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[1], |
1381 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[2], |
1382 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[3], |
1383 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[4], |
1384 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[5], |
1385 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[6], |
1386 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[7], |
1387 | 15 | &ett_ubx_gal_inav_osnma_mack_tag[8], |
1388 | 15 | &ett_ubx_gal_inav_osnma_dsm, |
1389 | 15 | &ett_ubx_gal_inav_sar, |
1390 | 15 | &ett_ubx_gal_inav_sar_rlm, |
1391 | 15 | }; |
1392 | | |
1393 | 15 | proto_ubx_gal_inav = proto_register_protocol("Galileo E1-B I/NAV Navigation Message", "Galileo I/NAV", "gal_inav"); |
1394 | | |
1395 | 15 | proto_register_field_array(proto_ubx_gal_inav, hf, array_length(hf)); |
1396 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1397 | | |
1398 | 15 | register_dissector("ubx_gal_inav", dissect_ubx_gal_inav, proto_ubx_gal_inav); |
1399 | | |
1400 | 15 | ubx_gal_inav_word_dissector_table = register_dissector_table("ubx.rxm.sfrbx.gal_inav.word", |
1401 | 15 | "Galileo I/NAV Word", proto_ubx_gal_inav, FT_UINT8, BASE_DEC); |
1402 | 15 | } |
1403 | | |
1404 | 15 | void proto_reg_handoff_ubx_gal_inav(void) { |
1405 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gnssid", GNSS_ID_GALILEO, create_dissector_handle(dissect_ubx_gal_inav, proto_ubx_gal_inav)); |
1406 | | |
1407 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 0, create_dissector_handle(dissect_ubx_gal_inav_word0, proto_ubx_gal_inav)); |
1408 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 1, create_dissector_handle(dissect_ubx_gal_inav_word1, proto_ubx_gal_inav)); |
1409 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 2, create_dissector_handle(dissect_ubx_gal_inav_word2, proto_ubx_gal_inav)); |
1410 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 3, create_dissector_handle(dissect_ubx_gal_inav_word3, proto_ubx_gal_inav)); |
1411 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 4, create_dissector_handle(dissect_ubx_gal_inav_word4, proto_ubx_gal_inav)); |
1412 | 15 | dissector_add_uint("ubx.rxm.sfrbx.gal_inav.word", 6, create_dissector_handle(dissect_ubx_gal_inav_word6, proto_ubx_gal_inav)); |
1413 | 15 | } |