source: ntrip/trunk/BNC/bncsocket.cpp@ 1360

Last change on this file since 1360 was 1360, checked in by mervart, 16 years ago

* empty log message *

File size: 10.8 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class: bncSocket
6 *
7 * Purpose: Combines QTcpSocket (NTRIP v1) and QNetworkReply (NTRIP v2)
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 "bncsocket.h"
21#include "bncapp.h"
22
23using namespace std;
24
25#define BNCVERSION "1.7"
26
27// Constructor
28////////////////////////////////////////////////////////////////////////////
29bncSocket::bncSocket() {
30 bncApp* app = (bncApp*) qApp;
31 app->connect(this, SIGNAL(newMessage(QByteArray,bool)),
32 app, SLOT(slotMessage(const QByteArray,bool)));
33 _socket = 0;
34 _http = 0;
35 _buffer = 0;
36}
37
38// Destructor
39////////////////////////////////////////////////////////////////////////////
40bncSocket::~bncSocket() {
41 cout << "~bncSocket" << endl;
42 delete _socket;
43 delete _http;
44 delete _buffer;
45}
46
47//
48////////////////////////////////////////////////////////////////////////////
49void bncSocket::connectToHost(const QString &hostName, quint16 port,
50 QIODevice::OpenMode mode) {
51 if (_socket) {
52 _socket->connectToHost(hostName, port, mode);
53 }
54}
55
56//
57////////////////////////////////////////////////////////////////////////////
58bool bncSocket::waitForConnected(int msecs) {
59 if (_socket) {
60 return _socket->waitForConnected(msecs);
61 }
62 else {
63 return false;
64 }
65}
66
67//
68////////////////////////////////////////////////////////////////////////////
69QAbstractSocket::SocketState bncSocket::state() const {
70 if (_socket) {
71 return _socket->state();
72 }
73 else {
74 return QAbstractSocket::UnconnectedState;
75 }
76}
77
78//
79////////////////////////////////////////////////////////////////////////////
80void bncSocket::close() {
81 if (_socket) {
82 _socket->close();
83 }
84}
85
86//
87////////////////////////////////////////////////////////////////////////////
88qint64 bncSocket::bytesAvailable() const {
89 if (_http) {
90 for (int ii = 1; ii < 10; ii++) {
91 cout << "bytesAvailable " << _http->bytesAvailable() << endl;
92 msleep(100);
93 }
94 return _http->bytesAvailable();
95 }
96 else if (_socket) {
97 return _socket->bytesAvailable();
98 }
99 else {
100 return 0;
101 }
102}
103
104//
105////////////////////////////////////////////////////////////////////////////
106bool bncSocket::canReadLine() const {
107 if (_buffer) {
108 return _buffer->canReadLine();
109 }
110 else if (_socket) {
111 return _socket->canReadLine();
112 }
113 else {
114 return false;
115 }
116}
117
118//
119////////////////////////////////////////////////////////////////////////////
120QByteArray bncSocket::readLine(qint64 maxlen) {
121 if (_buffer) {
122 return _buffer->readLine(maxlen);
123 }
124 else if (_socket) {
125 return _socket->readLine(maxlen);
126 }
127 else {
128 return "";
129 }
130}
131
132//
133////////////////////////////////////////////////////////////////////////////
134bool bncSocket::waitForReadyRead(int msecs) {
135 if (_http) {
136 msleep(10);
137 }
138 else if (_socket) {
139 return _socket->waitForReadyRead(msecs);
140 }
141 else {
142 return false;
143 }
144}
145
146//
147////////////////////////////////////////////////////////////////////////////
148qint64 bncSocket::read(char* data, qint64 maxlen) {
149 if (_socket) {
150 return _socket->read(data, maxlen);
151 }
152 else {
153 return -1;
154 }
155}
156
157//
158////////////////////////////////////////////////////////////////////////////
159qint64 bncSocket::write(const char* data, qint64 len) {
160 if (_socket) {
161 return _socket->write(data, len);
162 }
163 else {
164 return -1;
165 }
166}
167
168//
169////////////////////////////////////////////////////////////////////////////
170bool bncSocket::waitForBytesWritten(int msecs) {
171 if (_socket) {
172 return _socket->waitForBytesWritten(msecs);
173 }
174 else {
175 return false;
176 }
177}
178
179// Connect to Caster, send the Request
180////////////////////////////////////////////////////////////////////////////
181t_irc bncSocket::request(const QUrl& mountPoint, const QByteArray& latitude,
182 const QByteArray& longitude, const QByteArray& nmea,
183 const QByteArray& ntripVersion,
184 int timeOut, QString& msg) {
185
186 if (ntripVersion == "AUTO") {
187 emit newMessage("NTRIP Version AUTO not yet implemented", "true");
188 return failure;
189 }
190 else if (ntripVersion == "2") {
191 return request2(mountPoint, latitude, longitude, nmea, timeOut, msg);
192 }
193 else if (ntripVersion != "1") {
194 emit newMessage("Unknown NTRIP Version " + ntripVersion, "true");
195 return failure;
196 }
197
198 delete _socket;
199 _socket = new QTcpSocket();
200
201 // Connect the Socket
202 // ------------------
203 QSettings settings;
204 QString proxyHost = settings.value("proxyHost").toString();
205 int proxyPort = settings.value("proxyPort").toInt();
206
207 if ( proxyHost.isEmpty() ) {
208 _socket->connectToHost(mountPoint.host(), mountPoint.port());
209 }
210 else {
211 _socket->connectToHost(proxyHost, proxyPort);
212 }
213 if (!_socket->waitForConnected(timeOut)) {
214 msg += "Connect timeout\n";
215 delete _socket;
216 _socket = 0;
217 return failure;
218 }
219
220 // Send Request
221 // ------------
222 QString uName = QUrl::fromPercentEncoding(mountPoint.userName().toAscii());
223 QString passW = QUrl::fromPercentEncoding(mountPoint.password().toAscii());
224 QByteArray userAndPwd;
225
226 if(!uName.isEmpty() || !passW.isEmpty())
227 {
228 userAndPwd = "Authorization: Basic " + (uName.toAscii() + ":" +
229 passW.toAscii()).toBase64() + "\r\n";
230 }
231
232 QUrl hlp;
233 hlp.setScheme("http");
234 hlp.setHost(mountPoint.host());
235 hlp.setPort(mountPoint.port());
236 hlp.setPath(mountPoint.path());
237
238 QByteArray reqStr;
239 if ( proxyHost.isEmpty() ) {
240 if (hlp.path().indexOf("/") != 0) hlp.setPath("/");
241 reqStr = "GET " + hlp.path().toAscii() + " HTTP/1.0\r\n"
242 + "User-Agent: NTRIP BNC/" BNCVERSION "\r\n"
243 + userAndPwd + "\r\n";
244 } else {
245 reqStr = "GET " + hlp.toEncoded() + " HTTP/1.0\r\n"
246 + "User-Agent: NTRIP BNC/" BNCVERSION "\r\n"
247 + "Host: " + hlp.host().toAscii() + "\r\n"
248 + userAndPwd + "\r\n";
249 }
250
251 // NMEA string to handle VRS stream
252 // --------------------------------
253 double lat, lon;
254
255 lat = strtod(latitude,NULL);
256 lon = strtod(longitude,NULL);
257
258 if ((nmea == "yes") && (hlp.path().length() > 2) && (hlp.path().indexOf(".skl") < 0)) {
259 const char* flagN="N";
260 const char* flagE="E";
261 if (lon >180.) {lon=(lon-360.)*(-1.); flagE="W";}
262 if ((lon < 0.) && (lon >= -180.)) {lon=lon*(-1.); flagE="W";}
263 if (lon < -180.) {lon=(lon+360.); flagE="E";}
264 if (lat < 0.) {lat=lat*(-1.); flagN="S";}
265 QTime ttime(QDateTime::currentDateTime().toUTC().time());
266 int lat_deg = (int)lat;
267 double lat_min=(lat-lat_deg)*60.;
268 int lon_deg = (int)lon;
269 double lon_min=(lon-lon_deg)*60.;
270 int hh = 0 , mm = 0;
271 double ss = 0.0;
272 hh=ttime.hour();
273 mm=ttime.minute();
274 ss=(double)ttime.second()+0.001*ttime.msec();
275 QString gga;
276 gga += "GPGGA,";
277 gga += QString("%1%2%3,").arg((int)hh, 2, 10, QLatin1Char('0')).arg((int)mm, 2, 10, QLatin1Char('0')).arg((int)ss, 2, 10, QLatin1Char('0'));
278 gga += QString("%1%2,").arg((int)lat_deg,2, 10, QLatin1Char('0')).arg(lat_min, 7, 'f', 4, QLatin1Char('0'));
279 gga += flagN;
280 gga += QString(",%1%2,").arg((int)lon_deg,3, 10, QLatin1Char('0')).arg(lon_min, 7, 'f', 4, QLatin1Char('0'));
281 gga += flagE + QString(",1,05,1.00,+00100,M,10.000,M,,");
282 int xori;
283 char XOR = 0;
284 char *Buff =gga.toAscii().data();
285 int iLen = strlen(Buff);
286 for (xori = 0; xori < iLen; xori++) {
287 XOR ^= (char)Buff[xori];
288 }
289 gga += QString("*%1").arg(XOR, 2, 16, QLatin1Char('0'));
290 reqStr += "$";
291 reqStr += gga;
292 reqStr += "\r\n";
293 }
294
295 msg += reqStr;
296
297 _socket->write(reqStr, reqStr.length());
298
299 if (!_socket->waitForBytesWritten(timeOut)) {
300 msg += "Write timeout\n";
301 delete _socket;
302 _socket = 0;
303 return failure;
304 }
305
306 return success;
307}
308
309//
310////////////////////////////////////////////////////////////////////////////
311void bncSocket::slotRequestFinished(int id, bool error) {
312 cout << "slotRequestFinished " << id << endl;
313 if (error) {
314 cout << "error: " << _http->error() << " "
315 << _http->errorString().toAscii().data() << endl;
316 }
317}
318
319//
320////////////////////////////////////////////////////////////////////////////
321void bncSocket::slotReadyRead() {
322 cout << "slotReadyRead " << _buffer->size() << endl;
323}
324
325//
326////////////////////////////////////////////////////////////////////////////
327void bncSocket::slotSslErrors(const QList<QSslError>&) {
328 cout << "slotSslError" << endl;
329}
330
331//
332////////////////////////////////////////////////////////////////////////////
333void bncSocket::slotDone(bool error) {
334 cout << "slotDone " << endl;
335 if (error) {
336 cout << "error: " << _http->error() << " "
337 << _http->errorString().toAscii().data() << endl;
338 }
339}
340
341// Connect to Caster NTRIP Version 2
342////////////////////////////////////////////////////////////////////////////
343t_irc bncSocket::request2(const QUrl& url, const QByteArray& latitude,
344 const QByteArray& longitude, const QByteArray& nmea,
345 int timeOut, QString& msg) {
346
347 delete _http;
348 _http = new QHttp();
349
350 _http->setHost(url.host());
351
352 // Network Request
353 // ---------------
354 QString path = url.path();
355 if (path.isEmpty()) {
356 path = "/";
357 }
358 QHttpRequestHeader request("GET", path);
359 request.addValue("Host" , url.host().toAscii());
360 request.addValue("Ntrip-Version", "NTRIP/2.0");
361 request.addValue("User-Agent" , "NTRIP BNC/" BNCVERSION);
362 if (!url.userName().isEmpty()) {
363 request.addValue("Authorization", "Basic " +
364 (url.userName() + ":" + url.password()).toAscii().toBase64());
365 }
366 request.addValue("Connection" , "close");
367
368
369 connect(_http, SIGNAL(done(bool)), this, SLOT(slotDone(bool)));
370 connect(_http, SIGNAL(requestFinished(int, bool)),
371 this, SLOT(slotRequestFinished(int, bool)));
372 connect(_http, SIGNAL(sslErrors(const QList<QSslError>&)),
373 this, SLOT(slotSslErrors(const QList<QSslError>&)));
374
375 _buffer = new QBuffer();
376 _buffer->open(QBuffer::ReadWrite);
377 connect(_buffer, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
378
379 _http->request(request, 0, _buffer);
380
381 return success;
382}
383
384// void startQuery(...)
385// {
386// m_eventLoop = new QEventLoop(this);
387// connect(this, SIGNAL(singleQueryDone()), m_eventLoop, SLOT(quit()));
388// connect( qHttp, SIGNAL( requestFinished(int,bool) ), this,
389// SLOT( dataDone(int, bool) ) );
390// qHttp->request( header, QByteArray(), m_buffer );
391// }
392//
393// void dataDone( int, bool )
394// {
395// emit singleQueryDone();
396// }
397//
398// void blockingThing()
399// {
400// startQuery( );
401// m_eventLoop->exec(QEventLoop::ExcludeUserInputEvents);
402// }
403//
Note: See TracBrowser for help on using the repository browser.