|
|
@@ -340,31 +340,13 @@ JingleSessionPC.prototype.sendAnswer = function (success, failure) {
|
|
340
|
340
|
JingleSessionPC.prototype.createdAnswer = function (sdp, success, failure) {
|
|
341
|
341
|
//logger.log('createAnswer callback');
|
|
342
|
342
|
|
|
343
|
|
- // XXX Videobridge is the (SDP) offerer and WebRTC (e.g. Chrome) is the
|
|
344
|
|
- // answerer (as orchestrated by Jicofo). In accord with
|
|
345
|
|
- // http://tools.ietf.org/html/rfc5245#section-5.2 and because both peers
|
|
346
|
|
- // are ICE FULL agents, Videobridge will take on the controlling role and
|
|
347
|
|
- // WebRTC will take on the controlled role. In accord with
|
|
348
|
|
- // https://tools.ietf.org/html/rfc5763#section-5, Videobridge will use the
|
|
349
|
|
- // setup attribute value of setup:actpass and WebRTC will be allowed to
|
|
350
|
|
- // choose either the setup attribute value of setup:active or
|
|
351
|
|
- // setup:passive. Chrome will by default choose setup:active because it is
|
|
352
|
|
- // RECOMMENDED by the respective RFC since setup:passive adds additional
|
|
353
|
|
- // latency. The case of setup:active allows WebRTC to send a DTLS
|
|
354
|
|
- // ClientHello as soon as an ICE connectivity check of its succeeds.
|
|
355
|
|
- // Unfortunately, Videobridge will be unable to respond immediately because
|
|
356
|
|
- // may not have WebRTC's answer or may have not completed the ICE
|
|
357
|
|
- // connectivity establishment. Even more unfortunate is that in the
|
|
358
|
|
- // described scenario Chrome's DTLS implementation will insist on
|
|
359
|
|
- // retransmitting its ClientHello after a second (the time is in accord
|
|
360
|
|
- // with the respective RFC) and will thus cause the whole connection
|
|
361
|
|
- // establishment to exceed at least 1 second. To work around Chrome's
|
|
362
|
|
- // idiosyncracy, don't allow it to send a ClientHello i.e. change its
|
|
363
|
|
- // default choice of setup:active to setup:passive.
|
|
364
|
|
- sdp.sdp = sdp.sdp.replace(/a=setup:active/g, 'a=setup:passive');
|
|
365
|
|
-
|
|
366
|
343
|
var self = this;
|
|
367
|
344
|
this.localSDP = new SDP(sdp.sdp);
|
|
|
345
|
+
|
|
|
346
|
+ this._fixAnswerRFC4145Setup(
|
|
|
347
|
+ /* offer */ this.remoteSDP,
|
|
|
348
|
+ /* answer */ this.localSDP);
|
|
|
349
|
+
|
|
368
|
350
|
var sendJingle = function (ssrcs) {
|
|
369
|
351
|
var accept
|
|
370
|
352
|
= $iq({ to: self.peerjid, type: 'set' })
|
|
|
@@ -417,6 +399,55 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, success, failure) {
|
|
417
|
399
|
}
|
|
418
|
400
|
};
|
|
419
|
401
|
|
|
|
402
|
+/**
|
|
|
403
|
+ * Modifies the values of the setup attributes (defined by
|
|
|
404
|
+ * {@link http://tools.ietf.org/html/rfc4145#section-4}) of a specific SDP
|
|
|
405
|
+ * answer in order to overcome a delay of 1 second in the connection
|
|
|
406
|
+ * establishment between Chrome and Videobridge.
|
|
|
407
|
+ *
|
|
|
408
|
+ * @param {SDP} offer - the SDP offer to which the specified SDP answer is
|
|
|
409
|
+ * being prepared to respond
|
|
|
410
|
+ * @param {SDP} answer - the SDP to modify
|
|
|
411
|
+ * @private
|
|
|
412
|
+ */
|
|
|
413
|
+JingleSessionPC.prototype._fixAnswerRFC4145Setup = function (offer, answer) {
|
|
|
414
|
+ // XXX Videobridge is the (SDP) offerer and WebRTC (e.g. Chrome) is the
|
|
|
415
|
+ // answerer (as orchestrated by Jicofo). In accord with
|
|
|
416
|
+ // http://tools.ietf.org/html/rfc5245#section-5.2 and because both peers
|
|
|
417
|
+ // are ICE FULL agents, Videobridge will take on the controlling role and
|
|
|
418
|
+ // WebRTC will take on the controlled role. In accord with
|
|
|
419
|
+ // https://tools.ietf.org/html/rfc5763#section-5, Videobridge will use the
|
|
|
420
|
+ // setup attribute value of setup:actpass and WebRTC will be allowed to
|
|
|
421
|
+ // choose either the setup attribute value of setup:active or
|
|
|
422
|
+ // setup:passive. Chrome will by default choose setup:active because it is
|
|
|
423
|
+ // RECOMMENDED by the respective RFC since setup:passive adds additional
|
|
|
424
|
+ // latency. The case of setup:active allows WebRTC to send a DTLS
|
|
|
425
|
+ // ClientHello as soon as an ICE connectivity check of its succeeds.
|
|
|
426
|
+ // Unfortunately, Videobridge will be unable to respond immediately because
|
|
|
427
|
+ // may not have WebRTC's answer or may have not completed the ICE
|
|
|
428
|
+ // connectivity establishment. Even more unfortunate is that in the
|
|
|
429
|
+ // described scenario Chrome's DTLS implementation will insist on
|
|
|
430
|
+ // retransmitting its ClientHello after a second (the time is in accord
|
|
|
431
|
+ // with the respective RFC) and will thus cause the whole connection
|
|
|
432
|
+ // establishment to exceed at least 1 second. To work around Chrome's
|
|
|
433
|
+ // idiosyncracy, don't allow it to send a ClientHello i.e. change its
|
|
|
434
|
+ // default choice of setup:active to setup:passive.
|
|
|
435
|
+ if (offer && answer
|
|
|
436
|
+ && offer.media && answer.media
|
|
|
437
|
+ && offer.media.length == answer.media.length) {
|
|
|
438
|
+ answer.media.forEach(function (a, i) {
|
|
|
439
|
+ if (SDPUtil.find_line(
|
|
|
440
|
+ offer.media[i],
|
|
|
441
|
+ 'a=setup:actpass',
|
|
|
442
|
+ offer.session)) {
|
|
|
443
|
+ answer.media[i]
|
|
|
444
|
+ = a.replace(/a=setup:active/g, 'a=setup:passive');
|
|
|
445
|
+ }
|
|
|
446
|
+ });
|
|
|
447
|
+ answer.raw = answer.session + answer.media.join('');
|
|
|
448
|
+ }
|
|
|
449
|
+}
|
|
|
450
|
+
|
|
420
|
451
|
JingleSessionPC.prototype.terminate = function (reason, text,
|
|
421
|
452
|
success, failure) {
|
|
422
|
453
|
var term = $iq({to: this.peerjid,
|