mUPnP for Objective-C
|
The programming guide describes how to create your UPnP™ devices and control points using mUPnP for C. The guide is divided into the following sections.
UPnP™*[^1] architecture is based on open networking to enable discovery and control of networked devices and services, such as media servers and players at home.
UPnP™ architecture is based on many standard protocols, such as GENA, SSDP, SOAP, HTTPU and HTTP. Therefore you have to understand and implement these protocols to create your devices of UPnP™.
mUPnP for C is a development package for UPnP™ developers. The mUPnP controls these protocols automatically, and supports to create your devices and control points quickly.
Please see the following site and documents to know about UPnP™ in more detail.
Document | URL |
---|---|
UPnP™ Forum | http://www.upnp.org/ |
Universal Plug and Play Device Architecture | http://www.upnp.org/download/UPnPDA10_20000613.htm |
Universal Plug and Play Vendor\'s Implementation Guide | http://www.upnp.org/download/UPnP_Vendor_Implementation_Guide_Jan2001.htm |
This section describes how to build and install the mUPnP package.
The mUPnP package has the header files, the source files, the project files to build the package and the some samples. The files are included the following directories.
File Type | Directory | |
---|---|---|
Source files | mupnp/src | |
Header Files | mupnp/include | |
Sample files | mupnp/sample | |
Project files | Unix (Automake) | mupnp |
WindowsXP (VisualC 6.0) | mupnp/*/win32/vc60 | |
T-Engine (GNU) | mupnp/*/tengine/gnu | |
uITRON | mupnp/*/itron | |
MacOSX | mupnp/*/macosx |
The mUPnP needs the following package to parse the XML and SOAP requests. Please get the parser package and install in your platform.
Package | URL |
---|---|
Expat | https://libexpat.github.io/ |
On Windows platform, you have to install latest Platform SDK and build on WindowsXP if you can. Please get the SDK and install in your platform.
Package | URL |
---|---|
Platform SDK | http://www.microsoft.com/msdownload/platformsdk/sdkupdate/ |
On T-Engine platform, you have to use the following development kit based on GNU GCC and TCP/IP protocol stack that supports the multicast protocol. The mUPnP uses the multicast protocol to search and announce UPnP devices and you have to use the protocol stack because the old package doesn't support the multicast protocol.
Package | URL |
---|---|
T-Engine Development Kit | http://www.personal-media.co.jp/te/welcome.html |
KASAGO for T-Engine | http://www.elwsc.co.jp/japanese/products/kasago_tengine.html |
The mUPnP supports the following TCP/IP protocol stack for T-Engine too, but the protocol stack doesn't support the multicast protocol and the functions are not implemented yet.
Package | URL |
---|---|
PMC T-Shell Kit | http://www.personal-media.co.jp/te/welcome.html |
The mUPnP supports the following compiler options to change the XML parser or disable UPnP functions. You haven't to set the options when you use Expat as the XML parser and all functions of the mUPnP.
Option | URL |
---|---|
MUPNP_XMLPARSER_LIBXML2 | Use libxml2 as the XML parser instead of Expat. |
MUPNP_NOUSE_CONTROLPOINT | Disable UPnP™ control point functions. |
MUPNP_NOUSE_SUBSCRIPTION | Disable UPnP™ subscription functions. |
MUPNP_NOUSE_ACTIONCTRL | Disable UPnP™ action control functions. |
MUPNP_NOUSE_QUERYCTRL | Disable UPnP™ query control functions. |
The mUPnP uses Expat as the default parser, but the following XML parser is supported with the compiler option. Please see the XML parser as the following site.
Package | URL |
---|---|
libxml2 | https://github.com/GNOME/libxml2 |
For Unix platforms, you can build the library and samples using the following steps. Use use the –enable-libxml2 option of the configure script instead of the compiler option. to use libxml2.
For Windows platforms The mUPnP has the platform projects for Visual Studio 2005. Please check the platform directories, mupnp/*/win32/vs2005, to use the projects. On WindowsCE, the mUPnP has no the platform
projects, but a contributer have been checked to compile the source codes normally.
For T-Engine platforms, you have to set the following compiler options. The mUPnP supports the process based and T-
Kernel based program. Use PROCESS_BASE option to compile the process based program. Please see the development manual of your T-Engine development kit.
Option | URL |
---|---|
TENGINE | Enable the platform option. |
MUPNP_TENGINE_NET_KASAGO | Enable KASAGO for T-Engine option. |
The mUPnP is compiled using the functions for PMC T-Shell Kit as the TCP/IP protocol stack, but it is no good because the protocol stack doesn't support the multicast protocol and the functions are not implemented yet.
To run applications using the mUPnP, the driver of the TCP/IP protocol stack has to be loaded and the network address has to be determined. Please see the manual of the protocol stack how to set the network interface.
You have to set EXPATROOT environment to an installed top directory of Expat on your shell as the following.
The source codes of Expat have to be included the "lib" directory.
I have built the library with T-Engine/SH7727 development kit with KASAGO for T-Engine. Please check the platform directories, mUPnPC/*/tengine/gnu , for the sample projects. To compile the samples, run configure script in the directory at first. Please see the development manual of your T-Engine development kit if you want to use on other TEngine platforms.
For MacOSX, I have released the wrapper class for Objective-C onCocoa. Currently, the framework supports only basic functions of the control point. Please use the standard C library for if you have to use all functions of mUPnP for C.
UPnP™ device is a networked device that supports the UPnP™ architecture. The device has some embedded devices and services, and the services have some actions and state variables. The device is created as a root device, and the root device is active using mUPnP for C.
This section describes how to create your UPnP™ device using mUPnP for C.
The following static structure diagram is related classes of mUPnP to create your device of UPnP™. The device has some embedded devices and services, and the services have some actions and state variables.
The above static structure diagram is modified simplify to explain.
At first, you have to make some description files of your devices and the services when you want to create your UPnP™ device..
The description of the root device should not have URLBase element because the element is added automatically when the device is created using the description.
The service descriptions are required to create a device, but the presentationURL and the iconList are recommended option. Please see UPnP™ specifications about the description format in more detail.
To create a UPnP™ device, use mupnp_device_new() to create the instance, set the descriptions using mupnp_device_parsedescription() and mupnp_service_parsedescription() from the memory description strings.
The device is created as a root device, and only the root device can be active using mupnp_device_start(). The device is announced to the UPnP™ network when the device is started. To terminate the device, use
mupnp_device_stop(). The following shows an example of the initiating device.
The active root device has some server processes, and returns the responses automatically when a control points sends a request to the device. For example, the device has a HTTP server to return the description files when a
control point gets the description file. The device searches an available port for the HTTP server automatically on the machine when the device is started.
The root device is created with the following default parameters, you can change the parameters using the following methods before the root device is started.
Parameter | Default | Function | |
---|---|---|---|
1 | HTTP port | 4004 | mupnp_device_sethttpport() |
2 | Description URI | /description.xml | mupnp_device_setdescriptionuri() |
3 | Lease time | 1800 | mupnp_device_setleasetime |
Your device is announced using mupnp_device_start() to the UPnP™ network using a notify message with ssdp::alive automatically when the device is started. When device is stopped using mupnp_device_stop(), a notify message is posted with ssdp::byebye. You can announce the notify messages using mupnp_device_announce() and mupnp_device_byebye().
When a control point sends a search request with M-SEARCH to the UPnP™ network, the active device send the search response to the control point automatically. The device repeats the announcement in the lease time automatically.
The devices may have some embedded devices. mupnp_device_getdevices() and mupnp_device_next() to get the embedded device list. The following example outputs friendly names of all embedded devices in a root device.
mUpnpDevice *childDev; for (childDev = mupnp_device_getdevices(rootDev), childDev != NULL; childDev = mupnp_device_next(childDev)) PrintDevice(childDev);
You can find a embedded device by the friendly name or UDN using mupnp_device_getdevicebyname(). The following example gets a embedded device by the friendly name.
Use mupnp_device_getservices() to access embedded services of the device. The service may have some actions and state variables. Use mupnp_service_getactions() and mupnp_action_next() to get the actions, and use mupnp_service_getstatevariables() and mupnp_statevariable_next() to the state variables. The following example outputs the all actions and state variables in a device.
You can find a service in the device by the service ID using mupnp_device_getservicebyname(), and you can find an action or state variable in the service by the name too. mupnp_device_getactionbyname() or
mupnp_service_getactionbyname() to find the action, and use mupnp_device_getstatevariablebyname() or mupnp_service_getstatevariablebyname () to find the state variable by the name. The following example gets
a service, an action and a state variable in a device by the name.
To receive action control events from control points, the device needs to implement the listener function. The listener must have an action, mUpnpAction, parameter. The input arguments has the passed values from the control point, set the response values in the output arguments and return a TRUE when the request is valid. Otherwise return a FALSE when the request is invalid. UPnPError response is returned to the control point automatically when the returned value is false or the device has no the interface. The UPnPError is INVALID_ACTION as default, but use mupnp_action_setstatuscode() to return other UPnP errors.
To receive query control events from control points, the device needs to implement the listener function. The listener must have a statevariable, mUpnpStateVariable, parameter, and return a TRUE when the request is valid. Otherwise return a FALSE when the request is invalid. UPnPError response is returned to the control point automatically when the returned value is false or the device has no the interface. The UPnPError is INVALID_ACTION as default, but use mupnp_statevariable_setstatuscode() to return other UPnP errors.
The following sample is a clock device. The device executes two action control requests and a query control request.
Use mupnp_action_setlistner() to set the action listener to a action. To set the listener to all actions in a device or service, use mupnp_device_setactionlistener() or mupnp_service_setactionlistener().
Similarly, Use mupnp_statevariable_setlistner() to set the query listener to a state variable. To set the listener to all state variables in a device or a service, use mupnp_device_setquerylistener() or mupnp_service_setquerylistener(). The following sample sets a listener into all actions in a device.
The control point may subscribe some events of the device. You don't need manage the subscription messages from control points because the device manages the subscription messages automatically. For example, the device adds a control point into the subscriber list when the control point sends a subscription message to the device, or the device removes the control point from the subscriber list when the control point sends a unsubscription message.
Use mupnp_statevariable_setvalue() when you want to send the state to the subscribers. The event is sent to the subscribers automatically when the state variable is updated using mupnp_statevariable_setvalue(). The following example updates a state variable, and the updated state is distributed to the subscribers automatically.
Using the following functions, you can set your original data to the objects. The default user data are NULL.
Object | setter | getter |
---|---|---|
mUpnpDevice | mupnp_device_setuserdata() | mupnp_device_getuserdata() |
mUpnpService | mupnp_service_setuserdata() | mupnp_service_getuserdata() |
mUpnpAction | mupnp_action_setuserdata() | mupnp_action_getuserdata() |
mUpnpStateVariable | mupnp_statevariable_setuserdata() | mupnp_statevariable_getuserdata() |
The following sample sets a structure data to a device object.
UPnP™ control point is a networked device that controls the UPnP™ devices in the UPnP™ network. The control point has some root devices in the UPnP™ network, and the control point can send action or query control messages to the discovered devices. The control point is created as a root device, and the root device is active using mUPnP for C.
This section describes how to create your UPnP™ control point using mUPnP for C.
The following static structure diagram is related classes of mUPnP to create your control point of UPnP™. The control point has some root devices in the UPnP™ network.
To create a UPnP™ control point, create a instance of ControlPoint class. Use mupnp_controlpoint_start() to active the control point. The control point multicasts a discovery message searching for all devices to the UPnP™ network automatically when the control point is active.
The active control point has some server processes, and returns the responses automatically when other UPnP™ devices send the messages to the control point. For example, the control point has a SSDP server to get MSEARCH responses, and the control point searches a available port for the SSDP server automatically on the machine when the control point is started.
The control point is created with the following default parameters. You can change the parameters using the following methods before the control point is started.
Parameter | Default | Function | |
---|---|---|---|
1 | HTTP port | 39500 | mupnp_controlpoint_seteventport() |
2 | SSDP port | 39400 | mupnp_controlpoint_setssdpresponseport() |
3 | Subscription URI | /eventSub | mupnp_controlpoint_seteventsuburi() |
4 | Search Response | 3 | mupnp_controlpoint_setssdpsearchmx() |
The control point receives notify events from devices in the UPnP™ network, and the devices are added or removed form the control point automatically. The expired device is removed from the device list of the control point automatically too. You don't manage the notify events, but you can receive the event to set the listener
function using mupnp_controlpoint_setssdplistener(). The following sample receives the notify messages.
You can update the device lists using mupnp_controlpoint_search(). The discovered root devices are added to the control point automatically, and you can receive the response to set the listener function using
mupnp_controlpoint_setssdpresponselistener(). The following sample receives the notify messages.
Use mupnp_controlpoint_getdevices() that returns only root devices to get the discovered device list. The following example outputs friendly names of the root devices.
You can find a root device by the friendly name using mupnp_controlpoint_getdevicebyname(). The following example gets a root device by the friendly name.
The control point can send action or query control messages to the discovered devices. To send the action control message, use mupnp_argument_setvalue() and mupnp_action_post(). You should set the action values to the all input arguments, and the output argument values is ignored if you set. The following sample posts a action control request that sets a new time, and output the response result.
Similarly, to send the query control message, use mupnp_statevariable_post(). The following sample posts a query control request, and output the return value.
The control point can subscribe events of the discovered devices. To get the state changes of the services, Use mupnp_controlpoint_subscribe() to subscribe the service events, and set the event listener function using mupnp_controlpoint_seteventlistener(). The
The mupnp_controlpoint_subscribe() returns true when the subscription is accepted from the service, and you can get the subscription id and timeout.