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

Last change on this file since 10638 was 10632, checked in by stuerze, 7 days ago

minor changes

File size: 75.6 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 SKIPBITS(2)
1552 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1553 GETBITS(i, 16)
1554 i <<= 4;
1555 if (i < 0 || i > 1048560) {
1556#ifdef BNC_DEBUG_BCE
1557 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1558 .arg(_staID)
1559 .arg(1041,4)
1560 .arg(eph._prn.toString().c_str())
1561 .arg(i).toLatin1(), true));
1562#endif
1563 return false;
1564 }
1565 eph._TOEsec = i;
1566 bncTime t;
1567 t.set(i * 1000);
1568 eph._TOEweek = t.gpsw();
1569 int numOfRollOvers = int(floor(t.gpsw()/1024.0));
1570 week += (numOfRollOvers * 1024);
1571 /* week from HOW, differs from TOC, TOE week, we use adapted value instead */
1572 if (eph._TOEweek > week + 1 || eph._TOEweek < week - 1) /* invalid week */
1573 return false;
1574 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1575 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1576 if (eph._sqrt_A < 1000.0) {
1577#ifdef BNC_DEBUG_BCE
1578 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1579 .arg(_staID).arg(1041,4).arg(eph._prn.toString().c_str())
1580 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1581#endif
1582 return false;
1583 }
1584 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1585 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1586 GETFLOATSIGN(eph._OMEGADOT, 22, R2R_PI/(double)(1<<30)/(double)(1<<11))
1587 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
1588 SKIPBITS(2)
1589 eph._TOT = 0.9999e9;
1590 eph._type = t_eph::LNAV;
1591 eph._prn.setFlag(eph._type);
1592
1593 emit newGPSEph(eph);
1594 decoded = true;
1595 }
1596 return decoded;
1597}
1598
1599//
1600////////////////////////////////////////////////////////////////////////////
1601bool RTCM3Decoder::DecodeSBASEphemeris(unsigned char* data, int size) {
1602 bool decoded = false;
1603
1604 if (size == 35) {
1605 t_ephSBAS eph;
1606 int i;
1607 eph._health = 0;
1608 uint64_t numbits = 0, bitfield = 0;
1609
1610 data += 3; /* header */
1611 size -= 6; /* header + crc */
1612 SKIPBITS(12)
1613
1614 eph._receptDateTime = currentDateAndTimeGPS();
1615 eph._receptStaID = _staID;
1616
1617 GETBITS(i, 6)
1618 if (i < 0 || i > 38 ) {
1619#ifdef BNC_DEBUG_BCE
1620 emit(newMessage(QString("%1: Block %2 (S) PRN# is out of range: %3!")
1621 .arg(_staID)
1622 .arg(1043,4)
1623 .arg(i).toLatin1(), true));
1624#endif
1625 return false;
1626 }
1627 eph._prn.set('S', 20 + i);
1628 GETBITS(eph._IODN, 8)
1629 GETBITS(i, 13)
1630 i <<= 4;
1631 if (i < 0 || i > 86384) {
1632#ifdef BNC_DEBUG_BCE
1633 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1634 .arg(_staID)
1635 .arg(1043,4)
1636 .arg(eph._prn.toString().c_str())
1637 .arg(i).toLatin1(), true));
1638#endif
1639 return false;
1640 }
1641 eph._TOC.setTOD(i * 1000);
1642 GETBITS(i, 4)
1643 int health = 0;
1644 if (i == 15) {
1645 health |= (1 << 5);
1646 // in this case it is recommended
1647 // to set the bits 0,1,2,3 to 1 (MT17health = 15)
1648 health |= (1 << 0);
1649 health |= (1 << 1);
1650 health |= (1 << 2);
1651 health |= (1 << 3);
1652 eph._health = double(health);
1653 }
1654 eph._ura = accuracyFromIndex(i, eph.system());
1655 GETFLOATSIGN(eph._x_pos, 30, 0.08)
1656 GETFLOATSIGN(eph._y_pos, 30, 0.08)
1657 GETFLOATSIGN(eph._z_pos, 25, 0.4)
1658 ColumnVector pos(3);
1659 pos(1) = eph._x_pos; pos(2) = eph._y_pos; pos(3) = eph._z_pos;
1660 if (pos.NormFrobenius() < 1.0) {
1661#ifdef BNC_DEBUG_BCE
1662 emit(newMessage(QString("%1: Block %2 (%3): zero position!")
1663 .arg(_staID).arg(1043,4).arg(eph._prn.toString().c_str()).toLatin1(), true));
1664#endif
1665 return false;
1666 }
1667 GETFLOATSIGN(eph._x_vel, 17, 0.000625)
1668 GETFLOATSIGN(eph._y_vel, 17, 0.000625)
1669 GETFLOATSIGN(eph._z_vel, 18, 0.004)
1670 GETFLOATSIGN(eph._x_acc, 10, 0.0000125)
1671 GETFLOATSIGN(eph._y_acc, 10, 0.0000125)
1672 GETFLOATSIGN(eph._z_acc, 10, 0.0000625)
1673 GETFLOATSIGN(eph._agf0, 12, 1.0 / (1 << 30) / (1 << 1))
1674 GETFLOATSIGN(eph._agf1, 8, 1.0 / (1 << 30) / (1 << 10))
1675
1676 eph._TOT = 0.9999E9;
1677
1678 eph._type = t_eph::SBASL1;
1679 eph._prn.setFlag(eph._type);
1680
1681 emit newSBASEph(eph);
1682 decoded = true;
1683 }
1684 return decoded;
1685}
1686
1687//
1688////////////////////////////////////////////////////////////////////////////
1689bool RTCM3Decoder::DecodeGalileoEphemeris(unsigned char* data, int size) {
1690 bool decoded = false;
1691 uint64_t numbits = 0, bitfield = 0;
1692 int i, week, mnum;
1693
1694 data += 3; /* header */
1695 size -= 6; /* header + crc */
1696 GETBITS(i, 12)
1697
1698 if ((i == 1046 && size == 61) ||
1699 (i == 1045 && size == 60)) {
1700 t_ephGal eph;
1701 eph._receptDateTime = currentDateAndTimeGPS();
1702 eph._receptStaID = _staID;
1703
1704 eph._inav = (i == 1046);
1705 eph._fnav = (i == 1045);
1706 mnum = i;
1707 GETBITS(i, 6)
1708 if (i < 1 || i > 36 ) { // max. constellation within I/NAV / F/NAV frames is 36
1709#ifdef BNC_DEBUG_BCE
1710 emit(newMessage(QString("%1: Block %2 (E) PRN# is out of range: %3!")
1711 .arg(_staID)
1712 .arg(mnum,4)
1713 .arg(i).toLatin1(), true));
1714#endif
1715 return false;
1716 }
1717 eph._prn.set('E', i, eph._inav ? t_eph::INAV : t_eph::FNAV);
1718
1719 GETBITS(week, 12) //FIXME: roll-over after week 4095!!
1720 if (week < 0 || week > 4095) {
1721#ifdef BNC_DEBUG_BCE
1722 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1723 .arg(_staID)
1724 .arg(mnum,4)
1725 .arg(eph._prn.toString().c_str())
1726 .arg(week).toLatin1(), true));
1727#endif
1728 return false;
1729 }
1730 eph._TOEweek = week;
1731 GETBITS(eph._IODnav, 10)
1732 GETBITS(i, 8)
1733 eph._SISA = accuracyFromIndex(i, eph.system());
1734 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1735 GETBITSFACTOR(i, 14, 60)
1736 if (i < 0 || i > 604740) {
1737#ifdef BNC_DEBUG_BCE
1738 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1739 .arg(_staID)
1740 .arg(mnum,4)
1741 .arg(eph._prn.toString().c_str())
1742 .arg(i).toLatin1(), true));
1743#endif
1744 return false;
1745 }
1746 eph._TOC.set(1024 + eph._TOEweek, i);// Period #2 = + 1 x 1024 (has to be determined)
1747 GETFLOATSIGN(eph._clock_driftrate, 6, 1.0 / (double )(1 << 30) / (double )(1 << 29))
1748 GETFLOATSIGN(eph._clock_drift, 21, 1.0 / (double )(1 << 30) / (double )(1 << 16))
1749 GETFLOATSIGN(eph._clock_bias, 31, 1.0 / (double )(1 << 30) / (double )(1 << 4))
1750 GETFLOATSIGN(eph._Crs, 16, 1.0 / (double )(1 << 5))
1751 GETFLOATSIGN(eph._Delta_n, 16, R2R_PI/(double)(1<<30)/(double)(1<<13))
1752 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1753 GETFLOATSIGN(eph._Cuc, 16, 1.0 / (double )(1 << 29))
1754 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1755 GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
1756 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1757 GETBITSFACTOR(eph._TOEsec, 14, 60)
1758 if (i < 0 || i > 604740) {
1759#ifdef BNC_DEBUG_BCE
1760 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1761 .arg(_staID)
1762 .arg(mnum,4)
1763 .arg(eph._prn.toString().c_str())
1764 .arg(i).toLatin1(), true));
1765#endif
1766 return false;
1767 }
1768 /* FIXME: overwrite value, copied from old code */
1769 //eph._TOEsec = eph._TOC.gpssec();
1770 GETFLOATSIGN(eph._Cic, 16, 1.0 / (double )(1 << 29))
1771 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1772 GETFLOATSIGN(eph._Cis, 16, 1.0 / (double )(1 << 29))
1773 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1774 GETFLOATSIGN(eph._Crc, 16, 1.0 / (double )(1 << 5))
1775 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1776 GETFLOATSIGN(eph._OMEGADOT, 24, R2R_PI/(double)(1<<30)/(double)(1<<13))
1777 GETFLOATSIGN(eph._BGD_1_5A, 10, 1.0 / (double )(1 << 30) / (double )(1 << 2))
1778 if (eph._inav) {
1779 eph._type = t_eph::INAV;
1780 /* set unused F/NAV values */
1781 eph._E5a_HS = 0.0;
1782 eph._E5a_DataInvalid = false;
1783
1784 GETFLOATSIGN(eph._BGD_1_5B, 10, 1.0 / (double )(1 << 30) / (double )(1 << 2))
1785 GETBITS(eph._E5b_HS, 2)
1786 GETBITS(eph._E5b_DataInvalid, 1)
1787 GETBITS(eph._E1B_HS, 2)
1788 GETBITS(eph._E1B_DataInvalid, 1)
1789 if (eph._E5b_HS != eph._E1B_HS) {
1790#ifdef BNC_DEBUG_BCE
1791 emit(newMessage(QString("%1: Block %2 (%3) SHS E5b %4 E1B %5: inconsistent health!")
1792 .arg(_staID).arg(1046,4).arg(eph._prn.toString().c_str())
1793 .arg(eph._E5b_HS).arg(eph._E1B_HS).toLatin1(), true));
1794#endif
1795 return false;
1796 }
1797 if ((eph._BGD_1_5A == 0.0 && fabs(eph._BGD_1_5B) > 1e-9) ||
1798 (eph._BGD_1_5B == 0.0 && fabs(eph._BGD_1_5A) > 1e-9)) {
1799#ifdef BNC_DEBUG_BCE
1800 emit(newMessage(QString("%1: Block %2 (%3) BGD_1_5a = %4 BGD_1_5b = %5: inconsistent BGD!")
1801 .arg(_staID).arg(1046,4).arg(eph._prn.toString().c_str())
1802 .arg(eph._BGD_1_5A,10,'E',3).arg(eph._BGD_1_5B,10,'E',3).toLatin1(), true));
1803#endif
1804 return false;
1805 }
1806 }
1807 else {
1808 eph._type = t_eph::FNAV;
1809 /* set unused I/NAV values */
1810 eph._BGD_1_5B = 0.0;
1811 eph._E5b_HS = 0.0;
1812 eph._E1B_HS = 0.0;
1813 eph._E1B_DataInvalid = false;
1814 eph._E5b_DataInvalid = false;
1815
1816 GETBITS(eph._E5a_HS, 2)
1817 GETBITS(eph._E5a_DataInvalid, 1)
1818 }
1819 eph._TOT = 0.9999e9;
1820
1821 if (eph._sqrt_A < 1000.0) {
1822#ifdef BNC_DEBUG_BCE
1823 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1824 .arg(_staID).arg(eph._inav? 1046 : 1045,4).arg(eph._prn.toString().c_str())
1825 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1826#endif
1827 return false;
1828 }
1829
1830 emit newGalileoEph(eph);
1831 decoded = true;
1832 }
1833 return decoded;
1834}
1835
1836//
1837////////////////////////////////////////////////////////////////////////////
1838bool RTCM3Decoder::DecodeBDSEphemeris(unsigned char* data, int size) {
1839 bool decoded = false;
1840 const double iMaxGEO = 10.0 / 180.0 * M_PI;
1841
1842 if (size == 70) {
1843 t_ephBDS eph;
1844 int i, week;
1845 uint64_t numbits = 0, bitfield = 0;
1846
1847 data += 3; /* header */
1848 size -= 6; /* header + crc */
1849 SKIPBITS(12)
1850
1851 eph._receptDateTime = currentDateAndTimeGPS();
1852 eph._receptStaID = _staID;
1853
1854 GETBITS(i, 6)
1855 if (i < 1 || i > 63 ) {
1856#ifdef BNC_DEBUG_BCE
1857 emit(newMessage(QString("%1: Block %2 (C) PRN# is out of range: %3!")
1858 .arg(_staID)
1859 .arg(1042,4)
1860 .arg(i).toLatin1(), true));
1861#endif
1862 return false;
1863 }
1864 eph._prn.set('C', i);
1865
1866 GETBITS(week, 13)
1867 if (week < 0 || week > 8191) {
1868#ifdef BNC_DEBUG_BCE
1869 emit(newMessage(QString("%1: Block %2 (%3) WEEK # is out of range: %4!")
1870 .arg(_staID)
1871 .arg(1042,4)
1872 .arg(eph._prn.toString().c_str())
1873 .arg(week).toLatin1(), true));
1874#endif
1875 return false;
1876 }
1877 eph._BDTweek = week;
1878 GETBITS(i, 4)
1879 eph._ura = accuracyFromIndex(i, eph.system());
1880 GETFLOATSIGN(eph._IDOT, 14, R2R_PI/(double)(1<<30)/(double)(1<<13))
1881 GETBITS(eph._AODE, 5)
1882 GETBITS(i, 17)
1883 i <<= 3;
1884 if (i < 0 || i > 604792) {
1885#ifdef BNC_DEBUG_BCE
1886 emit(newMessage(QString("%1: Block %2 (%3) TOC is out of range: %4!")
1887 .arg(_staID)
1888 .arg(1042,4)
1889 .arg(eph._prn.toString().c_str())
1890 .arg(i).toLatin1(), true));
1891#endif
1892 return false;
1893 }
1894 eph._TOC.setBDS(eph._BDTweek, i);
1895 GETFLOATSIGN(eph._clock_driftrate, 11, 1.0 / (double )(1 << 30) / (double )(1 << 30) / (double )(1 << 6))
1896 GETFLOATSIGN(eph._clock_drift, 22, 1.0 / (double )(1 << 30) / (double )(1 << 20))
1897 GETFLOATSIGN(eph._clock_bias, 24, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1898 GETBITS(eph._AODC, 5)
1899 GETFLOATSIGN(eph._Crs, 18, 1.0 / (double )(1 << 6))
1900 GETFLOATSIGN(eph._Delta_n, 16, R2R_PI/(double)(1<<30)/(double)(1<<13))
1901 GETFLOATSIGN(eph._M0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1902 GETFLOATSIGN(eph._Cuc, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1903 GETFLOAT(eph._e, 32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
1904 GETFLOATSIGN(eph._Cus, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1905 GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
1906 if (eph._sqrt_A < 1000.0) {
1907#ifdef BNC_DEBUG_BCE
1908 emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
1909 .arg(_staID).arg(1042,4).arg(eph._prn.toString().c_str())
1910 .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
1911#endif
1912 return false;
1913 }
1914 GETBITS(i, 17)
1915 i <<= 3;
1916 if (i < 0 || i > 604792) {
1917#ifdef BNC_DEBUG_BCE
1918 emit(newMessage(QString("%1: Block %2 (%3) TOE is out of range: %4!")
1919 .arg(_staID)
1920 .arg(1042,4)
1921 .arg(eph._prn.toString().c_str())
1922 .arg(i).toLatin1(), true));
1923#endif
1924 return false;
1925 }
1926 eph._TOEsec = i;
1927 eph._TOE.setBDS(eph._BDTweek, i);
1928 GETFLOATSIGN(eph._Cic, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1929 GETFLOATSIGN(eph._OMEGA0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1930 GETFLOATSIGN(eph._Cis, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
1931 GETFLOATSIGN(eph._i0, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1932 GETFLOATSIGN(eph._Crc, 18, 1.0 / (double )(1 << 6))
1933 GETFLOATSIGN(eph._omega, 32, R2R_PI/(double)(1<<30)/(double)(1<<1))
1934 GETFLOATSIGN(eph._OMEGADOT, 24, R2R_PI/(double)(1<<30)/(double)(1<<13))
1935 GETFLOATSIGN(eph._TGD1, 10, 0.0000000001)
1936 GETFLOATSIGN(eph._TGD2, 10, 0.0000000001)
1937 GETBITS(eph._SatH1, 1)
1938
1939 eph._TOT = 0.9999E9;
1940 if (eph._i0 > iMaxGEO) {
1941 eph._type = t_eph::D1;
1942 }
1943 else {
1944 eph._type = t_eph::D2;
1945 }
1946 eph._prn.setFlag(eph._type);
1947
1948 emit newBDSEph(eph);
1949 decoded = true;
1950 }
1951 return decoded;
1952}
1953
1954//
1955////////////////////////////////////////////////////////////////////////////
1956bool RTCM3Decoder::DecodeAntennaReceiver(unsigned char* data, int size) {
1957 char *antenna;
1958 char *antserialnum;
1959 char *receiver;
1960 char *recfirmware;
1961 char *recserialnum;
1962 int type;
1963 int antsernum = -1;
1964 int antnum = -1;
1965 int recnum = -1;
1966 int recsernum = -1;
1967 int recfirnum = -1;
1968 uint64_t numbits = 0, bitfield = 0;
1969
1970 data += 3; /* header*/
1971 size -= 6; /* header + crc */
1972
1973 GETBITS(type, 12)
1974 SKIPBITS(12) /* reference station ID */
1975 GETSTRING(antnum, antenna)
1976 if ((antnum > -1 && antnum < 265) &&
1977 (_antType.empty() || strncmp(_antType.back().descriptor, antenna, recnum) != 0)) {
1978 _antType.push_back(t_antInfo());
1979 memcpy(_antType.back().descriptor, antenna, antnum);
1980 _antType.back().descriptor[antnum] = 0;
1981 }
1982 SKIPBITS(8) /* antenna setup ID */
1983 if (type == 1008 || type == 1033 ) {
1984 GETSTRING(antsernum, antserialnum)
1985 if ((antsernum > -1 && antsernum < 265)) {
1986 memcpy(_antType.back().serialnumber, antserialnum, antsernum);
1987 _antType.back().serialnumber[antsernum] = 0;
1988 }
1989 }
1990
1991 if (type == 1033) {
1992 GETSTRING(recnum, receiver)
1993 GETSTRING(recfirnum, recfirmware)
1994 GETSTRING(recsernum, recserialnum)
1995 if ((recnum > -1 && recnum < 265) &&
1996 (_recType.empty() || strncmp(_recType.back().descriptor, receiver, recnum) != 0)) {
1997 _recType.push_back(t_recInfo());
1998 memcpy(_recType.back().descriptor, receiver, recnum);
1999 _recType.back().descriptor[recnum] = 0;
2000 if (recfirnum > -1 && recfirnum < 265) {
2001 memcpy(_recType.back().firmware, recfirmware, recfirnum);
2002 _recType.back().firmware[recfirnum] = 0;
2003 }
2004 if (recsernum > -1 && recsernum < 265) {
2005 memcpy(_recType.back().serialnumber, recserialnum, recsernum);
2006 _recType.back().serialnumber[recsernum] = 0;
2007 }
2008 }
2009 }
2010 return true;
2011}
2012
2013//
2014////////////////////////////////////////////////////////////////////////////
2015bool RTCM3Decoder::DecodeAntennaPosition(unsigned char* data, int size) {
2016 int type;
2017 uint64_t numbits = 0, bitfield = 0;
2018 double x, y, z;
2019
2020 data += 3; /* header */
2021 size -= 6; /* header + crc */
2022
2023 GETBITS(type, 12)
2024 _antList.push_back(t_antRefPoint());
2025 _antList.back().type = t_antRefPoint::ARP;
2026 SKIPBITS(22)
2027 GETBITSSIGN(x, 38)
2028 _antList.back().xx = x * 1e-4;
2029 SKIPBITS(2)
2030 GETBITSSIGN(y, 38)
2031 _antList.back().yy = y * 1e-4;
2032 SKIPBITS(2)
2033 GETBITSSIGN(z, 38)
2034 _antList.back().zz = z * 1e-4;
2035 if (type == 1006) {
2036 double h;
2037 GETBITS(h, 16)
2038 _antList.back().height = h * 1e-4;
2039 _antList.back().height_f = true;
2040 }
2041 _antList.back().message = type;
2042
2043 return true;
2044}
2045
2046//
2047////////////////////////////////////////////////////////////////////////////
2048bool RTCM3Decoder::DecodeServiceCRS(unsigned char* data, int size) {
2049 t_serviceCrs serviceCrs;
2050 int servicecrsnum = -1;
2051
2052 uint64_t numbits = 0, bitfield = 0;
2053
2054 data += 3; // header
2055 size -= 6; // header + crc
2056
2057 SKIPBITS(12) // Message Number
2058
2059 GETBITS(servicecrsnum, 5)
2060 if (servicecrsnum > -1 && servicecrsnum <= 31) {
2061 for(int i = 0; i < servicecrsnum; i++) {
2062 GETBITS(serviceCrs._name[i], 8);
2063 }
2064 serviceCrs._name[servicecrsnum] = 0;
2065 }
2066 if (_serviceCrs.empty() ||
2067 (strncmp(_serviceCrs.back()._name, serviceCrs._name, servicecrsnum) != 0)) {
2068 _serviceCrs.push_back(serviceCrs);
2069 GETFLOAT(_serviceCrs.back()._CE, 16, 1/100.0)
2070 _serviceCrs.back().setCoordinateEpochFromCE();
2071 //_serviceCrs.back().print();
2072 }
2073 return true;
2074
2075}
2076
2077//
2078////////////////////////////////////////////////////////////////////////////
2079bool RTCM3Decoder::DecodeRTCMCRS(unsigned char* data, int size) {
2080
2081 t_rtcmCrs rtcmCrs;
2082 int rtcmcrsnum = -1;
2083
2084 uint64_t numbits = 0, bitfield = 0;
2085
2086 data += 3; // header
2087 size -= 6; // header + crc
2088
2089 SKIPBITS(12) // Message Number
2090 GETBITS(rtcmcrsnum, 5)
2091 if (rtcmcrsnum > -1 && rtcmcrsnum <= 31) {
2092 for(int i = 0; i < rtcmcrsnum; i++) {
2093 GETBITS(rtcmCrs._name[i], 8);
2094 }
2095 rtcmCrs._name[rtcmcrsnum] = 0;
2096 }
2097 if (_rtcmCrs.empty() ||
2098 (strncmp(_rtcmCrs.back()._name, rtcmCrs._name, rtcmcrsnum) != 0)) {
2099 _rtcmCrs.push_back(rtcmCrs);
2100
2101 GETBITS(_rtcmCrs.back()._anchor, 1)
2102 GETBITS(_rtcmCrs.back()._plateNumber, 5)
2103
2104 int dblinksnum = 0;
2105 GETBITS(dblinksnum, 3)
2106 for (int i = 0; i < dblinksnum; i++) {
2107 int dblinknum = -1;
2108 char dblinkname[31];
2109 GETBITS(dblinknum, 5)
2110 if (dblinknum > -1 && dblinknum <= 31) {
2111 for(int i = 0; i < dblinknum; i++) {
2112 GETBITS(dblinkname[i], 8);
2113 }
2114 dblinkname[dblinknum] = 0;
2115 _rtcmCrs.back()._databaseLinks.append(QString("%1").arg(dblinkname));
2116 }
2117 }
2118 //_rtcmCrs.back().print();
2119 }
2120
2121 return true;
2122}
2123
2124
2125////////////////////////////////////////////////////////////////////////////
2126bool RTCM3Decoder::DecodeHelmertTrafoParameters(unsigned char* data, int size) {
2127
2128 t_helmertPar helmertPar;
2129 int sourcenum = -1;
2130 int targetnum = -1;
2131
2132 uint64_t numbits = 0, bitfield = 0;
2133 data += 3; // header
2134 size -= 6; // header + crc
2135
2136 SKIPBITS(12) // Message Number
2137 GETBITS(sourcenum, 5)
2138 if (sourcenum > -1 && sourcenum <= 31) {
2139 for(int i = 0; i < sourcenum; i++) {
2140 GETBITS(helmertPar._sourceName[i], 8);
2141 }
2142 helmertPar._sourceName[sourcenum] = 0;
2143 }
2144 GETBITS(targetnum, 5)
2145 if (targetnum > -1 && targetnum <= 31) {
2146 for(int i = 0; i < targetnum; i++) {
2147 GETBITS(helmertPar._targetName[i], 8);
2148 }
2149 helmertPar._targetName[targetnum] = 0;
2150 }
2151 GETBITS(helmertPar._sysIdentNum, 8)
2152 GETBITS(helmertPar._utilTrafoMessageIndicator, 10)
2153 GETBITS(helmertPar._mjd, 16)
2154 helmertPar._mjd += 44244;
2155
2156 // delete old parameter entries if available
2157 if (!_helmertPar.empty()) {
2158 QList<t_helmertPar>::iterator it = _helmertPar.begin();
2159 while (it != _helmertPar.end()) {
2160 (helmertPar == *it) ? it = _helmertPar.erase(it) : ++it;
2161 }
2162 }
2163 _helmertPar.push_back(helmertPar);
2164
2165 GETFLOATSIGN(_helmertPar.back()._dx, 23, 1/1000.0)
2166 GETFLOATSIGN(_helmertPar.back()._dy, 23, 1/1000.0)
2167 GETFLOATSIGN(_helmertPar.back()._dz, 23, 1/1000.0)
2168
2169 GETFLOATSIGN(_helmertPar.back()._ox, 32, 1/50000.0)
2170 GETFLOATSIGN(_helmertPar.back()._oy, 32, 1/50000.0)
2171 GETFLOATSIGN(_helmertPar.back()._oz, 32, 1/50000.0)
2172
2173 GETFLOATSIGN(_helmertPar.back()._sc, 25, 1/100000.0)
2174
2175 GETFLOATSIGN(_helmertPar.back()._dxr, 17, 1/50000.0)
2176 GETFLOATSIGN(_helmertPar.back()._dyr, 17, 1/50000.0)
2177 GETFLOATSIGN(_helmertPar.back()._dzr, 17, 1/50000.0)
2178
2179 GETFLOATSIGN(_helmertPar.back()._oxr, 17, 1/2500000.0)
2180 GETFLOATSIGN(_helmertPar.back()._oyr, 17, 1/2500000.0)
2181 GETFLOATSIGN(_helmertPar.back()._ozr, 17, 1/2500000.0)
2182
2183 GETFLOATSIGN(_helmertPar.back()._scr, 14, 1/5000000.0)
2184
2185 //_helmertPar.back().print();
2186
2187 return true;
2188}
2189
2190
2191//
2192////////////////////////////////////////////////////////////////////////////
2193t_irc RTCM3Decoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
2194 bool decoded = false;
2195
2196 errmsg.clear();
2197
2198 while (bufLen && _MessageSize < sizeof(_Message)) {
2199 int l = sizeof(_Message) - _MessageSize;
2200 if (l > bufLen)
2201 l = bufLen;
2202 memcpy(_Message + _MessageSize, buffer, l);
2203 _MessageSize += l;
2204 bufLen -= l;
2205 buffer += l;
2206 int id;
2207 while ((id = GetMessage())) {
2208 /* reset station ID for file loading as it can change */
2209 if (_rawFile)
2210 _staID = _rawFile->staID();
2211 /* store the id into the list of loaded blocks */
2212 _typeList.push_back(id);
2213
2214 /* SSR I+II data handled in another function, already pass the
2215 * extracted data block. That does no harm, as it anyway skip everything
2216 * else. */
2217 if ((id >= 1057 && id <= 1068) ||
2218 (id >= 1240 && id <= 1270) ||
2219 (id == 4076)) {
2220 if (!_coDecoders.contains(_staID.toLatin1())) {
2221 _coDecoders[_staID.toLatin1()] = new RTCM3coDecoder(_staID);
2222 if (id == 4076) {
2223 _coDecoders[_staID.toLatin1()]->initSsrFormatType(RTCM3coDecoder::IGSssr);
2224 }
2225 else {
2226 _coDecoders[_staID.toLatin1()]->initSsrFormatType(RTCM3coDecoder::RTCMssr);
2227 }
2228 }
2229 RTCM3coDecoder* coDecoder = _coDecoders[_staID.toLatin1()];
2230 if (coDecoder->Decode(reinterpret_cast<char *>(_Message), _BlockSize, errmsg) == success) {
2231 decoded = true;
2232 }
2233 }
2234 else if (id >= 1070 && id <= 1237) { /* MSM */
2235 if (DecodeRTCM3MSM(_Message, _BlockSize))
2236 decoded = true;
2237 }
2238 else {
2239 switch (id) {
2240 case 1001:
2241 case 1003:
2242#ifdef BNC_DEBUG_OBS
2243 emit(newMessage(QString("%1: Block %2 contain partial data! Ignored!")
2244 .arg(_staID).arg(id).toLatin1(), true));
2245#endif
2246 break; /* no use decoding partial data ATM, remove break when data can be used */
2247 case 1002:
2248 case 1004:
2249 if (DecodeRTCM3GPS(_Message, _BlockSize))
2250 decoded = true;
2251 break;
2252 case 1009:
2253 case 1011:
2254#ifdef BNC_DEBUG_OBS
2255 emit(newMessage(QString("%1: Block %2 contain partial data! Ignored!")
2256 .arg(_staID).arg(id).toLatin1(), true));
2257#endif
2258 break; /* no use decoding partial data ATM, remove break when data can be used */
2259 case 1010:
2260 case 1012:
2261 if (DecodeRTCM3GLONASS(_Message, _BlockSize))
2262 decoded = true;
2263 break;
2264 case 1019:
2265 if (DecodeGPSEphemeris(_Message, _BlockSize))
2266 decoded = true;
2267 break;
2268 case 1020:
2269 if (DecodeGLONASSEphemeris(_Message, _BlockSize))
2270 decoded = true;
2271 break;
2272 case 1043:
2273 if (DecodeSBASEphemeris(_Message, _BlockSize))
2274 decoded = true;
2275 break;
2276 case 1044:
2277 if (DecodeQZSSEphemeris(_Message, _BlockSize))
2278 decoded = true;
2279 break;
2280 case 1041:
2281 if (DecodeNavICEphemeris(_Message, _BlockSize))
2282 decoded = true;
2283 break;
2284 case 1045:
2285 case 1046:
2286 if (DecodeGalileoEphemeris(_Message, _BlockSize))
2287 decoded = true;
2288 break;
2289 case 1042:
2290 if (DecodeBDSEphemeris(_Message, _BlockSize))
2291 decoded = true;
2292 break;
2293 case 1007:
2294 case 1008:
2295 case 1033:
2296 DecodeAntennaReceiver(_Message, _BlockSize);
2297 break;
2298 case 1005:
2299 case 1006:
2300 DecodeAntennaPosition(_Message, _BlockSize);
2301 break;
2302 case 1300:
2303 DecodeServiceCRS(_Message, _BlockSize);
2304 break;
2305 case 1301:
2306 DecodeHelmertTrafoParameters(_Message, _BlockSize);
2307 break;
2308 case 1302:
2309 case 35:
2310 DecodeRTCMCRS(_Message, _BlockSize);
2311 break;
2312 }
2313 }
2314 }
2315 }
2316 /*
2317 for (int ii = 0; ii < _helmertParList.size(); ii++) {
2318 _helmertParList[ii].print();
2319 }*/
2320 return decoded ? success : failure;
2321}
2322
2323//
2324////////////////////////////////////////////////////////////////////////////
2325uint32_t RTCM3Decoder::CRC24(long size, const unsigned char *buf) {
2326 uint32_t crc = 0;
2327 int ii;
2328 while (size--) {
2329 crc ^= (*buf++) << (16);
2330 for (ii = 0; ii < 8; ii++) {
2331 crc <<= 1;
2332 if (crc & 0x1000000)
2333 crc ^= 0x01864cfb;
2334 }
2335 }
2336 return crc;
2337}
2338
2339//
2340////////////////////////////////////////////////////////////////////////////
2341int RTCM3Decoder::GetMessage(void) {
2342 unsigned char *m, *e;
2343 int i;
2344
2345 m = _Message + _SkipBytes;
2346 e = _Message + _MessageSize;
2347 _NeedBytes = _SkipBytes = 0;
2348 while (e - m >= 3) {
2349 if (m[0] == 0xD3) {
2350 _BlockSize = ((m[1] & 3) << 8) | m[2];
2351 if (e - m >= static_cast<int>(_BlockSize + 6)) {
2352 if (static_cast<uint32_t>((m[3 + _BlockSize] << 16)
2353 | (m[3 + _BlockSize + 1] << 8)
2354 | (m[3 + _BlockSize + 2])) == CRC24(_BlockSize + 3, m)) {
2355 _BlockSize += 6;
2356 _SkipBytes = _BlockSize;
2357 break;
2358 }
2359 else
2360 ++m;
2361 }
2362 else {
2363 _NeedBytes = _BlockSize;
2364 break;
2365 }
2366 }
2367 else
2368 ++m;
2369 }
2370 if (e - m < 3)
2371 _NeedBytes = 3;
2372
2373 /* copy buffer to front */
2374 i = m - _Message;
2375 if (i && m < e)
2376 memmove(_Message, m, static_cast<size_t>(_MessageSize - i));
2377 _MessageSize -= i;
2378
2379 return !_NeedBytes ? ((_Message[3] << 4) | (_Message[4] >> 4)) : 0;
2380}
2381
2382// Time of Corrections
2383//////////////////////////////////////////////////////////////////////////////
2384int RTCM3Decoder::corrGPSEpochTime() const {
2385 return
2386 _coDecoders.size() > 0 ?
2387 _coDecoders.begin().value()->corrGPSEpochTime() : -1;
2388}
2389
2390
2391
2392
Note: See TracBrowser for help on using the repository browser.