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

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

* empty log message *

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