Herqq

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

Classes | Typedefs

# Device Model

HUPnP Core

This page explains the concept of HUPnP Device Model, which is the logical object hierarchy of HUPnP representing the UPnP Device Architecture. More...

## Classes
class | HClientAction
| A client-side class that represents a server-side UPnP action. More...
class | HClientActionOp
| This class is used to identify a client-side action invocation and detail information of it. More...
class | HClientDevice
| This is a client-side class that represents a server-side UPnP device. More...
class | HClientService
| A client-side class that represents a server-side UPnP service. More...
class | HClientStateVariable
| A client-side class that represents a server-side UPnP state variable. More...
class | HActionArgument
| This is a class that represents an argument used in a UPnP action invocation. More...
class | HActionArguments
| A storage class for HActionArgument instances. More...
class | HActionSetup
| This class is used to specify information that can be used to setup an HServerAction or validate a UPnP action. More...
class | HActionsSetupData
| This class is used to specify information that can be used to setup HServerAction instances or generally validate the actions of a UPnP service. More...
class | HAsyncOp
| This abstract class is used as a base for identifying an asynchronous operation and detail information of it. More...
class | HDeviceModelInfoProvider
| A protocol class for providing information that is used to validate components of UPnP's device architecture and to setup components of HUPnP's device model. More...
class | HDeviceSetup
| This class is used to specify information that can be used to validate a UPnP device. More...
class | HDevicesSetupData
| This class is used to specify information that can be used to validate UPnP devices. More...
class | HExecArgs
| This class is used to specify information used to control the execution of an asynchronous operation and the notification of its completion. More...
class | HServiceSetup
| This class is used to specify information that can be used to validate a UPnP service. More...
class | HServicesSetupData
| This class is used to specify information that can be used to validate UPnP services. More...
class | HStateVariableEvent
| This is a class used to transfer state variable event information. More...
class | HStateVariablesSetupData
| This class is used to specify information that can be used to validate UPnP state variables. More...
class | HDeviceModelCreator
| A protocol class for creating HServerDevice and HServerService instances. More...
class | HServerAction
| A class that represents a server-side UPnP action. More...
class | HServerDevice
| This is an abstract base class for server-side UPnP devices hosted by HDeviceHost. More...
class | HServerService
| This is an abstract base class for server-side UPnP services. More...
class | HServerStateVariable
| This is a class that represents a server-side UPnP state variable. More...
## Typedefs
typedef Functor< int, H_TYPELIST_2(const Herqq::Upnp::HActionArguments &, Herqq::Upnp::HActionArguments *) | HActionInvoke )
typedef Functor< bool, H_TYPELIST_2(HClientAction *, const HClientActionOp &) | HActionInvokeCallback )
typedef QHash< QString, HActionInvoke > | HActionInvokes
typedef QList< HClientService * > | HClientServices
typedef QList< HServerService * > | HServerServices
typedef QList< HClientDevice * > | HClientDevices
typedef QList< HServerDevice * > | HServerDevices
typedef QHash< QString, const HClientStateVariable * > | HClientStateVariables
typedef QHash< QString, HServerStateVariable * > | HServerStateVariables
typedef QHash< QString, HStateVariableInfo > | HStateVariableInfos
typedef QHash< QString, HClientAction * > | HClientActions
typedef QHash< QString, HServerAction * > | HServerActions

## Detailed Description

This page explains the concept of HUPnP Device Model, which is the logical object hierarchy of HUPnP representing the UPnP Device Architecture.

## A few notes about the design

The main four components of the UPnP device model are a device, a service, a state variable and an action. These four components form a type of a tree in which devices and services are contained by devices, and state variables and actions are contained by services. This is called the device tree. A device tree has a root device, which is a UPnP device that has no parent, but may contain other UPnP devices. These contained devices are called embedded devices.

HUPnP's device model mimicts this design closely. At server-side the main four components are HServerDevice, HServerService, HServerStateVariable and HServerAction. At client-side the main four components are HClientDevice, HClientService, HClientStateVariable and HClientAction.

The purpose of the other classes part of the HUPnP's device model is to support the initialization and use of the four core components both at the server and client-side.

### API differences between client and server sides

