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

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

minor changes

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