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

Last change on this file since 8197 was 8197, checked in by stuerze, 3 years ago

receiver type extraction from 1033 RTCM3 messages is added

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