Comments on Networked Service Discovery and Messaging draft (UPnP-specific comments)

Below please find my comments on the UPnP discovery mechanism (Section 7.2)
in the Discovery API draft [1].

High level comments:
1. The description of the UPnP discovery algorithm begins with "For each
SSDP Presence Announcement [UPNP] - a HTTP NOTIFY request - received from a
user-agent-initiated SSDP Discovery Request [UPNP]". That in itself is
inaccurate. UPnP announcement messages are HTTP NOTIFY requests, but
responses received from a UA-initiated SSDP discovery request are HTTP 200
OK responses. In order to support responses received in response to
UA-initiated SSDP discovery requests, as is stipulated in Section 7.3, the
algorithm needs a few adjustments. For example, Step 2 and 3 rely on the NTS
header in the HTTP NOTIFY request. This header is not present in a search

2. UDA 1.1 introduces a new NTS value of ssdp:update. The algorithm does not
handle this at all, and would incorrectly treat it as an ssdp:byebye

3. Using the USN header to identify devices and services is insufficient. A
UPnP device is required to send multiple announcement messages for itself, 3
for the root device, 2 for each embedded device types, and 1 for each
embedded service types. Each of these messages would contain a different USN
value, but they all point to the same LOCATION and hence the same root
device. By using only the USN as the id to identify a UPnP device/service,
it would result in multiple copies of the same device/service in the UA's
list of devices/services, which differ only in the USN value.

As an example, a typical MediaRenderer device implements the AVTransport
service and the RenderingControl service, and is required to send 3+2+2=7
announcement messages. Among these seven messages, one would have a USN
value of "uuid:device-UUID::upnp:rootdevice", two would have USN values of
"uuid:device-UUID", another two would have USN values of
"uuid:device-UUID::urn:schemas-upnp-org:device:MediaRenderer:1", one with a
value of "uuid:device-UUID::urn:schemas-upnp-org:service:AVTransport:1", and
the last one with a value of
"uuid:device-UUID::urn:schemas-upnp-org:service:RenderingControl:1", where
"device-UUID" is a unique ID for the device. All of these messages would
point to the same LOCATION URL, where the device description file would
contain one device and two services. The algorithm described in Section 7.2
would result in a total of 5*2=10 network service records, instead of just

A better way to identify devices would be to use the device-UUID retrieved
from the UDN element in the device description document.

4. Additionally, directly plugging the USN value (or even the device-UUID
value) into the id attribute of a network service record (Step 7-2), and
eventually into the id attribute of the resulting NetworkService object
(Step 10), is problematic. A device that contains two services, as in the
above example, would result in two network service records/NetworkService
objects that have the same id attribute. In reality, one needs the
device-UUID together with a service ID to guarantee the uniqueness of a
network service record/NetworkService object.

5. The algorithm also assumes (in Step 7-9-1) that two services that have
the same USN value and type value are the same service. This is not always
the case, as some device types allow multiple instances of the same service
type to appear within a device. (See for example, which
explicitly describes the possibility of multiple instances of the
WANPPPConnection:1, WANIPConnection:2 and WANIPv6FirewallControl:1
services.) Instead of using type (serviceType) as the differentiator, the
name attribute (serviceId) should be used instead.

6. The algorithm cannot handle embedded devices, i.e. <device> elements
under the <deviceList> element under the root device descriptor file. Some
devices are known to use a dead simple root device (e.g. of type basic
device) and put the actual meaningful device(s) (such as a MediaServer), and
hence the actual meaningful services, under the deviceList. The algorithm
would not be able to properly discover and utilize such devices at all. 

7. ssdp:byebye messages are not handled correctly. In Step 3, an ssdp:byebye
message causes the algorithm to jump to Step 8, which doesn't make sense.
Step 8 operates on a service type, which is not available coming from Step
3, and is not available on an ssdp:byebye message at all. The case of a
byebye message needs to be handled in a completely separate step, which
encompasses identifying all the existing service records that belong to the
same UPnP device, marking each as Unavailable (readyState=2), and for each
of them, going through each NetworkServices object that contains the same
service, marking them as Unavailable (readyState=2, and firing
readystatechange event) and decrementing servicesAvailable (and firing
serviceunavailable events).

8. The eventing mechanism mandates a TIMEOUT header value of 86400. There is
absolutely no reason to have such a requirement. The length of an event
subscription is an implementation detail that should be left up to the

9. There is no description on when, if ever, and how the UA may cancel an
event subscription and abort the event listening steps. For example, the UA
should be allowed to cancel a subscription if it fails to renew the
subscription (after a certain number of attempts), when the NetworkService
object is being garbage-collected, an ssdp:byebye message is received etc.

Other finer details on the discovery algorithm:
- Step 2: s/at least one NTS, USN and Location parameters/at least one NTS,
at least one USN and at least one Location parameters/ to be unambiguous.
- Step 7-3 sets the network service record's name property to the value of
the serviceId property. The serviceId property is a rather cryptic string,
which certainly is not "a human-readable title for the service", which is
stated in the definition of the name property. (Well, it is human-readable
but not quite human-comprehensible.)
- Step 7-9-1 also needs to update the readyState attribute of the existing
service record to Available (1). readystatechange events might need to be
fired as well.
- Step 8 should be a sub-step of Step 7, as it needs to be performed on each
advertised service.
- Additionally Step 8 and 8-1 should be performed on NetworkServices
objects, not NetworkService objects. Also, instead of referring to the
object's type attribute, it should refer to the type used in the
getNetworkServices call that resulted in the creation of that
NetworkServices object.
- Step 8-2 s/announcement type/first occurrence of NTS/ (to be consistent)
- Step 8-2 The servicesAvailable attribute should only be incremented if
this is a new addition to the list of available service records (i.e. if the
condition in Step 7-9-1 is not satisfied), or if the readyState attribute of
the existing record changes from Unavailable to Available.

Other finer details on the events subscription algorithm:
- Step 3 (and Step 5-4-3) The value of the TIMEOUT header should be
Second-xxx, not just xxx.
- Step 5-4-4 After processing the 200 OK response, the algorithm should go
back to Step 5-2 (i.e. compute a new timeout date and start over).

Regards, Cathy.


Received on Monday, 6 August 2012 21:20:38 UTC