<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
  <!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
  <title>Jingle SDP Content</title>
  <abstract>This specification defines a Jingle application type for transport the Session Description Protocol (SDP) over Jingle.</abstract>
  &LEGALNOTICE;
  <number>xxxx</number>
  <status>ProtoXEP</status>
  <type>Standards Track</type>
  <sig>Standards</sig>
  <approver>Council</approver>
  <dependencies>
    <spec>XMPP Core</spec>
    <spec>XEP-0166</spec>
    <spec>XEP-0176</spec>
    <spec>XEP-0320</spec>
    <spec>RFC 4566</spec>
  </dependencies>
  <supersedes/>
  <supersededby/>
  <shortname>jingle-sdp</shortname>
  &fippo;
  <revision>
    <version>0.0.1</version>
    <date>2013-09-05</date>
    <initials>ph</initials>
    <remark><p>First draft.</p></remark>
  </revision>
</header>
<section1 topic='Introduction' anchor='intro'>
  <p>The IETFs RTCWEB working group has decided to use &rfc4566; as the API surface for WebRTC. For XMPP this opened up a number of questions about the future of Jingle, XMPPs native signalling protocol, since Jingle does not use SDP. Various proposals have been made, including mappingSDP to Jingle and vice versa over to a dumb transport of SDP (called SoX) inside &lt;message/&gt; stanzas. This document proposes a way to transport SDP over Jingle which respects the established session model of Jingle.</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
  <ol>
    <li>MUST use the Jingle session model defined in XEP-0166.</li>
    <li>MUST be able to transport a WebRTC SDP in a lossless way.</li>
    <li>MUST retain the separation of transport.</li>
    <li>MUST use one &lt;content&gt; element per m-line.</li>
  </ol>
