source: ntrip/trunk/BNC/bncgetthread.cpp@ 3624

Last change on this file since 3624 was 3595, checked in by mervart, 13 years ago
File size: 22.1 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 <QtNetwork>
48#include <QTime>
49
50#include "bncgetthread.h"
51#include "bnctabledlg.h"
52#include "bncapp.h"
53#include "bncutils.h"
54#include "bnczerodecoder.h"
55#include "bncnetqueryv0.h"
56#include "bncnetqueryv1.h"
57#include "bncnetqueryv2.h"
58#include "bncnetqueryrtp.h"
59#include "bncnetqueryudp.h"
60#include "bncnetqueryudp0.h"
61#include "bncnetquerys.h"
62#include "bncsettings.h"
63#include "latencychecker.h"
64#include "bncpppclient.h"
65#ifdef PPP_DLL_INTERFACE
66#include "dllinterface.h"
67#endif
68#include "upload/bncrtnetdecoder.h"
69#include "RTCM/RTCM2Decoder.h"
70#include "RTCM3/RTCM3Decoder.h"
71#include "GPSS/gpssDecoder.h"
72#include "GPSS/hassDecoder.h"
73#include "serial/qextserialport.h"
74
75using namespace std;
76
77// Constructor 1
78////////////////////////////////////////////////////////////////////////////
79bncGetThread::bncGetThread(bncRawFile* rawFile) {
80
81 _rawFile = rawFile;
82 _format = rawFile->format();
83 _staID = rawFile->staID();
84 _rawOutput = false;
85 _ntripVersion = "N";
86
87 initialize();
88}
89
90// Constructor 2
91////////////////////////////////////////////////////////////////////////////
92bncGetThread::bncGetThread(const QUrl& mountPoint,
93 const QByteArray& format,
94 const QByteArray& latitude,
95 const QByteArray& longitude,
96 const QByteArray& nmea,
97 const QByteArray& ntripVersion) {
98 _rawFile = 0;
99 _mountPoint = mountPoint;
100 _staID = mountPoint.path().mid(1).toAscii();
101 _format = format;
102 _latitude = latitude;
103 _longitude = longitude;
104 _nmea = nmea;
105 _ntripVersion = ntripVersion;
106
107 bncSettings settings;
108 if (!settings.value("rawOutFile").toString().isEmpty()) {
109 _rawOutput = true;
110 }
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 bncApp* app = (bncApp*) qApp;
125
126 connect(this, SIGNAL(newMessage(QByteArray,bool)),
127 app, SLOT(slotMessage(const QByteArray,bool)));
128
129 _isToBeDeleted = false;
130 _query = 0;
131 _nextSleep = 0;
132 _PPPclient = 0;
133#ifdef PPP_DLL_INTERFACE
134 _dllInterface = 0;
135#endif
136 _miscMount = settings.value("miscMount").toString();
137 _decoder = 0;
138
139 // Serial Port
140 // -----------
141 _serialNMEA = NO_NMEA;
142 _serialOutFile = 0;
143 _serialPort = 0;
144
145 if (!_staID.isEmpty() &&
146 settings.value("serialMountPoint").toString() == _staID) {
147 _serialPort = new QextSerialPort(settings.value("serialPortName").toString() );
148 _serialPort->setTimeout(0,100);
149
150 // Baud Rate
151 // ---------
152 QString hlp = settings.value("serialBaudRate").toString();
153 if (hlp == "110") {
154 _serialPort->setBaudRate(BAUD110);
155 }
156 else if (hlp == "300") {
157 _serialPort->setBaudRate(BAUD300);
158 }
159 else if (hlp == "600") {
160 _serialPort->setBaudRate(BAUD600);
161 }
162 else if (hlp == "1200") {
163 _serialPort->setBaudRate(BAUD1200);
164 }
165 else if (hlp == "2400") {
166 _serialPort->setBaudRate(BAUD2400);
167 }
168 else if (hlp == "4800") {
169 _serialPort->setBaudRate(BAUD4800);
170 }
171 else if (hlp == "9600") {
172 _serialPort->setBaudRate(BAUD9600);
173 }
174 else if (hlp == "19200") {
175 _serialPort->setBaudRate(BAUD19200);
176 }
177 else if (hlp == "38400") {
178 _serialPort->setBaudRate(BAUD38400);
179 }
180 else if (hlp == "57600") {
181 _serialPort->setBaudRate(BAUD57600);
182 }
183 else if (hlp == "115200") {
184 _serialPort->setBaudRate(BAUD115200);
185 }
186
187 // Parity
188 // ------
189 hlp = settings.value("serialParity").toString();
190 if (hlp == "NONE") {
191 _serialPort->setParity(PAR_NONE);
192 }
193 else if (hlp == "ODD") {
194 _serialPort->setParity(PAR_ODD);
195 }
196 else if (hlp == "EVEN") {
197 _serialPort->setParity(PAR_EVEN);
198 }
199 else if (hlp == "SPACE") {
200 _serialPort->setParity(PAR_SPACE);
201 }
202
203 // Data Bits
204 // ---------
205 hlp = settings.value("serialDataBits").toString();
206 if (hlp == "5") {
207 _serialPort->setDataBits(DATA_5);
208 }
209 else if (hlp == "6") {
210 _serialPort->setDataBits(DATA_6);
211 }
212 else if (hlp == "7") {
213 _serialPort->setDataBits(DATA_7);
214 }
215 else if (hlp == "8") {
216 _serialPort->setDataBits(DATA_8);
217 }
218 hlp = settings.value("serialStopBits").toString();
219 if (hlp == "1") {
220 _serialPort->setStopBits(STOP_1);
221 }
222 else if (hlp == "2") {
223 _serialPort->setStopBits(STOP_2);
224 }
225
226 // Flow Control
227 // ------------
228 hlp = settings.value("serialFlowControl").toString();
229 if (hlp == "XONXOFF") {
230 _serialPort->setFlowControl(FLOW_XONXOFF);
231 }
232 else if (hlp == "HARDWARE") {
233 _serialPort->setFlowControl(FLOW_HARDWARE);
234 }
235 else {
236 _serialPort->setFlowControl(FLOW_OFF);
237 }
238
239 // Open Serial Port
240 // ----------------
241 _serialPort->open(QIODevice::ReadWrite|QIODevice::Unbuffered);
242 if (!_serialPort->isOpen()) {
243 delete _serialPort;
244 _serialPort = 0;
245 emit(newMessage((_staID + ": Cannot open serial port\n"), true));
246 }
247 connect(_serialPort, SIGNAL(readyRead()),
248 this, SLOT(slotSerialReadyRead()));
249
250 // Automatic NMEA
251 // --------------
252 if (settings.value("serialAutoNMEA").toString() == "Auto") {
253 _serialNMEA = AUTO_NMEA;
254
255 QString fName = settings.value("serialFileNMEA").toString();
256 if (!fName.isEmpty()) {
257 _serialOutFile = new QFile(fName);
258 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
259 _serialOutFile->open(QIODevice::WriteOnly | QIODevice::Append);
260 }
261 else {
262 _serialOutFile->open(QIODevice::WriteOnly);
263 }
264 }
265 }
266
267 // Manual NMEA
268 // -----------
269 else {
270 _serialNMEA = MANUAL_NMEA;
271 }
272 }
273
274 if (!_staID.isEmpty()) {
275 _latencyChecker = new latencyChecker(_staID);
276 }
277 else {
278 _latencyChecker = 0;
279 }
280}
281
282// Instantiate the decoder
283//////////////////////////////////////////////////////////////////////////////
284t_irc bncGetThread::initDecoder() {
285
286 _decoder = 0;
287
288 if (_format.indexOf("RTCM_2") != -1 || _format.indexOf("RTCM2") != -1 ||
289 _format.indexOf("RTCM 2") != -1 ) {
290 emit(newMessage(_staID + ": Get data in RTCM 2.x format", true));
291 _decoder = new RTCM2Decoder(_staID.data());
292 }
293 else if (_format.indexOf("RTCM_3") != -1 || _format.indexOf("RTCM3") != -1 ||
294 _format.indexOf("RTCM 3") != -1 ) {
295 emit(newMessage(_staID + ": Get data in RTCM 3.x format", true));
296 RTCM3Decoder* newDecoder = new RTCM3Decoder(_staID, _rawFile);
297 _decoder = newDecoder;
298 connect((RTCM3Decoder*) newDecoder, SIGNAL(newMessage(QByteArray,bool)),
299 this, SIGNAL(newMessage(QByteArray,bool)));
300 }
301 else if (_format.indexOf("GPSS") != -1 || _format.indexOf("BNC") != -1) {
302 emit(newMessage(_staID + ": Get Data in GPSS format", true));
303 _decoder = new gpssDecoder();
304 }
305 else if (_format.indexOf("ZERO") != -1) {
306 emit(newMessage(_staID + ": Get data in original format", true));
307 _decoder = new bncZeroDecoder(_staID);
308 }
309 else if (_format.indexOf("RTNET") != -1) {
310 emit(newMessage(_staID + ": Get data in RTNet format", true));
311 _decoder = new bncRtnetDecoder();
312 }
313 else if (_format.indexOf("HASS2ASCII") != -1) {
314 emit(newMessage(_staID + ": Get data in HASS2ASCII format", true));
315 _decoder = new hassDecoder(_staID);
316 }
317 else {
318 emit(newMessage(_staID + ": Unknown data format " + _format, true));
319 _isToBeDeleted = true;
320 return failure;
321 }
322
323 msleep(100); //sleep 0.1 sec
324
325 _decoder->initRinex(_staID, _mountPoint, _latitude, _longitude,
326 _nmea, _ntripVersion);
327
328 if (_rawFile) {
329 _decodersRaw[_staID] = _decoder;
330 }
331
332 // Initialize PPP Client?
333 // ----------------------
334#ifndef MLS_SOFTWARE
335 bncSettings settings;
336 if (settings.value("pppMount").toString() == _staID) {
337 _PPPclient = new bncPPPclient(_staID);
338 bncApp* app = (bncApp*) qApp;
339 app->_bncPPPclient = _PPPclient;
340 qRegisterMetaType<bncTime>("bncTime");
341 connect(_PPPclient, SIGNAL(newPosition(bncTime, double, double, double)),
342 this, SIGNAL(newPosition(bncTime, double, double, double)));
343 connect(_PPPclient, SIGNAL(newNMEAstr(QByteArray)),
344 this, SIGNAL(newNMEAstr(QByteArray)));
345#ifdef PPP_DLL_INTERFACE
346 _dllInterface = new t_dllInterface();
347#endif
348 }
349#endif
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 delete _PPPclient;
379#ifdef PPP_DLL_INTERFACE
380 delete _dllInterface;
381#endif
382 if (_rawFile) {
383 QMapIterator<QString, GPSDecoder*> it(_decodersRaw);
384 while (it.hasNext()) {
385 it.next();
386 delete it.value();
387 }
388 }
389 else {
390 delete _decoder;
391 }
392 delete _rawFile;
393 delete _serialOutFile;
394 delete _serialPort;
395 delete _latencyChecker;
396 emit getThreadFinished(_staID);
397}
398
399//
400////////////////////////////////////////////////////////////////////////////
401void bncGetThread::terminate() {
402 _isToBeDeleted = true;
403 if (!isRunning()) {
404 delete this;
405 }
406}
407
408// Run
409////////////////////////////////////////////////////////////////////////////
410void bncGetThread::run() {
411
412 while (true) {
413 try {
414 if (_isToBeDeleted) {
415 QThread::exit(0);
416 this->deleteLater();
417 return;
418 }
419
420 if (tryReconnect() != success) {
421 if (_latencyChecker) {
422 _latencyChecker->checkReconnect();
423 }
424 continue;
425 }
426
427 // Delete old observations
428 // -----------------------
429 if (_rawFile) {
430 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
431 while (itDec.hasNext()) {
432 itDec.next();
433 GPSDecoder* decoder = itDec.value();
434 decoder->_obsList.clear();
435 }
436 }
437 else {
438 _decoder->_obsList.clear();
439 }
440
441 // Read Data
442 // ---------
443 QByteArray data;
444 if (_query) {
445 _query->waitForReadyRead(data);
446 }
447 else if (_rawFile) {
448 data = _rawFile->readChunk();
449 _format = _rawFile->format();
450 _staID = _rawFile->staID();
451
452 if (data.isEmpty()) {
453 cout << "no more data" << endl;
454 ((bncApp*) qApp)->stopCombination();
455 QThread::exit(0);
456 delete this;
457 ::exit(0);
458 }
459 }
460 qint64 nBytes = data.size();
461
462 // Timeout, reconnect
463 // ------------------
464 if (nBytes == 0) {
465 if (_latencyChecker) {
466 _latencyChecker->checkReconnect();
467 }
468 emit(newMessage(_staID + ": Data timeout, reconnecting", true));
469 msleep(10000); //sleep 10 sec, G. Weber
470 continue;
471 }
472 else {
473 emit newBytes(_staID, nBytes);
474 }
475
476 // Output Data
477 // -----------
478 if (_rawOutput) {
479 bncApp* app = (bncApp*) qApp;
480 app->writeRawData(data, _staID, _format);
481 }
482
483 if (_serialPort) {
484 slotSerialReadyRead();
485 _serialPort->write(data);
486 }
487
488 // Decode Data
489 // -----------
490 vector<string> errmsg;
491 if (!decoder()) {
492 _isToBeDeleted = true;
493 continue;
494 }
495 decoder()->_obsList.clear();
496 t_irc irc = decoder()->Decode(data.data(), data.size(), errmsg);
497
498 // Perform various scans and checks
499 // --------------------------------
500 if (_latencyChecker) {
501 _latencyChecker->checkOutage(irc == success);
502 _latencyChecker->checkObsLatency(decoder()->_obsList);
503 _latencyChecker->checkCorrLatency(decoder()->corrGPSEpochTime());
504
505 emit newLatency(_staID, _latencyChecker->currentLatency());
506 }
507
508 scanRTCM();
509
510 // Loop over all observations (observations output)
511 // ------------------------------------------------
512 QListIterator<t_obs> it(decoder()->_obsList);
513 bool firstObs = true;
514 while (it.hasNext()) {
515 const t_obs& obs = it.next();
516
517 QString prn = QString("%1%2").arg(obs.satSys)
518 .arg(obs.satNum, 2, 10, QChar('0'));
519 long iSec = long(floor(obs.GPSWeeks+0.5));
520 long obsTime = obs.GPSWeek * 7*24*3600 + iSec;
521
522 // Check observation epoch
523 // -----------------------
524 if (!_rawFile && !dynamic_cast<gpssDecoder*>(decoder())) {
525 int week;
526 double sec;
527 currentGPSWeeks(week, sec);
528 long currTime = week * 7*24*3600 + long(sec);
529 const double maxDt = 600.0;
530 if (fabs(currTime - obsTime) > maxDt) {
531 emit( newMessage(_staID + ": Wrong observation epoch(s)", false) );
532 continue;
533 }
534 }
535
536 // Check observations coming twice (e.g. KOUR0 Problem)
537 // ----------------------------------------------------
538 if (!_rawFile) {
539 QMap<QString, long>::const_iterator it = _prnLastEpo.find(prn);
540 if (it != _prnLastEpo.end()) {
541 long oldTime = it.value();
542 if (obsTime < oldTime) {
543 emit( newMessage(_staID +
544 ": old observation " + prn.toAscii(), false));
545 continue;
546 }
547 else if (obsTime == oldTime) {
548 emit( newMessage(_staID +
549 ": observation coming more than once " + prn.toAscii(), false));
550 continue;
551 }
552 }
553 _prnLastEpo[prn] = obsTime;
554 }
555
556 decoder()->dumpRinexEpoch(obs, _format);
557
558 // PPP Client
559 // ----------
560#ifndef MLS_SOFTWARE
561 if (_PPPclient && _staID == _PPPclient->staID()) {
562 _PPPclient->putNewObs(obs);
563#ifdef PPP_DLL_INTERFACE
564 _dllInterface->putNewObs(obs);
565#endif
566 }
567#endif
568
569 // Emit new observation signal
570 // ---------------------------
571 if (!_isToBeDeleted) {
572 emit newObs(_staID, firstObs, obs);
573 }
574 firstObs = false;
575 }
576 decoder()->_obsList.clear();
577 }
578 catch (Exception& exc) {
579 emit(newMessage(_staID + " " + exc.what(), true));
580 _isToBeDeleted = true;
581 }
582 catch (...) {
583 emit(newMessage(_staID + " bncGetThread exception", true));
584 _isToBeDeleted = true;
585 }
586 }
587}
588
589// Try Re-Connect
590////////////////////////////////////////////////////////////////////////////
591t_irc bncGetThread::tryReconnect() {
592
593 // Easy Return
594 // -----------
595 if (_query && _query->status() == bncNetQuery::running) {
596 _nextSleep = 0;
597 if (_rawFile) {
598 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
599 while (itDec.hasNext()) {
600 itDec.next();
601 GPSDecoder* decoder = itDec.value();
602 decoder->setRinexReconnectFlag(false);
603 }
604 }
605 else {
606 _decoder->setRinexReconnectFlag(false);
607 }
608 return success;
609 }
610
611 // Start a new query
612 // -----------------
613 if (!_rawFile) {
614
615 sleep(_nextSleep);
616 if (_nextSleep == 0) {
617 _nextSleep = 1;
618 }
619 else {
620 _nextSleep = 2 * _nextSleep;
621 if (_nextSleep > 256) {
622 _nextSleep = 256;
623 }
624#ifdef MLS_SOFTWARE
625 if (_nextSleep > 4) {
626 _nextSleep = 4;
627 }
628#endif
629 }
630
631 delete _query;
632 if (_ntripVersion == "U") {
633 _query = new bncNetQueryUdp();
634 }
635 else if (_ntripVersion == "R") {
636 _query = new bncNetQueryRtp();
637 }
638 else if (_ntripVersion == "S") {
639 _query = new bncNetQueryS();
640 }
641 else if (_ntripVersion == "N") {
642 _query = new bncNetQueryV0();
643 }
644 else if (_ntripVersion == "UN") {
645 _query = new bncNetQueryUdp0();
646 }
647 else if (_ntripVersion == "2") {
648 _query = new bncNetQueryV2(false);
649 }
650 else if (_ntripVersion == "2s") {
651 _query = new bncNetQueryV2(true);
652 }
653 else {
654 _query = new bncNetQueryV1();
655 }
656 if (_nmea == "yes" && _serialNMEA != AUTO_NMEA) {
657 QByteArray gga = ggaString(_latitude, _longitude, "100.0");
658 _query->startRequest(_mountPoint, gga);
659 }
660 else {
661 _query->startRequest(_mountPoint, "");
662 }
663 if (_query->status() != bncNetQuery::running) {
664 return failure;
665 }
666 }
667
668 if (_rawFile) {
669 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
670 while (itDec.hasNext()) {
671 itDec.next();
672 GPSDecoder* decoder = itDec.value();
673 decoder->setRinexReconnectFlag(false);
674 }
675 }
676 else {
677 _decoder->setRinexReconnectFlag(false);
678 }
679
680 return success;
681}
682
683// RTCM scan output
684//////////////////////////////////////////////////////////////////////////////
685void bncGetThread::scanRTCM() {
686
687 if (!decoder()) {
688 return;
689 }
690
691 bncSettings settings;
692 if ( Qt::CheckState(settings.value("scanRTCM").toInt()) == Qt::Checked ) {
693
694 if ( _miscMount == _staID || _miscMount == "ALL" ) {
695
696 // RTCM message types
697 // ------------------
698 for (int ii = 0; ii <decoder()->_typeList.size(); ii++) {
699 QString type = QString("%1 ").arg(decoder()->_typeList[ii]);
700 emit(newMessage(_staID + ": Received message type " + type.toAscii(), true));
701 }
702
703 // RTCMv3 antenna descriptor
704 // -------------------------
705 for (int ii=0;ii<decoder()->_antType.size();ii++) {
706 QString ant1 = QString("%1 ").arg(decoder()->_antType[ii]);
707 emit(newMessage(_staID + ": Antenna descriptor " + ant1.toAscii(), true));
708 }
709
710 // RTCM Antenna Coordinates
711 // ------------------------
712 for (int ii=0; ii <decoder()->_antList.size(); ii++) {
713 QByteArray antT;
714 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
715 antT = "ARP";
716 }
717 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
718 antT = "APC";
719 }
720 QByteArray ant1, ant2, ant3;
721 ant1 = QString("%1 ").arg(decoder()->_antList[ii].xx,0,'f',4).toAscii();
722 ant2 = QString("%1 ").arg(decoder()->_antList[ii].yy,0,'f',4).toAscii();
723 ant3 = QString("%1 ").arg(decoder()->_antList[ii].zz,0,'f',4).toAscii();
724 emit(newMessage(_staID + ": " + antT + " (ITRF) X " + ant1 + "m", true));
725 emit(newMessage(_staID + ": " + antT + " (ITRF) Y " + ant2 + "m", true));
726 emit(newMessage(_staID + ": " + antT + " (ITRF) Z " + ant3 + "m", true));
727 double hh = 0.0;
728 if (decoder()->_antList[ii].height_f) {
729 hh = decoder()->_antList[ii].height;
730 QByteArray ant4 = QString("%1 ").arg(hh,0,'f',4).toAscii();
731 emit(newMessage(_staID + ": Antenna height above marker " + ant4 + "m", true));
732 }
733 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
734 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
735 hh, antT));
736 }
737 }
738 }
739
740#ifdef MLS_SOFTWARE
741 for (int ii=0; ii <decoder()->_antList.size(); ii++) {
742 QByteArray antT;
743 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
744 antT = "ARP";
745 }
746 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
747 antT = "APC";
748 }
749 double hh = 0.0;
750 if (decoder()->_antList[ii].height_f) {
751 hh = decoder()->_antList[ii].height;
752 }
753 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
754 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
755 hh, antT));
756 }
757
758 for (int ii = 0; ii <decoder()->_typeList.size(); ii++) {
759 emit(newRTCMMessage(_staID, decoder()->_typeList[ii]));
760 }
761#endif
762
763 decoder()->_typeList.clear();
764 decoder()->_antType.clear();
765 decoder()->_antList.clear();
766}
767
768// Handle Data from Serial Port
769////////////////////////////////////////////////////////////////////////////
770void bncGetThread::slotSerialReadyRead() {
771 if (_serialPort) {
772 int nb = _serialPort->bytesAvailable();
773 if (nb > 0) {
774 QByteArray data = _serialPort->read(nb);
775
776 if (_serialNMEA == AUTO_NMEA) {
777 int i1 = data.indexOf("$GPGGA");
778 if (i1 != -1) {
779 int i2 = data.indexOf("*", i1);
780 if (i2 != -1 && data.size() > i2 + 1) {
781 QByteArray gga = data.mid(i1,i2-i1+3);
782 _query->sendNMEA(gga);
783 }
784 }
785 }
786
787 if (_serialOutFile) {
788 _serialOutFile->write(data);
789 _serialOutFile->flush();
790 }
791 }
792 }
793}
Note: See TracBrowser for help on using the repository browser.