A class for discovering and interacting with UPnP devices in the network. More...
#include <HControlPoint>
According to the UPnP Device Architecture specification, a control point is an entity, which "retrieves device and service descriptions, sends actions to services, polls for service state variables, and receives events from services" . In other words, a UPnP control point discovers UPnP devices, queries their state, listens their asynchronous events and invokes them to perform actions. A control point is the client in the UPnP architecture, whereas a UPnP device is the server.
HControlPoint
does all of the above, but mostly hiding it from the user if the user wishes so. To discover UPnP devices all you need to do is create an instance of HControlPoint
, initialize it by calling init() and check if devices are already found by calling rootDevices(), devices() or device(). You can also listen for a number of events, such as:
Consider an example:
// myclass.h #include <HUpnpCore/HControlPoint> class MyClass : public QObject { Q_OBJECT private: Herqq::Upnp::HControlPoint* m_controlPoint; private slots: void rootDeviceOnline(Herqq::Upnp::HClientDevice*); void rootDeviceOffline(Herqq::Upnp::HClientDevice*); public: MyClass(QObject* parent = 0); }; // myclass.cpp #include "myclass.h" #include <HUpnpCore/HClientDevice> MyClass::MyClass(QObject* parent) : QObject(parent), m_controlPoint(new Herqq::Upnp::HControlPoint(this)) { connect( m_controlPoint, SIGNAL(rootDeviceOnline(Herqq::Upnp::HClientDevice*)), this, SLOT(rootDeviceOnline(Herqq::Upnp::HClientDevice*))); connect( m_controlPoint, SIGNAL(rootDeviceOffline(Herqq::Upnp::HClientDevice*)), this, SLOT(rootDeviceOffline(Herqq::Upnp::HClientDevice*))); if (!m_controlPoint->init()) { // the initialization failed, perhaps you should do something? // for starters, you can call error() to check the error type and // errorDescription() for a human-readable description of // the error that occurred. return; } // the control point is running and any standard-compliant UPnP device // on the same network should now be discoverable. // remember also that the current thread has to have an event loop } void MyClass::rootDeviceOnline(Herqq::Upnp::HClientDevice* newDevice) { // device discovered, should something be done with it? Perhaps we want // to learn something from it: Herqq::Upnp::HDeviceInfo info = newDevice->info(); // do something with the info object } void MyClass::rootDeviceOffline(Herqq::Upnp::HClientDevice* rootDevice) { // device announced that it is going away and the control point sends // a notification of this. However, the device isn't removed from the // control point until explicitly requested: m_controlPoint->removeRootDevice(rootDevice); }
Once you have obtained a pointer to a HClientDevice you can enumerate its services, invoke its actions, listen for events of changed state and so on. Basically, a root HClientDevice
object at the control point side is an entry point to a very accurate object model depicting the real root UPnP device that has been discovered. For more information about the HClientDevice
and the object model, see the page detailing the HUPnP Device Model.
You can call quit() to stop an initialized control point instance from listening the network and to clear its state.
QObject::moveToThread()
on the HControlPoint
, which causes the control point and every object managed by it to be moved to the chosen thread. However, you cannot move individual objects managed by HControlPoint
. enum DeviceDiscoveryAction [protected] |
This enumeration specifies the actions to take when a device has been discovered.
IgnoreDevice |
Ignores the device. In case the discovered device is a new device this value instructs the control point to ignore and delete it. In case the discovered device is already in the control of the control point this value instructs the control point to ignore it. However, the device is not removed from the control point. To do that you have to call removeRootDevice(). |
AddDevice |
Adds a new device into the control point and retains an existing device in the control point. In case the discovered device is a new device the new device is added into the The control point will not subscribe to events. |
AddDevice_SubscribeEventsIfConfigured |
Adds the device into the control point and subscribes to evented services according to the configuration of the control point. In case the discovered device is a new device the new device is added into the The control point determines whether to subscribe to events based on its configuration. Default configuration instructs the control point to subscribe to all events. The same is done if no configuration was provided. |
AddDevice_SubscribeAllEvents |
Adds the device into the control point and subscribes to all evented services. In case the discovered device is a new device the new device is added into the The control points subscribes to all evented services contained by the device and its embedded devices. |
enum ControlPointError |
This enumeration specifies error types some of the methods of HControlPoint
may return.
enum SubscriptionStatus |
This enumeration is used to describe the status of an event subscription.
Unsubscribed |
No subscription exists for the specified service. This value is used when there is no subscription or subscription attempt being made to a specified service. |
Subscribing |
A subscription attempt is in progress. This value is used when a subscription attempt to the events of the specified service is in progress.
|
Subscribed |
A subscription is active. This value is used when the control point has successfully subscribed to the events of the specified service. |
HControlPoint | ( | QObject * | parent = 0 ) |
Creates a new instance.
parent | specifies the parent QObject , if any. |
HControlPoint | ( | const HControlPointConfiguration & | configuration, |
QObject * | parent = 0 |
||
) |
Creates a new instance.
configuration | specifies information that can be used to modify the default behavior of the control point instance. If you want to use the default configuration, you should use the default constructor. |
parent | specifies the parent QObject , if any. |
~HControlPoint | ( | ) | [virtual] |
Destroys the control point and every hosted device.
HControlPoint
instance has to be destroyed in the thread in which it is located. bool doInit | ( | ) | [private, virtual] |
Performs the initialization of a derived class.
The HControlPoint
uses two-phase initialization in which the user first constructs an instance and then calls init() in order to ready the object for use. This method is called by the HControlPoint
during its private initialization after all the private data structures are constructed but before any network activity. At this point, no HTTP or SSDP requests are served.
You can override this method to perform any further initialization of a derived class.
void doQuit | ( | ) | [private, virtual] |
Performs the de-initialization of a derived class.
Since it is possible to shutdown a control point without actually destroying the instance by calling quit(), derived classes have the possibility to run their own shutdown procedure by overriding this method. This method is called before the HControlPoint
cleans its private data structures but after it has stopped listening requests from the network.
HControlPoint::DeviceDiscoveryAction acceptRootDevice | ( | HClientDevice * | device ) | [private, virtual] |
This method specifies the actions to take when a device has been discovered.
A discovered device may be a new device to the control point or a device that is already in the control point. The latter scenario is true when a device goes offline, is not removed from the control point and later comes back online with the same UPnP configuration (see UDA for more information about a UPnP device configuration).
If you have derived a class from HControlPoint you have the option of choosing whether a discovered device should be managed by the control point, and whether the control point should subscribe to the events published by the services of the device. To do this you have to override this method.
device | specifies the discovered device. |
By default every successfully built device will be added to the control point and its events are subscribed according to the control point configuration.
bool acceptResource | ( | const HDiscoveryType & | usn, |
const HEndpoint & | source | ||
) | [private, virtual] |
This method is called whenever a new a device has been detected on the network.
Override this method in case you want to control which devices get built.
Every UPnP resource belongs to a UPnP device tree, and every advertisement and notification of a resource contains all the information needed to build a full model of the device tree. An advertisement is sent by a UPnP device to advertise itself, its embedded devices or any of the services contained within the device tree. A notification is the response from a UPnP device to a discovery sent by a control point.
If an advertisement or a notification is received that identifies a resource belonging to a device that is currently not in the control of this control point, this method is called. If you accept the specified resource the control point will retrieve all the information from the target UPnP device to build a device model of the device tree the UPnP device represents.
usn | contains information about the resource. |
source | specifies the source of the advertisement. |
HControlPoint
. const HControlPointConfiguration * configuration | ( | ) | const [protected] |
Returns the configuration used to initialize the control point.
void setError | ( | ControlPointError | error, |
const QString & | errorDescr | ||
) | [protected] |
Sets the type and description of the last occurred error.
error | specifies the error type. |
errorDescr | specifies a human readable description of the error. |
bool init | ( | ) |
Initializes the control point.
This has to be called for the control point to start monitoring the network for UPnP devices. To stop an initialized control point instance from listening network events you can call quit() or delete the object.
HControlPoint
instance performs a device discovery upon initialization. However, you can override this in the configuration.HControlPoint::ControlPointError error | ( | ) | const |
Returns the type of the last error occurred.
QString errorDescription | ( | ) | const |
Returns a human readable description of the last error occurred.
bool isStarted | ( | ) | const |
Indicates whether or not the host is successfully started.
HClientDevice * device | ( | const HUdn & | udn, |
TargetDeviceType | deviceType = RootDevices |
||
) | const |
Returns a device with the specified Unique Device Name that the control point is currently managing.
udn | specifies the Unique Device Name of the desired device. |
deviceType | specifies whether the search should consider root devices only. The default is to search root devices only. |
HClientDevices rootDevices | ( | ) | const |
Returns a list of UPnP root devices the control point is currently managing.
The returned list contains pointers to root HClientDevice objects that are currently managed by this instance.
HClientDevices devices | ( | const HResourceType & | deviceType, |
HResourceType::VersionMatch | versionMatch = HResourceType::Inclusive , |
||
TargetDeviceType | deviceTypes = RootDevices |
||
) |
Returns a list of UPnP devices the control point is currently managing and that match the provided search criteria.
The returned list contains pointers to HClientDevice objects that are currently managed by this instance. It is important to note that unlike the method rootDevices() this method may return pointers to both root and embedded devices.
deviceType | specifies the UPnP device type to be searched. |
versionMatch | specifies how the version information in argument deviceType should be used. The default is inclusive match, which essentially means that any device with a device type version that is less than or equal to the version specified in argument deviceType is successfully matched. |
deviceTypes | specifies whether the search should consider root devices only. The default is to search root devices only. |
bool removeRootDevice | ( | HClientDevice * | rootDevice ) |
Removes the root device from the control point and deletes it.
rootDevice | specifies the root device to be removed. Nothing is done if the device is not in the control of this control point or the device is not a root device. |
true | in case the device was successfully removed and deleted. |
false | in case:
|
bool subscribeEvents | ( | HClientDevice * | device, |
DeviceVisitType | visitType | ||
) |
Subscribes to events of the specified services contained by the specified device.
You can use this method to subscribe to events of multiple evented services contained by the specified device at once.
device | specifies the device that contains the services, which events are subscribed. |
visitType | specifies how the device tree is traversed. A subscription is sent to every service of every visited device. |
true | in case the subscriptions were successfully dispatched. Note, any subscription may still fail. You can connect to subscriptionSucceeded() and subscriptionFailed() signals to be notified upon subscription success and failure. |
false | in case the specified argument is null or it does not belong to a device held by the control point. |
Thus, a subscription is automatically renewed before expiration until an error occurs or it is canceled.
bool subscribeEvents | ( | HClientService * | service ) |
Subscribes to the events of the service.
service | specifies the service |
true | in case the subscription request was successfully dispatched. Note, the subscription may still fail. You can connect to subscriptionSucceeded() and subscriptionFailed() signals to be notified upon subscription success and failure. |
false | in case the specified argument:
|
Thus, a subscription is automatically renewed before expiration until an error occurs or it is canceled.
HControlPoint::SubscriptionStatus subscriptionStatus | ( | const HClientService * | service ) | const |
Checks if there exists a subscription to the events of the specified service.
service | specifies the service to be checked. |
HControlPoint::Unsubscribed | when the service is not evented or there is no active susbcription or subscription attempt going on to the specified service. |
HControlPoint::Subscribing | when the service is evented and an subscription attempt is being made to the specified service. |
HControlPoint::Subscribed | when there exists an active subscription to the specified service. |
bool cancelEvents | ( | HClientDevice * | device, |
DeviceVisitType | visitType | ||
) |
Cancels the event subscriptions of every service contained by the device.
Any services which events are not subscribed are skipped.
device | specifies the device that contains the services, which subscriptions are canceled. |
visitType | specifies how the device tree is traversed. A subscription cancellation request is sent to every service of every visited device. |
true | in case the cancellation request of a subscription was successfully dispatched. Note, this does not mean that the cancellation was successfully received and handled by the UPnP device in question. Upon success the state of the control point instance is modified appropriately, but it is never guaranteed that the target UPnP device receives or processes the cancellation request. |
false | in case
|
bool cancelEvents | ( | HClientService * | service ) |
Cancels the event subscription of the service.
service | specifies the service, which event subscription is to be canceled. |
true | in case the cancellation request of a subscription was successfully dispatched. Note, this does not mean that the cancellation was successfully received and handled by the UPnP device in question. Upon success the state of the control point instance is modified appropriately, but it is never guaranteed that the target UPnP device receives or processes the cancellation request. |
false | in case
|
bool scan | ( | const HDiscoveryType & | discoveryType, |
qint32 | count = 1 |
||
) |
Scans the network for resources of interest.
Using the default configuration HControlPoint
automatically searches and adds every device it finds. In that case the device list returned by rootDevices() usually reflects the UPnP device status of the network. However, there are situations where you may want to explicitly ask the HControlPoint
to update its status and you can call this method to do that.
discoveryType | specifies the type of the discovery to perform. |
count | specifies how many times the discovery should be performed. The number translates directly to the number of SSDP messages send. The default is 1. |
bool scan | ( | const HDiscoveryType & | discoveryType, |
const HEndpoint & | destination, | ||
qint32 | count = 1 |
||
) |
Scans the network for resources of interest.
Using the default configuration HControlPoint
automatically searches and adds every device it finds. In that case the device list returned by rootDevices() usually reflects the UPnP device status of the network. However, there are situations where you may want to explicitly ask the HControlPoint
to perform a discovery on a specific TCP/IP endpoint. In other words, you can perform a unicast device discovery using this method.
discoveryType | specifies the type of the discovery to perform. |
destination | specifies the location where the discovery is sent. If the port of the specified endpoint is set to zero the message is sent to the specified host address using the default port 1900. |
count | specifies how many times the discovery should be performed. The number translates directly to the number of SSDP messages send. The default is 1. |
void quit | ( | ) | [slot] |
Shuts down the control point.
The control point stops listening for network events, deletes all the devices it is hosting and cancels all event subscriptions. In essence, the control point purges it state. You can re-initialize the control point by calling init() again.
void authenticationRequired | ( | QNetworkReply * | reply, |
QAuthenticator * | authenticator | ||
) | [signal] |
This signal is emitted whenever a final server requests authentication before it delivers the requested contents.
This signal is relayed from the underlying QNetworkAccessManager
, which is used by the HControlPoint
to run HTTP messaging. As specified in the reference documentation of QNetworkAccessManager, the slot connected to this signal should fill the credentials for the contents (which can be determined by inspecting the reply object) in the authenticator object. QNetworkAccessManager
will cache the credentials internally and will send the same values if the server requires authentication again, without emitting the authenticationRequired() signal. If it rejects the credentials, this signal will be emitted again.
reply | specifies the requested contents. |
authenticator | specifies the authenticator object to which the user should fill in the credentials. |
void subscriptionSucceeded | ( | Herqq::Upnp::HClientService * | service ) | [signal] |
This signal is emitted when the initial subscription to the specified service succeeded.
service | specifies the target service of the event subscription. |
void subscriptionFailed | ( | Herqq::Upnp::HClientService * | service ) | [signal] |
This signal is emitted when an event subscription to the specified service failed.
service | specifies the service, which event subscription failed. |
void subscriptionCanceled | ( | Herqq::Upnp::HClientService * | service ) | [signal] |
This signal is emitted when an event subscription to the specified service has been canceled.
service | specifies the service, which subscription was canceled. |
void rootDeviceOnline | ( | Herqq::Upnp::HClientDevice * | device ) | [signal] |
This signal is emitted when a device has been discovered.
device | is the discovered device. |
void rootDeviceOffline | ( | Herqq::Upnp::HClientDevice * | device ) | [signal] |
This signal is sent when a root device has announced that it is going offline or the expiration timeout associated with the device tree has elapsed.
After a device has gone offline you may want to remove the device from the control point using removeRootDevice(). Alternatively, if you do not remove the device and the device comes back online later:
device | is the device that went offline and is not reachable at the moment. |
void rootDeviceInvalidated | ( | Herqq::Upnp::HClientDevice * | device ) | [signal] |
This signal is emitted when a previously discovered device has changed its configuration and must be discarded.
The UDA v1.1 specifies the configuration of a root device to consist of the device description documents of all the devices in the device tree and all the service description documents of the services in the device tree. If the configuration changes the old device tree has to be discarded in place of the new one.
After this signal is emitted the specified HClientDevice object has become invalid and should be discarded and removed immediately. In addition, rootDeviceOnline() signal may be emitted shortly after this signal, but only when the new configuration of the device is accepted by this instance.
device | is the device that has been invalidated. |
void rootDeviceRemoved | ( | const Herqq::Upnp::HDeviceInfo & | deviceInfo ) | [signal] |
This signal is emitted when a root device has been removed from the control of this control point and deleted.
deviceInfo | specifies information about the device that was removed and deleted. |