source: ntrip/branches/BNC_2.12/src/bncgetthread.cpp@ 8012

Last change on this file since 8012 was 8012, checked in by stuerze, 10 years ago

check regarding wrong observation epochs is done in latencychecker as well to prevent erroneous latencies

File size: 27.4 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 <iomanip>
43#include <sstream>
44
45#include <QFile>
46#include <QTextStream>
47#include <QMutex>
48#include <QtNetwork>
49#include <QTime>
50
51#include "bncgetthread.h"
52#include "bnctabledlg.h"
53#include "bnccore.h"
54#include "bncutils.h"
55#include "bnczerodecoder.h"
56#include "bncnetqueryv0.h"
57#include "bncnetqueryv1.h"
58#include "bncnetqueryv2.h"
59#include "bncnetqueryrtp.h"
60#include "bncnetqueryudp.h"
61#include "bncnetqueryudp0.h"
62#include "bncnetquerys.h"
63#include "bncsettings.h"
64#include "latencychecker.h"
65#include "upload/bncrtnetdecoder.h"
66#include "RTCM/RTCM2Decoder.h"
67#include "RTCM3/RTCM3Decoder.h"
68#include "serial/qextserialport.h"
69
70using namespace std;
71
72// Constructor 1
73////////////////////////////////////////////////////////////////////////////
74bncGetThread::bncGetThread(bncRawFile* rawFile) {
75
76 _rawFile = rawFile;
77 _format = rawFile->format();
78 _staID = rawFile->staID();
79 _rawOutput = false;
80 _ntripVersion = "N";
81
82 initialize();
83}
84
85// Constructor 2
86////////////////////////////////////////////////////////////////////////////
87bncGetThread::bncGetThread(const QUrl& mountPoint,
88 const QByteArray& format,
89 const QByteArray& latitude,
90 const QByteArray& longitude,
91 const QByteArray& nmea,
92 const QByteArray& ntripVersion) {
93 _rawFile = 0;
94 _mountPoint = mountPoint;
95 _staID = mountPoint.path().mid(1).toAscii();
96 _format = format;
97 _latitude = latitude;
98 _longitude = longitude;
99 _nmea = nmea;
100 _ntripVersion = ntripVersion;
101
102 bncSettings settings;
103 if (!settings.value("rawOutFile").toString().isEmpty()) {
104 _rawOutput = true;
105 } else {
106 _rawOutput = false;
107 }
108
109 initialize();
110 initDecoder();
111}
112
113// Initialization (common part of the constructor)
114////////////////////////////////////////////////////////////////////////////
115void bncGetThread::initialize() {
116
117 bncSettings settings;
118
119 setTerminationEnabled(true);
120
121 connect(this, SIGNAL(newMessage(QByteArray,bool)),
122 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
123
124 _isToBeDeleted = false;
125 _query = 0;
126 _nextSleep = 0;
127 _miscMount = settings.value("miscMount").toString();
128 _decoder = 0;
129
130 // NMEA Port
131 // -----------
132 QListIterator<QString> iSta(settings.value("PPP/staTable").toStringList());
133 int nmeaPort = 0;
134 while (iSta.hasNext()) {
135 QStringList hlp = iSta.next().split(",");
136 if (hlp.size() < 10) {continue;}
137 QByteArray mp = hlp[0].toAscii();
138 if (_staID == mp) {
139 nmeaPort = hlp[9].toInt();
140 }
141 }
142 if (nmeaPort != 0) {
143 _nmeaServer = new QTcpServer;
144 if ( !_nmeaServer->listen(QHostAddress::Any, nmeaPort) ) {
145 emit newMessage("bncCaster: Cannot listen on port", true);
146 }
147 else {
148 connect(_nmeaServer, SIGNAL(newConnection()), this, SLOT(slotNewNMEAConnection()));
149 connect(BNC_CORE, SIGNAL(newNMEAstr(QByteArray, QByteArray)),
150 this, SLOT(slotNewNMEAstr(QByteArray, QByteArray)));
151 _nmeaSockets = new QList<QTcpSocket*>;
152 _nmeaPortsMap[_staID] = nmeaPort;
153 }
154 } else {
155 _nmeaServer = 0;
156 _nmeaSockets = 0;
157 }
158
159 // Serial Port
160 // -----------
161 _serialNMEA = NO_NMEA;
162 _serialOutFile = 0;
163 _serialPort = 0;
164
165 if (!_staID.isEmpty() &&
166 settings.value("serialMountPoint").toString() == _staID) {
167 _serialPort = new QextSerialPort(settings.value("serialPortName").toString() );
168 _serialPort->setTimeout(0,100);
169
170 // Baud Rate
171 // ---------
172 QString hlp = settings.value("serialBaudRate").toString();
173 if (hlp == "110") {
174 _serialPort->setBaudRate(BAUD110);
175 }
176 else if (hlp == "300") {
177 _serialPort->setBaudRate(BAUD300);
178 }
179 else if (hlp == "600") {
180 _serialPort->setBaudRate(BAUD600);
181 }
182 else if (hlp == "1200") {
183 _serialPort->setBaudRate(BAUD1200);
184 }
185 else if (hlp == "2400") {
186 _serialPort->setBaudRate(BAUD2400);
187 }
188 else if (hlp == "4800") {
189 _serialPort->setBaudRate(BAUD4800);
190 }
191 else if (hlp == "9600") {
192 _serialPort->setBaudRate(BAUD9600);
193 }
194 else if (hlp == "19200") {
195 _serialPort->setBaudRate(BAUD19200);
196 }
197 else if (hlp == "38400") {
198 _serialPort->setBaudRate(BAUD38400);
199 }
200 else if (hlp == "57600") {
201 _serialPort->setBaudRate(BAUD57600);
202 }
203 else if (hlp == "115200") {
204 _serialPort->setBaudRate(BAUD115200);
205 }
206
207 // Parity
208 // ------
209 hlp = settings.value("serialParity").toString();
210 if (hlp == "NONE") {
211 _serialPort->setParity(PAR_NONE);
212 }
213 else if (hlp == "ODD") {
214 _serialPort->setParity(PAR_ODD);
215 }
216 else if (hlp == "EVEN") {
217 _serialPort->setParity(PAR_EVEN);
218 }
219 else if (hlp == "SPACE") {
220 _serialPort->setParity(PAR_SPACE);
221 }
222
223 // Data Bits
224 // ---------
225 hlp = settings.value("serialDataBits").toString();
226 if (hlp == "5") {
227 _serialPort->setDataBits(DATA_5);
228 }
229 else if (hlp == "6") {
230 _serialPort->setDataBits(DATA_6);
231 }
232 else if (hlp == "7") {
233 _serialPort->setDataBits(DATA_7);
234 }
235 else if (hlp == "8") {
236 _serialPort->setDataBits(DATA_8);
237 }
238 hlp = settings.value("serialStopBits").toString();
239 if (hlp == "1") {
240 _serialPort->setStopBits(STOP_1);
241 }
242 else if (hlp == "2") {
243 _serialPort->setStopBits(STOP_2);
244 }
245
246 // Flow Control
247 // ------------
248 hlp = settings.value("serialFlowControl").toString();
249 if (hlp == "XONXOFF") {
250 _serialPort->setFlowControl(FLOW_XONXOFF);
251 }
252 else if (hlp == "HARDWARE") {
253 _serialPort->setFlowControl(FLOW_HARDWARE);
254 }
255 else {
256 _serialPort->setFlowControl(FLOW_OFF);
257 }
258
259 // Open Serial Port
260 // ----------------
261 _serialPort->open(QIODevice::ReadWrite|QIODevice::Unbuffered);
262 if (!_serialPort->isOpen()) {
263 delete _serialPort;
264 _serialPort = 0;
265 emit(newMessage((_staID + ": Cannot open serial port\n"), true));
266 }
267 connect(_serialPort, SIGNAL(readyRead()),
268 this, SLOT(slotSerialReadyRead()));
269
270 // Automatic NMEA
271 // --------------
272 QString nmeaMode = settings.value("serialAutoNMEA").toString();
273 if (nmeaMode == "Auto") {
274 _serialNMEA = AUTO_NMEA;
275 QString fName = settings.value("serialFileNMEA").toString();
276 if (!fName.isEmpty()) {
277 _serialOutFile = new QFile(fName);
278 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
279 _serialOutFile->open(QIODevice::WriteOnly | QIODevice::Append);
280 }
281 else {
282 _serialOutFile->open(QIODevice::WriteOnly);
283 }
284 }
285 }
286 // Manual NMEA
287 // -----------
288 if ((nmeaMode == "Manual GPGGA") ||(nmeaMode == "Manual GNGGA")) {
289 _serialNMEA = MANUAL_NMEA;
290 bncSettings settings;
291 _manualNMEASampl = settings.value("serialManualNMEASampling").toInt();
292 QString hlp = settings.value("serialHeightNMEA").toString();
293 if (hlp.isEmpty()) {
294 hlp = "0.0";
295 }
296 QByteArray _serialHeightNMEA = hlp.toAscii();
297 _manualNMEAString = ggaString(_latitude, _longitude, _serialHeightNMEA, nmeaMode);
298 }
299 }
300
301 if (!_staID.isEmpty()) {
302 _latencyChecker = new latencyChecker(_staID);
303 }
304 else {
305 _latencyChecker = 0;
306 }
307}
308
309// Instantiate the decoder
310//////////////////////////////////////////////////////////////////////////////
311t_irc bncGetThread::initDecoder() {
312
313 _decoder = 0;
314
315 if (_format.indexOf("RTCM_2") != -1 || _format.indexOf("RTCM2") != -1 ||
316 _format.indexOf("RTCM 2") != -1 ) {
317 emit(newMessage(_staID + ": Get data in RTCM 2.x format", true));
318 _decoder = new RTCM2Decoder(_staID.data());
319 }
320 else if (_format.indexOf("RTCM_3") != -1 || _format.indexOf("RTCM3") != -1 ||
321 _format.indexOf("RTCM 3") != -1 ) {
322 emit(newMessage(_staID + ": Get data in RTCM 3.x format", true));
323 RTCM3Decoder* newDecoder = new RTCM3Decoder(_staID, _rawFile);
324 _decoder = newDecoder;
325 connect((RTCM3Decoder*) newDecoder, SIGNAL(newMessage(QByteArray,bool)),
326 this, SIGNAL(newMessage(QByteArray,bool)));
327 }
328 else if (_format.indexOf("ZERO") != -1) {
329 emit(newMessage(_staID + ": Get data in original format", true));
330 _decoder = new bncZeroDecoder(_staID);
331 }
332 else if (_format.indexOf("RTNET") != -1) {
333 emit(newMessage(_staID + ": Get data in RTNet format", true));
334 _decoder = new bncRtnetDecoder();
335 }
336 else {
337 emit(newMessage(_staID + ": Unknown data format " + _format, true));
338 _isToBeDeleted = true;
339 return failure;
340 }
341
342 msleep(100); //sleep 0.1 sec
343
344 _decoder->initRinex(_staID, _mountPoint, _latitude, _longitude,
345 _nmea, _ntripVersion);
346
347 if (_rawFile) {
348 _decodersRaw[_staID] = _decoder;
349 }
350
351 return success;
352}
353
354// Current decoder in use
355////////////////////////////////////////////////////////////////////////////
356GPSDecoder* bncGetThread::decoder() {
357 if (!_rawFile) {
358 return _decoder;
359 }
360 else {
361 if (_decodersRaw.contains(_staID) || initDecoder() == success) {
362 return _decodersRaw[_staID];
363 }
364 }
365 return 0;
366}
367
368// Destructor
369////////////////////////////////////////////////////////////////////////////
370bncGetThread::~bncGetThread() {
371 if (isRunning()) {
372 wait();
373 }
374 if (_query) {
375 _query->stop();
376 _query->deleteLater();
377 }
378 if (_rawFile) {
379 QMapIterator<QString, GPSDecoder*> it(_decodersRaw);
380 while (it.hasNext()) {
381 it.next();
382 delete it.value();
383 }
384 }
385 else {
386 delete _decoder;
387 }
388 delete _rawFile;
389 delete _serialOutFile;
390 delete _serialPort;
391 delete _latencyChecker;
392 emit getThreadFinished(_staID);
393}
394
395//
396////////////////////////////////////////////////////////////////////////////
397void bncGetThread::terminate() {
398 _isToBeDeleted = true;
399
400 if(_nmeaPortsMap.contains(_staID)) {
401 _nmeaPortsMap.remove(_staID);
402 }
403 if (_nmeaServer) {
404 delete _nmeaServer;
405 }
406 if (_nmeaSockets) {
407 delete _nmeaSockets;
408 }
409
410#ifdef BNC_DEBUG
411 if (BNC_CORE->mode() != t_bncCore::interactive) {
412 while (!isFinished()) {wait();}
413 delete this;
414 }
415 else {
416 if (!isRunning()) {delete this;}
417 }
418#else
419 if (!isRunning()) {delete this;}
420#endif
421
422}
423
424// Run
425////////////////////////////////////////////////////////////////////////////
426void bncGetThread::run() {
427
428 while (true) {
429 try {
430 if (_isToBeDeleted) {
431 QThread::exit(0);
432 this->deleteLater();
433 return;
434 }
435
436 if (tryReconnect() != success) {
437 if (_latencyChecker) {
438 _latencyChecker->checkReconnect();
439 }
440 continue;
441 }
442
443 // Delete old observations
444 // -----------------------
445 if (_rawFile) {
446 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
447 while (itDec.hasNext()) {
448 itDec.next();
449 GPSDecoder* decoder = itDec.value();
450 decoder->_obsList.clear();
451 }
452 }
453 else {
454 _decoder->_obsList.clear();
455 }
456
457 // Read Data
458 // ---------
459 QByteArray data;
460 if (_query) {
461 _query->waitForReadyRead(data);
462 }
463 else if (_rawFile) {
464 data = _rawFile->readChunk();
465 _format = _rawFile->format();
466 _staID = _rawFile->staID();
467
468 QCoreApplication::processEvents();
469
470 if (data.isEmpty() || BNC_CORE->sigintReceived) {
471 cout << "no more data or Ctrl-C received" << endl;
472 BNC_CORE->stopCombination();
473 BNC_CORE->stopPPP();
474 ::exit(0);
475 }
476 }
477 qint64 nBytes = data.size();
478
479 // Timeout, reconnect
480 // ------------------
481 if (nBytes == 0) {
482 if (_latencyChecker) {
483 _latencyChecker->checkReconnect();
484 }
485 emit(newMessage(_staID + ": Data timeout, reconnecting", true));
486 msleep(10000); //sleep 10 sec, G. Weber
487 continue;
488 }
489 else {
490 emit newBytes(_staID, nBytes);
491 emit newRawData(_staID, data);
492 }
493
494 // Output Data
495 // -----------
496 if (_rawOutput) {
497 BNC_CORE->writeRawData(data, _staID, _format);
498 }
499
500 if (_serialPort) {
501 slotSerialReadyRead();
502 _serialPort->write(data);
503 }
504
505 // Decode Data
506 // -----------
507 vector<string> errmsg;
508 if (!decoder()) {
509 _isToBeDeleted = true;
510 continue;
511 }
512
513 t_irc irc = decoder()->Decode(data.data(), data.size(), errmsg);
514
515 if (irc != success) {
516 continue;
517 }
518 // Perform various scans and checks
519 // --------------------------------
520 if (_latencyChecker) {
521 _latencyChecker->checkOutage(irc == success);
522 _latencyChecker->checkObsLatency(decoder()->_obsList);
523 _latencyChecker->checkCorrLatency(decoder()->corrGPSEpochTime());
524
525 emit newLatency(_staID, _latencyChecker->currentLatency());
526 }
527
528 miscScanRTCM();
529
530 // Loop over all observations (observations output)
531 // ------------------------------------------------
532 QListIterator<t_satObs> it(decoder()->_obsList);
533
534 QList<t_satObs> obsListHlp;
535
536 while (it.hasNext()) {
537 const t_satObs& obs = it.next();
538
539 // Check observation epoch
540 // -----------------------
541 if (!_rawFile) {
542 bool wrongObservationEpoch = checkForWrongObsEpoch(obs._time);
543 if (wrongObservationEpoch) {
544 emit( newMessage(_staID + ": Wrong observation epoch(s)", false) );
545 continue;
546 }
547 }
548
549 // Check observations coming twice (e.g. KOUR0 Problem)
550 // ----------------------------------------------------
551 if (!_rawFile) {
552 QString prn(obs._prn.toString().c_str());
553 long iSec = long(floor(obs._time.gpssec()+0.5));
554 long obsTime = obs._time.gpsw()*7*24*3600 + iSec;
555 QMap<QString, long>::const_iterator it = _prnLastEpo.find(prn);
556 if (it != _prnLastEpo.end()) {
557 long oldTime = it.value();
558 if (obsTime < oldTime) {
559 emit( newMessage(_staID +
560 ": old observation " + prn.toAscii(), false));
561 continue;
562 }
563 else if (obsTime == oldTime) {
564 emit( newMessage(_staID +
565 ": observation coming more than once " + prn.toAscii(), false));
566 continue;
567 }
568 }
569 _prnLastEpo[prn] = obsTime;
570 }
571
572 decoder()->dumpRinexEpoch(obs, _format);
573
574 // Save observations
575 // -----------------
576 obsListHlp.append(obs);
577 }
578
579 // Emit signal
580 // -----------
581 if (!_isToBeDeleted && obsListHlp.size() > 0) {
582 emit newObs(_staID, obsListHlp);
583 }
584
585 }
586 catch (Exception& exc) {
587 emit(newMessage(_staID + " " + exc.what(), true));
588 _isToBeDeleted = true;
589 }
590 catch (...) {
591 emit(newMessage(_staID + " bncGetThread exception", true));
592 _isToBeDeleted = true;
593 }
594 }
595}
596
597// Try Re-Connect
598////////////////////////////////////////////////////////////////////////////
599t_irc bncGetThread::tryReconnect() {
600
601 // Easy Return
602 // -----------
603 if (_query && _query->status() == bncNetQuery::running) {
604 _nextSleep = 0;
605 if (_rawFile) {
606 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
607 while (itDec.hasNext()) {
608 itDec.next();
609 GPSDecoder* decoder = itDec.value();
610 decoder->setRinexReconnectFlag(false);
611 }
612 }
613 else {
614 _decoder->setRinexReconnectFlag(false);
615 }
616 return success;
617 }
618
619 // Start a new query
620 // -----------------
621 if (!_rawFile) {
622
623 sleep(_nextSleep);
624 if (_nextSleep == 0) {
625 _nextSleep = 1;
626 }
627 else {
628 _nextSleep = 2 * _nextSleep;
629 if (_nextSleep > 256) {
630 _nextSleep = 256;
631 }
632#ifdef MLS_SOFTWARE
633 if (_nextSleep > 4) {
634 _nextSleep = 4;
635 }
636#endif
637 }
638 if (_query) {
639 delete _query;
640 }
641 if (_ntripVersion == "U") {
642 _query = new bncNetQueryUdp();
643 }
644 else if (_ntripVersion == "R") {
645 _query = new bncNetQueryRtp();
646 }
647 else if (_ntripVersion == "S") {
648 _query = new bncNetQueryS();
649 }
650 else if (_ntripVersion == "N") {
651 _query = new bncNetQueryV0();
652 }
653 else if (_ntripVersion == "UN") {
654 _query = new bncNetQueryUdp0();
655 }
656 else if (_ntripVersion == "2") {
657 _query = new bncNetQueryV2(false);
658 }
659 else if (_ntripVersion == "2s") {
660 _query = new bncNetQueryV2(true);
661 }
662 else {
663 _query = new bncNetQueryV1();
664 }
665 if (_nmea == "yes") {
666 if (_serialNMEA == MANUAL_NMEA) {
667 _query->startRequest(_mountPoint, _manualNMEAString);
668 _lastManualNMEA = QDateTime::currentDateTime();
669 }
670 else if (_serialNMEA == AUTO_NMEA) {
671 if (_serialPort) {
672 int nb = _serialPort->bytesAvailable();
673 if (nb > 0) {
674 QByteArray data = _serialPort->read(nb);
675 int i1 = data.indexOf("$GPGGA");
676 if (i1 == -1) {
677 i1 = data.indexOf("$GNGGA");
678 }
679 if (i1 != -1) {
680 int i2 = data.indexOf("*", i1);
681 if (i2 != -1 && data.size() > i2 + 1) {
682 QByteArray gga = data.mid(i1, i2 - i1 + 3);
683 _query->startRequest(_mountPoint, gga);
684 }
685 }
686 }
687 }
688 }
689 }
690 else {
691 _query->startRequest(_mountPoint, "");
692 }
693
694 if (_query->status() != bncNetQuery::running) {
695 return failure;
696 }
697 }
698
699 if (_rawFile) {
700 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
701 while (itDec.hasNext()) {
702 itDec.next();
703 GPSDecoder* decoder = itDec.value();
704 decoder->setRinexReconnectFlag(false);
705 }
706 }
707 else {
708 _decoder->setRinexReconnectFlag(false);
709 }
710
711 return success;
712}
713
714// RTCM scan output
715//////////////////////////////////////////////////////////////////////////////
716void bncGetThread::miscScanRTCM() {
717
718 if ( !decoder() ) {
719 return;
720 }
721
722 bncSettings settings;
723 if ( Qt::CheckState(settings.value("miscScanRTCM").toInt()) == Qt::Checked ) {
724
725 if ( _miscMount == _staID || _miscMount == "ALL" ) {
726 // RTCM message types
727 // ------------------
728 for (int ii = 0; ii < decoder()->_typeList.size(); ii++) {
729 QString type = QString("%1 ").arg(decoder()->_typeList[ii]);
730 emit(newMessage(_staID + ": Received message type " + type.toAscii(), true));
731 }
732
733 // Check Observation Types
734 // -----------------------
735 for (int ii = 0; ii < decoder()->_obsList.size(); ii++) {
736 t_satObs& obs = decoder()->_obsList[ii];
737 QVector<QString>& rnxTypes = _rnxTypes[obs._prn.system()];
738 bool allFound = true;
739 for (unsigned iFrq = 0; iFrq < obs._obs.size(); iFrq++) {
740 if (obs._obs[iFrq]->_codeValid) {
741 QString rnxStr('C');
742 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
743 if (_format.indexOf("RTCM_2") != -1 ||
744 _format.indexOf("RTCM2") != -1 ||
745 _format.indexOf("RTCM 2") != -1 ) {
746 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
747 }
748 if (rnxTypes.indexOf(rnxStr) == -1) {
749 rnxTypes.push_back(rnxStr);
750 allFound = false;
751 }
752 }
753 if (obs._obs[iFrq]->_phaseValid) {
754 QString rnxStr('L');
755 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
756 if (_format.indexOf("RTCM_2") != -1 ||
757 _format.indexOf("RTCM2") != -1 ||
758 _format.indexOf("RTCM 2") != -1 ) {
759 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
760 }
761 if (rnxTypes.indexOf(rnxStr) == -1) {
762 rnxTypes.push_back(rnxStr);
763 allFound = false;
764 }
765 }
766 if (obs._obs[iFrq]->_dopplerValid){
767 QString rnxStr('D');
768 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
769 if (_format.indexOf("RTCM_2") != -1 ||
770 _format.indexOf("RTCM2") != -1 ||
771 _format.indexOf("RTCM 2") != -1 ) {
772 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
773 }
774 if (rnxTypes.indexOf(rnxStr) == -1) {
775 rnxTypes.push_back(rnxStr);
776 allFound = false;
777 }
778 }
779 if (obs._obs[iFrq]->_snrValid){
780 QString rnxStr('S');
781 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
782 if (_format.indexOf("RTCM_2") != -1 ||
783 _format.indexOf("RTCM2") != -1 ||
784 _format.indexOf("RTCM 2") != -1 ) {
785 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
786 }
787 if (rnxTypes.indexOf(rnxStr) == -1) {
788 rnxTypes.push_back(rnxStr);
789 allFound = false;
790 }
791 }
792 }
793 if (!allFound) {
794 QString msg;
795 QTextStream str(&msg);
796 QString s;
797 str << obs._prn.system() << " " << s.sprintf("%2d", rnxTypes.size()) << " ";
798 for (int iType = 0; iType < rnxTypes.size(); iType++) {
799 str << " " << rnxTypes[iType];
800 }
801 emit(newMessage(_staID + ": Observation Types: " + msg.toAscii(), true));
802 }
803 }
804
805 // RTCMv3 antenna descriptor
806 // -------------------------
807 for (int ii = 0; ii < decoder()->_antType.size(); ii++) {
808 QString ant1 = QString("%1 ").arg(decoder()->_antType[ii]);
809 emit(newMessage(_staID + ": Antenna descriptor " + ant1.toAscii(), true));
810 }
811
812 // RTCM Antenna Coordinates
813 // ------------------------
814 for (int ii=0; ii < decoder()->_antList.size(); ii++) {
815 QByteArray antT;
816 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
817 antT = "ARP";
818 }
819 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
820 antT = "APC";
821 }
822 QByteArray ant1, ant2, ant3;
823 ant1 = QString("%1 ").arg(decoder()->_antList[ii].xx,0,'f',4).toAscii();
824 ant2 = QString("%1 ").arg(decoder()->_antList[ii].yy,0,'f',4).toAscii();
825 ant3 = QString("%1 ").arg(decoder()->_antList[ii].zz,0,'f',4).toAscii();
826 emit(newMessage(_staID + ": " + antT + " (ITRF) X " + ant1 + "m", true));
827 emit(newMessage(_staID + ": " + antT + " (ITRF) Y " + ant2 + "m", true));
828 emit(newMessage(_staID + ": " + antT + " (ITRF) Z " + ant3 + "m", true));
829 double hh = 0.0;
830 if (decoder()->_antList[ii].height_f) {
831 hh = decoder()->_antList[ii].height;
832 QByteArray ant4 = QString("%1 ").arg(hh,0,'f',4).toAscii();
833 emit(newMessage(_staID + ": Antenna height above marker " + ant4 + "m", true));
834 }
835 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
836 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
837 hh, antT));
838 }
839
840 // RTCM GLONASS slots
841 // ------------------
842 if (decoder()->_gloFrq.size()) {
843 bool allFound = true;
844 QString slot = decoder()->_gloFrq;
845 slot.replace(" "," ").replace(" ",":");
846 if (_gloSlots.indexOf(slot) == -1) {
847 _gloSlots.append(slot);
848 allFound = false;
849 }
850 if (!allFound) {
851 _gloSlots.sort();
852 emit(newMessage(_staID + ": GLONASS Slot:Freq " + _gloSlots.join(" ").toAscii(), true));
853 }
854 }
855 }
856 }
857
858#ifdef MLS_SOFTWARE
859 for (int ii=0; ii <decoder()->_antList.size(); ii++) {
860 QByteArray antT;
861 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
862 antT = "ARP";
863 }
864 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
865 antT = "APC";
866 }
867 double hh = 0.0;
868 if (decoder()->_antList[ii].height_f) {
869 hh = decoder()->_antList[ii].height;
870 }
871 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
872 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
873 hh, antT));
874 }
875
876 for (int ii = 0; ii <decoder()->_typeList.size(); ii++) {
877 emit(newRTCMMessage(_staID, decoder()->_typeList[ii]));
878 }
879#endif
880
881 decoder()->_gloFrq.clear();
882 decoder()->_typeList.clear();
883 decoder()->_antType.clear();
884 decoder()->_antList.clear();
885}
886
887// Handle Data from Serial Port
888////////////////////////////////////////////////////////////////////////////
889void bncGetThread::slotSerialReadyRead() {
890
891 if (_serialPort) {
892
893 if (_nmea == "yes" && _serialNMEA == MANUAL_NMEA) {
894 if (_manualNMEASampl) {
895 int dt = _lastManualNMEA.secsTo(QDateTime::currentDateTime());
896 if (dt && (fmod(double(dt), double(_manualNMEASampl)) == 0.0)) {
897 _query->sendNMEA(_manualNMEAString);
898 _lastManualNMEA = QDateTime::currentDateTime();
899 }
900 }
901 }
902
903 int nb = _serialPort->bytesAvailable();
904 if (nb > 0) {
905 QByteArray data = _serialPort->read(nb);
906
907 if (_nmea == "yes" && _serialNMEA == AUTO_NMEA) {
908 int i1 = data.indexOf("$GPGGA");
909 if (i1 == -1) {
910 i1 = data.indexOf("$GNGGA");
911 }
912 if (i1 != -1) {
913 int i2 = data.indexOf("*", i1);
914 if (i2 != -1 && data.size() > i2 + 1) {
915 QByteArray gga = data.mid(i1, i2 - i1 + 3);
916 _query->sendNMEA(gga);
917 }
918 }
919 }
920
921 if (_serialOutFile) {
922 _serialOutFile->write(data);
923 _serialOutFile->flush();
924 }
925 }
926 }
927}
928
929void bncGetThread::slotNewNMEAConnection() {
930 _nmeaSockets->push_back(_nmeaServer->nextPendingConnection());
931 emit( newMessage(QString("New PPP client on port: # %1")
932 .arg(_nmeaSockets->size()).toAscii(), true) );
933}
934
935//
936////////////////////////////////////////////////////////////////////////////
937void bncGetThread::slotNewNMEAstr(QByteArray staID, QByteArray str) {
938 if (_nmeaPortsMap.contains(staID)) {
939 int nmeaPort = _nmeaPortsMap.value(staID);
940 QMutableListIterator<QTcpSocket*> is(*_nmeaSockets);
941 while (is.hasNext()) {
942 QTcpSocket* sock = is.next();
943 if (sock->localPort() == nmeaPort) {
944 if (sock->state() == QAbstractSocket::ConnectedState) {
945 sock->write(str);
946 }
947 else if (sock->state() != QAbstractSocket::ConnectingState) {
948 delete sock;
949 is.remove();
950 }
951 }
952 }
953 }
954}
Note: See TracBrowser for help on using the repository browser.