MRTKLIB 0.7.14
Modernized GNSS Positioning Library
Loading...
Searching...
No Matches
mrtk_rtcm3.c
Go to the documentation of this file.
1/*------------------------------------------------------------------------------
2 * mrtk_rtcm3.c : RTCM version 3 message decoder functions
3 *
4 * Copyright (C) 2026 H.SHIONO (MRTKLIB Project)
5 * Copyright (C) 2023-2025 Cabinet Office, Japan
6 * Copyright (C) 2024-2025 Lighthouse Technology & Consulting Co. Ltd.
7 * Copyright (C) 2023-2025 Japan Aerospace Exploration Agency
8 * Copyright (C) 2023-2025 TOSHIBA ELECTRONIC TECHNOLOGIES CORPORATION
9 * Copyright (C) 2015- Mitsubishi Electric Corp.
10 * Copyright (C) 2014 Geospatial Information Authority of Japan
11 * Copyright (C) 2014 T.SUZUKI
12 * Copyright (C) 2007-2023 T.TAKASU
13 *
14 * SPDX-License-Identifier: BSD-2-Clause
15 *----------------------------------------------------------------------------*/
16#include <math.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include "mrtklib/mrtk_atmos.h"
21#include "mrtklib/mrtk_bits.h"
22#include "mrtklib/mrtk_coords.h"
23#include "mrtklib/mrtk_eph.h"
24#include "mrtklib/mrtk_obs.h"
25#include "mrtklib/mrtk_rtcm.h"
26#include "mrtklib/mrtk_sys.h"
27#include "mrtklib/mrtk_trace.h"
28
29/*--- local constants (duplicated to avoid rtklib.h dependency) -------------*/
30#define SYS_NONE 0x00
31#define SYS_GPS 0x01
32#define SYS_SBS 0x02
33#define SYS_GLO 0x04
34#define SYS_GAL 0x08
35#define SYS_QZS 0x10
36#define SYS_CMP 0x20
37#define SYS_IRN 0x40
38
39#define TSYS_GPS 0
40#define TSYS_UTC 1
41#define TSYS_GLO 2
42#define TSYS_GAL 3
43#define TSYS_QZS 4
44#define TSYS_CMP 5
45#define TSYS_IRN 6
46
47#define LLI_SLIP 0x01
48#define LLI_HALFC 0x02
49#define LLI_BOCTRK 0x04
50#define LLI_HALFA 0x40
51#define LLI_HALFS 0x80
52
53static const double CLIGHT = 299792458.0;
54static const double FREQ1 = 1.57542E9;
55static const double FREQ2 = 1.22760E9;
56static const double FREQ5 = 1.17645E9;
57static const double FREQ6 = 1.27875E9;
58static const double FREQ7 = 1.20714E9;
59static const double FREQ8 = 1.191795E9;
60static const double FREQ9 = 2.492028E9;
61static const double FREQ1_GLO = 1.60200E9;
62static const double DFRQ1_GLO = 0.56250E6;
63static const double FREQ2_GLO = 1.24600E9;
64static const double DFRQ2_GLO = 0.43750E6;
65static const double FREQ3_GLO = 1.202025E9;
66static const double FREQ1a_GLO = 1.600995E9;
67static const double FREQ2a_GLO = 1.248060E9;
68static const double FREQ1_CMP = 1.561098E9;
69static const double FREQ2_CMP = 1.20714E9;
70static const double FREQ3_CMP = 1.26852E9;
71static const double D2R = 3.1415926535897932 / 180.0;
72static const double R2D = 180.0 / 3.1415926535897932;
73static const double SC2RAD = 3.1415926535897932;
74static const double RE_WGS84 = 6378137.0;
75
76#define SSR_VENDOR_L6 0 /* vendor type L6(MADOCA-PPP) */
77#define SSR_VENDOR_RTCM 1 /* vendor type RTCM3(JAXA-MADOCA) */
78
79/*--- forward declarations for legacy functions resolved at link time -------*/
80extern int decode_qzss_l6emsg(rtcm_t* rtcm);
81
82/* constants -----------------------------------------------------------------*/
83
84#define PRUNIT_GPS 299792.458 /* rtcm ver.3 unit of gps pseudorange (m) */
85#define PRUNIT_GLO 599584.916 /* rtcm ver.3 unit of glonass pseudorange (m) */
86#define RANGE_MS (CLIGHT * 0.001) /* range in 1 ms */
87
88#define P2_5 0.03125
89#define P2_6 0.015625
90#define P2_10 0.0009765625
91#define P2_11 4.882812500000000E-04
92#define P2_19 1.907348632812500E-06
93#define P2_20 9.536743164062500E-07
94#define P2_24 5.960464477539063E-08
95#define P2_28 3.725290298461914E-09
96#define P2_29 1.862645149230957E-09
97#define P2_30 9.313225746154785E-10
98#define P2_31 4.656612873077393E-10
99#define P2_32 2.328306436538696E-10
100#define P2_33 1.164153218269348E-10
101#define P2_34 5.820766091346740E-11
102#define P2_40 9.094947017729280E-13
103#define P2_41 4.547473508864641E-13
104#define P2_43 1.136868377216160E-13
105#define P2_46 1.421085471520200E-14
106#define P2_50 8.881784197001252E-16
107#define P2_55 2.775557561562891E-17
108#define P2_59 1.734723475976810E-18
109#define P2_66 1.355252715606880E-20
110
111/* type definition -----------------------------------------------------------*/
112
113typedef struct { /* multi-signal-message header type */
114 uint8_t iod; /* issue of data station */
115 uint8_t time_s; /* cumulative session transmitting time */
116 uint8_t clk_str; /* clock steering indicator */
117 uint8_t clk_ext; /* external clock indicator */
118 uint8_t smooth; /* divergence free smoothing indicator */
119 uint8_t tint_s; /* soothing interval */
120 uint8_t nsat, nsig; /* number of satellites/signals */
121 uint8_t sats[64]; /* satellites */
122 uint8_t sigs[32]; /* signals */
123 uint8_t cellmask[64]; /* cell mask */
124} msm_h_t;
125
126/* MSM signal ID table -------------------------------------------------------*/
127const char* msm_sig_gps[32] = {
128 /* GPS: ref [17] table 3.5-91 */
129 "", "1C", "1P", "1W", "", "", "", "2C", "2P", "2W", "", "", /* 1-12 */
130 "", "", "2S", "2L", "2X", "", "", "", "", "5I", "5Q", "5X", /* 13-24 */
131 "", "", "", "", "", "1S", "1L", "1X" /* 25-32 */
132};
133const char* msm_sig_glo[32] = {
134 /* GLONASS: ref [17] table 3.5-96 */
135 "", "1C", "1P", "", "", "", "", "2C", "2P", "", "", "", "", "", "", "",
136 "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};
137const char* msm_sig_gal[32] = {
138 /* Galileo: ref [17] table 3.5-99 */
139 "", "1C", "1A", "1B", "1X", "1Z", "", "6C", "6A", "6B", "6X", "6Z", "", "7I", "7Q", "7X",
140 "", "8I", "8Q", "8X", "", "5I", "5Q", "5X", "", "", "", "", "", "", "", ""};
141const char* msm_sig_qzs[32] = {
142 /* QZSS: ref [17] table 3.5-105 */
143 "", "1C", "", "", "", "", "", "", "6S", "6L", "6X", "", "", "", "2S", "2L",
144 "2X", "", "", "", "", "5I", "5Q", "5X", "", "", "", "", "", "1S", "1L", "1X"};
145const char* msm_sig_sbs[32] = {
146 /* SBAS: ref [17] table 3.5-102 */
147 "", "1C", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
148 "", "", "", "", "", "5I", "5Q", "5X", "", "", "", "", "", "", "", ""};
149const char* msm_sig_cmp[32] = {
150 /* BeiDou: ref [17] table 3.5-108; B2b (7D/7P/7Z, IDs 25-27) per RTCM 10403.3 Amendment 2 (#333) */
151 "", "2I", "2Q", "2X", "", "", "", "6I", "6Q", "6X", "", "", "", "7I", "7Q", "7X",
152 "", "", "", "", "", "5D", "5P", "5X", "7D", "7P", "7Z", "", "", "1D", "1P", "1X"};
153const char* msm_sig_irn[32] = {
154 /* NavIC/IRNSS: ref [17] table 3.5-108.3 */
155 "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
156 "", "", "", "", "", "5A", "", "", "", "", "", "", "", "", "", ""};
157/* SSR signal and tracking mode IDs ------------------------------------------*/
170const uint8_t ssr_sig_sbs[32] = {CODE_L1C, CODE_L5I, CODE_L5Q};
171/* SSR update intervals ------------------------------------------------------*/
172static const double ssrudint[16] = {1, 2, 5, 10, 15, 30, 60, 120, 240, 300, 600, 900, 1800, 3600, 7200, 10800};
173/* get sign-magnitude bits ---------------------------------------------------*/
174static double getbitg(const uint8_t* buff, int pos, int len) {
175 double value = getbitu(buff, pos + 1, len - 1);
176 return getbitu(buff, pos, 1) ? -value : value;
177}
178/* adjust weekly rollover of GPS time ----------------------------------------*/
179static void adjweek(rtcm_t* rtcm, double tow) {
180 double tow_p;
181 int week;
182
183 /* if no time, get cpu time */
184 if (rtcm->time.time == 0) {
185 rtcm->time = utc2gpst(timeget());
186 }
187 tow_p = time2gpst(rtcm->time, &week);
188 if (tow < tow_p - 302400.0) {
189 tow += 604800.0;
190 } else if (tow > tow_p + 302400.0) {
191 tow -= 604800.0;
192 }
193 rtcm->time = gpst2time(week, tow);
194}
195/* adjust weekly rollover of BDS time ----------------------------------------*/
196static int adjbdtweek(int week) {
197 int w;
198 (void)time2bdt(gpst2bdt(utc2gpst(timeget())), &w);
199 if (w < 1) {
200 w = 1; /* use 2006/1/1 if time is earlier than 2006/1/1 */
201 }
202 return week + (w - week + 512) / 1024 * 1024;
203}
204/* adjust daily rollover of GLONASS time -------------------------------------*/
205static void adjday_glot(rtcm_t* rtcm, double tod) {
206 gtime_t time;
207 double tow, tod_p;
208 int week;
209
210 if (rtcm->time.time == 0) {
211 rtcm->time = utc2gpst(timeget());
212 }
213 time = timeadd(gpst2utc(rtcm->time), 10800.0); /* glonass time */
214 tow = time2gpst(time, &week);
215 tod_p = fmod(tow, 86400.0);
216 tow -= tod_p;
217 if (tod < tod_p - 43200.0) {
218 tod += 86400.0;
219 } else if (tod > tod_p + 43200.0) {
220 tod -= 86400.0;
221 }
222 time = gpst2time(week, tow + tod);
223 rtcm->time = utc2gpst(timeadd(time, -10800.0));
224}
225/* adjust carrier-phase rollover ---------------------------------------------*/
226static double adjcp(rtcm_t* rtcm, int sat, int idx, double cp) {
227 if (rtcm->cp[sat - 1][idx] == 0.0) {
228 /* first epoch: no rollover adjustment */
229 } else if (cp < rtcm->cp[sat - 1][idx] - 750.0) {
230 cp += 1500.0;
231 } else if (cp > rtcm->cp[sat - 1][idx] + 750.0) {
232 cp -= 1500.0;
233 }
234 rtcm->cp[sat - 1][idx] = cp;
235 return cp;
236}
237/* loss-of-lock indicator ----------------------------------------------------*/
238static int lossoflock(rtcm_t* rtcm, int sat, int idx, int lock) {
239 int lli = (!lock && !rtcm->lock[sat - 1][idx]) || lock < rtcm->lock[sat - 1][idx];
240 rtcm->lock[sat - 1][idx] = (uint16_t)lock;
241 return lli;
242}
243/* S/N ratio -----------------------------------------------------------------*/
244static uint16_t snratio(double snr) { return (uint16_t)(snr <= 0.0 || 100.0 <= snr ? 0.0 : snr / SNR_UNIT + 0.5); }
245/* get observation data index ------------------------------------------------*/
246static int obsindex(obs_t* obs, gtime_t time, int sat) {
247 int i, j;
248
249 for (i = 0; i < obs->n; i++) {
250 if (obs->data[i].sat == sat) {
251 return i; /* field already exists */
252 }
253 }
254 if (i >= MAXOBS) {
255 return -1; /* overflow */
256 }
257
258 /* add new field */
259 obs->data[i].time = time;
260 obs->data[i].sat = sat;
261 for (j = 0; j < NFREQ + NEXOBS; j++) {
262 obs->data[i].L[j] = obs->data[i].P[j] = 0.0;
263 obs->data[i].D[j] = 0.0;
264 obs->data[i].SNR[j] = obs->data[i].LLI[j] = obs->data[i].code[j] = 0;
265 }
266 obs->n++;
267 return i;
268}
269/* test station ID consistency -----------------------------------------------*/
270static int test_staid(rtcm_t* rtcm, int staid) {
271 char* p;
272 int type, id;
273
274 /* test station id option */
275 if ((p = strstr(rtcm->opt, "-STA=")) && sscanf(p, "-STA=%d", &id) == 1) {
276 if (staid != id) {
277 return 0;
278 }
279 }
280 /* save station id */
281 if (rtcm->staid == 0 || rtcm->obsflag) {
282 rtcm->staid = staid;
283 } else if (staid != rtcm->staid) {
284 type = getbitu(rtcm->buff, 24, 12);
285 trace(NULL, 2, "rtcm3 %d staid invalid id=%d %d\n", type, staid, rtcm->staid);
286
287 /* reset station id if station id error */
288 rtcm->staid = 0;
289 return 0;
290 }
291 return 1;
292}
293/* decode type 1001-1004 message header --------------------------------------*/
294static int decode_head1001(rtcm_t* rtcm, int* sync) {
295 double tow;
296 char *msg, tstr[64];
297 int i = 24, staid, nsat, type;
298
299 type = getbitu(rtcm->buff, i, 12);
300 i += 12;
301
302 if (i + 52 <= rtcm->len * 8) {
303 staid = getbitu(rtcm->buff, i, 12);
304 i += 12;
305 tow = getbitu(rtcm->buff, i, 30) * 0.001;
306 i += 30;
307 *sync = getbitu(rtcm->buff, i, 1);
308 i += 1;
309 nsat = getbitu(rtcm->buff, i, 5);
310 } else {
311 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
312 return -1;
313 }
314 /* test station ID */
315 if (!test_staid(rtcm, staid)) {
316 return -1;
317 }
318
319 adjweek(rtcm, tow);
320
321 time2str(rtcm->time, tstr, 2);
322 trace(NULL, 4, "decode_head1001: time=%s nsat=%d sync=%d\n", tstr, nsat, *sync);
323
324 if (rtcm->outtype) {
325 msg = rtcm->msgtype + strlen(rtcm->msgtype);
326 sprintf(msg, " staid=%4d %s nsat=%2d sync=%d", staid, tstr, nsat, *sync);
327 }
328 return nsat;
329}
330/* decode type 1001: L1-only GPS RTK observation -----------------------------*/
332 int sync;
333 if (decode_head1001(rtcm, &sync) < 0) {
334 return -1;
335 }
336 rtcm->obsflag = !sync;
337 return sync ? 0 : 1;
338}
339/* decode type 1002: extended L1-only GPS RTK observables --------------------*/
341 double pr1, cnr1, tt, cp1, freq = FREQ1;
342 int i = 24 + 64, j, index, nsat, sync, prn, code, sat, ppr1, lock1, amb, sys;
343
344 if ((nsat = decode_head1001(rtcm, &sync)) < 0) {
345 return -1;
346 }
347
348 for (j = 0; j < nsat && rtcm->obs.n < MAXOBS && i + 74 <= rtcm->len * 8; j++) {
349 prn = getbitu(rtcm->buff, i, 6);
350 i += 6;
351 code = getbitu(rtcm->buff, i, 1);
352 i += 1;
353 pr1 = getbitu(rtcm->buff, i, 24);
354 i += 24;
355 ppr1 = getbits(rtcm->buff, i, 20);
356 i += 20;
357 lock1 = getbitu(rtcm->buff, i, 7);
358 i += 7;
359 amb = getbitu(rtcm->buff, i, 8);
360 i += 8;
361 cnr1 = getbitu(rtcm->buff, i, 8);
362 i += 8;
363 if (prn < 40) {
364 sys = SYS_GPS;
365 } else {
366 sys = SYS_SBS;
367 prn += 80;
368 }
369 if (!(sat = satno(sys, prn))) {
370 trace(NULL, 2, "rtcm3 1002 satellite number error: prn=%d\n", prn);
371 continue;
372 }
373 tt = timediff(rtcm->obs.data[0].time, rtcm->time);
374 if (rtcm->obsflag || fabs(tt) > 1E-9) {
375 rtcm->obs.n = rtcm->obsflag = 0;
376 }
377 if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) {
378 continue;
379 }
380 pr1 = pr1 * 0.02 + amb * PRUNIT_GPS;
381 rtcm->obs.data[index].P[0] = pr1;
382
383 if (ppr1 != (int)0xFFF80000) {
384 cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq / CLIGHT);
385 rtcm->obs.data[index].L[0] = pr1 * freq / CLIGHT + cp1;
386 }
387 rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1);
388 rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25);
389 rtcm->obs.data[index].code[0] = code ? CODE_L1P : CODE_L1C;
390 }
391 return sync ? 0 : 1;
392}
393/* decode type 1003: L1&L2 gps rtk observables -------------------------------*/
395 int sync;
396 if (decode_head1001(rtcm, &sync) < 0) {
397 return -1;
398 }
399 rtcm->obsflag = !sync;
400 return sync ? 0 : 1;
401}
402/* decode type 1004: extended L1&L2 GPS RTK observables ----------------------*/
404 const int L2codes[] = {CODE_L2X, CODE_L2P, CODE_L2D, CODE_L2W};
405 double pr1, cnr1, cnr2, tt, cp1, cp2, freq[2] = {FREQ1, FREQ2};
406 int i = 24 + 64, j, index, nsat, sync, prn, sat, code1, code2, pr21, ppr1, ppr2;
407 int lock1, lock2, amb, sys;
408
409 if ((nsat = decode_head1001(rtcm, &sync)) < 0) {
410 return -1;
411 }
412
413 for (j = 0; j < nsat && rtcm->obs.n < MAXOBS && i + 125 <= rtcm->len * 8; j++) {
414 prn = getbitu(rtcm->buff, i, 6);
415 i += 6;
416 code1 = getbitu(rtcm->buff, i, 1);
417 i += 1;
418 pr1 = getbitu(rtcm->buff, i, 24);
419 i += 24;
420 ppr1 = getbits(rtcm->buff, i, 20);
421 i += 20;
422 lock1 = getbitu(rtcm->buff, i, 7);
423 i += 7;
424 amb = getbitu(rtcm->buff, i, 8);
425 i += 8;
426 cnr1 = getbitu(rtcm->buff, i, 8);
427 i += 8;
428 code2 = getbitu(rtcm->buff, i, 2);
429 i += 2;
430 pr21 = getbits(rtcm->buff, i, 14);
431 i += 14;
432 ppr2 = getbits(rtcm->buff, i, 20);
433 i += 20;
434 lock2 = getbitu(rtcm->buff, i, 7);
435 i += 7;
436 cnr2 = getbitu(rtcm->buff, i, 8);
437 i += 8;
438 if (prn < 40) {
439 sys = SYS_GPS;
440 } else {
441 sys = SYS_SBS;
442 prn += 80;
443 }
444 if (!(sat = satno(sys, prn))) {
445 trace(NULL, 2, "rtcm3 1004 satellite number error: sys=%d prn=%d\n", sys, prn);
446 continue;
447 }
448 tt = timediff(rtcm->obs.data[0].time, rtcm->time);
449 if (rtcm->obsflag || fabs(tt) > 1E-9) {
450 rtcm->obs.n = rtcm->obsflag = 0;
451 }
452 if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) {
453 continue;
454 }
455 pr1 = pr1 * 0.02 + amb * PRUNIT_GPS;
456 rtcm->obs.data[index].P[0] = pr1;
457
458 if (ppr1 != (int)0xFFF80000) {
459 cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq[0] / CLIGHT);
460 rtcm->obs.data[index].L[0] = pr1 * freq[0] / CLIGHT + cp1;
461 }
462 rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1);
463 rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25);
464 rtcm->obs.data[index].code[0] = code1 ? CODE_L1P : CODE_L1C;
465
466 if (pr21 != (int)0xFFFFE000) {
467 rtcm->obs.data[index].P[1] = pr1 + pr21 * 0.02;
468 }
469 if (ppr2 != (int)0xFFF80000) {
470 cp2 = adjcp(rtcm, sat, 1, ppr2 * 0.0005 * freq[1] / CLIGHT);
471 rtcm->obs.data[index].L[1] = pr1 * freq[1] / CLIGHT + cp2;
472 }
473 rtcm->obs.data[index].LLI[1] = lossoflock(rtcm, sat, 1, lock2);
474 rtcm->obs.data[index].SNR[1] = snratio(cnr2 * 0.25);
475 rtcm->obs.data[index].code[1] = L2codes[code2];
476 }
477 rtcm->obsflag = !sync;
478 return sync ? 0 : 1;
479}
480/* get signed 38bit field ----------------------------------------------------*/
481static double getbits_38(const uint8_t* buff, int pos) {
482 return (double)getbits(buff, pos, 32) * 64.0 + getbitu(buff, pos + 32, 6);
483}
484/* decode type 1005: stationary RTK reference station ARP --------------------*/
486 double rr[3], re[3], pos[3];
487 char* msg;
488 int i = 24 + 12, j, staid, itrf;
489
490 if (i + 140 == rtcm->len * 8) {
491 staid = getbitu(rtcm->buff, i, 12);
492 i += 12;
493 itrf = getbitu(rtcm->buff, i, 6);
494 i += 6 + 4;
495 rr[0] = getbits_38(rtcm->buff, i);
496 i += 38 + 2;
497 rr[1] = getbits_38(rtcm->buff, i);
498 i += 38 + 2;
499 rr[2] = getbits_38(rtcm->buff, i);
500 } else {
501 trace(NULL, 2, "rtcm3 1005 length error: len=%d\n", rtcm->len);
502 return -1;
503 }
504 if (rtcm->outtype) {
505 msg = rtcm->msgtype + strlen(rtcm->msgtype);
506 for (j = 0; j < 3; j++) {
507 re[j] = rr[j] * 0.0001;
508 }
509 ecef2pos(re, pos);
510 sprintf(msg, " staid=%4d pos=%.8f %.8f %.3f", staid, pos[0] * R2D, pos[1] * R2D, pos[2]);
511 }
512 /* test station id */
513 if (!test_staid(rtcm, staid)) {
514 return -1;
515 }
516
517 sprintf(rtcm->sta.name, "%04d", staid);
518 rtcm->sta.deltype = 0; /* xyz */
519 for (j = 0; j < 3; j++) {
520 rtcm->sta.pos[j] = rr[j] * 0.0001;
521 rtcm->sta.del[j] = 0.0;
522 }
523 rtcm->sta.hgt = 0.0;
524 rtcm->sta.itrf = itrf;
525 return 5;
526}
527/* decode type 1006: stationary RTK reference station ARP with height --------*/
529 double rr[3], re[3], pos[3], anth;
530 char* msg;
531 int i = 24 + 12, j, staid, itrf;
532
533 if (i + 156 <= rtcm->len * 8) {
534 staid = getbitu(rtcm->buff, i, 12);
535 i += 12;
536 itrf = getbitu(rtcm->buff, i, 6);
537 i += 6 + 4;
538 rr[0] = getbits_38(rtcm->buff, i);
539 i += 38 + 2;
540 rr[1] = getbits_38(rtcm->buff, i);
541 i += 38 + 2;
542 rr[2] = getbits_38(rtcm->buff, i);
543 i += 38;
544 anth = getbitu(rtcm->buff, i, 16);
545 } else {
546 trace(NULL, 2, "rtcm3 1006 length error: len=%d\n", rtcm->len);
547 return -1;
548 }
549 if (rtcm->outtype) {
550 msg = rtcm->msgtype + strlen(rtcm->msgtype);
551 for (j = 0; j < 3; j++) {
552 re[j] = rr[j] * 0.0001;
553 }
554 ecef2pos(re, pos);
555 sprintf(msg, " staid=%4d pos=%.8f %.8f %.3f anth=%.3f", staid, pos[0] * R2D, pos[1] * R2D, pos[2],
556 anth * 0.0001);
557 }
558 /* test station id */
559 if (!test_staid(rtcm, staid)) {
560 return -1;
561 }
562
563 sprintf(rtcm->sta.name, "%04d", staid);
564 rtcm->sta.deltype = 1; /* xyz */
565 for (j = 0; j < 3; j++) {
566 rtcm->sta.pos[j] = rr[j] * 0.0001;
567 rtcm->sta.del[j] = 0.0;
568 }
569 rtcm->sta.hgt = anth * 0.0001;
570 rtcm->sta.itrf = itrf;
571 return 5;
572}
573/* decode type 1007: antenna descriptor --------------------------------------*/
575 char des[32] = "";
576 char* msg;
577 int i = 24 + 12, j, staid, n, setup;
578
579 n = getbitu(rtcm->buff, i + 12, 8);
580
581 if (i + 28 + 8 * n <= rtcm->len * 8) {
582 staid = getbitu(rtcm->buff, i, 12);
583 i += 12 + 8;
584 for (j = 0; j < n && j < 31; j++) {
585 des[j] = (char)getbitu(rtcm->buff, i, 8);
586 i += 8;
587 }
588 setup = getbitu(rtcm->buff, i, 8);
589 } else {
590 trace(NULL, 2, "rtcm3 1007 length error: len=%d\n", rtcm->len);
591 return -1;
592 }
593 if (rtcm->outtype) {
594 msg = rtcm->msgtype + strlen(rtcm->msgtype);
595 sprintf(msg, " staid=%4d", staid);
596 }
597 /* test station ID */
598 if (!test_staid(rtcm, staid)) {
599 return -1;
600 }
601
602 sprintf(rtcm->sta.name, "%04d", staid);
603 strncpy(rtcm->sta.antdes, des, n);
604 rtcm->sta.antdes[n] = '\0';
605 rtcm->sta.antsetup = setup;
606 rtcm->sta.antsno[0] = '\0';
607 return 5;
608}
609/* decode type 1008: antenna descriptor & serial number ----------------------*/
611 char des[32] = "", sno[32] = "";
612 char* msg;
613 int i = 24 + 12, j, staid, n, m, setup;
614
615 n = getbitu(rtcm->buff, i + 12, 8);
616 m = getbitu(rtcm->buff, i + 28 + 8 * n, 8);
617
618 if (i + 36 + 8 * (n + m) <= rtcm->len * 8) {
619 staid = getbitu(rtcm->buff, i, 12);
620 i += 12 + 8;
621 for (j = 0; j < n && j < 31; j++) {
622 des[j] = (char)getbitu(rtcm->buff, i, 8);
623 i += 8;
624 }
625 setup = getbitu(rtcm->buff, i, 8);
626 i += 8 + 8;
627 for (j = 0; j < m && j < 31; j++) {
628 sno[j] = (char)getbitu(rtcm->buff, i, 8);
629 i += 8;
630 }
631 } else {
632 trace(NULL, 2, "rtcm3 1008 length error: len=%d\n", rtcm->len);
633 return -1;
634 }
635 if (rtcm->outtype) {
636 msg = rtcm->msgtype + strlen(rtcm->msgtype);
637 sprintf(msg, " staid=%4d", staid);
638 }
639 /* test station ID */
640 if (!test_staid(rtcm, staid)) {
641 return -1;
642 }
643
644 sprintf(rtcm->sta.name, "%04d", staid);
645 strncpy(rtcm->sta.antdes, des, n);
646 rtcm->sta.antdes[n] = '\0';
647 rtcm->sta.antsetup = setup;
648 strncpy(rtcm->sta.antsno, sno, m);
649 rtcm->sta.antsno[m] = '\0';
650 return 5;
651}
652/* decode type 1009-1012 message header --------------------------------------*/
653static int decode_head1009(rtcm_t* rtcm, int* sync) {
654 double tod;
655 char *msg, tstr[64];
656 int i = 24, staid, nsat, type;
657
658 type = getbitu(rtcm->buff, i, 12);
659 i += 12;
660
661 if (i + 49 <= rtcm->len * 8) {
662 staid = getbitu(rtcm->buff, i, 12);
663 i += 12;
664 tod = getbitu(rtcm->buff, i, 27) * 0.001;
665 i += 27; /* sec in a day */
666 *sync = getbitu(rtcm->buff, i, 1);
667 i += 1;
668 nsat = getbitu(rtcm->buff, i, 5);
669 } else {
670 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
671 return -1;
672 }
673 /* test station ID */
674 if (!test_staid(rtcm, staid)) {
675 return -1;
676 }
677
678 adjday_glot(rtcm, tod);
679
680 time2str(rtcm->time, tstr, 2);
681 trace(NULL, 4, "decode_head1009: time=%s nsat=%d sync=%d\n", tstr, nsat, *sync);
682
683 if (rtcm->outtype) {
684 msg = rtcm->msgtype + strlen(rtcm->msgtype);
685 sprintf(msg, " staid=%4d %s nsat=%2d sync=%d", staid, tstr, nsat, *sync);
686 }
687 return nsat;
688}
689/* decode type 1009: L1-only glonass rtk observables -------------------------*/
691 int sync;
692 if (decode_head1009(rtcm, &sync) < 0) {
693 return -1;
694 }
695 rtcm->obsflag = !sync;
696 return sync ? 0 : 1;
697}
698/* decode type 1010: extended L1-only glonass rtk observables ----------------*/
700 double pr1, cnr1, tt, cp1, freq1;
701 int i = 24 + 61, j, index, nsat, sync, prn, sat, code, fcn, ppr1, lock1, amb, sys = SYS_GLO;
702
703 if ((nsat = decode_head1009(rtcm, &sync)) < 0) {
704 return -1;
705 }
706
707 for (j = 0; j < nsat && rtcm->obs.n < MAXOBS && i + 79 <= rtcm->len * 8; j++) {
708 prn = getbitu(rtcm->buff, i, 6);
709 i += 6;
710 code = getbitu(rtcm->buff, i, 1);
711 i += 1;
712 fcn = getbitu(rtcm->buff, i, 5);
713 i += 5; /* fcn+7 */
714 pr1 = getbitu(rtcm->buff, i, 25);
715 i += 25;
716 ppr1 = getbits(rtcm->buff, i, 20);
717 i += 20;
718 lock1 = getbitu(rtcm->buff, i, 7);
719 i += 7;
720 amb = getbitu(rtcm->buff, i, 7);
721 i += 7;
722 cnr1 = getbitu(rtcm->buff, i, 8);
723 i += 8;
724 if (!(sat = satno(sys, prn))) {
725 trace(NULL, 2, "rtcm3 1010 satellite number error: prn=%d\n", prn);
726 continue;
727 }
728 if (!rtcm->nav.glo_fcn[prn - 1]) {
729 rtcm->nav.glo_fcn[prn - 1] = fcn - 7 + 8; /* fcn+8 */
730 }
731 tt = timediff(rtcm->obs.data[0].time, rtcm->time);
732 if (rtcm->obsflag || fabs(tt) > 1E-9) {
733 rtcm->obs.n = rtcm->obsflag = 0;
734 }
735 if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) {
736 continue;
737 }
738 pr1 = pr1 * 0.02 + amb * PRUNIT_GLO;
739 rtcm->obs.data[index].P[0] = pr1;
740
741 if (ppr1 != (int)0xFFF80000) {
742 freq1 = code2freq(SYS_GLO, CODE_L1C, fcn - 7);
743 cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq1 / CLIGHT);
744 rtcm->obs.data[index].L[0] = pr1 * freq1 / CLIGHT + cp1;
745 }
746 rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1);
747 rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25);
748 rtcm->obs.data[index].code[0] = code ? CODE_L1P : CODE_L1C;
749 }
750 return sync ? 0 : 1;
751}
752/* decode type 1011: L1&L2 GLONASS RTK observables ---------------------------*/
754 int sync;
755 if (decode_head1009(rtcm, &sync) < 0) {
756 return -1;
757 }
758 rtcm->obsflag = !sync;
759 return sync ? 0 : 1;
760}
761/* decode type 1012: extended L1&L2 GLONASS RTK observables ------------------*/
763 double pr1, cnr1, cnr2, tt, cp1, cp2, freq1, freq2;
764 int i = 24 + 61, j, index, nsat, sync, prn, sat, fcn, code1, code2, pr21, ppr1, ppr2;
765 int lock1, lock2, amb, sys = SYS_GLO;
766
767 if ((nsat = decode_head1009(rtcm, &sync)) < 0) {
768 return -1;
769 }
770
771 for (j = 0; j < nsat && rtcm->obs.n < MAXOBS && i + 130 <= rtcm->len * 8; j++) {
772 prn = getbitu(rtcm->buff, i, 6);
773 i += 6;
774 code1 = getbitu(rtcm->buff, i, 1);
775 i += 1;
776 fcn = getbitu(rtcm->buff, i, 5);
777 i += 5; /* fcn+7 */
778 pr1 = getbitu(rtcm->buff, i, 25);
779 i += 25;
780 ppr1 = getbits(rtcm->buff, i, 20);
781 i += 20;
782 lock1 = getbitu(rtcm->buff, i, 7);
783 i += 7;
784 amb = getbitu(rtcm->buff, i, 7);
785 i += 7;
786 cnr1 = getbitu(rtcm->buff, i, 8);
787 i += 8;
788 code2 = getbitu(rtcm->buff, i, 2);
789 i += 2;
790 pr21 = getbits(rtcm->buff, i, 14);
791 i += 14;
792 ppr2 = getbits(rtcm->buff, i, 20);
793 i += 20;
794 lock2 = getbitu(rtcm->buff, i, 7);
795 i += 7;
796 cnr2 = getbitu(rtcm->buff, i, 8);
797 i += 8;
798 if (!(sat = satno(sys, prn))) {
799 trace(NULL, 2, "rtcm3 1012 satellite number error: sys=%d prn=%d\n", sys, prn);
800 continue;
801 }
802 if (!rtcm->nav.glo_fcn[prn - 1]) {
803 rtcm->nav.glo_fcn[prn - 1] = fcn - 7 + 8; /* fcn+8 */
804 }
805 tt = timediff(rtcm->obs.data[0].time, rtcm->time);
806 if (rtcm->obsflag || fabs(tt) > 1E-9) {
807 rtcm->obs.n = rtcm->obsflag = 0;
808 }
809 if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) {
810 continue;
811 }
812 pr1 = pr1 * 0.02 + amb * PRUNIT_GLO;
813 rtcm->obs.data[index].P[0] = pr1;
814
815 if (ppr1 != (int)0xFFF80000) {
816 freq1 = code2freq(SYS_GLO, CODE_L1C, fcn - 7);
817 cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq1 / CLIGHT);
818 rtcm->obs.data[index].L[0] = pr1 * freq1 / CLIGHT + cp1;
819 }
820 rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1);
821 rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25);
822 rtcm->obs.data[index].code[0] = code1 ? CODE_L1P : CODE_L1C;
823
824 if (pr21 != (int)0xFFFFE000) {
825 rtcm->obs.data[index].P[1] = pr1 + pr21 * 0.02;
826 }
827 if (ppr2 != (int)0xFFF80000) {
828 freq2 = code2freq(SYS_GLO, CODE_L2C, fcn - 7);
829 cp2 = adjcp(rtcm, sat, 1, ppr2 * 0.0005 * freq2 / CLIGHT);
830 rtcm->obs.data[index].L[1] = pr1 * freq2 / CLIGHT + cp2;
831 }
832 rtcm->obs.data[index].LLI[1] = lossoflock(rtcm, sat, 1, lock2);
833 rtcm->obs.data[index].SNR[1] = snratio(cnr2 * 0.25);
834 rtcm->obs.data[index].code[1] = code2 ? CODE_L2P : CODE_L2C;
835 }
836 rtcm->obsflag = !sync;
837 return sync ? 0 : 1;
838}
839/* decode type 1013: system parameters ---------------------------------------*/
840static int decode_type1013(rtcm_t* rtcm) { return 0; }
841/* decode type 1019: GPS ephemerides -----------------------------------------*/
843 eph_t eph = {0};
844 double toc, sqrtA, tt;
845 char* msg;
846 int i = 24 + 12, prn, sat, week, sys = SYS_GPS;
847
848 if (i + 476 <= rtcm->len * 8) {
849 prn = getbitu(rtcm->buff, i, 6);
850 i += 6;
851 week = getbitu(rtcm->buff, i, 10);
852 i += 10;
853 eph.sva = getbitu(rtcm->buff, i, 4);
854 i += 4;
855 eph.code = getbitu(rtcm->buff, i, 2);
856 i += 2;
857 eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD;
858 i += 14;
859 eph.iode = getbitu(rtcm->buff, i, 8);
860 i += 8;
861 toc = getbitu(rtcm->buff, i, 16) * 16.0;
862 i += 16;
863 eph.f2 = getbits(rtcm->buff, i, 8) * P2_55;
864 i += 8;
865 eph.f1 = getbits(rtcm->buff, i, 16) * P2_43;
866 i += 16;
867 eph.f0 = getbits(rtcm->buff, i, 22) * P2_31;
868 i += 22;
869 eph.iodc = getbitu(rtcm->buff, i, 10);
870 i += 10;
871 eph.crs = getbits(rtcm->buff, i, 16) * P2_5;
872 i += 16;
873 eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD;
874 i += 16;
875 eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
876 i += 32;
877 eph.cuc = getbits(rtcm->buff, i, 16) * P2_29;
878 i += 16;
879 eph.e = getbitu(rtcm->buff, i, 32) * P2_33;
880 i += 32;
881 eph.cus = getbits(rtcm->buff, i, 16) * P2_29;
882 i += 16;
883 sqrtA = getbitu(rtcm->buff, i, 32) * P2_19;
884 i += 32;
885 eph.toes = getbitu(rtcm->buff, i, 16) * 16.0;
886 i += 16;
887 eph.cic = getbits(rtcm->buff, i, 16) * P2_29;
888 i += 16;
889 eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
890 i += 32;
891 eph.cis = getbits(rtcm->buff, i, 16) * P2_29;
892 i += 16;
893 eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
894 i += 32;
895 eph.crc = getbits(rtcm->buff, i, 16) * P2_5;
896 i += 16;
897 eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
898 i += 32;
899 eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD;
900 i += 24;
901 eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31;
902 i += 8;
903 eph.svh = getbitu(rtcm->buff, i, 6);
904 i += 6;
905 eph.flag = getbitu(rtcm->buff, i, 1);
906 i += 1;
907 eph.fit = getbitu(rtcm->buff, i, 1) ? 0.0 : 4.0; /* 0:4hr,1:>4hr */
908 } else {
909 trace(NULL, 2, "rtcm3 1019 length error: len=%d\n", rtcm->len);
910 return -1;
911 }
912 if (prn >= 40) {
913 sys = SYS_SBS;
914 prn += 80;
915 }
916 trace(NULL, 4, "decode_type1019: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes);
917
918 if (rtcm->outtype) {
919 msg = rtcm->msgtype + strlen(rtcm->msgtype);
920 sprintf(msg, " prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, eph.iodc, week,
921 eph.toes, toc, eph.svh);
922 }
923 if (!(sat = satno(sys, prn))) {
924 trace(NULL, 2, "rtcm3 1019 satellite number error: prn=%d\n", prn);
925 return -1;
926 }
927 eph.sat = sat;
928 eph.type = 0; /* ephemeris type = LNAV */
929 eph.week = adjgpsweek(week);
930 if (rtcm->time.time == 0) {
931 rtcm->time = utc2gpst(timeget());
932 }
933 tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time);
934 if (tt < -302400.0) {
935 eph.week++;
936 } else if (tt >= 302400.0) {
937 eph.week--;
938 }
939 eph.toe = gpst2time(eph.week, eph.toes);
940 eph.toc = gpst2time(eph.week, toc);
941 eph.ttr = rtcm->time;
942 eph.A = sqrtA * sqrtA;
943 if (!strstr(rtcm->opt, "-EPHALL")) {
944 if (eph.iode == rtcm->nav.eph[sat - 1].iode) {
945 return 0; /* unchanged */
946 }
947 }
948 rtcm->nav.eph[sat - 1] = eph;
949 rtcm->ephsat = sat;
950 rtcm->ephset = 0;
951 return 2;
952}
953/* decode type 1020: GLONASS ephemerides -------------------------------------*/
955 geph_t geph = {0};
956 double tk_h, tk_m, tk_s, toe, tow, tod, tof;
957 char* msg;
958 int i = 24 + 12, prn, sat, week, tb, Bn, Cn, Cn_a, P1, P2, P3, P4, P, M, ln, sys = SYS_GLO;
959
960 if (i + 348 <= rtcm->len * 8) {
961 prn = getbitu(rtcm->buff, i, 6);
962 i += 6;
963 geph.frq = getbitu(rtcm->buff, i, 5) - 7;
964 i += 5;
965 Cn = getbitu(rtcm->buff, i, 1);
966 i += 1;
967 Cn_a = getbitu(rtcm->buff, i, 1);
968 i += 1;
969 P1 = getbitu(rtcm->buff, i, 2);
970 i += 2;
971 tk_h = getbitu(rtcm->buff, i, 5);
972 i += 5;
973 tk_m = getbitu(rtcm->buff, i, 6);
974 i += 6;
975 tk_s = getbitu(rtcm->buff, i, 1) * 30.0;
976 i += 1;
977 Bn = getbitu(rtcm->buff, i, 1);
978 i += 1;
979 P2 = getbitu(rtcm->buff, i, 1);
980 i += 1;
981 tb = getbitu(rtcm->buff, i, 7);
982 i += 7;
983 geph.vel[0] = getbitg(rtcm->buff, i, 24) * P2_20 * 1E3;
984 i += 24;
985 geph.pos[0] = getbitg(rtcm->buff, i, 27) * P2_11 * 1E3;
986 i += 27;
987 geph.acc[0] = getbitg(rtcm->buff, i, 5) * P2_30 * 1E3;
988 i += 5;
989 geph.vel[1] = getbitg(rtcm->buff, i, 24) * P2_20 * 1E3;
990 i += 24;
991 geph.pos[1] = getbitg(rtcm->buff, i, 27) * P2_11 * 1E3;
992 i += 27;
993 geph.acc[1] = getbitg(rtcm->buff, i, 5) * P2_30 * 1E3;
994 i += 5;
995 geph.vel[2] = getbitg(rtcm->buff, i, 24) * P2_20 * 1E3;
996 i += 24;
997 geph.pos[2] = getbitg(rtcm->buff, i, 27) * P2_11 * 1E3;
998 i += 27;
999 geph.acc[2] = getbitg(rtcm->buff, i, 5) * P2_30 * 1E3;
1000 i += 5;
1001 P3 = getbitu(rtcm->buff, i, 1);
1002 i += 1;
1003 geph.gamn = getbitg(rtcm->buff, i, 11) * P2_40;
1004 i += 11;
1005 P = getbitu(rtcm->buff, i, 2);
1006 i += 2;
1007 ln = getbitu(rtcm->buff, i, 1);
1008 i += 1;
1009 geph.taun = getbitg(rtcm->buff, i, 22) * P2_30;
1010 i += 22;
1011 geph.dtaun = getbitg(rtcm->buff, i, 5) * P2_30;
1012 i += 5;
1013 geph.age = getbitu(rtcm->buff, i, 5);
1014 i += 5;
1015 P4 = getbitu(rtcm->buff, i, 1);
1016 i += 1;
1017 geph.sva = getbitu(rtcm->buff, i, 4);
1018 i += 4 + 11;
1019 M = getbitu(rtcm->buff, i, 2);
1020 } else {
1021 trace(NULL, 2, "rtcm3 1020 length error: len=%d\n", rtcm->len);
1022 return -1;
1023 }
1024 if (!(sat = satno(sys, prn))) {
1025 trace(NULL, 2, "rtcm3 1020 satellite number error: prn=%d\n", prn);
1026 return -1;
1027 }
1028 trace(NULL, 4, "decode_type1020: prn=%d tk=%02.0f:%02.0f:%02.0f\n", prn, tk_h, tk_m, tk_s);
1029
1030 if (rtcm->outtype) {
1031 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1032 sprintf(msg, " prn=%2d tk=%02.0f:%02.0f:%02.0f frq=%2d Bn=%d tb=%d", prn, tk_h, tk_m, tk_s, geph.frq, Bn, tb);
1033 }
1034 geph.sat = sat;
1035 geph.svh = (ln << 3) + (Cn_a << 2) + (Cn << 1) + Bn;
1036 geph.flags = (M << 7) + (P4 << 6) + (P3 << 5) + (P2 << 4) + (P1 << 2) + P;
1037 geph.iode = tb & 0x7F;
1038 if (rtcm->time.time == 0) {
1039 rtcm->time = utc2gpst(timeget());
1040 }
1041 tow = time2gpst(gpst2utc(rtcm->time), &week);
1042 tod = fmod(tow, 86400.0);
1043 tow -= tod;
1044 tof = tk_h * 3600.0 + tk_m * 60.0 + tk_s - 10800.0; /* lt->utc */
1045 if (tof < tod - 43200.0) {
1046 tof += 86400.0;
1047 } else if (tof > tod + 43200.0) {
1048 tof -= 86400.0;
1049 }
1050 geph.tof = utc2gpst(gpst2time(week, tow + tof));
1051 toe = tb * 900.0 - 10800.0; /* lt->utc */
1052 if (toe < tod - 43200.0) {
1053 toe += 86400.0;
1054 } else if (toe > tod + 43200.0) {
1055 toe -= 86400.0;
1056 }
1057 geph.toe = utc2gpst(gpst2time(week, tow + toe)); /* utc->gpst */
1058
1059 if (!strstr(rtcm->opt, "-EPHALL")) {
1060 if (fabs(timediff(geph.toe, rtcm->nav.geph[prn - 1].toe)) < 1.0 && geph.svh == rtcm->nav.geph[prn - 1].svh) {
1061 return 0; /* unchanged */
1062 }
1063 }
1064 rtcm->nav.geph[prn - 1] = geph;
1065 rtcm->ephsat = sat;
1066 rtcm->ephset = 0;
1067 return 2;
1068}
1069/* decode type 1021: helmert/abridged molodenski -----------------------------*/
1071 trace(NULL, 2, "rtcm3 1021: not supported message\n");
1072 return 0;
1073}
1074/* decode type 1022: Moledenski-Badekas transfromation -----------------------*/
1076 trace(NULL, 2, "rtcm3 1022: not supported message\n");
1077 return 0;
1078}
1079/* decode type 1023: residual, ellipsoidal grid representation ---------------*/
1081 trace(NULL, 2, "rtcm3 1023: not supported message\n");
1082 return 0;
1083}
1084/* decode type 1024: residual, plane grid representation ---------------------*/
1086 trace(NULL, 2, "rtcm3 1024: not supported message\n");
1087 return 0;
1088}
1089/* decode type 1025: projection (types except LCC2SP,OM) ---------------------*/
1091 trace(NULL, 2, "rtcm3 1025: not supported message\n");
1092 return 0;
1093}
1094/* decode type 1026: projection (LCC2SP - lambert conic conformal (2sp)) -----*/
1096 trace(NULL, 2, "rtcm3 1026: not supported message\n");
1097 return 0;
1098}
1099/* decode type 1027: projection (type OM - oblique mercator) -----------------*/
1101 trace(NULL, 2, "rtcm3 1027: not supported message\n");
1102 return 0;
1103}
1104/* decode type 1029: UNICODE text string -------------------------------------*/
1106 char* msg;
1107 int i = 24 + 12, j, staid, mjd, tod, nchar, cunit;
1108
1109 if (i + 60 <= rtcm->len * 8) {
1110 staid = getbitu(rtcm->buff, i, 12);
1111 i += 12;
1112 mjd = getbitu(rtcm->buff, i, 16);
1113 i += 16;
1114 tod = getbitu(rtcm->buff, i, 17);
1115 i += 17;
1116 nchar = getbitu(rtcm->buff, i, 7);
1117 i += 7;
1118 cunit = getbitu(rtcm->buff, i, 8);
1119 i += 8;
1120 } else {
1121 trace(NULL, 2, "rtcm3 1029 length error: len=%d\n", rtcm->len);
1122 return -1;
1123 }
1124 if (i + nchar * 8 > rtcm->len * 8) {
1125 trace(NULL, 2, "rtcm3 1029 length error: len=%d nchar=%d\n", rtcm->len, nchar);
1126 return -1;
1127 }
1128 for (j = 0; j < nchar && j < 126; j++) {
1129 rtcm->msg[j] = getbitu(rtcm->buff, i, 8);
1130 i += 8;
1131 }
1132 rtcm->msg[j] = '\0';
1133
1134 if (rtcm->outtype) {
1135 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1136 sprintf(msg, " staid=%4d text=%s", staid, rtcm->msg);
1137 }
1138 return 0;
1139}
1140/* decode type 1030: network RTK residual ------------------------------------*/
1142 trace(NULL, 2, "rtcm3 1030: not supported message\n");
1143 return 0;
1144}
1145/* decode type 1031: GLONASS network RTK residual ----------------------------*/
1147 trace(NULL, 2, "rtcm3 1031: not supported message\n");
1148 return 0;
1149}
1150/* decode type 1032: physical reference station position information ---------*/
1152 trace(NULL, 2, "rtcm3 1032: not supported message\n");
1153 return 0;
1154}
1155/* decode type 1033: receiver and antenna descriptor -------------------------*/
1157 char des[32] = "", sno[32] = "", rec[32] = "", ver[32] = "", rsn[32] = "";
1158 char* msg;
1159 int i = 24 + 12, j, staid, n, m, n1, n2, n3, setup;
1160
1161 n = getbitu(rtcm->buff, i + 12, 8);
1162 m = getbitu(rtcm->buff, i + 28 + 8 * n, 8);
1163 n1 = getbitu(rtcm->buff, i + 36 + 8 * (n + m), 8);
1164 n2 = getbitu(rtcm->buff, i + 44 + 8 * (n + m + n1), 8);
1165 n3 = getbitu(rtcm->buff, i + 52 + 8 * (n + m + n1 + n2), 8);
1166
1167 if (i + 60 + 8 * (n + m + n1 + n2 + n3) <= rtcm->len * 8) {
1168 staid = getbitu(rtcm->buff, i, 12);
1169 i += 12 + 8;
1170 for (j = 0; j < n && j < 31; j++) {
1171 des[j] = (char)getbitu(rtcm->buff, i, 8);
1172 i += 8;
1173 }
1174 setup = getbitu(rtcm->buff, i, 8);
1175 i += 8 + 8;
1176 for (j = 0; j < m && j < 31; j++) {
1177 sno[j] = (char)getbitu(rtcm->buff, i, 8);
1178 i += 8;
1179 }
1180 i += 8;
1181 for (j = 0; j < n1 && j < 31; j++) {
1182 rec[j] = (char)getbitu(rtcm->buff, i, 8);
1183 i += 8;
1184 }
1185 i += 8;
1186 for (j = 0; j < n2 && j < 31; j++) {
1187 ver[j] = (char)getbitu(rtcm->buff, i, 8);
1188 i += 8;
1189 }
1190 i += 8;
1191 for (j = 0; j < n3 && j < 31; j++) {
1192 rsn[j] = (char)getbitu(rtcm->buff, i, 8);
1193 i += 8;
1194 }
1195 } else {
1196 trace(NULL, 2, "rtcm3 1033 length error: len=%d\n", rtcm->len);
1197 return -1;
1198 }
1199 if (rtcm->outtype) {
1200 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1201 sprintf(msg, " staid=%4d", staid);
1202 }
1203 /* test station id */
1204 if (!test_staid(rtcm, staid)) {
1205 return -1;
1206 }
1207
1208 sprintf(rtcm->sta.name, "%04d", staid);
1209 strncpy(rtcm->sta.antdes, des, n);
1210 rtcm->sta.antdes[n] = '\0';
1211 rtcm->sta.antsetup = setup;
1212 strncpy(rtcm->sta.antsno, sno, m);
1213 rtcm->sta.antsno[m] = '\0';
1214 strncpy(rtcm->sta.rectype, rec, n1);
1215 rtcm->sta.rectype[n1] = '\0';
1216 strncpy(rtcm->sta.recver, ver, n2);
1217 rtcm->sta.recver[n2] = '\0';
1218 strncpy(rtcm->sta.recsno, rsn, n3);
1219 rtcm->sta.recsno[n3] = '\0';
1220
1221 trace(NULL, 3, "rtcm3 1033: ant=%s:%s rec=%s:%s:%s\n", des, sno, rec, ver, rsn);
1222 return 5;
1223}
1224/* decode type 1034: GPS network FKP gradient --------------------------------*/
1226 trace(NULL, 2, "rtcm3 1034: not supported message\n");
1227 return 0;
1228}
1229/* decode type 1035: GLONASS network FKP gradient ----------------------------*/
1231 trace(NULL, 2, "rtcm3 1035: not supported message\n");
1232 return 0;
1233}
1234/* decode type 1037: GLONASS network RTK ionospheric correction difference ---*/
1236 trace(NULL, 2, "rtcm3 1037: not supported message\n");
1237 return 0;
1238}
1239/* decode type 1038: GLONASS network RTK geometic correction difference ------*/
1241 trace(NULL, 2, "rtcm3 1038: not supported message\n");
1242 return 0;
1243}
1244/* decode type 1039: GLONASS network RTK combined correction difference ------*/
1246 trace(NULL, 2, "rtcm3 1039: not supported message\n");
1247 return 0;
1248}
1249/* decode type 1041: NavIC/IRNSS ephemerides ---------------------------------*/
1251 eph_t eph = {0};
1252 double toc, sqrtA, tt;
1253 char* msg;
1254 int i = 24 + 12, prn, sat, week, sys = SYS_IRN;
1255
1256 if (i + 482 - 12 <= rtcm->len * 8) {
1257 prn = getbitu(rtcm->buff, i, 6);
1258 i += 6;
1259 week = getbitu(rtcm->buff, i, 10);
1260 i += 10;
1261 eph.f0 = getbits(rtcm->buff, i, 22) * P2_31;
1262 i += 22;
1263 eph.f1 = getbits(rtcm->buff, i, 16) * P2_43;
1264 i += 16;
1265 eph.f2 = getbits(rtcm->buff, i, 8) * P2_55;
1266 i += 8;
1267 eph.sva = getbitu(rtcm->buff, i, 4);
1268 i += 4;
1269 toc = getbitu(rtcm->buff, i, 16) * 16.0;
1270 i += 16;
1271 eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31;
1272 i += 8;
1273 eph.deln = getbits(rtcm->buff, i, 22) * P2_41 * SC2RAD;
1274 i += 22;
1275 eph.iode = getbitu(rtcm->buff, i, 8);
1276 i += 8 + 10; /* IODEC */
1277 eph.svh = getbitu(rtcm->buff, i, 2);
1278 i += 2; /* L5+Sflag */
1279 eph.cuc = getbits(rtcm->buff, i, 15) * P2_28;
1280 i += 15;
1281 eph.cus = getbits(rtcm->buff, i, 15) * P2_28;
1282 i += 15;
1283 eph.cic = getbits(rtcm->buff, i, 15) * P2_28;
1284 i += 15;
1285 eph.cis = getbits(rtcm->buff, i, 15) * P2_28;
1286 i += 15;
1287 eph.crc = getbits(rtcm->buff, i, 15) * 0.0625;
1288 i += 15;
1289 eph.crs = getbits(rtcm->buff, i, 15) * 0.0625;
1290 i += 15;
1291 eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD;
1292 i += 14;
1293 eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1294 i += 32;
1295 eph.toes = getbitu(rtcm->buff, i, 16) * 16.0;
1296 i += 16;
1297 eph.e = getbitu(rtcm->buff, i, 32) * P2_33;
1298 i += 32;
1299 sqrtA = getbitu(rtcm->buff, i, 32) * P2_19;
1300 i += 32;
1301 eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1302 i += 32;
1303 eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1304 i += 32;
1305 eph.OMGd = getbits(rtcm->buff, i, 22) * P2_41 * SC2RAD;
1306 i += 22;
1307 eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1308 } else {
1309 trace(NULL, 2, "rtcm3 1041 length error: len=%d\n", rtcm->len);
1310 return -1;
1311 }
1312 trace(NULL, 4, "decode_type1041: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes);
1313
1314 if (rtcm->outtype) {
1315 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1316 sprintf(msg, " prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, week, eph.toes, toc,
1317 eph.svh);
1318 }
1319 if (!(sat = satno(sys, prn))) {
1320 trace(NULL, 2, "rtcm3 1041 satellite number error: prn=%d\n", prn);
1321 return -1;
1322 }
1323 eph.sat = sat;
1324 eph.type = 0; /* ephemeris type = LNAV */
1325 eph.week = adjgpsweek(week);
1326 if (rtcm->time.time == 0) {
1327 rtcm->time = utc2gpst(timeget());
1328 }
1329 tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time);
1330 if (tt < -302400.0) {
1331 eph.week++;
1332 } else if (tt >= 302400.0) {
1333 eph.week--;
1334 }
1335 eph.toe = gpst2time(eph.week, eph.toes);
1336 eph.toc = gpst2time(eph.week, toc);
1337 eph.ttr = rtcm->time;
1338 eph.A = sqrtA * sqrtA;
1339 eph.iodc = eph.iode;
1340 if (!strstr(rtcm->opt, "-EPHALL")) {
1341 if (eph.iode == rtcm->nav.eph[sat - 1].iode) {
1342 return 0; /* unchanged */
1343 }
1344 }
1345 rtcm->nav.eph[sat - 1] = eph;
1346 rtcm->ephsat = sat;
1347 rtcm->ephset = 0;
1348 return 2;
1349}
1350/* decode type 1044: QZSS ephemerides ----------------------------------------*/
1352 eph_t eph = {0};
1353 double toc, sqrtA, tt;
1354 char* msg;
1355 int i = 24 + 12, prn, sat, week, sys = SYS_QZS;
1356
1357 if (i + 473 <= rtcm->len * 8) {
1358 prn = getbitu(rtcm->buff, i, 4) + 192;
1359 i += 4;
1360 toc = getbitu(rtcm->buff, i, 16) * 16.0;
1361 i += 16;
1362 eph.f2 = getbits(rtcm->buff, i, 8) * P2_55;
1363 i += 8;
1364 eph.f1 = getbits(rtcm->buff, i, 16) * P2_43;
1365 i += 16;
1366 eph.f0 = getbits(rtcm->buff, i, 22) * P2_31;
1367 i += 22;
1368 eph.iode = getbitu(rtcm->buff, i, 8);
1369 i += 8;
1370 eph.crs = getbits(rtcm->buff, i, 16) * P2_5;
1371 i += 16;
1372 eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD;
1373 i += 16;
1374 eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1375 i += 32;
1376 eph.cuc = getbits(rtcm->buff, i, 16) * P2_29;
1377 i += 16;
1378 eph.e = getbitu(rtcm->buff, i, 32) * P2_33;
1379 i += 32;
1380 eph.cus = getbits(rtcm->buff, i, 16) * P2_29;
1381 i += 16;
1382 sqrtA = getbitu(rtcm->buff, i, 32) * P2_19;
1383 i += 32;
1384 eph.toes = getbitu(rtcm->buff, i, 16) * 16.0;
1385 i += 16;
1386 eph.cic = getbits(rtcm->buff, i, 16) * P2_29;
1387 i += 16;
1388 eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1389 i += 32;
1390 eph.cis = getbits(rtcm->buff, i, 16) * P2_29;
1391 i += 16;
1392 eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1393 i += 32;
1394 eph.crc = getbits(rtcm->buff, i, 16) * P2_5;
1395 i += 16;
1396 eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1397 i += 32;
1398 eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD;
1399 i += 24;
1400 eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD;
1401 i += 14;
1402 eph.code = getbitu(rtcm->buff, i, 2);
1403 i += 2;
1404 week = getbitu(rtcm->buff, i, 10);
1405 i += 10;
1406 eph.sva = getbitu(rtcm->buff, i, 4);
1407 i += 4;
1408 eph.svh = getbitu(rtcm->buff, i, 6);
1409 i += 6;
1410 eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31;
1411 i += 8;
1412 eph.iodc = getbitu(rtcm->buff, i, 10);
1413 i += 10;
1414 eph.fit = getbitu(rtcm->buff, i, 1) ? 0.0 : 2.0; /* 0:2hr,1:>2hr */
1415 } else {
1416 trace(NULL, 2, "rtcm3 1044 length error: len=%d\n", rtcm->len);
1417 return -1;
1418 }
1419 trace(NULL, 4, "decode_type1044: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes);
1420
1421 if (rtcm->outtype) {
1422 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1423 sprintf(msg, " prn=%3d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, eph.iodc, week,
1424 eph.toes, toc, eph.svh);
1425 }
1426 if (!(sat = satno(sys, prn))) {
1427 trace(NULL, 2, "rtcm3 1044 satellite number error: prn=%d\n", prn);
1428 return -1;
1429 }
1430 eph.sat = sat;
1431 eph.type = 0; /* ephemeris type = LNAV */
1432 eph.week = adjgpsweek(week);
1433 if (rtcm->time.time == 0) {
1434 rtcm->time = utc2gpst(timeget());
1435 }
1436 tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time);
1437 if (tt < -302400.0) {
1438 eph.week++;
1439 } else if (tt >= 302400.0) {
1440 eph.week--;
1441 }
1442 eph.toe = gpst2time(eph.week, eph.toes);
1443 eph.toc = gpst2time(eph.week, toc);
1444 eph.ttr = rtcm->time;
1445 eph.A = sqrtA * sqrtA;
1446 eph.flag = 1; /* fixed to 1 */
1447 if (!strstr(rtcm->opt, "-EPHALL")) {
1448 if (eph.iode == rtcm->nav.eph[sat - 1].iode && eph.iodc == rtcm->nav.eph[sat - 1].iodc) {
1449 return 0; /* unchanged */
1450 }
1451 }
1452 rtcm->nav.eph[sat - 1] = eph;
1453 rtcm->ephsat = sat;
1454 rtcm->ephset = 0;
1455 return 2;
1456}
1457/* decode type 1045: Galileo F/NAV satellite ephemerides ---------------------*/
1459 eph_t eph = {0};
1460 double toc, sqrtA, tt;
1461 char* msg;
1462 int i = 24 + 12, prn, sat, week, e5a_hs, e5a_dvs, rsv, sys = SYS_GAL;
1463
1464 if (strstr(rtcm->opt, "-GALINAV")) {
1465 return 0;
1466 }
1467
1468 if (i + 484 <= rtcm->len * 8) {
1469 prn = getbitu(rtcm->buff, i, 6);
1470 i += 6;
1471 week = getbitu(rtcm->buff, i, 12);
1472 i += 12; /* gst-week */
1473 eph.iode = getbitu(rtcm->buff, i, 10);
1474 i += 10;
1475 eph.sva = getbitu(rtcm->buff, i, 8);
1476 i += 8;
1477 eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD;
1478 i += 14;
1479 toc = getbitu(rtcm->buff, i, 14) * 60.0;
1480 i += 14;
1481 eph.f2 = getbits(rtcm->buff, i, 6) * P2_59;
1482 i += 6;
1483 eph.f1 = getbits(rtcm->buff, i, 21) * P2_46;
1484 i += 21;
1485 eph.f0 = getbits(rtcm->buff, i, 31) * P2_34;
1486 i += 31;
1487 eph.crs = getbits(rtcm->buff, i, 16) * P2_5;
1488 i += 16;
1489 eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD;
1490 i += 16;
1491 eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1492 i += 32;
1493 eph.cuc = getbits(rtcm->buff, i, 16) * P2_29;
1494 i += 16;
1495 eph.e = getbitu(rtcm->buff, i, 32) * P2_33;
1496 i += 32;
1497 eph.cus = getbits(rtcm->buff, i, 16) * P2_29;
1498 i += 16;
1499 sqrtA = getbitu(rtcm->buff, i, 32) * P2_19;
1500 i += 32;
1501 eph.toes = getbitu(rtcm->buff, i, 14) * 60.0;
1502 i += 14;
1503 eph.cic = getbits(rtcm->buff, i, 16) * P2_29;
1504 i += 16;
1505 eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1506 i += 32;
1507 eph.cis = getbits(rtcm->buff, i, 16) * P2_29;
1508 i += 16;
1509 eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1510 i += 32;
1511 eph.crc = getbits(rtcm->buff, i, 16) * P2_5;
1512 i += 16;
1513 eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1514 i += 32;
1515 eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD;
1516 i += 24;
1517 eph.tgd[0] = getbits(rtcm->buff, i, 10) * P2_32;
1518 i += 10; /* E5a/E1 */
1519 e5a_hs = getbitu(rtcm->buff, i, 2);
1520 i += 2; /* OSHS */
1521 e5a_dvs = getbitu(rtcm->buff, i, 1);
1522 i += 1; /* OSDVS */
1523 rsv = getbitu(rtcm->buff, i, 7);
1524 } else {
1525 trace(NULL, 2, "rtcm3 1045 length error: len=%d\n", rtcm->len);
1526 return -1;
1527 }
1528 trace(NULL, 4, "decode_type1045: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes);
1529
1530 if (rtcm->outtype) {
1531 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1532 sprintf(msg, " prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d dvs=%d", prn, eph.iode, week, eph.toes, toc,
1533 e5a_hs, e5a_dvs);
1534 }
1535 if (!(sat = satno(sys, prn))) {
1536 trace(NULL, 2, "rtcm3 1045 satellite number error: prn=%d\n", prn);
1537 return -1;
1538 }
1539 if (strstr(rtcm->opt, "-GALINAV")) {
1540 return 0;
1541 }
1542 eph.sat = sat;
1543 eph.type = 1; /* ephemeris type = F/NAV */
1544 eph.week = week + 1024; /* gal-week = gst-week + 1024 */
1545 if (rtcm->time.time == 0) {
1546 rtcm->time = utc2gpst(timeget());
1547 }
1548 tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time);
1549 if (tt < -302400.0) {
1550 eph.week++;
1551 } else if (tt >= 302400.0) {
1552 eph.week--;
1553 }
1554 eph.toe = gpst2time(eph.week, eph.toes);
1555 eph.toc = gpst2time(eph.week, toc);
1556 eph.ttr = rtcm->time;
1557 eph.A = sqrtA * sqrtA;
1558 eph.svh = (e5a_hs << 4) + (e5a_dvs << 3);
1559 eph.code = (1 << 1) + (1 << 8); /* data source = F/NAV+E5a */
1560 eph.iodc = eph.iode;
1561 if (!strstr(rtcm->opt, "-EPHALL")) {
1562 if (eph.iode == rtcm->nav.eph[sat - 1 + MAXSAT].iode) {
1563 return 0; /* unchanged */
1564 }
1565 }
1566 rtcm->nav.eph[sat - 1 + MAXSAT] = eph;
1567 rtcm->ephsat = sat;
1568 rtcm->ephset = 1; /* F/NAV */
1569 return 2;
1570}
1571/* decode type 1046: Galileo I/NAV satellite ephemerides ---------------------*/
1573 eph_t eph = {0};
1574 double toc, sqrtA, tt;
1575 char* msg;
1576 int i = 24 + 12, prn, sat, week, e5b_hs, e5b_dvs, e1_hs, e1_dvs, sys = SYS_GAL;
1577
1578 if (strstr(rtcm->opt, "-GALFNAV")) {
1579 return 0;
1580 }
1581
1582 if (i + 492 <= rtcm->len * 8) {
1583 prn = getbitu(rtcm->buff, i, 6);
1584 i += 6;
1585 week = getbitu(rtcm->buff, i, 12);
1586 i += 12;
1587 eph.iode = getbitu(rtcm->buff, i, 10);
1588 i += 10;
1589 eph.sva = getbitu(rtcm->buff, i, 8);
1590 i += 8;
1591 eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD;
1592 i += 14;
1593 toc = getbitu(rtcm->buff, i, 14) * 60.0;
1594 i += 14;
1595 eph.f2 = getbits(rtcm->buff, i, 6) * P2_59;
1596 i += 6;
1597 eph.f1 = getbits(rtcm->buff, i, 21) * P2_46;
1598 i += 21;
1599 eph.f0 = getbits(rtcm->buff, i, 31) * P2_34;
1600 i += 31;
1601 eph.crs = getbits(rtcm->buff, i, 16) * P2_5;
1602 i += 16;
1603 eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD;
1604 i += 16;
1605 eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1606 i += 32;
1607 eph.cuc = getbits(rtcm->buff, i, 16) * P2_29;
1608 i += 16;
1609 eph.e = getbitu(rtcm->buff, i, 32) * P2_33;
1610 i += 32;
1611 eph.cus = getbits(rtcm->buff, i, 16) * P2_29;
1612 i += 16;
1613 sqrtA = getbitu(rtcm->buff, i, 32) * P2_19;
1614 i += 32;
1615 eph.toes = getbitu(rtcm->buff, i, 14) * 60.0;
1616 i += 14;
1617 eph.cic = getbits(rtcm->buff, i, 16) * P2_29;
1618 i += 16;
1619 eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1620 i += 32;
1621 eph.cis = getbits(rtcm->buff, i, 16) * P2_29;
1622 i += 16;
1623 eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1624 i += 32;
1625 eph.crc = getbits(rtcm->buff, i, 16) * P2_5;
1626 i += 16;
1627 eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1628 i += 32;
1629 eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD;
1630 i += 24;
1631 eph.tgd[0] = getbits(rtcm->buff, i, 10) * P2_32;
1632 i += 10; /* E5a/E1 */
1633 eph.tgd[1] = getbits(rtcm->buff, i, 10) * P2_32;
1634 i += 10; /* E5b/E1 */
1635 e5b_hs = getbitu(rtcm->buff, i, 2);
1636 i += 2; /* E5b OSHS */
1637 e5b_dvs = getbitu(rtcm->buff, i, 1);
1638 i += 1; /* E5b OSDVS */
1639 e1_hs = getbitu(rtcm->buff, i, 2);
1640 i += 2; /* E1 OSHS */
1641 e1_dvs = getbitu(rtcm->buff, i, 1);
1642 i += 1; /* E1 OSDVS */
1643 } else {
1644 trace(NULL, 2, "rtcm3 1046 length error: len=%d\n", rtcm->len);
1645 return -1;
1646 }
1647 trace(NULL, 4, "decode_type1046: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes);
1648
1649 if (rtcm->outtype) {
1650 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1651 sprintf(msg, " prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d %d dvs=%d %d", prn, eph.iode, week, eph.toes,
1652 toc, e5b_hs, e1_hs, e5b_dvs, e1_dvs);
1653 }
1654 if (!(sat = satno(sys, prn))) {
1655 trace(NULL, 2, "rtcm3 1046 satellite number error: prn=%d\n", prn);
1656 return -1;
1657 }
1658 if (strstr(rtcm->opt, "-GALFNAV")) {
1659 return 0;
1660 }
1661 eph.sat = sat;
1662 eph.type = 0; /* ephemeris type = I/NAV */
1663 eph.week = week + 1024; /* gal-week = gst-week + 1024 */
1664 if (rtcm->time.time == 0) {
1665 rtcm->time = utc2gpst(timeget());
1666 }
1667 tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time);
1668 if (tt < -302400.0) {
1669 eph.week++;
1670 } else if (tt >= 302400.0) {
1671 eph.week--;
1672 }
1673 eph.toe = gpst2time(eph.week, eph.toes);
1674 eph.toc = gpst2time(eph.week, toc);
1675 eph.ttr = rtcm->time;
1676 eph.A = sqrtA * sqrtA;
1677 eph.svh = (e5b_hs << 7) + (e5b_dvs << 6) + (e1_hs << 1) + (e1_dvs << 0);
1678 eph.code = (1 << 0) + (1 << 2) + (1 << 9); /* data source = I/NAV+E1+E5b */
1679 eph.iodc = eph.iode;
1680 if (!strstr(rtcm->opt, "-EPHALL")) {
1681 if (eph.iode == rtcm->nav.eph[sat - 1].iode) {
1682 return 0; /* unchanged */
1683 }
1684 }
1685 rtcm->nav.eph[sat - 1] = eph;
1686 rtcm->ephsat = sat;
1687 rtcm->ephset = 0; /* I/NAV */
1688 return 2;
1689}
1690/* decode type 1042/63: Beidou ephemerides -----------------------------------*/
1692 eph_t eph = {0};
1693 double toc, sqrtA, tt;
1694 char* msg;
1695 int i = 24 + 12, prn, sat, week, sys = SYS_CMP;
1696
1697 if (i + 499 <= rtcm->len * 8) {
1698 prn = getbitu(rtcm->buff, i, 6);
1699 i += 6;
1700 week = getbitu(rtcm->buff, i, 13);
1701 i += 13;
1702 eph.sva = getbitu(rtcm->buff, i, 4);
1703 i += 4;
1704 eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD;
1705 i += 14;
1706 eph.iode = getbitu(rtcm->buff, i, 5);
1707 i += 5; /* AODE */
1708 toc = getbitu(rtcm->buff, i, 17) * 8.0;
1709 i += 17;
1710 eph.f2 = getbits(rtcm->buff, i, 11) * P2_66;
1711 i += 11;
1712 eph.f1 = getbits(rtcm->buff, i, 22) * P2_50;
1713 i += 22;
1714 eph.f0 = getbits(rtcm->buff, i, 24) * P2_33;
1715 i += 24;
1716 eph.iodc = getbitu(rtcm->buff, i, 5);
1717 i += 5; /* AODC */
1718 eph.crs = getbits(rtcm->buff, i, 18) * P2_6;
1719 i += 18;
1720 eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD;
1721 i += 16;
1722 eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1723 i += 32;
1724 eph.cuc = getbits(rtcm->buff, i, 18) * P2_31;
1725 i += 18;
1726 eph.e = getbitu(rtcm->buff, i, 32) * P2_33;
1727 i += 32;
1728 eph.cus = getbits(rtcm->buff, i, 18) * P2_31;
1729 i += 18;
1730 sqrtA = getbitu(rtcm->buff, i, 32) * P2_19;
1731 i += 32;
1732 eph.toes = getbitu(rtcm->buff, i, 17) * 8.0;
1733 i += 17;
1734 eph.cic = getbits(rtcm->buff, i, 18) * P2_31;
1735 i += 18;
1736 eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1737 i += 32;
1738 eph.cis = getbits(rtcm->buff, i, 18) * P2_31;
1739 i += 18;
1740 eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1741 i += 32;
1742 eph.crc = getbits(rtcm->buff, i, 18) * P2_6;
1743 i += 18;
1744 eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD;
1745 i += 32;
1746 eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD;
1747 i += 24;
1748 eph.tgd[0] = getbits(rtcm->buff, i, 10) * 1E-10;
1749 i += 10;
1750 eph.tgd[1] = getbits(rtcm->buff, i, 10) * 1E-10;
1751 i += 10;
1752 eph.svh = getbitu(rtcm->buff, i, 1);
1753 i += 1;
1754 } else {
1755 trace(NULL, 2, "rtcm3 1042 length error: len=%d\n", rtcm->len);
1756 return -1;
1757 }
1758 trace(NULL, 4, "decode_type1042: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes);
1759
1760 if (rtcm->outtype) {
1761 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1762 sprintf(msg, " prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, eph.iodc, week,
1763 eph.toes, toc, eph.svh);
1764 }
1765 if (!(sat = satno(sys, prn))) {
1766 trace(NULL, 2, "rtcm3 1042 satellite number error: prn=%d\n", prn);
1767 return -1;
1768 }
1769 eph.sat = sat;
1770 eph.type = (prn >= 6 && prn <= 58) ? 0 : 1; /* ephemeris type = D1 or D2 */
1771 eph.week = adjbdtweek(week);
1772 if (rtcm->time.time == 0) {
1773 rtcm->time = utc2gpst(timeget());
1774 }
1775 tt = timediff(bdt2gpst(bdt2time(eph.week, eph.toes)), rtcm->time);
1776 if (tt < -302400.0) {
1777 eph.week++;
1778 } else if (tt >= 302400.0) {
1779 eph.week--;
1780 }
1781 eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */
1782 eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */
1783 eph.ttr = rtcm->time;
1784 eph.A = sqrtA * sqrtA;
1785 if (!strstr(rtcm->opt, "-EPHALL")) {
1786 if (timediff(eph.toe, rtcm->nav.eph[sat - 1].toe) == 0.0 && eph.iode == rtcm->nav.eph[sat - 1].iode &&
1787 eph.iodc == rtcm->nav.eph[sat - 1].iodc) {
1788 return 0; /* unchanged */
1789 }
1790 }
1791 rtcm->nav.eph[sat - 1] = eph;
1792 rtcm->ephset = 0;
1793 rtcm->ephsat = sat;
1794 return 2;
1795}
1796/* decode SSR message epoch time ---------------------------------------------*/
1797static int decode_ssr_epoch(rtcm_t* rtcm, int sys, int subtype) {
1798 double tod, tow;
1799 int i = 24 + 12;
1800
1801 if (subtype == 0) { /* RTCM SSR */
1802
1803 if (sys == SYS_GLO) {
1804 tod = getbitu(rtcm->buff, i, 17);
1805 i += 17;
1806 adjday_glot(rtcm, tod);
1807 } else {
1808 tow = getbitu(rtcm->buff, i, 20);
1809 i += 20;
1810 adjweek(rtcm, tow);
1811 }
1812 } else { /* IGS SSR */
1813 i += 3 + 8;
1814 tow = getbitu(rtcm->buff, i, 20);
1815 i += 20;
1816 adjweek(rtcm, tow);
1817 }
1818 return i;
1819}
1820/* decode SSR 1,4 message header ---------------------------------------------*/
1821static int decode_ssr1_head(rtcm_t* rtcm, int sys, int subtype, int* sync, int* iod, double* udint, int* refd,
1822 int* hsize) {
1823 char *msg, tstr[64];
1824 int i = 24 + 12, nsat, udi, provid = 0, solid = 0, ns;
1825
1826 if (subtype == 0) { /* RTCM SSR */
1827 ns = (sys == SYS_QZS) ? 4 : 6;
1828 if (i + ((sys == SYS_GLO) ? 53 : 50 + ns) > rtcm->len * 8) {
1829 return -1;
1830 }
1831 } else { /* IGS SSR */
1832 ns = 6;
1833 if (i + 3 + 8 + 50 + ns > rtcm->len * 8) {
1834 return -1;
1835 }
1836 }
1837 i = decode_ssr_epoch(rtcm, sys, subtype);
1838 udi = getbitu(rtcm->buff, i, 4);
1839 i += 4;
1840 *sync = getbitu(rtcm->buff, i, 1);
1841 i += 1;
1842 if (subtype == 0) { /* RTCM SSR */
1843 *refd = getbitu(rtcm->buff, i, 1);
1844 i += 1; /* satellite ref datum */
1845 }
1846 *iod = getbitu(rtcm->buff, i, 4);
1847 i += 4; /* IOD SSR */
1848 provid = getbitu(rtcm->buff, i, 16);
1849 i += 16; /* provider ID */
1850 solid = getbitu(rtcm->buff, i, 4);
1851 i += 4; /* solution ID */
1852 if (subtype > 0) { /* IGS SSR */
1853 *refd = getbitu(rtcm->buff, i, 1);
1854 i += 1; /* global/regional CRS indicator */
1855 }
1856 nsat = getbitu(rtcm->buff, i, ns);
1857 i += ns;
1858 *udint = ssrudint[udi];
1859
1860 time2str(rtcm->time, tstr, 2);
1861 trace(NULL, 4,
1862 "decode_ssr1_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d"
1863 " provid=%d solid=%d\n",
1864 tstr, sys, subtype, nsat, *sync, *iod, provid, solid);
1865
1866 if (rtcm->outtype) {
1867 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1868 sprintf(msg, " %s nsat=%2d iod=%2d udi=%2d sync=%d", tstr, nsat, *iod, udi, *sync);
1869 }
1870 *hsize = i;
1871 return nsat;
1872}
1873/* decode SSR 2,3,5,6 message header -----------------------------------------*/
1874static int decode_ssr2_head(rtcm_t* rtcm, int sys, int subtype, int* sync, int* iod, double* udint, int* hsize) {
1875 char *msg, tstr[64];
1876 int i = 24 + 12, nsat, udi, provid = 0, solid = 0, ns;
1877
1878 if (subtype == 0) { /* RTCM SSR */
1879 ns = (sys == SYS_QZS) ? 4 : 6;
1880 if (i + ((sys == SYS_GLO) ? 52 : 49 + ns) > rtcm->len * 8) {
1881 return -1;
1882 }
1883 } else {
1884 ns = 6;
1885 if (i + 3 + 8 + 49 + ns > rtcm->len * 8) {
1886 return -1;
1887 }
1888 }
1889 i = decode_ssr_epoch(rtcm, sys, subtype);
1890 udi = getbitu(rtcm->buff, i, 4);
1891 i += 4;
1892 *sync = getbitu(rtcm->buff, i, 1);
1893 i += 1;
1894 *iod = getbitu(rtcm->buff, i, 4);
1895 i += 4;
1896 provid = getbitu(rtcm->buff, i, 16);
1897 i += 16; /* provider ID */
1898 solid = getbitu(rtcm->buff, i, 4);
1899 i += 4; /* solution ID */
1900 nsat = getbitu(rtcm->buff, i, ns);
1901 i += ns;
1902 *udint = ssrudint[udi];
1903
1904 time2str(rtcm->time, tstr, 2);
1905 trace(NULL, 4,
1906 "decode_ssr2_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d"
1907 " provid=%d solid=%d\n",
1908 tstr, sys, subtype, nsat, *sync, *iod, provid, solid);
1909
1910 if (rtcm->outtype) {
1911 msg = rtcm->msgtype + strlen(rtcm->msgtype);
1912 sprintf(msg, " %s nsat=%2d iod=%2d udi=%2d sync=%d", tstr, nsat, *iod, udi, *sync);
1913 }
1914 *hsize = i;
1915 return nsat;
1916}
1917/* decode SSR 1: orbit corrections -------------------------------------------*/
1918static int decode_ssr1(rtcm_t* rtcm, int sys, int subtype) {
1919 double udint, deph[3], ddeph[3];
1920 int i, j, k, type, sync, iod, nsat, prn, sat, iode, iodcrc = 0, refd = 0, np, ni, nj, offp;
1921
1922 type = getbitu(rtcm->buff, 24, 12);
1923
1924 if ((nsat = decode_ssr1_head(rtcm, sys, subtype, &sync, &iod, &udint, &refd, &i)) < 0) {
1925 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
1926 return -1;
1927 }
1928 switch (sys) {
1929 case SYS_GPS:
1930 np = 6;
1931 ni = 8;
1932 nj = 0;
1933 offp = 0;
1934 break;
1935 case SYS_GLO:
1936 np = 5;
1937 ni = 8;
1938 nj = 0;
1939 offp = 0;
1940 break;
1941 case SYS_GAL:
1942 np = 6;
1943 ni = 10;
1944 nj = 0;
1945 offp = 0;
1946 break;
1947 case SYS_QZS:
1948 np = 4;
1949 ni = 8;
1950 nj = 0;
1951 offp = 192;
1952 break;
1953 case SYS_CMP:
1954 np = 6;
1955 ni = 10;
1956 nj = 24;
1957 offp = 1;
1958 break;
1959 case SYS_SBS:
1960 np = 6;
1961 ni = 9;
1962 nj = 24;
1963 offp = 120;
1964 break;
1965 default:
1966 return sync ? 0 : 10;
1967 }
1968 if (subtype > 0) { /* IGS SSR */
1969 np = 6;
1970 ni = 8;
1971 nj = 0;
1972 if (sys == SYS_CMP) {
1973 offp = 0;
1974 } else if (sys == SYS_SBS) {
1975 offp = 119;
1976 }
1977 }
1978 for (j = 0; j < nsat && i + 121 + np + ni + nj <= rtcm->len * 8; j++) {
1979 prn = getbitu(rtcm->buff, i, np) + offp;
1980 i += np;
1981 iode = getbitu(rtcm->buff, i, ni);
1982 i += ni;
1983 if (sys == SYS_CMP) {
1984 iode *= 8;
1985 }
1986 iodcrc = getbitu(rtcm->buff, i, nj);
1987 i += nj;
1988 deph[0] = getbits(rtcm->buff, i, 22) * 1E-4;
1989 i += 22;
1990 deph[1] = getbits(rtcm->buff, i, 20) * 4E-4;
1991 i += 20;
1992 deph[2] = getbits(rtcm->buff, i, 20) * 4E-4;
1993 i += 20;
1994 ddeph[0] = getbits(rtcm->buff, i, 21) * 1E-6;
1995 i += 21;
1996 ddeph[1] = getbits(rtcm->buff, i, 19) * 4E-6;
1997 i += 19;
1998 ddeph[2] = getbits(rtcm->buff, i, 19) * 4E-6;
1999 i += 19;
2000
2001 if (!(sat = satno(sys, prn))) {
2002 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2003 continue;
2004 }
2005 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2006 rtcm->ssr[sat - 1].t0[0] = rtcm->time;
2007 rtcm->ssr[sat - 1].udi[0] = udint;
2008 rtcm->ssr[sat - 1].iod[0] = iod;
2009 rtcm->ssr[sat - 1].iode = iode; /* SBAS/BDS: toe/t0 modulo */
2010 rtcm->ssr[sat - 1].iodcrc = iodcrc; /* SBAS/BDS: IOD CRC */
2011 rtcm->ssr[sat - 1].refd = refd;
2012
2013 for (k = 0; k < 3; k++) {
2014 rtcm->ssr[sat - 1].deph[k] = deph[k];
2015 rtcm->ssr[sat - 1].ddeph[k] = ddeph[k];
2016 }
2017 rtcm->ssr[sat - 1].update = 1;
2018 }
2019 return sync ? 0 : 10;
2020}
2021/* decode SSR 2: clock corrections -------------------------------------------*/
2022static int decode_ssr2(rtcm_t* rtcm, int sys, int subtype) {
2023 double udint, dclk[3];
2024 int i, j, k, type, sync, iod, nsat, prn, sat, np, offp;
2025
2026 type = getbitu(rtcm->buff, 24, 12);
2027
2028 if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) {
2029 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2030 return -1;
2031 }
2032 switch (sys) {
2033 case SYS_GPS:
2034 np = 6;
2035 offp = 0;
2036 break;
2037 case SYS_GLO:
2038 np = 5;
2039 offp = 0;
2040 break;
2041 case SYS_GAL:
2042 np = 6;
2043 offp = 0;
2044 break;
2045 case SYS_QZS:
2046 np = 4;
2047 offp = 192;
2048 break;
2049 case SYS_CMP:
2050 np = 6;
2051 offp = 1;
2052 break;
2053 case SYS_SBS:
2054 np = 6;
2055 offp = 120;
2056 break;
2057 default:
2058 return sync ? 0 : 10;
2059 }
2060 if (subtype > 0) { /* IGS SSR */
2061 np = 6;
2062 if (sys == SYS_CMP) {
2063 offp = 0;
2064 } else if (sys == SYS_SBS) {
2065 offp = 119;
2066 }
2067 }
2068 for (j = 0; j < nsat && i + 70 + np <= rtcm->len * 8; j++) {
2069 prn = getbitu(rtcm->buff, i, np) + offp;
2070 i += np;
2071 dclk[0] = getbits(rtcm->buff, i, 22) * 1E-4;
2072 i += 22;
2073 dclk[1] = getbits(rtcm->buff, i, 21) * 1E-6;
2074 i += 21;
2075 dclk[2] = getbits(rtcm->buff, i, 27) * 2E-8;
2076 i += 27;
2077
2078 if (!(sat = satno(sys, prn))) {
2079 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2080 continue;
2081 }
2082 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2083 rtcm->ssr[sat - 1].t0[1] = rtcm->time;
2084 rtcm->ssr[sat - 1].udi[1] = udint;
2085 rtcm->ssr[sat - 1].iod[1] = iod;
2086
2087 for (k = 0; k < 3; k++) {
2088 rtcm->ssr[sat - 1].dclk[k] = dclk[k];
2089 }
2090 rtcm->ssr[sat - 1].update = 1;
2091 }
2092 return sync ? 0 : 10;
2093}
2094/* decode SSR 3: satellite code biases ---------------------------------------*/
2095static int decode_ssr3(rtcm_t* rtcm, int sys, int subtype) {
2096 const uint8_t* sigs;
2097 double udint, bias, cbias[MAXCODE];
2098 int i, j, k, type, mode, sync, iod, nsat, prn, sat, nbias, np, offp;
2099 int vcbias[MAXCODE] = {0};
2100
2101 type = getbitu(rtcm->buff, 24, 12);
2102
2103 if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) {
2104 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2105 return -1;
2106 }
2107 switch (sys) {
2108 case SYS_GPS:
2109 np = 6;
2110 offp = 0;
2111 sigs = ssr_sig_gps;
2112 break;
2113 case SYS_GLO:
2114 np = 5;
2115 offp = 0;
2116 sigs = ssr_sig_glo;
2117 break;
2118 case SYS_GAL:
2119 np = 6;
2120 offp = 0;
2121 sigs = ssr_sig_gal;
2122 break;
2123 case SYS_QZS:
2124 np = 4;
2125 offp = 192;
2126 sigs = ssr_sig_qzs;
2127 break;
2128 case SYS_CMP:
2129 np = 6;
2130 offp = 1;
2131 sigs = ssr_sig_cmp;
2132 break;
2133 case SYS_SBS:
2134 np = 6;
2135 offp = 120;
2136 sigs = ssr_sig_sbs;
2137 break;
2138 default:
2139 return sync ? 0 : 10;
2140 }
2141 if (subtype > 0) { /* IGS SSR */
2142 np = 6;
2143 if (sys == SYS_CMP) {
2144 offp = 0;
2145 } else if (sys == SYS_SBS) {
2146 offp = 119;
2147 }
2148 }
2149 for (j = 0; j < nsat && i + 5 + np <= rtcm->len * 8; j++) {
2150 prn = getbitu(rtcm->buff, i, np) + offp;
2151 i += np;
2152 nbias = getbitu(rtcm->buff, i, 5);
2153 i += 5;
2154
2155 for (k = 0; k < MAXCODE; k++) {
2156 cbias[k] = 0.0;
2157 vcbias[k] = 0;
2158 }
2159 for (k = 0; k < nbias && i + 19 <= rtcm->len * 8; k++) {
2160 mode = getbitu(rtcm->buff, i, 5);
2161 i += 5;
2162 bias = getbits(rtcm->buff, i, 14) * 0.01;
2163 i += 14;
2164 if (sigs[mode]) {
2165 cbias[sigs[mode] - 1] = (float)bias;
2166 vcbias[sigs[mode] - 1] = 1; /* 1:output */
2167 } else {
2168 trace(NULL, 2, "rtcm3 %d not supported mode: mode=%d\n", type, mode);
2169 }
2170 }
2171 if (!(sat = satno(sys, prn))) {
2172 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2173 continue;
2174 }
2175 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2176 rtcm->ssr[sat - 1].t0[4] = rtcm->time;
2177 rtcm->ssr[sat - 1].udi[4] = udint;
2178 rtcm->ssr[sat - 1].iod[4] = iod;
2179
2180 for (k = 0; k < MAXCODE; k++) {
2181 rtcm->ssr[sat - 1].cbias[k] = (float)cbias[k];
2182 rtcm->ssr[sat - 1].vcbias[k] = vcbias[k];
2183 }
2184 rtcm->ssr[sat - 1].update = 1;
2185 }
2186 return sync ? 0 : 10;
2187}
2188/* decode SSR 4: combined orbit and clock corrections ------------------------*/
2189static int decode_ssr4(rtcm_t* rtcm, int sys, int subtype) {
2190 double udint, deph[3], ddeph[3], dclk[3];
2191 int i, j, k, type, nsat, sync, iod, prn, sat, iode, iodcrc = 0, refd = 0, np, ni, nj, offp;
2192
2193 type = getbitu(rtcm->buff, 24, 12);
2194
2195 if ((nsat = decode_ssr1_head(rtcm, sys, subtype, &sync, &iod, &udint, &refd, &i)) < 0) {
2196 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2197 return -1;
2198 }
2199 switch (sys) {
2200 case SYS_GPS:
2201 np = 6;
2202 ni = 8;
2203 nj = 0;
2204 offp = 0;
2205 break;
2206 case SYS_GLO:
2207 np = 5;
2208 ni = 8;
2209 nj = 0;
2210 offp = 0;
2211 break;
2212 case SYS_GAL:
2213 np = 6;
2214 ni = 10;
2215 nj = 0;
2216 offp = 0;
2217 break;
2218 case SYS_QZS:
2219 np = 4;
2220 ni = 8;
2221 nj = 0;
2222 offp = 192;
2223 break;
2224 case SYS_CMP:
2225 np = 6;
2226 ni = 10;
2227 nj = 24;
2228 offp = 1;
2229 break;
2230 case SYS_SBS:
2231 np = 6;
2232 ni = 9;
2233 nj = 24;
2234 offp = 120;
2235 break;
2236 default:
2237 return sync ? 0 : 10;
2238 }
2239 if (subtype > 0) { /* IGS SSR */
2240 np = 6;
2241 ni = 8;
2242 nj = 0;
2243 if (sys == SYS_CMP) {
2244 offp = 0;
2245 } else if (sys == SYS_SBS) {
2246 offp = 119;
2247 }
2248 }
2249 for (j = 0; j < nsat && i + 191 + np + ni + nj <= rtcm->len * 8; j++) {
2250 prn = getbitu(rtcm->buff, i, np) + offp;
2251 i += np;
2252 iode = getbitu(rtcm->buff, i, ni);
2253 i += ni;
2254 iodcrc = getbitu(rtcm->buff, i, nj);
2255 i += nj;
2256 deph[0] = getbits(rtcm->buff, i, 22) * 1E-4;
2257 i += 22;
2258 deph[1] = getbits(rtcm->buff, i, 20) * 4E-4;
2259 i += 20;
2260 deph[2] = getbits(rtcm->buff, i, 20) * 4E-4;
2261 i += 20;
2262 ddeph[0] = getbits(rtcm->buff, i, 21) * 1E-6;
2263 i += 21;
2264 ddeph[1] = getbits(rtcm->buff, i, 19) * 4E-6;
2265 i += 19;
2266 ddeph[2] = getbits(rtcm->buff, i, 19) * 4E-6;
2267 i += 19;
2268
2269 dclk[0] = getbits(rtcm->buff, i, 22) * 1E-4;
2270 i += 22;
2271 dclk[1] = getbits(rtcm->buff, i, 21) * 1E-6;
2272 i += 21;
2273 dclk[2] = getbits(rtcm->buff, i, 27) * 2E-8;
2274 i += 27;
2275
2276 if (!(sat = satno(sys, prn))) {
2277 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2278 continue;
2279 }
2280 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2281 rtcm->ssr[sat - 1].t0[0] = rtcm->ssr[sat - 1].t0[1] = rtcm->time;
2282 rtcm->ssr[sat - 1].udi[0] = rtcm->ssr[sat - 1].udi[1] = udint;
2283 rtcm->ssr[sat - 1].iod[0] = rtcm->ssr[sat - 1].iod[1] = iod;
2284 rtcm->ssr[sat - 1].iode = iode;
2285 rtcm->ssr[sat - 1].iodcrc = iodcrc;
2286 rtcm->ssr[sat - 1].refd = refd;
2287
2288 for (k = 0; k < 3; k++) {
2289 rtcm->ssr[sat - 1].deph[k] = deph[k];
2290 rtcm->ssr[sat - 1].ddeph[k] = ddeph[k];
2291 rtcm->ssr[sat - 1].dclk[k] = dclk[k];
2292 }
2293 rtcm->ssr[sat - 1].update = 1;
2294 }
2295 return sync ? 0 : 10;
2296}
2297/* decode SSR 5: URA ---------------------------------------------------------*/
2298static int decode_ssr5(rtcm_t* rtcm, int sys, int subtype) {
2299 double udint;
2300 int i, j, type, nsat, sync, iod, prn, sat, ura, np, offp;
2301
2302 type = getbitu(rtcm->buff, 24, 12);
2303
2304 if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) {
2305 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2306 return -1;
2307 }
2308 switch (sys) {
2309 case SYS_GPS:
2310 np = 6;
2311 offp = 0;
2312 break;
2313 case SYS_GLO:
2314 np = 5;
2315 offp = 0;
2316 break;
2317 case SYS_GAL:
2318 np = 6;
2319 offp = 0;
2320 break;
2321 case SYS_QZS:
2322 np = 4;
2323 offp = 192;
2324 break;
2325 case SYS_CMP:
2326 np = 6;
2327 offp = 1;
2328 break;
2329 case SYS_SBS:
2330 np = 6;
2331 offp = 120;
2332 break;
2333 default:
2334 return sync ? 0 : 10;
2335 }
2336 if (subtype > 0) { /* IGS SSR */
2337 np = 6;
2338 if (sys == SYS_CMP) {
2339 offp = 0;
2340 } else if (sys == SYS_SBS) {
2341 offp = 119;
2342 }
2343 }
2344 for (j = 0; j < nsat && i + 6 + np <= rtcm->len * 8; j++) {
2345 prn = getbitu(rtcm->buff, i, np) + offp;
2346 i += np;
2347 ura = getbitu(rtcm->buff, i, 6);
2348 i += 6;
2349
2350 if (!(sat = satno(sys, prn))) {
2351 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2352 continue;
2353 }
2354 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2355 rtcm->ssr[sat - 1].t0[3] = rtcm->time;
2356 rtcm->ssr[sat - 1].udi[3] = udint;
2357 rtcm->ssr[sat - 1].iod[3] = iod;
2358 rtcm->ssr[sat - 1].ura = ura;
2359 rtcm->ssr[sat - 1].update = 1;
2360 }
2361 return sync ? 0 : 10;
2362}
2363/* decode SSR 6: high rate clock correction ----------------------------------*/
2364static int decode_ssr6(rtcm_t* rtcm, int sys, int subtype) {
2365 double udint, hrclk;
2366 int i, j, type, nsat, sync, iod, prn, sat, np, offp;
2367
2368 type = getbitu(rtcm->buff, 24, 12);
2369
2370 if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) {
2371 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2372 return -1;
2373 }
2374 switch (sys) {
2375 case SYS_GPS:
2376 np = 6;
2377 offp = 0;
2378 break;
2379 case SYS_GLO:
2380 np = 5;
2381 offp = 0;
2382 break;
2383 case SYS_GAL:
2384 np = 6;
2385 offp = 0;
2386 break;
2387 case SYS_QZS:
2388 np = 4;
2389 offp = 192;
2390 break;
2391 case SYS_CMP:
2392 np = 6;
2393 offp = 1;
2394 break;
2395 case SYS_SBS:
2396 np = 6;
2397 offp = 120;
2398 break;
2399 default:
2400 return sync ? 0 : 10;
2401 }
2402 if (subtype > 0) { /* IGS SSR */
2403 np = 6;
2404 if (sys == SYS_CMP) {
2405 offp = 0;
2406 } else if (sys == SYS_SBS) {
2407 offp = 119;
2408 }
2409 }
2410 for (j = 0; j < nsat && i + 22 + np <= rtcm->len * 8; j++) {
2411 prn = getbitu(rtcm->buff, i, np) + offp;
2412 i += np;
2413 hrclk = getbits(rtcm->buff, i, 22) * 1E-4;
2414 i += 22;
2415
2416 if (!(sat = satno(sys, prn))) {
2417 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2418 continue;
2419 }
2420 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2421 rtcm->ssr[sat - 1].t0[2] = rtcm->time;
2422 rtcm->ssr[sat - 1].udi[2] = udint;
2423 rtcm->ssr[sat - 1].iod[2] = iod;
2424 rtcm->ssr[sat - 1].hrclk = hrclk;
2425 rtcm->ssr[sat - 1].update = 1;
2426 }
2427 return sync ? 0 : 10;
2428}
2429/* decode SSR 7 message header -----------------------------------------------*/
2430static int decode_ssr7_head(rtcm_t* rtcm, int sys, int subtype, int* sync, int* iod, double* udint, int* dispe, int* mw,
2431 int* hsize) {
2432 char *msg, tstr[64];
2433 int i = 24 + 12, nsat, udi, provid = 0, solid = 0, ns;
2434
2435 if (subtype == 0) { /* RTCM SSR */
2436 ns = (sys == SYS_QZS) ? 4 : 6;
2437 if (i + ((sys == SYS_GLO) ? 54 : 51 + ns) > rtcm->len * 8) {
2438 return -1;
2439 }
2440 } else { /* IGS SSR */
2441 ns = 6;
2442 if (i + 3 + 8 + 51 + ns > rtcm->len * 8) {
2443 return -1;
2444 }
2445 }
2446 i = decode_ssr_epoch(rtcm, sys, subtype);
2447 udi = getbitu(rtcm->buff, i, 4);
2448 i += 4;
2449 *sync = getbitu(rtcm->buff, i, 1);
2450 i += 1;
2451 *iod = getbitu(rtcm->buff, i, 4);
2452 i += 4;
2453 provid = getbitu(rtcm->buff, i, 16);
2454 i += 16; /* provider ID */
2455 solid = getbitu(rtcm->buff, i, 4);
2456 i += 4; /* solution ID */
2457 *dispe = getbitu(rtcm->buff, i, 1);
2458 i += 1; /* dispersive bias consistency ind */
2459 *mw = getbitu(rtcm->buff, i, 1);
2460 i += 1; /* MW consistency indicator */
2461 nsat = getbitu(rtcm->buff, i, ns);
2462 i += ns;
2463 *udint = ssrudint[udi];
2464
2465 time2str(rtcm->time, tstr, 2);
2466 trace(NULL, 4,
2467 "decode_ssr7_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d"
2468 " provid=%d solid=%d\n",
2469 tstr, sys, subtype, nsat, *sync, *iod, provid, solid);
2470
2471 if (rtcm->outtype) {
2472 msg = rtcm->msgtype + strlen(rtcm->msgtype);
2473 sprintf(msg, " %s nsat=%2d iod=%2d udi=%2d sync=%d", tstr, nsat, *iod, udi, *sync);
2474 }
2475 *hsize = i;
2476 return nsat;
2477}
2478/* decode SSR 7: phase bias --------------------------------------------------*/
2479static int decode_ssr7(rtcm_t* rtcm, int sys, int subtype) {
2480 const uint8_t* sigs;
2481 double udint, bias, std = 0.0, pbias[MAXCODE], stdpb[MAXCODE];
2482 int i, j, k, type, mode, sync, iod, nsat, prn, sat, nbias, np, mw, offp, sii, swl;
2483 int dispe, sdc, yaw_ang, yaw_rate;
2484 int vpbias[MAXCODE] = {0}, discnt[MAXCODE] = {0};
2485
2486 type = getbitu(rtcm->buff, 24, 12);
2487
2488 if ((nsat = decode_ssr7_head(rtcm, sys, subtype, &sync, &iod, &udint, &dispe, &mw, &i)) < 0) {
2489 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2490 return -1;
2491 }
2492 switch (sys) {
2493 case SYS_GPS:
2494 np = 6;
2495 offp = 0;
2496 sigs = ssr_sig_gps;
2497 break;
2498 case SYS_GLO:
2499 np = 5;
2500 offp = 0;
2501 sigs = ssr_sig_glo;
2502 break;
2503 case SYS_GAL:
2504 np = 6;
2505 offp = 0;
2506 sigs = ssr_sig_gal;
2507 break;
2508 case SYS_QZS:
2509 np = 4;
2510 offp = 192;
2511 sigs = ssr_sig_qzs;
2512 break;
2513 case SYS_CMP:
2514 np = 6;
2515 offp = 1;
2516 sigs = ssr_sig_cmp;
2517 break;
2518 default:
2519 return sync ? 0 : 10;
2520 }
2521 if (subtype > 0) { /* IGS SSR */
2522 np = 6;
2523 if (sys == SYS_CMP) {
2524 offp = 0;
2525 } else if (sys == SYS_SBS) {
2526 offp = 119;
2527 }
2528 }
2529 for (j = 0; j < nsat && i + 5 + 17 + np <= rtcm->len * 8; j++) {
2530 prn = getbitu(rtcm->buff, i, np) + offp;
2531 i += np;
2532 nbias = getbitu(rtcm->buff, i, 5);
2533 i += 5;
2534 yaw_ang = getbitu(rtcm->buff, i, 9);
2535 i += 9;
2536 yaw_rate = getbits(rtcm->buff, i, 8);
2537 i += 8;
2538
2539 for (k = 0; k < MAXCODE; k++) {
2540 pbias[k] = stdpb[k] = 0.0;
2541 discnt[k] = vpbias[k] = 0;
2542 }
2543 for (k = 0; k < nbias && i + ((subtype == 0) ? 49 : 32) <= rtcm->len * 8; k++) {
2544 mode = getbitu(rtcm->buff, i, 5);
2545 i += 5;
2546 sii = getbitu(rtcm->buff, i, 1);
2547 i += 1; /* integer-indicator */
2548 swl = getbitu(rtcm->buff, i, 2);
2549 i += 2; /* WL integer-indicator */
2550 sdc = getbitu(rtcm->buff, i, 4);
2551 i += 4; /* discontinuity counter */
2552 bias = getbits(rtcm->buff, i, 20);
2553 i += 20; /* phase bias (m) */
2554 if (subtype == 0) {
2555 std = getbitu(rtcm->buff, i, 17);
2556 i += 17; /* phase bias std-dev (m) */
2557 }
2558 if (sigs[mode]) {
2559 pbias[sigs[mode] - 1] = bias * 0.0001; /* (m) */
2560 stdpb[sigs[mode] - 1] = std * 0.0001; /* (m) */
2561 discnt[sigs[mode] - 1] = sdc;
2562 vpbias[sigs[mode] - 1] = 1; /* 1:output */
2563 } else {
2564 trace(NULL, 2, "rtcm3 %d not supported mode: mode=%d\n", type, mode);
2565 }
2566 }
2567 if (!(sat = satno(sys, prn))) {
2568 trace(NULL, 2, "rtcm3 %d satellite number error: prn=%d\n", type, prn);
2569 continue;
2570 }
2571 rtcm->ssr[sat - 1].vendor = SSR_VENDOR_RTCM;
2572 rtcm->ssr[sat - 1].t0[5] = rtcm->time;
2573 rtcm->ssr[sat - 1].udi[5] = udint;
2574 rtcm->ssr[sat - 1].iod[5] = iod;
2575 rtcm->ssr[sat - 1].yaw_ang = yaw_ang / 256.0 * 180.0; /* (deg) */
2576 rtcm->ssr[sat - 1].yaw_rate = yaw_rate / 8192.0 * 180.0; /* (deg/s) */
2577
2578 for (k = 0; k < MAXCODE; k++) {
2579 rtcm->ssr[sat - 1].pbias[k] = pbias[k];
2580 rtcm->ssr[sat - 1].stdpb[k] = (float)stdpb[k];
2581 rtcm->ssr[sat - 1].vpbias[k] = vpbias[k];
2582 rtcm->ssr[sat - 1].discnt[k] = discnt[k];
2583 }
2584 }
2585 return sync ? 0 : 10;
2586}
2587/* get signal index ----------------------------------------------------------*/
2588static void sigindex(int sys, const uint8_t* code, int n, const char* opt, int* idx) {
2589 int i, nex, pri, pri_h[8] = {0}, index[8] = {0}, ex[32] = {0};
2590
2591 /* test code priority */
2592 for (i = 0; i < n; i++) {
2593 if (!code[i]) {
2594 continue;
2595 }
2596
2597 if (idx[i] >= NFREQ) { /* save as extended signal if idx >= NFREQ */
2598 ex[i] = 1;
2599 continue;
2600 }
2601 /* code priority */
2602 pri = getcodepri(sys, code[i], opt);
2603
2604 /* select highest priority signal */
2605 if (pri > pri_h[idx[i]]) {
2606 if (index[idx[i]]) {
2607 ex[index[idx[i]] - 1] = 1;
2608 }
2609 pri_h[idx[i]] = pri;
2610 index[idx[i]] = i + 1;
2611 } else {
2612 ex[i] = 1;
2613 }
2614 }
2615 /* signal index in obs data */
2616 for (i = nex = 0; i < n; i++) {
2617 if (ex[i] == 0) {
2618 /* primary signal: index already assigned */
2619 } else if (nex < NEXOBS) {
2620 idx[i] = NFREQ + nex++;
2621 } else { /* no space in obs data */
2622 trace(NULL, 2, "rtcm msm: no space in obs data sys=%d code=%d\n", sys, code[i]);
2623 idx[i] = -1;
2624 }
2625#if 0 /* for debug */
2626 trace(NULL,2,"sig pos: sys=%d code=%d ex=%d idx=%d\n",sys,code[i],ex[i],idx[i]);
2627#endif
2628 }
2629}
2630/* save obs data in MSM message ----------------------------------------------*/
2631static void save_msm_obs(rtcm_t* rtcm, int sys, msm_h_t* h, const double* r, const double* pr, const double* cp,
2632 const double* rr, const double* rrf, const double* cnr, const int* lock, const int* ex,
2633 const int* half) {
2634 const char* sig[32];
2635 double tt, freq;
2636 uint8_t code[32];
2637 char *msm_type = "", *q = NULL;
2638 int i, j, k, type, prn, sat, fcn, index = 0, idx[32];
2639
2640 type = getbitu(rtcm->buff, 24, 12);
2641
2642 switch (sys) {
2643 case SYS_GPS:
2644 msm_type = q = rtcm->msmtype[0];
2645 break;
2646 case SYS_GLO:
2647 msm_type = q = rtcm->msmtype[1];
2648 break;
2649 case SYS_GAL:
2650 msm_type = q = rtcm->msmtype[2];
2651 break;
2652 case SYS_QZS:
2653 msm_type = q = rtcm->msmtype[3];
2654 break;
2655 case SYS_SBS:
2656 msm_type = q = rtcm->msmtype[4];
2657 break;
2658 case SYS_CMP:
2659 msm_type = q = rtcm->msmtype[5];
2660 break;
2661 case SYS_IRN:
2662 msm_type = q = rtcm->msmtype[6];
2663 break;
2664 }
2665 /* id to signal */
2666 for (i = 0; i < h->nsig; i++) {
2667 switch (sys) {
2668 case SYS_GPS:
2669 sig[i] = msm_sig_gps[h->sigs[i] - 1];
2670 break;
2671 case SYS_GLO:
2672 sig[i] = msm_sig_glo[h->sigs[i] - 1];
2673 break;
2674 case SYS_GAL:
2675 sig[i] = msm_sig_gal[h->sigs[i] - 1];
2676 break;
2677 case SYS_QZS:
2678 sig[i] = msm_sig_qzs[h->sigs[i] - 1];
2679 break;
2680 case SYS_SBS:
2681 sig[i] = msm_sig_sbs[h->sigs[i] - 1];
2682 break;
2683 case SYS_CMP:
2684 sig[i] = msm_sig_cmp[h->sigs[i] - 1];
2685 break;
2686 case SYS_IRN:
2687 sig[i] = msm_sig_irn[h->sigs[i] - 1];
2688 break;
2689 default:
2690 sig[i] = "";
2691 break;
2692 }
2693 /* signal to rinex obs type */
2694 code[i] = obs2code(sig[i]);
2695 idx[i] = code2freq_idx(sys, code[i]);
2696
2697 if (code[i] != CODE_NONE) {
2698 if (q) {
2699 q += sprintf(q, "L%s%s", sig[i], i < h->nsig - 1 ? "," : "");
2700 }
2701 } else {
2702 if (q) {
2703 q += sprintf(q, "(%d)%s", h->sigs[i], i < h->nsig - 1 ? "," : "");
2704 }
2705
2706 trace(NULL, 2, "rtcm3 %d: unknown signal id=%2d\n", type, h->sigs[i]);
2707 }
2708 }
2709 trace(NULL, 3, "rtcm3 %d: signals=%s\n", type, msm_type);
2710
2711 /* get signal index */
2712 sigindex(sys, code, h->nsig, rtcm->opt, idx);
2713
2714 for (i = j = 0; i < h->nsat; i++) {
2715 prn = h->sats[i];
2716 if (sys == SYS_QZS) {
2717 prn += MINPRNQZS - 1;
2718 } else if (sys == SYS_SBS) {
2719 prn += MINPRNSBS - 1;
2720 }
2721
2722 if ((sat = satno(sys, prn))) {
2723 tt = timediff(rtcm->obs.data[0].time, rtcm->time);
2724 if (rtcm->obsflag || fabs(tt) > 1E-9) {
2725 rtcm->obs.n = rtcm->obsflag = 0;
2726 }
2727 index = obsindex(&rtcm->obs, rtcm->time, sat);
2728 } else {
2729 trace(NULL, 2, "rtcm3 %d satellite error: prn=%d\n", type, prn);
2730 }
2731 fcn = 0;
2732 if (sys == SYS_GLO) {
2733 fcn = -8; /* no glonass fcn info */
2734 if (ex && ex[i] <= 13) {
2735 fcn = ex[i] - 7;
2736 if (!rtcm->nav.glo_fcn[prn - 1]) {
2737 rtcm->nav.glo_fcn[prn - 1] = fcn + 8; /* fcn+8 */
2738 }
2739 } else if (rtcm->nav.geph[prn - 1].sat == sat) {
2740 fcn = rtcm->nav.geph[prn - 1].frq;
2741 } else if (rtcm->nav.glo_fcn[prn - 1] > 0) {
2742 fcn = rtcm->nav.glo_fcn[prn - 1] - 8;
2743 }
2744 }
2745 for (k = 0; k < h->nsig; k++) {
2746 if (!h->cellmask[k + i * h->nsig]) {
2747 continue;
2748 }
2749
2750 if (sat && index >= 0 && idx[k] >= 0) {
2751 freq = fcn < -7 ? 0.0 : code2freq(sys, code[k], fcn);
2752
2753 /* pseudorange (m) */
2754 if (r[i] != 0.0 && pr[j] > -1E12) {
2755 rtcm->obs.data[index].P[idx[k]] = r[i] + pr[j];
2756 }
2757 /* carrier-phase (cycle) */
2758 if (r[i] != 0.0 && cp[j] > -1E12) {
2759 rtcm->obs.data[index].L[idx[k]] = (r[i] + cp[j]) * freq / CLIGHT;
2760 }
2761 /* doppler (hz) */
2762 if (rr && rrf && rrf[j] > -1E12) {
2763 rtcm->obs.data[index].D[idx[k]] = (float)(-(rr[i] + rrf[j]) * freq / CLIGHT);
2764 }
2765 rtcm->obs.data[index].LLI[idx[k]] = lossoflock(rtcm, sat, idx[k], lock[j]) + (half[j] ? 3 : 0);
2766 rtcm->obs.data[index].SNR[idx[k]] = (uint16_t)(cnr[j] / SNR_UNIT + 0.5);
2767 rtcm->obs.data[index].code[idx[k]] = code[k];
2768 }
2769 j++;
2770 }
2771 }
2772}
2773/* decode type MSM message header --------------------------------------------*/
2774static int decode_msm_head(rtcm_t* rtcm, int sys, int* sync, int* iod, msm_h_t* h, int* hsize) {
2775 msm_h_t h0 = {0};
2776 double tow, tod;
2777 char *msg, tstr[64];
2778 int i = 24, j, dow, mask, staid, type, ncell = 0;
2779
2780 type = getbitu(rtcm->buff, i, 12);
2781 i += 12;
2782
2783 *h = h0;
2784 if (i + 157 <= rtcm->len * 8) {
2785 staid = getbitu(rtcm->buff, i, 12);
2786 i += 12;
2787
2788 if (sys == SYS_GLO) {
2789 dow = getbitu(rtcm->buff, i, 3);
2790 i += 3;
2791 tod = getbitu(rtcm->buff, i, 27) * 0.001;
2792 i += 27;
2793 adjday_glot(rtcm, tod);
2794 } else if (sys == SYS_CMP) {
2795 tow = getbitu(rtcm->buff, i, 30) * 0.001;
2796 i += 30;
2797 tow += 14.0; /* BDT -> GPST */
2798 adjweek(rtcm, tow);
2799 } else {
2800 tow = getbitu(rtcm->buff, i, 30) * 0.001;
2801 i += 30;
2802 adjweek(rtcm, tow);
2803 }
2804 *sync = getbitu(rtcm->buff, i, 1);
2805 i += 1;
2806 *iod = getbitu(rtcm->buff, i, 3);
2807 i += 3;
2808 h->time_s = getbitu(rtcm->buff, i, 7);
2809 i += 7;
2810 h->clk_str = getbitu(rtcm->buff, i, 2);
2811 i += 2;
2812 h->clk_ext = getbitu(rtcm->buff, i, 2);
2813 i += 2;
2814 h->smooth = getbitu(rtcm->buff, i, 1);
2815 i += 1;
2816 h->tint_s = getbitu(rtcm->buff, i, 3);
2817 i += 3;
2818 for (j = 1; j <= 64; j++) {
2819 mask = getbitu(rtcm->buff, i, 1);
2820 i += 1;
2821 if (mask) {
2822 h->sats[h->nsat++] = j;
2823 }
2824 }
2825 for (j = 1; j <= 32; j++) {
2826 mask = getbitu(rtcm->buff, i, 1);
2827 i += 1;
2828 if (mask) {
2829 h->sigs[h->nsig++] = j;
2830 }
2831 }
2832 } else {
2833 trace(NULL, 2, "rtcm3 %d length error: len=%d\n", type, rtcm->len);
2834 return -1;
2835 }
2836 /* test station id */
2837 if (!test_staid(rtcm, staid)) {
2838 return -1;
2839 }
2840
2841 if (h->nsat * h->nsig > 64) {
2842 trace(NULL, 2, "rtcm3 %d number of sats and sigs error: nsat=%d nsig=%d\n", type, h->nsat, h->nsig);
2843 return -1;
2844 }
2845 if (i + h->nsat * h->nsig > rtcm->len * 8) {
2846 trace(NULL, 2, "rtcm3 %d length error: len=%d nsat=%d nsig=%d\n", type, rtcm->len, h->nsat, h->nsig);
2847 return -1;
2848 }
2849 for (j = 0; j < h->nsat * h->nsig; j++) {
2850 h->cellmask[j] = getbitu(rtcm->buff, i, 1);
2851 i += 1;
2852 if (h->cellmask[j]) {
2853 ncell++;
2854 }
2855 }
2856 *hsize = i;
2857
2858 time2str(rtcm->time, tstr, 2);
2859 trace(NULL, 4, "decode_head_msm: time=%s sys=%d staid=%d nsat=%d nsig=%d sync=%d iod=%d ncell=%d\n", tstr, sys,
2860 staid, h->nsat, h->nsig, *sync, *iod, ncell);
2861
2862 if (rtcm->outtype) {
2863 msg = rtcm->msgtype + strlen(rtcm->msgtype);
2864 sprintf(msg, " staid=%4d %s nsat=%2d nsig=%2d iod=%2d ncell=%2d sync=%d", staid, tstr, h->nsat, h->nsig, *iod,
2865 ncell, *sync);
2866 }
2867 return ncell;
2868}
2869/* decode unsupported MSM message --------------------------------------------*/
2870static int decode_msm0(rtcm_t* rtcm, int sys) {
2871 msm_h_t h = {0};
2872 int i, sync, iod;
2873 if (decode_msm_head(rtcm, sys, &sync, &iod, &h, &i) < 0) {
2874 return -1;
2875 }
2876 rtcm->obsflag = !sync;
2877 return sync ? 0 : 1;
2878}
2879/* decode MSM 4: full pseudorange and phaserange plus CNR --------------------*/
2880static int decode_msm4(rtcm_t* rtcm, int sys) {
2881 msm_h_t h = {0};
2882 double r[64], pr[64], cp[64], cnr[64];
2883 int i, j, type, sync, iod, ncell, rng, rng_m, prv, cpv, lock[64], half[64];
2884
2885 type = getbitu(rtcm->buff, 24, 12);
2886
2887 /* decode msm header */
2888 if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) {
2889 return -1;
2890 }
2891
2892 if (i + h.nsat * 18 + ncell * 48 > rtcm->len * 8) {
2893 trace(NULL, 2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len);
2894 return -1;
2895 }
2896 for (j = 0; j < h.nsat; j++) {
2897 r[j] = 0.0;
2898 }
2899 for (j = 0; j < ncell; j++) {
2900 pr[j] = cp[j] = -1E16;
2901 }
2902
2903 /* decode satellite data */
2904 for (j = 0; j < h.nsat; j++) { /* range */
2905 rng = getbitu(rtcm->buff, i, 8);
2906 i += 8;
2907 if (rng != 255) {
2908 r[j] = rng * RANGE_MS;
2909 }
2910 }
2911 for (j = 0; j < h.nsat; j++) {
2912 rng_m = getbitu(rtcm->buff, i, 10);
2913 i += 10;
2914 if (r[j] != 0.0) {
2915 r[j] += rng_m * P2_10 * RANGE_MS;
2916 }
2917 }
2918 /* decode signal data */
2919 for (j = 0; j < ncell; j++) { /* pseudorange */
2920 prv = getbits(rtcm->buff, i, 15);
2921 i += 15;
2922 if (prv != -16384) {
2923 pr[j] = prv * P2_24 * RANGE_MS;
2924 }
2925 }
2926 for (j = 0; j < ncell; j++) { /* phaserange */
2927 cpv = getbits(rtcm->buff, i, 22);
2928 i += 22;
2929 if (cpv != -2097152) {
2930 cp[j] = cpv * P2_29 * RANGE_MS;
2931 }
2932 }
2933 for (j = 0; j < ncell; j++) { /* lock time */
2934 lock[j] = getbitu(rtcm->buff, i, 4);
2935 i += 4;
2936 }
2937 for (j = 0; j < ncell; j++) { /* half-cycle ambiguity */
2938 half[j] = getbitu(rtcm->buff, i, 1);
2939 i += 1;
2940 }
2941 for (j = 0; j < ncell; j++) { /* cnr */
2942 cnr[j] = getbitu(rtcm->buff, i, 6) * 1.0;
2943 i += 6;
2944 }
2945 /* save obs data in msm message */
2946 save_msm_obs(rtcm, sys, &h, r, pr, cp, NULL, NULL, cnr, lock, NULL, half);
2947
2948 rtcm->obsflag = !sync;
2949 return sync ? 0 : 1;
2950}
2951/* decode MSM 5: full pseudorange, phaserange, phaserangerate and CNR --------*/
2952static int decode_msm5(rtcm_t* rtcm, int sys) {
2953 msm_h_t h = {0};
2954 double r[64], rr[64], pr[64], cp[64], rrf[64], cnr[64];
2955 int i, j, type, sync, iod, ncell, rng, rng_m, rate, prv, cpv, rrv, lock[64];
2956 int ex[64], half[64];
2957
2958 type = getbitu(rtcm->buff, 24, 12);
2959
2960 /* decode msm header */
2961 if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) {
2962 return -1;
2963 }
2964
2965 if (i + h.nsat * 36 + ncell * 63 > rtcm->len * 8) {
2966 trace(NULL, 2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len);
2967 return -1;
2968 }
2969 for (j = 0; j < h.nsat; j++) {
2970 r[j] = rr[j] = 0.0;
2971 ex[j] = 15;
2972 }
2973 for (j = 0; j < ncell; j++) {
2974 pr[j] = cp[j] = rrf[j] = -1E16;
2975 }
2976
2977 /* decode satellite data */
2978 for (j = 0; j < h.nsat; j++) { /* range */
2979 rng = getbitu(rtcm->buff, i, 8);
2980 i += 8;
2981 if (rng != 255) {
2982 r[j] = rng * RANGE_MS;
2983 }
2984 }
2985 for (j = 0; j < h.nsat; j++) { /* extended info */
2986 ex[j] = getbitu(rtcm->buff, i, 4);
2987 i += 4;
2988 }
2989 for (j = 0; j < h.nsat; j++) {
2990 rng_m = getbitu(rtcm->buff, i, 10);
2991 i += 10;
2992 if (r[j] != 0.0) {
2993 r[j] += rng_m * P2_10 * RANGE_MS;
2994 }
2995 }
2996 for (j = 0; j < h.nsat; j++) { /* phaserangerate */
2997 rate = getbits(rtcm->buff, i, 14);
2998 i += 14;
2999 if (rate != -8192) {
3000 rr[j] = rate * 1.0;
3001 }
3002 }
3003 /* decode signal data */
3004 for (j = 0; j < ncell; j++) { /* pseudorange */
3005 prv = getbits(rtcm->buff, i, 15);
3006 i += 15;
3007 if (prv != -16384) {
3008 pr[j] = prv * P2_24 * RANGE_MS;
3009 }
3010 }
3011 for (j = 0; j < ncell; j++) { /* phaserange */
3012 cpv = getbits(rtcm->buff, i, 22);
3013 i += 22;
3014 if (cpv != -2097152) {
3015 cp[j] = cpv * P2_29 * RANGE_MS;
3016 }
3017 }
3018 for (j = 0; j < ncell; j++) { /* lock time */
3019 lock[j] = getbitu(rtcm->buff, i, 4);
3020 i += 4;
3021 }
3022 for (j = 0; j < ncell; j++) { /* half-cycle ambiguity */
3023 half[j] = getbitu(rtcm->buff, i, 1);
3024 i += 1;
3025 }
3026 for (j = 0; j < ncell; j++) { /* cnr */
3027 cnr[j] = getbitu(rtcm->buff, i, 6) * 1.0;
3028 i += 6;
3029 }
3030 for (j = 0; j < ncell; j++) { /* phaserangerate */
3031 rrv = getbits(rtcm->buff, i, 15);
3032 i += 15;
3033 if (rrv != -16384) {
3034 rrf[j] = rrv * 0.0001;
3035 }
3036 }
3037 /* save obs data in msm message */
3038 save_msm_obs(rtcm, sys, &h, r, pr, cp, rr, rrf, cnr, lock, ex, half);
3039
3040 rtcm->obsflag = !sync;
3041 return sync ? 0 : 1;
3042}
3043/* decode MSM 6: full pseudorange and phaserange plus CNR (high-res) ---------*/
3044static int decode_msm6(rtcm_t* rtcm, int sys) {
3045 msm_h_t h = {0};
3046 double r[64], pr[64], cp[64], cnr[64];
3047 int i, j, type, sync, iod, ncell, rng, rng_m, prv, cpv, lock[64], half[64];
3048
3049 type = getbitu(rtcm->buff, 24, 12);
3050
3051 /* decode msm header */
3052 if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) {
3053 return -1;
3054 }
3055
3056 if (i + h.nsat * 18 + ncell * 65 > rtcm->len * 8) {
3057 trace(NULL, 2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len);
3058 return -1;
3059 }
3060 for (j = 0; j < h.nsat; j++) {
3061 r[j] = 0.0;
3062 }
3063 for (j = 0; j < ncell; j++) {
3064 pr[j] = cp[j] = -1E16;
3065 }
3066
3067 /* decode satellite data */
3068 for (j = 0; j < h.nsat; j++) { /* range */
3069 rng = getbitu(rtcm->buff, i, 8);
3070 i += 8;
3071 if (rng != 255) {
3072 r[j] = rng * RANGE_MS;
3073 }
3074 }
3075 for (j = 0; j < h.nsat; j++) {
3076 rng_m = getbitu(rtcm->buff, i, 10);
3077 i += 10;
3078 if (r[j] != 0.0) {
3079 r[j] += rng_m * P2_10 * RANGE_MS;
3080 }
3081 }
3082 /* decode signal data */
3083 for (j = 0; j < ncell; j++) { /* pseudorange */
3084 prv = getbits(rtcm->buff, i, 20);
3085 i += 20;
3086 if (prv != -524288) {
3087 pr[j] = prv * P2_29 * RANGE_MS;
3088 }
3089 }
3090 for (j = 0; j < ncell; j++) { /* phaserange */
3091 cpv = getbits(rtcm->buff, i, 24);
3092 i += 24;
3093 if (cpv != -8388608) {
3094 cp[j] = cpv * P2_31 * RANGE_MS;
3095 }
3096 }
3097 for (j = 0; j < ncell; j++) { /* lock time */
3098 lock[j] = getbitu(rtcm->buff, i, 10);
3099 i += 10;
3100 }
3101 for (j = 0; j < ncell; j++) { /* half-cycle ambiguity */
3102 half[j] = getbitu(rtcm->buff, i, 1);
3103 i += 1;
3104 }
3105 for (j = 0; j < ncell; j++) { /* cnr */
3106 cnr[j] = getbitu(rtcm->buff, i, 10) * 0.0625;
3107 i += 10;
3108 }
3109 /* save obs data in msm message */
3110 save_msm_obs(rtcm, sys, &h, r, pr, cp, NULL, NULL, cnr, lock, NULL, half);
3111
3112 rtcm->obsflag = !sync;
3113 return sync ? 0 : 1;
3114}
3115/* decode MSM 7: full pseudorange, phaserange, phaserangerate and CNR (h-res) */
3116static int decode_msm7(rtcm_t* rtcm, int sys) {
3117 msm_h_t h = {0};
3118 double r[64], rr[64], pr[64], cp[64], rrf[64], cnr[64];
3119 int i, j, type, sync, iod, ncell, rng, rng_m, rate, prv, cpv, rrv, lock[64];
3120 int ex[64], half[64];
3121
3122 type = getbitu(rtcm->buff, 24, 12);
3123
3124 /* decode msm header */
3125 if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) {
3126 return -1;
3127 }
3128
3129 if (i + h.nsat * 36 + ncell * 80 > rtcm->len * 8) {
3130 trace(NULL, 2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len);
3131 return -1;
3132 }
3133 for (j = 0; j < h.nsat; j++) {
3134 r[j] = rr[j] = 0.0;
3135 ex[j] = 15;
3136 }
3137 for (j = 0; j < ncell; j++) {
3138 pr[j] = cp[j] = rrf[j] = -1E16;
3139 }
3140
3141 /* decode satellite data */
3142 for (j = 0; j < h.nsat; j++) { /* range */
3143 rng = getbitu(rtcm->buff, i, 8);
3144 i += 8;
3145 if (rng != 255) {
3146 r[j] = rng * RANGE_MS;
3147 }
3148 }
3149 for (j = 0; j < h.nsat; j++) { /* extended info */
3150 ex[j] = getbitu(rtcm->buff, i, 4);
3151 i += 4;
3152 }
3153 for (j = 0; j < h.nsat; j++) {
3154 rng_m = getbitu(rtcm->buff, i, 10);
3155 i += 10;
3156 if (r[j] != 0.0) {
3157 r[j] += rng_m * P2_10 * RANGE_MS;
3158 }
3159 }
3160 for (j = 0; j < h.nsat; j++) { /* phaserangerate */
3161 rate = getbits(rtcm->buff, i, 14);
3162 i += 14;
3163 if (rate != -8192) {
3164 rr[j] = rate * 1.0;
3165 }
3166 }
3167 /* decode signal data */
3168 for (j = 0; j < ncell; j++) { /* pseudorange */
3169 prv = getbits(rtcm->buff, i, 20);
3170 i += 20;
3171 if (prv != -524288) {
3172 pr[j] = prv * P2_29 * RANGE_MS;
3173 }
3174 }
3175 for (j = 0; j < ncell; j++) { /* phaserange */
3176 cpv = getbits(rtcm->buff, i, 24);
3177 i += 24;
3178 if (cpv != -8388608) {
3179 cp[j] = cpv * P2_31 * RANGE_MS;
3180 }
3181 }
3182 for (j = 0; j < ncell; j++) { /* lock time */
3183 lock[j] = getbitu(rtcm->buff, i, 10);
3184 i += 10;
3185 }
3186 for (j = 0; j < ncell; j++) { /* half-cycle amiguity */
3187 half[j] = getbitu(rtcm->buff, i, 1);
3188 i += 1;
3189 }
3190 for (j = 0; j < ncell; j++) { /* cnr */
3191 cnr[j] = getbitu(rtcm->buff, i, 10) * 0.0625;
3192 i += 10;
3193 }
3194 for (j = 0; j < ncell; j++) { /* phaserangerate */
3195 rrv = getbits(rtcm->buff, i, 15);
3196 i += 15;
3197 if (rrv != -16384) {
3198 rrf[j] = rrv * 0.0001;
3199 }
3200 }
3201 /* save obs data in msm message */
3202 save_msm_obs(rtcm, sys, &h, r, pr, cp, rr, rrf, cnr, lock, ex, half);
3203
3204 rtcm->obsflag = !sync;
3205 return sync ? 0 : 1;
3206}
3207/* decode type 1230: GLONASS L1 and L2 code-phase biases ---------------------*/
3209 int i = 24 + 12, j, staid, align, mask, bias;
3210
3211 if (i + 20 >= rtcm->len * 8) {
3212 trace(NULL, 2, "rtcm3 1230: length error len=%d\n", rtcm->len);
3213 return -1;
3214 }
3215 staid = getbitu(rtcm->buff, i, 12);
3216 i += 12;
3217 align = getbitu(rtcm->buff, i, 1);
3218 i += 1 + 3;
3219 mask = getbitu(rtcm->buff, i, 4);
3220 i += 4;
3221
3222 if (rtcm->outtype) {
3223 sprintf(rtcm->msgtype + strlen(rtcm->msgtype), " staid=%4d align=%d mask=0x%X", staid, align, mask);
3224 }
3225 /* test station ID */
3226 if (!test_staid(rtcm, staid)) {
3227 return -1;
3228 }
3229
3230 rtcm->sta.glo_cp_align = align;
3231 for (j = 0; j < 4; j++) {
3232 rtcm->sta.glo_cp_bias[j] = 0.0;
3233 }
3234 for (j = 0; j < 4 && i + 16 <= rtcm->len * 8; j++) {
3235 if (!(mask & (1 << (3 - j)))) {
3236 continue;
3237 }
3238 bias = getbits(rtcm->buff, i, 16);
3239 i += 16;
3240 if (bias != -32768) {
3241 rtcm->sta.glo_cp_bias[j] = bias * 0.02;
3242 }
3243 }
3244 return 5;
3245}
3246/* decode type 4073: proprietary message Mitsubishi Electric -----------------*/
3248 int i = 24 + 12, subtype;
3249
3250 subtype = getbitu(rtcm->buff, i, 4);
3251 i += 4;
3252
3253 if (rtcm->outtype) {
3254 sprintf(rtcm->msgtype + strlen(rtcm->msgtype), " subtype=%d", subtype);
3255 }
3256 trace(NULL, 2, "rtcm3 4073: unsupported message subtype=%d\n", subtype);
3257 return 0;
3258}
3259/* decode type 4076: proprietary message IGS ---------------------------------*/
3261 int i = 24 + 12, ver, subtype;
3262
3263 if (i + 3 + 8 >= rtcm->len * 8) {
3264 trace(NULL, 2, "rtcm3 4076: length error len=%d\n", rtcm->len);
3265 return -1;
3266 }
3267 ver = getbitu(rtcm->buff, i, 3);
3268 i += 3;
3269 subtype = getbitu(rtcm->buff, i, 8);
3270 i += 8;
3271
3272 if (rtcm->outtype) {
3273 sprintf(rtcm->msgtype + strlen(rtcm->msgtype), " ver=%d subtype=%3d", ver, subtype);
3274 }
3275 switch (subtype) {
3276 case 21:
3277 return decode_ssr1(rtcm, SYS_GPS, subtype);
3278 case 22:
3279 return decode_ssr2(rtcm, SYS_GPS, subtype);
3280 case 23:
3281 return decode_ssr4(rtcm, SYS_GPS, subtype);
3282 case 24:
3283 return decode_ssr6(rtcm, SYS_GPS, subtype);
3284 case 25:
3285 return decode_ssr3(rtcm, SYS_GPS, subtype);
3286 case 26:
3287 return decode_ssr7(rtcm, SYS_GPS, subtype);
3288 case 27:
3289 return decode_ssr5(rtcm, SYS_GPS, subtype);
3290 case 41:
3291 return decode_ssr1(rtcm, SYS_GLO, subtype);
3292 case 42:
3293 return decode_ssr2(rtcm, SYS_GLO, subtype);
3294 case 43:
3295 return decode_ssr4(rtcm, SYS_GLO, subtype);
3296 case 44:
3297 return decode_ssr6(rtcm, SYS_GLO, subtype);
3298 case 45:
3299 return decode_ssr3(rtcm, SYS_GLO, subtype);
3300 case 46:
3301 return decode_ssr7(rtcm, SYS_GLO, subtype);
3302 case 47:
3303 return decode_ssr5(rtcm, SYS_GLO, subtype);
3304 case 61:
3305 return decode_ssr1(rtcm, SYS_GAL, subtype);
3306 case 62:
3307 return decode_ssr2(rtcm, SYS_GAL, subtype);
3308 case 63:
3309 return decode_ssr4(rtcm, SYS_GAL, subtype);
3310 case 64:
3311 return decode_ssr6(rtcm, SYS_GAL, subtype);
3312 case 65:
3313 return decode_ssr3(rtcm, SYS_GAL, subtype);
3314 case 66:
3315 return decode_ssr7(rtcm, SYS_GAL, subtype);
3316 case 67:
3317 return decode_ssr5(rtcm, SYS_GAL, subtype);
3318 case 81:
3319 return decode_ssr1(rtcm, SYS_QZS, subtype);
3320 case 82:
3321 return decode_ssr2(rtcm, SYS_QZS, subtype);
3322 case 83:
3323 return decode_ssr4(rtcm, SYS_QZS, subtype);
3324 case 84:
3325 return decode_ssr6(rtcm, SYS_QZS, subtype);
3326 case 85:
3327 return decode_ssr3(rtcm, SYS_QZS, subtype);
3328 case 86:
3329 return decode_ssr7(rtcm, SYS_QZS, subtype);
3330 case 87:
3331 return decode_ssr5(rtcm, SYS_QZS, subtype);
3332 case 101:
3333 return decode_ssr1(rtcm, SYS_CMP, subtype);
3334 case 102:
3335 return decode_ssr2(rtcm, SYS_CMP, subtype);
3336 case 103:
3337 return decode_ssr4(rtcm, SYS_CMP, subtype);
3338 case 104:
3339 return decode_ssr6(rtcm, SYS_CMP, subtype);
3340 case 105:
3341 return decode_ssr3(rtcm, SYS_CMP, subtype);
3342 case 106:
3343 return decode_ssr7(rtcm, SYS_CMP, subtype);
3344 case 107:
3345 return decode_ssr5(rtcm, SYS_CMP, subtype);
3346 case 121:
3347 return decode_ssr1(rtcm, SYS_SBS, subtype);
3348 case 122:
3349 return decode_ssr2(rtcm, SYS_SBS, subtype);
3350 case 123:
3351 return decode_ssr4(rtcm, SYS_SBS, subtype);
3352 case 124:
3353 return decode_ssr6(rtcm, SYS_SBS, subtype);
3354 case 125:
3355 return decode_ssr3(rtcm, SYS_SBS, subtype);
3356 case 126:
3357 return decode_ssr7(rtcm, SYS_SBS, subtype);
3358 case 127:
3359 return decode_ssr5(rtcm, SYS_SBS, subtype);
3360 }
3361 trace(NULL, 2, "rtcm3 4076: unsupported message subtype=%d\n", subtype);
3362 return 0;
3363}
3364
3365/* decode type 4050: QZSS LEX signal raw data MAGELLAN SYSTEMS JAPAN, INC. -----------------*/
3367 int i = 24 + 12, tow, errbits, prn, type, alert;
3368 uint8_t tmpbuff[1200]; /* message buffer */
3369
3370 if (1776 != rtcm->len * 8) {
3371 trace(NULL, 2, "rtcm3 4050: length error len=%d\n", rtcm->len);
3372 return -1;
3373 }
3374
3375 i += 4; /* Reserved */
3376 tow = getbitu(rtcm->buff, i, 20);
3377 i += 20; /* TOW */
3378 errbits = getbitu(rtcm->buff, i, 4);
3379 i += 4; /* Number of correction error bits */
3380 prn = getbitu(rtcm->buff, i, 8);
3381 i += 8; /* PRN */
3382 type = getbits(rtcm->buff, i, 8);
3383 i += 8; /* L6 Message Type ID */
3384 alert = getbits(rtcm->buff, i, 1);
3385 i += 1; /* Alert Flag */
3386
3387 trace(NULL, 3, "rtcm3 4050: tow=%d errbits=%d prn=%d type=%d alert=%d\n", tow, errbits, prn, type, alert);
3388
3389 memcpy(tmpbuff, rtcm->buff, sizeof(tmpbuff));
3390
3391 memset(rtcm->buff, 0x00, sizeof(rtcm->buff));
3392
3393 rtcm->buff[0] = 0x1A;
3394 rtcm->buff[1] = 0xCF;
3395 rtcm->buff[2] = 0xFC;
3396 rtcm->buff[3] = 0x1D;
3397 memcpy(rtcm->buff + 4, tmpbuff + 8, sizeof(uint8_t) * 217);
3398
3399 return decode_qzss_l6emsg(rtcm);
3400}
3401/* decode RTCM ver.3 message -------------------------------------------------*/
3403 double tow;
3404 int ret = 0, type = getbitu(rtcm->buff, 24, 12), week;
3405
3406 trace(NULL, 3, "decode_rtcm3: len=%3d type=%d\n", rtcm->len, type);
3407
3408 if (rtcm->outtype) {
3409 sprintf(rtcm->msgtype, "RTCM %4d (%4d):", type, rtcm->len);
3410 }
3411 /* real-time input option */
3412 if (strstr(rtcm->opt, "-RT_INP")) {
3413 tow = time2gpst(utc2gpst(timeget()), &week);
3414 rtcm->time = gpst2time(week, floor(tow));
3415 }
3416 switch (type) {
3417 case 1001:
3418 ret = decode_type1001(rtcm);
3419 break; /* not supported */
3420 case 1002:
3421 ret = decode_type1002(rtcm);
3422 break;
3423 case 1003:
3424 ret = decode_type1003(rtcm);
3425 break; /* not supported */
3426 case 1004:
3427 ret = decode_type1004(rtcm);
3428 break;
3429 case 1005:
3430 ret = decode_type1005(rtcm);
3431 break;
3432 case 1006:
3433 ret = decode_type1006(rtcm);
3434 break;
3435 case 1007:
3436 ret = decode_type1007(rtcm);
3437 break;
3438 case 1008:
3439 ret = decode_type1008(rtcm);
3440 break;
3441 case 1009:
3442 ret = decode_type1009(rtcm);
3443 break; /* not supported */
3444 case 1010:
3445 ret = decode_type1010(rtcm);
3446 break;
3447 case 1011:
3448 ret = decode_type1011(rtcm);
3449 break; /* not supported */
3450 case 1012:
3451 ret = decode_type1012(rtcm);
3452 break;
3453 case 1013:
3454 ret = decode_type1013(rtcm);
3455 break; /* not supported */
3456 case 1019:
3457 ret = decode_type1019(rtcm);
3458 break;
3459 case 1020:
3460 ret = decode_type1020(rtcm);
3461 break;
3462 case 1021:
3463 ret = decode_type1021(rtcm);
3464 break; /* not supported */
3465 case 1022:
3466 ret = decode_type1022(rtcm);
3467 break; /* not supported */
3468 case 1023:
3469 ret = decode_type1023(rtcm);
3470 break; /* not supported */
3471 case 1024:
3472 ret = decode_type1024(rtcm);
3473 break; /* not supported */
3474 case 1025:
3475 ret = decode_type1025(rtcm);
3476 break; /* not supported */
3477 case 1026:
3478 ret = decode_type1026(rtcm);
3479 break; /* not supported */
3480 case 1027:
3481 ret = decode_type1027(rtcm);
3482 break; /* not supported */
3483 case 1029:
3484 ret = decode_type1029(rtcm);
3485 break;
3486 case 1030:
3487 ret = decode_type1030(rtcm);
3488 break; /* not supported */
3489 case 1031:
3490 ret = decode_type1031(rtcm);
3491 break; /* not supported */
3492 case 1032:
3493 ret = decode_type1032(rtcm);
3494 break; /* not supported */
3495 case 1033:
3496 ret = decode_type1033(rtcm);
3497 break;
3498 case 1034:
3499 ret = decode_type1034(rtcm);
3500 break; /* not supported */
3501 case 1035:
3502 ret = decode_type1035(rtcm);
3503 break; /* not supported */
3504 case 1037:
3505 ret = decode_type1037(rtcm);
3506 break; /* not supported */
3507 case 1038:
3508 ret = decode_type1038(rtcm);
3509 break; /* not supported */
3510 case 1039:
3511 ret = decode_type1039(rtcm);
3512 break; /* not supported */
3513 case 1041:
3514 ret = decode_type1041(rtcm);
3515 break;
3516 case 1044:
3517 ret = decode_type1044(rtcm);
3518 break;
3519 case 1045:
3520 ret = decode_type1045(rtcm);
3521 break;
3522 case 1046:
3523 ret = decode_type1046(rtcm);
3524 break;
3525 case 63:
3526 ret = decode_type1042(rtcm);
3527 break; /* RTCM draft */
3528 case 1042:
3529 ret = decode_type1042(rtcm);
3530 break;
3531 case 1057:
3532 ret = decode_ssr1(rtcm, SYS_GPS, 0);
3533 break;
3534 case 1058:
3535 ret = decode_ssr2(rtcm, SYS_GPS, 0);
3536 break;
3537 case 1059:
3538 ret = decode_ssr3(rtcm, SYS_GPS, 0);
3539 break;
3540 case 1060:
3541 ret = decode_ssr4(rtcm, SYS_GPS, 0);
3542 break;
3543 case 1061:
3544 ret = decode_ssr5(rtcm, SYS_GPS, 0);
3545 break;
3546 case 1062:
3547 ret = decode_ssr6(rtcm, SYS_GPS, 0);
3548 break;
3549 case 1063:
3550 ret = decode_ssr1(rtcm, SYS_GLO, 0);
3551 break;
3552 case 1064:
3553 ret = decode_ssr2(rtcm, SYS_GLO, 0);
3554 break;
3555 case 1065:
3556 ret = decode_ssr3(rtcm, SYS_GLO, 0);
3557 break;
3558 case 1066:
3559 ret = decode_ssr4(rtcm, SYS_GLO, 0);
3560 break;
3561 case 1067:
3562 ret = decode_ssr5(rtcm, SYS_GLO, 0);
3563 break;
3564 case 1068:
3565 ret = decode_ssr6(rtcm, SYS_GLO, 0);
3566 break;
3567 case 1071:
3568 ret = decode_msm0(rtcm, SYS_GPS);
3569 break; /* not supported */
3570 case 1072:
3571 ret = decode_msm0(rtcm, SYS_GPS);
3572 break; /* not supported */
3573 case 1073:
3574 ret = decode_msm0(rtcm, SYS_GPS);
3575 break; /* not supported */
3576 case 1074:
3577 ret = decode_msm4(rtcm, SYS_GPS);
3578 break;
3579 case 1075:
3580 ret = decode_msm5(rtcm, SYS_GPS);
3581 break;
3582 case 1076:
3583 ret = decode_msm6(rtcm, SYS_GPS);
3584 break;
3585 case 1077:
3586 ret = decode_msm7(rtcm, SYS_GPS);
3587 break;
3588 case 1081:
3589 ret = decode_msm0(rtcm, SYS_GLO);
3590 break; /* not supported */
3591 case 1082:
3592 ret = decode_msm0(rtcm, SYS_GLO);
3593 break; /* not supported */
3594 case 1083:
3595 ret = decode_msm0(rtcm, SYS_GLO);
3596 break; /* not supported */
3597 case 1084:
3598 ret = decode_msm4(rtcm, SYS_GLO);
3599 break;
3600 case 1085:
3601 ret = decode_msm5(rtcm, SYS_GLO);
3602 break;
3603 case 1086:
3604 ret = decode_msm6(rtcm, SYS_GLO);
3605 break;
3606 case 1087:
3607 ret = decode_msm7(rtcm, SYS_GLO);
3608 break;
3609 case 1091:
3610 ret = decode_msm0(rtcm, SYS_GAL);
3611 break; /* not supported */
3612 case 1092:
3613 ret = decode_msm0(rtcm, SYS_GAL);
3614 break; /* not supported */
3615 case 1093:
3616 ret = decode_msm0(rtcm, SYS_GAL);
3617 break; /* not supported */
3618 case 1094:
3619 ret = decode_msm4(rtcm, SYS_GAL);
3620 break;
3621 case 1095:
3622 ret = decode_msm5(rtcm, SYS_GAL);
3623 break;
3624 case 1096:
3625 ret = decode_msm6(rtcm, SYS_GAL);
3626 break;
3627 case 1097:
3628 ret = decode_msm7(rtcm, SYS_GAL);
3629 break;
3630 case 1101:
3631 ret = decode_msm0(rtcm, SYS_SBS);
3632 break; /* not supported */
3633 case 1102:
3634 ret = decode_msm0(rtcm, SYS_SBS);
3635 break; /* not supported */
3636 case 1103:
3637 ret = decode_msm0(rtcm, SYS_SBS);
3638 break; /* not supported */
3639 case 1104:
3640 ret = decode_msm4(rtcm, SYS_SBS);
3641 break;
3642 case 1105:
3643 ret = decode_msm5(rtcm, SYS_SBS);
3644 break;
3645 case 1106:
3646 ret = decode_msm6(rtcm, SYS_SBS);
3647 break;
3648 case 1107:
3649 ret = decode_msm7(rtcm, SYS_SBS);
3650 break;
3651 case 1111:
3652 ret = decode_msm0(rtcm, SYS_QZS);
3653 break; /* not supported */
3654 case 1112:
3655 ret = decode_msm0(rtcm, SYS_QZS);
3656 break; /* not supported */
3657 case 1113:
3658 ret = decode_msm0(rtcm, SYS_QZS);
3659 break; /* not supported */
3660 case 1114:
3661 ret = decode_msm4(rtcm, SYS_QZS);
3662 break;
3663 case 1115:
3664 ret = decode_msm5(rtcm, SYS_QZS);
3665 break;
3666 case 1116:
3667 ret = decode_msm6(rtcm, SYS_QZS);
3668 break;
3669 case 1117:
3670 ret = decode_msm7(rtcm, SYS_QZS);
3671 break;
3672 case 1121:
3673 ret = decode_msm0(rtcm, SYS_CMP);
3674 break; /* not supported */
3675 case 1122:
3676 ret = decode_msm0(rtcm, SYS_CMP);
3677 break; /* not supported */
3678 case 1123:
3679 ret = decode_msm0(rtcm, SYS_CMP);
3680 break; /* not supported */
3681 case 1124:
3682 ret = decode_msm4(rtcm, SYS_CMP);
3683 break;
3684 case 1125:
3685 ret = decode_msm5(rtcm, SYS_CMP);
3686 break;
3687 case 1126:
3688 ret = decode_msm6(rtcm, SYS_CMP);
3689 break;
3690 case 1127:
3691 ret = decode_msm7(rtcm, SYS_CMP);
3692 break;
3693 case 1131:
3694 ret = decode_msm0(rtcm, SYS_IRN);
3695 break; /* not supported */
3696 case 1132:
3697 ret = decode_msm0(rtcm, SYS_IRN);
3698 break; /* not supported */
3699 case 1133:
3700 ret = decode_msm0(rtcm, SYS_IRN);
3701 break; /* not supported */
3702 case 1134:
3703 ret = decode_msm4(rtcm, SYS_IRN);
3704 break;
3705 case 1135:
3706 ret = decode_msm5(rtcm, SYS_IRN);
3707 break;
3708 case 1136:
3709 ret = decode_msm6(rtcm, SYS_IRN);
3710 break;
3711 case 1137:
3712 ret = decode_msm7(rtcm, SYS_IRN);
3713 break;
3714 case 1230:
3715 ret = decode_type1230(rtcm);
3716 break;
3717 case 1240:
3718 ret = decode_ssr1(rtcm, SYS_GAL, 0);
3719 break; /* draft */
3720 case 1241:
3721 ret = decode_ssr2(rtcm, SYS_GAL, 0);
3722 break; /* draft */
3723 case 1242:
3724 ret = decode_ssr3(rtcm, SYS_GAL, 0);
3725 break; /* draft */
3726 case 1243:
3727 ret = decode_ssr4(rtcm, SYS_GAL, 0);
3728 break; /* draft */
3729 case 1244:
3730 ret = decode_ssr5(rtcm, SYS_GAL, 0);
3731 break; /* draft */
3732 case 1245:
3733 ret = decode_ssr6(rtcm, SYS_GAL, 0);
3734 break; /* draft */
3735 case 1246:
3736 ret = decode_ssr1(rtcm, SYS_QZS, 0);
3737 break; /* draft */
3738 case 1247:
3739 ret = decode_ssr2(rtcm, SYS_QZS, 0);
3740 break; /* draft */
3741 case 1248:
3742 ret = decode_ssr3(rtcm, SYS_QZS, 0);
3743 break; /* draft */
3744 case 1249:
3745 ret = decode_ssr4(rtcm, SYS_QZS, 0);
3746 break; /* draft */
3747 case 1250:
3748 ret = decode_ssr5(rtcm, SYS_QZS, 0);
3749 break; /* draft */
3750 case 1251:
3751 ret = decode_ssr6(rtcm, SYS_QZS, 0);
3752 break; /* draft */
3753 case 1252:
3754 ret = decode_ssr1(rtcm, SYS_SBS, 0);
3755 break; /* draft */
3756 case 1253:
3757 ret = decode_ssr2(rtcm, SYS_SBS, 0);
3758 break; /* draft */
3759 case 1254:
3760 ret = decode_ssr3(rtcm, SYS_SBS, 0);
3761 break; /* draft */
3762 case 1255:
3763 ret = decode_ssr4(rtcm, SYS_SBS, 0);
3764 break; /* draft */
3765 case 1256:
3766 ret = decode_ssr5(rtcm, SYS_SBS, 0);
3767 break; /* draft */
3768 case 1257:
3769 ret = decode_ssr6(rtcm, SYS_SBS, 0);
3770 break; /* draft */
3771 case 1258:
3772 ret = decode_ssr1(rtcm, SYS_CMP, 0);
3773 break; /* draft */
3774 case 1259:
3775 ret = decode_ssr2(rtcm, SYS_CMP, 0);
3776 break; /* draft */
3777 case 1260:
3778 ret = decode_ssr3(rtcm, SYS_CMP, 0);
3779 break; /* draft */
3780 case 1261:
3781 ret = decode_ssr4(rtcm, SYS_CMP, 0);
3782 break; /* draft */
3783 case 1262:
3784 ret = decode_ssr5(rtcm, SYS_CMP, 0);
3785 break; /* draft */
3786 case 1263:
3787 ret = decode_ssr6(rtcm, SYS_CMP, 0);
3788 break; /* draft */
3789 case 1265:
3790 ret = decode_ssr7(rtcm, SYS_GPS, 0);
3791 break; /* draft */
3792 case 1266:
3793 ret = decode_ssr7(rtcm, SYS_GLO, 0);
3794 break; /* draft */
3795 case 1267:
3796 ret = decode_ssr7(rtcm, SYS_GAL, 0);
3797 break; /* draft */
3798 case 1268:
3799 ret = decode_ssr7(rtcm, SYS_QZS, 0);
3800 break; /* draft */
3801 case 11:
3802 ret = decode_ssr7(rtcm, SYS_GPS, 0);
3803 break; /* tentative */
3804 case 12:
3805 ret = decode_ssr7(rtcm, SYS_GAL, 0);
3806 break; /* tentative */
3807 case 13:
3808 ret = decode_ssr7(rtcm, SYS_QZS, 0);
3809 break; /* tentative */
3810 case 14:
3811 ret = decode_ssr7(rtcm, SYS_CMP, 0);
3812 break; /* tentative */
3813 case 4073:
3814 ret = decode_type4073(rtcm);
3815 break;
3816 case 4076:
3817 ret = decode_type4076(rtcm);
3818 break;
3819 case 4050:
3820 ret = decode_type4050(rtcm);
3821 break;
3822 case 2001:
3823 ret = decode_lcltrop(rtcm, type);
3824 break; /* tentative */
3825 case 2002:
3826 ret = decode_lcliono(rtcm, type);
3827 break; /* tentative */
3828 case 2003:
3829 ret = decode_lcliono(rtcm, type);
3830 break; /* tentative */
3831 case 2004:
3832 ret = decode_lcliono(rtcm, type);
3833 break; /* tentative */
3834 case 2005:
3835 ret = decode_lcliono(rtcm, type);
3836 break; /* tentative */
3837 case 2006:
3838 ret = decode_lcliono(rtcm, type);
3839 break; /* tentative */
3840 case 2011:
3841 ret = decode_lcltrop(rtcm, type);
3842 break; /* tentative */
3843 case 2012:
3844 ret = decode_lcliono(rtcm, type);
3845 break; /* tentative */
3846 case 2013:
3847 ret = decode_lcliono(rtcm, type);
3848 break; /* tentative */
3849 case 2014:
3850 ret = decode_lcliono(rtcm, type);
3851 break; /* tentative */
3852 case 2015:
3853 ret = decode_lcliono(rtcm, type);
3854 break; /* tentative */
3855 case 2016:
3856 ret = decode_lcliono(rtcm, type);
3857 break; /* tentative */
3858 }
3859 if (ret >= 0) {
3860 if (1001 <= type && type <= 1299) {
3861 rtcm->nmsg3[type - 1000]++; /* 1-299 */
3862 } else if (4070 <= type && type <= 4099) {
3863 rtcm->nmsg3[type - 3770]++; /* 300-329 */
3864 } else {
3865 rtcm->nmsg3[0]++; /* other */
3866 }
3867 }
3868 return ret;
3869}
MRTKLIB Atmosphere Module — Ionospheric and tropospheric models.
uint8_t obs2code(const char *obs)
Definition mrtk_obs.c:173
uint32_t getbitu(const uint8_t *buff, int pos, int len)
Extract unsigned bits from byte data.
Definition mrtk_bits.c:99
int32_t getbits(const uint8_t *buff, int pos, int len)
Extract signed bits from byte data.
Definition mrtk_bits.c:107
MRTKLIB Bits Module — Binary bit operations and CRC functions.
static const double ssrudint[16]
Definition mrtk_clas.c:44
#define D2R
Definition mrtk_coords.c:36
#define CLIGHT
Definition mrtk_coords.c:41
#define MAXSAT
Definition mrtk_coords.c:45
#define RE_WGS84
Definition mrtk_coords.c:38
void ecef2pos(const double *r, double *pos)
Transform ECEF position to geodetic position.
MRTKLIB Coordinates Module — Coordinate transformations and geometry.
#define SYS_GPS
Definition mrtk_eph.c:65
#define SYS_SBS
Definition mrtk_eph.c:66
#define SYS_QZS
Definition mrtk_eph.c:69
#define SYS_IRN
Definition mrtk_eph.c:71
#define SYS_CMP
Definition mrtk_eph.c:70
#define SYS_GAL
Definition mrtk_eph.c:68
#define SYS_GLO
Definition mrtk_eph.c:67
MRTKLIB Broadcast Ephemeris Module — Satellite orbit/clock types and Kepler/GLONASS/SBAS orbit comput...
double code2freq(int sys, uint8_t code, int fcn)
Definition mrtk_obs.c:236
#define SNR_UNIT
#define CODE_L5Q
#define CODE_L2Q
#define CODE_L6C
#define CODE_L1S
#define CODE_L5I
#define CODE_L2X
#define CODE_L1L
#define MAXOBS
#define MINPRNQZS
#define CODE_L5X
#define CODE_L7X
#define CODE_L2P
#define CODE_L2I
#define CODE_L6S
#define MAXCODE
#define CODE_L1C
#define CODE_L6I
#define CODE_L2C
#define CODE_L7I
#define CODE_L6X
#define CODE_NONE
#define CODE_L4B
#define CODE_L1Y
#define CODE_L8Q
#define CODE_L5P
#define CODE_L3Q
#define CODE_L5D
#define CODE_L3I
#define CODE_L1B
#define CODE_L2S
#define CODE_L6L
#define CODE_L7Q
#define CODE_L1W
#define CODE_L6B
#define CODE_L8X
#define CODE_L1M
#define CODE_L2W
#define CODE_L2L
#define CODE_L1Z
#define CODE_L1D
#define CODE_L2D
#define CODE_L2Y
#define CODE_L8I
#define CODE_L1P
#define CODE_L6A
#define CODE_L2M
#define CODE_L6Q
#define CODE_L6Z
#define CODE_L1X
#define CODE_L4A
#define CODE_L1A
int satno(int sys, int prn)
Convert satellite system+prn/slot number to satellite number.
Definition mrtk_nav.c:58
#define DFRQ2_GLO
Definition mrtk_obs.c:77
#define FREQ5
Definition mrtk_obs.c:69
#define FREQ2
Definition mrtk_obs.c:68
#define FREQ8
Definition mrtk_obs.c:72
#define FREQ6
Definition mrtk_obs.c:70
#define FREQ2_CMP
Definition mrtk_obs.c:82
#define FREQ9
Definition mrtk_obs.c:73
int getcodepri(int sys, uint8_t code, const char *opt)
Get code priority for multiple codes in a frequency.
Definition mrtk_obs.c:276
#define R2D
Definition mrtk_obs.c:51
#define FREQ7
Definition mrtk_obs.c:71
#define FREQ1
Definition mrtk_obs.c:67
#define FREQ1a_GLO
Definition mrtk_obs.c:79
#define FREQ2_GLO
Definition mrtk_obs.c:76
#define FREQ1_GLO
Definition mrtk_obs.c:74
#define FREQ3_CMP
Definition mrtk_obs.c:83
#define FREQ1_CMP
Definition mrtk_obs.c:81
#define FREQ2a_GLO
Definition mrtk_obs.c:80
int code2freq_idx(int sys, uint8_t code)
Convert system and obs code to frequency index (obsdef-based).
Definition mrtk_obs.c:225
#define DFRQ1_GLO
Definition mrtk_obs.c:75
#define FREQ3_GLO
Definition mrtk_obs.c:78
MRTKLIB Observation Module — Observation data types and utility functions.
static rtcm_t * rtcm
#define MINPRNSBS
#define P2_10
#define P2_31
Definition mrtk_rcvraw.c:56
#define P2_28
Definition mrtk_rcvraw.c:72
#define P2_41
Definition mrtk_rcvraw.c:74
#define P2_55
Definition mrtk_rcvraw.c:64
#define P2_50
Definition mrtk_rcvraw.c:63
#define P2_29
Definition mrtk_rcvraw.c:54
#define P2_66
Definition mrtk_rcvraw.c:78
#define P2_24
Definition mrtk_rcvraw.c:52
#define P2_43
Definition mrtk_rcvraw.c:62
#define P2_40
Definition mrtk_rcvraw.c:61
#define P2_59
Definition mrtk_rcvraw.c:77
#define P2_46
Definition mrtk_rcvraw.c:75
#define P2_11
Definition mrtk_rcvraw.c:45
#define P2_19
Definition mrtk_rcvraw.c:48
#define P2_33
Definition mrtk_rcvraw.c:58
#define P2_6
Definition mrtk_rcvraw.c:44
#define P2_20
Definition mrtk_rcvraw.c:49
#define P2_34
Definition mrtk_rcvraw.c:73
#define P2_32
Definition mrtk_rcvraw.c:57
#define P2_5
Definition mrtk_rcvraw.c:43
#define P2_30
Definition mrtk_rcvraw.c:55
#define SC2RAD
Definition mrtk_rcvraw.c:33
static int decode_type1029(rtcm_t *rtcm)
static int decode_type1033(rtcm_t *rtcm)
static int decode_ssr6(rtcm_t *rtcm, int sys, int subtype)
static uint16_t snratio(double snr)
Definition mrtk_rtcm3.c:244
static int decode_msm6(rtcm_t *rtcm, int sys)
static int decode_type1021(rtcm_t *rtcm)
const uint8_t ssr_sig_qzs[32]
Definition mrtk_rtcm3.c:166
static int decode_ssr1_head(rtcm_t *rtcm, int sys, int subtype, int *sync, int *iod, double *udint, int *refd, int *hsize)
static int decode_type1031(rtcm_t *rtcm)
static int decode_type4076(rtcm_t *rtcm)
static double getbitg(const uint8_t *buff, int pos, int len)
Definition mrtk_rtcm3.c:174
static void adjweek(rtcm_t *rtcm, double tow)
Definition mrtk_rtcm3.c:179
static void sigindex(int sys, const uint8_t *code, int n, const char *opt, int *idx)
static int decode_type1030(rtcm_t *rtcm)
int decode_qzss_l6emsg(rtcm_t *rtcm)
static int decode_type1045(rtcm_t *rtcm)
static int decode_ssr4(rtcm_t *rtcm, int sys, int subtype)
static int decode_type1038(rtcm_t *rtcm)
static int decode_type4073(rtcm_t *rtcm)
static int decode_type1008(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:610
static int adjbdtweek(int week)
Definition mrtk_rtcm3.c:196
static int decode_ssr7_head(rtcm_t *rtcm, int sys, int subtype, int *sync, int *iod, double *udint, int *dispe, int *mw, int *hsize)
static int decode_ssr_epoch(rtcm_t *rtcm, int sys, int subtype)
static int test_staid(rtcm_t *rtcm, int staid)
Definition mrtk_rtcm3.c:270
static int decode_ssr7(rtcm_t *rtcm, int sys, int subtype)
static int decode_type1044(rtcm_t *rtcm)
static int decode_msm5(rtcm_t *rtcm, int sys)
static int decode_type1032(rtcm_t *rtcm)
const uint8_t ssr_sig_gps[32]
Definition mrtk_rtcm3.c:158
#define RANGE_MS
Definition mrtk_rtcm3.c:86
const uint8_t ssr_sig_gal[32]
Definition mrtk_rtcm3.c:163
static int decode_msm_head(rtcm_t *rtcm, int sys, int *sync, int *iod, msm_h_t *h, int *hsize)
static int decode_type4050(rtcm_t *rtcm)
const char * msm_sig_glo[32]
Definition mrtk_rtcm3.c:133
const uint8_t ssr_sig_glo[32]
Definition mrtk_rtcm3.c:161
static int decode_type1004(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:403
const uint8_t ssr_sig_sbs[32]
Definition mrtk_rtcm3.c:170
#define PRUNIT_GLO
Definition mrtk_rtcm3.c:85
static int decode_type1023(rtcm_t *rtcm)
static int decode_type1019(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:842
static int decode_type1230(rtcm_t *rtcm)
static int decode_type1025(rtcm_t *rtcm)
static double getbits_38(const uint8_t *buff, int pos)
Definition mrtk_rtcm3.c:481
static int decode_type1037(rtcm_t *rtcm)
static int decode_msm0(rtcm_t *rtcm, int sys)
static void adjday_glot(rtcm_t *rtcm, double tod)
Definition mrtk_rtcm3.c:205
const char * msm_sig_gps[32]
Definition mrtk_rtcm3.c:127
static int decode_type1012(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:762
static int decode_type1020(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:954
const uint8_t ssr_sig_cmp[32]
Definition mrtk_rtcm3.c:168
static int decode_type1007(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:574
static int decode_type1009(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:690
const char * msm_sig_irn[32]
Definition mrtk_rtcm3.c:153
int decode_rtcm3(rtcm_t *rtcm)
Decode RTCM ver.3 message (called from rtcm.c).
static int lossoflock(rtcm_t *rtcm, int sat, int idx, int lock)
Definition mrtk_rtcm3.c:238
static int decode_ssr2(rtcm_t *rtcm, int sys, int subtype)
static int decode_type1003(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:394
const char * msm_sig_gal[32]
Definition mrtk_rtcm3.c:137
static int decode_type1046(rtcm_t *rtcm)
static double adjcp(rtcm_t *rtcm, int sat, int idx, double cp)
Definition mrtk_rtcm3.c:226
static int decode_type1035(rtcm_t *rtcm)
static int decode_head1009(rtcm_t *rtcm, int *sync)
Definition mrtk_rtcm3.c:653
static int decode_type1010(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:699
static int decode_msm4(rtcm_t *rtcm, int sys)
static int decode_msm7(rtcm_t *rtcm, int sys)
static int decode_type1005(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:485
static int decode_ssr1(rtcm_t *rtcm, int sys, int subtype)
static int decode_type1006(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:528
static int decode_type1027(rtcm_t *rtcm)
static int obsindex(obs_t *obs, gtime_t time, int sat)
Definition mrtk_rtcm3.c:246
static int decode_type1002(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:340
static int decode_type1024(rtcm_t *rtcm)
static int decode_type1026(rtcm_t *rtcm)
#define PRUNIT_GPS
Definition mrtk_rtcm3.c:84
static int decode_ssr3(rtcm_t *rtcm, int sys, int subtype)
static void save_msm_obs(rtcm_t *rtcm, int sys, msm_h_t *h, const double *r, const double *pr, const double *cp, const double *rr, const double *rrf, const double *cnr, const int *lock, const int *ex, const int *half)
const char * msm_sig_sbs[32]
Definition mrtk_rtcm3.c:145
static int decode_type1013(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:840
static int decode_type1039(rtcm_t *rtcm)
static int decode_type1001(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:331
static int decode_ssr2_head(rtcm_t *rtcm, int sys, int subtype, int *sync, int *iod, double *udint, int *hsize)
static int decode_type1042(rtcm_t *rtcm)
static int decode_type1011(rtcm_t *rtcm)
Definition mrtk_rtcm3.c:753
static int decode_head1001(rtcm_t *rtcm, int *sync)
Definition mrtk_rtcm3.c:294
const char * msm_sig_qzs[32]
Definition mrtk_rtcm3.c:141
static int decode_type1041(rtcm_t *rtcm)
static int decode_ssr5(rtcm_t *rtcm, int sys, int subtype)
static int decode_type1034(rtcm_t *rtcm)
static int decode_type1022(rtcm_t *rtcm)
const char * msm_sig_cmp[32]
Definition mrtk_rtcm3.c:149
int decode_lcliono(rtcm_t *rtcm, int type)
Decode local ionospheric delay correction grid RTCM message.
int decode_lcltrop(rtcm_t *rtcm, int type)
Decode local tropospheric delay correction grid RTCM message.
MRTKLIB RTCM Module — RTCM message types and functions.
#define SSR_VENDOR_RTCM
Definition mrtk_rtkpos.c:66
MRTKLIB System Module — OS/filesystem utility functions.
gtime_t bdt2time(int week, double sec)
Convert BeiDou time week/tow to gtime_t.
Definition mrtk_time.c:229
gtime_t gpst2time(int week, double sec)
Convert GPS week/tow to gtime_t.
Definition mrtk_time.c:165
gtime_t gpst2bdt(gtime_t t)
Convert GPS time to BeiDou time.
Definition mrtk_time.c:458
void time2str(gtime_t t, char *s, int n)
Convert gtime_t struct to string.
Definition mrtk_time.c:507
gtime_t gpst2utc(gtime_t t)
Convert GPS time to UTC considering leap seconds.
Definition mrtk_time.c:422
double timediff(gtime_t t1, gtime_t t2)
Compute time difference (t1 - t2).
Definition mrtk_time.c:279
double time2gpst(gtime_t t, int *week)
Convert gtime_t to GPS week/tow.
Definition mrtk_time.c:181
double time2bdt(gtime_t t, int *week)
Convert gtime_t to BeiDou time week/tow.
Definition mrtk_time.c:245
int adjgpsweek(int week)
Adjust GPS week number using CPU time.
Definition mrtk_time.c:553
gtime_t timeadd(gtime_t t, double sec)
Add seconds to gtime_t.
Definition mrtk_time.c:265
gtime_t bdt2gpst(gtime_t t)
Convert BeiDou time to GPS time.
Definition mrtk_time.c:465
gtime_t utc2gpst(gtime_t t)
Convert UTC to GPS time considering leap seconds.
Definition mrtk_time.c:440
gtime_t timeget(void)
Get current time in UTC.
Definition mrtk_time.c:289
void trace(mrtk_ctx_t *ctx, int level, const char *format,...)
Output trace message.
Definition mrtk_trace.c:78
MRTKLIB Trace Module — debug trace and logging functions.
GPS/GAL/QZS/BDS/IRN broadcast ephemeris type.
Definition mrtk_eph.h:77
double OMG0
Definition mrtk_eph.h:90
double omg
Definition mrtk_eph.h:90
int sat
Definition mrtk_eph.h:78
gtime_t ttr
Definition mrtk_eph.h:88
double OMGd
Definition mrtk_eph.h:90
double f1
Definition mrtk_eph.h:94
double f0
Definition mrtk_eph.h:94
int svh
Definition mrtk_eph.h:81
double e
Definition mrtk_eph.h:90
double idot
Definition mrtk_eph.h:90
double M0
Definition mrtk_eph.h:90
double A
Definition mrtk_eph.h:90
double cis
Definition mrtk_eph.h:91
int flag
Definition mrtk_eph.h:86
gtime_t toe
Definition mrtk_eph.h:88
double fit
Definition mrtk_eph.h:93
int week
Definition mrtk_eph.h:82
gtime_t toc
Definition mrtk_eph.h:88
double cic
Definition mrtk_eph.h:91
double tgd[6]
Definition mrtk_eph.h:95
double cus
Definition mrtk_eph.h:91
double cuc
Definition mrtk_eph.h:91
double toes
Definition mrtk_eph.h:92
int code
Definition mrtk_eph.h:83
int type
Definition mrtk_eph.h:100
double crs
Definition mrtk_eph.h:91
double i0
Definition mrtk_eph.h:90
int iode
Definition mrtk_eph.h:79
int sva
Definition mrtk_eph.h:80
double deln
Definition mrtk_eph.h:90
double crc
Definition mrtk_eph.h:91
double f2
Definition mrtk_eph.h:94
int iodc
Definition mrtk_eph.h:79
GLONASS broadcast ephemeris type.
Definition mrtk_eph.h:111
double vel[3]
Definition mrtk_eph.h:121
double dtaun
Definition mrtk_eph.h:124
gtime_t toe
Definition mrtk_eph.h:118
double pos[3]
Definition mrtk_eph.h:120
int sva
Definition mrtk_eph.h:117
int flags
Definition mrtk_eph.h:116
int iode
Definition mrtk_eph.h:113
double gamn
Definition mrtk_eph.h:123
double acc[3]
Definition mrtk_eph.h:122
int age
Definition mrtk_eph.h:117
int svh
Definition mrtk_eph.h:115
double taun
Definition mrtk_eph.h:123
gtime_t tof
Definition mrtk_eph.h:119
int sat
Definition mrtk_eph.h:112
int frq
Definition mrtk_eph.h:114
GNSS time representation.
Definition mrtk_time.h:49
uint8_t cellmask[64]
Definition mrtk_rtcm3.c:123
uint8_t tint_s
Definition mrtk_rtcm3.c:119
uint8_t iod
Definition mrtk_rtcm3.c:114
uint8_t sigs[32]
Definition mrtk_rtcm3.c:122
uint8_t clk_str
Definition mrtk_rtcm3.c:116
uint8_t smooth
Definition mrtk_rtcm3.c:118
uint8_t time_s
Definition mrtk_rtcm3.c:115
uint8_t nsat
Definition mrtk_rtcm3.c:120
uint8_t nsig
Definition mrtk_rtcm3.c:120
uint8_t sats[64]
Definition mrtk_rtcm3.c:121
uint8_t clk_ext
Definition mrtk_rtcm3.c:117
Observation data collection.
Definition mrtk_obs.h:59
obsd_t * data
Definition mrtk_obs.h:61
int n
Definition mrtk_obs.h:60
float D[5+5]
Definition mrtk_obs.h:52
gtime_t time
Definition mrtk_obs.h:45
uint8_t sat
Definition mrtk_obs.h:46
uint8_t LLI[5+5]
Definition mrtk_obs.h:48
double L[5+5]
Definition mrtk_obs.h:50
double P[5+5]
Definition mrtk_obs.h:51
uint16_t SNR[5+5]
Definition mrtk_obs.h:47
uint8_t code[5+5]
Definition mrtk_obs.h:49
RTCM control struct type.
Definition mrtk_rtcm.h:50