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

Last change on this file since 8273 was 8273, checked in by stuerze, 2 years ago

a small bug regarding latency checker should be solved now

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