MRTKLIB 0.7.14
Modernized GNSS Positioning Library
Loading...
Searching...
No Matches
mrtk_rcv_javad.c
Go to the documentation of this file.
1/*------------------------------------------------------------------------------
2 * mrtk_rcv_javad.c : Javad receiver raw data decoder
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 <ctype.h>
17#include <math.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include "mrtklib/mrtk_bits.h"
23#include "mrtklib/mrtk_eph.h"
24#include "mrtklib/mrtk_mat.h"
25#include "mrtklib/mrtk_nav.h"
26#include "mrtklib/mrtk_obs.h"
27#include "mrtklib/mrtk_rcvraw.h"
28#include "mrtklib/mrtk_rtcm.h"
29#include "mrtklib/mrtk_sys.h"
30#include "mrtklib/mrtk_time.h"
31#include "mrtklib/mrtk_trace.h"
32
33/* Local constants (duplicated from rtklib.h to avoid dependency) */
34#define PI 3.1415926535897932 /* pi */
35#define D2R (PI / 180.0) /* deg to rad */
36#define R2D (180.0 / PI) /* rad to deg */
37#define CLIGHT 299792458.0 /* speed of light (m/s) */
38#define SC2RAD 3.1415926535898 /* semi-circle to radian (IS-GPS) */
39
40#define SYS_NONE 0x00
41#define SYS_GPS 0x01
42#define SYS_SBS 0x02
43#define SYS_GLO 0x04
44#define SYS_GAL 0x08
45#define SYS_QZS 0x10
46#define SYS_CMP 0x20
47#define SYS_IRN 0x40
48
49#define TSYS_GPS 0
50#define TSYS_UTC 1
51#define TSYS_GLO 2
52#define TSYS_GAL 3
53#define TSYS_QZS 4
54#define TSYS_CMP 5
55#define TSYS_IRN 6
56
57#define FREQ1 1.57542E9 /* L1/E1/B1C frequency (Hz) */
58#define FREQ2 1.22760E9 /* L2 frequency (Hz) */
59#define FREQ5 1.17645E9 /* L5/E5a/B2a frequency (Hz) */
60#define FREQ6 1.27875E9 /* E6/L6 frequency (Hz) */
61#define FREQ7 1.20714E9 /* E5b/B2I frequency (Hz) */
62#define FREQ8 1.191795E9 /* E5ab/B2ab frequency (Hz) */
63#define FREQ9 2.492028E9 /* S frequency (Hz) */
64#define FREQ1_GLO 1.60200E9 /* GLONASS G1 base frequency (Hz) */
65#define DFRQ1_GLO 0.56250E6 /* GLONASS G1 bias frequency (Hz/n) */
66#define FREQ2_GLO 1.24600E9 /* GLONASS G2 base frequency (Hz) */
67#define DFRQ2_GLO 0.43750E6 /* GLONASS G2 bias frequency (Hz/n) */
68#define FREQ3_GLO 1.202025E9 /* GLONASS G3 frequency (Hz) */
69#define FREQ1a_GLO 1.600995E9 /* GLONASS G1a frequency (Hz) */
70#define FREQ2a_GLO 1.248060E9 /* GLONASS G2a frequency (Hz) */
71#define FREQ1_CMP 1.561098E9 /* BDS B1I frequency (Hz) */
72
73#define MINPRNGPS 1
74#define MAXPRNGPS 32
75#define MINPRNSBS 120
76#define MAXPRNSBS 158
77
78/* Power-of-2 constants */
79#define P2_5 0.03125
80#define P2_6 0.015625
81#define P2_11 4.882812500000000E-04
82#define P2_15 3.051757812500000E-05
83#define P2_17 7.629394531250000E-06
84#define P2_19 1.907348632812500E-06
85#define P2_20 9.536743164062500E-07
86#define P2_21 4.768371582031250E-07
87#define P2_23 1.192092895507810E-07
88#define P2_24 5.960464477539063E-08
89#define P2_27 7.450580596923828E-09
90#define P2_29 1.862645149230957E-09
91#define P2_30 9.313225746154785E-10
92#define P2_31 4.656612873077393E-10
93#define P2_32 2.328306436538696E-10
94#define P2_33 1.164153218269348E-10
95#define P2_34 5.820766091346740E-11
96#define P2_35 2.910383045673370E-11
97#define P2_38 3.637978807091710E-12
98#define P2_40 9.094947017729280E-13
99#define P2_43 1.136868377216160E-13
100#define P2_46 1.421085471520200E-14
101#define P2_50 8.881784197001252E-16
102#define P2_55 2.775557561562891E-17
103#define P2_59 1.734723475976810E-18
104
105/* Forward declarations for functions in rtklib (resolved at link time) */
106
107#define PREAMB_CNAV 0x8B
108
109#define ISTXT(c) ('0' <= (c) && (c) <= '~')
110#define ISHEX(c) (('0' <= (c) && (c) <= '9') || ('A' <= (c) && (c) <= 'F'))
111#define ROT_LEFT(val) (((val) << 2) | ((val) >> 6))
112
113/* extract field (little-endian) ---------------------------------------------*/
114#define U1(p) (*((uint8_t*)(p)))
115#define I1(p) (*((int8_t*)(p)))
116static uint16_t U2(uint8_t* p) {
117 uint16_t u;
118 memcpy(&u, p, 2);
119 return u;
120}
121static uint32_t U4(uint8_t* p) {
122 uint32_t u;
123 memcpy(&u, p, 4);
124 return u;
125}
126static int16_t I2(uint8_t* p) {
127 int16_t i;
128 memcpy(&i, p, 2);
129 return i;
130}
131static int32_t I4(uint8_t* p) {
132 int32_t i;
133 memcpy(&i, p, 4);
134 return i;
135}
136
137static float R4(uint8_t* p) {
138 float value;
139 uint8_t* q = (uint8_t*)&value;
140 int i;
141 if (U4(p) == 0x7FC00000) {
142 return 0.0f; /* quiet nan */
143 }
144 for (i = 0; i < 4; i++) {
145 *q++ = *p++;
146 }
147 return value;
148}
149static double R8(uint8_t* p) {
150 double value;
151 uint8_t* q = (uint8_t*)&value;
152 int i;
153 if (U4(p + 4) == 0x7FF80000 && U4(p) == 0) {
154 return 0.0; /* quiet nan */
155 }
156 for (i = 0; i < 8; i++) {
157 *q++ = *p++;
158 }
159 return value;
160}
161/* decode message length -----------------------------------------------------*/
162static int decodelen(const uint8_t* buff) {
163 uint32_t len;
164 if (!ISHEX(buff[0]) || !ISHEX(buff[1]) || !ISHEX(buff[2])) {
165 return 0;
166 }
167 if (sscanf((char*)buff, "%3X", &len) == 1) {
168 return (int)len;
169 }
170 return 0;
171}
172/* test measurement data -----------------------------------------------------*/
173static int is_meas(char sig) {
174 return sig == 'c' || sig == 'C' || sig == '1' || sig == '2' || sig == '3' || sig == '5' || sig == 'l';
175}
176/* convert signal to freq-index ----------------------------------------------*/
177static int sig2idx(int sys, char sig, int* code) {
178 const uint8_t codes[7][6] = {
179 /* ref [7] table 3-8 */
180 /* c/C 1 2 3 5 l */
181 /* (CA/L1 P/L1 P/L2 CA/L2 L5 L1C) */
184 {CODE_L1C, 0, 0, 0, CODE_L5X, 0}, /* SBS */
185 {CODE_L1X, CODE_L8X, CODE_L7X, CODE_L6X, CODE_L5X, 0}, /* GAL */
186 {CODE_L1C, CODE_L1P, CODE_L2P, CODE_L2C, CODE_L3X, 0}, /* GLO */
187 {CODE_L2I, 0, CODE_L7I, CODE_L6I, CODE_L5X, CODE_L1X}, /* BDS */
188 {0, 0, 0, 0, CODE_L5X, 0} /* IRN */
189 };
190 int i, j, idx;
191
192 switch (sig) {
193 case 'c':
194 case 'C':
195 i = 0;
196 break;
197 case '1':
198 i = 1;
199 break;
200 case '2':
201 i = 2;
202 break;
203 case '3':
204 i = 3;
205 break;
206 case '5':
207 i = 4;
208 break;
209 case 'l':
210 i = 5;
211 break;
212 default:
213 return -1;
214 }
215 switch (sys) {
216 case SYS_GPS:
217 j = 0;
218 break;
219 case SYS_QZS:
220 j = 1;
221 break;
222 case SYS_SBS:
223 j = 2;
224 break;
225 case SYS_GAL:
226 j = 3;
227 break;
228 case SYS_GLO:
229 j = 4;
230 break;
231 case SYS_CMP:
232 j = 5;
233 break;
234 case SYS_IRN:
235 j = 6;
236 break;
237 default:
238 return -1;
239 }
240 if (!(*code = codes[j][i])) {
241 return -1;
242 }
243 idx = code2freq_idx(sys, (uint8_t)*code);
244 return idx < NFREQ ? idx : -1;
245}
246/* check code priority and return freq-index ---------------------------------*/
247static int checkpri(int sys, int code, const char* opt, int idx) {
248 int nex = NEXOBS; /* number of extended obs data */
249
250 if (sys == SYS_GPS) {
251 if (strstr(opt, "-GL1W") && idx == 0) {
252 return code == CODE_L1W ? 0 : -1;
253 }
254 if (strstr(opt, "-GL1X") && idx == 0) {
255 return code == CODE_L1X ? 0 : -1;
256 }
257 if (strstr(opt, "-GL2X") && idx == 1) {
258 return code == CODE_L2X ? 1 : -1;
259 }
260 if (code == CODE_L1W) {
261 return nex < 1 ? -1 : NFREQ;
262 }
263 if (code == CODE_L2X) {
264 return nex < 2 ? -1 : NFREQ + 1;
265 }
266 if (code == CODE_L1X) {
267 return nex < 3 ? -1 : NFREQ + 2;
268 }
269 } else if (sys == SYS_GLO) {
270 if (strstr(opt, "-RL1P") && idx == 0) {
271 return code == CODE_L1P ? 0 : -1;
272 }
273 if (strstr(opt, "-RL2C") && idx == 1) {
274 return code == CODE_L2C ? 1 : -1;
275 }
276 if (code == CODE_L1P) {
277 return nex < 1 ? -1 : NFREQ;
278 }
279 if (code == CODE_L2C) {
280 return nex < 2 ? -1 : NFREQ + 1;
281 }
282 } else if (sys == SYS_QZS) {
283 if (strstr(opt, "-JL1Z") && idx == 0) {
284 return code == CODE_L1Z ? 0 : -1;
285 }
286 if (strstr(opt, "-JL1X") && idx == 0) {
287 return code == CODE_L1X ? 0 : -1;
288 }
289 if (code == CODE_L1Z) {
290 return nex < 1 ? -1 : NFREQ;
291 }
292 if (code == CODE_L1X) {
293 return nex < 2 ? -1 : NFREQ + 1;
294 }
295 }
296 return idx;
297}
298/* checksum ------------------------------------------------------------------*/
299static int checksum(uint8_t* buff, int len) {
300 uint8_t cs = 0;
301 int i;
302 for (i = 0; i < len - 1; i++) {
303 cs = ROT_LEFT(cs) ^ buff[i];
304 }
305 cs = ROT_LEFT(cs);
306 return cs == buff[len - 1];
307}
308/* adjust weekly rollover of GPS time ----------------------------------------*/
309static gtime_t adjweek(gtime_t time, double tow) {
310 double tow_p;
311 int week;
312 tow_p = time2gpst(time, &week);
313 if (tow < tow_p - 302400.0) {
314 tow += 604800.0;
315 } else if (tow > tow_p + 302400.0) {
316 tow -= 604800.0;
317 }
318 return gpst2time(week, tow);
319}
320/* adjust daily rollover of time ---------------------------------------------*/
321static gtime_t adjday(gtime_t time, double tod) {
322 double ep[6], tod_p;
323 time2epoch(time, ep);
324 tod_p = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5];
325 if (tod < tod_p - 43200.0) {
326 tod += 86400.0;
327 } else if (tod > tod_p + 43200.0) {
328 tod -= 86400.0;
329 }
330 ep[3] = ep[4] = ep[5] = 0.0;
331 return timeadd(epoch2time(ep), tod);
332}
333/* set time tag --------------------------------------------------------------*/
334static int settag(obsd_t* data, gtime_t time) {
335 char s1[64], s2[64];
336
337 if (data->time.time != 0 && fabs(timediff(data->time, time)) > 5E-4) {
338 time2str(data->time, s1, 4);
339 time2str(time, s2, 4);
340 trace(NULL, 2, "time inconsistent: time=%s %s sat=%2d\n", s1, s2, data->sat);
341 return 0;
342 }
343 data->time = time;
344 return 1;
345}
346/* flush observation data buffer ---------------------------------------------*/
347static int flushobuf(raw_t* raw) {
348 gtime_t time0 = {0};
349 int i, j, n = 0;
350
351 trace(NULL, 3, "flushobuf: n=%d\n", raw->obuf.n);
352
353 /* copy observation data buffer */
354 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
355 if (!satsys(raw->obuf.data[i].sat, NULL)) {
356 continue;
357 }
358 if (raw->obuf.data[i].time.time == 0) {
359 continue;
360 }
361 raw->obs.data[n++] = raw->obuf.data[i];
362 }
363 raw->obs.n = n;
364
365 /* clear observation data buffer */
366 for (i = 0; i < MAXOBS; i++) {
367 raw->obuf.data[i].time = time0;
368 for (j = 0; j < NFREQ + NEXOBS; j++) {
369 raw->obuf.data[i].L[j] = raw->obuf.data[i].P[j] = 0.0;
370 raw->obuf.data[i].D[j] = 0.0;
371 raw->obuf.data[i].SNR[j] = raw->obuf.data[i].LLI[j] = 0;
372 raw->obuf.data[i].code[j] = CODE_NONE;
373 }
374 }
375 for (i = 0; i < MAXSAT; i++) {
376 raw->prCA[i] = raw->dpCA[i] = 0.0;
377 }
378 return n > 0 ? 1 : 0;
379}
380/* decode [~~] receiver time -------------------------------------------------*/
381static int decode_RT(raw_t* raw) {
382 gtime_t time;
383 char* msg;
384 uint8_t* p = raw->buff + 5;
385
386 if (!checksum(raw->buff, raw->len)) {
387 trace(NULL, 2, "javad RT error: len=%d\n", raw->len);
388 return -1;
389 }
390 if (raw->len < 10) {
391 trace(NULL, 2, "javad RT length error: len=%d\n", raw->len);
392 return -1;
393 }
394 raw->tod = U4(p);
395
396 if (raw->time.time == 0) {
397 return 0;
398 }
399
400 /* update receiver time */
401 time = raw->time;
402 if (raw->tbase >= 1) {
403 time = gpst2utc(time); /* GPST->UTC */
404 }
405 time = adjday(time, raw->tod * 0.001);
406 if (raw->tbase >= 1) {
407 time = utc2gpst(time); /* UTC->GPST */
408 }
409 raw->time = time;
410
411 trace(NULL, 3, "decode_RT: time=%s\n", time_str(time, 3));
412
413 if (raw->outtype) {
414 msg = raw->msgtype + strlen(raw->msgtype);
415 sprintf(msg, " %s", time_str(time, 3));
416 }
417 /* flush observation data buffer */
418 return flushobuf(raw);
419}
420/* decode [::] epoch time ----------------------------------------------------*/
421static int decode_ET(raw_t* raw) {
422 uint8_t* p = raw->buff + 5;
423
424 if (!checksum(raw->buff, raw->len)) {
425 trace(NULL, 2, "javad ET checksum error: len=%d\n", raw->len);
426 return -1;
427 }
428 if (raw->len < 10) {
429 trace(NULL, 2, "javad ET length error: len=%d\n", raw->len);
430 return -1;
431 }
432 if (raw->tod != (int)U4(p)) {
433 trace(NULL, 2, "javad ET inconsistent tod: tod=%d %d\n", raw->tod, U4(p));
434 return -1;
435 }
436 raw->tod = -1; /* end of epoch */
437
438 /* flush observation data buffer */
439 return flushobuf(raw);
440}
441/* decode [RD] receiver date -------------------------------------------------*/
442static int decode_RD(raw_t* raw) {
443 double ep[6] = {0};
444 char* msg;
445 uint8_t* p = raw->buff + 5;
446
447 if (!checksum(raw->buff, raw->len)) {
448 trace(NULL, 2, "javad RD checksum error: len=%d\n", raw->len);
449 return -1;
450 }
451 if (raw->len < 11) {
452 trace(NULL, 2, "javad RD length error: len=%d\n", raw->len);
453 return -1;
454 }
455 ep[0] = U2(p);
456 p += 2;
457 ep[1] = U1(p);
458 p += 1;
459 ep[2] = U1(p);
460 p += 1;
461 raw->tbase = U1(p);
462
463 if (raw->outtype) {
464 msg = raw->msgtype + strlen(raw->msgtype);
465 sprintf(msg, " %04.0f/%02.0f/%02.0f base=%d", ep[0], ep[1], ep[2], raw->tbase);
466 }
467 if (raw->tod < 0) {
468 trace(NULL, 2, "javad RD lack of preceding RT\n");
469 return 0;
470 }
471 raw->time = timeadd(epoch2time(ep), raw->tod * 0.001);
472 if (raw->tbase >= 1) {
473 raw->time = utc2gpst(raw->time); /* UTC->GPST */
474 }
475
476 trace(NULL, 3, "decode_RD: time=%s\n", time_str(raw->time, 3));
477
478 return 0;
479}
480/* decode [SI] satellite indices ---------------------------------------------*/
481static int decode_SI(raw_t* raw) {
482 int i, usi, sat;
483 char* msg;
484 uint8_t* p = raw->buff + 5;
485
486 if (!checksum(raw->buff, raw->len)) {
487 trace(NULL, 2, "javad SI checksum error: len=%d\n", raw->len);
488 return -1;
489 }
490 raw->obuf.n = raw->len - 6;
491
492 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
493 usi = U1(p);
494 p += 1;
495
496 if (usi <= 0) {
497 sat = 0; /* ref [5] table 3-6 */
498 } else if (usi <= 37) {
499 sat = satno(SYS_GPS, usi); /* 1- 37: GPS */
500 } else if (usi <= 70) {
501 sat = 255; /* 38- 70: GLONASS */
502 } else if (usi <= 119) {
503 sat = satno(SYS_GAL, usi - 70); /* 71-119: GALILEO */
504 } else if (usi <= 142) {
505 sat = satno(SYS_SBS, usi); /* 120-142: SBAS */
506 } else if (usi <= 192) {
507 sat = 0;
508 } else if (usi <= 197) {
509 sat = satno(SYS_QZS, usi); /* 193-197: QZSS */
510 } else if (usi <= 210) {
511 sat = 0;
512 } else if (usi <= 240) {
513 sat = satno(SYS_CMP, usi - 210); /* 211-240: BeiDou */
514 } else if (usi <= 247) {
515 sat = satno(SYS_IRN, usi - 240); /* 241-247: IRNSS */
516 } else {
517 sat = 0;
518 }
519
520 raw->obuf.data[i].time = raw->time;
521 raw->obuf.data[i].sat = sat;
522
523 /* glonass fcn (frequency channel number) */
524 if (sat == 255) {
525 raw->freqn[i] = usi - 45;
526 }
527 }
528 trace(NULL, 4, "decode_SI: nsat=raw->obuf.n\n");
529
530 if (raw->outtype) {
531 msg = raw->msgtype + strlen(raw->msgtype);
532 sprintf(msg, " nsat=%2d", raw->obuf.n);
533 }
534 return 0;
535}
536/* decode [NN] GLONASS satellite system numbers ------------------------------*/
537static int decode_NN(raw_t* raw) {
538 uint8_t* p = raw->buff + 5;
539 char* msg;
540 int i, n, ns, slot, sat, index[MAXOBS];
541
542 if (!checksum(raw->buff, raw->len)) {
543 trace(NULL, 2, "javad NN checksum error: len=%d\n", raw->len);
544 return -1;
545 }
546 for (i = n = 0; i < raw->obuf.n && i < MAXOBS; i++) {
547 if (raw->obuf.data[i].sat == 255) {
548 index[n++] = i;
549 }
550 }
551 ns = raw->len - 6;
552
553 for (i = 0; i < ns && i < n; i++) {
554 slot = U1(p);
555 p += 1;
556 sat = satno(SYS_GLO, slot);
557 raw->obuf.data[index[i]].sat = sat;
558 }
559 if (raw->outtype) {
560 msg = raw->msgtype + strlen(raw->msgtype);
561 sprintf(msg, " nsat=%2d", ns);
562 }
563 return 0;
564}
565/* decode [GA] GPS almanac ---------------------------------------------------*/
566static int decode_GA(raw_t* raw) {
567 trace(NULL, 3, "javad GA unsupported\n");
568
569 return 0;
570}
571/* decode [NA] GLONASS almanac -----------------------------------------------*/
572static int decode_NA(raw_t* raw) {
573 trace(NULL, 3, "javad NA unsupported\n");
574
575 return 0;
576}
577/* decode [EA] Galileo almanac -----------------------------------------------*/
578static int decode_EA(raw_t* raw) {
579 trace(NULL, 3, "javad EA unsupported\n");
580
581 return 0;
582}
583/* decode [WA] WAAS almanac --------------------------------------------------*/
584static int decode_WA(raw_t* raw) {
585 trace(NULL, 3, "javad WA unsupported\n");
586
587 return 0;
588}
589/* decode [QA] QZSS almanac --------------------------------------------------*/
590static int decode_QA(raw_t* raw) {
591 trace(NULL, 3, "javad QA unsupported\n");
592
593 return 0;
594}
595/* decode [CA] Beidou almanac ------------------------------------------------*/
596static int decode_CA(raw_t* raw) {
597 trace(NULL, 3, "javad CA unsupported\n");
598
599 return 0;
600}
601/* decode [IA] IRNSS almanac -------------------------------------------------*/
602static int decode_IA(raw_t* raw) {
603 trace(NULL, 3, "javad IA unsupported\n");
604
605 return 0;
606}
607/* decode GPS/Galileo/QZSS/Beidou ephemeris ----------------------------------*/
608static int decode_eph(raw_t* raw, int sys) {
609 eph_t eph = {0};
610 double toc, sqrtA, tt;
611 char* msg;
612 int sat, prn, tow, flag, week, navtype, sigtype, set = 0;
613 int eph_sel = 3; /* Galileo ephemeris selection */
614 uint8_t* p = raw->buff + 5;
615
616 trace(NULL, 3, "decode_eph: sys=%2d prn=%3d\n", sys, U1(p));
617
618 if (strstr(raw->opt, "-GALINAV")) {
619 eph_sel = 1;
620 }
621 if (strstr(raw->opt, "-GALFNAV")) {
622 eph_sel = 2;
623 }
624
625 prn = U1(p);
626 p += 1;
627 tow = U4(p);
628 p += 4;
629 flag = U1(p);
630 p += 1;
631 eph.iodc = I2(p);
632 p += 2;
633 toc = I4(p);
634 p += 4;
635 eph.sva = I1(p);
636 p += 1;
637 eph.svh = U1(p);
638 p += 1;
639 week = I2(p);
640 p += 2;
641 eph.tgd[0] = R4(p);
642 p += 4;
643 eph.f2 = R4(p);
644 p += 4;
645 eph.f1 = R4(p);
646 p += 4;
647 eph.f0 = R4(p);
648 p += 4;
649 eph.toes = I4(p);
650 p += 4;
651 eph.iode = I2(p);
652 p += 2;
653 sqrtA = R8(p);
654 p += 8;
655 eph.e = R8(p);
656 p += 8;
657 eph.M0 = R8(p) * SC2RAD;
658 p += 8;
659 eph.OMG0 = R8(p) * SC2RAD;
660 p += 8;
661 eph.i0 = R8(p) * SC2RAD;
662 p += 8;
663 eph.omg = R8(p) * SC2RAD;
664 p += 8;
665 eph.deln = R4(p) * SC2RAD;
666 p += 4;
667 eph.OMGd = R4(p) * SC2RAD;
668 p += 4;
669 eph.idot = R4(p) * SC2RAD;
670 p += 4;
671 eph.crc = R4(p);
672 p += 4;
673 eph.crs = R4(p);
674 p += 4;
675 eph.cuc = R4(p);
676 p += 4;
677 eph.cus = R4(p);
678 p += 4;
679 eph.cic = R4(p);
680 p += 4;
681 eph.cis = R4(p);
682 p += 4;
683 eph.A = sqrtA * sqrtA;
684
685 if (raw->outtype) {
686 msg = raw->msgtype + strlen(raw->msgtype);
687 sprintf(msg, " prn=%3d iode=%3d iodc=%3d toes=%6.0f", prn, eph.iode, eph.iodc, eph.toes);
688 }
689 if (sys == SYS_GPS || sys == SYS_QZS || sys == SYS_IRN) {
690 if (!(sat = satno(sys, prn))) {
691 trace(NULL, 2, "javad ephemeris satellite error: sys=%d prn=%d\n", sys, prn);
692 return -1;
693 }
694 eph.type = 0; /* ephemeris type = LNAV */
695 eph.flag = (flag >> 1) & 1;
696 eph.code = (flag >> 2) & 3;
697 eph.fit = flag & 1;
698 eph.week = adjgpsweek(week);
699 eph.toe = gpst2time(eph.week, eph.toes);
700
701 /* for week-handover problem */
702 tt = timediff(eph.toe, raw->time);
703 if (tt < -302400.0) {
704 eph.week++;
705 } else if (tt > 302400.0) {
706 eph.week--;
707 }
708 eph.toe = gpst2time(eph.week, eph.toes);
709
710 eph.toc = gpst2time(eph.week, toc);
711 eph.ttr = adjweek(eph.toe, tow);
712 } else if (sys == SYS_GAL) {
713 if (!(sat = satno(sys, prn))) {
714 trace(NULL, 2, "javad ephemeris satellite error: sys=%d prn=%d\n", sys, prn);
715 return -1;
716 }
717 eph.tgd[0] = R4(p);
718 p += 4; /* BGD: E1-E5A (s) */
719 eph.tgd[1] = R4(p);
720 p += 4 + 13; /* BGD: E1-E5B (s) */
721 navtype = U1(p); /* navtype: 0:E1B(INAV),1:E5A(FNAV) */
722 /* 3:GIOVE E1B,4:GIOVE E5A */
723
724 set = (navtype == 1) ? 1 : 0; /* 0:I/NAV,1:F/NAV */
725 if (!(eph_sel & 1) && set == 0) {
726 return 0;
727 }
728 if (!(eph_sel & 2) && set == 1) {
729 return 0;
730 }
731 eph.code = set ? (1 << 1) + (1 << 8) : (1 << 0) + (1 << 2) + (1 << 9);
732 eph.type = set; /* ephemeris type = I/NAV or F/NAV */
733
734 /* gal-week = gst-week + 1024 */
735 eph.week = week + 1024;
736 eph.toe = gpst2time(eph.week, eph.toes);
737
738 /* for week-handover problem */
739 tt = timediff(eph.toe, raw->time);
740 if (tt < -302400.0) {
741 eph.week++;
742 } else if (tt > 302400.0) {
743 eph.week--;
744 }
745 eph.toe = gpst2time(eph.week, eph.toes);
746
747 eph.toc = gpst2time(eph.week, toc);
748 eph.ttr = adjweek(eph.toe, tow);
749 } else if (sys == SYS_CMP) {
750 if (!(sat = satno(sys, prn))) {
751 trace(NULL, 2, "javad ephemeris satellite error: sys=%d prn=%d\n", sys, prn);
752 return -1;
753 }
754 eph.type = (prn >= 6 && prn <= 58) ? 0 : 1; /* ephemeris type = D1 or D2 */
755 eph.tgd[1] = R4(p);
756 p += 4; /* TGD2 (s) */
757 sigtype = U1(p); /* signal type: 0:B1,1:B2,2:B3 */
758 switch (sigtype) {
759 case 0:
760 eph.code = 1;
761 break;
762 case 1:
763 eph.code = 3;
764 break;
765 case 2:
766 eph.code = 5;
767 break;
768 default:
769 eph.code = 0;
770 break;
771 }
772 eph.week = week;
773 eph.toe = bdt2time(week, eph.toes); /* BDT -> GPST */
774 eph.toc = bdt2time(week, toc); /* BDT -> GPST */
775 eph.ttr = adjweek(eph.toe, tow);
776 } else {
777 return 0;
778 }
779
780 if (!strstr(raw->opt, "-EPHALL")) {
781 if (timediff(raw->nav.eph[sat - 1 + MAXSAT * set].toe, eph.toe) == 0.0 &&
782 raw->nav.eph[sat - 1 + MAXSAT * set].iode == eph.iode &&
783 raw->nav.eph[sat - 1 + MAXSAT * set].iodc == eph.iodc) {
784 return 0; /* unchanged */
785 }
786 }
787 eph.sat = sat;
788 raw->nav.eph[sat - 1] = eph;
789 raw->ephsat = sat;
790 raw->ephset = set;
791 return 2;
792}
793/* decode [GE] GPS ephemeris -------------------------------------------------*/
794static int decode_GE(raw_t* raw) {
795 if (!checksum(raw->buff, raw->len)) {
796 trace(NULL, 2, "javad GE checksum error: len=%d\n", raw->len);
797 return -1;
798 }
799 if (raw->len < 128) {
800 trace(NULL, 2, "javad GE length error: len=%d\n", raw->len);
801 return -1;
802 }
803 return decode_eph(raw, SYS_GPS);
804}
805/* decode [NE] GLONASS ephemeris ---------------------------------------------*/
806static int decode_NE(raw_t* raw) {
807 geph_t geph = {0};
808 double tt;
809 char* msg;
810 int prn, tk, tb;
811 uint8_t* p = raw->buff + 5;
812
813 if (!checksum(raw->buff, raw->len)) {
814 trace(NULL, 2, "javad NE checksum error: len=%d\n", raw->len);
815 return -1;
816 }
817 if (raw->len >= 85) { /* firmware v 2.6.0 [2] */
818 prn = U1(p);
819 p += 1;
820 geph.frq = I1(p);
821 p += 1 + 2;
822 tk = I4(p);
823 p += 4;
824 tb = I4(p);
825 p += 4;
826 geph.svh = U1(p) & 0x1;
827 p += 1; /* MSB of Bn */
828 geph.age = U1(p);
829 p += 1 + 1;
830 geph.pos[0] = R8(p) * 1E3;
831 p += 8;
832 geph.pos[1] = R8(p) * 1E3;
833 p += 8;
834 geph.pos[2] = R8(p) * 1E3;
835 p += 8;
836 geph.vel[0] = R4(p) * 1E3;
837 p += 4;
838 geph.vel[1] = R4(p) * 1E3;
839 p += 4;
840 geph.vel[2] = R4(p) * 1E3;
841 p += 4;
842 geph.acc[0] = R4(p) * 1E3;
843 p += 4;
844 geph.acc[1] = R4(p) * 1E3;
845 p += 4;
846 geph.acc[2] = R4(p) * 1E3;
847 p += 4 + 8;
848 geph.taun = R4(p);
849 p += 4;
850 geph.gamn = R4(p);
851 p += 4;
852 } else {
853 trace(NULL, 2, "javad NE length error: len=%d\n", raw->len);
854 return -1;
855 }
856 if (raw->len >= 93) { /* firmware v 3.2.0 [1] */
857 geph.dtaun = R4(p);
858 p += 4;
859 geph.sva = U1(p);
860 }
861 if (raw->outtype) {
862 msg = raw->msgtype + strlen(raw->msgtype);
863 sprintf(msg, " prn=%2d frq=%2d tk=%6d tb=%4d", prn, geph.frq, tk, tb);
864 }
865 if (!(geph.sat = satno(SYS_GLO, prn))) {
866 trace(NULL, 2, "javad NE satellite error: prn=%d\n", prn);
867 return 0;
868 }
869 if (raw->time.time == 0) {
870 return 0;
871 }
872 geph.iode = (tb / 900) & 0x7F;
873 geph.toe = utc2gpst(adjday(raw->time, tb - 10800.0));
874 geph.tof = utc2gpst(adjday(raw->time, tk - 10800.0));
875
876 /* check illegal ephemeris by toe */
877 tt = timediff(raw->time, geph.toe);
878 if (fabs(tt) > 3600.0) {
879 trace(NULL, 3, "javad NE illegal toe: prn=%2d tt=%6.0f\n", prn, tt);
880 return 0;
881 }
882 /* check illegal ephemeris by frequency number consistency */
883 if (raw->nav.geph[prn - 1].toe.time && geph.frq != raw->nav.geph[prn - 1].frq) {
884 trace(NULL, 2, "javad NE glonass fcn changed: prn=%2d fcn=%2d->%2d\n", prn, raw->nav.geph[prn - 1].frq,
885 geph.frq);
886 return -1;
887 }
888 if (!strstr(raw->opt, "-EPHALL")) {
889 if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && geph.svh == raw->nav.geph[prn - 1].svh) {
890 return 0; /* unchanged */
891 }
892 }
893 raw->nav.geph[prn - 1] = geph;
894 raw->ephsat = geph.sat;
895 return 2;
896}
897/* decode [EN] Galileo ephemeris ---------------------------------------------*/
898static int decode_EN(raw_t* raw) {
899 if (!checksum(raw->buff, raw->len)) {
900 trace(NULL, 2, "javad EN checksum error: len=%d\n", raw->len);
901 return -1;
902 }
903 if (raw->len < 150) {
904 trace(NULL, 2, "javad EN length error: len=%d\n", raw->len);
905 return -1;
906 }
907 return decode_eph(raw, SYS_GAL);
908}
909/* decode [WE] SBAS ephemeris ------------------------------------------------*/
910static int decode_WE(raw_t* raw) {
911 seph_t seph = {0};
912 uint32_t tod, tow;
913 char* msg;
914 int i, prn, week;
915 uint8_t* p = raw->buff + 5;
916
917 if (!checksum(raw->buff, raw->len)) {
918 trace(NULL, 2, "javad WE checksum error: len=%d\n", raw->len);
919 return -1;
920 }
921 if (raw->len < 44) {
922 trace(NULL, 2, "javad WE length error: len=%d\n", raw->len);
923 return -1;
924 }
925 prn = U1(p);
926 p += 1 + 1 + 1;
927 seph.sva = U1(p);
928 p += 1;
929 tod = U4(p);
930 p += 4;
931 for (i = 0; i < 3; i++) {
932 seph.pos[i] = R8(p);
933 p += 8;
934 }
935 for (i = 0; i < 3; i++) {
936 seph.vel[i] = R4(p);
937 p += 4;
938 }
939 for (i = 0; i < 3; i++) {
940 seph.acc[i] = R4(p);
941 p += 4;
942 }
943 seph.af0 = R4(p);
944 p += 4;
945 seph.af1 = R4(p);
946 p += 4;
947 tow = U4(p);
948 p += 4;
949 week = U2(p);
950
951 if (raw->outtype) {
952 msg = raw->msgtype + strlen(raw->msgtype);
953 sprintf(msg, " prn=%3d tod=%6d", prn, tod);
954 }
955 if (!(seph.sat = satno(SYS_SBS, prn))) {
956 trace(NULL, 2, "javad WE satellite error: prn=%d\n", prn);
957 return -1;
958 }
959 seph.tof = gpst2time(adjgpsweek(week), tow);
960 seph.t0 = adjday(seph.tof, tod);
961
962 if (!strstr(raw->opt, "-EPHALL")) {
963 if (fabs(timediff(seph.t0, raw->nav.seph[prn - MINPRNSBS].t0)) < 1.0 &&
964 seph.sva == raw->nav.seph[prn - MINPRNSBS].sva) {
965 return 0; /* unchanged */
966 }
967 }
968 raw->nav.seph[prn - MINPRNSBS] = seph;
969 raw->ephsat = seph.sat;
970 return 2;
971}
972/* decode [QE] QZSS ephemeris ------------------------------------------------*/
973static int decode_QE(raw_t* raw) {
974 if (!checksum(raw->buff, raw->len)) {
975 trace(NULL, 2, "javad QE checksum error: len=%d\n", raw->len);
976 return -1;
977 }
978 if (raw->len < 128) {
979 trace(NULL, 2, "javad QE length error: len=%d\n", raw->len);
980 return -1;
981 }
982 return decode_eph(raw, SYS_QZS);
983}
984/* decode [CN] Beidou ephemeris ----------------------------------------------*/
985static int decode_CN(raw_t* raw) {
986 if (!checksum(raw->buff, raw->len)) {
987 trace(NULL, 2, "javad CN checksum error: len=%d\n", raw->len);
988 return -1;
989 }
990 if (raw->len < 133) {
991 trace(NULL, 2, "javad QE length error: len=%d\n", raw->len);
992 return -1;
993 }
994 return decode_eph(raw, SYS_CMP);
995}
996/* decode [IE] IRNSS ephemeris -----------------------------------------------*/
997static int decode_IE(raw_t* raw) {
998 if (!checksum(raw->buff, raw->len)) {
999 trace(NULL, 2, "javad IE checksum error: len=%d\n", raw->len);
1000 return -1;
1001 }
1002 if (raw->len < 129) {
1003 trace(NULL, 2, "javad IE length error: len=%d\n", raw->len);
1004 return -1;
1005 }
1006 return decode_eph(raw, SYS_IRN);
1007}
1008/* decode [UO] GPS UTC time parameters ---------------------------------------*/
1009static int decode_UO(raw_t* raw) {
1010 uint8_t* p = raw->buff + 5;
1011
1012 if (!checksum(raw->buff, raw->len)) {
1013 trace(NULL, 2, "javad UO checksum error: len=%d\n", raw->len);
1014 return -1;
1015 }
1016 if (raw->len < 29) {
1017 trace(NULL, 2, "javad UO length error: len=%d\n", raw->len);
1018 return -1;
1019 }
1020 raw->nav.utc_gps[0] = R8(p);
1021 p += 8;
1022 raw->nav.utc_gps[1] = R4(p);
1023 p += 4;
1024 raw->nav.utc_gps[2] = U4(p);
1025 p += 4;
1026 raw->nav.utc_gps[3] = adjgpsweek((int)U2(p));
1027 p += 2;
1028 raw->nav.utc_gps[4] = I1(p);
1029 return 9;
1030}
1031/* decode [NU] GLONASS UTC and GPS time parameters ---------------------------*/
1032static int decode_NU(raw_t* raw) {
1033 trace(NULL, 3, "javad NU unsupported\n");
1034
1035 return 0;
1036}
1037/* decode [EU] Galileo UTC and GPS time parameters ---------------------------*/
1038static int decode_EU(raw_t* raw) {
1039 trace(NULL, 3, "javad EU unsupported\n");
1040
1041 return 0;
1042}
1043/* decode [WU] WAAS UTC time parameters --------------------------------------*/
1044static int decode_WU(raw_t* raw) {
1045 trace(NULL, 3, "javad WU unsupported\n");
1046
1047 return 0;
1048}
1049/* decode [QU] QZSS UTC and GPS time parameters ------------------------------*/
1050static int decode_QU(raw_t* raw) {
1051 trace(NULL, 3, "javad QU unsupported\n");
1052
1053 return 0;
1054}
1055/* decode [IO] ionospheric parameters ----------------------------------------*/
1056static int decode_IO(raw_t* raw) {
1057 int i;
1058 uint8_t* p = raw->buff + 5;
1059
1060 if (!checksum(raw->buff, raw->len)) {
1061 trace(NULL, 2, "javad IO checksum error: len=%d\n", raw->len);
1062 return -1;
1063 }
1064 if (raw->len < 44) {
1065 trace(NULL, 2, "javad IO length error: len=%d\n", raw->len);
1066 return -1;
1067 }
1068 p += 4 + 2;
1069 for (i = 0; i < 8; i++) {
1070 raw->nav.ion_gps[i] = R4(p);
1071 p += 4;
1072 }
1073 return 9;
1074}
1075/* decode L1 ephemeris -------------------------------------------------------*/
1076static int decode_L1eph(int sat, raw_t* raw) {
1077 eph_t eph = {0};
1078
1079 if (!decode_frame(raw->subfrm[sat - 1], &eph, NULL, NULL, NULL)) {
1080 return 0;
1081 }
1082
1083 if (!strstr(raw->opt, "-EPHALL")) {
1084 if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc) {
1085 return 0;
1086 }
1087 }
1088 eph.sat = sat;
1089 raw->nav.eph[sat - 1] = eph;
1090 raw->ephsat = sat;
1091 raw->ephset = 0;
1092 return 2;
1093}
1094/* UTC 8-bit week -> full week -----------------------------------------------*/
1095static void adj_utcweek(gtime_t time, double* utc) {
1096 int week;
1097
1098 time2gpst(time, &week);
1099 utc[3] += week / 256 * 256;
1100 if (utc[3] < week - 127) {
1101 utc[3] += 256.0;
1102 } else if (utc[3] > week + 127) {
1103 utc[3] -= 256.0;
1104 }
1105 utc[5] += utc[3] / 256 * 256;
1106 if (utc[5] < utc[3] - 127) {
1107 utc[5] += 256.0;
1108 } else if (utc[5] > utc[3] + 127) {
1109 utc[5] -= 256.0;
1110 }
1111}
1112/* decode L1 ION/UTC parameters ----------------------------------------------*/
1113static int decode_L1ionutc(int sat, raw_t* raw) {
1114 double ion[8], utc[8];
1115 int sys = satsys(sat, NULL);
1116
1117 if (!decode_frame(raw->subfrm[sat - 1], NULL, NULL, ion, utc)) {
1118 return 0;
1119 }
1120
1121 adj_utcweek(raw->time, utc);
1122 if (sys == SYS_QZS) {
1123 matcpy(raw->nav.ion_qzs, ion, 8, 1);
1124 matcpy(raw->nav.utc_qzs, utc, 8, 1);
1125 } else {
1126 matcpy(raw->nav.ion_gps, ion, 8, 1);
1127 matcpy(raw->nav.utc_gps, utc, 8, 1);
1128 }
1129 return 9;
1130}
1131/* decode L1 NAV data --------------------------------------------------------*/
1132static int decode_L1nav(uint8_t* buff, int len, int sat, raw_t* raw) {
1133 uint8_t subfrm[30], *p;
1134 int i, id, sys = satsys(sat, NULL);
1135
1136 if (sys != SYS_GPS && sys != SYS_QZS) {
1137 trace(NULL, 2, "navigation subframe system error: sat=%d\n", sat);
1138 return -1;
1139 }
1140 if (len < 10) {
1141 trace(NULL, 2, "navigation subframe length error: len=%d\n", len);
1142 return -1;
1143 }
1144 for (i = 0, p = buff; i < 10; i++, p += 4) {
1145 setbitu(subfrm, 24 * i, 24, U4(p) >> 6);
1146 }
1147 id = getbitu(subfrm, 43, 3);
1148 if (id < 1 || id > 5) {
1149 trace(NULL, 2, "navigation subframe format error: sat=%d id=%d\n", sat, id);
1150 return -1;
1151 }
1152 memcpy(raw->subfrm[sat - 1] + (id - 1) * 30, subfrm, 30);
1153
1154 if (id == 3) {
1155 return decode_L1eph(sat, raw);
1156 } else if (id == 4 || id == 5) {
1157 return decode_L1ionutc(sat, raw);
1158 }
1159 return 0;
1160}
1161/* decode raw L2C CNAV data --------------------------------------------------*/
1162static int decode_L2nav(uint8_t* buff, int len, int sat, raw_t* raw) {
1163 uint8_t msg[1024] = {0};
1164 int i, j, preamb, prn, msgid, tow, alert;
1165
1166 trace(NULL, 3, "decode_L2nav len=%2d sat=%2d L5 CNAV\n", len, sat);
1167
1168 for (i = 0; i < len; i++) {
1169 for (j = 0; j < 4; j++) {
1170 msg[3 - j + i * 4] = buff[j + i * 4];
1171 }
1172 }
1173 i = 0;
1174 preamb = getbitu(msg, i, 8);
1175 i += 8;
1176 prn = getbitu(msg, i, 6);
1177 i += 6;
1178 msgid = getbitu(msg, i, 6);
1179 i += 6;
1180 tow = getbitu(msg, i, 17);
1181 i += 17;
1182 alert = getbitu(msg, i, 1);
1183 i += 1;
1184
1185 if (preamb != PREAMB_CNAV) {
1186 trace(NULL, 2, "javad *d sat=%2d L2 CNAV preamble error preamb=%02X\n", preamb);
1187 return -1;
1188 }
1189 trace(NULL, 3, "L2CNAV: sat=%2d prn=%2d msgid=%2d tow=%6d alert=%d\n", sat, prn, msgid, tow, alert);
1190
1191 return 0;
1192}
1193/* decode raw L5 CNAV data ---------------------------------------------------*/
1194static int decode_L5nav(uint8_t* buff, int len, int sat, raw_t* raw) {
1195 uint8_t msg[1024] = {0};
1196 int i, j, preamb, prn, msgid, tow, alert;
1197
1198 trace(NULL, 3, "decode_L5nav len=%2d sat=%2d L5 CNAV\n", len, sat);
1199
1200 for (i = 0; i < len; i++) {
1201 for (j = 0; j < 4; j++) {
1202 msg[3 - j + i * 4] = buff[j + i * 4];
1203 }
1204 }
1205 i = 0;
1206 preamb = getbitu(msg, i, 8);
1207 i += 8;
1208 prn = getbitu(msg, i, 6);
1209 i += 6;
1210 msgid = getbitu(msg, i, 6);
1211 i += 6;
1212 tow = getbitu(msg, i, 17);
1213 i += 17;
1214 alert = getbitu(msg, i, 1);
1215 i += 1;
1216
1217 if (preamb != PREAMB_CNAV) {
1218 trace(NULL, 2, "javad *d sat=%2d L5 CNAV preamble error preamb=%02X\n", preamb);
1219 return -1;
1220 }
1221 trace(NULL, 3, "L5CNAV: sat=%2d prn=%2d msgid=%2d tow=%6d alert=%d\n", sat, prn, msgid, tow, alert);
1222
1223 return 0;
1224}
1225/* decode raw L1C CNAV2 data -------------------------------------------------*/
1226static int decode_L1Cnav(uint8_t* buff, int len, int sat, raw_t* raw) {
1227 trace(NULL, 3, "javad *d len=%2d sat=%2d L1C CNAV2 unsupported\n", len, sat);
1228
1229 return 0;
1230}
1231/* decode [*D] raw navigation data -------------------------------------------*/
1232static int decode_nD(raw_t* raw, int sys) {
1233 int i, n, siz, sat, prn, stat = 0;
1234 uint8_t* p = raw->buff + 5;
1235
1236 if (!checksum(raw->buff, raw->len)) {
1237 trace(NULL, 2, "javad nD checksum error: sys=%d len=%d\n", sys, raw->len);
1238 return -1;
1239 }
1240 siz = U1(p);
1241 p += 1;
1242 n = (raw->len - 7) / siz;
1243
1244 if (n <= 0) {
1245 trace(NULL, 2, "javad nD length error: sys=%d len=%d\n", sys, raw->len);
1246 return -1;
1247 }
1248 for (i = 0; i < n; i++, p += siz) {
1249 trace(NULL, 3, "decode_*D: sys=%2d prn=%3d\n", sys, U1(p));
1250
1251 prn = U1(p);
1252 if (!(sat = satno(sys, prn))) {
1253 trace(NULL, 2, "javad nD satellite error: sys=%d prn=%d\n", sys, prn);
1254 continue;
1255 }
1256 stat = decode_L1nav(p + 2, 0, sat, raw);
1257 }
1258 return stat;
1259}
1260/* decode [*d] raw navigation data -------------------------------------------*/
1261static int decode_nd(raw_t* raw, int sys) {
1262 uint8_t* p = raw->buff + 5;
1263 char* msg;
1264 int sat, prn, time, type, len;
1265
1266 if (!checksum(raw->buff, raw->len)) {
1267 trace(NULL, 2, "javad nd checksum error: sys=%d len=%d\n", sys, raw->len);
1268 return -1;
1269 }
1270 trace(NULL, 3, "decode_*d: sys=%2d prn=%3d\n", sys, U1(p));
1271
1272 prn = U1(p);
1273 p += 1;
1274 time = U4(p);
1275 p += 4;
1276 type = U1(p);
1277 p += 1;
1278 len = U1(p);
1279 p += 1;
1280 if (raw->len != 13 + len * 4) {
1281 trace(NULL, 2, "javad nd length error: sys=%d len=%d\n", sys, raw->len);
1282 return -1;
1283 }
1284 if (raw->outtype) {
1285 msg = raw->msgtype + strlen(raw->msgtype);
1286 sprintf(msg, " prn=%3d time=%7d type=%d", prn, time, type);
1287 }
1288 if (!(sat = satno(sys, prn))) {
1289 trace(NULL, 2, "javad nd satellite error: sys=%d prn=%d\n", sys, prn);
1290 return 0;
1291 }
1292 trace(NULL, 4, "sat=%2d time=%7d type=%d len=%3d\n", sat, time, type, len);
1293
1294 switch (type) {
1295 case 0:
1296 return decode_L1nav(p, len, sat, raw); /* L1 NAV */
1297 case 1:
1298 return decode_L2nav(p, len, sat, raw); /* L2C CNAV */
1299 case 2:
1300 return decode_L5nav(p, len, sat, raw); /* L5 CNAV */
1301 case 3:
1302 return decode_L1Cnav(p, len, sat, raw); /* L1C CNAV2 */
1303 }
1304 return 0;
1305}
1306/* decode [LD] GLONASS raw navigation data -----------------------------------*/
1307static int decode_LD(raw_t* raw) {
1308 trace(NULL, 3, "javad LD unsupported\n");
1309
1310 return 0;
1311}
1312/* decode [lD] GLONASS raw navigation data -----------------------------------*/
1313static int decode_lD(raw_t* raw) {
1314 geph_t geph = {0};
1315 uint8_t* p = raw->buff + 5;
1316 char* msg;
1317 int i, sat, prn, frq, time, type, len, id;
1318
1319 if (!checksum(raw->buff, raw->len)) {
1320 trace(NULL, 2, "javad lD checksum error: len=%d\n", raw->len);
1321 return -1;
1322 }
1323 trace(NULL, 3, "decode_lD: prn=%3d\n", U1(p));
1324
1325 prn = U1(p);
1326 p += 1;
1327 frq = I1(p);
1328 p += 1;
1329 time = U4(p);
1330 p += 4;
1331 type = U1(p);
1332 p += 1;
1333 len = U1(p);
1334 p += 1;
1335
1336 if (raw->len != 14 + len * 4) {
1337 trace(NULL, 2, "javad lD length error: len=%d\n", raw->len);
1338 return -1;
1339 }
1340 if (raw->outtype) {
1341 msg = raw->msgtype + strlen(raw->msgtype);
1342 sprintf(msg, " prn=%2d frq=%2d time=%7d type=%d", prn, frq, time, type);
1343 }
1344 if (!(sat = satno(SYS_GLO, prn))) {
1345 trace(NULL, 2, "javad lD satellite error: prn=%d\n", prn);
1346 return 0;
1347 }
1348 if (type != 0) {
1349 trace(NULL, 3, "javad lD type unsupported: type=%d\n", type);
1350 return 0;
1351 }
1352 if ((id = (U4(p) >> 20) & 0xF) < 1) {
1353 return 0;
1354 }
1355
1356 /* get 77 bit (25x3+2) in frame without hamming and time mark */
1357 for (i = 0; i < 4; i++) {
1358 setbitu(raw->subfrm[sat - 1] + (id - 1) * 10, i * 25, i < 3 ? 25 : 2, U4(p + 4 * i) >> (i < 3 ? 0 : 23));
1359 }
1360 if (id != 4) {
1361 return 0;
1362 }
1363
1364 /* decode glonass ephemeris strings */
1365 geph.tof = raw->time;
1366 if (!decode_glostr(raw->subfrm[sat - 1], &geph, NULL) || geph.sat != sat) {
1367 return -1;
1368 }
1369 geph.frq = frq;
1370
1371 if (!strstr(raw->opt, "-EPHALL")) {
1372 if (geph.iode == raw->nav.geph[prn - 1].iode) {
1373 return 0; /* unchanged */
1374 }
1375 }
1376 raw->nav.geph[prn - 1] = geph;
1377 raw->ephsat = sat;
1378 return 2;
1379}
1380/* decode [ED] Galileo raw navigation data -----------------------------------*/
1381static int decode_ED(raw_t* raw) {
1382 trace(NULL, 3, "javad ED unsupported\n");
1383
1384 return 0;
1385}
1386/* decode [cd] Beidou raw navigation data ------------------------------------*/
1387static int decode_cd(raw_t* raw) {
1388 trace(NULL, 3, "javad cd unsupported\n");
1389
1390 return 0;
1391}
1392/* decode [id] IRNSS raw navigation data -------------------------------------*/
1393static int decode_id(raw_t* raw) {
1394 trace(NULL, 3, "javad id unsupported\n");
1395
1396 return 0;
1397}
1398/* decode [WD] SBAS raw navigation data --------------------------------------*/
1399static int decode_WD(raw_t* raw) {
1400 int i, prn, tow, tow_p, week;
1401 char* msg;
1402 uint8_t* p = raw->buff + 5;
1403
1404 if (!checksum(raw->buff, raw->len)) {
1405 trace(NULL, 2, "javad WD checksum error: len=%d\n", raw->len);
1406 return -1;
1407 }
1408 if (raw->len < 45) {
1409 trace(NULL, 2, "javad WD length error: len=%d\n", raw->len);
1410 return -1;
1411 }
1412 trace(NULL, 3, "decode_WD: prn=%3d\n", U1(p));
1413
1414 prn = U1(p);
1415 p += 1;
1416 tow = U4(p);
1417 p += 4 + 2;
1418
1419 if (raw->outtype) {
1420 msg = raw->msgtype + strlen(raw->msgtype);
1421 sprintf(msg, " prn=%3d tow=%6d", prn, tow);
1422 }
1423 if ((prn < MINPRNSBS || MAXPRNSBS < prn) && (prn < MINPRNQZS || MAXPRNQZS < prn)) {
1424 trace(NULL, 2, "javad WD satellite error: prn=%d\n", prn);
1425 return 0;
1426 }
1427 if (prn >= MINPRNQZS && prn <= MAXPRNQZS) {
1428 prn -= 10; /* QZSS L1S */
1429 }
1430 raw->sbsmsg.prn = prn;
1431 raw->sbsmsg.tow = tow;
1432
1433 if (raw->time.time == 0) {
1434 raw->sbsmsg.week = 0;
1435 } else {
1436 tow_p = (int)time2gpst(raw->time, &week);
1437 if (tow < tow_p - 302400.0) {
1438 week++;
1439 } else if (tow > tow_p + 302400.0) {
1440 week--;
1441 }
1442 raw->sbsmsg.week = week;
1443 }
1444 for (i = 0; i < 29; i++) {
1445 raw->sbsmsg.msg[i] = *p++;
1446 }
1447 raw->sbsmsg.msg[28] &= 0xC0;
1448 return 3;
1449}
1450/* decode [R*] pseudoranges --------------------------------------------------*/
1451static int decode_Rx(raw_t* raw, char sig) {
1452 uint8_t* p = raw->buff + 5;
1453 double pr, prm;
1454 int i, idx, code, sat, sys;
1455
1456 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1457 return 0;
1458 }
1459
1460 if (!checksum(raw->buff, raw->len)) {
1461 trace(NULL, 2, "javad R%c checksum error: len=%d\n", sig, raw->len);
1462 return -1;
1463 }
1464 if (raw->len != raw->obuf.n * 8 + 6) {
1465 trace(NULL, 2, "javad R%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1466 return -1;
1467 }
1468 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1469 pr = R8(p);
1470 p += 8;
1471 if (pr == 0.0) {
1472 continue;
1473 }
1474
1475 sat = raw->obuf.data[i].sat;
1476 if (!(sys = satsys(sat, NULL))) {
1477 continue;
1478 }
1479
1480 prm = pr * CLIGHT;
1481
1482 if (sig == 'C') {
1483 raw->prCA[sat - 1] = prm;
1484 }
1485
1486 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1487 continue;
1488 }
1489
1490 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1491 if (!settag(raw->obuf.data + i, raw->time)) {
1492 continue;
1493 }
1494 raw->obuf.data[i].P[idx] = prm;
1495 raw->obuf.data[i].code[idx] = code;
1496 }
1497 }
1498 return 0;
1499}
1500/* decode [r*] short pseudoranges --------------------------------------------*/
1501static int decode_rx(raw_t* raw, char sig) {
1502 uint8_t* p = raw->buff + 5;
1503 double prm;
1504 int i, idx, code, pr, sat, sys;
1505
1506 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1507 return 0;
1508 }
1509
1510 if (!checksum(raw->buff, raw->len)) {
1511 trace(NULL, 2, "javad r%c checksum error: len=%d\n", sig, raw->len);
1512 return -1;
1513 }
1514 if (raw->len != raw->obuf.n * 4 + 6) {
1515 trace(NULL, 2, "javad r%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1516 return -1;
1517 }
1518 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1519 pr = I4(p);
1520 p += 4;
1521 sat = raw->obuf.data[i].sat;
1522 if (!(sys = satsys(sat, NULL))) {
1523 continue;
1524 }
1525
1526 if (pr == 0x7FFFFFFF) {
1527 trace(NULL, 3, "javad r%c value missing: sat=%2d\n", sig, sat);
1528 continue;
1529 }
1530 /* Ksys Asys */
1531 if (sys == SYS_SBS) {
1532 prm = (pr * 1E-11 + 0.125) * CLIGHT; /* [6] */
1533 } else if (sys == SYS_QZS) {
1534 prm = (pr * 2E-11 + 0.125) * CLIGHT; /* [3] */
1535 } else if (sys == SYS_CMP) {
1536 prm = (pr * 2E-11 + 0.105) * CLIGHT; /* [4] */
1537 } else if (sys == SYS_GAL) {
1538 prm = (pr * 2E-11 + 0.085) * CLIGHT; /* [7] */
1539 } else if (sys == SYS_IRN) {
1540 prm = (pr * 2E-11 + 0.105) * CLIGHT; /* [6] */
1541 } else {
1542 prm = (pr * 1E-11 + 0.075) * CLIGHT;
1543 }
1544
1545 if (sig == 'c') {
1546 raw->prCA[sat - 1] = prm;
1547 }
1548
1549 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1550 continue;
1551 }
1552
1553 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1554 if (!settag(raw->obuf.data + i, raw->time)) {
1555 continue;
1556 }
1557 raw->obuf.data[i].P[idx] = prm;
1558 raw->obuf.data[i].code[idx] = (uint8_t)code;
1559 }
1560 }
1561 return 0;
1562}
1563/* decode [*R] relative pseudoranges -----------------------------------------*/
1564static int decode_xR(raw_t* raw, char sig) {
1565 uint8_t* p = raw->buff + 5;
1566 float pr;
1567 int i, idx, code, sat, sys;
1568
1569 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1570 return 0;
1571 }
1572
1573 if (!checksum(raw->buff, raw->len)) {
1574 trace(NULL, 2, "javad %cR checksum error: len=%d\n", sig, raw->len);
1575 return -1;
1576 }
1577 if (raw->len != raw->obuf.n * 4 + 6) {
1578 trace(NULL, 2, "javad %cR length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1579 return -1;
1580 }
1581 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1582 pr = R4(p);
1583 p += 4;
1584 if (pr == 0.0) {
1585 continue;
1586 }
1587
1588 sat = raw->obuf.data[i].sat;
1589 if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) {
1590 continue;
1591 }
1592
1593 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1594 continue;
1595 }
1596
1597 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1598 if (!settag(raw->obuf.data + i, raw->time)) {
1599 continue;
1600 }
1601 raw->obuf.data[i].P[idx] = pr * CLIGHT + raw->prCA[sat - 1];
1602 raw->obuf.data[i].code[idx] = (uint8_t)code;
1603 }
1604 }
1605 return 0;
1606}
1607/* decode [*r] short relative pseudoranges -----------------------------------*/
1608static int decode_xr(raw_t* raw, char sig) {
1609 uint8_t* p = raw->buff + 5;
1610 double prm;
1611 int16_t pr;
1612 int i, idx, code, sat, sys;
1613
1614 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1615 return 0;
1616 }
1617
1618 if (!checksum(raw->buff, raw->len)) {
1619 trace(NULL, 2, "javad %cr checksum error: len=%d\n", sig, raw->len);
1620 return -1;
1621 }
1622 if (raw->len != raw->obuf.n * 2 + 6) {
1623 trace(NULL, 2, "javad %cR length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1624 return -1;
1625 }
1626 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1627 pr = I2(p);
1628 p += 2;
1629 if (pr == (int16_t)0x7FFF) {
1630 continue;
1631 }
1632
1633 sat = raw->obuf.data[i].sat;
1634 if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) {
1635 continue;
1636 }
1637
1638 prm = (pr * 1E-11 + 2E-7) * CLIGHT + raw->prCA[sat - 1];
1639
1640 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1641 continue;
1642 }
1643
1644 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1645 if (!settag(raw->obuf.data + i, raw->time)) {
1646 continue;
1647 }
1648 raw->obuf.data[i].P[idx] = prm;
1649 raw->obuf.data[i].code[idx] = (uint8_t)code;
1650 }
1651 }
1652 return 0;
1653}
1654/* decode [P*] carrier phases ------------------------------------------------*/
1655static int decode_Px(raw_t* raw, char sig) {
1656 uint8_t* p = raw->buff + 5;
1657 double cp;
1658 int i, idx, code, sys;
1659
1660 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1661 return 0;
1662 }
1663
1664 if (!checksum(raw->buff, raw->len)) {
1665 trace(NULL, 2, "javad P%c checksum error: len=%d\n", sig, raw->len);
1666 return -1;
1667 }
1668 if (raw->len != raw->obuf.n * 8 + 6) {
1669 trace(NULL, 2, "javad P%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1670 return -1;
1671 }
1672 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1673 cp = R8(p);
1674 p += 8;
1675 if (cp == 0.0) {
1676 continue;
1677 }
1678
1679 if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) {
1680 continue;
1681 }
1682
1683 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1684 continue;
1685 }
1686
1687 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1688 if (!settag(raw->obuf.data + i, raw->time)) {
1689 continue;
1690 }
1691 raw->obuf.data[i].L[idx] = cp;
1692 raw->obuf.data[i].code[idx] = (uint8_t)code;
1693 }
1694 }
1695 return 0;
1696}
1697/* decode [p*] short carrier phases ------------------------------------------*/
1698static int decode_px(raw_t* raw, char sig) {
1699 uint8_t* p = raw->buff + 5;
1700 uint32_t cp;
1701 int i, idx, code, sys;
1702
1703 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1704 return 0;
1705 }
1706
1707 if (!checksum(raw->buff, raw->len)) {
1708 trace(NULL, 2, "javad p%c checksum error: len=%d\n", sig, raw->len);
1709 return -1;
1710 }
1711 if (raw->len != raw->obuf.n * 4 + 6) {
1712 trace(NULL, 2, "javad p%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1713 return -1;
1714 }
1715 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1716 cp = U4(p);
1717 p += 4;
1718 if (cp == 0xFFFFFFFF) {
1719 continue;
1720 }
1721
1722 if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) {
1723 continue;
1724 }
1725
1726 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1727 continue;
1728 }
1729
1730 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1731 if (!settag(raw->obuf.data + i, raw->time)) {
1732 continue;
1733 }
1734 raw->obuf.data[i].L[idx] = cp / 1024.0;
1735 raw->obuf.data[i].code[idx] = (uint8_t)code;
1736 }
1737 }
1738 return 0;
1739}
1740/* decode [*P] short relative carrier phases ---------------------------------*/
1741static int decode_xP(raw_t* raw, char sig) {
1742 uint8_t* p = raw->buff + 5;
1743 double cp, rcp, freq;
1744 int i, idx, code, sat, sys;
1745
1746 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1747 return 0;
1748 }
1749
1750 if (!checksum(raw->buff, raw->len)) {
1751 trace(NULL, 2, "javad %cP checksum error: len=%d\n", sig, raw->len);
1752 return -1;
1753 }
1754 if (raw->len != raw->obuf.n * 4 + 6) {
1755 trace(NULL, 2, "javad %cP length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1756 return -1;
1757 }
1758 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1759 rcp = R4(p);
1760 p += 4;
1761 if (rcp == 0.0) {
1762 continue;
1763 }
1764
1765 sat = raw->obuf.data[i].sat;
1766 if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) {
1767 continue;
1768 }
1769
1770 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1771 continue;
1772 }
1773
1774 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1775 if (!settag(raw->obuf.data + i, raw->time)) {
1776 continue;
1777 }
1778
1779 freq = code2freq(sys, code, raw->freqn[i]);
1780 cp = (rcp + raw->prCA[sat - 1] / CLIGHT) * freq;
1781
1782 raw->obuf.data[i].L[idx] = cp;
1783 raw->obuf.data[i].code[idx] = (uint8_t)code;
1784 }
1785 }
1786 return 0;
1787}
1788/* decode [*p] short relative carrier phases ---------------------------------*/
1789static int decode_xp(raw_t* raw, char sig) {
1790 uint8_t* p = raw->buff + 5;
1791 double cp, freq;
1792 int i, idx, code, rcp, sat, sys;
1793
1794 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1795 return 0;
1796 }
1797
1798 if (!checksum(raw->buff, raw->len)) {
1799 trace(NULL, 2, "javad %cp checksum error: len=%d\n", sig, raw->len);
1800 return -1;
1801 }
1802 if (raw->len != raw->obuf.n * 4 + 6) {
1803 trace(NULL, 2, "javad %cp length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1804 return -1;
1805 }
1806 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1807 rcp = I4(p);
1808 p += 4;
1809 if (rcp == 0x7FFFFFFF) {
1810 continue;
1811 }
1812
1813 sat = raw->obuf.data[i].sat;
1814 if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) {
1815 continue;
1816 }
1817
1818 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1819 continue;
1820 }
1821
1822 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1823 if (!settag(raw->obuf.data + i, raw->time)) {
1824 continue;
1825 }
1826
1827 freq = code2freq(sys, (uint8_t)code, raw->freqn[i]);
1828 cp = (rcp * P2_40 + raw->prCA[sat - 1] / CLIGHT) * freq;
1829
1830 raw->obuf.data[i].L[idx] = cp;
1831 raw->obuf.data[i].code[idx] = (uint8_t)code;
1832 }
1833 }
1834 return 0;
1835}
1836/* decode [D*] doppler -------------------------------------------------------*/
1837static int decode_Dx(raw_t* raw, char sig) {
1838 uint8_t* p = raw->buff + 5;
1839 double dop;
1840 int i, idx, code, dp, sat, sys;
1841
1842 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1843 return 0;
1844 }
1845
1846 if (!checksum(raw->buff, raw->len)) {
1847 trace(NULL, 2, "javad D%c checksum error: len=%d\n", sig, raw->len);
1848 return -1;
1849 }
1850 if (raw->len != raw->obuf.n * 4 + 6) {
1851 trace(NULL, 2, "javad D%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1852 return -1;
1853 }
1854 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1855 dp = I4(p);
1856 p += 4;
1857 if (dp == 0x7FFFFFFF) {
1858 continue;
1859 }
1860
1861 sat = raw->obuf.data[i].sat;
1862 if (!(sys = satsys(sat, NULL))) {
1863 continue;
1864 }
1865
1866 dop = -dp * 1E-4;
1867
1868 if (sig == 'C') {
1869 raw->dpCA[sat - 1] = dop;
1870 }
1871
1872 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1873 continue;
1874 }
1875
1876 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1877 if (!settag(raw->obuf.data + i, raw->time)) {
1878 continue;
1879 }
1880 raw->obuf.data[i].D[idx] = (float)dop;
1881 }
1882 }
1883 return 0;
1884}
1885/* decode [*d] short relative doppler ----------------------------------------*/
1886static int decode_xd(raw_t* raw, char sig) {
1887 uint8_t* p = raw->buff + 5;
1888 double dop, f1, fn;
1889 int16_t rdp;
1890 int i, idx, code, sat, sys;
1891
1892 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1893 return 0;
1894 }
1895
1896 if (!checksum(raw->buff, raw->len)) {
1897 trace(NULL, 2, "javad %cd checksum error: len=%d\n", sig, raw->len);
1898 return -1;
1899 }
1900 if (raw->len != raw->obuf.n * 2 + 6) {
1901 trace(NULL, 2, "javad %cd length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1902 return -1;
1903 }
1904 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1905 rdp = I2(p);
1906 p += 2;
1907 if (rdp == (int16_t)0x7FFF) {
1908 continue;
1909 }
1910
1911 sat = raw->obuf.data[i].sat;
1912 if (!(sys = satsys(sat, NULL)) || raw->dpCA[sat - 1] == 0.0) {
1913 continue;
1914 }
1915
1916 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1917 continue;
1918 }
1919
1920 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1921 if (!settag(raw->obuf.data + i, raw->time)) {
1922 continue;
1923 }
1924 f1 = code2freq(sys, CODE_L1X, raw->freqn[i]);
1925 fn = code2freq(sys, code, raw->freqn[i]);
1926 dop = (-rdp + raw->dpCA[sat - 1] * 1E4) * fn / f1 * 1E-4;
1927
1928 raw->obuf.data[i].D[idx] = (float)dop;
1929 }
1930 }
1931 return 0;
1932}
1933/* decode [E*] carrier to noise ratio ----------------------------------------*/
1934static int decode_Ex(raw_t* raw, char sig) {
1935 uint8_t* p = raw->buff + 5;
1936 uint8_t cnr;
1937 int i, idx, code, sys;
1938
1939 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1940 return 0;
1941 }
1942
1943 if (!checksum(raw->buff, raw->len)) {
1944 trace(NULL, 2, "javad E%c checksum error: len=%d\n", sig, raw->len);
1945 return -1;
1946 }
1947 if (raw->len != raw->obuf.n + 6) {
1948 trace(NULL, 2, "javad E%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1949 return -1;
1950 }
1951 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1952 cnr = U1(p);
1953 p += 1;
1954 if (cnr == 255) {
1955 continue;
1956 }
1957
1958 if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) {
1959 continue;
1960 }
1961
1962 if ((idx = sig2idx(sys, sig, &code)) < 0) {
1963 continue;
1964 }
1965
1966 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
1967 if (!settag(raw->obuf.data + i, raw->time)) {
1968 continue;
1969 }
1970 raw->obuf.data[i].SNR[idx] = (uint16_t)(cnr / SNR_UNIT + 0.5);
1971 }
1972 }
1973 return 0;
1974}
1975/* decode [*E] carrier to noise ratio x 4 ------------------------------------*/
1976static int decode_xE(raw_t* raw, char sig) {
1977 uint8_t* p = raw->buff + 5;
1978 uint8_t cnr;
1979 int i, idx, code, sys;
1980
1981 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
1982 return 0;
1983 }
1984
1985 if (!checksum(raw->buff, raw->len)) {
1986 trace(NULL, 2, "javad %cE checksum error: len=%d\n", sig, raw->len);
1987 return -1;
1988 }
1989 if (raw->len != raw->obuf.n + 6) {
1990 trace(NULL, 2, "javad %cE length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
1991 return -1;
1992 }
1993 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
1994 cnr = U1(p);
1995 p += 1;
1996 if (cnr == 255) {
1997 continue;
1998 }
1999
2000 if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) {
2001 continue;
2002 }
2003
2004 if ((idx = sig2idx(sys, sig, &code)) < 0) {
2005 continue;
2006 }
2007
2008 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
2009 if (!settag(raw->obuf.data + i, raw->time)) {
2010 continue;
2011 }
2012 raw->obuf.data[i].SNR[idx] = (uint16_t)(cnr * 0.25 / SNR_UNIT + 0.5);
2013 }
2014 }
2015 return 0;
2016}
2017/* decode [F*] signal lock loop flags ----------------------------------------*/
2018static int decode_Fx(raw_t* raw, char sig) {
2019 uint8_t* p = raw->buff + 5;
2020 uint16_t flags;
2021 int i, idx, code, sat, sys;
2022
2023 if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) {
2024 return 0;
2025 }
2026
2027 if (!checksum(raw->buff, raw->len)) {
2028 trace(NULL, 2, "javad F%c checksum error: len=%d\n", sig, raw->len);
2029 return -1;
2030 }
2031 if (raw->len != raw->obuf.n * 2 + 6) {
2032 trace(NULL, 2, "javad F%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len);
2033 return -1;
2034 }
2035 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
2036 flags = U2(p);
2037 p += 1;
2038 if (flags == 0xFFFF) {
2039 continue;
2040 }
2041
2042 sat = raw->obuf.data[i].sat;
2043 if (!(sys = satsys(sat, NULL))) {
2044 continue;
2045 }
2046
2047 if ((idx = sig2idx(sys, sig, &code)) < 0) {
2048 continue;
2049 }
2050
2051 if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) {
2052 if (!settag(raw->obuf.data + i, raw->time)) {
2053 continue;
2054 }
2055#if 0 /* disable to suppress overdetection of cycle-slips */
2056 if (flags&0x20) { /* loss-of-lock potential */
2057 raw->obuf.data[i].LLI[idx]|=1;
2058 }
2059 if (!(flags&0x40)||!(flags&0x100)) { /* integral indicator */
2060 raw->obuf.data[i].LLI[idx]|=2;
2061 }
2062#endif
2063 }
2064 }
2065 return 0;
2066}
2067/* decode [TC] CA/L1 continuous tracking time --------------------------------*/
2068static int decode_TC(raw_t* raw) {
2069 uint16_t tt, tt_p;
2070 int i, sat;
2071 uint8_t* p = raw->buff + 5;
2072
2073 if (raw->obuf.n == 0) {
2074 return 0;
2075 }
2076
2077 if (!checksum(raw->buff, raw->len)) {
2078 trace(NULL, 2, "javad TC checksum error: len=%d\n", raw->len);
2079 return -1;
2080 }
2081 if (raw->len != raw->obuf.n * 2 + 6) {
2082 trace(NULL, 2, "javad TC length error: n=%d len=%d\n", raw->obuf.n, raw->len);
2083 return -1;
2084 }
2085 for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) {
2086 tt = U2(p);
2087 p += 2;
2088 if (tt == 0xFFFF) {
2089 continue;
2090 }
2091
2092 if (!settag(raw->obuf.data + i, raw->time)) {
2093 continue;
2094 }
2095
2096 sat = raw->obuf.data[i].sat;
2097 tt_p = (uint16_t)raw->lockt[sat - 1][0];
2098
2099 trace(NULL, 4, "%s: sat=%2d tt=%6d->%6d\n", time_str(raw->time, 3), sat, tt_p, tt);
2100
2101 /* loss-of-lock detected by lock-time counter */
2102 if (tt == 0 || tt < tt_p) {
2103 trace(NULL, 3, "decode_TC: loss-of-lock detected: t=%s sat=%2d tt=%6d->%6d\n", time_str(raw->time, 3), sat,
2104 tt_p, tt);
2105 raw->obuf.data[i].LLI[0] |= 1;
2106 }
2107 raw->lockt[sat - 1][0] = tt;
2108 }
2109 return 0;
2110}
2111/* decode JAVAD raw message --------------------------------------------------*/
2112static int decode_javad(raw_t* raw) {
2113 char* p = (char*)raw->buff;
2114
2115 trace(NULL, 3, "decode_javad: type=%2.2s len=%3d\n", p, raw->len);
2116
2117 if (raw->outtype) {
2118 sprintf(raw->msgtype, "JAVAD %2.2s (%4d)", p, raw->len);
2119 }
2120 if (!strncmp(p, "~~", 2)) {
2121 return decode_RT(raw); /* receiver time */
2122 }
2123
2124 if (strstr(raw->opt, "-NOET")) {
2125 if (!strncmp(p, "::", 2)) {
2126 return decode_ET(raw); /* epoch time */
2127 }
2128 }
2129 if (!strncmp(p, "RD", 2)) {
2130 return decode_RD(raw); /* receiver date */
2131 }
2132 if (!strncmp(p, "SI", 2)) {
2133 return decode_SI(raw); /* satellite indices */
2134 }
2135 if (!strncmp(p, "NN", 2)) {
2136 return decode_NN(raw); /* GLONASS slot numbers */
2137 }
2138 if (!strncmp(p, "GA", 2)) {
2139 return decode_GA(raw); /* GPS almanac */
2140 }
2141 if (!strncmp(p, "NA", 2)) {
2142 return decode_NA(raw); /* GLONASS almanac */
2143 }
2144 if (!strncmp(p, "EA", 2)) {
2145 return decode_EA(raw); /* Galileo almanac */
2146 }
2147 if (!strncmp(p, "WA", 2)) {
2148 return decode_WA(raw); /* SBAS almanac */
2149 }
2150 if (!strncmp(p, "QA", 2)) {
2151 return decode_QA(raw); /* QZSS almanac */
2152 }
2153 if (!strncmp(p, "CA", 2)) {
2154 return decode_CA(raw); /* Beidou almanac */
2155 }
2156 if (!strncmp(p, "IA", 2)) {
2157 return decode_IA(raw); /* IRNSS almanac */
2158 }
2159
2160 if (!strncmp(p, "GE", 2)) {
2161 return decode_GE(raw); /* GPS ephemeris */
2162 }
2163 if (!strncmp(p, "NE", 2)) {
2164 return decode_NE(raw); /* GLONASS ephemeris */
2165 }
2166 if (!strncmp(p, "EN", 2)) {
2167 return decode_EN(raw); /* Galileo ephemeris */
2168 }
2169 if (!strncmp(p, "WE", 2)) {
2170 return decode_WE(raw); /* SBAS ephemeris */
2171 }
2172 if (!strncmp(p, "QE", 2)) {
2173 return decode_QE(raw); /* QZSS ephemeris */
2174 }
2175 if (!strncmp(p, "CN", 2)) {
2176 return decode_CN(raw); /* Beidou ephemeris */
2177 }
2178 if (!strncmp(p, "IE", 2)) {
2179 return decode_IE(raw); /* IRNSS ephemeris */
2180 }
2181
2182 if (!strncmp(p, "UO", 2)) {
2183 return decode_UO(raw); /* GPS UTC time parameters */
2184 }
2185 if (!strncmp(p, "NU", 2)) {
2186 return decode_NU(raw); /* GLONASS UTC and GPS time par */
2187 }
2188 if (!strncmp(p, "EU", 2)) {
2189 return decode_EU(raw); /* Galileo UTC and GPS time par */
2190 }
2191 if (!strncmp(p, "WU", 2)) {
2192 return decode_WU(raw); /* WAAS UTC time parameters */
2193 }
2194 if (!strncmp(p, "QU", 2)) {
2195 return decode_QU(raw); /* QZSS UTC and GPS time par */
2196 }
2197 if (!strncmp(p, "IO", 2)) {
2198 return decode_IO(raw); /* ionospheric parameters */
2199 }
2200
2201 if (!strncmp(p, "GD", 2)) {
2202 return decode_nD(raw, SYS_GPS); /* raw navigation data */
2203 }
2204 if (!strncmp(p, "QD", 2)) {
2205 return decode_nD(raw, SYS_QZS); /* raw navigation data */
2206 }
2207 if (!strncmp(p, "gd", 2)) {
2208 return decode_nd(raw, SYS_GPS); /* raw navigation data */
2209 }
2210 if (!strncmp(p, "qd", 2)) {
2211 return decode_nd(raw, SYS_QZS); /* raw navigation data */
2212 }
2213 if (!strncmp(p, "ED", 2)) {
2214 return decode_ED(raw); /* Galileo raw navigation data */
2215 }
2216
2217 if (!strncmp(p, "cd", 2)) {
2218 return decode_cd(raw); /* Beidou raw navigation data */
2219 }
2220 if (!strncmp(p, "id", 2)) {
2221 return decode_id(raw); /* IRNSS raw navigation data */
2222 }
2223 if (!strncmp(p, "LD", 2)) {
2224 return decode_LD(raw); /* GLONASS raw navigation data */
2225 }
2226 if (!strncmp(p, "lD", 2)) {
2227 return decode_lD(raw); /* GLONASS raw navigation data */
2228 }
2229 if (!strncmp(p, "WD", 2)) {
2230 return decode_WD(raw); /* SBAS raw navigation data */
2231 }
2232 if (!strncmp(p, "TC", 2)) {
2233 return decode_TC(raw); /* CA/L1 continuous track time */
2234 }
2235
2236 if (p[0] == 'R') {
2237 return decode_Rx(raw, p[1]); /* pseudoranges */
2238 }
2239 if (p[0] == 'r') {
2240 return decode_rx(raw, p[1]); /* short pseudoranges */
2241 }
2242 if (p[1] == 'R') {
2243 return decode_xR(raw, p[0]); /* relative pseudoranges */
2244 }
2245 if (p[1] == 'r') {
2246 return decode_xr(raw, p[0]); /* short relative pseudoranges */
2247 }
2248 if (p[0] == 'P') {
2249 return decode_Px(raw, p[1]); /* carrier phases */
2250 }
2251 if (p[0] == 'p') {
2252 return decode_px(raw, p[1]); /* short carrier phases */
2253 }
2254 if (p[1] == 'P') {
2255 return decode_xP(raw, p[0]); /* relative carrier phases */
2256 }
2257 if (p[1] == 'p') {
2258 return decode_xp(raw, p[0]); /* relative carrier phases */
2259 }
2260 if (p[0] == 'D') {
2261 return decode_Dx(raw, p[1]); /* doppler */
2262 }
2263 if (p[1] == 'd') {
2264 return decode_xd(raw, p[0]); /* short relative doppler */
2265 }
2266 if (p[0] == 'E') {
2267 return decode_Ex(raw, p[1]); /* carrier to noise ratio */
2268 }
2269 if (p[1] == 'E') {
2270 return decode_xE(raw, p[0]); /* carrier to noise ratio x 4 */
2271 }
2272 if (p[0] == 'F') {
2273 return decode_Fx(raw, p[1]); /* signal lock loop flags */
2274 }
2275
2276 return 0;
2277}
2278/* sync JAVAD message --------------------------------------------------------*/
2279static int sync_javad(uint8_t* buff, uint8_t data) {
2280 uint8_t p = buff[0];
2281
2282 buff[0] = buff[1];
2283 buff[1] = buff[2];
2284 buff[2] = buff[3];
2285 buff[3] = buff[4];
2286 buff[4] = data;
2287
2288 /* sync message header {\r|\n}IIHHH (II:id,HHH: hex length) */
2289 return (p == '\r' || p == '\n') && ISTXT(buff[0]) && ISTXT(buff[1]) && ISHEX(buff[2]) && ISHEX(buff[3]) &&
2290 ISHEX(buff[4]);
2291}
2292/* clear buffer --------------------------------------------------------------*/
2293static void clearbuff(raw_t* raw) {
2294 int i;
2295 for (i = 0; i < 5; i++) {
2296 raw->buff[i] = 0;
2297 }
2298 raw->len = raw->nbyte = 0;
2299}
2300/* input JAVAD raw message from stream -----------------------------------------
2301 * fetch next JAVAD raw data and input a mesasge from stream
2302 * args : raw_t *raw IO receiver raw data control struct
2303 * uint8_t data I stream data (1 byte)
2304 * return : status (-1: error message, 0: no message, 1: input observation data,
2305 * 2: input ephemeris, 3: input sbas message,
2306 * 9: input ion/utc parameter)
2307 *
2308 * notes : to specify input options, set raw->opt to the following option
2309 * strings separated by spaces.
2310 *
2311 * -EPHALL : input all ephemerides
2312 * -GL1W : select 1W for GPS L1 (default 1C)
2313 * -GL1X : select 1X for GPS L1 (default 1C)
2314 * -GL2X : select 2X for GPS L2 (default 2W)
2315 * -RL1P : select 1C for GLO G1 (default 1C)
2316 * -RL2C : select 2C for GLO G2 (default 2P)
2317 * -JL1Z : select 1Z for QZS L1 (default 1C)
2318 * -JL1X : select 1X for QZS L1 (default 1C)
2319 * -NOET : discard epoch time message ET (::)
2320 * -GALINAV: select F/NAV for Galileo ephemeris (default: all)
2321 * -GALFNAV: select F/NAV for Galileo ephemeris (default: all)
2322 *-----------------------------------------------------------------------------*/
2323extern int input_javad(raw_t* raw, uint8_t data) {
2324 int len, stat;
2325
2326 trace(NULL, 5, "input_javad: data=%02x\n", data);
2327
2328 /* synchronize message */
2329 if (raw->nbyte == 0) {
2330 if (!sync_javad(raw->buff, data)) {
2331 return 0;
2332 }
2333 if (!(len = decodelen(raw->buff + 2)) || len > MAXRAWLEN - 5) {
2334 trace(NULL, 2, "javad message length error: len=%d\n", len);
2335 clearbuff(raw);
2336 return -1;
2337 }
2338 raw->len = len + 5;
2339 raw->nbyte = 5;
2340 return 0;
2341 }
2342 raw->buff[raw->nbyte++] = data;
2343
2344 if (raw->nbyte < raw->len) {
2345 return 0;
2346 }
2347
2348 /* decode javad raw message */
2349 stat = decode_javad(raw);
2350
2351 clearbuff(raw);
2352 return stat;
2353}
2354/* start input file ----------------------------------------------------------*/
2355static void startfile(raw_t* raw) {
2356 raw->tod = -1;
2357 raw->obuf.n = 0;
2358 raw->buff[4] = '\n';
2359}
2360/* end input file ------------------------------------------------------------*/
2361static int endfile(raw_t* raw) {
2362 /* flush observation data buffer */
2363 if (!flushobuf(raw)) {
2364 return -2;
2365 }
2366 raw->obuf.n = 0;
2367 return 1;
2368}
2369/* input JAVAD raw message from file -------------------------------------------
2370 * fetch next JAVAD raw data and input a message from file
2371 * args : raw_t *raw IO receiver raw data control struct
2372 * FILE *fp I file pointer
2373 * return : status(-2: end of file, -1...9: same as above)
2374 *-----------------------------------------------------------------------------*/
2375extern int input_javadf(raw_t* raw, FILE* fp) {
2376 int i, data, len, stat;
2377
2378 trace(NULL, 4, "input_javadf:\n");
2379
2380 /* start input file */
2381 if (raw->flag) {
2382 startfile(raw);
2383 raw->flag = 0;
2384 }
2385 /* synchronize message */
2386 if (raw->nbyte == 0) {
2387 for (i = 0;; i++) {
2388 if ((data = fgetc(fp)) == EOF) {
2389 return endfile(raw);
2390 }
2391 if (sync_javad(raw->buff, (uint8_t)data)) {
2392 break;
2393 }
2394 if (i >= 4096) {
2395 return 0;
2396 }
2397 }
2398 }
2399 if (!(len = decodelen(raw->buff + 2)) || len > MAXRAWLEN - 5) {
2400 trace(NULL, 2, "javad message length error: len=%3.3s\n", raw->buff + 2);
2401 clearbuff(raw);
2402 return -1;
2403 }
2404 raw->len = len + 5;
2405 raw->nbyte = 5;
2406
2407 if (fread(raw->buff + 5, 1, raw->len - 5, fp) < (size_t)(raw->len - 5)) {
2408 return endfile(raw);
2409 }
2410 /* decode javad raw message */
2411 stat = decode_javad(raw);
2412
2413 clearbuff(raw);
2414 return stat;
2415}
void setbitu(uint8_t *buff, int pos, int len, uint32_t data)
Set unsigned bits in byte data.
Definition mrtk_bits.c:122
uint32_t getbitu(const uint8_t *buff, int pos, int len)
Extract unsigned bits from byte data.
Definition mrtk_bits.c:99
MRTKLIB Bits Module — Binary bit operations and CRC functions.
#define CLIGHT
Definition mrtk_coords.c:41
#define MAXSAT
Definition mrtk_coords.c:45
int satsys(int sat, int *prn)
Definition mrtk_nav.c:117
static int eph_sel[]
Definition mrtk_eph.c:450
#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_L2X
#define CODE_L3X
#define MAXOBS
#define MINPRNQZS
#define CODE_L5X
#define CODE_L7X
#define CODE_L2P
#define CODE_L2I
#define MAXPRNQZS
#define CODE_L1C
#define CODE_L6I
#define CODE_L2C
#define CODE_L7I
#define CODE_L6X
#define CODE_NONE
#define MAXRAWLEN
#define CODE_L1W
#define CODE_L8X
#define CODE_L2W
#define CODE_L1Z
#define CODE_L1P
#define CODE_L1X
void matcpy(double *A, const double *B, int n, int m)
Copy matrix.
Definition mrtk_mat.c:205
MRTKLIB Matrix Module — Matrix/vector operations and estimation.
int satno(int sys, int prn)
Convert satellite system+prn/slot number to satellite number.
Definition mrtk_nav.c:58
MRTKLIB Navigation Module — Navigation data types and satellite/nav utility functions.
int code2freq_idx(int sys, uint8_t code)
Convert system and obs code to frequency index (obsdef-based).
Definition mrtk_obs.c:225
MRTKLIB Observation Module — Observation data types and utility functions.
#define MAXPRNSBS
#define MINPRNSBS
static int decode_javad(raw_t *raw)
#define U1(p)
static int decode_cd(raw_t *raw)
static gtime_t adjweek(gtime_t time, double tow)
static int sync_javad(uint8_t *buff, uint8_t data)
static int decode_WA(raw_t *raw)
#define ROT_LEFT(val)
static int decode_xE(raw_t *raw, char sig)
static int decode_SI(raw_t *raw)
static int decode_nD(raw_t *raw, int sys)
static gtime_t adjday(gtime_t time, double tod)
static int decode_QA(raw_t *raw)
#define ISHEX(c)
static int decode_CA(raw_t *raw)
static int decode_xr(raw_t *raw, char sig)
static void adj_utcweek(gtime_t time, double *utc)
static int decode_Rx(raw_t *raw, char sig)
int input_javadf(raw_t *raw, FILE *fp)
static int decode_GE(raw_t *raw)
int input_javad(raw_t *raw, uint8_t data)
static int decode_WE(raw_t *raw)
static int decode_Px(raw_t *raw, char sig)
static int decode_xP(raw_t *raw, char sig)
static int decode_Fx(raw_t *raw, char sig)
static int decode_L1eph(int sat, raw_t *raw)
static int decode_QU(raw_t *raw)
static int decode_L1ionutc(int sat, raw_t *raw)
static void clearbuff(raw_t *raw)
static int decode_nd(raw_t *raw, int sys)
static int decodelen(const uint8_t *buff)
static int decode_IE(raw_t *raw)
static int decode_GA(raw_t *raw)
static int checkpri(int sys, int code, const char *opt, int idx)
static int decode_EU(raw_t *raw)
static int decode_L2nav(uint8_t *buff, int len, int sat, raw_t *raw)
static int decode_EA(raw_t *raw)
static int decode_NN(raw_t *raw)
#define ISTXT(c)
static int decode_px(raw_t *raw, char sig)
static int decode_LD(raw_t *raw)
static int decode_NA(raw_t *raw)
static int decode_NU(raw_t *raw)
static int decode_WD(raw_t *raw)
static int decode_id(raw_t *raw)
static int sig2idx(int sys, char sig, int *code)
static void startfile(raw_t *raw)
static int decode_IA(raw_t *raw)
static int decode_CN(raw_t *raw)
static int decode_xR(raw_t *raw, char sig)
static int settag(obsd_t *data, gtime_t time)
static int endfile(raw_t *raw)
static int decode_NE(raw_t *raw)
static int decode_EN(raw_t *raw)
static int decode_QE(raw_t *raw)
static int decode_L5nav(uint8_t *buff, int len, int sat, raw_t *raw)
static int decode_Dx(raw_t *raw, char sig)
static int decode_Ex(raw_t *raw, char sig)
static int decode_UO(raw_t *raw)
static int decode_ED(raw_t *raw)
static int is_meas(char sig)
static int checksum(uint8_t *buff, int len)
static int decode_ET(raw_t *raw)
static int decode_L1Cnav(uint8_t *buff, int len, int sat, raw_t *raw)
static int decode_xp(raw_t *raw, char sig)
static int decode_RT(raw_t *raw)
static int decode_eph(raw_t *raw, int sys)
static int decode_rx(raw_t *raw, char sig)
static int decode_L1nav(uint8_t *buff, int len, int sat, raw_t *raw)
#define I1(p)
static int decode_RD(raw_t *raw)
#define PREAMB_CNAV
static int decode_IO(raw_t *raw)
static int decode_WU(raw_t *raw)
static int decode_xd(raw_t *raw, char sig)
static int decode_lD(raw_t *raw)
static int decode_TC(raw_t *raw)
static int flushobuf(raw_t *raw)
#define R8(p)
#define U4(p)
#define I4(p)
#define R4(p)
#define U2(p)
#define I2(p)
int decode_frame(const uint8_t *buff, eph_t *eph, alm_t *alm, double *ion, double *utc)
#define P2_40
Definition mrtk_rcvraw.c:61
int decode_glostr(const uint8_t *buff, geph_t *geph, double *utc)
#define SC2RAD
Definition mrtk_rcvraw.c:33
MRTKLIB Receiver Raw Data Module — Receiver raw data types and decoder functions for various GNSS rec...
MRTKLIB RTCM Module — RTCM message types and functions.
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 epoch2time(const double *ep)
Convert calendar day/time to gtime_t struct.
Definition mrtk_time.c:113
gtime_t gpst2time(int week, double sec)
Convert GPS week/tow to gtime_t.
Definition mrtk_time.c:165
void time2epoch(gtime_t t, double *ep)
Convert gtime_t struct to calendar day/time.
Definition mrtk_time.c:136
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
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
char * time_str(gtime_t t, int n)
Get time string (not reentrant).
Definition mrtk_time.c:530
gtime_t utc2gpst(gtime_t t)
Convert UTC to GPS time considering leap seconds.
Definition mrtk_time.c:440
MRTKLIB Time Module — GNSS time types and conversion functions.
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 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
time_t time
Definition mrtk_time.h:50
double utc_qzs[8]
Definition mrtk_nav.h:417
seph_t * seph
Definition mrtk_nav.h:408
double utc_gps[8]
Definition mrtk_nav.h:414
geph_t * geph
Definition mrtk_nav.h:407
eph_t * eph
Definition mrtk_nav.h:400
double ion_gps[8]
Definition mrtk_nav.h:421
double ion_qzs[8]
Definition mrtk_nav.h:423
obsd_t * data
Definition mrtk_obs.h:61
int n
Definition mrtk_obs.h:60
Observation data record.
Definition mrtk_obs.h:44
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
Receiver raw data control type.
Definition mrtk_rcvraw.h:78
sbsmsg_t sbsmsg
Definition mrtk_rcvraw.h:87
uint8_t subfrm[MAXSAT][380]
Definition mrtk_rcvraw.h:89
nav_t nav
Definition mrtk_rcvraw.h:83
double lockt[MAXSAT][5+5]
Definition mrtk_rcvraw.h:90
int tbase
Definition mrtk_rcvraw.h:99
int ephset
Definition mrtk_rcvraw.h:86
char freqn[MAXOBS]
Definition mrtk_rcvraw.h:94
int outtype
obs_t obs
Definition mrtk_rcvraw.h:81
int len
Definition mrtk_rcvraw.h:96
uint8_t buff[MAXRAWLEN]
char msgtype[256]
Definition mrtk_rcvraw.h:88
double prCA[MAXSAT]
Definition mrtk_rcvraw.h:92
int nbyte
Definition mrtk_rcvraw.h:95
int flag
char opt[256]
double dpCA[MAXSAT]
Definition mrtk_rcvraw.h:92
int ephsat
Definition mrtk_rcvraw.h:85
gtime_t time
Definition mrtk_rcvraw.h:79
int tod
Definition mrtk_rcvraw.h:98
obs_t obuf
Definition mrtk_rcvraw.h:82
int tow
Definition mrtk_nav.h:102
uint8_t msg[29]
Definition mrtk_nav.h:104
uint8_t prn
Definition mrtk_nav.h:103
int week
Definition mrtk_nav.h:102
SBAS ephemeris type.
Definition mrtk_eph.h:130
int sva
Definition mrtk_eph.h:134
double pos[3]
Definition mrtk_eph.h:136
double vel[3]
Definition mrtk_eph.h:137
double acc[3]
Definition mrtk_eph.h:138
gtime_t tof
Definition mrtk_eph.h:133
double af0
Definition mrtk_eph.h:139
double af1
Definition mrtk_eph.h:139
int sat
Definition mrtk_eph.h:131
gtime_t t0
Definition mrtk_eph.h:132