Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ubx-gps_l1_lnav.c
bloba6e9dfc2227da55b4620a8eee4961d3b6f0b57e9
1 /* packet-ubx-gps_l1_lnav.c
2 * Dissection of Global Positioning System (GPS) L1 C/A LNAV 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
15 #include "config.h"
17 #include <epan/expert.h>
18 #include <epan/packet.h>
20 #include "packet-ubx.h"
23 * Dissects GPS L1 C/A LNAV navigation messages as encoded by UBX (in
24 * UBX-RXM-SFRBX messages).
26 * UBX encodes the 30 bit words of GPS subframes as 32 bit words in little-endian.
28 * The two most significant bits of the 32 bit word can be ignored.
30 * UBX takes care of the word parity checks. So, parity checks do not have to be
31 * repeated for dissection. UBX inverts the bits of a word if the least
32 * significant parity bit (D30) of the previous word is 1 (i.e. UBX undoes the
33 * bit inverting of GPS removing the need to do so for dissection).
37 * mapping from L2 channel code ID to description
38 * see IS-GPS-200N, Section 20.3.3.3.1.2
40 static const value_string L2_CHANNEL_CODE[] = {
41 {0x0, "invalid"},
42 {0x1, "P-code ON"},
43 {0x2, "C/A-code ON"},
44 {0x3, "invalid"},
45 {0, NULL},
49 * mapping from URA index to URA
50 * see IS-GPS-200N, Section 20.3.3.3.1.3
52 static const value_string URA_INDEX[] = {
53 { 0, "0.00 < URA <= 2.40"},
54 { 1, "2.40 < URA <= 3.40"},
55 { 2, "3.40 < URA <= 4.85"},
56 { 3, "4.85 < URA <= 6.85"},
57 { 4, "6.85 < URA <= 9.65"},
58 { 5, "9.65 < URA <= 13.65"},
59 { 6, "13.65 < URA <= 24.00"},
60 { 7, "24.00 < URA <= 48.00"},
61 { 8, "48.00 < URA <= 96.00"},
62 { 9, "96.00 < URA <= 192.00"},
63 {10, "192.00 < URA <= 384.00"},
64 {11, "384.00 < URA <= 768.00"},
65 {12, "768.00 < URA <= 1536.00"},
66 {13, "1536.00 < URA <= 3072.00"},
67 {14, "3072.00 < URA <= 6144.00"},
68 {15, "6144.00 < URA"},
69 {0, NULL},
73 * mapping for SV health summary
74 * see IS-GPS-200N, Section 20.3.3.3.1.4
76 static const value_string SV_HEALTH_SUMMARY[] = {
77 {0, "all LNAV data are OK"},
78 {1, "some or all LNAV data are bad"},
79 {0, NULL},
83 * mapping for codes for health of SV signal components
84 * see IS-GPS-200N, Section 20.3.3.5.1.3
86 static const value_string SV_HEALTH_CODE[] = {
87 {0, "All Signals OK"},
88 {1, "All Signals Weak"},
89 {2, "All Signals Dead"},
90 {3, "All Signals Have No Data Modulation"},
91 {4, "L1 P Signal Weak"},
92 {5, "L1 P Signal Dead"},
93 {6, "L1 P Signal Has No Data Modulation"},
94 {7, "L2 P Signal Weak"},
95 {8, "L2 P Signal Dead"},
96 {9, "L2 P Signal Has No Data Modulation"},
97 {10, "L1C Signal Weak"},
98 {11, "L1C Signal Dead"},
99 {12, "L1C Signal Has No Data Modulation"},
100 {13, "L2C Signal Weak"},
101 {14, "L2C Signal Dead"},
102 {15, "L2C Signal Has No Data Modulation"},
103 {16, "L1 & L2 P Signal Weak"},
104 {17, "L1 & L2 P Signal Dead"},
105 {18, "L1 & L2 P Signal Has No Data Modulation"},
106 {19, "L1 & L2C Signal Weak"},
107 {20, "L1 & L2C Signal Dead"},
108 {21, "L1 & L2C Signal Has No Data Modulation"},
109 {22, "L1 Signal Weak"},
110 {23, "L1 Signal Dead"},
111 {24, "L1 Signal Has No Data Modulation"},
112 {25, "L2 Signal Weak"},
113 {26, "L2 Signal Dead"},
114 {27, "L2 Signal Has No Data Modulation"},
115 {28, "SV Is Temporarily Out (Do not use this SV during current pass)"},
116 {29, "SV Will Be Temporarily Out (Use with caution)"},
117 {30, "One Or More Signals Are Deformed, However The Relevant URA Parameters Are Valid"},
118 {31, "More Than One Combination Would Be Required To Describe Anomalies"},
119 {0, NULL},
122 // Initialize the protocol and registered fields
123 static int proto_ubx_gps_l1;
125 // Telemetry Word (see IS-GPS-200N, Section 20.3.3.1)
126 static int hf_ubx_gps_l1_tlm_preamble;
127 static int hf_ubx_gps_l1_tlm_message;
128 static int hf_ubx_gps_l1_tlm_integrity;
129 static int hf_ubx_gps_l1_tlm_reserved;
130 static int hf_ubx_gps_l1_tlm_parity;
132 // Handover Word (see IS-GPS-200N, Section 20.3.3.2)
133 static int hf_ubx_gps_l1_how_tow_count;
134 static int hf_ubx_gps_l1_how_alert;
135 static int hf_ubx_gps_l1_how_anti_spoof;
136 static int hf_ubx_gps_l1_how_subframe_id;
137 static int hf_ubx_gps_l1_how_parity_sol;
138 static int hf_ubx_gps_l1_how_parity;
140 // Subframe 1 (see IS-GPS-200N, Section 20.3.3.3)
141 static int hf_ubx_gps_l1_sf1;
142 static int hf_ubx_gps_l1_sf1_week_no;
143 static int hf_ubx_gps_l1_sf1_l2_channel_code;
144 static int hf_ubx_gps_l1_sf1_ura_index;
145 static int hf_ubx_gps_l1_sf1_sv_health_summary;
146 static int hf_ubx_gps_l1_sf1_sv_health;
147 static int hf_ubx_gps_l1_sf1_iodc_msbs;
148 static int hf_ubx_gps_l1_sf1_w3_parity;
149 static int hf_ubx_gps_l1_sf1_w4_l2_p_data_flag;
150 static int hf_ubx_gps_l1_sf1_w4_reserved;
151 static int hf_ubx_gps_l1_sf1_w4_parity;
152 static int hf_ubx_gps_l1_sf1_w5_reserved;
153 static int hf_ubx_gps_l1_sf1_w5_parity;
154 static int hf_ubx_gps_l1_sf1_w6_reserved;
155 static int hf_ubx_gps_l1_sf1_w6_parity;
156 static int hf_ubx_gps_l1_sf1_w7_reserved;
157 static int hf_ubx_gps_l1_sf1_w7_tgd;
158 static int hf_ubx_gps_l1_sf1_w7_parity;
159 static int hf_ubx_gps_l1_sf1_w8_iodc_lsbs;
160 static int hf_ubx_gps_l1_sf1_w8_toc;
161 static int hf_ubx_gps_l1_sf1_w8_parity;
162 static int hf_ubx_gps_l1_sf1_w9_af2;
163 static int hf_ubx_gps_l1_sf1_w9_af1;
164 static int hf_ubx_gps_l1_sf1_w9_parity;
165 static int hf_ubx_gps_l1_sf1_w10_af0;
166 static int hf_ubx_gps_l1_sf1_w10_parity;
168 static dissector_table_t ubx_gps_l1_sf_dissector_table;
170 static expert_field ei_ubx_gps_l1_tlm_preamble;
171 static expert_field ei_ubx_gps_l1_how_tow_count;
172 static expert_field ei_ubx_gps_l1_how_subframe_id;
174 static int ett_ubx_gps_l1;
175 static int ett_ubx_gps_l1_tlm;
176 static int ett_ubx_gps_l1_how;
177 static int ett_ubx_gps_l1_sf1_w3;
178 static int ett_ubx_gps_l1_sf1_w4;
179 static int ett_ubx_gps_l1_sf1_w5;
180 static int ett_ubx_gps_l1_sf1_w6;
181 static int ett_ubx_gps_l1_sf1_w7;
182 static int ett_ubx_gps_l1_sf1_w8;
183 static int ett_ubx_gps_l1_sf1_w9;
184 static int ett_ubx_gps_l1_sf1_w10;
186 /* Format TOW count */
187 static void fmt_tow_count(char *label, int32_t c) {
188 unsigned tow = c << 2;
189 snprintf(label, ITEM_LABEL_LENGTH, "%d (TOW: %.1fs)", c, tow * 1.5);
192 /* Format Clock Data Reference Time t_OC */
193 static void fmt_t_oc(char *label, int32_t i) {
194 unsigned t_oc = i << 4;
195 snprintf(label, ITEM_LABEL_LENGTH, "%ds", t_oc);
198 /* Dissect GPS L1 C/A LNAV navigation message */
199 static int dissect_ubx_gps_l1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
200 uint32_t subframe_id = (tvb_get_uint32(tvb, 4, ENC_LITTLE_ENDIAN) & 0x00000700) >> 8;
202 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GPS L1 LNAV");
203 col_clear(pinfo->cinfo, COL_INFO);
204 col_append_fstr(pinfo->cinfo, COL_INFO, "Subframe %i", subframe_id);
206 proto_tree *gps_l1_tree = proto_tree_add_subtree_format(tree, tvb, 0, 40, ett_ubx_gps_l1, NULL, "GPS L1 LNAV (Subframe %i)", subframe_id);
208 // send the subframe to the next dissector
209 if (!dissector_try_uint(ubx_gps_l1_sf_dissector_table, subframe_id, tvb, pinfo, gps_l1_tree)) {
210 call_data_dissector(tvb, pinfo, tree);
213 return tvb_captured_length(tvb);
216 // Dissect the telemetry (TLM) word
217 static void dissect_ubx_gps_l1_tlm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) {
218 proto_tree *tlm_tree = proto_tree_add_subtree_format(tree, tvb, 0, 4, ett_ubx_gps_l1_tlm, NULL, "Word 1: Telemetry");
220 uint32_t tlm_preamble;
221 proto_item* pi_tlm_preamble = proto_tree_add_item_ret_uint(tlm_tree, hf_ubx_gps_l1_tlm_preamble, tvb, 0, 4, ENC_LITTLE_ENDIAN, &tlm_preamble);
222 if (tlm_preamble != 0x8b) {
223 expert_add_info_format(pinfo, pi_tlm_preamble, &ei_ubx_gps_l1_tlm_preamble, "Invalid preamble");
226 proto_tree_add_item(tlm_tree, hf_ubx_gps_l1_tlm_message, tvb, 0, 4, ENC_LITTLE_ENDIAN);
227 proto_tree_add_item(tlm_tree, hf_ubx_gps_l1_tlm_integrity, tvb, 0, 4, ENC_LITTLE_ENDIAN);
228 proto_tree_add_item(tlm_tree, hf_ubx_gps_l1_tlm_reserved, tvb, 0, 4, ENC_LITTLE_ENDIAN);
229 proto_tree_add_item(tlm_tree, hf_ubx_gps_l1_tlm_parity, tvb, 0, 4, ENC_LITTLE_ENDIAN);
232 // Dissect the handover word (HOW)
233 static void dissect_ubx_gps_l1_how(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) {
234 uint32_t subframe_id;
236 proto_tree *how_tree = proto_tree_add_subtree_format(tree, tvb, 4, 4, ett_ubx_gps_l1_how, NULL, "Word 2: Handover");
238 uint32_t tow_count;
239 proto_item* pi_how_tow_count = proto_tree_add_item_ret_uint(how_tree, hf_ubx_gps_l1_how_tow_count, tvb, 4, 4, ENC_LITTLE_ENDIAN, &tow_count);
240 if (tow_count > 100799) {
241 expert_add_info_format(pinfo, pi_how_tow_count, &ei_ubx_gps_l1_how_tow_count, "Invalid TOW count");
244 proto_tree_add_item(how_tree, hf_ubx_gps_l1_how_alert, tvb, 4, 4, ENC_LITTLE_ENDIAN);
245 proto_tree_add_item(how_tree, hf_ubx_gps_l1_how_anti_spoof, tvb, 4, 4, ENC_LITTLE_ENDIAN);
247 proto_item* pi_how_sf_id = proto_tree_add_item_ret_uint(how_tree, hf_ubx_gps_l1_how_subframe_id, tvb, 4, 4, ENC_LITTLE_ENDIAN, &subframe_id);
248 if (subframe_id > 5) {
249 expert_add_info_format(pinfo, pi_how_sf_id, &ei_ubx_gps_l1_how_subframe_id, "Invalid subframe ID");
252 proto_tree_add_item(how_tree, hf_ubx_gps_l1_how_parity_sol, tvb, 4, 4, ENC_LITTLE_ENDIAN);
253 proto_tree_add_item(how_tree, hf_ubx_gps_l1_how_parity, tvb, 4, 4, ENC_LITTLE_ENDIAN);
256 /* Dissect subframe 1 */
257 static int dissect_ubx_gps_l1_sf1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) {
258 dissect_ubx_gps_l1_tlm(tvb, pinfo, tree, data);
259 dissect_ubx_gps_l1_how(tvb, pinfo, tree, data);
261 // subframe 1, word 3
262 proto_tree *w3_tree = proto_tree_add_subtree_format(tree, tvb, 8, 4, ett_ubx_gps_l1_sf1_w3, NULL, "Word 3");
263 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_week_no, tvb, 8, 4, ENC_LITTLE_ENDIAN);
264 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_l2_channel_code, tvb, 8, 4, ENC_LITTLE_ENDIAN);
265 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_ura_index, tvb, 8, 4, ENC_LITTLE_ENDIAN);
266 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_sv_health_summary, tvb, 8, 4, ENC_LITTLE_ENDIAN);
267 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_sv_health, tvb, 8, 4, ENC_LITTLE_ENDIAN);
268 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_iodc_msbs, tvb, 8, 4, ENC_LITTLE_ENDIAN);
269 proto_tree_add_item(w3_tree, hf_ubx_gps_l1_sf1_w3_parity, tvb, 8, 4, ENC_LITTLE_ENDIAN);
271 // subframe 1, word 4
272 proto_tree *w4_tree = proto_tree_add_subtree_format(tree, tvb, 12, 4, ett_ubx_gps_l1_sf1_w4, NULL, "Word 4");
273 proto_tree_add_item(w4_tree, hf_ubx_gps_l1_sf1_w4_l2_p_data_flag, tvb, 12, 4, ENC_LITTLE_ENDIAN);
274 proto_tree_add_item(w4_tree, hf_ubx_gps_l1_sf1_w4_reserved, tvb, 12, 4, ENC_LITTLE_ENDIAN);
275 proto_tree_add_item(w4_tree, hf_ubx_gps_l1_sf1_w4_parity, tvb, 12, 4, ENC_LITTLE_ENDIAN);
278 // subframe 1, word 5
279 proto_tree *w5_tree = proto_tree_add_subtree_format(tree, tvb, 16, 4, ett_ubx_gps_l1_sf1_w5, NULL, "Word 5");
280 proto_tree_add_item(w5_tree, hf_ubx_gps_l1_sf1_w5_reserved, tvb, 16, 4, ENC_LITTLE_ENDIAN);
281 proto_tree_add_item(w5_tree, hf_ubx_gps_l1_sf1_w5_parity, tvb, 16, 4, ENC_LITTLE_ENDIAN);
283 // subframe 1, word 6
284 proto_tree *w6_tree = proto_tree_add_subtree_format(tree, tvb, 20, 4, ett_ubx_gps_l1_sf1_w6, NULL, "Word 6");
285 proto_tree_add_item(w6_tree, hf_ubx_gps_l1_sf1_w6_reserved, tvb, 20, 4, ENC_LITTLE_ENDIAN);
286 proto_tree_add_item(w6_tree, hf_ubx_gps_l1_sf1_w6_parity, tvb, 20, 4, ENC_LITTLE_ENDIAN);
288 // subframe 1, word 7
289 proto_tree *w7_tree = proto_tree_add_subtree_format(tree, tvb, 24, 4, ett_ubx_gps_l1_sf1_w7, NULL, "Word 7");
290 proto_tree_add_item(w7_tree, hf_ubx_gps_l1_sf1_w7_reserved, tvb, 24, 4, ENC_LITTLE_ENDIAN);
291 proto_tree_add_item(w7_tree, hf_ubx_gps_l1_sf1_w7_tgd, tvb, 24, 4, ENC_LITTLE_ENDIAN);
292 proto_tree_add_item(w7_tree, hf_ubx_gps_l1_sf1_w7_parity, tvb, 24, 4, ENC_LITTLE_ENDIAN);
294 // subframe 1, word 8
295 proto_tree *w8_tree = proto_tree_add_subtree_format(tree, tvb, 28, 4, ett_ubx_gps_l1_sf1_w8, NULL, "Word 8");
296 proto_tree_add_item(w8_tree, hf_ubx_gps_l1_sf1_w8_iodc_lsbs, tvb, 28, 4, ENC_LITTLE_ENDIAN);
297 proto_tree_add_item(w8_tree, hf_ubx_gps_l1_sf1_w8_toc, tvb, 28, 4, ENC_LITTLE_ENDIAN);
298 proto_tree_add_item(w8_tree, hf_ubx_gps_l1_sf1_w8_parity, tvb, 28, 4, ENC_LITTLE_ENDIAN);
300 // subframe 1, word 9
301 proto_tree *w9_tree = proto_tree_add_subtree_format(tree, tvb, 32, 4, ett_ubx_gps_l1_sf1_w9, NULL, "Word 9");
302 proto_tree_add_item(w9_tree, hf_ubx_gps_l1_sf1_w9_af2, tvb, 32, 4, ENC_LITTLE_ENDIAN);
303 proto_tree_add_item(w9_tree, hf_ubx_gps_l1_sf1_w9_af1, tvb, 32, 4, ENC_LITTLE_ENDIAN);
304 proto_tree_add_item(w9_tree, hf_ubx_gps_l1_sf1_w9_parity, tvb, 32, 4, ENC_LITTLE_ENDIAN);
306 // subframe 1, word 10
307 proto_tree *w10_tree = proto_tree_add_subtree_format(tree, tvb, 36, 4, ett_ubx_gps_l1_sf1_w10, NULL, "Word 10");
308 proto_tree_add_item(w10_tree, hf_ubx_gps_l1_sf1_w10_af0, tvb, 36, 4, ENC_LITTLE_ENDIAN);
309 proto_tree_add_item(w10_tree, hf_ubx_gps_l1_sf1_w10_parity, tvb, 36, 4, ENC_LITTLE_ENDIAN);
311 return tvb_captured_length(tvb);
314 void proto_register_ubx_gps_l1(void) {
316 static hf_register_info hf[] = {
317 // TLM
318 {&hf_ubx_gps_l1_tlm_preamble, {"Preamble", "gps_l1.tlm.preamble", FT_UINT32, BASE_HEX, NULL, 0x3fc00000, NULL, HFILL}},
319 {&hf_ubx_gps_l1_tlm_message, {"Message", "gps_l1.tlm.message", FT_UINT32, BASE_HEX, NULL, 0x003fff00, NULL, HFILL}},
320 {&hf_ubx_gps_l1_tlm_integrity, {"Integrity Status Flag (ISF)", "gps_l1.tlm.integrity", FT_BOOLEAN, 32, NULL, 0x00000080, NULL, HFILL}},
321 {&hf_ubx_gps_l1_tlm_reserved, {"Reserved", "gps_l1.tlm.reserved", FT_UINT32, BASE_HEX, NULL, 0x00000040, NULL, HFILL}},
322 {&hf_ubx_gps_l1_tlm_parity, {"Parity", "gps_l1.tlm.parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
324 // HOW
325 {&hf_ubx_gps_l1_how_tow_count, {"Time-of-Week (TOW) Count", "gps_l1.how.tow_count", FT_UINT32, BASE_CUSTOM, CF_FUNC(&fmt_tow_count), 0x3fffe000, NULL, HFILL}},
326 {&hf_ubx_gps_l1_how_alert, {"Alert", "gps_l1.how.alert", FT_BOOLEAN, 32, NULL, 0x00001000, NULL, HFILL}},
327 {&hf_ubx_gps_l1_how_anti_spoof, {"Anti-Spoof (A-S)", "gps_l1.how.anti_spoof", FT_BOOLEAN, 32, NULL, 0x00000800, NULL, HFILL}},
328 {&hf_ubx_gps_l1_how_subframe_id, {"Subframe ID", "gps_l1.how.subframe_id", FT_UINT32, BASE_DEC, NULL, 0x00000700, NULL, HFILL}},
329 {&hf_ubx_gps_l1_how_parity_sol, {"Solved for parity zero bits", "gps_l1.how.parity_sol", FT_UINT32, BASE_HEX, NULL, 0x000000c0, NULL, HFILL}},
330 {&hf_ubx_gps_l1_how_parity, {"Parity", "gps_l1.how.parity", FT_UINT32, BASE_DEC, NULL, 0x0000003f, NULL, HFILL}},
332 // SF1
333 {&hf_ubx_gps_l1_sf1, {"Subframe 1", "gps_l1.sf1", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
334 {&hf_ubx_gps_l1_sf1_week_no, {"Week Number", "gps_l1.sf1.week_number", FT_UINT32, BASE_DEC, NULL, 0x3ff00000, NULL, HFILL}},
335 {&hf_ubx_gps_l1_sf1_l2_channel_code, {"L2 Channel Code", "gps_l1.sf1.l2_channel_code", FT_UINT32, BASE_HEX, VALS(L2_CHANNEL_CODE), 0x000c0000, NULL, HFILL}},
336 {&hf_ubx_gps_l1_sf1_ura_index, {"URA Index", "gps_l1.sf1.ura_index", FT_UINT32, BASE_HEX, VALS(URA_INDEX), 0x0003c000, NULL, HFILL}},
337 {&hf_ubx_gps_l1_sf1_sv_health_summary, {"SV Health Summary", "gps_l1.sf1.sv_health_summary", FT_UINT32, BASE_HEX, VALS(SV_HEALTH_SUMMARY), 0x00002000, NULL, HFILL}},
338 {&hf_ubx_gps_l1_sf1_sv_health, {"SV's Signal Component Health Status", "gps_l1.sf1.sv_health", FT_UINT32, BASE_HEX, VALS(SV_HEALTH_CODE), 0x00001f00, NULL, HFILL}},
339 {&hf_ubx_gps_l1_sf1_iodc_msbs, {"Issue of Data Clock (IODC) MSBs", "gps_l1.sf1.iodc_msbs", FT_UINT32, BASE_HEX, NULL, 0x000000c0, NULL, HFILL}},
340 {&hf_ubx_gps_l1_sf1_w3_parity, {"Parity", "gps_l1.sf1.w3_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
341 {&hf_ubx_gps_l1_sf1_w4_l2_p_data_flag, {"L2 P Data Flag", "gps_l1.sf1.l2_p_data_flag", FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL}},
342 {&hf_ubx_gps_l1_sf1_w4_reserved, {"Reserved", "gps_l1.sf1.w4_reserved", FT_UINT32, BASE_HEX, NULL, 0x1fffffc0, NULL, HFILL}},
343 {&hf_ubx_gps_l1_sf1_w4_parity, {"Parity", "gps_l1.sf1.w4_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
344 {&hf_ubx_gps_l1_sf1_w5_reserved, {"Reserved", "gps_l1.sf1.w5_reserved", FT_UINT32, BASE_HEX, NULL, 0x3fffffc0, NULL, HFILL}},
345 {&hf_ubx_gps_l1_sf1_w5_parity, {"Parity", "gps_l1.sf1.w5_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
346 {&hf_ubx_gps_l1_sf1_w6_reserved, {"Reserved", "gps_l1.sf1.w6_reserved", FT_UINT32, BASE_HEX, NULL, 0x3fffffc0, NULL, HFILL}},
347 {&hf_ubx_gps_l1_sf1_w6_parity, {"Parity", "gps_l1.sf1.w6_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
348 {&hf_ubx_gps_l1_sf1_w7_reserved, {"Reserved", "gps_l1.sf1.w7_reserved", FT_UINT32, BASE_HEX, NULL, 0x3fffc000, NULL, HFILL}},
349 {&hf_ubx_gps_l1_sf1_w7_tgd, {"Estimated Group Delay Differential T_GD", "gps_l1.sf1.w7_tgd", FT_INT32, BASE_DEC, NULL, 0x00003fc0, NULL, HFILL}},
350 {&hf_ubx_gps_l1_sf1_w7_parity, {"Parity", "gps_l1.sf1.w7_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
351 {&hf_ubx_gps_l1_sf1_w8_iodc_lsbs, {"Issue of Data Clock (IODC) LSBs", "gps_l1.sf1.w8_iodc_lsbs", FT_UINT32, BASE_HEX, NULL, 0x3fc00000, NULL, HFILL}},
352 {&hf_ubx_gps_l1_sf1_w8_toc, {"Clock Data Reference Time t_OC", "gps_l1.sf1.w8_toc", FT_UINT32, BASE_CUSTOM, CF_FUNC(&fmt_t_oc), 0x003fffc0, NULL, HFILL}},
353 {&hf_ubx_gps_l1_sf1_w8_parity, {"Parity", "gps_l1.sf1.w8_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
354 {&hf_ubx_gps_l1_sf1_w9_af2, {"Drift Rate Correction Coefficient a_f2", "gps_l1.sf1.w9_af2", FT_INT32, BASE_DEC, NULL, 0x3fc00000, NULL, HFILL}},
355 {&hf_ubx_gps_l1_sf1_w9_af1, {"SV Clock Drift Correction Coefficient a_f1", "gps_l1.sf1.w9_af1", FT_INT32, BASE_DEC, NULL, 0x003fffc0, NULL, HFILL}},
356 {&hf_ubx_gps_l1_sf1_w9_parity, {"Parity", "gps_l1.sf1.w9_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
357 {&hf_ubx_gps_l1_sf1_w10_af0, {"SV Clock Bias Correction Coefficient a_f0", "gps_l1.sf1.w10_af0", FT_INT32, BASE_DEC, NULL, 0x3fffffc0, NULL, HFILL}},
358 {&hf_ubx_gps_l1_sf1_w10_parity, {"Parity", "gps_l1.sf1.w10_parity", FT_UINT32, BASE_HEX, NULL, 0x0000003f, NULL, HFILL}},
361 expert_module_t *expert_ubx_gps_l1;
363 static ei_register_info ei[] = {
364 {&ei_ubx_gps_l1_tlm_preamble, {"gps_l1.tlm.preamble", PI_PROTOCOL, PI_WARN, "Illegal preamble", EXPFILL}},
365 {&ei_ubx_gps_l1_how_tow_count, {"gps_l1.how.tow_count", PI_PROTOCOL, PI_WARN, "Illegal TOW count", EXPFILL}},
366 {&ei_ubx_gps_l1_how_subframe_id, {"gps_l1.how.subframe_id", PI_PROTOCOL, PI_WARN, "Illegal subframe ID", EXPFILL}},
369 static int *ett[] = {
370 &ett_ubx_gps_l1,
371 &ett_ubx_gps_l1_tlm,
372 &ett_ubx_gps_l1_how,
373 &ett_ubx_gps_l1_sf1_w3,
374 &ett_ubx_gps_l1_sf1_w4,
375 &ett_ubx_gps_l1_sf1_w5,
376 &ett_ubx_gps_l1_sf1_w6,
377 &ett_ubx_gps_l1_sf1_w7,
378 &ett_ubx_gps_l1_sf1_w8,
379 &ett_ubx_gps_l1_sf1_w9,
380 &ett_ubx_gps_l1_sf1_w10,
383 proto_ubx_gps_l1 = proto_register_protocol("GPS L1 Navigation Message", "GPS L1", "gps_l1");
385 register_dissector("ubx_gps_l1", dissect_ubx_gps_l1, proto_ubx_gps_l1);
387 proto_register_field_array(proto_ubx_gps_l1, hf, array_length(hf));
388 proto_register_subtree_array(ett, array_length(ett));
390 expert_ubx_gps_l1 = expert_register_protocol(proto_ubx_gps_l1);
391 expert_register_field_array(expert_ubx_gps_l1, ei, array_length(ei));
393 ubx_gps_l1_sf_dissector_table = register_dissector_table("ubx.rxm.sfrbx.gps_l1.sf",
394 "GPS L1 LNAV Subframe", proto_ubx_gps_l1, FT_UINT8, BASE_DEC);
397 void proto_reg_handoff_ubx_gps_l1(void) {
398 dissector_add_uint("ubx.rxm.sfrbx.gnssid", GNSS_ID_GPS,
399 create_dissector_handle(dissect_ubx_gps_l1, proto_ubx_gps_l1));
401 dissector_add_uint("ubx.rxm.sfrbx.gps_l1.sf", 1,
402 create_dissector_handle(dissect_ubx_gps_l1_sf1, proto_ubx_gps_l1));