void SSDP::PerformSearch( const QString &sST ) { QString rRequest = QString( "M-SEARCH * HTTP/1.1\r\n" "HOST: 239.255.255.250:1900\r\n" "MAN: \"ssdp:discover\"\r\n" "MX: 2\r\n" "ST: %1\r\n" "\r\n" ).arg( sST ); QByteArray sRequest = rRequest.toUtf8(); MSocketDevice *pSocket = m_Sockets[ SocketIdx_Search ]; QHostAddress address; address.setAddress( SSDP_GROUP ); int nSize = sRequest.size(); if ( pSocket->writeBlock( sRequest.data(), sRequest.size(), address, SSDP_PORT ) != nSize) cerr << "SSDP::PerformSearch - did not write entire buffer." << endl; usleep( rand() % 250000 ); if ( pSocket->writeBlock( sRequest.data(), sRequest.size(), address, SSDP_PORT ) != nSize) cerr << "SSDP::PerformSearch - did not write entire buffer." << endl; }
QHostAddress MSocketDevice::peerAddress() const { if ( pp==0 && isValid() ) { MSocketDevice *that = (MSocketDevice*)this; // mutable that->fetchPeerConnectionParameters(); } return pa; }
quint16 MSocketDevice::peerPort() const { if ( pp==0 && isValid() ) { MSocketDevice *that = (MSocketDevice*)this; // mutable that->fetchPeerConnectionParameters(); } return pp; }
bool UPNPSubscription::SendUnsubscribeRequest(const QString &usn, const QUrl &url, const QString &path, const QString &uuid) { bool success = false; QString host = url.host(); int port = url.port(); QByteArray sub; QTextStream data(&sub); data.setCodec(QTextCodec::codecForName("UTF-8")); // N.B. Play On needs an extra space between UNSUBSCRIBE and path... data << QString("UNSUBSCRIBE %1 HTTP/1.1\r\n").arg(path); data << QString("HOST: %1:%2\r\n").arg(host).arg(QString::number(port)); data << QString("SID: uuid:%1\r\n").arg(uuid); data << "\r\n"; data.flush(); LOG(VB_UPNP, LOG_DEBUG, LOC + "\n\n" + sub); MSocketDevice *sockdev = new MSocketDevice(MSocketDevice::Stream); BufferedSocketDevice *sock = new BufferedSocketDevice(sockdev); sockdev->setBlocking(true); if (sock->Connect(QHostAddress(host), port)) { if (sock->WriteBlockDirect(sub.constData(), sub.size()) != -1) { QString line = sock->ReadLine(MAX_WAIT); success = !line.isEmpty(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Socket write error for %1:%2") .arg(host).arg(port)); } sock->Close(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open socket for %1:%2") .arg(host).arg(port)); } delete sock; delete sockdev; if (success) LOG(VB_GENERAL, LOG_INFO, LOC + QString("Unsubscribed to %1").arg(usn)); else LOG(VB_UPNP, LOG_WARNING, LOC + QString("Failed to unsubscribe to %1") .arg(usn)); return success; }
void SSDP::PerformSearch(const QString &sST, uint timeout_secs) { timeout_secs = std::max(std::min(timeout_secs, 5U), 1U); QString rRequest = QString("M-SEARCH * HTTP/1.1\r\n" "HOST: 239.255.255.250:1900\r\n" "MAN: \"ssdp:discover\"\r\n" "MX: %1\r\n" "ST: %2\r\n" "\r\n") .arg(timeout_secs).arg(sST); LOG(VB_UPNP, LOG_DEBUG, QString("\n\n%1\n").arg(rRequest)); QByteArray sRequest = rRequest.toUtf8(); MSocketDevice *pSocket = m_Sockets[ SocketIdx_Search ]; if ( !pSocket->isValid() ) { pSocket->setProtocol(MSocketDevice::IPv4); pSocket->setSocket(pSocket->createNewSocket(), MSocketDevice::Datagram); } QHostAddress address; address.setAddress( SSDP_GROUP ); int nSize = sRequest.size(); if ( pSocket->writeBlock( sRequest.data(), sRequest.size(), address, SSDP_PORT ) != nSize) LOG(VB_GENERAL, LOG_INFO, "SSDP::PerformSearch - did not write entire buffer."); usleep( random() % 250000 ); if ( pSocket->writeBlock( sRequest.data(), sRequest.size(), address, SSDP_PORT ) != nSize) LOG(VB_GENERAL, LOG_INFO, "SSDP::PerformSearch - did not write entire buffer."); }
void UPnpEventTask::Execute( TaskQueue * /*pQueue*/ ) { if (m_pPayload == NULL) return; MSocketDevice *pSockDev = new MSocketDevice( MSocketDevice::Stream ); BufferedSocketDevice *pSock = new BufferedSocketDevice( pSockDev ); pSockDev->setBlocking( true ); if (pSock->Connect( m_PeerAddress, m_nPeerPort )) { // ------------------------------------------------------------------ // Send NOTIFY message // ------------------------------------------------------------------ if (pSock->WriteBlockDirect( m_pPayload->data(), m_pPayload->size() ) != -1) { // -------------------------------------------------------------- // Read first line to determine success/Fail // -------------------------------------------------------------- QString sResponseLine = pSock->ReadLine( 3000 ); if ( sResponseLine.length() > 0) { //if (sResponseLine.contains("200 OK")) //{ VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - NOTIFY to %1:%2 returned %3." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) .arg( sResponseLine )); //} } else { VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - Timeout reading first line of reply from %1:%2." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) ); } } else VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - Error sending to %1:%2." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) ); pSock->Close(); } else { VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - Error sending to %1:%2." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) ); } if ( pSock != NULL ) delete pSock; if ( pSockDev != NULL ) delete pSockDev; }
int UPNPSubscription::SendSubscribeRequest(const QString &callback, const QString &usn, const QUrl &url, const QString &path, const QString &uuidin, QString &uuidout) { QString host = url.host(); int port = url.port(); QByteArray sub; QTextStream data(&sub); data.setCodec(QTextCodec::codecForName("UTF-8")); // N.B. Play On needs an extra space between SUBSCRIBE and path... data << QString("SUBSCRIBE %1 HTTP/1.1\r\n").arg(path); data << QString("HOST: %1:%2\r\n").arg(host).arg(QString::number(port)); if (uuidin.isEmpty()) // new subscription { data << QString("CALLBACK: <%1%2>\r\n") .arg(callback).arg(usn); data << "NT: upnp:event\r\n"; } else // renewal data << QString("SID: uuid:%1\r\n").arg(uuidin); data << QString("TIMEOUT: Second-%1\r\n").arg(SUBSCRIPTION_TIME); data << "\r\n"; data.flush(); LOG(VB_UPNP, LOG_DEBUG, LOC + "\n\n" + sub); MSocketDevice *sockdev = new MSocketDevice(MSocketDevice::Stream); BufferedSocketDevice *sock = new BufferedSocketDevice(sockdev); sockdev->setBlocking(true); QString uuid; QString timeout; uint result = 0; if (sock->Connect(QHostAddress(host), port)) { if (sock->WriteBlockDirect(sub.constData(), sub.size()) != -1) { bool ok = false; QString line = sock->ReadLine(MAX_WAIT); while (!line.isEmpty()) { LOG(VB_UPNP, LOG_DEBUG, LOC + line); if (line.contains("HTTP/1.1 200 OK", Qt::CaseInsensitive)) ok = true; if (line.startsWith("SID:", Qt::CaseInsensitive)) uuid = line.mid(4).trimmed().mid(5).trimmed(); if (line.startsWith("TIMEOUT:", Qt::CaseInsensitive)) timeout = line.mid(8).trimmed().mid(7).trimmed(); if (ok && !uuid.isEmpty() && !timeout.isEmpty()) break; line = sock->ReadLine(MAX_WAIT); } if (ok && !uuid.isEmpty() && !timeout.isEmpty()) { uuidout = uuid; result = timeout.toUInt(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to subscribe to %1").arg(usn)); } } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Socket write error for %1:%2") .arg(host).arg(port)); } sock->Close(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open socket for %1:%2") .arg(host).arg(port)); } delete sock; delete sockdev; return result; }