source: ntrip/branches/BNC_2.12/src/bncnetqueryv1.cpp@ 10576

Last change on this file since 10576 was 6787, checked in by stuerze, 10 years ago

add keep-alive request to send gga message in ntrip version 1 mode without interruption

File size: 7.9 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class: bncNetQueryV1
6 *
7 * Purpose: Blocking Network Requests (NTRIP Version 1)
8 *
9 * Author: L. Mervart
10 *
11 * Created: 27-Dec-2008
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iostream>
18#include <iomanip>
19
20#include "bncnetqueryv1.h"
21#include "bncsettings.h"
22#include "bncversion.h"
23
24using namespace std;
25
26// Constructor
27////////////////////////////////////////////////////////////////////////////
28bncNetQueryV1::bncNetQueryV1() {
29 _socket = 0;
30 _eventLoop = new QEventLoop(this);
31 _timeOut = 20000;
32}
33
34// Destructor
35////////////////////////////////////////////////////////////////////////////
36bncNetQueryV1::~bncNetQueryV1() {
37 delete _socket;
38 delete _eventLoop;
39}
40
41//
42////////////////////////////////////////////////////////////////////////////
43void bncNetQueryV1::stop() {
44 _eventLoop->quit();
45#ifndef sparc
46 if (_socket) {
47 _socket->abort();
48 }
49#endif
50 _status = finished;
51}
52
53//
54////////////////////////////////////////////////////////////////////////////
55void bncNetQueryV1::waitForRequestResult(const QUrl& url, QByteArray& outData){
56
57 delete _socket;
58 _socket = new QTcpSocket();
59
60 connect(_socket, SIGNAL(disconnected()), _eventLoop, SLOT(quit()));
61
62 startRequestPrivate(url, "", true);
63
64 QTimer::singleShot(10000, _eventLoop, SLOT(quit()));
65
66 _eventLoop->exec();
67
68 if (_socket) {
69 outData = _socket->readAll();
70 delete _socket; _socket = 0;
71 _status = finished;
72 }
73}
74
75//
76////////////////////////////////////////////////////////////////////////////
77void bncNetQueryV1::waitForReadyRead(QByteArray& outData) {
78 if (_socket && _socket->state() == QAbstractSocket::ConnectedState) {
79 while (true) {
80 int nBytes = _socket->bytesAvailable();
81 if (nBytes > 0) {
82 outData = _socket->readAll();
83 return;
84 }
85 else if (!_socket->waitForReadyRead(_timeOut)) {
86 QString errStr = _socket->errorString();
87 if (errStr.isEmpty()) {
88 errStr = "Read timeout";
89 }
90 delete _socket;
91 _socket = 0;
92 _status = error;
93 emit newMessage(_url.path().toAscii().replace(0,1,"")
94 + ": " + errStr.toAscii(), true);
95 return;
96 }
97 }
98 }
99}
100
101// Connect to Caster, send the Request
102////////////////////////////////////////////////////////////////////////////
103void bncNetQueryV1::startRequest(const QUrl& url, const QByteArray& gga) {
104 startRequestPrivate(url, gga, false);
105}
106
107
108// Already connected to Caster, send another Request
109////////////////////////////////////////////////////////////////////////////
110void bncNetQueryV1::keepAliveRequest(const QUrl& url, const QByteArray& gga) {
111
112 _status = running;
113
114 // Default scheme and path
115 // -----------------------
116 _url = url;
117 if (_url.scheme().isEmpty()) {
118 _url.setScheme("http");
119 }
120 if (_url.path().isEmpty()) {
121 _url.setPath("/");
122 }
123
124 // Connect the Socket
125 // ------------------
126 bncSettings settings;
127 QString proxyHost = settings.value("proxyHost").toString();
128 int proxyPort = settings.value("proxyPort").toInt();
129
130 if ( proxyHost.isEmpty() ) {
131 _socket->connectToHost(_url.host(), _url.port());
132 }
133 else {
134 _socket->connectToHost(proxyHost, proxyPort);
135 }
136 if (!_socket->waitForConnected(_timeOut)) {
137 delete _socket;
138 _socket = 0;
139 _status = error;
140 return;
141 }
142
143 // Send Request
144 // ------------
145 QByteArray reqStr;
146
147 // NMEA string to handle VRS stream
148 // --------------------------------
149 if (!gga.isEmpty()) {
150 reqStr += gga + "\r\n";
151 }
152
153 _socket->write(reqStr, reqStr.length());
154
155 if (!_socket->waitForBytesWritten(_timeOut)) {
156 delete _socket;
157 _socket = 0;
158 _status = error;
159 emit newMessage(_url.path().toAscii().replace(0,1,"")
160 + ": Write timeout", true);
161 return;
162 }
163
164}
165
166// Connect to Caster, send the Request
167////////////////////////////////////////////////////////////////////////////
168void bncNetQueryV1::startRequestPrivate(const QUrl& url,
169 const QByteArray& gga,
170 bool sendRequestOnly) {
171
172 _status = running;
173
174 if (!sendRequestOnly) {
175 delete _socket;
176 _socket = new QTcpSocket();
177 }
178
179 // Default scheme and path
180 // -----------------------
181 _url = url;
182 if (_url.scheme().isEmpty()) {
183 _url.setScheme("http");
184 }
185 if (_url.path().isEmpty()) {
186 _url.setPath("/");
187 }
188
189 // Connect the Socket
190 // ------------------
191 bncSettings settings;
192 QString proxyHost = settings.value("proxyHost").toString();
193 int proxyPort = settings.value("proxyPort").toInt();
194
195 if ( proxyHost.isEmpty() ) {
196 _socket->connectToHost(_url.host(), _url.port());
197 }
198 else {
199 _socket->connectToHost(proxyHost, proxyPort);
200 }
201 if (!_socket->waitForConnected(_timeOut)) {
202 delete _socket;
203 _socket = 0;
204 _status = error;
205 return;
206 }
207
208 // Send Request
209 // ------------
210 QString uName = QUrl::fromPercentEncoding(_url.userName().toAscii());
211 QString passW = QUrl::fromPercentEncoding(_url.password().toAscii());
212 QByteArray userAndPwd;
213
214 if(!uName.isEmpty() || !passW.isEmpty()) {
215 userAndPwd = "Authorization: Basic " + (uName.toAscii() + ":" +
216 passW.toAscii()).toBase64() + "\r\n";
217 }
218
219 QByteArray reqStr;
220 if ( proxyHost.isEmpty() ) {
221 if (_url.path().indexOf("/") != 0) _url.setPath("/");
222 reqStr = "GET " + _url.path().toAscii() + " HTTP/1.0\r\n"
223 + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n"
224 + "Host: " + _url.host().toAscii() + "\r\n"
225 + userAndPwd + "\r\n";
226 } else {
227 reqStr = "GET " + _url.toEncoded() + " HTTP/1.0\r\n"
228 + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n"
229 + "Host: " + _url.host().toAscii() + "\r\n"
230 + userAndPwd + "\r\n";
231 }
232
233 // NMEA string to handle VRS stream
234 // --------------------------------
235 if (!gga.isEmpty()) {
236 reqStr += gga + "\r\n";
237 }
238
239 _socket->write(reqStr, reqStr.length());
240
241 if (!_socket->waitForBytesWritten(_timeOut)) {
242 delete _socket;
243 _socket = 0;
244 _status = error;
245 emit newMessage(_url.path().toAscii().replace(0,1,"")
246 + ": Write timeout", true);
247 return;
248 }
249
250 // Read Caster Response
251 // --------------------
252 if (!sendRequestOnly) {
253 bool proxyResponse = false;
254 QStringList response;
255 while (true) {
256 if (_socket->canReadLine()) {
257 QString line = _socket->readLine();
258
259 if (line.indexOf("ICY 200 OK") == -1 &&
260 line.indexOf("HTTP") != -1 &&
261 line.indexOf("200 OK") != -1 ) {
262 proxyResponse = true;
263 }
264
265 if (!proxyResponse && !line.trimmed().isEmpty()) {
266 response.push_back(line);
267 }
268
269 if (line.trimmed().isEmpty()) {
270 if (proxyResponse) {
271 proxyResponse = false;
272 }
273 else {
274 break;
275 }
276 }
277
278 if (line.indexOf("Unauthorized") != -1) {
279 break;
280 }
281
282 if (!proxyResponse &&
283 line.indexOf("200 OK") != -1 &&
284 line.indexOf("SOURCETABLE") == -1) {
285 response.clear();
286 if (_socket->canReadLine()) {
287 _socket->readLine();
288 }
289 break;
290 }
291 }
292 else if (!_socket->waitForReadyRead(_timeOut)) {
293 delete _socket;
294 _socket = 0;
295 _status = error;
296 emit newMessage(_url.path().toAscii().replace(0,1,"")
297 + ": Response timeout", true);
298 return;
299 }
300 }
301 if (response.size() > 0) {
302 delete _socket;
303 _socket = 0;
304 _status = error;
305 emit newMessage(_url.path().toAscii().replace(0,1,"")
306 + ": Wrong caster response\n"
307 + response.join("").toAscii(), true);
308 }
309 }
310}
311
Note: See TracBrowser for help on using the repository browser.