source: ntrip/trunk/BNS/bns.cpp@ 856

Last change on this file since 856 was 850, checked in by mervart, 17 years ago

* empty log message *

File size: 9.1 KB
RevLine 
[756]1/* -------------------------------------------------------------------------
2 * BKG NTRIP Server
3 * -------------------------------------------------------------------------
4 *
5 * Class: bns
6 *
7 * Purpose: This class implements the main application behaviour
8 *
9 * Author: L. Mervart
10 *
11 * Created: 29-Mar-2008
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iostream>
[800]18#include <newmatio.h>
[756]19
20#include "bns.h"
[799]21#include "bnsutils.h"
[847]22#include "bnsrinex.h"
[848]23#include "bnssp3.h"
[756]24
25using namespace std;
26
27// Constructor
28////////////////////////////////////////////////////////////////////////////
[757]29t_bns::t_bns(QObject* parent) : QThread(parent) {
[760]30
[764]31 this->setTerminationEnabled(true);
[828]32
[836]33 connect(this, SIGNAL(moveSocket(QThread*)),
34 this, SLOT(slotMoveSocket(QThread*)));
35
[828]36 // Thread that handles broadcast ephemeris
37 // ---------------------------------------
38 _bnseph = new t_bnseph(parent);
[827]39
[828]40 connect(_bnseph, SIGNAL(newEph(gpsEph*)), this, SLOT(slotNewEph(gpsEph*)));
41 connect(_bnseph, SIGNAL(newMessage(QByteArray)),
42 this, SLOT(slotMessage(const QByteArray)));
43 connect(_bnseph, SIGNAL(error(QByteArray)),
44 this, SLOT(slotError(const QByteArray)));
[760]45
[827]46 // Server listening for rtnet results
47 // ----------------------------------
[786]48 QSettings settings;
[828]49 _clkSocket = 0;
[827]50 _clkServer = new QTcpServer;
51 _clkServer->listen(QHostAddress::Any, settings.value("clkPort").toInt());
[828]52 connect(_clkServer, SIGNAL(newConnection()),this, SLOT(slotNewConnection()));
[827]53
[828]54 // Socket and file for outputting the results
55 // -------------------------------------------
56 _outSocket = 0;
[827]57
[816]58 QString outFileName = settings.value("outFile").toString();
59 if (outFileName.isEmpty()) {
[833]60 _outFile = 0;
61 _outStream = 0;
[811]62 }
[816]63 else {
64 _outFile = new QFile(outFileName);
[817]65 if (_outFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) {
[816]66 _outStream = new QTextStream(_outFile);
67 }
68 }
[812]69
70 // Log File
71 // --------
[816]72 QString logFileName = settings.value("logFile").toString();
73 if (logFileName.isEmpty()) {
74 _logFile = 0;
[812]75 }
[816]76 else {
77 _logFile = new QFile(logFileName);
[817]78 if (_logFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) {
[816]79 _logStream = new QTextStream(_logFile);
80 }
81 }
[847]82
83 // RINEX writer
84 // ------------
85 if ( settings.value("rnxPath").toString().isEmpty() ) {
86 _rnx = 0;
87 }
88 else {
[850]89 QString prep = "BNS";
90 QString ext = ".rnx";
91 QString path = settings.value("rnxPath").toString();
92 QString intr = settings.value("rnxIntr").toString();
93 int sampl = settings.value("rnxSampl").toInt();
94 _rnx = new bnsRinex(prep, ext, path, intr, sampl);
[847]95 }
[848]96
97 // SP3 writer
98 // ----------
99 if ( settings.value("sp3Path").toString().isEmpty() ) {
100 _sp3 = 0;
101 }
102 else {
[850]103 QString prep = "BNS";
104 QString ext = ".clk";
105 QString path = settings.value("sp3Path").toString();
106 QString intr = settings.value("sp3Intr").toString();
107 int sampl = settings.value("sp3Sampl").toInt();
108 _sp3 = new bnsSP3(prep, ext, path, intr, sampl);
[848]109 }
[756]110}
111
112// Destructor
113////////////////////////////////////////////////////////////////////////////
[757]114t_bns::~t_bns() {
[763]115 deleteBnsEph();
[769]116 delete _clkServer;
[837]117 delete _clkSocket;
[770]118 delete _outSocket;
[816]119 delete _outStream;
120 delete _logStream;
[812]121 delete _outFile;
122 delete _logFile;
[779]123 QMapIterator<QString, t_ephPair*> it(_ephList);
124 while (it.hasNext()) {
125 it.next();
126 delete it.value();
127 }
[849]128 delete _rnx;
129 delete _sp3;
[756]130}
131
[763]132// Delete bns thread
133////////////////////////////////////////////////////////////////////////////
134void t_bns::deleteBnsEph() {
135 if (_bnseph) {
136 _bnseph->terminate();
[764]137 _bnseph->wait(100);
[763]138 delete _bnseph;
139 _bnseph = 0;
140 }
141}
142
[756]143// Write a Program Message
144////////////////////////////////////////////////////////////////////////////
[758]145void t_bns::slotMessage(const QByteArray msg) {
[816]146 if (_logStream) {
147 *_logStream << msg << endl;
[818]148 _logStream->flush();
[812]149 }
[757]150 emit(newMessage(msg));
[756]151}
152
[760]153// Write a Program Message
154////////////////////////////////////////////////////////////////////////////
155void t_bns::slotError(const QByteArray msg) {
[816]156 if (_logStream) {
157 *_logStream << msg << endl;
[818]158 _logStream->flush();
[812]159 }
[763]160 deleteBnsEph();
[760]161 emit(error(msg));
162}
163
[769]164// New Connection
165////////////////////////////////////////////////////////////////////////////
166void t_bns::slotNewConnection() {
[786]167 slotMessage("t_bns::slotNewConnection");
[787]168 delete _clkSocket;
[769]169 _clkSocket = _clkServer->nextPendingConnection();
170}
171
[770]172// Start the Communication with NTRIP Caster
173////////////////////////////////////////////////////////////////////////////
174void t_bns::openCaster() {
175
176 QSettings settings;
177
[835]178 delete _outSocket;
[770]179 _outSocket = new QTcpSocket();
[811]180 _outSocket->connectToHost(settings.value("outHost").toString(),
181 settings.value("outPort").toInt());
[770]182
[819]183 const int timeOut = 100; // 0.1 seconds
184 if (!_outSocket->waitForConnected(timeOut)) {
185 delete _outSocket;
186 _outSocket = 0;
187 emit(error("bns::openCaster Connect Timeout"));
[840]188 return;
[819]189 }
190
[770]191 QString mountpoint = settings.value("mountpoint").toString();
192 QString password = settings.value("password").toString();
193
194 QByteArray msg = "SOURCE " + password.toAscii() + " /" +
195 mountpoint.toAscii() + "\r\n" +
196 "Source-Agent: NTRIP BNS/1.0\r\n\r\n";
197
198 _outSocket->write(msg);
[820]199 _outSocket->waitForBytesWritten();
[770]200
[820]201 _outSocket->waitForReadyRead();
[770]202 QByteArray ans = _outSocket->readLine();
203
204 if (ans.indexOf("OK") == -1) {
205 delete _outSocket;
206 _outSocket = 0;
[831]207 slotMessage("bns::openCaster socket deleted");
[770]208 }
[831]209 else {
210 slotMessage("bns::openCaster socket OK");
211 }
[770]212}
213
[784]214//
215////////////////////////////////////////////////////////////////////////////
216void t_bns::slotNewEph(gpsEph* ep) {
217
218 QMutexLocker locker(&_mutex);
219
220 t_ephPair* pair;
221 if ( !_ephList.contains(ep->prn) ) {
222 pair = new t_ephPair();
223 _ephList.insert(ep->prn, pair);
224 }
225 else {
226 pair = _ephList[ep->prn];
227 }
228
229 if (pair->eph == 0) {
230 pair->eph = ep;
231 }
232 else {
233 if (ep->GPSweek > pair->eph->GPSweek ||
234 (ep->GPSweek == pair->eph->GPSweek && ep->TOC > pair->eph->TOC)) {
235 delete pair->oldEph;
236 pair->oldEph = pair->eph;
237 pair->eph = ep;
238 }
239 else {
240 delete ep;
241 }
242 }
243}
244
[756]245// Start
246////////////////////////////////////////////////////////////////////////////
[757]247void t_bns::run() {
[769]248
[758]249 slotMessage("============ Start BNS ============");
[770]250
[828]251 // Start Thread that retrieves broadcast Ephemeris
252 // -----------------------------------------------
[758]253 _bnseph->start();
[769]254
[770]255 // Endless loop
256 // ------------
[769]257 while (true) {
[836]258
259 if (_clkSocket && _clkSocket->thread() != currentThread()) {
260 emit(moveSocket(currentThread()));
261 }
262
[796]263 if (_clkSocket && _clkSocket->state() == QAbstractSocket::ConnectedState) {
264 if ( _clkSocket->canReadLine()) {
[832]265 if (_outSocket == 0 ||
266 _outSocket->state() != QAbstractSocket::ConnectedState) {
[830]267 openCaster();
268 }
[796]269 readEpoch();
270 }
[809]271 else {
272 _clkSocket->waitForReadyRead(10);
273 }
[769]274 }
275 else {
[794]276 msleep(10);
[769]277 }
278 }
[756]279}
280
[778]281//
282////////////////////////////////////////////////////////////////////////////
[784]283void t_bns::readEpoch() {
[778]284
[784]285 QByteArray line = _clkSocket->readLine();
[786]286
[784]287 if (line.indexOf('*') == -1) {
288 return;
[778]289 }
290
[784]291 QTextStream in(line);
292
293 QString hlp;
[798]294 int GPSweek, numSat;
295 double GPSweeks;
[784]296
[798]297 in >> hlp >> GPSweek >> GPSweeks >> numSat;
[784]298
299 for (int ii = 1; ii <= numSat; ii++) {
[792]300 line = _clkSocket->readLine();
[791]301
[784]302 QTextStream in(line);
303
304 QString prn;
305 ColumnVector xx(4);
306
[795]307 in >> prn >> xx(1) >> xx(2) >> xx(3) >> xx(4);
[797]308 xx(4) *= 1e-6;
[784]309
[798]310 processSatellite(GPSweek, GPSweeks, prn, xx);
[780]311 }
[778]312}
[784]313
314//
315////////////////////////////////////////////////////////////////////////////
[798]316void t_bns::processSatellite(int GPSweek, double GPSweeks, const QString& prn,
[784]317 const ColumnVector& xx) {
318
[795]319 // No broadcast ephemeris available
320 // --------------------------------
321 if ( !_ephList.contains(prn) ) {
322 return;
323 }
324
325 t_ephPair* pair = _ephList[prn];
326 gpsEph* ep = pair->eph;
327
[799]328 ColumnVector xB(4);
[802]329 ColumnVector vv(3);
[799]330
[803]331 satellitePosition(GPSweek, GPSweeks, ep, xB(1), xB(2), xB(3), xB(4),
[802]332 vv(1), vv(2), vv(3));
[799]333
[804]334 ColumnVector dx = xx.Rows(1,3) - xB.Rows(1,3);
335 double dClk = (xx(4) - xB(4)) * 299792458.0;
336 ColumnVector rsw(3);
[800]337
[806]338 XYZ_to_RSW(xB.Rows(1,3), vv, dx, rsw);
[804]339
[811]340 QString line;
[817]341 line.sprintf("%d %.1f %s %3d %3d %8.3f %8.3f %8.3f %8.3f\n",
[811]342 GPSweek, GPSweeks, ep->prn.toAscii().data(),
343 int(ep->IODC), int(ep->IODE), dClk, rsw(1), rsw(2), rsw(3));
344
[816]345 if (_outStream) {
346 *_outStream << line;
[818]347 _outStream->flush();
[811]348 }
349 if (_outSocket) {
350 _outSocket->write(line.toAscii());
[831]351 _outSocket->flush();
[811]352 }
[847]353 if (_rnx) {
354 _rnx->write(GPSweek, GPSweeks, prn, xx);
355 }
[848]356 if (_sp3) {
357 _sp3->write(GPSweek, GPSweeks, prn, xx);
358 }
[784]359}
[836]360
361//
362////////////////////////////////////////////////////////////////////////////
363void t_bns::slotMoveSocket(QThread* tt) {
364 _clkSocket->setParent(0);
365 _clkSocket->moveToThread(tt);
366 slotMessage("bns::slotMoveSocket");
367}
Note: See TracBrowser for help on using the repository browser.