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
19 #include <epan/packet.h>
20 #include <epan/asn1.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)"
33 void proto_register_lpp(void);
34 void proto_reg_handoff_lpp(void);
36 /* Initialize the protocol and registered fields */
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 */
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)"},
72 struct lpp_private_data
{
73 lpp_pos_sib_type_t pos_sib_type
;
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);
83 lpp_data
= wmem_new0(pinfo
->pool
, struct lpp_private_data
);
84 p_add_proto_data(pinfo
->pool
, pinfo
, proto_lpp
, 0, 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_
);
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
);
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
);
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
);
171 snprintf(s
, ITEM_LABEL_LENGTH
, "%fkm (%u)", uncertainty
/1000, v
);
176 lpp_angle_fmt(char *s
, uint32_t v
)
178 snprintf(s
, ITEM_LABEL_LENGTH
, "%u degrees (%u)", 2*v
, v
);
182 lpp_confidence_fmt(char *s
, uint32_t v
)
185 snprintf(s
, ITEM_LABEL_LENGTH
, "no information (0)");
187 snprintf(s
, ITEM_LABEL_LENGTH
, "%u%%", v
);
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
);
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
);
208 lpp_measurementLimit_fmt(char *s
, uint32_t v
)
210 snprintf(s
, ITEM_LABEL_LENGTH
, "%u octets (%u)", 100*v
, v
);
214 lpp_altitude_fmt(char *s
, uint32_t v
)
216 snprintf(s
, ITEM_LABEL_LENGTH
, "%um", v
);
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
);
228 lpp_radius_fmt(char *s
, uint32_t v
)
230 snprintf(s
, ITEM_LABEL_LENGTH
, "%um (%u)", 5*v
, v
);
234 lpp_nr_LTE_fineTiming_Offset_fmt(char *s
, uint32_t v
)
236 snprintf(s
, ITEM_LABEL_LENGTH
, "%.1fms (%u)", (float)v
/2, v
);
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
);
248 lpp_expectedRSTD_Uncertainty_fmt(char *s
, uint32_t v
)
250 snprintf(s
, ITEM_LABEL_LENGTH
, "%uTs (%u)", 3*v
, v
);
254 lpp_rstd_fmt(char *s
, uint32_t v
)
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
);
269 snprintf(s
, ITEM_LABEL_LENGTH
, "15391Ts < RSTD (12711)");
273 static const value_string lpp_error_Resolution_vals
[] = {
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"},
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"},
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
);
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"},
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
);
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"},
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
449 lpp_teop_fmt(char *s
, uint32_t v
)
451 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", 16*v
, v
);
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
);
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
);
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
);
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
);
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
);
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"},
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"},
514 static const value_string lpp_smoothingIndicator_r15_vals
[] = {
515 { 0, "Other type of smoothing is used"},
516 { 1, "Divergence-free smoothing is used"},
520 static const value_string lpp_smoothingInterval_r15_vals
[] = {
521 { 0, "No smoothing"},
528 { 7, "Unlimited smoothing interval"},
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
);
540 lpp_gnss_TimeModelRefTime_fmt(char *s
, uint32_t v
)
542 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", v
*16, v
);
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
);
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
);
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
[] = {
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"},
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"},
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
);
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
[] = {
625 static const value_string lpp_udreValidityTime_vals
[] = {
637 static const value_string lpp_signal_health_status_vals
[] = {
639 { 1, "Signal out of service"},
640 { 2, "Signal will be out of service"},
641 { 3, "Signal Component currently in Test"},
645 lpp_stanClockToc_fmt(char *s
, uint32_t v
)
647 snprintf(s
, ITEM_LABEL_LENGTH
, "%um/s (%u)", 60*v
, v
);
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
);
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
);
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
);
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
);
683 lpp_sisa_fmt(char *s
, uint32_t v
)
686 snprintf(s
, ITEM_LABEL_LENGTH
, "%ucm (%u)", v
, v
);
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
);
696 snprintf(s
, ITEM_LABEL_LENGTH
, "No Accuracy Prediction Available (255)");
700 static const value_string lpp_stanModelID_vals
[] = {
707 lpp_navToc_fmt(char *s
, uint32_t v
)
709 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", 16*v
, v
);
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
);
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
);
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
);
737 lpp_cnavToc_cnavTop_fmt(char *s
, uint32_t v
)
739 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", 300*v
, v
);
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
);
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
);
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
);
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
);
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
);
783 lpp_sbasTo_fmt(char *s
, uint32_t v
)
785 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", 16*v
, v
);
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
);
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
);
805 lpp_bdsAODC_AODE_r12_fmt(char *s
, uint32_t v
)
808 snprintf(s
, ITEM_LABEL_LENGTH
, "Age of the satellite clock correction parameters is %u hours (%u)", v
, v
);
810 snprintf(s
, ITEM_LABEL_LENGTH
, "Age of the satellite clock correction parameters is %u days (%u)", v
-23, v
);
812 snprintf(s
, ITEM_LABEL_LENGTH
, "Age of the satellite clock correction parameters is over 7 days (%u)", v
);
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
);
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
);
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
);
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
);
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
);
856 lpp_keplerToe_fmt(char *s
, uint32_t v
)
858 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", 60*v
, v
);
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
);
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
);
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
);
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
);
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
);
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
);
910 lpp_navToe_fmt(char *s
, uint32_t v
)
912 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", 16*v
, v
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
[] = {
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"},
1207 static value_string_ext lpp_codePhaseSearchWindow_vals_ext
= VALUE_STRING_EXT_INIT(lpp_codePhaseSearchWindow_vals
);
1210 lpp_azimuth_elevation_fmt(char *s
, uint32_t v
)
1212 snprintf(s
, ITEM_LABEL_LENGTH
, "%f degrees (%u)", (float)v
*0.703125, v
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1328 lpp_redAlmDeltaA_fmt(char *s
, uint32_t v
)
1330 snprintf(s
, ITEM_LABEL_LENGTH
, "%dm (%d)", 512*(int)v
, (int)v
);
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
);
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
);
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
);
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
);
1366 lpp_midiAlmSqrtA_fmt(char *s
, uint32_t v
)
1368 snprintf(s
, ITEM_LABEL_LENGTH
, "%fm1/2 (%u)", (float)v
*0.0625, v
);
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
);
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
);
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
);
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
);
1404 lpp_gloAlmtlambdaA_fmt(char *s
, uint32_t v
)
1406 snprintf(s
, ITEM_LABEL_LENGTH
, "%fs (%u)", (float)v
*0.03125, v
);
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
);
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
);
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
);
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
);
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
);
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
);
1456 lpp_sbasAlmZg_fmt(char *s
, uint32_t v
)
1458 snprintf(s
, ITEM_LABEL_LENGTH
, "%dkm (%d)", (int32_t)v
*26, (int32_t)v
);
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
);
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
);
1474 lpp_sbasAlmTo_fmt(char *s
, uint32_t v
)
1476 snprintf(s
, ITEM_LABEL_LENGTH
, "%um/s (%u)", v
*64, v
);
1480 lpp_bdsAlmToa_r12_fmt(char *s
, uint32_t v
)
1482 snprintf(s
, ITEM_LABEL_LENGTH
, "%us (%u)", v
*4096, v
);
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
);
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
);
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
);
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
);
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
);
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
);
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
= {
1546 static const true_false_string lpp_bdsSvHealth_r12_nav_value
= {
1548 "Bad (IOD over limit)"
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
);
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
);
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
[] = {
1586 { 12, "100 meters"},
1587 { 13, "150 meters"},
1588 { 14, "Not monitored"},
1589 { 15, "Not available"},
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
[] = {
1597 { 2, "1.25 meters"},
1598 { 3, "1.75 meters"},
1599 { 4, "2.25 meters"},
1601 { 6, "3.75 meters"},
1603 { 8, "5.25 meters"},
1605 { 10, "7.5 meters"},
1608 { 13, "150 meters"},
1609 { 14, "300 meters"},
1610 { 15, "> 300 meters"},
1613 static value_string_ext lpp_bds_RURAI_vals_ext
= VALUE_STRING_EXT_INIT(lpp_bds_RURAI_vals
);
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
);
1621 snprintf(s
, ITEM_LABEL_LENGTH
, "%gm (%d)", (float)((int32_t)v
)*0.1, (int32_t)v
);
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
[] = {
1642 { 10, "3.6 meters"},
1643 { 11, "4.5 meters"},
1650 static value_string_ext lpp_bds_givei_vals_ext
= VALUE_STRING_EXT_INIT(lpp_bds_givei_vals
);
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
);
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
);
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
);
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
);
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"},
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
);
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
);
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
[] = {
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"},
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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)"},
1824 static const value_string lpp_dataBitInterval_vals
[] = {
1840 { 15, "Not specified"},
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"},
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
);
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;
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
);
1875 snprintf(s
, ITEM_LABEL_LENGTH
, "112 <= P (63)");
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
);
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
);
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
);
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
);
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
);
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
);
1928 lpp_PressureValidityPeriod_v1520_fmt(char *s
, uint32_t v
)
1930 snprintf(s
, ITEM_LABEL_LENGTH
, "%umin (%u)", 15*v
, v
);
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
);
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
);
1948 lpp_adrMSB_r15_fmt(char *s
, uint32_t v
)
1950 snprintf(s
, ITEM_LABEL_LENGTH
, "%um (%u)", v
*32768, v
);
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
);
1962 lpp_deliveryAmount_r15_fmt(char *s
, uint32_t v
)
1964 snprintf(s
, ITEM_LABEL_LENGTH
, "%g (%u)", pow(2, v
), v
);
1968 lpp_rsrp_Result_fmt(char *s
, uint32_t v
)
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
);
1975 snprintf(s
, ITEM_LABEL_LENGTH
, "-44dBm <= RSRP (97)");
1980 lpp_rsrq_Result_fmt(char *s
, uint32_t v
)
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
);
1987 snprintf(s
, ITEM_LABEL_LENGTH
, "-3dB <= RSRQ (34)");
1992 lpp_nrsrp_Result_fmt(char *s
, uint32_t v
)
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
);
1999 snprintf(s
, ITEM_LABEL_LENGTH
, "-44dBm <= NRSRP (97)");
2004 lpp_nrsrq_Result_fmt(char *s
, uint32_t v
)
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
);
2011 snprintf(s
, ITEM_LABEL_LENGTH
, "2.5dB <= NRSRQ (%u)", v
);
2016 lpp_rsrp_Result_v1470_fmt(char *s
, uint32_t v
)
2018 int32_t d
= (int32_t)v
;
2021 snprintf(s
, ITEM_LABEL_LENGTH
, "RSRP < -157dBm (-17)");
2023 snprintf(s
, ITEM_LABEL_LENGTH
, "%ddBm <= RSRP < %ddBm (%d)", d
-141, d
-140, d
);
2028 lpp_rsrq_Result_v1470_fmt(char *s
, uint32_t v
)
2030 int32_t d
= (int32_t)v
;
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
);
2037 snprintf(s
, ITEM_LABEL_LENGTH
, "3dB <= RSRQ (46)");
2042 lpp_ue_RxTxTimeDiff_fmt(char *s
, uint32_t v
)
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
);
2051 snprintf(s
, ITEM_LABEL_LENGTH
, "20472Ts <= T (4095)");
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
) {
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;
2077 static int dissect_lpp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
2078 proto_tree
*subtree
;
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,
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,
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,
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,
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,
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,
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,
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,
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,
2131 { &hf_lpp_AssistanceDataSIBelement_r15_PDU
,
2132 { "AssistanceDataSIBelement-r15", "lpp.AssistanceDataSIBelement_r15_element",
2133 FT_NONE
, BASE_NONE
, NULL
, 0,
2137 /* List of subtrees */
2138 static int *ett
[] = {
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 ---------------------------------------*/
2163 proto_reg_handoff_lpp(void)
2165 lppe_handle
= find_dissector_add_dependency("lppe", proto_lpp
);