discovery-api/Overview.src.html
author Rich Tibbett <richt@opera.com>
Wed, 22 Aug 2012 15:45:40 +0200
changeset 191 5e0da09685f7
parent 180 ee3a89da06e1
child 192 3ecf12df315d
permissions -rw-r--r--
Discovery API updates following feedback from http://lists.w3.org/Archives/Public/public-device-apis/2012Aug/0016.html
     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     <!-- This spec has been compiled with ReSpec v2 -->
     7     <script type="text/javascript" class='remove'>
     8       var respecConfig = {
     9           specStatus:   "ED",
    10           //publishDate:  "2012-08-22",
    11           shortName:    "discovery-api",
    12           edDraftURI:   "http://w3c-test.org/dap/discovery-api/",
    13           previousMaturity: "WD",
    14           previousPublishDate: "2012-08-07",
    15           editors: [
    16             {
    17               name:       "Rich Tibbett",
    18               //url:        "http://richt.me/",
    19               company:    "Opera Software ASA",
    20               companyURL: "http://opera.com/"
    21             },
    22             {
    23               name:       "Clarke Stevens",
    24               //url:      "",
    25               company:    "CableLabs",
    26               companyURL: "http://cablelabs.com/"
    27             }
    28           ],
    29           //extraCSS:             ["./css/respec2.css"],
    30           noIDLIn:      true,
    31           wg:           "Device APIs and Policy Working Group",
    32           wgURI:        "http://www.w3.org/2009/dap/",
    33           wgPublicList: "public-device-apis",
    34           wgPatentURI:  "http://www.w3.org/2004/01/pp-impl/43696/status"
    35       };
    36     </script>
    37 
    38     <style type="text/css">
    39       /**
    40        * SyntaxHighlighter
    41        * http://alexgorbatchev.com/SyntaxHighlighter
    42        *
    43        * SyntaxHighlighter is donationware. If you are using it, please donate.
    44        * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
    45        *
    46        * @version
    47        * 3.0.83 (July 02 2010)
    48        *
    49        * @copyright
    50        * Copyright (C) 2004-2010 Alex Gorbatchev.
    51        *
    52        * @license
    53        * Dual licensed under the MIT and GPL licenses.
    54        */
    55       .syntaxhighlighter a,
    56       .syntaxhighlighter div,
    57       .syntaxhighlighter code,
    58       .syntaxhighlighter table,
    59       .syntaxhighlighter table td,
    60       .syntaxhighlighter table tr,
    61       .syntaxhighlighter table tbody,
    62       .syntaxhighlighter table thead,
    63       .syntaxhighlighter table caption,
    64       .syntaxhighlighter textarea {
    65         -moz-border-radius: 0 0 0 0 !important;
    66         -webkit-border-radius: 0 0 0 0 !important;
    67         background: none !important;
    68         border: 0 !important;
    69         bottom: auto !important;
    70         float: none !important;
    71         height: auto !important;
    72         left: auto !important;
    73         line-height: 1.1em !important;
    74         margin: 0 !important;
    75         outline: 0 !important;
    76         overflow: visible !important;
    77         padding: 0 !important;
    78         position: static !important;
    79         right: auto !important;
    80         text-align: left !important;
    81         top: auto !important;
    82         vertical-align: baseline !important;
    83         width: auto !important;
    84         box-sizing: content-box !important;
    85         font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
    86         font-weight: normal !important;
    87         font-style: normal !important;
    88         font-size: 1em !important;
    89         min-height: inherit !important;
    90         min-height: auto !important;
    91       }
    92 
    93       .syntaxhighlighter {
    94         width: 100% !important;
    95         margin: 1em 0 1em 0 !important;
    96         position: relative !important;
    97         overflow: auto !important;
    98         font-size: 0.8em !important;
    99       }
   100       .syntaxhighlighter.source {
   101         overflow: hidden !important;
   102       }
   103       .syntaxhighlighter .bold {
   104         font-weight: bold !important;
   105       }
   106       .syntaxhighlighter .italic {
   107         font-style: italic !important;
   108       }
   109       .syntaxhighlighter .line {
   110         white-space: pre !important;
   111       }
   112       .syntaxhighlighter table {
   113         width: 100% !important;
   114       }
   115       .syntaxhighlighter table caption {
   116         text-align: left !important;
   117         padding: .5em 0 0.5em 1em !important;
   118       }
   119       .syntaxhighlighter table td.code {
   120         width: 100% !important;
   121       }
   122       .syntaxhighlighter table td.code .container {
   123         position: relative !important;
   124       }
   125       .syntaxhighlighter table td.code .container textarea {
   126         box-sizing: border-box !important;
   127         position: absolute !important;
   128         left: 0 !important;
   129         top: 0 !important;
   130         width: 100% !important;
   131         height: 100% !important;
   132         border: none !important;
   133 
   134         padding-left: 1em !important;
   135         overflow: hidden !important;
   136         white-space: pre !important;
   137       }
   138       .syntaxhighlighter table td.gutter .line {
   139         text-align: right !important;
   140         padding: 0 0.5em 0 1em !important;
   141       }
   142       .syntaxhighlighter table td.code .line {
   143         padding: 0 1em !important;
   144       }
   145       .syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
   146         padding-left: 0em !important;
   147       }
   148       .syntaxhighlighter.show {
   149         display: block !important;
   150       }
   151       .syntaxhighlighter.collapsed table {
   152         display: none !important;
   153       }
   154       .syntaxhighlighter.collapsed .toolbar {
   155         padding: 0.1em 0.8em 0em 0.8em !important;
   156         font-size: 1em !important;
   157         position: static !important;
   158         width: auto !important;
   159         height: auto !important;
   160       }
   161       .syntaxhighlighter.collapsed .toolbar span {
   162         display: inline !important;
   163         margin-right: 1em !important;
   164       }
   165       .syntaxhighlighter.collapsed .toolbar span a {
   166         padding: 0 !important;
   167         display: none !important;
   168       }
   169       .syntaxhighlighter.collapsed .toolbar span a.expandSource {
   170         display: inline !important;
   171       }
   172       .syntaxhighlighter .toolbar {
   173         position: absolute !important;
   174         right: 1px !important;
   175         top: 1px !important;
   176         width: 11px !important;
   177         height: 11px !important;
   178         font-size: 10px !important;
   179         z-index: 10 !important;
   180       }
   181       .syntaxhighlighter .toolbar span.title {
   182         display: inline !important;
   183       }
   184       .syntaxhighlighter .toolbar a {
   185         display: block !important;
   186         text-align: center !important;
   187         text-decoration: none !important;
   188         padding-top: 1px !important;
   189       }
   190       .syntaxhighlighter .toolbar a.expandSource {
   191         display: none !important;
   192       }
   193       .syntaxhighlighter.ie {
   194         font-size: .9em !important;
   195         padding: 1px 0 1px 0 !important;
   196       }
   197       .syntaxhighlighter.ie .toolbar {
   198         line-height: 8px !important;
   199       }
   200       .syntaxhighlighter.ie .toolbar a {
   201         padding-top: 0px !important;
   202       }
   203       .syntaxhighlighter.printing .line.alt1 .content,
   204       .syntaxhighlighter.printing .line.alt2 .content,
   205       .syntaxhighlighter.printing .line.highlighted .number,
   206       .syntaxhighlighter.printing .line.highlighted.alt1 .content,
   207       .syntaxhighlighter.printing .line.highlighted.alt2 .content {
   208         background: none !important;
   209       }
   210       .syntaxhighlighter.printing .line .number {
   211         color: #bbbbbb !important;
   212       }
   213       .syntaxhighlighter.printing .line .content {
   214         color: black !important;
   215       }
   216       .syntaxhighlighter.printing .toolbar {
   217         display: none !important;
   218       }
   219       .syntaxhighlighter.printing a {
   220         text-decoration: none !important;
   221       }
   222       .syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
   223         color: black !important;
   224       }
   225       .syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
   226         color: #008200 !important;
   227       }
   228       .syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
   229         color: blue !important;
   230       }
   231       .syntaxhighlighter.printing .keyword {
   232         color: #006699 !important;
   233         font-weight: bold !important;
   234       }
   235       .syntaxhighlighter.printing .preprocessor {
   236         color: gray !important;
   237       }
   238       .syntaxhighlighter.printing .variable {
   239         color: #aa7700 !important;
   240       }
   241       .syntaxhighlighter.printing .value {
   242         color: #009900 !important;
   243       }
   244       .syntaxhighlighter.printing .functions {
   245         color: #ff1493 !important;
   246       }
   247       .syntaxhighlighter.printing .constants {
   248         color: #0066cc !important;
   249       }
   250       .syntaxhighlighter.printing .script {
   251         font-weight: bold !important;
   252       }
   253       .syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
   254         color: gray !important;
   255       }
   256       .syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
   257         color: #ff1493 !important;
   258       }
   259       .syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
   260         color: red !important;
   261       }
   262       .syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
   263         color: black !important;
   264       }
   265     </style>
   266     <style type="text/css">
   267       /**
   268        * SyntaxHighlighter
   269        * http://alexgorbatchev.com/SyntaxHighlighter
   270        *
   271        * SyntaxHighlighter is donationware. If you are using it, please donate.
   272        * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
   273        *
   274        * @version
   275        * 3.0.83 (July 02 2010)
   276        *
   277        * @copyright
   278        * Copyright (C) 2004-2010 Alex Gorbatchev.
   279        *
   280        * @license
   281        * Dual licensed under the MIT and GPL licenses.
   282        */
   283       .syntaxhighlighter {
   284         background-color: none !important;
   285       }
   286       .syntaxhighlighter .line.alt1 {
   287         background-color: none !important;
   288       }
   289       .syntaxhighlighter .line.alt2 {
   290         background-color: none !important;
   291       }
   292       .syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
   293         background-color: none !important;
   294       }
   295       .syntaxhighlighter .line.highlighted.number {
   296         color: black !important;
   297       }
   298       .syntaxhighlighter table caption {
   299         color: black !important;
   300       }
   301       .syntaxhighlighter .gutter {
   302         color: #afafaf !important;
   303       }
   304       .syntaxhighlighter .gutter .line {
   305         border-right: 3px solid #6ce26c !important;
   306       }
   307       .syntaxhighlighter .gutter .line.highlighted {
   308         background-color: #6ce26c !important;
   309         color: white !important;
   310       }
   311       .syntaxhighlighter.printing .line .content {
   312         border: none !important;
   313       }
   314       .syntaxhighlighter.collapsed {
   315         overflow: visible !important;
   316       }
   317       .syntaxhighlighter.collapsed .toolbar {
   318         color: blue !important;
   319         background: none !important;
   320         border: 1px solid #6ce26c !important;
   321       }
   322       .syntaxhighlighter.collapsed .toolbar a {
   323         color: blue !important;
   324       }
   325       .syntaxhighlighter.collapsed .toolbar a:hover {
   326         color: red !important;
   327       }
   328       .syntaxhighlighter .toolbar {
   329         color: white !important;
   330         background: #6ce26c !important;
   331         border: none !important;
   332       }
   333       .syntaxhighlighter .toolbar a {
   334         color: white !important;
   335       }
   336       .syntaxhighlighter .toolbar a:hover {
   337         color: black !important;
   338       }
   339       .syntaxhighlighter .plain, .syntaxhighlighter .plain a {
   340         color: black !important;
   341       }
   342       .syntaxhighlighter .comments, .syntaxhighlighter .comments a {
   343         color: #008200 !important;
   344       }
   345       .syntaxhighlighter .string, .syntaxhighlighter .string a {
   346         color: blue !important;
   347       }
   348       .syntaxhighlighter .keyword {
   349         color: #006699 !important;
   350       }
   351       .syntaxhighlighter .preprocessor {
   352         color: gray !important;
   353       }
   354       .syntaxhighlighter .variable {
   355         color: #aa7700 !important;
   356       }
   357       .syntaxhighlighter .value {
   358         color: #009900 !important;
   359       }
   360       .syntaxhighlighter .functions {
   361         color: #ff1493 !important;
   362       }
   363       .syntaxhighlighter .constants {
   364         color: #0066cc !important;
   365       }
   366       .syntaxhighlighter .script {
   367         font-weight: bold !important;
   368         color: #006699 !important;
   369         background-color: none !important;
   370       }
   371       .syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
   372         color: gray !important;
   373       }
   374       .syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
   375         color: #ff1493 !important;
   376       }
   377       .syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
   378         color: red !important;
   379       }
   380 
   381       .syntaxhighlighter .keyword {
   382         font-weight: bold !important;
   383       }
   384     </style>
   385     <script src="tools/syntaxhighlighter/js/shCore.js" type="text/javascript" class='remove'></script>
   386     <script src="tools/syntaxhighlighter/js/shAutoloader.js" type="text/javascript" class='remove'></script>
   387     <script src="tools/syntaxhighlighter/js/shBrushXml.js" type="text/javascript" class='remove'></script>
   388     <script src="tools/syntaxhighlighter/js/shBrushJScript.js" type="text/javascript" class='remove'></script>
   389 
   390     <script src='./js/profiles/w3c-common-loader.js' type="text/javascript" class='remove'></script>
   391     <style type="text/css">
   392       /* Custom CSS optimizations (Richard Tibbett) */
   393 
   394       /* Add better spacing to sections */
   395       section, .section { margin-bottom: 2em; }
   396 
   397       /* Reduce note & issue render size */
   398       .note, .issue { font-size:0.8em; }
   399 
   400       /* Add addition spacing to <ol> and <ul> for rule definition */
   401       ol.rule li, ul.rule li { padding:0.6em; }
   402 
   403       pre.widl { border: solid thin; background: #EEEEEE; color: black; padding: 0.5em 1em; position: relative; }
   404       pre.widl :link, pre.widl :visited { color: #000; background: transparent; }
   405       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 }
   406 
   407       div.example { border: solid thin red; background: #F7DFE5; color: black; padding: 0.5em 1em; position: relative; margin: 1em 0 1em 4.6em; width: auto; }
   408       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 }
   409 
   410       dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #DDFFDD; }
   411       hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; }
   412       dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; }
   413       dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; }
   414       dl.domintro dd p { margin: 0.5em 0; }
   415       dl.domintro code {font-size: inherit; font-style: italic; }
   416       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; }
   417     </style>
   418   </head>
   419 
   420   <body>
   421     <section id='abstract'>
   422       <p>
   423         This specification defines a mechanism for an HTML document to discover and subsequently communicate with <acronym title="Hypertext Transfer Protocol">HTTP</acronym>-based services
   424         advertised via common discovery protocols within a user's network.
   425       </p>
   426     </section>
   427 
   428     <section id='sotd'>
   429       <p>
   430         This document represents the early consensus of the group on the scope and features of the proposed
   431         API.
   432       </p>
   433     </section>
   434 
   435     <section class="informative">
   436       <h3>Introduction</h3>
   437 
   438       <p>To enable Web pages to connect and communicate with Local-networked Services provided over HTTP, this specification introduces the
   439       <a href="#navigatornetworkservice"><code>NavigatorNetworkService</code></a> interface.</p>
   440 
   441       <p>
   442          Using this <acronym title="Application Programming Interface">API</acronym> 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,
   443          is expected before the web page is able to interact with any Local-networked Services.
   444       </p>
   445 
   446       <p>
   447          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.
   448       </p>
   449 
   450       <p>
   451          The user agent, having captured all advertised services on the network from the Service Discovery mechanisms included in this recommendation, attempts to match
   452       the requested service type to a discovered service according to the processing described herein.
   453       </p>
   454 
   455       <p>
   456           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.
   457           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.
   458       </p>
   459 
   460       <p>
   461          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
   462          authorized via the provided API.
   463          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
   464          connected Local-networked Service.
   465       </p>
   466 
   467       <div class="example">
   468        <p>Example of requesting a DNS-SD advertised service:</p>
   469        <hr />
   470        <pre class="brush:js">function showServices( services ) {
   471   // Show a list of all the services provided to the web page
   472   for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name );
   473 }
   474 
   475 navigator.getNetworkServices('zeroconf:_boxee-jsonrpc._tcp', showServices);</pre>
   476       </div>
   477 
   478       <div class="example">
   479         <p>Example of requesting a UPnP advertised service, also handling error conditions:</p>
   480         <hr />
   481         <pre class="brush:js">function showServices( services ) {
   482   // Show a list of all the services provided to the web page
   483   for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name );
   484 }
   485 
   486 function error( e ) {
   487   console.log( "Error occurred: " + e.code );
   488 }
   489 
   490 navigator.getNetworkServices('upnp:urn:schemas-upnp-org:service:ContentDirectory:1', showServices, error);</pre>
   491       </div>
   492 
   493       <div class="example">
   494         <p>Example of requesting either a DNS-SD or UPnP advertised service:</p>
   495         <hr />
   496         <pre class="brush:js">function showServices( services ) {
   497   // Show a list of all the services provided to the web page (+ service type)
   498   for(var i = 0, l = services.length; i < l; i++)
   499      console.log( services[i].name + '(' + services[i].type + ')' );
   500 }
   501 
   502 navigator.getNetworkServices([
   503   'zeroconf:_boxee-jsonrpc._tcp',
   504   'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'
   505 ], showServices);</pre>
   506       </div>
   507 
   508       <p>For more detailed examples see the <a href="#examples">Examples</a> section.
   509     </section>
   510 
   511     <section
   512      id='conformance'>
   513 
   514      <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
   515      meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.</p>
   516 
   517      <p>
   518       Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements are to be interpreted as requirements on user agents.
   519      </p>
   520 
   521      <p>
   522       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
   523       this specification are intended to be easy to follow, and not intended to be performant.)
   524      </p>
   525 
   526      <p>
   527       The only conformance class defined by this specification is a <dfn>user agent</dfn>.
   528      </p>
   529 
   530      <p>
   531       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
   532       around platform-specific limitations.
   533      </p>
   534 
   535      <p>
   536       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
   537       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
   538       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
   539       is insufficient.
   540      </p>
   541 
   542       <section>
   543          <h3>Dependencies</h3>
   544 
   545          This specification relies on several other underlying specifications.
   546 
   547          <dl>
   548             <dt>HTML</dt>
   549             <dd>Many fundamental concepts from HTML are used by this specification. [[!HTML5]]</dd>
   550             <dt>WebIDL</dt>
   551             <dd>The IDL blocks in this specification use the semantics of the WebIDL specification. [[!WEBIDL]]</dd>
   552          </dl>
   553       </section>
   554     </section>
   555 
   556     <section>
   557       <h3>Terminology</h3>
   558 
   559       <p>
   560          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>".
   561       </p>
   562 
   563       <p>
   564          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
   565          other <code>Node</code> objects as defined in the DOM Core specifications. [[!DOM-CORE]]
   566       </p>
   567 
   568       <p>
   569          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.
   570       </p>
   571 
   572       <p>
   573         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.
   574       </p>
   575 
   576       <p>
   577         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.
   578       </p>
   579     </section>
   580 
   581     <section>
   582      <h2>Requesting networked services</h2>
   583 
   584 
   585 <pre class="widl">[Supplemental, NoInterfaceObject]
   586 interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> {
   587   // Obtain a Local-networked Service
   588   void <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type,
   589                            in <a href="#navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</a> successCallback,
   590                            in optional <a href="#navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</a> errorCallback );
   591 };
   592 <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>;
   593 
   594 [Callback=FunctionOnly, NoInterfaceObject]
   595 interface <dfn id="navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</dfn> {
   596   void handleEvent( in <a href="#networkservices">NetworkServices</a> services );
   597 };
   598 
   599 [NoInterfaceObject]
   600 interface <dfn id="navigatornetworkserviceerror">NavigatorNetworkServiceError</dfn> {
   601   const unsigned short <a href="#dom-navigatornetworkserviceerror-permission_denied">PERMISSION_DENIED_ERR</a> = 1;
   602   const unsigned short <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix">UNKNOWN_TYPE_PREFIX_ERR</a> = 2;
   603   readonly attribute unsigned short <a href="#dom-navigatornetworkserviceerror-code">code</a>;
   604 };
   605 
   606 [Callback=FunctionOnly, NoInterfaceObject]
   607 interface <dfn id="navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</dfn> {
   608   void handleEvent( in <a href="#navigatornetworkserviceerror">NavigatorNetworkServiceError</a> error );
   609 };
   610 </pre>
   611 
   612   <section>
   613    <h2>Methods</h2>
   614 
   615       <dl class="domintro">
   616         <dt>
   617           <var title="">window</var>
   618            .
   619           <code title="dom-navigator">
   620             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">navigator</a>
   621           </code>
   622            .
   623           <code title="dom-navigator-getNetworkServices">
   624             <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>
   625           </code>
   626           (
   627           <var title="">type</var>
   628           ,
   629           <var title="">successCallback</var>
   630            [,
   631           <var title="">errorCallback</var>
   632            ] )
   633         </dt>
   634         <dd>
   635           <p>Prompts the user to select one or more discovered network services that have advertised support for the requested service type.</p>
   636           <p>
   637             The
   638             <var title="">type</var>
   639              argument contains one or more <a>valid service type</a> tokens that the web page would like to interact with.
   640           </p>
   641           <p>
   642             If the user accepts, the
   643             <var title="">successCallback</var>
   644              is
   645           invoked, with one or more
   646             <code>
   647               <a href="#networkservice"><code>NetworkService</code></a>
   648             </code>
   649              objects as
   650           its argument.
   651           </p>
   652           <p>
   653             If the user declines, the
   654             <var title="">errorCallback</var>
   655              (if
   656           any) is invoked.
   657           </p>
   658         </dd>
   659       </dl>
   660 
   661        <div>
   662           <p>
   663             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:
   664           </p>
   665 
   666           <ol class="rule">
   667 
   668             <li>
   669               Let <var>requested control types</var> be initially set to an empty array.
   670             </li>
   671 
   672             <li>
   673                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.
   674             </li>
   675 
   676             <li>
   677                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>.
   678             </li>
   679 
   680             <li>
   681                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
   682                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 2
   683                   (<a href="#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) as its argument,
   684                    abort any remaining steps and return.
   685             </li>
   686 
   687             <li>
   688                <em>Process</em>: Let <var>services found</var> be an empty array.
   689             </li>
   690 
   691             <li>
   692                For each <var>available service</var> in the <a>list of available service records</a> run the following steps:
   693                <ol class="rule">
   694                   <li>
   695                     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.
   696                   </li>
   697                   <li>
   698                      Continue at the next <var>available service</var>.
   699                   </li>
   700                   <li>
   701                      <em>Attach</em>: If <var>matched service</var> is not empty then run the following steps:
   702 
   703                      <ol class="rule">
   704                         <li>
   705                            Let <var>new service object</var> be a new <a href="#networkservice"><code>NetworkService</code></a> object, mapping the parameters of
   706                      <var>matched service</var> to this new object where possible.
   707                         </li>
   708                         <li>
   709                            Append <var>new service object</var> to the <var>services found</var> array.
   710                         </li>
   711                      </ol>
   712                   </li>
   713                </ol>
   714             </li>
   715 
   716             <li>
   717                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
   718                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   719                  (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   720             </li>
   721 
   722             <li>
   723                Return, and run the remaining steps asynchronously.
   724             </li>
   725 
   726             <li>
   727                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
   728                  <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   729                  (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   730             </li>
   731 
   732             <li>
   733                   The <a>user agent</a> MUST prompt the user in a user-agent-specific manner for permission to provide the
   734                   <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" class="externalDFN">entry script</a>'s
   735                   <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin" class="externalDFN">origin</a> with an array of
   736                   <a href="#networkservice"><code>NetworkService</code></a> objects representing the user-authorized subset of <var>services found</var>.
   737 
   738                <p>
   739                   If the user grants permission to access one or more networked services then the <a>user agent</a> SHOULD include an
   740                   "ongoing local-network communication" indicator.
   741                </p>
   742 
   743                <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
   744                 <a href="#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1
   745                 (<a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its argument, abort any remaining steps and return.
   746               </p>
   747 
   748               <p>
   749                 If the user never responds, this algorithm stalls on this step.
   750               </p>
   751 
   752             </li>
   753 
   754             <li>
   755                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.
   756             </li>
   757 
   758             <li>
   759                For each Object <var>service</var> in <var>services</var>, run the following substeps:
   760 
   761                <ol class="rule">
   762                   <li>
   763                      Add the <var>service</var>'s <code>url</code> parameter to the <a>entry script origin's <acronym title="Uniform Resource Locator">URL</acronym> whitelist</a>.
   764                   </li>
   765                   <li>
   766                     If <var>service</var>'s <code>type</code> parameter begins with the DOMString &quot;<code>upnp:</code>&quot; 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>.
   767                   </li>
   768                </ol>
   769             </li>
   770 
   771             <li>
   772                Let <var>services manager</var> be a new <a href="#networkservices"><code>NetworkServices</code></a> object.
   773             </li>
   774 
   775             <li>
   776                Set <var>services manager</var>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to the length of <var>services</var>.
   777             </li>
   778 
   779             <li>
   780               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.
   781             </li>
   782 
   783             <li>
   784                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
   785                <var>services manager</var> as its argument.
   786             </li>
   787 
   788           </ol>
   789 
   790           <p>
   791             The <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#task-source" class="externalDFN">task source</a> for these
   792             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#concept-task" class="externalDFN">tasks</a> is the
   793             <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>.
   794           </p>
   795 
   796           <p>
   797             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
   798              to the <dfn>entry script origin's URL whitelist</dfn>. This list enables the
   799             Web page to override and initiate cross-site resource requests towards these URLs, and any sub-resources of these URLs, within the current
   800             <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" class="externalDFN">entry script</a>'s
   801             <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,
   802             Web Messaging, XMLHttpRequest).
   803          </p>
   804 
   805          <p>
   806             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>.
   807             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:
   808             <ul>
   809               <li>If the current script is reloaded at any point in the same or different window.</li>
   810               <li>if the current script reinvokes the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method at any point in its execution.</li>
   811               <li>If the user navigates forward or back in their history to reload the current page.</li>
   812               <li>If a script is running in a different origin.</li>
   813             </ul>
   814          </p>
   815 
   816       </div>
   817       </section>
   818 
   819       <section>
   820          <h3>Error Handling</h3>
   821 
   822       <dl class="domintro">
   823         <dt>
   824           <var title="">error</var>
   825            .
   826           <code title="dom-NavigatorNetworkServiceError-code">
   827             <a href="#dom-navigatornetworkserviceerror-code">code</a>
   828           </code>
   829         </dt>
   830         <dd>
   831           <p>
   832             Returns the current error's error code. At the current time, this may be <code>1</code> or <code>2</code>, for which the
   833             corresponding error constants
   834             <a href="#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and
   835             <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are defined.
   836           </p>
   837         </dd>
   838       </dl>
   839 
   840          <p>
   841             The <dfn id="dom-navigatornetworkserviceerror-code" title="dom-navigatornetworkserviceerror-code"><code>code</code></dfn> attribute of a
   842             <a href="#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object MUST return the code for the error, which will be one of the following:
   843          </p>
   844 
   845          <dl>
   846             <dt>
   847                <dfn id="dom-navigatornetworkserviceerror-permission_denied" title="dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> (numeric value 1)
   848             </dt>
   849             <dd>
   850                The user denied the page permission to access any services.
   851             </dd>
   852             <dt>
   853                <dfn id="dom-navigatornetworkserviceerror-unknown_type_prefix" title="dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn> (numeric value 2)
   854             </dt>
   855             <dd>
   856                No <a>valid service type</a> tokens were provided in the method invocation.
   857             </dd>
   858          </dl>
   859 
   860       </section>
   861 
   862       </section>
   863       <section>
   864       <h2>Obtaining networked services</h2>
   865 
   866       <p>
   867          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.
   868       </p>
   869 
   870 <pre class="widl">
   871 [NoInterfaceObject]
   872 interface <dfn id="networkservices">NetworkServices</dfn> {
   873   readonly attribute unsigned long    <a href="#dom-networkservices-length">length</a>;
   874   getter <a href="#networkservice">NetworkService</a> (unsigned long index);
   875   <a href="#networkservice">NetworkService</a>? <a href="#dom-networkservices-getservicebyid">getServiceById</a>(DOMString id);
   876 
   877   readonly attribute unsigned long    <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>;
   878 
   879   // event handler attributes
   880            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>;
   881            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>;
   882 
   883 };
   884 
   885 <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>;
   886 </pre>
   887 
   888       <section>
   889       <h2>Attributes</h2>
   890 
   891         <dl class="domintro">
   892           <dt>
   893             <code title="dom-networkservices-length">
   894               <a href="#dom-networkservices-length">length</a>
   895             </code>
   896           </dt>
   897           <dd>
   898             <p>
   899               Returns the current number of services in the respective object's <a>current authorized services</a>.
   900             </p>
   901           </dd>
   902           <dt>
   903             <code title="dom-networkservices-servicesavailable">
   904               <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>
   905             </code>
   906           </dt>
   907           <dd>
   908             <p>
   909               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.
   910             </p>
   911           </dd>
   912         </dl>
   913 
   914         <div>
   915            <p>
   916               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.
   917            </p>
   918 
   919            <p>
   920               The <dfn id="dom-networkservices-servicesavailable"><code>servicesAvailable</code></dfn> attribute MUST return the number of services available in the
   921               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.
   922            </p>
   923 
   924            <p>
   925              When a previously unknown instance of a networked service matching one of 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 increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute by <code>1</code> and then
   926              <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
   927              to dispatch a newly created event with the name <code>serviceavailable</code> that uses the <code>Event</code> interface, which does
   928              not bubble, is not cancellable, and has no default action, at the current <a href="#networkservices"><code>NetworkServices</code></a>
   929              object.
   930            </p>
   931 
   932            <p>
   933              When a previously known instance of a networked service matching one of 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 decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute by <code>1</code> and then
   934              <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
   935               to dispatch a newly created event with the name <code>serviceunavailable</code> that uses the <code>Event</code> interface, which does
   936               not bubble, is not cancellable, and has no default action, at the current <a href="#networkservices"><code>NetworkServices</code></a>
   937               object.
   938            </p>
   939         </div>
   940 
   941       </section>
   942 
   943       <section>
   944       <h2>Methods</h2>
   945         <dl class="domintro">
   946         <dt>
   947           <code title="networkservices-getter">
   948             <a href="#networkservices">services</a>
   949           </code>
   950           [
   951           <var title="">index</var>
   952           ]
   953         </dt>
   954         <dd>
   955           <p>
   956             Returns the specified <a href="#networkservice"><code>NetworkService</code></a> object.
   957           </p>
   958         </dd>
   959         <dt>
   960           <code title="networkservices-getter">
   961             <a href="#networkservices">services</a>
   962           </code>
   963           .
   964           <code title="dom-networkservices-getservicebyid">
   965             <a href="#dom-networkservices-getservicebyid">getServiceById</a>
   966           </code>
   967           (
   968           <var title="">id</var>
   969           )
   970         </dt>
   971         <dd>
   972           <p>
   973             Returns the <a href="#networkservice"><code>NetworkService</code></a> object with the given identifier, or null if no
   974             service has that identifier.
   975           </p>
   976         </dd>
   977       </dl>
   978 
   979       <p>
   980         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. The list of <a>current authorized services</a> is <span>immutable</span> meaning that it cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> object.
   981       </p>
   982 
   983       <p class="note">
   984         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.
   985       </p>
   986 
   987       <p>
   988         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>.
   989       </p>
   990 
   991       <p>
   992         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>.
   993       </p>
   994 
   995       <p>
   996         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.
   997         When no services in <a>current authorized services</a> match the given argument, the method MUST return null.
   998       </p>
   999 
  1000       <p>
  1001          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
  1002          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
  1003          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.
  1004       </p>
  1005 
  1006       </section>
  1007 
  1008       <section>
  1009       <h2>Events</h2>
  1010 
  1011       <p>
  1012          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:
  1013        </p>
  1014 
  1015        <table border="1">
  1016         <thead>
  1017           <tr>
  1018             <th>
  1019               <span title="event handlers">Event handler</span>
  1020             </th>
  1021             <th>
  1022               <span>Event handler event type</span>
  1023             </th>
  1024           </tr>
  1025         </thead>
  1026         <tbody>
  1027           <tr>
  1028             <td>
  1029               <dfn id="dom-networkservices-onserviceavailable" title="dom-NetworkServices-onserviceavailable">
  1030                 <code>onserviceavailable</code>
  1031               </dfn>
  1032             </td>
  1033             <td>
  1034               <code title="event-serviceavailable">serviceavailable</code>
  1035             </td>
  1036           </tr>
  1037           <tr>
  1038             <td>
  1039               <dfn id="dom-networkservices-onserviceunavailable" title="dom-NetworkServices-onserviceunavailable">
  1040                 <code>onserviceunavailable</code>
  1041               </dfn>
  1042             </td>
  1043             <td>
  1044               <code title="event-serviceunavailable">serviceunavailable</code>
  1045             </td>
  1046           </tr>
  1047         </tbody>
  1048       </table>
  1049 
  1050       <p>
  1051          Events with an event type of <code>serviceavailable</code> or <code>serviceunavailable</code> defined in this specification are simple <code>Event</code> objects.
  1052       </p>
  1053 
  1054       </section>
  1055 
  1056     </section>
  1057     <section>
  1058     <h2>Communicating with a networked service</h3>
  1059 
  1060 <p>
  1061    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.
  1062 </p>
  1063 
  1064 <pre class="widl">
  1065 [NoInterfaceObject]
  1066 interface <dfn id="networkservice">NetworkService</dfn> {
  1067   readonly attribute DOMString        <a href="#dom-networkservice-id">id</a>;
  1068   readonly attribute DOMString        <a href="#dom-networkservice-name">name</a>;
  1069   readonly attribute DOMString        <a href="#dom-networkservice-type">type</a>;
  1070   readonly attribute DOMString        <a href="#dom-networkservice-url">url</a>;
  1071   readonly attribute DOMString        <a href="#dom-networkservice-config">config</a>;
  1072 
  1073   readonly attribute boolean          <a href="#dom-networkservice-online">online</a>;
  1074 
  1075   // event handler attributes
  1076            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onserviceonline">onserviceonline</a>;
  1077            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onserviceoffline">onserviceoffline</a>;
  1078 
  1079            attribute <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#eventhandler" class="externalDFN">EventHandler</a>     <a href="#dom-networkservice-onnotify">onnotify</a>;
  1080 };
  1081 
  1082 <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>;
  1083 </pre>
  1084 
  1085 <section>
  1086   <h2>Attributes</h2>
  1087 
  1088       <dl class="domintro">
  1089         <dt>
  1090           <var title="">service</var>
  1091            .
  1092           <code title="dom-networkservice-id">
  1093             <a href="#dom-networkservice-id">id</a>
  1094           </code>
  1095         </dt>
  1096         <dd>
  1097           <p>
  1098             A unique identifier for the given user-selected service instance.
  1099           </p>
  1100         </dd>
  1101         <dt>
  1102           <var title="">service</var>
  1103            .
  1104           <code title="dom-networkservice-name">
  1105             <a href="#dom-networkservice-name">name</a>
  1106           </code>
  1107         </dt>
  1108         <dd>
  1109           <p>
  1110             The name of the user-selected service.
  1111           </p>
  1112         </dd>
  1113         <dt>
  1114           <var title="">service</var>
  1115            .
  1116           <code title="dom-networkservice-type">
  1117             <a href="#dom-networkservice-type">type</a>
  1118           </code>
  1119         </dt>
  1120         <dd>
  1121           <p>
  1122             The <a>valid service type</a> token value of the user-selected service.
  1123           </p>
  1124         </dd>
  1125         <dt>
  1126           <var title="">service</var>
  1127            .
  1128           <code title="dom-networkservice-url">
  1129             <a href="#dom-networkservice-url">url</a>
  1130           </code>
  1131         </dt>
  1132         <dd>
  1133           <p>
  1134             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>.
  1135           </p>
  1136         </dd>
  1137         <dt>
  1138           <var title="">service</var>
  1139            .
  1140           <code title="dom-networkservice-config">
  1141             <a href="#dom-networkservice-config">config</a>
  1142           </code>
  1143         </dt>
  1144         <dd>
  1145           <p>
  1146             The configuration information associated with the service depending on the requested service type.
  1147           </p>
  1148         </dd>
  1149       </dl>
  1150 
  1151           <p>
  1152             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.
  1153          </p>
  1154 
  1155          <p>
  1156             The <dfn id="dom-networkservice-name"><code>name</code></dfn> attribute represents a human-readable title for the service.
  1157          </p>
  1158 
  1159          <p>
  1160              The <dfn id="dom-networkservice-type"><code>type</code></dfn> attribute reflects the value of the <a>valid service type</a> of the service.
  1161           </p>
  1162 
  1163          <p>
  1164             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
  1165             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).
  1166          </p>
  1167 
  1168          <p>
  1169             The <dfn id="dom-networkservice-config"><code>config</code></dfn> attribute provides the raw configuration information extracted from the given network service.
  1170          </p>
  1171 
  1172       </section>
  1173 
  1174       <section>
  1175          <h3>States</h3>
  1176 
  1177       <dl class="domintro">
  1178         <dt>
  1179           <var title="">service</var>
  1180            .
  1181           <code title="dom-networkservice-online">
  1182             <a href="#dom-networkservice-online">online</a>
  1183           </code>
  1184         </dt>
  1185         <dd>
  1186           <p>
  1187             Returns <code>true</code> if the service is reporting that it is accessible on the local network or <code>false</code> if the service is reporting that it is no longer accessible (temporarily or permanently) on the local network.
  1188           </p>
  1189         </dd>
  1190       </dl>
  1191 
  1192       <p>
  1193         The <dfn id="dom-networkservice-config"><code>online</code></dfn> attribute indicates whether the service is reporting itself as being
  1194         either <var>online</var>, and therefore accessible on the local network, in which case this attribute will return <code>true</code> or, <var>offline</var>, and therefore not accessible on the local network, either temporarily or permanently, in which case this attribute will return <code>false</code>. This attribute MUST default to <code>true</code>.
  1195       </p>
  1196 
  1197       </section>
  1198 
  1199       <section>
  1200          <h3>Events</h3>
  1201 
  1202       <p>
  1203          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
  1204          <a href="#networkservice"><code>NetworkService</code></a> interface:
  1205        </p>
  1206 
  1207        <table border="1">
  1208         <thead>
  1209           <tr>
  1210             <th>
  1211               <span title="event handlers">Event handler</span>
  1212             </th>
  1213             <th>
  1214               <span>Event handler event type</span>
  1215             </th>
  1216           </tr>
  1217         </thead>
  1218         <tbody>
  1219           <tr>
  1220             <td>
  1221               <dfn id="dom-networkservice-onnotify" title="dom-NetworkService-onnotify">
  1222                 <code>onnotify</code>
  1223               </dfn>
  1224             </td>
  1225             <td>
  1226               <code title="event-notify">notify</code>
  1227             </td>
  1228           </tr>
  1229           <tr>
  1230             <td>
  1231               <dfn id="dom-networkservice-onserviceonline" title="dom-NetworkService-onserviceonline">
  1232                 <code>onserviceonline</code>
  1233               </dfn>
  1234             </td>
  1235             <td>
  1236               <code title="event-onserviceonline">serviceonline</code>
  1237             </td>
  1238           </tr>
  1239           <tr>
  1240             <td>
  1241               <dfn id="dom-networkservice-offserviceoffline" title="dom-NetworkService-onserviceoffline">
  1242                 <code>onserviceoffline</code>
  1243               </dfn>
  1244             </td>
  1245             <td>
  1246               <code title="event-onserviceoffline">serviceoffline</code>
  1247             </td>
  1248           </tr>
  1249         </tbody>
  1250       </table>
  1251 
  1252       <p>
  1253          Events with an event type of <code>notify</code>, <code>serviceonline</code> or <code>serviceoffline</code> defined in this specification are simple <code>Event</code> objects.
  1254       </p>
  1255 
  1256       </section>
  1257    </section>
  1258 
  1259       <section>
  1260             <h2>Service Discovery</h2>
  1261 
  1262       <p>
  1263          A <a>user agent</a> conforming to this specification MAY implement <acronym title="Simple Service Discovery Protocol">SSDP</acronym> [[!UPNP]] and Zeroconf [[!DNS-SD]] + [[!MDNS]] service discovery mechanisms
  1264          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.
  1265       </p>
  1266       <p>
  1267          This section presents how the results of these two service discovery
  1268          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.
  1269       </p>
  1270 
  1271       <p>
  1272          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
  1273          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
  1274          invocation of this API from a Web page).
  1275       </p>
  1276 
  1277       <p>
  1278          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.
  1279          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
  1280          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>.
  1281       </p>
  1282 
  1283             <section>
  1284          <h4>Zeroconf (<acronym title="Multicast DNS">mDNS</acronym> + <acronym title="Domain Name System">DNS</acronym>-<acronym title="Service Discovery">SD</acronym>)</h4>
  1285 
  1286          <p>
  1287             For each DNS response received from a user-agent-initiated Multicast DNS Browse for <acronym title="DNS Pointer Record">PTR</acronym> records with the name <code>_services._dns-sd._udp</code> on the resolved recommended automatic browsing
  1288    domain [[!MDNS]], the <a>user agent</a> MUST run the following steps:
  1289          </p>
  1290 
  1291          <ol class="rule">
  1292 
  1293             <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>
  1294 
  1295             <li>For each Object <var>service mDNS response</var> in <var>service mDNS responses</var>, run the following steps:
  1296                <ol>
  1297 
  1298                   <li>
  1299                      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>.
  1300                   </li>
  1301 
  1302                   <li>
  1303                      Set <var>network service record</var>'s <code>id</code> property to the value of the full PTR Service Instance Name [[!MDNS]].
  1304                   </li>
  1305 
  1306                   <li>
  1307                      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]].
  1308                   </li>
  1309 
  1310                   <li>
  1311                      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]].
  1312                   </li>
  1313 
  1314                   <li>
  1315                      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]].
  1316                   </li>
  1317 
  1318                   <li>
  1319                      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]].
  1320                   </li>
  1321 
  1322                   <li>
  1323                      For each Object <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
  1324                      <ol class="rule">
  1325 
  1326                        <li>
  1327                         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
  1328                         value of <var>existing service record</var> in the current <a>list of available service records</a>  to the value of the
  1329                         <var>network service record</var> and skip the next step.
  1330                        </li>
  1331                      </ol>
  1332                   </li>
  1333 
  1334                   <li>
  1335                      Add <var>network service record</var> to the <a>list of available service records</a>.
  1336                   </li>
  1337 
  1338                   <li>
  1339                      For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
  1340 
  1341                      <ol class="rule">
  1342                         <li>
  1343                            If the <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
  1344                            current <a>network service record</a>'s <code>type</code> property then continue at the next available active
  1345                            <a href="#networkservice"><code>NetworkService</code></a> object.
  1346                         </li>
  1347                         <li>
  1348                            Increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a> object by <code>1</code>.
  1349                         </li>
  1350                         <li>
  1351                           <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
  1352                            to dispatch a newly created event with the name <code>serviceavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
  1353                             <a href="#networkservices"><code>NetworkServices</code></a> object.
  1354                         </li>
  1355                         <li>
  1356                           <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
  1357                            to dispatch a newly created event with the name <code>serviceonline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
  1358                            <a href="#networkservice"><code>NetworkService</code></a> object.
  1359                         </li>
  1360                      </ol>
  1361                   </li>
  1362             </ol>
  1363            </li>
  1364          </ol>
  1365 
  1366       </section>
  1367 
  1368       <section>
  1369          <h5>Universal Plug-and-Play (<acronym title="Universal Plug-and-Play">UPnP</acronym>)</h5>
  1370 
  1371          <p>
  1372             For each SSDP Presence Announcement [[!UPNP]] - a HTTP NOTIFY request - received from a user-agent-initiated SSDP Discovery Request [[!UPNP]], the <a>user agent</a> MUST run the following steps:
  1373          </p>
  1374 
  1375          <ol class="rule">
  1376             <li>
  1377                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
  1378                value being that HTTP header's accompanying value.
  1379             </li>
  1380 
  1381             <li>
  1382                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.
  1383             </li>
  1384 
  1385             <li>
  1386                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.
  1387             </li>
  1388 
  1389             <li>
  1390                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
  1391                defined in the section 'Retrieving a description using HTTP' [[!UPNP]].
  1392             </li>
  1393 
  1394             <li>
  1395                If <var>root device descriptor file</var> is empty, then the <a>user agent</a> MUST abort these steps.
  1396             </li>
  1397 
  1398             <li>
  1399                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
  1400                the section 'Device Description' [[!UPNP]].
  1401             </li>
  1402 
  1403             <li>
  1404                For each Object <var>advertised service</var> in <var>advertised services</var> run the following steps:
  1405                <ol class="rule">
  1406 
  1407                   <li>
  1408                      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>.
  1409                   </li>
  1410 
  1411                   <li>
  1412                      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.
  1413                   </li>
  1414 
  1415                   <li>
  1416                      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.
  1417                   </li>
  1418 
  1419                   <li>
  1420                      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.
  1421                   </li>
  1422 
  1423                   <li>
  1424                      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.
  1425                   </li>
  1426 
  1427                   <li>
  1428                      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.
  1429                   </li>
  1430 
  1431                   <li>
  1432                      If <var>service</var>'s <code>eventSubURL</code> property is empty, then continue to the step labeled <em>register</em> below.
  1433                   </li>
  1434 
  1435                   <li>
  1436                      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.
  1437                   </li>
  1438 
  1439                   <li>
  1440                      <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:
  1441                      <ol class="rule">
  1442 
  1443                        <li>
  1444                         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
  1445                         <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
  1446                         value of <var>existing service record</var> in the current <a>list of available service records</a>  to the value of the
  1447                         <var>network service record</var> and skip the next step.
  1448                        </li>
  1449                      </ol>
  1450                   </li>
  1451 
  1452                   <li>
  1453                      Add <var>network service record</var> to the <a>list of available service records</a>.
  1454                   </li>
  1455 
  1456                </ol>
  1457             </li>
  1458             <li>
  1459                <em>Update Service Monitor</em>: For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
  1460 
  1461                <ol class="rule">
  1462                   <li>
  1463                      If this <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
  1464                      current <a>network service record</a>'s <code>type</code> property then continue at the next available active
  1465                      <a href="#networkservice"><code>NetworkService</code></a> object.
  1466                   </li>
  1467                   <li>
  1468                      If the <var>announcement type</var> equals <code>ssdp:alive</code> then Increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
  1469                      object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
  1470                       to dispatch a newly created event with the name <code>serviceonline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
  1471                       <a href="#networkservice"><code>NetworkService</code></a> object. Otherwise, decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
  1472                      object by <code>1</code> and then  <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
  1473                        to dispatch a newly created event with the name <code>serviceoffline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
  1474                        <a href="#networkservice"><code>NetworkService</code></a> object..
  1475                   </li>
  1476                </ol>
  1477             </li>
  1478          </ol>
  1479 
  1480          <p>
  1481             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.
  1482          </p>
  1483 
  1484          <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>
  1485 
  1486          <ol class="rule">
  1487             <li>
  1488                If <var>network service record</var>'s <code>eventsUrl</code> property is empty then the <a>user agent</a> MUST abort these steps.
  1489             </li>
  1490 
  1491             <li>
  1492                Let <var>callback URL</var> be the value of creating a new <a>user-agent generated callback url</a>.
  1493             </li>
  1494 
  1495             <li>
  1496                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Æ’
  1497                <code>86400</code> and a <em>CALLBACK</em> header
  1498                with a string value of <var>callback URL</var> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
  1499             </li>
  1500 
  1501             <li>
  1502                If a non-200 OK response is received from the HTTP SUBSCRIBE request then the <a>user agent</a> MUST abort these steps.
  1503             </li>
  1504 
  1505             <li>
  1506                On receiving a valid 200 OK response, run the following steps:
  1507 
  1508                <ol class="rule">
  1509                   <li>
  1510                      Let <var>callback ID</var> equal the string value of the first included <em>SID</em> header, if it exists.
  1511                   </li>
  1512                   <li>
  1513                      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.
  1514                   </li>
  1515                   <li>
  1516                      Run the following steps aynchronously and continue to the step labeled <em>listen</em> below.
  1517                   </li>
  1518                   <li>
  1519                      <em>Refresh Subscription</em>: Run the following steps at a set interval (X) within the <a>user agent</a>:
  1520 
  1521                      <ol class="rule">
  1522                         <li>
  1523                            Let <var>current date</var> equal the current UTC date.
  1524                         </li>
  1525                         <li>
  1526                            If <var>current date</var> is less than the <var>timeout date</var> then continue to the step labeled <em>refresh subscription</em> above.
  1527                         </li>
  1528                         <li>
  1529                            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
  1530                            with an integer value of <code>86400</code> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
  1531                         </li>
  1532                         <li>
  1533                            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
  1534                            responses should cause the <a>user agent</a> to continue from the step labeled <em>refresh subscription</em> above.
  1535                         </li>
  1536                      </ol>
  1537 
  1538                   </li>
  1539 
  1540                   <li>
  1541                      <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:
  1542 
  1543                      <ol class="rule">
  1544                         <li>
  1545                            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.
  1546                         </li>
  1547                         <li>
  1548                           Let <var>notification event</var> be a new simple event that uses the <code>Event</code> interface with the name <code>notify</code>,
  1549                            which does not bubble, is not cancellable, and has no default action.
  1550                         </li>
  1551                         <li>
  1552                            Let the <code>data</code> attribute of <var>notification event</var> have the DOMString value of <var>content clone</var>.
  1553                         </li>
  1554                         <li>
  1555                            <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a> to
  1556                             dispatch <var>notification event</var> at the current <a><code>NetworkService</code></a> object.
  1557                         </li>
  1558                      </ol>
  1559                   </li>
  1560 
  1561                </ol>
  1562 
  1563             </li>
  1564          </ol>
  1565 
  1566          </section>
  1567 
  1568          <section>
  1569             <h3>Network Topology Monitoring</h3>
  1570 
  1571                   <div>
  1572                      <p>
  1573                         When the <a>user agent</a> detects that the user has dropped from their connected network, then it MUST run the following steps:
  1574                      </p>
  1575 
  1576                      <ol class="rule">
  1577                         <li>
  1578                            Flush all entries from the <a>list of available service records</a>.
  1579                         </li>
  1580                         <li>
  1581                            For each <a href="#networkservice"><code>NetworkService</code></a> object currently active in the <a>user agent</a> perform the following steps:
  1582 
  1583                            <ol class="rule">
  1584                               <li>
  1585                                  Set the <a href="#dom-networkservice-online"><code>online</code></a> attribute to <code>false</code>.
  1586                               </li>
  1587                               <li>
  1588                                  <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
  1589                                                       to dispatch a newly created event with the name <code>serviceoffline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
  1590                                                       <a href="#networkservice"><code>NetworkService</code></a> object.
  1591                            </ol>
  1592                         </li>
  1593                         <li>
  1594                           For each <a href="#networkservices"><code>NetworkServices</code></a> object currently active in the <a>user agent</a> perform the following steps:
  1595 
  1596                           <ol class="rule">
  1597                             <li>
  1598                               Let <var>number of available services</var> equal the value of <a href="#networkservices"><code>NetworkServices</code></a>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute.
  1599                             </li>
  1600                             <li>
  1601                               Set the <a href="#networkservices"><code>NetworkServices</code></a>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to zero (<code>0</code>).
  1602                             </li>
  1603                             <li>
  1604                               For each <var>available service</var> in <var>number of available services</var> the <a>user agent</a> MUST fire a new simple event with the name <code>serviceunavailable</code> that has no default action, does not bubble and is not cancellable, at the current <a href="#networkservices"><code>NetworkServices</code></a> object.
  1605                             </li>
  1606                           </ol>
  1607                         </li>
  1608 
  1609                      </ol>
  1610 
  1611                      <p>
  1612                         When the <a>user agent</a> detects that the user has connected to a new network, then it SHOULD run the following steps:
  1613                      </p>
  1614 
  1615                      <ol class="rule">
  1616                         <li>
  1617                            Re-issue an mDNS search and SSDP discovery search using all of the <a>valid service type</a> tokens initially provided to all active <a href="#networkservices"><code>NetworkServices</code></a> objects and handle all discovery responses according to the processing defined in <a href="#service-discovery">Section 7: Service Discovery</a>.
  1618                         </li>
  1619                      </ol>
  1620                   </div>
  1621          </section>
  1622       </section>
  1623 
  1624    <section>
  1625       <h3>Garbage collection</h3>
  1626 
  1627       <p>
  1628          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.
  1629       </p>
  1630 
  1631       <p>
  1632          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.
  1633       </p>
  1634 
  1635    </section>
  1636 
  1637 
  1638     <section>
  1639       <h3>Use Cases and Requirements</h3>
  1640 
  1641       <p>This section covers what the requirements are for this API, as well as illustrates some use cases.</p>
  1642 
  1643       <ul class="rule">
  1644          <li>
  1645             Once a user has given permission, user agents should provide the ability for Web pages to communicate directly with a Local-networked Service.
  1646             <ul class="rule">
  1647                <li>
  1648                   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
  1649                   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
  1650                   application logic to communicate. Local devices providing the request service types are discovered and presented to the user for authorization. The user selects one
  1651                   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
  1652                   the user-authorized Local-networked services.
  1653                </li>
  1654             </ul>
  1655          </li>
  1656 
  1657          <li>
  1658            Web pages should be able to communicate with Local-networked Services using the messaging channel supported by those Devices.
  1659            <ul class="rule">
  1660             <li>
  1661                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
  1662                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
  1663                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.
  1664             </li>
  1665            </ul>
  1666          </li>
  1667 
  1668          <li>
  1669            Web pages should be able to communicate with Local-networked Services using the messaging format supported by those Devices.
  1670            <ul class="rule">
  1671             <li>
  1672                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
  1673                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
  1674                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
  1675                Server in the messaging format supported by that Device, which, in this example is a simple key/value pair text format.
  1676             </li>
  1677            </ul>
  1678          </li>
  1679 
  1680          <li>
  1681            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.
  1682            <ul class="rule">
  1683             <li>
  1684                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
  1685                within the network, should not be accessible to the current Web page.
  1686             </li>
  1687            </ul>
  1688          </li>
  1689 
  1690          <li>
  1691            A user should be able to share one or more Local-networked Services based on a particular service type request from a Web page.
  1692            <ul class="rule">
  1693             <li>
  1694                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
  1695                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
  1696                actions on to one or more of the authorized Local-networked Services.
  1697             </li>
  1698            </ul>
  1699          </li>
  1700 
  1701          <li>
  1702            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
  1703            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
  1704            these APIs occur silently without user intervention.
  1705          </li>
  1706       </ul>
  1707     </section>
  1708 
  1709           <section class="informative appendix">
  1710              <h3>Examples</h3>
  1711 
  1712            <div class="example">
  1713             <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.
  1714             <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>
  1715             <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>
  1716             <hr />
  1717             <pre class="brush:js">&lt;input type="button" value="Start" onclick="start()" id="startBtn"/&gt;
  1718 &lt;div id="debugconsole">&lt;/div>
  1719 
  1720 &lt;script>
  1721  var startBtn = document.getElementById('startBtn'),
  1722      debug = document.getElementById('debugconsole');
  1723 
  1724  function start() {
  1725    if(navigator.getNetworkServices) {
  1726       navigator.getNetworkServices('zeroconf:_xbmc-jsonrpc._tcp', gotXBMCService, error);
  1727       startBtn.disabled = true;
  1728    } else {
  1729       debug.innerHTML += "&lt;br&gt;Service Discovery not supported!";
  1730    }
  1731  }
  1732 
  1733  function gotXBMCService(services) {
  1734 
  1735 // Listen for service disconnect messages
  1736 
  1737    services[0].addEventListener('serviceoffline', function ( e ) {
  1738        debug.innerHTML += "&lt;br>" + services[0].name + " disconnected.";
  1739        startBtn.disabled = false;
  1740    }, false);
  1741 
  1742 // Send a service message to get albums list (and process the service response)
  1743 
  1744    var svcXhr = new XMLHttpRequest();
  1745    svcXhr.open("POST", services[0].url + "/getAlbums"); // services[0].url and its subresources have been
  1746                                                         // whitelisted for cross-site XHR use in this
  1747                                                         // current browsing context.
  1748 
  1749    svcXhr.setRequestHeader('Content-Type', 'application/json-rpc');
  1750 
  1751    svcXhr.addEventListener('readystatechange', function ( response ) {
  1752      if( response.readyState != 4 || response.status != 200 )
  1753         return;
  1754      debug.innerHTML += "&lt;br>" + services[0].name + " response received: ";
  1755      debug.textContent += JSON.parse(response.responseText);
  1756    }, false);
  1757 
  1758    var svcMsg = [
  1759      { "jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "genreid": -1,
  1760          "artistid": -1, "start": -1, "end": -1 }, "id": "1" }
  1761    ];
  1762 
  1763    svcXhr.send(JSON.stringify(svcMsg));
  1764    debug.innerHTML += "&lt;br>" + services[0].name + " request sent: ";
  1765    debug.textContent += JSON.stringify(svcMsg);
  1766 
  1767  }
  1768 
  1769  function error( err ) {
  1770    debug.innerHTML += "&lt;br>An error occurred obtaining a local network service.";
  1771    startBtn.disabled = false;
  1772  }
  1773 &lt;/script></pre>
  1774            </div>
  1775 
  1776            <div class="example">
  1777             <p>
  1778              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
  1779              based on the service type requested. The user may also select multiple network services matching the selected service type.
  1780              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
  1781              (<var>urn:schemas-upnp-org:service:RenderingControl:1</var>).
  1782              <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.
  1783             </p>
  1784             <hr />
  1785             <pre class="brush:js">&lt;select name="make" id="make"&gt;
  1786   &lt;option selected="selected" disabled="disabled"&gt;Select make&lt;/option&gt;
  1787   &lt;option&gt;Sony&lt;/option&gt;
  1788   &lt;option&gt;Philips&lt;/option&gt;
  1789   &lt;option&gt;Alba&lt;/option&gt;
  1790 &lt;/select&gt;
  1791 &lt;select name="model" id="model"&gt;&lt;/select&gt;
  1792 &lt;div id="debugconsole"&gt;&lt;/div&gt;
  1793 
  1794 &lt;script&gt;
  1795   var debug = document.getElementById('debugconsole');
  1796 
  1797   var models = {
  1798     "Sony": [
  1799       {"name": "Bravia TV S1000", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" },
  1800       {"name": "Bravia TV S2000", "type": "zeroconf", "service": "_mediarenderer._http._tcp" },
  1801       {"name": "HiFi WD10", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" }
  1802     ],
  1803     "Philips": [ /* ... */ ],
  1804     "Alba": [ /* ... */ ]
  1805   };
  1806 
  1807   var makeEl = document.getElementById("make"),
  1808       modelEl = document.getElementById("model");
  1809 
  1810   makeEl.addEventListener('change', function() {
  1811     modelEl.innerHTML = ""; // reset
  1812     var defaultOption = document.createElement("option");
  1813     defaultOption.textContent = "Select model";
  1814     defaultOption.setAttribute("disabled", "disabled");
  1815     defaultOption.setAttribute("selected", "selected");
  1816     modelEl.appendChild(defaultOption);
  1817     for(var i = 0, l = models[makeEl.value].length; i < l; i++) {
  1818       var option = document.createElement("option");
  1819       option.textContent = models[makeEl.value][i]["name"];
  1820       option.setAttribute("value", models[makeEl.value][i]["type"] + ":" + models[makeEl.value][i]["service"]);
  1821       modelEl.appendChild(option);
  1822     }
  1823   }, false);
  1824 
  1825   modelEl.addEventListener('change', function() {
  1826     if(navigator.getNetworkServices &&
  1827          modelEl.value == "upnp:urn:schemas-upnp-org:service:RenderingControl:1") {
  1828       navigator.getNetworkServices(modelEl.value, successCallback, errorCallback);
  1829     } else if (modelEl.value == "zeroconf:_mediarenderer._http._tcp") {
  1830       debug.innerHTML += "&lt;br&gt;Service type is not implemented by this application.";
  1831     } else {
  1832       debug.innerHTML += "&lt;br&gt;Service Discovery is not supported!";
  1833     }
  1834   }, false);
  1835 &lt;/script&gt;
  1836 
  1837 &lt;script&gt;
  1838   function successCallback( services ) {
  1839 
  1840   // Listen for service push notification messages
  1841 
  1842     services[0].addEventListener('notify', function ( msg ) {
  1843          debug.innerHTML += "&lt;br>" + services[0].name + " event received: ";
  1844          debug.textContent += msg.data;
  1845     }, false);
  1846 
  1847  // Send a control signal to mute the service audio
  1848 
  1849     var svcXhr = new XMLHttpRequest();
  1850     svcXhr.open("POST", services[0].url); // services[0].url and its
  1851                                           // subresources have been whitelisted for
  1852                                           // cross-site XHR use in this current
  1853                                           // browsing context.
  1854 
  1855     svcXhr.setRequestHeader('SOAPAction', 'urn:schemas-upnp-org:service:RenderingControl:1#SetMute');
  1856     svcXhr.setRequestHeader('Content-Type', 'text/xml; charset="utf-8";');
  1857 
  1858     svcXhr.onreadystatechange = function ( response ) {
  1859       if( response.readyState != 4 || response.status != 200 )
  1860         return;
  1861       debug.innerHTML += "&lt;br&gt;" + services[0].name + " response received: ";
  1862       debug.textContent += response.responseXML;
  1863     }
  1864 
  1865     // Service messaging to mute the provided service
  1866     var svcMsg = '&lt;?xml version="1.0" encoding="utf-8"?&gt;' +
  1867                  '&lt;s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ' +
  1868                    'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;' +
  1869                    '&lt;s:Body&gt;' +
  1870                      '&lt;u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"&gt;' +
  1871                        '&lt;InstanceID&gt;0&lt;/InstanceID&gt;' +
  1872                        '&lt;Channel&gt;Master&lt;/Channel&gt;' +
  1873                        '&lt;DesiredMute&gt;true&lt;/DesiredMute&gt;' +
  1874                      '&lt;/u:SetMute&gt;' +
  1875                    '&lt;/s:Body&gt;' +
  1876                  '&lt;/s:Envelope&gt;';
  1877 
  1878     svcXhr.send(svcMsg);
  1879     debug.innerHTML += "&lt;br&gt;" + services[0].name + " request sent: ";
  1880     debug.textContent += svcMsg;
  1881   }
  1882 
  1883   function errorCallback( error ) {
  1884     debug.innerHTML += "&lt;br&gt;An error occurred: " + error.code;
  1885   }
  1886 &lt;/script&gt;</pre>
  1887           </div>
  1888 
  1889        </section>
  1890 
  1891     <section>
  1892       <h3>Acknowledgements</h3>
  1893 
  1894       <p>Thanks are expressed by the editor to the following individuals for their feedback on this specification to date (in alphabetical order):
  1895       <br /><br />
  1896       Gar Bergstedt, Lars-Erik Bolstad, Cathy Chan, Hari G Kumar, Bob Lund, Giuseppe Pascale, Marcin Simonides, Clarke Stevens, Christian S&ouml;derstr&ouml;m, Mark Vickers, ...</p>
  1897 
  1898       <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):
  1899       <br /></br />
  1900       CableLabs, Opera Software ASA, W3C Device APIs Working Group, W3C Web and TV Interest Group, ...</p>
  1901     </section>
  1902 
  1903     <script class='remove'>
  1904     if(SyntaxHighlighter) {
  1905       SyntaxHighlighter.defaults['gutter'] = false;
  1906       SyntaxHighlighter.defaults['toolbar'] = false;
  1907       SyntaxHighlighter.all()
  1908     }
  1909     </script>
  1910 
  1911 </body>
  1912 </html>