/* ------------------------------------------------------------------------- * BKG NTRIP Client * ------------------------------------------------------------------------- * * Class: bncNetQueryRtp * * Purpose: Blocking Network Requests (NTRIP Version 2 with RTSP) * * Author: L. Mervart * * Created: 27-Dec-2008 * * Changes: * * -----------------------------------------------------------------------*/ #include #include #include "bncnetqueryrtp.h" using namespace std; #define BNCVERSION "1.7" // Constructor //////////////////////////////////////////////////////////////////////////// bncNetQueryRtp::bncNetQueryRtp() { _socket = 0; _udpSocket = 0; _eventLoop = new QEventLoop(this); } // Destructor //////////////////////////////////////////////////////////////////////////// bncNetQueryRtp::~bncNetQueryRtp() { delete _eventLoop; delete _socket; delete _udpSocket; } // //////////////////////////////////////////////////////////////////////////// void bncNetQueryRtp::stop() { _eventLoop->quit(); _status = finished; } // //////////////////////////////////////////////////////////////////////////// void bncNetQueryRtp::waitForRequestResult(const QUrl&, QByteArray&) { } // //////////////////////////////////////////////////////////////////////////// void bncNetQueryRtp::waitForReadyRead(QByteArray& outData) { // Wait Loop // --------- if (!_udpSocket->hasPendingDatagrams()) { _eventLoop->exec(); } // Append Data // ----------- QByteArray datagram; datagram.resize(_udpSocket->pendingDatagramSize()); _udpSocket->readDatagram(datagram.data(), datagram.size()); if (datagram.size() > 12) { outData.append(datagram.mid(12)); } } // Connect to Caster, send the Request //////////////////////////////////////////////////////////////////////////// void bncNetQueryRtp::startRequest(const QUrl& url, const QByteArray& gga) { const int timeOut = 5000; _status = running; delete _socket; _socket = new QTcpSocket(); // Default scheme // -------------- QUrl urlLoc(url); urlLoc.setScheme("rtsp"); // Connect the Socket // ------------------ QSettings settings; QString proxyHost = settings.value("proxyHost").toString(); int proxyPort = settings.value("proxyPort").toInt(); if ( proxyHost.isEmpty() ) { _socket->connectToHost(urlLoc.host(), urlLoc.port()); } else { _socket->connectToHost(proxyHost, proxyPort); } // Send Request 1 // -------------- if (_socket->waitForConnected(timeOut)) { QString uName = QUrl::fromPercentEncoding(urlLoc.userName().toAscii()); QString passW = QUrl::fromPercentEncoding(urlLoc.password().toAscii()); QByteArray userAndPwd; if(!uName.isEmpty() || !passW.isEmpty()) { userAndPwd = "Authorization: Basic " + (uName.toAscii() + ":" + passW.toAscii()).toBase64() + "\r\n"; } // Find a free port number // ----------------------- int clientPortInt = 0; QTcpSocket* hlpSocket = new QTcpSocket(); if ( proxyHost.isEmpty() ) { hlpSocket->connectToHost(urlLoc.host(), urlLoc.port()); } else { hlpSocket->connectToHost(proxyHost, proxyPort); } if (hlpSocket->waitForConnected(timeOut)) { clientPortInt = hlpSocket->localPort(); } delete hlpSocket; // Setup the RTSP Connection // ------------------------- if (clientPortInt) { QByteArray clientPort = QString("%1").arg(clientPortInt).toAscii(); delete _udpSocket; _udpSocket = new QUdpSocket(); _udpSocket->bind(clientPortInt); connect(_udpSocket, SIGNAL(readyRead()), _eventLoop, SLOT(quit())); QByteArray reqStr; reqStr = "SETUP " + urlLoc.toEncoded() + " RTSP/1.0\r\n" + "CSeq: 1\r\n" + "Ntrip-Version: Ntrip/2.0\r\n" + "Ntrip-Component: Ntripclient\r\n" + "User-Agent: NTRIP BNC/" BNCVERSION "\r\n" + "Transport: RTP/GNSS;unicast;client_port=" + clientPort + "\r\n" + userAndPwd + "\r\n"; _socket->write(reqStr, reqStr.length()); // Read Server Answer 1 // -------------------- if (_socket->waitForBytesWritten(timeOut)) { if (_socket->waitForReadyRead(timeOut)) { QTextStream in(_socket); QByteArray session; QString line = in.readLine(); while (!line.isEmpty()) { if (line.indexOf("Session:") == 0) { session = line.mid(9).toAscii(); break; } line = in.readLine(); } // Send Request 2 // -------------- if (!session.isEmpty()) { reqStr = "PLAY " + urlLoc.toEncoded() + " RTSP/1.0\r\n" + "CSeq: 2\r\n" + "Session: " + session + "\r\n" + "\r\n"; _socket->write(reqStr, reqStr.length()); // Read Server Answer 2 // -------------------- if (_socket->waitForBytesWritten(timeOut)) { if (_socket->waitForReadyRead(timeOut)) { QTextStream in(_socket); line = in.readLine(); while (!line.isEmpty()) { if (line.indexOf("200 OK") != -1) { emit newMessage("NetQuery: UDP connection established", true); return; } line = in.readLine(); } } } } } } } } delete _socket; _socket = 0; _status = error; }