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

Last change on this file since 9714 was 9714, checked in by stuerze, 7 weeks ago

minor changes

File size: 9.0 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 _userName = userName;
39 _password = password;
40 _outSocket = 0;
41 _sOpenTrial = 0;
42 _iRow = iRow;
43 _rate = rate;
44
45 if (_rate < 0) {
46 _rate = 0;
47 }
48 else if (_rate > 60) {
49 _rate = 60;
50 }
51 _isToBeDeleted = false;
52
53 connect(this, SIGNAL(newMessage(QByteArray,bool)),
54 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
55
56 if (BNC_CORE->_uploadTableItems.find(_iRow) != BNC_CORE->_uploadTableItems.end()){
57 connect(this, SIGNAL(newBytes(QByteArray,double)),
58 BNC_CORE->_uploadTableItems.value(iRow),
59 SLOT(slotNewBytes(const QByteArray,double)));
60 }
61 if (BNC_CORE->_uploadEphTableItems.find(_iRow) != BNC_CORE->_uploadEphTableItems.end()){
62 connect(this, SIGNAL(newBytes(QByteArray,double)),
63 BNC_CORE->_uploadEphTableItems.value(iRow),
64 SLOT(slotNewBytes(const QByteArray,double)));
65 }
66
67 bncSettings settings;
68 _sslIgnoreErrors = (Qt::CheckState(settings.value("sslIgnoreErrors").toInt()) == Qt::Checked);
69 _proxyHost = settings.value("proxyHost").toString();
70 _proxyPort = settings.value("proxyPort").toInt();
71 (_proxyHost.isEmpty()) ? _proxy = false : _proxy = true;
72
73 if (_ntripVersion == "2s") {
74 _secure = true;
75 if (!QSslSocket::supportsSsl()) {
76 emit(newMessage("For SSL support please install OpenSSL run-time libraries: Ntrip Version 2 is tried", true));
77 _secure = false;
78 _ntripVersion == "2";
79 }
80 } else {
81 _secure = false;
82 }
83
84 if (_secure) {
85 _casterOutPort = 443;
86 (_proxy) ? _postExtension = QString("https://%1:%2").arg(_casterOutHost).arg(_casterOutPort) : _postExtension = "";
87 }
88 else {
89 (_proxy) ? _postExtension = QString("http://%1:%2").arg(_casterOutHost).arg(_casterOutPort) : _postExtension = "";
90 }
91
92}
93
94// Safe Desctructor
95////////////////////////////////////////////////////////////////////////////
96void bncUploadCaster::deleteSafely() {
97 _isToBeDeleted = true;
98 if (!isRunning()) {
99 delete this;
100 }
101}
102
103// Destructor
104////////////////////////////////////////////////////////////////////////////
105bncUploadCaster::~bncUploadCaster() {
106 if (isRunning()) {
107 wait();
108 }
109 if (_outSocket) {
110 delete _outSocket;
111 }
112}
113
114//
115////////////////////////////////////////////////////////////////////////////
116void bncUploadCaster::slotProxyAuthenticationRequired(const QNetworkProxy&,
117 QAuthenticator*) {
118 emit newMessage("slotProxyAuthenticationRequired", true);
119}
120
121
122/* TSL/SSL
123////////////////////////////////////////////////////////////////////////////
124void bncUploadCaster::slotSslErrors(QList<QSslError> errors) {
125
126 QString msg = "SSL Error\n";
127 QSslCertificate cert = _outSocket->sslConfiguration().peerCertificate();
128 if (!cert.isNull()) {
129 msg += QString("Server Certificate Issued by:\n"
130 "%1\n%2\nCannot be verified\n")
131#if QT_VERSION >= 0x050000
132 .arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName).at(0))
133 .arg(cert.issuerInfo(QSslCertificate::Organization).at(0));
134#else
135 .arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName))
136 .arg(cert.issuerInfo(QSslCertificate::Organization));
137#endif
138 }
139 QListIterator<QSslError> it(errors);
140 while (it.hasNext()) {
141 const QSslError& err = it.next();
142 msg += "\n" + err.errorString();
143 }
144
145 BNC_CORE->slotMessage(msg.toLatin1(), true);
146
147 if (_sslIgnoreErrors) {
148 _outSocket->ignoreSslErrors();
149 }
150 else {
151 deleteSafely();
152 }
153}
154*/
155
156// Endless Loop
157////////////////////////////////////////////////////////////////////////////
158void bncUploadCaster::run() {
159 while (true) {
160 if (_isToBeDeleted) {
161 QThread::quit();
162 deleteLater();
163 return;
164 }
165 open();
166 if (_outSocket && _outSocket->state() == QAbstractSocket::ConnectedState) {
167 QMutexLocker locker(&_mutex);
168 if (_outBuffer.size() > 0) {
169 if (_ntripVersion == "1") {
170 _outSocket->write(_outBuffer);
171 _outSocket->flush();
172 }
173 else {
174 QString chunkSize = QString("%1").arg(_outBuffer.size(),0,16,QLatin1Char('0'));
175 QByteArray chunkedData = chunkSize.toLatin1() + "\r\n" + _outBuffer + "\r\n";
176 _outSocket->write(chunkedData);
177 _outSocket->flush();
178 }
179 emit newBytes(_mountpoint.toLatin1(), _outBuffer.size());
180 }
181 }
182 if (_rate == 0) {
183 {
184 QMutexLocker locker(&_mutex);
185 _outBuffer.clear();
186 }
187 msleep(100); //sleep 0.1 sec
188 }
189 else {
190 sleep(_rate);
191 }
192 }
193}
194
195// Start the Communication with NTRIP Caster
196////////////////////////////////////////////////////////////////////////////
197void bncUploadCaster::open() {
198
199 if (_mountpoint.isEmpty()) {
200 return;
201 }
202
203 if (_outSocket != 0) {
204 if (_outSocket->state() == QAbstractSocket::ConnectedState) {
205 return;
206 }
207 else {
208 emit(newMessage("Broadcaster: No connection for " + _mountpoint.toLatin1(), true));
209 }
210 }
211
212 delete _outSocket; _outSocket = 0;
213
214 double minDt = pow(2.0,_sOpenTrial);
215 if (++_sOpenTrial > 4) {
216 _sOpenTrial = 4;
217 }
218 if (_outSocketOpenTime.isValid() &&
219 _outSocketOpenTime.secsTo(QDateTime::currentDateTime()) < minDt) {
220 return;
221 }
222 else {
223 _outSocketOpenTime = QDateTime::currentDateTime();
224 }
225
226 _outSocket = new QSslSocket();
227 const int timeOut = 5000; // 5 seconds
228 if (_sslIgnoreErrors) {
229 _outSocket->ignoreSslErrors();
230 }
231 _outSocket->setProxy(QNetworkProxy::NoProxy);
232 _outHost = _casterOutHost;
233 _outPort = _casterOutPort;
234 if (_proxy) {
235 _outHost = _proxyHost;
236 _outPort = _proxyPort;
237 connect(_outSocket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)),
238 this, SLOT(slotProxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)));
239 if (_ntripVersion == "1") {
240 emit(newMessage("No proxy support in Ntrip Version 1 upload!",true));
241 }
242 }
243
244 if (!_secure || _proxy) {
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.