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

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

* empty log message *

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