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

Last change on this file since 846 was 840, checked in by mervart, 17 years ago

* empty log message *

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