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
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
63 _sslIgnoreErrors = (Qt::CheckState(settings.value("sslIgnoreErrors").toInt()) == Qt::Checked);
64
65 _proxyHost = settings.value("proxyHost").toString();
66 _proxyPort = settings.value("proxyPort").toInt();
67 if (_secure) {
68 _casterOutPort = 443;
69 if (!_proxyHost.isEmpty()) {
70 _postExtension = QString("https://%1:%2").arg(_casterOutHost).arg(_casterOutPort);
71 }
72 }
73 else {
74 if (!_proxyHost.isEmpty()) {
75 _postExtension = QString("http://%1:%2").arg(_casterOutHost).arg(_casterOutPort);
76 }
77 }
78 }
79
80 connect(this, SIGNAL(newMessage(QByteArray,bool)),
81 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
82
83 if (BNC_CORE->_uploadTableItems.find(_iRow) != BNC_CORE->_uploadTableItems.end()){
84 connect(this, SIGNAL(newBytes(QByteArray,double)),
85 BNC_CORE->_uploadTableItems.value(iRow),
86 SLOT(slotNewBytes(const QByteArray,double)));
87 }
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 }
93}
94
95// Safe Desctructor
96////////////////////////////////////////////////////////////////////////////
97void bncUploadCaster::deleteSafely() {
98 _isToBeDeleted = true;
99 if (!isRunning()) {
100 delete this;
101 }
102}
103
104// Destructor
105////////////////////////////////////////////////////////////////////////////
106bncUploadCaster::~bncUploadCaster() {
107 if (isRunning()) {
108 wait();
109 }
110 if (_outSocket) {
111 disconnect(_outSocket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)),
112 this, SLOT(slotProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)));
113 delete _outSocket;
114 }
115}
116
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
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);
171 if (_outBuffer.size() > 0) {
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 }
182 emit newBytes(_mountpoint.toLatin1(), _outBuffer.size());
183 }
184 }
185 if (_rate == 0) {
186 {
187 QMutexLocker locker(&_mutex);
188 _outBuffer.clear();
189 }
190 msleep(100); //sleep 0.1 sec
191 }
192 else {
193 sleep(_rate);
194 }
195 }
196}
197
198// Start the Communication with NTRIP Caster
199////////////////////////////////////////////////////////////////////////////
200void bncUploadCaster::open() {
201
202 if (_mountpoint.isEmpty()) {
203 return;
204 }
205
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 }
213 }
214
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
229 _outSocket = new QSslSocket();
230 if (_sslIgnoreErrors) {
231 _outSocket->ignoreSslErrors();
232 }
233 _outSocket->setProxy(QNetworkProxy::NoProxy); // to prevent the usage of system entries
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*)));
241 }
242
243 const int timeOut = 5000; // 5 seconds
244 if (!_secure) {
245 _outSocket->connectToHost(_outHost, _outPort);
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 }
254 }
255 else {
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 }
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();
282 _outSocket->write(msg);
283 _outSocket->waitForBytesWritten();
284
285 _outSocket->waitForReadyRead();
286 QByteArray ans = _outSocket->readLine();cout << ans.toStdString().c_str() << endl;
287
288 if (ans.indexOf("OK") == -1) {
289 delete _outSocket;
290 _outSocket = 0;
291 emit(newMessage("Broadcaster: Connection broken for " + _mountpoint.toLatin1() + ": " + ans.left(ans.length()-2), true));
292 }
293 else {
294 emit(newMessage("Broadcaster: Connection opened for " + _mountpoint.toLatin1() + ": " + ans.left(ans.length()-2), true));
295 _sOpenTrial = 0;
296 }
297}
298
Note: See TracBrowser for help on using the repository browser.