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

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

* empty log message *

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