source: ntrip/trunk/BNC/bncapp.cpp@ 3971

Last change on this file since 3971 was 3734, checked in by stoecker, 13 years ago

fix crash with Galileo ephemeris available, some other valgrind fixes as well

File size: 26.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://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: bncApp
30 *
31 * Purpose: This class implements the main application
32 *
33 * Author: L. Mervart
34 *
35 * Created: 29-Aug-2006
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42#include <QMessageBox>
43#include <cmath>
44
45#include "bncapp.h"
46#include "bncutils.h"
47#include "bncrinex.h"
48#include "bncsettings.h"
49#include "bncversion.h"
50
51#ifdef USE_COMBINATION
52#include "combination/bnccomb.h"
53#endif
54
55using namespace std;
56
57// Constructor
58////////////////////////////////////////////////////////////////////////////
59bncApp::bncApp(int& argc, char* argv[], bool GUIenabled) :
60 QApplication(argc, argv, GUIenabled) {
61
62 _logFileFlag = 0;
63 _logFile = 0;
64 _logStream = 0;
65 _caster = 0;
66 _rawFile = 0;
67#ifdef USE_COMBINATION
68 _bncComb = 0;
69#endif
70
71 // Lists of Ephemeris
72 // ------------------
73 for (int ii = PRN_GPS_START; ii <= PRN_GPS_END; ii++) {
74 _gpsEph[ii-PRN_GPS_START] = 0;
75 }
76 for (int ii = PRN_GLONASS_START; ii <= PRN_GLONASS_END; ii++) {
77 _glonassEph[ii-PRN_GLONASS_START] = 0;
78 }
79 for (int ii = PRN_GALILEO_START; ii <= PRN_GALILEO_END; ii++) {
80 _galileoEph[ii-PRN_GALILEO_START] = 0;
81 }
82
83 // Eph file(s)
84 // -----------
85 _rinexVers = 0;
86 _ephFileGPS = 0;
87 _ephStreamGPS = 0;
88 _ephFileGlonass = 0;
89 _ephStreamGlonass = 0;
90 _ephFileGalileo = 0;
91 _ephStreamGalileo = 0;
92
93 _port = 0;
94 _server = 0;
95 _sockets = 0;
96
97 _portCorr = 0;
98 _serverCorr = 0;
99 _socketsCorr = 0;
100
101 _pgmName = QString(BNCPGMNAME).leftJustified(20, ' ', true);
102#ifdef WIN32
103 _userName = QString("${USERNAME}");
104#else
105 _userName = QString("${USER}");
106#endif
107 expandEnvVar(_userName);
108 _userName = _userName.leftJustified(20, ' ', true);
109
110 _lastDumpCoSec = 0;
111
112 _corrs = new QMultiMap<long, QString>;
113
114 _currentDateAndTimeGPS = 0;
115
116 for (int ii = 0; ii < PRN_GLONASS_NUM; ++ii) {
117 _GLOFreq[ii] = 0;
118 }
119
120 _bncPPPclient = 0;
121}
122
123// Destructor
124////////////////////////////////////////////////////////////////////////////
125bncApp::~bncApp() {
126 delete _logStream;
127 delete _logFile;
128 delete _ephStreamGPS;
129 delete _ephFileGPS;
130 delete _server;
131 delete _sockets;
132 delete _serverCorr;
133 delete _socketsCorr;
134 if (_rinexVers == 2) {
135 delete _ephStreamGlonass;
136 delete _ephFileGlonass;
137 }
138 for (int ii = PRN_GPS_START; ii <= PRN_GPS_END; ii++) {
139 delete _gpsEph[ii-PRN_GPS_START];
140 }
141 for (int ii = PRN_GLONASS_START; ii <= PRN_GLONASS_END; ii++) {
142 delete _glonassEph[ii-PRN_GLONASS_START];
143 }
144 for (int ii = PRN_GALILEO_START; ii <= PRN_GALILEO_END; ii++) {
145 delete _galileoEph[ii-PRN_GALILEO_START];
146 }
147
148 delete _corrs;
149
150 delete _currentDateAndTimeGPS;
151
152 delete _rawFile;
153
154#ifdef USE_COMBINATION
155 delete _bncComb;
156#endif
157}
158
159// Write a Program Message
160////////////////////////////////////////////////////////////////////////////
161void bncApp::slotMessage(QByteArray msg, bool showOnScreen) {
162
163 QMutexLocker locker(&_mutexMessage);
164
165 messagePrivate(msg);
166 emit newMessage(msg, showOnScreen);
167}
168
169// Write a Program Message (private, no lock)
170////////////////////////////////////////////////////////////////////////////
171void bncApp::messagePrivate(const QByteArray& msg) {
172
173 // First time resolve the log file name
174 // ------------------------------------
175 QDate currDate = currentDateAndTimeGPS().date();
176 if (_logFileFlag == 0 || _fileDate != currDate) {
177 delete _logStream; _logStream = 0;
178 delete _logFile; _logFile = 0;
179 _logFileFlag = 1;
180 bncSettings settings;
181 QString logFileName = settings.value("logFile").toString();
182 if ( !logFileName.isEmpty() ) {
183 expandEnvVar(logFileName);
184 _logFile = new QFile(logFileName + "_" +
185 currDate.toString("yyMMdd").toAscii().data());
186 _fileDate = currDate;
187 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
188 _logFile->open(QIODevice::WriteOnly | QIODevice::Append);
189 }
190 else {
191 _logFile->open(QIODevice::WriteOnly);
192 }
193 _logStream = new QTextStream();
194 _logStream->setDevice(_logFile);
195 }
196 }
197
198 if (_logStream) {
199 QByteArray msgLocal = msg;
200 if (msg.indexOf('\n') == 0) {
201 *_logStream << endl;
202 msgLocal = msg.mid(1);
203 }
204 *_logStream << currentDateAndTimeGPS().toString("yy-MM-dd hh:mm:ss ").toAscii().data();
205 *_logStream << msgLocal.data() << endl;
206 _logStream->flush();
207 _logFile->flush();
208 }
209}
210
211// New GPS Ephemeris
212////////////////////////////////////////////////////////////////////////////
213void bncApp::slotNewGPSEph(gpsephemeris* gpseph) {
214
215 QMutexLocker locker(&_mutex);
216
217 gpsephemeris copy_gpseph = *gpseph;
218 emit newEphGPS(copy_gpseph);
219
220 printEphHeader();
221
222 gpsephemeris** ee = &_gpsEph[gpseph->satellite-1];
223
224 if ( *ee == 0 ||
225 gpseph->GPSweek > (*ee)->GPSweek ||
226 (gpseph->GPSweek == (*ee)->GPSweek && gpseph->TOC > (*ee)->TOC) ) {
227 delete *ee;
228 *ee = gpseph;
229 printGPSEph(gpseph, true);
230 }
231 else {
232 printGPSEph(gpseph, false);
233 delete gpseph;
234 }
235}
236
237// New Glonass Ephemeris
238////////////////////////////////////////////////////////////////////////////
239void bncApp::slotNewGlonassEph(glonassephemeris* glonasseph) {
240
241 QMutexLocker locker(&_mutex);
242
243 glonassephemeris copy_glonasseph = *glonasseph;
244 emit newEphGlonass(copy_glonasseph);
245
246 printEphHeader();
247
248 glonassephemeris** ee = &_glonassEph[glonasseph->almanac_number-1];
249
250 int wwOld, towOld, wwNew, towNew;
251 if (*ee != 0) {
252 wwOld = (*ee)->GPSWeek;
253 towOld = (*ee)->GPSTOW;
254 updatetime(&wwOld, &towOld, (*ee)->tb*1000, 0); // Moscow -> GPS
255
256 wwNew = glonasseph->GPSWeek;
257 towNew = glonasseph->GPSTOW;
258 updatetime(&wwNew, &towNew, glonasseph->tb*1000, 0); // Moscow -> GPS
259 }
260
261 if ( *ee == 0 ||
262 wwNew > wwOld ||
263 (wwNew == wwOld && towNew > towOld) ) {
264 delete *ee;
265 *ee = glonasseph;
266 printGlonassEph(glonasseph, true);
267 }
268 else {
269 printGlonassEph(glonasseph, false);
270 delete glonasseph;
271 }
272}
273
274// New Galileo Ephemeris
275////////////////////////////////////////////////////////////////////////////
276void bncApp::slotNewGalileoEph(galileoephemeris* galileoeph) {
277
278 QMutexLocker locker(&_mutex);
279
280 galileoephemeris copy_galileoeph = *galileoeph;
281 emit newEphGalileo(copy_galileoeph);
282
283 printEphHeader();
284
285 int galIndex = galileoeph->satellite;
286 /* GIOVE */
287 if(galIndex == 51) galIndex = 1;
288 else if(galIndex == 52) galIndex = 16;
289 if (galIndex < 0 || galIndex > PRN_GALILEO_END - PRN_GALILEO_START) {
290 emit( newMessage("Wrong Galileo Satellite Number", true) );
291 exit(1);
292 }
293
294 galileoephemeris** ee = &_galileoEph[galIndex];
295
296 if ( *ee == 0 ||
297 galileoeph->Week > (*ee)->Week ||
298 (galileoeph->Week == (*ee)->Week && galileoeph->TOC > (*ee)->TOC) ) {
299 delete *ee;
300 *ee = galileoeph;
301 printGalileoEph(galileoeph, true);
302 }
303 else {
304 printGalileoEph(galileoeph, false);
305 delete galileoeph;
306 }
307}
308
309// Print Header of the output File(s)
310////////////////////////////////////////////////////////////////////////////
311void bncApp::printEphHeader() {
312
313 bncSettings settings;
314
315 // Initialization
316 // --------------
317 if (_rinexVers == 0) {
318
319 if ( Qt::CheckState(settings.value("ephV3").toInt()) == Qt::Checked) {
320 _rinexVers = 3;
321 }
322 else {
323 _rinexVers = 2;
324 }
325
326 _ephPath = settings.value("ephPath").toString();
327
328 if ( !_ephPath.isEmpty() ) {
329 if ( _ephPath[_ephPath.length()-1] != QDir::separator() ) {
330 _ephPath += QDir::separator();
331 }
332 expandEnvVar(_ephPath);
333 }
334 }
335
336 // (Re-)Open output File(s)
337 // ------------------------
338 if (!_ephPath.isEmpty()) {
339
340 QDateTime datTim = currentDateAndTimeGPS();
341
342 QString ephFileNameGPS = _ephPath + "BRDC" +
343 QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0'));
344
345 QString hlpStr = bncRinex::nextEpochStr(datTim,
346 settings.value("ephIntr").toString());
347
348 if (_rinexVers == 3) {
349 ephFileNameGPS += hlpStr + datTim.toString(".yyP");
350 }
351 else {
352 ephFileNameGPS += hlpStr + datTim.toString(".yyN");
353 }
354
355 if (_ephFileNameGPS == ephFileNameGPS) {
356 return;
357 }
358 else {
359 _ephFileNameGPS = ephFileNameGPS;
360 }
361
362 for (int ii = PRN_GPS_START; ii <= PRN_GPS_END; ii++) {
363 delete _gpsEph[ii-PRN_GPS_START];
364 _gpsEph[ii-PRN_GPS_START] = 0;
365 }
366 for (int ii = PRN_GLONASS_START; ii <= PRN_GLONASS_END; ii++) {
367 delete _glonassEph[ii-PRN_GLONASS_START];
368 _glonassEph[ii-PRN_GLONASS_START] = 0;
369 }
370 for (int ii = PRN_GALILEO_START; ii <= PRN_GALILEO_END; ii++) {
371 delete _galileoEph[ii-PRN_GALILEO_START];
372 _galileoEph[ii-PRN_GALILEO_START] = 0;
373 }
374
375 delete _ephStreamGPS;
376 delete _ephFileGPS;
377
378 QFlags<QIODevice::OpenModeFlag> appendFlagGPS;
379 QFlags<QIODevice::OpenModeFlag> appendFlagGlonass;
380 QFlags<QIODevice::OpenModeFlag> appendFlagGalileo;
381
382 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked &&
383 QFile::exists(ephFileNameGPS) ) {
384 appendFlagGPS = QIODevice::Append;
385 }
386
387 _ephFileGPS = new QFile(ephFileNameGPS);
388 _ephFileGPS->open(QIODevice::WriteOnly | appendFlagGPS);
389 _ephStreamGPS = new QTextStream();
390 _ephStreamGPS->setDevice(_ephFileGPS);
391
392 if (_rinexVers == 3) {
393 _ephFileGlonass = _ephFileGPS;
394 _ephStreamGlonass = _ephStreamGPS;
395 _ephFileGalileo = _ephFileGPS;
396 _ephStreamGalileo = _ephStreamGPS;
397 }
398 else if (_rinexVers == 2) {
399 QString ephFileNameGlonass = _ephPath + "BRDC" +
400 QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0')) +
401 hlpStr + datTim.toString(".yyG");
402
403 delete _ephStreamGlonass;
404 delete _ephFileGlonass;
405
406 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked &&
407 QFile::exists(ephFileNameGlonass) ) {
408 appendFlagGlonass = QIODevice::Append;
409 }
410
411 _ephFileGlonass = new QFile(ephFileNameGlonass);
412 _ephFileGlonass->open(QIODevice::WriteOnly | appendFlagGlonass);
413 _ephStreamGlonass = new QTextStream();
414 _ephStreamGlonass->setDevice(_ephFileGlonass);
415 }
416
417 // Header - RINEX Version 3
418 // ------------------------
419 if (_rinexVers == 3) {
420 if ( ! (appendFlagGPS & QIODevice::Append)) {
421 QString line;
422 line.sprintf(
423 "%9.2f%11sN: GNSS NAV DATA M: Mixed%12sRINEX VERSION / TYPE\n",
424 3.0, "", "");
425 *_ephStreamGPS << line;
426
427 QString hlp = currentDateAndTimeGPS().toString("yyyyMMdd hhmmss UTC").leftJustified(20, ' ', true);
428 *_ephStreamGPS << _pgmName.toAscii().data()
429 << _userName.toAscii().data()
430 << hlp.toAscii().data()
431 << "PGM / RUN BY / DATE" << endl;
432
433 line.sprintf("%60sEND OF HEADER\n", "");
434 *_ephStreamGPS << line;
435
436 _ephStreamGPS->flush();
437 }
438 }
439
440 // Headers - RINEX Version 2
441 // -------------------------
442 else if (_rinexVers == 2) {
443 if (! (appendFlagGPS & QIODevice::Append)) {
444 QString line;
445 line.sprintf(
446 "%9.2f%11sN: GPS NAV DATA%25sRINEX VERSION / TYPE\n", 2.10, "", "");
447 *_ephStreamGPS << line;
448
449 QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
450 *_ephStreamGPS << _pgmName.toAscii().data()
451 << _userName.toAscii().data()
452 << hlp.toAscii().data()
453 << "PGM / RUN BY / DATE" << endl;
454
455 line.sprintf("%60sEND OF HEADER\n", "");
456 *_ephStreamGPS << line;
457
458 _ephStreamGPS->flush();
459 }
460 if (! (appendFlagGlonass & QIODevice::Append)) {
461 QString line;
462 line.sprintf(
463 "%9.2f%11sG: GLONASS NAV DATA%21sRINEX VERSION / TYPE\n",2.10,"","");
464 *_ephStreamGlonass << line;
465
466 QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
467 *_ephStreamGlonass << _pgmName.toAscii().data()
468 << _userName.toAscii().data()
469 << hlp.toAscii().data()
470 << "PGM / RUN BY / DATE" << endl;
471
472 line.sprintf("%60sEND OF HEADER\n", "");
473 *_ephStreamGlonass << line;
474
475 _ephStreamGlonass->flush();
476 }
477 }
478 }
479}
480
481// Print One GPS Ephemeris
482////////////////////////////////////////////////////////////////////////////
483void bncApp::printGPSEph(gpsephemeris* ep, bool printFile) {
484
485 QString lineV2;
486 QString lineV3;
487
488 struct converttimeinfo cti;
489 converttime(&cti, ep->GPSweek, ep->TOC);
490
491 lineV3.sprintf("G%02d %04d %02d %02d %02d %02d %02d%19.12e%19.12e%19.12e\n",
492 ep->satellite, cti.year, cti.month, cti.day, cti.hour,
493 cti.minute, cti.second, ep->clock_bias, ep->clock_drift,
494 ep->clock_driftrate);
495
496 lineV2.sprintf("%02d %02d %02d %02d %02d %02d%5.1f%19.12e%19.12e%19.12e\n",
497 ep->satellite, cti.year%100, cti.month, cti.day, cti.hour,
498 cti.minute, (double) cti.second, ep->clock_bias,
499 ep->clock_drift, ep->clock_driftrate);
500
501 QString line;
502 QByteArray allLines;
503
504 QByteArray fmt;
505 QByteArray fmt2;
506 if (_rinexVers == 2) {
507 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
508 fmt2 = " %19.12e%19.12e\n";
509 }
510 else {
511 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
512 fmt2 = " %19.12e%19.12e\n";
513 }
514
515 line.sprintf(fmt.data(), (double)ep->IODE, ep->Crs, ep->Delta_n, ep->M0);
516 allLines += line;
517
518 line.sprintf(fmt.data(), ep->Cuc, ep->e, ep->Cus, ep->sqrt_A);
519 allLines += line;
520
521 line.sprintf(fmt.data(), (double) ep->TOE, ep->Cic, ep->OMEGA0, ep->Cis);
522 allLines += line;
523
524 line.sprintf(fmt.data(), ep->i0, ep->Crc, ep->omega, ep->OMEGADOT);
525 allLines += line;
526
527 double dd = 0;
528 unsigned long ii = ep->flags;
529 if(ii & GPSEPHF_L2CACODE)
530 dd += 2.0;
531 if(ii & GPSEPHF_L2PCODE)
532 dd += 1.0;
533 line.sprintf(fmt.data(), ep->IDOT, dd, (double) ep->GPSweek,
534 ii & GPSEPHF_L2PCODEDATA ? 1.0 : 0.0);
535 allLines += line;
536
537 if(ep->URAindex <= 6) /* URA index */
538 dd = ceil(10.0*pow(2.0, 1.0+((double)ep->URAindex)/2.0))/10.0;
539 else
540 dd = ceil(10.0*pow(2.0, ((double)ep->URAindex)/2.0))/10.0;
541 line.sprintf(fmt.data(), dd, ((double) ep->SVhealth), ep->TGD,
542 ((double) ep->IODC));
543 allLines += line;
544
545 line.sprintf(fmt2.data(), ((double)ep->TOW), 0.0);
546 allLines += line;
547
548 printOutput(printFile, _ephStreamGPS, lineV2, lineV3, allLines);
549}
550
551// Print One Glonass Ephemeris
552////////////////////////////////////////////////////////////////////////////
553void bncApp::printGlonassEph(glonassephemeris* ep, bool printFile) {
554
555 int ww = ep->GPSWeek;
556 int tow = ep->GPSTOW;
557 struct converttimeinfo cti;
558
559 updatetime(&ww, &tow, ep->tb*1000, 1); // Moscow -> UTC
560 converttime(&cti, ww, tow);
561
562 int tk = ep->tk-3*60*60;
563 if (tk < 0) {
564 tk += 86400;
565 }
566
567 QString lineV2;
568 QString lineV3;
569
570 lineV3.sprintf("R%02d %04d %02d %02d %02d %02d %02d%19.12e%19.12e%19.12e\n",
571 ep->almanac_number, cti.year, cti.month, cti.day, cti.hour,
572 cti.minute, cti.second, -ep->tau, ep->gamma, (double) tk);
573
574 lineV2.sprintf("%02d %02d %02d %02d %02d %02d%5.1f%19.12e%19.12e%19.12e\n",
575 ep->almanac_number, cti.year%100, cti.month, cti.day,
576 cti.hour, cti.minute, (double) cti.second, -ep->tau,
577 ep->gamma, (double) tk);
578
579 QString line;
580 QByteArray allLines;
581
582 QByteArray fmt;
583 if (_rinexVers == 2) {
584 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
585 }
586 else {
587 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
588 }
589
590 line.sprintf(fmt.data(), ep->x_pos, ep->x_velocity, ep->x_acceleration,
591 (ep->flags & GLOEPHF_UNHEALTHY) ? 1.0 : 0.0);
592 allLines += line;
593
594 line.sprintf(fmt.data(), ep->y_pos, ep->y_velocity, ep->y_acceleration,
595 (double) ep->frequency_number);
596 allLines += line;
597
598 line.sprintf(fmt.data(), ep->z_pos, ep->z_velocity, ep->z_acceleration,
599 (double) ep->E);
600 allLines += line;
601
602 printOutput(printFile, _ephStreamGlonass, lineV2, lineV3, allLines);
603}
604
605// Print One Galileo Ephemeris
606////////////////////////////////////////////////////////////////////////////
607void bncApp::printGalileoEph(galileoephemeris* ep, bool printFile) {
608
609 QString lineV2;
610 QString lineV3;
611
612 struct converttimeinfo cti;
613 converttime(&cti, ep->Week, ep->TOC);
614
615 lineV3.sprintf("E%02d %04d %02d %02d %02d %02d %02d%19.12e%19.12e%19.12e\n",
616 ep->satellite, cti.year, cti.month, cti.day, cti.hour,
617 cti.minute, cti.second, ep->clock_bias, ep->clock_drift,
618 ep->clock_driftrate);
619
620 QString line;
621 QByteArray allLines;
622
623 const QByteArray fmt4 = " %19.12e%19.12e%19.12e%19.12e\n";
624 const QByteArray fmt3 = " %19.12e%19.12e%19.12e\n";
625 const QByteArray fmt1 = " %19.12e\n";
626
627 line.sprintf(fmt4.data(), (double)ep->IODnav, ep->Crs, ep->Delta_n, ep->M0);
628 allLines += line;
629
630 line.sprintf(fmt4.data(), ep->Cuc, ep->e, ep->Cus, ep->sqrt_A);
631 allLines += line;
632
633 line.sprintf(fmt4.data(), (double) ep->TOE, ep->Cic, ep->OMEGA0, ep->Cis);
634 allLines += line;
635
636 line.sprintf(fmt4.data(), ep->i0, ep->Crc, ep->omega, ep->OMEGADOT);
637 allLines += line;
638
639 double dataSources = 0.0; // TODO
640 line.sprintf(fmt3.data(), ep->IDOT, dataSources, (double) ep->Week);
641 allLines += line;
642
643 double health = 0.0; // TODO
644 double BGD_1_5B = ep->BGD_1_5A; // TODO
645 line.sprintf(fmt4.data(), (double) ep->SISA, health, ep->BGD_1_5A, BGD_1_5B);
646 allLines += line;
647
648 double transmissionTimeOfMessage = 0.9999e9; // unknown (Rinex v3 standard)
649 line.sprintf(fmt1.data(), transmissionTimeOfMessage);
650 allLines += line;
651
652 printOutput(printFile, _ephStreamGalileo, lineV2, lineV3, allLines);
653}
654
655// Output
656////////////////////////////////////////////////////////////////////////////
657void bncApp::printOutput(bool printFile, QTextStream* stream,
658 const QString& lineV2,
659 const QString& lineV3,
660 const QByteArray& allLines) {
661 // Output into file
662 // ----------------
663 if (printFile && stream) {
664 if (_rinexVers == 2) {
665 *stream << lineV2.toAscii();
666 }
667 else {
668 *stream << lineV3.toAscii();
669 }
670 *stream << allLines;
671 stream->flush();
672 }
673
674 // Output into the socket
675 // ----------------------
676 if (_sockets) {
677 QMutableListIterator<QTcpSocket*> is(*_sockets);
678 while (is.hasNext()) {
679 QTcpSocket* sock = is.next();
680 if (sock->state() == QAbstractSocket::ConnectedState) {
681 if (sock->write(lineV3.toAscii()) == -1 ||
682 sock->write(allLines) == -1) {
683 delete sock;
684 is.remove();
685 }
686 }
687 else if (sock->state() != QAbstractSocket::ConnectingState) {
688 delete sock;
689 is.remove();
690 }
691 }
692 }
693}
694
695// Set Port Number
696////////////////////////////////////////////////////////////////////////////
697void bncApp::setPort(int port) {
698 _port = port;
699 if (_port != 0) {
700 delete _server;
701 _server = new QTcpServer;
702 if ( !_server->listen(QHostAddress::Any, _port) ) {
703 slotMessage("bncApp: Cannot listen on ephemeris port", true);
704 }
705 connect(_server, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
706 delete _sockets;
707 _sockets = new QList<QTcpSocket*>;
708 }
709}
710
711// Set Port Number
712////////////////////////////////////////////////////////////////////////////
713void bncApp::setPortCorr(int port) {
714 _portCorr = port;
715 if (_portCorr != 0) {
716 delete _serverCorr;
717 _serverCorr = new QTcpServer;
718 if ( !_serverCorr->listen(QHostAddress::Any, _portCorr) ) {
719 slotMessage("bncApp: Cannot listen on correction port", true);
720 }
721 connect(_serverCorr, SIGNAL(newConnection()), this, SLOT(slotNewConnectionCorr()));
722 delete _socketsCorr;
723 _socketsCorr = new QList<QTcpSocket*>;
724 }
725}
726
727// New Connection
728////////////////////////////////////////////////////////////////////////////
729void bncApp::slotNewConnection() {
730 _sockets->push_back( _server->nextPendingConnection() );
731}
732
733// New Connection
734////////////////////////////////////////////////////////////////////////////
735void bncApp::slotNewConnectionCorr() {
736 _socketsCorr->push_back( _serverCorr->nextPendingConnection() );
737}
738
739//
740////////////////////////////////////////////////////////////////////////////
741void bncApp::slotQuit() {
742 cout << "bncApp::slotQuit" << endl;
743 delete _caster;
744 quit();
745}
746
747//
748////////////////////////////////////////////////////////////////////////////
749void bncApp::slotNewCorrLine(QString line, QString staID, long coTime) {
750
751 QMutexLocker locker(&_mutex);
752
753 // Combination of Corrections
754 // --------------------------
755#ifdef USE_COMBINATION
756 if (_bncComb) {
757 _bncComb->processCorrLine(staID, line);
758 }
759#endif
760
761 bncSettings settings;
762 _waitCoTime = settings.value("corrTime").toInt();
763 if (_waitCoTime < 0) {
764 _waitCoTime = 0;
765 }
766
767 // First time, set the _lastDumpSec immediately
768 // --------------------------------------------
769 if (_lastDumpCoSec == 0) {
770 _lastDumpCoSec = coTime - 1;
771 }
772
773 // An old correction - throw it away
774 // ---------------------------------
775 if (_waitCoTime > 0 && coTime <= _lastDumpCoSec) {
776 if (!_bncComb) {
777 QString line = staID + ": Correction for one sat neglected because overaged by " +
778 QString().sprintf(" %ld sec",
779 _lastDumpCoSec - coTime + _waitCoTime);
780 messagePrivate(line.toAscii());
781 emit( newMessage(line.toAscii(), true) );
782 }
783 return;
784 }
785
786 _corrs->insert(coTime, QString(line + " " + staID));
787
788 // Dump Corrections
789 // ----------------
790 if (_waitCoTime == 0) {
791 dumpCorrs();
792 }
793 else if (coTime - _waitCoTime > _lastDumpCoSec) {
794 dumpCorrs(_lastDumpCoSec + 1, coTime - _waitCoTime);
795 _lastDumpCoSec = coTime - _waitCoTime;
796 }
797}
798
799// Dump Complete Correction Epochs
800////////////////////////////////////////////////////////////////////////////
801void bncApp::dumpCorrs(long minTime, long maxTime) {
802 for (long sec = minTime; sec <= maxTime; sec++) {
803 QList<QString> allCorrs = _corrs->values(sec);
804 dumpCorrs(allCorrs);
805 _corrs->remove(sec);
806 }
807}
808
809// Dump all corrections
810////////////////////////////////////////////////////////////////////////////
811void bncApp::dumpCorrs() {
812 QList<QString> allCorrs;
813 QMutableMapIterator<long, QString> it(*_corrs);
814 while (it.hasNext()) {
815 allCorrs << it.next().value();
816 it.remove();
817 }
818 dumpCorrs(allCorrs);
819}
820
821// Dump List of Corrections
822////////////////////////////////////////////////////////////////////////////
823void bncApp::dumpCorrs(const QList<QString>& allCorrs) {
824 emit newCorrections(allCorrs);
825 if (_socketsCorr) {
826 QListIterator<QString> it(allCorrs);
827 while (it.hasNext()) {
828 QString corrLine = it.next() + "\n";
829
830 QMutableListIterator<QTcpSocket*> is(*_socketsCorr);
831 while (is.hasNext()) {
832 QTcpSocket* sock = is.next();
833 if (sock->state() == QAbstractSocket::ConnectedState) {
834 if (sock->write(corrLine.toAscii()) == -1) {
835 delete sock;
836 is.remove();
837 }
838 }
839 else if (sock->state() != QAbstractSocket::ConnectingState) {
840 delete sock;
841 is.remove();
842 }
843 }
844 }
845 }
846}
847
848//
849////////////////////////////////////////////////////////////////////////////
850void bncApp::setConfFileName(const QString& confFileName) {
851 if (confFileName.isEmpty()) {
852 _confFileName = QDir::homePath() + QDir::separator()
853 + ".config" + QDir::separator()
854 + organizationName() + QDir::separator()
855 + applicationName() + ".ini";
856 }
857 else {
858 _confFileName = confFileName;
859 }
860}
861
862// Raw Output
863////////////////////////////////////////////////////////////////////////////
864void bncApp::writeRawData(const QByteArray& data, const QByteArray& staID,
865 const QByteArray& format) {
866
867 QMutexLocker locker(&_mutex);
868
869 if (!_rawFile) {
870 bncSettings settings;
871 QByteArray fileName = settings.value("rawOutFile").toByteArray();
872 if (!fileName.isEmpty()) {
873 _rawFile = new bncRawFile(fileName, staID, bncRawFile::output);
874 }
875 }
876
877 if (_rawFile) {
878 _rawFile->writeRawData(data, staID, format);
879 }
880}
881
882// Get Glonass Slot Numbers from Global Array
883////////////////////////////////////////////////////////////////////////////
884void bncApp::getGlonassSlotNums(int GLOFreq[]) {
885
886 QMutexLocker locker(&_mutex);
887
888 for (int ii = 0; ii < PRN_GLONASS_NUM; ++ii) {
889 if (_GLOFreq[ii] != 0) {
890 GLOFreq[ii] = _GLOFreq[ii];
891 }
892 }
893}
894
895// Store Glonass Slot Numbers to Global Array
896////////////////////////////////////////////////////////////////////////////
897void bncApp::storeGlonassSlotNums(const int GLOFreq[]) {
898
899 QMutexLocker locker(&_mutex);
900
901 for (int ii = 0; ii < PRN_GLONASS_NUM; ++ii) {
902 if (GLOFreq[ii] != 0) {
903 _GLOFreq[ii] = GLOFreq[ii];
904 }
905 }
906}
907
908//
909////////////////////////////////////////////////////////////////////////////
910void bncApp::initCombination() {
911#ifdef USE_COMBINATION
912 _bncComb = new bncComb();
913 if (_bncComb->nStreams() < 1) {
914 delete _bncComb;
915 _bncComb = 0;
916 }
917#endif
918}
919
920//
921////////////////////////////////////////////////////////////////////////////
922void bncApp::stopCombination() {
923#ifdef USE_COMBINATION
924 delete _bncComb;
925 _bncComb = 0;
926#endif
927}
Note: See TracBrowser for help on using the repository browser.