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

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

minor changes

File size: 8.9 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 if (_outSocket->state() == QAbstractSocket::ConnectedState) {
202 return;
203 }
204 else {
205 cout << "open(): outSocketState: " << _outSocket->state() << endl;
206 emit(newMessage("Broadcaster: No connection for " + _mountpoint.toLatin1(), true));
207 }
208 }
209
210 delete _outSocket; _outSocket = 0;
211
212 double minDt = pow(2.0,_sOpenTrial);
213 if (++_sOpenTrial > 4) {
214 _sOpenTrial = 4;
215 }
216 if (_outSocketOpenTime.isValid() &&
217 _outSocketOpenTime.secsTo(QDateTime::currentDateTime()) < minDt) {
218 return;
219 }
220 else {
221 _outSocketOpenTime = QDateTime::currentDateTime();
222 }
223
224 _outSocket = new QSslSocket();
225 if (_sslIgnoreErrors) {
226 _outSocket->ignoreSslErrors();
227 }
228 _outSocket->setProxy(QNetworkProxy::NoProxy); // to prevent the usage of system entries
229 _outHost = _casterOutHost;
230 _outPort = _casterOutPort;
231 if (!_proxyHost.isEmpty()) {
232 _outHost = _proxyHost;
233 _outPort = _proxyPort;
234 connect(_outSocket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)),
235 this, SLOT(slotProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)));
236 }
237
238 if (!_secure) {
239 _outSocket->connectToHost(_outHost, _outPort);
240 }
241 else {
242 _outSocket->connectToHostEncrypted(_outHost, _outPort);
243 if (!_outSocket->waitForEncrypted()) {
244 cout << "waitForEncrypted: " << _outSocket->errorString().toStdString().c_str() << endl;;
245 return;
246 }
247 }
248
249 const int timeOut = 5000; // 5 seconds
250 if (!_outSocket->waitForConnected(timeOut)) {
251 emit(newMessage("Broadcaster: Connect timeout for " + _mountpoint.toLatin1()
252 + " (" + _outHost.toLatin1()+ ":" + QString("%1) ").arg(_outPort).toLatin1()
253 + _outSocket->errorString().toLatin1(), true));
254 delete _outSocket;
255 _outSocket = 0;
256 return;
257 }
258
259 QByteArray msg;
260 if (_ntripVersion == "1") {
261 msg = "SOURCE " + _password.toLatin1() + " /" + _mountpoint.toLatin1() + "\r\n" +
262 "Source-Agent: NTRIP BNC/" BNCVERSION "\r\n\r\n";
263 }
264 else {
265 msg = "POST " + _postExtension.toLatin1() + "/" + _mountpoint.toLatin1() + " HTTP/1.1\r\n" +
266 "Host: " + _casterOutHost.toLatin1() + "\r\n" +
267 "Ntrip-Version: Ntrip/2.0\r\n" +
268 "Authorization: Basic " + (_userName + ":" + _password).toLatin1().toBase64() + "\r\n" +
269 "User-Agent: NTRIP BNC/" BNCVERSION " (" + BNC_OS + ")\r\n" +
270 "Connection: close\r\n" +
271 "Transfer-Encoding: chunked\r\n\r\n";
272 }
273 cout << msg.toStdString().c_str();
274 _outSocket->write(msg);
275 _outSocket->waitForBytesWritten();
276
277 _outSocket->waitForReadyRead();
278 QByteArray ans = _outSocket->readLine();cout << ans.toStdString().c_str() << endl;
279
280 if (ans.indexOf("OK") == -1) {
281 delete _outSocket;
282 _outSocket = 0;
283 emit(newMessage("Broadcaster: Connection broken for " + _mountpoint.toLatin1() + ": " + ans.left(ans.length()-2), true));
284 }
285 else {
286 emit(newMessage("Broadcaster: Connection opened for " + _mountpoint.toLatin1() + ": " + ans.left(ans.length()-2), true));
287 _sOpenTrial = 0;
288 }
289}
290
Note: See TracBrowser for help on using the repository browser.