source: ntrip/trunk/BNC/src/bncnetqueryrtp.cpp @ 8203

Last change on this file since 8203 was 8203, checked in by stoecker, 10 months ago

see #105 - some changes for Qt5

File size: 7.2 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class:      bncNetQueryRtp
6 *
7 * Purpose:    Blocking Network Requests (NTRIP Version 2 with RTSP)
8 *
9 * Author:     L. Mervart
10 *
11 * Created:    27-Dec-2008
12 *
13 * Changes:   
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iostream>
18#include <iomanip>
19
20#include "bncnetqueryrtp.h"
21#include "bncsettings.h"
22#include "bncversion.h"
23
24using namespace std;
25
26// Constructor
27////////////////////////////////////////////////////////////////////////////
28bncNetQueryRtp::bncNetQueryRtp() {
29  _socket    = 0;
30  _udpSocket = 0;
31  _CSeq      = 0;
32  _eventLoop = new QEventLoop(this);
33}
34
35// Destructor
36////////////////////////////////////////////////////////////////////////////
37bncNetQueryRtp::~bncNetQueryRtp() {
38  delete _eventLoop;
39  delete _socket;
40  delete _udpSocket;
41}
42
43//
44////////////////////////////////////////////////////////////////////////////
45void bncNetQueryRtp::stop() {
46  _eventLoop->quit();
47  _status = finished;
48  if (_socket) {
49    QByteArray reqStr = "TEARDOWN " + _url.toEncoded() + " RTSP/1.0\r\n"
50                      + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
51                      + "Session: " + _session + "\r\n"
52                      + "\r\n";
53    _socket->write(reqStr, reqStr.length());
54  }
55}
56
57//
58////////////////////////////////////////////////////////////////////////////
59void bncNetQueryRtp::slotKeepAlive() {
60  if (_socket) {
61    QByteArray reqStr = "GET_PARAMETER " + _url.toEncoded() + " RTSP/1.0\r\n"
62                      + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
63                      + "Session: " + _session + "\r\n"
64                      + "\r\n";
65    _socket->write(reqStr, reqStr.length());
66  }
67  QTimer::singleShot(30000, this, SLOT(slotKeepAlive()));
68}
69
70//
71////////////////////////////////////////////////////////////////////////////
72void bncNetQueryRtp::waitForRequestResult(const QUrl&, QByteArray&) {
73}
74
75//
76////////////////////////////////////////////////////////////////////////////
77void bncNetQueryRtp::waitForReadyRead(QByteArray& outData) {
78
79  // Wait Loop
80  // ---------
81  if (!_udpSocket->hasPendingDatagrams()) {
82    _eventLoop->exec();
83  }
84
85  // Append Data
86  // -----------
87  QByteArray datagram;
88  datagram.resize(_udpSocket->pendingDatagramSize());
89  _udpSocket->readDatagram(datagram.data(), datagram.size());
90
91  if (datagram.size() > 12) {
92    outData.append(datagram.mid(12));
93  }
94}
95
96// Connect to Caster, send the Request
97////////////////////////////////////////////////////////////////////////////
98void bncNetQueryRtp::startRequest(const QUrl& url, const QByteArray& gga) {
99
100  const int timeOut = 5000;
101
102  _status = running;
103
104  delete _socket;
105  _socket = new QTcpSocket();
106
107  // Default scheme
108  // --------------
109  _url = url;
110  _url.setScheme("rtsp");
111
112  // Connect the Socket
113  // ------------------
114  bncSettings settings;
115  QString proxyHost = settings.value("proxyHost").toString();
116  int     proxyPort = settings.value("proxyPort").toInt();
117 
118  if ( proxyHost.isEmpty() ) {
119    _socket->connectToHost(_url.host(), _url.port());
120  }
121  else {
122    _socket->connectToHost(proxyHost, proxyPort);
123  }
124
125  // Send Request 1
126  // --------------
127  if (_socket->waitForConnected(timeOut)) {
128    QString uName = QUrl::fromPercentEncoding(_url.userName().toLatin1());
129    QString passW = QUrl::fromPercentEncoding(_url.password().toLatin1());
130    QByteArray userAndPwd;
131   
132    if(!uName.isEmpty() || !passW.isEmpty()) {
133      userAndPwd = "Authorization: Basic " + (uName.toLatin1() + ":" +
134      passW.toLatin1()).toBase64() + "\r\n";
135    }
136
137    // Setup the RTSP Connection
138    // -------------------------
139    delete _udpSocket;
140    _udpSocket = new QUdpSocket();
141    _udpSocket->bind(0);
142    connect(_udpSocket, SIGNAL(readyRead()), _eventLoop, SLOT(quit()));
143    QByteArray clientPort = QString("%1").arg(_udpSocket->localPort()).toLatin1();
144
145    QByteArray reqStr;
146    reqStr = "SETUP " + _url.toEncoded() + " RTSP/1.0\r\n"
147           + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
148           + "Ntrip-Version: Ntrip/2.0\r\n"
149           + "Ntrip-Component: Ntripclient\r\n"
150           + "User-Agent: NTRIP BNC/" BNCVERSION " (" BNC_OS ")\r\n"
151           + "Transport: RTP/GNSS;unicast;client_port=" + clientPort + "\r\n"
152           + userAndPwd;
153    if (!gga.isEmpty()) {
154      reqStr += "Ntrip-GGA: " + gga + "\r\n";
155    }
156    reqStr += "\r\n";
157
158    _socket->write(reqStr, reqStr.length());
159   
160    // Read Server Answer 1
161    // --------------------
162    if (_socket->waitForBytesWritten(timeOut)) {
163      if (_socket->waitForReadyRead(timeOut)) {
164        QTextStream in(_socket);
165        QByteArray serverPort;
166        QString line = in.readLine();
167        while (!line.isEmpty()) {
168          if (line.indexOf("Session:") == 0) {
169            _session = line.mid(9).toLatin1();
170          }
171          int iSrv = line.indexOf("server_port=");
172          if (iSrv != -1) {
173            serverPort = line.mid(iSrv+12).toLatin1();
174          }
175          line = in.readLine();
176        }
177   
178        // Send Request 2
179        // --------------
180        if (!_session.isEmpty()) { 
181
182          // Send initial RTP packet for firewall handling
183          // ---------------------------------------------
184          if (!serverPort.isEmpty()) {
185            unsigned sessInt = _session.toInt();
186            char rtpbuffer[12];
187            rtpbuffer[0]  = 128;
188            rtpbuffer[1]  =  96;
189            rtpbuffer[2]  =   0;
190            rtpbuffer[3]  =   0;
191            rtpbuffer[4]  =   0;
192            rtpbuffer[5]  =   0;
193            rtpbuffer[6]  =   0;
194            rtpbuffer[7]  =   0;
195            rtpbuffer[8]  = (sessInt >> 24) & 0xFF;
196            rtpbuffer[9]  = (sessInt >> 16) & 0xFF;
197            rtpbuffer[10] = (sessInt >>  8) & 0xFF;
198            rtpbuffer[11] = (sessInt      ) & 0xFF;
199
200            _udpSocket->writeDatagram(rtpbuffer, 12, 
201                              _socket->peerAddress(), serverPort.toInt());
202          }
203
204          reqStr = "PLAY " + _url.toEncoded() + " RTSP/1.0\r\n"
205                 + "CSeq: " + QString("%1").arg(++_CSeq).toLatin1() + "\r\n"
206                 + "Session: " + _session + "\r\n"
207                 + "\r\n";
208          _socket->write(reqStr, reqStr.length());
209   
210          // Read Server Answer 2
211          // --------------------
212          if (_socket->waitForBytesWritten(timeOut)) {
213            if (_socket->waitForReadyRead(timeOut)) {
214              QTextStream in(_socket);
215              line = in.readLine();
216              while (!line.isEmpty()) {
217                if (line.indexOf("200 OK") != -1) {
218                  emit newMessage(_url.encodedPath().replace(0,1,"")
219                            + ": UDP connection established", true);
220                  slotKeepAlive();
221                  return;
222                }
223                line = in.readLine();
224              }
225            }
226          }
227        }
228      }
229    }
230  }
231
232  delete _socket;
233  _socket = 0;
234  _status = error;
235  emit newMessage(_url.encodedPath().replace(0,1,"")
236                  + ": NetQuery, waiting for connect", true);
237}
238
239void bncNetQueryRtp::keepAliveRequest(const QUrl& /* url */, const QByteArray& /* gga */) {
240}
Note: See TracBrowser for help on using the repository browser.