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"