source: ntrip/trunk/BNC/src/bncgetthread.cpp@ 10537

Last change on this file since 10537 was 10533, checked in by stuerze, 11 months ago

Service and RTCM CRS encoding and decoding as well as Helmert parameter decoding added + some re-organisation

File size: 35.5 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: bncGetThread
30 *
31 * Purpose: Thread that retrieves data from NTRIP caster
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <stdlib.h>
42#include <iostream>
43#include <iomanip>
44#include <sstream>
45
46#include <QComboBox>
47#include <QDialog>
48#include <QFile>
49#include <QTextStream>
50#include <QMutex>
51#include <QPushButton>
52#include <QTableWidget>
53#include <QTime>
54
55#include "bncgetthread.h"
56#include "bnctabledlg.h"
57#include "bnccore.h"
58#include "bncutils.h"
59#include "bnctime.h"
60#include "bnczerodecoder.h"
61#include "bncnetqueryv0.h"
62#include "bncnetqueryv1.h"
63#include "bncnetqueryv2.h"
64#include "bncnetqueryrtp.h"
65#include "bncnetqueryudp.h"
66#include "bncnetqueryudp0.h"
67#include "bncnetquerys.h"
68#include "bncsettings.h"
69#include "latencychecker.h"
70#include "upload/bncrtnetdecoder.h"
71#include "RTCM/RTCM2Decoder.h"
72#include "RTCM3/RTCM3Decoder.h"
73#include "serial/qextserialport.h"
74
75using namespace std;
76
77// Constructor 1
78////////////////////////////////////////////////////////////////////////////
79bncGetThread::bncGetThread(bncRawFile* rawFile) {
80
81 _rawFile = rawFile;
82 _format = rawFile->format();
83 _staID = rawFile->staID();
84 _rawOutput = false;
85 _ntripVersion = "N";
86
87 initialize();
88}
89
90// Constructor 2
91////////////////////////////////////////////////////////////////////////////
92bncGetThread::bncGetThread(const QUrl& mountPoint, const QByteArray& format,
93 const QByteArray& latitude, const QByteArray& longitude,
94 const QByteArray& nmea, const QByteArray& ntripVersion) {
95 _rawFile = 0;
96 _mountPoint = mountPoint;
97 _staID = mountPoint.path().mid(1).toLatin1();
98 _format = format;
99 _latitude = latitude;
100 _longitude = longitude;
101 _nmea = nmea;
102 _ntripVersion = ntripVersion;
103
104 bncSettings settings;
105 if (!settings.value("rawOutFile").toString().isEmpty()) {
106 _rawOutput = true;
107 }
108 else {
109 _rawOutput = false;
110 }
111
112 _latencycheck = true; // in order to allow at least to check for reconnect
113
114 _NMEASampl = settings.value("serialNMEASampling").toInt();
115
116 initialize();
117 initDecoder();
118}
119
120// Initialization (common part of the constructor)
121////////////////////////////////////////////////////////////////////////////
122void bncGetThread::initialize() {
123
124 bncSettings settings;
125
126 setTerminationEnabled(true);
127
128 connect(this, SIGNAL(newMessage(QByteArray,bool)),
129 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
130
131 _isToBeDeleted = false;
132 _query = 0;
133 _nextSleep = 0;
134 _miscMount = settings.value("miscMount").toString();
135 _decoder = 0;
136
137 // NMEA Port
138 // -----------
139 QListIterator<QString> iSta(settings.value("PPP/staTable").toStringList());
140 int nmeaPort = 0;
141 while (iSta.hasNext()) {
142 QStringList hlp = iSta.next().split(",");
143 if (hlp.size() < 10) {
144 continue;
145 }
146 QByteArray mp = hlp[0].toLatin1();
147 if (_staID == mp) {
148 nmeaPort = hlp[9].toInt();
149 }
150 }
151 if (nmeaPort != 0) {
152 _nmeaServer = new QTcpServer;
153 _nmeaServer->setProxy(QNetworkProxy::NoProxy);
154 if (!_nmeaServer->listen(QHostAddress::Any, nmeaPort)) {
155 QString message = "bncCaster: Cannot listen on port "
156 + QByteArray::number(nmeaPort) + ": "
157 + _nmeaServer->errorString();
158 emit newMessage(message.toLatin1(), true);
159 } else {
160 connect(_nmeaServer, SIGNAL(newConnection()), this,
161 SLOT(slotNewNMEAConnection()));
162 connect(BNC_CORE, SIGNAL(newNMEAstr(QByteArray, QByteArray)), this,
163 SLOT(slotNewNMEAstr(QByteArray, QByteArray)));
164 _nmeaSockets = new QList<QTcpSocket*>;
165 _nmeaPortsMap[_staID] = nmeaPort;
166 }
167 } else {
168 _nmeaServer = 0;
169 _nmeaSockets = 0;
170 }
171
172 // Serial Port
173 // -----------
174 _serialNMEA = NO_NMEA;
175 _serialOutFile = 0;
176 _serialPort = 0;
177
178 if (!_staID.isEmpty()
179 && settings.value("serialMountPoint").toString() == _staID) {
180 _serialPort = new QextSerialPort(
181 settings.value("serialPortName").toString());
182 _serialPort->setTimeout(0, 100);
183
184 // Baud Rate
185 // ---------
186 QString hlp = settings.value("serialBaudRate").toString();
187 if (hlp == "110") {
188 _serialPort->setBaudRate(BAUD110);
189 } else if (hlp == "300") {
190 _serialPort->setBaudRate(BAUD300);
191 } else if (hlp == "600") {
192 _serialPort->setBaudRate(BAUD600);
193 } else if (hlp == "1200") {
194 _serialPort->setBaudRate(BAUD1200);
195 } else if (hlp == "2400") {
196 _serialPort->setBaudRate(BAUD2400);
197 } else if (hlp == "4800") {
198 _serialPort->setBaudRate(BAUD4800);
199 } else if (hlp == "9600") {
200 _serialPort->setBaudRate(BAUD9600);
201 } else if (hlp == "19200") {
202 _serialPort->setBaudRate(BAUD19200);
203 } else if (hlp == "38400") {
204 _serialPort->setBaudRate(BAUD38400);
205 } else if (hlp == "57600") {
206 _serialPort->setBaudRate(BAUD57600);
207 } else if (hlp == "115200") {
208 _serialPort->setBaudRate(BAUD115200);
209 }
210
211 // Parity
212 // ------
213 hlp = settings.value("serialParity").toString();
214 if (hlp == "NONE") {
215 _serialPort->setParity(PAR_NONE);
216 } else if (hlp == "ODD") {
217 _serialPort->setParity(PAR_ODD);
218 } else if (hlp == "EVEN") {
219 _serialPort->setParity(PAR_EVEN);
220 } else if (hlp == "SPACE") {
221 _serialPort->setParity(PAR_SPACE);
222 }
223
224 // Data Bits
225 // ---------
226 hlp = settings.value("serialDataBits").toString();
227 if (hlp == "5") {
228 _serialPort->setDataBits(DATA_5);
229 } else if (hlp == "6") {
230 _serialPort->setDataBits(DATA_6);
231 } else if (hlp == "7") {
232 _serialPort->setDataBits(DATA_7);
233 } else if (hlp == "8") {
234 _serialPort->setDataBits(DATA_8);
235 }
236 hlp = settings.value("serialStopBits").toString();
237 if (hlp == "1") {
238 _serialPort->setStopBits(STOP_1);
239 } else if (hlp == "2") {
240 _serialPort->setStopBits(STOP_2);
241 }
242
243 // Flow Control
244 // ------------
245 hlp = settings.value("serialFlowControl").toString();
246 if (hlp == "XONXOFF") {
247 _serialPort->setFlowControl(FLOW_XONXOFF);
248 } else if (hlp == "HARDWARE") {
249 _serialPort->setFlowControl(FLOW_HARDWARE);
250 } else {
251 _serialPort->setFlowControl(FLOW_OFF);
252 }
253
254 // Open Serial Port
255 // ----------------
256 _serialPort->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
257 if (!_serialPort->isOpen()) {
258 delete _serialPort;
259 _serialPort = 0;
260 emit(newMessage((_staID + ": Cannot open serial port\n"), true));
261 }
262 connect(_serialPort, SIGNAL(readyRead()), this,
263 SLOT(slotSerialReadyRead()));
264
265 // Automatic NMEA
266 // --------------
267 QString nmeaMode = settings.value("serialAutoNMEA").toString();
268 if (nmeaMode == "Auto") {
269 _serialNMEA = AUTO_NMEA;
270 QString fName = settings.value("serialFileNMEA").toString();
271 if (!fName.isEmpty()) {
272 _serialOutFile = new QFile(fName);
273 if (Qt::CheckState(settings.value("rnxAppend").toInt())
274 == Qt::Checked) {
275 _serialOutFile->open(QIODevice::WriteOnly | QIODevice::Append);
276 } else {
277 _serialOutFile->open(QIODevice::WriteOnly);
278 }
279 }
280 }
281 // Manual NMEA
282 // -----------
283 if ((nmeaMode == "Manual GPGGA") ||
284 (nmeaMode == "Manual GNGGA")) {
285 _serialNMEA = MANUAL_NMEA;
286 bncSettings settings;
287 QString hlp = settings.value("serialHeightNMEA").toString();
288 if (hlp.isEmpty()) {
289 hlp = "0.0";
290 }
291 QByteArray _serialHeightNMEA = hlp.toLatin1();
292 _manualNMEAString = ggaString(_latitude, _longitude, _serialHeightNMEA, nmeaMode);
293 }
294 }
295
296 if (!_staID.isEmpty() && _latencycheck) {
297 _latencyChecker = new latencyChecker(_staID);
298 _rtcmObs = false;
299 _rtcmSsrOrb = false;
300 _rtcmSsrClk = false;
301 _rtcmSsrOrbClk = false;
302 _rtcmSsrCbi = false;
303 _rtcmSsrPbi = false;
304 _rtcmSsrVtec = false;
305 _rtcmSsrUra = false;
306 _rtcmSsrHr = false;
307 _rtcmSsrIgs = false;
308 _ssrEpoch = 0;
309 } else {
310 _latencyChecker = 0;
311 }
312}
313
314// Instantiate the decoder
315//////////////////////////////////////////////////////////////////////////////
316t_irc bncGetThread::initDecoder() {
317
318 _decoder = 0;
319
320 if (_format.indexOf("RTCM_2") != -1 ||
321 _format.indexOf("RTCM2") != -1 ||
322 _format.indexOf("RTCM 2") != -1) {
323 emit(newMessage(_staID + ": Get data in RTCM 2.x format", true));
324 _decoder = new RTCM2Decoder(_staID.data());
325 } else if (_format.indexOf("RTCM_3") != -1 ||
326 _format.indexOf("RTCM3") != -1 ||
327 _format.indexOf("RTCM 3") != -1) {
328 emit(newMessage(_staID + ": Get data in RTCM 3.x format", true));
329 RTCM3Decoder* newDecoder = new RTCM3Decoder(_staID, _rawFile);
330 _decoder = newDecoder;
331 connect((RTCM3Decoder*) newDecoder, SIGNAL(newMessage(QByteArray,bool)),
332 this, SIGNAL(newMessage(QByteArray,bool)));
333 } else if (_format == "ZERO") {
334 emit(newMessage(_staID + ": Forward data in original format", true));
335 _decoder = new bncZeroDecoder(_staID, false);
336 }
337 else if (_format == "ZERO2FILE") {
338 emit(newMessage(_staID + ": Get data in original format and store it", true));
339 _decoder = new bncZeroDecoder(_staID, true);
340 }
341 else if (_format.indexOf("RTNET") != -1) {
342 emit(newMessage(_staID + ": Get data in RTNet format", true));
343 _decoder = new bncRtnetDecoder();
344 } else {
345 emit(newMessage(_staID + ": Unknown data format " + _format, true));
346 _isToBeDeleted = true;
347 return failure;
348 }
349
350 msleep(100); //sleep 0.1 sec
351
352 _decoder->initRinex(_staID, _mountPoint, _latitude, _longitude, _nmea,
353 _ntripVersion);
354
355 if (_rawFile) {
356 _decodersRaw[_staID] = _decoder;
357 }
358
359 return success;
360}
361
362// Current decoder in use
363////////////////////////////////////////////////////////////////////////////
364GPSDecoder* bncGetThread::decoder() {
365 if (!_rawFile) {
366 return _decoder;
367 } else {
368 if (_decodersRaw.contains(_staID) || initDecoder() == success) {
369 return _decodersRaw[_staID];
370 }
371 }
372 return 0;
373}
374
375// Destructor
376////////////////////////////////////////////////////////////////////////////
377bncGetThread::~bncGetThread() {
378 if (isRunning()) {
379 wait();
380 }
381 if (_query) {
382 _query->stop();
383 _query->deleteLater();
384 }
385 if (_rawFile) {
386 QMapIterator<QString, GPSDecoder*> it(_decodersRaw);
387 while (it.hasNext()) {
388 it.next();
389 delete it.value();
390 }
391 _decodersRaw.clear();
392 } else {
393 delete _decoder;
394 }
395 delete _rawFile;
396 delete _serialOutFile;
397 delete _serialPort;
398 delete _latencyChecker;
399 emit getThreadFinished(_staID);
400}
401
402//
403////////////////////////////////////////////////////////////////////////////
404void bncGetThread::terminate() {
405 _isToBeDeleted = true;
406
407 if (_nmeaPortsMap.contains(_staID)) {
408 _nmeaPortsMap.remove(_staID);
409 }
410 if (_nmeaServer) {
411 delete _nmeaServer;
412 }
413 if (_nmeaSockets) {
414 delete _nmeaSockets;
415 }
416
417#ifdef BNC_DEBUG
418 if (BNC_CORE->mode() != t_bncCore::interactive) {
419 while (!isFinished()) {
420 wait();
421 }
422 delete this;
423 } else {
424 if (!isRunning()) {
425 delete this;
426 }
427 }
428#else
429 if (!isRunning()) {delete this;}
430#endif
431
432}
433
434// Run
435////////////////////////////////////////////////////////////////////////////
436void bncGetThread::run() {
437
438 while (true) {
439 try {
440 if (_isToBeDeleted) {
441 emit(newMessage(_staID + ": is to be deleted", true));
442 QThread::exit(4);
443 this->deleteLater();
444 return;
445 }
446
447 if (tryReconnect() != success) {
448 if (_latencyChecker) {
449 _latencyChecker->checkReconnect();
450 }
451 continue;
452 }
453
454 // Delete old observations
455 // -----------------------
456 if (_rawFile) {
457 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
458 while (itDec.hasNext()) {
459 itDec.next();
460 GPSDecoder* decoder = itDec.value();
461 decoder->_obsList.clear();
462 }
463 } else {
464 _decoder->_obsList.clear();
465 }
466
467 // Read Data
468 // ---------
469 QByteArray data;
470 if (_query) {
471 _query->waitForReadyRead(data);
472 } else if (_rawFile) {
473 data = _rawFile->readChunk();
474 _format = _rawFile->format();
475 _staID = _rawFile->staID();
476
477 QCoreApplication::processEvents();
478
479 if (data.isEmpty() || BNC_CORE->sigintReceived) {
480 emit(newMessage("No more data or SIGINT/SIGTERM received", true));
481 BNC_CORE->stopPPP();
482 BNC_CORE->stopCombination();
483 sleep(2);
484 ::exit(5);
485 }
486 }
487
488 qint64 nBytes = data.size();
489
490 // Timeout, reconnect
491 // ------------------
492 if (nBytes == 0) {
493 if (_latencyChecker) {
494 _latencyChecker->checkReconnect();
495 }
496 emit(newMessage(_staID + ": Data timeout, reconnecting", true));
497 msleep(10000); //sleep 10 sec, G. Weber
498 continue;
499 } else {
500 emit newBytes(_staID, nBytes);
501 emit newRawData(_staID, data);
502 }
503
504 // Output Data
505 // -----------
506 if (_rawOutput) {
507 BNC_CORE->writeRawData(data, _staID, _format);
508 }
509
510 if (_serialPort) {
511 slotSerialReadyRead();
512 _serialPort->write(data);
513 }
514
515 // Decode Data
516 // -----------
517 vector<string> errmsg;
518 if (!decoder()) {
519 _isToBeDeleted = true;
520 continue;
521 }
522
523 t_irc irc = decoder()->Decode(data.data(), data.size(), errmsg);
524
525 if (irc != success) {
526 continue;
527 }
528 // Perform various scans and checks
529 // --------------------------------
530 if (_latencyChecker) {
531 _latencyChecker->checkOutage(irc);
532 QListIterator<int> it(decoder()->_typeList);
533 _ssrEpoch = static_cast<int>(decoder()->corrGPSEpochTime());
534 if (_ssrEpoch != -1) {
535 if (_rtcmSsrOrb) {
536 _latencyChecker->checkCorrLatency(_ssrEpoch, 1057);
537 _rtcmSsrOrb = false;
538 }
539 if (_rtcmSsrClk) {
540 _latencyChecker->checkCorrLatency(_ssrEpoch, 1058);
541 _rtcmSsrClk = false;
542 }
543 if (_rtcmSsrOrbClk) {
544 _latencyChecker->checkCorrLatency(_ssrEpoch, 1060);
545 _rtcmSsrOrbClk = false;
546 }
547 if (_rtcmSsrCbi) {
548 _latencyChecker->checkCorrLatency(_ssrEpoch, 1059);
549 _rtcmSsrCbi = false;
550 }
551 if (_rtcmSsrPbi) {
552 _latencyChecker->checkCorrLatency(_ssrEpoch, 1265);
553 _rtcmSsrPbi = false;
554 }
555 if (_rtcmSsrVtec) {
556 _latencyChecker->checkCorrLatency(_ssrEpoch, 1264);
557 _rtcmSsrVtec = false;
558 }
559 if (_rtcmSsrUra) {
560 _latencyChecker->checkCorrLatency(_ssrEpoch, 1061);
561 _rtcmSsrUra = false;
562 }
563 if (_rtcmSsrHr) {
564 _latencyChecker->checkCorrLatency(_ssrEpoch, 1062);
565 _rtcmSsrHr = false;
566 }
567 if (_rtcmSsrIgs) {
568 _latencyChecker->checkCorrLatency(_ssrEpoch, 4076);
569 _rtcmSsrIgs = false;
570 }
571 }
572 while (it.hasNext()) {
573 int rtcmType = it.next();
574 if ((rtcmType >= 1001 && rtcmType <= 1004) || // legacy RTCM OBS
575 (rtcmType >= 1009 && rtcmType <= 1012) || // legacy RTCM OBS
576 (rtcmType >= 1070 && rtcmType <= 1137)) { // MSM RTCM OBS
577 _rtcmObs = true;
578 } else if ((rtcmType >= 1057 && rtcmType <= 1068) ||
579 (rtcmType >= 1240 && rtcmType <= 1270) ||
580 (rtcmType == 4076)) {
581 switch (rtcmType) {
582 case 1057: case 1063: case 1240: case 1246: case 1252: case 1258:
583 _rtcmSsrOrb = true;
584 break;
585 case 1058: case 1064: case 1241: case 1247: case 1253: case 1259:
586 _rtcmSsrClk = true;
587 break;
588 case 1060: case 1066: case 1243: case 1249: case 1255: case 1261:
589 _rtcmSsrOrbClk = true;
590 break;
591 case 1059: case 1065: case 1242: case 1248: case 1254: case 1260:
592 _rtcmSsrCbi = true;
593 break;
594 case 1265: case 1266: case 1267: case 1268: case 1269: case 1270:
595 _rtcmSsrPbi = true;
596 break;
597 case 1264:
598 _rtcmSsrVtec = true;
599 break;
600 case 1061: case 1067: case 1244: case 1250: case 1256: case 1262:
601 _rtcmSsrUra = true;
602 break;
603 case 1062: case 1068: case 1245: case 1251: case 1257: case 1263:
604 _rtcmSsrHr = true;
605 break;
606 case 4076:
607 _rtcmSsrIgs = true;
608 break;
609 }
610 }
611 }
612 if (_rtcmObs) {
613 _latencyChecker->checkObsLatency(decoder()->_obsList);
614 }
615 emit newLatency(_staID, _latencyChecker->currentLatency());
616 }
617 miscScanRTCM();
618
619 // Loop over all observations (observations output)
620 // ------------------------------------------------
621 QListIterator<t_satObs> it(decoder()->_obsList);
622
623 QList<t_satObs> obsListHlp;
624
625 while (it.hasNext()) {
626 const t_satObs& obs = it.next();
627
628 // Check observation epoch
629 // -----------------------
630 if (!_rawFile) {
631 bool wrongObservationEpoch = checkForWrongObsEpoch(obs._time);
632 if (wrongObservationEpoch) {
633 QString prn(obs._prn.toString().c_str());
634 QString type = QString("%1").arg(obs._type);
635 emit(newMessage(_staID + " (" + prn.toLatin1() + ")" + ": Wrong observation epoch(s)" + "( MT: " + type.toLatin1() + ")", false));
636 continue;
637 }
638 }
639
640 // Check observations coming twice (e.g. KOUR0 Problem)
641 // ----------------------------------------------------
642 if (!_rawFile) {
643 QString prn(obs._prn.toString().c_str());
644 bncTime obsTime = obs._time;
645 QMap<QString, bncTime>::const_iterator it = _prnLastEpo.find(prn);
646 if (it != _prnLastEpo.end()) {
647 bncTime oldTime = it.value();
648 if (obsTime < oldTime) {
649 emit(newMessage(_staID + ": old observation " + prn.toLatin1(), false));
650 continue;
651 } else if (obsTime == oldTime) {
652 emit(newMessage(_staID + ": observation coming more than once " + prn.toLatin1(), false));
653 continue;
654 }
655 }
656 _prnLastEpo[prn] = obsTime;
657 }
658
659 decoder()->dumpRinexEpoch(obs, _format);
660
661 // Save observations
662 // -----------------
663 obsListHlp.append(obs);
664 }
665
666 // Emit signal
667 // -----------
668 if (!_isToBeDeleted && obsListHlp.size() > 0) {
669 emit newObs(_staID, obsListHlp);
670 }
671
672 } catch (Exception& exc) {
673 emit(newMessage(_staID + " " + exc.what(), true));
674 _isToBeDeleted = true;
675 } catch (...) {
676 emit(newMessage(_staID + " bncGetThread exception", true));
677 _isToBeDeleted = true;
678 }
679 }
680}
681
682// Try Re-Connect
683////////////////////////////////////////////////////////////////////////////
684t_irc bncGetThread::tryReconnect() {
685
686 // Easy Return
687 // -----------
688 if (_query && _query->status() == bncNetQuery::running) {
689 _nextSleep = 0;
690 if (_rawFile) {
691 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
692 while (itDec.hasNext()) {
693 itDec.next();
694 GPSDecoder* decoder = itDec.value();
695 decoder->setRinexReconnectFlag(false);
696 }
697 } else {
698 _decoder->setRinexReconnectFlag(false);
699 }
700 return success;
701 }
702
703 // Start a new query
704 // -----------------
705 if (!_rawFile) {
706
707 sleep(_nextSleep);
708 if (_nextSleep == 0) {
709 _nextSleep = 1;
710 } else {
711 _nextSleep = 2 * _nextSleep;
712 if (_nextSleep > 256) {
713 _nextSleep = 256;
714 }
715#ifdef MLS_SOFTWARE
716 if (_nextSleep > 4) {
717 _nextSleep = 4;
718 }
719#endif
720 }
721 delete _query;
722 if (_ntripVersion == "U") {
723 _query = new bncNetQueryUdp();
724 } else if (_ntripVersion == "R") {
725 _query = new bncNetQueryRtp();
726 } else if (_ntripVersion == "S") {
727 _query = new bncNetQueryS();
728 } else if (_ntripVersion == "N") {
729 _query = new bncNetQueryV0();
730 } else if (_ntripVersion == "UN") {
731 _query = new bncNetQueryUdp0();
732 } else if (_ntripVersion == "2") {
733 _query = new bncNetQueryV2(false);
734 } else if (_ntripVersion == "2s") {
735 _query = new bncNetQueryV2(true);
736 } else {
737 _query = new bncNetQueryV1();
738 }
739 if (_nmea == "yes") {
740 if (_serialNMEA == MANUAL_NMEA) {
741 _query->startRequest(_mountPoint, _manualNMEAString);
742 _lastNMEA = QDateTime::currentDateTime();
743 } else if (_serialNMEA == AUTO_NMEA) {
744 if (_serialPort) {
745 int nb = _serialPort->bytesAvailable();
746 if (nb > 0) {
747 QByteArray data = _serialPort->read(nb);
748 int i1 = data.indexOf("$GPGGA");
749 if (i1 == -1) {
750 i1 = data.indexOf("$GNGGA");
751 }
752 if (i1 != -1) {
753 int i2 = data.indexOf("*", i1);
754 if (i2 != -1 && data.size() > i2 + 1) {
755 QByteArray gga = data.mid(i1, i2 - i1 + 3);
756 _query->startRequest(_mountPoint, gga);
757 _lastNMEA = QDateTime::currentDateTime();
758 }
759 }
760 }
761 }
762 }
763 } else {
764 _query->startRequest(_mountPoint, "");
765 }
766
767 if (_query->status() != bncNetQuery::running) {
768 return failure;
769 }
770 }
771
772 if (_rawFile) {
773 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
774 while (itDec.hasNext()) {
775 itDec.next();
776 GPSDecoder* decoder = itDec.value();
777 decoder->setRinexReconnectFlag(false);
778 }
779 } else {
780 _decoder->setRinexReconnectFlag(false);
781 }
782
783 return success;
784}
785
786// RTCM scan output
787//////////////////////////////////////////////////////////////////////////////
788void bncGetThread::miscScanRTCM() {
789
790 if (!decoder()) {
791 return;
792 }
793
794 bncSettings settings;
795 if (Qt::CheckState(settings.value("miscScanRTCM").toInt()) == Qt::Checked) {
796
797 if (_miscMount == _staID || _miscMount == "ALL") {
798 // RTCM message types
799 // ------------------
800 for (int ii = 0; ii < decoder()->_typeList.size(); ii++) {
801 QString type = QString("%1 ").arg(decoder()->_typeList[ii]);
802 emit(newMessage(_staID + ": Received message type " + type.toLatin1(), true));
803 }
804
805 // Check Observation Types
806 // -----------------------
807 for (int ii = 0; ii < decoder()->_obsList.size(); ii++) {
808 t_satObs& obs = decoder()->_obsList[ii];
809 QVector<QString>& rnxTypes = _rnxTypes[obs._prn.system()];
810 bool allFound = true;
811 for (unsigned iFrq = 0; iFrq < obs._obs.size(); iFrq++) {
812 if (obs._obs[iFrq]->_codeValid) {
813 QString rnxStr('C');
814 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
815 if (_format.indexOf("RTCM_2") != -1
816 || _format.indexOf("RTCM2") != -1
817 || _format.indexOf("RTCM 2") != -1) {
818 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
819 }
820 if (rnxTypes.indexOf(rnxStr) == -1) {
821 rnxTypes.push_back(rnxStr);
822 allFound = false;
823 }
824 }
825 if (obs._obs[iFrq]->_phaseValid) {
826 QString rnxStr('L');
827 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
828 if (_format.indexOf("RTCM_2") != -1
829 || _format.indexOf("RTCM2") != -1
830 || _format.indexOf("RTCM 2") != -1) {
831 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
832 }
833 if (rnxTypes.indexOf(rnxStr) == -1) {
834 rnxTypes.push_back(rnxStr);
835 allFound = false;
836 }
837 }
838 if (obs._obs[iFrq]->_dopplerValid) {
839 QString rnxStr('D');
840 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
841 if (_format.indexOf("RTCM_2") != -1
842 || _format.indexOf("RTCM2") != -1
843 || _format.indexOf("RTCM 2") != -1) {
844 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
845 }
846 if (rnxTypes.indexOf(rnxStr) == -1) {
847 rnxTypes.push_back(rnxStr);
848 allFound = false;
849 }
850 }
851 if (obs._obs[iFrq]->_snrValid) {
852 QString rnxStr('S');
853 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
854 if (_format.indexOf("RTCM_2") != -1
855 || _format.indexOf("RTCM2") != -1
856 || _format.indexOf("RTCM 2") != -1) {
857 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
858 }
859 if (rnxTypes.indexOf(rnxStr) == -1) {
860 rnxTypes.push_back(rnxStr);
861 allFound = false;
862 }
863 }
864 }
865 if (!allFound) {
866 QString msg;
867 QTextStream str(&msg);
868 str << obs._prn.system() << QString(" %1 ").arg(rnxTypes.size());
869 for (int iType = 0; iType < rnxTypes.size(); iType++) {
870 str << " " << rnxTypes[iType];
871 }
872 emit(newMessage(_staID + ": Observation Types: " + msg.toLatin1(),
873 true));
874 }
875 }
876
877 // RTCMv3 antenna descriptor
878 // -------------------------
879 for (int ii = 0; ii < decoder()->_antType.size(); ii++) {
880 QString ant1 = QString(": Antenna Descriptor: %1 ").arg(decoder()->_antType[ii].descriptor);
881 emit(newMessage(_staID + ant1.toLatin1(), true));
882 if (strlen(decoder()->_antType[ii].serialnumber)) {
883 QString ant2 = QString(": Antenna Serial Number: %1 ").arg(decoder()->_antType[ii].serialnumber);
884 emit(newMessage(_staID + ant2.toLatin1(), true));
885 }
886 }
887
888 // RTCM Antenna Coordinates
889 // ------------------------
890 for (int ii = 0; ii < decoder()->_antList.size(); ii++) {
891 QByteArray antT;
892 if (decoder()->_antList[ii].type == GPSDecoder::t_antRefPoint::ARP) {
893 antT = "ARP";
894 } else if (decoder()->_antList[ii].type == GPSDecoder::t_antRefPoint::APC) {
895 antT = "APC";
896 }
897 QByteArray ant1, ant2, ant3;
898 ant1 = QString("%1 ").arg(decoder()->_antList[ii].xx, 0, 'f', 4).toLatin1();
899 ant2 = QString("%1 ").arg(decoder()->_antList[ii].yy, 0, 'f', 4).toLatin1();
900 ant3 = QString("%1 ").arg(decoder()->_antList[ii].zz, 0, 'f', 4).toLatin1();
901 emit(newMessage(_staID + ": " + antT + " (ITRF) X " + ant1 + "m", true));
902 emit(newMessage(_staID + ": " + antT + " (ITRF) Y " + ant2 + "m", true));
903 emit(newMessage(_staID + ": " + antT + " (ITRF) Z " + ant3 + "m", true));
904 double hh = 0.0;
905 if (decoder()->_antList[ii].height_f) {
906 hh = decoder()->_antList[ii].height;
907 QByteArray ant4 = QString("%1 ").arg(hh, 0, 'f', 4).toLatin1();
908 emit(newMessage(
909 _staID + ": Antenna height above marker " + ant4 + "m", true));
910 }
911 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
912 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz, hh, antT));
913 }
914
915 // RTCMv3 receiver descriptor
916 // --------------------------
917 for (int ii = 0; ii < decoder()->_recType.size(); ii++) {
918 QString rec1 = QString(": Receiver Descriptor: %1 ").arg(decoder()->_recType[ii].descriptor);
919 QString rec2 = QString(": Receiver Firmware Version: %1 ").arg(decoder()->_recType[ii].firmware);
920 QString rec3 = QString(": Receiver Serial Number: %1 ").arg(decoder()->_recType[ii].serialnumber);
921 emit(newMessage(_staID + rec1.toLatin1(), true));
922 emit(newMessage(_staID + rec2.toLatin1(), true));
923 emit(newMessage(_staID + rec3.toLatin1(), true));
924 }
925
926 // RTCM GLONASS slots
927 // ------------------
928 if (decoder()->_gloFrq.size()) {
929 bool allFound = true;
930 QString slot = decoder()->_gloFrq;
931 slot.replace(" ", " ").replace(" ", ":");
932 if (_gloSlots.indexOf(slot) == -1) {
933 _gloSlots.append(slot);
934 allFound = false;
935 }
936 if (!allFound) {
937 _gloSlots.sort();
938 emit(newMessage(
939 _staID + ": GLONASS Slot:Freq " + _gloSlots.join(" ").toLatin1(),
940 true));
941 }
942 }
943 // Service CRS
944 // -----------
945 for (int ii = 0; ii < decoder()->_serviceCrs.size(); ii++) {
946 QString servicecrsname = QString(": Servive CRS Name: %1 ").arg(decoder()->_serviceCrs[ii]._name);
947 QString coordinateEpoch = QString(": Coordinate Epoch: %1 ").arg(decoder()->_serviceCrs[ii]._coordinateEpoch);
948 QString ce = QString(": CE: %1 ").arg(decoder()->_serviceCrs[ii]._CE);
949 emit(newMessage(_staID + servicecrsname.toLatin1(), true));
950 emit(newMessage(_staID + coordinateEpoch.toLatin1(), true));
951 emit(newMessage(_staID + ce.toLatin1(), true));
952 }
953
954 // RTCM CRS
955 // -----------
956 for (int ii = 0; ii < decoder()->_rtcmCrs.size(); ii++) {
957 QString rtcmcrsname = QString(": RTCM CRS Name: %1 ").arg(decoder()->_rtcmCrs[ii]._name);
958 QString anchor = QString(": Anchor: %1 ").arg(decoder()->_rtcmCrs[ii]._anchor);
959 QString platenumber = QString(": Plate Number: %1 ").arg(decoder()->_rtcmCrs[ii]._plateNumber);
960 emit(newMessage(_staID + rtcmcrsname.toLatin1(), true));
961 emit(newMessage(_staID + anchor.toLatin1(), true));
962 emit(newMessage(_staID + platenumber.toLatin1(), true));
963 for (int i = 0; i<decoder()->_rtcmCrs[ii]._databaseLinks.size(); i++) {
964 QString dblink = QString(": Database Link: %1 ").arg(decoder()->_rtcmCrs[ii]._databaseLinks[i]);
965 emit(newMessage(_staID + dblink.toLatin1(), true));
966 }
967 }
968
969 // Helmert Parameters
970 //-------------------
971 for (int ii = 0; ii < decoder()->_helmertPar.size(); ii++) {
972 t_helmertPar& helmertPar = decoder()->_helmertPar[ii];
973 bncTime t; t.setmjd(0, helmertPar._t0); QString dateStr = QString::fromStdString(t.datestr());
974 QString sourcename = QString(": MT1301 Source Name: %1 ").arg(helmertPar._sourceName);
975 QString targetname = QString(": MT1301 Target Name: %1 ").arg(helmertPar._targetName);
976 QString sysidentnum = QString(": MT1301 Sys Ident Num: %1 ").arg(helmertPar._sysIdentNum);
977 QString trafomessageind = QString(": MT1301 Trafo Ident Num: %1 ").arg(helmertPar.IndtoString());
978 QString epoch = QString(": MT1301 t0: MJD %1 (%2) ").arg(helmertPar._t0).arg(dateStr);
979 QString partrans = QString(": MT1301 Helmert Par Trans: dx = %1, dy = %2, dz = %3, dxr = %4, dyr = %5, dzr = %6")
980 .arg(helmertPar._dx).arg(helmertPar._dy).arg(helmertPar._dz)
981 .arg(helmertPar._dxr).arg(helmertPar._dyr).arg(helmertPar._dzr);
982 QString parrot = QString(": MT1301 Helmert Par Rot: ox = %1, oy = %2, oz = %3, oxr = %4, oyr = %5, ozr = %6")
983 .arg(helmertPar._ox).arg(helmertPar._oy).arg(helmertPar._oz)
984 .arg(helmertPar._oxr).arg(helmertPar._oyr).arg(helmertPar._ozr);
985 QString parscale = QString(": MT1301 Helmert Par Scale: sc = %1, scr = %2").arg(helmertPar._sc).arg(helmertPar._scr);
986 emit(newMessage(_staID + sourcename.toLatin1(), true));
987 emit(newMessage(_staID + targetname.toLatin1(), true));
988 emit(newMessage(_staID + sysidentnum.toLatin1(), true));
989 emit(newMessage(_staID + trafomessageind.toLatin1(), true));
990 emit(newMessage(_staID + epoch.toLatin1(), true));
991 emit(newMessage(_staID + partrans.toLatin1(), true));
992 emit(newMessage(_staID + parrot.toLatin1(), true));
993 emit(newMessage(_staID + parscale.toLatin1(), true));
994 }
995 }
996 }
997
998#ifdef MLS_SOFTWARE
999 for (int ii=0; ii <decoder()->_antList.size(); ii++) {
1000 QByteArray antT;
1001 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
1002 antT = "ARP";
1003 }
1004 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
1005 antT = "APC";
1006 }
1007 double hh = 0.0;
1008 if (decoder()->_antList[ii].height_f) {
1009 hh = decoder()->_antList[ii].height;
1010 }
1011 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
1012 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
1013 hh, antT));
1014 }
1015
1016 for (int ii = 0; ii <decoder()->_typeList.size(); ii++) {
1017 emit(newRTCMMessage(_staID, decoder()->_typeList[ii]));
1018 }
1019#endif
1020
1021 decoder()->_gloFrq.clear();
1022 decoder()->_typeList.clear();
1023 decoder()->_antType.clear();
1024 decoder()->_recType.clear();
1025 decoder()->_antList.clear();
1026}
1027
1028// Handle Data from Serial Port
1029////////////////////////////////////////////////////////////////////////////
1030void bncGetThread::slotSerialReadyRead() {
1031
1032 if (_serialPort) {
1033
1034 if (_nmea == "yes" && _serialNMEA == MANUAL_NMEA) {
1035 if (_NMEASampl) {
1036 int dt = _lastNMEA.secsTo(QDateTime::currentDateTime());
1037 if (dt && (fmod(double(dt), double(_NMEASampl)) == 0.0)) {
1038 _query->sendNMEA(_manualNMEAString);
1039 _lastNMEA = QDateTime::currentDateTime();
1040 }
1041 }
1042 }
1043
1044 int nb = _serialPort->bytesAvailable();
1045 if (nb > 0) {
1046 QByteArray data = _serialPort->read(nb);
1047
1048 if (_nmea == "yes" && _serialNMEA == AUTO_NMEA) {
1049 int i1 = data.indexOf("$GPGGA");
1050 if (i1 == -1) {
1051 i1 = data.indexOf("$GNGGA");
1052 }
1053 if (i1 != -1) {
1054 int i2 = data.indexOf("*", i1);
1055 if (i2 != -1 && data.size() > i2 + 1) {
1056 QByteArray gga = data.mid(i1, i2 - i1 + 3);
1057 if (_NMEASampl) {
1058 int dt = _lastNMEA.secsTo(QDateTime::currentDateTime());
1059 if (dt && (fmod(double(dt), double(_NMEASampl)) == 0.0)) {
1060 _query->sendNMEA(gga);
1061 _lastNMEA = QDateTime::currentDateTime();
1062 }
1063 }
1064 }
1065 }
1066 }
1067
1068 if (_serialOutFile) {
1069 _serialOutFile->write(data);
1070 _serialOutFile->flush();
1071 }
1072 }
1073 }
1074}
1075
1076void bncGetThread::slotNewNMEAConnection() {
1077 _nmeaSockets->push_back(_nmeaServer->nextPendingConnection());
1078 emit(newMessage(
1079 QString("New PPP client on port: # %1").arg(_nmeaSockets->size()).toLatin1(),
1080 true));
1081}
1082
1083//
1084////////////////////////////////////////////////////////////////////////////
1085void bncGetThread::slotNewNMEAstr(QByteArray staID, QByteArray str) {
1086 if (_nmeaPortsMap.contains(staID)) {
1087 int nmeaPort = _nmeaPortsMap.value(staID);
1088 QMutableListIterator<QTcpSocket*> is(*_nmeaSockets);
1089 while (is.hasNext()) {
1090 QTcpSocket* sock = is.next();
1091 if (sock->localPort() == nmeaPort) {
1092 if (sock->state() == QAbstractSocket::ConnectedState) {
1093 sock->write(str);
1094 } else if (sock->state() != QAbstractSocket::ConnectingState) {
1095 delete sock;
1096 is.remove();
1097 }
1098 }
1099 }
1100 }
1101}
Note: See TracBrowser for help on using the repository browser.