Proposed resolution to Issue 93: ICE restart behavior still needs to be resolved

After much cogitation, RFC and draft reading and re-reading, and general gnashing of teeth, we may have a proposed resolution to Issue 93.

One of the related questions was when a change to the ICE gather policy takes effect.  The proposed resolution is to cause an ICE restart to
occur when a new gatherPolicy is installed via gather() and RTCIceTransport.start is called.

Since a gather policy needs to apply to all RTCIceTransport objects using an RTCIceListener, the proposal is to move the gather() method to the RTCIceListener.

The RTCIceTransport.start method also takes a new (optional) iceListener argument.

Find below a summary of all the potential changes.

Section 3.3

[Constructor(RTCIceListener iceListener),
    Constructor(RTCIceOptions options)]
partial interface RTCIceTransport : RTCStatsProvider {
   readonly    attribute RTCIceListener       iceListener;
   readonly    attribute RTCIceRole           role;
   readonly    attribute RTCIceComponent      component;
   readonly    attribute RTCIceTransportState state;
   readonly    attribute RTCIceGatheringState iceGatheringState;
   void        start (RTCIceParameters remoteParameters, optional RTCIceRole role, optional RTCIceListener iceListener);
   void                      stop ();
   RTCIceParameters          getLocalParameters ();
   RTCIceParameters?         getRemoteParameters ();
// (removed)   void                      gather (RTCIceGatherPolicy gatherPolicy);
               attribute EventHandler?        onlocalcandidate;
               attribute EventHandler?        onicestatechange;
               attribute EventHandler?        onicegatheringstatechange;
};

start
Starts candidate connectivity checks and attempts to connect to the remote RTCIceTransport. If listener.gather() has not been called, start gathering with a default gatherPolicy of "all". If start is called with invalid parameters, throw an InvalidParameters exception.

Parameter Type   Nullable     Optional     Description
remoteParameters      RTCIceParameters    ✘     ✘
role     RTCIceRole   ✘     ✔
listener RTCIceListener      ✘     ✔
Return type: void

Section 5.3

[Constructor(optional RTCIceOptions options)]
interface RTCIceListener {
   void             gather (RTCIceGatherPolicy gatherPolicy);
   RTCIceParameters getLocalParameters ();
   RTCIceOptions    getOptions ();
   void             setOptions (RTCIceOptions options);
               attribute EventHandler? onerror;
};

gather
Set the gather policy.  Gathering does not begin until RTCIceTransport.start() is called. If gatherPolicy is invalid, throw an InvalidParameter exception.

Parameter     Type   Nullable      Optional      Description
gatherPolicy  RTCIceGatherPolicy    ✘      ✘
Return type: void

getLocalParameters
Obtain the ICE parameters of the RTCIceListener.

No parameters.
Return type: RTCIceParameters

Section 5.4

enum RTCIceGatherPolicy {
   "all",
   "nohost",
   "relay"
};

Examples
Assuming that the getLocalParameters() and onlocalcandidate() methods are retained in the  RTCIceTransport object, it does not appear to me that any changes are required to Section 3.15 (Examples 3 and 4).  Similarly, it does not appear that changes are needed to Section 4.4 (Example 5).  In order to illustrate the use of a custom gatherPolicy, I propose changing Section 5.5 Example 6 to the following:
EXAMPLE 6

// Example to demonstrate forking when RTP and RTCP are not multiplexed.

var iceOptions = ...;
var iceRtpListener = new RTCIceListener(iceOptions);
var iceBaseRtpTransport = new RTCIceTransport(iceRtpListener);
//create the RTCP ICE transport
var iceBaseRtcpTransport = iceBaseRtpTransport.createAssociatedTransport();
// Set the ICE listener gather policy to "relay", presumably for privacy reasons.
iceBaseRtpTransport.iceListener.gather(RTCIceGatherPolicy.relay);
iceBaseRtcpTransport.iceListener.gather(RTCIceGatherPolicy.relay);

mySendInitiate(
{
  "icertp": iceBaseRtpTransport.getLocalParameters(),
  "icertcp": iceBaseRtcpTransport.getLocalParameters()
},
 function(response) {
 // We may get N responses
 var iceRtpTransport = new RTCIceTransport(iceRtpListener);
 // Create new ice RTCP transport based on the (implicitly created) iceListener
 var iceRtcpTransport = iceRtpTransport.createAssociatedTransport();

 // check to make sure the RTCRtpIceListener objects are set up as expected.
 assert(iceRtpTransport.iceListener == iceBaseRtpTransport.iceListener);
 assert(iceRtcpTransport.iceListener == iceBaseRtcpTransport.iceListener);
 // Create the ICE Transport Controller object
 var controller = new RTCIceTransportController();
 controller.addTransport(iceRtpTransport);
 controller.addTransport(iceRtcpTransport);
 // Start the ICE transports (using the "relay" gather policy inherited from the iceListener)
 iceRtpTransport.start(response.icertp, RTCIceRole.controlling);
 iceRtcpTransport.start(response.icertcp, RTCIceRole.controlling);
 // ... setup DTLS, RTP, SCTP, etc.
});

iceBaseRtpTransport.onlocalcandidate = mySendLocalRtpCandidate;
iceBaseRtcpTransport.onlocalcandidate = mySendLocalRtcpCandidate;

Received on Wednesday, 6 August 2014 20:01:45 UTC