2

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.

4

2 回答 2

2

SCPD 文档必须添加 XML 声明。例如:<?xml version="1.0"?>

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
...
</scpd>
于 2012-06-14T03:11:23.893 回答
1

我已经针对设备和服务 XSD 验证了您的 XML,它们没有问题。我建议使用Intel Device Spy等外部工具检查您正在运行的 SwitchPower 设备,以了解您的 SCPD 是否真的由该设备提供服务。我有点怀疑SCPDURL前面没有斜线。根据 DeviceArchitecture,它“必须与设备描述所在的 URL 相关”,因此如果它不以斜杠开头,则可能会构建一些有趣的 URL。这样你确实得到了一个服务(因为设备描述提到了它)但它无法获得任何关于它的信息,所以你可能会得到某种无效的初始化。只是一个理论。这一切都取决于那些我一无所知的 IUPnP* 实现。

第二个想法,SwitchPower 有几个你没有在 SCPD 中指定的必需功能。但这可能不是问题,只要您(尚未)尝试以标准方式访问服务。

于 2012-06-13T14:54:50.187 回答