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

Last change on this file since 1366 was 1366, checked in by mervart, 15 years ago

* empty log message *

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