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

Last change on this file since 855 was 850, checked in by mervart, 16 years ago

* empty log message *

File size: 9.1 KB
Line 
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>
18#include <newmatio.h>
19
20#include "bns.h"
21#include "bnsutils.h"
22#include "bnsrinex.h"
23#include "bnssp3.h"
24
25using namespace std;
26
27// Constructor
28////////////////////////////////////////////////////////////////////////////
29t_bns::t_bns(QObject* parent) : QThread(parent) {
30
31 this->setTerminationEnabled(true);
32
33 connect(this, SIGNAL(moveSocket(QThread*)),
34 this, SLOT(slotMoveSocket(QThread*)));
35
36 // Thread that handles broadcast ephemeris
37 // ---------------------------------------
38 _bnseph = new t_bnseph(parent);
39
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)));
45
46 // Server listening for rtnet results
47 // ----------------------------------
48 QSettings settings;
49 _clkSocket = 0;
50 _clkServer = new QTcpServer;
51 _clkServer->listen(QHostAddress::Any, settings.value("clkPort").toInt());
52 connect(_clkServer, SIGNAL(newConnection()),this, SLOT(slotNewConnection()));
53
54 // Socket and file for outputting the results
55 // -------------------------------------------
56 _outSocket = 0;
57
58 QString outFileName = settings.value("outFile").toString();
59 if (outFileName.isEmpty()) {
60 _outFile = 0;
61 _outStream = 0;
62 }
63 else {
64 _outFile = new QFile(outFileName);
65 if (_outFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) {
66 _outStream = new QTextStream(_outFile);
67 }
68 }
69
70 // Log File
71 // --------
72 QString logFileName = settings.value("logFile").toString();
73 if (logFileName.isEmpty()) {
74 _logFile = 0;
75 }
76 else {
77 _logFile = new QFile(logFileName);
78 if (_logFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) {
79 _logStream = new QTextStream(_logFile);
80 }
81 }
82
83 // RINEX writer
84 // ------------
85 if ( settings.value("rnxPath").toString().isEmpty() ) {
86 _rnx = 0;
87 }
88 else {
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);
95 }
96
97 // SP3 writer
98 // ----------
99 if ( settings.value("sp3Path").toString().isEmpty() ) {
100 _sp3 = 0;
101 }
102 else {
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);
109 }
110}
111
112// Destructor
113////////////////////////////////////////////////////////////////////////////
114t_bns::~t_bns() {
115 deleteBnsEph();
116 delete _clkServer;
117 delete _clkSocket;
118 delete _outSocket;
119 delete _outStream;
120 delete _logStream;
121 delete _outFile;
122 delete _logFile;
123 QMapIterator<QString, t_ephPair*> it(_ephList);
124 while (it.hasNext()) {
125 it.next();
126 delete it.value();
127 }
128 delete _rnx;
129 delete _sp3;
130}
131
132// Delete bns thread
133////////////////////////////////////////////////////////////////////////////
134void t_bns::deleteBnsEph() {
135 if (_bnseph) {
136 _bnseph->terminate();
137 _bnseph->wait(100);
138 delete _bnseph;
139 _bnseph = 0;
140 }
141}
142
143// Write a Program Message
144////////////////////////////////////////////////////////////////////////////
145void t_bns::slotMessage(const QByteArray msg) {
146 if (_logStream) {
147 *_logStream << msg << endl;
148 _logStream->flush();
149 }
150 emit(newMessage(msg));
151}
152
153// Write a Program Message
154////////////////////////////////////////////////////////////////////////////
155void t_bns::slotError(const QByteArray msg) {
156 if (_logStream) {
157 *_logStream << msg << endl;
158 _logStream->flush();
159 }
160 deleteBnsEph();
161 emit(error(msg));
162}
163
164// New Connection
165////////////////////////////////////////////////////////////////////////////
166void t_bns::slotNewConnection() {
167 slotMessage("t_bns::slotNewConnection");
168 delete _clkSocket;
169 _clkSocket = _clkServer->nextPendingConnection();
170}
171
172// Start the Communication with NTRIP Caster
173////////////////////////////////////////////////////////////////////////////
174void t_bns::openCaster() {
175
176 QSettings settings;
177
178 delete _outSocket;
179 _outSocket = new QTcpSocket();
180 _outSocket->connectToHost(settings.value("outHost").toString(),
181 settings.value("outPort").toInt());
182
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"));
188 return;
189 }
190
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);
199 _outSocket->waitForBytesWritten();
200
201 _outSocket->waitForReadyRead();
202 QByteArray ans = _outSocket->readLine();
203
204 if (ans.indexOf("OK") == -1) {
205 delete _outSocket;
206 _outSocket = 0;
207 slotMessage("bns::openCaster socket deleted");
208 }
209 else {
210 slotMessage("bns::openCaster socket OK");
211 }
212}
213
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
245// Start
246////////////////////////////////////////////////////////////////////////////
247void t_bns::run() {
248
249 slotMessage("============ Start BNS ============");
250
251 // Start Thread that retrieves broadcast Ephemeris
252 // -----------------------------------------------
253 _bnseph->start();
254
255 // Endless loop
256 // ------------
257 while (true) {
258
259 if (_clkSocket && _clkSocket->thread() != currentThread()) {
260 emit(moveSocket(currentThread()));
261 }
262
263 if (_clkSocket && _clkSocket->state() == QAbstractSocket::ConnectedState) {
264 if ( _clkSocket->canReadLine()) {
265 if (_outSocket == 0 ||
266 _outSocket->state() != QAbstractSocket::ConnectedState) {
267 openCaster();
268 }
269 readEpoch();
270 }
271 else {
272 _clkSocket->waitForReadyRead(10);
273 }
274 }
275 else {
276 msleep(10);
277 }
278 }
279}
280
281//
282////////////////////////////////////////////////////////////////////////////
283void t_bns::readEpoch() {
284
285 QByteArray line = _clkSocket->readLine();
286
287 if (line.indexOf('*') == -1) {
288 return;
289 }
290
291 QTextStream in(line);
292
293 QString hlp;
294 int GPSweek, numSat;
295 double GPSweeks;
296
297 in >> hlp >> GPSweek >> GPSweeks >> numSat;
298
299 for (int ii = 1; ii <= numSat; ii++) {
300 line = _clkSocket->readLine();
301
302 QTextStream in(line);
303
304 QString prn;
305 ColumnVector xx(4);
306
307 in >> prn >> xx(1) >> xx(2) >> xx(3) >> xx(4);
308 xx(4) *= 1e-6;
309
310 processSatellite(GPSweek, GPSweeks, prn, xx);
311 }
312}
313
314//
315////////////////////////////////////////////////////////////////////////////
316void t_bns::processSatellite(int GPSweek, double GPSweeks, const QString& prn,
317 const ColumnVector& xx) {
318
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
328 ColumnVector xB(4);
329 ColumnVector vv(3);
330
331 satellitePosition(GPSweek, GPSweeks, ep, xB(1), xB(2), xB(3), xB(4),
332 vv(1), vv(2), vv(3));
333
334 ColumnVector dx = xx.Rows(1,3) - xB.Rows(1,3);
335 double dClk = (xx(4) - xB(4)) * 299792458.0;
336 ColumnVector rsw(3);
337
338 XYZ_to_RSW(xB.Rows(1,3), vv, dx, rsw);
339
340 QString line;
341 line.sprintf("%d %.1f %s %3d %3d %8.3f %8.3f %8.3f %8.3f\n",
342 GPSweek, GPSweeks, ep->prn.toAscii().data(),
343 int(ep->IODC), int(ep->IODE), dClk, rsw(1), rsw(2), rsw(3));
344
345 if (_outStream) {
346 *_outStream << line;
347 _outStream->flush();
348 }
349 if (_outSocket) {
350 _outSocket->write(line.toAscii());
351 _outSocket->flush();
352 }
353 if (_rnx) {
354 _rnx->write(GPSweek, GPSweeks, prn, xx);
355 }
356 if (_sp3) {
357 _sp3->write(GPSweek, GPSweeks, prn, xx);
358 }
359}
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.