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