File indexing completed on 2024-04-28 04:44:20
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 "upnpabstractdevice.h" 0008 0009 #include "upnplogging.h" 0010 0011 #include "upnpabstractservice.h" 0012 #include "upnpssdpengine.h" 0013 0014 #include "upnpdevicedescription.h" 0015 #include "upnpservicedescription.h" 0016 0017 #include <QBuffer> 0018 #include <QIODevice> 0019 #include <QPointer> 0020 #include <QSharedPointer> 0021 #include <QXmlStreamWriter> 0022 0023 #include <QLoggingCategory> 0024 0025 class UpnpAbstractDevicePrivate 0026 { 0027 public: 0028 UpnpDeviceDescription mDevice; 0029 0030 std::unique_ptr<QIODevice> mXmlDescription; 0031 }; 0032 0033 UpnpAbstractDevice::UpnpAbstractDevice(QObject *parent) 0034 : QObject(parent) 0035 , d(std::make_unique<UpnpAbstractDevicePrivate>()) 0036 { 0037 } 0038 0039 UpnpAbstractDevice::~UpnpAbstractDevice() = default; 0040 0041 UpnpServiceDescription UpnpAbstractDevice::serviceDescriptionById(const QString &serviceId) const 0042 { 0043 auto result = UpnpServiceDescription {}; 0044 const auto &allServices = d->mDevice.services(); 0045 0046 for (const auto &service : allServices) { 0047 if (service.serviceId() == serviceId) { 0048 result = service; 0049 return result; 0050 } 0051 } 0052 return result; 0053 } 0054 0055 UpnpServiceDescription UpnpAbstractDevice::serviceDescriptionByIndex(int serviceIndex) const 0056 { 0057 if (serviceIndex < 0 || serviceIndex > d->mDevice.services().size() - 1) { 0058 return UpnpServiceDescription {}; 0059 } 0060 0061 return d->mDevice.services()[serviceIndex]; 0062 } 0063 0064 const QList<UpnpServiceDescription> &UpnpAbstractDevice::services() const 0065 { 0066 return d->mDevice.services(); 0067 } 0068 0069 QVector<QString> UpnpAbstractDevice::servicesName() const 0070 { 0071 QVector<QString> result; 0072 const auto &allServices = d->mDevice.services(); 0073 0074 for (const auto &itService : allServices) { 0075 result.push_back(itService.serviceType()); 0076 } 0077 0078 return result; 0079 } 0080 0081 void UpnpAbstractDevice::setDescription(UpnpDeviceDescription value) 0082 { 0083 d->mDevice = std::move(value); 0084 Q_EMIT descriptionChanged(); 0085 } 0086 0087 UpnpDeviceDescription &UpnpAbstractDevice::description() 0088 { 0089 return d->mDevice; 0090 } 0091 0092 const UpnpDeviceDescription &UpnpAbstractDevice::description() const 0093 { 0094 return d->mDevice; 0095 } 0096 0097 std::unique_ptr<QIODevice> UpnpAbstractDevice::buildAndGetXmlDescription() 0098 { 0099 if (!d->mXmlDescription) { 0100 QPointer<QBuffer> newDescription(new QBuffer); 0101 0102 newDescription->open(QIODevice::ReadWrite); 0103 0104 QXmlStreamWriter insertStream(newDescription.data()); 0105 insertStream.setAutoFormatting(true); 0106 0107 insertStream.writeStartDocument(); 0108 insertStream.writeStartElement(QStringLiteral("root")); 0109 insertStream.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("urn:schemas-upnp-org:device-1-0")); 0110 insertStream.writeStartElement(QStringLiteral("specVersion")); 0111 insertStream.writeTextElement(QStringLiteral("major"), QStringLiteral("1")); 0112 insertStream.writeTextElement(QStringLiteral("minor"), QStringLiteral("0")); 0113 insertStream.writeEndElement(); 0114 insertStream.writeTextElement(QStringLiteral("URLBase"), d->mDevice.URLBase()); 0115 insertStream.writeStartElement(QStringLiteral("device")); 0116 insertStream.writeTextElement(QStringLiteral("deviceType"), d->mDevice.deviceType()); 0117 insertStream.writeTextElement(QStringLiteral("friendlyName"), d->mDevice.friendlyName()); 0118 insertStream.writeTextElement(QStringLiteral("manufacturer"), d->mDevice.manufacturer()); 0119 insertStream.writeTextElement(QStringLiteral("manufacterURL"), d->mDevice.manufacturerURL().toString()); 0120 insertStream.writeTextElement(QStringLiteral("modelDescription"), d->mDevice.modelDescription()); 0121 insertStream.writeTextElement(QStringLiteral("modelName"), d->mDevice.modelName()); 0122 insertStream.writeTextElement(QStringLiteral("modelNumber"), d->mDevice.modelNumber()); 0123 insertStream.writeTextElement(QStringLiteral("modelURL"), d->mDevice.modelURL().toString()); 0124 insertStream.writeTextElement(QStringLiteral("serialNumber"), d->mDevice.serialNumber()); 0125 insertStream.writeTextElement(QStringLiteral("UDN"), QStringLiteral("uuid:") + d->mDevice.UDN()); 0126 insertStream.writeTextElement(QStringLiteral("UPC"), d->mDevice.UPC()); 0127 0128 if (!d->mDevice.services().empty()) { 0129 insertStream.writeStartElement(QStringLiteral("serviceList")); 0130 const auto &allServices = d->mDevice.services(); 0131 0132 for (const auto &itService : allServices) { 0133 insertStream.writeStartElement(QStringLiteral("service")); 0134 insertStream.writeTextElement(QStringLiteral("serviceType"), itService.serviceType()); 0135 insertStream.writeTextElement(QStringLiteral("serviceId"), itService.serviceId()); 0136 insertStream.writeTextElement(QStringLiteral("SCPDURL"), itService.SCPDURL().toString()); 0137 insertStream.writeTextElement(QStringLiteral("controlURL"), itService.controlURL().toString()); 0138 insertStream.writeTextElement(QStringLiteral("eventSubURL"), itService.eventURL().toString()); 0139 insertStream.writeEndElement(); 0140 } 0141 insertStream.writeEndElement(); 0142 } 0143 0144 insertStream.writeEndElement(); 0145 insertStream.writeEndElement(); 0146 insertStream.writeEndDocument(); 0147 0148 d->mXmlDescription .reset( newDescription); 0149 } 0150 0151 d->mXmlDescription->seek(0); 0152 0153 return std::move(d->mXmlDescription); 0154 } 0155 0156 void UpnpAbstractDevice::newSearchQuery(UpnpSsdpEngine *engine, const UpnpSearchQuery &searchQuery) 0157 { 0158 qCDebug(orgKdeUpnpLibQtUpnp()) << "UpnpAbstractDevice::newSearchQuery" 0159 << "search for" << searchQuery.mSearchTarget; 0160 switch (searchQuery.mSearchTargetType) { 0161 case SearchTargetType::All: 0162 qCDebug(orgKdeUpnpLibQtUpnp()) << "UpnpAbstractDevice::newSearchQuery" 0163 << "publish"; 0164 engine->publishDevice(this); 0165 break; 0166 case SearchTargetType::RootDevice: 0167 case SearchTargetType::DeviceUUID: 0168 case SearchTargetType::DeviceType: 0169 case SearchTargetType::ServiceType: 0170 break; 0171 } 0172 } 0173 0174 int UpnpAbstractDevice::addService(const UpnpServiceDescription &newService) 0175 { 0176 d->mDevice.services().push_back(newService); 0177 return d->mDevice.services().count() - 1; 0178 } 0179 0180 #include "moc_upnpabstractdevice.cpp"