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

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

* empty log message *

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