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

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

* empty log message *

File size: 7.8 KB
Line 
1
2/* -------------------------------------------------------------------------
3 * BKG NTRIP Client
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"
23#include "bnctabledlg.h"
24#include "bncapp.h"
25
26#include "RTCM/RTCM2Decoder.h"
27#include "RTCM3/rtcm3.h"
28#include "RTIGS/rtigs.h"
29
30using namespace std;
31
32// Constructor
33////////////////////////////////////////////////////////////////////////////
34bncGetThread::bncGetThread(const QUrl& mountPoint, const QByteArray& format) {
35 _decoder = 0;
36 _mountPoint = mountPoint;
37 _staID = mountPoint.path().mid(1).toAscii();
38 _staID_orig = _staID;
39 _format = format;
40 _socket = 0;
41 _timeOut = 20*1000; // 20 seconds
42 _nextSleep = 1; // 1 second
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 }
64}
65
66// Destructor
67////////////////////////////////////////////////////////////////////////////
68bncGetThread::~bncGetThread() {
69 delete _socket;
70 delete _decoder;
71}
72
73// Connect to Caster, send the Request (static)
74////////////////////////////////////////////////////////////////////////////
75QTcpSocket* bncGetThread::request(const QUrl& mountPoint, int timeOut,
76 QString& msg) {
77
78 // Connect the Socket
79 // ------------------
80 QSettings settings;
81 QString proxyHost = settings.value("proxyHost").toString();
82 int proxyPort = settings.value("proxyPort").toInt();
83
84 QTcpSocket* socket = new QTcpSocket();
85 if ( proxyHost.isEmpty() ) {
86 socket->connectToHost(mountPoint.host(), mountPoint.port());
87 }
88 else {
89 socket->connectToHost(proxyHost, proxyPort);
90 }
91 if (!socket->waitForConnected(timeOut)) {
92 msg += "Connect timeout\n";
93 delete socket;
94 return 0;
95 }
96
97 // Send Request
98 // ------------
99 QByteArray userAndPwd = mountPoint.userName().toAscii() + ":" +
100 mountPoint.password().toAscii();
101
102 QUrl hlp;
103 hlp.setScheme("http");
104 hlp.setHost(mountPoint.host());
105 hlp.setPort(mountPoint.port());
106 hlp.setPath(mountPoint.path());
107
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"
113 "User-Agent: NTRIP BNC 1.0b\r\n"
114 "Authorization: Basic " +
115 userAndPwd.toBase64() + "\r\n\r\n";
116 } else {
117 reqStr = "GET " + hlp.toEncoded() +
118 " HTTP/1.0\r\n"
119 "User-Agent: NTRIP BNC 1.0b\r\n"
120 "Authorization: Basic " +
121 userAndPwd.toBase64() + "\r\n\r\n";
122 }
123
124 msg += reqStr;
125
126 socket->write(reqStr, reqStr.length());
127
128 if (!socket->waitForBytesWritten(timeOut)) {
129 msg += "Write timeout\n";
130 delete socket;
131 return 0;
132 }
133
134 return socket;
135}
136
137// Init Run
138////////////////////////////////////////////////////////////////////////////
139t_irc bncGetThread::initRun() {
140
141 // Send the Request
142 // ----------------
143 QString msg;
144
145 _socket = bncGetThread::request(_mountPoint, _timeOut, msg);
146
147 //// emit(newMessage(msg.toAscii()));
148
149 if (!_socket) {
150 return failure;
151 }
152
153 // Read Caster Response
154 // --------------------
155 _socket->waitForReadyRead(_timeOut);
156 if (_socket->canReadLine()) {
157 QString line = _socket->readLine();
158 if (line.indexOf("Unauthorized") != -1) {
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(";");
167 if (tags.at(1) == _staID_orig) {
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 }
186 emit(newMessage((_staID + ": Caster Response: " + line +
187 " Adjust User-ID and Password Register, see"
188 "\n " + reg).toAscii()));
189 return fatal;
190 }
191 if (line.indexOf("ICY 200 OK") != 0) {
192 emit(newMessage((_staID + ": Wrong Caster Response:\n" + line).toAscii()));
193 return failure;
194 }
195 }
196 else {
197 emit(newMessage(_staID + ": Response Timeout"));
198 return failure;
199 }
200
201 // Instantiate the filter
202 // ----------------------
203 if (!_decoder) {
204 if (_format.indexOf("RTCM_2") != -1) {
205 emit(newMessage("Get Data: " + _staID + " in RTCM 2.x format"));
206 _decoder = new RTCM2Decoder();
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 {
217 emit(newMessage(_staID + ": Unknown data format " + _format));
218 return fatal;
219 }
220 }
221 return success;
222}
223
224// Run
225////////////////////////////////////////////////////////////////////////////
226void bncGetThread::run() {
227
228 t_irc irc = initRun();
229
230 if (irc == fatal) {
231 QThread::exit(1);
232 return;
233 }
234 else if (irc != success) {
235 emit(newMessage(_staID + ": initRun failed, reconnecting"));
236 tryReconnect();
237 }
238
239 // Read Incoming Data
240 // ------------------
241 while (true) {
242 try {
243 if (_socket->state() != QAbstractSocket::ConnectedState) {
244 emit(newMessage(_staID + ": Socket not connected, reconnecting"));
245 tryReconnect();
246 }
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);
259 _global_caster->newObs(_staID, _mountPoint, *it);
260 }
261 _decoder->_obsList.clear();
262 }
263 else {
264 emit(newMessage(_staID + ": Data Timeout, reconnecting"));
265 tryReconnect();
266 }
267 }
268 catch (const char* msg) {
269 emit(newMessage(_staID + msg));
270 tryReconnect();
271 }
272 }
273}
274
275// Exit
276////////////////////////////////////////////////////////////////////////////
277void bncGetThread::exit(int exitCode) {
278 if (exitCode!= 0) {
279 emit error(_staID);
280 }
281 QThread::exit(exitCode);
282 terminate();
283}
284
285// Try Re-Connect
286////////////////////////////////////////////////////////////////////////////
287void bncGetThread::tryReconnect() {
288 while (1) {
289 delete _socket; _socket = 0;
290 sleep(_nextSleep);
291 if ( initRun() == success ) {
292 break;
293 }
294 else {
295 _nextSleep *= 2;
296 if (_nextSleep > 128) {
297 _nextSleep = 128;
298 }
299 }
300 }
301 _nextSleep = 1;
302}
Note: See TracBrowser for help on using the repository browser.