discovery-api/Overview.src.html
author Robin Berjon <robin@berjon.com>
Fri, 03 Aug 2012 15:58:23 +0200
changeset 185 ef42cb5f9a60
parent 183 21b44409354f
child 192 3ecf12df315d
permissions -rw-r--r--
validity errors
     1 <!DOCTYPE html>
     2 <html>
     3   <head>
     4     <title>Networked Service Discovery and Messaging</title>
     5     <meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
     6     <script type="text/javascript" class='remove'>
     7       var respecConfig = {
     8           specStatus: "ED",
     9           shortName:  "discovery-api",
    10           edDraftURI: "http://w3c-test.org/dap/discovery-api/",
    11           editors: [
    12                 {   name:       "Rich Tibbett",
    13                     //url:        "http://richt.me/",
    14                     company:    "Opera Software ASA",
    15                     companyURL: "http://opera.com/" },
    16                 {   name:       "Clarke Stevens",
    17                     //url:      "",
    18                     company:    "CableLabs",
    19                     companyURL: "http://cablelabs.com/"
    20                 }
    21           ],
    22           noIDLIn:  true,
    23 
    24           wg:           "Device APIs and Policy Working Group",
    25           wgURI:        "http://www.w3.org/2009/dap/",
    26           wgPublicList: "public-device-apis",
    27           wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/43696/status",
    28       };
    29     </script>
    30 
    31     <script src='http://www.w3.org/Tools/respec/respec-w3c-common' type="text/javascript" class='remove' async></script>
    32     <style type="text/css">
    33       /* Custom CSS optimizations (Richard Tibbett) */
    34 
    35       /* Add better spacing to sections */
    36       section, .section { margin-bottom: 2em; }
    37 
    38       /* Reduce note & issue render size */
    39       .note, .issue { font-size:0.8em; }
    40 
    41       /* Add addition spacing to <ol> and <ul> for rule definition */
    42       ol.rule li, ul.rule li { padding:0.6em; }
    43 
    44       pre.widl { border: solid thin; background: #EEEEEE; color: black; padding: 0.5em 1em; position: relative; }
    45       pre.widl :link, pre.widl :visited { color: #000; background: transparent; }
    46       pre.widl:before { content: "IDL"; font: bold small sans-serif; padding: 0.5em; background: white; position: absolute; top: 0; margin: -1px 0 0 -4em; width: 1.5em; border: thin solid; border-radius: 0 0 0 0.5em }
    47 
    48       div.example { border: solid thin red; background: #F7DFE5; color: black; padding: 0.5em 1em; position: relative; margin: 1em 0 1em 4.6em; width: auto; }
    49       div.example:before { content: "EXAMPLE"; font: bold small sans-serif; padding: 0.5em; background: red; color: white; position: absolute; top: 0; margin: -1px 0 0 -7.6em; width: 5em; border: thin solid red; border-radius: 0 0 0 0.5em }
    50 
    51       dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #DDFFDD; }
    52       hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; }
    53       dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; }
    54       dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; }
    55       dl.domintro dd p { margin: 0.5em 0; }
    56       dl.domintro code {font-size: inherit; font-style: italic; }
    57       dl.domintro:before { display: table; margin: -1em -0.5em 0.5em auto; width: auto; content: 'This box is non-normative. Implementation requirements are given below this box.'; color: red; border: solid 2px; background: white; padding: 0 0.25em; }
    58     </style>
    59   </head>
    60 
    61   <body>
    62     <section id='abstract'>
    63       <p>
    64         This specification defines a mechanism for an HTML document to discover and subsequently communicate with <abbr title="Hypertext Transfer Protocol">HTTP</abbr>-based services
    65         advertised via common discovery protocols within a user's network.
    66       </p>
    67     </section>
    68 
    69     <section id='sotd'>
    70       <p>
    71         This document represents the early consensus of the group on the scope and features of the proposed
    72         API.
    73       </p>
    74     </section>
    75 
    76     <section class="informative">
    77       <h3>Introduction</h3>
    78 
    79       <p>To enable Web pages to connect and communicate with Local-networked Services provided over HTTP, this specification introduces the
    80       <a href="#navigatornetworkservice"><code>NavigatorNetworkService</code></a> interface.</p>
    81 
    82       <p>
    83          Using this <abbr title="Application Programming Interface">API</abbr> consists of requesting a well-known service type, known by developers and advertised by Local-networked Devices. User authorization, where the user connects the web page to one or more discovered services,
    84          is expected before the web page is able to interact with any Local-networked Services.
    85       </p>
    86 
    87       <p>
    88          A web page creates a request to obtain connectivity to services running in the network by specifying a well-known discovery service type that it wishes to interact with.
    89       </p>
    90 
    91       <p>
    92          The user agent, having captured all advertised services on the network from the Service Discovery mechanisms included in this recommendation, attempts to match
    93       the requested service type to a discovered service according to the processing described herein.
    94       </p>
    95 
    96       <p>
    97           If a service connectivity request is successful then the Web page is provided with the necessary information to communicate with the authorized Local-networked Service.
    98           If the request fails then the Web page will receive an error callback containing an error code describing the cause of Local-networked Service connectivity failure.
    99       </p>
   100 
   101       <p>
   102          Once connected to a Local-networked Service the Web page can send requests and receive responses to the Local-networked Service via the messaging format and appropriate channel inferred from the service type
   103          authorized via the provided API.
   104          The Web page, once connected, can also receive service-pushed events, in the messaging format supported by the Local-networked Device, if such event subscription functionality is provided by the
   105          connected Local-networked Service.
   106       </p>
   107 
   108       <div class="example">
   109        <p>Example of requesting a DNS-SD advertised service:</p>
   110        <hr />
   111        <pre class="highlight">function showServices( services ) {
   112   // Show a list of all the services provided to the web page
   113   for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name );
   114 }
   115 
   116 navigator.getNetworkServices('zeroconf:_boxee-jsonrpc._tcp', showServices);</pre>
   117       </div>
   118 
   119       <div class="example">
   120         <p>Example of requesting a UPnP advertised service, also handling error conditions:</p>
   121         <hr />
   122         <pre class="highlight">function showServices( services ) {
   123   // Show a list of all the services provided to the web page
   124   for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name );
   125 }
   126 
   127 function error( e ) {
   128   console.log( "Error occurred: " + e.code );
   129 }
   130 
   131 navigator.getNetworkServices('upnp:urn:schemas-upnp-org:service:ContentDirectory:1', showServices, error);</pre>
   132       </div>
   133 
   134       <div class="example">
   135         <p>Example of requesting either a DNS-SD or UPnP advertised service:</p>
   136         <hr />
   137         <pre class="highlight">function showServices( services ) {
   138   // Show a list of all the services provided to the web page (+ service type)
   139   for(var i = 0, l = services.length; i < l; i++)
   140      console.log( services[i].name + '(' + services[i].type + ')' );
   141 }
   142 
   143 navigator.getNetworkServices([
   144   'zeroconf:_boxee-jsonrpc._tcp',
   145   'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'
   146 ], showServices);</pre>
   147       </div>
   148 
   149       <p>For more detailed examples see the <a href="#examples">Examples</a> section.
   150     </section>
   151 
   152     <section
   153      id='conformance'>
   154 
   155      <p>Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the
   156      meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.</p>
   157 
   158      <p>
   159       Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements are to be interpreted as requirements on user agents.
   160      </p>
   161 
   162      <p>
   163       Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in
   164       this specification are intended to be easy to follow, and not intended to be performant.)
   165      </p>
   166 
   167      <p>
   168       The only conformance class defined by this specification is a <dfn>user agent</dfn>.
   169      </p>
   170 
   171      <p>
   172       User agents may impose implementation-specific limits on otherwise unconstrained inputs, e.g. to prevent denial of service attacks, to guard against running out of memory, or to work
   173       around platform-specific limitations.
   174      </p>
   175 
   176      <p>
   177       When support for a feature is disabled (e.g. as an emergency measure to mitigate a security problem, or to aid in development, or for performance reasons), user agents must act as if
   178       they had no support for the feature whatsoever, and as if the feature was not mentioned in this specification. For example, if a particular feature is accessed via an attribute in a Web
   179       IDL interface, the attribute itself would be omitted from the objects that implement that interface - leaving the attribute on the object but making it return null or throw an exception
   180       is insufficient.
   181      </p>
   182 
   183       <section>
   184          <h3>Dependencies</h3>
   185 
   186          This specification relies on several other underlying specifications.
   187 
   188          <dl>
   189             <dt>HTML</dt>
   190             <dd>Many fundamental concepts from HTML are used by this specification. [[!HTML5]]</dd>
   191             <dt>WebIDL</dt>
   192             <dd>The IDL blocks in this specification use the semantics of the WebIDL specification. [[!WEBIDL]]</dd>
   193          </dl>
   194       </section>
   195     </section>
   196 
   197     <section>
   198       <h3>Terminology</h3>
   199 
   200       <p>
   201          The construction "a <code>Foo</code> object", where <code>Foo</code> is actually an interface, is sometimes used instead of the more accurate "an object implementing the interface <code>Foo</code>".
   202       </p>
   203 
   204       <p>
   205          The term DOM is used to refer to the API set made available to scripts in Web applications, and does not necessarily imply the existence of an actual <code>Document</code> object or of any
   206          other <code>Node</code> objects as defined in the DOM Core specifications. [[!DOM4]]
   207       </p>
   208 
   209       <p>
   210          An IDL attribute is said to be <em>getting</em> when its value is being retrieved (e.g. by author script), and is said to be <em>setting</em> when a new value is assigned to it.
   211       </p>
   212 
   213       <p>
   214         A <dfn>valid service type</dfn> is a string that begins with <code>upnp:</code> or <code>zeroconf:</code> followed by one or more characters in the ranges U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E.
   215       </p>
   216 
   217       <p>
   218         A <a>valid service type</a> provided in the <code>type</code> attribute of the <code>getNetworkServices()</code> method will be matched against the services currently contained in the <a>list of available service records</a> according to the algorithms defined in this specification.
   219       </p>
   220     </section>
   221 
   222     <section>
   223      <h2>Requesting networked services</h2>
   224 
   225 
   226 <pre class="widl">[Supplemental, NoInterfaceObject]
   227 interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> {
   228   // Obtain a Local-networked Service
   229   void <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type,
   230                            in <a href="#navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</a> successCallback,
   231                            in optional <a href="#navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</a> errorCallback );
   232 };
   233 <a class="externalDFN" href="http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">Navigator</a> implements <a href="#navigatornetworkservice">NavigatorNetworkService</a>;
   234 
   235 [Callback=FunctionOnly, NoInterfaceObject]
   236 interface <dfn id="navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</dfn> {
   237   void handleEvent( in <a href="#networkservices">NetworkServices</a> services );
   238 };
   239 
   240 [NoInterfaceObject]
   241 interface <dfn id="navigatornetworkserviceerror">NavigatorNetworkServiceError</dfn> {
   242   const unsigned short <a href="#dom-navigatornetworkserviceerror-permission_denied">PERMISSION_DENIED_ERR</a> = 1;
   243   const unsigned short <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix">UNKNOWN_TYPE_PREFIX_ERR</a> = 2;
   244   readonly attribute unsigned short <a href="#dom-navigatornetworkserviceerror-code">code</a>;
   245 };
   246 
   247 [Callback=FunctionOnly, NoInterfaceObject]
   248 interface <dfn id="navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</dfn> {
   249   void handleEvent( in <a href="#navigatornetworkserviceerror">NavigatorNetworkServiceError</a> error );
   250 };
   251 </pre>
   252 
   253   <section>
   254    <h2>Methods</h2>
   255 
   256       <dl class="domintro">
   257         <dt>
   258           <var title="">window</var>
   259            .
   260           <code title="dom-navigator">
   261             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">navigator</a>
   262           </code>
   263            .
   264           <code title="dom-navigator-getNetworkServices">
   265             <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>
   266           </code>
   267           (
   268           <var title="">type</var>
   269           ,
   270           <var title="">successCallback</var>
   271            [,
   272           <var title="">errorCallback</var>
   273            ] )
   274         </dt>
   275         <dd>
   276           <p>Prompts the user to select one or more discovered network services that have advertised support for the requested service type.</p>
   277           <p>
   278             The
   279             <var title="">type</var>
   280              argument contains one or more <a>valid service type</a> tokens that the web page would like to interact with.
   281           </p>
   282           <p>
   283             If the user accepts, the
   284             <var title="">successCallback</var>
   285              is
   286           invoked, with one or more
   287             <code>
   288               <a href="#networkservice"><code>NetworkService</code></a>
   289             </code>
   290              objects as
   291           its argument.
   292           </p>
   293           <p>
   294             If the user declines, the
   295             <var title="">errorCallback</var>
   296              (if
   297           any) is invoked.
   298           </p>
   299         </dd>
   300       </dl>
   301 
   302        <div>
   303           <p>
   304             When the <dfn id="dom-navigator-getnetworkservices" title="dom-navigator-getnetworkservices"><code>getNetworkServices(type, successCallback[, errorCallback])</code></dfn> method is called, the <a>user agent</a> MUST run the following steps:
   305           </p>
   306 
   307           <ol class="rule">
   308             <li>
   309                If <var>successCallback</var> is empty or is not an object of type <code>Function</code> then the <a>user agent</a> MUST abort these steps.
   310             </li>
   311 
   312             <li>
   313               Let <var>requested control types</var> be initially set to an empty array.
   314             </li>
   315 
   316             <li>
   317                If <var>type</var> is an array consisting of one or more <a>valid service type</a> tokens, then let <var>requested control types</var> by the value of <var>type</var>, removing any non-<a>valid service type</a> tokens from the resulting array.
   318             </li>
   319 
   320             <li>
   321                If <var>type</var> is a string consisting of one <a>valid service type</a> token, then let <var>requested control types</var> be an array containing one item with a value of <var>type</var>.
   322             </li>
   323 
   324             <li>
   325                If <var>requested control types</var> is an array that contains at least one or more <a title="valid service type">valid service type</a> tokens then continue to the step labeled <em>process</em> below. Otherwise, the <a>user agent</a> MUST <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   326                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 2
   327                   (<a href="#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) as its argument,
   328                    abort any remaining steps and return.
   329             </li>
   330 
   331             <li>
   332                <em>Process</em>: Let <var>services found</var> be an empty array.
   333             </li>
   334 
   335             <li>
   336                For each <var>available service</var> in the <a>list of available service records</a> run the following steps:
   337                <ol class="rule">
   338                   <li>
   339                     For each <var>requested control type</var> in <var>requested control types</var>: If <var>available service</var>'s <code>type</code> attribute equals the <var>requested control type</var> then let <var>matched service</var> equal the value of <var>available service</var> and continue at the step labeled <var>attach</var> below.
   340                   </li>
   341                   <li>
   342                      Continue at the next <var>available service</var>.
   343                   </li>
   344                   <li>
   345                      <em>Attach</em>: If <var>matched service</var> is not empty then run the following steps:
   346 
   347                      <ol class="rule">
   348                         <li>
   349                            Let <var>new service object</var> be a new <a href="#networkservice"><code>NetworkService</code></a> object, mapping the parameters of
   350                      <var>matched service</var> to this new object where possible.
   351                         </li>
   352                         <li>
   353                            Append <var>new service object</var> to the <var>services found</var> array.
   354                         </li>
   355                      </ol>
   356                   </li>
   357                </ol>
   358             </li>
   359 
   360             <li>
   361                If <var>services found</var> is an empty array, then the <a>user agent</a> MUST <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   362                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   363                  (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   364             </li>
   365 
   366             <li>
   367                Return, and run the remaining steps asynchronously.
   368             </li>
   369 
   370             <li>
   371                Optionally, e.g. based on a previously-established user preference, for security reasons, or due to platform limitations, the <a>user agent</a> MAY <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   372                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   373                  (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   374             </li>
   375 
   376             <li>
   377                   The <a>user agent</a> MUST prompt the user in a user-agent-specific manner for permission to provide the
   378                   <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" class="externalDFN">entry script</a>'s
   379                   <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin" class="externalDFN">origin</a> with an array of
   380                   <a href="#networkservice"><code>NetworkService</code></a> objects representing the user-authorized subset of <var>services found</var>.
   381 
   382                <p>
   383                   If the user grants permission to access one or more networked services then the <a>user agent</a> SHOULD include an
   384                   "ongoing local-network communication" indicator.
   385                </p>
   386 
   387                <p>If the user denies permission, then the <a>user agent</a> MUST <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>errorCallback</var>, if it is provided and is an object of type <code>Function</code>, with a new <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object whose
   388                 <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   389                 (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   390               </p>
   391 
   392               <p>
   393                 If the user never responds, this algorithm stalls on this step.
   394               </p>
   395 
   396             </li>
   397 
   398             <li>
   399                Let <var>services</var> be the array of one or more <a href="#networkservice"><code>NetworkService</code></a> objects for which the user granted permission.
   400             </li>
   401 
   402             <li>
   403                For each Object <var>service</var> in <var>services</var>, run the following substeps:
   404 
   405                <ol class="rule">
   406                   <li>
   407                      Add the <var>service</var>'s <code>url</code> parameter to the <a>entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> whitelist</a>.
   408                   </li>
   409                   <li>
   410                     If <var>service</var> was originally created from a UPnP discovery process and the <var>service</var>'s <code>eventsUrl</code> parameter is not empty then <a>setup a UPnP Events Subscription</a> for <var>service</var>.
   411                   </li>
   412                </ol>
   413             </li>
   414 
   415             <li>
   416                Let <var>services manager</var> be a new <a href="#networkservices"><code>NetworkServices</code></a> object.
   417             </li>
   418 
   419             <li>
   420                Set <var>services manager</var>'s <code>servicesAvailable</code> attribute to the length of <var>services</var>.
   421             </li>
   422 
   423             <li>
   424               Store the set of <var>services</var> as <dfn id="current_authorized_services">current authorized services</dfn> internally against the newly created <var>services manager</var> object.
   425             </li>
   426 
   427             <li>
   428                The <a>user agent</a> MUST <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a> to invoke <var>successCallback</var> with
   429                <var>services manager</var> as its argument.
   430             </li>
   431 
   432           </ol>
   433 
   434           <p>
   435             The <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#task-source" class="externalDFN">task source</a> for these
   436             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#concept-task" class="externalDFN">tasks</a> is the
   437             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#user-interaction-task-source" class="externalDFN">user interaction task source</a>.
   438           </p>
   439 
   440           <p>
   441             When a <a href="#networkservice"><code>NetworkService</code></a> object is provided to a Web page, the <a>user agent</a> MUST add the <code>url</code> property
   442              to the <dfn>entry script origin's URL whitelist</dfn>. This list enables the
   443             Web page to override and initiate cross-site resource requests towards these URLs, and any sub-resources of these URLs, within the current
   444             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" class="externalDFN">entry script</a>'s
   445             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin" class="externalDFN">origin</a> via various existing mechanisms (e.g. Web Sockets, Server-Sent Events,
   446             Web Messaging, XMLHttpRequest).
   447          </p>
   448 
   449          <p>
   450             If the user navigates away from the current browsing context, the <a>user agent</a> MUST remove all previously whitelisted urls from the <a>entry script origin's URL whitelist</a>.
   451             There is no persistence to network service selections provided to a web page. It is not possible to access a previously white-listed networked service without the necessary user authorization in all of the following cases:
   452             <ul>
   453               <li>If the current script is reloaded at any point in the same or different window.</li>
   454               <li>if the current script reinvokes the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method at any point in its execution.</li>
   455               <li>If the user navigates forward or back in their history to reload the current page.</li>
   456               <li>If a script is running in a different origin.</li>
   457             </ul>
   458          </p>
   459 
   460       </div>
   461       </section>
   462 
   463       <section>
   464          <h3>Error Handling</h3>
   465 
   466       <dl class="domintro">
   467         <dt>
   468           <var title="">error</var>
   469            .
   470           <code title="dom-NavigatorNetworkServiceError-code">
   471             <a href="#dom-navigatornetworkserviceerror-code">code</a>
   472           </code>
   473         </dt>
   474         <dd>
   475           <p>
   476             Returns the current error's error code. At the current time, this may be <code>1</code> or <code>2</code>, for which the
   477             corresponding error constants
   478             <a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and
   479             <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are defined.
   480           </p>
   481         </dd>
   482       </dl>
   483 
   484          <p>
   485             The <dfn id="dom-navigatornetworkserviceerror-code" title="dom-navigatornetworkserviceerror-code"><code>code</code></dfn> attribute of a
   486             <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object MUST return the code for the error, which will be one of the following:
   487          </p>
   488 
   489          <dl>
   490             <dt>
   491                <dfn id="dom-navigatornetworkserviceerror-permission_denied" title="dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> (numeric value 1)
   492             </dt>
   493             <dd>
   494                The user denied the page permission to access any services.
   495             </dd>
   496             <dt>
   497                <dfn id="dom-navigatornetworkserviceerror-unknown_type_prefix" title="dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn> (numeric value 2)
   498             </dt>
   499             <dd>
   500                No <a>valid service type</a> tokens were provided in the method invocation.
   501             </dd>
   502          </dl>
   503 
   504       </section>
   505 
   506       </section>
   507       <section>
   508       <h2>Obtaining networked services</h2>
   509 
   510       <p>
   511          The <a href="#networkservices"><code>NetworkServices</code></a> interface is the top-level response object from a call to <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> and provides access to a set of user-authorized <a href="#networkservice"><code>NetworkService</code></a> objects for the given request.
   512       </p>
   513 
   514 <pre class="widl">
   515 [NoInterfaceObject]
   516 interface <dfn id="networkservices">NetworkServices</dfn> {
   517   readonly attribute unsigned long    <a href="#dom-networkservices-length">length</a>;
   518   getter <a href="#networkservice">NetworkService</a> (unsigned long index);
   519   <a href="#networkservice">NetworkService</a>? <a href="#dom-networkservices-getservicebyid">getServiceById</a>(DOMString id);
   520 
   521   readonly attribute unsigned long    <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>;
   522 
   523   // event handler attributes
   524            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservices-onserviceavailable">onserviceavailable</a>;
   525            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservices-onserviceunavailable">onserviceunavailable</a>;
   526 
   527 };
   528 
   529 <a href="#networkservices">NetworkServices</a> implements <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget" class="externalDFN">EventTarget</a>;
   530 </pre>
   531 
   532       <section>
   533       <h2>Attributes</h2>
   534 
   535         <dl class="domintro">
   536           <dt>
   537             <code title="dom-networkservices-length">
   538               <a href="#dom-networkservices-length">length</a>
   539             </code>
   540           </dt>
   541           <dd>
   542             <p>
   543               Returns the current number of services in the respective object's <a>current authorized services</a>.
   544             </p>
   545           </dd>
   546           <dt>
   547             <code title="dom-networkservices-servicesavailable">
   548               <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>
   549             </code>
   550           </dt>
   551           <dd>
   552             <p>
   553               Returns the current number of services matching one of the app-requested <a>valid service type</a> tokens that are actively available within the user's current network.
   554             </p>
   555           </dd>
   556         </dl>
   557 
   558         <div>
   559            <p>
   560               The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute MUST return the number of services represented in the object's corresponding <a>current authorized services</a> list at the time of getting.
   561            </p>
   562 
   563            <p>
   564               The <dfn id="dom-networkservices-servicesavailable"><code>servicesAvailable</code></dfn> attribute MUST return the number of services available in the
   565               user's network that match the <a>valid service type</a> that was initially used to create the current <a href="#networkservices"><code>NetworkServices</code></a> object.
   566               By default, <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> MUST be set to <code>1</code>.
   567            </p>
   568 
   569            <p>
   570              When a previously unknown instance of a networked service matching one or the requested <a href="#dfn-valid-service-type">valid service types</a> becomes available on the user's current network, the <a>user agent</a> MUST fire a new simple
   571              event at the <a href="#dom-networkservices-onserviceavailable"><code>onserviceavailable</code></a> event handler.
   572            </p>
   573 
   574            <p>
   575              When a previously known instance of a networked service matching one or the requested <a href="#dfn-valid-service-type">valid service types</a> becomes unavailable on the user's current network, the <a>user agent</a> MUST fire a new simple
   576              event at the <a href="#dom-networkservices-onserviceunavailable"><code>onserviceunavailable</code></a> event handler.
   577            </p>
   578         </div>
   579 
   580       </section>
   581 
   582       <section>
   583       <h2>Methods</h2>
   584         <dl class="domintro">
   585         <dt>
   586           <code title="networkservices-getter">
   587             <a href="#networkservices">services</a>
   588           </code>
   589           [
   590           <var title="">index</var>
   591           ]
   592         </dt>
   593         <dd>
   594           <p>
   595             Returns the specified <a href="#networkservice"><code>NetworkService</code></a> object.
   596           </p>
   597         </dd>
   598         <dt>
   599           <code title="networkservices-getter">
   600             <a href="#networkservices">services</a>
   601           </code>
   602           .
   603           <code title="dom-networkservices-getservicebyid">
   604             <a href="#dom-networkservices-getservicebyid">getServiceById</a>
   605           </code>
   606           (
   607           <var title="">id</var>
   608           )
   609         </dt>
   610         <dd>
   611           <p>
   612             Returns the <a href="#networkservice"><code>NetworkService</code></a> object with the given identifier, or null if no
   613             service has that identifier.
   614           </p>
   615         </dd>
   616       </dl>
   617 
   618       <p>
   619         A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of zero or more <a>current authorized services</a>, of which zero or more can be available at a time. Each item in <a>current authorized services</a> is represented by a <a href="#networkservice"><code>NetworkService</code></a> object.
   620       </p>
   621 
   622       <p class="note">
   623         Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the first has the index 0, and each subsequent service is numbered one higher than the previous one. If the <a>user agent</a> dynamically adds or removes network services for any reason, then the indices of the services in <a>current authorized services</a> will change dynamically. If the set of network services changes entirely, then all the previous services will be removed from <a>current authorized services</a> and replaced with new services.
   624       </p>
   625 
   626       <p>
   627         The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a> of <a href="#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to the number of items in <a>current authorized services</a> represented by the respective object minus one, if any services are represented in <a>current authorized services</a>. If a <a href="#networkservices"><code>NetworkServices</code></a> object represents no <a>current authorized services</a>, it has no <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a>.
   628       </p>
   629 
   630       <p>
   631         To <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property" class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a <a href="#networkservices"><code>NetworkServices</code></a> object's <a>current authorized services</a>, the user agent MUST return the <a href="#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th service in <a>current authorized services</a>.
   632       </p>
   633 
   634       <p>
   635         The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method MUST return the first <a href="#networkservice"><code>NetworkService</code></a> object in <a>current authorized services</a> represented by the respective object whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the <var>id</var> argument.
   636         When no services in <a>current authorized services</a> match the given argument, the method MUST return null.
   637       </p>
   638 
   639       <p>
   640          Services available within the local network can connect and disconnect at different times during the execution of a web page. A <a>user agent</a> can
   641          inform a web page when the state of networked services matching the requested <a>valid service type</a> change. Web pages can use this information to enable in-page experiences for communicating the state of networked services
   642          with the ability to change the particular service or set of services the page is connected to by re-invoking the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method.
   643       </p>
   644 
   645       </section>
   646 
   647       <section>
   648       <h2>Events</h2>
   649 
   650       <p>
   651          The following are the event handlers (and their corresponding event handler event types) that must be supported, as IDL attributes, by all objects implementing the <a href="#networkservices"><code>NetworkServices</code></a> interface:
   652        </p>
   653 
   654        <table border="1">
   655         <thead>
   656           <tr>
   657             <th>
   658               <span title="event handlers">Event handler</span>
   659             </th>
   660             <th>
   661               <span>Event handler event type</span>
   662             </th>
   663           </tr>
   664         </thead>
   665         <tbody>
   666           <tr>
   667             <td>
   668               <dfn id="dom-networkservices-onserviceavailable" title="dom-NetworkServices-onserviceavailable">
   669                 <code>onserviceavailable</code>
   670               </dfn>
   671             </td>
   672             <td>
   673               <code title="event-serviceavailable">serviceavailable</code>
   674             </td>
   675           </tr>
   676           <tr>
   677             <td>
   678               <dfn id="dom-networkservices-onserviceunavailable" title="dom-NetworkServices-onserviceunavailable">
   679                 <code>onserviceunavailable</code>
   680               </dfn>
   681             </td>
   682             <td>
   683               <code title="event-serviceunavailable">serviceunavailable</code>
   684             </td>
   685           </tr>
   686         </tbody>
   687       </table>
   688 
   689       <p>
   690          Events with an event type of <code>serviceavailable</code> or <code>serviceunavailable</code> defined in this specification are simple <code>Event</code> objects.
   691       </p>
   692 
   693       </section>
   694 
   695     </section>
   696     <section>
   697     <h2>Communicating with a networked service</h3>
   698 
   699 <p>
   700    The <a href="#networkservice"><code>NetworkService</code></a> interface is used to provide a set of connection information for an HTTP service endpoint and if available, service events, running on a networked device.
   701 </p>
   702 
   703 <pre class="widl">
   704 [NoInterfaceObject]
   705 interface <dfn id="networkservice">NetworkService</dfn> {
   706   readonly attribute DOMString        <a href="#dom-networkservice-id">id</a>;
   707   readonly attribute DOMString        <a href="#dom-networkservice-name">name</a>;
   708   readonly attribute DOMString        <a href="#dom-networkservice-type">type</a>;
   709   readonly attribute DOMString        <a href="#dom-networkservice-url">url</a>;
   710   readonly attribute DOMString        <a href="#dom-networkservice-config">config</a>;
   711 
   712   const unsigned short <a href="#dom-networkservice-AVAILABLE">AVAILABLE</a>      = 1;
   713   const unsigned short <a href="#dom-networkservice-UNAVAILABLE">UNAVAILABLE</a>    = 2;
   714   readonly attribute unsigned short   <a href="#dom-networkservice-readystate">readyState</a>;
   715 
   716   // event handler attributes
   717            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onreadystatechange">onreadystatechange</a>;
   718            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onmessage">onmessage</a>;
   719 };
   720 
   721 <a href="#networkservice">NetworkService</a> implements <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget" class="externalDFN">EventTarget</a>;
   722 </pre>
   723 
   724 <section>
   725   <h2>Attributes</h2>
   726 
   727       <dl class="domintro">
   728         <dt>
   729           <var title="">service</var>
   730            .
   731           <code title="dom-networkservice-id">
   732             <a href="#dom-networkservice-id">id</a>
   733           </code>
   734         </dt>
   735         <dd>
   736           <p>
   737             A unique identifier for the given user-selected service instance.
   738           </p>
   739         </dd>
   740         <dt>
   741           <var title="">service</var>
   742            .
   743           <code title="dom-networkservice-name">
   744             <a href="#dom-networkservice-name">name</a>
   745           </code>
   746         </dt>
   747         <dd>
   748           <p>
   749             The name of the user-selected service.
   750           </p>
   751         </dd>
   752         <dt>
   753           <var title="">service</var>
   754            .
   755           <code title="dom-networkservice-type">
   756             <a href="#dom-networkservice-type">type</a>
   757           </code>
   758         </dt>
   759         <dd>
   760           <p>
   761             The <a>valid service type</a> token value of the user-selected service.
   762           </p>
   763         </dd>
   764         <dt>
   765           <var title="">service</var>
   766            .
   767           <code title="dom-networkservice-url">
   768             <a href="#dom-networkservice-url">url</a>
   769           </code>
   770         </dt>
   771         <dd>
   772           <p>
   773             The control URL endpoint (including any required port information) of the user-selected control service that has been added to the <a>entry script origin's URL whitelist</a>.
   774           </p>
   775         </dd>
   776         <dt>
   777           <var title="">service</var>
   778            .
   779           <code title="dom-networkservice-config">
   780             <a href="#dom-networkservice-config">config</a>
   781           </code>
   782         </dt>
   783         <dd>
   784           <p>
   785             The configuration information associated with the service depending on the requested service type.
   786           </p>
   787         </dd>
   788       </dl>
   789 
   790           <p>
   791             The <dfn id="dom-networkservice-id"><code>id</code></dfn> attribute is a unique identifier for the service. Two services provided at different times or on different objects MUST have the same <a href="#dom-networkservice-id"><code>id</code></a> value.
   792          </p>
   793 
   794          <p>
   795             The <dfn id="dom-networkservice-name"><code>name</code></dfn> attribute represents a human-readable title for the service.
   796          </p>
   797 
   798          <p>
   799              The <dfn id="dom-networkservice-type"><code>type</code></dfn> attribute reflects the value of the <a>valid service type</a> of the service.
   800           </p>
   801 
   802          <p>
   803             The <dfn id="dom-networkservice-url"><code>url</code></dfn> attribute is an <a href="http://www.w3.org/TR/html5/urls.html#absolute-url" class="externalDFN">absolute URL</a> pointing to the root HTTP
   804             endpoint for the service that has been added to the <a>entry script origin's URL whitelist</a>. Web pages can subsequently use this value for implicit cross-document messaging via various existing mechanisms (e.g. Web Sockets, Server-Sent Events, Web Messaging, XMLHttpRequest).
   805          </p>
   806 
   807          <p>
   808             The <dfn id="dom-networkservice-config"><code>config</code></dfn> attribute provides the raw configuration information extracted from the given network service.
   809          </p>
   810 
   811       </section>
   812 
   813       <section>
   814          <h3>States</h3>
   815 
   816       <dl class="domintro">
   817         <dt>
   818           <var title="">service</var>
   819            .
   820           <code title="dom-networkservice-readystate">
   821             <a href="#dom-networkservice-readystate">readyState</a>
   822           </code>
   823         </dt>
   824         <dd>
   825           <p>
   826             Returns the current state.
   827           </p>
   828         </dd>
   829       </dl>
   830 
   831          A <a href="#networkservice"><code>NetworkService</code></a> object can be in several states. The <dfn id="dom-networkservice-readystate"><code>readyState</code></dfn> attribute MUST return the current state of the networked service,
   832          which MUST be one of the following values:
   833 
   834          <dl>
   835            <dt>
   836              <dfn id="dom-networkservice-AVAILABLE" title="dom-networkservice-AVAILABLE">
   837                <code>AVAILABLE</code>
   838              </dfn>
   839               (numeric value
   840              1)
   841 
   842 
   843            </dt>
   844            <dd>
   845              <p>The object is connected to its service endpoint.
   846 
   847             </p>
   848            </dd>
   849            <dt>
   850              <dfn id="dom-networkservice-UNAVAILABLE" title="dom-networkservice-UNAVAILABLE">
   851                <code>UNAVAILABLE</code>
   852              </dfn>
   853               (numeric value
   854              2)
   855            </dt>
   856            <dd>
   857              <p>The object is not connected to its service endpoint.
   858             </p>
   859            </dd>
   860          </dl>
   861 
   862       </section>
   863 
   864       <section>
   865          <h3>Events</h3>
   866 
   867       <p>
   868          The following are the event handlers (and their corresponding event handler event types) that must be supported, as IDL attributes, by all objects implementing the
   869          <a href="#networkservice"><code>NetworkService</code></a> interface:
   870        </p>
   871 
   872        <table border="1">
   873         <thead>
   874           <tr>
   875             <th>
   876               <span title="event handlers">Event handler</span>
   877             </th>
   878             <th>
   879               <span>Event handler event type</span>
   880             </th>
   881           </tr>
   882         </thead>
   883         <tbody>
   884           <tr>
   885             <td>
   886               <dfn id="dom-networkservice-onmessage" title="dom-NetworkService-onmessage">
   887                 <code>onmessage</code>
   888               </dfn>
   889             </td>
   890             <td>
   891               <code title="event-message">message</code>
   892             </td>
   893           </tr>
   894           <tr>
   895             <td>
   896               <dfn id="dom-networkservice-onreadystatechange" title="dom-NetworkService-onreadystatechange">
   897                 <code>onreadystatechange</code>
   898               </dfn>
   899             </td>
   900             <td>
   901               <code title="event-onreadystatechange">readystatechange</code>
   902             </td>
   903           </tr>
   904         </tbody>
   905       </table>
   906 
   907       <p>
   908          Events with an event type of <code>message</code> defined in this specification are <a href="http://dev.w3.org/html5/postmsg/#messageevent" class="externalDFN"><code>MessageEvent</code></a> objects as defined in [[!POSTMSG]].
   909       </p>
   910 
   911       <p>
   912          Events with an event type of <code>readystatechange</code> defined in this specification are simple <code>Event</code> objects.
   913       </p>
   914 
   915       </section>
   916    </section>
   917 
   918       <section>
   919             <h2>Service Discovery</h2>
   920 
   921       <p>
   922          A <a>user agent</a> conforming to this specification MAY implement <abbr title="Simple Service Discovery Protocol">SSDP</abbr> [[!UPNP-DEVICEARCH11]] and Zeroconf [[!ZEROCONF]] service discovery mechanisms
   923          to enable Web pages to request and connect with HTTP services running on networked devices, discovered via either mechanism, through this API. When a <a>user agent</a> implements either of these service discovery mechanisms, then it MUST conform to the corresponding algorithms provided in this section of the specification.
   924       </p>
   925       <p>
   926          This section presents how the results of these two service discovery
   927          mechanisms will be matched to requested service types and how their properties will be applied to any resulting <a href="#networkservice"><code>NetworkService</code></a> objects.
   928       </p>
   929 
   930       <p>
   931          It is expected that user agents will perform these service discovery mechansisms asynchronously and periodically update the <a>list of networked devices</a> as required. The timing of any
   932          service discovery mechanisms is an implementation detail left to the discretion of the implementer (e.g. once on user agent start-up, every X seconds during user agent execution or on
   933          invocation of this API from a Web page).
   934       </p>
   935 
   936       <p>
   937          The <dfn>list of available service records</dfn> is a single dynamic internal lookup table within user agents that is used to track the current services available in the network at any given time.
   938          At any point during the running of either of the two service discovery mechanisms then existing entries within this table can be updated, entries can be added and entries can be removed as the status of networked
   939          services changes. Each record contained within this table contains the attributes: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code> and <code>config</code>.
   940       </p>
   941 
   942             <section>
   943          <h4>Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</h4>
   944 
   945          <p>
   946             For each DNS response received from a user-agent-initiated Multicast DNS Browse for <abbr title="DNS Pointer Record">PTR</abbr> records with the name <code>_services._dns-sd._udp</code> on the resolved recommended automatic browsing
   947    domain [[!MDNS]], the <a>user agent</a> MUST run the following steps:
   948          </p>
   949 
   950          <ol class="rule">
   951 
   952             <li>Let <var>service mDNS responses</var> be an array of PTR records received by issuing a Multicast DNS Browse for PTR records with the name of the current discovered service type.</li>
   953 
   954             <li>For each Object <var>service mDNS response</var> in <var>service mDNS responses</var>, run the following steps:
   955                <ol>
   956 
   957                   <li>
   958                      Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>.
   959                   </li>
   960 
   961                   <li>
   962                      Set <var>network service record</var>'s <code>id</code> property to the value of the full PTR Service Instance Name [[!MDNS]].
   963                   </li>
   964 
   965                   <li>
   966                      Set <var>network service record</var>'s <code>name</code> property to the value of the PTR Service Instance Name's <var>Instance</var> component [[!MDNS]].
   967                   </li>
   968 
   969                   <li>
   970                      Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>zeroconf:</code> followed by the value of the PTR Service Instance Name's <var>Service</var> component [[!MDNS]].
   971                   </li>
   972 
   973                   <li>
   974                      Set <var>network service record</var>'s <code>url</code> property to the resolvable Service URL obtained from performing an DNS-SD Lookup [[!DNS-SD]] of the current service from the PTR record provided [[!MDNS]].
   975                   </li>
   976 
   977                   <li>
   978                      Set <var>network service record</var>'s <code>config</code> property to the string value of the contents of the first DNS-SD TXT record associated with the <var>service mDNS response</var> as defined in [[!DNS-SD]].
   979                   </li>
   980 
   981                   <li>
   982                      For each Object <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
   983                      <ol class="rule">
   984 
   985                        <li>
   986                         If the <var>existing service record</var>'s <code>id</code> property matches the value of the <var>network service record</var>'s <code>id</code>, then set the
   987                         value of <var>existing service record</var> in the current <a>list of available service records</a>  to the value of the
   988                         <var>network service record</var> and skip the next step.
   989                        </li>
   990                      </ol>
   991                   </li>
   992 
   993                   <li>
   994                      Add <var>network service record</var> to the <a>list of available service records</a>.
   995                   </li>
   996 
   997                   <li>
   998                      For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
   999 
  1000                      <ol class="rule">
  1001                         <li>
  1002                            If the <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
  1003                            current <a>network service record</a>'s <code>type</code> property then continue at the next available active
  1004                            <a href="#networkservice"><code>NetworkService</code></a> object.
  1005                         </li>
  1006                         <li>
  1007                            Increment the <code>servicesAvailable</code> attribute of the <a href="#networkservices"><code>NetworkServices</code></a> object by <code>1</code>.
  1008                         </li>
  1009                      </ol>
  1010                   </li>
  1011             </ol>
  1012            </li>
  1013          </ol>
  1014 
  1015       </section>
  1016 
  1017       <section>
  1018          <h5>Universal Plug-and-Play (<abbr title="Universal Plug-and-Play">UPnP</abbr>)</h5>
  1019 
  1020          <p>
  1021             For each SSDP Presence Announcement [[!UPNP-DEVICEARCH11]] - a HTTP NOTIFY request - received from a user-agent-initiated SSDP Discovery Request [[!UPNP-DEVICEARCH11]], the <a>user agent</a> MUST run the following steps:
  1022          </p>
  1023 
  1024          <ol class="rule">
  1025             <li>
  1026                Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the received SSDP Presence Announcement, with each key being the name of a HTTP header and its
  1027                value being that HTTP header's accompanying value.
  1028             </li>
  1029 
  1030             <li>
  1031                If <var>ssdp device</var> does not contain at least one <var>NTS</var>, <var>USN</var> and <var>Location</var> parameter, then the <a>user agent</a> MUST abort these steps.
  1032             </li>
  1033 
  1034             <li>
  1035                If the first occurrence of <var>NTS</var> has a value other than <code>ssdp:alive</code>, then continue to the step labeled <var>update service monitor</var> below.
  1036             </li>
  1037 
  1038             <li>
  1039                Let <var>root device descriptor file</var> contain the contents of the file located at the URL provided in the first occurrence of <var>Location</var> obtained according to the rules
  1040                defined in the section 'Retrieving a description using HTTP' [[!UPNP-DEVICEARCH11]].
  1041             </li>
  1042 
  1043             <li>
  1044                If <var>root device descriptor file</var> is empty, then the <a>user agent</a> MUST abort these steps.
  1045             </li>
  1046 
  1047             <li>
  1048                Let <var>advertised services</var> be a <a>list of all advertised services</a> obtained from the <var>root device descriptor file</var> containing all sub-nodes of the <code>serviceList</code> node as described in
  1049                the section 'Device Description' [[!UPNP-DEVICEARCH11]].
  1050             </li>
  1051 
  1052             <li>
  1053                For each Object <var>advertised service</var> in <var>advertised services</var> run the following steps:
  1054                <ol class="rule">
  1055 
  1056                   <li>
  1057                      Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>eventsUrl</code>, <code>config</code>.
  1058                   </li>
  1059 
  1060                   <li>
  1061                      Set <var>network service record</var>'s <code>id</code> property to the string value of the first occurrence of <var>ssdp device</var>'s <var>USN</var> parameter.
  1062                   </li>
  1063 
  1064                   <li>
  1065                      Set <var>network service record</var>'s <code>name</code> property to the string value of the first occurrence of the <var>service</var>'s <code>serviceId</code> property.
  1066                   </li>
  1067 
  1068                   <li>
  1069                      Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>upnp:</code> followed by the string value of the first occurrence of the <var>service</var>'s <code>serviceType</code> property.
  1070                   </li>
  1071 
  1072                   <li>
  1073                      Set <var>network service record</var>'s <code>url</code> property to the string value of the first occurrence of the <var>service</var>'s <code>controlURL</code> property.
  1074                   </li>
  1075 
  1076                   <li>
  1077                      Set <var>network service record</var>'s <code>config</code> property to the string value of the first occurrence of the <var>device</var> property.
  1078                   </li>
  1079 
  1080                   <li>
  1081                      If <var>service</var>'s <code>eventSubURL</code> property is empty, then continue to the step labeled <em>register</em> below.
  1082                   </li>
  1083 
  1084                   <li>
  1085                      Set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first occurrence of the <var>service</var>'s <code>eventSubURL</code> property.
  1086                   </li>
  1087 
  1088                   <li>
  1089                      <em>Register</em>: For each Object <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
  1090                      <ol class="rule">
  1091 
  1092                        <li>
  1093                         If the <var>existing service record</var>'s <var>id</var> property matches the value of the first occurrence of <var>USN</var> and the
  1094                         <var>existing service record</var>'s <code>type</code> property matches the value of <var>network service record</var>'s <code>type</code>, then set the
  1095                         value of <var>existing service record</var> in the current <a>list of available service records</a>  to the value of the
  1096                         <var>network service record</var> and skip the next step.
  1097                        </li>
  1098                      </ol>
  1099                   </li>
  1100 
  1101                   <li>
  1102                      Add <var>network service record</var> to the <a>list of available service records</a>.
  1103                   </li>
  1104 
  1105                </ol>
  1106             </li>
  1107             <li>
  1108                <em>Update Service Monitor</em>: For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
  1109 
  1110                <ol class="rule">
  1111                   <li>
  1112                      If this <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
  1113                      current <a>network service record</a>'s <code>type</code> property then continue at the next available active
  1114                      <a href="#networkservice"><code>NetworkService</code></a> object.
  1115                   </li>
  1116                   <li>
  1117                      If the <var>announcement type</var> equals <code>ssdp:alive</code> then Increment the <code>servicesAvailable</code> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
  1118                      object by <code>1</code>. Otherwise, decrement the <code>servicesAvailable</code> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
  1119                      object by <code>1</code>.
  1120                   </li>
  1121                </ol>
  1122             </li>
  1123          </ol>
  1124 
  1125          <p>
  1126             A <dfn>user-agent generated callback url</dfn> is a Local-network accessible URL endpoint that a <a>user agent</a> must generate and maintain for receiving HTTP NOTIFY requests from UPnP Event sources.
  1127          </p>
  1128 
  1129          <p>When the <a>user agent</a> is to <dfn>setup a UPnP Events Subscription</dfn>, it is to run the following steps with the current <var>network service record</var> object:</p>
  1130 
  1131          <ol class="rule">
  1132             <li>
  1133                If <var>network service record</var>'s <code>eventsUrl</code> property is empty then the <a>user agent</a> MUST abort these steps.
  1134             </li>
  1135 
  1136             <li>
  1137                Let <var>callback URL</var> be the value of creating a new <a>user-agent generated callback url</a>.
  1138             </li>
  1139 
  1140             <li>
  1141                Send a HTTP SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with an integer value of
  1142                <code>86400</code> and a <em>CALLBACK</em> header
  1143                with a string value of <var>callback URL</var> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
  1144             </li>
  1145 
  1146             <li>
  1147                If a non-200 OK response is received from the HTTP SUBSCRIBE request then the <a>user agent</a> MUST abort these steps.
  1148             </li>
  1149 
  1150             <li>
  1151                On receiving a valid 200 OK response, run the following steps:
  1152 
  1153                <ol class="rule">
  1154                   <li>
  1155                      Let <var>callback ID</var> equal the string value of the first included <em>SID</em> header, if it exists.
  1156                   </li>
  1157                   <li>
  1158                      Let <var>timeout date</var> equal the sum of the current UTC date value plus the integer value of the first included <em>TIMEOUT</em> header, if it exists.
  1159                   </li>
  1160                   <li>
  1161                      Run the following steps aynchronously and continue to the step labeled <em>listen</em> below.
  1162                   </li>
  1163                   <li>
  1164                      <em>Refresh Subscription</em>: Run the following steps at a set interval (X) within the <a>user agent</a>:
  1165 
  1166                      <ol class="rule">
  1167                         <li>
  1168                            Let <var>current date</var> equal the current UTC date.
  1169                         </li>
  1170                         <li>
  1171                            If <var>current date</var> is less than the <var>timeout date</var> then continue to the step labeled <em>refresh subscription</em> above.
  1172                         </li>
  1173                         <li>
  1174                            Send a HTTP SUBSCRIBE request with a <em>SID</em> header with the string value of <var>callback ID</var> and a <em>TIMEOUT</em> header
  1175                            with an integer value of <code>86400</code> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
  1176                         </li>
  1177                         <li>
  1178                            On receiving a valid 200 OK, update <var>callback ID</var> with the string value of the first included <em>SID</em> header, if it exists. All other HTTP
  1179                            responses should cause the <a>user agent</a> to continue from the step labeled <em>refresh subscription</em> above.
  1180                         </li>
  1181                      </ol>
  1182 
  1183                   </li>
  1184 
  1185                   <li>
  1186                      <em>Listen</em>: For each HTTP NOTIFY request received at the <var>callback URL</var> the <a>user agent</a> is to run the following steps:
  1187 
  1188                      <ol class="rule">
  1189                         <li>
  1190                            Let <var>content clone</var> be the result of obtaining the message body of the HTTP NOTIFY request. If <var>content clone</var> is empty, then the <a>user agent</a> MUST abort these steps.
  1191                         </li>
  1192                         <li>
  1193                           Create a new <code>message</code> event that uses the <a href="http://dev.w3.org/html5/postmsg/#messageevent" class="externalDFN"><code>MessageEvent</code></a> interface [[!POSTMSG]], with the name <code>message</code>,
  1194                            which does not bubble, is not cancelable, and has no default action.
  1195                         </li>
  1196                         <li>
  1197                            Let the <code>data</code> attribute of the event have the DOMString value of <var>content clone</var>.
  1198                         </li>
  1199                         <li>
  1200                            <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a> to
  1201                             dispatch the newly created event at the current <a><code>NetworkService</code></a> object.
  1202                         </li>
  1203                      </ol>
  1204                   </li>
  1205 
  1206                </ol>
  1207 
  1208             </li>
  1209          </ol>
  1210 
  1211          </section>
  1212 
  1213          <section>
  1214             <h3>Network Topology Monitoring</h3>
  1215 
  1216                   <div>
  1217                      <p>
  1218                         When the <a>user agent</a> detects that the user has dropped from their connected network, then it MUST run the following steps:
  1219                      </p>
  1220 
  1221                      <ol class="rule">
  1222                         <li>
  1223                            Flush all entries from the <a>list of available service records</a>.
  1224                         </li>
  1225                         <li>
  1226                            For each <a href="#networkservice"><code>NetworkService</code></a> object currently active in the <a>user agent</a> perform the following steps:
  1227 
  1228                            <ol class="rule">
  1229                               <li>
  1230                                  Set the <a href="#dom-networkservice-readystate"><code>readyState</code></a> attribute to <code>2</code> (<a href="#dom-networkservice-UNAVAILABLE"><code>UNAVAILABLE</code></a>).
  1231                               </li>
  1232                               <li>
  1233                                  Create a new <code>readystatechange</code> event that uses the <code>Event</code> interface which does not bubble, is not cancelable, and has no default action.
  1234                               </li>
  1235                               <li>
  1236                                  <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a> to
  1237                                         dispatch the newly created event at the <a href="#networkservice"><code>NetworkService</code></a> object.
  1238                               </li>
  1239                            </ol>
  1240                         </li>
  1241                      </ol>
  1242 
  1243                      <p>
  1244                         When the <a>user agent</a> detects that the user has connected to a new network, then it SHOULD run the following steps:
  1245                      </p>
  1246 
  1247                      <ol class="rule">
  1248                         <li>
  1249                            Re-issue an mDNS search and SSDP discovery search and handle the responses according to the processing defined in <a href="#service-discovery">Section 6: Service Discovery</a>.
  1250                         </li>
  1251                      </ol>
  1252                   </div>
  1253          </section>
  1254       </section>
  1255 
  1256    <section>
  1257       <h3>Garbage collection</h3>
  1258 
  1259       <p>
  1260          A <a><code>NetworkService</code></a> object containing a <code>url</code> parameter currently in the <a>entry script origin's URL whitelist</a> MUST NOT be garbage collected.
  1261       </p>
  1262 
  1263       <p>
  1264          Only when the user navigates away from the current browsing context can <a><code>NetworkService</code></a> objects be garbage-collected and records in the <a>entry script origin's URL whitelist</a> be removed.
  1265       </p>
  1266 
  1267    </section>
  1268 
  1269 
  1270     <section>
  1271       <h3>Use Cases and Requirements</h3>
  1272 
  1273       <p>This section covers what the requirements are for this API, as well as illustrates some use cases.</p>
  1274 
  1275       <ul class="rule">
  1276          <li>
  1277             Once a user has given permission, user agents should provide the ability for Web pages to communicate directly with a Local-networked Service.
  1278             <ul class="rule">
  1279                <li>
  1280                   Example: A web-based TV remote control. A Web page wants to control the current user's TV, changing the programming shown or increasing/decreasing/muting the
  1281                   volume of the Local-networked Device. The Web page requests a service type that is known to be implemented by television sets to which it has the
  1282                   application logic to communicate. Local devices providing the request service types are discovered and presented to the user for authorization. The user selects one
  1283                   or more of the discovered television sets to be accessible to the current Web page and then clicks 'Share'. The Web page can now communicate directly with
  1284                   the user-authorized Local-networked services.
  1285                </li>
  1286             </ul>
  1287          </li>
  1288 
  1289          <li>
  1290            Web pages should be able to communicate with Local-networked Services using the messaging channel supported by those Devices.
  1291            <ul class="rule">
  1292             <li>
  1293                Example: A Web page advertises that it is capable of controlling multiple Home Media Servers. The user can select their Home Media Server type from a drop-down list, at which point the
  1294                Web page sends a request to the user agent to connect with the associated service type of the Home Media Server. The Media Server selected implements a Web Socket channel for
  1295                bi-directional service communication and so the Web page opens a web socket to the requested Media Server and can communicate as required via that appropriate channel.
  1296             </li>
  1297            </ul>
  1298          </li>
  1299 
  1300          <li>
  1301            Web pages should be able to communicate with Local-networked Services using the messaging format supported by those Devices.
  1302            <ul class="rule">
  1303             <li>
  1304                Example: A Web page advertises that it is capable of interacting with and controlling multiple types of Home Media Server. The user can select their Home Media Server type from a drop-down list or known Media Servers, at which point the
  1305                Web page sends a request to the user agent to connect with the associated service type (and, optionally, the associated event type) of the Home Media Server. The communiciation protocols supported by Home Media Servers typically vary
  1306                between UPnP, JSON-RPC, Protocol Buffers or other messaging formats depending on the Home Media Server requested. The Web page is able to communicate with the user-selected Home Media
  1307                Server in the messaging format supported by that Device, which, in this example is a simple key/value pair text format.
  1308             </li>
  1309            </ul>
  1310          </li>
  1311 
  1312          <li>
  1313            Web pages should not be able to communicate with Local-networked Services that have not been authorized by the user thereby maintaining the user's privacy.
  1314            <ul class="rule">
  1315             <li>
  1316                Example: A Web page requests access to one type of Local-networked service. The user authorizes access to that particular service. Other services running on that same device, and on other devices
  1317                within the network, should not be accessible to the current Web page.
  1318             </li>
  1319            </ul>
  1320          </li>
  1321 
  1322          <li>
  1323            A user should be able to share one or more Local-networked Services based on a particular service type request from a Web page.
  1324            <ul class="rule">
  1325             <li>
  1326                Example: A Web page is capable of interacting with a specific profile of Local-networked Service. As such, it makes a request to the user agent to access those services, of which multiple matches
  1327                are found. The user is capable of selecting one or more of the discovered services to share with the Web page. The Web page can then implement a drag-and-drop interface for the user to drag specific
  1328                actions on to one or more of the authorized Local-networked Services.
  1329             </li>
  1330            </ul>
  1331          </li>
  1332 
  1333          <li>
  1334            User agents should provide an API exposed to script that exposes the features above. The user is notified by UI anytime interaction with Local-networked Services is requested, giving the user
  1335            full ability to cancel or abort the transaction. The user selects the Local-networked Services to be connected to the current Web page, and can cancel these at any time. No invocations to
  1336            these APIs occur silently without user intervention.
  1337          </li>
  1338       </ul>
  1339     </section>
  1340 
  1341           <section class="informative appendix">
  1342              <h3>Examples</h3>
  1343 
  1344            <div class="example">
  1345             <p>This sample code exposes a button. When clicked, this button is disabled and the user is prompted to offer a network service. The user may also select multiple network services. When the user has authorized a network service to be connected to the web page then the web page issues a simple command to get a list of all the albums stored on the connected media player service.
  1346             <p>The button is re-enabled only when the connected network service disconnects for whatever reason (the service becomes unavailable on the network, the user disconnects from their current network or the user revokes access to the service from the current web page). At this point the user can re-click the button to select a new network service to connect to the web page and the above steps are repeated.</p>
  1347             <p>The provided service type identifier and service interaction used in this example is based on the well-defined service type and messaging format supported by the <a href="http://xbmc.org/about/">XBMC Media Server</a>. </p>
  1348             <hr />
  1349             <pre class="highlight">&lt;input type="button" value="Start" onclick="start()" id="startBtn"/&gt;
  1350 &lt;div id="debugconsole">&lt;/div>
  1351 
  1352 &lt;script>
  1353  var startBtn = document.getElementById('startBtn'),
  1354      debug = document.getElementById('debugconsole');
  1355 
  1356  function start() {
  1357    if(navigator.getNetworkServices) {
  1358       navigator.getNetworkServices('zeroconf:_xbmc-jsonrpc._tcp', gotXBMCService, error);
  1359       startBtn.disabled = true;
  1360    } else {
  1361       debug.innerHTML += "&lt;br&gt;Service Discovery API not supported!";
  1362    }
  1363  }
  1364 
  1365  function gotXBMCService(services) {
  1366 
  1367 // Listen for service disconnect messages
  1368 
  1369    services[0].addEventListener('readystatechange', function ( e ) {
  1370      if(services[0].readyState === services[0].UNAVAILABLE) {
  1371        debug.innerHTML += "&lt;br>" + services[0].name + " disconnected.";
  1372        startBtn.disabled = false;
  1373      }
  1374    }, false);
  1375 
  1376 // Send a service message to get albums list (and process the service response)
  1377 
  1378    var svcXhr = new XMLHttpRequest();
  1379    svcXhr.open("POST", services[0].url + "/getAlbums"); // services[0].url and its subresources have been
  1380                                                         // whitelisted for cross-site XHR use in this
  1381                                                         // current browsing context.
  1382 
  1383    svcXhr.setRequestHeader('Content-Type', 'application/json-rpc');
  1384 
  1385    svcXhr.addEventListener('readystatechange', function ( response ) {
  1386      if( response.readyState != 4 || response.status != 200 )
  1387         return;
  1388      debug.innerHTML += "&lt;br>" + services[0].name + " response received: ";
  1389      debug.textContent += JSON.parse(response.responseText);
  1390    }, false);
  1391 
  1392    var svcMsg = [
  1393      { "jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "genreid": -1,
  1394          "artistid": -1, "start": -1, "end": -1 }, "id": "1" }
  1395    ];
  1396 
  1397    svcXhr.send(JSON.stringify(svcMsg));
  1398    debug.innerHTML += "&lt;br>" + services[0].name + " request sent: ";
  1399    debug.textContent += JSON.stringify(svcMsg);
  1400 
  1401  }
  1402 
  1403  function error( err ) {
  1404    debug.innerHTML += "&lt;br>An error occurred obtaining a local network service.";
  1405    startBtn.disabled = false;
  1406  }
  1407 &lt;/script></pre>
  1408            </div>
  1409 
  1410            <div class="example">
  1411             <p>
  1412              This sample exposes a drop-down list containing a number of common Home-based audio devices. When the user selects an audio device from the list provided, they are prompted to authorize a network service
  1413              based on the service type requested. The user may also select multiple network services matching the selected service type.
  1414              In this example, the user selects their make as being <var>Sony</var> and their model as being <var>Bravia S1000</var> from which the Web page can derive a service type
  1415              (<var>urn:schemas-upnp-org:service:RenderingControl:1</var>).
  1416              <br /><br />Once the user has authorized the device, the web page sends a simple mute command according to the messaging format supported by the device.
  1417             </p>
  1418             <hr />
  1419             <pre class="highlight">&lt;select name="make" id="make"&gt;
  1420   &lt;option selected="selected" disabled="disabled"&gt;Select make&lt;/option&gt;
  1421   &lt;option&gt;Sony&lt;/option&gt;
  1422   &lt;option&gt;Philips&lt;/option&gt;
  1423   &lt;option&gt;Alba&lt;/option&gt;
  1424 &lt;/select&gt;
  1425 &lt;select name="model" id="model"&gt;&lt;/select&gt;
  1426 &lt;div id="debugconsole"&gt;&lt;/div&gt;
  1427 
  1428 &lt;script&gt;
  1429   var debug = document.getElementById('debugconsole');
  1430 
  1431   var models = {
  1432     "Sony": [
  1433       {"name": "Bravia TV S1000", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" },
  1434       {"name": "Bravia TV S2000", "type": "zeroconf", "service": "_mediarenderer._http._tcp" },
  1435       {"name": "HiFi WD10", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" }
  1436     ],
  1437     "Philips": [ /* ... */ ],
  1438     "Alba": [ /* ... */ ]
  1439   };
  1440 
  1441   var makeEl = document.getElementById("make"),
  1442       modelEl = document.getElementById("model");
  1443 
  1444   makeEl.addEventListener('change', function() {
  1445     modelEl.innerHTML = ""; // reset
  1446     var defaultOption = document.createElement("option");
  1447     defaultOption.textContent = "Select model";
  1448     defaultOption.setAttribute("disabled", "disabled");
  1449     defaultOption.setAttribute("selected", "selected");
  1450     modelEl.appendChild(defaultOption);
  1451     for(var i = 0, l = models[makeEl.value].length; i < l; i++) {
  1452       var option = document.createElement("option");
  1453       option.textContent = models[makeEl.value][i]["name"];
  1454       option.setAttribute("value", models[makeEl.value][i]["type"] + ":" + models[makeEl.value][i]["service"]);
  1455       modelEl.appendChild(option);
  1456     }
  1457   }, false);
  1458 
  1459   modelEl.addEventListener('change', function() {
  1460     if(navigator.getNetworkServices &&
  1461          modelEl.value == "upnp:urn:schemas-upnp-org:service:RenderingControl:1") {
  1462       navigator.getNetworkServices(modelEl.value, successCallback, errorCallback);
  1463     } else if (modelEl.value == "zeroconf:_mediarenderer._http._tcp") {
  1464       debug.innerHTML += "&lt;br&gt;Service type is not implemented by this application.";
  1465     } else {
  1466       debug.innerHTML += "&lt;br&gt;Service Discovery is not supported!";
  1467     }
  1468   }, false);
  1469 &lt;/script&gt;
  1470 
  1471 &lt;script&gt;
  1472   function successCallback( services ) {
  1473 
  1474   // Listen for service push messages
  1475 
  1476     services[0].addEventListener('message', function ( msg ) {
  1477          debug.innerHTML += "&lt;br>" + services[0].name + " event received: ";
  1478          debug.textContent += msg.data;
  1479     }, false);
  1480 
  1481  // Send a control signal to mute the service audio
  1482 
  1483     var svcXhr = new XMLHttpRequest();
  1484     svcXhr.open("POST", services[0].url); // services[0].url and its
  1485                                           // subresources have been whitelisted for
  1486                                           // cross-site XHR use in this current
  1487                                           // browsing context.
  1488 
  1489     svcXhr.setRequestHeader('SOAPAction', 'urn:schemas-upnp-org:service:RenderingControl:1#SetMute');
  1490     svcXhr.setRequestHeader('Content-Type', 'text/xml; charset="utf-8";');
  1491 
  1492     svcXhr.onreadystatechange = function ( response ) {
  1493       if( response.readyState != 4 || response.status != 200 )
  1494         return;
  1495       debug.innerHTML += "&lt;br&gt;" + services[0].name + " response received: ";
  1496       debug.textContent += response.responseXML;
  1497     }
  1498 
  1499     // Service messaging to mute the provided service
  1500     var svcMsg = '&lt;?xml version="1.0" encoding="utf-8"?&gt;' +
  1501                  '&lt;s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ' +
  1502                    'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;' +
  1503                    '&lt;s:Body&gt;' +
  1504                      '&lt;u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"&gt;' +
  1505                        '&lt;InstanceID&gt;0&lt;/InstanceID&gt;' +
  1506                        '&lt;Channel&gt;Master&lt;/Channel&gt;' +
  1507                        '&lt;DesiredMute&gt;true&lt;/DesiredMute&gt;' +
  1508                      '&lt;/u:SetMute&gt;' +
  1509                    '&lt;/s:Body&gt;' +
  1510                  '&lt;/s:Envelope&gt;';
  1511 
  1512     svcXhr.send(svcMsg);
  1513     debug.innerHTML += "&lt;br&gt;" + services[0].name + " request sent: ";
  1514     debug.textContent += svcMsg;
  1515   }
  1516 
  1517   function errorCallback( error ) {
  1518     debug.innerHTML += "&lt;br&gt;An error occurred: " + error.code;
  1519   }
  1520 &lt;/script&gt;</pre>
  1521           </div>
  1522 
  1523        </section>
  1524 
  1525     <section>
  1526       <h3>Acknowledgements</h3>
  1527 
  1528       <p>Thanks are expressed by the editor to the following individuals for their feedback on this specification to date (in alphabetical order):
  1529       <br /><br />
  1530       Gar Bergstedt, Lars-Erik Bolstad, Hari G Kumar, Bob Lund, Giuseppe Pascale, Marcin Simonides, Clarke Stevens, Christian S&ouml;derstr&ouml;m, Mark Vickers, ...</p>
  1531 
  1532       <p>Thanks are also expressed by the editor to the following organizations and groups for their support in producing this specification to date (in alphabetical order):
  1533       <br /></br />
  1534       CableLabs, Opera Software ASA, W3C Device APIs Working Group, W3C Web and TV Interest Group, ...</p>
  1535     </section>
  1536 </body>
  1537 </html>