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 | _decoder = 0; |
---|
320 | |
---|
321 | if (_format.indexOf("RTCM_2") != -1 || _format.indexOf("RTCM2") != -1 |
---|
322 | || _format.indexOf("RTCM 2") != -1) { |
---|
323 | emit(newMessage(_staID + ": Get data in RTCM 2.x format", true)); |
---|
324 | _decoder = new RTCM2Decoder(_staID.data()); |
---|
325 | } else if (_format.indexOf("RTCM_3") != -1 || _format.indexOf("RTCM3") != -1 |
---|
326 | || _format.indexOf("RTCM 3") != -1) { |
---|
327 | emit(newMessage(_staID + ": Get data in RTCM 3.x format", true)); |
---|
328 | RTCM3Decoder* newDecoder = new RTCM3Decoder(_staID, _rawFile); |
---|
329 | _decoder = newDecoder; |
---|
330 | connect((RTCM3Decoder*) newDecoder, SIGNAL(newMessage(QByteArray,bool)), |
---|
331 | this, SIGNAL(newMessage(QByteArray,bool))); |
---|
332 | } else if (_format.indexOf("ZERO") != -1) { |
---|
333 | emit(newMessage(_staID + ": Get data in original format", true)); |
---|
334 | _decoder = new bncZeroDecoder(_staID); |
---|
335 | } else if (_format.indexOf("RTNET") != -1) { |
---|
336 | emit(newMessage(_staID + ": Get data in RTNet format", true)); |
---|
337 | _decoder = new bncRtnetDecoder(); |
---|
338 | } else { |
---|
339 | emit(newMessage(_staID + ": Unknown data format " + _format, true)); |
---|
340 | _isToBeDeleted = true; |
---|
341 | return failure; |
---|
342 | } |
---|
343 | |
---|
344 | msleep(100); //sleep 0.1 sec |
---|
345 | |
---|
346 | _decoder->initRinex(_staID, _mountPoint, _latitude, _longitude, _nmea, |
---|
347 | _ntripVersion); |
---|
348 | |
---|
349 | if (_rawFile) { |
---|
350 | _decodersRaw[_staID] = _decoder; |
---|
351 | } |
---|
352 | |
---|
353 | return success; |
---|
354 | } |
---|
355 | |
---|
356 | // Current decoder in use |
---|
357 | //////////////////////////////////////////////////////////////////////////// |
---|
358 | GPSDecoder* bncGetThread::decoder() { |
---|
359 | if (!_rawFile) { |
---|
360 | return _decoder; |
---|
361 | } else { |
---|
362 | if (_decodersRaw.contains(_staID) || initDecoder() == success) { |
---|
363 | return _decodersRaw[_staID]; |
---|
364 | } |
---|
365 | } |
---|
366 | return 0; |
---|
367 | } |
---|
368 | |
---|
369 | // Destructor |
---|
370 | //////////////////////////////////////////////////////////////////////////// |
---|
371 | bncGetThread::~bncGetThread() { |
---|
372 | if (isRunning()) { |
---|
373 | wait(); |
---|
374 | } |
---|
375 | if (_query) { |
---|
376 | _query->stop(); |
---|
377 | _query->deleteLater(); |
---|
378 | } |
---|
379 | if (_rawFile) { |
---|
380 | QMapIterator<QString, GPSDecoder*> it(_decodersRaw); |
---|
381 | while (it.hasNext()) { |
---|
382 | it.next(); |
---|
383 | delete it.value(); |
---|
384 | } |
---|
385 | } else { |
---|
386 | delete _decoder; |
---|
387 | } |
---|
388 | delete _rawFile; |
---|
389 | delete _serialOutFile; |
---|
390 | delete _serialPort; |
---|
391 | delete _latencyChecker; |
---|
392 | emit getThreadFinished(_staID); |
---|
393 | } |
---|
394 | |
---|
395 | // |
---|
396 | //////////////////////////////////////////////////////////////////////////// |
---|
397 | void bncGetThread::terminate() { |
---|
398 | _isToBeDeleted = true; |
---|
399 | |
---|
400 | if (_nmeaPortsMap.contains(_staID)) { |
---|
401 | _nmeaPortsMap.remove(_staID); |
---|
402 | } |
---|
403 | if (_nmeaServer) { |
---|
404 | delete _nmeaServer; |
---|
405 | } |
---|
406 | if (_nmeaSockets) { |
---|
407 | delete _nmeaSockets; |
---|
408 | } |
---|
409 | |
---|
410 | //#ifdef BNC_DEBUG |
---|
411 | if (BNC_CORE->mode() != t_bncCore::interactive) { |
---|
412 | while (!isFinished()) { |
---|
413 | wait(); |
---|
414 | } |
---|
415 | delete this; |
---|
416 | } else { |
---|
417 | if (!isRunning()) { |
---|
418 | delete this; |
---|
419 | } |
---|
420 | } |
---|
421 | //#else |
---|
422 | // if (!isRunning()) {delete this;} |
---|
423 | //#endif |
---|
424 | |
---|
425 | } |
---|
426 | |
---|
427 | // Run |
---|
428 | //////////////////////////////////////////////////////////////////////////// |
---|
429 | void bncGetThread::run() { |
---|
430 | |
---|
431 | while (true) { |
---|
432 | try { |
---|
433 | if (_isToBeDeleted) { |
---|
434 | QThread::exit(0); |
---|
435 | this->deleteLater(); |
---|
436 | return; |
---|
437 | } |
---|
438 | |
---|
439 | if (tryReconnect() != success) { |
---|
440 | if (_latencyChecker) { |
---|
441 | _latencyChecker->checkReconnect(); |
---|
442 | } |
---|
443 | continue; |
---|
444 | } |
---|
445 | |
---|
446 | // Delete old observations |
---|
447 | // ----------------------- |
---|
448 | if (_rawFile) { |
---|
449 | QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw); |
---|
450 | while (itDec.hasNext()) { |
---|
451 | itDec.next(); |
---|
452 | GPSDecoder* decoder = itDec.value(); |
---|
453 | decoder->_obsList.clear(); |
---|
454 | } |
---|
455 | } else { |
---|
456 | _decoder->_obsList.clear(); |
---|
457 | } |
---|
458 | |
---|
459 | // Read Data |
---|
460 | // --------- |
---|
461 | QByteArray data; |
---|
462 | if (_query) { |
---|
463 | _query->waitForReadyRead(data); |
---|
464 | } else if (_rawFile) { |
---|
465 | data = _rawFile->readChunk(); |
---|
466 | _format = _rawFile->format(); |
---|
467 | _staID = _rawFile->staID(); |
---|
468 | |
---|
469 | QCoreApplication::processEvents(); |
---|
470 | |
---|
471 | if (data.isEmpty() || BNC_CORE->sigintReceived) { |
---|
472 | cout << "no more data or Ctrl-C received" << endl; |
---|
473 | BNC_CORE->stopCombination(); |
---|
474 | BNC_CORE->stopPPP(); |
---|
475 | sleep(2); |
---|
476 | ::exit(0); |
---|
477 | } |
---|
478 | } |
---|
479 | |
---|
480 | qint64 nBytes = data.size(); |
---|
481 | |
---|
482 | // Timeout, reconnect |
---|
483 | // ------------------ |
---|
484 | if (nBytes == 0) { |
---|
485 | if (_latencyChecker) { |
---|
486 | _latencyChecker->checkReconnect(); |
---|
487 | } |
---|
488 | emit(newMessage(_staID + ": Data timeout, reconnecting", true)); |
---|
489 | msleep(10000); //sleep 10 sec, G. Weber |
---|
490 | continue; |
---|
491 | } else { |
---|
492 | emit newBytes(_staID, nBytes); |
---|
493 | emit newRawData(_staID, data); |
---|
494 | } |
---|
495 | |
---|
496 | // Output Data |
---|
497 | // ----------- |
---|
498 | if (_rawOutput) { |
---|
499 | BNC_CORE->writeRawData(data, _staID, _format); |
---|
500 | } |
---|
501 | |
---|
502 | if (_serialPort) { |
---|
503 | slotSerialReadyRead(); |
---|
504 | _serialPort->write(data); |
---|
505 | } |
---|
506 | |
---|
507 | // Decode Data |
---|
508 | // ----------- |
---|
509 | vector<string> errmsg; |
---|
510 | if (!decoder()) { |
---|
511 | _isToBeDeleted = true; |
---|
512 | continue; |
---|
513 | } |
---|
514 | |
---|
515 | t_irc irc = decoder()->Decode(data.data(), data.size(), errmsg); |
---|
516 | |
---|
517 | if (irc != success) { |
---|
518 | continue; |
---|
519 | } |
---|
520 | // Perform various scans and checks |
---|
521 | // -------------------------------- |
---|
522 | if (_latencyChecker) { |
---|
523 | _latencyChecker->checkOutage(irc); |
---|
524 | QListIterator<int> it(decoder()->_typeList); |
---|
525 | _ssrEpoch = static_cast<int>(decoder()->corrGPSEpochTime()); |
---|
526 | if (_ssrEpoch != -1) { |
---|
527 | if (_rtcmSsrOrb) { |
---|
528 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1057); |
---|
529 | _rtcmSsrOrb = false; |
---|
530 | } |
---|
531 | if (_rtcmSsrClk) { |
---|
532 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1058); |
---|
533 | _rtcmSsrClk = false; |
---|
534 | } |
---|
535 | if (_rtcmSsrOrbClk) { |
---|
536 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1060); |
---|
537 | _rtcmSsrOrbClk = false; |
---|
538 | } |
---|
539 | if (_rtcmSsrCbi) { |
---|
540 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1059); |
---|
541 | _rtcmSsrCbi = false; |
---|
542 | } |
---|
543 | if (_rtcmSsrPbi) { |
---|
544 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1265); |
---|
545 | _rtcmSsrPbi = false; |
---|
546 | } |
---|
547 | if (_rtcmSsrVtec) { |
---|
548 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1264); |
---|
549 | _rtcmSsrVtec = false; |
---|
550 | } |
---|
551 | if (_rtcmSsrUra) { |
---|
552 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1061); |
---|
553 | _rtcmSsrUra = false; |
---|
554 | } |
---|
555 | if (_rtcmSsrHr) { |
---|
556 | _latencyChecker->checkCorrLatency(_ssrEpoch, 1062); |
---|
557 | _rtcmSsrHr = false; |
---|
558 | } |
---|
559 | if (_rtcmSsrIgs) { |
---|
560 | _latencyChecker->checkCorrLatency(_ssrEpoch, 4076); |
---|
561 | _rtcmSsrIgs = false; |
---|
562 | } |
---|
563 | } |
---|
564 | while (it.hasNext()) { |
---|
565 | int rtcmType = it.next(); |
---|
566 | if ((rtcmType >= 1001 && rtcmType <= 1004) || // legacy RTCM OBS |
---|
567 | (rtcmType >= 1009 && rtcmType <= 1012) || // legacy RTCM OBS |
---|
568 | (rtcmType >= 1071 && rtcmType <= 1137)) { // MSM RTCM OBS |
---|
569 | _rtcmObs = true; |
---|
570 | } else if ((rtcmType >= 1057 && rtcmType <= 1068) || |
---|
571 | (rtcmType >= 1240 && rtcmType <= 1270) || |
---|
572 | (rtcmType == 4076)) { |
---|
573 | switch (rtcmType) { |
---|
574 | case 1057: case 1063: case 1240: case 1246: case 1252: case 1258: |
---|
575 | _rtcmSsrOrb = true; |
---|
576 | break; |
---|
577 | case 1058: case 1064: case 1241: case 1247: case 1253: case 1259: |
---|
578 | _rtcmSsrClk = true; |
---|
579 | break; |
---|
580 | case 1060: case 1066: case 1243: case 1249: case 1255: case 1261: |
---|
581 | _rtcmSsrOrbClk = true; |
---|
582 | break; |
---|
583 | case 1059: case 1065: case 1242: case 1248: case 1254: case 1260: |
---|
584 | _rtcmSsrCbi = true; |
---|
585 | break; |
---|
586 | case 1265: case 1266: case 1267: case 1268: case 1269: case 1270: |
---|
587 | _rtcmSsrPbi = true; |
---|
588 | break; |
---|
589 | case 1264: |
---|
590 | _rtcmSsrVtec = true; |
---|
591 | break; |
---|
592 | case 1061: case 1067: case 1244: case 1250: case 1256: case 1262: |
---|
593 | _rtcmSsrUra = true; |
---|
594 | break; |
---|
595 | case 1062: case 1068: case 1245: case 1251: case 1257: case 1263: |
---|
596 | _rtcmSsrHr = true; |
---|
597 | break; |
---|
598 | case 4076: |
---|
599 | _rtcmSsrIgs = true; |
---|
600 | break; |
---|
601 | } |
---|
602 | } |
---|
603 | } |
---|
604 | if (_rtcmObs) { |
---|
605 | _latencyChecker->checkObsLatency(decoder()->_obsList); |
---|
606 | } |
---|
607 | emit newLatency(_staID, _latencyChecker->currentLatency()); |
---|
608 | } |
---|
609 | miscScanRTCM(); |
---|
610 | |
---|
611 | // Loop over all observations (observations output) |
---|
612 | // ------------------------------------------------ |
---|
613 | QListIterator<t_satObs> it(decoder()->_obsList); |
---|
614 | |
---|
615 | QList<t_satObs> obsListHlp; |
---|
616 | |
---|
617 | while (it.hasNext()) { |
---|
618 | const t_satObs& obs = it.next(); |
---|
619 | |
---|
620 | // Check observation epoch |
---|
621 | // ----------------------- |
---|
622 | if (!_rawFile) { |
---|
623 | bool wrongObservationEpoch = checkForWrongObsEpoch(obs._time); |
---|
624 | if (wrongObservationEpoch) { |
---|
625 | QString prn(obs._prn.toString().c_str()); |
---|
626 | emit(newMessage(_staID + " (" + prn.toLatin1() + ")" + ": Wrong observation epoch(s)", false)); |
---|
627 | continue; |
---|
628 | } |
---|
629 | } |
---|
630 | |
---|
631 | // Check observations coming twice (e.g. KOUR0 Problem) |
---|
632 | // ---------------------------------------------------- |
---|
633 | if (!_rawFile) { |
---|
634 | QString prn(obs._prn.toString().c_str()); |
---|
635 | bncTime obsTime = obs._time; |
---|
636 | QMap<QString, bncTime>::const_iterator it = _prnLastEpo.find(prn); |
---|
637 | if (it != _prnLastEpo.end()) { |
---|
638 | bncTime oldTime = it.value(); |
---|
639 | if (obsTime < oldTime) { |
---|
640 | emit(newMessage(_staID + ": old observation " + prn.toLatin1(), false)); |
---|
641 | continue; |
---|
642 | } else if (obsTime == oldTime) { |
---|
643 | emit(newMessage(_staID + ": observation coming more than once " + prn.toLatin1(), false)); |
---|
644 | continue; |
---|
645 | } |
---|
646 | } |
---|
647 | _prnLastEpo[prn] = obsTime; |
---|
648 | } |
---|
649 | |
---|
650 | decoder()->dumpRinexEpoch(obs, _format); |
---|
651 | |
---|
652 | // Save observations |
---|
653 | // ----------------- |
---|
654 | obsListHlp.append(obs); |
---|
655 | } |
---|
656 | |
---|
657 | // Emit signal |
---|
658 | // ----------- |
---|
659 | if (!_isToBeDeleted && obsListHlp.size() > 0) { |
---|
660 | emit newObs(_staID, obsListHlp); |
---|
661 | } |
---|
662 | |
---|
663 | } catch (Exception& exc) { |
---|
664 | emit(newMessage(_staID + " " + exc.what(), true)); |
---|
665 | _isToBeDeleted = true; |
---|
666 | } catch (...) { |
---|
667 | emit(newMessage(_staID + " bncGetThread exception", true)); |
---|
668 | _isToBeDeleted = true; |
---|
669 | } |
---|
670 | } |
---|
671 | } |
---|
672 | |
---|
673 | // Try Re-Connect |
---|
674 | //////////////////////////////////////////////////////////////////////////// |
---|
675 | t_irc bncGetThread::tryReconnect() { |
---|
676 | |
---|
677 | // Easy Return |
---|
678 | // ----------- |
---|
679 | if (_query && _query->status() == bncNetQuery::running) { |
---|
680 | _nextSleep = 0; |
---|
681 | if (_rawFile) { |
---|
682 | QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw); |
---|
683 | while (itDec.hasNext()) { |
---|
684 | itDec.next(); |
---|
685 | GPSDecoder* decoder = itDec.value(); |
---|
686 | decoder->setRinexReconnectFlag(false); |
---|
687 | } |
---|
688 | } else { |
---|
689 | _decoder->setRinexReconnectFlag(false); |
---|
690 | } |
---|
691 | return success; |
---|
692 | } |
---|
693 | |
---|
694 | // Start a new query |
---|
695 | // ----------------- |
---|
696 | if (!_rawFile) { |
---|
697 | |
---|
698 | sleep(_nextSleep); |
---|
699 | if (_nextSleep == 0) { |
---|
700 | _nextSleep = 1; |
---|
701 | } else { |
---|
702 | _nextSleep = 2 * _nextSleep; |
---|
703 | if (_nextSleep > 256) { |
---|
704 | _nextSleep = 256; |
---|
705 | } |
---|
706 | #ifdef MLS_SOFTWARE |
---|
707 | if (_nextSleep > 4) { |
---|
708 | _nextSleep = 4; |
---|
709 | } |
---|
710 | #endif |
---|
711 | } |
---|
712 | delete _query; |
---|
713 | if (_ntripVersion == "U") { |
---|
714 | _query = new bncNetQueryUdp(); |
---|
715 | } else if (_ntripVersion == "R") { |
---|
716 | _query = new bncNetQueryRtp(); |
---|
717 | } else if (_ntripVersion == "S") { |
---|
718 | _query = new bncNetQueryS(); |
---|
719 | } else if (_ntripVersion == "N") { |
---|
720 | _query = new bncNetQueryV0(); |
---|
721 | } else if (_ntripVersion == "UN") { |
---|
722 | _query = new bncNetQueryUdp0(); |
---|
723 | } else if (_ntripVersion == "2") { |
---|
724 | _query = new bncNetQueryV2(false); |
---|
725 | } else if (_ntripVersion == "2s") { |
---|
726 | _query = new bncNetQueryV2(true); |
---|
727 | } else { |
---|
728 | _query = new bncNetQueryV1(); |
---|
729 | } |
---|
730 | if (_nmea == "yes") { |
---|
731 | if (_serialNMEA == MANUAL_NMEA) { |
---|
732 | _query->startRequest(_mountPoint, _manualNMEAString); |
---|
733 | _lastManualNMEA = QDateTime::currentDateTime(); |
---|
734 | } else if (_serialNMEA == AUTO_NMEA) { |
---|
735 | if (_serialPort) { |
---|
736 | int nb = _serialPort->bytesAvailable(); |
---|
737 | if (nb > 0) { |
---|
738 | QByteArray data = _serialPort->read(nb); |
---|
739 | int i1 = data.indexOf("$GPGGA"); |
---|
740 | if (i1 == -1) { |
---|
741 | i1 = data.indexOf("$GNGGA"); |
---|
742 | } |
---|
743 | if (i1 != -1) { |
---|
744 | int i2 = data.indexOf("*", i1); |
---|
745 | if (i2 != -1 && data.size() > i2 + 1) { |
---|
746 | QByteArray gga = data.mid(i1, i2 - i1 + 3); |
---|
747 | _query->startRequest(_mountPoint, gga); |
---|
748 | } |
---|
749 | } |
---|
750 | } |
---|
751 | } |
---|
752 | } |
---|
753 | } else { |
---|
754 | _query->startRequest(_mountPoint, ""); |
---|
755 | } |
---|
756 | |
---|
757 | if (_query->status() != bncNetQuery::running) { |
---|
758 | return failure; |
---|
759 | } |
---|
760 | } |
---|
761 | |
---|
762 | if (_rawFile) { |
---|
763 | QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw); |
---|
764 | while (itDec.hasNext()) { |
---|
765 | itDec.next(); |
---|
766 | GPSDecoder* decoder = itDec.value(); |
---|
767 | decoder->setRinexReconnectFlag(false); |
---|
768 | } |
---|
769 | } else { |
---|
770 | _decoder->setRinexReconnectFlag(false); |
---|
771 | } |
---|
772 | |
---|
773 | return success; |
---|
774 | } |
---|
775 | |
---|
776 | // RTCM scan output |
---|
777 | ////////////////////////////////////////////////////////////////////////////// |
---|
778 | void bncGetThread::miscScanRTCM() { |
---|
779 | |
---|
780 | if (!decoder()) { |
---|
781 | return; |
---|
782 | } |
---|
783 | |
---|
784 | bncSettings settings; |
---|
785 | if (Qt::CheckState(settings.value("miscScanRTCM").toInt()) == Qt::Checked) { |
---|
786 | |
---|
787 | if (_miscMount == _staID || _miscMount == "ALL") { |
---|
788 | // RTCM message types |
---|
789 | // ------------------ |
---|
790 | for (int ii = 0; ii < decoder()->_typeList.size(); ii++) { |
---|
791 | QString type = QString("%1 ").arg(decoder()->_typeList[ii]); |
---|
792 | emit(newMessage(_staID + ": Received message type " + type.toLatin1(), |
---|
793 | true)); |
---|
794 | } |
---|
795 | |
---|
796 | // Check Observation Types |
---|
797 | // ----------------------- |
---|
798 | for (int ii = 0; ii < decoder()->_obsList.size(); ii++) { |
---|
799 | t_satObs& obs = decoder()->_obsList[ii]; |
---|
800 | QVector<QString>& rnxTypes = _rnxTypes[obs._prn.system()]; |
---|
801 | bool allFound = true; |
---|
802 | for (unsigned iFrq = 0; iFrq < obs._obs.size(); iFrq++) { |
---|
803 | if (obs._obs[iFrq]->_codeValid) { |
---|
804 | QString rnxStr('C'); |
---|
805 | rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str()); |
---|
806 | if (_format.indexOf("RTCM_2") != -1 |
---|
807 | || _format.indexOf("RTCM2") != -1 |
---|
808 | || _format.indexOf("RTCM 2") != -1) { |
---|
809 | rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr); |
---|
810 | } |
---|
811 | if (rnxTypes.indexOf(rnxStr) == -1) { |
---|
812 | rnxTypes.push_back(rnxStr); |
---|
813 | allFound = false; |
---|
814 | } |
---|
815 | } |
---|
816 | if (obs._obs[iFrq]->_phaseValid) { |
---|
817 | QString rnxStr('L'); |
---|
818 | rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str()); |
---|
819 | if (_format.indexOf("RTCM_2") != -1 |
---|
820 | || _format.indexOf("RTCM2") != -1 |
---|
821 | || _format.indexOf("RTCM 2") != -1) { |
---|
822 | rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr); |
---|
823 | } |
---|
824 | if (rnxTypes.indexOf(rnxStr) == -1) { |
---|
825 | rnxTypes.push_back(rnxStr); |
---|
826 | allFound = false; |
---|
827 | } |
---|
828 | } |
---|
829 | if (obs._obs[iFrq]->_dopplerValid) { |
---|
830 | QString rnxStr('D'); |
---|
831 | rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str()); |
---|
832 | if (_format.indexOf("RTCM_2") != -1 |
---|
833 | || _format.indexOf("RTCM2") != -1 |
---|
834 | || _format.indexOf("RTCM 2") != -1) { |
---|
835 | rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr); |
---|
836 | } |
---|
837 | if (rnxTypes.indexOf(rnxStr) == -1) { |
---|
838 | rnxTypes.push_back(rnxStr); |
---|
839 | allFound = false; |
---|
840 | } |
---|
841 | } |
---|
842 | if (obs._obs[iFrq]->_snrValid) { |
---|
843 | QString rnxStr('S'); |
---|
844 | rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str()); |
---|
845 | if (_format.indexOf("RTCM_2") != -1 |
---|
846 | || _format.indexOf("RTCM2") != -1 |
---|
847 | || _format.indexOf("RTCM 2") != -1) { |
---|
848 | rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr); |
---|
849 | } |
---|
850 | if (rnxTypes.indexOf(rnxStr) == -1) { |
---|
851 | rnxTypes.push_back(rnxStr); |
---|
852 | allFound = false; |
---|
853 | } |
---|
854 | } |
---|
855 | } |
---|
856 | if (!allFound) { |
---|
857 | QString msg; |
---|
858 | QTextStream str(&msg); |
---|
859 | QString s; |
---|
860 | str << obs._prn.system() << " " |
---|
861 | << s.sprintf("%2d", rnxTypes.size()) << " "; |
---|
862 | for (int iType = 0; iType < rnxTypes.size(); iType++) { |
---|
863 | str << " " << rnxTypes[iType]; |
---|
864 | } |
---|
865 | emit(newMessage(_staID + ": Observation Types: " + msg.toLatin1(), |
---|
866 | true)); |
---|
867 | } |
---|
868 | } |
---|
869 | |
---|
870 | // RTCMv3 antenna descriptor |
---|
871 | // ------------------------- |
---|
872 | for (int ii = 0; ii < decoder()->_antType.size(); ii++) { |
---|
873 | QString ant1 = QString(": Antenna Descriptor: %1 ").arg(decoder()->_antType[ii].descriptor); |
---|
874 | emit(newMessage(_staID + ant1.toLatin1(), true)); |
---|
875 | if (strlen(decoder()->_antType[ii].serialnumber)) { |
---|
876 | QString ant2 = QString(": Antenna Serial Number: %1 ").arg(decoder()->_antType[ii].serialnumber); |
---|
877 | emit(newMessage(_staID + ant2.toLatin1(), true)); |
---|
878 | } |
---|
879 | } |
---|
880 | |
---|
881 | // RTCM Antenna Coordinates |
---|
882 | // ------------------------ |
---|
883 | for (int ii = 0; ii < decoder()->_antList.size(); ii++) { |
---|
884 | QByteArray antT; |
---|
885 | if (decoder()->_antList[ii].type == GPSDecoder::t_antRefPoint::ARP) { |
---|
886 | antT = "ARP"; |
---|
887 | } else if (decoder()->_antList[ii].type == GPSDecoder::t_antRefPoint::APC) { |
---|
888 | antT = "APC"; |
---|
889 | } |
---|
890 | QByteArray ant1, ant2, ant3; |
---|
891 | ant1 = QString("%1 ").arg(decoder()->_antList[ii].xx, 0, 'f', 4).toLatin1(); |
---|
892 | ant2 = QString("%1 ").arg(decoder()->_antList[ii].yy, 0, 'f', 4).toLatin1(); |
---|
893 | ant3 = QString("%1 ").arg(decoder()->_antList[ii].zz, 0, 'f', 4).toLatin1(); |
---|
894 | emit(newMessage(_staID + ": " + antT + " (ITRF) X " + ant1 + "m", true)); |
---|
895 | emit(newMessage(_staID + ": " + antT + " (ITRF) Y " + ant2 + "m", true)); |
---|
896 | emit(newMessage(_staID + ": " + antT + " (ITRF) Z " + ant3 + "m", true)); |
---|
897 | double hh = 0.0; |
---|
898 | if (decoder()->_antList[ii].height_f) { |
---|
899 | hh = decoder()->_antList[ii].height; |
---|
900 | QByteArray ant4 = QString("%1 ").arg(hh, 0, 'f', 4).toLatin1(); |
---|
901 | emit(newMessage( |
---|
902 | _staID + ": Antenna height above marker " + ant4 + "m", true)); |
---|
903 | } |
---|
904 | emit(newAntCrd(_staID, decoder()->_antList[ii].xx, |
---|
905 | decoder()->_antList[ii].yy, decoder()->_antList[ii].zz, hh, antT)); |
---|
906 | } |
---|
907 | |
---|
908 | // RTCMv3 receiver descriptor |
---|
909 | // -------------------------- |
---|
910 | for (int ii = 0; ii < decoder()->_recType.size(); ii++) { |
---|
911 | QString rec1 = QString(": Receiver Descriptor: %1 ").arg(decoder()->_recType[ii].descriptor); |
---|
912 | QString rec2 = QString(": Receiver Firmware Version: %1 ").arg(decoder()->_recType[ii].firmware); |
---|
913 | QString rec3 = QString(": Receiver Serial Number: %1 ").arg(decoder()->_recType[ii].serialnumber); |
---|
914 | emit(newMessage(_staID + rec1.toLatin1(), true)); |
---|
915 | emit(newMessage(_staID + rec2.toLatin1(), true)); |
---|
916 | emit(newMessage(_staID + rec3.toLatin1(), true)); |
---|
917 | } |
---|
918 | |
---|
919 | // RTCM GLONASS slots |
---|
920 | // ------------------ |
---|
921 | if (decoder()->_gloFrq.size()) { |
---|
922 | bool allFound = true; |
---|
923 | QString slot = decoder()->_gloFrq; |
---|
924 | slot.replace(" ", " ").replace(" ", ":"); |
---|
925 | if (_gloSlots.indexOf(slot) == -1) { |
---|
926 | _gloSlots.append(slot); |
---|
927 | allFound = false; |
---|
928 | } |
---|
929 | if (!allFound) { |
---|
930 | _gloSlots.sort(); |
---|
931 | emit(newMessage( |
---|
932 | _staID + ": GLONASS Slot:Freq " + _gloSlots.join(" ").toLatin1(), |
---|
933 | true)); |
---|
934 | } |
---|
935 | } |
---|
936 | } |
---|
937 | } |
---|
938 | |
---|
939 | #ifdef MLS_SOFTWARE |
---|
940 | for (int ii=0; ii <decoder()->_antList.size(); ii++) { |
---|
941 | QByteArray antT; |
---|
942 | if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) { |
---|
943 | antT = "ARP"; |
---|
944 | } |
---|
945 | else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) { |
---|
946 | antT = "APC"; |
---|
947 | } |
---|
948 | double hh = 0.0; |
---|
949 | if (decoder()->_antList[ii].height_f) { |
---|
950 | hh = decoder()->_antList[ii].height; |
---|
951 | } |
---|
952 | emit(newAntCrd(_staID, decoder()->_antList[ii].xx, |
---|
953 | decoder()->_antList[ii].yy, decoder()->_antList[ii].zz, |
---|
954 | hh, antT)); |
---|
955 | } |
---|
956 | |
---|
957 | for (int ii = 0; ii <decoder()->_typeList.size(); ii++) { |
---|
958 | emit(newRTCMMessage(_staID, decoder()->_typeList[ii])); |
---|
959 | } |
---|
960 | #endif |
---|
961 | |
---|
962 | decoder()->_gloFrq.clear(); |
---|
963 | decoder()->_typeList.clear(); |
---|
964 | decoder()->_antType.clear(); |
---|
965 | decoder()->_recType.clear(); |
---|
966 | decoder()->_antList.clear(); |
---|
967 | } |
---|
968 | |
---|
969 | // Handle Data from Serial Port |
---|
970 | //////////////////////////////////////////////////////////////////////////// |
---|
971 | void bncGetThread::slotSerialReadyRead() { |
---|
972 | |
---|
973 | if (_serialPort) { |
---|
974 | |
---|
975 | if (_nmea == "yes" && _serialNMEA == MANUAL_NMEA) { |
---|
976 | if (_manualNMEASampl) { |
---|
977 | int dt = _lastManualNMEA.secsTo(QDateTime::currentDateTime()); |
---|
978 | if (dt && (fmod(double(dt), double(_manualNMEASampl)) == 0.0)) { |
---|
979 | _query->sendNMEA(_manualNMEAString); |
---|
980 | _lastManualNMEA = QDateTime::currentDateTime(); |
---|
981 | } |
---|
982 | } |
---|
983 | } |
---|
984 | |
---|
985 | int nb = _serialPort->bytesAvailable(); |
---|
986 | if (nb > 0) { |
---|
987 | QByteArray data = _serialPort->read(nb); |
---|
988 | |
---|
989 | if (_nmea == "yes" && _serialNMEA == AUTO_NMEA) { |
---|
990 | int i1 = data.indexOf("$GPGGA"); |
---|
991 | if (i1 == -1) { |
---|
992 | i1 = data.indexOf("$GNGGA"); |
---|
993 | } |
---|
994 | if (i1 != -1) { |
---|
995 | int i2 = data.indexOf("*", i1); |
---|
996 | if (i2 != -1 && data.size() > i2 + 1) { |
---|
997 | QByteArray gga = data.mid(i1, i2 - i1 + 3); |
---|
998 | _query->sendNMEA(gga); |
---|
999 | } |
---|
1000 | } |
---|
1001 | } |
---|
1002 | |
---|
1003 | if (_serialOutFile) { |
---|
1004 | _serialOutFile->write(data); |
---|
1005 | _serialOutFile->flush(); |
---|
1006 | } |
---|
1007 | } |
---|
1008 | } |
---|
1009 | } |
---|
1010 | |
---|
1011 | void bncGetThread::slotNewNMEAConnection() { |
---|
1012 | _nmeaSockets->push_back(_nmeaServer->nextPendingConnection()); |
---|
1013 | emit(newMessage( |
---|
1014 | QString("New PPP client on port: # %1").arg(_nmeaSockets->size()).toLatin1(), |
---|
1015 | true)); |
---|
1016 | } |
---|
1017 | |
---|
1018 | // |
---|
1019 | //////////////////////////////////////////////////////////////////////////// |
---|
1020 | void bncGetThread::slotNewNMEAstr(QByteArray staID, QByteArray str) { |
---|
1021 | if (_nmeaPortsMap.contains(staID)) { |
---|
1022 | int nmeaPort = _nmeaPortsMap.value(staID); |
---|
1023 | QMutableListIterator<QTcpSocket*> is(*_nmeaSockets); |
---|
1024 | while (is.hasNext()) { |
---|
1025 | QTcpSocket* sock = is.next(); |
---|
1026 | if (sock->localPort() == nmeaPort) { |
---|
1027 | if (sock->state() == QAbstractSocket::ConnectedState) { |
---|
1028 | sock->write(str); |
---|
1029 | } else if (sock->state() != QAbstractSocket::ConnectingState) { |
---|
1030 | delete sock; |
---|
1031 | is.remove(); |
---|
1032 | } |
---|
1033 | } |
---|
1034 | } |
---|
1035 | } |
---|
1036 | } |
---|