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

Last change on this file since 253 was 250, checked in by mervart, 19 years ago

* empty log message *

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