</section1>
<section1 topic='Protocol' anchor='proto'>
  <p>Take the following SDP offer</p>
  <example caption='Offer SDP'><![CDATA[
v=0
o=- 8065558698633182641 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:6dCka9VISByPAFOH
a=ice-pwd:k9ct1Zmco8RPW9C147atRl2X
a=ice-options:google-ice
a=fingerprint:sha-256 7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:107 CN/48000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:126 telephone-event/8000
a=maxptime:60
a=ssrc:3176601530 cname:GD84ngCycPaY3cQx
a=ssrc:3176601530 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCla0
a=ssrc:3176601530 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
a=ssrc:3176601530 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCla0
m=video 1 RTP/SAVPF 100 116 117
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:6dCka9VISByPAFOH
a=ice-pwd:k9ct1Zmco8RPW9C147atRl2X
a=ice-options:google-ice
a=fingerprint:sha-256 7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=sendrecv
a=mid:video
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 goog-remb
a=rtpmap:116 red/90000
a=rtpmap:117 ulpfec/90000
a=ssrc:2358488720 cname:GD84ngCycPaY3cQx
a=ssrc:2358488720 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
a=ssrc:2358488720 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
a=ssrc:2358488720 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
]]></example>
  <p>This SDP consists of a session level section and has two media description. It can easily be transformed to the following session-initiate by splitting it at "\r\nm=":</p>
  <example caption='Initiation'><![CDATA[
<iq from='romeo@montague.lit/orchard'
    id='ih28sx61'
    to='juliet@capulet.lit/balcony'
    type='set'>
  <jingle xmlns='urn:xmpp:jingle:1'
          action='session-initiate'
          initiator='romeo@montague.lit/orchard'
          sid='a73sjjvkla37jfea'>
    <session xmlns='urn:xmpp:jingle:apps:sdp'>
      v=0
      o=- 8065558698633182641 2 IN IP4 127.0.0.1
      s=-
      t=0 0
      a=group:BUNDLE audio video
      a=msid-semantic: WMS QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
    </session>
    <content creator='initiator' name='audio'>
      <description xmlns='urn:xmpp:jingle:apps:sdp'>
        m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
        c=IN IP4 0.0.0.0
        a=rtcp:1 IN IP4 0.0.0.0
        a=ice-options:google-ice
        a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
        a=sendrecv
        a=mid:audio
        a=rtcp-mux
        a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
        a=rtpmap:111 opus/48000/2
        a=fmtp:111 minptime=10
        a=rtpmap:103 ISAC/16000
        a=rtpmap:104 ISAC/32000
        a=rtpmap:0 PCMU/8000
        a=rtpmap:8 PCMA/8000
        a=rtpmap:107 CN/48000
        a=rtpmap:106 CN/32000
        a=rtpmap:105 CN/16000
        a=rtpmap:13 CN/8000
        a=rtpmap:126 telephone-event/8000
        a=maxptime:60
        a=ssrc:3176601530 cname:GD84ngCycPaY3cQx
        a=ssrc:3176601530 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCla0
        a=ssrc:3176601530 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
        a=ssrc:3176601530 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCla0
      </description>
      <transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
                 ufrag='6dCka9VISByPAFOH'
                 pwd='k9ct1Zmco8RPW9C147atRl2X'>
        <fingerprint xmlns='urn:xmpp:tmp:jingle:apps:dtls:0' hash='sha-256'>
          7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
        </fingerprint>
      </transport>
    </content>
    <content creator='initiator' name='video'>
      <description xmlns='urn:xmpp:jingle:apps:sdp'>
        m=video 1 RTP/SAVPF 100 116 117
        c=IN IP4 0.0.0.0
        a=rtcp:1 IN IP4 0.0.0.0
        a=ice-options:google-ice
        a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
        a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
        a=sendrecv
        a=mid:video
        a=rtcp-mux
        a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
        a=rtpmap:100 VP8/90000
        a=rtcp-fb:100 ccm fir
        a=rtcp-fb:100 nack
        a=rtcp-fb:100 goog-remb
        a=rtpmap:116 red/90000
        a=rtpmap:117 ulpfec/90000
        a=ssrc:2358488720 cname:GD84ngCycPaY3cQx
        a=ssrc:2358488720 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
        a=ssrc:2358488720 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
        a=ssrc:2358488720 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
      </description>
      <transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
                 ufrag='6dCka9VISByPAFOH'
                 pwd='k9ct1Zmco8RPW9C147atRl2X'>
        <fingerprint xmlns='urn:xmpp:tmp:jingle:apps:dtls:0' hash='sha-256'>
          7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
        </fingerprint>
      </transport>
    </content>
  </jingle>
</iq>
]]></example>
  <p>Note that the a=ice-ufrag, a=ice-pwd and a=fingerprint lines are removed from the SDP (either in session level or all of the mediadescriptions) and put into the transport element. The same rule applies to any a=candidate lines.<note>FIXME: what about ice-options and rtcp-mux?</note></p>
  <p>The receiver can reconstruct the SDP by first extracting the session section and then appending the media descriptions. When reconstructing the mediasections, the transport information can simply be appended to the raw SDP.</p>
  <p>Sending individual ice candidates is done as described in &xep0176;:</p>
    <example caption="Initiator sends a subsequent candidate"><![CDATA[
<iq from='romeo@montague.lit/orchard'
    id='uh3g1f48'
    to='juliet@capulet.lit/balcony'
    type='set'>
  <jingle xmlns='urn:xmpp:jingle:1'
          action='transport-info'
          initiator='romeo@montague.lit/orchard'
          sid='a73sjjvkla37jfea'>
    <content creator='initiator' name='this-is-the-audio-content'>
      <transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
                 pwd='6dCka9VISByPAFOH'
                 ufrag='k9ct1Zmco8RPW9C147atRl2X'>
        <candidate component='1'
                   foundation='1'
                   generation='0'
                   id='m3110wc4nd'
                   ip='2001:db8::9:1'
                   network='0'
                   port='9001'
                   priority='21149780477'
                   protocol='udp'
                   type='host'/>
      </transport>
    </content>
  </jingle>
</iq>
    ]]></example>
  <p>The mapping of a=candidate lines to Jingle and vice versa is relatively simple and described in <cite>XEP-0176</cite>.</p>
