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

Last change on this file since 11047 was 11047, checked in by stuerze, 3 days ago

updates regarding RTCM-SSR and some ovarall improvements

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