00001 #ifndef UPNPSCANNER_H
00002 #define UPNPSCANNER_H
00003
00004 #include <QNetworkAccessManager>
00005 #include <QNetworkRequest>
00006 #include <QNetworkReply>
00007 #include <QDomDocument>
00008 #include <QMutex>
00009 #include <QTimer>
00010
00011 #include "upnpsubscription.h"
00012 #include "mthread.h"
00013 #include "upnpexp.h"
00014
00015 #include "videometadatalistmanager.h"
00016
00017 class MediaServer;
00018 class UPNPSubscription;
00019 class meta_dir_node;
00020
00021 class MediaServerItem
00022 {
00023 public:
00024 MediaServerItem() : m_scanned(false) { }
00025 MediaServerItem(QString id, QString parent, QString name, QString url)
00026 : m_id(id), m_parentid(parent), m_name(name), m_url(url),
00027 m_scanned(false) { }
00028 QString NextUnbrowsed(void);
00029 MediaServerItem* Find(QString &id);
00030 bool Add(MediaServerItem &item);
00031 void Reset(void);
00032
00033 QString m_id;
00034 QString m_parentid;
00035 QString m_name;
00036 QString m_url;
00037 bool m_scanned;
00038 QMap<QString, MediaServerItem> m_children;
00039 };
00040
00041 class UPNPScanner : public QObject
00042 {
00043 Q_OBJECT
00044
00045 public:
00046 ~UPNPScanner();
00047
00048 static void Enable(bool enable, UPNPSubscription *sub = NULL);
00049 static UPNPScanner* Instance(UPNPSubscription *sub = NULL);
00050
00051 void StartFullScan(void);
00052 void GetInitialMetadata(VideoMetadataListManager::metadata_list* list,
00053 meta_dir_node *node);
00054 void GetMetadata(VideoMetadataListManager::metadata_list* list,
00055 meta_dir_node *node);
00056 bool GetMetadata(QVariant &data);
00057 QMap<QString,QString> ServerList(void);
00058
00059 protected:
00060 virtual void customEvent(QEvent *event);
00061 virtual void timerEvent(QTimerEvent * event);
00062
00063 private slots:
00064 void Start();
00065 void Stop(void);
00066 void Update(void);
00067 void CheckStatus(void);
00068 void replyFinished(QNetworkReply *reply);
00069
00070 private:
00071 UPNPScanner(UPNPSubscription *sub);
00072 void ScheduleUpdate(void);
00073 void CheckFailure(const QUrl &url);
00074 void Debug(void);
00075 void BrowseNextContainer(void);
00076 void SendBrowseRequest(const QUrl &url, const QString &objectid);
00077 void AddServer(const QString &usn, const QString &url);
00078 void RemoveServer(const QString &usn);
00079 void ScheduleRenewal(const QString &usn, int timeout);
00080
00081
00082 void ParseBrowse(const QUrl &url, QNetworkReply *reply);
00083 void FindItems(const QDomNode &n, MediaServerItem &content,
00084 bool &resetparent);
00085 QDomDocument* FindResult(const QDomNode &n, uint &num,
00086 uint &total, uint &updateid);
00087
00088
00089 bool ParseDescription(const QUrl &url, QNetworkReply *reply);
00090 void ParseDevice(QDomElement &element, QString &controlURL,
00091 QString &eventURL, QString &friendlyName);
00092 void ParseServiceList(QDomElement &element, QString &controlURL,
00093 QString &eventURL);
00094 void ParseService(QDomElement &element, QString &controlURL,
00095 QString &eventURL);
00096
00097
00098 void GetServerContent(QString &usn, MediaServerItem *content,
00099 VideoMetadataListManager::metadata_list* list,
00100 meta_dir_node *node);
00101
00102 private:
00103 static UPNPScanner* gUPNPScanner;
00104 static bool gUPNPScannerEnabled;
00105 static MThread* gUPNPScannerThread;
00106 static QMutex* gUPNPScannerLock;
00107
00108 UPNPSubscription *m_subscription;
00109 QMutex m_lock;
00110 QHash<QString,MediaServer*> m_servers;
00111 QNetworkAccessManager *m_network;
00112
00113
00114 QMultiMap<QUrl, QNetworkReply*> m_descriptionRequests;
00115 QMultiMap<QUrl, QNetworkReply*> m_browseRequests;
00116
00117 QTimer *m_updateTimer;
00118 QTimer *m_watchdogTimer;
00119
00120 QString m_masterHost;
00121 int m_masterPort;
00122
00123 bool m_scanComplete;
00124 bool m_fullscan;
00125 };
00126
00127 #endif // UPNPSCANNER_H