Classes | Typedefs

# Device Hosting
[HUPnP Core]

This page explains the concept of device hosts, which encapsulate the technical details of UPnP networking. More...

## Classes
class | HControlPoint
| A class for discovering and interacting with UPnP devices in the network. More...
class | HControlPointConfiguration
| Class for specifying initialization information to HControlPoint instances. More...
class | HDeviceHost
| A class for creating and hosting `HDevice` instances on the network. More...
class | HDeviceHostRuntimeStatus
| This is a class for detailing information of the runtime status of an HDeviceHost instance. More...
class | HDeviceConfiguration
| This is a class for specifying a configuration to an HDevice that is to be created and hosted by an HDeviceHost. More...
class | HDeviceHostConfiguration
| This class is used to specify one or more device configurations to an HDeviceHost instance and to configure the functionality of the HDeviceHost that affect every hosted HDevice. More...
## Typedefs
typedef Functor < Herqq::Upnp::HDeviceProxy *, H_TYPELIST_1(const Herqq::Upnp::HDeviceInfo &)> | HDeviceProxyCreator
typedef Functor < Herqq::Upnp::HDevice *, H_TYPELIST_1(const Herqq::Upnp::HDeviceInfo &)> | HDeviceCreator

## Detailed Description

## A few notes about the design

The logical core of HUPnP is divided into two major modules; a collection of classes that enable the hosting of UPnP device model and the collection of classes that form up the Device Model. The separation is very distinct. The device hosts provide the technical foundation for the UPnP networking. They encapsulate and implement the protocols the UPnP Device Architecture specification details. The device model, on the other hand, is about the logical structure of the UPnP core concepts, which is clearly independent of the technical details of communication. Because of this HUPnP uses the same device model both at the server and client side.

HUPnP introduces two types of hosts.

- The Herqq::Upnp::HDeviceHost is the class that enables a UPnP device to be published for UPnP control points to use.
- The Herqq::Upnp::HControlPoint is the class that enables the discovery and use of UPnP devices that are available on the network.

The difference between these two classes is important to notice. You could picture an `HDeviceHost` as a server and an `HControlPoint` as a client. The `HDeviceHost` publishes instances of `HDevice` for UPnP control points to use and the `HControlPoint` uses instances of `HDevice` to communicate with UPnP devices. But as implied, they both use and expose the HUPnP Device Model.

Note:
  While a Herqq::Upnp::HDevice published by a `HDeviceHost` is always usable by UPnP control points over the network, the same device can also be accesed and used simultaneously in process. See Herqq::Upnp::HDeviceHost for more information.

When an `HControlPoint` discovers a UPnP device on the network it attempts to build an object model for that device. If the device is hosted by an `HDeviceHost` the `HControlPoint` will build almost identical device model compared to the model the `HDeviceHost` uses. The fact that some of the calls to the objects of the device model retrieved from `HControlPoint` go over the network to the real UPnP device is completely abstracted.

## Basic use

The basic use of a device host is straightforward. You only need to initialize it by providing information that enables one or more UPnP devices to be created and hosted. Note, you can access and use the `HDevice` instances the host manages.

In other words, you could create and initialize an `HDeviceHost` like this:

     #include <HUpnpCore/HDeviceHost>

     #include "my_hdevice.h" // your code

     namespace
     {
     class Creator
     {
     public:
         Herqq::Upnp::HDevice* operator()(const Herqq::Upnp::HDeviceInfo& deviceInfo)
         {
             return new MyHDevice(); // your class derived from HDevice
         }
     };

     Herqq::Upnp::HDeviceHost* createDeviceHost()
     {
         Herqq::Upnp::HDeviceConfiguration deviceConf;
         deviceConf.setPathToDeviceDescription("my_hdevice_devicedescription.xml");
         // this is the device description for our custom UPnP device type
         // the device host uses this file to build the device tree.

         Creator mydeviceCreatorFunctor;
         deviceConf.setDeviceCreator(mydeviceCreatorFunctor);
         // this functor is used to create types that represent UPnP devices found
         // in the device description.
         //
         // note, the creator can also be a normal or a member function

         Herqq::Upnp::HDeviceHost* deviceHost = new HDeviceHost();
         if (!deviceHost->init(deviceConf))
         {
             // the initialization failed. perhaps something should be done?
             // call error() to check the type of the error and errorDescription()
             // to get a human-readable description of the error.
         }

         return deviceHost;
     }
     }

