MRTKLIB 0.7.14
Modernized GNSS Positioning Library
Loading...
Searching...
No Matches
mrtk_madoca.c
Go to the documentation of this file.
1/*------------------------------------------------------------------------------
2 * mrtk_madoca.c : MADOCA-PPP processing 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 "mrtklib/mrtk_madoca.h"
17
18#include <math.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include "mrtklib/mrtk_bits.h"
24#include "mrtklib/mrtk_const.h"
25#include "mrtklib/mrtk_l6.h"
26#include "mrtklib/mrtk_trace.h"
27
28/* local system constants (duplicated to avoid rtklib.h dependency) ----------*/
29#define SYS_NONE 0x00
30#define SYS_GPS 0x01
31#define SYS_SBS 0x02
32#define SYS_GLO 0x04
33#define SYS_GAL 0x08
34#define SYS_QZS 0x10
35#define SYS_CMP 0x20
36#define SYS_IRN 0x40
37
38/* forward declarations (implemented in rtkcmn.c, resolved at link time) -----*/
39extern int satno(int sys, int prn);
40extern int satsys_bd2(int sat, int* prn);
41extern void satno2id(int sat, char* id);
42extern double time2gpst(gtime_t t, int* week);
43extern gtime_t utc2gpst(gtime_t t);
44extern gtime_t timeget(void);
45extern char* time_str(gtime_t t, int n);
46
47/* constants -----------------------------------------------------------------*/
48
49#define L6DATA_BYTELEN 212 /* L6 message data part byte length */
50
51#define RTCM_MN_CSSR 4073 /* Compact SSR message number */
52
53#define MCSSR_BYTELEN 1060 /* MADOCA-PPP message 5 frames byte length */
54
55#define MCSSR_ST_MASK 1 /* Compact SSR Mask */
56#define MCSSR_ST_OC 2 /* Compact SSR GNSS Orbit Correction */
57#define MCSSR_ST_CC 3 /* Compact SSR GNSS Clock Correction */
58#define MCSSR_ST_CB 4 /* Compact SSR GNSS Satellite Code Bias */
59#define MCSSR_ST_PB 5 /* Compact SSR GNSS Satellite Phase Bias */
60#define MCSSR_ST_URA 7 /* Compact SSR GNSS URA */
61
62#define MCSSR_MAX_SYS 16 /* GNSS ID (Table 4.2.2-7) w/o SBS */
63#define MCSSR_SYS_GPS 0
64#define MCSSR_SYS_GLO 1
65#define MCSSR_SYS_GAL 2
66#define MCSSR_SYS_BDS 3
67#define MCSSR_SYS_QZS 4
68#define MCSSR_SYS_BD3 7
69
70#define MCSSR_MAX_SATMASK 40 /* Satellite Mask (Table 4.2.2-8) */
71#define MCSSR_SATMASK_GPS_U 0xFFFFFFFFu /* Note, U and L for -Wlong-long Avoidance */
72#define MCSSR_SATMASK_GPS_L 0xFF
73#define MCSSR_SATMASK_GLO_U 0xFFFFFF00u
74#define MCSSR_SATMASK_GLO_L 0x00
75#define MCSSR_SATMASK_GAL_U 0xFFFFFFFFu
76#define MCSSR_SATMASK_GAL_L 0xF8
77#define MCSSR_SATMASK_BDS_U 0xFFFFFFFFu
78#define MCSSR_SATMASK_BDS_L 0xFF
79#define MCSSR_SATMASK_QZS_U 0xFFC00000u
80#define MCSSR_SATMASK_QZS_L 0x00
81#define MCSSR_SATMASK_BD3_U 0xFFFFFFFFu
82#define MCSSR_SATMASK_BD3_L 0xFF
83#define MCSSR_SATMASK_RSV_U 0xFFFFFFFFu
84#define MCSSR_SATMASK_RSV_L 0xFF
85
86#define MCSSR_MAX_SIGMASK 16 /* Signal Mask (Table 4.2.2-9) */
87
88#define MCSSR_INVALID_15BIT -16384 /* Invalid Value (Table. 4.2.2-11, etc.) */
89#define MCSSR_INVALID_13BIT -4096
90#define MCSSR_INVALID_11BIT -1024
91
92#define MCSSR_MAX_PRN 7 /* Max defined MADOCA-PPP L6E signal (Table 3-1) */
93
94/* SSR update intervals (Table 4.2.2-6) --------------------------------------*/
95static const double ssrudint[16] = {1, 2, 5, 10, 15, 30, 60, 120, 240, 300, 600, 900, 1800, 3600, 7200, 10800};
96
97/* Compact SSR Signal mask (Table 4.2.2-9) w/o SBS ---------------------------*/
105 CODE_L7X, 0, 0, 0, 0, 0, 0, 0};
110
111const uint8_t cssr_sig_rsv[16] = {0};
112
113/* MADOCA-PPP Sub Type Transmission Pattern (Figure 4.2.2-1) -----------------*/
114/* note : Change MCSSR_BYTELEN when defining 6 or more. */
115static const int framelen[] = {
116 /* frame length(-1 : invalid) */
117 -1, 5, -1, 3, 5, 5, -1, 3, /* ST 0, 1, 2, 3, 4, 5, 6, 7 */
118 -1, -1, -1, -1, -1, -1, -1, -1 /* ST 8, 9,10,11,12,13,14,15 */
119};
120
121typedef struct {
122 gtime_t gt; /* current Epoch Time 1s */
123 int mgfid; /* current Msg. Gen. Facility ID */
124 int prn; /* current Msg. PRN */
125 int prn_chk_cnt; /* check counter for PRN auto selection */
126 uint8_t buff[MCSSR_BYTELEN]; /* Compact-SSR Message */
127 int ibuff; /* indicate the end of buff */
128 int satlist[MAXSAT]; /* 0 : invalid, 1... : satno(G01...) */
129 int gidlist[MAXSAT]; /* GNSS ID */
130 int cellmask[MAXSAT]; /* Cellmask */
131 int ncell[MAXSAT]; /* No. of cellmask flags */
132 int siglist[MCSSR_MAX_SYS][MCSSR_MAX_SIGMASK]; /* 0:Terminate,1...:CODE_xxx */
133 int siglist_bd3[MCSSR_MAX_SIGMASK]; /* GNSS ID 3 signal list read by the BDS-3 table */
134 int nsat[MCSSR_MAX_SYS]; /* No. of sat */
135 int nsig[MCSSR_MAX_SYS]; /* No. of signal */
136 int ns; /* total No. of */
137 int maxframe; /* set framelen[first subtype] */
138 int frame; /* frame counter */
139 int tow0; /* for Hourly Epoch Time 1s */
140 int ep0; /* for Hourly Epoch Time 1s regresses check */
141 int iod; /* IOD SSR */
142} mcssr_t;
143
145static int _mcssr_ch = 0; /* current channel index */
146
147/* signal code of a cell -------------------------------------------------------
148 * IS-QZSS-MDC-005: a BDS-3 satellite sent in GNSS ID 3 (PRN 1-18, after the
149 * April 2026 BeiDou PRN reassignment) has its signal mask read with the
150 * GNSS ID 7 (BDS-3) table. returns 0 for a signal undefined in the table.
151 *----------------------------------------------------------------------------*/
152static int mcssr_sigcode(const mcssr_t* mc, int gnssid, int sat, int k) {
153 if (gnssid == MCSSR_SYS_BDS && sat > 0 && satsys_bd2(sat, NULL) == SYS_CMP) {
154 return mc->siglist_bd3[k];
155 }
156 return mc->siglist[gnssid][k];
157}
158
159/* count 16 bit flags --------------------------------------------------------*/
160static int flgcnt16(const uint16_t flg) {
161 int i, cnt = 0;
162
163 for (i = 0; i < 16; i++) {
164 if ((flg >> i) & 0x1) {
165 cnt++;
166 }
167 }
168 return cnt;
169}
170/* ---------------------------------------------------------------------------*/
171static int gnssid2sys(const int gnssid) {
172 switch (gnssid) {
173 case MCSSR_SYS_GPS:
174 return SYS_GPS;
175 case MCSSR_SYS_GLO:
176 return SYS_GLO;
177 case MCSSR_SYS_GAL:
178 return SYS_GAL;
179 case MCSSR_SYS_BDS:
180 return SYS_CMP;
181 case MCSSR_SYS_QZS:
182 return SYS_QZS;
183 case MCSSR_SYS_BD3:
184 return SYS_CMP;
185 }
186 return SYS_NONE;
187}
188/* ---------------------------------------------------------------------------*/
189static int svmask2list(const uint64_t mask, const int gnssid, int* satlist, int* gidlist) {
190 int i, offp, ns = 0;
191 uint64_t svbit = (uint64_t)1 << (MCSSR_MAX_SATMASK - 1);
192
193 for (i = 0; i < MCSSR_MAX_SATMASK; i++) {
194 if (mask & svbit) {
195 switch (gnssid) {
196 case MCSSR_SYS_GPS:
197 offp = 1;
198 break;
199 case MCSSR_SYS_GLO:
200 offp = 1;
201 break;
202 case MCSSR_SYS_GAL:
203 offp = 1;
204 break;
205 case MCSSR_SYS_BDS:
206 offp = 1;
207 break;
208 case MCSSR_SYS_QZS:
209 offp = 193;
210 break;
211 case MCSSR_SYS_BD3:
212 offp = 19;
213 break;
214 default:
215 offp = 1;
216 }
217 satlist[ns] = satno(gnssid2sys(gnssid), offp + i);
218 gidlist[ns] = gnssid;
219 ns++;
220 }
221 svbit >>= 1;
222 }
223 return ns;
224}
225
226/* ---------------------------------------------------------------------------*/
227static int sigmask2list(const uint16_t mask, const int gnssid, int* siglist) {
228 int i, nsig = 0;
229 const uint8_t* sigs;
230 uint16_t sigbit = (uint16_t)1 << (MCSSR_MAX_SIGMASK - 1);
231
232 switch (gnssid) {
233 case MCSSR_SYS_GPS:
234 sigs = cssr_sig_gps;
235 break;
236 case MCSSR_SYS_GLO:
237 sigs = cssr_sig_glo;
238 break;
239 case MCSSR_SYS_GAL:
240 sigs = cssr_sig_gal;
241 break;
242 case MCSSR_SYS_BDS:
243 sigs = cssr_sig_bd2;
244 break;
245 case MCSSR_SYS_QZS:
246 sigs = cssr_sig_qzs;
247 break;
248 case MCSSR_SYS_BD3:
249 sigs = cssr_sig_bd3;
250 break;
251 default:
252 sigs = cssr_sig_rsv;
253 }
254
255 for (i = 0; i < MCSSR_MAX_SIGMASK; i++) {
256 if (mask & sigbit) {
257 siglist[nsig] = sigs[i];
258 nsig++;
259 }
260 sigbit >>= 1;
261 }
262 return nsig;
263}
264
265/* adjust weekly rollover of gps time ----------------------------------------*/
266static void adjweek(gtime_t* gt, double tow) {
267 double tow_p;
268 int week;
269
270 /* if no time, get cpu time */
271 if (gt->time == 0) {
272 *gt = utc2gpst(timeget());
273 }
274 tow_p = time2gpst(*gt, &week);
275 if (tow < tow_p - 302400.0) {
276 tow += 604800.0;
277 } else if (tow > tow_p + 302400.0) {
278 tow -= 604800.0;
279 }
280 *gt = gpst2time(week, tow);
281}
282
283/* decode MADOCA-PPP L6E CSSR header -----------------------------------------*/
284static int decode_mcssr_head(const mcssr_t* mc, int* sync, int* iod, int* ep, double* udint, int i, const int st) {
285 int n, udi;
286
287 n = (st == MCSSR_ST_MASK) ? 20 : 12;
288 *ep = getbitu(mc->buff, i, n);
289 i += n; /* GPS or GNSS Hourly Epoch Time 1s */
290 udi = getbitu(mc->buff, i, 4);
291 i += 4; /* SSR Update Interval */
292 *sync = getbitu(mc->buff, i, 1);
293 i += 1; /* Multiple Message Indicator */
294 *iod = getbitu(mc->buff, i, 4);
295 i += 4; /* IOD SSR */
296 *udint = ssrudint[udi];
297
298 trace(NULL, 4, "decode_mcssr_head: st=%d, ep=%d, udi=%d, sync=%d, iod=%d\n", st, *ep, udi, *sync, *iod);
299 return i;
300}
301
302/* decode MADOCA-PPP L6E CSSR ST1 mask message -------------------------------*/
303static int decode_mcssr_mask(mcssr_t* mc, int i) {
304 int j, k, sync, iod, ep, ngnss, gnssid, cmaflg, nsat, nsig;
305 uint64_t svmask, gnssmask;
306 uint16_t sigmask, cellmask;
307 double udint;
308
309 i = decode_mcssr_head(mc, &sync, &iod, &ep, &udint, i, MCSSR_ST_MASK);
310
311 mc->tow0 = ep / 3600 * 3600;
312 mc->ep0 = ep % 3600;
313 adjweek(&mc->gt, ep);
314 mc->iod = iod;
315 mc->ns = 0;
316 for (j = 0; j < MCSSR_MAX_SYS; j++) {
317 mc->nsig[j] = 0;
318 mc->nsat[j] = 0;
319 }
320 for (j = 0; j < MAXSAT; j++) {
321 mc->cellmask[j] = 0;
322 }
323
324 ngnss = getbitu(mc->buff, i, 4);
325 i += 4; /* No. of GNSS */
326 for (j = 0; j < ngnss; j++) {
327 gnssid = getbitu(mc->buff, i, 4);
328 i += 4; /* GNSS ID */
329 switch (gnssid) {
330 case MCSSR_SYS_GPS:
331 gnssmask = ((uint64_t)MCSSR_SATMASK_GPS_U) << 8 | MCSSR_SATMASK_GPS_L;
332 break;
333 case MCSSR_SYS_GLO:
334 gnssmask = ((uint64_t)MCSSR_SATMASK_GLO_U) << 8 | MCSSR_SATMASK_GLO_L;
335 break;
336 case MCSSR_SYS_GAL:
337 gnssmask = ((uint64_t)MCSSR_SATMASK_GAL_U) << 8 | MCSSR_SATMASK_GAL_L;
338 break;
339 case MCSSR_SYS_BDS:
340 gnssmask = ((uint64_t)MCSSR_SATMASK_BDS_U) << 8 | MCSSR_SATMASK_BDS_L;
341 break;
342 case MCSSR_SYS_QZS:
343 gnssmask = ((uint64_t)MCSSR_SATMASK_QZS_U) << 8 | MCSSR_SATMASK_QZS_L;
344 break;
345 case MCSSR_SYS_BD3:
346 gnssmask = ((uint64_t)MCSSR_SATMASK_BD3_U) << 8 | MCSSR_SATMASK_BD3_L;
347 break;
348 default:
349 gnssmask = ((uint64_t)MCSSR_SATMASK_RSV_U) << 8 | MCSSR_SATMASK_RSV_L;
350 trace(NULL, 2, "decode_mcssr_mask: reserved gnssid=%d\n", gnssid);
351 }
352 svmask = (uint64_t)getbitu(mc->buff, i, 8) << 32;
353 i += 8;
354 svmask |= getbitu(mc->buff, i, 32);
355 i += 32; /* Sat mask */
356 svmask &= gnssmask;
357 sigmask = getbitu(mc->buff, i, 16);
358 i += 16; /* Signal mask */
359 cmaflg = getbitu(mc->buff, i, 1);
360 i += 1; /* Cell-mask Avail.Flag */
361 nsat = svmask2list(svmask, gnssid, &mc->satlist[mc->ns], &mc->gidlist[mc->ns]);
362 nsig = sigmask2list(sigmask, gnssid, mc->siglist[gnssid]);
363 if (gnssid == MCSSR_SYS_BDS) {
365 }
366
367 trace(NULL, 4, "decode_mcssr_mask: gnssid=%d, svmask=0x%02X%08X, sigmask=0x%X, cmaflg=%d, nsat=%d, nsig=%d\n",
368 gnssid, (uint8_t)(svmask >> 32), (uint32_t)(svmask), sigmask, cmaflg, nsat, nsig);
369
370 if (cmaflg) {
371 for (k = 0; k < nsat; k++) {
372 cellmask = getbitu(mc->buff, i, nsig);
373 i += nsig; /* Cell-mask */
374 mc->cellmask[mc->ns + k] = cellmask;
375 mc->ncell[mc->ns + k] = flgcnt16(cellmask);
376 trace(NULL, 4, "decode_mcssr_mask: k=%d, cellmask=0x%X, ncell=%2d\n", k, cellmask,
377 mc->ncell[mc->ns + k]);
378 }
379 } else {
380 for (k = 0; k < nsat; k++) {
381 mc->cellmask[mc->ns + k] = (1 << nsig) - 1; /* ex) 4=0xF,5=0x1F */
382 mc->ncell[mc->ns + k] = nsig;
383 }
384 }
385 mc->nsat[gnssid] = nsat;
386 mc->nsig[gnssid] = nsig;
387 mc->ns += nsat;
388 }
389 return i;
390}
391
392/* decode MADOCA-PPP L6E CSSR ST2 orbit correction ---------------------------*/
393static int decode_mcssr_oc(mcssr_t* mc, ssr_t* ssr, int i, int apply) {
394 int j, k, n, sync, iod, ep, sat, iode, deph[3];
395 double udint;
396 char satid[8];
397
398 i = decode_mcssr_head(mc, &sync, &iod, &ep, &udint, i, MCSSR_ST_OC);
399 if (mc->tow0 < 0) {
400 trace(NULL, 2, "decode_mcssr_oc: %s,unprocessed mask\n", time_str(mc->gt, 3));
401 apply = 0;
402 return -1;
403 } else {
404 if (mc->ep0 > ep) {
405 ep += 3600;
406 }
407 adjweek(&mc->gt, mc->tow0 + ep);
408 if (mc->iod != iod) {
409 trace(NULL, 2, "decode_mcssr_oc: %s,iod mismatch %d != %d\n", time_str(mc->gt, 3), mc->iod, iod);
410 apply = 0;
411 }
412 }
413 for (j = 0; j < mc->ns; j++) {
414 n = (mc->gidlist[j] == MCSSR_SYS_GAL) ? 10 : 8;
415 iode = getbitu(mc->buff, i, n);
416 i += n; /* IODE */
417 deph[0] = getbits(mc->buff, i, 15);
418 i += 15; /* Delta Radial */
419 deph[1] = getbits(mc->buff, i, 13);
420 i += 13; /* Delta Along-Track */
421 deph[2] = getbits(mc->buff, i, 13);
422 i += 13; /* Delta Cross-Track */
423
424 sat = mc->satlist[j];
425 satno2id(sat, satid);
426 trace(NULL, 4, "decode_mcssr_oc :%s,i=%4d,j=%3d,sat=%s,iode=%4d,deph=%6d,%6d,%6d,%8.4f,%8.4f,%8.4f\n",
427 time_str(mc->gt, 3), i, j, satid, iode, deph[0], deph[1], deph[2], deph[0] * 0.0016, deph[1] * 0.0064,
428 deph[2] * 0.0064);
429
430 if (sat == 0) {
431 continue; /* unsupprted sat */
432 }
433 if ((deph[0] == MCSSR_INVALID_15BIT) || (deph[1] == MCSSR_INVALID_13BIT) || (deph[2] == MCSSR_INVALID_13BIT)) {
434 continue; /* invalid value */
435 }
436
437 if (apply) {
438 ssr[sat - 1].t0[0] = mc->gt;
439 ssr[sat - 1].udi[0] = udint;
440 ssr[sat - 1].iod[0] = iod;
441 ssr[sat - 1].iode = iode;
442 ssr[sat - 1].deph[0] = deph[0] * 0.0016;
443 ssr[sat - 1].deph[1] = deph[1] * 0.0064;
444 ssr[sat - 1].deph[2] = deph[2] * 0.0064;
445 for (k = 0; k < 3; k++) {
446 ssr[sat - 1].ddeph[k] = 0.0;
447 }
448 ssr[sat - 1].update = 1;
449 }
450 }
451 return i;
452}
453
454/* decode MADOCA-PPP L6E CSSR ST3 clock correction ---------------------------*/
455static int decode_mcssr_cc(mcssr_t* mc, ssr_t* ssr, int i, int apply) {
456 int j, sync, iod, ep, sat, dclk;
457 double udint;
458 char satid[8];
459
460 i = decode_mcssr_head(mc, &sync, &iod, &ep, &udint, i, MCSSR_ST_CC);
461 if (mc->tow0 < 0) {
462 trace(NULL, 2, "decode_mcssr_cc: %s,unprocessed mask\n", time_str(mc->gt, 3));
463 apply = 0;
464 return -1;
465 } else {
466 if (mc->ep0 > ep) {
467 ep += 3600;
468 }
469 adjweek(&mc->gt, mc->tow0 + ep);
470 if (mc->iod != iod) {
471 trace(NULL, 2, "decode_mcssr_cc: %s,iod mismatch %d != %d\n", time_str(mc->gt, 3), mc->iod, iod);
472 apply = 0;
473 }
474 }
475 for (j = 0; j < mc->ns; j++) {
476 dclk = getbits(mc->buff, i, 15);
477 i += 15; /* Delta Clock C0 */
478
479 sat = mc->satlist[j];
480 satno2id(sat, satid);
481
482 trace(NULL, 4, "decode_mcssr_cc :%s,i=%4d,j=%3d,sat=%s,dclk=%6d,%8.4f\n", time_str(mc->gt, 3), i, j, satid,
483 dclk, dclk * 0.0016);
484
485 if (sat == 0) {
486 continue; /* unsupprted sat */
487 }
488 if (dclk == MCSSR_INVALID_15BIT) {
489 continue; /* invalid value */
490 }
491
492 if (apply) {
493 ssr[sat - 1].t0[1] = mc->gt;
494 ssr[sat - 1].udi[1] = udint;
495 ssr[sat - 1].iod[1] = iod;
496 ssr[sat - 1].dclk[0] = dclk * 0.0016;
497 ssr[sat - 1].dclk[1] = 0.0;
498 ssr[sat - 1].dclk[2] = 0.0;
499 ssr[sat - 1].update = 1;
500 }
501 }
502 return i;
503}
504
505/* decode MADOCA-PPP L6E CSSR ST4 code bias ----------------------------------*/
506static int decode_mcssr_cb(mcssr_t* mc, ssr_t* ssr, int i, int apply) {
507 int j, k, sync, iod, ep, sat, nsig, mask, cb, flg, code;
508 int vcbias[MAXCODE] = {0};
509 double udint, cbias[MAXCODE];
510 char satid[8];
511
512 i = decode_mcssr_head(mc, &sync, &iod, &ep, &udint, i, MCSSR_ST_CB);
513 if (mc->tow0 < 0) {
514 trace(NULL, 2, "decode_mcssr_cb: %s,unprocessed mask\n", time_str(mc->gt, 3));
515 apply = 0;
516 return -1;
517 } else {
518 if (mc->ep0 > ep) {
519 ep += 3600;
520 }
521 adjweek(&mc->gt, mc->tow0 + ep);
522 if (mc->iod != iod) {
523 trace(NULL, 2, "decode_mcssr_cb: %s,iod mismatch %d != %d\n", time_str(mc->gt, 3), mc->iod, iod);
524 apply = 0;
525 }
526 }
527 for (j = 0; j < mc->ns; j++) {
528 for (k = 0; k < MAXCODE; k++) {
529 cbias[k] = 0.0;
530 vcbias[k] = 0;
531 }
532 sat = mc->satlist[j];
533 satno2id(sat, satid);
534 nsig = mc->nsig[mc->gidlist[j]];
535 mask = 1 << (nsig - 1);
536 /* advance the mask in the loop header: the skips below must not leave it
537 * on the current cell (upstream mdccssr.c re-reads it for a sparse mask) */
538 for (k = 0; k < nsig; k++, mask >>= 1) {
539 if ((flg = (mc->cellmask[j] & mask))) {
540 cb = getbits(mc->buff, i, 11);
541 i += 11; /* Code Bias */
542 trace(NULL, 4, "decode_mcssr_cb: %s,i=%4d,j=%3d,k=%2d,sat=%s,flg=0x%2X,sig=%2d,cb=%5d,%6.2f\n",
543 time_str(mc->gt, 3), i, j, k, satid, flg, mc->siglist[mc->gidlist[j]][k], cb, cb * 0.02);
544
545 if (sat == 0) {
546 continue; /* unsupprted sat */
547 }
548
549 code = mcssr_sigcode(mc, mc->gidlist[j], sat, k);
550 if (code <= 0) {
551 continue; /* undefined signal */
552 }
553 cbias[code - 1] = cb * 0.02;
554 vcbias[code - 1] = 1; /* 1:output */
555
556 if (cb == MCSSR_INVALID_11BIT) { /* invalid value */
557 cbias[code - 1] = SSR_INVALID_CBIAS;
558 trace(NULL, 3, "decode_mcssr_cb: invalid cbias %s %s %s\n", time_str(mc->gt, 3), satid,
559 code2obs(code));
560 }
561 }
562 }
563 if (apply && sat > 0) { /* sat 0 (unsupported): cells read above, nothing to store */
564 ssr[sat - 1].t0[4] = mc->gt;
565 ssr[sat - 1].udi[4] = udint;
566 ssr[sat - 1].iod[4] = iod;
567 for (k = 0; k < MAXCODE; k++) {
568 ssr[sat - 1].cbias[k] = (float)cbias[k];
569 ssr[sat - 1].vcbias[k] = vcbias[k];
570 }
571 ssr[sat - 1].update = 1;
572 }
573 }
574 return i;
575}
576
577/* decode MADOCA-PPP L6E CSSR ST5 phase bias ---------------------------------*/
578static int decode_mcssr_pb(mcssr_t* mc, ssr_t* ssr, int i, int apply) {
579 int j, k, sync, iod, ep, sat, nsig, mask, pb, di, flg, code;
580 int discnt[MAXCODE] = {0}, vpbias[MAXCODE] = {0};
581 double udint, pbias[MAXCODE];
582 char satid[8];
583
584 i = decode_mcssr_head(mc, &sync, &iod, &ep, &udint, i, MCSSR_ST_PB);
585 if (mc->tow0 < 0) {
586 trace(NULL, 2, "decode_mcssr_pb :%s,unprocessed mask\n", time_str(_mcssr[_mcssr_ch].gt, 3));
587 apply = 0;
588 return -1;
589 } else {
590 if (mc->ep0 > ep) {
591 ep += 3600;
592 }
593 adjweek(&mc->gt, mc->tow0 + ep);
594 if (mc->iod != iod) {
595 trace(NULL, 2, "decode_mcssr_pb: %s,iod mismatch %d != %d\n", time_str(mc->gt, 3), mc->iod, iod);
596 apply = 0;
597 }
598 }
599 for (j = 0; j < mc->ns; j++) {
600 for (k = 0; k < MAXCODE; k++) {
601 pbias[k] = 0.0;
602 discnt[k] = vpbias[k] = 0;
603 }
604 sat = mc->satlist[j];
605 satno2id(sat, satid);
606 nsig = mc->nsig[mc->gidlist[j]];
607 mask = 1 << (nsig - 1);
608 /* advance the mask in the loop header: the skips below must not leave it
609 * on the current cell (upstream mdccssr.c re-reads it for a sparse mask) */
610 for (k = 0; k < nsig; k++, mask >>= 1) {
611 if ((flg = (mc->cellmask[j] & mask))) {
612 pb = getbits(mc->buff, i, 15);
613 i += 15; /* Phase Bias */
614 di = getbitu(mc->buff, i, 2);
615 i += 2; /* Discontinuity Indicator */
616
617 trace(NULL, 4, "decode_mcssr_pb: %s,i=%4d,j=%3d,k=%2d,sat=%s,flg=0x%2X,sig=%2d,di=%d,pb=%5d,%7.3f\n",
618 time_str(mc->gt, 3), i, j, k, satid, flg, mc->siglist[mc->gidlist[j]][k], di, pb, pb * 0.001);
619
620 if (sat == 0) {
621 continue; /* unsupprted sat */
622 }
623
624 code = mcssr_sigcode(mc, mc->gidlist[j], sat, k);
625 if (code <= 0) {
626 continue; /* undefined signal */
627 }
628 pbias[code - 1] = pb * 0.001;
629 vpbias[code - 1] = 1; /* 1:output */
630 discnt[code - 1] = di;
631
632 if (pb == MCSSR_INVALID_15BIT) { /* invalid value */
633 pbias[code - 1] = SSR_INVALID_PBIAS;
634 }
635 }
636 }
637 if (apply && sat > 0) { /* sat 0 (unsupported): cells read above, nothing to store */
638 ssr[sat - 1].t0[5] = mc->gt;
639 ssr[sat - 1].udi[5] = udint;
640 ssr[sat - 1].iod[5] = iod;
641 ssr[sat - 1].yaw_ang = 0.0;
642 ssr[sat - 1].yaw_rate = 0.0;
643 for (k = 0; k < MAXCODE; k++) {
644 ssr[sat - 1].pbias[k] = (float)pbias[k];
645 ssr[sat - 1].vpbias[k] = vpbias[k];
646 ssr[sat - 1].discnt[k] = discnt[k];
647 }
648 ssr[sat - 1].update = 1;
649 }
650 }
651 return i;
652}
653
654/* decode MADOCA-PPP L6E CSSR ST7 URA ----------------------------------------*/
655static int decode_mcssr_ura(mcssr_t* mc, ssr_t* ssr, int i, int apply) {
656 int j, sync, iod, ep, sat, ura;
657 double udint;
658 char satid[8];
659
660 i = decode_mcssr_head(mc, &sync, &iod, &ep, &udint, i, MCSSR_ST_URA);
661 if (mc->tow0 < 0) {
662 trace(NULL, 2, "decode_mcssr_ura: %s,unprocessed mask\n", time_str(mc->gt, 3));
663 apply = 0;
664 return -1;
665 } else {
666 if (mc->ep0 > ep) {
667 ep += 3600;
668 }
669 adjweek(&mc->gt, mc->tow0 + ep);
670 if (mc->iod != iod) {
671 trace(NULL, 2, "decode_mcssr_ura: %s,iod mismatch %d != %d\n", time_str(mc->gt, 3), mc->iod, iod);
672 apply = 0;
673 }
674 }
675 for (j = 0; j < mc->ns; j++) {
676 ura = getbitu(mc->buff, i, 6);
677 i += 6;
678
679 sat = mc->satlist[j];
680 satno2id(sat, satid);
681
682 trace(NULL, 4, "decode_mcssr_ura :%s,i=%4d,j=%3d,sat=%s,ura=0x%02X\n", time_str(mc->gt, 3), i, j, satid, ura);
683
684 if (sat == 0) {
685 continue; /* unsupprted sat */
686 }
687 if (apply) {
688 ssr[sat - 1].t0[3] = mc->gt;
689 ssr[sat - 1].udi[3] = udint;
690 ssr[sat - 1].iod[3] = iod;
691 ssr[sat - 1].ura = ura;
692 ssr[sat - 1].update = 1;
693 }
694 }
695 return i;
696}
697
698/* decode QZSS L6E message ---------------------------------------------------
699 * decode QZSS L6E message and convert to RTCM SSR
700 * args : rtcm_t *rtcm IO rtcm control struct
701 * return : status (-1: error message, 0: no message, 10: input ssr messages)
702 * note : before calling the function, init_mcssr()
703 *-----------------------------------------------------------------------------*/
705 unsigned int preamb, prn, type, alert, vid, mgfid, csid, anme, si;
706 l6_header_t hdr;
707 int i = 0, n, ibuff, mn, st, apply, ret, optprn;
708 char* str;
709 uint8_t mask;
710
711 /* decode L6 message header (49 bits) */
712 l6_parse_header(rtcm->buff, &hdr);
713 preamb = hdr.preamble;
714 prn = hdr.prn;
715 type = hdr.msgid; /* L6 Msg. Type ID */
716 vid = hdr.vid; /* Vendor ID(2:MADOCA-PPP) */
717 mgfid = hdr.fac; /* Msg. Gen. Facility ID(0-1:Hitachi-Ota,2-3:Kobe) */
718 csid = hdr.csid; /* Correction Service ID(0:Clock/Ephemeris,1:Iono) */
719 anme = hdr.anme; /* Applicable Nav. Msg. Ext.(0:Default,1:CNAV/CNAV2) */
720 si = hdr.sf_ind; /* Subframe Indicator(0:others,1:First Data) */
721 alert = hdr.alert; /* Alert Flag(1:Alert) */
722 i = L6_HEADER_BITS;
723
724 trace(NULL, 3,
725 "decode_qzss_l6emsg : %s,preamb=0x%08X,prn=%d,type=0x%X(vid=%d,mgfid=%d,csid=%d,anme=%d,si=%d),alert=%d\n",
726 time_str(_mcssr[_mcssr_ch].gt, 3), preamb, prn, type, vid, mgfid, csid, anme, si, alert);
727
728 if (preamb != L6_PREAMBLE) {
729 trace(NULL, 2, "decode_qzss_l6emsg : %s,invalid preamb=0x%08X\n", time_str(_mcssr[_mcssr_ch].gt, 3), preamb);
730 return -1;
731 }
732
733 if (alert) {
734 if (strstr(rtcm->opt, "-IGNORE_MCSSR_ALERT")) {
735 trace(NULL, 3, "decode_qzss_l6emsg : ignore alert\n", time_str(_mcssr[_mcssr_ch].gt, 3));
736 } else {
737 trace(NULL, 2, "decode_qzss_l6emsg : alert\n", time_str(_mcssr[_mcssr_ch].gt, 3));
738 return -1;
739 }
740 }
741
742 if (vid != 2) {
743 return 0; /* unsupport vendor ID */
744 }
745
746 if ((str = strstr(rtcm->opt, "-MCSSR_PRN"))) {
747 optprn = atoi(strstr(str, "=") + 1);
748 if (optprn != prn) {
749 trace(NULL, 3, "decode_qzss_l6emsg : -MCSSR_PRN=%d\n", optprn);
750 return -1;
751 }
752 } else {
753 if (_mcssr[_mcssr_ch].prn == -1) {
754 _mcssr[_mcssr_ch].prn = prn;
755 } else {
756 if (_mcssr[_mcssr_ch].prn != prn) {
757 _mcssr[_mcssr_ch].prn_chk_cnt++;
758 trace(NULL, 3, "decode_qzss_l6emsg : prn mismatch _mcssr[_mcssr_ch].prn=%d,prn=%d,cnt=%d\n",
759 _mcssr[_mcssr_ch].prn, prn, _mcssr[_mcssr_ch].prn_chk_cnt);
760 if (_mcssr[_mcssr_ch].prn_chk_cnt < MCSSR_MAX_PRN) {
761 return -1;
762 } else {
763 trace(NULL, 2, "decode_qzss_l6emsg :%s,prn switched %d -> %d\n", time_str(_mcssr[_mcssr_ch].gt, 3),
764 _mcssr[_mcssr_ch].prn, prn);
765 _mcssr[_mcssr_ch].prn = prn;
766 }
767 }
768 }
769 _mcssr[_mcssr_ch].prn_chk_cnt = 0;
770 }
771
772 if (si == 1) {
773 _mcssr[_mcssr_ch].maxframe = 0; /* Subframe Indicator : First Data */
774 }
775
776 /* frame recognition */
777 if (_mcssr[_mcssr_ch].maxframe <= 0) {
778 mn = getbitu(rtcm->buff, i, 12); /* Message Number(note:not i++) */
779 st = getbitu(rtcm->buff, i + 12, 4); /* Message Sub Type ID */
780 if (mn != RTCM_MN_CSSR) {
781 trace(NULL, 2, "decode_qzss_l6emsg :%s,invalid mn=%d\n", time_str(_mcssr[_mcssr_ch].gt, 3), mn);
782 return -1;
783 }
784 if ((_mcssr[_mcssr_ch].maxframe = framelen[st]) < 1) {
785 trace(NULL, 2, "decode_qzss_l6emsg :%s,invalid frame start st=%d\n", time_str(_mcssr[_mcssr_ch].gt, 3), st);
786 return -1;
787 }
788 trace(NULL, 3, "decode_qzss_l6emsg : %s,mn=%d,st=%d,maxframe=%d\n", time_str(_mcssr[_mcssr_ch].gt, 3), mn, st,
789 _mcssr[_mcssr_ch].maxframe);
790 _mcssr[_mcssr_ch].frame = 0;
791 _mcssr[_mcssr_ch].ibuff = 0;
792 }
793
794 /* save data part (1695 bits) */
795 _mcssr[_mcssr_ch].frame++;
796 trace(NULL, 3, "decode_qzss_l6emsg : %s,maxframe=%d,frame=%d\n", time_str(_mcssr[_mcssr_ch].gt, 3),
797 _mcssr[_mcssr_ch].maxframe, _mcssr[_mcssr_ch].frame);
798 switch (_mcssr[_mcssr_ch].frame) {
799 case 1:
800 ibuff = 0;
801 n = 8;
802 mask = 0xFE;
803 break;
804 case 2:
805 ibuff = 211;
806 n = 1;
807 mask = 0xFC;
808 break;
809 case 3:
810 ibuff = 423;
811 n = 2;
812 mask = 0xF8;
813 break;
814 case 4:
815 ibuff = 635;
816 n = 3;
817 mask = 0xF0;
818 break;
819 case 5:
820 ibuff = 847;
821 n = 4;
822 mask = 0xE0;
823 break;
824 default:
825 trace(NULL, 3, "decode_qzss_l6emsg : invalid frame\n");
826 return -1;
827 }
828 _mcssr[_mcssr_ch].buff[ibuff++] |= (unsigned char)getbitu(rtcm->buff, i, n);
829 i += n;
830 while (i < L6_HEADER_BITS + L6_DATA_BITS) {
831 _mcssr[_mcssr_ch].buff[ibuff++] = (unsigned char)getbitu(rtcm->buff, i, 8);
832 i += 8;
833 }
834 _mcssr[_mcssr_ch].buff[ibuff - 1] &= mask;
835
836 if (_mcssr[_mcssr_ch].frame != _mcssr[_mcssr_ch].maxframe) {
837 return 0; /* no message */
838 }
839
840 ret = 10; /* input ssr messages */
841 i = 0;
842 while (i < L6_DATA_BITS * _mcssr[_mcssr_ch].maxframe) {
843 mn = getbitu(_mcssr[_mcssr_ch].buff, i, 12);
844 i += 12; /* Message Number */
845 if (mn != RTCM_MN_CSSR) {
846 continue;
847 }
848 st = getbitu(_mcssr[_mcssr_ch].buff, i, 4);
849 i += 4; /* Message Sub Type ID */
850 if ((st != MCSSR_ST_MASK) && (st != MCSSR_ST_OC) && (st != MCSSR_ST_CC) && (st != MCSSR_ST_CB) &&
851 (st != MCSSR_ST_PB) && (st != MCSSR_ST_URA)) {
852 continue;
853 }
854 if (st == MCSSR_ST_MASK) {
855 if (_mcssr[_mcssr_ch].mgfid != mgfid) {
856 trace(NULL, 2, "decode_qzss_l6emsg :%s,mgfid switched %d -> %d\n", time_str(_mcssr[_mcssr_ch].gt, 3),
857 _mcssr[_mcssr_ch].mgfid, mgfid);
858 _mcssr[_mcssr_ch].mgfid = mgfid;
859 }
861 } else {
862 apply = 1;
863 /* Note, ref[1] 4.2.1(3) ID 0 and 2 are the same, 1 and 3 are the same. */
864 if ((_mcssr[_mcssr_ch].mgfid & 0x1) != (mgfid & 0x1)) {
865 trace(NULL, 2, "decode_qzss_l6emsg :%s,st=%d,mgfid mismatch %d != %d\n",
866 time_str(_mcssr[_mcssr_ch].gt, 3), st, _mcssr[_mcssr_ch].mgfid, mgfid);
867 apply = 0;
868 }
869 switch (st) {
870 case MCSSR_ST_OC:
871 i = decode_mcssr_oc(&_mcssr[_mcssr_ch], rtcm->ssr, i, apply);
872 break;
873 case MCSSR_ST_CC:
874 i = decode_mcssr_cc(&_mcssr[_mcssr_ch], rtcm->ssr, i, apply);
875 break;
876 case MCSSR_ST_CB:
877 if (strstr(rtcm->opt, "-DIS_MCSSR_CB")) {
878 apply = 0;
879 }
880 i = decode_mcssr_cb(&_mcssr[_mcssr_ch], rtcm->ssr, i, apply);
881 break;
882 case MCSSR_ST_PB:
883 i = decode_mcssr_pb(&_mcssr[_mcssr_ch], rtcm->ssr, i, apply);
884 break;
885 case MCSSR_ST_URA:
886 i = decode_mcssr_ura(&_mcssr[_mcssr_ch], rtcm->ssr, i, apply);
887 break;
888 default:
889 trace(NULL, 2, "decode_qzss_l6emsg : invalid st=%d\n", st);
890 ret = -1;
891 break;
892 }
893 }
894 if (i < 0) {
895 trace(NULL, 2, "decode_qzss_l6emsg : decode error st=%d\n", st);
896 ret = -1;
897 break;
898 }
899 rtcm->time = _mcssr[_mcssr_ch].gt;
900 }
901 _mcssr[_mcssr_ch].maxframe = 0;
902 trace(NULL, 4, "decode_qzss_l6emsg : %s,frames=%d\n", time_str(_mcssr[_mcssr_ch].gt, 3), _mcssr[_mcssr_ch].frame);
903 return ret;
904}
905
906/* set/get MADOCA-PPP CSSR channel index -------------------------------------*/
907extern void set_mcssr_ch(int ch) {
908 if (ch >= 0 && ch < SSR_CH_NUM) {
909 _mcssr_ch = ch;
910 }
911}
912extern int get_mcssr_ch(void) { return _mcssr_ch; }
913
914/* initialize MADOCA-PPP CSSR control ----------------------------------------
915 * initialize MADOCA-PPP CSSR control struct for current channel
916 * args : gtime_t *gt I GPST for week number determination
917 * return : none
918 *-----------------------------------------------------------------------------*/
919extern void init_mcssr(const gtime_t gt) {
920 _mcssr[_mcssr_ch].gt = gt; /* for week number determination */
921 _mcssr[_mcssr_ch].mgfid = -1; /* invalid value */
922 _mcssr[_mcssr_ch].prn = -1; /* invalid value */
923 _mcssr[_mcssr_ch].tow0 = -1; /* invalid value */
924 _mcssr[_mcssr_ch].frame = 0; /* initial value */
925}
926
927/* stack QZSS L6E message ----------------------------------------------------
928 * stack QZSS L6E message and synchronize frame with L6 preamble
929 * args : rtcm_t *rtcm IO rtcm control struct
930 * uint8_t data I L6E 1byte data
931 * return : status (-1: error message, 0: no message,
932 * 10: input CSSR messages)
933 * note : before calling the function, init_mcssr()
934 *-----------------------------------------------------------------------------*/
935extern int input_qzssl6e(rtcm_t* rtcm, const uint8_t data) {
936 trace(NULL, 5, "input_qzssl6e: data=%02x,%d\n", data, rtcm->nbyte);
937
938 /* synchronize frame with L6 preamble */
939 if ((rtcm->nbyte == 0) && (data != 0x1A)) {
940 return 0;
941 } else if (((rtcm->nbyte == 1) && (data != 0xCF)) || ((rtcm->nbyte == 2) && (data != 0xFC)) ||
942 ((rtcm->nbyte == 3) && (data != 0x1D))) {
943 rtcm->nbyte = 0;
944 if (data != 0x1A) {
945 return 0;
946 }
947 }
948 rtcm->buff[rtcm->nbyte++] = data;
949
950 if (rtcm->nbyte < L6_FRAME_LEN) {
951 return 0;
952 }
953
954 rtcm->nbyte = 0;
955 return decode_qzss_l6emsg(rtcm);
956}
957
958/* input QZSS L6E message from file ------------------------------------------
959 * fetch next QZSS L6E message and input a messsage from file
960 * args : rtcm_t *rtcm IO rtcm control struct
961 * FILE *fp I file pointer
962 * return : status (-2: end of file, -1...10: same as input_qzssl6e())
963 * note : same as input_qzssl6e()
964 *-----------------------------------------------------------------------------*/
965extern int input_qzssl6ef(rtcm_t* rtcm, FILE* fp) {
966 int i, data, ret;
967
968 trace(NULL, 4, "input_qzssl6ef\n");
969
970 for (i = 0; i < 4096; i++) {
971 if ((data = fgetc(fp)) == EOF) {
972 return -2;
973 }
974 if ((ret = input_qzssl6e(rtcm, (uint8_t)data))) {
975 return ret;
976 }
977 }
978 return 0; /* return at every 4k bytes */
979}
980
981/* MADOCA-PPP bias code selection -------------------------------------------
982 * select MADOCA-PPP code bias, phase bias code from observation code
983 * args : int sys I navigation system
984 * int code I observation code
985 * return : MADOCA-PPP CB,PB code
986 * note : ref [1] section 5.5.3.1 Applicable Signals of Code/Phase Bias
987 *-----------------------------------------------------------------------------*/
988extern int mcssr_sel_biascode(const int sys, const int code) {
989 switch (sys) {
990 case SYS_GPS:
991 switch (code) {
992 case CODE_L1C:
993 return CODE_L1C; /* L1C/A */
994 case CODE_L1P: /* L1P */
995 case CODE_L1W:
996 return CODE_L1W; /* L1 Z-tracking */
997 case CODE_L1S: /* L1C(D) */
998 case CODE_L1L: /* L1C(P) */
999 case CODE_L1X:
1000 return CODE_L1X; /* L1C(D+P) */
1001 case CODE_L2S: /* L2C(M) */
1002 case CODE_L2L: /* L2C(L) */
1003 case CODE_L2X:
1004 return CODE_L2X; /* L2C(M+L) */
1005 case CODE_L2P: /* L2P */
1006 case CODE_L2W:
1007 return CODE_L2W; /* L2 Z-tracking */
1008 case CODE_L5I:
1009 return CODE_L5I; /* L5I */
1010 case CODE_L5Q:
1011 return CODE_L5Q; /* L5Q */
1012 case CODE_L5X:
1013 return CODE_L5X; /* L5X */
1014 }
1015 break;
1016 case SYS_GLO:
1017 switch (code) {
1018 case CODE_L1C: /* G1C/A */
1019 case CODE_L1P:
1020 return CODE_L1C; /* G1P */
1021 case CODE_L2C: /* G2C/A */
1022 case CODE_L2P:
1023 return CODE_L2C; /* G2P */
1024 }
1025 break;
1026 case SYS_GAL:
1027 switch (code) {
1028 case CODE_L1C: /* E1C */
1029 case CODE_L1B: /* E1B */
1030 case CODE_L1X:
1031 return CODE_L1X; /* E1B+C */
1032 case CODE_L5I: /* E5aI */
1033 case CODE_L5Q: /* E5aQ */
1034 case CODE_L5X:
1035 return CODE_L5X; /* E5aI+Q */
1036 case CODE_L7I: /* E5bI */
1037 case CODE_L7Q: /* E5bQ */
1038 case CODE_L7X:
1039 return CODE_L7X; /* E5bI+Q */
1040 case CODE_L6B: /* E6B */
1041 case CODE_L6C: /* E6C */
1042 case CODE_L6X:
1043 return CODE_L6B; /* E6B+C */
1044 }
1045 break;
1046 case SYS_QZS:
1047 switch (code) {
1048 case CODE_L1C:
1049 return CODE_L1C; /* L1C/A */
1050 case CODE_L1S: /* L1C(D) */
1051 case CODE_L1L: /* L1C(P) */
1052 case CODE_L1X:
1053 return CODE_L1X; /* L1C(D+P) */
1054 case CODE_L2S: /* L2C(M) */
1055 case CODE_L2L: /* L2C(L) */
1056 case CODE_L2X:
1057 return CODE_L2X; /* L2C(M+L) */
1058 case CODE_L5I: /* L5I */
1059 case CODE_L5Q: /* L5Q */
1060 case CODE_L5X:
1061 return CODE_L5X; /* L5X */
1062 case CODE_L1E:
1063 return CODE_L1E; /* L1C/B */
1064 }
1065 break;
1066 case SYS_CMP:
1067 switch (code) {
1068 case CODE_L2I: /* B1I */
1069 case CODE_L2Q: /* B1Q */
1070 case CODE_L2X:
1071 return CODE_L2I; /* B1I+Q */
1072 case CODE_L6I: /* B3I */
1073 case CODE_L6Q: /* B3Q */
1074 case CODE_L6X:
1075 return CODE_L6I; /* B3I+Q */
1076 case CODE_L7I: /* B2I */
1077 case CODE_L7Q: /* B2Q */
1078 case CODE_L7X:
1079 return CODE_L7I; /* B2I+Q */
1080 case CODE_L5D:
1081 return CODE_L5D; /* B2aI */
1082 case CODE_L5P:
1083 return CODE_L5P; /* B2aQ */
1084 case CODE_L5X:
1085 return CODE_L5X; /* B2aI+Q */
1086 case CODE_L1D:
1087 return CODE_L1D; /* B1C(D) */
1088 case CODE_L1P:
1089 return CODE_L1P; /* B1C(P) */
1090 case CODE_L1X:
1091 return CODE_L1X; /* B1C(D+P) */
1092 case CODE_L7D:
1093 return CODE_L7D; /* B2b */
1094 }
1095 break;
1096 }
1097 return CODE_NONE;
1098}
char * code2obs(uint8_t code)
Definition mrtk_obs.c:190
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
MRTKLIB Constants — Physical, navigation, and system constants.
#define SSR_INVALID_PBIAS
Definition mrtk_const.h:427
#define SSR_INVALID_CBIAS
Definition mrtk_const.h:426
#define MAXSAT
Definition mrtk_coords.c:45
#define SYS_GPS
Definition mrtk_eph.c:65
#define SYS_NONE
Definition mrtk_eph.c:64
#define SYS_QZS
Definition mrtk_eph.c:69
#define SYS_CMP
Definition mrtk_eph.c:70
#define SYS_GAL
Definition mrtk_eph.c:68
#define SYS_GLO
Definition mrtk_eph.c:67
#define CODE_L5Q
#define CODE_L2Q
#define CODE_L6C
#define CODE_L1S
#define CODE_L7Z
#define CODE_L5I
#define CODE_L7P
#define CODE_L2X
#define CODE_L3X
#define CODE_L6E
#define CODE_L1L
#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_L4X
#define CODE_L6X
#define CODE_NONE
#define CODE_L4B
#define CODE_L8Q
#define CODE_L5P
#define CODE_L3Q
#define CODE_L5D
#define CODE_L1E
#define CODE_L3I
#define CODE_L1B
#define CODE_L7D
#define CODE_L2S
#define CODE_L6L
#define CODE_L7Q
#define CODE_L1W
#define CODE_L6B
#define CODE_L8X
#define SSR_CH_NUM
#define CODE_L2W
#define CODE_L2L
#define CODE_L1D
#define CODE_L8I
#define CODE_L1P
#define CODE_L6A
#define CODE_L6Q
#define CODE_L1X
#define CODE_L4A
int l6_parse_header(const uint8_t *frame, l6_header_t *h)
Parse the header of one L6 frame and classify its service.
Definition mrtk_l6.c:44
MRTKLIB L6 Module — QZSS L6 frame header parsing.
#define L6_DATA_BITS
Definition mrtk_l6.h:46
#define L6_FRAME_LEN
Definition mrtk_l6.h:43
#define L6_PREAMBLE
Definition mrtk_l6.h:42
#define L6_HEADER_BITS
Definition mrtk_l6.h:45
void satno2id(int sat, char *id)
Definition mrtk_nav.c:817
static const int framelen[]
#define MCSSR_ST_MASK
Definition mrtk_madoca.c:55
static const uint8_t cssr_sig_bd3[16]
#define MCSSR_SATMASK_BD3_U
Definition mrtk_madoca.c:81
#define MCSSR_SYS_GPS
Definition mrtk_madoca.c:63
#define MCSSR_SATMASK_GLO_U
Definition mrtk_madoca.c:73
static const uint8_t cssr_sig_qzs[16]
static int decode_mcssr_mask(mcssr_t *mc, int i)
#define MCSSR_INVALID_15BIT
Definition mrtk_madoca.c:88
static const uint8_t cssr_sig_bd2[16]
int decode_qzss_l6emsg(rtcm_t *rtcm)
Decode QZSS L6E message and convert to RTCM SSR.
#define MCSSR_SATMASK_GPS_U
Definition mrtk_madoca.c:71
static void adjweek(gtime_t *gt, double tow)
static int decode_mcssr_oc(mcssr_t *mc, ssr_t *ssr, int i, int apply)
static int _mcssr_ch
#define MCSSR_SATMASK_GAL_L
Definition mrtk_madoca.c:76
#define MCSSR_ST_CB
Definition mrtk_madoca.c:58
#define MCSSR_SATMASK_GAL_U
Definition mrtk_madoca.c:75
int get_mcssr_ch(void)
Get current MADOCA-PPP CSSR channel index.
static int mcssr_sigcode(const mcssr_t *mc, int gnssid, int sat, int k)
static int decode_mcssr_head(const mcssr_t *mc, int *sync, int *iod, int *ep, double *udint, int i, const int st)
#define MCSSR_INVALID_13BIT
Definition mrtk_madoca.c:89
static const uint8_t cssr_sig_gps[16]
Definition mrtk_madoca.c:98
#define MCSSR_BYTELEN
Definition mrtk_madoca.c:53
int input_qzssl6ef(rtcm_t *rtcm, FILE *fp)
Fetch next QZSS L6E message and input a message from file.
#define MCSSR_ST_CC
Definition mrtk_madoca.c:57
#define MCSSR_SATMASK_BD3_L
Definition mrtk_madoca.c:82
#define MCSSR_SATMASK_QZS_U
Definition mrtk_madoca.c:79
#define MCSSR_SATMASK_RSV_L
Definition mrtk_madoca.c:84
#define MCSSR_MAX_SIGMASK
Definition mrtk_madoca.c:86
int satno(int sys, int prn)
Definition mrtk_nav.c:58
static int decode_mcssr_cc(mcssr_t *mc, ssr_t *ssr, int i, int apply)
int mcssr_sel_biascode(const int sys, const int code)
Select MADOCA-PPP code/phase bias code from observation code.
mcssr_t _mcssr[SSR_CH_NUM]
#define MCSSR_MAX_SATMASK
Definition mrtk_madoca.c:70
static const uint8_t cssr_sig_glo[16]
#define MCSSR_ST_OC
Definition mrtk_madoca.c:56
static int decode_mcssr_pb(mcssr_t *mc, ssr_t *ssr, int i, int apply)
#define MCSSR_SATMASK_RSV_U
Definition mrtk_madoca.c:83
const uint8_t cssr_sig_rsv[16]
#define MCSSR_SYS_BD3
Definition mrtk_madoca.c:68
double time2gpst(gtime_t t, int *week)
Definition mrtk_time.c:181
#define MCSSR_MAX_PRN
Definition mrtk_madoca.c:92
void init_mcssr(const gtime_t gt)
Initialize MADOCA-PPP CSSR control struct for current channel.
#define MCSSR_SATMASK_BDS_L
Definition mrtk_madoca.c:78
#define MCSSR_SATMASK_GLO_L
Definition mrtk_madoca.c:74
static int gnssid2sys(const int gnssid)
#define MCSSR_SATMASK_QZS_L
Definition mrtk_madoca.c:80
static int decode_mcssr_cb(mcssr_t *mc, ssr_t *ssr, int i, int apply)
int satsys_bd2(int sat, int *prn)
Definition mrtk_nav.c:159
char * time_str(gtime_t t, int n)
Definition mrtk_time.c:530
#define MCSSR_ST_PB
Definition mrtk_madoca.c:59
#define MCSSR_INVALID_11BIT
Definition mrtk_madoca.c:90
#define RTCM_MN_CSSR
Definition mrtk_madoca.c:51
#define MCSSR_SATMASK_BDS_U
Definition mrtk_madoca.c:77
#define MCSSR_SYS_QZS
Definition mrtk_madoca.c:67
#define MCSSR_SATMASK_GPS_L
Definition mrtk_madoca.c:72
static int decode_mcssr_ura(mcssr_t *mc, ssr_t *ssr, int i, int apply)
static int svmask2list(const uint64_t mask, const int gnssid, int *satlist, int *gidlist)
void set_mcssr_ch(int ch)
Set MADOCA-PPP CSSR channel index for multi-L6E.
static int flgcnt16(const uint16_t flg)
static const uint8_t cssr_sig_gal[16]
#define MCSSR_ST_URA
Definition mrtk_madoca.c:60
#define MCSSR_SYS_GLO
Definition mrtk_madoca.c:64
static int sigmask2list(const uint16_t mask, const int gnssid, int *siglist)
#define MCSSR_SYS_BDS
Definition mrtk_madoca.c:66
#define MCSSR_SYS_GAL
Definition mrtk_madoca.c:65
gtime_t utc2gpst(gtime_t t)
Definition mrtk_time.c:440
gtime_t timeget(void)
Definition mrtk_time.c:289
#define MCSSR_MAX_SYS
Definition mrtk_madoca.c:62
int input_qzssl6e(rtcm_t *rtcm, const uint8_t data)
Stack QZSS L6E message and synchronize frame with L6 preamble.
MRTKLIB MADOCA-PPP Module — QZSS L6E CSSR message decode functions.
static rtcm_t * rtcm
gtime_t gpst2time(int week, double sec)
Convert GPS week/tow to gtime_t.
Definition mrtk_time.c:165
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.
GNSS time representation.
Definition mrtk_time.h:49
time_t time
Definition mrtk_time.h:50
Decoded L6 frame header. Raw bit fields; no service-specific remapping.
Definition mrtk_l6.h:68
uint8_t prn
Definition mrtk_l6.h:70
uint8_t anme
Definition mrtk_l6.h:76
uint8_t alert
Definition mrtk_l6.h:78
uint8_t csid
Definition mrtk_l6.h:75
uint8_t msgid
Definition mrtk_l6.h:71
uint8_t fac
Definition mrtk_l6.h:73
uint8_t vid
Definition mrtk_l6.h:72
uint32_t preamble
Definition mrtk_l6.h:69
uint8_t sf_ind
Definition mrtk_l6.h:77
int nsat[16]
int siglist[16][16]
int ncell[MAXSAT]
int gidlist[MAXSAT]
int prn_chk_cnt
int siglist_bd3[16]
uint8_t buff[1060]
gtime_t gt
int nsig[16]
int cellmask[MAXSAT]
int satlist[MAXSAT]
int maxframe
RTCM control struct type.
Definition mrtk_rtcm.h:50
double dclk[3]
Definition mrtk_nav.h:185
double ddeph[3]
Definition mrtk_nav.h:184
gtime_t t0[6]
Definition mrtk_nav.h:176
int iod[6]
Definition mrtk_nav.h:178
uint8_t update
Definition mrtk_nav.h:194
int vpbias[MAXCODE]
Definition mrtk_nav.h:191
double yaw_ang
Definition mrtk_nav.h:193
int iode
Definition mrtk_nav.h:179
double deph[3]
Definition mrtk_nav.h:183
int vcbias[MAXCODE]
Definition mrtk_nav.h:190
double pbias[MAXCODE]
Definition mrtk_nav.h:188
float cbias[MAXCODE]
Definition mrtk_nav.h:187
double udi[6]
Definition mrtk_nav.h:177
int ura
Definition mrtk_nav.h:181
double yaw_rate
Definition mrtk_nav.h:193
int discnt[MAXCODE]
Definition mrtk_nav.h:192