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

Last change on this file since 268 was 258, checked in by mervart, 20 years ago

* empty log message *

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