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

Last change on this file since 10768 was 10766, checked in by stuerze, 11 months ago

external class QextSerialPort was replaced by Qt5 internal class QSerialPort, serial port is now introduced as case sensitive

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