1 /*****************************************************************************
3 This is a decoder for RTCM-104 3.x, a serial protocol used for
4 broadcasting pseudorange corrections from differential-GPS reference
5 stations. The applicable specification is RTCM 10403.1: RTCM Paper
6 177-2006-SC104-STD. This obsolesces the esrlier RTCM-104 2.x
7 specifications. The specification document is proprietary; ordering
8 instructions are accessible from <http://www.rtcm.org/>
11 Unike the RTCM 2.x protocol, RTCM3.x does not use the strange
12 sliding-bit-window IS-GPS-200 protocol as a transport layer, but is a
13 self-contained byte-oriented packet protocol. Packet recognition is
14 handled in the GPSD packet-getter state machine; this code is
15 concerned with unpacking the packets into well-behaved C structures,
16 coping with odd field lengths and fields that may overlap byte
17 boudaries. These report structures live in gps.h.
19 Note that the unpacking this module does is probably useful only for
20 RTCM reporting and diagnostic tools. It is not necessary when
21 passing RTCM corrections to a GPS, which normally should just be
22 passed an entire correction packet for processing by their internal
25 This file is Copyright (c) 2010 by the GPSD project
26 BSD terms apply: see the file COPYING in the distribution root for details.
28 *****************************************************************************/
30 #include <sys/types.h>
33 #endif /* S_SPLINT_S */
39 #include "gpsd_config.h"
42 #include <arpa/inet.h> /* for ntohl(3) and friends */
43 #endif /* HAVE_ARPA_INET */
44 #endif /* S_SPLINT_S */
49 #ifdef RTCM104V3_ENABLE
51 /* scaling constants for RTCM3 real number types */
52 #define PSEUDORANGE_RESOLUTION 0.2 /* DF011 */
53 #define PSEUDORANGE_DIFF_RESOLUTION 0.0005 /* DF012 */
54 #define CARRIER_NOISE_RATIO_UNITS 0.25 /* DF015 */
55 #define ANTENNA_POSITION_RESOLUTION 0.0001 /* DF025-027 */
56 #define ANTENNA_DEGREE_RESOLUTION 25e-6 /* DF062 */
57 #define GPS_EPOCH_TIME_RESOLUTION 0.1 /* DF065 */
58 #define PHASE_CORRECTION_RESOLUTION 0.5 /* DF069-070 */
60 /* Other magic values */
61 #define INVALID_PSEUDORANGE 0x80000 /* DF012 */
63 /* Large case statements make GNU indent very confused */
65 /*@ -type @*//* re-enable when we're ready to take this live */
67 void rtcm3_unpack( /*@out@*/ struct rtcm3_t *rtcm, char *buf)
68 /* break out the raw bits into the scaled report-structure fields */
75 /*@ -evalorder -sefparams -mayaliasunique @*/
76 #define ugrab(width) (bitcount += width, ubits(buf, bitcount-width, width))
77 #define sgrab(width) (bitcount += width, sbits(buf, bitcount-width, width))
78 assert(ugrab(8) == 0xD3);
79 assert(ugrab(6) == 0x00);
81 rtcm->length = (uint) ugrab(10);
82 rtcm->type = (uint) ugrab(12);
85 case 1001: /* GPS Basic RTK, L1 Only */
86 rtcm->rtcmtypes.rtcm3_1001.header.station_id = (uint) ugrab(12);
87 rtcm->rtcmtypes.rtcm3_1001.header.tow = (time_t) ugrab(30);
88 rtcm->rtcmtypes.rtcm3_1001.header.sync = (bool) ugrab(1);
89 rtcm->rtcmtypes.rtcm3_1001.header.satcount = (ushort) ugrab(5);
90 rtcm->rtcmtypes.rtcm3_1001.header.smoothing = (bool) ugrab(1);
91 rtcm->rtcmtypes.rtcm3_1001.header.interval = (ushort) ugrab(3);
92 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1001.header.satcount; i++) {
93 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].ident = (ushort) ugrab(6);
94 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.indicator =
95 (unsigned char)ugrab(1);
96 temp = (unsigned long)ugrab(24);
97 if (temp == INVALID_PSEUDORANGE)
98 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.pseudorange = 0;
100 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.pseudorange =
101 temp * PSEUDORANGE_RESOLUTION;
102 temp = (long)sgrab(20);
103 if (temp == INVALID_PSEUDORANGE)
104 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.rangediff = 0;
106 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.rangediff =
107 temp * PSEUDORANGE_DIFF_RESOLUTION;
108 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.locktime =
109 (unsigned char)sgrab(7);
112 64 + 58 * rtcm->rtcmtypes.rtcm3_1001.header.satcount);
115 case 1002: /* GPS Extended RTK, L1 Only */
116 rtcm->rtcmtypes.rtcm3_1002.header.station_id = (uint) ugrab(12);
117 rtcm->rtcmtypes.rtcm3_1002.header.tow = (time_t) ugrab(30);
118 rtcm->rtcmtypes.rtcm3_1002.header.sync = (bool) ugrab(1);
119 rtcm->rtcmtypes.rtcm3_1002.header.satcount = (ushort) ugrab(5);
120 rtcm->rtcmtypes.rtcm3_1002.header.smoothing = (bool) ugrab(1);
121 rtcm->rtcmtypes.rtcm3_1002.header.interval = (ushort) ugrab(3);
122 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1002.header.satcount; i++) {
123 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].ident = (ushort) ugrab(6);
124 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.indicator =
125 (unsigned char)ugrab(1);
126 temp = (unsigned long)ugrab(24);
127 if (temp == INVALID_PSEUDORANGE)
128 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.pseudorange = 0;
130 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.pseudorange =
131 temp * PSEUDORANGE_RESOLUTION;
132 temp = (long)sgrab(20);
133 if (temp == INVALID_PSEUDORANGE)
134 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.rangediff = 0;
136 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.rangediff =
137 temp * PSEUDORANGE_DIFF_RESOLUTION;
138 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.locktime =
139 (unsigned char)sgrab(7);
140 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.ambiguity =
142 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.CNR =
143 (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
146 64 + 74 * rtcm->rtcmtypes.rtcm3_1002.header.satcount);
149 case 1003: /* GPS Basic RTK, L1 & L2 */
150 rtcm->rtcmtypes.rtcm3_1003.header.station_id = (uint) ugrab(12);
151 rtcm->rtcmtypes.rtcm3_1003.header.tow = (time_t) ugrab(30);
152 rtcm->rtcmtypes.rtcm3_1003.header.sync = (bool) ugrab(1);
153 rtcm->rtcmtypes.rtcm3_1003.header.satcount = (ushort) ugrab(5);
154 rtcm->rtcmtypes.rtcm3_1003.header.smoothing = (bool) ugrab(1);
155 rtcm->rtcmtypes.rtcm3_1003.header.interval = (ushort) ugrab(3);
156 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1003.header.satcount; i++) {
157 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].ident = (ushort) ugrab(6);
158 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.indicator =
159 (unsigned char)ugrab(1);
160 temp = (unsigned long)ugrab(24);
161 if (temp == INVALID_PSEUDORANGE)
162 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.pseudorange = 0;
164 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.pseudorange =
165 temp * PSEUDORANGE_RESOLUTION;
166 temp = (long)sgrab(20);
167 if (temp == INVALID_PSEUDORANGE)
168 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.rangediff = 0;
170 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.rangediff =
171 temp * PSEUDORANGE_DIFF_RESOLUTION;
172 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.locktime =
173 (unsigned char)sgrab(7);
174 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.indicator =
175 (unsigned char)ugrab(2);
176 temp = (unsigned long)ugrab(24);
177 if (temp == INVALID_PSEUDORANGE)
178 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.pseudorange = 0;
180 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.pseudorange =
181 temp * PSEUDORANGE_RESOLUTION;
182 temp = (long)sgrab(20);
183 if (temp == INVALID_PSEUDORANGE)
184 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.rangediff = 0;
186 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.rangediff =
187 temp * PSEUDORANGE_DIFF_RESOLUTION;
188 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.locktime =
189 (unsigned char)sgrab(7);
192 64 + 101 * rtcm->rtcmtypes.rtcm3_1003.header.satcount);
195 case 1004: /* GPS Extended RTK, L1 & L2 */
196 rtcm->rtcmtypes.rtcm3_1004.header.station_id = (uint) ugrab(12);
197 rtcm->rtcmtypes.rtcm3_1004.header.tow = (time_t) ugrab(30);
198 rtcm->rtcmtypes.rtcm3_1004.header.sync = (bool) ugrab(1);
199 rtcm->rtcmtypes.rtcm3_1004.header.satcount = (ushort) ugrab(5);
200 rtcm->rtcmtypes.rtcm3_1004.header.smoothing = (bool) ugrab(1);
201 rtcm->rtcmtypes.rtcm3_1004.header.interval = (ushort) ugrab(3);
202 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1004.header.satcount; i++) {
203 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].ident = (ushort) ugrab(6);
204 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.indicator =
206 temp = (unsigned long)ugrab(24);
207 if (temp == INVALID_PSEUDORANGE)
208 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.pseudorange = 0;
210 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.pseudorange =
211 temp * PSEUDORANGE_RESOLUTION;
212 temp = (long)sgrab(20);
213 if (temp == INVALID_PSEUDORANGE)
214 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.rangediff = 0;
216 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.rangediff =
217 temp * PSEUDORANGE_DIFF_RESOLUTION;
218 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.locktime =
219 (unsigned char)sgrab(7);
220 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.ambiguity =
222 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.CNR =
223 (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
224 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.indicator =
225 (unsigned char)ugrab(2);
226 temp = (unsigned long)ugrab(24);
227 if (temp == INVALID_PSEUDORANGE)
228 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.pseudorange = 0;
230 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.pseudorange =
231 temp * PSEUDORANGE_RESOLUTION;
232 temp = (long)sgrab(20);
233 if (temp == INVALID_PSEUDORANGE)
234 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.rangediff = 0;
236 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.rangediff =
237 temp * PSEUDORANGE_DIFF_RESOLUTION;
238 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.locktime =
239 (unsigned char)sgrab(7);
240 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.ambiguity =
242 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.CNR =
243 (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
246 64 + 125 * rtcm->rtcmtypes.rtcm3_1004.header.satcount);
249 case 1005: /* Stationary Antenna Reference Point, No Height Information */
250 rtcm->rtcmtypes.rtcm3_1005.station_id = (unsigned short)ugrab(12);
251 ugrab(6); /* reserved */
253 rtcm->rtcmtypes.rtcm3_1005.system = NAVSYSTEM_GPS;
254 else if ((bool) ugrab(1))
255 rtcm->rtcmtypes.rtcm3_1005.system = NAVSYSTEM_GLONASS;
256 else if ((bool) ugrab(1))
257 rtcm->rtcmtypes.rtcm3_1005.system = NAVSYSTEM_GALILEO;
258 rtcm->rtcmtypes.rtcm3_1005.reference_station = (bool) ugrab(1);
259 rtcm->rtcmtypes.rtcm3_1005.ecef_x =
260 sgrab(38) * ANTENNA_POSITION_RESOLUTION;
261 rtcm->rtcmtypes.rtcm3_1005.single_receiver = ugrab(1);
263 rtcm->rtcmtypes.rtcm3_1005.ecef_y =
264 sgrab(38) * ANTENNA_POSITION_RESOLUTION;
266 rtcm->rtcmtypes.rtcm3_1005.ecef_z =
267 sgrab(38) * ANTENNA_POSITION_RESOLUTION;
268 assert(bitcount == 152);
271 case 1006: /* Stationary Antenna Reference Point, with Height Information */
272 rtcm->rtcmtypes.rtcm3_1006.station_id = (unsigned short)ugrab(12);
273 ugrab(6); /* reserved */
275 rtcm->rtcmtypes.rtcm3_1006.system = NAVSYSTEM_GPS;
276 else if ((bool) ugrab(1))
277 rtcm->rtcmtypes.rtcm3_1006.system = NAVSYSTEM_GLONASS;
278 else if ((bool) ugrab(1))
279 rtcm->rtcmtypes.rtcm3_1006.system = NAVSYSTEM_GALILEO;
280 rtcm->rtcmtypes.rtcm3_1006.reference_station = (bool) ugrab(1);
281 rtcm->rtcmtypes.rtcm3_1006.ecef_x =
282 sgrab(38) * ANTENNA_POSITION_RESOLUTION;
283 rtcm->rtcmtypes.rtcm3_1006.single_receiver = ugrab(1);
285 rtcm->rtcmtypes.rtcm3_1006.ecef_y =
286 sgrab(38) * ANTENNA_POSITION_RESOLUTION;
288 rtcm->rtcmtypes.rtcm3_1006.ecef_z =
289 sgrab(38) * ANTENNA_POSITION_RESOLUTION;
290 rtcm->rtcmtypes.rtcm3_1006.height =
291 ugrab(16) * ANTENNA_POSITION_RESOLUTION;
292 assert(bitcount == 168);
295 case 1007: /* Antenna Descriptor */
296 rtcm->rtcmtypes.rtcm3_1007.station_id = (unsigned short)ugrab(12);
297 n = (unsigned long)ugrab(8);
298 (void)memcpy(rtcm->rtcmtypes.rtcm3_1007.descriptor, buf + 4, n);
299 rtcm->rtcmtypes.rtcm3_1007.descriptor[n] = '\0';
301 rtcm->rtcmtypes.rtcm3_1007.setup_id = ugrab(8);
302 assert(bitcount == (int)(40 + 8 * n));
305 case 1008: /* Antenna Descriptor & Serial Number */
306 rtcm->rtcmtypes.rtcm3_1008.station_id = (unsigned short)ugrab(12);
307 n = (unsigned long)ugrab(8);
308 (void)memcpy(rtcm->rtcmtypes.rtcm3_1008.descriptor, buf + 4, n);
309 rtcm->rtcmtypes.rtcm3_1008.descriptor[n] = '\0';
311 rtcm->rtcmtypes.rtcm3_1008.setup_id = ugrab(8);
312 n2 = (unsigned long)ugrab(8);
313 (void)memcpy(rtcm->rtcmtypes.rtcm3_1008.serial, buf + 6 + n, n2);
314 rtcm->rtcmtypes.rtcm3_1008.serial[n2] = '\0';
316 assert(bitcount == (int)(48 + 8 * (n + n2)));
319 case 1009: /* GLONASS Basic RTK, L1 Only */
320 rtcm->rtcmtypes.rtcm3_1009.header.station_id =
321 (unsigned short)ugrab(12);
322 rtcm->rtcmtypes.rtcm3_1009.header.tow = (time_t) ugrab(27);
323 rtcm->rtcmtypes.rtcm3_1009.header.sync = (bool) ugrab(1);
324 rtcm->rtcmtypes.rtcm3_1009.header.satcount = (ushort) ugrab(5);
325 rtcm->rtcmtypes.rtcm3_1009.header.smoothing = (bool) ugrab(1);
326 rtcm->rtcmtypes.rtcm3_1009.header.interval = (ushort) ugrab(3);
327 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1009.header.satcount; i++) {
328 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].ident = (ushort) ugrab(6);
329 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.indicator =
331 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.channel =
333 temp = (unsigned long)ugrab(25);
334 if (temp == INVALID_PSEUDORANGE)
335 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.pseudorange = 0;
337 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.pseudorange =
338 temp * PSEUDORANGE_RESOLUTION;
339 temp = (long)sgrab(20);
340 if (temp == INVALID_PSEUDORANGE)
341 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.rangediff = 0;
343 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.rangediff =
344 temp * PSEUDORANGE_DIFF_RESOLUTION;
345 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.locktime =
346 (unsigned char)sgrab(7);
349 61 + 64 * rtcm->rtcmtypes.rtcm3_1009.header.satcount);
352 case 1010: /* GLONASS Extended RTK, L1 Only */
353 rtcm->rtcmtypes.rtcm3_1010.header.station_id =
354 (unsigned short)ugrab(12);
355 rtcm->rtcmtypes.rtcm3_1010.header.tow = (time_t) ugrab(27);
356 rtcm->rtcmtypes.rtcm3_1010.header.sync = (bool) ugrab(1);
357 rtcm->rtcmtypes.rtcm3_1010.header.satcount = (ushort) ugrab(5);
358 rtcm->rtcmtypes.rtcm3_1010.header.smoothing = (bool) ugrab(1);
359 rtcm->rtcmtypes.rtcm3_1010.header.interval = (ushort) ugrab(3);
360 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1010.header.satcount; i++) {
361 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].ident = (ushort) ugrab(6);
362 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.indicator =
364 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.channel =
366 temp = (unsigned long)ugrab(25);
367 if (temp == INVALID_PSEUDORANGE)
368 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.pseudorange = 0;
370 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.pseudorange =
371 temp * PSEUDORANGE_RESOLUTION;
372 temp = (long)sgrab(20);
373 if (temp == INVALID_PSEUDORANGE)
374 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.rangediff = 0;
376 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.rangediff =
377 temp * PSEUDORANGE_DIFF_RESOLUTION;
378 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.locktime =
379 (unsigned char)sgrab(7);
380 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.ambiguity =
382 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.CNR =
383 (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
386 61 + 79 * rtcm->rtcmtypes.rtcm3_1010.header.satcount);
389 case 1011: /* GLONASS Basic RTK, L1 & L2 */
390 rtcm->rtcmtypes.rtcm3_1011.header.station_id =
391 (unsigned short)ugrab(12);
392 rtcm->rtcmtypes.rtcm3_1011.header.tow = (time_t) ugrab(27);
393 rtcm->rtcmtypes.rtcm3_1011.header.sync = (bool) ugrab(1);
394 rtcm->rtcmtypes.rtcm3_1011.header.satcount = (ushort) ugrab(5);
395 rtcm->rtcmtypes.rtcm3_1011.header.smoothing = (bool) ugrab(1);
396 rtcm->rtcmtypes.rtcm3_1011.header.interval = (ushort) ugrab(3);
397 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1011.header.satcount; i++) {
398 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].ident = (ushort) ugrab(6);
399 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.indicator =
401 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.channel =
403 temp = (unsigned long)ugrab(25);
404 if (temp == INVALID_PSEUDORANGE)
405 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.pseudorange = 0;
407 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.pseudorange =
408 temp * PSEUDORANGE_RESOLUTION;
409 temp = (long)sgrab(20);
410 if (temp == INVALID_PSEUDORANGE)
411 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.rangediff = 0;
413 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.rangediff =
414 temp * PSEUDORANGE_DIFF_RESOLUTION;
415 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.locktime =
416 (unsigned char)sgrab(7);
417 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.ambiguity =
419 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.CNR =
420 (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
421 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.indicator =
423 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.channel =
425 temp = (unsigned long)ugrab(25);
426 if (temp == INVALID_PSEUDORANGE)
427 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.pseudorange = 0;
429 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.pseudorange =
430 temp * PSEUDORANGE_RESOLUTION;
431 temp = (long)sgrab(20);
432 if (temp == INVALID_PSEUDORANGE)
433 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.rangediff = 0;
435 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.rangediff =
436 temp * PSEUDORANGE_DIFF_RESOLUTION;
437 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.locktime =
438 (unsigned char)sgrab(7);
439 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.ambiguity =
441 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.CNR =
442 (bool) ugrab(8) * CARRIER_NOISE_RATIO_UNITS;
445 61 + 107 * rtcm->rtcmtypes.rtcm3_1011.header.satcount);
448 case 1012: /* GLONASS Extended RTK, L1 & L2 */
449 rtcm->rtcmtypes.rtcm3_1012.header.station_id =
450 (unsigned short)ugrab(12);
451 rtcm->rtcmtypes.rtcm3_1012.header.tow = (time_t) ugrab(27);
452 rtcm->rtcmtypes.rtcm3_1012.header.sync = (bool) ugrab(1);
453 rtcm->rtcmtypes.rtcm3_1012.header.satcount = (ushort) ugrab(5);
454 rtcm->rtcmtypes.rtcm3_1012.header.smoothing = (bool) ugrab(1);
455 rtcm->rtcmtypes.rtcm3_1012.header.interval = (ushort) ugrab(3);
456 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1012.header.satcount; i++) {
457 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].ident = (ushort) ugrab(6);
458 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.indicator =
460 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.channel =
462 temp = (unsigned long)ugrab(25);
463 if (temp == INVALID_PSEUDORANGE)
464 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.pseudorange = 0;
466 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.pseudorange =
467 temp * PSEUDORANGE_RESOLUTION;
468 temp = (long)sgrab(20);
469 if (temp == INVALID_PSEUDORANGE)
470 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.rangediff = 0;
472 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.rangediff =
473 temp * PSEUDORANGE_DIFF_RESOLUTION;
474 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.locktime =
475 (unsigned char)sgrab(7);
476 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.indicator =
478 temp = (unsigned long)ugrab(25);
479 if (temp == INVALID_PSEUDORANGE)
480 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.pseudorange = 0;
482 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.pseudorange =
483 temp * PSEUDORANGE_RESOLUTION;
484 temp = (long)sgrab(20);
485 if (temp == INVALID_PSEUDORANGE)
486 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.rangediff = 0;
488 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.rangediff =
489 temp * PSEUDORANGE_DIFF_RESOLUTION;
490 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.locktime =
491 (unsigned char)sgrab(7);
494 61 + 130 * rtcm->rtcmtypes.rtcm3_1012.header.satcount);
497 case 1013: /* System Parameters */
498 rtcm->rtcmtypes.rtcm3_1013.station_id = (unsigned short)ugrab(12);
499 rtcm->rtcmtypes.rtcm3_1013.mjd = (unsigned short)ugrab(16);
500 rtcm->rtcmtypes.rtcm3_1013.sod = (unsigned short)ugrab(17);
501 rtcm->rtcmtypes.rtcm3_1013.ncount = (unsigned long)ugrab(5);
502 rtcm->rtcmtypes.rtcm3_1013.leapsecs = (unsigned char)ugrab(8);
503 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1013.ncount; i++) {
504 rtcm->rtcmtypes.rtcm3_1013.announcements[i].id =
505 (unsigned short)ugrab(12);
506 rtcm->rtcmtypes.rtcm3_1013.announcements[i].sync =
508 rtcm->rtcmtypes.rtcm3_1013.announcements[i].interval =
509 (unsigned short)ugrab(16);
511 assert(bitcount == 70 + 29 * rtcm->rtcmtypes.rtcm3_1013.ncount);
515 rtcm->rtcmtypes.rtcm3_1014.network_id = (int)ugrab(8);
516 rtcm->rtcmtypes.rtcm3_1014.subnetwork_id = (int)ugrab(4);
517 rtcm->rtcmtypes.rtcm3_1014.stationcount = (char)ugrab(5);
518 rtcm->rtcmtypes.rtcm3_1014.master_id = (int)ugrab(12);
519 rtcm->rtcmtypes.rtcm3_1014.aux_id = (int)ugrab(12);
520 rtcm->rtcmtypes.rtcm3_1014.d_lat =
521 (unsigned short)ugrab(20) * ANTENNA_DEGREE_RESOLUTION;
522 rtcm->rtcmtypes.rtcm3_1014.d_lon =
523 (unsigned short)ugrab(21) * ANTENNA_DEGREE_RESOLUTION;
524 rtcm->rtcmtypes.rtcm3_1014.d_alt = (unsigned short)ugrab(23) / 1000;
525 assert(bitcount == 117);
547 rtcm->rtcmtypes.rtcm3_1029.station_id = (unsigned short)ugrab(12);
548 rtcm->rtcmtypes.rtcm3_1029.mjd = (unsigned short)ugrab(16);
549 rtcm->rtcmtypes.rtcm3_1029.sod = (unsigned short)ugrab(17);
550 rtcm->rtcmtypes.rtcm3_1029.len = (unsigned long)ugrab(7);
551 n = rtcm->rtcmtypes.rtcm3_1029.unicode_units =
552 (unsigned long)ugrab(8);
553 (void)memcpy(rtcm->rtcmtypes.rtcm3_1029.text, buf + 9, n);
555 assert(bitcount == (int)(72 + 8 * n));
560 /*@ +evalorder +sefparams +mayaliasunique @*/
563 void rtcm3_dump(struct rtcm3_t *rtcm, FILE * fp)
564 /* dump the contents of a parsed RTCM104 message */
568 char *systems[] = { "GPS", "Glonass", "Galileo", "unknown" };
570 (void)fprintf(fp, "%u (%u):\n", rtcm->type, rtcm->length);
572 #define BOOL(c) (c!=0 ? 't' : 'f')
573 #define CODE(x) (unsigned int)(x)
574 #define INT(x) (unsigned int)(x)
575 switch (rtcm->type) {
578 " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u",
579 rtcm->rtcmtypes.rtcm3_1001.header.station_id,
580 (int)rtcm->rtcmtypes.rtcm3_1001.header.tow,
581 BOOL(rtcm->rtcmtypes.rtcm3_1001.header.sync),
582 BOOL(rtcm->rtcmtypes.rtcm3_1001.header.smoothing),
583 rtcm->rtcmtypes.rtcm3_1001.header.interval,
584 rtcm->rtcmtypes.rtcm3_1001.header.satcount);
585 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1001.header.satcount; i++) {
587 " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n",
588 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].ident,
589 CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
591 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].
593 rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].L1.rangediff,
594 INT(rtcm->rtcmtypes.rtcm3_1001.rtk_data[i].
601 " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u",
602 rtcm->rtcmtypes.rtcm3_1002.header.station_id,
603 (int)rtcm->rtcmtypes.rtcm3_1002.header.tow,
604 BOOL(rtcm->rtcmtypes.rtcm3_1002.header.sync),
605 BOOL(rtcm->rtcmtypes.rtcm3_1002.header.smoothing),
606 rtcm->rtcmtypes.rtcm3_1002.header.interval,
607 rtcm->rtcmtypes.rtcm3_1002.header.satcount);
608 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1002.header.satcount; i++) {
610 " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n",
611 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].ident,
612 CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
614 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].
616 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.rangediff,
617 INT(rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].
619 INT(rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].
621 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.CNR);
627 " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u",
628 rtcm->rtcmtypes.rtcm3_1003.header.station_id,
629 (int)rtcm->rtcmtypes.rtcm3_1003.header.tow,
630 BOOL(rtcm->rtcmtypes.rtcm3_1003.header.sync),
631 BOOL(rtcm->rtcmtypes.rtcm3_1003.header.smoothing),
632 rtcm->rtcmtypes.rtcm3_1003.header.interval,
633 rtcm->rtcmtypes.rtcm3_1003.header.satcount);
634 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1003.header.satcount; i++) {
636 " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n",
637 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].ident,
638 CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
640 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
642 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L1.rangediff,
643 INT(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
645 CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
647 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
649 rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].L2.rangediff,
650 INT(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
657 " #station_id=%u, tow=%d sync=%c smoothing=%c interval=%u satcount=%u\n",
658 rtcm->rtcmtypes.rtcm3_1004.header.station_id,
659 (int)rtcm->rtcmtypes.rtcm3_1004.header.tow,
660 BOOL(rtcm->rtcmtypes.rtcm3_1004.header.sync),
661 BOOL(rtcm->rtcmtypes.rtcm3_1004.header.smoothing),
662 rtcm->rtcmtypes.rtcm3_1004.header.interval,
663 rtcm->rtcmtypes.rtcm3_1004.header.satcount);
664 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1004.header.satcount; i++) {
666 " ident=%u\n L1: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n",
667 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].ident,
668 CODE(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
670 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
672 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L1.rangediff,
673 INT(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
675 INT(rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].
677 rtcm->rtcmtypes.rtcm3_1002.rtk_data[i].L1.CNR,
678 CODE(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
680 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
682 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.rangediff,
683 INT(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
685 INT(rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].
687 rtcm->rtcmtypes.rtcm3_1004.rtk_data[i].L2.CNR);
693 " station_id=%u, %s refstation=%c sro=%c x=%f y=%f z=%f\n",
694 rtcm->rtcmtypes.rtcm3_1005.station_id,
695 systems[rtcm->rtcmtypes.rtcm3_1005.system],
696 BOOL(rtcm->rtcmtypes.rtcm3_1005.reference_station),
697 BOOL(rtcm->rtcmtypes.rtcm3_1005.single_receiver),
698 rtcm->rtcmtypes.rtcm3_1005.ecef_x,
699 rtcm->rtcmtypes.rtcm3_1005.ecef_y,
700 rtcm->rtcmtypes.rtcm3_1005.ecef_z);
705 " station_id=%u, %s refstation=%c sro=%c x=%f y=%f z=%f a=%f\n",
706 rtcm->rtcmtypes.rtcm3_1006.station_id,
707 systems[rtcm->rtcmtypes.rtcm3_1006.system],
708 BOOL(rtcm->rtcmtypes.rtcm3_1006.reference_station),
709 BOOL(rtcm->rtcmtypes.rtcm3_1006.single_receiver),
710 rtcm->rtcmtypes.rtcm3_1006.ecef_x,
711 rtcm->rtcmtypes.rtcm3_1006.ecef_y,
712 rtcm->rtcmtypes.rtcm3_1006.ecef_z,
713 rtcm->rtcmtypes.rtcm3_1006.height);
718 " station_id=%u, desc=%s setup-id=%u\n",
719 rtcm->rtcmtypes.rtcm3_1007.station_id,
720 rtcm->rtcmtypes.rtcm3_1007.descriptor,
721 INT(rtcm->rtcmtypes.rtcm3_1007.setup_id));
726 " station_id=%u, desc=%s setup-id=%u serial=%s\n",
727 rtcm->rtcmtypes.rtcm3_1008.station_id,
728 rtcm->rtcmtypes.rtcm3_1008.descriptor,
729 INT(rtcm->rtcmtypes.rtcm3_1008.setup_id),
730 rtcm->rtcmtypes.rtcm3_1008.serial);
735 " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u",
736 rtcm->rtcmtypes.rtcm3_1009.header.station_id,
737 (int)rtcm->rtcmtypes.rtcm3_1009.header.tow,
738 BOOL(rtcm->rtcmtypes.rtcm3_1009.header.sync),
739 BOOL(rtcm->rtcmtypes.rtcm3_1009.header.smoothing),
740 rtcm->rtcmtypes.rtcm3_1009.header.interval,
741 rtcm->rtcmtypes.rtcm3_1009.header.satcount);
742 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1009.header.satcount; i++) {
744 " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u\n",
745 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].ident,
746 CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
748 INT(rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].
750 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].
752 rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].L1.rangediff,
753 INT(rtcm->rtcmtypes.rtcm3_1009.rtk_data[i].
760 " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u",
761 rtcm->rtcmtypes.rtcm3_1010.header.station_id,
762 (int)rtcm->rtcmtypes.rtcm3_1010.header.tow,
763 BOOL(rtcm->rtcmtypes.rtcm3_1010.header.sync),
764 BOOL(rtcm->rtcmtypes.rtcm3_1010.header.smoothing),
765 rtcm->rtcmtypes.rtcm3_1010.header.interval,
766 rtcm->rtcmtypes.rtcm3_1010.header.satcount);
767 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1010.header.satcount; i++) {
769 " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n",
770 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].ident,
771 CODE(rtcm->rtcmtypes.rtcm3_1003.rtk_data[i].
773 INT(rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].
775 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].
777 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.rangediff,
778 INT(rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].
780 INT(rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].
782 rtcm->rtcmtypes.rtcm3_1010.rtk_data[i].L1.CNR);
788 " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u",
789 rtcm->rtcmtypes.rtcm3_1011.header.station_id,
790 (int)rtcm->rtcmtypes.rtcm3_1011.header.tow,
791 BOOL(rtcm->rtcmtypes.rtcm3_1011.header.sync),
792 BOOL(rtcm->rtcmtypes.rtcm3_1011.header.smoothing),
793 rtcm->rtcmtypes.rtcm3_1011.header.interval,
794 rtcm->rtcmtypes.rtcm3_1011.header.satcount);
795 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1011.header.satcount; i++) {
797 " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u\n",
798 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].ident,
799 CODE(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
801 INT(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
803 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
805 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L1.rangediff,
806 INT(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
808 CODE(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
810 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
812 rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].L2.rangediff,
813 INT(rtcm->rtcmtypes.rtcm3_1011.rtk_data[i].
820 " #station_id=%u, tow=%d sync=%c smooting=%c interval=%u satcount=%u",
821 rtcm->rtcmtypes.rtcm3_1012.header.station_id,
822 (int)rtcm->rtcmtypes.rtcm3_1012.header.tow,
823 BOOL(rtcm->rtcmtypes.rtcm3_1012.header.sync),
824 BOOL(rtcm->rtcmtypes.rtcm3_1012.header.smoothing),
825 rtcm->rtcmtypes.rtcm3_1012.header.interval,
826 rtcm->rtcmtypes.rtcm3_1012.header.satcount);
827 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1012.header.satcount; i++) {
829 " ident=%u\n L1: ind=%u channel=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n L2: ind=%u prange=%8.1f delta=%6.4f lockt=%u amb=%u CNR=%.2f\n",
830 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].ident,
831 CODE(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
833 INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
835 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
837 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.rangediff,
838 INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
840 INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
842 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L1.CNR,
843 CODE(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
845 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
847 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.rangediff,
848 INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
850 INT(rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].
852 rtcm->rtcmtypes.rtcm3_1012.rtk_data[i].L2.CNR);
858 " station_id=%u, mjd=%u sec=%u leapsecs=%u ncount=%u\n",
859 rtcm->rtcmtypes.rtcm3_1013.station_id,
860 rtcm->rtcmtypes.rtcm3_1013.mjd,
861 rtcm->rtcmtypes.rtcm3_1013.sod,
862 INT(rtcm->rtcmtypes.rtcm3_1013.leapsecs),
863 INT(rtcm->rtcmtypes.rtcm3_1013.ncount));
864 for (i = 0; i < rtcm->rtcmtypes.rtcm3_1013.ncount; i++)
866 " id=%u sync=%c interval=%u\n",
867 rtcm->rtcmtypes.rtcm3_1013.announcements[i].id,
868 BOOL(rtcm->rtcmtypes.rtcm3_1013.
869 announcements[i].sync),
870 rtcm->rtcmtypes.rtcm3_1013.
871 announcements[i].interval);
876 " netid=%u subnetid=%u statcount=%u master=%u aux=%u lat=%f, lon=%f, alt=%f\n",
877 rtcm->rtcmtypes.rtcm3_1014.network_id,
878 rtcm->rtcmtypes.rtcm3_1014.subnetwork_id,
879 (uint) rtcm->rtcmtypes.rtcm3_1014.stationcount,
880 rtcm->rtcmtypes.rtcm3_1014.master_id,
881 rtcm->rtcmtypes.rtcm3_1014.aux_id,
882 rtcm->rtcmtypes.rtcm3_1014.d_lat,
883 rtcm->rtcmtypes.rtcm3_1014.d_lon,
884 rtcm->rtcmtypes.rtcm3_1014.d_alt);
907 " station_id=%u, mjd=%u sec=%u len=%u units=%u msg=%s\n",
908 rtcm->rtcmtypes.rtcm3_1029.station_id,
909 rtcm->rtcmtypes.rtcm3_1029.mjd,
910 rtcm->rtcmtypes.rtcm3_1029.sod,
911 INT(rtcm->rtcmtypes.rtcm3_1029.len),
912 INT(rtcm->rtcmtypes.rtcm3_1029.unicode_units),
913 (char *)rtcm->rtcmtypes.rtcm3_1029.text);
917 (void)fprintf(fp, " Unknown content\n");
928 #endif /* RTCM104V3_ENABLE */