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

Last change on this file since 837 was 837, checked in by mervart, 16 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 }
157
158 QString mountpoint = settings.value("mountpoint").toString();
159 QString password = settings.value("password").toString();
160
161 QByteArray msg = "SOURCE " + password.toAscii() + " /" +
162 mountpoint.toAscii() + "\r\n" +
163 "Source-Agent: NTRIP BNS/1.0\r\n\r\n";
164
165 _outSocket->write(msg);
166 _outSocket->waitForBytesWritten();
167
168 _outSocket->waitForReadyRead();
169 QByteArray ans = _outSocket->readLine();
170
171 if (ans.indexOf("OK") == -1) {
172 delete _outSocket;
173 _outSocket = 0;
174 slotMessage("bns::openCaster socket deleted");
175 }
176 else {
177 slotMessage("bns::openCaster socket OK");
178 }
179}
180
181//
182////////////////////////////////////////////////////////////////////////////
183void t_bns::slotNewEph(gpsEph* ep) {
184
185 QMutexLocker locker(&_mutex);
186
187 t_ephPair* pair;
188 if ( !_ephList.contains(ep->prn) ) {
189 pair = new t_ephPair();
190 _ephList.insert(ep->prn, pair);
191 }
192 else {
193 pair = _ephList[ep->prn];
194 }
195
196 if (pair->eph == 0) {
197 pair->eph = ep;
198 }
199 else {
200 if (ep->GPSweek > pair->eph->GPSweek ||
201 (ep->GPSweek == pair->eph->GPSweek && ep->TOC > pair->eph->TOC)) {
202 delete pair->oldEph;
203 pair->oldEph = pair->eph;
204 pair->eph = ep;
205 }
206 else {
207 delete ep;
208 }
209 }
210}
211
212// Start
213////////////////////////////////////////////////////////////////////////////
214void t_bns::run() {
215
216 slotMessage("============ Start BNS ============");
217
218 // Start Thread that retrieves broadcast Ephemeris
219 // -----------------------------------------------
220 _bnseph->start();
221
222 // Endless loop
223 // ------------
224 while (true) {
225
226 if (_clkSocket && _clkSocket->thread() != currentThread()) {
227 emit(moveSocket(currentThread()));
228 }
229
230 if (_clkSocket && _clkSocket->state() == QAbstractSocket::ConnectedState) {
231 if ( _clkSocket->canReadLine()) {
232 if (_outSocket == 0 ||
233 _outSocket->state() != QAbstractSocket::ConnectedState) {
234 openCaster();
235 }
236 readEpoch();
237 }
238 else {
239 _clkSocket->waitForReadyRead(10);
240 }
241 }
242 else {
243 msleep(10);
244 }
245 }
246}
247
248//
249////////////////////////////////////////////////////////////////////////////
250void t_bns::readEpoch() {
251
252 QByteArray line = _clkSocket->readLine();
253
254 if (line.indexOf('*') == -1) {
255 return;
256 }
257
258 QTextStream in(line);
259
260 QString hlp;
261 int GPSweek, numSat;
262 double GPSweeks;
263
264 in >> hlp >> GPSweek >> GPSweeks >> numSat;
265
266 for (int ii = 1; ii <= numSat; ii++) {
267 line = _clkSocket->readLine();
268
269 QTextStream in(line);
270
271 QString prn;
272 ColumnVector xx(4);
273
274 in >> prn >> xx(1) >> xx(2) >> xx(3) >> xx(4);
275 xx(4) *= 1e-6;
276
277 processSatellite(GPSweek, GPSweeks, prn, xx);
278 }
279}
280
281//
282////////////////////////////////////////////////////////////////////////////
283void t_bns::processSatellite(int GPSweek, double GPSweeks, const QString& prn,
284 const ColumnVector& xx) {
285
286 // No broadcast ephemeris available
287 // --------------------------------
288 if ( !_ephList.contains(prn) ) {
289 return;
290 }
291
292 t_ephPair* pair = _ephList[prn];
293 gpsEph* ep = pair->eph;
294
295 ColumnVector xB(4);
296 ColumnVector vv(3);
297
298 satellitePosition(GPSweek, GPSweeks, ep, xB(1), xB(2), xB(3), xB(4),
299 vv(1), vv(2), vv(3));
300
301 ColumnVector dx = xx.Rows(1,3) - xB.Rows(1,3);
302 double dClk = (xx(4) - xB(4)) * 299792458.0;
303 ColumnVector rsw(3);
304
305 XYZ_to_RSW(xB.Rows(1,3), vv, dx, rsw);
306
307 QString line;
308 line.sprintf("%d %.1f %s %3d %3d %8.3f %8.3f %8.3f %8.3f\n",
309 GPSweek, GPSweeks, ep->prn.toAscii().data(),
310 int(ep->IODC), int(ep->IODE), dClk, rsw(1), rsw(2), rsw(3));
311
312 if (_outStream) {
313 *_outStream << line;
314 _outStream->flush();
315 }
316 if (_outSocket) {
317 _outSocket->write(line.toAscii());
318 _outSocket->flush();
319 }
320}
321
322//
323////////////////////////////////////////////////////////////////////////////
324void t_bns::slotMoveSocket(QThread* tt) {
325 _clkSocket->setParent(0);
326 _clkSocket->moveToThread(tt);
327 slotMessage("bns::slotMoveSocket");
328}
Note: See TracBrowser for help on using the repository browser.