Draft: draft-ietf-rtcweb-jsep

Commentary: Note : this pull request contains the changes made to the document to address the original RFC Editor AUTH48 questions captured in the following email :
Paragraph (version A):
This document describes the mechanisms for allowing a JavaScript
application to control the signaling plane of a multimedia session
via the interface specified in the W3C RTCPeerConnection API, and
discusses how this relates to existing signaling protocols.
Paragraph (version A):
This document describes how the W3C WEBRTC RTCPeerConnection
interface W3C.webrtc is used to control the setup, management and
teardown of a multimedia session.
Paragraph (version A):
WebRTC call setup has been designed to focus on controlling the media
plane, leaving signaling plane behavior up to the application as much
as possible.  The rationale is that different applications may prefer
to use different protocols, such as the existing SIP call signaling
protocol, or something custom to the particular application, perhaps
for a novel use case.  In this approach, the key information that
needs to be exchanged is the multimedia session description, which
specifies the necessary transport and media configuration information
necessary to establish the media plane.
Paragraph (version A):
With these considerations in mind, this document describes the
JavaScript Session Establishment Protocol (JSEP) that allows for full
control of the signaling state machine from JavaScript.  As described
above, JSEP assumes a model in which a JavaScript application
executes inside a runtime containing WebRTC APIs (the "JSEP
implementation").  The JSEP implementation is almost entirely
divorced from the core signaling flow, which is instead handled by
the JavaScript making use of two interfaces: (1) passing in local and
remote session descriptions and (2) interacting with the ICE state
machine.  The combination of the JSEP implementation and the
JavaScript application is referred to throughout this document as a
"JSEP endpoint".
Paragraph (version B):
This document describes the mechanisms for allowing a JavaScript
application to control the signaling plane of a multimedia session
via the interface specified in the W3C RTCPeerConnection API and
discusses how this relates to existing signaling protocols.
Paragraph (version B):
This document describes how the W3C Web Real-Time Communication
(WebRTC) RTCPeerConnection interface W3C.webrtc is used to control
the setup, management, and teardown of a multimedia session.
Paragraph (version B):
WebRTC call setup has been designed to focus on controlling the media
plane, leaving signaling-plane behavior up to the application as much
as possible.  The rationale is that different applications may prefer
to use different protocols, such as the existing SIP call signaling
protocol, or something custom to the particular application, perhaps
for a novel use case.  In this approach, the key information that
needs to be exchanged is the multimedia session description, which
specifies the transport and media configuration information necessary
to establish the media plane.
Paragraph (version B):
With these considerations in mind, this document describes the
JavaScript Session Establishment Protocol (JSEP), which allows for
full control of the signaling state machine from JavaScript.  As
described above, JSEP assumes a model in which a JavaScript
application executes inside a runtime containing WebRTC APIs (the
"JSEP implementation").  The JSEP implementation is almost entirely
divorced from the core signaling flow, which is instead handled by
the JavaScript making use of two interfaces: (1) passing in local and
remote session descriptions and (2) interacting with the Interactive
Connectivity Establishment (ICE) state machine RFC8445.  The
combination of the JSEP implementation and the JavaScript application
is referred to throughout this document as a "JSEP endpoint".
Paragraph (version B):
In this document, the use of JSEP is described as if it always occurs
between two JSEP endpoints.  Note, though, that in many cases it will
actually be between a JSEP endpoint and some kind of server, such as
a gateway or Multipoint Control Unit (MCU).  This distinction is
invisible to the JSEP endpoint; it just follows the instructions it
is given via the API.
Paragraph (version B):
JSEP's handling of session descriptions is simple and
straightforward.  Whenever an offer/answer exchange is needed, the
initiating side creates an offer by calling a createOffer API.  The
application then uses that offer to set up its local configuration
via the setLocalDescription API.  The offer is finally sent off to
the remote side over its preferred signaling mechanism (e.g.,
WebSockets); upon receipt of that offer, the remote party installs it
using the setRemoteDescription API.
Paragraph (version B):
To complete the offer/answer exchange, the remote party uses the
createAnswer API to generate an appropriate answer, applies it using
the setLocalDescription API, and sends the answer back to the
initiator over the signaling channel.  When the initiator gets that
answer, it installs it using the setRemoteDescription API, and
initial setup is complete.  This process can be repeated for
additional offer/answer exchanges.
Paragraph (version A):
Regarding ICE RFC8445, JSEP decouples the ICE state machine from the
overall signaling state machine, as the ICE state machine must remain
in the JSEP implementation, because only the implementation has the
necessary knowledge of candidates and other transport information.
Performing this separation provides additional flexibility in
protocols that decouple session descriptions from transport.  For
instance, in traditional SIP, each offer or answer is self-contained,
including both the session descriptions and the transport
information.  However, RFCYYY8 allows SIP to be used with trickle ICE
RFCYYY6, in which the session description can be sent immediately and
the transport information can be sent when available.  Sending
transport information separately can allow for faster ICE and DTLS
startup, since ICE checks can start as soon as any transport
information is available rather than waiting for all of it.  JSEP's
decoupling of the ICE and signaling state machines allows it to
accommodate either model.
Paragraph (version B):
Regarding ICE RFC8445, JSEP decouples the ICE state machine from the
overall signaling state machine, as the ICE state machine must remain
in the JSEP implementation, because only the implementation has the
necessary knowledge of candidates and other transport information.
Performing this separation provides additional flexibility in
protocols that decouple session descriptions from transport.  For
instance, in traditional SIP, each offer or answer is self-contained,
including both the session descriptions and the transport
information.  However, RFC8840 allows SIP to be used with Trickle ICE
RFC8838, in which the session description can be sent immediately and
the transport information can be sent when available.  Sending
transport information separately can allow for faster ICE and DTLS
startup, since ICE checks can start as soon as any transport
information is available rather than waiting for all of it.  JSEP's
decoupling of the ICE and signaling state machines allows it to
accommodate either model.
Paragraph (version A):
Through its abstraction of signaling, the JSEP approach does require
the application to be aware of the signaling process.  While the
application does not need to understand the contents of session
descriptions to set up a call, the application must call the right
APIs at the right times, convert the session descriptions and ICE
information into the defined messages of its chosen signaling
protocol, and perform the reverse conversion on the messages it
receives from the other side.
Paragraph (version A):
One way to make life easier for the application is to provide a
JavaScript library that hides this complexity from the developer;
said library would implement a given signaling protocol along with
its state machine and serialization code, presenting a higher level
call-oriented interface to the application developer.  For example,
libraries exist to adapt the JSEP API into an API suitable for a SIP
or XMPP.  Thus, JSEP provides greater control for the experienced
developer without forcing any additional complexity on the novice
developer.
Paragraph (version B):
Although it abstracts signaling, the JSEP approach requires that the
application be aware of the signaling process.  While the application
does not need to understand the contents of session descriptions to
set up a call, the application must call the right APIs at the right
times, convert the session descriptions and ICE information into the
defined messages of its chosen signaling protocol, and perform the
reverse conversion on the messages it receives from the other side.
Paragraph (version B):
One way to make life easier for the application is to provide a
JavaScript library that hides this complexity from the developer;
said library would implement a given signaling protocol along with
its state machine and serialization code, presenting a higher-level
call-oriented interface to the application developer.  For example,
libraries exist to provide implementations of the SIP RFC3261 and
Extensible Messaging and Presence Protocol (XMPP) RFC6120 signaling
protocols atop the JSEP API.  Thus, JSEP provides greater control for
the experienced developer without forcing any additional complexity
on the novice developer.
Paragraph (version B):
A second approach that was considered but not chosen was to decouple
the management of the media control objects from session
descriptions, instead offering APIs that would control each component
directly.  This was rejected based on the argument that requiring
exposure of this level of complexity to the application programmer
would not be beneficial; it would (1) result in an API where even a
simple example would require a significant amount of code to
orchestrate all the needed interactions and (2) create a large API
surface that would need to be agreed upon and documented.  In
addition, these API points could be called in any order, resulting in
a more complex set of interactions with the media subsystem than the
JSEP approach, which specifies how session descriptions are to be
evaluated and applied.
Paragraph (version B):
One variation on JSEP that was considered was to keep the basic
session-description-oriented API but to move the mechanism for
generating offers and answers out of the JSEP implementation.
Instead of providing createOffer/createAnswer methods within the
implementation, this approach would instead expose a getCapabilities
API, which would provide the application with the information it
needed in order to generate its own session descriptions.  This
increases the amount of work that the application needs to do; it
needs to know how to generate session descriptions from capabilities,
and especially how to generate the correct answer from an arbitrary
offer and the supported capabilities.  While this could certainly be
addressed by using a library like the one mentioned above, it
basically forces the use of said library even for a simple example.
Providing createOffer/createAnswer avoids this problem.
Paragraph (version A):
Whether a session description applies to the local side or the remote
side affects the meaning of that description.  For example, the list
of codecs sent to a remote party indicates what the local side is
willing to receive, which, when intersected with the set of codecs
the remote side supports, specifies what the remote side should send.
However, not all parameters follow this rule; some parameters are
declarative and the remote side MUST either accept them or reject
them altogether.  An example of such a parameter is the DTLS
fingerprints RFC8122, which are calculated based on the local
certificate(s) offered, and are not subject to negotiation.
Paragraph (version A):
In addition, various RFCs put different conditions on the format of
offers versus answers.  For example, an offer may propose an
arbitrary number of m= sections (i.e., media descriptions as
described in RFC4566), but an answer must contain the exact same
number as the offer.
Paragraph (version A):
Lastly, while the exact media parameters are only known only after an
offer and an answer have been exchanged, the offerer may receive ICE
checks, and possibly media (e.g., in the case of a re-offer after a
connection has been established) before it receives an answer.  To
properly process incoming media in this case, the offerer's media
handler must be aware of the details of the offer before the answer
arrives.
Paragraph (version B):
Whether a session description applies to the local side or the remote
side affects the meaning of that description.  For example, the list
of codecs sent to a remote party indicates what the local side is
willing to receive, which, when intersected with the set of codecs
the remote side supports, specifies what the remote side should send.
However, not all parameters follow this rule; some parameters are
declarative, and the remote side must either accept them or reject
them altogether.  An example of such a parameter is the TLS
fingerprints RFC8122 as used in the context of DTLS RFC6347; these
fingerprints are calculated based on the local certificate(s) offered
and are not subject to negotiation.
Paragraph (version B):
In addition, various RFCs put different conditions on the format of
offers versus answers.  For example, an offer may propose an
arbitrary number of "m=" sections (i.e., media descriptions as
described in RFC4566), but an answer must contain the exact same
number as the offer.
Paragraph (version B):
Lastly, while the exact media parameters are known only after an
offer and an answer have been exchanged, the offerer may receive ICE
checks, and possibly media (e.g., in the case of a re-offer after a
connection has been established) before it receives an answer.  To
properly process incoming media in this case, the offerer's media
handler must be aware of the details of the offer before the answer
arrives.
Paragraph (version A):
JSEP addresses this by adding both setLocalDescription and
setRemoteDescription methods and having session description objects
contain a type field indicating the type of session description being
supplied.  This satisfies the requirements listed above for both the
offerer, who first calls setLocalDescription(sdp [offer]) and then
later setRemoteDescription(sdp [answer]), as well as for the
answerer, who first calls setRemoteDescription(sdp [offer]) and then
later setLocalDescription(sdp [answer]).
Paragraph (version A):
During the offer/answer exchange, the outstanding offer is considered
to be "pending" at the offerer and the answerer, as it may either be
accepted or rejected.  If this is a re-offer, each side will also
have "current" local and remote descriptions, which reflect the
result of the last offer/answer exchange.  Sections
sec.pendinglocaldescription, sec.pendingremotedescription,
sec.currentlocaldescription, and sec.currentremotedescription,
provide more detail on pending and current descriptions.
Paragraph (version B):
JSEP addresses this by adding both setLocalDescription and
setRemoteDescription methods and having session description objects
contain a type field indicating the type of session description being
supplied.  This satisfies the requirements listed above for both the
offerer, who first calls setLocalDescription(sdp [offer]) and then
later setRemoteDescription(sdp [answer]), and the answerer, who first
calls setRemoteDescription(sdp [offer]) and then later
setLocalDescription(sdp [answer]).
Paragraph (version B):
During the offer/answer exchange, the outstanding offer is considered
to be "pending" at the offerer and the answerer, as it may be either
accepted or rejected.  If this is a re-offer, each side will also
have "current" local and remote descriptions, which reflect the
result of the last offer/answer exchange.  Sections
sec.pendinglocaldescription, sec.pendingremotedescription,
sec.currentlocaldescription, and sec.currentremotedescription provide
more detail on pending and current descriptions.
Paragraph (version A):
Aside from these state transitions there is no other difference
between the handling of provisional ("pranswer") and final ("answer")
answers.
Paragraph (version A):
JSEP's session descriptions use SDP syntax for their internal
representation.  While this format is not optimal for manipulation
from JavaScript, it is widely accepted, and frequently updated with
new features; any alternate encoding of session descriptions would
have to keep pace with the changes to SDP, at least until the time
that this new encoding eclipsed SDP in popularity.
Paragraph (version A):
However, to provide for future flexibility, the SDP syntax is
encapsulated within a SessionDescription object, which can be
constructed from SDP, and be serialized out to SDP.  If future
specifications agree on a JSON format for session descriptions, we
could easily enable this object to generate and consume that JSON.
Paragraph (version B):
JSEP also allows for an answer to be treated as provisional by the
application.  Provisional answers provide a way for an answerer to
communicate initial session parameters back to the offerer, in order
to allow the session to begin, while allowing a final answer to be
specified later.  This concept of a final answer is important to the
offer/answer model; when such an answer is received, any extra
resources allocated by the caller can be released, now that the exact
session configuration is known.  These "resources" can include things
like extra ICE components, Traversal Using Relays around NAT (TURN)
candidates, or video decoders.  Provisional answers, on the other
hand, do no such deallocation; as a result, multiple dissimilar
provisional answers, with their own codec choices, transport
parameters, etc., can be received and applied during call setup.
Note that the final answer itself may be different than any received
provisional answers.
Paragraph (version B):
Aside from these state transitions, there is no other difference
between the handling of provisional ("pranswer") and final ("answer")
answers.
Paragraph (version B):
JSEP's session descriptions use Session Description Protocol (SDP)
syntax for their internal representation.  While this format is not
optimal for manipulation from JavaScript, it is widely accepted and
is frequently updated with new features; any alternate encoding of
session descriptions would have to keep pace with the changes to SDP,
at least until the time that this new encoding eclipsed SDP in
popularity.
Paragraph (version B):
However, to provide for future flexibility, the SDP syntax is
encapsulated within a SessionDescription object, which can be
constructed from SDP and be serialized out to SDP.  If future
specifications agree on a JSON format for session descriptions, we
could easily enable this object to generate and consume that JSON.
Paragraph (version A):
In order to give the application control over various common session
parameters, JSEP provides control surfaces which tell the JSEP
implementation how to generate session descriptions.  This avoids the
need for JavaScript to modify session descriptions in most cases.
Paragraph (version A):
RtpTransceivers allow the application to control the RTP media
associated with one m= section.  Each RtpTransceiver has an RtpSender
and an RtpReceiver, which an application can use to control the
sending and receiving of RTP media.  The application may also modify
the RtpTransceiver directly, for instance, by stopping it.
Paragraph (version A):
RtpTransceivers generally have a 1:1 mapping with m= sections,
although there may be more RtpTransceivers than m= sections when
RtpTransceivers are created but not yet associated with a m= section,
or if RtpTransceivers have been stopped and disassociated from m=
sections.  An RtpTransceiver is said to be associated with an m=
section if its mid property is non-null; otherwise it is said to be
disassociated.  The associated m= section is determined using a
mapping between transceivers and m= section indices, formed when
creating an offer or applying a remote offer.
Paragraph (version A):
An RtpTransceiver is never associated with more than one m= section,
and once a session description is applied, a m= section is always
associated with exactly one RtpTransceiver.  However, in certain
cases where a m= section has been rejected, as discussed in
sec.subsequent-offers below, that m= section will be "recycled" and
associated with a new RtpTransceiver with a new mid value.
Paragraph (version B):
In order to give the application control over various common session
parameters, JSEP provides control surfaces that tell the JSEP
implementation how to generate session descriptions.  This avoids the
need for JavaScript to modify session descriptions in most cases.
Paragraph (version B):
Changes to these objects result in changes to the session
descriptions generated by subsequent createOffer/createAnswer calls.
Paragraph (version B):
RtpTransceivers allow the application to control the RTP media
associated with one "m=" section.  Each RtpTransceiver has an
RtpSender and an RtpReceiver, which an application can use to control
the sending and receiving of RTP media.  The application may also
modify the RtpTransceiver directly, for instance, by stopping it.
Paragraph (version B):
RtpTransceivers generally have a 1:1 mapping with "m=" sections,
although there may be more RtpTransceivers than "m=" sections when
RtpTransceivers are created but not yet associated with an "m="
section, or if RtpTransceivers have been stopped and disassociated
from "m=" sections.  An RtpTransceiver is said to be associated with
an "m=" section if its media identification (mid) property is non-
null; otherwise, it is said to be disassociated.  The associated "m="
section is determined using a mapping between transceivers and "m="
section indices, formed when creating an offer or applying a remote
offer.
Paragraph (version B):
An RtpTransceiver is never associated with more than one "m="
section, and once a session description is applied, an "m=" section
is always associated with exactly one RtpTransceiver.  However, in
certain cases where an "m=" section has been rejected, as discussed
in sec.subsequent-offers below, that "m=" section will be "recycled"
and associated with a new RtpTransceiver with a new MID value.
Paragraph (version B):
RtpTransceivers can be created explicitly by the application or
implicitly by calling setRemoteDescription with an offer that adds
new "m=" sections.
Paragraph (version B):
RtpSenders allow the application to control how RTP media is sent.
An RtpSender is conceptually responsible for the outgoing RTP
stream(s) described by an "m=" section.  This includes encoding the
attached MediaStreamTrack, sending RTP media packets, and generating/
processing the RTP Control Protocol (RTCP) for the outgoing RTP
streams(s).
Paragraph (version B):
RtpReceivers allow the application to inspect how RTP media is
received.  An RtpReceiver is conceptually responsible for the
incoming RTP stream(s) described by an "m=" section.  This includes
processing received RTP media packets, decoding the incoming
stream(s) to produce a remote MediaStreamTrack, and generating/
processing RTCP for the incoming RTP stream(s).
Paragraph (version B):
JSEP gathers ICE candidates as needed by the application.  Collection
of ICE candidates is referred to as a gathering phase, and this is
triggered either by the addition of a new or recycled "m=" section to
the local session description or by new ICE credentials in the
description, indicating an ICE restart.  Use of new ICE credentials
can be triggered explicitly by the application or implicitly by the
JSEP implementation in response to changes in the ICE configuration.
Paragraph (version A):
When a new gathering phase starts, the ICE agent will notify the
application that gathering is occurring through an event.  Then, when
each new ICE candidate becomes available, the ICE agent will supply
it to the application via an additional event; these candidates will
also automatically be added to the current and/or pending local
session description.  Finally, when all candidates have been
gathered, an event will be dispatched to signal that the gathering
process is complete.
Paragraph (version A):
Note that gathering phases only gather the candidates needed by
new/recycled/restarting m= sections; other m= sections continue to
use their existing candidates.  Also, if an m= section is bundled
(either by a successful bundle negotiation or by being marked as
bundle-only), then candidates will be gathered and exchanged for that
m= section if and only if its MID is a BUNDLE-tag, as described in
RFCYYYB.
Paragraph (version A):
Candidate trickling is a technique through which a caller may
incrementally provide candidates to the callee after the initial
offer has been dispatched; the semantics of "Trickle ICE" are defined
in RFCYYY6.  This process allows the callee to begin acting upon the
call and setting up the ICE (and perhaps DTLS) connections
immediately, without having to wait for the caller to gather all
possible candidates.  This results in faster media setup in cases
where gathering is not performed prior to initiating the call.
Paragraph (version B):
When the ICE configuration changes in a way that requires a new
gathering phase, a 'needs-ice-restart' bit is set.  When this bit is
set, calls to the createOffer API will generate new ICE credentials.
This bit is cleared by a call to the setLocalDescription API with new
ICE credentials from either an offer or an answer, i.e., from either
a locally or remotely initiated ICE restart.
Paragraph (version B):
When a new gathering phase starts, the ICE agent will notify the
application that gathering is occurring through a state change event.
Then, when each new ICE candidate becomes available, the ICE agent
will supply it to the application via an onicecandidate event; these
candidates will also automatically be added to the current and/or
pending local session description.  Finally, when all candidates have
been gathered, a final onicecandidate event will be dispatched to
signal that the gathering process is complete.
Paragraph (version B):
Note that gathering phases only gather the candidates needed by
new/recycled/restarting "m=" sections; other "m=" sections continue
to use their existing candidates.  Also, if an "m=" section is
bundled (either by a successful bundle negotiation or by being marked
as bundle-only), then candidates will be gathered and exchanged for
that "m=" section if and only if its MID item is a BUNDLE-tag, as
described in RFC8843.
Paragraph (version B):
Candidate trickling is a technique through which a caller may
incrementally provide candidates to the callee after the initial
offer has been dispatched; the semantics of "Trickle ICE" are defined
in RFC8838.  This process allows the callee to begin acting upon the
call and setting up the ICE (and perhaps DTLS) connections
immediately, without having to wait for the caller to gather all
possible candidates.  This results in faster media setup in cases
where gathering is not performed prior to initiating the call.
Paragraph (version A):
JSEP supports optional candidate trickling by providing APIs, as
described above, that provide control and feedback on the ICE
candidate gathering process.  Applications that support candidate
trickling can send the initial offer immediately and send individual
candidates when they get the notified of a new candidate;
applications that do not support this feature can simply wait for the
indication that gathering is complete, and then create and send their
offer, with all the candidates, at this time.
Paragraph (version B):
JSEP supports optional candidate trickling by providing APIs, as
described above, that provide control and feedback on the ICE
candidate gathering process.  Applications that support candidate
trickling can send the initial offer immediately and send individual
candidates when they get notified of a new candidate; applications
that do not support this feature can simply wait for the indication
that gathering is complete, and then create and send their offer,
with all the candidates, at that time.
Paragraph (version A):
The IceCandidate object contains a field to indicate which ICE ufrag
it is associated with, as defined in RFCYYY7.  This value is used to
determine which session description (and thereby which gathering
phase) this IceCandidate belongs to, which helps resolve ambiguities
during ICE restarts.  If this field is absent in a received
IceCandidate (perhaps when communicating with a non-JSEP endpoint),
the most recently received session description is assumed.
Paragraph (version A):
The IceCandidate object also contains fields to indicate which m=
section it is associated with, which can be identified in one of two
ways, either by a m= section index, or a MID.  The m= section index
is a zero-based index, with index N referring to the N+1th m= section
in the session description referenced by this IceCandidate.  The MID
is a "media stream identification" value, as defined in RFC5888,
which provides a more robust way to identify the m= section in the
session description, using the MID of the associated RtpTransceiver
object (which may have been locally generated by the answerer when
interacting with a non-JSEP endpoint that does not support the MID
attribute, as discussed in sec.applying-a-remote-desc below).  If the
MID field is present in a received IceCandidate, it MUST be used for
identification; otherwise, the m= section index is used instead.
Paragraph (version A):
When creating an IceCandidate object, JSEP implementations MUST
populate each of the candidate, ufrag, m= section index, and MID
fields.  Implementations MUST also be prepared to receive objects
with some fields missing, as mentioned above.
Paragraph (version B):
The IceCandidate object contains a field to indicate which ICE
username fragment (ufrag) it is associated with, as defined in
RFC8839.  This value is used to determine which session description
(and thereby which gathering phase) this IceCandidate belongs to,
which helps resolve ambiguities during ICE restarts.  If this field
is absent in a received IceCandidate (perhaps when communicating with
a non-JSEP endpoint), the most recently received session description
is assumed.
Paragraph (version B):
The IceCandidate object also contains fields to indicate which "m="
section it is associated with, which can be identified in one of two
ways: either by an "m=" section index or by a MID.  The "m=" section
index is a zero-based index, with index N referring to the N+1th "m="
section in the session description referenced by this IceCandidate.
The MID is a "media stream identification" value, as defined in
RFC5888, which provides a more robust way to identify the "m="
section in the session description, using the MID of the associated
RtpTransceiver object (which may have been locally generated by the
answerer when interacting with a non-JSEP endpoint that does not
support the MID attribute, as discussed in sec.applying-a-remote-desc
below).  If the MID field is present in a received IceCandidate, it
MUST be used for identification; otherwise, the "m=" section index is
used instead.
Paragraph (version A):
permitted for the application, as discussed in RFCYYY3.
Paragraph (version B):
permitted for the application, as discussed in RFC8828.
Paragraph (version B):
There may also be cases where the application wants to change which
types of candidates are used while the session is active.  A prime
example is where a callee may initially want to use only relay
candidates, to avoid leaking location information to an arbitrary
caller, but then change to use all candidates (for lower operational
cost) once the user has indicated that they want to take the call.
For this scenario, the JSEP implementation MUST allow the candidate
policy to be changed in mid-session, subject to the aforementioned
interactions with local policy.
Paragraph (version A):
JSEP applications typically inform the JSEP implementation to begin
ICE gathering via the information supplied to setLocalDescription, as
the local description indicates the number of ICE components which
will be needed and for which candidates must be gathered.  However,
to accelerate cases where the application knows the number of ICE
components to use ahead of time, it may ask the implementation to
gather a pool of potential ICE candidates to help ensure rapid media
setup.
Paragraph (version B):
JSEP applications typically inform the JSEP implementation to begin
ICE gathering via the information supplied to setLocalDescription, as
the local description indicates the number of ICE components that
will be needed and for which candidates must be gathered.  However,
to accelerate cases where the application knows the number of ICE
components to use ahead of time, it may ask the implementation to
gather a pool of potential ICE candidates to help ensure rapid media
setup.
Paragraph (version B):
When setLocalDescription is eventually called and the JSEP
implementation prepares to gather the needed ICE candidates, it
SHOULD start by checking if any candidates are available in the pool.
If there are candidates in the pool, they SHOULD be handed to the
application immediately via the ICE candidate event.  If the pool
becomes depleted, either because a larger-than-expected number of ICE
components are used or because the pool has not had enough time to
gather candidates, the remaining candidates are gathered as usual.
This only occurs for the first offer/answer exchange, after which the
candidate pool is emptied and no longer used.
Paragraph (version A):
One example of where this concept is useful is an application that
expects an incoming call at some point in the future, and wants to
minimize the time it takes to establish connectivity, to avoid
clipping of initial media.  By pre-gathering candidates into the
pool, it can exchange and start sending connectivity checks from
these candidates almost immediately upon receipt of a call.  Note
though that by holding on to these pre-gathered candidates, which
will be kept alive as long as they may be needed, the application
will consume resources on the STUN/TURN servers it is using.
Paragraph (version A):
While this specification formally relies on RFC8445, at the time of
its publication, the majority of WebRTC implementations support the
version of ICE described in RFC5245.  The use of the "ice2" attribute
defined in RFC8445 can be used to detect the version in use by a
remote endpoint and to provide a smooth transition from the older
specification to the newer one.  Implementations MUST be able to
accept remote descriptions that do not have the "ice2" attribute.
Paragraph (version B):
While this specification formally relies on RFC8445, at the time of
its publication, the majority of WebRTC implementations support the
version of ICE described in RFC5245.  The "ice2" attribute defined in
RFC8445 can be used to detect the version in use by a remote endpoint
and to provide a smooth transition from the older specification to
the newer one.  Implementations MUST be able to accept remote
descriptions that do not have the "ice2" attribute.
Paragraph (version B):
Note that certain codecs support transmission of samples with aspect
ratios other than 1.0 (i.e., non-square pixels).  JSEP
implementations will not transmit non-square pixels but SHOULD
receive and render such video with the correct aspect ratio.
However, sample aspect ratio has no impact on the size negotiation
described below; all dimensions are measured in pixels, whether
square or not.
Paragraph (version A):
The receiver will first intersect any known local limits (e.g.,
hardware decoder capababilities, local policy) to determine the
absolute minimum and maximum sizes it can receive.  If there are no
known local limits, the "a=imageattr" attribute SHOULD be omitted.
If these local limits preclude receiving any video, i.e., the
degenerate case of no permitted resolutions, the "a=imageattr"
attribute MUST be omitted, and the m= section MUST be marked as
sendonly/inactive, as appropriate.
Paragraph (version A):
Otherwise, an "a=imageattr" attribute is created with "recv"
direction, and the resulting resolution space formed from the
aforementioned intersection is used to specify its minimum and
maximum x= and y= values.
Paragraph (version B):
The receiver will first combine any known local limits (e.g.,
hardware decoder capabilities or local policy) to determine the
absolute minimum and maximum sizes it can receive.  If there are no
known local limits, the "a=imageattr" attribute SHOULD be omitted.
If these local limits preclude receiving any video, i.e., the
degenerate case of no permitted resolutions, the "a=imageattr"
attribute MUST be omitted, and the "m=" section MUST be marked as
sendonly/inactive, as appropriate.
Paragraph (version B):
Otherwise, an "a=imageattr" attribute is created with a "recv"
direction, and the resulting resolution space formed from the
aforementioned intersection is used to specify its minimum and
maximum "x=" and "y=" values.
Paragraph (version B):
The rules here express a single set of preferences, and therefore,
the "a=imageattr" "q=" value is not important.  It SHOULD be set to
"1.0".
Paragraph (version A):
RFC6236 defines "a=imageattr" to be an advisory field.  This means
that it does not absolutely constrain the video formats that the
sender can use, but gives an indication of the preferred values.
Paragraph (version A):
This specification prescribes more specific behavior.  When a
MediaStreamTrack, which is producing video of a certain resolution
(the "track resolution"), is attached to a RtpSender, which is
encoding the track video at the same or lower resolution(s) (the
"encoder resolutions"), and a remote description is applied that
references the sender and contains valid "a=imageattr recv"
attributes, it MUST follow the rules below to ensure the sender does
not transmit a resolution that would exceed the size criteria
specified in the attributes.  These rules MUST be followed as long as
the attributes remain present in the remote description, including
cases in which the track changes its resolution, or is replaced with
a different track.
Paragraph (version A):
Depending on how the RtpSender is configured, it may be producing a
single encoding at a certain resolution, or, if simulcast
sec.simulcast has been negotiated, multiple encodings, each at their
own specific resolution.  In addition, depending on the
configuration, each encoding may have the flexibility to reduce
resolution when needed, or may be locked to a specific output
resolution.
Paragraph (version A):
For each encoding being produced by the RtpSender, the set of
"a=imageattr recv" attributes in the corresponding m= section of the
remote description is processed to determine what should be
transmitted.  Only attributes that reference the media format
selected for the encoding are considered; each such attribute is
evaluated individually, starting with the attribute with the highest
"q=" value.  If multiple attributes have the same "q=" value, they
are evaluated in the order they appear in their containing m=
section.  Note that while JSEP endpoints will include at most one
"a=imageattr recv" attribute per media format, JSEP endpoints may
receive session descriptions from non-JSEP endpoints with m= sections
that contain multiple such attributes.
Paragraph (version B):
RFC6236 defines "a=imageattr" to be an advisory field.  This means
that it does not absolutely constrain the video formats that the
sender can use but gives an indication of the preferred values.
Paragraph (version B):
This specification prescribes behavior that is more specific.  When a
MediaStreamTrack, which is producing video of a certain resolution
(the "track resolution"), is attached to an RtpSender, which is
encoding the track video at the same or lower resolution(s) (the
"encoder resolutions"), and a remote description is applied that
references the sender and contains valid "a=imageattr recv"
attributes, it MUST follow the rules below to ensure that the sender
does not transmit a resolution that would exceed the size criteria
specified in the attributes.  These rules MUST be followed as long as
the attributes remain present in the remote description, including
cases in which the track changes its resolution or is replaced with a
different track.
Paragraph (version B):
Depending on how the RtpSender is configured, it may be producing a
single encoding at a certain resolution or, if simulcast
(sec.simulcast) has been negotiated, multiple encodings, each at
their own specific resolution.  In addition, depending on the
configuration, each encoding may have the flexibility to reduce
resolution when needed or may be locked to a specific output
resolution.
Paragraph (version B):
For each encoding being produced by the RtpSender, the set of
"a=imageattr recv" attributes in the corresponding "m=" section of
the remote description is processed to determine what should be
transmitted.  Only attributes that reference the media format
selected for the encoding are considered; each such attribute is
evaluated individually, starting with the attribute with the highest
"q=" value.  If multiple attributes have the same "q=" value, they
are evaluated in the order they appear in their containing "m="
section.  Note that while JSEP endpoints will include at most one
"a=imageattr recv" attribute per media format, JSEP endpoints may
receive session descriptions from non-JSEP endpoints with "m="
sections that contain multiple such attributes.
Paragraph (version B):
JSEP supports simulcast transmission of a MediaStreamTrack, where
multiple encodings of the source media can be transmitted within the
context of a single "m=" section.  The current JSEP API is designed
to allow applications to send simulcasted media but only to receive a
single encoding.  This allows for multi-user scenarios where each
sending client sends multiple encodings to a server, which then, for
each receiving client, chooses the appropriate encoding to forward.
Paragraph (version A):
Applications request support for simulcast by configuring multiple
encodings on an RtpSender.  Upon generation of an offer or answer,
these encodings are indicated via SDP markings on the corresponding
m= section, as described below.  Receivers that understand simulcast
and are willing to receive it will also include SDP markings to
indicate their support, and JSEP endpoints will use these markings to
determine whether simulcast is permitted for a given RtpSender.  If
simulcast support is not negotiated, the RtpSender will only use the
first configured encoding.
Paragraph (version B):
Applications request support for simulcast by configuring multiple
encodings on an RtpSender.  Upon generation of an offer or answer,
these encodings are indicated via SDP markings on the corresponding
"m=" section, as described below.  Receivers that understand
simulcast and are willing to receive it will also include SDP
markings to indicate their support, and JSEP endpoints will use these
markings to determine whether simulcast is permitted for a given
RtpSender.  If simulcast support is not negotiated, the RtpSender
will only use the first configured encoding.
Paragraph (version B):
Note that the exact simulcast parameters are up to the sending
application.  While the aforementioned SDP markings are provided to
ensure that the remote side can receive and demux multiple simulcast
encodings, the specific resolutions and bitrates to be used for each
encoding are purely a send-side decision in JSEP.
Paragraph (version A):
In addition, JSEP does not provide a mechanism to handle an incoming
offer requesting simulcast from the JSEP endpoint.  This means that
setting up simulcast in the case where the JSEP endpoint receives the
initial offer requires out-of-band signaling or SDP inspection.
However, in the case where the JSEP endpoint sets up simulcast in its
in initial offer, any established simulcast streams will continue to
work upon receipt of an incoming re-offer.  Future versions of this
specification may add additional APIs to handle the incoming initial
offer scenario.
Paragraph (version A):
When using JSEP to transmit multiple encodings from a RtpSender, the
techniques from RFCYYYE and RFCYYYC are used.  Specifically, when
multiple encodings have been configured for a RtpSender, the m=
section for the RtpSender will include an "a=simulcast" attribute, as
defined in RFCYYYE, with a "send" simulcast stream description that
lists each desired encoding, and no "recv" simulcast stream
description.  The m= section will also include an "a=rid" attribute
for each encoding, as specified in RFCYYYC; the use of RID
identifiers allows the individual encodings to be disambiguated even
though they are all part of the same m= section.
Paragraph (version B):
JSEP currently does not provide a mechanism to configure receipt of
simulcast.  This means that if simulcast is offered by the remote
endpoint, the answer generated by a JSEP endpoint will not indicate
support for receipt of simulcast, and as such the remote endpoint
will only send a single encoding per "m=" section.
Paragraph (version B):
In addition, JSEP does not provide a mechanism to handle an incoming
offer requesting simulcast from the JSEP endpoint.  This means that
setting up simulcast in the case where the JSEP endpoint receives the
initial offer requires out-of-band signaling or SDP inspection.
However, in the case where the JSEP endpoint sets up simulcast in its
initial offer, any established simulcast streams will continue to
work upon receipt of an incoming re-offer.  Future versions of this
specification may add additional APIs to handle the incoming initial
offer scenario.
Paragraph (version B):
When using JSEP to transmit multiple encodings from an RtpSender, the
techniques from RFC8853 and RFC8851 are used.  Specifically, when
multiple encodings have been configured for an RtpSender, the "m="
section for the RtpSender will include an "a=simulcast" attribute, as
defined in RFC8853, with a "send" simulcast stream description that
lists each desired encoding, and no "recv" simulcast stream
description.  The "m=" section will also include an "a=rid" attribute
for each encoding, as specified in RFC8851; the use of Restriction
Identifiers (RIDs, also called rid-ids or RtpStreamIds) allows the
individual encodings to be disambiguated even though they are all
part of the same "m=" section.
Paragraph (version A):
JSEP handles sequential forking well, allowing the application to
easily control the policy for selecting the desired remote endpoint.
When an answer arrives from one of the callees, the application can
choose to apply it either as a provisional answer, leaving open the
possibility of using a different answer in the future, or apply it as
a final answer, ending the setup flow.
Paragraph (version B):
JSEP handles sequential forking well, allowing the application to
easily control the policy for selecting the desired remote endpoint.
When an answer arrives from one of the callees, the application can
choose to apply it as either (1) a provisional answer, leaving open
the possibility of using a different answer in the future or (2) a
final answer, ending the setup flow.
Paragraph (version A):
Parallel forking involves a call being dispatched to multiple remote
callees, where each callee can accept the call, and multiple
simultaneous active signaling sessions can be established as a
result.  If multiple callees send media at the same time, the
possibilities for handling this are described in RFC3960.  Most SIP
devices today only support exchanging media with a single device at a
time, and do not try to mix multiple early media audio sources, as
that could result in a confusing situation.  For example, consider
having a European ringback tone mixed together with the North
American ringback tone - the resulting sound would not be like either
tone, and would confuse the user.  If the signaling application
wishes to only exchange media with one of the remote endpoints at a
time, then from a media engine point of view, this is exactly like
the sequential forking case.
Paragraph (version B):
Parallel forking involves a call being dispatched to multiple remote
callees, where each callee can accept the call and multiple
simultaneous active signaling sessions can be established as a
result.  If multiple callees send media at the same time, the
possibilities for handling this are described in RFC3960.  Most SIP
devices today only support exchanging media with a single device at a
time and do not try to mix multiple early media audio sources, as
that could result in a confusing situation.  For example, consider
having a European ringback tone mixed together with the North
American ringback tone -- the resulting sound would not be like
either tone and would confuse the user.  If the signaling application
wishes to only exchange media with one of the remote endpoints at a
time, then from a media engine point of view, this is exactly like
the sequential forking case.
Paragraph (version A):
In the parallel forking case where the JavaScript application wishes
to simultaneously exchange media with multiple peers, the flow is
slightly more complex, but the JavaScript application can follow the
strategy that RFC3960 describes using UPDATE.  The UPDATE approach
allows the signaling to set up a separate media flow for each peer
that it wishes to exchange media with.  In JSEP, this offer used in
the UPDATE would be formed by simply creating a new PeerConnection
(see sec.peerconnection) and making sure that the same local media
streams have been added into this new PeerConnection.  Then the new
PeerConnection object would produce a SDP offer that could be used by
the signaling to perform the UPDATE strategy discussed in RFC3960.
Paragraph (version B):
In the parallel forking case where the JavaScript application wishes
to simultaneously exchange media with multiple peers, the flow is
slightly more complex, but the JavaScript application can follow the
strategy that RFC3960 describes, using UPDATE.  The UPDATE approach
allows the signaling to set up a separate media flow for each peer
that it wishes to exchange media with.  In JSEP, this offer used in
the UPDATE would be formed by simply creating a new PeerConnection
(see sec.peerconnection) and making sure that the same local media
streams have been added into this new PeerConnection.  Then the new
PeerConnection object would produce an SDP offer that could be used
by the signaling to perform the UPDATE strategy discussed in RFC3960.
Paragraph (version A):
This section details the basic operations that must be present to
implement JSEP functionality.  The actual API exposed in the W3C API
may have somewhat different syntax, but should map easily to these
concepts.
Paragraph (version B):
This section details the basic operations that must be present to
implement JSEP functionality.  The actual API exposed in the W3C API
may have somewhat different syntax but should map easily to these
concepts.
Paragraph (version A):
If a size is specified for the ICE candidate pool, this indicates the
number of ICE components to pre-gather candidates for.  Because pre-
gathering results in utilizing STUN/TURN server resources for
potentially long periods of time, this must only occur upon
application request, and therefore the default candidate pool size
MUST be zero.
Paragraph (version A):
The application can specify its preferred policy regarding use of
bundle, the multiplexing mechanism defined in RFCYYYB.  Regardless of
policy, the application will always try to negotiate bundle onto a
single transport, and will offer a single bundle group across all m=
sections; use of this single transport is contingent upon the
answerer accepting bundle.  However, by specifying a policy from the
list below, the application can control exactly how aggressively it
will try to bundle media streams together, which affects how it will
interoperate with a non-bundle-aware endpoint.  When negotiating with
a non-bundle-aware endpoint, only the streams not marked as bundle-
only streams will be established.
Paragraph (version B):
The default ICE candidate policy MUST be set to "all", as this is
generally the desired policy and also typically reduces the use of
application TURN server resources significantly.
Paragraph (version B):
If a size is specified for the ICE candidate pool, this indicates the
number of ICE components to pre-gather candidates for.  Because
pre-gathering results in utilizing STUN/TURN server resources for
potentially long periods of time, this MUST only occur upon
application request, and therefore the default candidate pool size
MUST be zero.
Paragraph (version B):
The application can specify its preferred policy regarding use of
bundle, the multiplexing mechanism defined in RFC8843.  Regardless of
policy, the application will always try to negotiate bundle onto a
single transport and will offer a single bundle group across all "m="
sections; use of this single transport is contingent upon the
answerer accepting bundle.  However, by specifying a policy from the
list below, the application can control exactly how aggressively it
will try to bundle media streams together, which affects how it will
interoperate with a non-bundle-aware endpoint.  When negotiating with
a non-bundle-aware endpoint, only the streams not marked as bundle-
only streams will be established.
Paragraph (version A):
As it provides the best tradeoff between performance and
compatibility with legacy endpoints, the default bundle policy MUST
be set to "balanced".
Paragraph (version B):
As it provides the best trade-off between performance and
compatibility with legacy endpoints, the default bundle policy MUST
be set to "balanced".
Paragraph (version A):
The addTrack method adds a MediaStreamTrack to the PeerConnection,
using the MediaStream argument to associate the track with other
tracks in the same MediaStream, so that they can be added to the same
"LS" group when creating an offer or answer.  Adding tracks to the
same "LS" group indicates that the playback of these tracks should be
synchronized for proper lip sync, as described in RFC5888. addTrack
attempts to minimize the number of transceivers as follows: If the
PeerConnection is in the "have-remote-offer" state, the track will be
attached to the first compatible transceiver that was created by the
most recent call to setRemoteDescription() and does not have a local
track.  Otherwise, a new transceiver will be created, as described in
sec.addTransceiver.
Paragraph (version B):
The addTrack method adds a MediaStreamTrack to the PeerConnection,
using the MediaStream argument to associate the track with other
tracks in the same MediaStream, so that they can be added to the same
"LS" (Lip Synchronization) group when creating an offer or answer.
Adding tracks to the same "LS" group indicates that the playback of
these tracks should be synchronized for proper lip sync, as described
in RFC5888.  addTrack attempts to minimize the number of transceivers
as follows: if the PeerConnection is in the "have-remote-offer"
state, the track will be attached to the first compatible transceiver
that was created by the most recent call to setRemoteDescription and
does not have a local track.  Otherwise, a new transceiver will be
created, as described in sec.addTransceiver.
Paragraph (version A):
The removeTrack method removes a MediaStreamTrack from the
PeerConnection, using the RtpSender argument to indicate which sender
should have its track removed.  The sender's track is cleared, and
the sender stops sending.  Future calls to createOffer will mark the
m= section associated with the sender as recvonly (if
transceiver.direction is sendrecv) or as inactive (if
transceiver.direction is sendonly).
Paragraph (version B):
The removeTrack method removes a MediaStreamTrack from the
PeerConnection, using the RtpSender argument to indicate which sender
should have its track removed.  The sender's track is cleared, and
the sender stops sending.  Future calls to createOffer will mark the
"m=" section associated with the sender as recvonly (if
transceiver.direction is sendrecv) or as inactive (if
transceiver.direction is sendonly).
Paragraph (version A):
The createOffer method generates a blob of SDP that contains a
RFC3264 offer with the supported configurations for the session,
including descriptions of the media added to this PeerConnection, the
codec/RTP/RTCP options supported by this implementation, and any
candidates that have been gathered by the ICE agent.  An options
parameter may be supplied to provide additional control over the
generated offer.  This options parameter allows an application to
trigger an ICE restart, for the purpose of reestablishing
connectivity.
Paragraph (version B):
At the time of creation, the application can also specify a
transceiver direction attribute, a set of MediaStreams that the
transceiver is associated with (allowing "LS" group assignments), and
a set of encodings for the media (used for simulcast as described in
sec.simulcast).
Paragraph (version B):
The onaddtrack event is dispatched to the application when a new
remote track has been signaled as a result of a setRemoteDescription
call.  The new track is supplied as a MediaStreamTrack object in the
event, along with the MediaStream(s) the track is part of.
Paragraph (version B):
The createDataChannel method creates a new data channel and attaches
it to the PeerConnection.  If no data channel currently exists for
this PeerConnection, then a new offer/answer exchange is required.
All data channels on a given PeerConnection share the same SCTP/DTLS
association ("SCTP" stands for "Stream Control Transmission
Protocol") and therefore the same "m=" section, so subsequent
creation of data channels does not have any impact on the JSEP state.
Paragraph (version B):
The createDataChannel method also includes a number of arguments that
are used by the PeerConnection (e.g., maxPacketLifetime) but are not
reflected in the SDP and do not affect the JSEP state.
Paragraph (version B):
The ondatachannel event is dispatched to the application when a new
data channel has been negotiated by the remote side, which can occur
at any time after the underlying SCTP/DTLS association has been
established.  The new data channel object is supplied in the event.
Paragraph (version B):
The createOffer method generates a blob of SDP that contains an offer
per RFC3264 with the supported configurations for the session,
including descriptions of the media added to this PeerConnection, the
codec, RTP, and RTCP options supported by this implementation, and
any candidates that have been gathered by the ICE agent.  An options
parameter may be supplied to provide additional control over the
generated offer.  This options parameter allows an application to
trigger an ICE restart, for the purpose of reestablishing
connectivity.
Paragraph (version A):
Calling this method may do things such as generating new ICE
credentials, but does not change the PeerConnection state, trigger
candidate gathering, or cause media to start or stop flowing.
Specifically, the offer is not applied, and does not become the
pending local description, until setLocalDescription is called.
Paragraph (version A):
The createAnswer method generates a blob of SDP that contains a
RFC3264 SDP answer with the supported configuration for the session
that is compatible with the parameters supplied in the most recent
call to setRemoteDescription, which MUST have been called prior to
calling createAnswer.  Like createOffer, the returned blob contains
descriptions of the media added to this PeerConnection, the
codec/RTP/RTCP options negotiated for this session, and any
candidates that have been gathered by the ICE agent.  An options
parameter may be supplied to provide additional control over the
generated answer.
Paragraph (version B):
In the initial offer, the generated SDP will contain all desired
functionality for the session (functionality that is supported but
not desired by default may be omitted); for each SDP line, the
generation of the SDP will follow the process defined for generating
an initial offer from the specification that defines the given SDP
line.  The exact handling of initial offer generation is detailed in
sec.initial-offers below.
Paragraph (version B):
In the event createOffer is called after the session is established,
createOffer will generate an offer to modify the current session
based on any changes that have been made to the session, e.g., adding
or stopping RtpTransceivers, or requesting an ICE restart.  For each
existing stream, the generation of each SDP line MUST follow the
process defined for generating an updated offer from the RFC that
specifies the given SDP line.  For each new stream, the generation of
the SDP MUST follow the process of generating an initial offer, as
mentioned above.  If no changes have been made, or for SDP lines that
are unaffected by the requested changes, the offer will only contain
the parameters negotiated by the last offer/answer exchange.  The
exact handling of subsequent offer generation is detailed in
sec.subsequent-offers below.
Paragraph (version B):
Session descriptions generated by createOffer MUST be immediately
usable by setLocalDescription; if a system has limited resources
(e.g., a finite number of decoders), createOffer SHOULD return an
offer that reflects the current state of the system, so that
setLocalDescription will succeed when it attempts to acquire those
resources.
Paragraph (version B):
Calling this method may do things such as generating new ICE
credentials, but it does not change the PeerConnection state, trigger
candidate gathering, or cause media to start or stop flowing.
Specifically, the offer is not applied, and does not become the
pending local description, until setLocalDescription is called.
Paragraph (version B):
The createAnswer method generates a blob of SDP that contains an SDP
answer per RFC3264 with the supported configuration for the session
that is compatible with the parameters supplied in the most recent
call to setRemoteDescription, which MUST have been called prior to
calling createAnswer.  Like createOffer, the returned blob contains
descriptions of the media added to this PeerConnection, the
codec/RTP/RTCP options negotiated for this session, and any
candidates that have been gathered by the ICE agent.  An options
parameter may be supplied to provide additional control over the
generated answer.
Paragraph (version A):
As an answer, the generated SDP will contain a specific configuration
that specifies how the media plane should be established; for each
SDP line, the generation of the SDP must follow the process defined
for generating an answer from the document that specifies the given
SDP line.  The exact handling of answer generation is detailed in
sec.generating-an-answer. below.
Paragraph (version A):
Calling this method may do things such as generating new ICE
credentials, but does not change the PeerConnection state, trigger
candidate gathering, or or cause a media state change.  Specifically,
the answer is not applied, and does not become the current local
description, until setLocalDescription is called.
Paragraph (version A):
"offer" indicates that a description should be parsed as an offer;
said description may include many possible media configurations.  A
description used as an "offer" may be applied anytime the
PeerConnection is in a stable state, or as an update to a previously
supplied but unanswered "offer".
Paragraph (version A):
"pranswer" indicates that a description should be parsed as an
answer, but not a final answer, and so should not result in the
freeing of allocated resources.  It may result in the start of media
transmission, if the answer does not specify an inactive media
direction.  A description used as a "pranswer" may be applied as a
response to an "offer", or an update to a previously sent "pranswer".
Paragraph (version A):
The only difference between a provisional and final answer is that
the final answer results in the freeing of any unused resources that
were allocated as a result of the offer.  As such, the application
can use some discretion on whether an answer should be applied as
provisional or final, and can change the type of the session
description as needed.  For example, in a serial forking scenario, an
application may receive multiple "final" answers, one from each
remote endpoint.  The application could choose to accept the initial
answers as provisional answers, and only apply an answer as final
when it receives one that meets its criteria (e.g. a live user
instead of voicemail).
Paragraph (version B):
As an answer, the generated SDP will contain a specific configuration
that specifies how the media plane should be established; for each
SDP line, the generation of the SDP MUST follow the process defined
for generating an answer from the specification that defines the
given SDP line.  The exact handling of answer generation is detailed
in sec.generating-an-answer below.
Paragraph (version B):
Calling this method may do things such as generating new ICE
credentials, but it does not change the PeerConnection state, trigger
candidate gathering, or cause a media state change.  Specifically,
the answer is not applied, and does not become the current local
description, until setLocalDescription is called.
Paragraph (version B):
Session description objects (RTCSessionDescription) may be of type
"offer", "pranswer", "answer", or "rollback".  These types provide
information as to how the description parameter should be parsed and
how the media state should be changed.
Paragraph (version B):
"offer" indicates that a description MUST be parsed as an offer; said
description may include many possible media configurations.  A
description used as an "offer" may be applied any time the
PeerConnection is in a "stable" state or applied as an update to a
previously supplied but unanswered "offer".
Paragraph (version B):
"pranswer" indicates that a description MUST be parsed as an answer,
but not a final answer, and so MUST NOT result in the freeing of
allocated resources.  It may result in the start of media
transmission, if the answer does not specify an inactive media
direction.  A description used as a "pranswer" may be applied as a
response to an "offer" or as an update to a previously sent
"pranswer".
Paragraph (version B):
"answer" indicates that a description MUST be parsed as an answer,
the offer/answer exchange MUST be considered complete, and any
resources (decoders, candidates) that are no longer needed SHOULD be
released.  A description used as an "answer" may be applied as a
response to an "offer" or as an update to a previously sent
"pranswer".
Paragraph (version B):
The only difference between a provisional and final answer is that
the final answer results in the freeing of any unused resources that
were allocated as a result of the offer.  As such, the application
can use some discretion on whether an answer should be applied as
provisional or final and can change the type of the session
description as needed.  For example, in a serial forking scenario, an
application may receive multiple "final" answers, one from each
remote endpoint.  The application could choose to accept the initial
answers as provisional answers and only apply an answer as final when
it receives one that meets its criteria (e.g., a live user instead of
voicemail).
Paragraph (version B):
"rollback" is a special session description type indicating that the
state machine MUST be rolled back to the previous "stable" state, as
described in sec.rollback.  The contents MUST be empty.
Paragraph (version B):
Most applications will not need to create answers using the
"pranswer" type.  While it is good practice to send an immediate
response to an offer, in order to warm up the session transport and
prevent media clipping, the preferred handling for a JSEP application
is to create and send a "sendonly" final answer with a null
MediaStreamTrack immediately after receiving the offer, which will
prevent media from being sent by the caller and allow media to be
sent immediately upon answer by the callee.  Later, when the callee
actually accepts the call, the application can plug in the real
MediaStreamTrack and create a new "sendrecv" offer to update the
previous offer/answer pair and start bidirectional media flow.  While
this could also be done with a "sendonly" pranswer followed by a
"sendrecv" answer, the initial pranswer leaves the offer/answer
exchange open, which means that the caller cannot send an updated
offer during this time.
Paragraph (version A):
In certain situations it may be desirable to "undo" a change made to
setLocalDescription or setRemoteDescription.  Consider a case where a
call is ongoing, and one side wants to change some of the session
parameters; that side generates an updated offer and then calls
setLocalDescription.  However, the remote side, either before or
after setRemoteDescription, decides it does not want to accept the
new parameters, and sends a reject message back to the offerer.  Now,
the offerer, and possibly the answerer as well, need to return to a
stable state and the previous local/remote description.  To support
this, we introduce the concept of "rollback", which discards any
proposed changes to the session, returning the state machine to the
stable state.  A rollback is performed by supplying a session
description of type "rollback" with empty contents to either
setLocalDescription or setRemoteDescription.
Paragraph (version B):
As an example, consider a typical JSEP application that wants to set
up audio and video as quickly as possible.  When the callee receives
an offer with audio and video MediaStreamTracks, it will send an
immediate answer accepting these tracks as sendonly (meaning that the
caller will not send the callee any media yet, and because the callee
has not yet added its own MediaStreamTracks, the callee will not send
any media either).  It will then ask the user to accept the call and
acquire the needed local tracks.  Upon acceptance by the user, the
application will plug in the tracks it has acquired, which, because
ICE handshaking and DTLS handshaking have likely completed by this
point, can start transmitting immediately.  The application will also
send a new offer to the remote side indicating call acceptance and
moving the audio and video to be two-way media.  A detailed example
flow along these lines is shown in sec.warmup-example.
Paragraph (version B):
Of course, some applications may not be able to perform this double
offer/answer exchange, particularly ones that are attempting to
gateway to legacy signaling protocols.  In these cases, pranswer can
still provide the application with a mechanism to warm up the
transport.
Paragraph (version A):
This API changes the local media state; among other things, it sets
up local resources for receiving and decoding media.  In order to
successfully handle scenarios where the application wants to offer to
change from one media format to a different, incompatible format, the
PeerConnection must be able to simultaneously support use of both the
current and pending local descriptions (e.g., support the codecs that
exist in either description).  This dual processing begins when the
PeerConnection enters the "have-local-offer" state, and continues
until setRemoteDescription is called with either a final answer, at
which point the PeerConnection can fully adopt the pending local
description, or a rollback, which results in a revert to the current
local description.
Paragraph (version B):
This API changes the local media state; among other things, it sets
up local resources for receiving and decoding media.  In order to
successfully handle scenarios where the application wants to offer to
change from one media format to a different, incompatible format, the
PeerConnection MUST be able to simultaneously support use of both the
current and pending local descriptions (e.g., support the codecs that
exist in either description).  This dual processing begins when the
PeerConnection enters the "have-local-offer" state, and it continues
until setRemoteDescription is called with either (1) a final answer,
at which point the PeerConnection can fully adopt the pending local
description or (2) a rollback, which results in a revert to the
current local description.
Paragraph (version B):
This API indirectly controls the candidate gathering process.  When a
local description is supplied and the number of transports currently
in use does not match the number of transports needed by the local
description, the PeerConnection will create transports as needed and
begin gathering candidates for each transport, using ones from the
candidate pool if available.
Paragraph (version B):
If (1) setRemoteDescription was previously called with an offer, (2)
setLocalDescription is called with an answer (provisional or final),
(3) the media directions are compatible, and (4) media is available
to send, this will result in the starting of media transmission.
Paragraph (version A):
The currentLocalDescription method returns the current negotiated
local description - i.e., the local description from the last
successful offer/answer exchange - in addition to any local
candidates that have been generated by the ICE agent since the local
description was set.
Paragraph (version A):
The pendingLocalDescription method returns a copy of the local
description currently in negotiation - i.e., a local offer set
without any corresponding remote answer - in addition to any local
candidates that have been generated by the ICE agent since the local
description was set.
Paragraph (version B):
If (1) setLocalDescription was previously called with an offer, (2)
setRemoteDescription is called with an answer (provisional or final),
(3) the media directions are compatible, and (4) media is available
to send, this will result in the starting of media transmission.
Paragraph (version B):
The currentLocalDescription method returns the current negotiated
local description -- i.e., the local description from the last
successful offer/answer exchange -- in addition to any local
candidates that have been generated by the ICE agent since the local
description was set.
Paragraph (version B):
The pendingLocalDescription method returns a copy of the local
description currently in negotiation -- i.e., a local offer set
without any corresponding remote answer -- in addition to any local
candidates that have been generated by the ICE agent since the local
description was set.
Paragraph (version B):
The currentRemoteDescription method returns a copy of the current
negotiated remote description -- i.e., the remote description from
the last successful offer/answer exchange -- in addition to any
remote candidates that have been supplied via processIceMessage since
the remote description was set.
Paragraph (version B):
The pendingRemoteDescription method returns a copy of the remote
description currently in negotiation -- i.e., a remote offer set
without any corresponding local answer -- in addition to any remote
candidates that have been supplied via processIceMessage since the
remote description was set.
Paragraph (version A):
As described in sec.ice-candidate-trickling, JSEP implementations
always provide candidates to the application individually, consistent
with what is needed for Trickle ICE.  However, applications can use
the canTrickleIceCandidates property to determine whether their peer
can actually do Trickle ICE, i.e., whether it is safe to send an
initial offer or answer followed later by candidates as they are
gathered.  As "true" is the only value that definitively indicates
remote Trickle ICE support, an application which compares
canTrickleIceCandidates against "true" will by default attempt Half
Trickle on initial offers and Full Trickle on subsequent interactions
with a Trickle ICE-compatible agent.
Paragraph (version A):
The addIceCandidate method provides an update to the ICE agent via an
IceCandidate object sec.ice-candidate-format.  If the IceCandidate's
candidate field is filled in, the IceCandidate is treated as a new
remote ICE candidate, which will be added to the current and/or
pending remote description according to the rules defined for Trickle
ICE.  Otherwise, the IceCandidate is treated as an end-of-candidates
indication, as defined in RFCYYY6.
Paragraph (version A):
In either case, the m= section index, MID, and ufrag fields from the
supplied IceCandidate are used to determine which m= section and ICE
candidate generation the IceCandidate belongs to, as described in
sec.ice-candidate-format above.  In the case of an end-of-candidates
indication, the absence of both the m= section index and MID fields
is interpreted to mean that the indication applies to all m= sections
in the specified ICE candidate generation.  However, if both fields
are absent for a new remote candidate, this MUST be treated as an
invalid condition, as specified below.
Paragraph (version A):
If any IceCandidate fields contain invalid values, or an error occurs
during the processing of the IceCandidate object, the supplied
IceCandidate MUST be ignored and an error MUST be returned.
Paragraph (version B):
As described in sec.ice-candidate-trickling, JSEP implementations
always provide candidates to the application individually, consistent
with what is needed for Trickle ICE.  However, applications can use
the canTrickleIceCandidates property to determine whether their peer
can actually do Trickle ICE, i.e., whether it is safe to send an
initial offer or answer followed later by candidates as they are
gathered.  As "true" is the only value that definitively indicates
remote Trickle ICE support, an application that compares
canTrickleIceCandidates against "true" will by default attempt Half
Trickle on initial offers and Full Trickle on subsequent interactions
with a Trickle ICE-compatible agent.
Paragraph (version B):
Calling this method may result in a change to the state of the ICE
agent.
Paragraph (version B):
The addIceCandidate method provides an update to the ICE agent via an
IceCandidate object (sec.ice-candidate-format).  If the
IceCandidate's candidate field is non-null, the IceCandidate is
treated as a new remote ICE candidate, which will be added to the
current and/or pending remote description according to the rules
defined for Trickle ICE.  Otherwise, the IceCandidate is treated as
an end-of-candidates indication, as defined in RFC8838.
Paragraph (version B):
In either case, the "m=" section index, MID, and ufrag fields from
the supplied IceCandidate are used to determine which "m=" section
and ICE candidate generation the IceCandidate belongs to, as
described in sec.ice-candidate-format above.  In the case of an end-
of-candidates indication, null values for the "m=" section index and
MID fields are interpreted to mean that the indication applies to all
"m=" sections in the specified ICE candidate generation.  However, if
both fields are null for a new remote candidate, this MUST be treated
as an invalid condition, as specified below.
Paragraph (version B):
If any IceCandidate fields contain invalid values or an error occurs
during the processing of the IceCandidate object, the supplied
IceCandidate MUST be ignored and an error MUST be returned.
Paragraph (version B):
The onicecandidate event is dispatched to the application in two
situations: (1) when the ICE agent has discovered a new allowed local
ICE candidate during ICE gathering, as outlined in sec.ice-gather-
overview and subject to the restrictions discussed in sec.ice-
candidate-policy, or (2) when an ICE gathering phase completes.  The
event contains a single IceCandidate object, as defined in sec.ice-
candidate-format.
Paragraph (version B):
In the first case, the newly discovered candidate is reflected in the
IceCandidate object, and all of its fields MUST be non-null.  This
candidate will also be added to the current and/or pending local
description according to the rules defined for Trickle ICE.
Paragraph (version B):
In the second case, the event's IceCandidate object MUST have its
candidate field set to null to indicate that the current gathering
phase is complete, i.e., there will be no further onicecandidate
events in this phase.  However, the IceCandidate's ufrag field MUST
be specified to indicate which ICE candidate generation is ending.
The IceCandidate's "m=" section index and MID fields MAY be specified
to indicate that the event applies to a specific "m=" section, or set
to null to indicate it applies to all "m=" sections in the current
ICE candidate generation.  This event can be used by the application
to generate an end-of-candidates indication, as defined in RFC8838.
Paragraph (version B):
The stop method stops an RtpTransceiver.  This will cause future
calls to createOffer to generate a zero port for the associated "m="
section.  See below for more details.
Paragraph (version B):
The stopped property indicates whether the transceiver has been
stopped, either by a call to stop or by applying an answer that
rejects the associated "m=" section.  In either of these cases, it is
set to "true" and otherwise will be set to "false".
Paragraph (version A):
The setDirection method sets the direction of a transceiver, which
affects the direction property of the associated m= section on future
calls to createOffer and createAnswer.  The permitted values for
direction are "recvonly", "sendrecv", "sendonly", and "inactive",
mirroring the identically-named directional attributes defined in
RFC4566.
Paragraph (version B):
The setDirection method sets the direction of a transceiver, which
affects the direction property of the associated "m=" section on
future calls to createOffer and createAnswer.  The permitted values
for direction are "recvonly", "sendrecv", "sendonly", and "inactive",
mirroring the identically named direction attributes defined in
RFC4566.
Paragraph (version A):
Note that while setDirection sets the direction property of the
transceiver immediately ( sec.transceiver-direction), this property
does not immediately affect whether the transceiver's RtpSender will
send or its RtpReceiver will receive.  The direction in effect is
represented by the currentDirection property, which is only updated
when an answer is applied.
Paragraph (version A):
The currentDirection property indicates the last negotiated direction
for the transceiver's associated m= section.  More specifically, it
indicates the RFC3264 directional attribute of the associated m=
section in the last applied answer (including provisional answers),
with "send" and "recv" directions reversed if it was a remote answer.
For example, if the directional attribute for the associated m=
section in a remote answer is "recvonly", currentDirection is set to
"sendonly".
Paragraph (version B):
The currentDirection property indicates the last negotiated direction
for the transceiver's associated "m=" section.  More specifically, it
indicates the direction attribute RFC3264 of the associated "m="
section in the last applied answer (including provisional answers),
with "send" and "recv" directions reversed if it was a remote answer.
For example, if the direction attribute for the associated "m="
section in a remote answer is "recvonly", currentDirection is set to
"sendonly".
Paragraph (version B):
If an answer that references this transceiver has not yet been
applied or if the transceiver is stopped, currentDirection is set to
"null".
Paragraph (version B):
The setCodecPreferences method sets the codec preferences of a
transceiver, which in turn affect the presence and order of codecs of
the associated "m=" section on future calls to createOffer and
createAnswer.  Note that setCodecPreferences does not directly affect
which codec the implementation decides to send.  It only affects
which codecs the implementation indicates that it prefers to receive,
via the offer or answer.  Even when a codec is excluded by
setCodecPreferences, it still may be used to send until the next
offer/answer exchange discards it.
Paragraph (version A):
The codec preferences of an RtpTransceiver can cause codecs to be
excluded by subsequent calls to createOffer and createAnswer, in
which case the corresponding media formats in the associated m=
section will be excluded.  The codec preferences cannot add media
formats that would otherwise not be present.
Paragraph (version B):
The codec preferences of an RtpTransceiver can cause codecs to be
excluded by subsequent calls to createOffer and createAnswer, in
which case the corresponding media formats in the associated "m="
section will be excluded.  The codec preferences cannot add media
formats that would otherwise not be present.
Paragraph (version B):
The codec preferences of an RtpTransceiver can also determine the
order of codecs in subsequent calls to createOffer and createAnswer,
in which case the order of the media formats in the associated "m="
section will follow the specified preferences.
Paragraph (version A):
The SDES SRTP keying mechanism from RFC4568 MUST NOT be used, as
discussed in RFCYYY2.
Paragraph (version A):
For media m= sections, JSEP implementations MUST support the
"UDP/TLS/RTP/SAVPF" profile specified in RFC5764 as well as the
"TCP/DTLS/RTP/SAVPF" profile specified in RFC7850, and MUST indicate
one of these profiles for each media m= line they produce in an
offer.  For data m= sections, implementations MUST support the
"UDP/DTLS/SCTP" profile as well as the "TCP/DTLS/SCTP" profile, and
MUST indicate one of these profiles for each data m= line they
produce in an offer.  The exact profile to use is determined by the
protocol associated with the current default or selected ICE
candidate, as described in RFCYYY7.
Paragraph (version B):
The SDP security descriptions mechanism for SRTP keying RFC4568 MUST
NOT be used, as discussed in RFC8827.
Paragraph (version B):
For media "m=" sections, JSEP implementations MUST support the
"UDP/TLS/RTP/SAVPF" profile specified in RFC5764 as well as the
"TCP/DTLS/RTP/SAVPF" profile specified in RFC7850 and MUST indicate
one of these profiles for each media "m=" line they produce in an
offer.  For data "m=" sections, implementations MUST support the
"UDP/DTLS/SCTP" profile as well as the "TCP/DTLS/SCTP" profile and
MUST indicate one of these profiles for each data "m=" line they
produce in an offer.  The exact profile to use is determined by the
protocol associated with the current default or selected ICE
candidate, as described in RFC8839.
Paragraph (version A):
When createOffer is called, a new SDP description must be created
that includes the functionality specified in RFCYYY5.  The exact
details of this process are explained below.
Paragraph (version B):
When createOffer is called, a new SDP description MUST be created
that includes the functionality specified in RFC8834.  The exact
details of this process are explained below.
Paragraph (version A):
The next step is to generate m= sections, as specified in RFC4566.
An m= section is generated for each RtpTransceiver that has been
added to the PeerConnection, excluding any stopped RtpTransceivers;
this is done in the order the RtpTransceivers were added to the
PeerConnection.  If there are no such RtpTransceivers, no m= sections
are generated; more can be added later, as discussed in RFC3264.
Paragraph (version A):
For DTLS, all m= sections MUST use all the certificate(s) that have
been specified for the PeerConnection; as a result, they MUST all
have the same RFC8122 fingerprint value(s), or these value(s) MUST be
session-level attributes.
Paragraph (version A):
RFCYYYH groups SDP attributes into different categories.  To avoid
unnecessary duplication when bundling, attributes of category
IDENTICAL or TRANSPORT MUST NOT be repeated in bundled m= sections,
repeating the guidance from RFCYYYB.  This includes m= sections for
which bundling has been negotiated and is still desired, as well as
m= sections marked as bundle-only.
Paragraph (version A):
Lastly, if a data channel has been created, a m= section MUST be
generated for data.  The <media> field MUST be set to "application"
and the <proto> field MUST be set to "UDP/DTLS/SCTP" RFCYYY9.  The
"fmt" value MUST be set to "webrtc-datachannel" as specified in
RFCYYY9.
Paragraph (version A):
Once all m= sections have been generated, a session-level "a=group"
attribute MUST be added as specified in RFC5888.  This attribute MUST
have semantics "BUNDLE", and MUST include the mid identifiers of each
m= section.  The effect of this is that the JSEP implementation
offers all m= sections as one bundle group.  However, whether the m=
sections are bundle-only or not depends on the bundle policy.
Paragraph (version A):
Attributes which SDP permits to either be at the session level or the
media level SHOULD generally be at the media level even if they are
identical.  This assists development and debugging by making it
easier to understand individual media sections, especially if one of
a set of initially identical attributes is subsequently changed.
However, implementations MAY choose to aggregate attributes at the
session level and JSEP implementations MUST be prepared to receive
attributes in either location.
Paragraph (version A):
Note that when bundle is used, any additional attributes that are
added MUST follow the advice in RFCYYYH on how those attributes
interact with bundle.
Paragraph (version B):
The next step is to generate "m=" sections, as specified in RFC4566.
An "m=" section is generated for each RtpTransceiver that has been
added to the PeerConnection, excluding any stopped RtpTransceivers;
this is done in the order the RtpTransceivers were added to the
PeerConnection.  If there are no such RtpTransceivers, no "m="
sections are generated; more can be added later, as discussed in
RFC3264.
Paragraph (version B):
For each "m=" section generated for an RtpTransceiver, establish a
mapping between the transceiver and the index of the generated "m="
section.
Paragraph (version B):
Each "m=" section, provided it is not marked as bundle-only, MUST
generate a unique set of ICE credentials and gather its own unique
set of ICE candidates.  Bundle-only "m=" sections MUST NOT contain
any ICE credentials and MUST NOT gather any candidates.
Paragraph (version B):
For DTLS, all "m=" sections MUST use any and all certificates that
have been specified for the PeerConnection; as a result, they MUST
all have the same fingerprint value or values RFC8122, or these
values MUST be session-level attributes.
Paragraph (version B):
RFC8859 groups SDP attributes into different categories.  To avoid
unnecessary duplication when bundling, attributes of category
IDENTICAL or TRANSPORT MUST NOT be repeated in bundled "m=" sections,
repeating the guidance from RFC8843.  This includes "m=" sections for
which bundling has been negotiated and is still desired, as well as
"m=" sections marked as bundle-only.
Paragraph (version B):
Lastly, if a data channel has been created, an "m=" section MUST be
generated for data.  The <media> field MUST be set to "application",
and the <proto> field MUST be set to "UDP/DTLS/SCTP" RFC8841.  The
<fmt> value MUST be set to "webrtc-datachannel" as specified in
RFC8841.
Paragraph (version B):
Once all "m=" sections have been generated, a session-level "a=group"
attribute MUST be added as specified in RFC5888.  This attribute MUST
have semantics "BUNDLE" and MUST include the mid identifiers of each
"m=" section.  The effect of this is that the JSEP implementation
offers all "m=" sections as one bundle group.  However, whether the
"m=" sections are bundle-only or not depends on the bundle policy.
Paragraph (version B):
Attributes that SDP permits to be at either the session level or the
media level SHOULD generally be at the media level even if they are
identical.  This assists development and debugging by making it
easier to understand individual media sections, especially if one of
a set of initially identical attributes is subsequently changed.
However, implementations MAY choose to aggregate attributes at the
session level, and JSEP implementations MUST be prepared to receive
attributes in either location.
Paragraph (version B):
Note that when bundle is used, any additional attributes that are
added MUST follow the advice in RFC8859 on how those attributes
interact with bundle.
Paragraph (version A):
When createOffer is called a second (or later) time, or is called
after a local description has already been installed, the processing
is somewhat different than for an initial offer.
Paragraph (version B):
When createOffer is called a second (or later) time or is called
after a local description has already been installed, the processing
is somewhat different than for an initial offer.
Paragraph (version A):
If the previous offer was applied using setLocalDescription, and a
corresponding answer from the remote side has been applied using
setRemoteDescription, meaning the PeerConnection is in the "have-
remote-pranswer" or "stable" states, an offer is generated based on
the negotiated session descriptions by following the steps mentioned
for the "have-local-offer" state above.
Paragraph (version A):
The "a=group:BUNDLE" attribute MUST include the MID identifiers
specified in the bundle group in the most recent answer, minus any m=
sections that have been marked as rejected, plus any newly added or
re-enabled m= sections.  In other words, the bundle attribute must
contain all m= sections that were previously bundled, as long as they
are still alive, as well as any new m= sections.
Paragraph (version A):
The createOffer method takes as a parameter an RTCOfferOptions
object.  Special processing is performed when generating a SDP
description if the following options are present.
Paragraph (version A):
If the "IceRestart" option is specified, with a value of "true", the
offer MUST indicate an ICE restart by generating new ICE ufrag and
pwd attributes, as specified in RFCYYY7.  If this option is specified
on an initial offer, it has no effect (since a new ICE ufrag and pwd
are already generated).  Similarly, if the ICE configuration has
changed, this option has no effect, since new ufrag and pwd
attributes will be generated automatically.  This option is primarily
useful for reestablishing connectivity in cases where failures are
detected by the application.
Paragraph (version B):
If the previous offer was applied using setLocalDescription, and a
corresponding answer from the remote side has been applied using
setRemoteDescription, meaning the PeerConnection is in the "have-
remote-pranswer" state or the "stable" state, an offer is generated
based on the negotiated session descriptions by following the steps
mentioned for the "have-local-offer" state above.
Paragraph (version B):
The "a=group:BUNDLE" attribute MUST include the MID identifiers
specified in the bundle group in the most recent answer, minus any
"m=" sections that have been marked as rejected, plus any newly added
or re-enabled "m=" sections.  In other words, the bundle attribute
MUST contain all "m=" sections that were previously bundled, as long
as they are still alive, as well as any new "m=" sections.
Paragraph (version B):
"a=group:LS" attributes are generated in the same way as for initial
offers, with the additional stipulation that any lip sync groups that
were present in the most recent answer MUST continue to exist and
MUST contain any previously existing MID identifiers, as long as the
identified "m=" sections still exist and are not rejected, and the
group still contains at least two MID identifiers.  This ensures that
any synchronized "recvonly" "m=" sections continue to be synchronized
in the new offer.
Paragraph (version B):
The createOffer method takes as a parameter an RTCOfferOptions
object.  Special processing is performed when generating an SDP
description if the following options are present.
Paragraph (version B):
If the IceRestart option is specified, with a value of "true", the
offer MUST indicate an ICE restart by generating new ICE ufrag and
pwd attributes, as specified in RFC8839.  If this option is specified
on an initial offer, it has no effect (since a new ICE ufrag and pwd
are already generated).  Similarly, if the ICE configuration has
changed, this option has no effect, since new ufrag and pwd
attributes will be generated automatically.  This option is primarily
useful for reestablishing connectivity in cases where failures are
detected by the application.
Paragraph (version A):
The "VoiceActivityDetection" option does not have any impact on the
setting of the "vad" value in the signaling of the client to mixer
audio level header extension described in RFC6464.
Paragraph (version A):
When createAnswer is called, a new SDP description must be created
that is compatible with the supplied remote description as well as
the requirements specified in RFCYYY5.  The exact details of this
process are explained below.
Paragraph (version B):
The "VoiceActivityDetection" option does not have any impact on the
setting of the "vad" value in the signaling of the client-to-mixer
audio level header extension described in RFC6464.
Paragraph (version B):
When createAnswer is called, a new SDP description MUST be created
that is compatible with the supplied remote description as well as
the requirements specified in RFC8834.  The exact details of this
process are explained below.
Paragraph (version A):
Note that the remote description SDP may not have been created by a
JSEP endpoint and may not conform to all the requirements listed in
sec-create-offer.  For many cases, this is not a problem.  However,
if any mandatory SDP attributes are missing, or functionality listed
as mandatory-to-use above is not present, this MUST be treated as an
error, and MUST cause the affected m= sections to be marked as
rejected.
Paragraph (version A):
The first step in generating an initial answer is to generate
session-level attributes.  The process here is identical to that
indicated in the initial offers section above, except that the
"a=ice-options" line, with the "trickle" option as specified in
RFCYYY6, and the "ice2" option as specified in RFC8445, is only
included if such an option was present in the offer.
Paragraph (version A):
The next step is to generate session-level lip sync groups, as
defined in RFC5888.  For each group of type "LS" present in the
offer, select the local RtpTransceivers that are referenced by the
MID values in the specified group, and determine which of them either
reference a common local MediaStream (specified in the calls to
addTrack/addTransceiver used to create them), or have no MediaStream
to reference because they were not created by addTrack/
addTransceiver.  If at least two such RtpTransceivers exist, a group
of type "LS" with the mid values of these RtpTransceivers MUST be
added.  Otherwise the offered "LS" group MUST be ignored and no
corresponding group generated in the answer.
Paragraph (version B):
Note that the remote description SDP may not have been created by a
JSEP endpoint and may not conform to all the requirements listed in
sec-create-offer.  For many cases, this is not a problem.  However,
if any mandatory SDP attributes are missing or functionality listed
as mandatory-to-use above is not present, this MUST be treated as an
error and MUST cause the affected "m=" sections to be marked as
rejected.
Paragraph (version B):
The first step in generating an initial answer is to generate
session-level attributes.  The process here is identical to that
indicated in sec.initial-offers above, except that the "a=ice-
options" line, with the "trickle" option as specified in RFC8840 and
the "ice2" option as specified in RFC8445, is only included if such
an option was present in the offer.
Paragraph (version B):
The next step is to generate session-level lip sync groups, as
defined in RFC5888.  For each group of type "LS" present in the
offer, select the local RtpTransceivers that are referenced by the
MID values in the specified group, and determine which of them either
reference a common local MediaStream (specified in the calls to
addTrack/addTransceiver used to create them) or have no MediaStream
to reference because they were not created by addTrack/
addTransceiver.  If at least two such RtpTransceivers exist, a group
of type "LS" with the MID values of these RtpTransceivers MUST be
added.  Otherwise, the offered "LS" group MUST be ignored and no
corresponding group generated in the answer.
Paragraph (version A):
The next step is to generate m= sections for each m= section that is
present in the remote offer, as specified in RFC3264.  For the
purposes of this discussion, any session-level attributes in the
offer that are also valid as media-level attributes are considered to
be present in each m= section.  Each offered m= section will have an
associated RtpTransceiver, as described in sec.applying-a-remote-
desc.  If there are more RtpTransceivers than there are m= sections,
the unmatched RtpTransceivers will need to be associated in a
subsequent offer.
Paragraph (version A):
If "a=group" attributes with semantics of "BUNDLE" are offered,
corresponding session-level "a=group" attributes MUST be added as
specified in RFC5888.  These attributes MUST have semantics "BUNDLE",
and MUST include the all mid identifiers from the offered bundle
groups that have not been rejected.  Note that regardless of the
presence of "a=bundle-only" in the offer, no m= sections in the
answer should have an "a=bundle-only" line.
Paragraph (version A):
Attributes that are common between all m= sections MAY be moved to
session-level, if explicitly defined to be valid at session-level.
Paragraph (version A):
When createAnswer is called a second (or later) time, or is called
after a local description has already been installed, the processing
is somewhat different than for an initial answer.
Paragraph (version B):
The example in sec.detailed-example shows a more involved case of
"LS" group generation.
Paragraph (version B):
The next step is to generate "m=" sections for each "m=" section that
is present in the remote offer, as specified in RFC3264.  For the
purposes of this discussion, any session-level attributes in the
offer that are also valid as media-level attributes are considered to
be present in each "m=" section.  Each offered "m=" section will have
an associated RtpTransceiver, as described in sec.applying-a-remote-
desc.  If there are more RtpTransceivers than there are "m="
sections, the unmatched RtpTransceivers will need to be associated in
a subsequent offer.
Paragraph (version B):
If a data channel "m=" section has been offered, an "m=" section MUST
also be generated for data.  The <media> field MUST be set to
"application", and the <proto> and <fmt> fields MUST be set to
exactly match the fields in the offer.
Paragraph (version B):
Note that if media "m=" sections are bundled into a data "m="
section, then certain TRANSPORT and IDENTICAL attributes may also
appear in the data "m=" section even if they would otherwise only be
appropriate for a media "m=" section (e.g., "a=rtcp-mux").
Paragraph (version B):
If "a=group" attributes with semantics of "BUNDLE" are offered,
corresponding session-level "a=group" attributes MUST be added as
specified in RFC5888.  These attributes MUST have semantics "BUNDLE"
and MUST include all mid identifiers from the offered bundle groups
that have not been rejected.  Note that regardless of the presence of
"a=bundle-only" in the offer, all "m=" sections in the answer MUST
NOT have an "a=bundle-only" line.
Paragraph (version B):
Attributes that are common between all "m=" sections MAY be moved to
the session level if explicitly defined to be valid at the session
level.
Paragraph (version B):
When createAnswer is called a second (or later) time or is called
after a local description has already been installed, the processing
is somewhat different than for an initial answer.
Paragraph (version B):
The createAnswer method takes as a parameter an RTCAnswerOptions
object.  The set of parameters for RTCAnswerOptions is different than
those supported in RTCOfferOptions; the IceRestart option is
unnecessary, as ICE credentials will automatically be changed for all
"m=" sections where the offerer chose to perform ICE restart.
Paragraph (version A):
Silence suppression in the answer is handled as described in
sec.voiceactivitydetection1, with one exception: if support for
silence suppression was not indicated in the offer, the
VoiceActivityDetection parameter has no effect, and the answer should
be generated as if VoiceActivityDetection was set to false.  This is
done on a per-codec basis (e.g., if the offerer somehow offered
support for CN but set "usedtx=0" for Opus, setting
VoiceActivityDetection to true would result in an answer with CN
codecs and "usedtx=0").  The impact of this rule is that an answerer
will not try to use silence suppression with any endpoint that does
not offer it, making silence suppression support bilateral even with
non-JSEP endpoints.
Paragraph (version B):
Silence suppression in the answer is handled as described in
sec.voiceactivitydetection1, with one exception: if support for
silence suppression was not indicated in the offer, the
VoiceActivityDetection parameter has no effect, and the answer MUST
be generated as if VoiceActivityDetection was set to "false".  This
is done on a per-codec basis (e.g., if the offerer somehow offered
support for CN but set "usedtx=0" for Opus, setting
VoiceActivityDetection to "true" would result in an answer with CN
codecs and "usedtx=0").  The impact of this rule is that an answerer
will not try to use silence suppression with any endpoint that does
not offer it, making silence suppression support bilateral even with
non-JSEP endpoints.
Paragraph (version B):
As always, the application is solely responsible for what it sends to
the other party, and all incoming SDP will be processed by the JSEP
implementation to the extent of its capabilities.  It is an error to
assume that all SDP is well formed; however, one should be able to
assume that any implementation of this specification will be able to
process, as a remote offer or answer, unmodified SDP coming from any
other implementation of this specification.
Paragraph (version A):
A rollback may be performed if the PeerConnection is in any state
except for "stable".  This means that both offers and provisional
answers can be rolled back.  Rollback can only be used to cancel
proposed changes; there is no support for rolling back from a stable
state to a previous stable state.  If a rollback is attempted in the
"stable" state, processing MUST stop and an error MUST be returned.
Note that this implies that once the answerer has performed
setLocalDescription with his answer, this cannot be rolled back.
Paragraph (version B):
A rollback may be performed if the PeerConnection is in any state
except for "stable".  This means that both offers and provisional
answers can be rolled back.  Rollback can only be used to cancel
proposed changes; there is no support for rolling back from a
"stable" state to a previous "stable" state.  If a rollback is
attempted in the "stable" state, processing MUST stop and an error
MUST be returned.  Note that this implies that once the answerer has
performed setLocalDescription with its answer, this cannot be rolled
back.
Paragraph (version A):
In order to process rollback, a JSEP implementation abandons the
current offer/answer transaction, sets the signaling state to
"stable", and sets the pending local and/or remote description (see
Sections sec.pendinglocaldescription and
sec.pendingremotedescription) to null.  Any resources or candidates
that were allocated by the abandoned local description are discarded;
any media that is received is processed according to the previous
local and remote descriptions.
Paragraph (version A):
A rollback disassociates any RtpTransceivers that were associated
with m= sections by the application of the rolled-back session
description (see Sections sec.applying-a-remote-desc and
sec.applying-a-local-desc).  This means that some RtpTransceivers
that were previously associated will no longer be associated with any
m= section; in such cases, the value of the RtpTransceiver's mid
property MUST be set to null, and the mapping between the transceiver
and its m= section index MUST be discarded.  RtpTransceivers that
were created by applying a remote offer that was subsequently rolled
back MUST be stopped and removed from the PeerConnection.  However, a
RtpTransceiver MUST NOT be removed if a track was attached to the
RtpTransceiver via the addTrack method.  This is so that an
application may call addTrack, then call setRemoteDescription with an
offer, then roll back that offer, then call createOffer and have a m=
section for the added track appear in the generated offer.
Paragraph (version A):
The SDP contained in the session description object consists of a
sequence of text lines, each containing a key-value expression, as
described in RFC4566.  The SDP is read, line-by-line, and converted
to a data structure that contains the deserialized information.
However, SDP allows many types of lines, not all of which are
relevant to JSEP applications.  For each line, the implementation
will first ensure it is syntactically correct according to its
defining ABNF, check that it conforms to RFC4566 and RFC3264
semantics, and then either parse and store or discard the provided
value, as described below.
Paragraph (version B):
In order to process rollback, a JSEP implementation abandons the
current offer/answer transaction, sets the signaling state to
"stable", and sets the pending local and/or remote description (see
Sections sec.pendinglocaldescription and
sec.pendingremotedescription) to "null".  Any resources or candidates
that were allocated by the abandoned local description are discarded;
any media that is received is processed according to the previous
local and remote descriptions.
Paragraph (version B):
A rollback disassociates any RtpTransceivers that were associated
with "m=" sections by the application of the rolled-back session
description (see Sections sec.applying-a-remote-desc and
sec.applying-a-local-desc).  This means that some RtpTransceivers
that were previously associated will no longer be associated with any
"m=" section; in such cases, the value of the RtpTransceiver's mid
property MUST be set to "null", and the mapping between the
transceiver and its "m=" section index MUST be discarded.
RtpTransceivers that were created by applying a remote offer that was
subsequently rolled back MUST be stopped and removed from the
PeerConnection.  However, an RtpTransceiver MUST NOT be removed if a
track was attached to the RtpTransceiver via the addTrack method.
This is so that an application may call addTrack, then call
setRemoteDescription with an offer, then roll back that offer, then
call createOffer and have an "m=" section for the added track appear
in the generated offer.
Paragraph (version B):
The SDP contained in the session description object consists of a
sequence of text lines, each containing a key-value expression, as
described in RFC4566.  The SDP is read, line by line, and converted
to a data structure that contains the deserialized information.
However, SDP allows many types of lines, not all of which are
relevant to JSEP applications.  For each line, the implementation
will first ensure that it is syntactically correct according to its
defining ABNF, check that it conforms to the semantics used in
RFC4566 and RFC3264, and then either parse and store or discard the
provided value, as described below.
Paragraph (version B):
If any line is not well formed or cannot be parsed as described, the
parser MUST stop with an error and reject the session description,
even if the value is to be discarded.  This ensures that
implementations do not accidentally misinterpret ambiguous SDP.
Paragraph (version A):
First, the session-level lines are checked and parsed.  These lines
MUST occur in a specific order, and with a specific syntax, as
defined in RFC4566.  Note that while the specific line types (e.g.
"v=", "c=") MUST occur in the defined order, lines of the same type
(typically "a=") can occur in any order.
Paragraph (version B):
First, the session-level lines are checked and parsed.  These lines
MUST occur in a specific order, and with a specific syntax, as
defined in RFC4566.  Note that while the specific line types (e.g.,
"v=", "c=") MUST occur in the defined order, lines of the same type
(typically "a=") can occur in any order.
Paragraph (version B):
Once all the session-level lines have been parsed, processing
continues with the lines in "m=" sections.
Paragraph (version A):
The "m=" line itself MUST be parsed as described in RFC4566, and the
media, port, proto, and fmt values stored.
Paragraph (version B):
The "m=" line itself MUST be parsed as described in RFC4566, and the
<media>, <port>, <proto>, and <fmt> values stored.
Paragraph (version A):
First, m= sections are processed.  For each m= section, the following
steps MUST be performed; if any parameters are out of bounds, or
cannot be applied, processing MUST stop and an error MUST be
returned.
Paragraph (version B):
First, "m=" sections are processed.  For each "m=" section, the
following steps MUST be performed; if any parameters are out of
bounds or cannot be applied, processing MUST stop and an error MUST
be returned.
Paragraph (version B):
If the answer contains any "a=ice-options" attributes where "trickle"
is listed as an attribute, update the PeerConnection
canTrickleIceCandidates property to be "true".  Otherwise, set this
property to "false".
Paragraph (version B):
The following steps MUST be performed for attributes at the session
level; if any parameters are out of bounds or cannot be applied,
processing MUST stop and an error MUST be returned.
Paragraph (version B):
For each "m=" section, the following steps MUST be performed; if any
parameters are out of bounds or cannot be applied, processing MUST
stop and an error MUST be returned.
Paragraph (version A):
If the answer contains valid bundle groups, discard any ICE
components for the m= sections that will be bundled onto the primary
ICE components in each bundle, and begin muxing these m= sections
accordingly, as described in RFCYYYB.
Paragraph (version A):
When bundling, associating incoming RTP/RTCP with the proper m=
section is defined in RFCYYYB.  When not bundling, the proper m=
section is clear from the ICE component over which the RTP/RTCP is
received.
Paragraph (version A):
Once the proper m= section(s) are known, RTP/RTCP is delivered to the
RtpTransceiver(s) associated with the m= section(s) and further
processing of the RTP/RTCP is done at the RtpTransceiver level.  This
includes using RID RFCYYYC to distinguish between multiple Encoded
Streams, as well as determine which Source RTP stream should be
repaired by a given Redundancy RTP stream.
Paragraph (version A):
Note that this example section shows several SDP fragments.  To
format in 72 columns, some of the lines in SDP have been split into
multiple lines, where leading whitespace indicates that a line is a
continuation of the previous line.  In addition, some blank lines
have been added to improve readability but are not valid in SDP.
Paragraph (version A):
The code flow below shows Alice's endpoint initiating the session to
Bob's endpoint.  The messages from the JavaScript application in
Alice's browser to the JavaScript in Bob's browser, abbreviated as
AliceJS and BobJS respectively, are assumed to flow over some
signaling protocol via a web server.  The JavaScript on both Alice's
side and Bob's side waits for all candidates before sending the offer
or answer, so the offers and answers are complete; trickle ICE is not
used.  The user agents (JSEP implementations) in Alice and Bob's
browsers, abbreviated as AliceUA and BobUA respectively, are using
the default bundle policy of "balanced", and the default RTCP mux
policy of "require".
Paragraph (version B):
If the answer contains valid bundle groups, discard any ICE
components for the "m=" sections that will be bundled onto the
primary ICE components in each bundle, and begin muxing these "m="
sections accordingly, as described in RFC8843.
Paragraph (version B):
If the description is of type "answer" and there are still remaining
candidates in the ICE candidate pool, discard them.
Paragraph (version B):
When bundling, associating incoming RTP/RTCP with the proper "m="
section is defined in RFC8843.  When not bundling, the proper "m="
section is clear from the ICE component over which the RTP/RTCP is
received.
Paragraph (version B):
Once the proper "m=" section or sections are known, RTP/RTCP is
delivered to the RtpTransceiver(s) associated with the "m="
section(s) and further processing of the RTP/RTCP is done at the
RtpTransceiver level.  This includes using the RID mechanism RFC8851
and its associated RtpStreamId and RepairedRtpStreamId identifiers to
distinguish between multiple encoded streams and determine which
Source RTP stream should be repaired by a given redundancy RTP
stream.
Paragraph (version B):
Note that this example section shows several SDP fragments.  To
accommodate RFC line-length restrictions, some of the SDP lines have
been split into multiple lines, where leading whitespace indicates
that a line is a continuation of the previous line.  In addition,
some blank lines have been added to improve readability but are not
valid in SDP.
Paragraph (version B):
This section shows a very simple example that sets up a minimal
audio/video call between two JSEP endpoints without using Trickle
ICE.  The example in the following section provides a more detailed
example of what could happen in a JSEP session.
Paragraph (version B):
The code flow below shows Alice's endpoint initiating the session to
Bob's endpoint.  The messages from the JavaScript application in
Alice's browser to the JavaScript in Bob's browser, abbreviated as
"AliceJS" and "BobJS", respectively, are assumed to flow over some
signaling protocol via a web server.  The JavaScript on both Alice's
side and Bob's side waits for all candidates before sending the offer
or answer, so the offers and answers are complete; Trickle ICE is not
used.  The user agents (JSEP implementations) in Alice's and Bob's
browsers, abbreviated as "AliceUA" and "BobUA", respectively, are
both using the default bundle policy of "balanced" and the default
RTCP mux policy of "require".
Paragraph (version B):
This section shows a more involved example of a session between two
JSEP endpoints.  Trickle ICE is used in full trickle mode, with a
bundle policy of "max-bundle", an RTCP mux policy of "require", and a
single TURN server.  Initially, both Alice and Bob establish an audio
channel and a data channel.  Later, Bob adds two video flows -- one
for his video feed and one for screen sharing, both supporting FEC --
with the video feed configured for simulcast.  Alice accepts these
video flows but does not add video flows of her own, so they are
handled as recvonly.  Alice also specifies a maximum video decoder
resolution.
Paragraph (version B):
The SDP for |offer-B2| is shown below.  In addition to the new "m="
sections for video, both of which are offering FEC and one of which
is offering simulcast, note the increment of the version number in
the "o=" line; changes to the "c=" line, indicating the local
candidate that was selected; and the inclusion of gathered candidates
as a=candidate lines.
Paragraph (version B):
The SDP for |answer-B2| is shown below.  In addition to the
acceptance of the video "m=" sections, the use of a=recvonly to
indicate one-way video, and the use of a=imageattr to limit the
received resolution, note the use of setup:passive to maintain the
existing DTLS roles.
Paragraph (version B):
This example demonstrates the early-warmup technique described in
sec.use-of-provisional-answer.  Here, Alice's endpoint sends an offer
to Bob's endpoint to start an audio/video call.  Bob immediately
responds with an answer that accepts the audio/video "m=" sections
but marks them as sendonly (from his perspective), meaning that Alice
will not yet send media.  This allows the JSEP implementation to
start negotiating ICE and DTLS immediately.  Bob's endpoint then
prompts him to answer the call, and when he does, his endpoint sends
a second offer, which enables the audio and video "m=" sections, and
thereby bidirectional media transmission.  The advantage of such a
flow is that as soon as the first answer is received, the
implementation can proceed with ICE and DTLS negotiation and
establish the session transport.  If the transport setup completes
before the second offer is sent, then media can be transmitted by the
callee immediately upon answering the call, minimizing perceived
post-dial delay.  The second offer/answer exchange can also change
the preferred codecs or other session parameters.
Paragraph (version A):
The IETF has published separate documents RFCYYY2 RFCYYY1 describing
the security architecture for WebRTC as a whole.  The remainder of
this section describes security considerations for this document.
Paragraph (version B):
The IETF has published separate documents RFC8827 RFC8826 describing
the security architecture for WebRTC as a whole.  The remainder of
this section describes security considerations for this document.
Paragraph (version A):
While formally the JSEP interface is an API, it is better to think of
it as an Internet protocol, with the application JavaScript being
untrustworthy from the perspective of the JSEP implementation.  Thus,
the threat model of RFC3552 applies.  In particular, JavaScript can
call the API in any order and with any inputs, including malicious
ones.  This is particularly relevant when we consider the SDP which
is passed to setLocalDescription().  While correct API usage requires
that the application pass in SDP which was derived from createOffer()
or createAnswer(), there is no guarantee that applications do so.
The JSEP implementation MUST be prepared for the JavaScript to pass
in bogus data instead.
Paragraph (version A):
learning your public IP address by removing server reflexive
candidates.  Applications which wish to conceal their public IP
address should instead configure the ICE agent to use only relay
candidates.
Paragraph (version A):
This document requires no actions from IANA.
Paragraph (version A):
provided significant text for this draft.
Paragraph (version B):
learning your public IP address by removing server-reflexive
candidates.  Applications that wish to conceal their public IP
address MUST instead configure the ICE agent to use only relay
candidates.