Browse Source

Adds support for bundle.

master
Boris Grozev 10 years ago
parent
commit
20b69ce5ca
2 changed files with 64 additions and 9 deletions
  1. 1
    0
      config.js
  2. 63
    9
      libs/colibri/colibri.focus.js

+ 1
- 0
config.js View File

@@ -19,5 +19,6 @@ var config = {
19 19
     //defaultSipNumber: '20669', //Default SIP number used in call dialog
20 20
 //    channelLastN: -1, // The default value of the channel attribute last-n.
21 21
 //    useRtcpMux: true,
22
+//    useBundle: true,
22 23
     enableRecording: false
23 24
 };

+ 63
- 9
libs/colibri/colibri.focus.js View File

@@ -72,6 +72,7 @@ function ColibriFocus(connection, bridgejid) {
72 72
         this.media = ['audio', 'video'];
73 73
 
74 74
     this.connection.jingle.sessions[this.sid] = this;
75
+    this.bundledTransports = {};
75 76
     this.mychannel = [];
76 77
     this.channels = [];
77 78
     this.remotessrc = {};
@@ -296,13 +297,20 @@ ColibriFocus.prototype._makeConference = function () {
296 297
 
297 298
         elem.c(elemName, elemAttrs);
298 299
         elem.attrs({ endpoint: self.myMucResource });
300
+        if (config.useBundle) {
301
+            elem.attrs({ 'channel-bundle-id': self.myMucResource });
302
+        }
299 303
         elem.up();// end of channel/sctpconnection
300 304
 
301 305
         for (var j = 0; j < self.peers.length; j++) {
302 306
             var peer = self.peers[j];
307
+            var peerEndpoint = peer.substr(1 + peer.lastIndexOf('/'));
303 308
 
304 309
             elem.c(elemName, elemAttrs);
305
-            elem.attrs({ endpoint: peer.substr(1 + peer.lastIndexOf('/')) });
310
+            elem.attrs({ endpoint: peerEndpoint });
311
+            if (config.useBundle) {
312
+                elem.attrs({ 'channel-bundle-id': peerEndpoint });
313
+            }
306 314
             elem.up(); // end of channel/sctpconnection
307 315
         }
308 316
         elem.up(); // end of content
@@ -353,7 +361,7 @@ ColibriFocus.prototype._makeConference = function () {
353 361
     );
354 362
 };
355 363
 
356
-// callback when a conference was created
364
+// callback when a colibri conference was created
357 365
 ColibriFocus.prototype.createdConference = function (result) {
358 366
     console.log('created a conference on the bridge');
359 367
     var self = this;
@@ -379,6 +387,14 @@ ColibriFocus.prototype.createdConference = function (result) {
379 387
         }
380 388
     }
381 389
 
390
+    // save the 'transport' elements from 'channel-bundle'-s
391
+    var channelBundles = $(result).find('>conference>channel-bundle');
392
+    for (var i = 0; i < channelBundles.length; i++)
393
+    {
394
+        var endpointId = $(channelBundles[i]).attr('id');
395
+        this.bundledTransports[endpointId] = $(channelBundles[i]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
396
+    }
397
+
382 398
     console.log('remote channels', this.channels);
383 399
 
384 400
     // Notify that the focus has created the conference on the bridge
@@ -390,6 +406,11 @@ ColibriFocus.prototype.createdConference = function (result) {
390 406
         's=-\r\n' +
391 407
         't=0 0\r\n' +
392 408
         /* Audio */
409
+        (config.useBundle
410
+            ? ('a=group:BUNDLE audio video' +
411
+                (config.openSctp ? ' data' : '') +
412
+               '\r\n')
413
+            : '') +
393 414
         'm=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n' +
394 415
         'c=IN IP4 0.0.0.0\r\n' +
395 416
         'a=rtcp:1 IN IP4 0.0.0.0\r\n' +
@@ -490,7 +511,13 @@ ColibriFocus.prototype.createdConference = function (result) {
490 511
         }
491 512
 
492 513
         // FIXME: should take code from .fromJingle
493
-        tmp = $(this.mychannel[channel]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
514
+        var channelBundleId = $(this.mychannel[channel]).attr('channel-bundle-id');
515
+        if (typeof channelBundleId != 'undefined') {
516
+            tmp = this.bundledTransports[channelBundleId];
517
+        } else {
518
+            tmp = $(this.mychannel[channel]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
519
+        }
520
+
494 521
         if (tmp.length) {
495 522
             bridgeSDP.media[channel] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
496 523
             bridgeSDP.media[channel] += 'a=ice-pwd:' + tmp.attr('pwd') + '\r\n';
@@ -514,7 +541,7 @@ ColibriFocus.prototype.createdConference = function (result) {
514 541
                 function (answer) {
515 542
                     self.peerconnection.setLocalDescription(answer,
516 543
                         function () {
517
-                            console.log('setLocalDescription succeded.');
544
+                            console.log('setLocalDescription succeeded.');
518 545
                             // make sure our presence is updated
519 546
                             $(document).trigger('setLocalDescription.jingle', [self.sid]);
520 547
                             var elem = $iq({to: self.bridgejid, type: 'get'});
@@ -570,7 +597,7 @@ ColibriFocus.prototype.createdConference = function (result) {
570 597
                                 },
571 598
                                 function (error) {
572 599
                                     console.error(
573
-                                        "ERROR setLocalDescription succeded",
600
+                                        "ERROR sending colibri message",
574 601
                                         error, elem);
575 602
                                 }
576 603
                             );
@@ -616,7 +643,9 @@ ColibriFocus.prototype.initiate = function (peer, isInitiator) {
616 643
         var localSDP = new SDP(this.peerconnection.localDescription.sdp);
617 644
         // throw away stuff we don't want
618 645
         // not needed with static offer
619
-        sdp.removeSessionLines('a=group:');
646
+        if (!config.useBundle) {
647
+            sdp.removeSessionLines('a=group:');
648
+        }
620 649
         sdp.removeSessionLines('a=msid-semantic:'); // FIXME: not mapped over jingle anyway...
621 650
         for (var i = 0; i < sdp.media.length; i++) {
622 651
             if (!config.useRtcpMux){
@@ -670,7 +699,14 @@ ColibriFocus.prototype.initiate = function (peer, isInitiator) {
670 699
             sdp.media[j] += 'a=ssrc:' + '3735928559' + ' ' + 'mslabel:mixedmslabel' + '\r\n';
671 700
         }
672 701
 
673
-        tmp = chan.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
702
+        // In the case of bundle, we add each candidate to all m= lines/jingle contents,
703
+        // just as chrome does
704
+        if (config.useBundle){
705
+            tmp = this.bundledTransports[chan.attr('channel-bundle-id')];
706
+        } else {
707
+            tmp = chan.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
708
+        }
709
+
674 710
         if (tmp.length) {
675 711
             if (tmp.attr('ufrag'))
676 712
                 sdp.media[j] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
@@ -757,12 +793,17 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
757 793
     localSDP.media.forEach(function (media, channel) {
758 794
         var name = SDPUtil.parse_mid(SDPUtil.find_line(media, 'a=mid:'));
759 795
         var elemName;
796
+        var endpointId = peer.substr(1 + peer.lastIndexOf('/'));
760 797
         var elemAttrs
761 798
             = {
762 799
                 initiator: 'true',
763 800
                 expire: self.channelExpire,
764
-                endpoint: peer.substr(1 + peer.lastIndexOf('/'))
801
+                endpoint: endpointId
765 802
             };
803
+        if (config.useBundle) {
804
+            elemAttrs['channel-bundle-id'] = endpointId;
805
+        }
806
+
766 807
 
767 808
         if ('data' == name)
768 809
         {
@@ -785,7 +826,8 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
785 826
     this.connection.sendIQ(elem,
786 827
         function (result) {
787 828
             var contents = $(result).find('>conference>content').get();
788
-            for (var i = 0; i < contents.length; i++) {
829
+            var i;
830
+            for (i = 0; i < contents.length; i++) {
789 831
                 var channelXml = $(contents[i]).find('>channel');
790 832
                 if (channelXml.length)
791 833
                 {
@@ -797,6 +839,12 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
797 839
                 }
798 840
                 self.channels[index][i] = tmp[0];
799 841
             }
842
+            var channelBundles = $(result).find('>conference>channel-bundle');
843
+            for (i = 0; i < channelBundles.length; i++)
844
+            {
845
+                var endpointId = $(channelBundles[i]).attr('id');
846
+                self.bundledTransports[endpointId] = $(channelBundles[i]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
847
+            }
800 848
             self.initiate(peer, true);
801 849
         },
802 850
         function (error) {
@@ -1023,6 +1071,12 @@ ColibriFocus.prototype.addIceCandidate = function (session, elem) {
1023 1071
     $(elem).each(function () {
1024 1072
         var name = $(this).attr('name');
1025 1073
 
1074
+        // If we are using bundle, audio/video/data channel will have the same candidates, so only send them for
1075
+        // the audio channel.
1076
+        if (config.useBundle && name !== 'audio') {
1077
+            return;
1078
+        }
1079
+
1026 1080
         var channel = name == 'audio' ? 0 : 1; // FIXME: search mlineindex in localdesc
1027 1081
         if (name != 'audio' && name != 'video')
1028 1082
             channel = 2; // name == 'data'

Loading…
Cancel
Save