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

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

* empty log message *

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