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

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

* empty log message *

File size: 8.6 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 _rnx = new bnsRinex();
90 }
91
92 // SP3 writer
93 // ----------
94 if ( settings.value("sp3Path").toString().isEmpty() ) {
95 _sp3 = 0;
96 }
97 else {
98 _sp3 = new bnsSP3();
99 }
100}
101
102// Destructor
103////////////////////////////////////////////////////////////////////////////
104t_bns::~t_bns() {
105 deleteBnsEph();
106 delete _clkServer;
107 delete _clkSocket;
108 delete _outSocket;
109 delete _outStream;
110 delete _logStream;
111 delete _outFile;
112 delete _logFile;
113 QMapIterator<QString, t_ephPair*> it(_ephList);
114 while (it.hasNext()) {
115 it.next();
116 delete it.value();
117 }
118}
119
120// Delete bns thread
121////////////////////////////////////////////////////////////////////////////
122void t_bns::deleteBnsEph() {
123 if (_bnseph) {
124 _bnseph->terminate();
125 _bnseph->wait(100);
126 delete _bnseph;
127 _bnseph = 0;
128 }
129}
130
131// Write a Program Message
132////////////////////////////////////////////////////////////////////////////
133void t_bns::slotMessage(const QByteArray msg) {
134 if (_logStream) {
135 *_logStream << msg << endl;
136 _logStream->flush();
137 }
138 emit(newMessage(msg));
139}
140
141// Write a Program Message
142////////////////////////////////////////////////////////////////////////////
143void t_bns::slotError(const QByteArray msg) {
144 if (_logStream) {
145 *_logStream << msg << endl;
146 _logStream->flush();
147 }
148 deleteBnsEph();
149 emit(error(msg));
150}
151
152// New Connection
153////////////////////////////////////////////////////////////////////////////
154void t_bns::slotNewConnection() {
155 slotMessage("t_bns::slotNewConnection");
156 delete _clkSocket;
157 _clkSocket = _clkServer->nextPendingConnection();
158}
159
160// Start the Communication with NTRIP Caster
161////////////////////////////////////////////////////////////////////////////
162void t_bns::openCaster() {
163
164 QSettings settings;
165
166 delete _outSocket;
167 _outSocket = new QTcpSocket();
168 _outSocket->connectToHost(settings.value("outHost").toString(),
169 settings.value("outPort").toInt());
170
171 const int timeOut = 100; // 0.1 seconds
172 if (!_outSocket->waitForConnected(timeOut)) {
173 delete _outSocket;
174 _outSocket = 0;
175 emit(error("bns::openCaster Connect Timeout"));
176 return;
177 }
178
179 QString mountpoint = settings.value("mountpoint").toString();
180 QString password = settings.value("password").toString();
181
182 QByteArray msg = "SOURCE " + password.toAscii() + " /" +
183 mountpoint.toAscii() + "\r\n" +
184 "Source-Agent: NTRIP BNS/1.0\r\n\r\n";
185
186 _outSocket->write(msg);
187 _outSocket->waitForBytesWritten();
188
189 _outSocket->waitForReadyRead();
190 QByteArray ans = _outSocket->readLine();
191
192 if (ans.indexOf("OK") == -1) {
193 delete _outSocket;
194 _outSocket = 0;
195 slotMessage("bns::openCaster socket deleted");
196 }
197 else {
198 slotMessage("bns::openCaster socket OK");
199 }
200}
201
202//
203////////////////////////////////////////////////////////////////////////////
204void t_bns::slotNewEph(gpsEph* ep) {
205
206 QMutexLocker locker(&_mutex);
207
208 t_ephPair* pair;
209 if ( !_ephList.contains(ep->prn) ) {
210 pair = new t_ephPair();
211 _ephList.insert(ep->prn, pair);
212 }
213 else {
214 pair = _ephList[ep->prn];
215 }
216
217 if (pair->eph == 0) {
218 pair->eph = ep;
219 }
220 else {
221 if (ep->GPSweek > pair->eph->GPSweek ||
222 (ep->GPSweek == pair->eph->GPSweek && ep->TOC > pair->eph->TOC)) {
223 delete pair->oldEph;
224 pair->oldEph = pair->eph;
225 pair->eph = ep;
226 }
227 else {
228 delete ep;
229 }
230 }
231}
232
233// Start
234////////////////////////////////////////////////////////////////////////////
235void t_bns::run() {
236
237 slotMessage("============ Start BNS ============");
238
239 // Start Thread that retrieves broadcast Ephemeris
240 // -----------------------------------------------
241 _bnseph->start();
242
243 // Endless loop
244 // ------------
245 while (true) {
246
247 if (_clkSocket && _clkSocket->thread() != currentThread()) {
248 emit(moveSocket(currentThread()));
249 }
250
251 if (_clkSocket && _clkSocket->state() == QAbstractSocket::ConnectedState) {
252 if ( _clkSocket->canReadLine()) {
253 if (_outSocket == 0 ||
254 _outSocket->state() != QAbstractSocket::ConnectedState) {
255 openCaster();
256 }
257 readEpoch();
258 }
259 else {
260 _clkSocket->waitForReadyRead(10);
261 }
262 }
263 else {
264 msleep(10);
265 }
266 }
267}
268
269//
270////////////////////////////////////////////////////////////////////////////
271void t_bns::readEpoch() {
272
273 QByteArray line = _clkSocket->readLine();
274
275 if (line.indexOf('*') == -1) {
276 return;
277 }
278
279 QTextStream in(line);
280
281 QString hlp;
282 int GPSweek, numSat;
283 double GPSweeks;
284
285 in >> hlp >> GPSweek >> GPSweeks >> numSat;
286
287 for (int ii = 1; ii <= numSat; ii++) {
288 line = _clkSocket->readLine();
289
290 QTextStream in(line);
291
292 QString prn;
293 ColumnVector xx(4);
294
295 in >> prn >> xx(1) >> xx(2) >> xx(3) >> xx(4);
296 xx(4) *= 1e-6;
297
298 processSatellite(GPSweek, GPSweeks, prn, xx);
299 }
300}
301
302//
303////////////////////////////////////////////////////////////////////////////
304void t_bns::processSatellite(int GPSweek, double GPSweeks, const QString& prn,
305 const ColumnVector& xx) {
306
307 // No broadcast ephemeris available
308 // --------------------------------
309 if ( !_ephList.contains(prn) ) {
310 return;
311 }
312
313 t_ephPair* pair = _ephList[prn];
314 gpsEph* ep = pair->eph;
315
316 ColumnVector xB(4);
317 ColumnVector vv(3);
318
319 satellitePosition(GPSweek, GPSweeks, ep, xB(1), xB(2), xB(3), xB(4),
320 vv(1), vv(2), vv(3));
321
322 ColumnVector dx = xx.Rows(1,3) - xB.Rows(1,3);
323 double dClk = (xx(4) - xB(4)) * 299792458.0;
324 ColumnVector rsw(3);
325
326 XYZ_to_RSW(xB.Rows(1,3), vv, dx, rsw);
327
328 QString line;
329 line.sprintf("%d %.1f %s %3d %3d %8.3f %8.3f %8.3f %8.3f\n",
330 GPSweek, GPSweeks, ep->prn.toAscii().data(),
331 int(ep->IODC), int(ep->IODE), dClk, rsw(1), rsw(2), rsw(3));
332
333 if (_outStream) {
334 *_outStream << line;
335 _outStream->flush();
336 }
337 if (_outSocket) {
338 _outSocket->write(line.toAscii());
339 _outSocket->flush();
340 }
341 if (_rnx) {
342 _rnx->write(GPSweek, GPSweeks, prn, xx);
343 }
344 if (_sp3) {
345 _sp3->write(GPSweek, GPSweeks, prn, xx);
346 }
347}
348
349//
350////////////////////////////////////////////////////////////////////////////
351void t_bns::slotMoveSocket(QThread* tt) {
352 _clkSocket->setParent(0);
353 _clkSocket->moveToThread(tt);
354 slotMessage("bns::slotMoveSocket");
355}
Note: See TracBrowser for help on using the repository browser.