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

Last change on this file since 3941 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
RevLine 
[280]1// Part of BNC, a utility for retrieving decoding and
[464]2// converting GNSS data streams from NTRIP broadcasters.
[280]3//
[464]4// Copyright (C) 2007
[280]5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
[464]7// Czech Technical University Prague, Department of Geodesy
[280]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.
[82]24
25/* -------------------------------------------------------------------------
[93]26 * BKG NTRIP Client
[82]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
[1029]41#include <iostream>
[150]42#include <QMessageBox>
[519]43#include <cmath>
[82]44
45#include "bncapp.h"
[151]46#include "bncutils.h"
[647]47#include "bncrinex.h"
[1535]48#include "bncsettings.h"
[2011]49#include "bncversion.h"
[82]50
[2899]51#ifdef USE_COMBINATION
52#include "combination/bnccomb.h"
53#endif
54
[82]55using namespace std;
56
57// Constructor
58////////////////////////////////////////////////////////////////////////////
[1291]59bncApp::bncApp(int& argc, char* argv[], bool GUIenabled) :
[82]60 QApplication(argc, argv, GUIenabled) {
[109]61
[150]62 _logFileFlag = 0;
63 _logFile = 0;
64 _logStream = 0;
[621]65 _caster = 0;
[2519]66 _rawFile = 0;
[2922]67#ifdef USE_COMBINATION
68 _bncComb = 0;
69#endif
[152]70
[516]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 }
[2770]79 for (int ii = PRN_GALILEO_START; ii <= PRN_GALILEO_END; ii++) {
80 _galileoEph[ii-PRN_GALILEO_START] = 0;
81 }
[516]82
[533]83 // Eph file(s)
84 // -----------
[534]85 _rinexVers = 0;
[533]86 _ephFileGPS = 0;
87 _ephStreamGPS = 0;
88 _ephFileGlonass = 0;
89 _ephStreamGlonass = 0;
[2770]90 _ephFileGalileo = 0;
91 _ephStreamGalileo = 0;
[559]92
[591]93 _port = 0;
[589]94 _server = 0;
95 _sockets = 0;
96
[937]97 _portCorr = 0;
98 _serverCorr = 0;
99 _socketsCorr = 0;
100
[2011]101 _pgmName = QString(BNCPGMNAME).leftJustified(20, ' ', true);
[559]102#ifdef WIN32
103 _userName = QString("${USERNAME}");
104#else
105 _userName = QString("${USER}");
106#endif
107 expandEnvVar(_userName);
108 _userName = _userName.leftJustified(20, ' ', true);
[973]109
110 _lastDumpCoSec = 0;
[975]111
112 _corrs = new QMultiMap<long, QString>;
[1155]113
114 _currentDateAndTimeGPS = 0;
[2673]115
116 for (int ii = 0; ii < PRN_GLONASS_NUM; ++ii) {
117 _GLOFreq[ii] = 0;
118 }
[3027]119
120 _bncPPPclient = 0;
[82]121}
122
123// Destructor
124////////////////////////////////////////////////////////////////////////////
125bncApp::~bncApp() {
[109]126 delete _logStream;
127 delete _logFile;
[533]128 delete _ephStreamGPS;
129 delete _ephFileGPS;
[589]130 delete _server;
131 delete _sockets;
[937]132 delete _serverCorr;
133 delete _socketsCorr;
[534]134 if (_rinexVers == 2) {
[533]135 delete _ephStreamGlonass;
136 delete _ephFileGlonass;
137 }
[516]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 }
[2770]144 for (int ii = PRN_GALILEO_START; ii <= PRN_GALILEO_END; ii++) {
145 delete _galileoEph[ii-PRN_GALILEO_START];
146 }
[975]147
148 delete _corrs;
[1156]149
150 delete _currentDateAndTimeGPS;
[2385]151
[2519]152 delete _rawFile;
[2865]153
[2899]154#ifdef USE_COMBINATION
[2865]155 delete _bncComb;
[2899]156#endif
[82]157}
158
159// Write a Program Message
160////////////////////////////////////////////////////////////////////////////
[1383]161void bncApp::slotMessage(QByteArray msg, bool showOnScreen) {
[150]162
[1218]163 QMutexLocker locker(&_mutexMessage);
[243]164
[990]165 messagePrivate(msg);
[1299]166 emit newMessage(msg, showOnScreen);
[990]167}
168
169// Write a Program Message (private, no lock)
170////////////////////////////////////////////////////////////////////////////
171void bncApp::messagePrivate(const QByteArray& msg) {
172
[150]173 // First time resolve the log file name
174 // ------------------------------------
[1549]175 QDate currDate = currentDateAndTimeGPS().date();
176 if (_logFileFlag == 0 || _fileDate != currDate) {
[3034]177 delete _logStream; _logStream = 0;
178 delete _logFile; _logFile = 0;
[150]179 _logFileFlag = 1;
[1535]180 bncSettings settings;
[150]181 QString logFileName = settings.value("logFile").toString();
182 if ( !logFileName.isEmpty() ) {
[151]183 expandEnvVar(logFileName);
[1549]184 _logFile = new QFile(logFileName + "_" +
185 currDate.toString("yyMMdd").toAscii().data());
186 _fileDate = currDate;
[275]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 }
[150]193 _logStream = new QTextStream();
194 _logStream->setDevice(_logFile);
195 }
196 }
197
[109]198 if (_logStream) {
[3371]199 QByteArray msgLocal = msg;
200 if (msg.indexOf('\n') == 0) {
201 *_logStream << endl;
202 msgLocal = msg.mid(1);
203 }
[1154]204 *_logStream << currentDateAndTimeGPS().toString("yy-MM-dd hh:mm:ss ").toAscii().data();
[3371]205 *_logStream << msgLocal.data() << endl;
[109]206 _logStream->flush();
[3637]207 _logFile->flush();
[82]208 }
209}
[511]210
[535]211// New GPS Ephemeris
[511]212////////////////////////////////////////////////////////////////////////////
213void bncApp::slotNewGPSEph(gpsephemeris* gpseph) {
[516]214
215 QMutexLocker locker(&_mutex);
216
[1044]217 gpsephemeris copy_gpseph = *gpseph;
218 emit newEphGPS(copy_gpseph);
219
[534]220 printEphHeader();
221
[532]222 gpsephemeris** ee = &_gpsEph[gpseph->satellite-1];
[1218]223
[538]224 if ( *ee == 0 ||
225 gpseph->GPSweek > (*ee)->GPSweek ||
[594]226 (gpseph->GPSweek == (*ee)->GPSweek && gpseph->TOC > (*ee)->TOC) ) {
[516]227 delete *ee;
228 *ee = gpseph;
[600]229 printGPSEph(gpseph, true);
[516]230 }
231 else {
[600]232 printGPSEph(gpseph, false);
[516]233 delete gpseph;
234 }
[511]235}
236
[535]237// New Glonass Ephemeris
[511]238////////////////////////////////////////////////////////////////////////////
239void bncApp::slotNewGlonassEph(glonassephemeris* glonasseph) {
[516]240
241 QMutexLocker locker(&_mutex);
242
[1164]243 glonassephemeris copy_glonasseph = *glonasseph;
244 emit newEphGlonass(copy_glonasseph);
245
[534]246 printEphHeader();
247
[532]248 glonassephemeris** ee = &_glonassEph[glonasseph->almanac_number-1];
[531]249
[3539]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
[578]261 if ( *ee == 0 ||
[3539]262 wwNew > wwOld ||
263 (wwNew == wwOld && towNew > towOld) ) {
[531]264 delete *ee;
265 *ee = glonasseph;
[600]266 printGlonassEph(glonasseph, true);
[531]267 }
268 else {
[600]269 printGlonassEph(glonasseph, false);
[531]270 delete glonasseph;
271 }
[511]272}
273
[2770]274// New Galileo Ephemeris
275////////////////////////////////////////////////////////////////////////////
276void bncApp::slotNewGalileoEph(galileoephemeris* galileoeph) {
277
278 QMutexLocker locker(&_mutex);
279
[2772]280 galileoephemeris copy_galileoeph = *galileoeph;
281 emit newEphGalileo(copy_galileoeph);
282
283 printEphHeader();
284
[3734]285 int galIndex = galileoeph->satellite;
286 /* GIOVE */
287 if(galIndex == 51) galIndex = 1;
288 else if(galIndex == 52) galIndex = 16;
[2785]289 if (galIndex < 0 || galIndex > PRN_GALILEO_END - PRN_GALILEO_START) {
[2773]290 emit( newMessage("Wrong Galileo Satellite Number", true) );
291 exit(1);
292 }
[2772]293
[2773]294 galileoephemeris** ee = &_galileoEph[galIndex];
295
296 if ( *ee == 0 ||
[2772]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 }
[2770]307}
308
[535]309// Print Header of the output File(s)
[516]310////////////////////////////////////////////////////////////////////////////
311void bncApp::printEphHeader() {
[528]312
[1535]313 bncSettings settings;
[535]314
[534]315 // Initialization
316 // --------------
317 if (_rinexVers == 0) {
[528]318
[533]319 if ( Qt::CheckState(settings.value("ephV3").toInt()) == Qt::Checked) {
[534]320 _rinexVers = 3;
[533]321 }
322 else {
[534]323 _rinexVers = 2;
[533]324 }
[529]325
[533]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 }
[517]334 }
[533]335
[534]336 // (Re-)Open output File(s)
337 // ------------------------
[533]338 if (!_ephPath.isEmpty()) {
339
[1154]340 QDateTime datTim = currentDateAndTimeGPS();
[533]341
[583]342 QString ephFileNameGPS = _ephPath + "BRDC" +
[563]343 QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0'));
[533]344
[647]345 QString hlpStr = bncRinex::nextEpochStr(datTim,
346 settings.value("ephIntr").toString());
[584]347
[575]348 if (_rinexVers == 3) {
349 ephFileNameGPS += hlpStr + datTim.toString(".yyP");
350 }
351 else {
352 ephFileNameGPS += hlpStr + datTim.toString(".yyN");
353 }
[563]354
[533]355 if (_ephFileNameGPS == ephFileNameGPS) {
356 return;
357 }
358 else {
359 _ephFileNameGPS = ephFileNameGPS;
360 }
361
[575]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 }
[2770]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 }
[575]374
[533]375 delete _ephStreamGPS;
376 delete _ephFileGPS;
377
[535]378 QFlags<QIODevice::OpenModeFlag> appendFlagGPS;
[536]379 QFlags<QIODevice::OpenModeFlag> appendFlagGlonass;
[2770]380 QFlags<QIODevice::OpenModeFlag> appendFlagGalileo;
[536]381
[535]382 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked &&
383 QFile::exists(ephFileNameGPS) ) {
384 appendFlagGPS = QIODevice::Append;
385 }
386
[533]387 _ephFileGPS = new QFile(ephFileNameGPS);
[535]388 _ephFileGPS->open(QIODevice::WriteOnly | appendFlagGPS);
[533]389 _ephStreamGPS = new QTextStream();
390 _ephStreamGPS->setDevice(_ephFileGPS);
391
[534]392 if (_rinexVers == 3) {
[533]393 _ephFileGlonass = _ephFileGPS;
394 _ephStreamGlonass = _ephStreamGPS;
[2770]395 _ephFileGalileo = _ephFileGPS;
396 _ephStreamGalileo = _ephStreamGPS;
[533]397 }
[534]398 else if (_rinexVers == 2) {
[583]399 QString ephFileNameGlonass = _ephPath + "BRDC" +
[563]400 QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0')) +
[575]401 hlpStr + datTim.toString(".yyG");
[533]402
403 delete _ephStreamGlonass;
404 delete _ephFileGlonass;
405
[535]406 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked &&
407 QFile::exists(ephFileNameGlonass) ) {
408 appendFlagGlonass = QIODevice::Append;
409 }
410
[533]411 _ephFileGlonass = new QFile(ephFileNameGlonass);
[535]412 _ephFileGlonass->open(QIODevice::WriteOnly | appendFlagGlonass);
[533]413 _ephStreamGlonass = new QTextStream();
414 _ephStreamGlonass->setDevice(_ephFileGlonass);
415 }
416
[534]417 // Header - RINEX Version 3
418 // ------------------------
419 if (_rinexVers == 3) {
[537]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
[1154]427 QString hlp = currentDateAndTimeGPS().toString("yyyyMMdd hhmmss UTC").leftJustified(20, ' ', true);
[559]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", "");
[537]434 *_ephStreamGPS << line;
435
436 _ephStreamGPS->flush();
[535]437 }
[533]438 }
439
[536]440 // Headers - RINEX Version 2
441 // -------------------------
[534]442 else if (_rinexVers == 2) {
[536]443 if (! (appendFlagGPS & QIODevice::Append)) {
444 QString line;
445 line.sprintf(
[2405]446 "%9.2f%11sN: GPS NAV DATA%25sRINEX VERSION / TYPE\n", 2.10, "", "");
[536]447 *_ephStreamGPS << line;
448
[1154]449 QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
[559]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", "");
[536]456 *_ephStreamGPS << line;
[537]457
458 _ephStreamGPS->flush();
[536]459 }
460 if (! (appendFlagGlonass & QIODevice::Append)) {
461 QString line;
462 line.sprintf(
[2405]463 "%9.2f%11sG: GLONASS NAV DATA%21sRINEX VERSION / TYPE\n",2.10,"","");
[536]464 *_ephStreamGlonass << line;
465
[1154]466 QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
[559]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", "");
[536]473 *_ephStreamGlonass << line;
[537]474
475 _ephStreamGlonass->flush();
[536]476 }
[533]477 }
478 }
[516]479}
480
[535]481// Print One GPS Ephemeris
[516]482////////////////////////////////////////////////////////////////////////////
[600]483void bncApp::printGPSEph(gpsephemeris* ep, bool printFile) {
[519]484
[941]485 QString lineV2;
486 QString lineV3;
[533]487
[590]488 struct converttimeinfo cti;
489 converttime(&cti, ep->GPSweek, ep->TOC);
[941]490
[2861]491 lineV3.sprintf("G%02d %04d %02d %02d %02d %02d %02d%19.12e%19.12e%19.12e\n",
[589]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);
[941]495
[2861]496 lineV2.sprintf("%02d %02d %02d %02d %02d %02d%5.1f%19.12e%19.12e%19.12e\n",
[590]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);
[520]500
[941]501 QString line;
502 QByteArray allLines;
503
[1316]504 QByteArray fmt;
[1321]505 QByteArray fmt2;
[1316]506 if (_rinexVers == 2) {
[2861]507 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
508 fmt2 = " %19.12e%19.12e\n";
[1316]509 }
510 else {
[2861]511 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
512 fmt2 = " %19.12e%19.12e\n";
[1316]513 }
514
515 line.sprintf(fmt.data(), (double)ep->IODE, ep->Crs, ep->Delta_n, ep->M0);
[590]516 allLines += line;
517
[1316]518 line.sprintf(fmt.data(), ep->Cuc, ep->e, ep->Cus, ep->sqrt_A);
[590]519 allLines += line;
[520]520
[1316]521 line.sprintf(fmt.data(), (double) ep->TOE, ep->Cic, ep->OMEGA0, ep->Cis);
[590]522 allLines += line;
523
[1316]524 line.sprintf(fmt.data(), ep->i0, ep->Crc, ep->omega, ep->OMEGADOT);
[590]525 allLines += line;
[520]526
[590]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;
[1316]533 line.sprintf(fmt.data(), ep->IDOT, dd, (double) ep->GPSweek,
534 ii & GPSEPHF_L2PCODEDATA ? 1.0 : 0.0);
[590]535 allLines += line;
[520]536
[590]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;
[1316]541 line.sprintf(fmt.data(), dd, ((double) ep->SVhealth), ep->TGD,
542 ((double) ep->IODC));
[590]543 allLines += line;
[519]544
[1321]545 line.sprintf(fmt2.data(), ((double)ep->TOW), 0.0);
[590]546 allLines += line;
[519]547
[943]548 printOutput(printFile, _ephStreamGPS, lineV2, lineV3, allLines);
[516]549}
550
[535]551// Print One Glonass Ephemeris
[516]552////////////////////////////////////////////////////////////////////////////
[600]553void bncApp::printGlonassEph(glonassephemeris* ep, bool printFile) {
[523]554
[590]555 int ww = ep->GPSWeek;
556 int tow = ep->GPSTOW;
557 struct converttimeinfo cti;
[523]558
[2257]559 updatetime(&ww, &tow, ep->tb*1000, 1); // Moscow -> UTC
[590]560 converttime(&cti, ww, tow);
[525]561
[885]562 int tk = ep->tk-3*60*60;
563 if (tk < 0) {
564 tk += 86400;
[590]565 }
[525]566
[941]567 QString lineV2;
568 QString lineV3;
569
[2861]570 lineV3.sprintf("R%02d %04d %02d %02d %02d %02d %02d%19.12e%19.12e%19.12e\n",
[590]571 ep->almanac_number, cti.year, cti.month, cti.day, cti.hour,
[885]572 cti.minute, cti.second, -ep->tau, ep->gamma, (double) tk);
[941]573
[2861]574 lineV2.sprintf("%02d %02d %02d %02d %02d %02d%5.1f%19.12e%19.12e%19.12e\n",
[590]575 ep->almanac_number, cti.year%100, cti.month, cti.day,
576 cti.hour, cti.minute, (double) cti.second, -ep->tau,
[885]577 ep->gamma, (double) tk);
[590]578
[941]579 QString line;
580 QByteArray allLines;
581
[1316]582 QByteArray fmt;
583 if (_rinexVers == 2) {
[2861]584 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
[1316]585 }
586 else {
[2861]587 fmt = " %19.12e%19.12e%19.12e%19.12e\n";
[1316]588 }
589
590 line.sprintf(fmt.data(), ep->x_pos, ep->x_velocity, ep->x_acceleration,
[590]591 (ep->flags & GLOEPHF_UNHEALTHY) ? 1.0 : 0.0);
592 allLines += line;
593
[1316]594 line.sprintf(fmt.data(), ep->y_pos, ep->y_velocity, ep->y_acceleration,
[590]595 (double) ep->frequency_number);
596 allLines += line;
597
[1316]598 line.sprintf(fmt.data(), ep->z_pos, ep->z_velocity, ep->z_acceleration,
599 (double) ep->E);
[590]600 allLines += line;
[525]601
[943]602 printOutput(printFile, _ephStreamGlonass, lineV2, lineV3, allLines);
[941]603}
604
[2770]605// Print One Galileo Ephemeris
606////////////////////////////////////////////////////////////////////////////
607void bncApp::printGalileoEph(galileoephemeris* ep, bool printFile) {
[2772]608
609 QString lineV2;
610 QString lineV3;
611
612 struct converttimeinfo cti;
613 converttime(&cti, ep->Week, ep->TOC);
614
[2861]615 lineV3.sprintf("E%02d %04d %02d %02d %02d %02d %02d%19.12e%19.12e%19.12e\n",
[2772]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
[2861]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";
[2772]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
[2774]645 line.sprintf(fmt4.data(), (double) ep->SISA, health, ep->BGD_1_5A, BGD_1_5B);
[2772]646 allLines += line;
647
[2775]648 double transmissionTimeOfMessage = 0.9999e9; // unknown (Rinex v3 standard)
649 line.sprintf(fmt1.data(), transmissionTimeOfMessage);
[2772]650 allLines += line;
651
652 printOutput(printFile, _ephStreamGalileo, lineV2, lineV3, allLines);
[2770]653}
654
[941]655// Output
656////////////////////////////////////////////////////////////////////////////
[943]657void bncApp::printOutput(bool printFile, QTextStream* stream,
658 const QString& lineV2,
[941]659 const QString& lineV3,
660 const QByteArray& allLines) {
[590]661 // Output into file
662 // ----------------
[943]663 if (printFile && stream) {
[941]664 if (_rinexVers == 2) {
[943]665 *stream << lineV2.toAscii();
[941]666 }
667 else {
[943]668 *stream << lineV3.toAscii();
[941]669 }
[943]670 *stream << allLines;
671 stream->flush();
[517]672 }
[590]673
674 // Output into the socket
675 // ----------------------
676 if (_sockets) {
[642]677 QMutableListIterator<QTcpSocket*> is(*_sockets);
[590]678 while (is.hasNext()) {
679 QTcpSocket* sock = is.next();
680 if (sock->state() == QAbstractSocket::ConnectedState) {
[941]681 if (sock->write(lineV3.toAscii()) == -1 ||
682 sock->write(allLines) == -1) {
[642]683 delete sock;
684 is.remove();
685 }
[590]686 }
[642]687 else if (sock->state() != QAbstractSocket::ConnectingState) {
688 delete sock;
689 is.remove();
690 }
[590]691 }
692 }
[516]693}
[589]694
[591]695// Set Port Number
696////////////////////////////////////////////////////////////////////////////
697void bncApp::setPort(int port) {
698 _port = port;
699 if (_port != 0) {
[942]700 delete _server;
[591]701 _server = new QTcpServer;
[1228]702 if ( !_server->listen(QHostAddress::Any, _port) ) {
[1451]703 slotMessage("bncApp: Cannot listen on ephemeris port", true);
[1228]704 }
[591]705 connect(_server, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
[942]706 delete _sockets;
[591]707 _sockets = new QList<QTcpSocket*>;
708 }
709}
710
[937]711// Set Port Number
712////////////////////////////////////////////////////////////////////////////
713void bncApp::setPortCorr(int port) {
714 _portCorr = port;
715 if (_portCorr != 0) {
[942]716 delete _serverCorr;
[937]717 _serverCorr = new QTcpServer;
[1228]718 if ( !_serverCorr->listen(QHostAddress::Any, _portCorr) ) {
[1451]719 slotMessage("bncApp: Cannot listen on correction port", true);
[1228]720 }
[937]721 connect(_serverCorr, SIGNAL(newConnection()), this, SLOT(slotNewConnectionCorr()));
[942]722 delete _socketsCorr;
[937]723 _socketsCorr = new QList<QTcpSocket*>;
724 }
725}
726
[589]727// New Connection
728////////////////////////////////////////////////////////////////////////////
729void bncApp::slotNewConnection() {
730 _sockets->push_back( _server->nextPendingConnection() );
731}
732
[937]733// New Connection
734////////////////////////////////////////////////////////////////////////////
735void bncApp::slotNewConnectionCorr() {
736 _socketsCorr->push_back( _serverCorr->nextPendingConnection() );
737}
738
[621]739//
740////////////////////////////////////////////////////////////////////////////
741void bncApp::slotQuit() {
[1029]742 cout << "bncApp::slotQuit" << endl;
[621]743 delete _caster;
744 quit();
745}
746
[936]747//
748////////////////////////////////////////////////////////////////////////////
[974]749void bncApp::slotNewCorrLine(QString line, QString staID, long coTime) {
750
751 QMutexLocker locker(&_mutex);
752
[2866]753 // Combination of Corrections
754 // --------------------------
[2899]755#ifdef USE_COMBINATION
[2866]756 if (_bncComb) {
757 _bncComb->processCorrLine(staID, line);
758 }
[2899]759#endif
[2866]760
[1535]761 bncSettings settings;
[3109]762 _waitCoTime = settings.value("corrTime").toInt();
763 if (_waitCoTime < 0) {
764 _waitCoTime = 0;
[995]765 }
766
[974]767 // First time, set the _lastDumpSec immediately
768 // --------------------------------------------
769 if (_lastDumpCoSec == 0) {
770 _lastDumpCoSec = coTime - 1;
771 }
772
[975]773 // An old correction - throw it away
774 // ---------------------------------
[3109]775 if (_waitCoTime > 0 && coTime <= _lastDumpCoSec) {
[2916]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 }
[975]783 return;
784 }
785
786 _corrs->insert(coTime, QString(line + " " + staID));
787
[976]788 // Dump Corrections
789 // ----------------
[3109]790 if (_waitCoTime == 0) {
791 dumpCorrs();
792 }
793 else if (coTime - _waitCoTime > _lastDumpCoSec) {
[976]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);
[3109]804 dumpCorrs(allCorrs);
805 _corrs->remove(sec);
806 }
807}
808
809// Dump all corrections
810////////////////////////////////////////////////////////////////////////////
811void bncApp::dumpCorrs() {
[3110]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);
[3109]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) {
[976]835 delete sock;
836 is.remove();
837 }
838 }
[3109]839 else if (sock->state() != QAbstractSocket::ConnectingState) {
840 delete sock;
841 is.remove();
842 }
[937]843 }
844 }
845 }
[936]846}
[1538]847
848//
849////////////////////////////////////////////////////////////////////////////
850void bncApp::setConfFileName(const QString& confFileName) {
851 if (confFileName.isEmpty()) {
[1539]852 _confFileName = QDir::homePath() + QDir::separator()
853 + ".config" + QDir::separator()
854 + organizationName() + QDir::separator()
855 + applicationName() + ".ini";
[1538]856 }
857 else {
858 _confFileName = confFileName;
859 }
860}
[2385]861
862// Raw Output
863////////////////////////////////////////////////////////////////////////////
[2518]864void bncApp::writeRawData(const QByteArray& data, const QByteArray& staID,
865 const QByteArray& format) {
[2385]866
[2386]867 QMutexLocker locker(&_mutex);
868
[2519]869 if (!_rawFile) {
[2386]870 bncSettings settings;
[2519]871 QByteArray fileName = settings.value("rawOutFile").toByteArray();
872 if (!fileName.isEmpty()) {
[3524]873 _rawFile = new bncRawFile(fileName, staID, bncRawFile::output);
[2407]874 }
[2386]875 }
876
[2519]877 if (_rawFile) {
878 _rawFile->writeRawData(data, staID, format);
[2386]879 }
[2385]880}
[2672]881
882// Get Glonass Slot Numbers from Global Array
883////////////////////////////////////////////////////////////////////////////
884void bncApp::getGlonassSlotNums(int GLOFreq[]) {
885
886 QMutexLocker locker(&_mutex);
887
[2673]888 for (int ii = 0; ii < PRN_GLONASS_NUM; ++ii) {
889 if (_GLOFreq[ii] != 0) {
890 GLOFreq[ii] = _GLOFreq[ii];
891 }
892 }
[2672]893}
894
895// Store Glonass Slot Numbers to Global Array
896////////////////////////////////////////////////////////////////////////////
897void bncApp::storeGlonassSlotNums(const int GLOFreq[]) {
898
899 QMutexLocker locker(&_mutex);
900
[2673]901 for (int ii = 0; ii < PRN_GLONASS_NUM; ++ii) {
902 if (GLOFreq[ii] != 0) {
903 _GLOFreq[ii] = GLOFreq[ii];
904 }
905 }
[2672]906}
[2909]907
908//
909////////////////////////////////////////////////////////////////////////////
910void bncApp::initCombination() {
911#ifdef USE_COMBINATION
912 _bncComb = new bncComb();
[3142]913 if (_bncComb->nStreams() < 1) {
[2909]914 delete _bncComb;
915 _bncComb = 0;
916 }
917#endif
918}
[3231]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.