git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@1333 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2007-11-02 21:10:00 +00:00
parent 43a52466e2
commit ce522cb7e4
1 changed files with 616 additions and 164 deletions

View File

@ -26,6 +26,12 @@
&robmcqueen;
&seanegan;
&hildjj;
<revision>
<version>0.18pre1</version>
<date>in progress, last updated 2007-11-02</date>
<initials>psa</initials>
<remark><p>Added scenarios containing more examples.</p></remark>
</revision>
<revision>
<version>0.17</version>
<date>2007-06-20</date>
@ -195,6 +201,104 @@
<p>The purpose of Jingle is not to supplant or replace technologies based on Session Initiation Protocol (SIP; &rfc3261;). Because dual-stack XMPP+SIP clients are difficult to build, Jingle was designed as a pure XMPP signalling protocol. However, Jingle is at the same time designed to interwork with SIP so that the millions of deployed XMPP clients can be added onto existing Voice over Internet Protocol (VoIP) networks, rather than limiting XMPP users to a separate and distinct network.</p>
<p>Jingle is designed in a modular way so that developers can easily add support for multimedia session types other than voice chat, such as video chat (see &xep0180;), application sharing, file sharing, collaborative editing, whiteboarding, and torrent broadcasting. The transport methods are also modular, so that Jingle implementations can use any appropriate media transport (including proprietary methods not standardized through the XMPP Standards Foundation).</p>
</section1>
<section1 topic='How It Works' anchor='howitworks'>
<p>This section provides a friendly introduction to Jingle.</p>
<p>In essence, Jingle enables two XMPP entities (e.g., romeo@montague.lit and juliet@capulet.lit) to set up, manage, and tear down a multimedia session. The negotiation takes place over XMPP, and the media transfer takes place outside of XMPP. The simplest session flow is as follows:</p>
<code><![CDATA[
Romeo Juliet
| |
| session-initiate |
|---------------------------->|
| ack |
|<----------------------------|
| session-accept |
|<----------------------------|
| ack |
|---------------------------->|
| MEDIA SESSION (RTP) |
|<===========================>|
| session-terminate |
|<----------------------------|
| ack |
|---------------------------->|
| |
]]></code>
<p>Naturally, more complex scenarios are possible (indeed, likely).</p>
<p>The simplest flow might happens as follows. The example is that of a voice chat (see <cite>XEP-0167</cite>) initiated by Romeo, where the transport is &xep0177;.</p>
<example caption="Initiator sends session-initiate"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='jingle1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
<payload-type id='96' name='speex' clockrate='16000'/>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='103' name='L16' clockrate='16000' channels='2'/>
<payload-type id='98' name='x-ISAC' clockrate='8000'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0177.html#ns'>
<candidate ip='10.1.1.104' port='13540' generation='0'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<example caption="Receiver sends provisional acceptance"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='accept1'
to='romeo@montague.lit/orchard'
type='result'/>
]]></example>
<example caption="Receiver sends session-accept"><![CDATA[
<iq type='set' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='accept1'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-accept'
initiator='romeo@montague.lit/orchard'
responder='juliet@capulet.lit/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='0' name='PCMU' />
<payload-type id='102' name='iLBC'/>
<payload-type id='4' name='G723'/>
<payload-type id='8' name='PCMA'/>
<payload-type id='13' name='CN'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0177.html#ns'>
<candidate ip='208.245.212.67' port='9876' generation='0'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>If the foregoing payload types and transport candidates can be successfully used, then the parties would begin to exchange media (in this case audio).</p>
<p>The parties may continue the session as long as desired. Either party may terminate the session.</p>
<example caption="Receiver terminates the session"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='term1'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-terminate'
initiator='romeo@montague.lit/orchard'
reason='Sorry, gotta go!'
sid='a73sjjvkla37jfea'/>
</iq>
]]></example>
<p>The other party MUST then acknowledge termination of the session:</p>
<example caption="Initiator Acknowledges Termination"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='term1'
to='juliet@capulet.lit/balcony'
type='result'/>
]]></example>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<p>The protocol defined herein is designed to meet the following requirements:</p>
<ol>
@ -207,8 +311,8 @@
</ol>
<p>This document defines the signalling protocol only. Additional documents specify the following:</p>
<ul>
<li><p>Various content description formats (audio, video, etc.) and, where possible, mapping those types to the Session Description Protocol (SDP; see &rfc4566;); examples include <cite>XEP-0167</cite> and <cite>XEP-0180</cite>.</p></li>
<li><p>Various content transport methods; examples include &xep0176; and &xep0177;.</p></li>
<li><p>Various content description formats (audio, video, etc.) and, where possible, mapping those types to the Session Description Protocol (SDP; see &rfc4566;); examples include <cite>Jingle Audio via RTP</cite> and <cite>Jingle Video via RTP</cite>.</p></li>
<li><p>Various content transport methods; examples include &xep0176; and <cite>Raw UDP Transport</cite>.</p></li>
<li><p>Procedures for mapping the Jingle signalling protocol to existing signalling standards such as the IETF's Session Initiation Protocol (SIP) and the ITU's H.323 protocol (see &h323;); these documents are forthcoming.</p></li>
</ul>
</section1>
@ -314,11 +418,11 @@ PENDING o---------------------+ |
</tr>
<tr>
<td>content-modify</td>
<td>Change an existing content type. The recipient MUST NOT reply to a content-modify action with another content-modify action.</td>
<td>Change an existing content type. The recipient MUST NOT reply to a content-modify action with another content-modify action. <note>If both parties send modify messages at the same time, the modify message from the session initiator MUST trump the modify message from the recipient and the initiator SHOULD return an &unexpected; error to the other party.</note></td>
</tr>
<tr>
<td>content-remove</td>
<td>Remove one or more content types from the session. <note>A client MUST NOT return an error upon receipt of a 'content-remove' action for a content description that is received after a 'content-remove' action has been sent but before the action has been acknowledged by the peer.</note></td>
<td>Remove one or more content types from the session. <note>A client MUST NOT return an error upon receipt of a 'content-remove' action for a content description that is received after a 'content-remove' action has been sent but before the action has been acknowledged by the peer.</note> <note>If the content-remove results in no more content types for the session, the entity that receives the content-remove SHOULD send a session-terminate action to the other party (since a session with no content types is void).</note></td>
</tr>
<tr>
<td>session-accept</td>
@ -344,63 +448,24 @@ PENDING o---------------------+ |
</section2>
</section1>
<section1 topic='Session Flow' anchor='session'>
<p>This section defines the high-level flow of a Jingle session. More detailed descriptions are provided in the <link url='#scenarios'>Scenarios</link> section of this document.</p>
<section2 topic='Resource Determination' anchor='session-resource'>
<p>In order to initiate a Jingle session, the initiator must determine which of the receiver's XMPP resources is best for the desired content description format. There are several possible scenarios:</p>
<ol>
<li><p>If the intended responder shares presence with the initiator (see &xmppim;) and has only one available resource, this task SHOULD be completed using &xep0030; or the presence-based profile of service discovery specified in &xep0115;. <note>Naturally, instead of sending service discovery requests to every contact in a user's roster, it is more efficient to use <cite>Entity Capabilities</cite>, whereby support for Jingle and various Jingle content description formats and content transport methods is determined for a client version in general (rather than on a per-JID basis) and then cached. Refer to <cite>XEP-0115</cite> for details.</note></p></li>
<li><p>If the intended responder shares presence with the initiator and has more than one available resource but only one of the resources supports Jingle and the desired content description format, the initiator SHOULD MUST initiate the Jingle signalling with that resource.</p></li>
<li><p>If the intended responder shares presence with the initiator and has more than one available resource but only one of the resources supports Jingle and the desired content description format, the initiator SHOULD initiate the Jingle signalling with that resource.</p></li>
<li><p>If the intended responder shares presence with the initiator and has more than one available resource but more than one of the resources supports Jingle and the desired content description format, the initiator SHOULD use &xep0168; in order to determine which is the best resource with which to initiate the desired Jingle session.</p></li>
<li><p>If the intended responder does not share presence with the initiator, the initiator SHOULD first send a &xep0155; request to the responder in order to initiate the exchange of XMPP stanzas. The request SHOULD include a RAP routing hint as specified in <cite>XEP-0168</cite> and the &MESSAGE; stanza containing the request SHOULD be of type "headline" so that (typically) it is not stored offline for later delivery.</p></li>
</ol>
</section2>
<section2 topic='Initiation' anchor='protocol-initiate'>
<p>Once the initiator has discovered which of the receiver's XMPP resources is ideal for the desired content description format, it sends a session initiation request to the receiver. This request is an IQ-set containing a &JINGLE; element qualified by the 'http://www.xmpp.org/extensions/xep-0166.html#ns' namespace. The &JINGLE; element MUST possess the 'action', 'initiator', and 'sid' attributes (the latter two uniquely identify the session). For initiation, the 'action' attribute MUST have a value of "session-initiate" and the &JINGLE; element MUST contain one or more &CONTENT; elements, each of which defines a content type to be transferred during the session; each &CONTENT; element in turn contains one &DESCRIPTION; child element that specifies a desired content description format and one &TRANSPORT; child element that specifies a potential content transport method. If either party wishes to propose the use of multiple transport methods for the same content description, it must send multiple &CONTENT; elements.</p>
<p>The following example shows a Jingle session initiation request for a session that contains both audio and video content:</p>
<example caption="Initiation Example"><![CDATA[
<iq from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony' id='jingle1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-initiate'
initiator='romeo@montague.net/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
...
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'/>
</content>
<content creator='initiator' name='this-is-the-video-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'>
...
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'/>
</content>
</jingle>
</iq>
]]></example>
<p>Note: The syntax and semantics of the &DESCRIPTION; and &TRANSPORT; elements are out of scope for this specification, but are defined in related specifications.</p>
<p>The attributes of the &JINGLE; element are as follows:</p>
<ul>
<li>The 'action' attribute is REQUIRED; it specifies a Jingle action as listed in this document (e.g., "session-initiate").</li>
<li>The 'initiator' attribute is the full JID of the entity that has initiated the session flow (which may be different from the 'from' address on the IQ-set).</li>
<li>The OPTIONAL 'reasoncode' attribute specifies a machine-readable purpose for the action being sent (e.g., "connectivity-error" for a session-terminate action).</li>
<li>The OPTIONAL 'reasontext' attribute specifies a human-readable purpose for the action being sent (e.g., "Sorry, gotta go!" for a session-terminate action).</li>
<li>The 'responder' attribute (see examples below) is the full JID of the entity that has replied to the initiation (which may be different from the 'to' address on the IQ-set).</li>
<li>The 'sid' attribute is a random session identifier generated by the initiator; this SHOULD match the XML Nmtoken production <note>See &lt;<link url='http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken'>http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken</link>&gt;</note> so that XML character escaping is not needed for characters such as &amp;. (Note: the 'sid' attribute effectively maps to the SIP "Call-ID" parameter.)</li>
</ul>
<p>The attributes of the &CONTENT; element are as follows:</p>
<ul>
<li>The 'creator' attribute is REQUIRED; it specifies which party originally generated the content description (used to prevent race conditions regarding modifications).</li>
<li>The 'name' attribute is REQUIRED; it specifies a unique name or identifier for the content type (this identifier is opaque and does not have semantic meaning).</li>
<li>The 'profile' attribute is RECOMMENDED; for some content types, it specifies the profile in use (e.g., "RTP/AVP" in the context of the Real-time Transport Protocol).</li>
<li>The 'senders' attribute is RECOMMENDED; it specifies which entities in the session will be generating content; the allowable values are "initiator", "recipient", or "both" (where "both" is the default).</li>
</ul>
<p>Once the initiator has discovered which of the receiver's XMPP resources is ideal for the desired content description format, it sends a session initiation request to the receiver. This request is an IQ-set containing a &JINGLE; element qualified by the 'http://www.xmpp.org/extensions/xep-0166.html#ns' namespace &NSNOTE;, where the value of the 'action' attribute is "session-initiate" and where the &JINGLE; element contains one or more &CONTENT; elements. Each &CONTENT; element defines a content type to be transferred during the session, and each &CONTENT; element in turn contains one &DESCRIPTION; child element that specifies a desired content description format and one &TRANSPORT; child element that specifies a potential content transport method. If either party wishes to propose the use of multiple transport methods for the same content description, it must send multiple &CONTENT; elements.</p>
<p>Note: The syntax and semantics of the &DESCRIPTION; and &TRANSPORT; elements are out of scope for this specification, since they are defined in related specifications. The syntax and semantics of the &JINGLE; and &CONTENT; elements are specified in this document under <link url='#def'>Formal Definition</link>.</p>
<p>Note: In order to expedite session establishment, the initiator MAY send transport candidates (e.g., for negotiation of the ICE transport) immediately after sending the "session-initiate" message and before receiving acknowledgement from the receiver (i.e., the initiator MUST consider the session to be live even before receiving acknowledgement). Given in-order delivery, the receiver should receive such "transport-info" messages after receiving the "session-initiate" message (if not, it is appropriate for the receiver to return &lt;unknown-session/&gt; errors since it according to its state machine the session does not exist).</p>
</section2>
<section2 topic='Receiver Response' anchor='protocol-response'>
<p>Unless an error occurs, the receiver MUST acknowledge receipt of the initiation request:</p>
<example caption="Receiver Acknowledges Receipt of Initiation Request"><![CDATA[
<iq type='result' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'/>
]]></example>
<p>Unless an error occurs, the receiver MUST acknowledge receipt of the initiation request.</p>
<p>If the receiver acknowledges receipt of the initation request, both parties must consider the session to be in the PENDING state.</p>
<p>There are several reasons why the receiver might return an error instead of acknowledging receipt of the initiation request:</p>
<ul>
@ -413,7 +478,7 @@ PENDING o---------------------+ |
</ul>
<p>If the initiator is unknown to the receiver (e.g., via presence subscription) and the receiver has a policy of not communicating via Jingle with unknown entities, it SHOULD return a &unavailable; error.</p>
<example caption="Initiator Unknown to Receiver"><![CDATA[
<iq type='error' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'>
<iq type='error' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'>
<error type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -421,15 +486,15 @@ PENDING o---------------------+ |
]]></example>
<p>If the receiver wishes to redirect to another address, it SHOULD return a &redirect; error.</p>
<example caption="Receiver Redirection"><![CDATA[
<iq type='error' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'>
<iq type='error' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'>
<error type='cancel'>
<redirect xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>xmpp:voicemail@capulet.com</redirect>
<redirect xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>xmpp:voicemail@capulet.lit</redirect>
</error>
</iq>
]]></example>
<p>If the receiver does not support Jingle, it MUST return a &unavailable; error.</p>
<example caption="Receiver Does Not Support Jingle"><![CDATA[
<iq type='error' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'>
<iq type='error' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'>
<error type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -437,7 +502,7 @@ PENDING o---------------------+ |
]]></example>
<p>If the receiver does not support any of the specified content description formats, it MUST return a &feature; error with a Jingle-specific error condition of &lt;unsupported-content/&gt;.</p>
<example caption="Receiver Does Not Support Any Content Description Formats"><![CDATA[
<iq type='error' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'>
<iq type='error' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unsupported-content xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns-errors'/>
@ -446,7 +511,7 @@ PENDING o---------------------+ |
]]></example>
<p>If the receiver does not support any of the specified content transport methods, it MUST return a &feature; error with a Jingle-specific error condition of &lt;unsupported-transports/&gt;.</p>
<example caption="Receiver Does Not Support Any Transport Methods"><![CDATA[
<iq type='error' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'>
<iq type='error' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unsupported-transports xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns-errors'/>
@ -455,7 +520,7 @@ PENDING o---------------------+ |
]]></example>
<p>If the initiation request was malformed, the receiver MUST return a &badrequest; error.</p>
<example caption="Initiation Request Malformed"><![CDATA[
<iq type='error' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='jingle1'>
<iq type='error' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'>
<error type='cancel'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -466,118 +531,27 @@ PENDING o---------------------+ |
<p>In order to decline the session initiation request, the receiver MUST acknowledge receipt of the session initiation request, then terminate the session as described under <link url='#session-terminate'>Termination</link>.</p>
</section2>
<section2 topic='Negotiation' anchor='session-negotiation'>
<p>In general, negotiation will be necessary before the parties can agree on an acceptable set of content types, content description formats, and content transport methods. The potential combinations of parameters to be negotiated are many, and not all are shown herein (some are shown in the relevant specifications for various content description formats and content transport methods).</p>
<p>One session-level negotiation is to <em>remove</em> a content types. For example, let us imagine that Juliet is having a bad hair day. She certainly does not want to include video in her Jingle session with Romeo, so she sends a "content-remove" request to Romeo:</p>
<example caption="Content Type Removal"><![CDATA[
<iq from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='reduce1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-remove'
initiator='romeo@montague.net/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-video-content'/>
</jingle>
</iq>
]]></example>
<p>The entity receiving the session reduction request then acknowledges the request:</p>
<example caption="Acknowledgement"><![CDATA[
<iq from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony' id='reduce1' type='result'/>
]]></example>
<p>If the reduction results in no more content types for the session, the entity that receives the session-reduce SHOULD send a session-terminate action to the other party (since a session with no content types is void).</p>
<p>Another session-level negotiation is to <em>add</em> a content type; however, this MUST NOT be done while the session is in the PENDING state and is allowed only while the session is in the ACTIVE state.</p>
<p>In general, negotiation will be necessary before the parties can agree on an acceptable set of content types, content description formats, and content transport methods. The potential combinations of parameters to be negotiated are many, and not all are shown herein. Some are defined in the relevant specifications for various content description formats and content transport methods, and illustrated in the <link url='#scenarios'>Scenarios</link> section of this document.</p>
<p>The allowable negotiations (including content-level and transport-level negotiations) are as follows:</p>
<ul>
<li>Adding a content type via the content-add action (not allowed in the PENDING state).</li>
<li>Modifying a content type via the content-modify action.</li>
<li>Removing a content type via the content-remove action.</li>
<li>Exchanging transport methods via the transport-info action.</li>
</ul>
</section2>
<section2 topic='Acceptance' anchor='session-acceptance'>
<p>If (after negotiation of content transport methods and content description formats) the receiver determines that it will be able to establish a connection, it sends a definitive acceptance to the initiator:</p>
<example caption="Receiver Definitively Accepts the Call"><![CDATA[
<iq type='set' from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='accept1'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-accept'
initiator='romeo@montague.net/orchard'
responder='juliet@capulet.com/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
...
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0177.html#ns'>
<candidate .../>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>The &JINGLE; element in the accept stanza MUST contain one or more &lt;content/&gt; elements, each of which MUST contain one &lt;description/&gt; element and one &lt;transport/&gt; element. The &JINGLE; element SHOULD possess a 'responder' attribute that explicitly specifies the full JID of the responding entity, and the initiator SHOULD send all future commmunications about this Jingle session to the JID provided in the 'responder' attribute.</p>
<p>The initiator then acknowledges the receiver's definitive acceptance:</p>
<example caption="Initiator Acknowledges Definitive Acceptance"><![CDATA[
<iq type='result' to='juliet@capulet.com/balcony' from='romeo@montague.net/orchard' id='accept1'/>
]]></example>
<p>Now the initiator and receiver can begin sending content over the negotiated connection.</p>
<p>If (after negotiation of content transport methods and content description formats) the receiver determines that it will be able to establish a connection, it sends a definitive acceptance to the initiator.</p>
<p>Note: In the accept stanza, the &JINGLE; element MUST contain one or more &lt;content/&gt; elements, each of which MUST contain one &lt;description/&gt; element and one &lt;transport/&gt; element. The &JINGLE; element SHOULD possess a 'responder' attribute that explicitly specifies the full JID of the responding entity, and the initiator SHOULD send all future commmunications about this Jingle session to the JID provided in the 'responder' attribute.</p>
<p>The initiator then acknowledges the receiver's definitive acceptance, after which the parties can exchange content over the negotiated connection.</p>
<p>If one of the parties cannot find a suitable content transport method, it SHOULD terminate the session as described below.</p>
</section2>
<section2 topic='Modifying an Active Session' anchor='session-modify'>
<p>In order to modify an active session, either party may send a "content-remove", "content-add", "content-modify", "description-modify", or "transport-modify" action to the other party. The receiving party then sends an appropriate "-accept" or "-decline" action, and may first send an appropriate "-info" action.</p>
<p>If both parties send modify messages at the same time, the modify message from the session initiator MUST trump the modify message from the recipient and the initiator SHOULD return an &unexpected; error to the other party.</p>
<p>One example of modifying an active session is to <em>add</em> a content type. For example, let us imagine that Juliet gets her hair in order and now wants to add video. She now sends a "content-add" request to Romeo:</p>
<example caption="Adding a Content Type"><![CDATA[
<iq from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='add1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-add'
initiator='romeo@montague.net/orchard'
sid='a73sjjvkla37jfea'>
<content creator='responder' name='video-is-back'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'>
...
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0177.html#ns'>
<candidate .../>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>The entity receiving the session extension request then acknowledges the request and, if it is acceptable, returns a content-accept:</p>
<example caption="Acknowledgement"><![CDATA[
<iq from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony' id='add1' type='result'/>
]]></example>
<example caption="Content Acceptance"><![CDATA[
<iq from='romeo@montague.net/orchard' to='juliet@capulet.com/balcony' id='add2' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-accept'
initiator='romeo@montague.net/orchard'
sid='a73sjjvkla37jfea'>
<content creator='responder' name='video-is-back'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'>
...
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0177.html#ns'>
<candidate .../>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>The other party then acknowledges the acceptance.</p>
<example caption="Acknowledgement"><![CDATA[
<iq from='juliet@capulet.com/balcony' to='romeo@montague.net/orchard' id='add2' type='result'/>
]]></example>
<p>Once a session is in the ACTIVE state, it may be modified. Potential modifications are shown in the <link url='#scenarios'>Scenarios</link> section of this document.</p>
</section2>
<section2 topic='Termination' anchor='session-terminate'>
<p>In order to gracefully end the session (which MAY be done at any point after acknowledging receipt of the initiation request, including immediately thereafter in order to decline the request), either the receiver or the initiator MUST a send a "terminate" action to the other party:</p>
<example caption="Receiver Terminates the Session"><![CDATA[
<iq from='juliet@capulet.com/balcony'
id='term1'
to='romeo@montague.net/orchard'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-terminate'
initiator='romeo@montague.net/orchard'
reason='Sorry, gotta go!'
sid='a73sjjvkla37jfea'/>
</iq>
]]></example>
<p>In order to gracefully end the session (which MAY be done at any point after acknowledging receipt of the initiation request, including immediately thereafter in order to decline the request), either the receiver or the initiator MUST a send a "terminate" action to the other party.</p>
<p>The other party (in this case the initiator) MUST then acknowledge termination of the session:</p>
<example caption="Initiator Acknowledges Termination"><![CDATA[
<iq type='result' to='juliet@capulet.com/balcony' from='romeo@montague.net/orchard' id='term1'/>
]]></example>
<p>Note: As soon as an entity sends a "session-terminate" action, it MUST consider the session to be ended (even before receiving acknowledgement from the other party). If the terminating entity receives additional IQ-sets from the other party after sending the "session-terminate" action, it MUST reply with an &lt;unknown-session/&gt; error.</p>
<p>Unfortunately, not all sessions end gracefully. In applications of Jingle that also involve the exchange of presence information, receipt of &UNAVAILABLE; from the other party MAY be a considered session-ending event. However, in this case there is nothing for the party to acknowledge.</p>
</section2>
@ -585,6 +559,484 @@ PENDING o---------------------+ |
<p>At any point after initiation of a Jingle session, either entity MAY send an informational message to the other party, for example to change a content transport method or content description format parameter, inform the other party that a session initiation request is queued, that a device is ringing, or that a scheduled event has occurred or will occur.</p>
<p>An informational message MUST be an IQ-set containing a &JINGLE; element whose 'action' attribute is set to a value of "session-info" or "transport-info"; the &JINGLE; element MUST further contain a payload child element (specific to the session or to a transport method) that specifies the information being communicated. If the party that receives an informational message does not understand the payload, it MUST return a &feature; error with a Jingle-specific error condition of &lt;unsupported-info/&gt;.</p>
<p>If either party receives an empty "session-info" message for an active session, it MUST send an empty IQ result; this way, an empty "session-info" message may be used as a "ping" to determine session vitality.</p>
<p>Most informational messages are specific to a particular description format or transport method and therefore are described in specifications other than this one.</p>
</section2>
</section1>
<section1 topic='Scenarios' anchor='scenarios'>
<p>The very simple scenario described in the <link url='#howitworks'>How It Works</link> section of this document is just that: very simple. Typically, the session flow is more complex. The following sections show some more complex scenarios, in order of complexity.</p>
<section2 topic='Jingle Audio via RTP, Negotiated with ICE-UDP' anchor='scenarios-voicechat'>
<p>In this scenario, Romeo initiates a voice chat with Juliet using a transport method of ICE-UDP.</p>
<p>The session flow is as follows:</p>
<code><![CDATA[
Romeo Juliet
| |
| session-initiate |
|---------------------------->|
| ack |
|<----------------------------|
| transport-info (X times) |
| (with acks) |
|<--------------------------->|
| session-accept |
|<----------------------------|
| ack |
|---------------------------->|
| AUDIO (RTP) |
|<===========================>|
| session-terminate |
|<----------------------------|
| ack |
|---------------------------->|
| |
]]></code>
<p>The protocol flow is as follows.</p>
<example caption="Initiator sends session-initiate"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='jingle1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
<payload-type id='96' name='speex' clockrate='16000'/>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='103' name='L16' clockrate='16000' channels='2'/>
<payload-type id='98' name='x-ISAC' clockrate='8000'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns-udp'/>
</content>
</jingle>
</iq>
]]></example>
<example caption="Receiver sends provisional acceptance"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='accept1'
to='romeo@montague.lit/orchard'
type='result'/>
]]></example>
<example caption="Initiator Sends a Candidate"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='info1'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='transport-info'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns-udp'>
<candidate component='1'
foundation='1'
generation='0'
ip='10.0.1.1'
network='0'
port='8998'
priority='2114978302'
protocol='udp'
pwd='asd88fgpdd777uzjYhagZg'
type='host'
ufrag='8hhy'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<example caption="Initiator Sends a Second Candidate"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='info2'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='transport-info'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns-udp'>
<candidate component='1'
foundation='1'
generation='0'
ip='192.0.2.3'
network='1'
port='45664'
priority='1678246398'
protocol='udp'
pwd='asd88fgpdd777uzjYhagZg'
type='srflx'
ufrag='8hhy'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<example caption="Initiator Sends a Third Candidate"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='info3'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='transport-info'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns-udp'>
<candidate component='1'
foundation='1'
generation='0'
ip='208.245.212.67'
network='2'
port='53267'
priority='1677984254'
protocol='udp'
pwd='asd88fgpdd777uzjYhagZg'
type='srflx'
ufrag='8hhy'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>For each candidate received, the other party MUST acknowledge receipt or return an error:</p>
<example caption="Responder Acknowledges Receipt"><![CDATA[
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='info1' type='result'/>
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='info2' type='result'/>
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='info3' type='result'/>
]]></example>
<p>At the same time (i.e., immediately after provisionally accepting the session, not waiting for the initiator to begin or finish sending candidates), the responder also begins sending candidates that may work for it. As above, the initiator acknowledges receipt of the candidates.</p>
<p>As the initiator and responder receive candidates, they probe the various candidate transports for connectivity. In performing these connectivity checks, the parties follow the procedure specified in Section 7 of draft-ietf-mmusic-ice.</p>
<p>If one of the candidate transports is found to work, the receiver accepts the session.</p>
<example caption="Receiver sends session-accept"><![CDATA[
<iq type='set' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='accept1'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-accept'
initiator='romeo@montague.lit/orchard'
responder='juliet@capulet.lit/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='0' name='PCMU' />
<payload-type id='102' name='iLBC'/>
<payload-type id='4' name='G723'/>
<payload-type id='8' name='PCMA'/>
<payload-type id='13' name='CN'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'>
<candidate ip='208.245.212.67' port='9876' generation='0'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>If the payload types and transport candidate can be successfully used by both parties, then the initiator acknowledges the session-accept and the parties begin to exchange media (in this case audio).</p>
<example caption="Initiator acknowledges session-accept"><![CDATA[
<iq type='result' to='juliet@capulet.lit/balcony' from='romeo@montague.lit/orchard' id='accept1'/>
]]></example>
<p>The parties may continue the session as long as desired. Either party may terminate the session.</p>
<example caption="Receiver terminates the session"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='term1'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-terminate'
initiator='romeo@montague.lit/orchard'
reason='Sorry, gotta go!'
sid='a73sjjvkla37jfea'/>
</iq>
]]></example>
<p>The other party MUST then acknowledge termination of the session:</p>
<example caption="Initiator Acknowledges Termination"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='term1'
to='juliet@capulet.lit/balcony'
type='result'/>
]]></example>
</section2>
<section2 topic='Jingle Audio and Video via RTP, Negotiated with ICE-UDP' anchor='scenarios-voicechat'>
<p>In this scenario, Romeo initiates a combined audio and video chat with Juliet using a transport method of ICE. Juliet at first refuses the video portion, then later offers to add video, which Romeo accepts.</p>
<p>The session flow is as follows:</p>
<code><![CDATA[
Romeo Juliet
| |
| session-initiate |
|---------------------------->|
| ack |
|<----------------------------|
| content-remove |
|<----------------------------|
| ack |
|---------------------------->|
| content-accept |
|---------------------------->|
| ack |
|<----------------------------|
| transport-info (X times) |
| (with acks) |
|<--------------------------->|
| session-accept |
|<----------------------------|
| ack |
|---------------------------->|
| AUDIO (RTP) |
|<===========================>|
| content-add |
|<----------------------------|
| ack |
|---------------------------->|
| content-accept |
|---------------------------->|
| ack |
|<----------------------------|
| AUDIO + VIDEO (RTP) |
|<===========================>|
| session-terminate |
|<----------------------------|
| ack |
|---------------------------->|
| |
]]></code>
<p>The protocol flow is as follows.</p>
<example caption="Initiation"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='jingle1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
<payload-type id='96' name='speex' clockrate='16000'/>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='103' name='L16' clockrate='16000' channels='2'/>
<payload-type id='98' name='x-ISAC' clockrate='8000'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'/>
</content>
<content creator='initiator' name='this-is-the-video-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'>
<payload-type id='96' name='theora' clockrate='90000' height='720' width='1280'>
<parameter name='delivery-method' value='inline'/>
<parameter name='configuration' value='somebase16string'/>
<parameter name='sampling' value='YCbCr-4:2:2'/>
</payload-type>
<payload-type id='28' name='nv' clockrate='90000'/>
<payload-type id='25' name='CelB' clockrate='90000'/>
<payload-type id='32' name='MPV' clockrate='90000'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'/>
</content>
</jingle>
</iq>
]]></example>
<example caption="Receiver Acknowledges Receipt of Initiation Request"><![CDATA[
<iq type='result' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='jingle1'/>
]]></example>
<p>However, Juliet doesn't want to do video because she is having a bad hair day, so she sends a "content-remove" request to Romeo.</p>
<example caption="Receiver request content-remove"><![CDATA[
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='remove1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-remove'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-video-content'/>
</jingle>
</iq>
]]></example>
<p>Romeo then acknowledges the content-remove request and, if it is acceptable, returns a content-accept:</p>
<example caption="Initiator acknowledges content-remove"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='remove1' type='result'/>
]]></example>
<example caption="Initiator accepts content definition"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='remove2' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-accept'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='responder' name='this-is-the-video-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'/>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'/>
</content>
</jingle>
</iq>
]]></example>
<p>The other party then acknowledges the acceptance.</p>
<example caption="Receiver acknowledges content-accept"><![CDATA[
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='remove2' type='result'/>
]]></example>
<p>As in Scenario #1, the parties exchange ICE candidates (see above for examples).</p>
<p>Once the parties find candidate transports that work, the receiver accepts the session.</p>
<example caption="Receiver sends session-accept"><![CDATA[
<iq type='set' from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='accept1'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-accept'
initiator='romeo@montague.lit/orchard'
responder='juliet@capulet.lit/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-the-audio-content'>
<description xmlns='http://www.xmpp.org/extensions/xep-0167.html#ns'>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='0' name='PCMU' />
<payload-type id='102' name='iLBC'/>
<payload-type id='4' name='G723'/>
<payload-type id='8' name='PCMA'/>
<payload-type id='13' name='CN'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'>
<candidate ip='208.245.212.67' port='9876' generation='0'/>
</transport>
</content>
</jingle>
</iq>
]]></example>
<p>As above, if the payload types and transport candidate can be successfully used by both parties, then the initiator acknowledges the session-accept and the parties begin to exchange media (in this case audio).</p>
<example caption="Initiator acknowledges session-accept"><![CDATA[
<iq type='result' to='juliet@capulet.lit/balcony' from='romeo@montague.lit/orchard' id='accept1'/>
]]></example>
<p>Once Juliet gets her hair in order, she decides that she is presentable for a video chat so she sends a content-add request to Romeo.</p>
<example caption="Receiver sends a content-add"><![CDATA[
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='add1' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-add'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='responder' name='video-is-back'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'>
<payload-type id='96' name='theora' height='720' width='1280'>
<parameter name='delivery-method' value='inline'/>
<parameter name='configuration' value='somebase16string'/>
<parameter name='sampling' value='YCbCr-4:2:2'/>
</payload-type>
<payload-type id='32' name='MPV' clockrate='90000'/>
<payload-type id='33' name='MP2T' clockrate='90000'/>
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'>
</content>
</jingle>
</iq>
]]></example>
<p>The entity receiving the content-add request then acknowledges the request and, if it is acceptable, returns a content-accept:</p>
<example caption="Initiator acknowledges content-add"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='add1' type='result'/>
]]></example>
<example caption="Initiator accepts content definition"><![CDATA[
<iq from='romeo@montague.lit/orchard' to='juliet@capulet.lit/balcony' id='add2' type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='content-accept'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='responder' name='video-is-back'>
<description xmlns='http://www.xmpp.org/extensions/xep-0180.html#ns'>
...
</description>
<transport xmlns='http://www.xmpp.org/extensions/xep-0176.html#ns'/>
</content>
</jingle>
</iq>
]]></example>
<p>The other party then acknowledges the acceptance.</p>
<example caption="Receiver acknowledges content-accept"><![CDATA[
<iq from='juliet@capulet.lit/balcony' to='romeo@montague.lit/orchard' id='add2' type='result'/>
]]></example>
<p>The media session proceeds, this time with both audio and video.</p>
<p>Eventually, one of the parties terminates the session.</p>
<example caption="Initiator sends session-terminate"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='term1'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='http://www.xmpp.org/extensions/xep-0166.html#ns'
action='session-terminate'
initiator='romeo@montague.lit/orchard'
reason='I&apos;m outta here!'
sid='a73sjjvkla37jfea'/>
</iq>
]]></example>
<example caption="Receiver acknowledges session-terminate"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='term1'
to='romeo@montague.lit/orchard'
type='result'/>
]]></example>
</section2>
</section1>
<section1 topic='Formal Definition' anchor='def'>
<section2 topic='Jingle Element' anchor='def-jingle'>
<p>The &JINGLE; element MAY be empty or contain one or more &CONTENT; elements (for which see <link url='#def-content'>Content Element</link>).</p>
<p>The attributes of the &JINGLE; element are as follows.</p>
<table caption='Attributes of Jingle Element'>
<tr>
<th>Attribute</th>
<th>Definition</th>
<th>Inclusion</th>
</tr>
<tr>
<td>action</td>
<td>A Jingle action as listed in this document (e.g., "session-terminate").</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>initiator</td>
<td>The full JID of the entity that has initiated the session flow (which may be different from the 'from' address on the IQ-set).</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>reasoncode</td>
<td>A machine-readable purpose for the action being sent (e.g., "connectivity-error" for a session-terminate action).</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>reasontext</td>
<td>A human-readable purpose for the action being sent (e.g., "Sorry, gotta go!" for a session-terminate action).</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>responder</td>
<td>The full JID of the entity that has replied to the initiation, which may be different from the 'to' address on the IQ-set.</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>sid</td>
<td>A random session identifier generated by the initiator, which effectively maps to the SIP "Call-ID" parameter; this SHOULD match the XML Nmtoken production <note>See &lt;<link url='http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken'>http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken</link>&gt;</note> so that XML character escaping is not needed for characters such as &amp;.</td>
<td>REQUIRED</td>
</tr>
</table>
</section2>
<section2 topic='Content Element' anchor='def-content'>
<p>The attributes of the &CONTENT; element are as follows:</p>
<table caption='Attributes of Content Element'>
<tr>
<th>Attribute</th>
<th>Definition</th>
<th>Inclusion</th>
</tr>
<tr>
<td>creator</td>
<td>Which party originally generated the content description (used to prevent race conditions regarding modifications).</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>name</td>
<td>A unique name or identifier for the content type (this identifier is opaque and does not have semantic meaning).</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>profile</td>
<td>The profile in use (e.g., "RTP/AVP" in the context of the Real-time Transport Protocol).</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>senders</td>
<td>which entities in the session will be generating content; the allowable values are "initiator", "recipient", or "both" (where "both" is the default).</td>
<td>RECOMMENDED</td>
</tr>
</table>
</section2>
</section1>
@ -627,17 +1079,17 @@ PENDING o---------------------+ |
<section1 topic='Determining Support' anchor='support'>
<p>If an entity supports Jingle, it MUST advertise that fact by returning a feature of "http://www.xmpp.org/extensions/xep-0166.html#ns" &NSNOTE; in response to &xep0030; information requests.</p>
<example caption="Service Discovery Information Request"><![CDATA[
<iq from='romeo@montague.net/orchard'
<iq from='romeo@montague.lit/orchard'
id='disco1'
to='juliet@capulet.com/balcony'
to='juliet@capulet.lit/balcony'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<example caption="Service Discovery Information Response"><![CDATA[
<iq from='juliet@capulet.com/balcony'
<iq from='juliet@capulet.lit/balcony'
id='disco1'
to='romeo@montague.net/orchard'
to='romeo@montague.lit/orchard'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
...