XEP-0327 v0.7: Updates based on XMPP Council feedback.

This commit is contained in:
Matthew A. Miller 2015-07-15 14:57:14 -06:00
parent 3905d3b3a6
commit b390cbd9f1
1 changed files with 64 additions and 32 deletions

View File

@ -11,7 +11,6 @@
&LEGALNOTICE;
<number>0327</number>
<status>Proposed</status>
<lastcall>2015-04-17</lastcall>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
@ -35,6 +34,12 @@
<jid>jdecastro@tropo.com</jid>
<uri>http://tropo.com</uri>
</author>
<revision>
<version>0.7</version>
<date>2015-07-15</date>
<initials>bl</initials>
<remark><p>Updates based on XMPP Council feedback.</p></remark>
</revision>
<revision>
<version>0.6</version>
<date>2015-04-29</date>
@ -89,7 +94,7 @@
<p>The relationship between the calling parties, the Rayo server and the Rayo client looks something like this:</p>
<code>
[caller] ----SIP---- [rayo server] ( -----Jingle---- [callee] ) optional
[caller] ----e.g. SIP---- [rayo server] ( -----e.g. Jingle---- [callee] ) optional
|
|
rayo client
@ -326,6 +331,9 @@
<p>Components have a lifecycle and are started by sending a specialized command to a call or mixer. Thus, a request for creation of a component will return a reference to the component's ID, and the component will continue to execute until it completes, potentially sending events and processing commands along the way (such as an instruction to pause or terminate), before finally issuing an event indicating its completion and thus unavailability. Multiple components may be active on a call or mixer at any one time, and commands may be executed on any entity during the execution of a component.</p>
</section3>
<section3 topic='Remote Party' anchor='concepts-actors-remote-party'>
<p>A call's Remote Party is the software or device with which the Call's signalling (and optionally media) connection is established. This might be a software or hardware phone, a PBX, a gateway or some other such system.</p>
</section3>
</section2>
<section2 topic="Addressing Scheme" anchor='addressing'>
@ -434,7 +442,9 @@
<p>On successfully receiving and parsing the dial command, the server SHOULD perform its own proprietary authorization measures to ensure that only desirable outbound sessions are created. If it is established that the command should not be allowed, the server MUST return an error giving an authorization reason.</p>
<p>If a 'uri' attribute is set on the dial command, the server should attempt to create the call at the requested URI. This allows clients to know the URI of the call prior to it coming into existence, for clients where this distinction might be important.</p>
<p>If a 'uri' attribute is set on the dial command, the server MUST attempt to create the call at the requested URI. This allows clients to know the URI of the call prior to it coming into existence, for clients where this distinction might be important. Such a URI MUST be a valid Rayo call address.</p>
<p>The specified metadata in the form of the 'from' attribute and any &lt;header/&gt; elements SHOULD be mapped to the underlying signalling protocol for communication to the remote party.</p>
<section4 topic='Errors' anchor='session-establishment-outbound-errors'>
<p>There are several reasons why the server might immediately return an error instead of acknowledging the creation of a new call:</p>
@ -567,7 +577,7 @@
</iq>
]]></example>
<p>Once the server receives notification that the session has been accepted by the third party, it should send a ringing event to the client to indicate such:</p>
<p>Once the server receives notification that the session has been accepted by the remote party, it should send a ringing event to the client to indicate such:</p>
<example caption="Call announces its ringing state (accepted by 3rd party but not yet answered)."><![CDATA[
<presence from='9f00061@call.shakespeare.lit'
to='juliet@capulet.lit/balcony'>
@ -575,7 +585,7 @@
</presence>
]]></example>
<p>Similarly, once the server receives notification that the session has been answered, it should negotiate media between the dialed party and its local media server. Once media negotiation is complete, it should send an answered event to the client to indicate such:</p>
<p>Similarly, once the server receives notification that the session has been answered, it should negotiate media between the remote party and its local media server. Once media negotiation is complete, it should send an answered event to the client to indicate such:</p>
<example caption="Call announces its answered state (media connected)."><![CDATA[
<presence from='9f00061@call.shakespeare.lit'
to='juliet@capulet.lit/balcony'>
@ -598,14 +608,14 @@
</iq>
]]></example>
<p>In this case, the server MUST treat the session creation in the same way as without the join element, until the point of media negotiation. Here, the server should negotiate media as specified by the join element, in accordance with the rules defined in <link url='#session-joining'>joining calls</link>. Media MUST NOT be negotiated with the local media server, unless the join specifies so. The join operation MUST behave as described in <link url='#session-joining'>joining calls</link>.</p>
<p>In this case, the server MUST negotiate media as specified by the join element, in accordance with the rules defined in <link url='#session-joining'>joining calls</link>. Media MUST NOT be negotiated with the local media server, unless the join specifies so. The join operation MUST behave as described in <link url='#session-joining'>joining calls</link>.</p>
</section4>
</section3>
<section3 topic='Inbound Call' anchor='session-establishment-inbound'>
<p>When the system receives a call from one of its connected networks, it MUST then expose that requested session to Rayo clients. It SHOULD use an implementation-specific routing mechanism to map incoming calls to some set of registered JIDs which are considered appropriate controlling parties. From this set, it SHOULD then remove any parties whom it can identify as being temporarily inappropriate for control (either unavailable based on presence, under too much load, or any other metric which the server has available). If, as a result, the set of Potentially Controlling Parties is empty, the server MUST reject the call indicating that the requested service was unavailable.</p>
<p>When the Server receives a call from one of its connected networks, it MUST then expose that requested session to Rayo clients. It SHOULD use an implementation-specific routing mechanism to map incoming calls to some set of registered JIDs which are considered appropriate controlling parties. From this set, it SHOULD then remove any parties whom it can identify as being temporarily inappropriate for control (either unavailable based on presence, under too much load, or any other metric which the server has available). If, as a result, the set of Potentially Controlling Parties is empty, the server MUST reject the call indicating that the requested service was unavailable.</p>
<p>If the server can identify active Potential Controlling Parties, it MUST offer them control of the call simultaneously. The server must broadcast an offer on behalf of the call to all Potential Controlling Parties, using applicable to/from/header data from the incoming session. The server MUST also include entity capabilities information in the presence stanza containing the offer, in order to advertise the fact that the entity is a call, qualified by the node name "urn:xmpp:rayo:call:1".</p>
<p>If the server can identify active Potential Controlling Parties, it MUST offer them control of the call according to its particular distribution method, which MAY be simultaneous or staged. The server must broadcast an offer on behalf of the call to all Potential Controlling Parties, using applicable to/from/header data from the incoming session. The server MUST also include entity capabilities information in the presence stanza containing the offer, in order to advertise the fact that the entity is a call, qualified by the node name "urn:xmpp:rayo:call:1".</p>
<example caption="New call announces itself to a potential controlling party"><![CDATA[
<presence from='9f00061@call.shakespeare.lit'
to='juliet@capulet.lit/balcony'>
@ -622,7 +632,7 @@
</presence>
]]></example>
<p>Once the server has offered control, it MUST wait indefinitely for a response from a PCP. The server SHOULD monitor the availability of PCPs to whom offers have been sent. If they all cease to be PCPs (eg by going offline) then the call should be rejected in the same way as if there had not been any available PCPs to begin with.</p>
<p>Once the server has offered control, it MUST wait for a response from a PCP or for the remote party to end the call. The server SHOULD monitor the availability of PCPs to whom offers have been sent. If they all cease to be PCPs (eg by going offline) then the call should be rejected in the same way as if there had not been any available PCPs to begin with.</p>
<p>If an offered PCP executes a command against the call, by sending a command node to the call's JID inside an IQ 'set', the server should execute the following routine:</p>
<ol>
@ -649,7 +659,7 @@
</section2>
<section2 topic='Joining Calls' anchor='session-joining'>
<p>Calls in a Rayo system are capable of having their media streams moved/manipulated. Once such manipulation is to join the media streams of two calls. In a scenario where callA and callB should be joined, the client MUST send a join command to either call (not both) specifying the call ID of the other call, like so:</p>
<p>Calls on a Rayo Server are capable of having their media streams moved/manipulated. Once such manipulation is to join the media streams of two calls. In a scenario where callA and callB should be joined, the client MUST send a join command to either call (not both) specifying the call ID of the other call, and optionally media attributes (direction and media) specified in the schema, like so:</p>
<example caption="Client instructs callA to join to callB and the server acknowledges the join was completed"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
to='callA@call.shakespeare.lit'
@ -925,7 +935,7 @@
</section2>
<section2 topic='Mixers' anchor='session-mixers'>
<p>While calls may generally be joined peer-to-peer in any desirable combination, such an implementation is not necessarily scalable or practical to manage. Rayo, therefore, includes the concept of mixers, which are entities like calls, to which calls or other mixers may be joined in the same way as joining multiple calls directly. A mixer MUST be implicitly created the first time a call attempts to join it, MUST immediately broadcast presence to all controlling parties who have calls joined to it, and must respond to the join command with a reference to the mixer. The server MUST include entity capabilities information in the first presence stanza it sends, in order to advertise the fact that the entity is a mixer, qualified by the node name "urn:xmpp:rayo:mixer:1". A mixer MUST emit events (joined, unjoined) to all controlling parties who have calls joined to it, using the same semantics as joining calls.</p>
<p>While calls may generally be joined peer-to-peer in any desirable combination, such an implementation is not necessarily scalable or practical to manage. Rayo, therefore, includes the concept of mixers, which are entities like calls, to which calls or other mixers may be joined in the same way as joining multiple calls directly. A mixer MUST be implicitly created the first time a call attempts to join it, MUST immediately broadcast presence to all controlling parties who have calls joined to it, and must respond to the join command with a reference to the mixer. If a mixer cannot be created, an error similar to those specified for &lt;dial/&gt; should be returned in response to the &lt;join/&gt; command. The server MUST include entity capabilities information in the first presence stanza it sends, in order to advertise the fact that the entity is a mixer, qualified by the node name "urn:xmpp:rayo:mixer:1". A mixer MUST emit events (joined, unjoined) to all controlling parties who have calls joined to it, using the same semantics as joining calls.</p>
<p>In order to support friendly-named mixers without causing naming collisions between security zones, a server SHOULD represent a mixer internally using some alternative name scoped to the client's security zone and mapped to the friendly name/URI presented to the client for the emission of events and processing of commands. A server MUST NOT allow clients to interact with mixers allocated within other security zones either by observing their status or media.</p>
@ -963,7 +973,7 @@
</presence>
]]></example>
<p>Mixers MUST respect the normal rules of XMPP presence subscriptions. If a client sends directed presence to a mixer, the mixer MUST implicitly create a presence subscription for the client. On receiving unavailable presence, the mixer MUST stop sending events to the client.</p>
<p>Mixers MUST respect the normal rules of XMPP presence subscriptions, and presence subscriptions from clients within the same security zone as the mixer must be implicitly permitted.</p>
<p>The error conditions on joining a mixer are the same as for calls, as are the unjoin and join modification semantics. Additionally, mixers SHOULD be able to host components just like calls, following the rules defined for each component.</p>
@ -972,7 +982,11 @@
to='myMixer@mixer.shakespeare.lit'
type='set'
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'/>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
Thanks for calling, goodbye!
</document>
</output>
</iq>
<iq from='myMixer@mixer.shakespeare.lit'
@ -1020,7 +1034,11 @@
to='9f00061@call.shakespeare.lit'
type='set'
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'/>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
Thanks for calling, goodbye!
</document>
</output>
</iq>
]]></example>
@ -1054,7 +1072,11 @@
to='juliet@capulet.lit/balcony'
type='error'
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'/>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
Thanks for calling, goodbye!
</document>
</output>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -1095,7 +1117,11 @@
to='juliet@capulet.lit/balcony'
type='error'
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'/>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
Thanks for calling, goodbye!
</document>
</output>
<error type='wait'>
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -1108,7 +1134,11 @@
to='juliet@capulet.lit/balcony'
type='error'
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'/>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
Thanks for calling, goodbye!
</document>
</output>
<error type='wait'>
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -1121,7 +1151,11 @@
to='juliet@capulet.lit/balcony'
type='error'
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'/>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
Thanks for calling, goodbye!
</document>
</output>
<error type='wait'>
<unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -1257,7 +1291,7 @@
]]></example>
<section3 topic='Output Component' anchor='session-component-execution-output'>
<p>Media output is a core concept in Rayo, and is provided by the output component. The component allows media to be rendered to a call or a mixer, using the server's local media server. A server MUST support audio file playback and MUST support the text/uri-list document format. A server MAY support speech synthesis and MAY support SSML. The component is created using an <link url='def-component-output'>&lt;output/&gt; command</link>, containing one or more documents to render, along with a set of options to determine the nature of the rendering.</p>
<p>Media output is a core concept in Rayo, and is provided by the output component. The component allows media to be rendered to a call or a mixer, using the server's local media server. A server MUST support audio file playback and MUST support the text/uri-list document format. A server MAY support speech synthesis and MAY support <link url='http://www.w3.org/TR/speech-synthesis/'>SSML</link> (in which case the document should be escaped or enclosed in CDATA). The component is created using an <link url='def-component-output'>&lt;output/&gt; command</link>, containing one or more documents to render, along with a set of options to determine the nature of the rendering.</p>
<example caption='Client renders a simple SSML document to a call'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
@ -1297,9 +1331,7 @@
id='h7ed2'>
<output xmlns='urn:xmpp:rayo:output:1'>
<document content-type='text/plain'>
<![CDATA[
Thanks for calling, goodbye!
]]]]><![CDATA[>
</document>
</output>
</iq>
@ -1308,7 +1340,7 @@
<p>The server MUST validate that it has apropriate resources/mechanisms to render the requested document before acknowledging the component creation.</p>
<section4 topic='Join considerations' anchor='session-component-exection-output-joins'>
<p>In the case that an output component is executed on a call joined to other calls or mixers, the output SHOULD be rendered only to the call and not the joined parties (also known as 'whisper'). In the case that an output component is executed on a mixer, the output should be rendered into the mixer, such that all participants receive the output (also known as 'announce').</p>
<p>In the case that an output component is executed on a call joined to other calls or mixers, the output MUST be rendered only to the call and not the joined parties (also known as 'whisper'). In the case that an output component is executed on a mixer, the output should be rendered into the mixer, such that all participants receive the output (also known as 'announce').</p>
</section4>
<section4 topic='Commands' anchor='session-component-execution-output-commands'>
@ -1461,7 +1493,7 @@
</section3>
<section3 topic='Input Component' anchor='session-component-execution-input'>
<p>Media input is a core concept in Rayo, and is provided by the input component. The component allows input to be collected from a call by way of either DTMF (dual-tone multi-frequency) or ASR (automatic speech recognition), using the server's local media server. A Rayo server MUST support DTMF input and MUST support SRGS XML grammars (application/srgs+xml). A server MAY suport speech input, and MAY support other grammar formats. The component is created using an <link url='def-component-input'>&lt;input/&gt; command</link>, containing one or more grammar documents by which to control input, along with a set of options to determine the nature of the collection.</p>
<p>Media input is a core concept in Rayo, and is provided by the input component. The component allows input to be collected from a call by way of either <link url='http://www.itu.int/rec/T-REC-Q.23-198811-I/en'>DTMF</link> (dual-tone multi-frequency) or ASR (automatic speech recognition), using the server's local media server. A Rayo server MUST support DTMF input and MUST support <link url='http://www.w3.org/TR/speech-grammar/'>SRGS</link> XML grammars (application/srgs+xml). A server MAY suport speech input, and MAY support other grammar formats. The component is created using an <link url='def-component-input'>&lt;input/&gt; command</link>, containing one or more grammar documents by which to control input, along with a set of options to determine the nature of the collection.</p>
<example caption='Client requests DTMF input collection from a call'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
@ -1514,7 +1546,7 @@
<p>The server MUST validate that it has appropriate resources/mechanisms to collect the requested input before acknowledging the component creation.</p>
<section4 topic='Join considerations' anchor='session-component-exection-input-joins'>
<p>In the case that an input component is executed on a call joined to other calls or mixers, the input SHOULD be collected only from the call and not the joined parties. Input components executed on a mixer SHOULD collect and combine input from all participants joined to the mixer.</p>
<p>In the case that an input component is executed on a call joined to other calls or mixers, the input MUST be collected only from the call and not the joined parties. Input components executed on a mixer MUST collect and combine input from all participants joined to the mixer.</p>
</section4>
<section4 topic='Commands' anchor='session-component-execution-input-commands'>
@ -1661,7 +1693,7 @@
</section3>
<section3 topic='Record Component' anchor='session-component-execution-record'>
<p>Call recording is a core concept in Rayo, and is provided by the record component. The component allows media to be captured from a call or a mixer, using the server's local media server, stored, and made available to clients. The component is created using a <link url='def-component-record'>&lt;record/&gt; command</link>, with a set of options to determine the nature of the recording.</p>
<p>Call recording is a core concept in Rayo, and is provided by the record component. The component allows media to be captured from a call or a mixer, using the server's local media server, stored, and made available to clients. The component is created using a <link url='def-component-record'>&lt;record/&gt; command</link>, potentially with a set of options to determine the nature of the recording.</p>
<example caption='Client requests a simple recording'><![CDATA[
<iq from='juliet@capulet.lit/balcony'
@ -2170,7 +2202,7 @@ Art thou not Romeo, and a Montague?
</tr>
<tr>
<td>timeout</td>
<td>Indicates the maximum time allowed for a response to be provided by the third party before the call should be considered to have come to an end.</td>
<td>Indicates the maximum time allowed for a response to be provided by the remote party before the call should be considered to have come to an end.</td>
<td>OPTIONAL</td>
<td>-1</td>
</tr>
@ -2870,7 +2902,7 @@ Art thou not Romeo, and a Montague?
<p>The &lt;resume/&gt; element has no attributes.</p>
</section4>
<section4 topic='Recording Element' anchor='def-component-input-recording'>
<section4 topic='Recording Element' anchor='def-component-record-recording'>
<p>Provides the result of a recording, as a reference to its location.</p>
<p>The &lt;recording/&gt; element MUST be empty.</p>
<p>The attributes of the &lt;recording/&gt; element are as follows.</p>
@ -2902,19 +2934,19 @@ Art thou not Romeo, and a Montague?
</table>
</section4>
<section4 topic='Max Duration Element' anchor='def-component-input-max-duration'>
<section4 topic='Max Duration Element' anchor='def-component-record-max-duration'>
<p>Indicates that the component came to an end due to the max duration being reached.</p>
<p>The &lt;max-duration/&gt; element MUST be empty.</p>
<p>The &lt;max-duration/&gt; element has no attributes.</p>
</section4>
<section4 topic='Initial Timeout Element' anchor='def-component-input-initial-timeout'>
<section4 topic='Initial Timeout Element' anchor='def-component-record-initial-timeout'>
<p>Indicates that the component came to an end due to no input being detected before the initial-timeout.</p>
<p>The &lt;initial-timeout/&gt; element MUST be empty.</p>
<p>The &lt;initial-timeout/&gt; element has no attributes.</p>
</section4>
<section4 topic='Final Timeout Element' anchor='def-component-input-final-timeout'>
<section4 topic='Final Timeout Element' anchor='def-component-record-final-timeout'>
<p>Indicates that the component came to an end because no input had been detected for the final timeout duration.</p>
<p>The &lt;final-timeout/&gt; element MUST be empty.</p>
<p>The &lt;final-timeout/&gt; element has no attributes.</p>
@ -3316,7 +3348,7 @@ Art thou not Romeo, and a Montague?
<attribute name="timeout" type="tns:timeoutType" use="optional" default="-1">
<annotation>
<documentation>
Indicates the maximum time allowed for a response to be provided by the third party before the call should be considered to have come to an end.
Indicates the maximum time allowed for a response to be provided by the remote party before the call should be considered to have come to an end.
</documentation>
</annotation>
</attribute>