An abstract base class that represents a UPnP service hosted by an HDevice. More...
#include <HService>
Public Slots | |
void | notifyListeners () |
Signals | |
void | stateChanged (const Herqq::Upnp::HService *source) |
Public Member Functions | |
virtual | ~HService ()=0 |
HDevice * | parentDevice () const |
const HServiceInfo & | info () const |
const QString & | description () const |
HActions | actions () const |
HAction * | actionByName (const QString &name) const |
HStateVariables | stateVariables () const |
HStateVariable * | stateVariableByName (const QString &name) const |
bool | isEvented () const |
Protected Member Functions | |
virtual HActionsSetupData | createActions () |
virtual HStateVariablesSetupData | stateVariablesSetupData () const |
virtual bool | finalizeInit (QString *errDescription) |
HService () |
HService
is a core component of the HUPnP Device Model and it models a UPnP service. The UPnP Device Architecture specifies a UPnP service as "Logical functional unit. Smallest units of control. Exposes
actions and models the state of a physical device with state variables". In other words, a UPnP service is the entry point for accessing certain type of functionality and state of the containing device.
You can retrieve the containing device, the parent device, using parentDevice(). You can retrieve all the actions the service contains by calling actions(), or if you know the name of the action you can call the actionByName(). Similarly, you can retrieve all the state variables the service contains by calling stateVariables(), or if you know the name of the state variable you can call stateVariableByName().
The class exposes all the details in the device description concerning a service through info(), which returns a const reference to a HServiceInfo instance. From this class you can retrieve the serviceId and serviceType along with various URLs found in the device description, such as the:
However, the above URLs usually provide informational value only, since HUPnP provides a simpler interface for everything those URLs expose:
In case you have written your own server-side HDevice that exposes UPnP services, you need to write corresponding HService
classes, which you instantiate in your HDevice::createServices() method.
Writing a custom HService
is simple, since usually you are required to override createActions() only. That is, if your service defines actions. This is the place where you plug-in the functionality of your UPnP device by providing the implementations of the UPnP actions defined in your service description documents.
Consider an example:
#include "myswitchpower.h" // your code Herqq::Upnp::HActionsSetupData MySwitchPower::createActions() { Herqq::Upnp::HActionsSetupData retVal; retVal.insert( HActionSetup( "SetTarget", Herqq::Upnp::HActionInvoke(this, &MySwitchPower::setTarget))); retVal.insert( HActionSetup( "GetTarget", Herqq::Upnp::HActionInvoke(this, &MySwitchPower::getTarget))); retVal.insert( HActionSetup( "GetStatus", Herqq::Upnp::HActionInvoke(this, &MySwitchPower::getStatus))); // The above binds member functions to the specified action names. // However, you could also use normal functions and functors. return retVal; }
In the above example three member functions of a fictional class named MySwitchPower
are bound to actions named SetTarget
, GetTarget
and GetStatus
. In this particular case, these action names have to be defined in the service's description document, but that is not necessarily always the case (more on that later). On the other hand, every action defined in the description document is always required to have an implementation bound and returned by the createActions(). The above example uses member functions as arguments to Herqq::Upnp::HActionInvoke, but you can use other callable entities as well, such as normal functions and functors. Once set up properly, it is these callable entities that are called whenever the corresponding actions are invoked.
QObject
base class is largely not. However, the signal stateChanged() has thread affinity and any connections to it must be done in the thread where the instance of HService resides. HService | ( | ) | [protected] |
Creates a new instance.
Default constructor for derived classes.
~HService | ( | ) | [pure virtual] |
Destroys the instance.
HActionsSetupData createActions | ( | ) | [protected, virtual] |
Creates and returns the actions the service exposes.
It is very important to note that every descendant that specifies actions has to override this. In addition, the override of this method should always call the implementation of the super class too. For instance,
void HService::HActionsSetupData MyServiceType::createActions() { HActionsSetupData retVal = SuperClass::createActions(); // create and add the actions of this class to the "retVal" variable return retVal; }
Most commonly this method is called only once when the instance is being initialized by the managing host (HDeviceHost or HControlPoint).
HService
exposes.Reimplemented in HServiceProxy.
HStateVariablesSetupData stateVariablesSetupData | ( | ) | const [protected, virtual] |
Creates and returns setup information about the state variables the service exposes.
The purpose of this method is to enable the custom HService to pass information of its state variables to HUPnP, which uses that information -if available- to verify that service descriptions are properly setup in respect to the custom HService class. The benefit of this is that your HService class can rest assured that once it is up and running all the required state variables are properly defined in the service description. This is important for two reasons:
In any case, overriding this method is always optional, but if you override it, remember to call the implementation of the super class too. For instance,
void HStateVariablesSetupData MyServiceType::createActions() { HStateVariablesSetupData retVal = SuperClass::stateVariablesSetupData(); // modify the "retVal" as desired. return retVal; }
Most commonly this method is called only once when the instance is being initialized by the managing host (HDeviceHost or HControlPoint).
HService
exposes.bool finalizeInit | ( | QString * | errDescription | ) | [protected, virtual] |
Provides an opportunity to do post-construction initialization routines in derived classes.
As HService
is part of the HUPnP's Device Model the object creation process is driven by HUPnP. At the time of instantiation of a descendant HService
the base HService
sub-object is not yet fully set up. In other words, at that time it is not guaranteed that every private or protected member of a HService
is set to its "final" value that is used once the object is fully initialized and ready to be used.
Because of the above, descendants of HService
should not reference or rely on values of HService
at the time of construction. If the initialization of a HService
descendant needs to do things that rely on HService
being fully set up, you can override this method. This method is called once right after the base HService
is fully initialized.
errDescription |
HService
small and fast, and do more involved initialization routines here. HDevice * parentDevice | ( | ) | const |
const HServiceInfo & info | ( | ) | const |
Returns information about the service that is read from the device description.
const QString & description | ( | ) | const |
Returns the full service description.
QList< HAction * > actions | ( | ) | const |
Returns the actions the service supports.
HAction * actionByName | ( | const QString & | name | ) | const |
Attempts to retrieve an action by name.
name | specifies the name of the action to be returned. This is the name of the action specified in the service description. |
QList< HStateVariable * > stateVariables | ( | ) | const |
Returns the state variables of the service.
HStateVariable * stateVariableByName | ( | const QString & | name | ) | const |
Attempts to retrieve a state variable by name.
name | specifies the name of the state variable to be returned. This is the name of the state variable specified in the service description. |
bool isEvented | ( | ) | const |
Indicates whether or not the service contains state variables that are evented.
void notifyListeners | ( | ) | [slot] |
Explicitly forces stateChanged() event to be emitted if the service is evented.
Otherwise this method does nothing.
void stateChanged | ( | const Herqq::Upnp::HService * | source | ) | [signal] |
This signal is emitted when the state of one or more state variables has changed.
source | specifies the source of the event. |