The HUPnP device model is largely the same at the server and client sides. That is, whether you are writing a custom UPnP device or trying to interact with a UPnP device found in the network, you will be interacting with the HUPnP device model in a similar manner. Regardless of that, there are some important differences, which is why the server and client-side define and use different types that do not share ancestors provided by HUPnP.

First and most importantly, server side contains the "businness" logic of a UPnP device and clients only invoke or use it. This logic should not be duplicated to the client-side, as it serves no purpose there. Having a design that explicitly states this separation of concerns at type level should certainly help in making the purpose of each type clear.

Second, UPnP clients are unable to modify server-side state variables directly and in a uniform manner. This is because UPnP Device Architecture does not specify a mechanism for changing the value of a state variable from client-side. Certainly the value of a state variable may be changeable, but that and the way it is done depends of the service type in which the state variable is defined. On the other hand, server-side has to have direct read-write access to the state variables. This type of difference should be explicit in the design.

Third, client-side action invocation should naturally be asynchronous to the user, as the call most often involves network access. On the server-side the action invocations are direct method calls and as such the burden of running them "asynchronously" with the help of worker threads should reside at the user code.

### The lifetime and ownership of objects

Every device (HClientDevice and HServerDevice) has the ownership of all of its embedded devices, services, actions and state variables and the ownership is never released. This means that every device always manages the memory used by the objects it owns. Hence, the owner of a root device ultimately has the ownership of an entire device tree.

This is a very important point to remember: the lifetime of every object contained by the root device depends of the lifetime of the root device.

In other words, when a root device is deleted, every embedded device, service, state variable and action underneath it are deleted as well. Furthermore, every root device is always owned by HUPnP and the ownership is never released. Because of this you must never call `delete` to any of the components of the device model that is setup by HUPnP. Failing to follow this rule will result in undefined behavior.

Note:
  There are situations where you may want to instruct HUPnP to `delete` a device. For instance, when a UPnP device is removed from the network you may want your HControlPoint instance to remove the device that is no longer available. This can be done through the `HControlPoint` interface. But note, HUPnP never deletes a device object without an explicit request from a user.

## Usage

Basic use is about interacting with already created objects that comprise the device model. To get started you need to initialize either a device host or a control point and retrieve a device or a list of devices from it. See Device Hosting for more information about device hosts and control points. Once you have access to a device you can interact with any of its embedded devices, services, state variables and actions until:

- you explicitly request the root device of the device tree to be deleted,
- `delete` the owner of a device tree, such as HControlPoint or HDeviceHost.

See the corresponding classes for more information concerning their use.

Note:
  By default, HControlPoint keeps the state of the state variables up-to-date. That is, using default configuration an `HControlPoint` automatically subscribes to events the UPnP services expose. In such a case the state of a device tree the control point maintains reflects the state of the corresponding device tree at server-side as accurately as the server keeps sending events.

If you wish to implement and host your own UPnP device things get more involved. See Tutorial for Building a UPnP Device to get started on building your own UPnP devices using HUPnP.

## Typedef Documentation

typedef Functor<int, H_TYPELIST_2( const Herqq::Upnp::HActionArguments&, Herqq::Upnp::HActionArguments*) HActionInvoke)

This is a type definition for a callable entity that is used for HServerAction invocation.

You can create `HActionInvoke` objects using normal functions, functors and member functions that follow the signature of

``

`qint32 function(const Herqq::Upnp::HActionArguments& inArgs, Herqq::Upnp::HActionArguments* outArgs = 0);`

``

The following example demonstrates how you can instantiate the `HActionInvoke` for a normal function, functor and a member function.

     #include <HActionInvoke>
     #include <HUpnpCore/HActionArguments>

     #include "myclass.h" // your code that contains declaration for MyClass

     namespace
     {
     qint32 freefun(
          const Herqq::Upnp::HActionArguments& inArgs,
          Herqq::Upnp::HActionArguments* outArgs)
     {
         return 0;
     }

     class MyFunctor
     {
     public:
         qint32 operator()(
             const Herqq::Upnp::HActionArguments& inArgs,
             Herqq::Upnp::HActionArguments* outArgs)
         {
             return 0;
         }
     };
     }

     qint32 MyClass::memfun(
          const Herqq::Upnp::HActionArguments& inArgs,
          Herqq::Upnp::HActionArguments* outArgs = 0)
     {
     }

     void MyClass::example()
     {
         Herqq::Upnp::HActionInvoke usingFreeFunction(freefun);

         MyFunctor myfunc;
         Herqq::Upnp::HActionInvoke usingFunctor(myfunc);

         Herqq::Upnp::HActionInvoke usingMemberFunction(this, &MyClass::memfun);
     }

