Why my UPnP device doesn't return services registered in UPnP SCPD xml file?

I register a UPnP device with:

var o: IUPnPRegistrar;
    W: string;
    R: HRESULT;
begin
  w := TFile.ReadAllText('UPnPDevice_Desc.xml');
  o := CoUPnPRegistrar.Create as IUPnPRegistrar;
  R := o.RegisterDevice(w, ...);
end;

File UPnPDevice_Desc.xml:

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
    <major>1</major>
    <minor>0</minor>
</specVersion>

<device>
    <pnpx:X_deviceCategory xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Other</pnpx:X_deviceCategory>
<!--<pnpx:X_hardwareId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Microsoft/SampleDevice/10000/urn:microsoft-com:device:SampleDimmerDevice:1</pnpx:X_hardwareId>-->
<!--    <df:X_containerId xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">{8C7B310D-90F8-40D4-B5EA-71D81821DEA6}</df:X_containerId>-->
    <deviceType>urn:example-com:device:uPnPDevice:1</deviceType>
    <friendlyName>My UPNP Device Hosted by Windows</friendlyName>
    <manufacturer>Example Company</manufacturer>
    <manufacturerURL>http://www.example.com/</manufacturerURL>
    <modelDescription>My UPnP Device</modelDescription>
    <modelName>uPnPDevice</modelName>
    <modelNumber>1001</modelNumber>
    <modelURL>http://www.example.com/</modelURL>
    <serialNumber>123456</serialNumber>
    <UDN>uuid:RootDevice</UDN>
    <UPC>00000-00001</UPC>

    <serviceList>
      <service>
        <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
        <controlURL></controlURL>
        <eventSubURL></eventSubURL>
        <SCPDURL>UPnPDevice_SCPD.xml</SCPDURL>
      </service>
    </serviceList>

    <presentationURL>DimmerPresentation.htm</presentationURL>
</device>
</root>

File UPnPDevice_SCPD.xml:

<scpd xmlns="urn:schemas-upnp-org:service-1-0">
<specVersion>
    <major>1</major>
    <minor>0</minor>
</specVersion>
<actionList>
    <action>
        <name>MagicOn</name>
    </action>
</actionList>
<serviceStateTable>
    <stateVariable>
        <name>OSMajorVersion</name>
        <dataType>i4</dataType>
    </stateVariable>
    <stateVariable>
        <name>OSMinorVersion</name>
        <dataType>i4</dataType>
    </stateVariable>
    <stateVariable>
        <name>OSBuildNumber</name>
        <dataType>i4</dataType>
    </stateVariable>
    <stateVariable>
        <name>OSMachineName</name>
        <dataType>string</dataType>
    </stateVariable>
</serviceStateTable>
</scpd>

I can confirm the UPnP device has been hosted in UPnP device host service by using IUPnPDeviceFinder or M-SEARCH to find the device.

The registry

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description

also contain the corresponding information:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\Files]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\Files\{B11E040A-6858-48BA-B1BD-85B4E8FCBA73}]
"Filename"="M:\\uPNP\\D16\\Win32\\Debug\\UPnPDevice_SCPD.xml"
"Mimetype"="text/xml; charset=\"utf-8\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\UDN Mappings]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\UPnP Device Host\Description\{00BB4949-F3B2-4F5A-B534-C6FE61B71F4E}\UDN Mappings\uuid:RootDevice]
@="uuid:00bb4949-f3b2-4f5a-b534-c6fe61b71f4e"

When query for services of the UPnP device using

var Enum: IEnumVARIANT;
    Fetched: Cardinal;
    K: OleVariant;
    P: IUPnPService;
    W: WideString;
    D: IUPnPDevice
begin
  ...
  if D.Services.Count > 0 then begin
    Enum := D.Services._NewEnum as IEnumVARIANT;
    Enum.Reset;
    while Enum.Next(1, K, Fetched) = S_OK do begin
      P := IDispatch(K) as IUPnPService;
    end;
  end;
end;

The D.Services.Count is 1 but the Enum doesn't fetch any services. Variable Fetched always return 0.

If I have query for Media Player UPnP device, It did return the services available.

Any ideas what's wrong with my UPnP Device that doesn't return services as indicated in SCPD xml file?

Once I registered the device, the XML description will change to:

<root xmlns="urn:schemas-upnp-org:device-1-0">
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>

    <device>
        <pnpx:X_deviceCategory xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Other</pnpx:X_deviceCategory>
<!--
<pnpx:X_hardwareId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">Microsoft/SampleDevice/10000/urn:microsoft-com:device:SampleDimmerDevice:1</pnpx:X_hardwareId>
-->
<!--
<df:X_containerId xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">{8C7B310D-90F8-40D4-B5EA-71D81821DEA6}</df:X_containerId>
-->
        <deviceType>urn:example-com:device:uPnPDevice:1</deviceType>
            <friendlyName>My UPNP Device Hosted by Windows</friendlyName>
            <manufacturer>Example Company</manufacturer>
            <manufacturerURL>http://www.example.com/</manufacturerURL>
            <modelDescription>My UPnP Device</modelDescription>
            <modelName>uPnPDevice</modelName>
            <modelNumber>1001</modelNumber>
            <modelURL>http://www.example.com/</modelURL>
            <serialNumber>123456</serialNumber>
            <UDN>uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9</UDN>
            <UPC>00000-00001</UPC>
            <serviceList>
                <service>
                    <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
                    <serviceId>urn:upnp-org:serviceId:SwitchPower:1</serviceId>
                    <controlURL>
                        /upnphost/udhisapi.dll?control=uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9+urn:upnp-org:serviceId:SwitchPower:1
                    </controlURL>
                    <eventSubURL>
                        /upnphost/udhisapi.dll?event=uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9+urn:upnp-org:serviceId:SwitchPower:1
                    </eventSubURL>
                    <SCPDURL>
                        /upnphost/udhisapi.dll?content=uuid:40c39217-e93b-4d0a-b5e0-abc582b2a2ed
                    </SCPDURL>
                </service>
            </serviceList>
        <presentationURL>
            /uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9/DimmerPresentation.htm?/upnphost/udhisapi.dll?content=uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9+uuid:9742f52d-f39f-4eaf-9ecf-bb742e9d79e9
        </presentationURL>
    </device>
</root>

Note the controlURL, eventSubURL and SCPDURL has been changed. Accessing

http://localhost:2869/upnphost/udhisapi.dll?content=uuid:40c39217-e93b-4d0a-b5e0-abc582b2a2ed

return exact content as file UPnPDevice_SCPD.xml.

Answers


The SCPD document must add XML declration. e.g.: <?xml version="1.0"?>

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
...
</scpd>

I have validated your XMLs against Device and Service XSDs and they have no problem. I recommend checking your running SwitchPower device with an external tool like Intel Device Spy, to find out whether your SCPD is really served by the device. I am somewhat suspicious about SCPDURL not being prepended with a slash. Per DeviceArchitecture it "MUST be relative to the URL at which the device description is located" so if it doesn't start with slash, some funny URL might be constructed. That way you indeed get a Service (because Device description mentions it) but it can't obtain any information about it, so you might get some sort of invalid initialization. Just a theory. This all depends on those IUPnP* implementations i know nothing about.

Second thought, SwitchPower has several REQUIRED functions which you are not specifying in the SCPD. But that might not be an issue as long as you are not (yet) trying to access the service in a standard way.


Need Your Help

Image zoom with jQuery

jquery image zoom

I've been searching for what plug in is used in these 2 sites for the full screen image viewing: