File indexing completed on 2024-04-28 04:49:05

0001 /*
0002    SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
0003 
0004    SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 #include "upnpdiscoverallmusic.h"
0008 
0009 #include "elisautils.h"
0010 
0011 #include "config-upnp-qt.h"
0012 
0013 #include "upnpLogging.h"
0014 
0015 #include <QNetworkAccessManager>
0016 
0017 #include "upnpdevicedescription.h"
0018 #include "upnpdiscoveryresult.h"
0019 #include "upnpservicedescription.h"
0020 #include "upnpdevicedescriptionparser.h"
0021 #include "upnpcontrolcontentdirectory.h"
0022 #include "didlparser.h"
0023 
0024 #include <QList>
0025 #include <QHash>
0026 #include <QString>
0027 
0028 #include <QLoggingCategory>
0029 
0030 class UpnpDiscoverAllMusicPrivate
0031 {
0032 public:
0033 
0034     QHash<QString, UpnpDiscoveryResult> mAllDeviceDiscoveryResults;
0035 
0036     QHash<QString, UpnpDeviceDescription> mAllHostsDescription;
0037 
0038     QHash<QString, QSharedPointer<UpnpDeviceDescriptionParser>> mDeviceDescriptionParsers;
0039 
0040     QList<QString> mAllHostsUUID;
0041 
0042     QNetworkAccessManager mNetworkAccess;
0043 
0044     DataTypes::ListNetworkServiceDataType mAllServices;
0045 
0046 };
0047 
0048 UpnpDiscoverAllMusic::UpnpDiscoverAllMusic(QObject *parent) : QObject(parent), d(new UpnpDiscoverAllMusicPrivate)
0049 {
0050 }
0051 
0052 const DataTypes::ListNetworkServiceDataType &UpnpDiscoverAllMusic::existingMediaServers() const
0053 {
0054     return d->mAllServices;
0055 }
0056 
0057 const UpnpDeviceDescription &UpnpDiscoverAllMusic::deviceDescriptionByUdn(const QString &udn) const
0058 {
0059     qDebug() << "UpnpDiscoverAllMusic::deviceDescriptionByUdn" << d->mAllHostsDescription.keys() << udn;
0060     return d->mAllHostsDescription[udn];
0061 }
0062 
0063 UpnpDiscoverAllMusic::~UpnpDiscoverAllMusic()
0064 = default;
0065 
0066 void UpnpDiscoverAllMusic::newDevice(const UpnpDiscoveryResult &newService)
0067 {
0068     qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::newDevice" << newService;
0069 
0070     const QString &deviceUuid = newService.usn().mid(5, 36);
0071     if (!d->mAllDeviceDiscoveryResults.contains(deviceUuid)) {
0072         qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::newDevice" << "new uuid" << deviceUuid;
0073         d->mAllDeviceDiscoveryResults[deviceUuid] = newService;
0074 
0075         const QString &decodedUdn(deviceUuid.right(36));
0076 
0077         d->mAllHostsUUID.push_back(decodedUdn);
0078         d->mAllHostsDescription[decodedUdn].setUDN(decodedUdn);
0079 
0080         d->mDeviceDescriptionParsers[decodedUdn].reset(new UpnpDeviceDescriptionParser(&d->mNetworkAccess, d->mAllHostsDescription[decodedUdn]));
0081 
0082         connect(&d->mNetworkAccess, &QNetworkAccessManager::finished, d->mDeviceDescriptionParsers[decodedUdn].data(), &UpnpDeviceDescriptionParser::finishedDownload);
0083         connect(d->mDeviceDescriptionParsers[decodedUdn].data(), &UpnpDeviceDescriptionParser::descriptionParsed, this, &UpnpDiscoverAllMusic::descriptionParsed);
0084 
0085         d->mDeviceDescriptionParsers[decodedUdn]->downloadDeviceDescription(QUrl(newService.location()));
0086     } else {
0087         qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::newDevice" << "existing uuid" << deviceUuid;
0088     }
0089 }
0090 
0091 void UpnpDiscoverAllMusic::removedDevice(const UpnpDiscoveryResult &removedService)
0092 {
0093     qCInfo(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::removedDevice" << removedService;
0094 
0095     const QString &deviceUuid = removedService.usn().mid(5, 36);
0096     if (!d->mAllDeviceDiscoveryResults.contains(deviceUuid)) {
0097         qCInfo(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::removedDevice" << removedService << "not found";
0098         return;
0099     }
0100 
0101     auto deviceUuidOnly = deviceUuid.right(36);
0102     std::remove_if(d->mAllServices.begin(), d->mAllServices.end(), [this, deviceUuidOnly](const auto &data) {
0103         return data.title() == d->mAllHostsDescription[deviceUuidOnly].friendlyName();
0104     });
0105 
0106     d->mAllDeviceDiscoveryResults.remove(deviceUuid);
0107 
0108     qCInfo(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::removedDevice" << "number of services" << d->mAllServices.count();
0109 
0110     qCInfo(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::removedDevice" << d->mAllHostsDescription[deviceUuid].friendlyName();
0111     Q_EMIT removedUpnpContentDirectoryService(d->mAllHostsDescription[deviceUuid].friendlyName());
0112 }
0113 
0114 void UpnpDiscoverAllMusic::networkChanged()
0115 {
0116     for (const auto &oneService : std::as_const(d->mAllServices)) {
0117         Q_EMIT removedUpnpContentDirectoryService(oneService.title());
0118     }
0119 
0120     d->mAllServices.clear();
0121     d->mAllHostsUUID.clear();
0122     d->mAllHostsDescription.clear();
0123     d->mDeviceDescriptionParsers.clear();
0124     d->mAllDeviceDiscoveryResults.clear();
0125 
0126     qCInfo(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::networkChanged"
0127                               << "searchAllMediaServers";
0128     Q_EMIT searchAllMediaServers(1);
0129 }
0130 
0131 void UpnpDiscoverAllMusic::deviceDescriptionChanged(const QString &uuid)
0132 {
0133     Q_UNUSED(uuid)
0134 }
0135 
0136 void UpnpDiscoverAllMusic::descriptionParsed(const QString &UDN)
0137 {
0138     qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::descriptionParsed" << UDN;
0139 
0140     QString uuid = UDN.mid(5);
0141 
0142     d->mDeviceDescriptionParsers.remove(uuid);
0143 
0144     int deviceIndex = d->mAllHostsUUID.indexOf(uuid);
0145 
0146     qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::descriptionParsed" << d->mAllHostsUUID;
0147     qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::descriptionParsed" << uuid;
0148     qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::descriptionParsed" << deviceIndex;
0149 
0150     if (deviceIndex == -1) {
0151         qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::descriptionParsed" << d->mAllHostsUUID;
0152         return;
0153     }
0154 
0155     qCDebug(orgKdeElisaUpnp()) << "UpnpDiscoverAllMusic::descriptionParsed" << d->mAllHostsDescription[uuid].friendlyName();
0156 
0157     d->mAllServices.push_back({{DataTypes::ElementTypeRole, QVariant::fromValue(ElisaUtils::UpnpMediaServer)},
0158                                {DataTypes::TitleRole, d->mAllHostsDescription[uuid].friendlyName()},
0159                                {DataTypes::UUIDRole, uuid},});
0160 
0161     Q_EMIT newUpnpContentDirectoryService(d->mAllHostsDescription[uuid].friendlyName(), uuid);
0162 }
0163 
0164 #include "moc_upnpdiscoverallmusic.cpp"