basic upnp discovery done
This commit is contained in:
parent
e48c9e4497
commit
3ddd9a2b92
@ -120,7 +120,7 @@ void UpnpDiscovery::requestDeviceInformation(const QNetworkRequest &networkReque
|
|||||||
m_informationRequestList.insert(replay, upnpDeviceDescriptor);
|
m_informationRequestList.insert(replay, upnpDeviceDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpnpDiscovery::respondToSearchRequest()
|
void UpnpDiscovery::respondToSearchRequest(QHostAddress host, int port)
|
||||||
{
|
{
|
||||||
GuhSettings settings(GuhSettings::SettingsRoleDevices);
|
GuhSettings settings(GuhSettings::SettingsRoleDevices);
|
||||||
settings.beginGroup("guhd");
|
settings.beginGroup("guhd");
|
||||||
@ -133,34 +133,38 @@ void UpnpDiscovery::respondToSearchRequest()
|
|||||||
|
|
||||||
GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal);
|
GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal);
|
||||||
globalSettings.beginGroup("WebServer");
|
globalSettings.beginGroup("WebServer");
|
||||||
int port = settings.value("port", 3333).toInt();
|
int serverPort = settings.value("port", 3333).toInt();
|
||||||
bool useSsl = settings.value("https", false).toBool();
|
bool useSsl = settings.value("https", false).toBool();
|
||||||
globalSettings.endGroup();
|
globalSettings.endGroup();
|
||||||
|
|
||||||
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
|
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
|
||||||
// listen only on IPv4
|
|
||||||
foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
|
foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
|
||||||
|
// check IPv4
|
||||||
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
|
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
QString locationString;
|
// check subnet
|
||||||
if (useSsl) {
|
if (host.isInSubnet(QHostAddress::parseSubnet(entry.ip().toString() + "/24"))) {
|
||||||
locationString = "https://" + entry.ip().toString() + ":" + QString::number(port) + "/server.xml";
|
QString locationString;
|
||||||
} else {
|
if (useSsl) {
|
||||||
locationString = "http://" + entry.ip().toString() + ":" + QString::number(port) + "/server.xml";
|
locationString = "https://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
|
||||||
|
} else {
|
||||||
|
locationString = "http://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
|
||||||
|
QByteArray rootdeviceResponseMessage = QByteArray("HTTP/1.1 200 OK\r\n"
|
||||||
|
"Cache-Control: max-age=1900\r\n"
|
||||||
|
"DATE: " + QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT\r\n"
|
||||||
|
"EXT:\r\n"
|
||||||
|
"CONTENT-LENGTH:0\r\n"
|
||||||
|
"Location: " + locationString.toUtf8() + "\r\n"
|
||||||
|
"Server: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
|
||||||
|
"ST:upnp:rootdevice\r\n"
|
||||||
|
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
|
||||||
|
"\r\n");
|
||||||
|
|
||||||
|
//qCDebug(dcHardware) << QString("Sending response to %1:%2\n").arg(host.toString()).arg(port);
|
||||||
|
writeDatagram(rootdeviceResponseMessage, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
|
|
||||||
QByteArray rootdeviceResponseMessage = QByteArray("HTTP/1.1 200 OK\r\n"
|
|
||||||
"CACHE-CONTROL: max-age=1900\r\n"
|
|
||||||
"DATE: " + QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT\r\n"
|
|
||||||
"EXT:\r\n"
|
|
||||||
"CONTENT-LENGTH:0\r\n"
|
|
||||||
"LOCATION: " + locationString.toUtf8() + "\r\n"
|
|
||||||
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
|
|
||||||
"ST:upnp:rootdevice\r\n"
|
|
||||||
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
|
|
||||||
"\r\n");
|
|
||||||
|
|
||||||
sendToMulticast(rootdeviceResponseMessage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +173,7 @@ void UpnpDiscovery::respondToSearchRequest()
|
|||||||
/*! This method will be called to send the SSDP message \a data to the UPnP multicast.*/
|
/*! This method will be called to send the SSDP message \a data to the UPnP multicast.*/
|
||||||
void UpnpDiscovery::sendToMulticast(const QByteArray &data)
|
void UpnpDiscovery::sendToMulticast(const QByteArray &data)
|
||||||
{
|
{
|
||||||
qCDebug(dcHardware) << "sending to multicast\n" << data;
|
//qCDebug(dcHardware) << "sending to multicast\n" << data;
|
||||||
writeDatagram(data, m_host, m_port);
|
writeDatagram(data, m_host, m_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,19 +185,20 @@ void UpnpDiscovery::error(QAbstractSocket::SocketError error)
|
|||||||
void UpnpDiscovery::readData()
|
void UpnpDiscovery::readData()
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
quint16 port;
|
||||||
QHostAddress hostAddress;
|
QHostAddress hostAddress;
|
||||||
QUrl location;
|
QUrl location;
|
||||||
|
|
||||||
// read the answere from the multicast
|
// read the answere from the multicast
|
||||||
while (hasPendingDatagrams()) {
|
while (hasPendingDatagrams()) {
|
||||||
data.resize(pendingDatagramSize());
|
data.resize(pendingDatagramSize());
|
||||||
readDatagram(data.data(), data.size(), &hostAddress);
|
readDatagram(data.data(), data.size(), &hostAddress, &port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.contains("M-SEARCH")) {
|
if (data.contains("M-SEARCH")) {
|
||||||
qCDebug(dcHardware) << "--------------------------------------";
|
qCDebug(dcHardware) << "--------------------------------------";
|
||||||
qCDebug(dcHardware) << "UPnP data:" << hostAddress.toString() << "\n" << data;
|
qCDebug(dcHardware) << QString("UPnP data: %1:%2 \n").arg(hostAddress.toString()).arg(QString::number(port)) << data;
|
||||||
respondToSearchRequest();
|
respondToSearchRequest(hostAddress, port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,16 +338,13 @@ void UpnpDiscovery::notificationTimeout()
|
|||||||
|
|
||||||
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
|
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
|
||||||
QByteArray rootdeviceResponseMessage = QByteArray("NOTIFY * HTTP/1.1\r\n"
|
QByteArray rootdeviceResponseMessage = QByteArray("NOTIFY * HTTP/1.1\r\n"
|
||||||
"CACHE-CONTROL: max-age=1900\r\n"
|
|
||||||
"HOST:239.255.255.250:1900\r\n"
|
"HOST:239.255.255.250:1900\r\n"
|
||||||
|
"Cache-Control: max-age=1900\r\n"
|
||||||
|
"Location: " + locationString.toUtf8() + "\r\n"
|
||||||
"NT:urn:schemas-upnp-org:device:Basic:1\r\n"
|
"NT:urn:schemas-upnp-org:device:Basic:1\r\n"
|
||||||
"NTS:ssdp:alive\r\n"
|
|
||||||
"DATE: " + QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT\r\n"
|
|
||||||
"EXT:\r\n"
|
|
||||||
"CONTENT-LENGTH:0\r\n"
|
|
||||||
"LOCATION: " + locationString.toUtf8() + "\r\n"
|
|
||||||
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
|
|
||||||
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
|
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
|
||||||
|
"NTS: ssdp:alive\r\n"
|
||||||
|
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
|
||||||
"\r\n");
|
"\r\n");
|
||||||
|
|
||||||
sendToMulticast(rootdeviceResponseMessage);
|
sendToMulticast(rootdeviceResponseMessage);
|
||||||
|
|||||||
@ -58,7 +58,7 @@ private:
|
|||||||
QHash<QNetworkReply*,UpnpDeviceDescriptor> m_informationRequestList;
|
QHash<QNetworkReply*,UpnpDeviceDescriptor> m_informationRequestList;
|
||||||
|
|
||||||
void requestDeviceInformation(const QNetworkRequest &networkRequest, const UpnpDeviceDescriptor &upnpDeviceDescriptor);
|
void requestDeviceInformation(const QNetworkRequest &networkRequest, const UpnpDeviceDescriptor &upnpDeviceDescriptor);
|
||||||
void respondToSearchRequest();
|
void respondToSearchRequest(QHostAddress host, int port);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
@ -216,135 +216,6 @@ QString WebServer::fileName(const QString &query)
|
|||||||
return m_webinterfaceDir.path() + fileName;
|
return m_webinterfaceDir.path() + fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray WebServer::createServerXmlDocument(QHostAddress address)
|
|
||||||
{
|
|
||||||
GuhSettings settings(GuhSettings::SettingsRoleDevices);
|
|
||||||
settings.beginGroup("guhd");
|
|
||||||
QByteArray uuid = settings.value("uuid", QVariant()).toByteArray();
|
|
||||||
if (uuid.isEmpty()) {
|
|
||||||
uuid = QUuid::createUuid().toByteArray().replace("{", "").replace("}","");
|
|
||||||
settings.setValue("uuid", uuid);
|
|
||||||
}
|
|
||||||
settings.endGroup();
|
|
||||||
|
|
||||||
|
|
||||||
QByteArray data;
|
|
||||||
QXmlStreamWriter writer(&data);
|
|
||||||
writer.setAutoFormatting(true);
|
|
||||||
writer.writeStartDocument("1.0");
|
|
||||||
writer.writeStartElement("root");
|
|
||||||
writer.writeAttribute("xmlns", "urn:schemas-upnp-org:device-1-0");
|
|
||||||
|
|
||||||
writer.writeStartElement("specVersion");
|
|
||||||
writer.writeTextElement("major", "1");
|
|
||||||
writer.writeTextElement("minor", "1");
|
|
||||||
writer.writeEndElement(); // specVersion
|
|
||||||
|
|
||||||
// if (m_useSsl) {
|
|
||||||
// writer.writeTextElement("URLBase", "https://" + address.toString() + ":" + QString::number(m_port));
|
|
||||||
// } else {
|
|
||||||
// writer.writeTextElement("URLBase", "http://" + address.toString() + ":" + QString::number(m_port));
|
|
||||||
// }
|
|
||||||
writer.writeStartElement("device");
|
|
||||||
writer.writeTextElement("deviceType", "urn:schemas-upnp-org:device:Basic:1");
|
|
||||||
writer.writeTextElement("friendlyName", "guhd");
|
|
||||||
writer.writeTextElement("manufacturer", "ARGE guh");
|
|
||||||
writer.writeTextElement("manufacturerURL", "http://guh.guru");
|
|
||||||
writer.writeTextElement("modelDescription", "Home automation server");
|
|
||||||
writer.writeTextElement("modelName", "guhd");
|
|
||||||
writer.writeTextElement("modelNumber", GUH_VERSION_STRING);
|
|
||||||
writer.writeTextElement("modelURL", "http://guh.io"); // (optional)
|
|
||||||
writer.writeTextElement("UDN", "uuid:" + uuid);
|
|
||||||
if (m_useSsl) {
|
|
||||||
writer.writeTextElement("presentationURL", "https://" + address.toString() + ":" + QString::number(m_port));
|
|
||||||
} else {
|
|
||||||
writer.writeTextElement("presentationURL", "http://" + address.toString() + ":" + QString::number(m_port));
|
|
||||||
}
|
|
||||||
|
|
||||||
//writer.writeTextElement("presentationURL", "/");
|
|
||||||
|
|
||||||
writer.writeStartElement("iconList");
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "8");
|
|
||||||
writer.writeTextElement("height", "8");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-8x8.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "16");
|
|
||||||
writer.writeTextElement("height", "16");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-16x16.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "22");
|
|
||||||
writer.writeTextElement("height", "22");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-22x22.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "32");
|
|
||||||
writer.writeTextElement("height", "32");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-32x32.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "48");
|
|
||||||
writer.writeTextElement("height", "48");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-48x48.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "64");
|
|
||||||
writer.writeTextElement("height", "64");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-64x64.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "128");
|
|
||||||
writer.writeTextElement("height", "128");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-128x128.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "256");
|
|
||||||
writer.writeTextElement("height", "256");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-256x256.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeStartElement("icon");
|
|
||||||
writer.writeTextElement("mimetype", "image/png");
|
|
||||||
writer.writeTextElement("width", "512");
|
|
||||||
writer.writeTextElement("height", "512");
|
|
||||||
writer.writeTextElement("depth", "24");
|
|
||||||
writer.writeTextElement("url", "/icons/guh-logo-512x512.png");
|
|
||||||
writer.writeEndElement(); // icon
|
|
||||||
|
|
||||||
writer.writeEndElement(); // iconList
|
|
||||||
|
|
||||||
writer.writeEndElement(); // device
|
|
||||||
writer.writeEndElement(); // root
|
|
||||||
writer.writeEndDocument();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpReply *WebServer::processIconRequest(const QString &fileName)
|
HttpReply *WebServer::processIconRequest(const QString &fileName)
|
||||||
{
|
{
|
||||||
if (!fileName.endsWith(".png"))
|
if (!fileName.endsWith(".png"))
|
||||||
@ -479,8 +350,8 @@ void WebServer::readClient()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check HTTP version
|
// check HTTP version
|
||||||
if (request.httpVersion() != "HTTP/1.1") {
|
if (request.httpVersion() != "HTTP/1.1" && request.httpVersion() != "HTTP/1.0") {
|
||||||
qCWarning(dcWebServer) << "HTTP version is not supported.";
|
qCWarning(dcWebServer) << "HTTP version is not supported." << request.httpVersion();
|
||||||
HttpReply *reply = RestResource::createErrorReply(HttpReply::HttpVersionNotSupported);
|
HttpReply *reply = RestResource::createErrorReply(HttpReply::HttpVersionNotSupported);
|
||||||
reply->setClientId(clientId);
|
reply->setClientId(clientId);
|
||||||
sendHttpReply(reply);
|
sendHttpReply(reply);
|
||||||
@ -676,6 +547,132 @@ bool WebServer::stopServer()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray WebServer::createServerXmlDocument(QHostAddress address)
|
||||||
|
{
|
||||||
|
GuhSettings settings(GuhSettings::SettingsRoleDevices);
|
||||||
|
settings.beginGroup("guhd");
|
||||||
|
QByteArray uuid = settings.value("uuid", QVariant()).toByteArray();
|
||||||
|
if (uuid.isEmpty()) {
|
||||||
|
uuid = QUuid::createUuid().toByteArray().replace("{", "").replace("}","");
|
||||||
|
settings.setValue("uuid", uuid);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
QXmlStreamWriter writer(&data);
|
||||||
|
writer.setAutoFormatting(true);
|
||||||
|
writer.writeStartDocument("1.0");
|
||||||
|
writer.writeStartElement("root");
|
||||||
|
writer.writeAttribute("xmlns", "urn:schemas-upnp-org:device-1-0");
|
||||||
|
|
||||||
|
writer.writeStartElement("specVersion");
|
||||||
|
writer.writeTextElement("major", "1");
|
||||||
|
writer.writeTextElement("minor", "1");
|
||||||
|
writer.writeEndElement(); // specVersion
|
||||||
|
|
||||||
|
if (m_useSsl) {
|
||||||
|
writer.writeTextElement("URLBase", "https://" + address.toString() + ":" + QString::number(m_port));
|
||||||
|
} else {
|
||||||
|
writer.writeTextElement("URLBase", "http://" + address.toString() + ":" + QString::number(m_port));
|
||||||
|
}
|
||||||
|
writer.writeTextElement("presentationURL", "/");
|
||||||
|
|
||||||
|
writer.writeStartElement("device");
|
||||||
|
writer.writeTextElement("deviceType", "urn:schemas-upnp-org:device:Basic:1");
|
||||||
|
writer.writeTextElement("friendlyName", "guhd");
|
||||||
|
writer.writeTextElement("manufacturer", "guh");
|
||||||
|
writer.writeTextElement("manufacturerURL", "http://guh.guru");
|
||||||
|
writer.writeTextElement("modelDescription", "Home automation server");
|
||||||
|
writer.writeTextElement("modelName", "guhd");
|
||||||
|
writer.writeTextElement("modelNumber", GUH_VERSION_STRING);
|
||||||
|
writer.writeTextElement("modelURL", "http://guh.io"); // (optional)
|
||||||
|
writer.writeTextElement("UDN", "uuid:" + uuid);
|
||||||
|
|
||||||
|
writer.writeStartElement("iconList");
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "8");
|
||||||
|
writer.writeTextElement("height", "8");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-8x8.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "16");
|
||||||
|
writer.writeTextElement("height", "16");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-16x16.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "22");
|
||||||
|
writer.writeTextElement("height", "22");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-22x22.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "32");
|
||||||
|
writer.writeTextElement("height", "32");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-32x32.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "48");
|
||||||
|
writer.writeTextElement("height", "48");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-48x48.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "64");
|
||||||
|
writer.writeTextElement("height", "64");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-64x64.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "128");
|
||||||
|
writer.writeTextElement("height", "128");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-128x128.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "256");
|
||||||
|
writer.writeTextElement("height", "256");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-256x256.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeStartElement("icon");
|
||||||
|
writer.writeTextElement("mimetype", "image/png");
|
||||||
|
writer.writeTextElement("width", "512");
|
||||||
|
writer.writeTextElement("height", "512");
|
||||||
|
writer.writeTextElement("depth", "24");
|
||||||
|
writer.writeTextElement("url", "/icons/guh-logo-512x512.png");
|
||||||
|
writer.writeEndElement(); // icon
|
||||||
|
|
||||||
|
writer.writeEndElement(); // iconList
|
||||||
|
|
||||||
|
writer.writeEndElement(); // device
|
||||||
|
writer.writeEndElement(); // root
|
||||||
|
writer.writeEndDocument();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WebServerClient::WebServerClient(const QHostAddress &address, QObject *parent):
|
WebServerClient::WebServerClient(const QHostAddress &address, QObject *parent):
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_address(address)
|
m_address(address)
|
||||||
|
|||||||
Reference in New Issue
Block a user