source: ntrip/trunk/BNC/src/upload/bncuploadcaster.cpp@ 9707

Last change on this file since 9707 was 9707, checked in by stuerze, 2 years ago

initial Ntrip verion 2 upload implementation

File size: 8.7 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Server
3 * -------------------------------------------------------------------------
4 *
5 * Class: bncUploadCaster
6 *
7 * Purpose: Connection to NTRIP Caster
8 *
9 * Author: L. Mervart
10 *
11 * Created: 29-Mar-2011
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <math.h>
18#include "bncuploadcaster.h"
19#include "bncversion.h"
20#include "bnccore.h"
21#include "bnctableitem.h"
22#include "bncsettings.h"
23
24using namespace std;
25
26// Constructor
27////////////////////////////////////////////////////////////////////////////
28bncUploadCaster::bncUploadCaster(const QString& mountpoint,
29 const QString& outHost, int outPort,
30 const QString& ntripVersion,
31 const QString& userName, const QString& password,
32 int iRow,
33 int rate) {
34 _mountpoint = mountpoint;
35 _casterOutHost = outHost;
36 _casterOutPort = outPort;
37 _ntripVersion = ntripVersion;
38 (_ntripVersion == "2s") ? _secure = true : _secure = false;
39 _postExtension = "";
40 _userName = userName;
41 _password = password;
42 _outSocket = 0;
43 _sOpenTrial = 0;
44 _iRow = iRow;
45 _rate = rate;
46
47 if (_rate < 0) {
48 _rate = 0;
49 }
50 else if (_rate > 60) {
51 _rate = 60;
52 }
53 _isToBeDeleted = false;
54
55 if (!QSslSocket::supportsSsl()) {
56 BNC_CORE->slotMessage("No SSL support, install OpenSSL run-time libraries", true);
57 deleteSafely();
58 }
59
60 if (_ntripVersion != "1") {
61 bncSettings settings;
62 _proxyHost = settings.value("proxyHost").toString();
63 _proxyPort = settings.value("proxyPort").toInt();
64 _sslIgnoreErrors = (Qt::CheckState(settings.value("sslIgnoreErrors").toInt()) == Qt::Checked);
65 if (_secure) {
66 _casterOutPort = 443;
67 _postExtension = QString("https://%1:%2").arg(_casterOutHost).arg(_casterOutPort);
68 }
69 else {
70 _postExtension = QString("http://%1:%2").arg(_casterOutHost).arg(_casterOutPort);
71 }
72 }
73
74 connect(this, SIGNAL(newMessage(QByteArray,bool)),
75 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
76
77 if (BNC_CORE->_uploadTableItems.find(_iRow) != BNC_CORE->_uploadTableItems.end()){
78 connect(this, SIGNAL(newBytes(QByteArray,double)),
79 BNC_CORE->_uploadTableItems.value(iRow),
80 SLOT(slotNewBytes(const QByteArray,double)));
81 }
82 if (BNC_CORE->_uploadEphTableItems.find(_iRow) != BNC_CORE->_uploadEphTableItems.end()){
83 connect(this, SIGNAL(newBytes(QByteArray,double)),
84 BNC_CORE->_uploadEphTableItems.value(iRow),
85 SLOT(slotNewBytes(const QByteArray,double)));
86 }
87}
88
89// Safe Desctructor
90////////////////////////////////////////////////////////////////////////////
91void bncUploadCaster::deleteSafely() {
92 _isToBeDeleted = true;
93 if (!isRunning()) {
94 delete this;
95 }
96}
97
98// Destructor
99////////////////////////////////////////////////////////////////////////////
100bncUploadCaster::~bncUploadCaster() {
101 if (isRunning()) {
102 wait();
103 }
104 if (_outSocket) {
105 disconnect(_outSocket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)),
106 this, SLOT(slotProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)));
107 delete _outSocket;
108 }
109}
110
111//
112////////////////////////////////////////////////////////////////////////////
113void bncUploadCaster::slotProxyAuthenticationRequired(const QNetworkProxy&,
114 QAuthenticator*) {
115 emit newMessage("slotProxyAuthenticationRequired", true);
116}
117
118
119/* TSL/SSL
120////////////////////////////////////////////////////////////////////////////
121void bncUploadCaster::slotSslErrors(QList<QSslError> errors) {
122
123 QString msg = "SSL Error\n";
124 QSslCertificate cert = _outSocket->sslConfiguration().peerCertificate();
125 if (!cert.isNull()) {
126 msg += QString("Server Certificate Issued by:\n"
127 "%1\n%2\nCannot be verified\n")
128#if QT_VERSION >= 0x050000
129 .arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName).at(0))
130 .arg(cert.issuerInfo(QSslCertificate::Organization).at(0));
131#else
132 .arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName))
133 .arg(cert.issuerInfo(QSslCertificate::Organization));
134#endif
135 }
136 QListIterator<QSslError> it(errors);
137 while (it.hasNext()) {
138 const QSslError& err = it.next();
139 msg += "\n" + err.errorString();
140 }
141
142 BNC_CORE->slotMessage(msg.toLatin1(), true);
143
144 if (_sslIgnoreErrors) {
145 _outSocket->ignoreSslErrors();
146 }
147 else {
148 deleteSafely();
149 }
150}
151*/
152
153// Endless Loop
154////////////////////////////////////////////////////////////////////////////
155void bncUploadCaster::run() {
156 while (true) {
157 if (_isToBeDeleted) {
158 QThread::quit();
159 deleteLater();
160 return;
161 }
162 open();
163 if (_outSocket && _outSocket->state() == QAbstractSocket::ConnectedState) {
164 QMutexLocker locker(&_mutex);
165 if (_outBuffer.size() > 0) {
166 if (_ntripVersion == "1") {
167 _outSocket->write(_outBuffer);
168 _outSocket->flush();
169 }
170 else {
171 QString chunkSize = QString("%1").arg(_outBuffer.size(),0,16,QLatin1Char('0'));
172 QByteArray chunkedData = chunkSize.toLatin1() + "\r\n" + _outBuffer + "\r\n";
173 _outSocket->write(chunkedData);
174 _outSocket->flush();
175 }
176 emit newBytes(_mountpoint.toLatin1(), _outBuffer.size());
177 }
178 }
179 if (_rate == 0) {
180 {
181 QMutexLocker locker(&_mutex);
182 _outBuffer.clear();
183 }
184 msleep(100); //sleep 0.1 sec
185 }
186 else {
187 sleep(_rate);
188 }
189 }
190}
191
192// Start the Communication with NTRIP Caster
193////////////////////////////////////////////////////////////////////////////
194void bncUploadCaster::open() {
195
196 if (_mountpoint.isEmpty()) {
197 return;
198 }
199
200 if (_outSocket != 0 &&
201 _outSocket->state() == QAbstractSocket::ConnectedState) {
202 return;
203 }
204
205 delete _outSocket; _outSocket = 0;
206
207 double minDt = pow(2.0,_sOpenTrial);
208 if (++_sOpenTrial > 4) {
209 _sOpenTrial = 4;
210 }
211 if (_outSocketOpenTime.isValid() &&
212 _outSocketOpenTime.secsTo(QDateTime::currentDateTime()) < minDt) {
213 return;
214 }
215 else {
216 _outSocketOpenTime = QDateTime::currentDateTime();
217 }
218
219 _outSocket = new QSslSocket();
220 if (_sslIgnoreErrors) {
221 _outSocket->ignoreSslErrors();
222 }
223 _outSocket->setProxy(QNetworkProxy::NoProxy); // to prevent the usage of system entries
224 if (_ntripVersion == "1") {
225 _outHost = _casterOutHost;
226 _outPort = _casterOutPort;
227 }
228 else {
229 if (!_proxyHost.isEmpty()) {
230 _outHost = _proxyHost;
231 _outPort = _proxyPort;
232 connect(_outSocket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)),
233 this, SLOT(slotProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)));
234 }
235 }
236
237 if (!_secure) {
238 _outSocket->connectToHost(_outHost, _outPort);
239 }
240 else {
241 _outSocket->connectToHostEncrypted(_outHost, _outPort);/*
242 if (!_outSocket->waitForEncrypted()) {
243 cout << "waitForEncrypted: " << _outSocket->errorString().toStdString().c_str() << endl;;
244 return;
245 }*/
246 }
247
248 const int timeOut = 5000; // 5 seconds
249 if (!_outSocket->waitForConnected(timeOut)) {
250 emit(newMessage("Broadcaster: Connect timeout for " + _mountpoint.toLatin1()
251 + " (" + _outHost.toLatin1()+ ":" + QString("%1) ").arg(_outPort).toLatin1()
252 + _outSocket->errorString().toLatin1(), true));
253 delete _outSocket;
254 _outSocket = 0;
255 return;
256 }
257
258 QByteArray msg;
259 if (_ntripVersion == "1") {
260 msg = "SOURCE " + _password.toLatin1() + " /" + _mountpoint.toLatin1() + "\r\n" +
261 "Source-Agent: NTRIP BNC/" BNCVERSION "\r\n\r\n";
262 }
263 else {
264 msg = "POST " + _postExtension.toLatin1() + "/" + _mountpoint.toLatin1() + " HTTP/1.1\r\n" +
265 "Host: " + _casterOutHost.toLatin1() + "\r\n" +
266 "Ntrip-Version: Ntrip/2.0\r\n" +
267 "Authorization: Basic " + (_userName + ":" + _password).toLatin1().toBase64() + "\r\n" +
268 "User-Agent: NTRIP BNC/" BNCVERSION " (" + BNC_OS + ")\r\n" +
269 "Connection: close\r\n" +
270 "Transfer-Encoding: chunked\r\n\r\n";
271 }
272 cout << msg.toStdString().c_str();
273 _outSocket->write(msg);
274 _outSocket->waitForBytesWritten();
275
276 _outSocket->waitForReadyRead();
277 QByteArray ans = _outSocket->readLine();cout << ans.toStdString().c_str() << endl;
278
279 if (ans.indexOf("OK") == -1) {
280 delete _outSocket;
281 _outSocket = 0;
282 emit(newMessage("Broadcaster: Connection broken for " + _mountpoint.toLatin1() + ": " + ans.left(ans.length()-2), true));
283 }
284 else {
285 emit(newMessage("Broadcaster: Connection opened for " + _mountpoint.toLatin1(), true));
286 _sOpenTrial = 0;
287 }
288}
289
Note: See TracBrowser for help on using the repository browser.