You can test if the object can be invoked simply by issuing `if (actionInvokeObject) { ... }`

typedef Functor<bool, H_TYPELIST_2( HClientAction*, const HClientActionOp&) HActionInvokeCallback)

This is a type definition for a callable entity that is used as a callback for signaling the completion of an HClientAction invocation.

You can create `HActionInvokeCallback` objects using normal functions, functors and member functions that follow the signature of

``

`bool function(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&);`

``

### Parameters

- The first parameter is a type of an "ID" of the asynchronous action invocation.
- The second parameter specifies the output arguments of the action invocation, which may be empty.

### Return value

The return value indicates if the invoked HClientAction should emit an HClientAction::invokeComplete() after the callback has returned.

- true indicates that the HClientAction should sent the corresponding event.

The following example demonstrates how you can instantiate the `HActionInvokeCallback` for a normal function, functor and a member function.

     #include <HUpnpCore/HClientAction>

     #include "myclass.h" // your code that contains declaration for MyClass

     namespace
     {
     bool freefun(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&)
     {
         return true;
     }

     class MyFunctor
     {
     public:
         bool operator()(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&)
         {
             return true;
         }
     };
     }

     bool MyClass::memfun(Herqq::Upnp::HClientAction*, const Herqq::Upnp::HClientActionOp&)
     {
         return true;
     }

     void MyClass::example()
     {
         Herqq::Upnp::HActionInvokeCallback usingFreeFunction(freefun);

         MyFunctor myfunc;
         Herqq::Upnp::HActionInvokeCallback usingFunctor(myfunc);

         Herqq::Upnp::HActionInvokeCallback usingMemberFunction(this, &MyClass::memfun);
     }

You can test if the object can be invoked simply by issuing `if (actionInvokeCallbackObject) { ... }`

typedef QHash<QString, HActionInvoke> HActionInvokes`[protected, inherited]`

This is a type definition for a hash table containing HActionInvoke objects keyed with strings representing the names of the actions.

See also:
  HActionInvoke

typedef QList<HClientService*> HClientServices

This is a type definition to a list of pointers to Herqq::Upnp::HClientService instances.

See also:
  HClientService

typedef QList<HServerService*> HServerServices

This is a type definition to a list of pointers to Herqq::Upnp::HServerService instances.

See also:
  HServerService

typedef QList<HClientDevice*> HClientDevices

This is a type definition to a list of pointers to Herqq::Upnp::HClientDevice instances.

See also:
  HClientDevice

typedef QList<HServerDevice*> HServerDevices

This is a type definition to a list of pointers to Herqq::Upnp::HServerDevice instances.

See also:
  HServerDevice

typedef QHash<QString, const HClientStateVariable*> HClientStateVariables

This is a type definition to a hash table of pointers to const Herqq::Upnp::HServerStateVariable instances keyed with the state variable names.

See also:
  HClientStateVariable

typedef QHash<QString, HServerStateVariable*> HServerStateVariables

This is a type definition to a hash table of pointers to Herqq::Upnp::HServerStateVariable instances keyed with the state variable names.

See also:
  HServerStateVariable

typedef QHash<QString, HStateVariableInfo> HStateVariableInfos

This is a type definition to a hash table of Herqq::Upnp::HStateVariableInfo instances keyed with the state variable names.

See also:
  HStateVariableInfo

typedef QHash<QString, HClientAction*> HClientActions

This is a type definition to a hash table of pointers to Herqq::Upnp::HClientAction instances keyed with the action names.

See also:
  HClientAction

typedef QHash<QString, HServerAction*> HServerActions

This is a type definition to a hash table of pointers to Herqq::Upnp::HServerAction instances keyed with the action names.

See also:
  HServerAction