- From: Mercurial notifier <cvsmail@w3.org>
- Date: Tue, 02 Oct 2012 17:09:07 +0000
- To: public-dap-commits@w3.org
changeset: 242:b00e3f4ff267 tag: tip user: Rich Tibbett <richt@opera.com> date: Tue Oct 02 19:09:00 2012 +0200 files: discovery-api/WD.html description: Prepare Working Draft for NSD. Attach WD diff -r 985e203d74f7 -r b00e3f4ff267 discovery-api/WD.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/discovery-api/WD.html Tue Oct 02 19:09:00 2012 +0200 @@ -0,0 +1,2790 @@ +<!DOCTYPE html> +<html lang="en" + dir="ltr"> + <head> + <title> + Network Service Discovery + </title> + <meta http-equiv="Content-Type" + content="text/html; charset=utf-8"> + <style type="text/css"> +/* Custom ReSpec CSS (by Rich Tibbett) */ + + /* Add better spacing to sections */ + section, .section { margin-bottom: 2em; } + + /* Reduce note & issue render size */ + .note, .issue { font-size:0.8em; } + + /* Add addition spacing to <ol> and <ul> for rule definition */ + ol.rule li, ul.rule li { padding:0.6em; } + + pre.widl { border: solid thin; background: #EEEEEE; color: black; padding: 0.5em 1em; position: relative; } + pre.widl :link, pre.widl :visited { color: #000; background: transparent; } + 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 } + + div.example { border: solid thin red; background: #F7DFE5; color: black; padding: 0.5em 1em; position: relative; margin: 1em 0 1em 4.6em; width: auto; } + 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 } + + dl.domintro { color: green; margin: 2em 0 2em 2em; padding: 0.5em 1em; border: none; background: #DDFFDD; } + hr + dl.domintro, div.impl + dl.domintro { margin-top: 2.5em; margin-bottom: 1.5em; } + dl.domintro dt, dl.domintro dt * { color: black; text-decoration: none; } + dl.domintro dd { margin: 0.5em 0 1em 2em; padding: 0; } + dl.domintro dd p { margin: 0.5em 0; } + dl.domintro code {font-size: inherit; font-style: italic; } + 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; } + + table { border-collapse:collapse; border-style:hidden hidden none hidden } + table thead { border-bottom:solid } + table tbody th:first-child { border-left:solid } + table td, table th { border-left:solid; border-right:solid; border-bottom:solid thin; vertical-align:top; padding:0.2em } + </style> + <style type="text/css"> +/***************************************************************** + * ReSpec 3 CSS + * Robin Berjon - http://berjon.com/ + *****************************************************************/ + + /* --- INLINES --- */ + em.rfc2119 { + text-transform: lowercase; + font-variant: small-caps; + font-style: normal; + color: #900; + } + + h1 acronym, h2 acronym, h3 acronym, h4 acronym, h5 acronym, h6 acronym, a acronym, + h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr { + border: none; + } + + dfn { + font-weight: bold; + } + + a.internalDFN { + color: inherit; + border-bottom: 1px solid #99c; + text-decoration: none; + } + + a.externalDFN { + color: inherit; + border-bottom: 1px dotted #ccc; + text-decoration: none; + } + + a.bibref { + text-decoration: none; + } + + cite .bibref { + font-style: normal; + } + + code { + color: #ff4500; + } + + + /* --- --- */ + ol.algorithm { counter-reset:numsection; list-style-type: none; } + ol.algorithm li { margin: 0.5em 0; } + ol.algorithm li:before { font-weight: bold; counter-increment: numsection; content: counters(numsection, ".") ") "; } + + /* --- TOC --- */ + .toc a, .tof a { + text-decoration: none; + } + + a .secno, a .figno { + color: #000; + } + + ul.tof, ol.tof { + list-style: none outside none; + } + + .caption { + margin-top: 0.5em; + font-style: italic; + } + + /* --- TABLE --- */ + table.simple { + border-spacing: 0; + border-collapse: collapse; + border-bottom: 3px solid #005a9c; + } + + .simple th { + background: #005a9c; + color: #fff; + padding: 3px 5px; + text-align: left; + } + + .simple th[scope="row"] { + background: inherit; + color: inherit; + border-top: 1px solid #ddd; + } + + .simple td { + padding: 3px 10px; + border-top: 1px solid #ddd; + } + + .simple tr:nth-child(even) { + background: #f0f6ff; + } + + /* --- DL --- */ + .section dd > p:first-child { + margin-top: 0; + } + + .section dd > p:last-child { + margin-bottom: 0; + } + + .section dd { + margin-bottom: 1em; + } + + .section dl.attrs dd, .section dl.eldef dd { + margin-bottom: 0; + } + </style> + <style type="text/css"> +/* --- ISSUES/NOTES --- */ + div.issue-title, div.note-title { + padding-right: 1em; + min-width: 7.5em; + color: #b9ab2d; + } + div.issue-title { color: #e05252; } + div.note-title { color: #52e052; } + div.issue-title span, div.note-title span { + text-transform: uppercase; + } + div.note, div.issue { + margin-top: 1em; + margin-bottom: 1em; + } + .note > p:first-child, .issue > p:first-child { margin-top: 0 } + .issue, .note { + padding: .5em; + border-left-width: .5em; + border-left-style: solid; + } + div.issue, div.note { + padding: 0.5em; + margin: 1em 0; + position: relative; + clear: both; + } + span.note, span.issue { padding: .1em .5em .15em; } + + .issue { + border-color: #e05252; + background: #fbe9e9; + } + .note { + border-color: #52e052; + background: #e9fbe9; + } + + + </style> + <style type="text/css"> +/* HIGHLIGHTS */ + code.prettyprint { + color: inherit; + } + + /* this from google-code-prettify */ + .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} + </style> + <link rel="stylesheet" + href="http://www.w3.org/StyleSheets/TR/W3C-WD" + type="text/css"> + </head> + <body> + <div class="head"> + <p> + <a href="http://www.w3.org/"><img width="72" + height="48" + src="http://www.w3.org/Icons/w3c_home" + alt="W3C"></a> + </p> + <h1 class="title" + id="title"> + Network Service Discovery + </h1> + <h2 id="w3c-working-draft-09-october-2012"> + <abbr title="World Wide Web Consortium">W3C</abbr> Working Draft 09 October 2012 + </h2> + <dl> + <dt> + This version: + </dt> + <dd> + <a href= + "http://www.w3.org/TR/2012/WD-discovery-api-20121009/">http://www.w3.org/TR/2012/WD-discovery-api-20121009/</a> + </dd> + <dt> + Latest published version: + </dt> + <dd> + <a href="http://www.w3.org/TR/discovery-api/">http://www.w3.org/TR/discovery-api/</a> + </dd> + <dt> + Latest editor's draft: + </dt> + <dd> + <a href= + "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html">http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html</a> + </dd> + <dt> + Previous version: + </dt> + <dd> + <a href= + "http://www.w3.org/TR/2012/WD-discovery-api-20120807/">http://www.w3.org/TR/2012/WD-discovery-api-20120807/</a> + </dd> + <dt> + Editors: + </dt> + <dd> + <span>Rich Tibbett</span>, <a href="http://opera.com/">Opera Software ASA</a> + </dd> + <dd> + <span>Clarke Stevens</span>, <a href="http://cablelabs.com/">CableLabs</a> + </dd> + </dl> + <p class="copyright"> + <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2012 <a href= + "http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href= + "http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href= + "http://www.ercim.eu/"><abbr title= + "European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href= + "http://www.keio.ac.jp/">Keio</a>), All Rights Reserved. <abbr title="World Wide Web Consortium">W3C</abbr> + <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href= + "http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href= + "http://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply. + </p> + <hr> + </div> + <section id="abstract" + class="introductory"> + <h2> + Abstract + </h2> + <p> + This specification defines a mechanism for an HTML document to discover and subsequently communicate with + <abbr title="Hypertext Transfer Protocol">HTTP</abbr>-based services advertised via common discovery protocols + within the current network. + </p> + </section> + <section id="sotd" + class="introductory"> + <h2> + Status of This Document + </h2> + <p> + <em>This section describes the status of this document at the time of its publication. Other documents may + supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and + the latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/"><abbr title= + "World Wide Web Consortium">W3C</abbr> technical reports index</a> at http://www.w3.org/TR/.</em> + </p> + <p> + This document represents the early consensus of the group on the scope and features of the proposed + <abbr title="Application Programming Interface">API</abbr>. + </p> + <p> + This document was published by the <a href="http://www.w3.org/2009/dap/">Device APIs Working Group</a> as a + Working Draft. This document is intended to become a <abbr title="World Wide Web Consortium">W3C</abbr> + Recommendation. If you wish to make comments regarding this document, please send them to <a href= + "mailto:public-device-apis@w3.org">public-device-apis@w3.org</a> (<a href= + "mailto:public-device-apis-request@w3.org?subject=subscribe">subscribe</a>, <a href= + "http://lists.w3.org/Archives/Public/public-device-apis/">archives</a>). All feedback is welcome. + </p> + <p> + Publication as a Working Draft does not imply endorsement by the <abbr title= + "World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may be updated, replaced or + obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in + progress. + </p> + <p> + This document was produced by a group operating under the <a href= + "http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 <abbr title= + "World Wide Web Consortium">W3C</abbr> Patent Policy</a>. <abbr title="World Wide Web Consortium">W3C</abbr> + maintains a <a href="http://www.w3.org/2004/01/pp-impl/43696/status" + rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the + group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge + of a patent which the individual believes contains <a href= + "http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential Claim(s)</a> must disclose + the information in accordance with <a href= + "http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section 6 of the <abbr title= + "World Wide Web Consortium">W3C</abbr> Patent Policy</a>. + </p> + </section> + <section id="toc"> + <h2 class="introductory"> + Table of Contents + </h2> + <ul class="toc"> + <li class="tocline"> + <a href="#introduction" + class="tocxref"><span class="secno">1.</span> Introduction</a> + </li> + <li class="tocline"> + <a href="#conformance" + class="tocxref"><span class="secno">2.</span> Conformance</a> + <ul class="toc"> + <li class="tocline"> + <a href="#dependencies" + class="tocxref"><span class="secno">2.1</span> Dependencies</a> + </li> + </ul> + </li> + <li class="tocline"> + <a href="#terminology" + class="tocxref"><span class="secno">3.</span> Terminology</a> + </li> + <li class="tocline"> + <a href="#requesting-networked-services" + class="tocxref"><span class="secno">4.</span> Requesting networked services</a> + <ul class="toc"> + <li class="tocline"> + <a href="#methods" + class="tocxref"><span class="secno">4.1</span> Methods</a> + </li> + <li class="tocline"> + <a href="#error-handling" + class="tocxref"><span class="secno">4.2</span> Error Handling</a> + </li> + </ul> + </li> + <li class="tocline"> + <a href="#obtaining-networked-services" + class="tocxref"><span class="secno">5.</span> Obtaining networked services</a> + <ul class="toc"> + <li class="tocline"> + <a href="#attributes" + class="tocxref"><span class="secno">5.1</span> Attributes</a> + </li> + <li class="tocline"> + <a href="#methods-1" + class="tocxref"><span class="secno">5.2</span> Methods</a> + </li> + <li class="tocline"> + <a href="#events" + class="tocxref"><span class="secno">5.3</span> Events</a> + </li> + </ul> + </li> + <li class="tocline"> + <a href="#communicating-with-a-networked-service" + class="tocxref"><span class="secno">6.</span> Communicating with a networked service</a> + <ul class="toc"> + <li class="tocline"> + <a href="#attributes-1" + class="tocxref"><span class="secno">6.1</span> Attributes</a> + </li> + <li class="tocline"> + <a href="#states" + class="tocxref"><span class="secno">6.2</span> States</a> + </li> + <li class="tocline"> + <a href="#events-1" + class="tocxref"><span class="secno">6.3</span> Events</a> + </li> + </ul> + </li> + <li class="tocline"> + <a href="#service-discovery" + class="tocxref"><span class="secno">7.</span> Service Discovery</a> + <ul class="toc"> + <li class="tocline"> + <a href="#zeroconf-mdns-dns-sd" + class="tocxref"><span class="secno">7.1</span> Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</a> + </li> + <li class="tocline"> + <a href="#simple-service-discovery-protocol-ssdp" + class="tocxref"><span class="secno">7.2</span> Simple Service Discovery Protocol (<abbr title= + "Simple Service Discovery Protocol">SSDP</abbr>)</a> + </li> + <li class="tocline"> + <a href="#network-topology-monitoring" + class="tocxref"><span class="secno">7.3</span> Network Topology Monitoring</a> + </li> + </ul> + </li> + <li class="tocline"> + <a href="#events-summary" + class="tocxref"><span class="secno">8.</span> Events Summary</a> + </li> + <li class="tocline"> + <a href="#garbage-collection" + class="tocxref"><span class="secno">9.</span> Garbage collection</a> + </li> + <li class="tocline"> + <a href="#use-cases-and-requirements" + class="tocxref"><span class="secno">10.</span> Use Cases and Requirements</a> + </li> + <li class="tocline"> + <a href="#examples" + class="tocxref"><span class="secno">A.</span> Examples</a> + </li> + <li class="tocline"> + <a href="#acknowledgements" + class="tocxref"><span class="secno">B.</span> Acknowledgements</a> + </li> + <li class="tocline"> + <a href="#references" + class="tocxref"><span class="secno">C.</span> References</a> + <ul class="toc"> + <li class="tocline"> + <a href="#normative-references" + class="tocxref"><span class="secno">C.1</span> Normative references</a> + </li> + </ul> + </li> + </ul> + </section> + <section class="informative" + id="introduction"> + <h2> + <span class="secno">1.</span> Introduction + </h2> + <p> + <em>This section is non-normative.</em> + </p> + <p> + To enable Web pages to connect and communicate with Local-networked Services provided over <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr>, this specification introduces the <a href= + "#navigatornetworkservice"><code>NavigatorNetworkService</code></a> interface. + </p> + <p> + Using this <abbr title="Application Programming Interface">API</abbr> consists of requesting a well-known + service type, known by developers and advertised by Local-networked Devices. User authorization, where the user + connects the web page to one or more discovered services, is expected before the web page is able to interact + with any Local-networked Services. + </p> + <p> + 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. + </p> + <p> + The user agent, having captured all advertised services on the network from the Service Discovery mechanisms + included in this recommendation, attempts to match the requested service type to a discovered service according + to the processing described herein. + </p> + <p> + 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. 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. + </p> + <p> + 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 + authorized via the provided <abbr title="Application Programming Interface">API</abbr>. 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 connected Local-networked Service. + </p> + <div class="example"> + <p> + Example of requesting a <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr> + advertised service: + </p> + <hr> + <pre class="highlight prettyprint"> +<span class="kwd">function</span><span class="pln"> showServices</span><span class="pun">(</span><span class= +"pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="com">// Show a list of all the services provided to the web page</span><span class="pln"> + </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class= +"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class= +"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> services</span><span class= +"pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class= +"pun"><</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class= +"pun">++)</span><span class="pln"> console</span><span class="pun">.</span><span class="pln">log</span><span class= +"pun">(</span><span class="pln"> services</span><span class="pun">[</span><span class="pln">i</span><span class= +"pun">].</span><span class="pln">name </span><span class="pun">);</span><span class="pln"> +</span><span class="pun">}</span><span class="pln"> + +navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class= +"pun">(</span><span class="str">'zeroconf:_boxee-jsonrpc._tcp'</span><span class="pun">,</span><span class= +"pln"> showServices</span><span class="pun">);</span> +</pre> + </div> + <div class="example"> + <p> + Example of requesting a UPnP advertised service, also handling error conditions: + </p> + <hr> + <pre class="highlight prettyprint"> +<span class="kwd">function</span><span class="pln"> showServices</span><span class="pun">(</span><span class= +"pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="com">// Show a list of all the services provided to the web page</span><span class="pln"> + </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class= +"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class= +"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> services</span><span class= +"pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class= +"pun"><</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class= +"pun">++)</span><span class="pln"> console</span><span class="pun">.</span><span class="pln">log</span><span class= +"pun">(</span><span class="pln"> services</span><span class="pun">[</span><span class="pln">i</span><span class= +"pun">].</span><span class="pln">name </span><span class="pun">);</span><span class="pln"> +</span><span class="pun">}</span><span class="pln"> + +</span><span class="kwd">function</span><span class="pln"> error</span><span class="pun">(</span><span class= +"pln"> e </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + console</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class= +"pln"> </span><span class="str">"Error occurred: "</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> e</span><span class="pun">.</span><span class="pln">code </span><span class= +"pun">);</span><span class="pln"> +</span><span class="pun">}</span><span class="pln"> + +navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class= +"pun">(</span><span class="str">'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'</span><span class= +"pun">,</span><span class="pln"> showServices</span><span class="pun">,</span><span class= +"pln"> error</span><span class="pun">);</span> +</pre> + </div> + <div class="example"> + <p> + Example of requesting either a <abbr title="Domain Name System">DNS</abbr>-<abbr title= + "Service Discovery">SD</abbr> or UPnP advertised service: + </p> + <hr> + <pre class="highlight prettyprint"> +<span class="kwd">function</span><span class="pln"> showServices</span><span class="pun">(</span><span class= +"pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class= +"com">// Show a list of all the services provided to the web page (+ service type)</span><span class="pln"> + </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class= +"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class= +"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> services</span><span class= +"pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class= +"pun"><</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class= +"pun">++)</span><span class="pln"> + console</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class= +"pln"> services</span><span class="pun">[</span><span class="pln">i</span><span class="pun">].</span><span class= +"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class="str">'('</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> services</span><span class="pun">[</span><span class= +"pln">i</span><span class="pun">].</span><span class="pln">type </span><span class="pun">+</span><span class= +"pln"> </span><span class="str">')'</span><span class="pln"> </span><span class="pun">);</span><span class="pln"> +</span><span class="pun">}</span><span class="pln"> + +navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class= +"pun">([</span><span class="pln"> + </span><span class="str">'zeroconf:_boxee-jsonrpc._tcp'</span><span class="pun">,</span><span class="pln"> + </span><span class="str">'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'</span><span class="pln"> +</span><span class="pun">],</span><span class="pln"> showServices</span><span class="pun">);</span> +</pre> + </div> + <p> + For more detailed examples see the <a href="#examples">Examples</a> section. + </p> + </section> + <section id="conformance"> + <h2> + <span class="secno">2.</span> Conformance + </h2> + <p> + As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this + specification are non-normative. Everything else in this specification is normative. + </p> + <p> + The key words <em class="rfc2119" + title="must">must</em>, <em class="rfc2119" + title="must not">must not</em>, <em class="rfc2119" + title="required">required</em>, <em class="rfc2119" + title="should">should</em>, <em class="rfc2119" + title="should not">should not</em>, <em class="rfc2119" + title="recommended">recommended</em>, <em class="rfc2119" + title="may">may</em>, and <em class="rfc2119" + title="optional">optional</em> in this specification are to be interpreted as described in [<cite><a class= + "bibref" + href="#bib-RFC2119">RFC2119</a></cite>]. + </p> + <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 meaning of the key word ("must", "should", + "may", etc) used in introducing the algorithm. + </p> + <p> + Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements + are to be interpreted as requirements on user agents. + </p> + <p> + Conformance requirements phrased as algorithms or specific steps <em class="rfc2119" + title="may">may</em> be implemented in any manner, so long as the end result is equivalent. (In particular, + the algorithms defined in this specification are intended to be easy to follow, and not intended to be + performant.) + </p> + <p> + The only conformance class defined by this specification is a <dfn id="dfn-user-agent">user agent</dfn>. + </p> + <p> + User agents <em class="rfc2119" + title="may">may</em> 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 around + platform-specific limitations. + </p> + <p> + 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 <em class="rfc2119" + title="must">must</em> act as if 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 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 is insufficient. + </p> + <section id="dependencies"> + <h3> + <span class="secno">2.1</span> Dependencies + </h3>This specification relies on several other underlying specifications. + <dl> + <dt> + HTML + </dt> + <dd> + Many fundamental concepts from HTML are used by this specification. [<cite><a class="bibref" + href="#bib-HTML5">HTML5</a></cite>] + </dd> + <dt> + WebIDL + </dt> + <dd> + The IDL blocks in this specification use the semantics of the WebIDL specification. [<cite><a class= + "bibref" + href="#bib-WEBIDL">WEBIDL</a></cite>] + </dd> + </dl> + </section> + </section> + <section id="terminology"> + <h2> + <span class="secno">3.</span> Terminology + </h2> + <p> + 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>". + </p> + <p> + The term DOM is used to refer to the <abbr title="Application Programming Interface">API</abbr> 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 other <code>Node</code> objects as defined in the DOM Core + specifications. [<cite><a class="bibref" + href="#bib-DOM4">DOM4</a></cite>] + </p> + <p> + 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. + </p> + <p> + A <dfn id="dfn-valid-service-type">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. + </p> + <p> + A <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> provided in the <code>type</code> attribute of the <a href= + "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method will be matched against the + services currently contained in the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> according to the algorithms defined in this + specification. + </p> + <p> + A <dfn id="dfn-user-agent-generated-callback-url">user-agent generated callback url</dfn> is a Local-network + accessible <abbr title="Uniform Resource Locator">URL</abbr> endpoint that a <a href="#dfn-user-agent" + class="internalDFN">user agent</a> generates and maintains for receiving <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> NOTIFY requests from UPnP Event sources. It is only required when + the user agent implements UPnP Service Discovery as defined in this specification. + </p> + </section> + <section id="requesting-networked-services"> + <h2> + <span class="secno">4.</span> Requesting networked services + </h2> + <pre class="widl"> +[Supplemental, NoInterfaceObject] +interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> { + // Obtain a Local-networked Service + void <a href="#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type, + in <a href= +"#navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</a> successCallback, + in optional <a href= +"#navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</a> errorCallback ); +}; +<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>; + +[Callback=FunctionOnly, NoInterfaceObject] +interface <dfn id="navigatornetworkservicesuccesscallback">NavigatorNetworkServiceSuccessCallback</dfn> { + void handleEvent( in <a href="#networkservices">NetworkServices</a> services ); +}; + +[NoInterfaceObject] +interface <dfn id="navigatornetworkserviceerror">NavigatorNetworkServiceError</dfn> { + const unsigned short <a href="#dom-navigatornetworkserviceerror-permission_denied">PERMISSION_DENIED_ERR</a> = 1; + const unsigned short <a href="#dom-navigatornetworkserviceerror-unknown_type_prefix">UNKNOWN_TYPE_PREFIX_ERR</a> = 2; + readonly attribute unsigned short <a href="#dom-navigatornetworkserviceerror-code">code</a>; +}; + +[Callback=FunctionOnly, NoInterfaceObject] +interface <dfn id="navigatornetworkserviceerrorcallback">NavigatorNetworkServiceErrorCallback</dfn> { + void handleEvent( in <a href="#navigatornetworkserviceerror">NavigatorNetworkServiceError</a> error ); +}; +</pre> + <section id="methods"> + <h3> + <span class="secno">4.1</span> Methods + </h3> + <dl class="domintro"> + <dt> + <var title="">window</var> . <code title="dom-navigator"><a href= + "http://www.whatwg.org/specs/web-apps/current-work/complete/timers.html#navigator">navigator</a></code> . + <code title="dom-navigator-getNetworkServices"><a href= + "#dom-navigator-getnetworkservices">getNetworkServices</a></code> ( <var title="">type</var> , <var title= + "">successCallback</var> [, <var title="">errorCallback</var> ] ) + </dt> + <dd> + <p> + Prompts the user to select one or more discovered network services that have advertised support for the + requested service type. + </p> + <p> + The <var title="">type</var> argument contains one or more <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens that the web page would like to interact with. + </p> + <p> + If the user accepts, the <var title="">successCallback</var> is invoked, with one or more <a href= + "#networkservice"><code>NetworkService</code></a> objects as its argument. + </p> + <p> + If the user declines, the <var title="">errorCallback</var> (if any) is invoked. + </p> + </dd> + </dl> + <div> + <p> + When the <dfn id="dom-navigator-getnetworkservices" + title="dom-navigator-getnetworkservices"><code>getNetworkServices(type, successCallback[, + errorCallback])</code></dfn> method is called, the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> run the following steps: + </p> + <ol class="rule"> + <li>Let <var>requested control types</var> be initially set to an empty array. + </li> + <li>If <var>type</var> is an array consisting of one or more <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens, then let <var>requested control types</var> by the + value of <var>type</var>, removing any non-<a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens from the resulting array. + </li> + <li>If <var>type</var> is a string consisting of one <a href="#dfn-valid-service-type" + class="internalDFN">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>. + </li> + <li>If <var>requested control types</var> is an array that contains at least one or more <a title= + "valid service type" + href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens then continue to the step labeled <em>process</em> + below. Otherwise, the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> <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 <a href= + "#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 2 + (<a href= + "#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) as + its argument, abort any remaining steps and return. + </li> + <li> + <em>Process</em>: Let <var>services found</var> be an empty array. + </li> + <li>For each <var>available service</var> in the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> run the following steps: + <ol class="rule"> + <li>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. + </li> + <li>Continue at the next <var>available service</var>. + </li> + <li> + <em>Attach</em>: If <var>matched service</var> is not empty then run the following steps: + <ol class="rule"> + <li>Let <var>new service object</var> be a new <a href= + "#networkservice"><code>NetworkService</code></a> object, mapping the parameters of <var>matched + service</var> to this new object where possible. + </li> + <li>Append <var>new service object</var> to the <var>services found</var> array. + </li> + </ol> + </li> + </ol> + </li> + <li>If <var>services found</var> is an empty array, then the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> <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 <a href= + "#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1 + (<a href= + "#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its + argument, abort any remaining steps and return. + </li> + <li>Return, and run the remaining steps asynchronously. + </li> + <li>Optionally, e.g. based on a previously-established user preference, for security reasons, or due to + platform limitations, the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="may">may</em> <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 <a href= + "#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1 + (<a href= + "#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its + argument, abort any remaining steps and return. + </li> + <li>The <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> prompt the user in a user-agent-specific manner for permission to provide the + <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" + class="externalDFN">entry script</a>'s <a href= + "http://www.whatwg.org/specs/web-apps/current-work/complete/origin-0.html#origin" + class="externalDFN">origin</a> with an array of <a href= + "#networkservice"><code>NetworkService</code></a> objects representing the user-authorized subset of + <var>services found</var>. + <p> + If the user grants permission to access one or more networked services then the <a href= + "#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="should">should</em> include an "ongoing local-network communication" indicator. + </p> + <p> + If the user denies permission, then the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> <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 <a href= + "#dom-navigatornetworkserviceerror-code"><code>code</code></a> attribute has the numeric value 1 + (<a href= + "#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) as its + argument, abort any remaining steps and return. + </p> + <p> + If the user never responds, this algorithm stalls on this step. + </p> + </li> + <li>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. + </li> + <li>For each Object <var>service</var> in <var>services</var>, run the following sub-steps: + <ol class="rule"> + <li>Add the <var>service</var>'s <code>url</code> parameter to the <a href= + "#dfn-entry-script-origin-s-url-whitelist" + class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> + whitelist</a>. + </li> + <li>If <var>service</var>'s <code>type</code> parameter begins with the DOMString "<code>upnp:</code>" + and the <var>service</var>'s <code>eventsUrl</code> parameter is not empty then <a href= + "#dfn-setup-a-upnp-events-subscription" + class="internalDFN">setup a UPnP Events Subscription</a> for <var>service</var>. + </li> + </ol> + </li> + <li>Let <var>services manager</var> be a new <a href="#networkservices"><code>NetworkServices</code></a> + object. + </li> + <li>Set <var>services manager</var>'s <a href= + "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to the number of + services currently found in the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> whose <code>type</code> property matches + any of the tokens requested in <var>requested control types</var>. + </li> + <li>Add the set of <var>services</var> to the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> internally against the newly created + <var>services manager</var> object. + </li> + <li>The <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> <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 <var>services + manager</var> as its argument. + </li> + </ol> + <p> + The <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#task-source" + class="externalDFN">task source</a> for these <a href= + "http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#concept-task" + class="externalDFN">tasks</a> is the <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>. + </p> + <p> + When a <a href="#networkservice"><code>NetworkService</code></a> object is provided to a Web page, the + <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> add the <code>url</code> property to the <dfn id= + "dfn-entry-script-origin-s-url-whitelist">entry script origin's <abbr title= + "Uniform Resource Locator">URL</abbr> whitelist</dfn>. This list enables the Web page to override and + initiate cross-site resource requests towards these URLs, and any sub-resources of these URLs, within + the current <a href= + "http://www.whatwg.org/specs/web-apps/current-work/complete/browsers.html#entry-script" + class="externalDFN">entry script</a>'s <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, + Web Messaging, XMLHttpRequest). + </p> + <p> + If the user navigates away from the current browsing context, the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="ct"><em class="rfc2119" + title="must">must</em></em> remove all previously whitelisted urls from the <a href= + "#dfn-entry-script-origin-s-url-whitelist" + class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> + whitelist</a>. 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: + </p> + <ul> + <li>If the current script is reloaded at any point in the same or different window. + </li> + <li>if the current script reinvokes the <a href= + "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method at any point in its + execution. + </li> + <li>If the user navigates forward or back in their history to reload the current page. + </li> + <li>If a script is running in a different origin. + </li> + </ul> + </div> + </section> + <section id="error-handling"> + <h3> + <span class="secno">4.2</span> Error Handling + </h3> + <dl class="domintro"> + <dt> + <var title="">error</var> . <code title="dom-NavigatorNetworkServiceError-code"><a href= + "#dom-navigatornetworkserviceerror-code">code</a></code> + </dt> + <dd> + <p> + Returns the current error's error code. At the current time, this will be <code>1</code> or + <code>2</code>, for which the corresponding error constants <a href= + "#dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and <a href= + "#dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are + defined. + </p> + </dd> + </dl> + <p> + The <dfn id="dom-navigatornetworkserviceerror-code" + title="dom-navigatornetworkserviceerror-code"><code>code</code></dfn> attribute of a <a href= + "#navigatornetworkserviceerror"><code>NavigatorNetworkServiceError</code></a> object <em class= + "ct"><em class="rfc2119" + title="must">must</em></em> return the code for the error, which will be one of the following: + </p> + <dl> + <dt> + <dfn id="dom-navigatornetworkserviceerror-permission_denied" + title="dom-navigatornetworkserviceerror-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> + (numeric value 1) + </dt> + <dd> + The user or user agent denied the page permission to access any services. + </dd> + <dt> + <dfn id="dom-navigatornetworkserviceerror-unknown_type_prefix" + title="dom-navigatornetworkserviceerror-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn> + (numeric value 2) + </dt> + <dd> + No <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens were provided in the method invocation. + </dd> + </dl> + </section> + </section> + <section id="obtaining-networked-services"> + <h2> + <span class="secno">5.</span> Obtaining networked services + </h2> + <p> + 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. + </p> + <pre class="widl"> +[NoInterfaceObject] +interface <dfn id="networkservices">NetworkServices</dfn> { + readonly attribute unsigned long <a href="#dom-networkservices-length">length</a>; + getter <a href="#networkservice">NetworkService</a> (unsigned long index); + <a href="#networkservice">NetworkService</a>? <a href= +"#dom-networkservices-getservicebyid">getServiceById</a>(DOMString id); + + readonly attribute unsigned long <a href="#dom-networkservices-servicesavailable">servicesAvailable</a>; + + // event handler attributes + 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>; + 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>; + +}; + +<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>; +</pre> + <section id="attributes"> + <h3> + <span class="secno">5.1</span> Attributes + </h3> + <dl class="domintro"> + <dt> + <code title="dom-networkservices-length"><a href="#dom-networkservices-length">length</a></code> + </dt> + <dd> + <p> + Returns the current number of services belonging in the respective object's <a href= + "#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a>. + </p> + </dd> + <dt> + <code title="dom-networkservices-servicesavailable"><a href= + "#dom-networkservices-servicesavailable">servicesAvailable</a></code> + </dt> + <dd> + <p> + Returns the current number of services matching one of the app-requested <a href= + "#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens in the <a href= + "#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>. + </p> + </dd> + </dl> + <div> + <p> + The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute <em class="rfc2119" + title="must">must</em> return the number of services represented in the object's corresponding <a href= + "#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> at the time of getting. + </p> + <p> + The <dfn id="dom-networkservices-servicesavailable"><code>servicesAvailable</code></dfn> attribute + <em class="rfc2119" + title="must">must</em> return the number of services in the <a href= + "#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> whose <code>type</code> attribute matches any + of the <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> tokens that was initially used to create the current <a href= + "#networkservices"><code>NetworkServices</code></a> object. + </p> + </div> + </section> + <section id="methods-1"> + <h3> + <span class="secno">5.2</span> Methods + </h3> + <dl class="domintro"> + <dt> + <code title="networkservices-getter"><a href="#networkservices">services</a></code> [ <var title= + "">index</var> ] + </dt> + <dd> + <p> + Returns the specified <a href="#networkservice"><code>NetworkService</code></a> object. + </p> + </dd> + <dt> + <code title="networkservices-getter"><a href="#networkservices">services</a></code> . <code title= + "dom-networkservices-getservicebyid"><a href= + "#dom-networkservices-getservicebyid">getServiceById</a></code> ( <var title="">id</var> ) + </dt> + <dd> + <p> + Returns the <a href="#networkservice"><code>NetworkService</code></a> object with the given identifier, + or null if no service has that identifier. + </p> + </dd> + </dl> + <p> + A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of one or + more current authorized services - the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a>. Each item in the <a href= + "#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> is represented by a <a href= + "#networkservice"><code>NetworkService</code></a> object. The <a href= + "#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> is <span>immutable</span> meaning that it + cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> + object. + </p> + <div class="note"> + <div class="note-title"> + <span>Note</span> + </div> + <p class=""> + 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. + </p> + </div> + <p> + 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 the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> represented by the respective object minus one, + if any services are represented in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a>. + </p> + <p> + 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 href= + "#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a>, the user agent <em class="rfc2119" + title="must">must</em> return the <a href="#networkservice"><code>NetworkService</code></a> object that + represents the <var>index</var>th service in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a>. + </p> + <p> + The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method <em class= + "ct"><em class="rfc2119" + title="must">must</em></em> return the first <a href="#networkservice"><code>NetworkService</code></a> + object in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</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. When no services in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> match the given argument, the method <em class= + "rfc2119" + title="must">must</em> return null. + </p> + <p> + Services available within the local network can connect and disconnect at different times during the + execution of a web page. A <a href="#dfn-user-agent" + class="internalDFN">user agent</a> can inform a web page when the state of networked services matching the + requested <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> change. Web pages can use this information to enable in-page + experiences for communicating the state of networked services 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. + </p> + </section> + <section id="events"> + <h3> + <span class="secno">5.3</span> Events + </h3> + <p> + The following are the event handlers (and their corresponding event handler event types) that <em class= + "ct"><em class="rfc2119" + title="must">must</em></em> be supported, as IDL attributes, by all objects implementing the <a href= + "#networkservices"><code>NetworkServices</code></a> interface: + </p> + <table border="1" + summary="Event handlers for NetworkServices objects"> + <thead> + <tr> + <th> + <span title="event handlers">Event handler</span> + </th> + <th> + <span>Event handler event type</span> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <dfn id="dom-networkservices-onserviceavailable" + title="dom-NetworkServices-onserviceavailable"><code>onserviceavailable</code></dfn> + </td> + <td> + <a href="#event-serviceavailable"><code>serviceavailable</code></a> + </td> + </tr> + <tr> + <td> + <dfn id="dom-networkservices-onserviceunavailable" + title="dom-NetworkServices-onserviceunavailable"><code>onserviceunavailable</code></dfn> + </td> + <td> + <a href="#event-serviceunavailable"><code>serviceunavailable</code></a> + </td> + </tr> + </tbody> + </table> + </section> + </section> + <section id="communicating-with-a-networked-service"> + <h2> + <span class="secno">6.</span> Communicating with a networked service + </h2> + <p> + The <a href="#networkservice"><code>NetworkService</code></a> interface is used to provide a set of connection + information for an <abbr title="Hypertext Transfer Protocol">HTTP</abbr> service endpoint and if available, + service events, running on a networked device. + </p> + <pre class="widl"> +[NoInterfaceObject] +interface <dfn id="networkservice">NetworkService</dfn> { + readonly attribute DOMString <a href="#dom-networkservice-id">id</a>; + readonly attribute DOMString <a href="#dom-networkservice-name">name</a>; + readonly attribute DOMString <a href="#dom-networkservice-type">type</a>; + readonly attribute DOMString <a href="#dom-networkservice-url">url</a>; + readonly attribute DOMString <a href="#dom-networkservice-config">config</a>; + + readonly attribute boolean <a href="#dom-networkservice-online">online</a>; + + // event handler attributes + 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>; + 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>; + + 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>; +}; + +<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>; +</pre> + <section id="attributes-1"> + <h3> + <span class="secno">6.1</span> Attributes + </h3> + <dl class="domintro"> + <dt> + <var title="">service</var> . <code title="dom-networkservice-id"><a href= + "#dom-networkservice-id">id</a></code> + </dt> + <dd> + <p> + A unique identifier for the given user-selected service instance. + </p> + </dd> + <dt> + <var title="">service</var> . <code title="dom-networkservice-name"><a href= + "#dom-networkservice-name">name</a></code> + </dt> + <dd> + <p> + The name of the user-selected service. + </p> + </dd> + <dt> + <var title="">service</var> . <code title="dom-networkservice-type"><a href= + "#dom-networkservice-type">type</a></code> + </dt> + <dd> + <p> + The <a href="#dfn-valid-service-type" + class="internalDFN">valid service type</a> token value of the user-selected service. + </p> + </dd> + <dt> + <var title="">service</var> . <code title="dom-networkservice-url"><a href= + "#dom-networkservice-url">url</a></code> + </dt> + <dd> + <p> + The control <abbr title="Uniform Resource Locator">URL</abbr> endpoint (including any required port + information) of the user-selected control service that has been added to the <a href= + "#dfn-entry-script-origin-s-url-whitelist" + class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> + whitelist</a>. + </p> + </dd> + <dt> + <var title="">service</var> . <code title="dom-networkservice-config"><a href= + "#dom-networkservice-config">config</a></code> + </dt> + <dd> + <p> + The configuration information associated with the service depending on the requested service type. + </p> + </dd> + </dl> + <p> + The <dfn id="dom-networkservice-id"><code>id</code></dfn> attribute is a unique identifier for the service. + The same service provided at different times or on different objects <em class="rfc2119" + title="must">must</em> have the same <a href="#dom-networkservice-id"><code>id</code></a> value. + </p> + <p> + The <dfn id="dom-networkservice-name"><code>name</code></dfn> attribute represents a human-readable title for + the service. + </p> + <p> + The <dfn id="dom-networkservice-type"><code>type</code></dfn> attribute reflects the value of the <a href= + "#dfn-valid-service-type" + class="internalDFN">valid service type</a> of the service. + </p> + <p> + 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 <abbr title="Uniform Resource Locator">URL</abbr></a> pointing to the root + <abbr title="Hypertext Transfer Protocol">HTTP</abbr> endpoint for the service that has been added to the + <a href="#dfn-entry-script-origin-s-url-whitelist" + class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> 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). + </p> + <p> + The <dfn id="dom-networkservice-config"><code>config</code></dfn> attribute provides the raw configuration + information extracted from the given network service. + </p> + </section> + <section id="states"> + <h3> + <span class="secno">6.2</span> States + </h3> + <dl class="domintro"> + <dt> + <var title="">service</var> . <code title="dom-networkservice-online"><a href= + "#dom-networkservice-online">online</a></code> + </dt> + <dd> + <p> + 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. + </p> + </dd> + </dl> + <p> + The <dfn id="dom-networkservice-online"><code>online</code></dfn> attribute indicates whether the service is + reporting itself as being 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 <em class="rfc2119" + title="must">must</em> default to <code>true</code>. + </p> + </section> + <section id="events-1"> + <h3> + <span class="secno">6.3</span> Events + </h3> + <p> + The following are the event handlers (and their corresponding event handler event types) that <em class= + "ct"><em class="rfc2119" + title="must">must</em></em> be supported, as IDL attributes, by all objects implementing the <a href= + "#networkservice"><code>NetworkService</code></a> interface: + </p> + <table border="1" + summary="Event handlers for NetworkService objects"> + <thead> + <tr> + <th> + <span title="event handlers">Event handler</span> + </th> + <th> + <span>Event handler event type</span> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <dfn id="dom-networkservice-onnotify" + title="dom-NetworkService-onnotify"><code>onnotify</code></dfn> + </td> + <td> + <a href="#event-notify"><code>notify</code></a> + </td> + </tr> + <tr> + <td> + <dfn id="dom-networkservice-onserviceonline" + title="dom-NetworkService-onserviceonline"><code>onserviceonline</code></dfn> + </td> + <td> + <a href="#event-serviceonline"><code>serviceonline</code></a> + </td> + </tr> + <tr> + <td> + <dfn id="dom-networkservice-onserviceoffline" + title="dom-NetworkService-onserviceoffline"><code>onserviceoffline</code></dfn> + </td> + <td> + <a href="#event-serviceoffline"><code>serviceoffline</code></a> + </td> + </tr> + </tbody> + </table> + </section> + </section> + <section id="service-discovery"> + <h2> + <span class="secno">7.</span> Service Discovery + </h2> + <p> + A <a href="#dfn-user-agent" + class="internalDFN">user agent</a> conforming to this specification <em class="rfc2119" + title="may">may</em> implement <acronym title="Simple Service Discovery Protocol"><abbr title= + "Simple Service Discovery Protocol">SSDP</abbr></acronym> [<cite><a class="bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] and Zeroconf [<cite><a class="bibref" + href="#bib-DNS-SD">DNS-SD</a></cite>] + [<cite><a class="bibref" + href="#bib-MDNS">MDNS</a></cite>] service discovery mechanisms to enable Web pages to request and connect + with <abbr title="Hypertext Transfer Protocol">HTTP</abbr> services running on networked devices, discovered + via either mechanism, through this <abbr title="Application Programming Interface">API</abbr>. When a + <a href="#dfn-user-agent" + class="internalDFN">user agent</a> implements either of these service discovery mechanisms, then it + <em class="rfc2119" + title="must">must</em> conform to the corresponding algorithms provided in this section of the + specification. + </p> + <p> + This section presents how the results of these two service discovery mechanisms will be matched to requested + service types, how the user agent stores available and active services, how their properties are applied to any + resulting <a href="#networkservice"><code>NetworkService</code></a> objects. + </p> + <p> + It is expected that user agents will perform these service discovery mechanisms asynchronously and periodically + update the <a>list of networked devices</a> as required. The timing of any 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 invocation of this <abbr title= + "Application Programming Interface">API</abbr> from a Web page). + </p> + <p> + The <dfn id="dfn-list-of-available-service-records">list of available service records</dfn> is a single dynamic + internal lookup table within user agents that is used to track all the services that have been discovered and + are available in the current network at any given time. 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 services changes according to the rules defined in this + specification. + </p> + <p> + The <dfn id="dfn-list-of-authorized-service-records">list of authorized service records</dfn> is a single + dynamic internal lookup table within user agents that is used to track the current services that are being + shared with web pages at any given time from the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>. Each record in the <a href= + "#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> is associated with a <var>services manager</var> + object that is assigned as part of the <a href= + "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> algorithm. + </p> + <p> + The rule for <dfn id="dfn-adding-an-available-service">adding an available service</dfn> is the process of + adding a new service or updating an existing service in the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> that is generally available on the user's current + network. This rule takes one argument, <var>network service record</var>, and consists of running the + following steps: + </p> + <ol class="rule"> + <li>Let <var>new service registration flag</var> be <code>true</code>. + </li> + <li>For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>, run the following sub-steps: + <ol class="rule"> + <li>If the <var>existing service record</var>'s <code>id</code> property does not equal <var>network + service record</var>'s <code>id</code> property then abort any remaining sub-steps and continue at the next + available <var>existing service record</var>. + </li> + <li>Set <var>new service registration flag</var> to <code>false</code>. + </li> + <li>Replace the value of <var>existing service record</var> in the current <a href= + "#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> with the value of <var>network service + record</var>. + </li> + </ol> + </li> + <li>If <var>new service registration flag</var> is set to <code>true</code> then add <var>network service + record</var> to the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> as a new entry. + </li> + <li>For each <var>active service</var> in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> run the following steps: + <ol class="rule"> + <li>If <var>network service record</var>'s <code>type</code> property does not equal the current + <var>active service</var>'s <code>type</code> attribute then abort any remaining sub-steps for this + <var>active service</var> and continue at the next available <var>active service</var>. + </li> + <li>If the <var>new service registration flag</var> is set to <code>true</code> then increment the + <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the + <var>services manager</var> associated with the current <var>active service</var> 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> to dispatch a newly created event with the name <a href= + "#event-serviceavailable"><code>serviceavailable</code></a> that uses the <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable, and + has no default action, at the <var>services manager</var> associated with the current <var>active + service</var> object. + </li> + <li>Set <var>active service</var>'s <a href="#dom-networkservice-online"><code>online</code></a> attribute + to <code>true</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> to dispatch a newly created event with the name <a href= + "#event-serviceonline"><code>serviceonline</code></a> that uses the <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable, and + has no default action, at the current <var>active service</var> object. + </li> + </ol> + </li> + </ol> + <p> + The rule for <dfn id="dfn-removing-an-available-service">removing an available service</dfn> is the general + process of removing a service from the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> that has left the user's current network or has + otherwise expired. This rule takes one argument, <var>service identifier</var>, and consists of running the + following steps: + </p> + <ol class="rule"> + <li>For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>, run the following sub-steps: + <ol class="rule"> + <li>If the <var>existing service record</var>'s <code>id</code> property does not match <var>service + identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and + continue at the next available <var>existing service record</var>. + </li> + <li>If the <var>existing service record</var>'s <code>type</code> property begins with the DOMString + "<code>upnp:</code>" and <var>existing service record</var>'s <code>eventsURL</code> property is set then + run the rule to <a href="#dfn-terminate-an-existing-upnp-events-subscription" + class="internalDFN">terminate an existing UPnP Events Subscription</a>, if one is currently active + (as a result of having previously called <a href="#dfn-setup-a-upnp-events-subscription" + class="internalDFN">setup a UPnP Events Subscription</a> against the current <var>existing service + record</var>). + </li> + <li>For each <var>active service</var> in <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> run the following steps: + <ol class="rule"> + <li>If <var>existing service record</var>'s <code>type</code> property does not equal the current <var> + active service</var>'s <code>type</code> attribute then abort any remaining sub-steps for this + <var>active service</var> and continue at the next available <var>active service</var>. + </li> + <li>Decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> + attribute of the <var>services manager</var> associated with the current <var>active service</var> + 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> to dispatch a newly created event with the name <a href= + "#event-serviceunavailable"><code>serviceunavailable</code></a> that uses the <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable, + and has no default action, at the <var>services manager</var> associated with the current + <var>active service</var> object. + </li> + <li>Set <var>active service</var>'s <a href="#dom-networkservice-online"><code>online</code></a> + attribute to <code>false</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> to dispatch a newly created event with the name <a href= + "#event-serviceoffline"><code>serviceoffline</code></a> that uses the <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> interface, which does not bubble, is not cancellable, + and has no default action, at the current <var>active service</var> object. + </li> + </ol> + </li> + <li>Remove <var>existing service record</var> from the current <a href= + "#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>. + </li> + </ol> + </li> + </ol> + <p> + User agents <em class="rfc2119" + title="should">should</em> expire a service record from the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> when its <code>expiryTimestamp</code> attribute + exceeds the current UTC timestamp. When this condition is met the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="should">should</em> run the rule for <a href="#dfn-removing-an-available-service" + class="internalDFN">removing an available service</a>, passing in the expired service record's + <code>id</code> attribute as the only argument. + </p> + <section id="zeroconf-mdns-dns-sd"> + <h3> + <span class="secno">7.1</span> Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title= + "Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>) + </h3> + <p> + For each <abbr title="Domain Name System">DNS</abbr> response received from a user-agent-initiated Multicast + <abbr title="Domain Name System">DNS</abbr> Browse for <abbr title="DNS Pointer Record">PTR</abbr> records + with the name <code>_services._dns-sd._udp</code> on the resolved recommended automatic browsing domain + [<cite><a class="bibref" + href="#bib-MDNS">MDNS</a></cite>], the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> run the following steps: + </p> + <ol class="rule"> + <li>Let <var>service <abbr title="Multicast DNS">mDNS</abbr> responses</var> be an array of <abbr title= + "DNS Pointer Record">PTR</abbr> records received by issuing a Multicast <abbr title= + "Domain Name System">DNS</abbr> Browse for <abbr title="DNS Pointer Record">PTR</abbr> records with the name + of the current discovered service type. + </li> + <li>For each Object <var>service <abbr title="Multicast DNS">mDNS</abbr> response</var> in <var>service + <abbr title="Multicast DNS">mDNS</abbr> responses</var>, run the following steps: + <ol> + <li>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>, + <code>expiryTimestamp</code>. + </li> + <li>Set <var>network service record</var>'s <code>id</code> property to the value of the full + <abbr title="DNS Pointer Record">PTR</abbr> Service Instance Name [<cite><a class="bibref" + href="#bib-MDNS">MDNS</a></cite>]. + </li> + <li>Set <var>network service record</var>'s <code>name</code> property to the value of the <abbr title= + "DNS Pointer Record">PTR</abbr> Service Instance Name's <var>Instance</var> component [<cite><a class= + "bibref" + href="#bib-MDNS">MDNS</a></cite>]. + </li> + <li>Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string + <code>zeroconf:</code> followed be the value of the <abbr title="DNS Pointer Record">PTR</abbr> Service + Instance Name's <var>Service</var> component [<cite><a class="bibref" + href="#bib-MDNS">MDNS</a></cite>]. + </li> + <li>Set <var>network service record</var>'s <code>url</code> property to the resolvable Service + <abbr title="Uniform Resource Locator">URL</abbr> obtained from performing an <abbr title= + "Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr> Lookup [<cite><a class="bibref" + href="#bib-DNS-SD">DNS-SD</a></cite>] of the current service from the <abbr title= + "DNS Pointer Record">PTR</abbr> record provided [<cite><a class="bibref" + href="#bib-MDNS">MDNS</a></cite>]. + </li> + <li>Set <var>network service record</var>'s <code>config</code> property to the string value of the + contents of the first <abbr title="Domain Name System">DNS</abbr>-<abbr title= + "Service Discovery">SD</abbr> TXT record associated with the <var>service <abbr title= + "Multicast DNS">mDNS</abbr> response</var> as defined in [<cite><a class="bibref" + href="#bib-DNS-SD">DNS-SD</a></cite>]. + </li> + <li>Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the + current date, in UTC timestamp format, plus a value of <code>120</code> seconds. + </li> + <li>Run the general rule for <a href="#dfn-adding-an-available-service" + class="internalDFN">adding an available service</a>, passing in the current <var>network service + record</var> as the only argument. + </li> + </ol> + </li> + </ol> + </section> + <section id="simple-service-discovery-protocol-ssdp"> + <h3> + <span class="secno">7.2</span> Simple Service Discovery Protocol (<abbr title= + "Simple Service Discovery Protocol">SSDP</abbr>) + </h3> + <p> + A user agent that implements UPnP service discovery <em class="rfc2119" + title="must">must</em> issue an <dfn id="dfn-advertisement-for-upnp-root-devices">advertisement for UPnP + root devices</dfn> against the user's current local network according to the full normative text and + timing provided in 'Section 1.3.2: Search request with M-SEARCH' detailed in [<cite><a class="bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>]. + </p> + <p> + The user agent <em class="rfc2119" + title="must">must</em> issue all <a title="advertisement for UPnP root devices" + href="#dfn-advertisement-for-upnp-root-devices" + class="internalDFN">advertisements for UPnP root devices</a> with a <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> request line equal to <code>M-SEARCH * <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr>/1.1</code>, with a HOST header equal to the reserved multicast + address and port of <code>239.255.255.250:1900</code>, a MAN header equal to <code>ssdp:discover</code>, + an ST header equal to <code>upnp:rootdevice</code> and a user-agent defined MX header equal to a <dfn id= + "dfn-maximum-upnp-advertisement-response-wait-time">maximum UPnP advertisement response wait time</dfn> + value between <code>1</code> and <code>5</code> seconds. + </p> + <p> + The user agent <em class="rfc2119" + title="must">must</em> listen for incoming requests and process any incoming responses to any <a href= + "#dfn-advertisement-for-upnp-root-devices" + class="internalDFN">advertisement for UPnP root devices</a> on the <dfn id= + "dfn-standard-upnp-address-and-port">standard UPnP address and port</dfn>, on all current local network + interface addresses with the port <code>1900</code>, according to the rules defined in this section. + </p> + <p> + For each <dfn id="dfn-http-response"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</dfn> + following an initial <a href="#dfn-advertisement-for-upnp-root-devices" + class="internalDFN">advertisement for UPnP root devices</a> sent on a <a href= + "#dfn-standard-upnp-address-and-port" + class="internalDFN">standard UPnP address and port</a> the user agent <em class="rfc2119" + title="must">must</em> run the following steps: + </p> + <ol class="rule"> + <li>If the <a href="#dfn-http-response" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is not a + <abbr title="Hypertext Transfer Protocol">HTTP</abbr> 200 OK response then this response is invalid and + the user agent <em class="rfc2119" + title="must">must</em> discard this response, abort any remaining steps and return. The user agent + <em class="rfc2119" + title="may">may</em> issue a new <a href="#dfn-advertisement-for-upnp-root-devices" + class="internalDFN">advertisement for UPnP root devices</a> as a result of this error occurring. + </li> + <li>If the <a href="#dfn-maximum-upnp-advertisement-response-wait-time" + class="internalDFN">maximum UPnP advertisement response wait time</a> has been exceeded since the + initial <a href="#dfn-advertisement-for-upnp-root-devices" + class="internalDFN">advertisement for UPnP root devices</a> was sent then the <a href= + "#dfn-http-response" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and + the user agent <em class="rfc2119" + title="must">must</em> discard this response, abort any remaining steps and return. + </li> + <li>Let <var>ssdp device</var> be an Object with a property for each <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> header received in the <a href="#dfn-http-response" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a>, with each key + being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> response header and each + value being that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> response header's value. + </li> + <li>If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one + <var>USN</var> entry, at least one <var>ST</var> entry and at least one <var>LOCATION</var> entry or the + value of its <var>ST</var> entry is not <code>upnp:rootdevice</code>, then the <a href="#dfn-http-response" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and + the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> discard this response, abort any remaining steps and return. + </li> + <li>The user agent <em class="rfc2119" + title="must">must</em> run the rule for <a href="#dfn-obtaining-a-upnp-device-description-file" + class="internalDFN">obtaining a UPnP Device Description File</a> passing in the first occurrence of + <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor <abbr title= + "Uniform Resource Locator">URL</abbr></var> argument and the first occurrence of <var>USN</var> from + <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of + <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var> argument. + </li> + </ol> + <p> + For each <dfn id="dfn-http-request"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</dfn> + received on a <a href="#dfn-standard-upnp-address-and-port" + class="internalDFN">standard UPnP address and port</a> the user agent <em class="rfc2119" + title="must">must</em> run the following steps: + </p> + <ol class="rule"> + <li>If the <a href="#dfn-http-request" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> is not a + <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request then it is not a valid UPnP + Request and the user agent <em class="rfc2119" + title="must">must</em> return a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> 200 OK response, + discard this request, abort any remaining steps and return. + </li> + <li>Let <var>ssdp device</var> be an Object with a property for each <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> header received in the <a href="#dfn-http-request" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a>, with each key + being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header and each value being + that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header's value. + </li> + <li>If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one + <var>USN</var> entry, at least one <var>NT</var> entry, at least one <var>NTS</var> entry and at least one + <var>LOCATION</var> entry or the value of its <var>NT</var> entry is not <code>upnp:rootdevice</code>, then + the <a href="#dfn-http-request" + class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> is a malformed + UPnP Request and the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> return a 400 Bad Request response, discard this request, abort any remaining + steps and return. + </li> + <li>If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> or + <code>ssdp:update</code> then the user agent <em class="rfc2119" + title="must">must</em> run the rule for <a href="#dfn-obtaining-a-upnp-device-description-file" + class="internalDFN">obtaining a UPnP Device Description File</a> passing in the first occurrence of + <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor <abbr title= + "Uniform Resource Locator">URL</abbr></var> argument and the first occurrence of <var>USN</var> from + <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of + <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var>.<br> + <br> + Otherwise, if <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:byebye</code> then the + user agent <em class="rfc2119" + title="must">must</em> run the rule for <a href= + "#dfn-removing-all-services-from-a-registered-upnp-device" + class="internalDFN">removing all services from a registered UPnP Device</a> passing in the first + occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument. + </li> + </ol> + <p> + The rule for <dfn id="dfn-obtaining-a-upnp-device-description-file">obtaining a UPnP Device Description + File</dfn> is the process of obtaining the contents of a standard UPnP Device Description [<cite><a class= + "bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] from a <abbr title= + "Uniform Resource Locator">URL</abbr>-based resource. This rule takes three arguments - <var>device + descriptor <abbr title="Uniform Resource Locator">URL</abbr></var>, <var>device identifier</var> and + <var>device expiry</var> - and when called the user agent <em class="rfc2119" + title="must">must</em> run the following steps: + </p> + <ol class="rule"> + <li>Let <var>device descriptor file</var> contain the contents of the file located at the <abbr title= + "Uniform Resource Locator">URL</abbr> provided in <var>device descriptor <abbr title= + "Uniform Resource Locator">URL</abbr></var> obtained according to the rules defined in 'Section 2.11: + Retrieving a description using <abbr title="Hypertext Transfer Protocol">HTTP</abbr>' in [<cite><a class= + "bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>]. + </li> + <li>If the value provided in <var>device descriptor <abbr title="Uniform Resource Locator">URL</abbr></var> + cannot be resolved as a reachable <abbr title="Uniform Resource Locator">URL</abbr> on the current network or + the <var>root device descriptor file</var> remains empty then it is invalid and the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> abort any remaining steps and return. + </li> + <li>Run the rule for <a href="#dfn-processing-a-upnp-device-description-file" + class="internalDFN">processing a UPnP Device Description File</a>, passing in the current <var>device + descriptor file</var>, <var>device identifier</var> and <var>device expiry</var> arguments. + </li> + <li>If the current <var>device descriptor file</var> contains a <code><deviceList></code> element then + for each <code><device></code> element within <code><deviceList></code> - herein known as an + <var>embedded device descriptor file</var> - the user agent <em class="rfc2119" + title="must">must</em> run the rule for <a href="#dfn-processing-a-upnp-device-description-file" + class="internalDFN">processing a UPnP Device Description File</a>, passing in the current <var>embedded + device descriptor file</var> as the <var>device descriptor file</var> argument, along with the common + <var>device identifier</var> and <var>device expiry</var> arguments. + </li> + </ol> + <p> + The rule for <dfn id="dfn-processing-a-upnp-device-description-file">processing a UPnP Device Description + File</dfn> is the process of parsing the contents of a standard UPnP Device Description [<cite><a class= + "bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] and registering the UPnP services contained + therein within the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>. + </p> + <p> + The rule for <a href="#dfn-processing-a-upnp-device-description-file" + class="internalDFN">processing a UPnP Device Description File</a> takes three arguments - <var>device + descriptor file</var>, <var>device identifier</var> and <var>device expiry</var> - and when called the + user agent <em class="rfc2119" + title="must">must</em> run the following steps: + </p> + <ol class="rule"> + <li>Let <var>advertised services</var> be a list of all advertised services obtained from the <var>device + descriptor file</var> containing the value of the first occurrence of the <code><serviceList></code> + element as it is defined in 'Section 2.3: Device Description' in [<cite><a class="bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>]. + </li> + <li>For each <code><service></code> element - known as an <var>advertised service</var> - in + <var>advertised services</var> run the following steps: + <ol class="rule"> + <li>Let <var>network service record</var> be a new Object consisting of the following empty properties: + <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>, + <code>eventsUrl</code>, <code>config</code>, <code>expiryTimestamp</code>. + </li> + <li>Set <var>network service record</var>'s <code>id</code> property to the concatenated string value of + <var>device identifier</var> with the <var>advertised service</var>'s <code><serviceId></code> + sub-element. + </li> + <li>Set <var>network service record</var>'s <code>deviceId</code> property to the value of <var>device + identifier</var>. + </li> + <li>Set <var>network service record</var>'s <code>name</code> property to the string value of the first + occurrence of the <var>advertised service</var>'s <code><serviceId></code> sub-element. + </li> + <li>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>advertised + service</var>'s <code><serviceType></code> sub-element. + </li> + <li>Set <var>network service record</var>'s <code>url</code> property to the string value of the first + occurrence of the <var>advertised service</var>'s <code><controlURL></code> sub-element. + </li> + <li>Set <var>network service record</var>'s <code>config</code> property to the string value of the + contents of the first occurrence of the <code><device></code> element in the <var>device descriptor + file</var>. + </li> + <li>If <var>advertised service</var>'s <code><eventSubURL></code> sub-element is not empty, then + set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first + occurrence of the <var>advertised service</var>'s <code><eventSubURL></code> sub-element. + Otherwise, do not set <var>network service record</var>'s <code>eventsUrl</code> property. + </li> + <li>Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the + current date, in UTC timestamp format, plus the value of <var>device expiry</var>. + </li> + <li>Run the general rule for <a href="#dfn-adding-an-available-service" + class="internalDFN">adding an available service</a>, passing in the current <var>network service + record</var> as the only argument. + </li> + </ol> + </li> + </ol> + <p> + The rule for <dfn id="dfn-removing-all-services-from-a-registered-upnp-device">removing all services from a + registered UPnP Device</dfn> is the process of removing all services associated with a device from the + <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a> that has left the user's current network or has + otherwise timed out or expired. This rule takes one argument, <var>device identifier</var>, and consists + of running the following steps: + </p> + <ol class="rule"> + <li>For each <var>existing service record</var> in the current <a href= + "#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>, run the following sub-steps: + <ol class="rule"> + <li>If the <var>existing service record</var>'s <code>deviceId</code> property does not match <var>device + identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and + continue at the next available <var>existing service record</var>. + </li> + <li>Run the general rule for <a href="#dfn-removing-an-available-service" + class="internalDFN">removing an available service</a> passing in <var>existing service + record</var>'s <code>id</code> property as the only argument. + </li> + </ol> + </li> + </ol> + <p> + When the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> is to <dfn id="dfn-setup-a-upnp-events-subscription">setup a UPnP + Events Subscription</dfn>, it is to run the following steps with the current <var>network service + record</var> object as defined in 'Section 4.1.2: SUBSCRIBE with NT and CALLBACK' in [<cite><a class= + "bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>]: + </p> + <ol class="rule"> + <li>If <var>network service record</var>'s <code>eventsUrl</code> property is empty then the <a href= + "#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> abort these steps. + </li> + <li>Let <var>callback <abbr title="Uniform Resource Locator">URL</abbr></var> be the value of creating a new + <a href="#dfn-user-agent-generated-callback-url" + class="internalDFN">user-agent generated callback url</a>. + </li> + <li>Send a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> SUBSCRIBE request with a <em>NT</em> header + with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with a user-agent defined timeout + value (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in + seconds) and a <em>CALLBACK</em> header with a string value of <var>callback <abbr title= + "Uniform Resource Locator">URL</abbr></var> towards the <var>network service record</var>'s + <code>eventsUrl</code> property. + </li> + <li>If a non-200 OK response is received from the <abbr title="Hypertext Transfer Protocol">HTTP</abbr> + SUBSCRIBE request then the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> abort these steps. + </li> + <li>On receiving a valid 200 OK response, run the following steps: + <ol class="rule"> + <li>Let <var>callback ID</var> equal the string value of the first included <em>SID</em> header, if it + exists. + </li> + <li>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 (minus the leading string of <code>Second-</code>), if it exists. + </li> + <li>Run the following steps asynchronously and continue to the step labeled <em>listen</em> below. + </li> + <li> + <em>Refresh Subscription</em>: Run the following steps at a set interval (X) within the <a href= + "#dfn-user-agent" + class="internalDFN">user agent</a>: + <ol class="rule"> + <li>Let <var>current date</var> equal the current UTC date. + </li> + <li>If <var>current date</var> is less than the <var>timeout date</var> then continue to the step + labeled <em>refresh subscription</em> above. + </li> + <li>Send a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> SUBSCRIBE request with a + <em>SID</em> header with the string value of <var>callback ID</var> and a user-agent defined + <em>TIMEOUT</em> header (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent + defined timeout value in seconds) towards the <var>network service record</var>'s + <code>eventsUrl</code> property. + </li> + <li>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 <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> responses should cause the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> to continue from the step labeled <em>refresh + subscription</em> above. + </li> + </ol> + </li> + <li> + <em>Listen</em>: For each <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request received + at the <var>callback <abbr title="Uniform Resource Locator">URL</abbr></var> the <a href= + "#dfn-user-agent" + class="internalDFN">user agent</a> is to run the following steps: + <ol class="rule"> + <li>Let <var>content clone</var> be the result of obtaining the message body of the <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request. If <var>content clone</var> is empty, then + the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> <em class="rfc2119" + title="must">must</em> abort these steps. + </li> + <li>Let <var>notification event</var> be a new simple event that uses the <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> interface with the name <a href= + "#event-notify"><code>notify</code></a>, which does not bubble, is not cancellable, and has no + default action. + </li> + <li>Let the <code>data</code> attribute of <var>notification event</var> have the DOMString value of + <var>content clone</var>. + </li> + <li> + <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" + class="externalDFN">Queue a task</a> to dispatch <var>notification event</var> at the current + <a href="#networkservice" + class="internalDFN"><code>NetworkService</code></a> object. + </li> + </ol> + </li> + </ol> + </li> + </ol> + <p> + A <a href="#dfn-user-agent" + class="internalDFN">user agent</a> can <dfn id= + "dfn-terminate-an-existing-upnp-events-subscription">terminate an existing UPnP Events Subscription</dfn> + at any time for any <var>active service</var> in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> by sending an <abbr title= + "Hypertext Transfer Protocol">HTTP</abbr> UNSUBSCRIBE request - as defined in 'Section 4.1.4: Cancelling a + subscription with UNSUBSCRIBE' in [<cite><a class="bibref" + href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] - with a HOST header set to that <var>active + service</var>'s <code>eventsUrl</code> property and a SID header set to the <var>callback ID</var> + obtained when the initial <a href="#dfn-setup-a-upnp-events-subscription" + class="internalDFN">setup a UPnP Events Subscription</a> action occurred. + </p> + </section> + <section id="network-topology-monitoring"> + <h3> + <span class="secno">7.3</span> Network Topology Monitoring + </h3> + <div> + <p> + When the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> detects that the user has dropped from their connected network then, + for each <var>existing service record</var> in the <a href="#dfn-list-of-available-service-records" + class="internalDFN">list of available service records</a>, the user agent <em class="rfc2119" + title="must">must</em> run the general rule for <a href="#dfn-removing-an-available-service" + class="internalDFN">removing an available service</a> passing in each <var>existing service + record</var>'s <code>id</code> property as the only argument for each call. + </p> + <p> + When the <a href="#dfn-user-agent" + class="internalDFN">user agent</a> detects that the user has connected to a new network or reconnected + to an existing network, then it <em class="rfc2119" + title="should">should</em> restart its discovery mechanisms as defined in the <a href= + "#service-discovery">Service Discovery</a> section of this specification, maintaining the existing + <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> currently in use. + </p> + </div> + </section> + </section> + <section id="events-summary"> + <h2> + <span class="secno">8.</span> Events Summary + </h2> + <p> + The following events are dispatched on the <a href="#networkservices"><code>NetworkServices</code></a> and/or + <a href="#networkservice"><code>NetworkService</code></a> objects: + </p> + <table border="1" + summary="Events Summary table"> + <thead> + <tr> + <th> + <span>Event name</span> + </th> + <th> + <span>Interface</span> + </th> + <th> + <span>Dispatched when...</span> + </th> + </tr> + </thead> + <tbody> + <tr> + <td> + <dfn id="event-serviceavailable"><code>serviceavailable</code></dfn> + </td> + <td> + <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> + </td> + <td> + When a new service that matches one of the <a>requested type tokens</a> is found in the current network. + </td> + </tr> + <tr> + <td> + <dfn id="event-serviceunavailable"><code>serviceunavailable</code></dfn> + </td> + <td> + <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> + </td> + <td> + When an existing service that matches one of the <a>requested type tokens</a> gracefully leaves or + expires from the current network. + </td> + </tr> + <tr> + <td> + <dfn id="event-serviceonline"><code>serviceonline</code></dfn> + </td> + <td> + <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> + </td> + <td> + When a current service renews its service registration within the current network. + </td> + </tr> + <tr> + <td> + <dfn id="event-serviceoffline"><code>serviceoffline</code></dfn> + </td> + <td> + <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> + </td> + <td> + When a current service gracefully leaves or otherwise expires from the current network. + </td> + </tr> + <tr> + <td> + <dfn id="event-notify"><code>notify</code></dfn> + </td> + <td> + <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event" + class="externalDFN"><code>Event</code></a> + </td> + <td> + When a valid UPnP Events Subscription Message is received on a <a href= + "#dfn-user-agent-generated-callback-url" + class="internalDFN">user-agent generated callback url</a> for a current service. This event never + fires for Zeroconf-based services. + </td> + </tr> + </tbody> + </table> + </section> + <section id="garbage-collection"> + <h2> + <span class="secno">9.</span> Garbage collection + </h2> + <p> + Only when the user navigates away from the current browsing context can <a href="#networkservice" + class="internalDFN"><code>NetworkService</code></a> objects be garbage-collected, its records in the <a href= + "#dfn-entry-script-origin-s-url-whitelist" + class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> whitelist</a> be + removed and its corresponding entry in the <a href="#dfn-list-of-authorized-service-records" + class="internalDFN">list of authorized service records</a> be removed according to passing each expired + object identifier through the rule for <a href="#dfn-removing-an-available-service" + class="internalDFN">removing an available service</a>. + </p> + </section> + <section id="use-cases-and-requirements"> + <h2> + <span class="secno">10.</span> Use Cases and Requirements + </h2> + <p> + This section covers what the requirements are for this <abbr title= + "Application Programming Interface">API</abbr>, as well as illustrates some use cases. + </p> + <ul class="rule"> + <li>Once a user has given permission, user agents should provide the ability for Web pages to communicate + directly with a Local-networked Service. + <ul class="rule"> + <li>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 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 application + logic to communicate. Local devices providing the request service types are discovered and presented to the + user for authorization. The user selects one 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 the + user-authorized Local-networked services. + </li> + </ul> + </li> + <li>Web pages should be able to communicate with Local-networked Services using the messaging channel supported + by those Devices. + <ul class="rule"> + <li>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 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 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. + </li> + </ul> + </li> + <li>Web pages should be able to communicate with Local-networked Services using the messaging format supported + by those Devices. + <ul class="rule"> + <li>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 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 communication + protocols supported by Home Media Servers typically vary 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 Server in the messaging format supported by that Device, which, in this + example is a simple key/value pair text format. + </li> + </ul> + </li> + <li>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. + <ul class="rule"> + <li>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 within the + network, should not be accessible to the current Web page. + </li> + </ul> + </li> + <li>A user should be able to share one or more Local-networked Services based on a particular service type + request from a Web page. + <ul class="rule"> + <li>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 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 actions on to one or more + of the authorized Local-networked Services. + </li> + </ul> + </li> + <li>User agents should provide an <abbr title="Application Programming Interface">API</abbr> 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 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 these APIs occur silently without user intervention. + </li> + </ul> + </section> + <section class="informative appendix" + id="examples"> + <h2> + <span class="secno">A.</span> Examples + </h2> + <p> + <em>This section is non-normative.</em> + </p> + <div class="example"> + <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. + </p> + <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> + <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> + <hr> + <pre class="highlight prettyprint"> +<span class="tag"><input</span><span class="pln"> </span><span class="atn">type</span><span class= +"pun">=</span><span class="atv">"button"</span><span class="pln"> </span><span class="atn">value</span><span class= +"pun">=</span><span class="atv">"Start"</span><span class="pln"> </span><span class="atn">onclick</span><span class= +"pun">=</span><span class="atv">"</span><span class="pln">start</span><span class="pun">()</span><span class= +"atv">"</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class= +"atv">"startBtn"</span><span class="tag">/></span><span class="pln"> +</span><span class="tag"><div</span><span class="pln"> </span><span class="atn">id</span><span class= +"pun">=</span><span class="atv">"debugconsole"</span><span class="tag">></div></span><span class="pln"> + +</span><span class="tag"><script></span><span class="pln"> + </span><span class="kwd">var</span><span class="pln"> startBtn </span><span class="pun">=</span><span class= +"pln"> document</span><span class="pun">.</span><span class="pln">getElementById</span><span class= +"pun">(</span><span class="str">'startBtn'</span><span class="pun">),</span><span class="pln"> + debug </span><span class="pun">=</span><span class="pln"> document</span><span class="pun">.</span><span class= +"pln">getElementById</span><span class="pun">(</span><span class="str">'debugconsole'</span><span class= +"pun">);</span><span class="pln"> + + </span><span class="kwd">function</span><span class="pln"> start</span><span class="pun">()</span><span class= +"pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">navigator</span><span class= +"pun">.</span><span class="pln">getNetworkServices</span><span class="pun">)</span><span class= +"pln"> </span><span class="pun">{</span><span class="pln"> + navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class= +"pun">(</span><span class="str">'zeroconf:_xbmc-jsonrpc._tcp'</span><span class="pun">,</span><span class= +"pln"> gotXBMCService</span><span class="pun">,</span><span class="pln"> error</span><span class= +"pun">);</span><span class="pln"> + startBtn</span><span class="pun">.</span><span class="pln">disabled </span><span class="pun">=</span><span class= +"pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class= +"pln"> </span><span class="pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>Service Discovery not supported!"</span><span class= +"pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> + + </span><span class="kwd">function</span><span class="pln"> gotXBMCService</span><span class="pun">(</span><span class= +"pln">services</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + +</span><span class="com">// Listen for service disconnect messages</span><span class="pln"> + + services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">addEventListener</span><span class="pun">(</span><span class="str">'serviceoffline'</span><span class= +"pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class= +"pun">(</span><span class="pln"> e </span><span class="pun">)</span><span class="pln"> </span><span class= +"pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>"</span><span class="pln"> </span><span class="pun">+</span><span class= +"pln"> services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">" disconnected."</span><span class="pun">;</span><span class="pln"> + startBtn</span><span class="pun">.</span><span class="pln">disabled </span><span class= +"pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln"> + </span><span class="pun">},</span><span class="pln"> </span><span class="kwd">false</span><span class= +"pun">);</span><span class="pln"> + +</span><span class= +"com">// Send a service message to get albums list (and process the service response)</span><span class="pln"> + + </span><span class="kwd">var</span><span class="pln"> svcXhr </span><span class="pun">=</span><span class= +"pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">XMLHttpRequest</span><span class= +"pun">();</span><span class="pln"> + svcXhr</span><span class="pun">.</span><span class="pln">open</span><span class="pun">(</span><span class= +"str">"POST"</span><span class="pun">,</span><span class="pln"> services</span><span class="pun">[</span><span class= +"lit">0</span><span class="pun">].</span><span class="pln">url </span><span class="pun">+</span><span class= +"pln"> </span><span class="str">"/getAlbums"</span><span class="pun">);</span><span class="pln"> </span><span class= +"com">// services[0].url and its sub-resources have been</span><span class="pln"> + </span><span class= +"com">// whitelisted for cross-site XHR use in this</span><span class="pln"> + </span><span class= +"com">// current browsing context.</span><span class="pln"> + + svcXhr</span><span class="pun">.</span><span class="pln">setRequestHeader</span><span class= +"pun">(</span><span class="str">'Content-Type'</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">'application/json-rpc'</span><span class="pun">);</span><span class="pln"> + + svcXhr</span><span class="pun">.</span><span class="pln">addEventListener</span><span class= +"pun">(</span><span class="str">'readystatechange'</span><span class="pun">,</span><span class= +"pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class="pun">(</span><span class= +"pln"> response </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="kwd">if</span><span class="pun">(</span><span class="pln"> response</span><span class= +"pun">.</span><span class="pln">readyState </span><span class="pun">!=</span><span class="pln"> </span><span class= +"lit">4</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> response</span><span class= +"pun">.</span><span class="pln">status </span><span class="pun">!=</span><span class="pln"> </span><span class= +"lit">200</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> + </span><span class="kwd">return</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>"</span><span class="pln"> </span><span class="pun">+</span><span class= +"pln"> services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">" response received: "</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">textContent </span><span class="pun">+=</span><span class= +"pln"> JSON</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class= +"pln">response</span><span class="pun">.</span><span class="pln">responseText</span><span class= +"pun">);</span><span class="pln"> + </span><span class="pun">},</span><span class="pln"> </span><span class="kwd">false</span><span class= +"pun">);</span><span class="pln"> + + </span><span class="kwd">var</span><span class="pln"> svcMsg </span><span class="pun">=</span><span class= +"pln"> </span><span class="pun">[</span><span class="pln"> + </span><span class="pun">{</span><span class="pln"> </span><span class="str">"jsonrpc"</span><span class= +"pun">:</span><span class="pln"> </span><span class="str">"2.0"</span><span class="pun">,</span><span class= +"pln"> </span><span class="str">"method"</span><span class="pun">:</span><span class="pln"> </span><span class= +"str">"AudioLibrary.GetAlbums"</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">"params"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class= +"pln"> </span><span class="str">"genreid"</span><span class="pun">:</span><span class="pln"> </span><span class= +"pun">-</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> + </span><span class="str">"artistid"</span><span class="pun">:</span><span class="pln"> </span><span class= +"pun">-</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">"start"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">-</span><span class= +"lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">"end"</span><span class= +"pun">:</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class= +"pln"> </span><span class="pun">},</span><span class="pln"> </span><span class="str">"id"</span><span class= +"pun">:</span><span class="pln"> </span><span class="str">"1"</span><span class="pln"> </span><span class= +"pun">}</span><span class="pln"> + </span><span class="pun">];</span><span class="pln"> + + svcXhr</span><span class="pun">.</span><span class="pln">send</span><span class="pun">(</span><span class= +"pln">JSON</span><span class="pun">.</span><span class="pln">stringify</span><span class="pun">(</span><span class= +"pln">svcMsg</span><span class="pun">));</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>"</span><span class="pln"> </span><span class="pun">+</span><span class= +"pln"> services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">" request sent: "</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">textContent </span><span class="pun">+=</span><span class= +"pln"> JSON</span><span class="pun">.</span><span class="pln">stringify</span><span class="pun">(</span><span class= +"pln">svcMsg</span><span class="pun">);</span><span class="pln"> + + </span><span class="pun">}</span><span class="pln"> + + </span><span class="kwd">function</span><span class="pln"> error</span><span class="pun">(</span><span class= +"pln"> err </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>An error occurred obtaining a local network service."</span><span class= +"pun">;</span><span class="pln"> + startBtn</span><span class="pun">.</span><span class="pln">disabled </span><span class="pun">=</span><span class= +"pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> +</span><span class="tag"></script></span> +</pre> + </div> + <div class="example"> + <p> + 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 based on the + service type requested. The user may also select multiple network services matching the selected service + type. 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 + (<var>urn:schemas-upnp-org:service:RenderingControl:1</var>).<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. + </p> + <hr> + <pre class="highlight prettyprint"> +<span class="tag"><select</span><span class="pln"> </span><span class="atn">name</span><span class= +"pun">=</span><span class="atv">"make"</span><span class="pln"> </span><span class="atn">id</span><span class= +"pun">=</span><span class="atv">"make"</span><span class="tag">></span><span class="pln"> + </span><span class="tag"><option</span><span class="pln"> </span><span class="atn">selected</span><span class= +"pun">=</span><span class="atv">"selected"</span><span class="pln"> </span><span class= +"atn">disabled</span><span class="pun">=</span><span class="atv">"disabled"</span><span class= +"tag">></span><span class="pln">Select make</span><span class="tag"></option></span><span class="pln"> + </span><span class="tag"><option></span><span class="pln">Sony</span><span class= +"tag"></option></span><span class="pln"> + </span><span class="tag"><option></span><span class="pln">Philips</span><span class= +"tag"></option></span><span class="pln"> + </span><span class="tag"><option></span><span class="pln">Alba</span><span class= +"tag"></option></span><span class="pln"> +</span><span class="tag"></select></span><span class="pln"> +</span><span class="tag"><select</span><span class="pln"> </span><span class="atn">name</span><span class= +"pun">=</span><span class="atv">"model"</span><span class="pln"> </span><span class="atn">id</span><span class= +"pun">=</span><span class="atv">"model"</span><span class="tag">></select></span><span class="pln"> +</span><span class="tag"><div</span><span class="pln"> </span><span class="atn">id</span><span class= +"pun">=</span><span class="atv">"debugconsole"</span><span class="tag">></div></span><span class="pln"> + +</span><span class="tag"><script></span><span class="pln"> + </span><span class="kwd">var</span><span class="pln"> debug </span><span class="pun">=</span><span class= +"pln"> document</span><span class="pun">.</span><span class="pln">getElementById</span><span class= +"pun">(</span><span class="str">'debugconsole'</span><span class="pun">);</span><span class="pln"> + + </span><span class="kwd">var</span><span class="pln"> models </span><span class="pun">=</span><span class= +"pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="str">"Sony"</span><span class="pun">:</span><span class="pln"> </span><span class= +"pun">[</span><span class="pln"> + </span><span class="pun">{</span><span class="str">"name"</span><span class="pun">:</span><span class= +"pln"> </span><span class="str">"Bravia TV S1000"</span><span class="pun">,</span><span class= +"pln"> </span><span class="str">"type"</span><span class="pun">:</span><span class="pln"> </span><span class= +"str">"upnp"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"service"</span><span class= +"pun">:</span><span class="pln"> </span><span class= +"str">"urn:schemas-upnp-org:service:RenderingControl:1"</span><span class="pln"> </span><span class= +"pun">},</span><span class="pln"> + </span><span class="pun">{</span><span class="str">"name"</span><span class="pun">:</span><span class= +"pln"> </span><span class="str">"Bravia TV S2000"</span><span class="pun">,</span><span class= +"pln"> </span><span class="str">"type"</span><span class="pun">:</span><span class="pln"> </span><span class= +"str">"zeroconf"</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">"service"</span><span class="pun">:</span><span class="pln"> </span><span class= +"str">"_mediarenderer._http._tcp"</span><span class="pln"> </span><span class="pun">},</span><span class="pln"> + </span><span class="pun">{</span><span class="str">"name"</span><span class="pun">:</span><span class= +"pln"> </span><span class="str">"HiFi WD10"</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">"type"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"upnp"</span><span class= +"pun">,</span><span class="pln"> </span><span class="str">"service"</span><span class="pun">:</span><span class= +"pln"> </span><span class="str">"urn:schemas-upnp-org:service:RenderingControl:1"</span><span class= +"pln"> </span><span class="pun">}</span><span class="pln"> + </span><span class="pun">],</span><span class="pln"> + </span><span class="str">"Philips"</span><span class="pun">:</span><span class="pln"> </span><span class= +"pun">[</span><span class="pln"> </span><span class="com">/* ... */</span><span class="pln"> </span><span class= +"pun">],</span><span class="pln"> + </span><span class="str">"Alba"</span><span class="pun">:</span><span class="pln"> </span><span class= +"pun">[</span><span class="pln"> </span><span class="com">/* ... */</span><span class="pln"> </span><span class= +"pun">]</span><span class="pln"> + </span><span class="pun">};</span><span class="pln"> + + </span><span class="kwd">var</span><span class="pln"> makeEl </span><span class="pun">=</span><span class= +"pln"> document</span><span class="pun">.</span><span class="pln">getElementById</span><span class= +"pun">(</span><span class="str">"make"</span><span class="pun">),</span><span class="pln"> + modelEl </span><span class="pun">=</span><span class="pln"> document</span><span class="pun">.</span><span class= +"pln">getElementById</span><span class="pun">(</span><span class="str">"model"</span><span class= +"pun">);</span><span class="pln"> + + makeEl</span><span class="pun">.</span><span class="pln">addEventListener</span><span class= +"pun">(</span><span class="str">'change'</span><span class="pun">,</span><span class="pln"> </span><span class= +"kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + modelEl</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">=</span><span class= +"pln"> </span><span class="str">""</span><span class="pun">;</span><span class="pln"> </span><span class= +"com">// reset</span><span class="pln"> + </span><span class="kwd">var</span><span class="pln"> defaultOption </span><span class="pun">=</span><span class= +"pln"> document</span><span class="pun">.</span><span class="pln">createElement</span><span class= +"pun">(</span><span class="str">"option"</span><span class="pun">);</span><span class="pln"> + defaultOption</span><span class="pun">.</span><span class="pln">textContent </span><span class= +"pun">=</span><span class="pln"> </span><span class="str">"Select model"</span><span class="pun">;</span><span class= +"pln"> + defaultOption</span><span class="pun">.</span><span class="pln">setAttribute</span><span class= +"pun">(</span><span class="str">"disabled"</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">"disabled"</span><span class="pun">);</span><span class="pln"> + defaultOption</span><span class="pun">.</span><span class="pln">setAttribute</span><span class= +"pun">(</span><span class="str">"selected"</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">"selected"</span><span class="pun">);</span><span class="pln"> + modelEl</span><span class="pun">.</span><span class="pln">appendChild</span><span class="pun">(</span><span class= +"pln">defaultOption</span><span class="pun">);</span><span class="pln"> + </span><span class="kwd">for</span><span class="pun">(</span><span class="kwd">var</span><span class= +"pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class= +"pun">,</span><span class="pln"> l </span><span class="pun">=</span><span class="pln"> models</span><span class= +"pun">[</span><span class="pln">makeEl</span><span class="pun">.</span><span class="pln">value</span><span class= +"pun">].</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i </span><span class= +"pun"><</span><span class="pln"> l</span><span class="pun">;</span><span class="pln"> i</span><span class= +"pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="kwd">var</span><span class="pln"> option </span><span class="pun">=</span><span class= +"pln"> document</span><span class="pun">.</span><span class="pln">createElement</span><span class= +"pun">(</span><span class="str">"option"</span><span class="pun">);</span><span class="pln"> + option</span><span class="pun">.</span><span class="pln">textContent </span><span class= +"pun">=</span><span class="pln"> models</span><span class="pun">[</span><span class="pln">makeEl</span><span class= +"pun">.</span><span class="pln">value</span><span class="pun">][</span><span class="pln">i</span><span class= +"pun">][</span><span class="str">"name"</span><span class="pun">];</span><span class="pln"> + option</span><span class="pun">.</span><span class="pln">setAttribute</span><span class= +"pun">(</span><span class="str">"value"</span><span class="pun">,</span><span class="pln"> models</span><span class= +"pun">[</span><span class="pln">makeEl</span><span class="pun">.</span><span class="pln">value</span><span class= +"pun">][</span><span class="pln">i</span><span class="pun">][</span><span class="str">"type"</span><span class= +"pun">]</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">":"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> models</span><span class= +"pun">[</span><span class="pln">makeEl</span><span class="pun">.</span><span class="pln">value</span><span class= +"pun">][</span><span class="pln">i</span><span class="pun">][</span><span class="str">"service"</span><span class= +"pun">]);</span><span class="pln"> + modelEl</span><span class="pun">.</span><span class="pln">appendChild</span><span class= +"pun">(</span><span class="pln">option</span><span class="pun">);</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> + </span><span class="pun">},</span><span class="pln"> </span><span class="kwd">false</span><span class= +"pun">);</span><span class="pln"> + + modelEl</span><span class="pun">.</span><span class="pln">addEventListener</span><span class= +"pun">(</span><span class="str">'change'</span><span class="pun">,</span><span class="pln"> </span><span class= +"kwd">function</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">navigator</span><span class= +"pun">.</span><span class="pln">getNetworkServices </span><span class="pun">&&</span><span class="pln"> + modelEl</span><span class="pun">.</span><span class="pln">value </span><span class="pun">==</span><span class= +"pln"> </span><span class="str">"upnp:urn:schemas-upnp-org:service:RenderingControl:1"</span><span class= +"pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + navigator</span><span class="pun">.</span><span class="pln">getNetworkServices</span><span class= +"pun">(</span><span class="pln">modelEl</span><span class="pun">.</span><span class="pln">value</span><span class= +"pun">,</span><span class="pln"> successCallback</span><span class="pun">,</span><span class= +"pln"> errorCallback</span><span class="pun">);</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class= +"pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class= +"pln">modelEl</span><span class="pun">.</span><span class="pln">value </span><span class="pun">==</span><span class= +"pln"> </span><span class="str">"zeroconf:_mediarenderer._http._tcp"</span><span class="pun">)</span><span class= +"pln"> </span><span class="pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>Service type is not implemented by this application."</span><span class= +"pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class= +"pln"> </span><span class="pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>Service Discovery is not supported!"</span><span class= +"pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> + </span><span class="pun">},</span><span class="pln"> </span><span class="kwd">false</span><span class= +"pun">);</span><span class="pln"> +</span><span class="tag"></script></span><span class="pln"> + +</span><span class="tag"><script></span><span class="pln"> + </span><span class="kwd">function</span><span class="pln"> successCallback</span><span class= +"pun">(</span><span class="pln"> services </span><span class="pun">)</span><span class="pln"> </span><span class= +"pun">{</span><span class="pln"> + + </span><span class="com">// Listen for service push notification messages</span><span class="pln"> + + services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">addEventListener</span><span class="pun">(</span><span class="str">'notify'</span><span class= +"pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class= +"pun">(</span><span class="pln"> msg </span><span class="pun">)</span><span class="pln"> </span><span class= +"pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class= +"pun">+=</span><span class="pln"> </span><span class="str">"<br>"</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> services</span><span class="pun">[</span><span class="lit">0</span><span class= +"pun">].</span><span class="pln">name </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">" event received: "</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">textContent </span><span class= +"pun">+=</span><span class="pln"> msg</span><span class="pun">.</span><span class="pln">data</span><span class= +"pun">;</span><span class="pln"> + </span><span class="pun">},</span><span class="pln"> </span><span class="kwd">false</span><span class= +"pun">);</span><span class="pln"> + + </span><span class="com">// Send a control signal to mute the service audio</span><span class="pln"> + + </span><span class="kwd">var</span><span class="pln"> svcXhr </span><span class="pun">=</span><span class= +"pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">XMLHttpRequest</span><span class= +"pun">();</span><span class="pln"> + svcXhr</span><span class="pun">.</span><span class="pln">open</span><span class="pun">(</span><span class= +"str">"POST"</span><span class="pun">,</span><span class="pln"> services</span><span class="pun">[</span><span class= +"lit">0</span><span class="pun">].</span><span class="pln">url</span><span class="pun">);</span><span class= +"pln"> </span><span class="com">// services[0].url and its</span><span class="pln"> + </span><span class= +"com">// sub-resources have been whitelisted for</span><span class="pln"> + </span><span class= +"com">// cross-site XHR use in this current</span><span class="pln"> + </span><span class="com">// browsing context.</span><span class="pln"> + + svcXhr</span><span class="pun">.</span><span class="pln">setRequestHeader</span><span class= +"pun">(</span><span class="str">'SOAPAction'</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">'urn:schemas-upnp-org:service:RenderingControl:1#SetMute'</span><span class="pun">);</span><span class="pln"> + svcXhr</span><span class="pun">.</span><span class="pln">setRequestHeader</span><span class= +"pun">(</span><span class="str">'Content-Type'</span><span class="pun">,</span><span class="pln"> </span><span class= +"str">'text/xml; charset="utf-8";'</span><span class="pun">);</span><span class="pln"> + + svcXhr</span><span class="pun">.</span><span class="pln">onreadystatechange </span><span class= +"pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> </span><span class= +"pun">(</span><span class="pln"> response </span><span class="pun">)</span><span class="pln"> </span><span class= +"pun">{</span><span class="pln"> + </span><span class="kwd">if</span><span class="pun">(</span><span class="pln"> response</span><span class= +"pun">.</span><span class="pln">readyState </span><span class="pun">!=</span><span class="pln"> </span><span class= +"lit">4</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> response</span><span class= +"pun">.</span><span class="pln">status </span><span class="pun">!=</span><span class="pln"> </span><span class= +"lit">200</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> + </span><span class="kwd">return</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>"</span><span class="pln"> </span><span class="pun">+</span><span class= +"pln"> services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">" response received: "</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">textContent </span><span class= +"pun">+=</span><span class="pln"> response</span><span class="pun">.</span><span class= +"pln">responseXML</span><span class="pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> + + </span><span class="com">// Service messaging to mute the provided service</span><span class="pln"> + </span><span class="kwd">var</span><span class="pln"> svcMsg </span><span class="pun">=</span><span class= +"pln"> </span><span class="str">'<?xml version="1.0" encoding="utf-8"?>'</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> + </span><span class= +"str">'<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" '</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> + </span><span class= +"str">'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> + </span><span class="str">'<s:Body>'</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> + </span><span class= +"str">'<u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">'</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> + </span><span class="str">'<InstanceID>0</InstanceID>'</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> + </span><span class="str">'<Channel>Master</Channel>'</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> + </span><span class="str">'<DesiredMute>true</DesiredMute>'</span><span class= +"pln"> </span><span class="pun">+</span><span class="pln"> + </span><span class="str">'</u:SetMute>'</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> + </span><span class="str">'</s:Body>'</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> + </span><span class="str">'</s:Envelope>'</span><span class="pun">;</span><span class="pln"> + + svcXhr</span><span class="pun">.</span><span class="pln">send</span><span class="pun">(</span><span class= +"pln">svcMsg</span><span class="pun">);</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>"</span><span class="pln"> </span><span class="pun">+</span><span class= +"pln"> services</span><span class="pun">[</span><span class="lit">0</span><span class="pun">].</span><span class= +"pln">name </span><span class="pun">+</span><span class="pln"> </span><span class= +"str">" request sent: "</span><span class="pun">;</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">textContent </span><span class="pun">+=</span><span class= +"pln"> svcMsg</span><span class="pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> + + </span><span class="kwd">function</span><span class="pln"> errorCallback</span><span class="pun">(</span><span class= +"pln"> error </span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> + debug</span><span class="pun">.</span><span class="pln">innerHTML </span><span class="pun">+=</span><span class= +"pln"> </span><span class="str">"<br>An error occurred: "</span><span class="pln"> </span><span class= +"pun">+</span><span class="pln"> error</span><span class="pun">.</span><span class="pln">code</span><span class= +"pun">;</span><span class="pln"> + </span><span class="pun">}</span><span class="pln"> +</span><span class="tag"></script></span> +</pre> + </div> + </section> + <section id="acknowledgements"> + <h2> + <span class="secno">B.</span> Acknowledgements + </h2> + <p> + Thanks are expressed by the editor to the following individuals for their feedback on this specification to + date (in alphabetical order):<br> + <br> + Gar Bergstedt, Lars-Erik Bolstad, Cathy Chan, Hari G Kumar, Bob Lund, Giuseppe Pascale, Marcin Simonides, + Clarke Stevens, Christian Söderström, Mark Vickers. + </p> + <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):<br> + <br> + CableLabs, Opera Software ASA, <abbr title="World Wide Web Consortium">W3C</abbr> Device APIs Working Group, + <abbr title="World Wide Web Consortium">W3C</abbr> Web and TV Interest Group. + </p> + </section> + <section id="references" + class="appendix"> + <h2> + <span class="secno">C.</span> References + </h2> + <section id="normative-references"> + <h3> + <span class="secno">C.1</span> Normative references + </h3> + <dl class="bibliography"> + <dt id="bib-DNS-SD"> + [DNS-SD] + </dt> + <dd> + S. Cheshire; M. Krochmal. <a href= + "http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt"><cite>DNS-Based Service Discovery.</cite></a> 27 + February 2011. IETF Draft. URL: <a href= + "http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt">http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt</a> + </dd> + <dt id="bib-DOM4"> + [DOM4] + </dt> + <dd> + Anne van Kesteren; Aryeh Gregor; Ms2ger. <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html/"><cite>DOM4.</cite></a> URL: <a href= + "http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html/">http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html/</a> + </dd> + <dt id="bib-HTML5"> + [HTML5] + </dt> + <dd> + Ian Hickson; David Hyatt. <a href="http://www.w3.org/TR/html5"><cite>HTML5.</cite></a> 29 March 2012. W3C + Working Draft. (Work in progress.) URL: <a href="http://www.w3.org/TR/html5">http://www.w3.org/TR/html5</a> + </dd> + <dt id="bib-MDNS"> + [MDNS] + </dt> + <dd> + S. Cheshire; M. Krochmal. <a href= + "http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt"><cite>Multicast DNS.</cite></a> 14 + February 2011. IETF Draft. URL: <a href= + "http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt">http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt</a> + </dd> + <dt id="bib-RFC2119"> + [RFC2119] + </dt> + <dd> + S. Bradner. <a href="http://www.ietf.org/rfc/rfc2119.txt"><cite>Key words for use in RFCs to Indicate + Requirement Levels.</cite></a> March 1997. Internet RFC 2119. URL: <a href= + "http://www.ietf.org/rfc/rfc2119.txt">http://www.ietf.org/rfc/rfc2119.txt</a> + </dd> + <dt id="bib-UPNP-DEVICEARCH11"> + [UPNP-DEVICEARCH11] + </dt> + <dd> + <a href="http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf"><cite>UPnP Device Architecture + 1.1</cite></a>. 15 October 2008. UPnP Forum. PDF document. URL: <a href= + "http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf">http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf</a> + </dd> + <dt id="bib-WEBIDL"> + [WEBIDL] + </dt> + <dd> + Cameron McCormack. <a href="http://www.w3.org/TR/2011/WD-WebIDL-20110927/"><cite>Web IDL.</cite></a> 27 + September 2011. W3C Working Draft. (Work in progress.) URL: <a href= + "http://www.w3.org/TR/2011/WD-WebIDL-20110927/">http://www.w3.org/TR/2011/WD-WebIDL-20110927/</a> + </dd> + </dl> + </section> + </section> + </body> +</html>
Received on Tuesday, 2 October 2012 17:09:13 UTC