- From: Mercurial notifier <cvsmail@w3.org>
- Date: Thu, 12 Jan 2017 13:23:55 +0000
- To: public-dap-commits@w3.org
changeset: 594:ffb713303c21 tag: tip user: Dominique Hazael-Massieux <dom@w3.org> date: Wed Jan 11 10:30:32 2017 +0100 files: discovery-api/Overview.html discovery-api/Overview.src.html description: Shelve Network Service Discovery API per https://lists.w3.org/Archives/Public/public-device-apis/2017Jan/0000.html diff -r 794817a23d8e -r ffb713303c21 discovery-api/Overview.html --- a/discovery-api/Overview.html Thu Mar 17 16:00:35 2016 +0200 +++ b/discovery-api/Overview.html Wed Jan 11 10:30:32 2017 +0100 @@ -1,3405 +1,643 @@ <!DOCTYPE html> -<html lang="en" - dir="ltr" - typeof="bibo:Document" - about="" - property="dcterms:language" - content="en"> - <head> - <title> - Network Service Discovery - </title> - <meta http-equiv="Content-Type" - content="text/html; charset=utf-8"> - <style> -/* Custom ReSpec CSS (by Rich Tibbett) */ +<html dir="ltr" typeof="bibo:Document " prefix="bibo: http://purl.org/ontology/bibo/ w3p: http://www.w3.org/2001/02pd/rec54#" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta property="dc:language" content="en" lang=""> + <style> + /* - /* Add better spacing to sections */ - section, .section { margin-bottom: 2em; } +github.com style (c) Vasily Polovnyov <vast@whiteants.net> - /* Add addition spacing to <ol> and <ul> for rule definition */ - ol.rule li, ul.rule li { padding:0.6em; } +*/ + + .hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; + } + + .hljs-comment, + .hljs-quote { + color: #998; + font-style: italic; + } + + .hljs-keyword, + .hljs-selector-tag, + .hljs-subst { + color: #333; + font-weight: bold; + } + + .hljs-number, + .hljs-literal, + .hljs-variable, + .hljs-template-variable, + .hljs-tag .hljs-attr { + color: #008080; + } + + .hljs-string, + .hljs-doctag { + color: #d14; + } + + .hljs-title, + .hljs-section, + .hljs-selector-id { + color: #900; + font-weight: bold; + } + + .hljs-subst { + font-weight: normal; + } + + .hljs-type, + .hljs-class .hljs-title { + color: #458; + font-weight: bold; + } + + .hljs-tag, + .hljs-name, + .hljs-attribute { + color: #000080; + font-weight: normal; + } + + .hljs-regexp, + .hljs-link { + color: #009926; + } + + .hljs-symbol, + .hljs-bullet { + color: #990073; + } + + .hljs-built_in, + .hljs-builtin-name { + color: #0086b3; + } + + .hljs-meta { + color: #999; + font-weight: bold; + } + + .hljs-deletion { + background: #fdd; + } + + .hljs-addition { + background: #dfd; + } + + .hljs-emphasis { + font-style: italic; + } + + .hljs-strong { + font-weight: bold; + } + </style> + <style id="respec-mainstyle"> + /***************************************************************** + * ReSpec 3 CSS + * Robin Berjon - http://berjon.com/ + *****************************************************************/ + /* Override code highlighter background */ + + .hljs { + background: transparent !important; + } + /* --- 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: #C83500; + } + + th code { + color: inherit; + } + /* --- 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; + } + + .respec-hidden { + display: none; + } + + #respec-ui { + position: fixed; + top: 20px; + right: 20px; + width: 202px; + text-align: right; + } + + #respec-pill, + .respec-info-button { + background: #fff; + height: 2.5em; + color: rgb(120, 120, 120); + border: 1px solid #ccc; + box-shadow: 1px 1px 8px 0 rgba(100, 100, 100, .5); + } + + .respec-info-button { + border: none; + border-radius: 2em; + margin-right: 1em; + min-width: 3.5em; + } + + #respec-pill:disabled { + margin: 10px auto; + font-size: 2.8px; + position: relative; + text-indent: -9999em; + border-top: 1.1em solid rgba(40, 40, 40, 0.2); + border-right: 1.1em solid rgba(40, 40, 40, 0.2); + border-bottom: 1.1em solid rgba(40, 40, 40, 0.2); + border-left: 1.1em solid #ffffff; + transform: translateZ(0); + animation: respec-spin 1.1s infinite linear; + box-shadow: none; + } + + #respec-pill:disabled, + #respec-pill:disabled:after { + border-radius: 50%; + width: 10em; + height: 10em; + } + + @keyframes respec-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + + #respec-pill:hover, + #respec-pill:focus { + color: rgb(0, 0, 0); + transition: color .2s + } + + #respec-menu { + font-family: sans-serif; + background: #fff; + box-shadow: 1px 1px 8px 0 rgba(100, 100, 100, .5); + width: 200px; + display: none; + text-align: left; + margin-top: 5px; + font-size: .8em; + } + + .respec-save-button { + background: #fff; + border: 1px solid #000; + border-radius: 5px; + padding: 5px; + margin: 5px; + display: block; + width: 100%; + color: #000; + text-decoration: none; + text-align: center; + font-size: inherit; + } + + #respec-ui button:focus, + #respec-pill:focus, + .respec-option:focus { + outline: 0; + outline-style: none; + } + + #respec-ui button.respec-pill-error { + background-color: red; + color: white; + } + + #respec-ui button.respec-pill-warning { + background-color: orange; + color: white; + } + + #respec-menu button.respec-option { + background: white; + border: none; + width: 100%; + text-align: left; + font-size: inherit; + padding: 1.2em 1.2em; + } + + #respec-menu button.respec-option:hover { + background-color: #eeeeee; + } + + .respec-cmd-icon { + padding-right: .5em; + } + + #respec-ui button.respec-option:last-child { + border: none; + border-radius: inherit; + } + + .respec-offending-element { + display: inline-block; + position: relative; + background: url(data:image/gif;base64,R0lGODdhBAADAPEAANv///8AAP///wAAACwAAAAABAADAEACBZQjmIAFADs=) bottom repeat-x; + } + + @media print { + .removeOnSave { + display: none; + } + } + </style> + <title> + Network Service Discovery + </title> - 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 black; background: #FFFFF0; 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: white; color: black; position: absolute; top: 0; margin: -1px 0 0 -7.6em; width: 5em; border: thin solid black; 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; font-size:0.8em; } + <style> + /* Custom ReSpec CSS (by Rich Tibbett) */ + /* Add better spacing to sections */ + + section, + .section { + margin-bottom: 2em; + } + /* 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 black; + background: #FFFFF0; + 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: white; + color: black; + position: absolute; + top: 0; + margin: -1px 0 0 -7.6em; + width: 5em; + border: thin solid black; + 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; + font-size: 0.8em; + } + + 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> - 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> -/***************************************************************** - * ReSpec 3 CSS - * Robin Berjon - http://berjon.com/ - *****************************************************************/ + <!--[if lt IE 9]><script src='https://www.w3.org/2008/site/js/html5shiv.js'></script><![endif]--> + <script id="initialUserConfig" type="application/json"> + { + "specStatus": "WG-NOTE", + "shortName": "discovery-api", + "edDraftURI": "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html", + "previousMaturity": "WD", + "previousPublishDate": "2014-02-20", + "editors": [ + { + "name": "Rich Tibbett", + "company": "Opera Software ASA", + "companyURL": "http://opera.com/" + }], + "wg": "Device and Sensors Working Group", + "wgURI": "https://www.w3.org/2009/dap/", + "wgPublicList": "public-device-apis", + "wgPatentURI": "https://www.w3.org/2004/01/pp-impl/43696/status", + "noIDLIn": true, + "publishDate": "2017-01-12" + } + </script> + <link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/2016/W3C-WG-NOTE.css"> + <meta name="generator" content="ReSpec 8.4.1"> + <link rel="canonical" href="https://www.w3.org/TR/discovery-api/"> +</head> +<body class="h-entry" role="document" id="respecDocument"> + <div class="head" role="contentinfo" id="respecHeader"> + <p> + <a class="logo" href="https://www.w3.org/"><img src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" alt="W3C" width="72" height="48"></a> + </p> + <h1 class="title p-name" id="title" property="dcterms:title">Network Service Discovery</h1> + <h2 id="w3c-working-group-note-12-january-2017"><abbr title="World Wide Web Consortium">W3C</abbr> Working Group Note <time property="dcterms:issued" class="dt-published" datetime="2017-01-12">12 January 2017</time></h2> + <dl> + <dt>This version:</dt> + <dd><a class="u-url" href="https://www.w3.org/TR/2017/NOTE-discovery-api-20170112/">https://www.w3.org/TR/2017/NOTE-discovery-api-20170112/</a></dd> + <dt>Latest published version:</dt> + <dd><a href="https://www.w3.org/TR/discovery-api/">https://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 rel="dcterms:replaces" href="https://www.w3.org/TR/2014/WD-discovery-api-20140220/">https://www.w3.org/TR/2014/WD-discovery-api-20140220/</a></dd> + <dt>Editor:</dt> + <dd class="p-author h-card vcard" property="bibo:editor" resource="_:editor0"><span property="rdf:first" typeof="foaf:Person"><span property="foaf:name" class="p-name fn">Rich Tibbett</span>, <a property="foaf:workplaceHomepage" class="p-org org h-org h-card" href="http://opera.com/">Opera Software ASA</a></span> + <span property="rdf:rest" resource="rdf:nil"></span> + </dd> - /* --- INLINES --- */ - em.rfc2119 { - text-transform: lowercase; - font-variant: small-caps; - font-style: normal; - color: #900; + </dl> + <p class="copyright"> + <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2017 + + <a href="https://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="https://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, + <a href="https://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, + <a href="https://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>). + <abbr title="World Wide Web Consortium">W3C</abbr> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, + <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and + <a rel="license" href="https://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply. + </p> + <hr title="Separator for header"> + </div> + + <section id="abstract" class="introductory" property="dc:abstract"> + <h2 id="h-abstract" resource="#h-abstract"><span property="xhv:role" resource="xhv:heading">Abstract</span></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 id="h-sotd" resource="#h-sotd"><span property="xhv:role" resource="xhv:heading">Status of This Document</span></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="https://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at https://www.w3.org/TR/.</em> + </p> + + <p> + <strong>Work on this document has been discontinued and it should not be referenced or used as a basis for implementation.</strong> The <a href="https://www.w3.org/TR/presentation-api/">Presentation API</a> and the <a href="https://www.w3.org/TR/remote-playback/">Remote Playback API</a> address a subset of the use cases this API attempted to address. + </p> + + <p> + This document was published by the <a href="https://www.w3.org/2009/dap/">Device and Sensors Working Group</a> as a Working Group Note. 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="https://lists.w3.org/Archives/Public/public-device-apis/">archives</a>). All comments are welcome. + </p> + <p> + Publication as a Working Group Note 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 id="sotd_patent" property="w3p:patentRules" href="https://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="https://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="https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential + Claim(s)</a> must disclose the information in accordance with + <a href="https://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> + <p>This document is governed by the <a id="w3c_process_revision" href="https://www.w3.org/2015/Process-20150901/">1 September 2015 <abbr title="World Wide Web Consortium">W3C</abbr> Process Document</a>. + </p> + + </section> + + + + <style> + a.externalDFN { + color: #00C; + border-bottom: 1px dashed #00C; } - - 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; + + a.internalDFN { + color: #00C; + text-decoration: solid; } - - 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; - } - - /* --- 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; - } - - @media print { - .removeOnSave { - display: none; - } - } - </style> - <style> -/* --- 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: #2b2; } - 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: 1em 1.2em 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> -/* 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="https://www.w3.org/StyleSheets/TR/W3C-ED"> - </head> - <body class="h-entry" - style="" - role="document" - id="respecDocument"> - <div class="head" - role="contentinfo" - id="respecHeader"> - <p> - <a href="http://www.w3.org/"><img width="72" - height="48" - src="https://www.w3.org/Icons/w3c_home" - alt="W3C"></a> - </p> - <h1 class="title p-name" - id="title" - property="dcterms:title"> - Network Service Discovery - </h1> - <h2 property="dcterms:issued" - datatype="xsd:dateTime" - content="2014-02-18T12:22:23.000Z" - id="w3c-editor-s-draft-18-february-2014"> - <abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" - datetime="2014-02-18">18 February 2014</time> - </h2> - <dl> - <dt> - This version: - </dt> - <dd> - <a class="u-url" - 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> - 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> - Editor: - </dt> - <dd class="p-author h-card vcard" - rel="bibo:editor" - inlist=""> - <span typeof="foaf:Person"><span property="foaf:name" - class="p-name fn">Rich Tibbett</span>, <a rel="foaf:workplaceHomepage" - class="p-org org h-org h-card" - href="http://opera.com/">Opera Software ASA</a></span> - </dd> - </dl> - <p class="copyright"> - <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2014 <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>, <a href="http://ev.buaa.edu.cn/">Beihang</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" - property="dcterms:abstract" - datatype="" - typeof="bibo:Chapter" - resource="#ref" - rel="bibo:Chapter"> - <h2 aria-level="1" - role="heading" - id="h2_abstract"> - 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" - typeof="bibo:Chapter" - resource="#ref" - rel="bibo:Chapter"> - <h2 aria-level="1" - role="heading" - id="h2_sotd"> - 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 an - Editor's Draft. 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 comments are welcome. - </p> - <p> - Publication as an Editor's 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 id="sotd_patent" - about="" - rel="w3p:patentRules" - 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" - aria-level="1" - role="heading" - id="h2_toc"> - Table of Contents - </h2> - <ul class="toc" - role="directory" - id="respecContents"> - <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="#security-and-privacy-considerations" - class="tocxref"><span class="secno">4.</span> Security and privacy considerations</a> - <ul class="toc"> - <li class="tocline"> - <a href="#security-considerations-for-api-implementations" - class="tocxref"><span class="secno">4.1</span> Security considerations for <abbr title= - "Application Programming Interface">API</abbr> implementations</a> - </li> - <li class="tocline"> - <a href="#privacy-considerations-for-api-implementations" - class="tocxref"><span class="secno">4.2</span> Privacy considerations for <abbr title= - "Application Programming Interface">API</abbr> implementations</a> - </li> - <li class="tocline"> - <a href="#additional-api-implementation-considerations" - class="tocxref"><span class="secno">4.3</span> Additional <abbr title= - "Application Programming Interface">API</abbr> implementation considerations</a> - </li> - </ul> - </li> - <li class="tocline"> - <a href="#requesting-networked-services" - class="tocxref"><span class="secno">5.</span> Requesting networked services</a> - <ul class="toc"> - <li class="tocline"> - <a href="#methods" - class="tocxref"><span class="secno">5.1</span> Methods</a> - </li> - <li class="tocline"> - <a href="#error-handling" - class="tocxref"><span class="secno">5.2</span> Error Handling</a> - </li> - </ul> - </li> - <li class="tocline"> - <a href="#obtaining-networked-services" - class="tocxref"><span class="secno">6.</span> Obtaining networked services</a> - <ul class="toc"> - <li class="tocline"> - <a href="#attributes" - class="tocxref"><span class="secno">6.1</span> Attributes</a> - </li> - <li class="tocline"> - <a href="#methods-1" - class="tocxref"><span class="secno">6.2</span> Methods</a> - </li> - <li class="tocline"> - <a href="#events" - class="tocxref"><span class="secno">6.3</span> Events</a> - </li> - </ul> - </li> - <li class="tocline"> - <a href="#communicating-with-a-networked-service" - class="tocxref"><span class="secno">7.</span> Communicating with a networked service</a> - <ul class="toc"> - <li class="tocline"> - <a href="#attributes-1" - class="tocxref"><span class="secno">7.1</span> Attributes</a> - </li> - <li class="tocline"> - <a href="#states" - class="tocxref"><span class="secno">7.2</span> States</a> - </li> - <li class="tocline"> - <a href="#events-1" - class="tocxref"><span class="secno">7.3</span> Events</a> - </li> - </ul> - </li> - <li class="tocline"> - <a href="#service-discovery" - class="tocxref"><span class="secno">8.</span> Service Discovery</a> - <ul class="toc"> - <li class="tocline"> - <a href="#zeroconf-mdns-dns-sd" - class="tocxref"><span class="secno">8.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">8.2</span> Simple Service Discovery Protocol (<abbr title= - "Simple Service Discovery Protocol">SSDP</abbr>)</a> - </li> - <li class="tocline"> - <a href="#discovery-and-launch-protocol-dial" - class="tocxref"><span class="secno">8.3</span> Discovery and Launch Protocol (<abbr title= - "Discovery and Launch Protocol">DIAL</abbr>)</a> - </li> - <li class="tocline"> - <a href="#network-topology-monitoring" - class="tocxref"><span class="secno">8.4</span> Network Topology Monitoring</a> - </li> - </ul> - </li> - <li class="tocline"> - <a href="#events-summary" - class="tocxref"><span class="secno">9.</span> Events Summary</a> - </li> - <li class="tocline"> - <a href="#garbage-collection" - class="tocxref"><span class="secno">10.</span> Garbage collection</a> - </li> - <li class="tocline"> - <a href="#use-cases-and-requirements" - class="tocxref"><span class="secno">11.</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> - <li class="tocline"> - <a href="#informative-references" - class="tocxref"><span class="secno">C.2</span> Informative references</a> - </li> - </ul> - </li> - </ul> - </section> - <section class="informative" - id="introduction"> - <h2 aria-level="1" - role="heading" - id="h2_introduction"> - <span class="secno">1.</span> Introduction - </h2> - <p> - <em>This section is non-normative.</em> - </p> - <p> - This specification defines the <a href="#navigatornetworkservice"><code>NavigatorNetworkService</code></a> - interface to enable Web pages to connect and communicate with Local-networked Services provided over - <abbr title="Hypertext Transfer Protocol">HTTP</abbr>. This enables access to services and content provided by - home network devices, including the discovery and playback of content available to those devices, both from - services such as traditional broadcast media and internet based services as well as local services. Initial - design goals and requirements provided by the <a href="http://www.w3.org/2011/webtv/"><abbr title= - "World Wide Web Consortium">W3C</abbr> Web & TV interest group</a> are documented in [<cite><a class= - "bibref" - href="#bib-hnreq">hnreq</a></cite>]. - </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 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 <a href= - "#dfn-service-discovery-mechanisms" - class="internalDFN">service discovery mechanisms</a> included in this recommendation, attempts to match the - requested service type to a discovered service according to the processing described herein. Only - Local-networked Services that pass a <a href="#dfn-preliminary-cors-check" - class="internalDFN">preliminary CORS check</a> should be made available to web pages by a user agent. A user - agent may provide a way for users to white-list non-CORS enabled Local-networked Services but implementation - of such a feature is left to the discretion of the implementer. - </p> - <p> - If a service connectivity request is successful then the Web page is provided with a promise-based success - callback with the all necessary information to communicate with the authorized Local-networked Service. If the - request fails then the Web page will receive a promise-based error callback containing an error string - 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> - <p> - Services available within the local network can connect and disconnect at different times during the execution - of a web page. The user agent can inform a web page when the state of networked services matching any of the - requested valid service types 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 defined herein). - </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 prettyprinted" - style=""> -<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= -"kwd">then</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 prettyprinted" - style=""> -<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">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">'upnp:urn:schemas-upnp-org:service:ContentDirectory:1'</span><span class= -"pun">).</span><span class="kwd">then</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 prettyprinted" - style=""> -<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="kwd">then</span><span class="pun">(</span><span class= -"pln">showServices</span><span class="pun">);</span> -</pre> - </div> - <p> - For more detailed examples, including examples of communicating with obtained networked services, see the - <a href="#examples">Examples</a> section. - </p> - </section> - <section id="conformance" - typeof="bibo:Chapter" - resource="#ref" - rel="bibo:Chapter"> - <h2 aria-level="1" - role="heading" - id="h2_conformance"> - <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 aria-level="2" - role="heading" - id="h3_dependencies"> - <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 aria-level="1" - role="heading" - id="h2_terminology"> - <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 any of the following: - </p> - <ul> - <li>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. - </li> - <li>a string that begins with <code>dial:</code> followed by an integer version. - </li> - </ul> - <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 URL 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> - <p> - In this specification we use the following terms to describe the processes required for Local-networked - Services management: - </p> - <ul> - <li>A <dfn id="dfn-new-service">new service</dfn> is a Local-networked Service that has not previously been - discovered or registered in the <a href="#dfn-list-of-available-service-records" - class="internalDFN">list of available service records</a>. - </li> - <li>An <dfn id="dfn-existing-service">existing service</dfn> is a Local-networked Service that has previously - been discovered and is registered in the <a href="#dfn-list-of-available-service-records" - class="internalDFN">list of available service records</a>. - </li> - <li>A <dfn id="dfn-current-service">current service</dfn> is a Local-networked Service, represented by a - <a href="#networkservice"><code>NetworkService</code></a> object, that is currently being shared with a web - page via a <a href="#networkservices"><code>NetworkServices</code></a> object registered in the <a href= - "#dfn-list-of-active-service-managers" - class="internalDFN">list of active service managers</a>. - </li> - </ul> - <p> - A <dfn id="dfn-network-services-whitelist">network services whitelist</dfn> is a list of zero or more <a href= - "#dfn-valid-service-type" - class="internalDFN">valid service type</a> tokens that, when matched to a service type discovered in the - local network, enables that service to be shared with a web page even if that Local-networked Service does - not itself allow Cross-Origin Resource Sharing [<cite><a class="bibref" - href="#bib-CORS">CORS</a></cite>]. A <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST">MUST</em> simulate CORS support for all service interaction in this case. Implementation of - this feature is at implementer's discretion. When a <a href="#dfn-user-agent" - class="internalDFN">user agent</a> does not implement a <a href="#dfn-network-services-whitelist" - class="internalDFN">network services whitelist</a> then it is to treat this as always being an empty list. - </p> - </section> - <section id="security-and-privacy-considerations"> - <h2 aria-level="1" - role="heading" - id="h2_security-and-privacy-considerations"> - <span class="secno">4.</span> Security and privacy considerations - </h2> - <p> - The <abbr title="Application Programming Interface">API</abbr> defined in this specification can be used to - find and connect to devices and services within a user's current network. This discloses information related to - a user's network: devices available on their network and the publicly-accessible services ("networked - services") currently running and available on those devices. The distribution of this information could - potentially compromise the user's privacy. A conforming implementation of this specification <em class= - "rfc2119" - title="MUST">MUST</em> provide a mechanism that protects the user's privacy. This mechanism <em class= - "rfc2119" - title="MUST">MUST</em> ensure that no networked service information is retrievable without the user's - express permission. - </p> - <section id="security-considerations-for-api-implementations"> - <h3 aria-level="2" - role="heading" - id="h3_security-considerations-for-api-implementations"> - <span class="secno">4.1</span> Security considerations for <abbr title= - "Application Programming Interface">API</abbr> implementations - </h3> - <p> - A <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="SHOULD">SHOULD</em> only allow web pages to connect with Local-networked Services that have passed - a <a href="#dfn-preliminary-cors-check" - class="internalDFN">preliminary CORS check</a> indicating they support Cross-Origin Resource Sharing - [<cite><a class="bibref" - href="#bib-CORS">CORS</a></cite>]. In this way, a <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="SHOULD NOT">SHOULD NOT</em> allow web pages to access other arbitrary networked services on the - current local network. - </p> - <p> - A <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MAY">MAY</em> provide a way for users to enable access to non-CORS enabled Local-networked Services - from web pages (i.e. operate a <a href="#dfn-network-services-whitelist" - class="internalDFN">network services whitelist</a>). Implementation of such a <a href= - "#dfn-network-services-whitelist" - class="internalDFN">network services whitelist</a>, if any, is left to an implementer's discretion. Such a - whitelist may be configurable by each user at runtime or may be managed by the implementation itself on - behalf of its users. In the case that a <a href="#dfn-user-agent" - class="internalDFN">user agent</a> provides a <a href="#dfn-network-services-whitelist" - class="internalDFN">network services whitelist</a>, it <em class="rfc2119" - title="MUST">MUST</em> act as if all URLs for the Local-networked Service corresponding to any previously - whitelisted service type had Cross-Origin Resource Sharing [<cite><a class="bibref" - href="#bib-CORS">CORS</a></cite>] enabled indefinitely. - </p> - </section> - <section id="privacy-considerations-for-api-implementations"> - <h3 aria-level="2" - role="heading" - id="h3_privacy-considerations-for-api-implementations"> - <span class="secno">4.2</span> Privacy considerations for <abbr title= - "Application Programming Interface">API</abbr> implementations - </h3> - <p> - A <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST NOT">MUST NOT</em> provide networked service information to web sites without the express - permission of the user. A user agent <em class="rfc2119" - title="MUST">MUST</em> acquire permission through a user interface, unless they have prearranged trust - relationships with users, as described below. The user interface <em class="rfc2119" - title="MUST">MUST</em> include the document base URL. Those permissions that are acquired through the user - interface and that are preserved beyond the current browsing session (i.e. beyond the time when the - browsing context is navigated to another URL) <em class="rfc2119" - title="MUST">MUST</em> be revocable and a user agent <em class="rfc2119" - title="MUST">MUST</em> respect revoked permissions. - </p> - <p> - Obtaining the user's express permission to access one <abbr title= - "Application Programming Interface">API</abbr> method does not imply the user has granted permission for the - same web site to access any other methods that may be provided by this <abbr title= - "Application Programming Interface">API</abbr>, or to access the same method with a different set of - arguments, as part of the same permission context. If a user has expressed permission for an implementation - to, e.g. find a set of existing networked services, the implementation <em class="rfc2119" - title="MUST">MUST</em> seek the user's express permission if and when any subsequent functions are called - on this <abbr title="Application Programming Interface">API</abbr>. - </p> - <p> - A user agent <em class="rfc2119" - title="MAY">MAY</em> have prearranged trust relationships that do not require such user interfaces. For - example, while a web browser will present a user interface when a web site performs a networked service - lookup, a different runtime may have a prearranged, delegated security relationship with the user and, as - such, a suitable alternative security and privacy mechanism with which to authorise the retrieval of - networked service information. - </p> - </section> - <section class="informative" - id="additional-api-implementation-considerations"> - <h3 aria-level="2" - role="heading" - id="h3_additional-api-implementation-considerations"> - <span class="secno">4.3</span> Additional <abbr title="Application Programming Interface">API</abbr> - implementation considerations - </h3> - <p> - <em>This section is non-normative.</em> - </p> - <p> - Further to the requirements listed in the previous section, implementers of the Network Service Discovery - <abbr title="Application Programming Interface">API</abbr> are also advised to consider the following aspects - that can negatively affect the privacy of their users: in certain cases, users can inadvertently grant - permission to the user agent to disclose networked services to Web sites. In other cases, the content hosted - at a certain URL changes in such a way that previously granted networked service permissions no longer apply - as far as the user is concerned. Or the users might simply change their minds. - </p> - <p> - Predicting or preventing these situations is inherently difficult. Mitigation and in-depth defensive measures - are an implementation responsibility and not prescribed by this specification. However, in designing these - measures, implementers are advised to enable user awareness of networked service sharing, and to provide easy - access to interfaces that enable revocation of permissions that web applications have for accessing networked - services via this <abbr title="Application Programming Interface">API</abbr>. - </p> - </section> - </section> - <section id="requesting-networked-services"> - <h2 aria-level="1" - role="heading" - id="h2_requesting-networked-services"> - <span class="secno">5.</span> Requesting networked services - </h2> - <pre class="widl"> -[Supplemental, NoInterfaceObject] -interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> { - <a class="externalDFN" - href="http://dom.spec.whatwg.org/#promise">Promise</a> <a href= - "#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type ); -}; - -<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>; -</pre> - <section id="methods"> - <h3 aria-level="2" - role="heading" - id="h3_methods"> - <span class="secno">5.1</span> Methods - </h3> - <dl class="domintro"> - <dt> - <var title="">promise</var> = <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> ) - </dt> - <dd> - <p> - Immediately returns a new <a href="http://dom.spec.whatwg.org/#promise" - class="externalDFN">Promise</a> object and then the user is prompted to select discovered network - services that have advertised support for the requested service type(s). - </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="">promise</var> object is <a class="externalDFN" - href="http://dom.spec.whatwg.org/#concept-resolver-resolve">resolved</a>, with a <a href= - "#networkservices"><code>NetworkServices</code></a> object as its argument. - </p> - <p> - If the user declines, or an error occurs, the <var title="">promise</var> object is <a class= - "externalDFN" - href="http://dom.spec.whatwg.org/#concept-resolver-reject">rejected</a>. - </p> - </dd> - </dl> - <div> - <p> - When the <dfn id="dom-navigator-getnetworkservices" - title="dom-navigator-getnetworkservices"><code>getNetworkServices(type)</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>Network Service Promise</var> be a new <a href="http://dom.spec.whatwg.org/#promise" - class="externalDFN"><code>Promise</code></a> object. - </li> - <li>Let <var>Network Service Promise's Resolver</var> be the default <a href= - "http://dom.spec.whatwg.org/#concept-resolver" - class="externalDFN">resolver</a> of <var>Network Service Promise</var>. - </li> - <li>Return <var>Network Service Promise</var>, and run the remaining steps asynchronously. - </li> - <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> be 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, reject <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-reject" - class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the string - value "UnknownTypePrefixError" (<a href= - "#dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) and whose - <code>message</code> attribute has a helpful implementation-dependent message that explains this - error, 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>. Otherwise, abort the remaining - sub-steps and continue above at the next <var>available service</var>. - </li> - <li>If <var>matched service</var> is not empty then run the following steps: - <ol class="rule"> - <li>Let <var>CORS check result</var> be the result of running the <a href= - "#dfn-preliminary-cors-check" - class="internalDFN">preliminary CORS check</a> algorithm, passing in <var>matched - services</var>'s <code>url</code> attribute as the <var>control endpoint URL</var> argument - and 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> as the <var>request origin</var> argument. - </li> - <li>If <var>CORS check result</var> is not <code>pass</code> and <var>matched service</var>'s - <code>type</code> attribute is also not present in the <a href="#dfn-network-services-whitelist" - class="internalDFN">network services whitelist</a> then abort the remaining sub-steps and - continue above at the next <var>available service</var>. - </li> - <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>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> reject <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-reject" - class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the string - value "PermissionDeniedError" (<a href= - "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) and whose - <code>message</code> attribute has a helpful implementation-dependent message that explains this - error, abort any remaining steps and return. - </li> - <li>The user agent <em class="rfc2119" - title="MUST NOT">MUST NOT</em> provide the entry script's origin with a <a href= - "#networkservices"><code>NetworkServices</code></a> object without prior permission given by the - user. - <p> - If <var>services found</var> is not an empty array then the <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MAY">MAY</em> choose to 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 a <a href="#networkservices"><code>NetworkServices</code></a> - object representing the <a href="#dfn-user-authorized" - class="internalDFN">user-authorized</a> subset of <var>services found</var>. - </p> - <p> - Alternatively, the user agent <em class="rfc2119" - title="MAY">MAY</em> wish to skip this user opt-in step and choose to fulfill <var>Network Service - Promise</var> immediately based on a previously-established user preference, for security reasons, - or due to platform limitations. In such an implementation, if <var>Network Service Promise</var> is - to be fulfilled as a result of a previously-established user preference then the <a href= - "#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST">MUST</em> continue at the next step of this algorithm. - </p> - <p> - If permission has been granted by the user 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 permission has been denied by the user, <a href="#dfn-user-agent" - class="internalDFN">user agent</a> or platform, then the <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST">MUST</em> reject <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-reject" - class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the - string value "PermissionDeniedError" (<a href= - "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) and whose - <code>message</code> attribute has a helpful implementation-dependent message that explains this - error, abort any remaining steps and return. - </p> - <p> - If the user never responds or no previously-established user preference has been met, this algorithm - stalls on this step. - </p> - </li> - <li>Let <var>services</var> be an empty array. - </li> - <li>If <var>services found</var> is not an empty array then set <var>services</var> to be an array of one - or more <a href="#networkservice"><code>NetworkService</code></a> objects for which the user granted - permission above - known as the current objects <dfn id="dfn-user-authorized">user-authorized</dfn> - services. - </li> - <li>For each Object <var>service</var> in <var>services</var>, if any, run the following sub-steps: - <ol class="rule"> - <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>Store <var>requested control types</var> against <var>services manager</var> as an internal variable. - </li> - <li>Set <var>services manager</var>'s <a href= - "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to the number of - items 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 <var>services</var>, if any, to the <var>services manager</var> object as its collection of - <a href="#dfn-indexed-properties" - class="internalDFN">indexed properties</a>. If <var>services</var> is an empty array then the - <var>services manager</var> does not have any <var>indexed properties</var>. - </li> - <li>Set <var>services manager</var>'s <a href="#dom-networkservices-length"><code>length</code></a> - attribute to the number of items in <var>services</var>. - </li> - <li>Add <var>services manager</var> to the <a href="#dfn-list-of-active-service-managers" - class="internalDFN">list of active service managers</a>. - </li> - <li>The <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST">MUST</em> fulfill <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-fulfill" - class="externalDFN">resolver fulfill algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in <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> - The <dfn id="dfn-preliminary-cors-check">preliminary CORS check</dfn> algorithm determines whether a - Local-networked Service supports Cross-Origin Resource Sharing [<cite><a class="bibref" - href="#bib-CORS">CORS</a></cite>] as part of a call to the <a href= - "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method, prior to that service - being proposed for sharing to users and prior to active sharing with web pages. This algorithm takes two - arguments, <var>control endpoint URL</var> and <var>request origin</var>, and consists of running the - following steps: - </p> - <ol class="rule"> - <li>Let <var>CORS available check</var> be the result of applying the <a href= - "http://www.w3.org/TR/cors/#make-a-request-steps" - class="externalDFN">make a request steps</a> [<cite><a class="bibref" - href="#bib-CORS">CORS</a></cite>], setting the <a href="http://www.w3.org/TR/cors/#request-method" - class="externalDFN">request method</a> to <code>OPTIONS</code>, the <a href= - "http://www.w3.org/TR/cors/#request-url" - class="externalDFN">request URL</a> to <var>control endpoint URL</var>, the <a href= - "http://www.w3.org/TR/cors/#source-origin" - class="externalDFN">source origin</a> to <var>request origin</var>, setting the <a href= - "http://www.w3.org/TR/cors/#omit-credentials-flag" - class="externalDFN">omit credentials flag</a> to <code>true</code> and including an <a href= - "http://www.w3.org/TR/cors/#http-access-control-request-method" - class="externalDFN"><code>Access-Control-Request-Method</code></a> header with a value of - <code>GET</code>. - </li> - <li>If <var>CORS available check</var> is cancelled by the user, or it results in a network error, or its - response does not have an <abbr title="Hypertext Transfer Protocol">HTTP</abbr> status code of - <code>200</code> then abort any remaining steps and return <code>fail</code>. - </li> - <li>Return the result of running the <a href="http://www.w3.org/TR/cors/#resource-sharing-check" - class="externalDFN">resource sharing check</a> [<cite><a class="bibref" - href="#bib-CORS">CORS</a></cite>] against the successful <abbr title= - "Hypertext Transfer Protocol">HTTP</abbr> response of the <var>CORS available check</var>. - <div class="note"> - <div class="note-title" - aria-level="3" - role="heading" - id="h_note_1"> - <span>Note</span> - </div> - <p class=""> - This returned result will always be either <code>pass</code> or <code>fail</code>. - </p> - </div> - </li> - </ol> - <p> - There is no implied persistence to networked service sharing provided to a web page. It <em class="rfc2119" - title="MUST NOT">MUST NOT</em> be possible to access a networked service previously granted to a web - page without 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 aria-level="2" - role="heading" - id="h3_error-handling"> - <span class="secno">5.2</span> Error Handling - </h3> - <dl class="domintro"> - <dt> - <var title="">error</var> . <code title="dom-NavigatorNetworkServiceError-name"><a href= - "#dom-domerror-extensions-name">name</a></code> - </dt> - <dd> - <p> - Returns the current error's error name. At the current time, this will be "PermissionDeniedError" or - "UnknownTypePrefixError", for which the corresponding error constants <a href= - "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and <a href= - "#dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are defined. - </p> - </dd> - </dl> - <p> - The <dfn id="dom-domerror-extensions-name" - title="dom-domerror-extensions-name"><code>name</code></dfn> attribute of a <a href= - "http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object returned from this <abbr title= - "Application Programming Interface">API</abbr> <em class="ct"><em class="rfc2119" - title="MUST">MUST</em></em> return the name for the error, which will be one of the following: - </p> - <dl> - <dt> - <dfn id="dom-domerror-extensions-permission_denied" - title="dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> (DOMString - value "PermissionDeniedError") - </dt> - <dd> - The user or user agent denied the page permission to access any services. - </dd> - <dt> - <dfn id="dom-domerror-extensions-unknown_type_prefix" - title="dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn> - (DOMString value "UnknownTypePrefixError") - </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 aria-level="1" - role="heading" - id="h2_obtaining-networked-services"> - <span class="secno">6.</span> Obtaining networked services - </h2> - <p> - The <a href="#networkservices"><code>NetworkServices</code></a> interface represents a collection of zero or - more <a href="#dfn-indexed-properties" - class="internalDFN">indexed properties</a> that are each a <a href="#dfn-user-authorized" - class="internalDFN">user-authorized</a> <a href="#networkservice"><code>NetworkService</code></a> object. - </p> - <p> - A <a href="#networkservices"><code>NetworkServices</code></a> object is the <a href= - "http://dom.spec.whatwg.org/#concept-promise-result" - class="externalDFN">promise result</a> from a call to <a href= - "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a>. - </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-onservicefound">onservicefound</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-onservicelost">onservicelost</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 aria-level="2" - role="heading" - id="h3_attributes"> - <span class="secno">6.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 <a href="#dfn-indexed-properties" - class="internalDFN">indexed properties</a> in the current object's collection. - </p> - </dd> - <dt> - <code title="dom-networkservices-servicesavailable"><a href= - "#dom-networkservices-servicesavailable">servicesAvailable</a></code> - </dt> - <dd> - <p> - Returns the current number of items 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 <a href="#networkservice"><code>NetworkService</code></a> - objects represented by the collection. - </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 were initially used to create the current <a href= - "#networkservices"><code>NetworkServices</code></a> object. - </p> - </div> - </section> - <section id="methods-1"> - <h3 aria-level="2" - role="heading" - id="h3_methods-1"> - <span class="secno">6.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 collection of - zero or more <a href="#networkservice"><code>NetworkService</code></a> objects - its <a href= - "#dfn-indexed-properties" - class="internalDFN">indexed properties</a>. The <a href="#dfn-indexed-properties" - class="internalDFN">indexed properties</a> of a <a href= - "#networkservices"><code>NetworkServices</code></a> object are <span>immutable</span> meaning that <a href= - "#dfn-indexed-properties" - class="internalDFN">indexed properties</a> cannot be added and <a href="#dfn-indexed-properties" - class="internalDFN">indexed properties</a> cannot be removed for the lifetime of a <a href= - "#networkservices"><code>NetworkServices</code></a> object. - </p> - <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 the <a href="#networkservice"><code>NetworkService</code></a> objects in the collection - minus one. - </p> - <div class="note"> - <div class="note-title" - aria-level="3" - role="heading" - id="h_note_2"> - <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> - 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 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 item in the collection. - </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 collection whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to - the value of the <var>id</var> argument provided. When no <a href= - "#networkservice"><code>NetworkService</code></a> objects match the given argument, the method <em class= - "rfc2119" - title="MUST">MUST</em> return null. - </p> - </section> - <section id="events"> - <h3 aria-level="2" - role="heading" - id="h3_events"> - <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= - "#networkservices"><code>NetworkServices</code></a> interface: - </p> - <table border="1"> - <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-onservicefound" - title="dom-NetworkServices-onservicefound"><code>onservicefound</code></dfn> - </td> - <td> - <a href="#event-servicefound"><code>servicefound</code></a> - </td> - </tr> - <tr> - <td> - <dfn id="dom-networkservices-onservicelost" - title="dom-NetworkServices-onservicelost"><code>onservicelost</code></dfn> - </td> - <td> - <a href="#event-servicelost"><code>servicelost</code></a> - </td> - </tr> - </tbody> - </table> - </section> - </section> - <section id="communicating-with-a-networked-service"> - <h2 aria-level="1" - role="heading" - id="h2_communicating-with-a-networked-service"> - <span class="secno">7.</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-onavailable">onavailable</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-onunavailable">onunavailable</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 aria-level="2" - role="heading" - id="h3_attributes-1"> - <span class="secno">7.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 URL endpoint (including any required port information) of the user-selected control service. - </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://url.spec.whatwg.org/#concept-absolute-url" - class="externalDFN">absolute URL</a> pointing to the root <abbr title= - "Hypertext Transfer Protocol">HTTP</abbr> endpoint for the service. 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 aria-level="2" - role="heading" - id="h3_states"> - <span class="secno">7.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 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 - 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 aria-level="2" - role="heading" - id="h3_events-1"> - <span class="secno">7.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"> - <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-onavailable" - title="dom-NetworkService-onavailable"><code>onavailable</code></dfn> - </td> - <td> - <a href="#event-available"><code>available</code></a> - </td> - </tr> - <tr> - <td> - <dfn id="dom-networkservice-onunavailable" - title="dom-NetworkService-onunavailable"><code>onunavailable</code></dfn> - </td> - <td> - <a href="#event-unavailable"><code>unavailable</code></a> - </td> - </tr> - </tbody> - </table> - </section> - </section> - <section id="service-discovery"> - <h2 aria-level="1" - role="heading" - id="h2_service-discovery"> - <span class="secno">8.</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 <abbr title="Simple Service Discovery Protocol">SSDP</abbr> [<cite><a class= - "bibref" - href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>], Zeroconf [<cite><a class="bibref" - href="#bib-DNS-SD">DNS-SD</a></cite>] + [<cite><a class="bibref" - href="#bib-MDNS">MDNS</a></cite>] and/or <abbr title="Discovery and Launch Protocol">DIAL</abbr> [<a href= - "https://sites.google.com/a/dial-multiscreen.org/dial/dial-protocol-specification"><abbr title= - "Discovery and Launch Protocol">DIAL</abbr></a>] <dfn id="dfn-service-discovery-mechanisms">service - discovery mechanisms</dfn> - the requirements detailed in this section of the specification - to enable Web - pages to request and connect with <abbr title="Hypertext Transfer Protocol">HTTP</abbr> services running on - networked devices, discovered via any of these mechanisms, through this <abbr title= - "Application Programming Interface">API</abbr>. When a <a href="#dfn-user-agent" - class="internalDFN">user agent</a> implements any of these <a href="#dfn-service-discovery-mechanisms" - class="internalDFN">service discovery mechanisms</a>, 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 <a href="#dfn-service-discovery-mechanisms" - class="internalDFN">service discovery mechanisms</a> will be matched to requested service types, how the - user agent stores available and active services and 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 <a href="#dfn-service-discovery-mechanisms" - class="internalDFN">service discovery mechanisms</a> asynchronously and periodically update the <a href= - "#dfn-list-of-available-service-records" - class="internalDFN">list of available service records</a> as required. The timing of any <a href= - "#dfn-service-discovery-mechanisms" - class="internalDFN">service discovery mechanisms</a> is an implementation detail left to the discretion of - the implementer (e.g. by continuously monitoring the network as a background process 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 the current time. At any point during the running of any of the - <a href="#dfn-service-discovery-mechanisms" - class="internalDFN">service discovery mechanisms</a> 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-active-service-managers">list of active service managers</dfn> is an internal list - within user agents that is used to track all <a href="#networkservices"><code>NetworkServices</code></a> - objects currently being shared with any web pages at the current time within the user agent. Each <a href= - "#networkservices"><code>NetworkServices</code></a> object in the <a href= - "#dfn-list-of-active-service-managers" - class="internalDFN">list of active service managers</a> represents a collection of zero or more <a href= - "#networkservice"><code>NetworkService</code></a> objects - known as its <dfn id= - "dfn-indexed-properties">indexed properties</dfn>. <a href="#networkservice"><code>NetworkService</code></a> - objects are attached as the <a href="#dfn-indexed-properties" - class="internalDFN">indexed properties</a> of a <a href="#networkservices"><code>NetworkServices</code></a> - object 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 <a href="#dfn-new-service" - class="internalDFN">new service</a> or updating an <a href="#dfn-existing-service" - class="internalDFN">existing service</a> that is generally available on the user's current network in the - <a href="#dfn-list-of-available-service-records" - class="internalDFN">list of available service records</a>. This rule takes one argument, <var>network - service record</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 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>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>, aborting any remaining steps in this algorithm and return. - </li> - </ol> - </li> - <li>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 item. - </li> - <li>For each <var>service manager</var> in the <a href="#dfn-list-of-active-service-managers" - class="internalDFN">list of active service managers</a> run the following steps: - <ol class="rule"> - <li>For each <var>active service</var> in <var>service manager</var> run the following steps: - <ol class="rule"> - <li>If the <var>network service record</var>'s <code>id</code> property equals the <var>active - service</var>'s <code>id</code> attribute and <var>active service</var>'s <code>online</code> attribute - is currently set to <code>false</code> then 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-available"><code>available</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>Let <var>'service type in current service manager' flag</var> be <code>false</code>. - </li> - <li>For each <var>requested control type</var> of the <var>requested control types</var> in <var>service - manager</var> run the following steps: - <ol class="rule"> - <li>If <var>network service record</var>'s <code>type</code> property does not equal <var>requested - control type</var> then abort any remaining sub-steps and continue at the next available <var>requested - control type</var>. - </li> - <li>Set the <var>'service type in current service manager' flag</var> to <code>true</code>, abort any - remaining sub-steps and continue. - </li> - </ol> - </li> - <li>If the <var>'service type in current service manager' flag</var> is set to <code>true</code> then - increment <var>service manager</var>'s <a href= - "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute 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-servicefound"><code>servicefound</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>service manager</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 an <a href="#dfn-existing-service" - class="internalDFN">existing service</a> 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>Let <var>'service type in use' flag</var> be <code>false</code>. - </li> - <li>For each <var>service manager</var> in the <a href="#dfn-list-of-active-service-managers" - class="internalDFN">list of active service managers</a> run the following steps: - <ol class="rule"> - <li>Let <var>'service type in current service manager' flag</var> be <code>false</code>. - </li> - <li>For each <var>active service</var> in <var>service manager</var> run the following steps: - <ol class="rule"> - <li>If <var>existing service record</var>'s <code>id</code> property equals the <var>active - service</var>'s <code>id</code> attribute and <var>active service</var>'s <a href= - "#dom-networkservice-online"><code>online</code></a> attribute is currently set to - <code>true</code> then 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-unavailable"><code>unavailable</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>. - </li> - </ol> - </li> - <li>For each <var>requested control type</var> of the <var>requested control types</var> in - <var>service manager</var> run the following steps: - <ol class="rule"> - <li>If <var>existing service record</var>'s <code>type</code> property does not equal - <var>requested control type</var> then abort any remaining sub-steps and continue at the next - available <var>requested control type</var>. - </li> - <li>Set the <var>'service type in current service manager' flag</var> to <code>true</code> and the - <var>'service type in use' flag</var> to <code>true</code>, abort any remaining sub-steps and - continue. - </li> - </ol> - </li> - <li>If the <var>'service type in current service manager' flag</var> is set to <code>true</code> then - decrement <var>service manager</var>'s <a href= - "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute 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-servicelost"><code>servicelost</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>service manager</var> object. - </li> - </ol> - </li> - <li>If the <var>'service type in use' flag</var> is <code>false</code> and 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>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 aria-level="2" - role="heading" - id="h3_zeroconf-mdns-dns-sd"> - <span class="secno">8.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 URL - 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 aria-level="2" - role="heading" - id="h3_simple-service-discovery-protocol-ssdp"> - <span class="secno">8.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 a <dfn id="dfn-search-request-for-upnp-root-devices">search request 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="search request for UPnP root devices" - href="#dfn-search-request-for-upnp-root-devices" - class="internalDFN">search requests 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> and a MAN header equal to - <code>ssdp:discover</code>. The <a href="#dfn-user-agent" - class="internalDFN">user agent</a> must also send an ST header with this <abbr title= - "Hypertext Transfer Protocol">HTTP</abbr> request equal to the String value of <code>ssdp:all</code> or - <code>upnp:rootdevice</code> or a single <a href="#dfn-valid-service-type" - class="internalDFN">valid service type</a> token beginning with the String value <code>upnp:</code>. If a - single <a href="#dfn-valid-service-type" - class="internalDFN">valid service type</a> token beginning with the String value <code>upnp:</code> is to - be used, the user agent <em class="rfc2119" - title="MUST">MUST</em> strip the leading String <code>upnp:</code> before using this value in this - <abbr title="Hypertext Transfer Protocol">HTTP</abbr> request. The user-agent <em class="rfc2119" - title="MUST">MUST</em> also send an 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 with this <abbr title= - "Hypertext Transfer Protocol">HTTP</abbr> request. - </p> - <p> - The user agent <em class="rfc2119" - title="MUST">MUST</em> listen for any incoming responses to any <a href= - "#dfn-search-request-for-upnp-root-devices" - class="internalDFN">search request for UPnP root devices</a>. - </p> - <p> - For each <dfn id="dfn-http-response"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</dfn> - following an initial <a href="#dfn-search-request-for-upnp-root-devices" - class="internalDFN">search request 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-search-request-for-upnp-root-devices" - class="internalDFN">search request 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-search-request-for-upnp-root-devices" - class="internalDFN">search request 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. The user agent - <em class="rfc2119" - title="MAY">MAY</em> stop listening for responses from the current <a href= - "#dfn-search-request-for-upnp-root-devices" - class="internalDFN">search request for UPnP root devices</a> as a result of this error occurring. - Equally, the user agent <em class="rfc2119" - title="MAY">MAY</em> issue a new <a href="#dfn-search-request-for-upnp-root-devices" - class="internalDFN">search request for UPnP root devices</a> as a result of this error occurring. - </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 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 URL</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> (minus the - leading string of <code>max-age=</code>) as the <var>device expiry</var> argument. - </li> - </ol> - <p> - The user agent <em class="rfc2119" - title="MUST">MUST</em> listen for incoming requests 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>. - </p> - <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> 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>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> and the <a href= - "#dfn-http-request" - class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> 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, then - the <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST">MUST</em> 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> 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 URL</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> (minus the - leading string of <code>max-age=</code>) 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 URL-based resource. This rule takes - three arguments - <var>device descriptor URL</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 URL provided in - <var>device descriptor URL</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 URL</var> cannot be resolved as a reachable URL on the - current network or the <var>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> - </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 - the first occurrence of the <code><UDN></code> element in the <var>device descriptor file</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> - <li>If <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 current - <var>device identifier</var> and <var>device expiry</var> arguments. - </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 URL</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 URL</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 and set <var>timeout date</var> to 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. If the current date is greater than or equal to <var>timeout - date</var> then the <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="SHOULD">SHOULD</em> continue from the step labeled <em>refresh subscription</em> above. - For all non 200 OK responses the <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="SHOULD">SHOULD</em> 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 URL</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> - <li>Return a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> 200 OK response to the sender of - the <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request. - </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 a <var>network service record</var> 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="discovery-and-launch-protocol-dial"> - <h3 aria-level="2" - role="heading" - id="h3_discovery-and-launch-protocol-dial"> - <span class="secno">8.3</span> Discovery and Launch Protocol (<abbr title= - "Discovery and Launch Protocol">DIAL</abbr>) - </h3> - <p> - A user agent that implements <abbr title="Discovery and Launch Protocol">DIAL</abbr> service discovery - <em class="rfc2119" - title="MUST">MUST</em> issue a <dfn id="dfn-search-request-for-dial-enabled-devices">search request for - <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled 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> - Let <var>dial version</var> be the version number specified in the <a href="#dfn-valid-service-type" - class="internalDFN">valid service type</a> token. Let <var>dial search target</var> be the concatentation - of the <code>urn:dial-multiscreen-org:service:dial:</code> string constant with the <var>dial - version</var> (currently, <var>dial version</var> can only be <code>1</code>) - </p> - <p> - The user agent <em class="rfc2119" - title="MUST">MUST</em> issue all <a title="search request for DIAL-enabled devices" - href="#dfn-search-request-for-dial-enabled-devices" - class="internalDFN">search requests for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - 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 <var>dial search target</var> and a user-agent - defined MX header equal to a <dfn id="dfn-maximum-dial-advertisement-response-wait-time">maximum - <abbr title="Discovery and Launch Protocol">DIAL</abbr> 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 any incoming responses to a <a href= - "#dfn-search-request-for-dial-enabled-devices" - class="internalDFN">search request for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - devices</a>. - </p> - <p> - For each <abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response following an initial <a href= - "#dfn-search-request-for-dial-enabled-devices" - class="internalDFN">search request for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - 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 <abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response 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-search-request-for-dial-enabled-devices" - class="internalDFN">search request for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - devices</a> as a result of this error occurring. - </li> - <li>If the <a href="#dfn-maximum-dial-advertisement-response-wait-time" - class="internalDFN">maximum <abbr title="Discovery and Launch Protocol">DIAL</abbr> advertisement - response wait time</a> has been exceeded since the initial <a href= - "#dfn-search-request-for-dial-enabled-devices" - class="internalDFN">search request for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - 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. The user agent - <em class="rfc2119" - title="MAY">MAY</em> stop listening for responses from the current <a href= - "#dfn-search-request-for-dial-enabled-devices" - class="internalDFN">search request for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - devices</a> as a result of this error occurring. Equally, the user agent <em class="rfc2119" - title="MAY">MAY</em> issue a new <a href="#dfn-search-request-for-dial-enabled-devices" - class="internalDFN">search request for <abbr title="Discovery and Launch Protocol">DIAL</abbr>-enabled - devices</a> as a result of this error occurring. - </li> - <li>Let <var>dial 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>dial 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 <var>dial search target</var>, 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>dial device</var> as the <var>device descriptor URL</var> argument and - the first occurrence of <var>USN</var> from <var>dial device</var> as the <var>device identifier</var> - argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>dial device</var> (minus the - leading string of <code>max-age=</code>) as the <var>device expiry</var> argument. - </li> - </ol> - <p> - The rule for <dfn id="dfn-obtaining-a-dial-device-description-file">obtaining a <abbr title= - "Discovery and Launch Protocol">DIAL</abbr> 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 URL-based resource. This rule takes - three arguments - <var>device descriptor URL</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 URL provided in - <var>device descriptor URL</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>Let <var>application url</var> be the value of the first occurrence of the <code>Application-URL</code> - response header field obtained according to the rules defined in 'Section 5.4: Device Description Response' - in [<a href="https://sites.google.com/a/dial-multiscreen.org/dial/dial-protocol-specification"><abbr title= - "Discovery and Launch Protocol">DIAL</abbr></a>] - </li> - <li>If the value provided in <var>device descriptor URL</var> cannot be resolved as a reachable URL on the - current network or the <var>device descriptor file</var> remains empty or <var>application url</var> is - undefined 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 following steps to add the newly discovered <abbr title= - "Discovery and Launch Protocol">DIAL</abbr> service: - <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>expiryTimestamp</code>. - </li> - <li>Set <var>network service record</var>'s <code>id</code> property to the first occurrence of the - <code><UDN></code> element in the <var>descriptor file</var> prefixed with the <code>dial:</code> - string constant - </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 <code><friendlyName></code> element in the <var>descriptor file</var>. - </li> - <li>Set <var>network service record</var>'s <code>type</code> property to <var>dial search target</var>. - </li> - <li>Set <var>network service record</var>'s <code>url</code> property to the string value of the - <var>application url</var>. - </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> - </section> - <section id="network-topology-monitoring"> - <h3 aria-level="2" - role="heading" - id="h3_network-topology-monitoring"> - <span class="secno">8.4</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 a 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> discovered via that network connection, the - <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <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-active-service-managers" - class="internalDFN">list of active service managers</a> currently in use. - </p> - </div> - </section> - </section> - <section id="events-summary"> - <h2 aria-level="1" - role="heading" - id="h2_events-summary"> - <span class="secno">9.</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"> - <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-servicefound"><code>servicefound</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 <a href="#dfn-new-service" - class="internalDFN">new service</a> that matches one of the <a title="valid service type" - href="#dfn-valid-service-type" - class="internalDFN">requested type tokens</a> is found in the current network. - </td> - </tr> - <tr> - <td> - <dfn id="event-servicelost"><code>servicelost</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 <a href="#dfn-existing-service" - class="internalDFN">existing service</a> that matches one of the <a title="valid service type" - href="#dfn-valid-service-type" - class="internalDFN">requested type tokens</a> gracefully leaves or expires from the current network. - </td> - </tr> - <tr> - <td> - <dfn id="event-available"><code>available</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 <a href="#dfn-current-service" - class="internalDFN">current service</a> renews its service registration within the current network. - </td> - </tr> - <tr> - <td> - <dfn id="event-unavailable"><code>unavailable</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 <a href="#dfn-current-service" - class="internalDFN">current service</a> 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 <a href="#dfn-current-service" - class="internalDFN">current service</a>. This event never fires for Zeroconf-based services. - </td> - </tr> - </tbody> - </table> - </section> - <section id="garbage-collection"> - <h2 aria-level="1" - role="heading" - id="h2_garbage-collection"> - <span class="secno">10.</span> Garbage collection - </h2> - <p> - There is an <dfn id="dfn-implied-strong-reference">implied strong reference</dfn> from any IDL attribute in - this <abbr title="Application Programming Interface">API</abbr> that returns a pre-existing object to that - object. - </p> - <div class="note"> - <div class="note-title" - aria-level="2" - role="heading" - id="h_note_3"> - <span>Note</span> - </div> - <p class=""> - For example, if a <a href="#networkservices" - class="internalDFN"><code>NetworkServices</code></a> object has one or more <a href= - "#dfn-indexed-properties" - class="internalDFN">indexed properties</a> attached to it then there is a strong reference from that - <a href="#networkservices" - class="internalDFN"><code>NetworkServices</code></a> object toward each of its <a href= - "#dfn-indexed-properties" - class="internalDFN">indexed properties</a>. - </p> - </div> - <p> - If a <a href="#dfn-user-agent" - class="internalDFN">user agent</a> is to <dfn id="dfn-make-disappear">make disappear</dfn> a <a href= - "#networkservices" - class="internalDFN"><code>NetworkServices</code></a> object (this happens when a <a href= - "http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#document" - class="externalDFN"><code>Document</code></a> object goes away), the <a href="#dfn-user-agent" - class="internalDFN">user agent</a> <em class="rfc2119" - title="MUST">MUST</em> remove this object from the <a href="#dfn-list-of-active-service-managers" - class="internalDFN">list of active service managers</a>. - </p> - </section> - <section id="use-cases-and-requirements"> - <h2 aria-level="1" - role="heading" - id="h2_use-cases-and-requirements"> - <span class="secno">11.</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 aria-level="1" - role="heading" - id="h2_examples"> - <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 prettyprinted" - style=""> -<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">then</span><span class="pun">(</span><span class="pln">gotXBMCService</span><span class= -"pun">).</span><span class="kwd">catch</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">'unavailable'</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 are</span><span class="pln"> - </span><span class= -"com">// available for cross-site XHR use.</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 prettyprinted" - style=""> -<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"> - </span><span class="kwd">var</span><span class="pln"> servicesPromise </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">then</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 sub-resources are</span><span class="pln"> - </span><span class= -"com">// available for cross-site XHR use.</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">name</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 aria-level="1" - role="heading" - id="h2_acknowledgements"> - <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> - Adam Barth, Gar Bergstedt, Robin Berjon, Lars-Erik Bolstad, Marcos Caceres, Cathy Chan, Daniel Danciu, - Jean-Claude Dufourd, Youenn Fablot, Mark Foltz, Dominique Hazael-Massieux, Frederick Hirsch, Tatsuya Igarashi, - 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, Google Inc., Opera Software ASA, Nokia Corp., Télécom ParisTech, <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><style> -a.externalDFN { color: #00C; border-bottom: 1px dashed #00C; } - a.internalDFN { color: #00C; text-decoration: solid; } - </style> - <section id="references" - class="appendix" - typeof="bibo:Chapter" - resource="#ref" - rel="bibo:Chapter"> - <h2 aria-level="1" - role="heading" - id="h2_references"> - <span class="secno">C.</span> References - </h2> - <section id="normative-references" - typeof="bibo:Chapter" - resource="#ref" - rel="bibo:Chapter"> - <h3 aria-level="2" - role="heading" - id="h3_normative-references"> - <span class="secno">C.1</span> Normative references - </h3> - <dl class="bibliography" - about=""> - <dt id="bib-CORS"> - [CORS] - </dt> - <dd rel="dcterms:requires"> - Anne van Kesteren. <a href="http://www.w3.org/TR/cors/"><cite>Cross-Origin Resource Sharing</cite></a>. 16 - January 2014. W3C Recommendation. URL: <a href="http://www.w3.org/TR/cors/">http://www.w3.org/TR/cors/</a> - </dd> - <dt id="bib-DNS-SD"> - [DNS-SD] - </dt> - <dd rel="dcterms:requires"> - S. Cheshire; M. Krochmal. <a href="http://www.ietf.org/rfc/rfc6763.txt"><cite>DNS-Based Service - Discovery</cite></a>. February 2013. RFC. URL: <a href= - "http://www.ietf.org/rfc/rfc6763.txt">http://www.ietf.org/rfc/rfc6763.txt</a> - </dd> - <dt id="bib-DOM4"> - [DOM4] - </dt> - <dd rel="dcterms:requires"> - Anne van Kesteren; Aryeh Gregor; Ms2ger; Alex Russell; Robin Berjon. <a href= - "http://www.w3.org/TR/dom/"><cite>W3C DOM4</cite></a>. 4 February 2014. W3C Last Call Working Draft. URL: - <a href="http://www.w3.org/TR/dom/">http://www.w3.org/TR/dom/</a> - </dd> - <dt id="bib-HTML5"> - [HTML5] - </dt> - <dd rel="dcterms:requires"> - Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. - <a href="http://www.w3.org/TR/html5/"><cite>HTML5</cite></a>. 4 February 2014. W3C Candidate - Recommendation. URL: <a href="http://www.w3.org/TR/html5/">http://www.w3.org/TR/html5/</a> - </dd> - <dt id="bib-MDNS"> - [MDNS] - </dt> - <dd rel="dcterms:requires"> - S. Cheshire; M. Krochmal. <a href="http://www.ietf.org/rfc/rfc6763.txt"><cite>Multicast DNS</cite></a>. - February 2013. RFC. URL: <a href= - "http://www.ietf.org/rfc/rfc6763.txt">http://www.ietf.org/rfc/rfc6763.txt</a> - </dd> - <dt id="bib-RFC2119"> - [RFC2119] - </dt> - <dd rel="dcterms:requires"> - 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 rel="dcterms:requires"> - <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 rel="dcterms:requires"> - Cameron McCormack. <a href="http://www.w3.org/TR/WebIDL/"><cite>Web IDL</cite></a>. 19 April 2012. W3C - Candidate Recommendation. URL: <a href="http://www.w3.org/TR/WebIDL/">http://www.w3.org/TR/WebIDL/</a> - </dd> - </dl> - </section> - <section id="informative-references" - typeof="bibo:Chapter" - resource="#ref" - rel="bibo:Chapter"> - <h3 aria-level="2" - role="heading" - id="h3_informative-references"> - <span class="secno">C.2</span> Informative references - </h3> - <dl class="bibliography" - about=""> - <dt id="bib-hnreq"> - [hnreq] - </dt> - <dd rel="dcterms:references"> - Giuseppe Pascale. <a href="http://www.w3.org/TR/hnreq/"><cite>Requirements for Home Networking - Scenarios</cite></a>. 1 December 2011. W3C Note. URL: <a href= - "http://www.w3.org/TR/hnreq/">http://www.w3.org/TR/hnreq/</a> - </dd> - </dl> - </section> - </section> - </body> -</html> + </style> + <script src="https://www.w3.org/scripts/TR/2016/fixup.js"></script> +</body> +</html> \ No newline at end of file diff -r 794817a23d8e -r ffb713303c21 discovery-api/Overview.src.html --- a/discovery-api/Overview.src.html Thu Mar 17 16:00:35 2016 +0200 +++ b/discovery-api/Overview.src.html Wed Jan 11 10:30:32 2017 +0100 @@ -38,8 +38,8 @@ //publishDate: "2013-09-05", shortName: "discovery-api", edDraftURI: "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html", - previousMaturity: "FPWD", - previousPublishDate: "2013-04-04", + previousMaturity: "WD", + previousPublishDate: "2014-02-20", editors: [ { name: "Rich Tibbett", @@ -49,10 +49,10 @@ } ], - wg: "Device APIs Working Group", - wgURI: "http://www.w3.org/2009/dap/", + wg: "Device and Sensors Working Group", + wgURI: "https://www.w3.org/2009/dap/", wgPublicList: "public-device-apis", - wgPatentURI: "http://www.w3.org/2004/01/pp-impl/43696/status", + wgPatentURI: "https://www.w3.org/2004/01/pp-impl/43696/status", // extraCSS: ["http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/css/respec.nsd.css"], // inlineCSS: true, @@ -115,2043 +115,7 @@ </section> <section id='sotd'> <p> - This document represents the early consensus of the group on the scope and features of the proposed API. - </p> - </section> - <section class="informative"> - <h3> - Introduction - </h3> - <p> - This specification defines the <a href="#navigatornetworkservice"><code>NavigatorNetworkService</code></a> - interface to enable Web pages to connect and communicate with Local-networked Services provided over HTTP. This - enables access to services and content provided by home network devices, including the discovery and playback - of content available to those devices, both from services such as traditional broadcast media and internet - based services as well as local services. Initial design goals and requirements provided by the <a href= - "http://www.w3.org/2011/webtv/">W3C Web & TV interest group</a> are documented in [[hnreq]]. - </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 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 <a>service discovery - mechanisms</a> included in this recommendation, attempts to match the requested service type to a discovered - service according to the processing described herein. Only Local-networked Services that pass a <a>preliminary - CORS check</a> should be made available to web pages by a user agent. A user agent may provide a way for users - to white-list non-CORS enabled Local-networked Services but implementation of such a feature is left to the - discretion of the implementer. - </p> - <p> - If a service connectivity request is successful then the Web page is provided with a promise-based success - callback with the all necessary information to communicate with the authorized Local-networked Service. If the - request fails then the Web page will receive a promise-based error callback containing an error string - 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 API. 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> - <p> - Services available within the local network can connect and disconnect at different times during the execution - of a web page. The user agent can inform a web page when the state of networked services matching any of the - requested valid service types 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 defined herein). - </p> - <div class="example"> - <p> - Example of requesting a DNS-SD advertised service: - </p> - <hr> - <pre class="highlight"> -function showServices( services ) { - // Show a list of all the services provided to the web page - for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name ); -} - -navigator.getNetworkServices('zeroconf:_boxee-jsonrpc._tcp').then(showServices); -</pre> - </div> - <div class="example"> - <p> - Example of requesting a UPnP advertised service, also handling error conditions: - </p> - <hr> - <pre class="highlight"> -function showServices( services ) { - // Show a list of all the services provided to the web page - for(var i = 0, l = services.length; i < l; i++) console.log( services[i].name ); -} - -function error( e ) { - console.log( "Error occurred: " + e.name ); -} - -navigator.getNetworkServices('upnp:urn:schemas-upnp-org:service:ContentDirectory:1').then(showServices, error); -</pre> - </div> - <div class="example"> - <p> - Example of requesting either a DNS-SD or UPnP advertised service: - </p> - <hr> - <pre class="highlight"> -function showServices( services ) { - // Show a list of all the services provided to the web page (+ service type) - for(var i = 0, l = services.length; i < l; i++) - console.log( services[i].name + '(' + services[i].type + ')' ); -} - -navigator.getNetworkServices([ - 'zeroconf:_boxee-jsonrpc._tcp', - 'upnp:urn:schemas-upnp-org:service:ContentDirectory:1' -]).then(showServices); -</pre> - </div> - <p> - For more detailed examples, including examples of communicating with obtained networked services, see the - <a href="#examples">Examples</a> section. - </p> - </section> - <section id='conformance'> - <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 MAY 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>user agent</dfn>. - </p> - <p> - User agents MAY impose implementation-specific limits on otherwise unconstrained inputs, e.g. to prevent denial - of service attacks, to guard against running out of memory, or to work 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 MUST 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> - <h3> - 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. [[!HTML5]] - </dd> - <dt> - WebIDL - </dt> - <dd> - The IDL blocks in this specification use the semantics of the WebIDL specification. [[!WEBIDL]] - </dd> - </dl> - </section> - </section> - <section> - <h3> - Terminology - </h3> - <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 API set made available to scripts in Web applications, and does not - necessarily imply the existence of an actual <code>Document</code> object or of any other <code>Node</code> - objects as defined in the DOM Core specifications. [[!DOM4]] - </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>valid service type</dfn> is any of the following: - </p> - <ul> - <li>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. - </li> - <li>a string that begins with <code>dial:</code> followed by an integer version. - </li> - </ul> - <p> - A <a>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>list of available service records</a> according to the algorithms - defined in this specification. - </p> - <p> - A <dfn>user-agent generated callback url</dfn> is a Local-network accessible URL endpoint that a <a>user - agent</a> generates and maintains for receiving HTTP NOTIFY requests from UPnP Event sources. It is only - required when the user agent implements UPnP Service Discovery as defined in this specification. - </p> - <p> - In this specification we use the following terms to describe the processes required for Local-networked - Services management: - </p> - <ul> - <li>A <dfn>new service</dfn> is a Local-networked Service that has not previously been discovered or registered - in the <a>list of available service records</a>. - </li> - <li>An <dfn>existing service</dfn> is a Local-networked Service that has previously been discovered and is - registered in the <a>list of available service records</a>. - </li> - <li>A <dfn>current service</dfn> is a Local-networked Service, represented by a <a href= - "#networkservice"><code>NetworkService</code></a> object, that is currently being shared with a web page via a - <a href="#networkservices"><code>NetworkServices</code></a> object registered in the <a>list of active service - managers</a>. - </li> - </ul> - <p> - A <dfn>network services whitelist</dfn> is a list of zero or more <a>valid service type</a> tokens that, when - matched to a service type discovered in the local network, enables that service to be shared with a web page - even if that Local-networked Service does not itself allow Cross-Origin Resource Sharing [[!CORS]]. A <a>user - agent</a> MUST simulate CORS support for all service interaction in this case. Implementation of this feature - is at implementer's discretion. When a <a>user agent</a> does not implement a <a>network services whitelist</a> - then it is to treat this as always being an empty list. - </p> - </section> - <section> - <h2> - Security and privacy considerations - </h2> - <p> - The API defined in this specification can be used to find and connect to devices and services within a user's - current network. This discloses information related to a user's network: devices available on their network and - the publicly-accessible services ("networked services") currently running and available on those devices. The - distribution of this information could potentially compromise the user's privacy. A conforming implementation - of this specification MUST provide a mechanism that protects the user's privacy. This mechanism MUST ensure - that no networked service information is retrievable without the user's express permission. - </p> - <section> - <h3> - Security considerations for API implementations - </h3> - <p> - A <a>user agent</a> SHOULD only allow web pages to connect with Local-networked Services that have passed a - <a>preliminary CORS check</a> indicating they support Cross-Origin Resource Sharing [[!CORS]]. In this way, a - <a>user agent</a> SHOULD NOT allow web pages to access other arbitrary networked services on the current - local network. - </p> - <p> - A <a>user agent</a> MAY provide a way for users to enable access to non-CORS enabled Local-networked Services - from web pages (i.e. operate a <a>network services whitelist</a>). Implementation of such a <a>network - services whitelist</a>, if any, is left to an implementer's discretion. Such a whitelist may be configurable - by each user at runtime or may be managed by the implementation itself on behalf of its users. In the case - that a <a>user agent</a> provides a <a>network services whitelist</a>, it MUST act as if all URLs for the - Local-networked Service corresponding to any previously whitelisted service type had Cross-Origin Resource - Sharing [[!CORS]] enabled indefinitely. - </p> - </section> - <section> - <h3> - Privacy considerations for API implementations - </h3> - <p> - A <a>user agent</a> MUST NOT provide networked service information to web sites without the express - permission of the user. A user agent MUST acquire permission through a user interface, unless they have - prearranged trust relationships with users, as described below. The user interface MUST include the document - base URL. Those permissions that are acquired through the user interface and that are preserved beyond the - current browsing session (i.e. beyond the time when the browsing context is navigated to another URL) MUST be - revocable and a user agent MUST respect revoked permissions. - </p> - <p> - Obtaining the user's express permission to access one API method does not imply the user has granted - permission for the same web site to access any other methods that may be provided by this API, or to access - the same method with a different set of arguments, as part of the same permission context. If a user has - expressed permission for an implementation to, e.g. find a set of existing networked services, the - implementation MUST seek the user's express permission if and when any subsequent functions are called on - this API. - </p> - <p> - A user agent MAY have prearranged trust relationships that do not require such user interfaces. For example, - while a web browser will present a user interface when a web site performs a networked service lookup, a - different runtime may have a prearranged, delegated security relationship with the user and, as such, a - suitable alternative security and privacy mechanism with which to authorise the retrieval of networked - service information. - </p> - </section> - <section class="informative"> - <h3> - Additional API implementation considerations - </h3> - <p> - Further to the requirements listed in the previous section, implementers of the Network Service Discovery API - are also advised to consider the following aspects that can negatively affect the privacy of their users: in - certain cases, users can inadvertently grant permission to the user agent to disclose networked services to - Web sites. In other cases, the content hosted at a certain URL changes in such a way that previously granted - networked service permissions no longer apply as far as the user is concerned. Or the users might simply - change their minds. - </p> - <p> - Predicting or preventing these situations is inherently difficult. Mitigation and in-depth defensive measures - are an implementation responsibility and not prescribed by this specification. However, in designing these - measures, implementers are advised to enable user awareness of networked service sharing, and to provide easy - access to interfaces that enable revocation of permissions that web applications have for accessing networked - services via this API. - </p> - </section> - </section> - <section> - <h2> - Requesting networked services - </h2> - <pre class="widl"> -[Supplemental, NoInterfaceObject] -interface <dfn id="navigatornetworkservice">NavigatorNetworkService</dfn> { - <a class="externalDFN" - href="http://dom.spec.whatwg.org/#promise">Promise</a> <a href= - "#dom-navigator-getnetworkservices">getNetworkServices</a>( in any type ); -}; - -<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>; -</pre> - <section> - <h2> - Methods - </h2> - <dl class="domintro"> - <dt> - <var title="">promise</var> = <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> ) - </dt> - <dd> - <p> - Immediately returns a new <a href="http://dom.spec.whatwg.org/#promise" - class="externalDFN">Promise</a> object and then the user is prompted to select discovered network - services that have advertised support for the requested service type(s). - </p> - <p> - The <var title="">type</var> argument contains one or more <a>valid service type</a> tokens that the web - page would like to interact with. - </p> - <p> - If the user accepts, the <var title="">promise</var> object is <a class="externalDFN" - href="http://dom.spec.whatwg.org/#concept-resolver-resolve">resolved</a>, with a <a href= - "#networkservices"><code>NetworkServices</code></a> object as its argument. - </p> - <p> - If the user declines, or an error occurs, the <var title="">promise</var> object is <a class= - "externalDFN" - href="http://dom.spec.whatwg.org/#concept-resolver-reject">rejected</a>. - </p> - </dd> - </dl> - <div> - <p> - When the <dfn id="dom-navigator-getnetworkservices" - title="dom-navigator-getnetworkservices"><code>getNetworkServices(type)</code></dfn> method is called, - the <a>user agent</a> MUST run the following steps: - </p> - <ol class="rule"> - <li>Let <var>Network Service Promise</var> be a new <a href="http://dom.spec.whatwg.org/#promise" - class="externalDFN"><code>Promise</code></a> object. - </li> - <li>Let <var>Network Service Promise's Resolver</var> be the default <a href= - "http://dom.spec.whatwg.org/#concept-resolver" - class="externalDFN">resolver</a> of <var>Network Service Promise</var>. - </li> - <li>Return <var>Network Service Promise</var>, and run the remaining steps asynchronously. - </li> - <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>valid service type</a> tokens, then let - <var>requested control types</var> be the value of <var>type</var>, removing any non-<a>valid service - type</a> tokens from the resulting array. - </li> - <li>If <var>type</var> is a string consisting of one <a>valid service type</a> token, then let - <var>requested control types</var> be an array containing one item with a value of <var>type</var>. - </li> - <li>If <var>requested control types</var> is an array that contains at least one or more <a title= - "valid service type">valid service type</a> tokens then continue to the step labeled <em>process</em> - below. Otherwise, reject <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-reject" - class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the string - value "UnknownTypePrefixError" (<a href= - "#dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a>) and whose - <code>message</code> attribute has a helpful implementation-dependent message that explains this - error, 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>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>. Otherwise, abort the remaining - sub-steps and continue above at the next <var>available service</var>. - </li> - <li>If <var>matched service</var> is not empty then run the following steps: - <ol class="rule"> - <li>Let <var>CORS check result</var> be the result of running the <a>preliminary CORS check</a> - algorithm, passing in <var>matched services</var>'s <code>url</code> attribute as the <var>control - endpoint URL</var> argument and 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> as the <var>request origin</var> argument. - </li> - <li>If <var>CORS check result</var> is not <code>pass</code> and <var>matched service</var>'s - <code>type</code> attribute is also not present in the <a>network services whitelist</a> then abort - the remaining sub-steps and continue above at the next <var>available service</var>. - </li> - <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>Optionally, e.g. based on a previously-established user preference, for security reasons, or due to - platform limitations, the <a>user agent</a> MAY reject <var>Network Service Promise</var> by running the - <a href="http://dom.spec.whatwg.org/#concept-resolver-reject" - class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the string - value "PermissionDeniedError" (<a href= - "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) and whose - <code>message</code> attribute has a helpful implementation-dependent message that explains this - error, abort any remaining steps and return. - </li> - <li>The user agent MUST NOT provide the entry script's origin with a <a href= - "#networkservices"><code>NetworkServices</code></a> object without prior permission given by the user. - <p> - If <var>services found</var> is not an empty array then the <a>user agent</a> MAY choose to 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 a <a href="#networkservices"><code>NetworkServices</code></a> - object representing the <a>user-authorized</a> subset of <var>services found</var>. - </p> - <p> - Alternatively, the user agent MAY wish to skip this user opt-in step and choose to fulfill <var>Network - Service Promise</var> immediately based on a previously-established user preference, for security - reasons, or due to platform limitations. In such an implementation, if <var>Network Service - Promise</var> is to be fulfilled as a result of a previously-established user preference then the - <a>user agent</a> MUST continue at the next step of this algorithm. - </p> - <p> - If permission has been granted by the user to access one or more networked services then the <a>user - agent</a> SHOULD include an "ongoing local-network communication" indicator. - </p> - <p> - If permission has been denied by the user, <a>user agent</a> or platform, then the <a>user agent</a> - MUST reject <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-reject" - class="externalDFN">resolver reject algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in a newly constructed <a href="http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object whose <code>name</code> attribute has the - string value "PermissionDeniedError" (<a href= - "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a>) and whose - <code>message</code> attribute has a helpful implementation-dependent message that explains this - error, abort any remaining steps and return. - </p> - <p> - If the user never responds or no previously-established user preference has been met, this algorithm - stalls on this step. - </p> - </li> - <li>Let <var>services</var> be an empty array. - </li> - <li>If <var>services found</var> is not an empty array then set <var>services</var> to be an array of one - or more <a href="#networkservice"><code>NetworkService</code></a> objects for which the user granted - permission above - known as the current objects <dfn>user-authorized</dfn> services. - </li> - <li>For each Object <var>service</var> in <var>services</var>, if any, run the following sub-steps: - <ol class="rule"> - <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>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>Store <var>requested control types</var> against <var>services manager</var> as an internal variable. - </li> - <li>Set <var>services manager</var>'s <a href= - "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to the number of - items currently found in the <a>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 <var>services</var>, if any, to the <var>services manager</var> object as its collection of - <a>indexed properties</a>. If <var>services</var> is an empty array then the <var>services manager</var> - does not have any <var>indexed properties</var>. - </li> - <li>Set <var>services manager</var>'s <a href="#dom-networkservices-length"><code>length</code></a> - attribute to the number of items in <var>services</var>. - </li> - <li>Add <var>services manager</var> to the <a>list of active service managers</a>. - </li> - <li>The <a>user agent</a> MUST fulfill <var>Network Service Promise</var> by running the <a href= - "http://dom.spec.whatwg.org/#concept-resolver-fulfill" - class="externalDFN">resolver fulfill algorithm</a> against the <var>Network Service Promise's - Resolver</var>, passing in <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> - The <dfn>preliminary CORS check</dfn> algorithm determines whether a Local-networked Service supports - Cross-Origin Resource Sharing [[!CORS]] as part of a call to the <a href= - "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method, prior to that service - being proposed for sharing to users and prior to active sharing with web pages. This algorithm takes two - arguments, <var>control endpoint URL</var> and <var>request origin</var>, and consists of running the - following steps: - </p> - <ol class="rule"> - <li>Let <var>CORS available check</var> be the result of applying the <a href= - "http://www.w3.org/TR/cors/#make-a-request-steps" - class="externalDFN">make a request steps</a> [[!CORS]], setting the <a href= - "http://www.w3.org/TR/cors/#request-method" - class="externalDFN">request method</a> to <code>OPTIONS</code>, the <a href= - "http://www.w3.org/TR/cors/#request-url" - class="externalDFN">request URL</a> to <var>control endpoint URL</var>, the <a href= - "http://www.w3.org/TR/cors/#source-origin" - class="externalDFN">source origin</a> to <var>request origin</var>, setting the <a href= - "http://www.w3.org/TR/cors/#omit-credentials-flag" - class="externalDFN">omit credentials flag</a> to <code>true</code> and including an <a href= - "http://www.w3.org/TR/cors/#http-access-control-request-method" - class="externalDFN"><code>Access-Control-Request-Method</code></a> header with a value of - <code>GET</code>. - </li> - <li>If <var>CORS available check</var> is cancelled by the user, or it results in a network error, or its - response does not have an HTTP status code of <code>200</code> then abort any remaining steps and return - <code>fail</code>. - </li> - <li>Return the result of running the <a href="http://www.w3.org/TR/cors/#resource-sharing-check" - class="externalDFN">resource sharing check</a> [[!CORS]] against the successful HTTP response of the - <var>CORS available check</var>. - <p class="note"> - This returned result will always be either <code>pass</code> or <code>fail</code>. - </p> - </li> - </ol> - <p> - There is no implied persistence to networked service sharing provided to a web page. It MUST NOT be - possible to access a networked service previously granted to a web page without 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> - <h3> - Error Handling - </h3> - <dl class="domintro"> - <dt> - <var title="">error</var> . <code title="dom-NavigatorNetworkServiceError-name"><a href= - "#dom-domerror-extensions-name">name</a></code> - </dt> - <dd> - <p> - Returns the current error's error name. At the current time, this will be "PermissionDeniedError" or - "UnknownTypePrefixError", for which the corresponding error constants <a href= - "#dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></a> and <a href= - "#dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></a> are defined. - </p> - </dd> - </dl> - <p> - The <dfn id="dom-domerror-extensions-name" - title="dom-domerror-extensions-name"><code>name</code></dfn> attribute of a <a href= - "http://dom.spec.whatwg.org/#domerror" - class="externalDFN"><code>DOMError</code></a> object returned from this API <em class="ct">MUST</em> - return the name for the error, which will be one of the following: - </p> - <dl> - <dt> - <dfn id="dom-domerror-extensions-permission_denied" - title="dom-domerror-extensions-permission_denied"><code>PERMISSION_DENIED_ERR</code></dfn> (DOMString - value "PermissionDeniedError") - </dt> - <dd> - The user or user agent denied the page permission to access any services. - </dd> - <dt> - <dfn id="dom-domerror-extensions-unknown_type_prefix" - title="dom-domerror-extensions-unknown_type_prefix"><code>UNKNOWN_TYPE_PREFIX_ERR</code></dfn> - (DOMString value "UnknownTypePrefixError") - </dt> - <dd> - No <a>valid service type</a> tokens were provided in the method invocation. - </dd> - </dl> - </section> - </section> - <section> - <h2> - Obtaining networked services - </h2> - <p> - The <a href="#networkservices"><code>NetworkServices</code></a> interface represents a collection of zero or - more <a>indexed properties</a> that are each a <a>user-authorized</a> <a href= - "#networkservice"><code>NetworkService</code></a> object. - </p> - <p> - A <a href="#networkservices"><code>NetworkServices</code></a> object is the <a href= - "http://dom.spec.whatwg.org/#concept-promise-result" - class="externalDFN">promise result</a> from a call to <a href= - "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a>. - </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-onservicefound">onservicefound</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-onservicelost">onservicelost</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> - <h2> - Attributes - </h2> - <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 <a>indexed properties</a> in the current object's collection. - </p> - </dd> - <dt> - <code title="dom-networkservices-servicesavailable"><a href= - "#dom-networkservices-servicesavailable">servicesAvailable</a></code> - </dt> - <dd> - <p> - Returns the current number of items matching one of the app-requested <a>valid service type</a> tokens in - the <a>list of available service records</a>. - </p> - </dd> - </dl> - <div> - <p> - The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute MUST return the number of - <a href="#networkservice"><code>NetworkService</code></a> objects represented by the collection. - </p> - <p> - The <dfn id="dom-networkservices-servicesavailable"><code>servicesAvailable</code></dfn> attribute MUST - return the number of services in the <a>list of available service records</a> whose <code>type</code> - attribute matches any of the <a>valid service type</a> tokens that were initially used to create the - current <a href="#networkservices"><code>NetworkServices</code></a> object. - </p> - </div> - </section> - <section> - <h2> - Methods - </h2> - <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 collection of - zero or more <a href="#networkservice"><code>NetworkService</code></a> objects - its <a>indexed - properties</a>. The <a>indexed properties</a> of a <a href= - "#networkservices"><code>NetworkServices</code></a> object are <span>immutable</span> meaning that <a>indexed - properties</a> cannot be added and <a>indexed properties</a> cannot be removed for the lifetime of a <a href= - "#networkservices"><code>NetworkServices</code></a> object. - </p> - <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 the <a href="#networkservice"><code>NetworkService</code></a> objects in the collection - minus one. - </p> - <p class="note"> - 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> - <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 the user agent MUST return the <a href= - "#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th item in - the collection. - </p> - <p> - The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method <em class= - "ct">MUST</em> return the first <a href="#networkservice"><code>NetworkService</code></a> object in the - collection whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the - <var>id</var> argument provided. When no <a href="#networkservice"><code>NetworkService</code></a> objects - match the given argument, the method MUST return null. - </p> - </section> - <section> - <h2> - Events - </h2> - <p> - The following are the event handlers (and their corresponding event handler event types) that <em class= - "ct">MUST</em> be supported, as IDL attributes, by all objects implementing the <a href= - "#networkservices"><code>NetworkServices</code></a> interface: - </p> - <table border="1"> - <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-onservicefound" - title="dom-NetworkServices-onservicefound"><code>onservicefound</code></dfn> - </td> - <td> - <a href="#event-servicefound"><code>servicefound</code></a> - </td> - </tr> - <tr> - <td> - <dfn id="dom-networkservices-onservicelost" - title="dom-NetworkServices-onservicelost"><code>onservicelost</code></dfn> - </td> - <td> - <a href="#event-servicelost"><code>servicelost</code></a> - </td> - </tr> - </tbody> - </table> - </section> - </section> - <section> - <h2> - 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 HTTP 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-onavailable">onavailable</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-onunavailable">onunavailable</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> - <h2> - Attributes - </h2> - <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>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 URL endpoint (including any required port information) of the user-selected control service. - </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 MUST 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>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://url.spec.whatwg.org/#concept-absolute-url" - class="externalDFN">absolute URL</a> pointing to the root HTTP endpoint for the service. 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> - <h3> - 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 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 - either <var>online</var>, and therefore accessible on the local network, in which case this attribute will - return <code>true</code> or, <var>offline</var>, and therefore not accessible on the local network, either - temporarily or permanently, in which case this attribute will return <code>false</code>. This attribute MUST - default to <code>true</code>. - </p> - </section> - <section> - <h3> - Events - </h3> - <p> - The following are the event handlers (and their corresponding event handler event types) that <em class= - "ct">MUST</em> be supported, as IDL attributes, by all objects implementing the <a href= - "#networkservice"><code>NetworkService</code></a> interface: - </p> - <table border="1"> - <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-onavailable" - title="dom-NetworkService-onavailable"><code>onavailable</code></dfn> - </td> - <td> - <a href="#event-available"><code>available</code></a> - </td> - </tr> - <tr> - <td> - <dfn id="dom-networkservice-onunavailable" - title="dom-NetworkService-onunavailable"><code>onunavailable</code></dfn> - </td> - <td> - <a href="#event-unavailable"><code>unavailable</code></a> - </td> - </tr> - </tbody> - </table> - </section> - </section> - <section> - <h2> - Service Discovery - </h2> - <p> - A <a>user agent</a> conforming to this specification MAY implement <abbr title= - "Simple Service Discovery Protocol">SSDP</abbr> [[!UPNP-DEVICEARCH11]], Zeroconf [[!DNS-SD]] + [[!MDNS]] and/or - <abbr title="Discovery and Launch Protocol">DIAL</abbr> [<a href= - "https://sites.google.com/a/dial-multiscreen.org/dial/dial-protocol-specification">DIAL</a>] <dfn>service - discovery mechanisms</dfn> - the requirements detailed in this section of the specification - to enable Web - pages to request and connect with HTTP services running on networked devices, discovered via any of these - mechanisms, through this API. When a <a>user agent</a> implements any of these <a>service discovery - mechanisms</a>, then it MUST conform to the corresponding algorithms provided in this section of the - specification. - </p> - <p> - This section presents how the results of these <a>service discovery mechanisms</a> will be matched to requested - service types, how the user agent stores available and active services and 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 <a>service discovery mechanisms</a> asynchronously and - periodically update the <a>list of available service records</a> as required. The timing of any <a>service - discovery mechanisms</a> is an implementation detail left to the discretion of the implementer (e.g. by - continuously monitoring the network as a background process or on invocation of this API from a Web page). - </p> - <p> - The <dfn>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 - the current time. At any point during the running of any of the <a>service discovery mechanisms</a> 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>list of active service managers</dfn> is an internal list within user agents that is used to track all - <a href="#networkservices"><code>NetworkServices</code></a> objects currently being shared with any web pages - at the current time within the user agent. Each <a href="#networkservices"><code>NetworkServices</code></a> - object in the <a>list of active service managers</a> represents a collection of zero or more <a href= - "#networkservice"><code>NetworkService</code></a> objects - known as its <dfn>indexed properties</dfn>. - <a href="#networkservice"><code>NetworkService</code></a> objects are attached as the <a>indexed properties</a> - of a <a href="#networkservices"><code>NetworkServices</code></a> object as part of the <a href= - "#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> algorithm. - </p> - <p> - The rule for <dfn>adding an available service</dfn> is the process of adding a <a>new service</a> or updating - an <a>existing service</a> that is generally available on the user's current network in the <a>list of - available service records</a>. This rule takes one argument, <var>network service record</var>, and consists of - running the following steps: - </p> - <ol class="rule"> - <li>For each <var>existing service record</var> in the current <a>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>Replace the value of <var>existing service record</var> in the current <a>list of available service - records</a> with the value of <var>network service record</var>, aborting any remaining steps in this - algorithm and return. - </li> - </ol> - </li> - <li>Add <var>network service record</var> to the <a>list of available service records</a> as a new item. - </li> - <li>For each <var>service manager</var> in the <a>list of active service managers</a> run the following steps: - <ol class="rule"> - <li>For each <var>active service</var> in <var>service manager</var> run the following steps: - <ol class="rule"> - <li>If the <var>network service record</var>'s <code>id</code> property equals the <var>active - service</var>'s <code>id</code> attribute and <var>active service</var>'s <code>online</code> attribute - is currently set to <code>false</code> then 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-available"><code>available</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>Let <var>'service type in current service manager' flag</var> be <code>false</code>. - </li> - <li>For each <var>requested control type</var> of the <var>requested control types</var> in <var>service - manager</var> run the following steps: - <ol class="rule"> - <li>If <var>network service record</var>'s <code>type</code> property does not equal <var>requested - control type</var> then abort any remaining sub-steps and continue at the next available <var>requested - control type</var>. - </li> - <li>Set the <var>'service type in current service manager' flag</var> to <code>true</code>, abort any - remaining sub-steps and continue. - </li> - </ol> - </li> - <li>If the <var>'service type in current service manager' flag</var> is set to <code>true</code> then - increment <var>service manager</var>'s <a href= - "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute 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-servicefound"><code>servicefound</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>service manager</var> object. - </li> - </ol> - </li> - </ol> - <p> - The rule for <dfn>removing an available service</dfn> is the general process of removing an <a>existing - service</a> from the <a>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>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>Let <var>'service type in use' flag</var> be <code>false</code>. - </li> - <li>For each <var>service manager</var> in the <a>list of active service managers</a> run the following - steps: - <ol class="rule"> - <li>Let <var>'service type in current service manager' flag</var> be <code>false</code>. - </li> - <li>For each <var>active service</var> in <var>service manager</var> run the following steps: - <ol class="rule"> - <li>If <var>existing service record</var>'s <code>id</code> property equals the <var>active - service</var>'s <code>id</code> attribute and <var>active service</var>'s <a href= - "#dom-networkservice-online"><code>online</code></a> attribute is currently set to - <code>true</code> then 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-unavailable"><code>unavailable</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>. - </li> - </ol> - </li> - <li>For each <var>requested control type</var> of the <var>requested control types</var> in - <var>service manager</var> run the following steps: - <ol class="rule"> - <li>If <var>existing service record</var>'s <code>type</code> property does not equal - <var>requested control type</var> then abort any remaining sub-steps and continue at the next - available <var>requested control type</var>. - </li> - <li>Set the <var>'service type in current service manager' flag</var> to <code>true</code> and the - <var>'service type in use' flag</var> to <code>true</code>, abort any remaining sub-steps and - continue. - </li> - </ol> - </li> - <li>If the <var>'service type in current service manager' flag</var> is set to <code>true</code> then - decrement <var>service manager</var>'s <a href= - "#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute 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-servicelost"><code>servicelost</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>service manager</var> object. - </li> - </ol> - </li> - <li>If the <var>'service type in use' flag</var> is <code>false</code> and 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>terminate an existing - UPnP Events Subscription</a>, if one is currently active (as a result of having previously called <a>setup - a UPnP Events Subscription</a> against the current <var>existing service record</var>). - </li> - <li>Remove <var>existing service record</var> from the current <a>list of available service records</a>. - </li> - </ol> - </li> - </ol> - <p> - User agents SHOULD expire a service record from the <a>list of available service records</a> when its - <code>expiryTimestamp</code> attribute exceeds the current UTC timestamp. When this condition is met the - <a>user agent</a> SHOULD run the rule for <a>removing an available service</a>, passing in the expired service - record's <code>id</code> attribute as the only argument. - </p> - <section> - <h4> - Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title= - "Service Discovery">SD</abbr>) - </h4> - <p> - For each DNS response received from a user-agent-initiated Multicast DNS Browse for <abbr title= - "DNS Pointer Record">PTR</abbr> records with the name <code>_services._dns-sd._udp</code> on the resolved - recommended automatic browsing domain [[!MDNS]], the <a>user agent</a> MUST run the following steps: - </p> - <ol class="rule"> - <li>Let <var>service mDNS responses</var> be an array of PTR records received by issuing a Multicast DNS - Browse for PTR records with the name of the current discovered service type. - </li> - <li>For each Object <var>service mDNS response</var> in <var>service mDNS 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 PTR Service - Instance Name [[!MDNS]]. - </li> - <li>Set <var>network service record</var>'s <code>name</code> property to the value of the PTR Service - Instance Name's <var>Instance</var> component [[!MDNS]]. - </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 PTR Service Instance Name's <var>Service</var> - component [[!MDNS]]. - </li> - <li>Set <var>network service record</var>'s <code>url</code> property to the resolvable Service URL - obtained from performing an DNS-SD Lookup [[!DNS-SD]] of the current service from the PTR record provided - [[!MDNS]]. - </li> - <li>Set <var>network service record</var>'s <code>config</code> property to the string value of the - contents of the first DNS-SD TXT record associated with the <var>service mDNS response</var> as defined - in [[!DNS-SD]]. - </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>adding an available service</a>, passing in the current <var>network - service record</var> as the only argument. - </li> - </ol> - </li> - </ol> - </section> - <section> - <h5> - Simple Service Discovery Protocol (<abbr title="Simple Service Discovery Protocol">SSDP</abbr>) - </h5> - <p> - A user agent that implements UPnP service discovery MUST issue a <dfn>search request 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 [[!UPNP-DEVICEARCH11]]. - </p> - <p> - The user agent MUST issue all <a title="search request for UPnP root devices">search requests for UPnP root - devices</a> with a HTTP request line equal to <code>M-SEARCH * HTTP/1.1</code>, with a HOST header equal to - the reserved multicast address and port of <code>239.255.255.250:1900</code> and a MAN header equal to - <code>ssdp:discover</code>. The <a>user agent</a> must also send an ST header with this HTTP request equal to - the String value of <code>ssdp:all</code> or <code>upnp:rootdevice</code> or a single <a>valid service - type</a> token beginning with the String value <code>upnp:</code>. If a single <a>valid service type</a> - token beginning with the String value <code>upnp:</code> is to be used, the user agent MUST strip the leading - String <code>upnp:</code> before using this value in this HTTP request. The user-agent MUST also send an MX - header equal to a <dfn>maximum UPnP advertisement response wait time</dfn> value between <code>1</code> and - <code>5</code> seconds with this HTTP request. - </p> - <p> - The user agent MUST listen for any incoming responses to any <a>search request for UPnP root devices</a>. - </p> - <p> - For each <dfn>HTTP Response</dfn> following an initial <a>search request for UPnP root devices</a> sent on a - <a>standard UPnP address and port</a> the user agent MUST run the following steps: - </p> - <ol class="rule"> - <li>If the <a>HTTP Response</a> is not a HTTP 200 OK response then this response is invalid and the user - agent MUST discard this response, abort any remaining steps and return. The user agent MAY issue a new - <a>search request for UPnP root devices</a> as a result of this error occurring. - </li> - <li>If the <a>maximum UPnP advertisement response wait time</a> has been exceeded since the initial <a>search - request for UPnP root devices</a> was sent then the <a>HTTP Response</a> is invalid and the user agent MUST - discard this response, abort any remaining steps and return. The user agent MAY stop listening for responses - from the current <a>search request for UPnP root devices</a> as a result of this error occurring. Equally, - the user agent MAY issue a new <a>search request for UPnP root devices</a> as a result of this error - occurring. - </li> - <li>Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the <a>HTTP - Response</a>, with each key being the name of a HTTP response header and each value being that HTTP 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 then the - <a>HTTP Response</a> is invalid and the <a>user agent</a> MUST discard this response, abort any remaining - steps and return. - </li> - <li>The user agent MUST run the rule for <a>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 URL</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> - (minus the leading string of <code>max-age=</code>) as the <var>device expiry</var> argument. - </li> - </ol> - <p> - The user agent MUST listen for incoming requests on the <dfn>standard UPnP address and port</dfn> on all - current local network interface addresses with the port <code>1900</code>. - </p> - <p> - For each <dfn>HTTP Request</dfn> received on a <a>standard UPnP address and port</a> the user agent MUST run - the following steps: - </p> - <ol class="rule"> - <li>If the <a>HTTP Request</a> is not a HTTP NOTIFY request then it is not a valid UPnP Request and the user - agent MUST discard this request, abort any remaining steps and return. - </li> - <li>Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the <a>HTTP - Request</a>, with each key being the name of a HTTP header and each value being that HTTP header's value. - </li> - <li>If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> and the <a>HTTP - Request</a> 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, then the <a>user agent</a> MUST 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> then the user agent - MUST run the rule for <a>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 URL</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> (minus the leading string of - <code>max-age=</code>) 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 MUST run the rule for <a>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>obtaining a UPnP Device Description File</dfn> is the process of obtaining the contents of - a standard UPnP Device Description [[!UPNP-DEVICEARCH11]] from a URL-based resource. This rule takes three - arguments - <var>device descriptor URL</var>, <var>device identifier</var> and <var>device expiry</var> - and - when called the user agent MUST run the following steps: - </p> - <ol class="rule"> - <li>Let <var>device descriptor file</var> contain the contents of the file located at the URL provided in - <var>device descriptor URL</var> obtained according to the rules defined in 'Section 2.11: Retrieving a - description using HTTP' in [[!UPNP-DEVICEARCH11]]. - </li> - <li>If the value provided in <var>device descriptor URL</var> cannot be resolved as a reachable URL on the - current network or the <var>device descriptor file</var> remains empty then it is invalid and the <a>user - agent</a> MUST abort any remaining steps and return. - </li> - <li>Run the rule for <a>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> - </ol> - <p> - The rule for <dfn>processing a UPnP Device Description File</dfn> is the process of parsing the contents of a - standard UPnP Device Description [[!UPNP-DEVICEARCH11]] and registering the UPnP services contained therein - within the <a>list of available service records</a>. - </p> - <p> - The rule for <a>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 MUST - 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 [[!UPNP-DEVICEARCH11]]. - </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 - the first occurrence of the <code><UDN></code> element in the <var>device descriptor file</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>adding an available service</a>, passing in the current <var>network - service record</var> as the only argument. - </li> - </ol> - </li> - <li>If <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 MUST run the rule for <a>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 current <var>device identifier</var> and <var>device expiry</var> - arguments. - </li> - </ol> - <p> - The rule for <dfn>removing all services from a registered UPnP Device</dfn> is the process of removing all - services associated with a device from the <a>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>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>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>user agent</a> is to <dfn>setup a UPnP Events Subscription</dfn>, it is to run the following - steps with the current <var>network service record</var> object as defined in 'Section 4.1.2: SUBSCRIBE with - NT and CALLBACK' in [[!UPNP-DEVICEARCH11]]: - </p> - <ol class="rule"> - <li>If <var>network service record</var>'s <code>eventsUrl</code> property is empty then the <a>user - agent</a> MUST abort these steps. - </li> - <li>Let <var>callback URL</var> be the value of creating a new <a>user-agent generated callback url</a>. - </li> - <li>Send a HTTP SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a - <em>TIMEOUT</em> header with 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 URL</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 HTTP SUBSCRIBE request then the <a>user agent</a> MUST - 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>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 HTTP 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 and set <var>timeout date</var> to 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. If the current date is greater than or equal to <var>timeout - date</var> then the <a>user agent</a> SHOULD continue from the step labeled <em>refresh - subscription</em> above. For all non 200 OK responses the <a>user agent</a> SHOULD continue from the - step labeled <em>refresh subscription</em> above. - </li> - </ol> - </li> - <li> - <em>Listen</em>: For each HTTP NOTIFY request received at the <var>callback URL</var> the <a>user - agent</a> is to run the following steps: - <ol class="rule"> - <li>Let <var>content clone</var> be the result of obtaining the message body of the HTTP NOTIFY - request. If <var>content clone</var> is empty, then the <a>user agent</a> MUST abort these steps. - </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><code>NetworkService</code></a> object. - </li> - <li>Return a HTTP 200 OK response to the sender of the HTTP NOTIFY request. - </li> - </ol> - </li> - </ol> - </li> - </ol> - <p> - A <a>user agent</a> can <dfn>terminate an existing UPnP Events Subscription</dfn> at any time for a - <var>network service record</var> by sending an HTTP UNSUBSCRIBE request - as defined in 'Section 4.1.4: - Cancelling a subscription with UNSUBSCRIBE' in [[!UPNP-DEVICEARCH11]] - 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>setup a UPnP Events Subscription</a> action occurred. - </p> - </section> - <section> - <h5> - Discovery and Launch Protocol (<abbr title="Discovery and Launch Protocol">DIAL</abbr>) - </h5> - <p> - A user agent that implements DIAL service discovery MUST issue a <dfn>search request for DIAL-enabled - 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 [[!UPNP-DEVICEARCH11]]. - </p> - <p> - Let <var>dial version</var> be the version number specified in the <a>valid service type</a> token. Let - <var>dial search target</var> be the concatentation of the - <code>urn:dial-multiscreen-org:service:dial:</code> string constant with the <var>dial version</var> - (currently, <var>dial version</var> can only be <code>1</code>) - </p> - <p> - The user agent MUST issue all <a title="search request for DIAL-enabled devices">search requests for - DIAL-enabled devices</a> with a HTTP request line equal to <code>M-SEARCH * HTTP/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 <var>dial search target</var> and a user-agent - defined MX header equal to a <dfn>maximum DIAL advertisement response wait time</dfn> value between - <code>1</code> and <code>5</code> seconds. - </p> - <p> - The user agent MUST listen for any incoming responses to a <a>search request for DIAL-enabled devices</a>. - </p> - <p> - For each HTTP Response following an initial <a>search request for DIAL-enabled devices</a> sent on a - <a>standard UPnP address and port</a> the user agent MUST run the following steps: - </p> - <ol class="rule"> - <li>If the HTTP Response is not a HTTP 200 OK response then this response is invalid and the user agent MUST - discard this response, abort any remaining steps and return. The user agent MAY issue a new <a>search request - for DIAL-enabled devices</a> as a result of this error occurring. - </li> - <li>If the <a>maximum DIAL advertisement response wait time</a> has been exceeded since the initial <a>search - request for DIAL-enabled devices</a> was sent then the <a>HTTP Response</a> is invalid and the user agent - MUST discard this response, abort any remaining steps and return. The user agent MAY stop listening for - responses from the current <a>search request for DIAL-enabled devices</a> as a result of this error - occurring. Equally, the user agent MAY issue a new <a>search request for DIAL-enabled devices</a> as a result - of this error occurring. - </li> - <li>Let <var>dial device</var> be an Object with a property for each HTTP header received in the <a>HTTP - Response</a>, with each key being the name of a HTTP response header and each value being that HTTP response - header's value. - </li> - <li>If <var>dial 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 <var>dial search target</var>, then the <a>HTTP Response</a> is - invalid and the <a>user agent</a> MUST discard this response, abort any remaining steps and return. - </li> - <li>The user agent MUST run the rule for <a>obtaining a UPnP Device Description File</a> passing in the first - occurrence of <var>LOCATION</var> from <var>dial device</var> as the <var>device descriptor URL</var> - argument and the first occurrence of <var>USN</var> from <var>dial device</var> as the <var>device - identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>dial device</var> - (minus the leading string of <code>max-age=</code>) as the <var>device expiry</var> argument. - </li> - </ol> - <p> - The rule for <dfn>obtaining a DIAL Device Description File</dfn> is the process of obtaining the contents of - a standard UPnP Device Description [[!UPNP-DEVICEARCH11]] from a URL-based resource. This rule takes three - arguments - <var>device descriptor URL</var>, <var>device identifier</var> and <var>device expiry</var> - and - when called the user agent MUST run the following steps: - </p> - <ol class="rule"> - <li>Let <var>device descriptor file</var> contain the contents of the file located at the URL provided in - <var>device descriptor URL</var> obtained according to the rules defined in 'Section 2.11: Retrieving a - description using HTTP' in [[!UPNP-DEVICEARCH11]]. - </li> - <li>Let <var>application url</var> be the value of the first occurrence of the <code>Application-URL</code> - response header field obtained according to the rules defined in 'Section 5.4: Device Description Response' - in [<a href="https://sites.google.com/a/dial-multiscreen.org/dial/dial-protocol-specification">DIAL</a>] - </li> - <li>If the value provided in <var>device descriptor URL</var> cannot be resolved as a reachable URL on the - current network or the <var>device descriptor file</var> remains empty or <var>application url</var> is - undefined then it is invalid and the <a>user agent</a> MUST abort any remaining steps and return. - </li> - <li>Run the following steps to add the newly discovered DIAL service: - <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>expiryTimestamp</code>. - </li> - <li>Set <var>network service record</var>'s <code>id</code> property to the first occurrence of the - <code><UDN></code> element in the <var>descriptor file</var> prefixed with the <code>dial:</code> - string constant - </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 <code><friendlyName></code> element in the <var>descriptor file</var>. - </li> - <li>Set <var>network service record</var>'s <code>type</code> property to <var>dial search target</var>. - </li> - <li>Set <var>network service record</var>'s <code>url</code> property to the string value of the - <var>application url</var>. - </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>adding an available service</a>, passing in the current <var>network - service record</var> as the only argument. - </li> - </ol> - </li> - </ol> - </section> - <section> - <h3> - Network Topology Monitoring - </h3> - <div> - <p> - When the <a>user agent</a> detects that the user has dropped from a connected network then, for each - <var>existing service record</var> in the <a>list of available service records</a> discovered via that - network connection, the <a>user agent</a> MUST run the general rule for <a>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>user agent</a> detects that the user has connected to a new network or reconnected to an - existing network, then it SHOULD restart its discovery mechanisms as defined in the <a href= - "#service-discovery">Service Discovery</a> section of this specification, maintaining the existing <a>list - of active service managers</a> currently in use. - </p> - </div> - </section> - </section> - <section> - <h3> - Events Summary - </h3> - <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"> - <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-servicefound"><code>servicefound</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 <a>new service</a> that matches one of the <a title="valid service type">requested type tokens</a> - is found in the current network. - </td> - </tr> - <tr> - <td> - <dfn id="event-servicelost"><code>servicelost</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 <a>existing service</a> that matches one of the <a title="valid service type">requested type - tokens</a> gracefully leaves or expires from the current network. - </td> - </tr> - <tr> - <td> - <dfn id="event-available"><code>available</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 <a>current service</a> renews its service registration within the current network. - </td> - </tr> - <tr> - <td> - <dfn id="event-unavailable"><code>unavailable</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 <a>current service</a> 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>user-agent generated callback url</a> - for a <a>current service</a>. This event never fires for Zeroconf-based services. - </td> - </tr> - </tbody> - </table> - </section> - <section> - <h3> - Garbage collection - </h3> - <p> - There is an <dfn>implied strong reference</dfn> from any IDL attribute in this API that returns a pre-existing - object to that object. - </p> - <p class="note"> - For example, if a <a><code>NetworkServices</code></a> object has one or more <a>indexed properties</a> attached - to it then there is a strong reference from that <a><code>NetworkServices</code></a> object toward each of its - <a>indexed properties</a>. - </p> - <p> - If a <a>user agent</a> is to <dfn>make disappear</dfn> a <a><code>NetworkServices</code></a> object (this - happens when a <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#document" - class="externalDFN"><code>Document</code></a> object goes away), the <a>user agent</a> MUST remove this - object from the <a>list of active service managers</a>. - </p> - </section> - <section> - <h3> - Use Cases and Requirements - </h3> - <p> - This section covers what the requirements are for this API, 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 API exposed to script that exposes the features above. The user is notified - by UI anytime interaction with Local-networked Services is requested, giving the user 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"> - <h3> - Examples - </h3> - <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"> -<input type="button" value="Start" onclick="start()" id="startBtn"/> -<div id="debugconsole"></div> - -<script> - var startBtn = document.getElementById('startBtn'), - debug = document.getElementById('debugconsole'); - - function start() { - if(navigator.getNetworkServices) { - navigator.getNetworkServices('zeroconf:_xbmc-jsonrpc._tcp').then(gotXBMCService).catch(error); - startBtn.disabled = true; - } else { - debug.innerHTML += "<br>Service Discovery not supported!"; - } - } - - function gotXBMCService(services) { - -// Listen for service disconnect messages - - services[0].addEventListener('unavailable', function ( e ) { - debug.innerHTML += "<br>" + services[0].name + " disconnected."; - startBtn.disabled = false; - }, false); - -// Send a service message to get albums list (and process the service response) - - var svcXhr = new XMLHttpRequest(); - svcXhr.open("POST", services[0].url + "/getAlbums"); // services[0].url and its sub-resources are - // available for cross-site XHR use. - - svcXhr.setRequestHeader('Content-Type', 'application/json-rpc'); - - svcXhr.addEventListener('readystatechange', function ( response ) { - if( response.readyState != 4 || response.status != 200 ) - return; - debug.innerHTML += "<br>" + services[0].name + " response received: "; - debug.textContent += JSON.parse(response.responseText); - }, false); - - var svcMsg = [ - { "jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "genreid": -1, - "artistid": -1, "start": -1, "end": -1 }, "id": "1" } - ]; - - svcXhr.send(JSON.stringify(svcMsg)); - debug.innerHTML += "<br>" + services[0].name + " request sent: "; - debug.textContent += JSON.stringify(svcMsg); - - } - - function error( err ) { - debug.innerHTML += "<br>An error occurred obtaining a local network service."; - startBtn.disabled = false; - } -</script> -</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"> -<select name="make" id="make"> - <option selected="selected" disabled="disabled">Select make</option> - <option>Sony</option> - <option>Philips</option> - <option>Alba</option> -</select> -<select name="model" id="model"></select> -<div id="debugconsole"></div> - -<script> - var debug = document.getElementById('debugconsole'); - - var models = { - "Sony": [ - {"name": "Bravia TV S1000", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" }, - {"name": "Bravia TV S2000", "type": "zeroconf", "service": "_mediarenderer._http._tcp" }, - {"name": "HiFi WD10", "type": "upnp", "service": "urn:schemas-upnp-org:service:RenderingControl:1" } - ], - "Philips": [ /* ... */ ], - "Alba": [ /* ... */ ] - }; - - var makeEl = document.getElementById("make"), - modelEl = document.getElementById("model"); - - makeEl.addEventListener('change', function() { - modelEl.innerHTML = ""; // reset - var defaultOption = document.createElement("option"); - defaultOption.textContent = "Select model"; - defaultOption.setAttribute("disabled", "disabled"); - defaultOption.setAttribute("selected", "selected"); - modelEl.appendChild(defaultOption); - for(var i = 0, l = models[makeEl.value].length; i < l; i++) { - var option = document.createElement("option"); - option.textContent = models[makeEl.value][i]["name"]; - option.setAttribute("value", models[makeEl.value][i]["type"] + ":" + models[makeEl.value][i]["service"]); - modelEl.appendChild(option); - } - }, false); - - modelEl.addEventListener('change', function() { - if(navigator.getNetworkServices && - modelEl.value == "upnp:urn:schemas-upnp-org:service:RenderingControl:1") { - var servicesPromise = navigator.getNetworkServices(modelEl.value).then(successCallback, errorCallback); - } else if (modelEl.value == "zeroconf:_mediarenderer._http._tcp") { - debug.innerHTML += "<br>Service type is not implemented by this application."; - } else { - debug.innerHTML += "<br>Service Discovery is not supported!"; - } - }, false); -</script> - -<script> - function successCallback( services ) { - - // Listen for service push notification messages - - services[0].addEventListener('notify', function ( msg ) { - debug.innerHTML += "<br>" + services[0].name + " event received: "; - debug.textContent += msg.data; - }, false); - - // Send a control signal to mute the service audio - - var svcXhr = new XMLHttpRequest(); - svcXhr.open("POST", services[0].url); // services[0].url and its sub-resources are - // available for cross-site XHR use. - - svcXhr.setRequestHeader('SOAPAction', 'urn:schemas-upnp-org:service:RenderingControl:1#SetMute'); - svcXhr.setRequestHeader('Content-Type', 'text/xml; charset="utf-8";'); - - svcXhr.onreadystatechange = function ( response ) { - if( response.readyState != 4 || response.status != 200 ) - return; - debug.innerHTML += "<br>" + services[0].name + " response received: "; - debug.textContent += response.responseXML; - } - - // Service messaging to mute the provided service - var svcMsg = '<?xml version="1.0" encoding="utf-8"?>' + - '<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ' + - 'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' + - '<s:Body>' + - '<u:SetMute xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1">' + - '<InstanceID>0</InstanceID>' + - '<Channel>Master</Channel>' + - '<DesiredMute>true</DesiredMute>' + - '</u:SetMute>' + - '</s:Body>' + - '</s:Envelope>'; - - svcXhr.send(svcMsg); - debug.innerHTML += "<br>" + services[0].name + " request sent: "; - debug.textContent += svcMsg; - } - - function errorCallback( error ) { - debug.innerHTML += "<br>An error occurred: " + error.name; - } -</script> -</pre> - </div> - </section> - <section> - <h3> - Acknowledgements - </h3> - <p> - Thanks are expressed by the editor to the following individuals for their feedback on this specification to - date (in alphabetical order):<br> - <br> - Adam Barth, Gar Bergstedt, Robin Berjon, Lars-Erik Bolstad, Marcos Caceres, Cathy Chan, Daniel Danciu, - Jean-Claude Dufourd, Youenn Fablot, Mark Foltz, Dominique Hazael-Massieux, Frederick Hirsch, Tatsuya Igarashi, - 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, Google Inc., Opera Software ASA, Nokia Corp., Télécom ParisTech, W3C Device APIs Working Group, W3C - Web and TV Interest Group. + <strong>Work on this document has been discontinued and it should not be referenced or used as a basis for implementation.</strong> The <a href="https://www.w3.org/TR/presentation-api/">Presentation API</a> and the <a href="https://www.w3.org/TR/remote-playback/">Remote Playback API</a> address a subset of the use cases this API attempted to address. </p> </section> </body>
Received on Thursday, 12 January 2017 13:24:15 UTC