source: ntrip/trunk/BNC/src/RTCM3/RTCM3Decoder.cpp@ 10899

Last change on this file since 10899 was 10899, checked in by stuerze, 13 hours ago

bugfix in NavIC broadcast epehemeris encoding/decoding

File size: 77.0 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: RTCM3Decoder
30 *
31 * Purpose: RTCM3 Decoder
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Aug-2006
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42#include <iomanip>
43#include <sstream>
44#include <math.h>
45#include <string.h>
46
47#include "bits.h"
48#include "gnss.h"
49#include "RTCM3Decoder.h"
50#include "rtcm_utils.h"
51#include "bncconst.h"
52#include "bnccore.h"
53#include "bncutils.h"
54#include "bncsettings.h"
55#include "bnctime.h"
56#include "crs.h"
57
58using namespace std;
59
60// Error Handling
61////////////////////////////////////////////////////////////////////////////
62void RTCM3Error(const char*, ...) {
63}
64
65// Constructor
66////////////////////////////////////////////////////////////////////////////
67RTCM3Decoder::RTCM3Decoder(const QString& staID, bncRawFile* rawFile) :
68 GPSDecoder() {
69
70 _staID = staID;
71 _rawFile = rawFile;
72
73 connect(this, SIGNAL(newGPSEph(t_ephGPS)), BNC_CORE, SLOT(slotNewGPSEph(t_ephGPS)));
74 connect(this, SIGNAL(newGlonassEph(t_ephGlo)), BNC_CORE, SLOT(slotNewGlonassEph(t_ephGlo)));
75 connect(this, SIGNAL(newGalileoEph(t_ephGal)), BNC_CORE, SLOT(slotNewGalileoEph(t_ephGal)));
76 connect(this, SIGNAL(newSBASEph(t_ephSBAS)), BNC_CORE, SLOT(slotNewSBASEph(t_ephSBAS)));
77 connect(this, SIGNAL(newBDSEph(t_ephBDS)), BNC_CORE, SLOT(slotNewBDSEph(t_ephBDS)));
78
79 _MessageSize = _SkipBytes = _BlockSize = _NeedBytes = 0;
80}
81
82// Destructor
83////////////////////////////////////////////////////////////////////////////
84RTCM3Decoder::~RTCM3Decoder() {
85 QMapIterator<QByteArray, RTCM3coDecoder*> it(_coDecoders);
86 while (it.hasNext()) {
87 it.next();
88 delete it.value();
89 }
90 _coDecoders.clear();
91}
92
93//
94////////////////////////////////////////////////////////////////////////////
95bool RTCM3Decoder::DecodeRTCM3GPS(unsigned char* data, int size) {
96 bool decoded = false;
97 bncTime CurrentObsTime;
98 int i, numsats, syncf, type;
99 uint64_t numbits = 0, bitfield = 0;
100
101 data += 3; /* header */
102 size -= 6; /* header + crc */
103
104 GETBITS(type, 12)
105 SKIPBITS(12)
106 /* id */
107 GETBITS(i, 30)
108
109 CurrentObsTime.set(i);
110 if (_CurrentTime.valid() && CurrentObsTime != _CurrentTime) {
111 decoded = true;
112 _obsList.append(_CurrentObsList);
113 _CurrentObsList.clear();
114 }
115
116 _CurrentTime = CurrentObsTime;
117
118 GETBITS(syncf, 1)
119 /* sync */
120 GETBITS(numsats, 5)
121 SKIPBITS(4)
122 /* smind, smint */
123
124 while (numsats--) {
125 int sv, code, l1range, amb = 0;
126 t_satObs CurrentObs;
127 CurrentObs._time = CurrentObsTime;
128 CurrentObs._type = type;
129
130 GETBITS(sv, 6)
131 char sys;
132 int num, flag;
133 if (sv < 40) {
134 sys = 'G';
135 num = sv;
136 }
137 else {
138 sys = 'S';
139 num = sv - 20;
140 }
141 flag = t_corrSSR::getSsrNavTypeFlag(sys, num);
142 CurrentObs._prn.set(sys, num, flag);
143
144 t_frqObs *frqObs = new t_frqObs;
145 /* L1 */
146 GETBITS(code, 1);
147 (code) ?
148 frqObs->_rnxType2ch.assign("1W") : frqObs->_rnxType2ch.assign("1C");
149 GETBITS(l1range, 24);
150 GETBITSSIGN(i, 20);
151 if ((i & ((1 << 20) - 1)) != 0x80000) {
152 frqObs->_code = l1range * 0.02;
153 frqObs->_phase = (l1range * 0.02 + i * 0.0005) / GPS_WAVELENGTH_L1;
154 frqObs->_codeValid = frqObs->_phaseValid = true;
155 }
156 GETBITS(frqObs->_lockTimeIndicator, 7);
157 frqObs->_lockTime = lti2sec(type, frqObs->_lockTimeIndicator);
158 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
159 if (type == 1002 || type == 1004) {
160 GETBITS(amb, 8);
161 if (amb) {
162 frqObs->_code += amb * 299792.458;
163 frqObs->_phase += (amb * 299792.458) / GPS_WAVELENGTH_L1;
164 }
165 GETBITS(i, 8);
166 if (i) {
167 frqObs->_snr = i * 0.25;
168 frqObs->_snrValid = true;
169 }
170 }
171 CurrentObs._obs.push_back(frqObs);
172 if (type == 1003 || type == 1004) {
173 frqObs = new t_frqObs;
174 /* L2 */
175 GETBITS(code, 2);
176 switch (code) {
177 case 3:
178 frqObs->_rnxType2ch.assign("2W"); /* or "2Y"? */
179 break;
180 case 2:
181 frqObs->_rnxType2ch.assign("2W");
182 break;
183 case 1:
184 frqObs->_rnxType2ch.assign("2P");
185 break;
186 case 0:
187 frqObs->_rnxType2ch.assign("2X"); /* or "2S" or "2L"? */
188 break;
189 }
190 GETBITSSIGN(i, 14);
191 if ((i & ((1 << 14) - 1)) != 0x2000) {
192 frqObs->_code = l1range * 0.02 + i * 0.02 + amb * 299792.458;
193 frqObs->_codeValid = true;
194 }
195 GETBITSSIGN(i, 20);
196 if ((i & ((1 << 20) - 1)) != 0x80000) {
197 frqObs->_phase = (l1range * 0.02 + i * 0.0005 + amb * 299792.458)
198 / GPS_WAVELENGTH_L2;
199 frqObs->_phaseValid = true;
200 }
201 GETBITS(frqObs->_lockTimeIndicator, 7);
202 frqObs->_lockTime = lti2sec(type, frqObs->_lockTimeIndicator);
203 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
204 if (type == 1004) {
205 GETBITS(i, 8);
206 if (i) {
207 frqObs->_snr = i * 0.25;
208 frqObs->_snrValid = true;
209 }
210 }
211 CurrentObs._obs.push_back(frqObs);
212 }
213 _CurrentObsList.push_back(CurrentObs);
214 }
215
216 if (!syncf) {
217 decoded = true;
218 _obsList.append(_CurrentObsList);
219 _CurrentTime.reset();
220 _CurrentObsList.clear();
221 }
222 return decoded;
223}
224
225#define RTCM3_MSM_NUMSIG 32
226#define RTCM3_MSM_NUMSAT 64
227#define RTCM3_MSM_NUMCELLS 96 /* arbitrary limit */
228
229/**
230 * Frequency numbers of GLONASS with an offset of 100 to detect unset values.
231 * Gets filled by ephemeris and data blocks and shared between different streams.
232 */
233static int GLOFreq[RTCM3_MSM_NUMSAT];
234
235/*
236 * Storage structure to store frequency and RINEX ID assignment for MSM
237 * message */
238struct CodeData {
239 double wl;
240 const char *code; /* currently unused */
241};
242
243/** MSM signal types for GPS and SBAS */
244static struct CodeData gps[RTCM3_MSM_NUMSIG] = {
245 {0.0, 0},
246 {GPS_WAVELENGTH_L1, "1C"},
247 {GPS_WAVELENGTH_L1, "1P"},
248 {GPS_WAVELENGTH_L1, "1W"},
249 {0.0, 0},
250 {0.0, 0},
251 {0.0, 0},
252 {GPS_WAVELENGTH_L2, "2C"},
253 {GPS_WAVELENGTH_L2, "2P"},
254 {GPS_WAVELENGTH_L2, "2W"},
255 {0.0, 0},
256 {0.0, 0},
257 {0.0, 0},
258 {0.0, 0},
259 {GPS_WAVELENGTH_L2, "2S"},
260 {GPS_WAVELENGTH_L2, "2L"},
261 {GPS_WAVELENGTH_L2, "2X"},
262 {0.0, 0},
263 {0.0, 0},
264 {0.0, 0},
265 {0.0, 0},
266 {GPS_WAVELENGTH_L5, "5I"},
267 {GPS_WAVELENGTH_L5, "5Q"},
268 {GPS_WAVELENGTH_L5, "5X"},
269 {0.0, 0},
270 {0.0, 0},
271 {0.0, 0},
272 {0.0, 0},
273 {0.0, 0},
274 {GPS_WAVELENGTH_L1, "1S"},
275 {GPS_WAVELENGTH_L1, "1L"},
276 {GPS_WAVELENGTH_L1, "1X"}
277 };
278
279/**
280 * MSM signal types for GLONASS
281 *
282 * NOTE: Uses 0.0, 1.0 for wavelength as sat index dependence is done later!
283 */
284static struct CodeData glo[RTCM3_MSM_NUMSIG] = {
285 {0.0, 0},
286 {0.0, "1C"},
287 {0.0, "1P"},
288 {0.0, 0},
289 {0.0, 0},
290 {0.0, 0},
291 {0.0, 0},
292 {1.0, "2C"},
293 {1.0, "2P"},
294 {GLO_WAVELENGTH_L1a, "4A"},
295 {GLO_WAVELENGTH_L1a, "4B"},
296 {GLO_WAVELENGTH_L1a, "4X"},
297 {GLO_WAVELENGTH_L2a, "6A"},
298 {GLO_WAVELENGTH_L2a, "6B"},
299 {GLO_WAVELENGTH_L2a, "6X"},
300 {GLO_WAVELENGTH_L3, "3I"},
301 {GLO_WAVELENGTH_L3, "3Q"},
302 {GLO_WAVELENGTH_L3, "3X"},
303 {0.0, 0},
304 {0.0, 0},
305 {0.0, 0},
306 {0.0, 0},
307 {0.0, 0},
308 {0.0, 0},
309 {0.0, 0},
310 {0.0, 0},
311 {0.0, 0},
312 {0.0, 0},
313 {0.0, 0},
314 {0.0, 0},
315 {0.0, 0},
316 {0.0, 0}
317 };
318
319/** MSM signal types for Galileo */
320static struct CodeData gal[RTCM3_MSM_NUMSIG] = {
321 {0.0, 0},
322 {GAL_WAVELENGTH_E1, "1C"},
323 {GAL_WAVELENGTH_E1, "1A"},
324 {GAL_WAVELENGTH_E1, "1B"},
325 {GAL_WAVELENGTH_E1, "1X"},
326 {GAL_WAVELENGTH_E1, "1Z"},
327 {0.0, 0},
328 {GAL_WAVELENGTH_E6, "6C"},
329 {GAL_WAVELENGTH_E6, "6A"},
330 {GAL_WAVELENGTH_E6, "6B"},
331 {GAL_WAVELENGTH_E6, "6X"},
332 {GAL_WAVELENGTH_E6, "6Z"},
333 {0.0, 0},
334 {GAL_WAVELENGTH_E5B, "7I"},
335 {GAL_WAVELENGTH_E5B, "7Q"},
336 {GAL_WAVELENGTH_E5B, "7X"},
337 {0.0, 0},
338 {GAL_WAVELENGTH_E5AB,"8I"},
339 {GAL_WAVELENGTH_E5AB,"8Q"},
340 {GAL_WAVELENGTH_E5AB,"8X"},
341 {0.0, 0},
342 {GAL_WAVELENGTH_E5A, "5I"},
343 {GAL_WAVELENGTH_E5A, "5Q"},
344 {GAL_WAVELENGTH_E5A, "5X"},
345 {0.0, 0},
346 {0.0, 0},
347 {0.0, 0},
348 {0.0, 0},
349 {0.0, 0},
350 {0.0, 0},
351 {0.0, 0},
352 {0.0, 0}
353 };
354
355/** MSM signal types for QZSS */
356static struct CodeData qzss[RTCM3_MSM_NUMSIG] = {
357 {0.0, 0},
358 {GPS_WAVELENGTH_L1, "1C"},
359 {0.0, 0},
360 {0.0, 0},
361 {0.0, 0},
362 {0.0, 0},
363 {0.0, 0},
364 {0.0, 0},
365 {QZSS_WAVELENGTH_L6, "6S"},
366 {QZSS_WAVELENGTH_L6, "6L"},
367 {QZSS_WAVELENGTH_L6, "6X"},
368 {0.0, 0},
369 {0.0, 0},
370 {0.0, 0},
371 {GPS_WAVELENGTH_L2, "2S"},
372 {GPS_WAVELENGTH_L2, "2L"},
373 {GPS_WAVELENGTH_L2, "2X"},
374 {0.0, 0},
375 {0.0, 0},
376 {0.0, 0},
377 {0.0, 0},
378 {GPS_WAVELENGTH_L5, "5I"},
379 {GPS_WAVELENGTH_L5, "5Q"},
380 {GPS_WAVELENGTH_L5, "5X"},
381 {0.0, 0},
382 {0.0, 0},
383 {0.0, 0},
384 {0.0, 0},
385 {0.0, 0},
386 {GPS_WAVELENGTH_L1, "1S"},
387 {GPS_WAVELENGTH_L1, "1L"},
388 {GPS_WAVELENGTH_L1, "1X"}
389 };
390
391/** MSM signal types for Beidou/BDS */
392static struct CodeData bds[RTCM3_MSM_NUMSIG] = {
393 {0.0, 0},
394 {BDS_WAVELENGTH_B1, "2I"},
395 {BDS_WAVELENGTH_B1, "2Q"},
396 {BDS_WAVELENGTH_B1, "2X"},
397 {0.0, 0},
398 {0.0, 0},
399 {0.0, 0},
400 {BDS_WAVELENGTH_B3, "6I"},
401 {BDS_WAVELENGTH_B3, "6Q"},
402 {BDS_WAVELENGTH_B3, "6X"},
403 {0.0, 0},
404 {0.0, 0},
405 {0.0, 0},
406 {BDS_WAVELENGTH_B2, "7I"},
407 {BDS_WAVELENGTH_B2, "7Q"},
408 {BDS_WAVELENGTH_B2, "7X"},
409 {0.0, 0},
410 {0.0, 0},
411 {0.0, 0},
412 {0.0, 0},
413 {0.0, 0},
414 {BDS_WAVELENGTH_B2a, "5D"},
415 {BDS_WAVELENGTH_B2a, "5P"},
416 {BDS_WAVELENGTH_B2a, "5X"},
417 {BDS_WAVELENGTH_B2b, "7D"},
418 {0.0, 0},
419 {0.0, 0},
420 {0.0, 0},
421 {0.0, 0},
422 {BDS_WAVELENGTH_B1C, "1D"},
423 {BDS_WAVELENGTH_B1C, "1P"},
424 {BDS_WAVELENGTH_B1C, "1X"}
425 };
426
427/** MSM signal types for NavIC */
428static struct CodeData irn[RTCM3_MSM_NUMSIG] = {
429 {0.0, 0},
430 {0.0, 0},
431 {0.0, 0},
432 {0.0, 0},
433 {0.0, 0},
434 {0.0, 0},
435 {0.0, 0},
436 {NavIC_WAVELENGTH_S, "9A"},
437 {0.0, 0},
438 {0.0, 0},
439 {0.0, 0},
440 {0.0, 0},
441 {0.0, 0},
442 {0.0, 0},
443 {0.0, 0},
444 {0.0, 0},
445 {0.0, 0},
446 {0.0, 0},
447 {0.0, 0},
448 {0.0, 0},
449 {0.0, 0},
450 {NavIC_WAVELENGTH_L5, "5A"},
451 {0.0, 0},
452 {0.0, 0},
453 {0.0, 0},
454 {0.0, 0},
455 {0.0, 0},
456 {0.0, 0},
457 {0.0, 0},
458 {0.0, 0},
459 {0.0, 0},
460 {0.0, 0}
461 };
462
463#define UINT64(c) c ## ULL
464
465//
466////////////////////////////////////////////////////////////////////////////
467bool RTCM3Decoder::DecodeRTCM3MSM(unsigned char* data, int size) {
468 bool decoded = false;
469 int type, syncf, i;
470 uint64_t numbits = 0, bitfield = 0;
471
472 data += 3; /* header */
473 size -= 6; /* header + crc */
474
475 GETBITS(type, 12)
476 SKIPBITS(12)
477 /* id */
478 char sys;
479 if (type >= 1131 && type <= 1137) {
480 sys = 'I';
481 }
482 else if (type >= 1121 && type <= 1127) {
483 sys = 'C';
484 }
485 else if (type >= 1111 && type <= 1117) {
486 sys = 'J';
487 }
488 else if (type >= 1101 && type <= 1107) {
489 sys = 'S';
490 }
491 else if (type >= 1091 && type <= 1097) {
492 sys = 'E';
493 }
494 else if (type >= 1081 && type <= 1087) {
495 sys = 'R';
496 }
497 else if (type >= 1071 && type <= 1077) {
498 sys = 'G';
499 }
500 else {
501 return decoded; // false
502 }
503 bncTime CurrentObsTime;
504 if (sys == 'C') /* BDS */ {
505 GETBITS(i, 30)
506 CurrentObsTime.setBDS(i);
507 }
508 else if (sys == 'R') /* GLONASS */ {
509 SKIPBITS(3)
510 GETBITS(i, 27)
511 /* tk */
512 CurrentObsTime.setTk(i);
513 }
514 else /* GPS style date */ {
515 GETBITS(i, 30)
516 CurrentObsTime.set(i);
517 }
518 if (_CurrentTime.valid() && CurrentObsTime != _CurrentTime) {
519 decoded = true;
520 _obsList.append(_CurrentObsList);
521 _CurrentObsList.clear();
522 }
523 _CurrentTime = CurrentObsTime;
524
525 GETBITS(syncf, 1)
526 /**
527 * Ignore unknown types except for sync flag
528 *
529 * We actually support types 1-3 in following code, but as they are missing
530 * the full cycles and can't be used later we skip interpretation here already.
531 */
532 if (type <= 1137 && (type % 10) >= 4 && (type % 10) <= 7) {
533 int sigmask, numsat = 0, numsig = 0;
534 uint64_t satmask, cellmask, ui;
535 // satellite data
536 double rrmod[RTCM3_MSM_NUMSAT]; // GNSS sat rough ranges modulo 1 millisecond
537 int rrint[RTCM3_MSM_NUMSAT]; // number of integer msecs in GNSS sat rough ranges
538 int rdop[RTCM3_MSM_NUMSAT]; // GNSS sat rough phase range rates
539 int extsat[RTCM3_MSM_NUMSAT];// extended sat info
540 // signal data
541 int ll[RTCM3_MSM_NUMCELLS]; // lock time indicator
542 /*int hc[RTCM3_MSM_NUMCELLS];*/ // half cycle ambiguity indicator
543 double cnr[RTCM3_MSM_NUMCELLS]; // signal cnr
544 double cp[RTCM3_MSM_NUMCELLS]; // fine phase range data
545 double psr[RTCM3_MSM_NUMCELLS]; // fine psr
546 double dop[RTCM3_MSM_NUMCELLS]; // fine phase range rates
547
548 SKIPBITS(3 + 7 + 2 + 2 + 1 + 3)
549 GETBITS64(satmask, RTCM3_MSM_NUMSAT)
550
551 /* http://gurmeetsingh.wordpress.com/2008/08/05/fast-bit-counting-routines/ */
552 for (ui = satmask; ui; ui &= (ui - 1) /* remove rightmost bit */)
553 ++numsat;
554 GETBITS(sigmask, RTCM3_MSM_NUMSIG)
555 for (i = sigmask; i; i &= (i - 1) /* remove rightmost bit */)
556 ++numsig;
557 for (i = 0; i < RTCM3_MSM_NUMSAT; ++i)
558 extsat[i] = 15;
559
560 i = numsat * numsig;
561 GETBITS64(cellmask, (unsigned )i)
562 // satellite data
563 switch (type % 10) {
564 case 1:
565 case 2:
566 case 3:
567 /* partial data, already skipped above, but implemented for future expansion ! */
568 for (int j = numsat; j--;)
569 GETFLOAT(rrmod[j], 10, 1.0 / 1024.0)
570 break;
571 case 4:
572 case 6:
573 for (int j = numsat; j--;)
574 GETBITS(rrint[j], 8)
575 for (int j = numsat; j--;)
576 GETFLOAT(rrmod[j], 10, 1.0 / 1024.0)
577 break;
578 case 5:
579 case 7:
580 for (int j = numsat; j--;)
581 GETBITS(rrint[j], 8)
582 for (int j = numsat; j--;)
583 GETBITS(extsat[j], 4)
584 for (int j = numsat; j--;)
585 GETFLOAT(rrmod[j], 10, 1.0 / 1024.0)
586 for (int j = numsat; j--;)
587 GETBITSSIGN(rdop[j], 14)
588 break;
589 }
590 // signal data
591 int numcells = numsat * numsig;
592 /** Drop anything which exceeds our cell limit. Increase limit definition
593 * when that happens. */
594 if (numcells <= RTCM3_MSM_NUMCELLS) {
595 switch (type % 10) {
596 case 1:
597 for (int count = numcells; count--;)
598 if (cellmask & (UINT64(1) << count))
599 GETFLOATSIGN(psr[count], 15, 1.0 / (1 << 24))
600 break;
601 case 2:
602 for (int count = numcells; count--;)
603 if (cellmask & (UINT64(1) << count))
604 GETFLOATSIGN(cp[count], 22, 1.0 / (1 << 29))
605 for (int count = numcells; count--;)
606 if (cellmask & (UINT64(1) << count))
607 GETBITS(ll[count], 4)
608 for (int count = numcells; count--;)
609 if (cellmask & (UINT64(1) << count))
610 SKIPBITS(1)/*GETBITS(hc[count], 1)*/
611 break;
612 case 3:
613 for (int count = numcells; count--;)
614 if (cellmask & (UINT64(1) << count))
615 GETFLOATSIGN(psr[count], 15, 1.0 / (1 << 24))
616 for (int count = numcells; count--;)
617 if (cellmask & (UINT64(1) << count))
618 GETFLOATSIGN(cp[count], 22, 1.0 / (1 << 29))
619 for (int count = numcells; count--;)
620 if (cellmask & (UINT64(1) << count))
621 GETBITS(ll[count], 4)
622 for (int count = numcells; count--;)
623 if (cellmask & (UINT64(1) << count))
624 SKIPBITS(1)/*GETBITS(hc[count], 1)*/
625 break;
626 case 4:
627 for (int count = numcells; count--;)
628 if (cellmask & (UINT64(1) << count))
629 GETFLOATSIGN(psr[count], 15, 1.0 / (1 << 24))
630 for (int count = numcells; count--;)
631 if (cellmask & (UINT64(1) << count))
632 GETFLOATSIGN(cp[count], 22, 1.0 / (1 << 29))
633 for (int count = numcells; count--;)
634 if (cellmask & (UINT64(1) << count))
635 GETBITS(ll[count], 4)
636 for (int count = numcells; count--;)
637 if (cellmask & (UINT64(1) << count))
638 SKIPBITS(1)/*GETBITS(hc[count], 1)*/
639 for (int count = numcells; count--;)
640 if (cellmask & (UINT64(1) << count))
641 GETBITS(cnr[count], 6)
642 break;
643 case 5:
644 for (int count = numcells; count--;)
645 if (cellmask & (UINT64(1) << count))
646 GETFLOATSIGN(psr[count], 15, 1.0 / (1 << 24))
647 for (int count = numcells; count--;)
648 if (cellmask & (UINT64(1) << count))
649 GETFLOATSIGN(cp[count], 22, 1.0 / (1 << 29))
650 for (int count = numcells; count--;)
651 if (cellmask & (UINT64(1) << count))
652 GETBITS(ll[count], 4)
653 for (int count = numcells; count--;)
654 if (cellmask & (UINT64(1) << count))
655 SKIPBITS(1)/*GETBITS(hc[count], 1)*/
656 for (int count = numcells; count--;)
657 if (cellmask & (UINT64(1) << count))
658 GETFLOAT(cnr[count], 6, 1.0)
659 for (int count = numcells; count--;)
660 if (cellmask & (UINT64(1) << count))
661 GETFLOATSIGN(dop[count], 15, 0.0001)
662 break;
663 case 6:
664 for (int count = numcells; count--;)
665 if (cellmask & (UINT64(1) << count))
666 GETFLOATSIGN(psr[count], 20, 1.0 / (1 << 29))
667 for (int count = numcells; count--;)
668 if (cellmask & (UINT64(1) << count))
669 GETFLOATSIGN(cp[count], 24, 1.0 / (1U << 31))
670 for (int count = numcells; count--;)
671 if (cellmask & (UINT64(1) << count))
672 GETBITS(ll[count], 10)
673 for (int count = numcells; count--;)
674 if (cellmask & (UINT64(1) << count))
675 SKIPBITS(1)/*GETBITS(hc[count], 1)*/
676 for (int count = numcells; count--;)
677 if (cellmask & (UINT64(1) << count))
678 GETFLOAT(cnr[count], 10, 1.0 / (1 << 4))
679 break;
680 case 7:
681 for (int count = numcells; count--;)
682 if (cellmask & (UINT64(1) << count))
683 GETFLOATSIGN(psr[count], 20, 1.0 / (1 << 29))
684 for (int count = numcells; count--;)
685 if (cellmask & (UINT64(1) << count))
686 GETFLOATSIGN(cp[count], 24, 1.0 / (1U << 31))
687 for (int count = numcells; count--;)
688 if (cellmask & (UINT64(1) << count))
689 GETBITS(ll[count], 10)
690 for (int count = numcells; count--;)
691 if (cellmask & (UINT64(1) << count))
692 SKIPBITS(1)/*GETBITS(hc[count], 1)*/
693 for (int count = numcells; count--;)
694 if (cellmask & (UINT64(1) << count))
695 GETFLOAT(cnr[count], 10, 1.0 / (1 << 4))
696 for (int count = numcells; count--;)
697 if (cellmask & (UINT64(1) << count))
698 GETFLOATSIGN(dop[count], 15, 0.0001)
699 break;
700 }
701 i = RTCM3_MSM_NUMSAT;
702 int j = -1;
703 t_satObs CurrentObs;
704 for (int count = numcells; count--;) {
705 while (j >= 0 && !(sigmask & (1 << --j)))
706 ;
707 if (j < 0) {
708 while (!(satmask & (UINT64(1) << (--i))))
709 /* next satellite */
710 ;
711 if (CurrentObs._obs.size() > 0) {
712 char sys = CurrentObs._prn.system();
713 int num = CurrentObs._prn.number();
714 int flag = t_corrSSR::getSsrNavTypeFlag(sys, num);
715 CurrentObs._prn.setFlag(flag);
716 _CurrentObsList.push_back(CurrentObs);
717 }
718 CurrentObs.clear();
719 CurrentObs._time = CurrentObsTime;
720 CurrentObs._type = type;
721 if (sys == 'S')
722 CurrentObs._prn.set(sys, 20 - 1 + RTCM3_MSM_NUMSAT - i);
723 else
724 CurrentObs._prn.set(sys, RTCM3_MSM_NUMSAT - i);
725 j = RTCM3_MSM_NUMSIG;
726 while (!(sigmask & (1 << --j)))
727 ;
728 --numsat;
729 }
730 if (cellmask & (UINT64(1) << count)) {
731 struct CodeData cd = {0.0, 0};
732 switch (sys) {
733 case 'J':
734 cd = qzss[RTCM3_MSM_NUMSIG - j - 1];
735 break;
736 case 'C':
737 cd = bds[RTCM3_MSM_NUMSIG - j - 1];
738 break;
739 case 'G':
740 case 'S':
741 cd = gps[RTCM3_MSM_NUMSIG - j - 1];
742 break;
743 case 'R':
744 cd = glo[RTCM3_MSM_NUMSIG - j - 1];
745 {
746 int k = GLOFreq[RTCM3_MSM_NUMSAT - i - 1];
747 if (extsat[numsat] < 14) { // channel number is available as extended info for MSM5/7
748 k = GLOFreq[RTCM3_MSM_NUMSAT - i - 1] = 100 + extsat[numsat] - 7;
749 }
750 if (k) {
751 if (cd.wl == 0.0) {
752 cd.wl = GLO_WAVELENGTH_L1(k - 100);
753 }
754 else if (cd.wl == 1.0) {
755 cd.wl = GLO_WAVELENGTH_L2(k - 100);
756 }
757 }
758 else if (!k && cd.wl <= 1) {
759 cd.code = 0;
760 }
761 }
762 break;
763 case 'E':
764 cd = gal[RTCM3_MSM_NUMSIG - j - 1];
765 break;
766 case 'I':
767 cd = irn[RTCM3_MSM_NUMSIG - j - 1];
768 break;
769 }
770 if (cd.code) {
771 t_frqObs *frqObs = new t_frqObs;
772 frqObs->_rnxType2ch.assign(cd.code);
773
774 switch (type % 10) {
775 case 1:
776 if (psr[count] > -1.0 / (1 << 10)) {
777 frqObs->_code = psr[count] * LIGHTSPEED / 1000.0
778 + (rrmod[numsat]) * LIGHTSPEED / 1000.0;
779 frqObs->_codeValid = true;
780 }
781 break;
782 case 2:
783 if (cp[count] > -1.0 / (1 << 8)) {
784 frqObs->_phase = cp[count] * LIGHTSPEED / 1000.0 / cd.wl
785 + (rrmod[numsat]) * LIGHTSPEED / 1000.0 / cd.wl;
786 frqObs->_phaseValid = true;
787 frqObs->_lockTime = lti2sec(type,ll[count]);
788 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
789 frqObs->_lockTimeIndicator = ll[count];
790 }
791 break;
792 case 3:
793 if (psr[count] > -1.0 / (1 << 10)) {
794 frqObs->_code = psr[count] * LIGHTSPEED / 1000.0
795 + (rrmod[numsat]) * LIGHTSPEED / 1000.0;
796 frqObs->_codeValid = true;
797 }
798 if (cp[count] > -1.0 / (1 << 8)) {
799 frqObs->_phase = cp[count] * LIGHTSPEED / 1000.0 / cd.wl
800 + rrmod[numsat] * LIGHTSPEED / 1000.0 / cd.wl;
801 frqObs->_phaseValid = true;
802 frqObs->_lockTime = lti2sec(type,ll[count]);
803 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
804 frqObs->_lockTimeIndicator = ll[count];
805 }
806 break;
807 case 4:
808 if (psr[count] > -1.0 / (1 << 10)) {
809 frqObs->_code = psr[count] * LIGHTSPEED / 1000.0
810 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0;
811 frqObs->_codeValid = true;
812 }
813 if (cp[count] > -1.0 / (1 << 8)) {
814 frqObs->_phase = cp[count] * LIGHTSPEED / 1000.0 / cd.wl
815 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0 / cd.wl;
816 frqObs->_phaseValid = true;
817 frqObs->_lockTime = lti2sec(type,ll[count]);
818 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
819 frqObs->_lockTimeIndicator = ll[count];
820 }
821 frqObs->_snr = cnr[count];
822 frqObs->_snrValid = true;
823 break;
824 case 5:
825 if (psr[count] > -1.0 / (1 << 10)) {
826 frqObs->_code = psr[count] * LIGHTSPEED / 1000.0
827 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0;
828 frqObs->_codeValid = true;
829 }
830 if (cp[count] > -1.0 / (1 << 8)) {
831 frqObs->_phase = cp[count] * LIGHTSPEED / 1000.0 / cd.wl
832 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0 / cd.wl;
833 frqObs->_phaseValid = true;
834 frqObs->_lockTime = lti2sec(type,ll[count]);
835 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
836 frqObs->_lockTimeIndicator = ll[count];
837 }
838 frqObs->_snr = cnr[count];
839 frqObs->_snrValid = true;
840 if (dop[count] > -1.6384) {
841 frqObs->_doppler = -(dop[count] + rdop[numsat]) / cd.wl;
842 frqObs->_dopplerValid = true;
843 }
844 break;
845 case 6:
846 if (psr[count] > -1.0 / (1 << 10)) {
847 frqObs->_code = psr[count] * LIGHTSPEED / 1000.0
848 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0;
849 frqObs->_codeValid = true;
850 }
851 if (cp[count] > -1.0 / (1 << 8)) {
852 frqObs->_phase = cp[count] * LIGHTSPEED / 1000.0 / cd.wl
853 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0 / cd.wl;
854 frqObs->_phaseValid = true;
855 frqObs->_lockTime = lti2sec(type,ll[count]);
856 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
857 frqObs->_lockTimeIndicator = ll[count];
858 }
859
860 frqObs->_snr = cnr[count];
861 frqObs->_snrValid = true;
862 break;
863 case 7:
864 if (psr[count] > -1.0 / (1 << 10)) {
865 frqObs->_code = psr[count] * LIGHTSPEED / 1000.0
866 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0;
867 frqObs->_codeValid = true;
868 }
869 if (cp[count] > -1.0 / (1 << 8)) {
870 frqObs->_phase = cp[count] * LIGHTSPEED / 1000.0 / cd.wl
871 + (rrmod[numsat] + rrint[numsat]) * LIGHTSPEED / 1000.0 / cd.wl;
872 frqObs->_phaseValid = true;
873 frqObs->_lockTime = lti2sec(type,ll[count]);
874 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
875 frqObs->_lockTimeIndicator = ll[count];
876 }
877
878 frqObs->_snr = cnr[count];
879 frqObs->_snrValid = true;
880
881 if (dop[count] > -1.6384) {
882 frqObs->_doppler = -(dop[count] + rdop[numsat]) / cd.wl;
883 frqObs->_dopplerValid = true;
884 }
885 break;
886 }
887 CurrentObs._obs.push_back(frqObs);
888 }
889 }
890 }
891 if (CurrentObs._obs.size() > 0) {
892 char sys = CurrentObs._prn.system();
893 int num = CurrentObs._prn.number();
894 int flag = t_corrSSR::getSsrNavTypeFlag(sys, num);
895 CurrentObs._prn.setFlag(flag);
896 _CurrentObsList.push_back(CurrentObs);
897 }
898 }
899 }
900 else if ((type % 10) < 4) {
901#ifdef BNC_DEBUG_OBS
902 emit(newMessage(QString("%1: Block %2 contain partial data! Ignored!")
903 .arg(_staID).arg(type).toLatin1(), true));
904#endif
905 }
906 if (!syncf) {
907 decoded = true;
908 _obsList.append(_CurrentObsList);
909 _CurrentTime.reset();
910 _CurrentObsList.clear();
911 }
912 return decoded;
913}
914
915//
916////////////////////////////////////////////////////////////////////////////
917bool RTCM3Decoder::DecodeRTCM3GLONASS(unsigned char* data, int size) {
918 bool decoded = false;
919 bncTime CurrentObsTime;
920 int i, numsats, syncf, type;
921 uint64_t numbits = 0, bitfield = 0;
922
923 data += 3; /* header */
924 size -= 6; /* header + crc */
925
926 GETBITS(type, 12)
927 SKIPBITS(12)
928 /* id */
929 GETBITS(i, 27)
930 /* tk */
931
932 CurrentObsTime.setTk(i);
933 if (_CurrentTime.valid() && CurrentObsTime != _CurrentTime) {
934 decoded = true;
935 _obsList.append(_CurrentObsList);
936 _CurrentObsList.clear();
937 }
938 _CurrentTime = CurrentObsTime;
939
940 GETBITS(syncf, 1)
941 /* sync */
942 GETBITS(numsats, 5)
943 SKIPBITS(4)
944 /* smind, smint */
945
946 while (numsats--) {
947 int sv, code, l1range, amb = 0, freq;
948 t_satObs CurrentObs;
949 CurrentObs._time = CurrentObsTime;
950 CurrentObs._type = type;
951
952 GETBITS(sv, 6)
953 char sys = 'R';
954 int flag = t_corrSSR::getSsrNavTypeFlag(sys, sv);
955 CurrentObs._prn.set(sys, sv, flag);
956 GETBITS(code, 1)
957 GETBITS(freq, 5)
958 GLOFreq[sv - 1] = 100 + freq - 7; /* store frequency for other users (MSM) */
959
960 t_frqObs *frqObs = new t_frqObs;
961 /* L1 */
962 (code) ?
963 frqObs->_rnxType2ch.assign("1P") : frqObs->_rnxType2ch.assign("1C");
964 GETBITS(l1range, 25);
965 GETBITSSIGN(i, 20);
966 if ((i & ((1 << 20) - 1)) != 0x80000) {
967 frqObs->_code = l1range * 0.02;
968 frqObs->_phase = (l1range * 0.02 + i * 0.0005) / GLO_WAVELENGTH_L1(freq - 7);
969 frqObs->_codeValid = frqObs->_phaseValid = true;
970 }
971 GETBITS(frqObs->_lockTimeIndicator, 7);
972 frqObs->_lockTime = lti2sec(type, frqObs->_lockTimeIndicator);
973 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
974 if (type == 1010 || type == 1012) {
975 GETBITS(amb, 7);
976 if (amb) {
977 frqObs->_code += amb * 599584.916;
978 frqObs->_phase += (amb * 599584.916) / GLO_WAVELENGTH_L1(freq - 7);
979 }
980 GETBITS(i, 8);
981 if (i) {
982 frqObs->_snr = i * 0.25;
983 frqObs->_snrValid = true;
984 }
985 }
986 CurrentObs._obs.push_back(frqObs);
987 if (type == 1011 || type == 1012) {
988 frqObs = new t_frqObs;
989 /* L2 */
990 GETBITS(code, 2);
991 switch (code) {
992 case 3:
993 frqObs->_rnxType2ch.assign("2P");
994 break;
995 case 2:
996 frqObs->_rnxType2ch.assign("2P");
997 break;
998 case 1:
999 frqObs->_rnxType2ch.assign("2P");
1000 break;
1001 case 0:
1002 frqObs->_rnxType2ch.assign("2C");
1003 break;
1004 }
1005 GETBITSSIGN(i, 14);
1006 if ((i & ((1 << 14) - 1)) != 0x2000) {
1007 frqObs->_code = l1range * 0.02 + i * 0.02 + amb * 599584.916;
1008 frqObs->_codeValid = true;
1009 }
1010 GETBITSSIGN(i, 20);
1011 if ((i & ((1 << 20) - 1)) != 0x80000) {
1012 frqObs->_phase = (l1range * 0.02 + i * 0.0005 + amb * 599584.916)
1013 / GLO_WAVELENGTH_L2(freq - 7);
1014 frqObs->_phaseValid = true;
1015 }
1016 GETBITS(frqObs->_lockTimeIndicator, 7);
1017 frqObs->_lockTime = lti2sec(type, frqObs->_lockTimeIndicator);
1018 frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
1019 if (type == 1012) {
1020 GETBITS(i, 8);
1021 if (i) {
1022 frqObs->_snr = i * 0.25;
1023 frqObs->_snrValid = true;
1024 }
1025 }
1026 CurrentObs._obs.push_back(frqObs);
1027 }
1028 _CurrentObsList.push_back(CurrentObs);
1029 }
1030 if (!syncf) {
1031 decoded = true;
1032 _obsList.append(_CurrentObsList);
1033 _CurrentTime.reset();
1034 _CurrentObsList.clear();
1035 }
1036 return decoded;
1037}
1038
1039//
1040////////////////////////////////////////////////////////////////////////////
1041bool RTCM3Decoder::DecodeGPSEphemeris(unsigned char* data, int size) {
1042 bool decoded = false;
1043
1044 if (size == 67) {
1045 t_ephGPS eph;
1046 int i, week;
1047 uint64_t numbits = 0, bitfield = 0;
1048 int fitIntervalFalg = 0;
1049
1050 data += 3; /* header */
1051 size -= 6; /* header + crc */
1052 SKIPBITS(12)
1053
1054 eph._receptDateTime = currentDateAndTimeGPS();
1055 eph._receptStaID = _staID;
1056
1057 GETBITS(i, 6)
1058 if (i < 1 || i > 63 ) {
1059#ifdef BNC_DEBUG_BCE
1060 emit(newMessage(QString("%1: Block %2 (G) PRN# is out of range: %3!")
1061 .arg(_staID)
1062 .arg(1019,4)
1063 .arg(i).toLatin1(), true));
1064#endif
1065 return false;
1066 }
1067 eph._prn.set('G', i);
1068 GETBITS(week, 10)
1069 if (week < 0 || week > 1023) {
1070#ifdef BNC_DEBUG_BCE
1071 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1072 .arg(_staID)
1073 .arg(1019,4)
1074 .arg(eph._prn.toString().c_str())
1075 .arg(week).toLatin1(), true));
1076#endif
1077 return false;
1078 }
1079 GETBITS(i, 4)
1080 eph._ura = accuracyFromIndex(i, eph.system());
1081 GETBITS(eph._L2Codes, 2)
1082 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1083 GETBITS(eph._IODE, 8)
1084 GETBITS(i, 16)
1085 i <<= 4;
1086 if (i < 0 || i > 604784) {
1087#ifdef BNC_DEBUG_BCE
1088 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1089 .arg(_staID)
1090 .arg(1019,4)
1091 .arg(eph._prn.toString().c_str())
1092 .arg(i).toLatin1(), true));
1093#endif
1094 return false;
1095 }
1096 eph._TOC.set(i * 1000);
1097 GETFLOATSIGN(eph._clock_driftrate, 8, 1.0 / (double )(1 << 30) / (double )(1 << 25))
1098 GETFLOATSIGN(eph._clock_drift, 16, 1.0 / (double )(1 << 30) / (double )(1 << 13))
1099 GETFLOATSIGN(eph._clock_bias, 22, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1100 GETBITS(eph._IODC, 10)
1101 GETFLOATSIGN(eph._Crs, 16, 1.0 / (double )(1 << 5))
1102 GETFLOATSIGN(eph._Delta_n, 16, R2R_PI/(double)(1<<30)/(double)(1<<13))
1103 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1104 GETFLOATSIGN(eph._Cuc, 16, 1.0 / (double )(1 << 29))
1105 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1106 GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
1107 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1108 if (eph._sqrt_A < 1000.0) {
1109#ifdef BNC_DEBUG_BCE
1110 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1111 .arg(_staID).arg(1019,4).arg(eph._prn.toString().c_str())
1112 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1113#endif
1114 return false;
1115 }
1116 GETBITS(i, 16)
1117 i <<= 4;
1118 if (i < 0 || i > 604784) {
1119#ifdef BNC_DEBUG_BCE
1120 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1121 .arg(_staID)
1122 .arg(1019,4)
1123 .arg(eph._prn.toString().c_str())
1124 .arg(i).toLatin1(), true));
1125#endif
1126 return false;
1127 }
1128 eph._TOEsec = i;
1129 bncTime t;
1130 t.set(i * 1000);
1131 eph._TOEweek = t.gpsw();
1132 int numOfRollOvers = int(floor(t.gpsw()/1024.0));
1133 week += (numOfRollOvers * 1024);
1134 /* week from HOW, differs from TOC, TOE week, we use adapted value instead */
1135 if (eph._TOEweek > week + 1 || eph._TOEweek < week - 1) /* invalid week */
1136 return false;
1137 GETFLOATSIGN(eph._Cic, 16, 1.0 / (double )(1 << 29))
1138 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1139 GETFLOATSIGN(eph._Cis, 16, 1.0 / (double )(1 << 29))
1140 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1141 GETFLOATSIGN(eph._Crc, 16, 1.0 / (double )(1 << 5))
1142 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1143 GETFLOATSIGN(eph._OMEGADOT, 24, R2R_PI/(double)(1<<30)/(double)(1<<13))
1144 GETFLOATSIGN(eph._TGD, 8, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1145 GETBITS(eph._health, 6)
1146 GETBITS(eph._L2PFlag, 1)
1147 GETBITS(fitIntervalFalg, 1)
1148 eph._fitInterval = fitIntervalFromFlag(fitIntervalFalg, eph._IODC, eph.system());
1149 eph._TOT = 0.9999e9;
1150 eph._type = t_eph::LNAV;
1151 eph._prn.setFlag(eph._type);
1152
1153 emit newGPSEph(eph);
1154 decoded = true;
1155 }
1156 return decoded;
1157}
1158
1159//
1160////////////////////////////////////////////////////////////////////////////
1161bool RTCM3Decoder::DecodeGLONASSEphemeris(unsigned char* data, int size) {
1162 bool decoded = false;
1163
1164 if (size == 51) {
1165 t_ephGlo eph;
1166 int sv, i, tk;
1167 uint64_t numbits = 0, bitfield = 0;
1168
1169 data += 3; /* header */
1170 size -= 6; /* header + crc */
1171 SKIPBITS(12)
1172
1173 eph._receptDateTime = currentDateAndTimeGPS();
1174 eph._receptStaID = _staID;
1175
1176 GETBITS(sv, 6)
1177 if (sv < 1 || sv > 63) {
1178#ifdef BNC_DEBUG_BCE
1179 emit(newMessage(QString("%1: Block %2 (R): SLOT# is unknown (0) or out of range: %3!")
1180 .arg(_staID)
1181 .arg(1020,4)
1182 .arg(sv).toLatin1(), true));
1183#endif
1184 return false;
1185 }
1186 eph._prn.set('R', sv);
1187
1188 GETBITS(i, 5)
1189 if (i < 0 || i > 20) {
1190#ifdef BNC_DEBUG_BCE
1191 emit(newMessage(QString("%1: Block %2 (%3): FRQ CHN# is out of range: %4")
1192 .arg(_staID)
1193 .arg(1020,4)
1194 .arg(eph._prn.toString().c_str())
1195 .arg(i).toLatin1(), true));
1196#endif
1197 return false;
1198 }
1199 eph._frq_num = i - 7;
1200 GETBITS(eph._almanac_health, 1) /* almanac healthy */
1201 GETBITS(eph._almanac_health_availablility_indicator, 1) /* almanac health ok */
1202 GETBITS(eph._P1, 2) /* P1 */
1203 /* tk */
1204 GETBITS(i, 5)
1205 if (i < 0 || i > 23) {
1206#ifdef BNC_DEBUG_BCE
1207 emit(newMessage(QString("%1: Block %2 (%3): T_k (bits 11-7) is out of range: %4")
1208 .arg(_staID)
1209 .arg(1020,4)
1210 .arg(eph._prn.toString().c_str())
1211 .arg(i).toLatin1(), true));
1212#endif
1213 return false;
1214 }
1215 tk = i * 60 * 60;
1216 GETBITS(i, 6)
1217 if (i < 0 || i > 59) {
1218#ifdef BNC_DEBUG_BCE
1219 emit(newMessage(QString("%1: Block %2 (%3): T_k (bits 6-1) is out of range: %4")
1220 .arg(_staID)
1221 .arg(1020,4)
1222 .arg(eph._prn.toString().c_str())
1223 .arg(i).toLatin1(), true));
1224#endif
1225 return false;
1226 }
1227 tk += i * 60;
1228 GETBITS(i, 1)
1229 if (i < 0 || i > 1) {
1230#ifdef BNC_DEBUG_BCE
1231 emit(newMessage(QString("%1: Block %2 (%3): T_k (bit 0) is out of range: %4")
1232 .arg(_staID)
1233 .arg(1020,4)
1234 .arg(eph._prn.toString().c_str())
1235 .arg(i).toLatin1(), true));
1236#endif
1237 return false;
1238 }
1239 tk += i * 30;
1240 eph._tki = tk - 3*60*60;
1241 if(eph._tki < 0.0) {
1242 eph._tki += 86400.0;
1243 }
1244 GETBITS(eph._health, 1) /* MSB of Bn*/
1245 GETBITS(eph._P2, 1) /* P2 */
1246 GETBITS(i, 7)
1247 i *= 15;
1248 if (i < 15 || i > 1425) {
1249#ifdef BNC_DEBUG_BCE
1250 emit(newMessage(QString("%1: Block %2 (%3): T_b is out of range: %4")
1251 .arg(_staID)
1252 .arg(1020,4)
1253 .arg(eph._prn.toString().c_str())
1254 .arg(i).toLatin1(), true));
1255#endif
1256 return false;
1257 }
1258 eph._TOC.setTk(i * 60 * 1000); /* tb */
1259
1260 GETFLOATSIGNM(eph._x_vel, 24, 1.0 / (double )(1 << 20))
1261 GETFLOATSIGNM(eph._x_pos, 27, 1.0 / (double )(1 << 11))
1262 GETFLOATSIGNM(eph._x_acc, 5, 1.0 / (double )(1 << 30))
1263 GETFLOATSIGNM(eph._y_vel, 24, 1.0 / (double )(1 << 20))
1264 GETFLOATSIGNM(eph._y_pos, 27, 1.0 / (double )(1 << 11))
1265 GETFLOATSIGNM(eph._y_acc, 5, 1.0 / (double )(1 << 30))
1266 GETFLOATSIGNM(eph._z_vel, 24, 1.0 / (double )(1 << 20))
1267 GETFLOATSIGNM(eph._z_pos, 27, 1.0 / (double )(1 << 11))
1268 GETFLOATSIGNM(eph._z_acc, 5, 1.0 / (double )(1 << 30))
1269 GETBITS(eph._P3, 1) /* P3 */
1270 GETFLOATSIGNM(eph._gamma, 11, 1.0 / (double )(1 << 30) / (double )(1 << 10))
1271 GETBITS(eph._M_P, 2) /* GLONASS-M P, */
1272 GETBITS(eph._M_l3, 1) /* GLONASS-M ln (third string) */
1273 GETFLOATSIGNM(eph._tau, 22, 1.0 / (double )(1 << 30)) /* GLONASS tau n(tb) */
1274 GETFLOATSIGNM(eph._M_delta_tau, 5, 1.0 / (double )(1 << 30)) /* GLONASS-M delta tau n(tb) */
1275 GETBITS(eph._E, 5)
1276 GETBITS(eph._M_P4, 1) /* GLONASS-M P4 */
1277 GETBITS(eph._M_FT, 4) /* GLONASS-M Ft */
1278 GETBITS(eph._M_NT, 11) /* GLONASS-M Nt */
1279 if (eph._M_NT == 0.0) {
1280#ifdef BNC_DEBUG_BCE
1281 emit(newMessage(QString("%1: Block %2 (%3): NT = %4: missing data!")
1282 .arg(_staID).arg(1020,4).arg(eph._prn.toString().c_str()).arg(eph._M_NT,4).toLatin1(), true));
1283#endif
1284 return false;
1285 }
1286 GETBITS(eph._M_M, 2) /* GLONASS-M M */
1287 GETBITS(eph._additional_data_availability, 1) /* GLONASS-M The Availability of Additional Data */
1288 if (eph._additional_data_availability == 0.0) {
1289#ifdef BNC_DEBUG_BCE
1290 emit(newMessage(QString("%1: Block %2 (%3): ADD = %4: missing data!")
1291 .arg(_staID).arg(1020,4).arg(eph._prn.toString().c_str())
1292 .arg(eph._additional_data_availability).toLatin1(), true));
1293#endif
1294 return false;
1295 }
1296 GETBITS(eph._M_NA, 11) /* GLONASS-M Na */
1297 GETFLOATSIGNM(eph._tauC, 32, 1.0/(double)(1<<30)/(double)(1<<1)) /* GLONASS tau c */
1298 GETBITS(eph._M_N4, 5) /* GLONASS-M N4 */
1299 GETFLOATSIGNM(eph._M_tau_GPS, 22, 1.0/(double)(1<<30)) /* GLONASS-M tau GPS */
1300 GETBITS(eph._M_l5, 1) /* GLONASS-M ln (fifth string) */
1301
1302 unsigned year, month, day;
1303 eph._TOC.civil_date(year, month, day);
1304 eph._gps_utc = gnumleap(year, month, day);
1305 eph._tt = eph._TOC;
1306
1307 eph._xv(1) = eph._x_pos * 1.e3;
1308 eph._xv(2) = eph._y_pos * 1.e3;
1309 eph._xv(3) = eph._z_pos * 1.e3;
1310 if (eph._xv.Rows(1,3).NormFrobenius() < 1.0) {
1311#ifdef BNC_DEBUG_BCE
1312 emit(newMessage(QString("%1: Block %2 (%3): zero position!")
1313 .arg(_staID).arg(1020,4).arg(eph._prn.toString().c_str()).toLatin1(), true));
1314#endif
1315 return false;
1316 }
1317 eph._xv(4) = eph._x_vel * 1.e3;
1318 eph._xv(5) = eph._y_vel * 1.e3;
1319 eph._xv(6) = eph._z_vel * 1.e3;
1320 if (eph._xv.Rows(4,6).NormFrobenius() < 1.0) {
1321#ifdef BNC_DEBUG_BCE
1322 emit(newMessage(QString("%1: Block %2 (%3): zero velocity!")
1323 .arg(_staID).arg(1020,4).arg(eph._prn.toString().c_str()).toLatin1(), true));
1324#endif
1325 return false;
1326 }
1327 GLOFreq[sv - 1] = 100 + eph._frq_num ; /* store frequency for other users (MSM) */
1328 _gloFrq = QString("%1 %2").arg(eph._prn.toString().c_str()).arg(eph._frq_num, 2, 'f', 0);
1329
1330 if (eph.validMdata()) {
1331 eph._type = t_eph::FDMA_M;
1332 }
1333 else {
1334 eph._type = t_eph::FDMA;
1335 }
1336 eph._prn.setFlag(eph._type);
1337 eph._healthflags_unknown = false;
1338 eph._statusflags_unknown = false;
1339
1340 emit newGlonassEph(eph);
1341 decoded = true;
1342 }
1343 return decoded;
1344}
1345
1346//
1347////////////////////////////////////////////////////////////////////////////
1348bool RTCM3Decoder::DecodeQZSSEphemeris(unsigned char* data, int size) {
1349 bool decoded = false;
1350
1351 if (size == 67) {
1352 t_ephGPS eph;
1353 int i, week;
1354 uint64_t numbits = 0, bitfield = 0;
1355 int fitIntervalFalg = 0;
1356
1357 data += 3; /* header */
1358 size -= 6; /* header + crc */
1359 SKIPBITS(12)
1360
1361 eph._receptDateTime = currentDateAndTimeGPS();
1362 eph._receptStaID = _staID;
1363
1364 GETBITS(i, 4)
1365 if (i < 1 || i > 10 ) {
1366#ifdef BNC_DEBUG_BCE
1367 emit(newMessage(QString("%1: Block %2 (J) SAT ID is out of range: %3!")
1368 .arg(_staID)
1369 .arg(1044,4)
1370 .arg(i).toLatin1(), true));
1371#endif
1372 return false;
1373 }
1374 eph._prn.set('J', i);
1375
1376 GETBITS(i, 16)
1377 i <<= 4;
1378 if (i < 0 || i > 604784) {
1379#ifdef BNC_DEBUG_BCE
1380 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1381 .arg(_staID)
1382 .arg(1044,4)
1383 .arg(eph._prn.toString().c_str())
1384 .arg(i).toLatin1(), true));
1385#endif
1386 return false;
1387 }
1388 eph._TOC.set(i * 1000);
1389
1390 GETFLOATSIGN(eph._clock_driftrate, 8, 1.0 / (double )(1 << 30) / (double )(1 << 25))
1391 GETFLOATSIGN(eph._clock_drift, 16, 1.0 / (double )(1 << 30) / (double )(1 << 13))
1392 GETFLOATSIGN(eph._clock_bias, 22, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1393 GETBITS(eph._IODE, 8)
1394 GETFLOATSIGN(eph._Crs, 16, 1.0 / (double )(1 << 5))
1395 GETFLOATSIGN(eph._Delta_n, 16, R2R_PI/(double)(1<<30)/(double)(1<<13))
1396 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1397 GETFLOATSIGN(eph._Cuc, 16, 1.0 / (double )(1 << 29))
1398 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1399 GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
1400 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1401 if (eph._sqrt_A < 1000.0) {
1402#ifdef BNC_DEBUG_BCE
1403 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1404 .arg(_staID).arg(1044,4).arg(eph._prn.toString().c_str())
1405 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1406#endif
1407 return false;
1408 }
1409 GETBITS(i, 16)
1410 i <<= 4;
1411 if (i < 0 || i > 604784) {
1412#ifdef BNC_DEBUG_BCE
1413 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1414 .arg(_staID)
1415 .arg(1044,4)
1416 .arg(eph._prn.toString().c_str())
1417 .arg(i).toLatin1(), true));
1418#endif
1419 return false;
1420 }
1421 eph._TOEsec = i;
1422 bncTime t;
1423 t.set(i*1000);
1424 eph._TOEweek = t.gpsw();
1425 GETFLOATSIGN(eph._Cic, 16, 1.0 / (double )(1 << 29))
1426 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1427 GETFLOATSIGN(eph._Cis, 16, 1.0 / (double )(1 << 29))
1428 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1429 GETFLOATSIGN(eph._Crc, 16, 1.0 / (double )(1 << 5))
1430 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1431 GETFLOATSIGN(eph._OMEGADOT, 24, R2R_PI/(double)(1<<30)/(double)(1<<13))
1432 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1433 GETBITS(eph._L2Codes, 2)
1434 GETBITS(week, 10)
1435 if (week < 0 || week > 1023) {
1436#ifdef BNC_DEBUG_BCE
1437 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1438 .arg(_staID)
1439 .arg(1044,4)
1440 .arg(eph._prn.toString().c_str())
1441 .arg(week).toLatin1(), true));
1442#endif
1443 return false;
1444 }
1445 int numOfRollOvers = int(floor(t.gpsw()/1024.0));
1446 week += (numOfRollOvers * 1024);
1447 /* week from HOW, differs from TOC, TOE week, we use adapted value instead */
1448 if (eph._TOEweek > week + 1 || eph._TOEweek < week - 1) /* invalid week */
1449 return false;
1450
1451 GETBITS(i, 4)
1452 eph._ura = accuracyFromIndex(i, eph.system());
1453 GETBITS(eph._health, 6)
1454 GETFLOATSIGN(eph._TGD, 8, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1455 GETBITS(eph._IODC, 10)
1456 GETBITS(fitIntervalFalg, 1)
1457 eph._fitInterval = fitIntervalFromFlag(fitIntervalFalg, eph._IODC, eph.system());
1458 eph._TOT = 0.9999e9;
1459 eph._type = t_eph::LNAV;
1460
1461 emit newGPSEph(eph);
1462 decoded = true;
1463 }
1464 return decoded;
1465}
1466
1467//
1468////////////////////////////////////////////////////////////////////////////
1469bool RTCM3Decoder::DecodeNavICEphemeris(unsigned char* data, int size) {
1470 bool decoded = false;
1471
1472 if (size == 67) {
1473 t_ephGPS eph;
1474 int i, week, L5Flag, SFlag;
1475 uint64_t numbits = 0, bitfield = 0;
1476
1477 data += 3; /* header */
1478 size -= 6; /* header + crc */
1479 SKIPBITS(12)
1480
1481 eph._receptDateTime = currentDateAndTimeGPS();
1482 eph._receptStaID = _staID;
1483
1484 GETBITS(i, 6)
1485 if (i < 1 || i > 63 ) {
1486#ifdef BNC_DEBUG_BCE
1487 emit(newMessage(QString("%1: Block %2 (I) PRN# is out of range: %3!")
1488 .arg(_staID)
1489 .arg(1041,4)
1490 .arg(i).toLatin1(), true));
1491#endif
1492 return false;
1493 }
1494 eph._prn.set('I', i);
1495 GETBITS(week, 10)
1496 if (week < 0 || week > 1023) {
1497#ifdef BNC_DEBUG_BCE
1498 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1499 .arg(_staID)
1500 .arg(1041,4)
1501 .arg(eph._prn.toString().c_str())
1502 .arg(week).toLatin1(), true));
1503#endif
1504 return false;
1505 }
1506 GETFLOATSIGN(eph._clock_bias, 22, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1507 GETFLOATSIGN(eph._clock_drift, 16, 1.0 / (double )(1 << 30) / (double )(1 << 13))
1508 GETFLOATSIGN(eph._clock_driftrate, 8, 1.0 / (double )(1 << 30) / (double )(1 << 25))
1509 GETBITS(i, 4)
1510 eph._ura = accuracyFromIndex(i, eph.system());
1511 GETBITS(i, 16)
1512 i <<= 4;
1513 if (i < 0 || i > 1048560) {
1514#ifdef BNC_DEBUG_BCE
1515 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1516 .arg(_staID)
1517 .arg(1041,4)
1518 .arg(eph._prn.toString().c_str())
1519 .arg(i).toLatin1(), true));
1520#endif
1521 return false;
1522 }
1523 eph._TOC.set(i * 1000);
1524 GETFLOATSIGN(eph._TGD, 8, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1525 GETFLOATSIGN(eph._Delta_n, 22, R2R_PI/(double)(1<<30)/(double)(1 << 11))
1526 // IODCE
1527 GETBITS(eph._IODE, 8)
1528 eph._IODC = eph._IODE;
1529 SKIPBITS(10)
1530 GETBITS(L5Flag, 1)
1531 GETBITS(SFlag, 1)
1532 if (L5Flag == 0 && SFlag == 0) {
1533 eph._health = 0.0;
1534 }
1535 else if (L5Flag == 0 && SFlag == 1) {
1536 eph._health = 1.0;
1537 }
1538 else if (L5Flag == 1 && SFlag == 0) {
1539 eph._health = 2.0;
1540 }
1541 else if (L5Flag == 1 && SFlag == 1) {
1542 eph._health = 3.0;
1543 }
1544 GETFLOATSIGN(eph._Cuc, 15, 1.0 / (double )(1 << 28))
1545 GETFLOATSIGN(eph._Cus, 15, 1.0 / (double )(1 << 28))
1546 GETFLOATSIGN(eph._Cic, 15, 1.0 / (double )(1 << 28))
1547 GETFLOATSIGN(eph._Cis, 15, 1.0 / (double )(1 << 28))
1548 GETFLOATSIGN(eph._Crc, 15, 1.0 / (double )(1 << 4))
1549 GETFLOATSIGN(eph._Crs, 15, 1.0 / (double )(1 << 4))
1550 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1551 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1552 GETBITS(i, 16)
1553 i <<= 4;
1554 if (i < 0 || i > 1048560) {
1555#ifdef BNC_DEBUG_BCE
1556 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1557 .arg(_staID)
1558 .arg(1041,4)
1559 .arg(eph._prn.toString().c_str())
1560 .arg(i).toLatin1(), true));
1561#endif
1562 return false;
1563 }
1564 eph._TOEsec = i;
1565 bncTime t;
1566 t.set(i * 1000);
1567 eph._TOEweek = t.gpsw();
1568 int numOfRollOvers = int(floor(t.gpsw()/1024.0));
1569 week += (numOfRollOvers * 1024);
1570 /* week from HOW, differs from TOC, TOE week, we use adapted value instead */
1571 if (eph._TOEweek > week + 1 || eph._TOEweek < week - 1) /* invalid week */
1572 return false;
1573 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1574 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1575 if (eph._sqrt_A < 1000.0) {
1576#ifdef BNC_DEBUG_BCE
1577 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1578 .arg(_staID).arg(1041,4).arg(eph._prn.toString().c_str())
1579 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1580#endif
1581 return false;
1582 }
1583 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1584 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1585 GETFLOATSIGN(eph._OMEGADOT, 22, R2R_PI/(double)(1<<30)/(double)(1<<11))
1586 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1587 GETBITS(eph._s_bits_after_IDOT, 2)
1588 GETBITS(eph._s_bits_after_i0, 2)
1589
1590 eph._TOT = 0.9999e9;
1591 eph._type = t_eph::LNAV;
1592 eph._prn.setFlag(eph._type);
1593
1594 emit newGPSEph(eph);
1595 decoded = true;
1596 }
1597 return decoded;
1598}
1599
1600//
1601////////////////////////////////////////////////////////////////////////////
1602bool RTCM3Decoder::DecodeSBASEphemeris(unsigned char* data, int size) {
1603 bool decoded = false;
1604
1605 if (size == 35) {
1606 t_ephSBAS eph;
1607 int i;
1608 eph._health = 0;
1609 uint64_t numbits = 0, bitfield = 0;
1610
1611 data += 3; /* header */
1612 size -= 6; /* header + crc */
1613 SKIPBITS(12)
1614
1615 eph._receptDateTime = currentDateAndTimeGPS();
1616 eph._receptStaID = _staID;
1617
1618 GETBITS(i, 6)
1619 if (i < 0 || i > 38 ) {
1620#ifdef BNC_DEBUG_BCE
1621 emit(newMessage(QString("%1: Block %2 (S) PRN# is out of range: %3!")
1622 .arg(_staID)
1623 .arg(1043,4)
1624 .arg(i).toLatin1(), true));
1625#endif
1626 return false;
1627 }
1628 eph._prn.set('S', 20 + i);
1629 GETBITS(eph._IODN, 8)
1630 GETBITS(i, 13)
1631 i <<= 4;
1632 if (i < 0 || i > 86384) {
1633#ifdef BNC_DEBUG_BCE
1634 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1635 .arg(_staID)
1636 .arg(1043,4)
1637 .arg(eph._prn.toString().c_str())
1638 .arg(i).toLatin1(), true));
1639#endif
1640 return false;
1641 }
1642 eph._TOC.setTOD(i * 1000);
1643 GETBITS(i, 4)
1644 int health = 0;
1645 if (i == 15) {
1646 health |= (1 << 5);
1647 // in this case it is recommended
1648 // to set the bits 0,1,2,3 to 1 (MT17health = 15)
1649 health |= (1 << 0);
1650 health |= (1 << 1);
1651 health |= (1 << 2);
1652 health |= (1 << 3);
1653 eph._health = double(health);
1654 }
1655 eph._ura = accuracyFromIndex(i, eph.system());
1656 GETFLOATSIGN(eph._x_pos, 30, 0.08)
1657 GETFLOATSIGN(eph._y_pos, 30, 0.08)
1658 GETFLOATSIGN(eph._z_pos, 25, 0.4)
1659 ColumnVector pos(3);
1660 pos(1) = eph._x_pos; pos(2) = eph._y_pos; pos(3) = eph._z_pos;
1661 if (pos.NormFrobenius() < 1.0) {
1662#ifdef BNC_DEBUG_BCE
1663 emit(newMessage(QString("%1: Block %2 (%3): zero position!")
1664 .arg(_staID).arg(1043,4).arg(eph._prn.toString().c_str()).toLatin1(), true));
1665#endif
1666 return false;
1667 }
1668 GETFLOATSIGN(eph._x_vel, 17, 0.000625)
1669 GETFLOATSIGN(eph._y_vel, 17, 0.000625)
1670 GETFLOATSIGN(eph._z_vel, 18, 0.004)
1671 GETFLOATSIGN(eph._x_acc, 10, 0.0000125)
1672 GETFLOATSIGN(eph._y_acc, 10, 0.0000125)
1673 GETFLOATSIGN(eph._z_acc, 10, 0.0000625)
1674 GETFLOATSIGN(eph._agf0, 12, 1.0 / (1 << 30) / (1 << 1))
1675 GETFLOATSIGN(eph._agf1, 8, 1.0 / (1 << 30) / (1 << 10))
1676
1677 eph._TOT = 0.9999E9;
1678
1679 eph._type = t_eph::SBASL1;
1680 eph._prn.setFlag(eph._type);
1681
1682 emit newSBASEph(eph);
1683 decoded = true;
1684 }
1685 return decoded;
1686}
1687
1688//
1689////////////////////////////////////////////////////////////////////////////
1690bool RTCM3Decoder::DecodeGalileoEphemeris(unsigned char* data, int size) {
1691 bool decoded = false;
1692 uint64_t numbits = 0, bitfield = 0;
1693 int i, week;
1694
1695 data += 3; /* header */
1696 size -= 6; /* header + crc */
1697 GETBITS(i, 12)
1698
1699 if ((i == 1046 && size == 61) ||
1700 (i == 1045 && size == 60)) {
1701 t_ephGal eph;
1702 eph._receptDateTime = currentDateAndTimeGPS();
1703 eph._receptStaID = _staID;
1704
1705 eph._inav = (i == 1046);
1706 eph._fnav = (i == 1045);
1707 int mnum = i;
1708 GETBITS(i, 6)
1709 if (i < 1 || i > 36 ) { // max. constellation within I/NAV / F/NAV frames is 36
1710#ifdef BNC_DEBUG_BCE
1711 emit(newMessage(QString("%1: Block %2 (E) PRN# is out of range: %3!")
1712 .arg(_staID)
1713 .arg(mnum,4)
1714 .arg(i).toLatin1(), true));
1715#endif
1716 return false;
1717 }
1718 eph._prn.set('E', i, eph._inav ? t_eph::INAV : t_eph::FNAV);
1719
1720 GETBITS(week, 12) //FIXME: roll-over after week 4095!!
1721 if (week < 0 || week > 4095) {
1722#ifdef BNC_DEBUG_BCE
1723 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1724 .arg(_staID)
1725 .arg(mnum,4)
1726 .arg(eph._prn.toString().c_str())
1727 .arg(week).toLatin1(), true));
1728#endif
1729 return false;
1730 }
1731 eph._TOEweek = week;
1732 GETBITS(eph._IODnav, 10)
1733 GETBITS(i, 8)
1734 eph._SISA = accuracyFromIndex(i, eph.system());
1735 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1736 GETBITSFACTOR(i, 14, 60)
1737 if (i < 0 || i > 604740) {
1738#ifdef BNC_DEBUG_BCE
1739 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1740 .arg(_staID)
1741 .arg(mnum,4)
1742 .arg(eph._prn.toString().c_str())
1743 .arg(i).toLatin1(), true));
1744#endif
1745 return false;
1746 }
1747 eph._TOC.set(1024 + eph._TOEweek, i);// Period #2 = + 1 x 1024 (has to be determined)
1748 GETFLOATSIGN(eph._clock_driftrate, 6, 1.0 / (double )(1 << 30) / (double )(1 << 29))
1749 GETFLOATSIGN(eph._clock_drift, 21, 1.0 / (double )(1 << 30) / (double )(1 << 16))
1750 GETFLOATSIGN(eph._clock_bias, 31, 1.0 / (double )(1 << 30) / (double )(1 << 4))
1751 GETFLOATSIGN(eph._Crs, 16, 1.0 / (double )(1 << 5))
1752 GETFLOATSIGN(eph._Delta_n, 16, R2R_PI/(double)(1<<30)/(double)(1<<13))
1753 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1754 GETFLOATSIGN(eph._Cuc, 16, 1.0 / (double )(1 << 29))
1755 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1756 GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
1757 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1758 GETBITSFACTOR(eph._TOEsec, 14, 60)
1759 if (i < 0 || i > 604740) {
1760#ifdef BNC_DEBUG_BCE
1761 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1762 .arg(_staID)
1763 .arg(mnum,4)
1764 .arg(eph._prn.toString().c_str())
1765 .arg(i).toLatin1(), true));
1766#endif
1767 return false;
1768 }
1769 /* FIXME: overwrite value, copied from old code */
1770 //eph._TOEsec = eph._TOC.gpssec();
1771 GETFLOATSIGN(eph._Cic, 16, 1.0 / (double )(1 << 29))
1772 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1773 GETFLOATSIGN(eph._Cis, 16, 1.0 / (double )(1 << 29))
1774 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1775 GETFLOATSIGN(eph._Crc, 16, 1.0 / (double )(1 << 5))
1776 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1777 GETFLOATSIGN(eph._OMEGADOT, 24, R2R_PI/(double)(1<<30)/(double)(1<<13))
1778 GETFLOATSIGN(eph._BGD_1_5A, 10, 1.0 / (double )(1 << 30) / (double )(1 << 2))
1779 if (eph._inav) {
1780 eph._type = t_eph::INAV;
1781 /* set unused F/NAV values */
1782 eph._E5a_HS = 0.0;
1783 eph._E5a_DataInvalid = false;
1784
1785 GETFLOATSIGN(eph._BGD_1_5B, 10, 1.0 / (double )(1 << 30) / (double )(1 << 2))
1786 GETBITS(eph._E5b_HS, 2)
1787 GETBITS(eph._E5b_DataInvalid, 1)
1788 GETBITS(eph._E1B_HS, 2)
1789 GETBITS(eph._E1B_DataInvalid, 1)
1790 if (eph._E5b_HS != eph._E1B_HS) {
1791#ifdef BNC_DEBUG_BCE
1792 emit(newMessage(QString("%1: Block %2 (%3) SHS E5b %4 E1B %5: inconsistent health!")
1793 .arg(_staID).arg(1046,4).arg(eph._prn.toString().c_str())
1794 .arg(eph._E5b_HS).arg(eph._E1B_HS).toLatin1(), true));
1795#endif
1796 return false;
1797 }
1798 if ((eph._BGD_1_5A == 0.0 && fabs(eph._BGD_1_5B) > 1e-9) ||
1799 (eph._BGD_1_5B == 0.0 && fabs(eph._BGD_1_5A) > 1e-9)) {
1800#ifdef BNC_DEBUG_BCE
1801 emit(newMessage(QString("%1: Block %2 (%3) BGD_1_5a = %4 BGD_1_5b = %5: inconsistent BGD!")
1802 .arg(_staID).arg(1046,4).arg(eph._prn.toString().c_str())
1803 .arg(eph._BGD_1_5A,10,'E',3).arg(eph._BGD_1_5B,10,'E',3).toLatin1(), true));
1804#endif
1805 return false;
1806 }
1807 }
1808 else {
1809 eph._type = t_eph::FNAV;
1810 /* set unused I/NAV values */
1811 eph._BGD_1_5B = 0.0;
1812 eph._E5b_HS = 0.0;
1813 eph._E1B_HS = 0.0;
1814 eph._E1B_DataInvalid = false;
1815 eph._E5b_DataInvalid = false;
1816
1817 GETBITS(eph._E5a_HS, 2)
1818 GETBITS(eph._E5a_DataInvalid, 1)
1819 }
1820 eph._TOT = 0.9999e9;
1821
1822 if (eph._sqrt_A < 1000.0) {
1823#ifdef BNC_DEBUG_BCE
1824 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1825 .arg(_staID).arg(eph._inav? 1046 : 1045,4).arg(eph._prn.toString().c_str())
1826 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1827#endif
1828 return false;
1829 }
1830
1831 emit newGalileoEph(eph);
1832 decoded = true;
1833 }
1834 return decoded;
1835}
1836
1837//
1838////////////////////////////////////////////////////////////////////////////
1839bool RTCM3Decoder::DecodeBDSEphemeris(unsigned char* data, int size) {
1840 bool decoded = false;
1841 const double iMaxGEO = 10.0 / 180.0 * M_PI;
1842
1843 if (size == 70) {
1844 t_ephBDS eph;
1845 int i, week;
1846 uint64_t numbits = 0, bitfield = 0;
1847
1848 data += 3; /* header */
1849 size -= 6; /* header + crc */
1850 SKIPBITS(12)
1851
1852 eph._receptDateTime = currentDateAndTimeGPS();
1853 eph._receptStaID = _staID;
1854
1855 GETBITS(i, 6)
1856 if (i < 1 || i > 63 ) {
1857#ifdef BNC_DEBUG_BCE
1858 emit(newMessage(QString("%1: Block %2 (C) PRN# is out of range: %3!")
1859 .arg(_staID)
1860 .arg(1042,4)
1861 .arg(i).toLatin1(), true));
1862#endif
1863 return false;
1864 }
1865 eph._prn.set('C', i);
1866
1867 GETBITS(week, 13)
1868 if (week < 0 || week > 8191) {
1869#ifdef BNC_DEBUG_BCE
1870 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1871 .arg(_staID)
1872 .arg(1042,4)
1873 .arg(eph._prn.toString().c_str())
1874 .arg(week).toLatin1(), true));
1875#endif
1876 return false;
1877 }
1878 eph._BDTweek = week;
1879 GETBITS(i, 4)
1880 eph._ura = accuracyFromIndex(i, eph.system());
1881 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1882 GETBITS(eph._AODE, 5)
1883 GETBITS(i, 17)
1884 i <<= 3;
1885 if (i < 0 || i > 604792) {
1886#ifdef BNC_DEBUG_BCE
1887 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1888 .arg(_staID)
1889 .arg(1042,4)
1890 .arg(eph._prn.toString().c_str())
1891 .arg(i).toLatin1(), true));
1892#endif
1893 return false;
1894 }
1895 eph._TOC.setBDS(eph._BDTweek, i);
1896 GETFLOATSIGN(eph._clock_driftrate, 11, 1.0 / (double )(1 << 30) / (double )(1 << 30) / (double )(1 << 6))
1897 GETFLOATSIGN(eph._clock_drift, 22, 1.0 / (double )(1 << 30) / (double )(1 << 20))
1898 GETFLOATSIGN(eph._clock_bias, 24, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1899 GETBITS(eph._AODC, 5)
1900 GETFLOATSIGN(eph._Crs, 18, 1.0 / (double )(1 << 6))
1901 GETFLOATSIGN(eph._Delta_n, 16, R2R_PI/(double)(1<<30)/(double)(1<<13))
1902 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1903 GETFLOATSIGN(eph._Cuc, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1904 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1905 GETFLOATSIGN(eph._Cus, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1906 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1907 if (eph._sqrt_A < 1000.0) {
1908#ifdef BNC_DEBUG_BCE
1909 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1910 .arg(_staID).arg(1042,4).arg(eph._prn.toString().c_str())
1911 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1912#endif
1913 return false;
1914 }
1915 GETBITS(i, 17)
1916 i <<= 3;
1917 if (i < 0 || i > 604792) {
1918#ifdef BNC_DEBUG_BCE
1919 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1920 .arg(_staID)
1921 .arg(1042,4)
1922 .arg(eph._prn.toString().c_str())
1923 .arg(i).toLatin1(), true));
1924#endif
1925 return false;
1926 }
1927 eph._TOEsec = i;
1928 eph._TOE.setBDS(eph._BDTweek, i);
1929 GETFLOATSIGN(eph._Cic, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1930 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1931 GETFLOATSIGN(eph._Cis, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1932 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1933 GETFLOATSIGN(eph._Crc, 18, 1.0 / (double )(1 << 6))
1934 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1935 GETFLOATSIGN(eph._OMEGADOT, 24, R2R_PI/(double)(1<<30)/(double)(1<<13))
1936 GETFLOATSIGN(eph._TGD1, 10, 0.0000000001)
1937 GETFLOATSIGN(eph._TGD2, 10, 0.0000000001)
1938 GETBITS(eph._SatH1, 1)
1939
1940 eph._TOT = 0.9999E9;
1941 if (eph._i0 > iMaxGEO) {
1942 eph._type = t_eph::D1;
1943 }
1944 else {
1945 eph._type = t_eph::D2;
1946 }
1947 eph._prn.setFlag(eph._type);
1948
1949 emit newBDSEph(eph);
1950 decoded = true;
1951 }
1952 return decoded;
1953}
1954
1955//
1956////////////////////////////////////////////////////////////////////////////
1957bool RTCM3Decoder::DecodeAntennaReceiver(unsigned char* data, int size) {
1958 char *antenna;
1959 char *antserialnum;
1960 char *receiver;
1961 char *rec_firmware;
1962 char *recserialnum;
1963 int type;
1964 int antsernum = -1;
1965 int antnum = -1;
1966 int recnum = -1;
1967 int recsernum = -1;
1968 int recfirnum = -1;
1969 uint64_t numbits = 0, bitfield = 0;
1970
1971 data += 3; /* header*/
1972 size -= 6; /* header + crc */
1973
1974 GETBITS(type, 12)
1975 SKIPBITS(12) /* reference station ID */
1976 GETSTRING(antnum, antenna)
1977 if ((antnum > -1 && antnum < 265) &&
1978 (_antType.empty() || strncmp(_antType.back()._descriptor, antenna, recnum) != 0)) {
1979 _antType.push_back(t_antInfo());
1980 memcpy(_antType.back()._descriptor, antenna, antnum);
1981 _antType.back()._descriptor[antnum] = 0;
1982 }
1983 SKIPBITS(8) /* antenna setup ID */
1984 if (type == 1008 || type == 1033 ) {
1985 GETSTRING(antsernum, antserialnum)
1986 if ((antsernum > -1 && antsernum < 265)) {
1987 memcpy(_antType.back()._serialnumber, antserialnum, antsernum);
1988 _antType.back()._serialnumber[antsernum] = 0;
1989 }
1990 }
1991
1992 if (type == 1033) {
1993 GETSTRING(recnum, receiver)
1994 GETSTRING(recfirnum, rec_firmware)
1995 GETSTRING(recsernum, recserialnum)
1996 if ((recnum > -1 && recnum < 265) &&
1997 (_recType.empty() || strncmp(_recType.back()._descriptor, receiver, recnum) != 0)) {
1998 _recType.push_back(t_recInfo());
1999 memcpy(_recType.back()._descriptor, receiver, recnum);
2000 _recType.back()._descriptor[recnum] = 0;
2001 if (recfirnum > -1 && recfirnum < 265) {
2002 memcpy(_recType.back()._firmware, rec_firmware, recfirnum);
2003 _recType.back()._firmware[recfirnum] = 0;
2004 }
2005 if (recsernum > -1 && recsernum < 265) {
2006 memcpy(_recType.back()._serialnumber, recserialnum, recsernum);
2007 _recType.back()._serialnumber[recsernum] = 0;
2008 }
2009 }
2010 }
2011 return true;
2012}
2013
2014//
2015////////////////////////////////////////////////////////////////////////////
2016bool RTCM3Decoder::DecodeAntennaPosition(unsigned char* data, int size) {
2017 int type;
2018 uint64_t numbits = 0, bitfield = 0;
2019 double x, y, z;
2020
2021 data += 3; /* header */
2022 size -= 6; /* header + crc */
2023
2024 GETBITS(type, 12)
2025 _antList.push_back(t_antRefPoint());
2026 _antList.back()._type = t_antRefPoint::ARP;
2027 SKIPBITS(22)
2028 GETBITSSIGN(x, 38)
2029 _antList.back()._xx = x * 1e-4;
2030 SKIPBITS(2)
2031 GETBITSSIGN(y, 38)
2032 _antList.back()._yy = y * 1e-4;
2033 SKIPBITS(2)
2034 GETBITSSIGN(z, 38)
2035 _antList.back()._zz = z * 1e-4;
2036 if (type == 1006) {
2037 double h;
2038 GETBITS(h, 16)
2039 _antList.back()._height = h * 1e-4;
2040 _antList.back()._height_f = true;
2041 }
2042 _antList.back()._message = type;
2043
2044 return true;
2045}
2046
2047//
2048////////////////////////////////////////////////////////////////////////////
2049bool RTCM3Decoder::DecodeGLONASSCodePhaseBiases(unsigned char* data, int size) {
2050 t_GloBiasInfo gloBiasInfo;
2051 int i = 0;
2052 uint64_t numbits = 0, bitfield = 0;
2053
2054 data += 3; // header
2055 size -= 6; // header + crc
2056
2057 SKIPBITS(12) // Message Number
2058 GETBITS(gloBiasInfo._staID, 12)
2059 GETBITS(gloBiasInfo._indicator, 1) // 0.. not aligned, 1.. aligned
2060 SKIPBITS(3) // reserved bits
2061 unsigned int bitmask;
2062 GETBITS(bitmask, 4)
2063 bool L1C_valid = bitExtracted(unsigned(bitmask), 1, 0);
2064 bool L1P_valid = bitExtracted(unsigned(bitmask), 1, 1);
2065 bool L2C_valid = bitExtracted(unsigned(bitmask), 1, 2);
2066 bool L2P_valid = bitExtracted(unsigned(bitmask), 1, 3);
2067
2068 if (L1C_valid) {
2069 GETBITSSIGN(i, 16)
2070 gloBiasInfo._L1C_value = i * 0.02;
2071 }
2072 if (L1P_valid) {
2073 GETBITSSIGN(i, 16)
2074 gloBiasInfo._L1P_value = i * 0.02;
2075 }
2076 if (L2C_valid) {
2077 GETBITSSIGN(i, 16)
2078 gloBiasInfo._L2C_value = i * 0.02;
2079 }
2080 if (L2P_valid) {
2081 GETBITSSIGN(i, 16)
2082 gloBiasInfo._L2P_value = i * 0.02;
2083 }
2084
2085 if (_gloBiasInfo != gloBiasInfo) {
2086 _gloBiasInfo.set(gloBiasInfo);
2087 }
2088 return true;
2089}
2090
2091//
2092////////////////////////////////////////////////////////////////////////////
2093bool RTCM3Decoder::DecodeServiceCRS(unsigned char* data, int size) {
2094 t_serviceCrs serviceCrs;
2095 int servicecrsnum = -1;
2096
2097 uint64_t numbits = 0, bitfield = 0;
2098
2099 data += 3; // header
2100 size -= 6; // header + crc
2101
2102 SKIPBITS(12) // Message Number
2103
2104 GETBITS(servicecrsnum, 5)
2105 if (servicecrsnum > -1 && servicecrsnum <= 31) {
2106 for(int i = 0; i < servicecrsnum; i++) {
2107 GETBITS(serviceCrs._name[i], 8);
2108 }
2109 serviceCrs._name[servicecrsnum] = 0;
2110 }
2111 if (_serviceCrs.empty() ||
2112 (strncmp(_serviceCrs.back()._name, serviceCrs._name, servicecrsnum) != 0)) {
2113 _serviceCrs.push_back(serviceCrs);
2114 GETFLOAT(_serviceCrs.back()._CE, 16, 1/100.0)
2115 _serviceCrs.back().setCoordinateEpochFromCE();
2116 //_serviceCrs.back().print();
2117 }
2118 return true;
2119
2120}
2121
2122//
2123////////////////////////////////////////////////////////////////////////////
2124bool RTCM3Decoder::DecodeRTCMCRS(unsigned char* data, int size) {
2125
2126 t_rtcmCrs rtcmCrs;
2127 int rtcmcrsnum = -1;
2128
2129 uint64_t numbits = 0, bitfield = 0;
2130
2131 data += 3; // header
2132 size -= 6; // header + crc
2133
2134 SKIPBITS(12) // Message Number
2135 GETBITS(rtcmcrsnum, 5)
2136 if (rtcmcrsnum > -1 && rtcmcrsnum <= 31) {
2137 for(int i = 0; i < rtcmcrsnum; i++) {
2138 GETBITS(rtcmCrs._name[i], 8);
2139 }
2140 rtcmCrs._name[rtcmcrsnum] = 0;
2141 }
2142 if (_rtcmCrs.empty() ||
2143 (strncmp(_rtcmCrs.back()._name, rtcmCrs._name, rtcmcrsnum) != 0)) {
2144 _rtcmCrs.push_back(rtcmCrs);
2145
2146 GETBITS(_rtcmCrs.back()._anchor, 1)
2147 GETBITS(_rtcmCrs.back()._plateNumber, 5)
2148
2149 int dblinksnum = 0;
2150 GETBITS(dblinksnum, 3)
2151 for (int i = 0; i < dblinksnum; i++) {
2152 int dblinknum = -1;
2153 char dblinkname[31];
2154 GETBITS(dblinknum, 5)
2155 if (dblinknum > -1 && dblinknum <= 31) {
2156 for(int i = 0; i < dblinknum; i++) {
2157 GETBITS(dblinkname[i], 8);
2158 }
2159 dblinkname[dblinknum] = 0;
2160 _rtcmCrs.back()._databaseLinks.append(QString("%1").arg(dblinkname));
2161 }
2162 }
2163 //_rtcmCrs.back().print();
2164 }
2165
2166 return true;
2167}
2168
2169
2170////////////////////////////////////////////////////////////////////////////
2171bool RTCM3Decoder::DecodeHelmertTrafoParameters(unsigned char* data, int size) {
2172
2173 t_helmertPar helmertPar;
2174 int sourcenum = -1;
2175 int targetnum = -1;
2176
2177 uint64_t numbits = 0, bitfield = 0;
2178 data += 3; // header
2179 size -= 6; // header + crc
2180
2181 SKIPBITS(12) // Message Number
2182 GETBITS(sourcenum, 5)
2183 if (sourcenum > -1 && sourcenum <= 31) {
2184 for(int i = 0; i < sourcenum; i++) {
2185 GETBITS(helmertPar._sourceName[i], 8);
2186 }
2187 helmertPar._sourceName[sourcenum] = 0;
2188 }
2189 GETBITS(targetnum, 5)
2190 if (targetnum > -1 && targetnum <= 31) {
2191 for(int i = 0; i < targetnum; i++) {
2192 GETBITS(helmertPar._targetName[i], 8);
2193 }
2194 helmertPar._targetName[targetnum] = 0;
2195 }
2196 GETBITS(helmertPar._sysIdentNum, 8)
2197 GETBITS(helmertPar._utilTrafoMessageIndicator, 10)
2198 GETBITS(helmertPar._mjd, 16)
2199 helmertPar._mjd += 44244;
2200
2201 // delete old parameter entries if available
2202 if (!_helmertPar.empty()) {
2203 QList<t_helmertPar>::iterator it = _helmertPar.begin();
2204 while (it != _helmertPar.end()) {
2205 (helmertPar == *it) ? it = _helmertPar.erase(it) : ++it;
2206 }
2207 }
2208 _helmertPar.push_back(helmertPar);
2209
2210 GETFLOATSIGN(_helmertPar.back()._dx, 23, 1/1000.0)
2211 GETFLOATSIGN(_helmertPar.back()._dy, 23, 1/1000.0)
2212 GETFLOATSIGN(_helmertPar.back()._dz, 23, 1/1000.0)
2213
2214 GETFLOATSIGN(_helmertPar.back()._ox, 32, 1/50000.0)
2215 GETFLOATSIGN(_helmertPar.back()._oy, 32, 1/50000.0)
2216 GETFLOATSIGN(_helmertPar.back()._oz, 32, 1/50000.0)
2217
2218 GETFLOATSIGN(_helmertPar.back()._sc, 25, 1/100000.0)
2219
2220 GETFLOATSIGN(_helmertPar.back()._dxr, 17, 1/50000.0)
2221 GETFLOATSIGN(_helmertPar.back()._dyr, 17, 1/50000.0)
2222 GETFLOATSIGN(_helmertPar.back()._dzr, 17, 1/50000.0)
2223
2224 GETFLOATSIGN(_helmertPar.back()._oxr, 17, 1/2500000.0)
2225 GETFLOATSIGN(_helmertPar.back()._oyr, 17, 1/2500000.0)
2226 GETFLOATSIGN(_helmertPar.back()._ozr, 17, 1/2500000.0)
2227
2228 GETFLOATSIGN(_helmertPar.back()._scr, 14, 1/5000000.0)
2229
2230 //_helmertPar.back().print();
2231
2232 return true;
2233}
2234
2235
2236//
2237////////////////////////////////////////////////////////////////////////////
2238t_irc RTCM3Decoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
2239 bool decoded = false;
2240
2241 errmsg.clear();
2242
2243 while (bufLen && _MessageSize < sizeof(_Message)) {
2244 int l = sizeof(_Message) - _MessageSize;
2245 if (l > bufLen)
2246 l = bufLen;
2247 memcpy(_Message + _MessageSize, buffer, l);
2248 _MessageSize += l;
2249 bufLen -= l;
2250 buffer += l;
2251 int id;
2252 while ((id = GetMessage())) {
2253 /* reset station ID for file loading as it can change */
2254 if (_rawFile)
2255 _staID = _rawFile->staID();
2256 /* store the id and message size into the list of loaded blocks */
2257 _typeList.push_back(t_typeInfo());
2258 _typeList.back()._type = id;
2259 _typeList.back()._size = _BlockSize -6; /* header + crc */
2260
2261 /* SSR I+II data handled in another function, already pass the
2262 * extracted data block. That does no harm, as it anyway skip everything
2263 * else. */
2264 if ((id >= 1057 && id <= 1068) ||
2265 (id >= 1240 && id <= 1270) ||
2266 (id == 4076)) {
2267 if (!_coDecoders.contains(_staID.toLatin1())) {
2268 _coDecoders[_staID.toLatin1()] = new RTCM3coDecoder(_staID);
2269 if (id == 4076) {
2270 _coDecoders[_staID.toLatin1()]->initSsrFormatType(RTCM3coDecoder::IGSssr);
2271 }
2272 else {
2273 _coDecoders[_staID.toLatin1()]->initSsrFormatType(RTCM3coDecoder::RTCMssr);
2274 }
2275 }
2276 RTCM3coDecoder* coDecoder = _coDecoders[_staID.toLatin1()];
2277 if (coDecoder->Decode(reinterpret_cast<char *>(_Message), _BlockSize, errmsg) == success) {
2278 decoded = true;
2279 }
2280 }
2281 else if (id >= 1070 && id <= 1137) { /* MSM */
2282 if (DecodeRTCM3MSM(_Message, _BlockSize))
2283 decoded = true;
2284 }
2285 else {
2286 switch (id) {
2287 case 1001:
2288 case 1003:
2289#ifdef BNC_DEBUG_OBS
2290 emit(newMessage(QString("%1: Block %2 contain partial data! Ignored!")
2291 .arg(_staID).arg(id).toLatin1(), true));
2292#endif
2293 break; /* no use decoding partial data ATM, remove break when data can be used */
2294 case 1002:
2295 case 1004:
2296 if (DecodeRTCM3GPS(_Message, _BlockSize))
2297 decoded = true;
2298 break;
2299 case 1009:
2300 case 1011:
2301#ifdef BNC_DEBUG_OBS
2302 emit(newMessage(QString("%1: Block %2 contain partial data! Ignored!")
2303 .arg(_staID).arg(id).toLatin1(), true));
2304#endif
2305 break; /* no use decoding partial data ATM, remove break when data can be used */
2306 case 1010:
2307 case 1012:
2308 if (DecodeRTCM3GLONASS(_Message, _BlockSize))
2309 decoded = true;
2310 break;
2311 case 1019:
2312 if (DecodeGPSEphemeris(_Message, _BlockSize))
2313 decoded = true;
2314 break;
2315 case 1020:
2316 if (DecodeGLONASSEphemeris(_Message, _BlockSize))
2317 decoded = true;
2318 break;
2319 case 1043:
2320 if (DecodeSBASEphemeris(_Message, _BlockSize))
2321 decoded = true;
2322 break;
2323 case 1044:
2324 if (DecodeQZSSEphemeris(_Message, _BlockSize))
2325 decoded = true;
2326 break;
2327 case 1041:
2328 if (DecodeNavICEphemeris(_Message, _BlockSize))
2329 decoded = true;
2330 break;
2331 case 1045:
2332 case 1046:
2333 if (DecodeGalileoEphemeris(_Message, _BlockSize))
2334 decoded = true;
2335 break;
2336 case 1042:
2337 if (DecodeBDSEphemeris(_Message, _BlockSize))
2338 decoded = true;
2339 break;
2340 case 1007:
2341 case 1008:
2342 case 1033:
2343 DecodeAntennaReceiver(_Message, _BlockSize);
2344 break;
2345 case 1005:
2346 case 1006:
2347 DecodeAntennaPosition(_Message, _BlockSize);
2348 break;
2349 case 1230:
2350 DecodeGLONASSCodePhaseBiases(_Message, _BlockSize);
2351 break;
2352 case 1300:
2353 DecodeServiceCRS(_Message, _BlockSize);
2354 break;
2355 case 1301:
2356 DecodeHelmertTrafoParameters(_Message, _BlockSize);
2357 break;
2358 case 1302:
2359 case 35:
2360 DecodeRTCMCRS(_Message, _BlockSize);
2361 break;
2362 }
2363 }
2364 }
2365 }
2366 /*
2367 for (int ii = 0; ii < _helmertParList.size(); ii++) {
2368 _helmertParList[ii].print();
2369 }*/
2370 return decoded ? success : failure;
2371}
2372
2373//
2374////////////////////////////////////////////////////////////////////////////
2375uint32_t RTCM3Decoder::CRC24(long size, const unsigned char *buf) {
2376 uint32_t crc = 0;
2377 int ii;
2378 while (size--) {
2379 crc ^= (*buf++) << (16);
2380 for (ii = 0; ii < 8; ii++) {
2381 crc <<= 1;
2382 if (crc & 0x1000000)
2383 crc ^= 0x01864cfb;
2384 }
2385 }
2386 return crc;
2387}
2388
2389//
2390////////////////////////////////////////////////////////////////////////////
2391int RTCM3Decoder::GetMessage(void) {
2392 unsigned char *m, *e;
2393 int i;
2394
2395 m = _Message + _SkipBytes;
2396 e = _Message + _MessageSize;
2397 _NeedBytes = _SkipBytes = 0;
2398 while (e - m >= 3) {
2399 if (m[0] == 0xD3) {
2400 _BlockSize = ((m[1] & 3) << 8) | m[2];
2401 if (e - m >= static_cast<int>(_BlockSize + 6)) {
2402 if (static_cast<uint32_t>((m[3 + _BlockSize] << 16)
2403 | (m[3 + _BlockSize + 1] << 8)
2404 | (m[3 + _BlockSize + 2])) == CRC24(_BlockSize + 3, m)) {
2405 _BlockSize += 6;
2406 _SkipBytes = _BlockSize;
2407 break;
2408 }
2409 else
2410 ++m;
2411 }
2412 else {
2413 _NeedBytes = _BlockSize;
2414 break;
2415 }
2416 }
2417 else
2418 ++m;
2419 }
2420 if (e - m < 3)
2421 _NeedBytes = 3;
2422
2423 /* copy buffer to front */
2424 i = m - _Message;
2425 if (i && m < e)
2426 memmove(_Message, m, static_cast<size_t>(_MessageSize - i));
2427 _MessageSize -= i;
2428
2429 return !_NeedBytes ? ((_Message[3] << 4) | (_Message[4] >> 4)) : 0;
2430}
2431
2432// Time of Corrections
2433//////////////////////////////////////////////////////////////////////////////
2434int RTCM3Decoder::corrGPSEpochTime() const {
2435 return
2436 _coDecoders.size() > 0 ?
2437 _coDecoders.begin().value()->corrGPSEpochTime() : -1;
2438}
2439
2440
2441
2442
Note: See TracBrowser for help on using the repository browser.