As we have seen, UPnP services use SOAP to call actions published by the service. But instead of using WSDL to describe the service method calls, a
Service Control Protocol Description (SCPD) document is used. Apart from being much more restrictive when it comes to defining web methods, it also has an added feature that is not supported by normal web services: handling of GENA-type events and event subscriptions. When we implement a UPnP web service, we will do so by inheriting the UPnPWebService
class defined in the Clayster.Library.Internet.UPnP
namespace. This class in turn is inherited from the normal HttpServerWebService
class but adds event handling and subscription capabilities to the web service:
public class DigitalSecurityCameraStillImage : UPnPWebService { public DigitalSecurityCameraStillImage() : base("/StillImage") {
Still in the constructor of the web service, there are no subscribers to the state variables it publishes. By using the NotifySubscribers
method from within the constructor, we don't actually send the state variables to anybody. What we do is inform about the underlying event handling mechanism of the initial values of the existing state variables. This is done as follows:
this.NotifySubscribers ( new KeyValuePair<string, string> ("DefaultResolution", MainClass.defaultSettings.Resolution.ToString (). Substring (1)), new KeyValuePair<string, string> ( "DefaultCompressionLevel", MainClass.defaultSettings.CompressionLevel. ToString ()), new KeyValuePair<string, string> ("DefaultEncoding", MainClass.defaultSettings.ImageEncoding));
Before we can get the web service to work, we need to provide some properties. One is the SOAP
namespace of the web service, which is the UPnP-service-type URN:
public override string Namespace { get { return "urn:schemas-upnp-org:service:" + "DigitalSecurityCameraStillImage:1"; } }
We also need to provide the UPnP service identity:
public override string ServiceID { get { return "urn:upnp-org:serviceId:" + "DigitalSecurityCameraStillImage"; } }
If we want to be able to test the web service using a test form, we must enable this feature to be accessed from remote machines:
public override bool CanShowTestFormOnRemoteComputers { get { return true; } }
To facilitate working with evented state variables, we will define the service properties that encapsulate these state variables and notify the possible subscribers when changes occur. By using these properties, we make sure the corresponding state variables work as expected throughout the application. We begin with the DefaultResolution
state variable, remembering that the actual value lies in the static defaultSettings
database object:
public LinkSpriteJpegColorCamera.ImageSize DefaultResolution { get { return MainClass.defaultSettings.Resolution; } set { if(value != MainClass.defaultSettings.Resolution) { MainClass.defaultSettings.Resolution = value; MainClass.defaultSettings.UpdateIfModified (); this.NotifySubscribers ("DefaultResolution", MainClass.defaultSettings.Resolution.ToString ().Substring (1)); } } }
Similarly, we encapsulate the DefaultCompressionLevel
and DefaultEncoding
state variables in two other properties, implemented in the same manner.
Adding the actions from the service definition available at http://upnp.org/specs/ha/UPnP-ha-StillImage-v1-Service.pdf is a very simple task once we get this far. They are implemented as normal web methods. Input parameters are specified as normal method parameters, and output parameters are defined using the out
keyword. It's sufficient here to simply show the web method declarations:
public void GetDefaultEncoding(out string RetEncoding); public void SetDefaultEncoding(string ReqEncoding); public void GetAvailableEncodings(out string RetAvailableEncodings);
Similar methods are then implemented for the DefaultCompressionLevel
and DefaultResolution
state variables as well.
It is similarly a very easy task to add actions that provide the caller with URLs to our image (/camera
) and web presentation (/html
) resources, with appropriate query parameters. The web method declarations for the corresponding actions are as follows:
public void GetImageURL(HttpServerRequest Request, string ReqEncoding, string ReqCompression, string ReqResolution, out string RetImageURL); public void GetDefaultImageURL(HttpServerRequest Request, out string RetImageURL); public void GetImagePresentationURL(HttpServerRequest Request, string ReqEncoding, string ReqCompression, string ReqResolution, out string RetImagePresentationURL); public void GetDefaultImagePresentationURL(HttpServerRequest Request, out string RetImagePresentationURL);
3.133.126.199