Public Slots | Signals | Public Member Functions | Protected Member Functions

# HService Class Reference
[Device Model]

An abstract base class that represents a UPnP service hosted by an HDevice. More...

`#include <HService>`

Inheritance diagram for HService:

List of all members.

## 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 ()

## Detailed Description

`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.

## Using the class

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:

- scpdUrl, which returns the URL for fetching the service description,
- controlUrl, which returns the URL to be used in action invocation and
- eventSubUrl, which returns the URL used in event (un)subscriptions.

However, the above URLs usually provide informational value only, since HUPnP provides a simpler interface for everything those URLs expose:

- You can retrieve the service description of a service using description().
- Action invocation is abstracted into the HAction class.
- You can receive all the event notifications from a UPnP service by connecting to the stateChanged() signal. You do not need to worry about UPnP eventing at all, since HUPnP handles that for you.

## Sub-classing

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.

See also:
  Device Model

Remarks:
  The methods introduced in this class are thread-safe, but the `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.

## Constructor & Destructor Documentation

HService | ( |  | ) | `[protected]`

Creates a new instance.

Default constructor for derived classes.

~HService | ( |  | ) | `[pure virtual]`

Destroys the instance.

## Member Function Documentation

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).

Returns:
  the actions that this `HService` exposes.

Remarks:
  The HService base class takes the ownership of the created objects and will delete them upon its destruction. Because of that, you can store the addresses of the created objects and use them safely throughout the lifetime of this service. However, you cannot delete them.

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:

- at server side the service description is the mechanism used to marshal device model information to clients. If the service description does not accurately reflect the back-end classes, the client side may not be able to correctly invoke the server-side.
- at client side HUPnP can use this information to verify that the server-side is publishing a device in a way the client-side understands.

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).

Returns:
  the actions that this `HService` exposes.

Remarks:
  The HService base class takes the ownership of the created objects and will delete them upon its destruction. Because of that, you can store the addresses of the created objects and use them safely throughout the lifetime of this service. However, you cannot delete them.

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.

Parameters:

  | errDescription |

Returns:
  true in case the initialization succeeded.

Note:
  It is advisable to keep the constructors of the descendants of `HService` small and fast, and do more involved initialization routines here.

HDevice * parentDevice | ( |  | ) | const

Returns the parent HDevice that contains this service instance.

Returns:
  the parent HDevice that contains this service instance.

const HServiceInfo & info | ( |  | ) | const

Returns information about the service that is read from the device description.

Returns:
  information about the service that is read from the device description.

const QString & description | ( |  | ) | const

Returns the full service description.

Returns:
  the full service description.

QList< HAction * > actions | ( |  | ) | const

Returns the actions the service supports.

Returns:
  the actions the service supports.

Remarks:
  the ownership of the returned objects is not transferred. Do not delete the returned objects.

HAction * actionByName | ( | const QString & | name | ) | const

Attempts to retrieve an action by name.

Parameters:

  | name | specifies the name of the action to be returned. This is the name of the action specified in the service description.

Returns:
  a pointer to an action supported by this service if the provided name is valid or a null pointer otherwise.

Remarks:
  the ownership of the object is not transferred. Do not delete the returned object.

QList< HStateVariable * > stateVariables | ( |  | ) | const

Returns the state variables of the service.

Returns:
  the state variables of the service.

Remarks:
  the ownership of the returned objects is not transferred. Do not delete the returned objects.

HStateVariable * stateVariableByName | ( | const QString & | name | ) | const

Attempts to retrieve a state variable by name.

Parameters:

  | name | specifies the name of the state variable to be returned. This is the name of the state variable specified in the service description.

Returns:
  a pointer to a state variable found in this service if the provided name is valid or a null pointer otherwise.

Remarks:
  the ownership of the object is not transferred. Do not delete the returned object.

bool isEvented | ( |  | ) | const

Indicates whether or not the service contains state variables that are evented.

Returns:
  true in case the service contains one or more state variables that are evented.

Remarks:
  in case the service is not evented, the stateChanged() signal will never be emitted and the notifyListeners() method does nothing.

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.

Parameters:

  | source | specifies the source of the event.

Remarks:
  This signal has thread affinity to the thread where the object resides. Do not connect to this signal from other threads.