Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / asn1 / lpp / packet-lpp-template.c
blob10d4e805a9518105579b8016fbb8c7dd99f566fc
1 /* packet-lpp.c
2 * Routines for 3GPP LTE Positioning Protocol (LPP) packet dissection
3 * Copyright 2011-2024 Pascal Quantin <pascal@wireshark.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
11 * Ref 3GPP TS 37.355 version 18.3.0 Release 18
12 * http://www.3gpp.org
15 #include "config.h"
17 #include "math.h"
19 #include <epan/packet.h>
20 #include <epan/asn1.h>
21 #include <epan/tfs.h>
22 #include <epan/proto_data.h>
23 #include <epan/unit_strings.h>
24 #include <wsutil/array.h>
26 #include "packet-per.h"
27 #include "packet-lpp.h"
29 #define PNAME "LTE Positioning Protocol (LPP)"
30 #define PSNAME "LPP"
31 #define PFNAME "lpp"
33 void proto_register_lpp(void);
34 void proto_reg_handoff_lpp(void);
36 /* Initialize the protocol and registered fields */
37 static int proto_lpp;
39 #include "packet-lpp-hf.c"
40 static int hf_lpp_svHealthExt_v1240_e5bhs;
41 static int hf_lpp_svHealthExt_v1240_e1_bhs;
42 static int hf_lpp_kepSV_StatusINAV_e5bhs;
43 static int hf_lpp_kepSV_StatusINAV_e1_bhs;
44 static int hf_lpp_kepSV_StatusFNAV_e5ahs;
45 static int hf_lpp_bdsSvHealth_r12_sat_clock;
46 static int hf_lpp_bdsSvHealth_r12_b1i;
47 static int hf_lpp_bdsSvHealth_r12_b2i;
48 static int hf_lpp_bdsSvHealth_r12_nav;
49 static int hf_lpp_AssistanceDataSIBelement_r15_PDU;
51 static dissector_handle_t lppe_handle;
53 static uint32_t lpp_epdu_id = -1;
55 /* Initialize the subtree pointers */
56 static int ett_lpp;
57 static int ett_lpp_svHealthExt_v1240;
58 static int ett_kepSV_StatusINAV;
59 static int ett_kepSV_StatusFNAV;
60 static int ett_lpp_bdsSvHealth_r12;
61 static int ett_lpp_assistanceDataElement_r15;
62 #include "packet-lpp-ett.c"
64 /* Include constants */
65 #include "packet-lpp-val.h"
67 static const value_string lpp_ePDU_ID_vals[] = {
68 { 1, "OMA LPP extensions (LPPe)"},
69 { 0, NULL}
72 struct lpp_private_data {
73 lpp_pos_sib_type_t pos_sib_type;
74 bool is_ciphered;
75 bool is_segmented;
78 static struct lpp_private_data*
79 lpp_get_private_data(packet_info *pinfo)
81 struct lpp_private_data *lpp_data = (struct lpp_private_data*)p_get_proto_data(pinfo->pool, pinfo, proto_lpp, 0);
82 if (!lpp_data) {
83 lpp_data = wmem_new0(pinfo->pool, struct lpp_private_data);
84 p_add_proto_data(pinfo->pool, pinfo, proto_lpp, 0, lpp_data);
86 return lpp_data;
89 /* Forward declarations */
90 static int dissect_GNSS_ReferenceTime_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
91 static int dissect_GNSS_ReferenceLocation_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
92 static int dissect_GNSS_IonosphericModel_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
93 static int dissect_GNSS_EarthOrientationParameters_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
94 static int dissect_GNSS_RTK_ReferenceStationInfo_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
95 static int dissect_GNSS_RTK_CommonObservationInfo_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
96 static int dissect_GNSS_RTK_AuxiliaryStationData_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
97 static int dissect_GNSS_SSR_CorrectionPoints_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
98 static int dissect_GNSS_Integrity_ServiceParameters_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
99 static int dissect_GNSS_Integrity_ServiceAlert_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
100 static int dissect_GNSS_TimeModelList_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
101 static int dissect_GNSS_DifferentialCorrections_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
102 static int dissect_GNSS_NavigationModel_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
103 static int dissect_GNSS_RealTimeIntegrity_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
104 static int dissect_GNSS_DataBitAssistance_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
105 static int dissect_GNSS_AcquisitionAssistance_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
106 static int dissect_GNSS_Almanac_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
107 static int dissect_GNSS_UTC_Model_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
108 static int dissect_GNSS_AuxiliaryInformation_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
109 static int dissect_BDS_DifferentialCorrections_r12_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
110 static int dissect_BDS_GridModelParameter_r12_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
111 static int dissect_GNSS_RTK_Observations_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
112 static int dissect_GLO_RTK_BiasInformation_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
113 static int dissect_GNSS_RTK_MAC_CorrectionDifferences_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
114 static int dissect_GNSS_RTK_Residuals_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
115 static int dissect_GNSS_RTK_FKP_Gradients_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
116 static int dissect_GNSS_SSR_OrbitCorrections_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
117 static int dissect_GNSS_SSR_ClockCorrections_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
118 static int dissect_GNSS_SSR_CodeBias_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
119 static int dissect_GNSS_SSR_URA_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
120 static int dissect_GNSS_SSR_PhaseBias_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
121 static int dissect_GNSS_SSR_STEC_Correction_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
122 static int dissect_GNSS_SSR_GriddedCorrection_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
123 static int dissect_NavIC_DifferentialCorrections_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
124 static int dissect_NavIC_GridModelParameter_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
125 static int dissect_OTDOA_UE_Assisted_r15_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
126 static int dissect_Sensor_AssistanceDataList_r14_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
127 static int dissect_TBS_AssistanceDataList_r14_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
128 static int dissect_NR_DL_PRS_AssistanceData_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
129 static int dissect_NR_UEB_TRP_LocationData_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
130 static int dissect_NR_UEB_TRP_RTD_Info_r16_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
131 static int dissect_NR_TRP_BeamAntennaInfo_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
132 static int dissect_NR_DL_PRS_TRP_TEG_Info_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
133 static int dissect_NR_On_Demand_DL_PRS_Configurations_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
134 static int dissect_GNSS_SSR_OrbitCorrectionsSet2_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
135 static int dissect_GNSS_SSR_ClockCorrectionsSet2_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
136 static int dissect_GNSS_SSR_URA_Set2_r17_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
137 static int dissect_GNSS_LOS_NLOS_GridPoints_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
138 static int dissect_GNSS_SSR_IOD_Update_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
139 static int dissect_GNSS_LOS_NLOS_GriddedIndications_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
140 static int dissect_GNSS_SSR_SatellitePCVResiduals_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
141 static int dissect_NR_PRU_DL_Info_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
142 static int dissect_NR_IntegrityRiskParameters_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
143 static int dissect_NR_IntegrityServiceParameters_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
144 static int dissect_NR_IntegrityServiceAlert_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
145 static int dissect_NR_IntegrityParameters_r18_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
147 static void
148 lpp_degreesLatitude_fmt(char *s, uint32_t v)
150 snprintf(s, ITEM_LABEL_LENGTH, "%f degrees (%u)",
151 ((float)v/8388607.0)*90, v);
154 static void
155 lpp_degreesLongitude_fmt(char *s, uint32_t v)
157 int32_t longitude = (int32_t) v;
159 snprintf(s, ITEM_LABEL_LENGTH, "%f degrees (%d)",
160 ((float)longitude/8388608.0)*180, longitude);
163 static void
164 lpp_uncertainty_fmt(char *s, uint32_t v)
166 double uncertainty = 10*(pow(1.1, (double)v)-1);
168 if (uncertainty < 1000) {
169 snprintf(s, ITEM_LABEL_LENGTH, "%fm (%u)", uncertainty, v);
170 } else {
171 snprintf(s, ITEM_LABEL_LENGTH, "%fkm (%u)", uncertainty/1000, v);
175 static void
176 lpp_angle_fmt(char *s, uint32_t v)
178 snprintf(s, ITEM_LABEL_LENGTH, "%u degrees (%u)", 2*v, v);
181 static void
182 lpp_confidence_fmt(char *s, uint32_t v)
184 if (v == 0) {
185 snprintf(s, ITEM_LABEL_LENGTH, "no information (0)");
186 } else {
187 snprintf(s, ITEM_LABEL_LENGTH, "%u%%", v);
191 static void
192 lpp_1_10_degrees_fmt(char *s, uint32_t v)
194 double val = (double)v/10;
196 snprintf(s, ITEM_LABEL_LENGTH, "%g degrees (%u)", val, v);
199 static void
200 lpp_1_100_m_fmt(char *s, uint32_t v)
202 double val = (double)v/100;
204 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%u)", val, v);
207 static void
208 lpp_measurementLimit_fmt(char *s, uint32_t v)
210 snprintf(s, ITEM_LABEL_LENGTH, "%u octets (%u)", 100*v, v);
213 static void
214 lpp_altitude_fmt(char *s, uint32_t v)
216 snprintf(s, ITEM_LABEL_LENGTH, "%um", v);
219 static void
220 lpp_uncertaintyAltitude_fmt(char *s, uint32_t v)
222 double uncertainty = 45*(pow(1.025, (double)v)-1);
224 snprintf(s, ITEM_LABEL_LENGTH, "%fm (%u)", uncertainty, v);
227 static void
228 lpp_radius_fmt(char *s, uint32_t v)
230 snprintf(s, ITEM_LABEL_LENGTH, "%um (%u)", 5*v, v);
233 static void
234 lpp_nr_LTE_fineTiming_Offset_fmt(char *s, uint32_t v)
236 snprintf(s, ITEM_LABEL_LENGTH, "%.1fms (%u)", (float)v/2, v);
239 static void
240 lpp_expectedRSTD_fmt(char *s, uint32_t v)
242 int32_t rstd = 3*((int32_t)v-8192);
244 snprintf(s, ITEM_LABEL_LENGTH, "%dTs (%u)", rstd, v);
247 static void
248 lpp_expectedRSTD_Uncertainty_fmt(char *s, uint32_t v)
250 snprintf(s, ITEM_LABEL_LENGTH, "%uTs (%u)", 3*v, v);
253 static void
254 lpp_rstd_fmt(char *s, uint32_t v)
256 if (v == 0) {
257 snprintf(s, ITEM_LABEL_LENGTH, "RSTD < -15391Ts (0)");
258 } else if (v < 2260) {
259 snprintf(s, ITEM_LABEL_LENGTH, "-%uTs <= RSTD < -%uTs (%u)", 15391-5*(v-1), 15391-5*v, v);
260 } else if (v < 6355) {
261 snprintf(s, ITEM_LABEL_LENGTH, "-%uTs <= RSTD < -%uTs (%u)", 6356-v, 6355-v, v);
262 } else if (v == 6355) {
263 snprintf(s, ITEM_LABEL_LENGTH, "-1Ts <= RSTD <= 0Ts (6355)");
264 } else if (v < 10452) {
265 snprintf(s, ITEM_LABEL_LENGTH, "%uTs < RSTD <= %uTs (%u)", v-6356, v-6355, v);
266 } else if (v < 12711) {
267 snprintf(s, ITEM_LABEL_LENGTH, "%uTs < RSTD <= %uTs (%u)", 5*(v-1)-48159, 5*v-48159, v);
268 } else {
269 snprintf(s, ITEM_LABEL_LENGTH, "15391Ts < RSTD (12711)");
273 static const value_string lpp_error_Resolution_vals[] = {
274 { 0, "5 meters"},
275 { 1, "10 meters"},
276 { 2, "20 meters"},
277 { 3, "30 meters"},
278 { 0, NULL}
281 static const value_string lpp_error_Value_vals[] = {
282 { 0, "0 to (R*1-1) meters"},
283 { 1, "R*1 to (R*2-1) meters"},
284 { 2, "R*2 to (R*3-1) meters"},
285 { 3, "R*3 to (R*4-1) meters"},
286 { 4, "R*4 to (R*5-1) meters"},
287 { 5, "R*5 to (R*6-1) meters"},
288 { 6, "R*6 to (R*7-1) meters"},
289 { 7, "R*7 to (R*8-1) meters"},
290 { 8, "R*8 to (R*9-1) meters"},
291 { 9, "R*9 to (R*10-1) meters"},
292 { 10, "R*10 to (R*11-1) meters"},
293 { 11, "R*11 to (R*12-1) meters"},
294 { 12, "R*12 to (R*13-1) meters"},
295 { 13, "R*13 to (R*14-1) meters"},
296 { 14, "R*14 to (R*15-1) meters"},
297 { 15, "R*15 to (R*16-1) meters"},
298 { 16, "R*16 to (R*17-1) meters"},
299 { 17, "R*17 to (R*18-1) meters"},
300 { 18, "R*18 to (R*19-1) meters"},
301 { 19, "R*19 to (R*20-1) meters"},
302 { 20, "R*20 to (R*21-1) meters"},
303 { 21, "R*21 to (R*22-1) meters"},
304 { 22, "R*22 to (R*23-1) meters"},
305 { 23, "R*23 to (R*24-1) meters"},
306 { 24, "R*24 to (R*25-1) meters"},
307 { 25, "R*25 to (R*26-1) meters"},
308 { 26, "R*26 to (R*27-1) meters"},
309 { 27, "R*27 to (R*28-1) meters"},
310 { 28, "R*28 to (R*29-1) meters"},
311 { 29, "R*29 to (R*30-1) meters"},
312 { 30, "R*30 to (R*31-1) meters"},
313 { 31, "R*31 meters or more"},
314 { 0, NULL}
316 static value_string_ext lpp_error_Value_vals_ext = VALUE_STRING_EXT_INIT(lpp_error_Value_vals);
318 static const value_string lpp_error_NumSamples_vals[] = {
319 { 0, "Not the baseline metric"},
320 { 1, "5-9"},
321 { 2, "10-14"},
322 { 3, "15-24"},
323 { 4, "25-34"},
324 { 5, "35-44"},
325 { 6, "45-54"},
326 { 7, "55 or more"},
327 { 0, NULL}
330 static void
331 lpp_relativeTimeDifference_fmt(char *s, uint32_t v)
333 double rtd = (double)((int32_t)v)*0.5;
335 snprintf(s, ITEM_LABEL_LENGTH, "%.1f Ts (%d)", rtd, (int32_t)v);
338 static void
339 lpp_referenceTimeUnc_fmt(char *s, uint32_t v)
341 double referenceTimeUnc = 0.5*(pow(1.14, (double)v)-1);
343 snprintf(s, ITEM_LABEL_LENGTH, "%fus (%u)", referenceTimeUnc, v);
346 static const value_string lpp_kp_vals[] = {
347 { 0, "No UTC correction at the end of current quarter"},
348 { 1, "UTC correction by plus (+1 s) in the end of current quarter"},
349 { 3, "UTC correction by minus (-1 s) in the end of current quarter"},
350 { 0, NULL}
353 static void
354 lpp_fractionalSecondsFromFrameStructureStart_fmt(char *s, uint32_t v)
356 float frac = ((float)v)/4;
358 snprintf(s, ITEM_LABEL_LENGTH, "%fus (%u)", frac, v);
361 static void
362 lpp_frameDrift_fmt(char *s, uint32_t v)
364 double drift = (double)((int32_t)v)*pow(2, -30);
366 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", drift, (int32_t)v);
369 static const value_string lpp_dataID_vals[] = {
370 { 0, "Parameters are applicable worldwide"},
371 { 1, "Parameters have been generated by BDS"},
372 { 3, "Parameters have been generated by QZSS"},
373 { 0, NULL}
376 static void
377 lpp_alpha0_fmt(char *s, uint32_t v)
379 double alpha = (double)((int32_t)v)*pow(2, -30);
381 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", alpha, (int32_t)v);
384 static void
385 lpp_alpha1_fmt(char *s, uint32_t v)
387 double alpha = (double)((int32_t)v)*pow(2, -27);
389 snprintf(s, ITEM_LABEL_LENGTH, "%gs/semi-circle (%d)", alpha, (int32_t)v);
392 static void
393 lpp_alpha2_3_fmt(char *s, uint32_t v)
395 double alpha = (double)((int32_t)v)*pow(2, -24);
397 snprintf(s, ITEM_LABEL_LENGTH, "%gs/semi-circle (%d)", alpha, (int32_t)v);
400 static void
401 lpp_beta0_fmt(char *s, uint32_t v)
403 double beta = (double)((int32_t)v)*pow(2, 11);
405 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", beta, (int32_t)v);
408 static void
409 lpp_beta1_fmt(char *s, uint32_t v)
411 double beta = (double)((int32_t)v)*pow(2, 14);
413 snprintf(s, ITEM_LABEL_LENGTH, "%gs/semi-circle (%d)", beta, (int32_t)v);
416 static void
417 lpp_beta2_3_fmt(char *s, uint32_t v)
419 double beta = (double)((int32_t)v)*pow(2, 16);
421 snprintf(s, ITEM_LABEL_LENGTH, "%gs/semi-circle (%d)", beta, (int32_t)v);
424 static void
425 lpp_ai0_fmt(char *s, uint32_t v)
427 double ai = (double)v*pow(2, -2);
429 snprintf(s, ITEM_LABEL_LENGTH, "%gsfu (%u)", ai, v);
432 static void
433 lpp_ai1_fmt(char *s, uint32_t v)
435 double ai = (double)v*pow(2, -8);
437 snprintf(s, ITEM_LABEL_LENGTH, "%gsfu/degree (%u)", ai, v);
440 static void
441 lpp_ai2_fmt(char *s, uint32_t v)
443 double ai = (double)v*pow(2, -15);
445 snprintf(s, ITEM_LABEL_LENGTH, "%gsfu/degree2 (%u)", ai, v);
448 static void
449 lpp_teop_fmt(char *s, uint32_t v)
451 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", 16*v, v);
454 static void
455 lpp_pmX_Y_fmt(char *s, uint32_t v)
457 double pm = (double)((int32_t)v)*pow(2, -20);
459 snprintf(s, ITEM_LABEL_LENGTH, "%g arc-seconds (%d)", pm, (int32_t)v);
462 static void
463 lpp_pmX_Ydot_fmt(char *s, uint32_t v)
465 double pmDot = (double)((int32_t)v)*pow(2, -21);
467 snprintf(s, ITEM_LABEL_LENGTH, "%g arc-seconds/day (%d)", pmDot, (int32_t)v);
470 static void
471 lpp_deltaUT1_fmt(char *s, uint32_t v)
473 double deltaUT1 = (double)((int32_t)v)*pow(2, -24);
475 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", deltaUT1, (int32_t)v);
478 static void
479 lpp_deltaUT1dot_fmt(char *s, uint32_t v)
481 double deltaUT1dot = (double)((int32_t)v)*pow(2, -25);
483 snprintf(s, ITEM_LABEL_LENGTH, "%gs/day (%d)", deltaUT1dot, (int32_t)v);
486 static void
487 lpp_1_1000m_64_fmt(char *s, uint64_t v)
489 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%"PRId64")", (double)v/1000, (int64_t)v);
492 static void
493 lpp_1_1000m_32_fmt(char *s, uint32_t v)
495 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", (double)v/1000, (int32_t)v);
498 static const value_string lpp_clockSteeringIndicator_vals[] = {
499 { 0, "Clock steering is not applied"},
500 { 1, "Clock steering has been applied"},
501 { 2, "Unknown clock steering status"},
502 { 3, "Reserved"},
503 { 0, NULL}
506 static const value_string lpp_externalClockIndicator_vals[] = {
507 { 0, "Internal clock is used"},
508 { 1, "External clock is used, clock status is \"locked\""},
509 { 2, "External clock is used, clock status is \"not locked\", which may indicate external clock failure and that the transmitted data may not be reliable"},
510 { 3, "Unknown clock is used"},
511 { 0, NULL}
514 static const value_string lpp_smoothingIndicator_r15_vals[] = {
515 { 0, "Other type of smoothing is used"},
516 { 1, "Divergence-free smoothing is used"},
517 { 0, NULL}
520 static const value_string lpp_smoothingInterval_r15_vals[] = {
521 { 0, "No smoothing"},
522 { 1, "< 30 s"},
523 { 2, "30-60 s"},
524 { 3, "1-2 min"},
525 { 4, "2-4 min"},
526 { 5, "4-8 min"},
527 { 6, "> 8 min"},
528 { 7, "Unlimited smoothing interval"},
529 { 0, NULL}
532 static void
533 lpp_aux_master_delta_fmt(char *s, uint32_t v)
535 double delta = (double)((int32_t)v)*25*pow(10, -6);
536 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%u)", delta, (int32_t)v);
539 static void
540 lpp_gnss_TimeModelRefTime_fmt(char *s, uint32_t v)
542 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", v*16, v);
545 static void
546 lpp_tA0_fmt(char *s, uint32_t v)
548 double tA0 = (double)((int32_t)v)*pow(2, -35);
550 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", tA0, (int32_t)v);
553 static void
554 lpp_tA1_fmt(char *s, uint32_t v)
556 double tA1 = (double)((int32_t)v)*pow(2, -51);
558 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", tA1, (int32_t)v);
561 static void
562 lpp_tA2_fmt(char *s, uint32_t v)
564 double tA2 = (double)((int32_t)v)*pow(2, -68);
566 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s2 (%d)", tA2, (int32_t)v);
569 static const value_string lpp_gnss_TO_ID_vals[] = {
570 { 1, "GPS"},
571 { 2, "Galileo"},
572 { 3, "QZSS"},
573 { 4, "GLONASS"},
574 { 0, NULL}
577 static const value_string lpp_gnss_StatusHealth_vals[] = {
578 { 0, "UDRE Scale Factor = 1.0"},
579 { 1, "UDRE Scale Factor = 0.75"},
580 { 2, "UDRE Scale Factor = 0.5"},
581 { 3, "UDRE Scale Factor = 0.3"},
582 { 4, "UDRE Scale Factor = 0.2"},
583 { 5, "UDRE Scale Factor = 0.1"},
584 { 6, "Reference Station Transmission Not Monitored"},
585 { 7, "Data is invalid - disregard"},
586 { 0, NULL}
589 static const value_string lpp_udre_vals[] = {
590 { 0, "UDRE <= 1.0m"},
591 { 1, "1.0m < UDRE <= 4.0m"},
592 { 2, "4.0m < UDRE <= 8.0m"},
593 { 3, "8.0m < UDRE"},
594 { 0, NULL}
597 static void
598 lpp_pseudoRangeCor_fmt(char *s, uint32_t v)
600 double pseudoRangeCor = ((double)(int32_t)v)*0.32;
602 snprintf(s, ITEM_LABEL_LENGTH, "%fm (%d)", pseudoRangeCor, (int32_t)v);
605 static void
606 lpp_rangeRateCor_fmt(char *s, uint32_t v)
608 double rangeRateCor = ((double)(int32_t)v)*0.032;
610 snprintf(s, ITEM_LABEL_LENGTH, "%fm/s (%d)", rangeRateCor, (int32_t)v);
613 static const value_string lpp_udreGrowthRate_vals[] = {
614 { 0, "1.5"},
615 { 1, "2"},
616 { 2, "4"},
617 { 3, "6"},
618 { 4, "8"},
619 { 5, "10"},
620 { 6, "12"},
621 { 7, "16"},
622 { 0, NULL}
625 static const value_string lpp_udreValidityTime_vals[] = {
626 { 0, "20s"},
627 { 1, "40s"},
628 { 2, "80s"},
629 { 3, "160s"},
630 { 4, "320s"},
631 { 5, "640s"},
632 { 6, "1280s"},
633 { 7, "2560s"},
634 { 0, NULL}
637 static const value_string lpp_signal_health_status_vals[] = {
638 { 0, "Signal OK"},
639 { 1, "Signal out of service"},
640 { 2, "Signal will be out of service"},
641 { 3, "Signal Component currently in Test"},
642 { 0, NULL}
644 static void
645 lpp_stanClockToc_fmt(char *s, uint32_t v)
647 snprintf(s, ITEM_LABEL_LENGTH, "%um/s (%u)", 60*v, v);
650 static void
651 lpp_stanClockAF2_fmt(char *s, uint32_t v)
653 double stanClockAF2 = (double)((int32_t)v)*pow(2, -59);
655 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s2 (%d)", stanClockAF2, (int32_t)v);
658 static void
659 lpp_stanClockAF1_fmt(char *s, uint32_t v)
661 double stanClockAF1 = (double)((int32_t)v)*pow(2, -46);
663 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", stanClockAF1, (int32_t)v);
666 static void
667 lpp_stanClockAF0_fmt(char *s, uint32_t v)
669 double stanClockAF0 = (double)((int32_t)v)*pow(2, -34);
671 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", stanClockAF0, (int32_t)v);
674 static void
675 lpp_stanClockTgd_fmt(char *s, uint32_t v)
677 double stanClockTgd = (double)((int32_t)v)*pow(2, -32);
679 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", stanClockTgd, (int32_t)v);
682 static void
683 lpp_sisa_fmt(char *s, uint32_t v)
685 if (v < 50) {
686 snprintf(s, ITEM_LABEL_LENGTH, "%ucm (%u)", v, v);
687 } else if (v < 75) {
688 snprintf(s, ITEM_LABEL_LENGTH, "%ucm (%u)", 50+((v-50)*2), v);
689 } else if (v < 100) {
690 snprintf(s, ITEM_LABEL_LENGTH, "%ucm (%u)", 100+((v-75)*4), v);
691 } else if (v < 126) {
692 snprintf(s, ITEM_LABEL_LENGTH, "%ucm (%u)", 200+((v-100)*16), v);
693 } else if (v < 255) {
694 snprintf(s, ITEM_LABEL_LENGTH, "Spare (%u)", v);
695 } else {
696 snprintf(s, ITEM_LABEL_LENGTH, "No Accuracy Prediction Available (255)");
700 static const value_string lpp_stanModelID_vals[] = {
701 { 0, "I/Nav"},
702 { 1, "F/Nav"},
703 { 0, NULL}
706 static void
707 lpp_navToc_fmt(char *s, uint32_t v)
709 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", 16*v, v);
712 static void
713 lpp_navaf2_fmt(char *s, uint32_t v)
715 double navaf2 = (double)((int32_t)v)*pow(2, -55);
717 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s2 (%d)", navaf2, (int32_t)v);
720 static void
721 lpp_navaf1_fmt(char *s, uint32_t v)
723 double navaf1 = (double)((int32_t)v)*pow(2, -43);
725 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", navaf1, (int32_t)v);
728 static void
729 lpp_navaf0_navTgd_fmt(char *s, uint32_t v)
731 double navaf0_navTgd = (double)((int32_t)v)*pow(2, -31);
733 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", navaf0_navTgd, (int32_t)v);
736 static void
737 lpp_cnavToc_cnavTop_fmt(char *s, uint32_t v)
739 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", 300*v, v);
742 static void
743 lpp_cnavAf2_fmt(char *s, uint32_t v)
745 double cnavAf2 = (double)((int32_t)v)*pow(2, -60);
747 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s2 (%d)", cnavAf2, (int32_t)v);
750 static void
751 lpp_cnavAf1_fmt(char *s, uint32_t v)
753 double cnavAf1 = (double)((int32_t)v)*pow(2, -48);
755 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", cnavAf1, (int32_t)v);
758 static void
759 lpp_cnavX_fmt(char *s, uint32_t v)
761 double cnavX = (double)((int32_t)v)*pow(2, -35);
763 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", cnavX, (int32_t)v);
766 static void
767 lpp_gloTau_gloDeltaTau_fmt(char *s, uint32_t v)
769 double gloTau_gloDeltaTau = (double)((int32_t)v)*pow(2, -30);
771 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", gloTau_gloDeltaTau, (int32_t)v);
774 static void
775 lpp_gloGamma_fmt(char *s, uint32_t v)
777 double gloGamma = (double)((int32_t)v)*pow(2, -40);
779 snprintf(s, ITEM_LABEL_LENGTH, "%g (%d)", gloGamma, (int32_t)v);
782 static void
783 lpp_sbasTo_fmt(char *s, uint32_t v)
785 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", 16*v, v);
788 static void
789 lpp_sbasAgfo_fmt(char *s, uint32_t v)
791 double sbasAgfo = (double)((int32_t)v)*pow(2, -31);
793 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", sbasAgfo, (int32_t)v);
796 static void
797 lpp_sbasAgf1_fmt(char *s, uint32_t v)
799 double sbasAgf1 = (double)((int32_t)v)*pow(2, -40);
801 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", sbasAgf1, (int32_t)v);
804 static void
805 lpp_bdsAODC_AODE_r12_fmt(char *s, uint32_t v)
807 if (v < 25) {
808 snprintf(s, ITEM_LABEL_LENGTH, "Age of the satellite clock correction parameters is %u hours (%u)", v, v);
809 } else if (v < 31) {
810 snprintf(s, ITEM_LABEL_LENGTH, "Age of the satellite clock correction parameters is %u days (%u)", v-23, v);
811 } else {
812 snprintf(s, ITEM_LABEL_LENGTH, "Age of the satellite clock correction parameters is over 7 days (%u)", v);
817 static void
818 lpp_bdsToc_Toe_r12_fmt(char *s, uint32_t v)
820 double bdsToc = (double)((int32_t)v)*pow(2, 3);
822 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", bdsToc, (int32_t)v);
825 static void
826 lpp_bdsA0_r12_fmt(char *s, uint32_t v)
828 double bdsA0 = (double)((int32_t)v)*pow(2, -33);
830 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", bdsA0, (int32_t)v);
833 static void
834 lpp_bdsA1_r12_fmt(char *s, uint32_t v)
836 double bdsA1 = (double)((int32_t)v)*pow(2, -50);
838 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", bdsA1, (int32_t)v);
841 static void
842 lpp_bdsA2_r12_fmt(char *s, uint32_t v)
844 double bdsA2 = (double)((int32_t)v)*pow(2, -66);
846 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s2 (%d)", bdsA2, (int32_t)v);
849 static void
850 lpp_bdsTgd1_r12_fmt(char *s, uint32_t v)
852 snprintf(s, ITEM_LABEL_LENGTH, "%gns (%d)", (float)((int32_t)v)*0.1, (int32_t)v);
855 static void
856 lpp_keplerToe_fmt(char *s, uint32_t v)
858 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", 60*v, v);
861 static void
862 lpp_keplerW_M0_I0_Omega0_fmt(char *s, uint32_t v)
864 double keplerW_M0_I0_Omega0 = (double)((int32_t)v)*pow(2, -31);
866 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", keplerW_M0_I0_Omega0, (int32_t)v);
869 static void
870 lpp_keplerDeltaN_OmegaDot_IDot_fmt(char *s, uint32_t v)
872 double keplerDeltaN_OmegaDot_IDot = (double)((int32_t)v)*pow(2, -43);
874 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", keplerDeltaN_OmegaDot_IDot, (int32_t)v);
877 static void
878 lpp_keplerE_fmt(char *s, uint32_t v)
880 double keplerE = (double)v*pow(2, -33);
882 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", keplerE, v);
885 static void
886 lpp_keplerAPowerHalf_fmt(char *s, uint32_t v)
888 double keplerAPowerHalf = (double)v*pow(2, -19);
890 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%u)", keplerAPowerHalf, v);
893 static void
894 lpp_keplerCrs_Crc_fmt(char *s, uint32_t v)
896 double keplerCrs_Crc = (double)((int32_t)v)*pow(2, -5);
898 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", keplerCrs_Crc, (int32_t)v);
901 static void
902 lpp_keplerCx_fmt(char *s, uint32_t v)
904 double keplerCx = (double)((int32_t)v)*pow(2, -29);
906 snprintf(s, ITEM_LABEL_LENGTH, "%grad (%d)", keplerCx, (int32_t)v);
909 static void
910 lpp_navToe_fmt(char *s, uint32_t v)
912 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", 16*v, v);
915 static void
916 lpp_navOmega_M0_I0_OmegaA0_fmt(char *s, uint32_t v)
918 double navOmega_M0_I0_OmegaA0 = (double)((int32_t)v)*pow(2, -31);
920 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", navOmega_M0_I0_OmegaA0, (int32_t)v);
923 static void
924 lpp_navDeltaN_OmegaADot_IDot_fmt(char *s, uint32_t v)
926 double navDeltaN_OmegaADot_IDot = (double)((int32_t)v)*pow(2, -43);
928 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", navDeltaN_OmegaADot_IDot, (int32_t)v);
931 static void
932 lpp_navE_fmt(char *s, uint32_t v)
934 double navE = (double)v*pow(2, -33);
936 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", navE, v);
939 static void
940 lpp_navAPowerHalf_fmt(char *s, uint32_t v)
942 double navAPowerHalf = (double)v*pow(2, -19);
944 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%u)", navAPowerHalf, v);
947 static void
948 lpp_navCrs_Crc_fmt(char *s, uint32_t v)
950 double navCrs_Crc = (double)((int32_t)v)*pow(2, -5);
952 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", navCrs_Crc, (int32_t)v);
955 static void
956 lpp_navCx_fmt(char *s, uint32_t v)
958 double navCx = (double)((int32_t)v)*pow(2, -29);
960 snprintf(s, ITEM_LABEL_LENGTH, "%grad (%d)", navCx, (int32_t)v);
963 static void
964 lpp_cnavDeltaA_fmt(char *s, uint32_t v)
966 double cnavDeltaA = (double)((int32_t)v)*pow(2, -9);
968 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", cnavDeltaA, (int32_t)v);
971 static void
972 lpp_cnavAdot_fmt(char *s, uint32_t v)
974 double cnavAdot = (double)((int32_t)v)*pow(2, -21);
976 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s (%d)", cnavAdot, (int32_t)v);
979 static void
980 lpp_cnavDeltaNo_fmt(char *s, uint32_t v)
982 double cnavDeltaNo = (double)((int32_t)v)*pow(2, -44);
984 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", cnavDeltaNo, (int32_t)v);
987 static void
988 lpp_cnavDeltaNoDot_fmt(char *s, uint32_t v)
990 double cnavDeltaNoDot = (double)((int32_t)v)*pow(2, -57);
992 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s2 (%d)", cnavDeltaNoDot, (int32_t)v);
995 static void
996 lpp_cnavDeltaOmegaDot_IoDot_fmt(char *s, uint32_t v)
998 double cnavDeltaOmegaDot_IoDot = (double)((int32_t)v)*pow(2, -44);
1000 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", cnavDeltaOmegaDot_IoDot, (int32_t)v);
1003 static void
1004 lpp_cnavCx_fmt(char *s, uint32_t v)
1006 double cnavCx = (double)((int32_t)v)*pow(2, -30);
1008 snprintf(s, ITEM_LABEL_LENGTH, "%grad (%d)", cnavCx, (int32_t)v);
1011 static void
1012 lpp_cnavCrs_Crc_fmt(char *s, uint32_t v)
1014 double cnavCrs_Crc = (double)((int32_t)v)*pow(2, -8);
1016 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", cnavCrs_Crc, (int32_t)v);
1019 static void
1020 lpp_gloX_Y_Z_fmt(char *s, uint32_t v)
1022 double gloX_Y_Z = (double)((int32_t)v)*pow(2, -11);
1024 snprintf(s, ITEM_LABEL_LENGTH, "%gkm (%d)", gloX_Y_Z, (int32_t)v);
1027 static void
1028 lpp_gloXdot_Ydot_Zdot_fmt(char *s, uint32_t v)
1030 double gloXdot_Ydot_Zdot = (double)((int32_t)v)*pow(2, -20);
1032 snprintf(s, ITEM_LABEL_LENGTH, "%gkm/s (%d)", gloXdot_Ydot_Zdot, (int32_t)v);
1035 static void
1036 lpp_gloXdotdot_Ydotdot_Zdotdot_fmt(char *s, uint32_t v)
1038 double gloXdotdot_Ydotdot_Zdotdot = (double)((int32_t)v)*pow(2, -30);
1040 snprintf(s, ITEM_LABEL_LENGTH, "%gkm/s2 (%d)", gloXdotdot_Ydotdot_Zdotdot, (int32_t)v);
1043 static void
1044 lpp_sbasXg_Yg_fmt(char *s, uint32_t v)
1046 double sbasXg_Yg = (double)((int32_t)v)*0.08;
1048 snprintf(s, ITEM_LABEL_LENGTH, "%fm (%d)", sbasXg_Yg, (int32_t)v);
1051 static void
1052 lpp_sbasZg_fmt(char *s, uint32_t v)
1054 double sbasZg = (double)((int32_t)v)*0.4;
1056 snprintf(s, ITEM_LABEL_LENGTH, "%fm (%d)", sbasZg, (int32_t)v);
1059 static void
1060 lpp_sbasXgDot_YgDot_fmt(char *s, uint32_t v)
1062 double sbasXgDot_YgDot = (double)((int32_t)v)*0.000625;
1064 snprintf(s, ITEM_LABEL_LENGTH, "%fm/s (%d)", sbasXgDot_YgDot, (int32_t)v);
1067 static void
1068 lpp_sbasZgDot_fmt(char *s, uint32_t v)
1070 double sbasZgDot = (double)((int32_t)v)*0.004;
1072 snprintf(s, ITEM_LABEL_LENGTH, "%fm/s (%d)", sbasZgDot, (int32_t)v);
1075 static void
1076 lpp_sbasXgDotDot_YgDotDot_fmt(char *s, uint32_t v)
1078 double sbasXgDotDot_YgDotDot = (double)((int32_t)v)*0.0000125;
1080 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s2 (%d)", sbasXgDotDot_YgDotDot, (int32_t)v);
1083 static void
1084 lpp_sbasZgDotDot_fmt(char *s, uint32_t v)
1086 double sbasZgDotDot = (double)((int32_t)v)*0.0000625;
1088 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s2 (%d)", sbasZgDotDot, (int32_t)v);
1091 static void
1092 lpp_bdsAPowerHalf_r12_fmt(char *s, uint32_t v)
1094 double bdsAPowerHalf = (double)v*pow(2, -19);
1096 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%u)", bdsAPowerHalf, v);
1099 static void
1100 lpp_bdsE_r12_fmt(char *s, uint32_t v)
1102 double bdsE = (double)v*pow(2, -33);
1104 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", bdsE, v);
1107 static void
1108 lpp_bdsW_M0_Omega0_I0_r12_fmt(char *s, uint32_t v)
1110 double bdsW_M0_Omega0_I0 = (double)((int32_t)v)*pow(2, -31);
1112 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", bdsW_M0_Omega0_I0, (int32_t)v);
1115 static void
1116 lpp_bdsDeltaN_OmegaDot_IDot_r12_fmt(char *s, uint32_t v)
1118 double bdsDeltaN_OmegaDot_IDot = (double)((int32_t)v)*pow(2, -43);
1120 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", bdsDeltaN_OmegaDot_IDot, (int32_t)v);
1123 static void
1124 lpp_bdsCuc_Cus_Cic_Cis_r12_fmt(char *s, uint32_t v)
1126 double bdsCuc_Cus_Cic_Cis = (double)((int32_t)v)*pow(2, -31);
1128 snprintf(s, ITEM_LABEL_LENGTH, "%grad (%d)", bdsCuc_Cus_Cic_Cis, (int32_t)v);
1131 static void
1132 lpp_bdsCrc_Crs_r12_fmt(char *s, uint32_t v)
1134 double bdsCrc_Crs = (double)((int32_t)v)*pow(2, -6);
1136 snprintf(s, ITEM_LABEL_LENGTH, "%grad (%d)", bdsCrc_Crs, (int32_t)v);
1139 static void
1140 lpp_doppler0_fmt(char *s, uint32_t v)
1142 double doppler0 = (double)((int32_t)v)*0.5;
1144 snprintf(s, ITEM_LABEL_LENGTH, "%fm/s (%d)", doppler0, (int32_t)v);
1147 static void
1148 lpp_doppler1_fmt(char *s, uint32_t v)
1150 double doppler1 = (double)((int32_t)(v-42))/210;
1152 snprintf(s, ITEM_LABEL_LENGTH, "%fm/s2 (%u)", doppler1, v);
1155 static const value_string lpp_dopplerUncertainty_vals[] = {
1156 { 0, "40m/s"},
1157 { 1, "20m/s"},
1158 { 2, "10m/s"},
1159 { 3, "5m/s"},
1160 { 4, "2.5m/s"},
1161 { 0, NULL}
1164 static void
1165 lpp_codePhase_fmt(char *s, uint32_t v)
1167 double codePhase = (double)v*pow(2, -10);
1169 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%u)", codePhase, v);
1172 static const value_string lpp_codePhaseSearchWindow_vals[] = {
1173 { 0, "No information"},
1174 { 1, "0.002ms"},
1175 { 2, "0.004ms"},
1176 { 3, "0.008ms"},
1177 { 4, "0.012ms"},
1178 { 5, "0.016ms"},
1179 { 6, "0.024ms"},
1180 { 7, "0.032ms"},
1181 { 8, "0.048ms"},
1182 { 9, "0.064ms"},
1183 { 10, "0.096ms"},
1184 { 11, "0.128ms"},
1185 { 12, "0.164ms"},
1186 { 13, "0.200ms"},
1187 { 14, "0.250ms"},
1188 { 15, "0.300ms"},
1189 { 16, "0.360ms"},
1190 { 17, "0.420ms"},
1191 { 18, "0.480ms"},
1192 { 19, "0.540ms"},
1193 { 20, "0.600ms"},
1194 { 21, "0.660ms"},
1195 { 22, "0.720ms"},
1196 { 23, "0.780ms"},
1197 { 24, "0.850ms"},
1198 { 25, "1.000ms"},
1199 { 26, "1.150ms"},
1200 { 27, "1.300ms"},
1201 { 28, "1.450ms"},
1202 { 29, "1.600ms"},
1203 { 30, "1.800ms"},
1204 { 31, "2.000ms"},
1205 { 0, NULL}
1207 static value_string_ext lpp_codePhaseSearchWindow_vals_ext = VALUE_STRING_EXT_INIT(lpp_codePhaseSearchWindow_vals);
1209 static void
1210 lpp_azimuth_elevation_fmt(char *s, uint32_t v)
1212 snprintf(s, ITEM_LABEL_LENGTH, "%f degrees (%u)", (float)v*0.703125, v);
1215 static void
1216 lpp_kepAlmanacE_fmt(char *s, uint32_t v)
1218 double kepAlmanacE = (double)v*pow(2, -16);
1220 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", kepAlmanacE, v);
1223 static void
1224 lpp_kepAlmanacDeltaI_fmt(char *s, uint32_t v)
1226 double kepAlmanacDeltaI = (double)((int32_t)v)*pow(2, -14);
1228 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", kepAlmanacDeltaI, (int32_t)v);
1231 static void
1232 lpp_kepAlmanacOmegaDot_fmt(char *s, uint32_t v)
1234 double kepAlmanacOmegaDot = (double)((int32_t)v)*pow(2, -33);
1236 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", kepAlmanacOmegaDot, (int32_t)v);
1239 static void
1240 lpp_kepAlmanacAPowerHalf_fmt(char *s, uint32_t v)
1242 double kepAlmanacAPowerHalf = (double)((int32_t)v)*pow(2, -9);
1244 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%d)", kepAlmanacAPowerHalf, (int32_t)v);
1247 static void
1248 lpp_kepAlmanacOmega0_W_M0_fmt(char *s, uint32_t v)
1250 double kepAlmanacOmega0_W_M0 = (double)((int32_t)v)*pow(2, -15);
1252 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", kepAlmanacOmega0_W_M0, (int32_t)v);
1255 static void
1256 lpp_kepAlmanacAF0_fmt(char *s, uint32_t v)
1258 double kepAlmanacAF0 = (double)((int32_t)v)*pow(2, -19);
1260 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", kepAlmanacAF0, (int32_t)v);
1263 static void
1264 lpp_kepAlmanacAF1_fmt(char *s, uint32_t v)
1266 double kepAlmanacAF1 = (double)((int32_t)v)*pow(2, -38);
1268 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", kepAlmanacAF1, (int32_t)v);
1271 static void
1272 lpp_navAlmE_fmt(char *s, uint32_t v)
1274 double navAlmE = (double)v*pow(2, -21);
1276 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", navAlmE, v);
1279 static void
1280 lpp_navAlmDeltaI_fmt(char *s, uint32_t v)
1282 double navAlmDeltaI = (double)((int32_t)v)*pow(2, -19);
1284 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", navAlmDeltaI, (int32_t)v);
1287 static void
1288 lpp_navAlmOMEGADOT_fmt(char *s, uint32_t v)
1290 double navAlmOMEGADOT = (double)((int32_t)v)*pow(2, -38);
1292 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", navAlmOMEGADOT, (int32_t)v);
1295 static void
1296 lpp_navAlmSqrtA_fmt(char *s, uint32_t v)
1298 double navAlmSqrtA = (double)v*pow(2, -11);
1300 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%u)", navAlmSqrtA, v);
1303 static void
1304 lpp_navAlmOMEGAo_Omega_Mo_fmt(char *s, uint32_t v)
1306 double navAlmOMEGAo_Omega_Mo = (double)((int32_t)v)*pow(2, -23);
1308 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", navAlmOMEGAo_Omega_Mo, (int32_t)v);
1311 static void
1312 lpp_navAlmaf0_fmt(char *s, uint32_t v)
1314 double navAlmaf0 = (double)((int32_t)v)*pow(2, -20);
1316 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", navAlmaf0, (int32_t)v);
1319 static void
1320 lpp_navAlmaf1_fmt(char *s, uint32_t v)
1322 double navAlmaf1 = (double)((int32_t)v)*pow(2, -38);
1324 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", navAlmaf1, (int32_t)v);
1327 static void
1328 lpp_redAlmDeltaA_fmt(char *s, uint32_t v)
1330 snprintf(s, ITEM_LABEL_LENGTH, "%dm (%d)", 512*(int)v, (int)v);
1333 static void
1334 lpp_redAlmOmega0_Phi0_fmt(char *s, uint32_t v)
1336 double redAlmOmega0_Phi0 = (double)((int32_t)v)*pow(2, -6);
1338 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", redAlmOmega0_Phi0, (int32_t)v);
1341 static void
1342 lpp_midiAlmE_fmt(char *s, uint32_t v)
1344 double midiAlmE = (double)v*pow(2, -16);
1346 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", midiAlmE, v);
1349 static void
1350 lpp_midiAlmDeltaI_fmt(char *s, uint32_t v)
1352 double midiAlmDeltaI = (double)((int32_t)v)*pow(2, -14);
1354 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", midiAlmDeltaI, (int32_t)v);
1357 static void
1358 lpp_midiAlmOmegaDot_fmt(char *s, uint32_t v)
1360 double midiAlmOmegaDot = (double)((int32_t)v)*pow(2, -33);
1362 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", midiAlmOmegaDot, (int32_t)v);
1365 static void
1366 lpp_midiAlmSqrtA_fmt(char *s, uint32_t v)
1368 snprintf(s, ITEM_LABEL_LENGTH, "%fm1/2 (%u)", (float)v*0.0625, v);
1371 static void
1372 lpp_midiAlmOmega0_Omega_Mo_fmt(char *s, uint32_t v)
1374 double midiAlmOmega0_Omega_Mo = (double)((int32_t)v)*pow(2, -15);
1376 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", midiAlmOmega0_Omega_Mo, (int32_t)v);
1379 static void
1380 lpp_midiAlmaf0_fmt(char *s, uint32_t v)
1382 double midiAlmaf0 = (double)((int32_t)v)*pow(2, -20);
1384 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", midiAlmaf0, (int32_t)v);
1387 static void
1388 lpp_midiAlmaf1_fmt(char *s, uint32_t v)
1390 double midiAlmaf1 = (double)((int32_t)v)*pow(2, -37);
1392 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", midiAlmaf1, (int32_t)v);
1395 static void
1396 lpp_gloAlmLambdaA_DeltaIa_fmt(char *s, uint32_t v)
1398 double gloAlmLambdaA_DeltaIa = (double)((int32_t)v)*pow(2, -20);
1400 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", gloAlmLambdaA_DeltaIa, (int32_t)v);
1403 static void
1404 lpp_gloAlmtlambdaA_fmt(char *s, uint32_t v)
1406 snprintf(s, ITEM_LABEL_LENGTH, "%fs (%u)", (float)v*0.03125, v);
1409 static void
1410 lpp_gloAlmDeltaTA_fmt(char *s, uint32_t v)
1412 double gloAlmDeltaTA = (double)((int32_t)v)*pow(2, -9);
1414 snprintf(s, ITEM_LABEL_LENGTH, "%gs/orbit period (%d)", gloAlmDeltaTA, (int32_t)v);
1417 static void
1418 lpp_gloAlmDeltaTdotA_fmt(char *s, uint32_t v)
1420 double gloAlmDeltaTdotA = (double)((int32_t)v)*pow(2, -14);
1422 snprintf(s, ITEM_LABEL_LENGTH, "%gs/orbit period (%d)", gloAlmDeltaTdotA, (int32_t)v);
1425 static void
1426 lpp_gloAlmEpsilonA_fmt(char *s, uint32_t v)
1428 double gloAlmEpsilonA = (double)v*pow(2, -20);
1430 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", gloAlmEpsilonA, (int32_t)v);
1433 static void
1434 lpp_gloAlmOmegaA_fmt(char *s, uint32_t v)
1436 double gloAlmOmegaA = (double)((int32_t)v)*pow(2, -15);
1438 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", gloAlmOmegaA, (int32_t)v);
1441 static void
1442 lpp_gloAlmTauA_fmt(char *s, uint32_t v)
1444 double gloAlmTauA = (double)((int32_t)v)*pow(2, -18);
1446 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", gloAlmTauA, (int32_t)v);
1449 static void
1450 lpp_sbasAlmXg_Yg_fmt(char *s, uint32_t v)
1452 snprintf(s, ITEM_LABEL_LENGTH, "%fkm (%d)", (int32_t)v*2.6, (int32_t)v);
1455 static void
1456 lpp_sbasAlmZg_fmt(char *s, uint32_t v)
1458 snprintf(s, ITEM_LABEL_LENGTH, "%dkm (%d)", (int32_t)v*26, (int32_t)v);
1461 static void
1462 lpp_sbasAlmXgdot_YgDot_fmt(char *s, uint32_t v)
1464 snprintf(s, ITEM_LABEL_LENGTH, "%dm/s (%d)", (int32_t)v*10, (int32_t)v);
1467 static void
1468 lpp_sbasAlmZgDot_fmt(char *s, uint32_t v)
1470 snprintf(s, ITEM_LABEL_LENGTH, "%fm/s (%d)", (int32_t)v*40.96, (int32_t)v);
1473 static void
1474 lpp_sbasAlmTo_fmt(char *s, uint32_t v)
1476 snprintf(s, ITEM_LABEL_LENGTH, "%um/s (%u)", v*64, v);
1479 static void
1480 lpp_bdsAlmToa_r12_fmt(char *s, uint32_t v)
1482 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", v*4096, v);
1485 static void
1486 lpp_bdsAlmSqrtA_r12_fmt(char *s, uint32_t v)
1488 double bdsAlmSqrtA = (double)v*pow(2, -11);
1490 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%u)", bdsAlmSqrtA, v);
1493 static void
1494 lpp_bdsAlmE_r12_fmt(char *s, uint32_t v)
1496 double bdsAlmE = (double)v*pow(2, -21);
1498 snprintf(s, ITEM_LABEL_LENGTH, "%gm1/2 (%u)", bdsAlmE, v);
1501 static void
1502 lpp_bdsAlmW_M0_Omega0_r12_fmt(char *s, uint32_t v)
1504 double bdsAlmW_M0_Omega0 = (double)((int32_t)v)*pow(2, -23);
1506 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", bdsAlmW_M0_Omega0, (int32_t)v);
1509 static void
1510 lpp_bdsAlmOmegaDot_r12_fmt(char *s, uint32_t v)
1512 double bdsAlmOmegaDot = (double)((int32_t)v)*pow(2, -38);
1514 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles/s (%d)", bdsAlmOmegaDot, (int32_t)v);
1517 static void
1518 lpp_bdsAlmDeltaI_r12_fmt(char *s, uint32_t v)
1520 double bdsAlmDeltaI = (double)((int32_t)v)*pow(2, -19);
1522 snprintf(s, ITEM_LABEL_LENGTH, "%g semi-circles (%d)", bdsAlmDeltaI, (int32_t)v);
1525 static void
1526 lpp_bdsAlmA0_r12_fmt(char *s, uint32_t v)
1528 double bdsAlmA0 = (double)((int32_t)v)*pow(2, -20);
1530 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", bdsAlmA0, (int32_t)v);
1533 static void
1534 lpp_bdsAlmA1_r12_fmt(char *s, uint32_t v)
1536 double bdsAlmA1 = (double)((int32_t)v)*pow(2, -38);
1538 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", bdsAlmA1, (int32_t)v);
1541 static const true_false_string lpp_bdsSvHealth_r12_b1i_b2i_value = {
1542 "OK",
1543 "Weak"
1546 static const true_false_string lpp_bdsSvHealth_r12_nav_value = {
1547 "OK",
1548 "Bad (IOD over limit)"
1551 static void
1552 lpp_gnss_Utc_A1_fmt(char *s, uint32_t v)
1554 double gnss_Utc_A1 = (double)((int32_t)v)*pow(2, -50);
1556 snprintf(s, ITEM_LABEL_LENGTH, "%gs/s (%d)", gnss_Utc_A1, (int32_t)v);
1559 static void
1560 lpp_gnss_Utc_A0_fmt(char *s, uint32_t v)
1562 double gnss_Utc_A0 = (double)((int32_t)v)*pow(2, -30);
1564 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", gnss_Utc_A0, (int32_t)v);
1567 static void
1568 lpp_gnss_Utc_Tot_fmt(char *s, uint32_t v)
1570 snprintf(s, ITEM_LABEL_LENGTH, "%us (%u)", v*4096, v);
1573 static const value_string lpp_bds_UDREI_vals[] = {
1574 { 0, "1 meter"},
1575 { 1, "1.5 meters"},
1576 { 2, "2 meters"},
1577 { 3, "3 meters"},
1578 { 4, "4 meters"},
1579 { 5, "5 meters"},
1580 { 6, "6 meters"},
1581 { 7, "8 meters"},
1582 { 8, "10 meters"},
1583 { 9, "15 meters"},
1584 { 10, "20 meters"},
1585 { 11, "50 meters"},
1586 { 12, "100 meters"},
1587 { 13, "150 meters"},
1588 { 14, "Not monitored"},
1589 { 15, "Not available"},
1590 { 0, NULL}
1592 static value_string_ext lpp_bds_UDREI_vals_ext = VALUE_STRING_EXT_INIT(lpp_bds_UDREI_vals);
1594 static const value_string lpp_bds_RURAI_vals[] = {
1595 { 0, "0.75 meter"},
1596 { 1, "1 meter"},
1597 { 2, "1.25 meters"},
1598 { 3, "1.75 meters"},
1599 { 4, "2.25 meters"},
1600 { 5, "3 meters"},
1601 { 6, "3.75 meters"},
1602 { 7, "4.5 meters"},
1603 { 8, "5.25 meters"},
1604 { 9, "6 meters"},
1605 { 10, "7.5 meters"},
1606 { 11, "15 meters"},
1607 { 12, "50 meters"},
1608 { 13, "150 meters"},
1609 { 14, "300 meters"},
1610 { 15, "> 300 meters"},
1611 { 0, NULL}
1613 static value_string_ext lpp_bds_RURAI_vals_ext = VALUE_STRING_EXT_INIT(lpp_bds_RURAI_vals);
1615 static void
1616 lpp_bds_ECC_DeltaT_r12_fmt(char *s, uint32_t v)
1618 if ((int32_t)v == -4096) {
1619 snprintf(s, ITEM_LABEL_LENGTH, "Not available (%d)", (int32_t)v);
1620 } else {
1621 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", (float)((int32_t)v)*0.1, (int32_t)v);
1625 static void
1626 lpp_bds_GridIonElement_dt_r12_fmt(char *s, uint32_t v)
1628 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", (float)((int32_t)v)*0.125, (int32_t)v);
1631 static const value_string lpp_bds_givei_vals[] = {
1632 { 0, "0.3 meter"},
1633 { 1, "0.6 meter"},
1634 { 2, "0.9 meter"},
1635 { 3, "1.2 meters"},
1636 { 4, "1.5 meters"},
1637 { 5, "1.8 meters"},
1638 { 6, "2.1 meters"},
1639 { 7, "2.4 meters"},
1640 { 8, "2.7 meters"},
1641 { 9, "3 meters"},
1642 { 10, "3.6 meters"},
1643 { 11, "4.5 meters"},
1644 { 12, "6 meters"},
1645 { 13, "9 meters"},
1646 { 14, "15 meters"},
1647 { 15, "45 meters"},
1648 { 0, NULL}
1650 static value_string_ext lpp_bds_givei_vals_ext = VALUE_STRING_EXT_INIT(lpp_bds_givei_vals);
1652 static void
1653 lpp_fine_PseudoRange_r15_fmt(char *s, uint32_t v)
1655 double val = (double)((int32_t)v)*pow(2, -29);
1657 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%d)", val, (int32_t)v);
1660 static void
1661 lpp_fine_PhaseRange_r15_fmt(char *s, uint32_t v)
1663 double val = (double)((int32_t)v)*pow(2, -31);
1665 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%d)", val, (int32_t)v);
1668 static void
1669 lpp_carrier_to_noise_ratio_r15_fmt(char *s, uint32_t v)
1671 double val = (double)v*pow(2, -4);
1673 snprintf(s, ITEM_LABEL_LENGTH, "%gdB-Hz (%d)", val, v);
1676 static void
1677 lpp_fine_PhaseRangeRate_r15_fmt(char *s, uint32_t v)
1679 double val = (double)((int32_t)v)/1000;
1681 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%d)", val, (int32_t)v);
1684 static void
1685 lpp_cpBias_r15_fmt(char *s, uint32_t v)
1687 double val = (double)((int32_t)v)/50;
1689 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", val, (int32_t)v);
1692 static const value_string lpp_ambiguityStatusFlag_r15_vals[] = {
1693 { 0, "Reserved for future use (artificial observations)"},
1694 { 1, "Correct Integer Ambiguity Level for L1 and L2"},
1695 { 2, "Correct Integer Ambiguity Level for L1-L2 widelane"},
1696 { 3, "Uncertain Integer Ambiguity Level. Only a likely guess is used"},
1697 { 0, NULL}
1700 static void
1701 lpp_1_2000m_fmt(char *s, uint32_t v)
1703 double val = (double)((int32_t)v)/2000;
1705 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", val, (int32_t)v);
1708 static void
1709 lpp_1_100ppm_fmt(char *s, uint32_t v)
1711 double val = (double)((int32_t)v)/100;
1713 snprintf(s, ITEM_LABEL_LENGTH, "%gppm (%d)", val, (int32_t)v);
1716 static void
1717 lpp_1_10ppm_fmt(char *s, uint32_t v)
1719 double val = (double)((int32_t)v)/10;
1721 snprintf(s, ITEM_LABEL_LENGTH, "%gppm (%d)", val, (int32_t)v);
1724 static const value_string lpp_ssrUpdateInterval_r15_vals[] = {
1725 { 0, "1 second"},
1726 { 1, "2 seconds"},
1727 { 2, "5 seconds"},
1728 { 3, "10 seconds"},
1729 { 4, "15 seconds"},
1730 { 5, "30 seconds"},
1731 { 6, "60 seconds"},
1732 { 7, "120 seconds"},
1733 { 8, "240 seconds"},
1734 { 9, "300 seconds"},
1735 { 10, "600 seconds"},
1736 { 11, "900 seconds"},
1737 { 12, "1800 seconds"},
1738 { 13, "3600 seconds"},
1739 { 14, "7200 seconds"},
1740 { 15, "10800 seconds"},
1741 { 0, NULL}
1744 static void
1745 lpp_1_10000m_fmt(char *s, uint32_t v)
1747 double val = (double)((int32_t)v)/10000;
1749 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", val, (int32_t)v);
1752 static void
1753 lpp_4_10000m_fmt(char *s, uint32_t v)
1755 double val = (double)((int32_t)v)/10000*4;
1757 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", val, (int32_t)v);
1760 static void
1761 lpp_1_1000000m_s_fmt(char *s, uint32_t v)
1763 double val = (double)((int32_t)v)/1000000;
1765 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s (%d)", val, (int32_t)v);
1768 static void
1769 lpp_4_1000000m_s_fmt(char *s, uint32_t v)
1771 double val = (double)((int32_t)v)/1000000*4;
1773 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s (%d)", val, (int32_t)v);
1776 static void
1777 lpp_2_100000000m_s2_fmt(char *s, uint32_t v)
1779 double val = (double)((int32_t)v)/100000000*2;
1781 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s2 (%d)", val, (int32_t)v);
1784 static void
1785 lpp_1_100000m_fmt(char *s, uint32_t v)
1787 double val = (double)((int32_t)v)/100000;
1789 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%d)", val, (int32_t)v);
1792 static void
1793 lpp_tauC_fmt(char *s, uint32_t v)
1795 double tauC = (double)((int32_t)v)*pow(2, -31);
1797 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", tauC, (int32_t)v);
1800 static void
1801 lpp_b1_fmt(char *s, uint32_t v)
1803 double b1 = (double)((int32_t)v)*pow(2, -10);
1805 snprintf(s, ITEM_LABEL_LENGTH, "%gs (%d)", b1, (int32_t)v);
1808 static void
1809 lpp_b2_fmt(char *s, uint32_t v)
1811 double b2 = (double)((int32_t)v)*pow(2, -16);
1813 snprintf(s, ITEM_LABEL_LENGTH, "%gs/msd (%d)", b2, (int32_t)v);
1816 static const value_string lpp_utcStandardID_vals[] = {
1817 { 0, "UTC as operated by the Communications Research Laboratory (CRL), Tokyo, Japan"},
1818 { 1, "UTC as operated by the National Institute of Standards and Technology (NIST)"},
1819 { 2, "UTC as operated by the U. S. Naval Observatory (USNO)"},
1820 { 3, "UTC as operated by the International Bureau of Weights and Measures (BIPM)"},
1821 { 0, NULL}
1824 static const value_string lpp_dataBitInterval_vals[] = {
1825 { 0, "0.1"},
1826 { 1, "0.2"},
1827 { 2, "0.4"},
1828 { 3, "0.8"},
1829 { 4, "1.6"},
1830 { 5, "3.2"},
1831 { 6, "6.4"},
1832 { 7, "12.8"},
1833 { 8, "25.6"},
1834 { 9, "51.2"},
1835 { 10, "102.4"},
1836 { 11, "204.8"},
1837 { 12, "409.6"},
1838 { 13, "819.2"},
1839 { 14, "1638.4"},
1840 { 15, "Not specified"},
1841 { 0, NULL}
1843 static value_string_ext lpp_dataBitInterval_vals_ext = VALUE_STRING_EXT_INIT(lpp_dataBitInterval_vals);
1845 static const value_string lpp_carrierQualityInd_vals[] = {
1846 { 0, "Data direct, carrier phase not continuous"},
1847 { 1, "Data inverted, carrier phase not continuous"},
1848 { 2, "Data direct, carrier phase continuous"},
1849 { 3, "Data inverted, carrier phase continuous"},
1850 { 0, NULL}
1853 static void
1854 lpp_GNSS_SatMeas_codePhase_fmt(char *s, uint32_t v)
1856 double codePhase = (double)v*pow(2, -21);
1858 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%u)", codePhase, v);
1861 static void
1862 lpp_codePhaseRMSError_fmt(char *s, uint32_t v)
1864 uint8_t mantissa = v & 0x07;
1865 uint8_t exponent = (v & 0x38) >> 3;
1866 uint8_t mantissa_1 = (v - 1) & 0x07;
1867 uint8_t exponent_1 = ((v - 1) & 0x38) >> 3;
1869 if (v == 0) {
1870 snprintf(s, ITEM_LABEL_LENGTH, "P < 0.5 (0)");
1871 } else if (v < 63) {
1872 snprintf(s, ITEM_LABEL_LENGTH, "%f <= P < %f (%u)", 0.5*(1+mantissa_1/8)*pow(2, exponent_1),
1873 0.5*(1+mantissa/8)*pow(2, exponent), v);
1874 } else {
1875 snprintf(s, ITEM_LABEL_LENGTH, "112 <= P (63)");
1879 static void
1880 lpp_transmitterLatitude_fmt(char *s, uint32_t v)
1882 double lat = ((double)v*4.0/pow(2, 20))-90.0;
1884 snprintf(s, ITEM_LABEL_LENGTH, "%g degrees (%u)", lat, v);
1887 static void
1888 lpp_transmitterLongitude_fmt(char *s, uint32_t v)
1890 double longitude = ((double)v*4.0/pow(2, 20))-180.0;
1892 snprintf(s, ITEM_LABEL_LENGTH, "%g degrees (%u)", longitude, v);
1895 static void
1896 lpp_transmitterAltitude_fmt(char *s, uint32_t v)
1898 double alt = ((double)v*0.29)-500.0;
1900 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%u)", alt, v);
1903 static void
1904 lpp_refPressure_fmt(char *s, uint32_t v)
1906 int32_t pressure = (int32_t)v;
1908 snprintf(s, ITEM_LABEL_LENGTH, "%dPa (%d)", 101325+pressure, pressure);
1911 static void
1912 lpp_refTemperature_fmt(char *s, uint32_t v)
1914 int32_t temp = (int32_t)v;
1916 snprintf(s, ITEM_LABEL_LENGTH, "%dK (%d)", 273+temp, temp);
1919 static void
1920 lpp_referencePressureRate_v1520_fmt(char *s, uint32_t v)
1922 int32_t rate = (int32_t)v;
1924 snprintf(s, ITEM_LABEL_LENGTH, "%dPa/hour (%d)", 10*rate, rate);
1927 static void
1928 lpp_PressureValidityPeriod_v1520_fmt(char *s, uint32_t v)
1930 snprintf(s, ITEM_LABEL_LENGTH, "%umin (%u)", 15*v, v);
1933 static void
1934 lpp_doppler_fmt(char *s, uint32_t v)
1936 snprintf(s, ITEM_LABEL_LENGTH, "%gm/s (%d)", (int32_t)v*0.04, (int32_t)v);
1939 static void
1940 lpp_adr_fmt(char *s, uint32_t v)
1942 double adr = (double)v*pow(2, -10);
1944 snprintf(s, ITEM_LABEL_LENGTH, "%gm (%u)", adr, v);
1947 static void
1948 lpp_adrMSB_r15_fmt(char *s, uint32_t v)
1950 snprintf(s, ITEM_LABEL_LENGTH, "%um (%u)", v*32768, v);
1953 static void
1954 lpp_GNSS_SatMeas_delta_codePhase_r15_fmt(char *s, uint32_t v)
1956 double codePhase = (double)v*pow(2, -24);
1958 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%u)", codePhase, v);
1961 static void
1962 lpp_deliveryAmount_r15_fmt(char *s, uint32_t v)
1964 snprintf(s, ITEM_LABEL_LENGTH, "%g (%u)", pow(2, v), v);
1967 static void
1968 lpp_rsrp_Result_fmt(char *s, uint32_t v)
1970 if (v == 0) {
1971 snprintf(s, ITEM_LABEL_LENGTH, "RSRP < -140dBm (0)");
1972 } else if (v < 97) {
1973 snprintf(s, ITEM_LABEL_LENGTH, "%ddBm <= RSRP < %ddBm (%u)", v-141, v-140, v);
1974 } else {
1975 snprintf(s, ITEM_LABEL_LENGTH, "-44dBm <= RSRP (97)");
1979 static void
1980 lpp_rsrq_Result_fmt(char *s, uint32_t v)
1982 if (v == 0) {
1983 snprintf(s, ITEM_LABEL_LENGTH, "RSRQ < -19.5dB (0)");
1984 } else if (v < 34) {
1985 snprintf(s, ITEM_LABEL_LENGTH, "%.1fdB <= RSRQ < %.1fdB (%u)", ((float)v/2)-20, (((float)v+1)/2)-20, v);
1986 } else {
1987 snprintf(s, ITEM_LABEL_LENGTH, "-3dB <= RSRQ (34)");
1991 static void
1992 lpp_nrsrp_Result_fmt(char *s, uint32_t v)
1994 if (v == 0) {
1995 snprintf(s, ITEM_LABEL_LENGTH, "NRSRP < -156dBm (0)");
1996 } else if (v < 113) {
1997 snprintf(s, ITEM_LABEL_LENGTH, "%ddBm <= NRSRP < %ddBm (%u)", v-157, v-156, v);
1998 } else {
1999 snprintf(s, ITEM_LABEL_LENGTH, "-44dBm <= NRSRP (97)");
2003 static void
2004 lpp_nrsrq_Result_fmt(char *s, uint32_t v)
2006 if (v == 0) {
2007 snprintf(s, ITEM_LABEL_LENGTH, "NRSRQ < -34dB (0)");
2008 } else if (v < 74) {
2009 snprintf(s, ITEM_LABEL_LENGTH, "%.1fdB <= NRSRQ < %.1fdB (%u)", (((float)v-1)/2)-34, ((float)v/2)-34, v);
2010 } else {
2011 snprintf(s, ITEM_LABEL_LENGTH, "2.5dB <= NRSRQ (%u)", v);
2015 static void
2016 lpp_rsrp_Result_v1470_fmt(char *s, uint32_t v)
2018 int32_t d = (int32_t)v;
2020 if (d == -17) {
2021 snprintf(s, ITEM_LABEL_LENGTH, "RSRP < -157dBm (-17)");
2022 } else {
2023 snprintf(s, ITEM_LABEL_LENGTH, "%ddBm <= RSRP < %ddBm (%d)", d-141, d-140, d);
2027 static void
2028 lpp_rsrq_Result_v1470_fmt(char *s, uint32_t v)
2030 int32_t d = (int32_t)v;
2032 if (v == 0) {
2033 snprintf(s, ITEM_LABEL_LENGTH, "RSRQ < -34.5dB (-30)");
2034 } else if (v < 46) {
2035 snprintf(s, ITEM_LABEL_LENGTH, "%.1fdB <= RSRQ < %.1fdB (%d)", ((float)d/2)-20, (((float)d+1)/2)-20, d);
2036 } else {
2037 snprintf(s, ITEM_LABEL_LENGTH, "3dB <= RSRQ (46)");
2041 static void
2042 lpp_ue_RxTxTimeDiff_fmt(char *s, uint32_t v)
2044 if (v == 0) {
2045 snprintf(s, ITEM_LABEL_LENGTH, "T < 2Ts (0)");
2046 } else if (v < 2048) {
2047 snprintf(s, ITEM_LABEL_LENGTH, "%uTs <= T < %uTs (%u)", v*2, (v+1)*2, v);
2048 } else if (v < 4095) {
2049 snprintf(s, ITEM_LABEL_LENGTH, "%uTs <= T < %uTs (%u)", (v*8)-12288, ((v+1)*8)-12288, v);
2050 } else {
2051 snprintf(s, ITEM_LABEL_LENGTH, "20472Ts <= T (4095)");
2055 static void
2056 lpp_mbs_beaconMeasElt_codePhase_fmt(char *s, uint32_t v)
2058 double codePhase = (double)v*pow(2, -21);
2060 snprintf(s, ITEM_LABEL_LENGTH, "%gms (%u)", codePhase, v);
2063 #include "packet-lpp-fn.c"
2065 int dissect_lpp_AssistanceDataSIBelement_r15_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, lpp_pos_sib_type_t pos_sib_type) {
2066 int offset = 0;
2067 asn1_ctx_t asn1_ctx;
2068 struct lpp_private_data *lpp_data = lpp_get_private_data(pinfo);
2070 asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, false, pinfo);
2071 lpp_data->pos_sib_type = pos_sib_type;
2072 offset = dissect_lpp_AssistanceDataSIBelement_r15(tvb, offset, &asn1_ctx, tree, hf_lpp_AssistanceDataSIBelement_r15_PDU);
2073 offset += 7; offset >>= 3;
2074 return offset;
2077 static int dissect_lpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
2078 proto_tree *subtree;
2079 proto_item *it;
2081 it = proto_tree_add_item(tree, proto_lpp, tvb, 0, -1, ENC_NA);
2082 col_append_sep_str(pinfo->cinfo, COL_PROTOCOL, "/", "LPP");
2083 subtree = proto_item_add_subtree(it, ett_lpp);
2085 return dissect_LPP_Message_PDU(tvb, pinfo, subtree, NULL);
2088 /*--- proto_register_lpp -------------------------------------------*/
2089 void proto_register_lpp(void) {
2091 /* List of fields */
2092 static hf_register_info hf[] = {
2094 #include "packet-lpp-hfarr.c"
2095 { &hf_lpp_svHealthExt_v1240_e5bhs,
2096 { "E5b Signal Health Status", "lpp.svHealthExt_v1240.e5bhs",
2097 FT_UINT8, BASE_DEC, VALS(lpp_signal_health_status_vals), 0,
2098 NULL, HFILL }},
2099 { &hf_lpp_svHealthExt_v1240_e1_bhs,
2100 { "E1-B Signal Health Status", "lpp.svHealthExt_v1240.e1_bhs",
2101 FT_UINT8, BASE_DEC, VALS(lpp_signal_health_status_vals), 0,
2102 NULL, HFILL }},
2103 { &hf_lpp_kepSV_StatusINAV_e5bhs,
2104 { "E5b Signal Health Status", "lpp.kepSV_StatusINAV.e5bhs",
2105 FT_UINT8, BASE_DEC, VALS(lpp_signal_health_status_vals), 0,
2106 NULL, HFILL }},
2107 { &hf_lpp_kepSV_StatusINAV_e1_bhs,
2108 { "E1-B Signal Health Status", "lpp.kepSV_StatusINAV.e1_bhs",
2109 FT_UINT8, BASE_DEC, VALS(lpp_signal_health_status_vals), 0,
2110 NULL, HFILL }},
2111 { &hf_lpp_kepSV_StatusFNAV_e5ahs,
2112 { "E5a Signal Health Status", "lpp.kepSV_StatusFNAV.e5ahs",
2113 FT_UINT8, BASE_DEC, VALS(lpp_signal_health_status_vals), 0,
2114 NULL, HFILL }},
2115 { &hf_lpp_bdsSvHealth_r12_sat_clock,
2116 { "Satellite Clock", "lpp.bdsSvHealth_r12.sat_clock",
2117 FT_BOOLEAN, BASE_NONE, TFS(&tfs_ok_error), 0,
2118 NULL, HFILL }},
2119 { &hf_lpp_bdsSvHealth_r12_b1i,
2120 { "B1I Signal", "lpp.bdsSvHealth_r12.b1i",
2121 FT_BOOLEAN, BASE_NONE, TFS(&lpp_bdsSvHealth_r12_b1i_b2i_value), 0,
2122 NULL, HFILL }},
2123 { &hf_lpp_bdsSvHealth_r12_b2i,
2124 { "B2I Signal", "lpp.bdsSvHealth_r12.b2i",
2125 FT_BOOLEAN, BASE_NONE, TFS(&lpp_bdsSvHealth_r12_b1i_b2i_value), 0,
2126 NULL, HFILL }},
2127 { &hf_lpp_bdsSvHealth_r12_nav,
2128 { "NAV Message", "lpp.bdsSvHealth_r12.nav",
2129 FT_BOOLEAN, BASE_NONE, TFS(&lpp_bdsSvHealth_r12_nav_value), 0,
2130 NULL, HFILL }},
2131 { &hf_lpp_AssistanceDataSIBelement_r15_PDU,
2132 { "AssistanceDataSIBelement-r15", "lpp.AssistanceDataSIBelement_r15_element",
2133 FT_NONE, BASE_NONE, NULL, 0,
2134 NULL, HFILL }},
2137 /* List of subtrees */
2138 static int *ett[] = {
2139 &ett_lpp,
2140 &ett_lpp_svHealthExt_v1240,
2141 &ett_kepSV_StatusINAV,
2142 &ett_kepSV_StatusFNAV,
2143 &ett_lpp_bdsSvHealth_r12,
2144 &ett_lpp_assistanceDataElement_r15,
2145 #include "packet-lpp-ettarr.c"
2149 /* Register protocol */
2150 proto_lpp = proto_register_protocol(PNAME, PSNAME, PFNAME);
2151 register_dissector("lpp", dissect_lpp, proto_lpp);
2153 /* Register fields and subtrees */
2154 proto_register_field_array(proto_lpp, hf, array_length(hf));
2155 proto_register_subtree_array(ett, array_length(ett));
2161 /*--- proto_reg_handoff_lpp ---------------------------------------*/
2162 void
2163 proto_reg_handoff_lpp(void)
2165 lppe_handle = find_dissector_add_dependency("lppe", proto_lpp);