File indexing completed on 2024-05-12 08:45:53
0001 /* 0002 SPDX-FileCopyrightText: 2015 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "upnpservicedescriptionparser.h" 0008 0009 #include "upnplogging.h" 0010 0011 #include "upnpactiondescription.h" 0012 #include "upnpservicedescription.h" 0013 0014 #include <QNetworkAccessManager> 0015 #include <QNetworkReply> 0016 #include <QNetworkRequest> 0017 0018 #include <QDomDocument> 0019 0020 #include <QLoggingCategory> 0021 0022 class UpnpServiceDescriptionParserPrivate 0023 { 0024 public: 0025 UpnpServiceDescriptionParserPrivate(QNetworkAccessManager *aNetworkAccess, UpnpServiceDescription &serviceDescription) 0026 : mNetworkAccess(aNetworkAccess) 0027 , mServiceDescription(serviceDescription) 0028 , mServiceURL() 0029 { 0030 } 0031 0032 QNetworkAccessManager *mNetworkAccess; 0033 0034 UpnpServiceDescription &mServiceDescription; 0035 0036 QUrl mServiceURL; 0037 }; 0038 0039 UpnpServiceDescriptionParser::UpnpServiceDescriptionParser(QNetworkAccessManager *aNetworkAccess, UpnpServiceDescription &deviceDescription, QObject *parent) 0040 : QObject(parent) 0041 , d(std::make_unique<UpnpServiceDescriptionParserPrivate>(aNetworkAccess, deviceDescription)) 0042 { 0043 } 0044 0045 UpnpServiceDescriptionParser::~UpnpServiceDescriptionParser() = default; 0046 0047 void UpnpServiceDescriptionParser::downloadServiceDescription(const QUrl &serviceUrl) 0048 { 0049 d->mServiceURL = serviceUrl; 0050 d->mNetworkAccess->get(QNetworkRequest(serviceUrl)); 0051 } 0052 0053 void UpnpServiceDescriptionParser::finishedDownload(QNetworkReply *reply) 0054 { 0055 if (reply->url() == d->mServiceURL) { 0056 if (reply->isFinished() && reply->error() == QNetworkReply::NoError) { 0057 parseServiceDescription(reply); 0058 } else if (reply->isFinished()) { 0059 qCDebug(orgKdeUpnpLibQtUpnp()) << "UpnpAbstractServiceDescription::finishedDownload" 0060 << "error"; 0061 } 0062 } 0063 } 0064 0065 void UpnpServiceDescriptionParser::parseServiceDescription(QIODevice *serviceDescriptionContent) 0066 { 0067 QDomDocument serviceDescriptionDocument; 0068 serviceDescriptionDocument.setContent(serviceDescriptionContent); 0069 0070 const QDomElement &scpdRoot = serviceDescriptionDocument.documentElement(); 0071 0072 const QDomElement &actionListRoot = scpdRoot.firstChildElement(QStringLiteral("actionList")); 0073 QDomNode currentChild = actionListRoot.firstChild(); 0074 while (!currentChild.isNull()) { 0075 const QDomNode &nameNode = currentChild.firstChildElement(QStringLiteral("name")); 0076 0077 QString actionName; 0078 if (!nameNode.isNull()) { 0079 actionName = nameNode.toElement().text(); 0080 } 0081 0082 UpnpActionDescription newAction; 0083 0084 newAction.mName = actionName; 0085 0086 const QDomNode &argumentListNode = currentChild.firstChildElement(QStringLiteral("argumentList")); 0087 QDomNode argumentNode = argumentListNode.firstChild(); 0088 while (!argumentNode.isNull()) { 0089 const QDomNode &argumentNameNode = argumentNode.firstChildElement(QStringLiteral("name")); 0090 const QDomNode &argumentDirectionNode = argumentNode.firstChildElement(QStringLiteral("direction")); 0091 const QDomNode &argumentRetvalNode = argumentNode.firstChildElement(QStringLiteral("retval")); 0092 const QDomNode &argumentRelatedStateVariableNode = argumentNode.firstChildElement(QStringLiteral("relatedStateVariable")); 0093 0094 UpnpActionArgumentDescription newArgument; 0095 newArgument.mName = argumentNameNode.toElement().text(); 0096 newArgument.mDirection = (argumentDirectionNode.toElement().text() == QStringLiteral("in") ? UpnpArgumentDirection::In : UpnpArgumentDirection::Out); 0097 newArgument.mIsReturnValue = !argumentRetvalNode.isNull(); 0098 newArgument.mRelatedStateVariable = argumentRelatedStateVariableNode.toElement().text(); 0099 0100 newAction.mArguments.push_back(newArgument); 0101 0102 d->mServiceDescription.addAction(newAction); 0103 0104 argumentNode = argumentNode.nextSibling(); 0105 } 0106 0107 currentChild = currentChild.nextSibling(); 0108 } 0109 0110 #if 0 0111 const QDomElement &serviceStateTableRoot = scpdRoot.firstChildElement(QStringLiteral("serviceStateTable")); 0112 currentChild = serviceStateTableRoot.firstChild(); 0113 while (!currentChild.isNull()) { 0114 const QDomNode &nameNode = currentChild.firstChildElement(QStringLiteral("name")); 0115 if (!nameNode.isNull()) { 0116 qCDebug(orgKdeUpnpLibQtUpnp()) << "state variable name" << nameNode.toElement().text(); 0117 } 0118 0119 currentChild = currentChild.nextSibling(); 0120 } 0121 #endif 0122 0123 Q_EMIT descriptionParsed(d->mServiceDescription.serviceId()); 0124 } 0125 0126 #include "moc_upnpservicedescriptionparser.cpp"