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

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