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

Last change on this file since 278 was 278, checked in by mervart, 18 years ago

* empty log message *

File size: 8.0 KB
RevLine 
[35]1
2/* -------------------------------------------------------------------------
[93]3 * BKG NTRIP Client
[35]4 * -------------------------------------------------------------------------
5 *
6 * Class: bncGetThread
7 *
8 * Purpose: Thread that retrieves data from NTRIP caster
9 *
10 * Author: L. Mervart
11 *
12 * Created: 24-Dec-2005
13 *
14 * Changes:
15 *
16 * -----------------------------------------------------------------------*/
17
[277]18#include <stdlib.h>
19
[35]20#include <QFile>
21#include <QTextStream>
22#include <QtNetwork>
23
24#include "bncgetthread.h"
[192]25#include "bnctabledlg.h"
[243]26#include "bncapp.h"
[65]27
[243]28#include "RTCM/RTCM2Decoder.h"
[65]29#include "RTCM3/rtcm3.h"
[61]30#include "RTIGS/rtigs.h"
[35]31
32using namespace std;
33
34// Constructor
35////////////////////////////////////////////////////////////////////////////
[278]36bncGetThread::bncGetThread(const QUrl& mountPoint,
37 const QByteArray& format, int iMount) {
[136]38 _decoder = 0;
[35]39 _mountPoint = mountPoint;
[89]40 _staID = mountPoint.path().mid(1).toAscii();
[255]41 _staID_orig = _staID;
[59]42 _format = format;
[35]43 _socket = 0;
[181]44 _timeOut = 20*1000; // 20 seconds
[138]45 _nextSleep = 1; // 1 second
[278]46 _iMount = iMount; // index in mountpoints array
[255]47
48 // Check name conflict
49 // -------------------
50 QSettings settings;
51 QListIterator<QString> it(settings.value("mountPoints").toStringList());
52 int num = 0;
[278]53 int ind = -1;
[255]54 while (it.hasNext()) {
[278]55 ++ind;
[255]56 QStringList hlp = it.next().split(" ");
57 if (hlp.size() <= 1) continue;
58 QUrl url(hlp[0]);
59 if (_mountPoint.path() == url.path()) {
[278]60 if (_iMount > ind) {
61 ++num;
[255]62 }
63 }
64 }
[278]65
66 if (num > 0) {
67 _staID = _staID.left(_staID.length()-1) + QString("%1").arg(num).toAscii();
[255]68 }
[35]69}
70
71// Destructor
72////////////////////////////////////////////////////////////////////////////
73bncGetThread::~bncGetThread() {
74 delete _socket;
[136]75 delete _decoder;
[35]76}
77
78// Connect to Caster, send the Request (static)
79////////////////////////////////////////////////////////////////////////////
[136]80QTcpSocket* bncGetThread::request(const QUrl& mountPoint, int timeOut,
81 QString& msg) {
[35]82
[88]83 // Connect the Socket
84 // ------------------
85 QSettings settings;
86 QString proxyHost = settings.value("proxyHost").toString();
87 int proxyPort = settings.value("proxyPort").toInt();
88
[35]89 QTcpSocket* socket = new QTcpSocket();
90 if ( proxyHost.isEmpty() ) {
[88]91 socket->connectToHost(mountPoint.host(), mountPoint.port());
[35]92 }
93 else {
94 socket->connectToHost(proxyHost, proxyPort);
95 }
96 if (!socket->waitForConnected(timeOut)) {
[82]97 msg += "Connect timeout\n";
[35]98 delete socket;
99 return 0;
100 }
101
102 // Send Request
103 // ------------
[88]104 QByteArray userAndPwd = mountPoint.userName().toAscii() + ":" +
105 mountPoint.password().toAscii();
[92]106
107 QUrl hlp;
108 hlp.setScheme("http");
109 hlp.setHost(mountPoint.host());
110 hlp.setPort(mountPoint.port());
111 hlp.setPath(mountPoint.path());
112
[214]113 QByteArray reqStr;
114 if ( proxyHost.isEmpty() ) {
115 if (hlp.path().indexOf("/") != 0) hlp.setPath("/");
116 reqStr = "GET " + hlp.path().toAscii() +
117 " HTTP/1.0\r\n"
[237]118 "User-Agent: NTRIP BNC 1.0b\r\n"
[214]119 "Authorization: Basic " +
120 userAndPwd.toBase64() + "\r\n\r\n";
121 } else {
122 reqStr = "GET " + hlp.toEncoded() +
123 " HTTP/1.0\r\n"
[237]124 "User-Agent: NTRIP BNC 1.0b\r\n"
[214]125 "Authorization: Basic " +
126 userAndPwd.toBase64() + "\r\n\r\n";
[205]127 }
128
[82]129 msg += reqStr;
[35]130
131 socket->write(reqStr, reqStr.length());
132
133 if (!socket->waitForBytesWritten(timeOut)) {
[82]134 msg += "Write timeout\n";
[35]135 delete socket;
136 return 0;
137 }
138
139 return socket;
140}
141
[136]142// Init Run
[35]143////////////////////////////////////////////////////////////////////////////
[138]144t_irc bncGetThread::initRun() {
[35]145
146 // Send the Request
147 // ----------------
[82]148 QString msg;
[88]149
[136]150 _socket = bncGetThread::request(_mountPoint, _timeOut, msg);
[88]151
[193]152 //// emit(newMessage(msg.toAscii()));
[82]153
[35]154 if (!_socket) {
[138]155 return failure;
[35]156 }
157
158 // Read Caster Response
159 // --------------------
[136]160 _socket->waitForReadyRead(_timeOut);
[35]161 if (_socket->canReadLine()) {
162 QString line = _socket->readLine();
[146]163 if (line.indexOf("Unauthorized") != -1) {
[192]164 QStringList table;
165 bncTableDlg::getFullTable(_mountPoint.host(), _mountPoint.port(), table);
166 QString net;
167 QStringListIterator it(table);
168 while (it.hasNext()) {
169 QString line = it.next();
170 if (line.indexOf("STR") == 0) {
171 QStringList tags = line.split(";");
[255]172 if (tags.at(1) == _staID_orig) {
[192]173 net = tags.at(7);
174 break;
175 }
176 }
177 }
178
179 QString reg;
180 it.toFront();
181 while (it.hasNext()) {
182 QString line = it.next();
183 if (line.indexOf("NET") == 0) {
184 QStringList tags = line.split(";");
185 if (tags.at(1) == net) {
186 reg = tags.at(7);
187 break;
188 }
189 }
190 }
[194]191 emit(newMessage((_staID + ": Caster Response: " + line +
[200]192 " Adjust User-ID and Password Register, see"
[194]193 "\n " + reg).toAscii()));
[192]194 return fatal;
[146]195 }
[35]196 if (line.indexOf("ICY 200 OK") != 0) {
[190]197 emit(newMessage((_staID + ": Wrong Caster Response:\n" + line).toAscii()));
[144]198 return failure;
[35]199 }
200 }
201 else {
[190]202 emit(newMessage(_staID + ": Response Timeout"));
[138]203 return failure;
[35]204 }
205
206 // Instantiate the filter
207 // ----------------------
[136]208 if (!_decoder) {
209 if (_format.indexOf("RTCM_2") != -1) {
210 emit(newMessage("Get Data: " + _staID + " in RTCM 2.x format"));
[243]211 _decoder = new RTCM2Decoder();
[136]212 }
213 else if (_format.indexOf("RTCM_3") != -1) {
214 emit(newMessage("Get Data: " + _staID + " in RTCM 3.0 format"));
215 _decoder = new rtcm3();
216 }
217 else if (_format.indexOf("RTIGS") != -1) {
218 emit(newMessage("Get Data: " + _staID + " in RTIGS format"));
219 _decoder = new rtigs();
220 }
221 else {
[190]222 emit(newMessage(_staID + ": Unknown data format " + _format));
[250]223 return fatal;
[136]224 }
[60]225 }
[138]226 return success;
[136]227}
[59]228
[136]229// Run
230////////////////////////////////////////////////////////////////////////////
231void bncGetThread::run() {
232
[229]233 t_irc irc = initRun();
234
235 if (irc == fatal) {
[192]236 QThread::exit(1);
237 return;
238 }
[229]239 else if (irc != success) {
[190]240 emit(newMessage(_staID + ": initRun failed, reconnecting"));
[138]241 tryReconnect();
242 }
[136]243
[35]244 // Read Incoming Data
245 // ------------------
246 while (true) {
[249]247 try {
248 if (_socket->state() != QAbstractSocket::ConnectedState) {
249 emit(newMessage(_staID + ": Socket not connected, reconnecting"));
250 tryReconnect();
[35]251 }
[249]252
253
254 _socket->waitForReadyRead(_timeOut);
255 qint64 nBytes = _socket->bytesAvailable();
256 if (nBytes > 0) {
257 char* data = new char[nBytes];
258 _socket->read(data, nBytes);
259 _decoder->Decode(data, nBytes);
260 delete data;
261 for (list<Observation*>::iterator it = _decoder->_obsList.begin();
262 it != _decoder->_obsList.end(); it++) {
263 emit newObs(_staID, *it);
[258]264 bool firstObs = (it == _decoder->_obsList.begin());
265 _global_caster->newObs(_staID, _mountPoint, firstObs, *it);
[249]266 }
267 _decoder->_obsList.clear();
268 }
269 else {
270 emit(newMessage(_staID + ": Data Timeout, reconnecting"));
271 tryReconnect();
272 }
[35]273 }
[249]274 catch (const char* msg) {
275 emit(newMessage(_staID + msg));
[136]276 tryReconnect();
[35]277 }
278 }
279}
280
281// Exit
282////////////////////////////////////////////////////////////////////////////
283void bncGetThread::exit(int exitCode) {
284 if (exitCode!= 0) {
[88]285 emit error(_staID);
[35]286 }
287 QThread::exit(exitCode);
[148]288 terminate();
[35]289}
[82]290
[136]291// Try Re-Connect
292////////////////////////////////////////////////////////////////////////////
293void bncGetThread::tryReconnect() {
[138]294 while (1) {
295 delete _socket; _socket = 0;
296 sleep(_nextSleep);
297 if ( initRun() == success ) {
298 break;
299 }
300 else {
301 _nextSleep *= 2;
[181]302 if (_nextSleep > 128) {
303 _nextSleep = 128;
[152]304 }
[277]305 _nextSleep += rand() % 6;
[138]306 }
307 }
308 _nextSleep = 1;
[136]309}
Note: See TracBrowser for help on using the repository browser.