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

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

* empty log message *

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