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

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