MythTV  master
upnpscanner.h
Go to the documentation of this file.
1 #ifndef UPNPSCANNER_H
2 #define UPNPSCANNER_H
3 
4 #include <utility>
5 
6 // Qt headers
7 #include <QDomDocument>
8 #include <QMutex>
9 #include <QNetworkAccessManager>
10 #include <QNetworkReply>
11 #include <QNetworkRequest>
12 #include <QTimer>
13 
14 // MythTV headers
15 #include "upnpsubscription.h"
16 #include "mthread.h"
17 #include "upnpexp.h"
19 
20 class MediaServer;
21 class UPNPSubscription;
22 class meta_dir_node;
23 
25 {
26  public:
27  MediaServerItem() = default;
28  MediaServerItem(QString id, QString parent,
29  QString name, QString url)
30  : m_id(std::move(id)), m_parentid(std::move(parent)),
31  m_name(std::move(name)), m_url(std::move(url)) { }
32  QString NextUnbrowsed(void);
33  MediaServerItem* Find(QString &id);
34  bool Add(MediaServerItem &item);
35  void Reset(void);
36 
37  QString m_id;
38  QString m_parentid;
39  QString m_name;
40  QString m_url;
41  bool m_scanned {false};
42  QMap<QString, MediaServerItem> m_children;
43 };
44 
45 class UPNPScanner : public QObject
46 {
47  Q_OBJECT
48 
49  public:
50  ~UPNPScanner() override;
51 
52  static void Enable(bool enable, UPNPSubscription *sub = nullptr);
53  static UPNPScanner* Instance(UPNPSubscription *sub = nullptr);
54 
55  void StartFullScan(void);
57  meta_dir_node *node);
59  meta_dir_node *node);
60  bool GetMetadata(QVariant &data);
61  QMap<QString,QString> ServerList(void);
62 
63  protected:
64  void customEvent(QEvent *event) override; // QObject
65  void timerEvent(QTimerEvent * event) override; // QObject
66 
67  private slots:
68  void Start();
69  void Stop(void);
70  void Update(void);
71  void CheckStatus(void);
72  void replyFinished(QNetworkReply *reply);
73 
74  private:
76  : m_subscription(sub) {}
77  void ScheduleUpdate(void);
78  void CheckFailure(const QUrl &url);
79  void Debug(void);
80  void BrowseNextContainer(void);
81  void SendBrowseRequest(const QUrl &url, const QString &objectid);
82  void AddServer(const QString &usn, const QString &url);
83  void RemoveServer(const QString &usn);
84  void ScheduleRenewal(const QString &usn, int timeout);
85 
86  // xml parsing of browse requests
87  void ParseBrowse(const QUrl &url, QNetworkReply *reply);
88  void FindItems(const QDomNode &n, MediaServerItem &content,
89  bool &resetparent);
90  QDomDocument* FindResult(const QDomNode &n, uint &num,
91  uint &total, uint &updateid);
92 
93  // xml parsing of device description
94  bool ParseDescription(const QUrl &url, QNetworkReply *reply);
95  static void ParseDevice(QDomElement &element, QString &controlURL,
96  QString &eventURL, QString &friendlyName);
97  static void ParseServiceList(QDomElement &element, QString &controlURL,
98  QString &eventURL);
99  static void ParseService(QDomElement &element, QString &controlURL,
100  QString &eventURL);
101 
102  // convert MediaServerItems to video metadata
103  void GetServerContent(QString &usn, MediaServerItem *content,
105  meta_dir_node *node);
106 
107  private:
109  static bool gUPNPScannerEnabled;
111  static QMutex* gUPNPScannerLock;
112 
114  QMutex m_lock {QMutex::Recursive};
115  QHash<QString,MediaServer*> m_servers;
116  QNetworkAccessManager *m_network {nullptr};
117  // TODO Move to QMultiHash when we move to Qt >=4.7
118  // QHash(QUrl) unsupported on < 4.7
119  QMultiMap<QUrl, QNetworkReply*> m_descriptionRequests;
120  QMultiMap<QUrl, QNetworkReply*> m_browseRequests;
121 
122  QTimer *m_updateTimer {nullptr};
123  QTimer *m_watchdogTimer {nullptr};
124 
125  QString m_masterHost;
126  int m_masterPort {0};
127 
128  bool m_scanComplete {false};
129  bool m_fullscan {false};
130 };
131 
132 #endif // UPNPSCANNER_H
QMultiMap< QUrl, QNetworkReply * > m_browseRequests
Definition: upnpscanner.h:120
void CheckStatus(void)
Removes media servers that can no longer be found in the SSDP cache.
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
void BrowseNextContainer(void)
For each known media server, find the next container which needs to be browsed and trigger sending of...
QHash< QString, MediaServer * > m_servers
Definition: upnpscanner.h:115
unsigned int slots[4]
Definition: element.c:38
UPnPScanner detects UPnP Media Servers available on the local network (via the UPnP SSDP cache),...
Definition: upnpscanner.h:45
static UPNPScanner * gUPNPScanner
Definition: upnpscanner.h:108
QString m_masterHost
Definition: upnpscanner.h:125
void ScheduleUpdate(void)
bool Add(MediaServerItem &item)
Definition: upnpscanner.cpp:59
void GetMetadata(VideoMetadataListManager::metadata_list *list, meta_dir_node *node)
Fill the given metadata_list and meta_dir_node with the metadata of content retrieved from known medi...
QMultiMap< QUrl, QNetworkReply * > m_descriptionRequests
Definition: upnpscanner.h:119
void GetInitialMetadata(VideoMetadataListManager::metadata_list *list, meta_dir_node *node)
Fill the given metadata_list and meta_dir_node with the root media server metadata (i....
void customEvent(QEvent *event) override
Processes subscription and SSDP cache update events.
A simple wrapper containing details about a UPnP Media Server.
Definition: mediaserver.h:32
void StartFullScan(void)
Instruct the UPNPScanner thread to start a full scan of metadata from known media servers.
bool m_fullscan
Definition: upnpscanner.h:129
UPNPScanner(UPNPSubscription *sub)
Definition: upnpscanner.h:75
QString m_name
Definition: upnpscanner.h:39
QNetworkAccessManager * m_network
Definition: upnpscanner.h:116
void Stop(void)
Stops scanning.
QMap< QString, MediaServerItem > m_children
Definition: upnpscanner.h:42
QDomDocument * FindResult(const QDomNode &n, uint &num, uint &total, uint &updateid)
MediaServerItem * Find(QString &id)
Definition: upnpscanner.cpp:42
void RemoveServer(const QString &usn)
void AddServer(const QString &usn, const QString &url)
Adds the server identified by usn and reachable via url to the list of known media servers and schedu...
UPNPSubscription * m_subscription
Definition: upnpscanner.h:113
void GetServerContent(QString &usn, MediaServerItem *content, VideoMetadataListManager::metadata_list *list, meta_dir_node *node)
Recursively search a MediaServerItem for video metadata and add it to the metadata_list and meta_dir_...
QTimer * m_updateTimer
Definition: upnpscanner.h:122
QMap< QString, QString > ServerList(void)
Returns a list of valid Media Servers discovered on the network.
void Reset(void)
Definition: upnpscanner.cpp:69
unsigned int uint
Definition: compat.h:140
bool m_scanComplete
Definition: upnpscanner.h:128
static void ParseDevice(QDomElement &element, QString &controlURL, QString &eventURL, QString &friendlyName)
void replyFinished(QNetworkReply *reply)
Validates network responses against known requests and parses expected responses for the required dat...
~UPNPScanner() override
void ParseBrowse(const QUrl &url, QNetworkReply *reply)
Parse the XML returned from Content Directory Service browse request.
QTimer * m_watchdogTimer
Definition: upnpscanner.h:123
void Start()
Initialises the scanner, hooks it up to the subscription service and the SSDP cache and starts scanni...
MediaServerItem(QString id, QString parent, QString name, QString url)
Definition: upnpscanner.h:28
void ScheduleRenewal(const QString &usn, int timeout)
Creates a QTimer to trigger a subscription renewal for a given media server.
static MThread * gUPNPScannerThread
Definition: upnpscanner.h:110
void SendBrowseRequest(const QUrl &url, const QString &objectid)
Formulates and sends a ContentDirectory Service Browse Request to the given control URL,...
bool ParseDescription(const QUrl &url, QNetworkReply *reply)
Parse the device description XML return my a media server.
static bool gUPNPScannerEnabled
Definition: upnpscanner.h:109
void CheckFailure(const QUrl &url)
Updates the logs for failed server connections.
static void ParseService(QDomElement &element, QString &controlURL, QString &eventURL)
QString m_parentid
Definition: upnpscanner.h:38
QString NextUnbrowsed(void)
Definition: upnpscanner.cpp:19
static void Enable(bool enable, UPNPSubscription *sub=nullptr)
Creates or destroys the global UPNPScanner instance.
int m_masterPort
Definition: upnpscanner.h:126
void Update(void)
Iterates through the list of known servers and initialises a connection by requesting the device desc...
MediaServerItem()=default
QMutex m_lock
Definition: upnpscanner.h:114
void timerEvent(QTimerEvent *event) override
Handles subscription renewal timer events.
static UPNPScanner * Instance(UPNPSubscription *sub=nullptr)
Returns the global UPNPScanner instance if it has been enabled or nullptr if UPNPScanner is currently...
void Debug(void)
static void ParseServiceList(QDomElement &element, QString &controlURL, QString &eventURL)
static QMutex * gUPNPScannerLock
Definition: upnpscanner.h:111
std::list< VideoMetadataPtr > metadata_list
void FindItems(const QDomNode &n, MediaServerItem &content, bool &resetparent)