and an `HControlPoint` like this:

     #include <HUpnpCore/HControlPoint>

     #include "myhdeviceproxy.h" // your code

     namespace
     {
     class Creator
     {
     public:
         Herqq::Upnp::HDeviceProxy* operator()(const Herqq::Upnp::HDeviceInfo& deviceInfo)
         {
             return new MyHDeviceProxy(); // your class derived from HDeviceProxy
         }
     };

     Herqq::Upnp::HControlPoint* createControlPoint()
     {
         Herqq::Upnp::HControlPointConfiguration controlPointConf;

         Creator mydeviceCreatorFunctor;
         controlPointConf.setDeviceCreator(mydeviceCreatorFunctor);
         // This functor can be used to create HDeviceProxy types for HControlPoint when
         // it discovers UPnP devices on the network. This can be useful if you want
         // to use your custom HDeviceProxy types that provide some custom
         // functionality / API perhaps.
         //
         // note, the creator can also be a normal or a member function.

         Herqq::Upnp::HControlPoint* controlPoint =
             new HControlPoint(controlPointConf);
         // note, the control point configuration is optional and usually you don't
         // need to provide one.

         if (!controlPoint->init())
         {
             // the initialization failed. perhaps something should be done?
             // call error() to check the type of the error and errorDescription()
             // to get a human-readable description of the error.
         }

         return controlPoint;
     }
     }

You do not have to provide any configuration to an `HControlPoint`. An `HControlPoint` is perfectly usable without it, but you can use a configuration to modify the behavior of it. Furthermore, by providing configuration you have the option to decide what `HDeviceProxy` types and `HServiceProxy` types are actually created when an `HControlPoint` instance builds its object model for a discovered device.

See also:
  Herqq::Upnp::HDeviceHost, Herqq::Upnp::HControlPoint, Device Model

## Typedef Documentation

typedef Functor<Herqq::Upnp::HDeviceProxy*, H_TYPELIST_1( const Herqq::Upnp::HDeviceInfo&)> HDeviceProxyCreator

This is a type definition for a callable entity that is used to create HDeviceProxy instances.

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

``

`Herqq::Upnp::HDeviceProxy* function(const Herqq::Upnp::HDeviceInfo&);`

``

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

     #include <HUpnpCore/HDeviceProxyCreator>

     #include "myclass.h"         // your code that contains the declaration for MyClass
     #include "my_hdeviceproxy.h" // your code that contains the declaration of MyHDeviceProxy

     namespace
     {
     Herqq::Upnp::HDeviceProxy* freefun(const Herqq::Upnp::HDeviceInfo&)
     {
         return new MyHDeviceProxy();
     }

     class MyFunctor
     {
     public:
         Herqq::Upnp::HDeviceProxy* operator(const Herqq::Upnp::HDeviceInfo&)
         {
             return new MyHDeviceProxy();
         }
     };
     }

     Herqq::Upnp::HDeviceProxy* MyClass::memfun(const Herqq::Upnp::HDeviceInfo&)
     {
         return new MyHDeviceProxy();
     }

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

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

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

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

typedef Functor<Herqq::Upnp::HDevice*, H_TYPELIST_1( const Herqq::Upnp::HDeviceInfo&)> HDeviceCreator

This is a type definition for a callable entity that is used to create HDevice instances.

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

``

`Herqq::Upnp::HDevice* function(const Herqq::Upnp::HDeviceInfo&);`

``

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

     #include <HDeviceCreator>

     #include "myclass.h"    // your code that contains the declaration for MyClass
     #include "my_hdevice.h" // your code that contains the declaration of MyHDevice

     namespace
     {
     Herqq::Upnp::HDevice* freefun(const Herqq::Upnp::HDeviceInfo&)
     {
         return new MyHDevice();
     }

     class MyFunctor
     {
     public:
         Herqq::Upnp::HDevice* operator(const Herqq::Upnp::HDeviceInfo&)
         {
             return new MyHDevice();
         }
     };
     }

     Herqq::Upnp::HDevice* MyClass::memfun(const Herqq::Upnp::HDeviceInfo&)
     {
         return new MyHDevice();
     }

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

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

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

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