Discovery-layer types in DPWS applications

The roles of Types in WS-Discovery messages is really clear for generic, non-DPWS services.  Types are qualified names expressed in the <d:Types> element of WS-Discovery messages, and these names identify a set of operations; the service advertised in the WS-Discovery message supports those operations.  In many cases a language like WSDL is used to express the connection between the name and the operations, but it's not strictly necessary.

When DPWS is involved, things are a little more complicated.  Remember that DPWS uses a Host service that is responsible for advertising all of the Hosted services.  The Hosted services are the ones that actually perform the device's functionality (e.g., WSD Toaster operations) so their types are advertised in the metadata that the Host service provides (e.g., the Host service would describe a Hosted service, and would advertise a type of t:WSDToasterService).

Now in most cases, the Host service does not actually implement any application-specific operations on its own; it only provides the metadata that allows a client to find the application-specific services.  Devices built like this don't advertise t:WSDToasterService at the device level because it's inaccurate--a client cannot send WSD Toaster operations directly to the Host service and expect them to work.  The Host service supports the WS-Transfer/Get request used to retrieve the device's metadata, that that operation is described by the dpws:Device type.

The difficulty is that clients cannot search for devices that support WSD Toaster services at the WS-Discovery layer.  After all, why should a device connect to hundreds of devices that have nothing to do with WSD Toaster?

To fix this problem, some specifications add an empty device-layer type with no associated operations, but which identifies that one or more service-layer types of interest can be found on this device.  So in this case, WSD Toaster would define a type t:WSDToasterDevice without any associated actions, but which is required on every device with a matching t:WSDToasterService service.  Clients can then merely search for t:WSDToasterDevice in WS-Discovery and only retrieve metadata for devices that contain toaster services.  t:WSDToasterDevice isn't useful on its own, but it does provide a hint that t:WSDToasterService is nearby.

DPWS v1.0 applications usually manually describe the association between their service-layer (t:WSDToasterService) and device-layer (t:WSDToasterDevice) types in normative text.  It usually looks something like this: "A device that supports one or more WSD Toaster services MUST advertise the t:WSDToasterDevice type at the DPWS DEVICE."  As a convenience, DPWS v1.1 Appendix C adds an optional WSDL attribute that can be used to express this association in a way that code generation tools can understand.  An example is shown in that appendix.

Now, this article doesn't completely describe the possible variations of these types, and the benefits and drawbacks of any of the arrangements.  Specification authors should be warned that this is a complex topic and shouldn't be taken lightly--at some point I may even put together a whole post on how to choose the layout.  But the basics I've described here are applicable to many of the most common cases (including WS-Print and WS-Scan), and should provide some clarity to specification authors, application-layer implementers, and generic stack implementers alike.