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

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

* empty log message *

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