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