</section1>
<section1 topic='Adding and removing a content'>
  <p>This section is actually where things get interesting. It should talk about adding or removing content which is a concept that has been known in Jingle for ages and is now coming to SDP with the "partial offer/partial answer" concept from Unified Plan. This is the reason why the individual m-lines are transported in separate &lt;content/&gt; elements.</p>
  <p>The initiator starts with the offer SDP as described in the first section, but with audio only. Video is added later. Thus it sends the following session-initiate:</p>
  <example caption='Initiation'><![CDATA[
<iq from='romeo@montague.lit/orchard'
    id='ih28sx61'
    to='juliet@capulet.lit/balcony'
    type='set'>
  <jingle xmlns='urn:xmpp:jingle:1'
          action='session-initiate'
          initiator='romeo@montague.lit/orchard'
          sid='a73sjjvkla37jfea'>
    <session xmlns='urn:xmpp:jingle:apps:sdp'>
      v=0
      o=- 8065558698633182641 2 IN IP4 127.0.0.1
      s=-
      t=0 0
      a=group:BUNDLE audio
      a=msid-semantic: WMS QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
    </session>
    <content creator='initiator' name='audio'>
      <description xmlns='urn:xmpp:jingle:apps:sdp'>
        m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
        c=IN IP4 0.0.0.0
        a=rtcp:1 IN IP4 0.0.0.0
        a=ice-options:google-ice
        a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
        a=sendrecv
        a=mid:audio
        a=rtcp-mux
        a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
        a=rtpmap:111 opus/48000/2
        a=fmtp:111 minptime=10
        a=rtpmap:103 ISAC/16000
        a=rtpmap:104 ISAC/32000
        a=rtpmap:0 PCMU/8000
        a=rtpmap:8 PCMA/8000
        a=rtpmap:107 CN/48000
        a=rtpmap:106 CN/32000
        a=rtpmap:105 CN/16000
        a=rtpmap:13 CN/8000
        a=rtpmap:126 telephone-event/8000
        a=maxptime:60
        a=ssrc:3176601530 cname:GD84ngCycPaY3cQx
        a=ssrc:3176601530 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCla0
        a=ssrc:3176601530 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
        a=ssrc:3176601530 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCla0
      </description>
      <transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
                 ufrag='6dCka9VISByPAFOH'
                 pwd='k9ct1Zmco8RPW9C147atRl2X'>
        <fingerprint xmlns='urn:xmpp:tmp:jingle:apps:dtls:0' hash='sha-256'>
          7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
        </fingerprint>
      </transport>
    </content>
  </jingle>
</iq>
]]></example>
  <p>After the session is established, the initiator wants to add video from his webcam. It creates a new (full) SDP offer which will look like the one in example 1, but with candidates already added. It then calculates the difference between the new offer and the initial offer<note>At some point, the browser may do this.</note> which may consist of more than one mediaparts.</p>
  <example caption='Partial offer'><![CDATA[
m=video 1 RTP/SAVPF 100 116 117
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:6dCka9VISByPAFOH
a=ice-pwd:k9ct1Zmco8RPW9C147atRl2X
a=ice-options:google-ice
a=fingerprint:sha-256 7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=sendrecv
a=mid:video
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 goog-remb
a=rtpmap:116 red/90000
a=rtpmap:117 ulpfec/90000
a=ssrc:2358488720 cname:GD84ngCycPaY3cQx
a=ssrc:2358488720 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
a=ssrc:2358488720 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
a=ssrc:2358488720 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
]]></example>
  <p>When BUNDLE is used this will typically also contain a=candidate lines which are omitted for simplicity. This is transformed to a content-add. Note that the session-part must be resent if BUNDLE is used in the session since the BUNDLE group has changed:</p>
  <example caption='content-add'><![CDATA[
<iq from='romeo@montague.lit/orchard'
    id='ih28sx61'
    to='juliet@capulet.lit/balcony'
    type='set'>
  <jingle xmlns='urn:xmpp:jingle:1'
          action='session-initiate'
          initiator='romeo@montague.lit/orchard'
          sid='a73sjjvkla37jfea'>
    <session xmlns='urn:xmpp:jingle:apps:sdp'>
      v=0
      o=- 8065558698633182643 2 IN IP4 127.0.0.1
      s=-
      t=0 0
      a=group:BUNDLE audio video
      a=msid-semantic: WMS QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
    </session>
    <content creator='initiator' name='audio'>
      <description xmlns='urn:xmpp:jingle:apps:sdp'>
        m=video 1 RTP/SAVPF 100 116 117
        c=IN IP4 0.0.0.0
        a=rtcp:1 IN IP4 0.0.0.0
        a=ice-options:google-ice
        a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
        a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
        a=sendrecv
        a=mid:video
        a=rtcp-mux
        a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:+dMXm95m1recm8SlC3Ux66LH+z7Ve1LKoPKjbxWL
        a=rtpmap:100 VP8/90000
        a=rtcp-fb:100 ccm fir
        a=rtcp-fb:100 nack
        a=rtcp-fb:100 goog-remb
        a=rtpmap:116 red/90000
        a=rtpmap:117 ulpfec/90000
        a=ssrc:2358488720 cname:GD84ngCycPaY3cQx
        a=ssrc:2358488720 msid:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
        a=ssrc:2358488720 mslabel:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcCl
        a=ssrc:2358488720 label:QoHel4kmL4ZFaJuTwmz3VpyxzMRCcNDEmcClv0
      </description>
      <transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
                 ufrag='6dCka9VISByPAFOH'
                 pwd='k9ct1Zmco8RPW9C147atRl2X'>
        <fingerprint xmlns='urn:xmpp:tmp:jingle:apps:dtls:0' hash='sha-256'>
          7C:BA:4D:D8:25:61:57:22:BA:0C:5C:F3:7E:55:61:70:AF:9A:E9:F0:E6:51:8F:3E:7A:45:57:67:E7:B1:AB:4E
        </fingerprint>
      </transport>
    </content>
  </jingle>
</iq>
]]></example>
  <p>The receiver extracts the new session part and the additional media description(s) and constructs the new SDP based on the previous one<note>at some point, the browser may be able to do this, too</note>.</p>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
  <p>probably appropriate for showing webrtc stuff.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
  <p>TBD. Nothing beyond considerations from 0166/0167.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
  <p>This document requires no interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
  <p>TBD.</p>
</section1>
<section1 topic='XML Schema' anchor='schema'>
  <p>TBD.</p>
</section1>
</xep>
