source: ntrip/trunk/BNC/src/bncnetqueryudp.cpp@ 6787

Last change on this file since 6787 was 6787, checked in by stuerze, 7 years ago

add keep-alive request to send gga message in ntrip version 1 mode without interruption

File size: 4.7 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class: bncNetQueryUdp
6 *
7 * Purpose: Blocking Network Requests (NTRIP Version 2 with plain UDP)
8 *
9 * Author: L. Mervart
10 *
11 * Created: 04-Feb-2009
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iostream>
18#include <iomanip>
19#include <time.h>
20
21#include "bncnetqueryudp.h"
22#include "bncsettings.h"
23#include "bncversion.h"
24
25using namespace std;
26
27#define TIME_RESOLUTION 125
28
29// Constructor
30////////////////////////////////////////////////////////////////////////////
31bncNetQueryUdp::bncNetQueryUdp() {
32 _port = 0;
33 _udpSocket = 0;
34 _eventLoop = new QEventLoop(this);
35
36 _keepAlive[ 0] = 128;
37 _keepAlive[ 1] = 96;
38 for (int ii = 2; ii <=11; ii++) {
39 _keepAlive[ii] = 0;
40 }
41}
42
43// Destructor
44////////////////////////////////////////////////////////////////////////////
45bncNetQueryUdp::~bncNetQueryUdp() {
46 delete _eventLoop;
47 delete _udpSocket;
48}
49
50//
51////////////////////////////////////////////////////////////////////////////
52void bncNetQueryUdp::stop() {
53 _eventLoop->quit();
54 _status = finished;
55}
56
57//
58////////////////////////////////////////////////////////////////////////////
59void bncNetQueryUdp::slotKeepAlive() {
60 if (_udpSocket) {
61 _udpSocket->writeDatagram(_keepAlive, 12, _address, _port);
62 }
63 QTimer::singleShot(15000, this, SLOT(slotKeepAlive()));
64}
65
66//
67////////////////////////////////////////////////////////////////////////////
68void bncNetQueryUdp::waitForRequestResult(const QUrl&, QByteArray&) {
69}
70
71//
72////////////////////////////////////////////////////////////////////////////
73void bncNetQueryUdp::waitForReadyRead(QByteArray& outData) {
74
75 // Wait Loop
76 // ---------
77 if (!_udpSocket->hasPendingDatagrams()) {
78 _eventLoop->exec();
79 }
80
81 // Append Data
82 // -----------
83 QByteArray datagram;
84 datagram.resize(_udpSocket->pendingDatagramSize());
85 _udpSocket->readDatagram(datagram.data(), datagram.size());
86
87 if (datagram.size() > 12) {
88 outData.append(datagram.mid(12));
89 }
90 else {
91 _status = error;
92 }
93}
94
95// Connect to Caster, send the Request
96////////////////////////////////////////////////////////////////////////////
97void bncNetQueryUdp::startRequest(const QUrl& url, const QByteArray& gga) {
98
99 _status = running;
100
101 // Default scheme and path
102 // -----------------------
103 _url = url;
104 if (_url.scheme().isEmpty()) {
105 _url.setScheme("http");
106 }
107 if (_url.path().isEmpty()) {
108 _url.setPath("/");
109 }
110
111 _port = _url.port();
112
113 delete _udpSocket;
114 _udpSocket = new QUdpSocket();
115 _udpSocket->bind(0);
116 connect(_udpSocket, SIGNAL(readyRead()), _eventLoop, SLOT(quit()));
117
118 QHostInfo hInfo = QHostInfo::fromName(url.host());
119
120 if (!hInfo.addresses().isEmpty()) {
121
122 _address = hInfo.addresses().first();
123
124 // Send Request
125 // ------------
126 QString uName = QUrl::fromPercentEncoding(_url.userName().toAscii());
127 QString passW = QUrl::fromPercentEncoding(_url.password().toAscii());
128 QByteArray userAndPwd;
129
130 if(!uName.isEmpty() || !passW.isEmpty()) {
131 userAndPwd = "Authorization: Basic " + (uName.toAscii() + ":" +
132 passW.toAscii()).toBase64() + "\r\n";
133 }
134
135 QByteArray reqStr = "GET " + _url.path().toAscii() + " HTTP/1.1\r\n"
136 + "Host: " + _url.host().toAscii() + "\r\n"
137 + "Ntrip-Version: Ntrip/2.0\r\n"
138 + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n";
139 if (!gga.isEmpty()) {
140 reqStr += "Ntrip-GGA: " + gga + "\r\n";
141 }
142 reqStr += userAndPwd + "Connection: close\r\n\r\n";
143
144 char rtpbuffer[12 + reqStr.size()];
145 rtpbuffer[0] = 128;
146 rtpbuffer[1] = 97;
147 for (int jj = 2; jj <= 11; jj++) {
148 rtpbuffer[jj] = _keepAlive[jj];
149 }
150 for (int ii = 0; ii < reqStr.size(); ii++) {
151 rtpbuffer[12+ii] = reqStr[ii];
152 }
153
154 _udpSocket->writeDatagram(rtpbuffer, 12 + reqStr.size(), _address, _port);
155
156 // Wait for Reply, read Session Number
157 // -----------------------------------
158 QByteArray repl;
159 waitForReadyRead(repl);
160
161 QTextStream in(repl);
162 QString line = in.readLine();
163 while (!line.isEmpty()) {
164 if (line.indexOf("Session:") == 0) {
165 _session = line.mid(9).toUInt();
166 _keepAlive[ 8] = (_session >> 24) & 0xFF;
167 _keepAlive[ 9] = (_session >> 16) & 0xFF;
168 _keepAlive[10] = (_session >> 8) & 0xFF;
169 _keepAlive[11] = (_session) & 0xFF;
170 break;
171 }
172 line = in.readLine();
173 }
174
175 QTimer::singleShot(15000, this, SLOT(slotKeepAlive()));
176 }
177}
178
179void bncNetQueryUdp::keepAliveRequest(const QUrl& /* url */ , const QByteArray& /* gga */) {
180}
Note: See TracBrowser for help on using the repository browser.