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