mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
remove protobuf (part 2)
This commit is contained in:
14
libsrc/ssdp/CMakeLists.txt
Normal file
14
libsrc/ssdp/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
# Define the current source locations
|
||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/ssdp)
|
||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/ssdp)
|
||||
|
||||
FILE ( GLOB SSDP_SOURCES "${CURRENT_HEADER_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.cpp" )
|
||||
|
||||
add_library(ssdp
|
||||
${SSDP_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(ssdp
|
||||
Qt5::Network
|
||||
webserver
|
||||
)
|
41
libsrc/ssdp/SSDPDescription.h
Normal file
41
libsrc/ssdp/SSDPDescription.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
///
|
||||
/// The xml to fill with data
|
||||
/// %1 base url http://192.168.0.177:80/
|
||||
/// %2 friendly name Hyperion 2.0.0 (192.168.0.177)
|
||||
/// %3 modelNumber 2.0.0
|
||||
/// %4 serialNumber / UDN (H ID) Fjsa723dD0....
|
||||
///
|
||||
/// def URN urn:schemas-upnp-org:device:Basic:1
|
||||
|
||||
static const QString SSDP_DESCRIPTION = "<?xml version=\"1.0\"?>"
|
||||
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
|
||||
"<specVersion>"
|
||||
"<major>1</major>"
|
||||
"<minor>0</minor>"
|
||||
"</specVersion>"
|
||||
"<URLBase>%1</URLBase>"
|
||||
"<device>"
|
||||
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
|
||||
"<friendlyName>%2</friendlyName>"
|
||||
"<manufacturer>Hyperion Open Source Ambient Lighting</manufacturer>"
|
||||
"<manufacturerURL>https://www.hyperion-project.org</manufacturerURL>"
|
||||
"<modelDescription>Hyperion Open Source Ambient Light</modelDescription>"
|
||||
"<modelName>Hyperion</modelName>"
|
||||
"<modelNumber>%3</modelNumber>"
|
||||
"<modelURL>https://www.hyperion-project.org</modelURL>"
|
||||
"<serialNumber>%4</serialNumber>"
|
||||
"<UDN>uuid:%4</UDN>"
|
||||
"<presentationURL>index.html</presentationURL>"
|
||||
"<iconList>"
|
||||
"<icon>"
|
||||
"<mimetype>image/png</mimetype>"
|
||||
"<height>100</height>"
|
||||
"<width>100</width>"
|
||||
"<depth>32</depth>"
|
||||
"<url>img/hyperion/ssdp_icon.png</url>"
|
||||
"</icon>"
|
||||
"</iconList>"
|
||||
"</device>"
|
||||
"</root>";
|
169
libsrc/ssdp/SSDPDiscover.cpp
Normal file
169
libsrc/ssdp/SSDPDiscover.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include <ssdp/SSDPDiscover.h>
|
||||
|
||||
// qt inc
|
||||
#include <QUdpSocket>
|
||||
#include <QUrl>
|
||||
|
||||
static const QHostAddress SSDP_ADDR("239.255.255.250");
|
||||
static const quint16 SSDP_PORT(1900);
|
||||
|
||||
// as per upnp spec 1.1, section 1.2.2.
|
||||
// TODO: Make IP and port below another #define and replace message below
|
||||
static const QString UPNP_DISCOVER_MESSAGE = "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: %1\r\n"
|
||||
"\r\n";
|
||||
|
||||
SSDPDiscover::SSDPDiscover(QObject* parent)
|
||||
: QObject(parent)
|
||||
, _log(Logger::getInstance("SSDPDISCOVER"))
|
||||
, _udpSocket(new QUdpSocket(this))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SSDPDiscover::searchForService(const QString& st)
|
||||
{
|
||||
_searchTarget = st;
|
||||
_usnList.clear();
|
||||
// setup socket
|
||||
connect(_udpSocket, &QUdpSocket::readyRead, this, &SSDPDiscover::readPendingDatagrams, Qt::UniqueConnection);
|
||||
|
||||
sendSearch(st);
|
||||
}
|
||||
|
||||
const QString SSDPDiscover::getFirstService(const searchType& type, const QString& st, const int& timeout_ms)
|
||||
{
|
||||
Info(_log, "Search for Hyperion server...");
|
||||
_searchTarget = st;
|
||||
|
||||
// search
|
||||
sendSearch(st);
|
||||
|
||||
_udpSocket->waitForReadyRead(timeout_ms);
|
||||
|
||||
while (_udpSocket->hasPendingDatagrams())
|
||||
{
|
||||
QByteArray datagram;
|
||||
datagram.resize(_udpSocket->pendingDatagramSize());
|
||||
QHostAddress sender;
|
||||
quint16 senderPort;
|
||||
|
||||
_udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||||
|
||||
QString data(datagram);
|
||||
QMap<QString,QString> headers;
|
||||
QString address;
|
||||
// parse request
|
||||
QStringList entries = data.split("\n", QString::SkipEmptyParts);
|
||||
for(auto entry : entries)
|
||||
{
|
||||
// http header parse skip
|
||||
if(entry.contains("HTTP/1.1"))
|
||||
continue;
|
||||
|
||||
// split into key:vale, be aware that value field may contain also a ":"
|
||||
entry = entry.simplified();
|
||||
int pos = entry.indexOf(":");
|
||||
if(pos == -1)
|
||||
continue;
|
||||
|
||||
headers[entry.left(pos).trimmed().toLower()] = entry.mid(pos+1).trimmed();
|
||||
}
|
||||
|
||||
// verify ssdp spec
|
||||
if(!headers.contains("st"))
|
||||
continue;
|
||||
|
||||
// usn duplicates
|
||||
if (_usnList.contains(headers.value("usn")))
|
||||
continue;
|
||||
|
||||
if (headers.value("st") == _searchTarget)
|
||||
{
|
||||
_usnList << headers.value("usn");
|
||||
QUrl url(headers.value("location"));
|
||||
//Info(_log, "Received msearch response from '%s:%d'. Search target: %s",QSTRING_CSTR(sender.toString()), senderPort, QSTRING_CSTR(headers.value("st")));
|
||||
if(type == STY_WEBSERVER)
|
||||
{
|
||||
Info(_log, "Found Hyperion server at: %s:%d", QSTRING_CSTR(url.host()), url.port());
|
||||
|
||||
return url.host()+":"+QString::number(url.port());
|
||||
}
|
||||
else if(type == STY_FLATBUFSERVER)
|
||||
{
|
||||
const QString fbsport = headers.value("hyperion-fbs-port");
|
||||
if(fbsport.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info(_log, "Found Hyperion server at: %s:%d", QSTRING_CSTR(url.host()), fbsport);
|
||||
return url.host()+":"+fbsport;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Info(_log,"Search timeout, no Hyperion server found");
|
||||
return QString();
|
||||
}
|
||||
|
||||
void SSDPDiscover::readPendingDatagrams()
|
||||
{
|
||||
while (_udpSocket->hasPendingDatagrams()) {
|
||||
|
||||
QByteArray datagram;
|
||||
datagram.resize(_udpSocket->pendingDatagramSize());
|
||||
QHostAddress sender;
|
||||
quint16 senderPort;
|
||||
|
||||
_udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||||
|
||||
QString data(datagram);
|
||||
QMap<QString,QString> headers;
|
||||
// parse request
|
||||
QStringList entries = data.split("\n", QString::SkipEmptyParts);
|
||||
for(auto entry : entries)
|
||||
{
|
||||
// http header parse skip
|
||||
if(entry.contains("HTTP/1.1"))
|
||||
continue;
|
||||
|
||||
// split into key:vale, be aware that value field may contain also a ":"
|
||||
entry = entry.simplified();
|
||||
int pos = entry.indexOf(":");
|
||||
if(pos == -1)
|
||||
continue;
|
||||
|
||||
headers[entry.left(pos).trimmed().toLower()] = entry.mid(pos+1).trimmed();
|
||||
}
|
||||
|
||||
// verify ssdp spec
|
||||
if(!headers.contains("st"))
|
||||
continue;
|
||||
|
||||
// usn duplicates
|
||||
if (_usnList.contains(headers.value("usn")))
|
||||
continue;
|
||||
|
||||
if (headers.value("st") == _searchTarget)
|
||||
{
|
||||
_usnList << headers.value("usn");
|
||||
//Info(_log, "Received msearch response from '%s:%d'. Search target: %s",QSTRING_CSTR(sender.toString()), senderPort, QSTRING_CSTR(headers.value("st")));
|
||||
QUrl url(headers.value("location"));
|
||||
emit newService(url.host()+":"+QString::number(url.port()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPDiscover::sendSearch(const QString& st)
|
||||
{
|
||||
const QString msg = UPNP_DISCOVER_MESSAGE.arg(st);
|
||||
|
||||
_udpSocket->writeDatagram(msg.toUtf8(),
|
||||
QHostAddress(SSDP_ADDR),
|
||||
SSDP_PORT);
|
||||
}
|
144
libsrc/ssdp/SSDPHandler.cpp
Normal file
144
libsrc/ssdp/SSDPHandler.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#include <ssdp/SSDPHandler.h>
|
||||
|
||||
#include <webserver/WebServer.h>
|
||||
#include "SSDPDescription.h"
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <HyperionConfig.h>
|
||||
|
||||
#include <QNetworkInterface>
|
||||
#include <QNetworkConfigurationManager>
|
||||
|
||||
SSDPHandler::SSDPHandler(WebServer* webserver, const quint16& flatBufPort, QObject * parent)
|
||||
: SSDPServer(parent)
|
||||
, _webserver(webserver)
|
||||
, _localAddress()
|
||||
, _NCA(nullptr)
|
||||
{
|
||||
_flatbufPort = flatBufPort;
|
||||
setFlatBufPort(_flatbufPort);
|
||||
}
|
||||
|
||||
void SSDPHandler::initServer()
|
||||
{
|
||||
// prep server
|
||||
SSDPServer::initServer();
|
||||
|
||||
_NCA = new QNetworkConfigurationManager(this);
|
||||
|
||||
// listen for mSearchRequestes
|
||||
connect(this, &SSDPServer::msearchRequestReceived, this, &SSDPHandler::handleMSearchRequest);
|
||||
|
||||
connect(_NCA, &QNetworkConfigurationManager::configurationChanged, this, &SSDPHandler::handleNetworkConfigurationChanged);
|
||||
|
||||
// get localAddress from interface
|
||||
if(!getLocalAddress().isEmpty())
|
||||
{
|
||||
_localAddress = getLocalAddress();
|
||||
}
|
||||
|
||||
// startup if localAddress is found
|
||||
if(!_localAddress.isEmpty() && _webserver->isInited())
|
||||
{
|
||||
handleWebServerStateChange(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPHandler::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
|
||||
{
|
||||
if(type == settings::FLATBUFSERVER)
|
||||
{
|
||||
const QJsonObject& obj = config.object();
|
||||
if(obj["port"].toInt() != _flatbufPort)
|
||||
{
|
||||
_flatbufPort = obj["port"].toInt();
|
||||
setFlatBufPort(_flatbufPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPHandler::handleWebServerStateChange(const bool newState)
|
||||
{
|
||||
if(newState)
|
||||
{
|
||||
// refresh info
|
||||
_webserver->setSSDPDescription(buildDesc());
|
||||
setDescriptionAddress(getDescAddress());
|
||||
if(start())
|
||||
{
|
||||
sendAlive("upnp:rootdevice");
|
||||
sendAlive("urn:schemas-upnp-org:device:basic:1");
|
||||
sendAlive("urn:hyperion-project.org:device:basic:1");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_webserver->setSSDPDescription("");
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
|
||||
{
|
||||
// get localAddress from interface
|
||||
if(!getLocalAddress().isEmpty())
|
||||
{
|
||||
QString localAddress = getLocalAddress();
|
||||
if(_localAddress != localAddress)
|
||||
{
|
||||
// revoke old ip
|
||||
sendByeBye("upnp:rootdevice");
|
||||
sendByeBye("urn:schemas-upnp-org:device:basic:1");
|
||||
sendByeBye("urn:hyperion-project.org:device:basic:1");
|
||||
|
||||
// update desc & notify new ip
|
||||
_localAddress = localAddress;
|
||||
_webserver->setSSDPDescription(buildDesc());
|
||||
setDescriptionAddress(getDescAddress());
|
||||
sendAlive("upnp:rootdevice");
|
||||
sendAlive("urn:schemas-upnp-org:device:basic:1");
|
||||
sendAlive("urn:hyperion-project.org:device:basic:1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QString SSDPHandler::getLocalAddress()
|
||||
{
|
||||
// get the first valid IPv4 address. This is probably not that one we actually want to announce
|
||||
for( const auto & address : QNetworkInterface::allAddresses())
|
||||
{
|
||||
// is valid when, no loopback, IPv4
|
||||
if (!address.isLoopback() && address.protocol() == QAbstractSocket::IPv4Protocol )
|
||||
{
|
||||
return address.toString();
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void SSDPHandler::handleMSearchRequest(const QString& target, const QString& mx, const QString address, const quint16 & port)
|
||||
{
|
||||
// TODO Response delay according to MX field (sec) random between 0 and MX
|
||||
|
||||
// when searched for all devices / root devices / basic device
|
||||
if(target == "ssdp:all" || target == "upnp:rootdevice" || target == "urn:schemas-upnp-org:device:basic:1" || target == "urn:hyperion-project.org:device:basic:1")
|
||||
sendMSearchResponse(target, address, port);
|
||||
}
|
||||
|
||||
const QString SSDPHandler::getDescAddress()
|
||||
{
|
||||
return getBaseAddress()+"description.xml";
|
||||
}
|
||||
|
||||
const QString SSDPHandler::getBaseAddress()
|
||||
{
|
||||
return "http://"+_localAddress+":"+QString::number(_webserver->getPort())+"/";
|
||||
}
|
||||
|
||||
const QString SSDPHandler::buildDesc()
|
||||
{
|
||||
/// %1 base url http://192.168.0.177:80/
|
||||
/// %2 friendly name Hyperion 2.0.0 (192.168.0.177)
|
||||
/// %3 modelNumber 2.0.0
|
||||
/// %4 serialNumber / UDN (H ID) Fjsa723dD0....
|
||||
return SSDP_DESCRIPTION.arg(getBaseAddress(), QString("Hyperion (%2)").arg(_localAddress), QString(HYPERION_VERSION), Hyperion::getInstance()->getId());
|
||||
}
|
227
libsrc/ssdp/SSDPServer.cpp
Normal file
227
libsrc/ssdp/SSDPServer.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
#include <ssdp/SSDPServer.h>
|
||||
|
||||
// util
|
||||
#include <utils/SysInfo.h>
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <HyperionConfig.h>
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QDateTime>
|
||||
|
||||
static const QHostAddress SSDP_ADDR("239.255.255.250");
|
||||
static const quint16 SSDP_PORT(1900);
|
||||
static const QString SSDP_MAX_AGE("1800");
|
||||
|
||||
// as per upnp spec 1.1, section 1.2.2.
|
||||
// - BOOTID.UPNP.ORG
|
||||
// - CONFIGID.UPNP.ORG
|
||||
// - SEARCHPORT.UPNP.ORG (optional)
|
||||
// TODO: Make IP and port below another #define and replace message below
|
||||
static const QString UPNP_ALIVE_MESSAGE = "NOTIFY * HTTP/1.1\r\n"
|
||||
"HOST: 239.255.255.250:1900\r\n"
|
||||
"CACHE-CONTROL: max-age=%1\r\n"
|
||||
"LOCATION: %2\r\n"
|
||||
"NT: %3\r\n"
|
||||
"NTS: ssdp:alive\r\n"
|
||||
"SERVER: %4\r\n"
|
||||
"USN: uuid:%5\r\n"
|
||||
"HYPERION-FBS-PORT: %6\r\n"
|
||||
"\r\n";
|
||||
|
||||
// Implement ssdp:update as per spec 1.1, section 1.2.4
|
||||
// and use the below define to build the message, where
|
||||
// SEARCHPORT.UPNP.ORG are optional.
|
||||
// TODO: Make IP and port below another #define and replace message below
|
||||
static const QString UPNP_UPDATE_MESSAGE = "NOTIFY * HTTP/1.1\r\n"
|
||||
"HOST: 239.255.255.250:1900\r\n"
|
||||
"LOCATION: %1\r\n"
|
||||
"NT: %2\r\n"
|
||||
"NTS: ssdp:update\r\n"
|
||||
"USN: uuid:%3\r\n"
|
||||
/* "CONFIGID.UPNP.ORG: %4\r\n"
|
||||
UPNP spec = 1.1 "NEXTBOOTID.UPNP.ORG: %5\r\n"
|
||||
"SEARCHPORT.UPNP.ORG: %6\r\n"
|
||||
*/ "\r\n";
|
||||
|
||||
// TODO: Add this two fields commented below in the BYEBYE MESSAGE
|
||||
// as per upnp spec 1.1, section 1.2.2 and 1.2.3.
|
||||
// - BOOTID.UPNP.ORG
|
||||
// - CONFIGID.UPNP.ORG
|
||||
// TODO: Make IP and port below another #define and replace message below
|
||||
static const QString UPNP_BYEBYE_MESSAGE = "NOTIFY * HTTP/1.1\r\n"
|
||||
"HOST: 239.255.255.250:1900\r\n"
|
||||
"NT: %1\r\n"
|
||||
"NTS: ssdp:byebye\r\n"
|
||||
"USN: uuid:%2\r\n"
|
||||
"\r\n";
|
||||
|
||||
// TODO: Add this three fields commented below in the MSEARCH_RESPONSE
|
||||
// as per upnp spec 1.1, section 1.3.3.
|
||||
// - BOOTID.UPNP.ORG
|
||||
// - CONFIGID.UPNP.ORG
|
||||
// - SEARCHPORT.UPNP.ORG (optional)
|
||||
static const QString UPNP_MSEARCH_RESPONSE = "HTTP/1.1 200 OK\r\n"
|
||||
"CACHE-CONTROL: max-age = %1\r\n"
|
||||
"DATE: %2\r\n"
|
||||
"EXT: \r\n"
|
||||
"LOCATION: %3\r\n"
|
||||
"SERVER: %4\r\n"
|
||||
"ST: %5\r\n"
|
||||
"USN: uuid:%6\r\n"
|
||||
"HYPERION-FBS-PORT: %7\r\n"
|
||||
"\r\n";
|
||||
|
||||
SSDPServer::SSDPServer(QObject * parent)
|
||||
: QObject(parent)
|
||||
, _log(Logger::getInstance("SSDP"))
|
||||
, _udpSocket(nullptr)
|
||||
, _running(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SSDPServer::~SSDPServer()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void SSDPServer::initServer()
|
||||
{
|
||||
_udpSocket = new QUdpSocket(this);
|
||||
|
||||
// get system info
|
||||
SysInfo::HyperionSysInfo data = SysInfo::get();
|
||||
|
||||
// create SERVER String
|
||||
_serverHeader = data.prettyName+"/"+data.productVersion+" UPnP/1.0 Hyperion/"+QString(HYPERION_VERSION);
|
||||
|
||||
// usn uuid
|
||||
_uuid = Hyperion::getInstance()->getId();
|
||||
|
||||
connect(_udpSocket, &QUdpSocket::readyRead, this, &SSDPServer::readPendingDatagrams);
|
||||
}
|
||||
|
||||
const bool SSDPServer::start()
|
||||
{
|
||||
if(!_running && _udpSocket->bind(QHostAddress::AnyIPv4, SSDP_PORT, QAbstractSocket::ShareAddress))
|
||||
{
|
||||
_udpSocket->joinMulticastGroup(SSDP_ADDR);
|
||||
_running = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SSDPServer::stop()
|
||||
{
|
||||
if(_running)
|
||||
{
|
||||
// send BYEBYE Msg
|
||||
sendByeBye("upnp:rootdevice");
|
||||
sendByeBye("urn:schemas-upnp-org:device:basic:1");
|
||||
sendByeBye("urn:hyperion-project.org:device:basic:1");
|
||||
_udpSocket->close();
|
||||
_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPServer::readPendingDatagrams()
|
||||
{
|
||||
while (_udpSocket->hasPendingDatagrams()) {
|
||||
|
||||
QByteArray datagram;
|
||||
datagram.resize(_udpSocket->pendingDatagramSize());
|
||||
QHostAddress sender;
|
||||
quint16 senderPort;
|
||||
|
||||
_udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||||
|
||||
QString data(datagram);
|
||||
QMap<QString,QString> headers;
|
||||
// parse request
|
||||
QStringList entries = data.split("\n", QString::SkipEmptyParts);
|
||||
for(auto entry : entries)
|
||||
{
|
||||
// http header parse skip
|
||||
if(entry.contains("HTTP/1.1"))
|
||||
continue;
|
||||
|
||||
// split into key:vale, be aware that value field may contain also a ":"
|
||||
entry = entry.simplified();
|
||||
int pos = entry.indexOf(":");
|
||||
if(pos == -1)
|
||||
continue;
|
||||
|
||||
headers[entry.left(pos).trimmed().toLower()] = entry.mid(pos+1).trimmed();
|
||||
}
|
||||
|
||||
// verify ssdp spec
|
||||
if(!headers.contains("man"))
|
||||
continue;
|
||||
|
||||
if (headers.value("man") == "\"ssdp:discover\"")
|
||||
{
|
||||
//Debug(_log, "Received msearch from '%s:%d'. Search target: %s",QSTRING_CSTR(sender.toString()), senderPort, QSTRING_CSTR(headers.value("st")));
|
||||
emit msearchRequestReceived(headers.value("st"), headers.value("mx"), sender.toString(), senderPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPServer::sendMSearchResponse(const QString& st, const QString& senderIp, const quint16& senderPort)
|
||||
{
|
||||
QString message = UPNP_MSEARCH_RESPONSE.arg(SSDP_MAX_AGE
|
||||
, QDateTime::currentDateTimeUtc().toString("ddd, dd MMM yyyy HH:mm:ss GMT")
|
||||
, _descAddress
|
||||
, _serverHeader
|
||||
, st
|
||||
, _uuid
|
||||
, _fbsPort );
|
||||
|
||||
_udpSocket->writeDatagram(message.toUtf8(),
|
||||
QHostAddress(senderIp),
|
||||
senderPort);
|
||||
}
|
||||
|
||||
void SSDPServer::sendByeBye(const QString& st)
|
||||
{
|
||||
QString message = UPNP_BYEBYE_MESSAGE.arg(st, _uuid+"::"+st );
|
||||
|
||||
// we repeat 3 times
|
||||
quint8 rep = 0;
|
||||
while(rep < 3) {
|
||||
_udpSocket->writeDatagram(message.toUtf8(),
|
||||
QHostAddress(SSDP_ADDR),
|
||||
SSDP_PORT);
|
||||
rep++;
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPServer::sendAlive(const QString& st)
|
||||
{
|
||||
QString message = UPNP_ALIVE_MESSAGE.arg(SSDP_MAX_AGE
|
||||
, _descAddress
|
||||
, st
|
||||
, _serverHeader
|
||||
, _uuid+"::"+st
|
||||
, _fbsPort);
|
||||
|
||||
// we repeat 3 times
|
||||
quint8 rep = 0;
|
||||
while(rep < 3) {
|
||||
_udpSocket->writeDatagram(message.toUtf8(),
|
||||
QHostAddress(SSDP_ADDR),
|
||||
SSDP_PORT);
|
||||
rep++;
|
||||
}
|
||||
}
|
||||
|
||||
void SSDPServer::sendUpdate(const QString& st)
|
||||
{
|
||||
QString message = UPNP_UPDATE_MESSAGE.arg(_descAddress
|
||||
, st
|
||||
, _uuid+"::"+st );
|
||||
|
||||
_udpSocket->writeDatagram(message.toUtf8(),
|
||||
QHostAddress(SSDP_ADDR),
|
||||
SSDP_PORT);
|
||||
}
|
Reference in New Issue
Block a user