11/*
2- * SIP version 0.6.3
2+ * SIP version 0.6.4
33 * Copyright (c) 2014-2014 Junction Networks, Inc <http://www.onsip.com>
44 * Homepage: http://sipjs.com
55 * License: http://sipjs.com/license/
@@ -37,7 +37,7 @@ module.exports={
3737 "name" : "sip.js" ,
3838 "title" : "SIP.js" ,
3939 "description" : "A simple, intuitive, and powerful JavaScript signaling library" ,
40- "version" : "0.6.3 " ,
40+ "version" : "0.6.4 " ,
4141 "main" : "src/SIP.js" ,
4242 "homepage" : "http://sipjs.com" ,
4343 "author" :
"Will Mitchell <[email protected] >" , @@ -2445,12 +2445,8 @@ module.exports = function(SIP) {
24452445 * as to most easily track when particular hacks may not be necessary anymore.
24462446 */
24472447
2448- module . exports = function ( window ) {
2449-
2450- var Hacks ;
2451-
2452- Hacks = {
2453-
2448+ module . exports = function ( SIP ) {
2449+ var Hacks = {
24542450 AllBrowsers : {
24552451 maskDtls : function ( message ) {
24562452 if ( message . body ) {
@@ -2478,12 +2474,6 @@ Hacks = {
24782474 return window . mozRTCPeerConnection !== undefined ;
24792475 } ,
24802476
2481- cannotHandleRelayCandidates : function ( message ) {
2482- if ( this . isFirefox ( ) && message . body ) {
2483- message . body = message . body . replace ( / r e l a y / g, 'host generation 0' ) ;
2484- }
2485- } ,
2486-
24872477 cannotHandleExtraWhitespace : function ( message ) {
24882478 if ( this . isFirefox ( ) && message . body ) {
24892479 message . body = message . body . replace ( / \r \n / g, "\r\n" ) ;
@@ -2516,7 +2506,7 @@ Hacks = {
25162506 if ( mlines [ i ] . toString ( ) . search ( / i = .* / ) >= 0 ) {
25172507 insertAt = sdp . indexOf ( mlines [ i ] . toString ( ) ) + mlines [ i ] . toString ( ) . length ;
25182508 if ( sdp . substr ( insertAt , 2 ) !== 'c=' ) {
2519- sdp = sdp . substr ( 0 , insertAt ) + '\r\nc=IN IP 4 0.0.0.0' + sdp . substr ( insertAt ) ;
2509+ sdp = sdp . substr ( 0 , insertAt ) + '\r\nc=IN IP4 0.0.0.0' + sdp . substr ( insertAt ) ;
25202510 }
25212511
25222512 // else add the C line if it's missing
@@ -2527,6 +2517,19 @@ Hacks = {
25272517 }
25282518 }
25292519 return sdp ;
2520+ } ,
2521+
2522+ hasIncompatibleCLineWithSomeSIPEndpoints : function ( sdp ) {
2523+ /*
2524+ * Firefox appears to be following https://tools.ietf.org/html/rfc5245#section-9.1.1.1
2525+ * and using a c line IP address of 0.0.0.0. This is completely valid, however it is
2526+ * causing some endpoints (such as FreeSWITCH) to interpret the SDP as being on hold
2527+ * https://freeswitch.org/jira/browse/FS-6955. To get around this issue we pull the
2528+ * replace the c line with 1.1.1.1 which SIP clients do not interpret as hold.
2529+ * This makes the other endpoint believe that the call is not on hold and audio flows
2530+ * because ICE determines the media pathway (not the c line).
2531+ */
2532+ return sdp . replace ( / ( 0 \. 0 \. 0 \. 0 ) / gmi, SIP . Utils . getRandomTestNetIP ( ) ) ;
25302533 }
25312534 } ,
25322535
@@ -2554,10 +2557,10 @@ Hacks = {
25542557 }
25552558} ;
25562559
2557-
25582560return Hacks ;
25592561} ;
25602562
2563+
25612564} , { } ] , 11 :[ function ( _dereq_ , module , exports ) {
25622565
25632566module . exports = ( function ( ) {
@@ -3623,7 +3626,7 @@ module.exports = (function(window) {
36233626 var WebRTCMediaStreamManager = _dereq_ ( './WebRTC/MediaStreamManager.js' ) ( SIP ) ;
36243627 SIP . WebRTC = _dereq_ ( './WebRTC.js' ) ( SIP . Utils , window , WebRTCMediaHandler , WebRTCMediaStreamManager ) ;
36253628 _dereq_ ( './UA.js' ) ( SIP , window ) ;
3626- SIP . Hacks = _dereq_ ( './Hacks.js' ) ( window ) ;
3629+ SIP . Hacks = _dereq_ ( './Hacks.js' ) ( SIP ) ;
36273630 _dereq_ ( './SanityCheck.js' ) ( SIP ) ;
36283631 SIP . DigestAuthentication = _dereq_ ( './DigestAuthentication.js' ) ( SIP . Utils ) ;
36293632 SIP . Grammar = _dereq_ ( './Grammar/dist/Grammar' ) ( SIP ) ;
@@ -5507,7 +5510,6 @@ InviteServerContext = function(ua, request) {
55075510 }
55085511
55095512 //TODO: move this into media handler
5510- SIP . Hacks . Firefox . cannotHandleRelayCandidates ( request ) ;
55115513 SIP . Hacks . Firefox . cannotHandleExtraWhitespace ( request ) ;
55125514 SIP . Hacks . AllBrowsers . maskDtls ( request ) ;
55135515
@@ -5805,7 +5807,7 @@ InviteServerContext.prototype = {
58055807 */
58065808 accept : function ( options ) {
58075809 options = options || { } ;
5808-
5810+ options = SIP . Utils . desugarSessionOptions ( options ) ;
58095811 SIP . Utils . optionsOverride ( options , 'media' , 'mediaConstraints' , true , this . logger , this . ua . configuration . media ) ;
58105812 this . mediaHint = options . media ;
58115813
@@ -5983,7 +5985,6 @@ InviteServerContext.prototype = {
59835985 if ( ! this . hasAnswer ) {
59845986 if ( request . body && request . getHeader ( 'content-type' ) === 'application/sdp' ) {
59855987 // ACK contains answer to an INVITE w/o SDP negotiation
5986- SIP . Hacks . Firefox . cannotHandleRelayCandidates ( request ) ;
59875988 SIP . Hacks . Firefox . cannotHandleExtraWhitespace ( request ) ;
59885989 SIP . Hacks . AllBrowsers . maskDtls ( request ) ;
59895990
@@ -6353,7 +6354,6 @@ InviteClientContext.prototype = {
63536354 return ;
63546355 }
63556356
6356- SIP . Hacks . Firefox . cannotHandleRelayCandidates ( response ) ;
63576357 SIP . Hacks . Firefox . cannotHandleExtraWhitespace ( response ) ;
63586358 SIP . Hacks . AllBrowsers . maskDtls ( response ) ;
63596359
@@ -6480,7 +6480,6 @@ InviteClientContext.prototype = {
64806480 break ;
64816481 }
64826482
6483- SIP . Hacks . Firefox . cannotHandleRelayCandidates ( response ) ;
64846483 SIP . Hacks . Firefox . cannotHandleExtraWhitespace ( response ) ;
64856484 SIP . Hacks . AllBrowsers . maskDtls ( response ) ;
64866485
@@ -8486,6 +8485,7 @@ UA.prototype.isConnected = function() {
84868485 */
84878486UA . prototype . invite = function ( target , options ) {
84888487 options = options || { } ;
8488+ options = SIP . Utils . desugarSessionOptions ( options ) ;
84898489 SIP . Utils . optionsOverride ( options , 'media' , 'mediaConstraints' , true , this . logger ) ;
84908490
84918491 var context = new SIP . InviteClientContext ( this , target , options ) ;
@@ -9132,6 +9132,7 @@ UA.prototype.loadConfig = function(configuration) {
91329132 // Hacks
91339133 hackViaTcp : false ,
91349134 hackIpInContact : false ,
9135+ hackWssInTransport : false ,
91359136
91369137 //autostarting
91379138 autostart : true ,
@@ -9181,14 +9182,19 @@ UA.prototype.loadConfig = function(configuration) {
91819182
91829183 SIP . Utils . optionsOverride ( configuration , 'rel100' , 'reliable' , true , this . logger , SIP . C . supported . UNSUPPORTED ) ;
91839184
9185+ var emptyArraysAllowed = [ 'stunServers' , 'turnServers' ] ;
9186+
91849187 // Check Optional parameters
91859188 for ( parameter in UA . configuration_check . optional ) {
91869189 aliasUnderscored ( parameter , this . logger ) ;
91879190 if ( configuration . hasOwnProperty ( parameter ) ) {
91889191 value = configuration [ parameter ] ;
91899192
9190- // If the parameter value is null, empty string,undefined, or empty array then apply its default value.
9191- if ( value === null || value === "" || value === undefined || ( value instanceof Array && value . length === 0 ) ) { continue ; }
9193+ // If the parameter value is an empty array, but shouldn't be, apply its default value.
9194+ if ( value instanceof Array && value . length === 0 && emptyArraysAllowed . indexOf ( parameter ) < 0 ) { continue ; }
9195+
9196+ // If the parameter value is null, empty string, or undefined then apply its default value.
9197+ if ( value === null || value === "" || value === undefined ) { continue ; }
91929198 // If it's a number with NaN value then also apply its default value.
91939199 // NOTE: JS does not allow "value === NaN", the following does the work:
91949200 else if ( typeof ( value ) === 'number' && isNaN ( value ) ) { continue ; }
@@ -9254,7 +9260,7 @@ UA.prototype.loadConfig = function(configuration) {
92549260 this . contact = {
92559261 pub_gruu : null ,
92569262 temp_gruu : null ,
9257- uri : new SIP . URI ( 'sip' , SIP . Utils . createRandomToken ( 8 ) , settings . viaHost , null , { transport : ' ws'} ) ,
9263+ uri : new SIP . URI ( 'sip' , SIP . Utils . createRandomToken ( 8 ) , settings . viaHost , null , { transport : ( ( settings . hackWssInTransport ) ? 'wss' : ' ws') } ) ,
92589264 toString : function ( options ) {
92599265 options = options || { } ;
92609266
@@ -9264,7 +9270,7 @@ UA.prototype.loadConfig = function(configuration) {
92649270 contact = '<' ;
92659271
92669272 if ( anonymous ) {
9267- contact += ( this . temp_gruu || 'sip:[email protected] ;transport=ws' ) . toString ( ) ; 9273+ contact += ( this . temp_gruu || ( 'sip:[email protected] ;transport=' + ( settings . hackWssInTransport ) ? 'wss' : ' ws') ) . toString ( ) ; 92689274 } else {
92699275 contact += ( this . pub_gruu || this . uri ) . toString ( ) ;
92709276 }
@@ -9334,6 +9340,7 @@ UA.configuration_skeleton = (function() {
93349340 "displayName" ,
93359341 "hackViaTcp" , // false.
93369342 "hackIpInContact" , //false
9343+ "hackWssInTransport" , //false
93379344 "instanceId" ,
93389345 "noAnswerTimeout" , // 30 seconds.
93399346 "password" ,
@@ -9508,6 +9515,12 @@ UA.configuration_check = {
95089515 }
95099516 } ,
95109517
9518+ hackWssInTransport : function ( hackWssInTransport ) {
9519+ if ( typeof hackWssInTransport === 'boolean' ) {
9520+ return hackWssInTransport ;
9521+ }
9522+ } ,
9523+
95119524 instanceId : function ( instanceId ) {
95129525 if ( typeof instanceId !== 'string' ) {
95139526 return ;
@@ -9912,6 +9925,7 @@ SIP.URI = URI;
99129925} ;
99139926
99149927} , { } ] , 30 :[ function ( _dereq_ , module , exports ) {
9928+ ( function ( global ) {
99159929/**
99169930 * @fileoverview Utils
99179931 */
@@ -9948,6 +9962,25 @@ Utils= {
99489962 options [ winner ] = options [ winner ] || options [ loser ] || defaultValue ;
99499963 } ,
99509964
9965+ desugarSessionOptions : function desugarSessionOptions ( options ) {
9966+ if ( global . HTMLMediaElement && options instanceof global . HTMLMediaElement ) {
9967+ options = {
9968+ media : {
9969+ constraints : {
9970+ audio : true ,
9971+ video : options . tagName === 'VIDEO'
9972+ } ,
9973+ render : {
9974+ remote : {
9975+ video : options
9976+ }
9977+ }
9978+ }
9979+ } ;
9980+ }
9981+ return options ;
9982+ } ,
9983+
99519984 str_utf8_length : function ( string ) {
99529985 return encodeURIComponent ( string ) . replace ( / % [ A - F \d ] { 2 } / g, 'U' ) . length ;
99539986 } ,
@@ -10376,6 +10409,7 @@ Utils= {
1037610409SIP . Utils = Utils ;
1037710410} ;
1037810411
10412+ } ) . call ( this , typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : { } )
1037910413} , { } ] , 31 :[ function ( _dereq_ , module , exports ) {
1038010414/**
1038110415 * @fileoverview WebRTC
@@ -10435,6 +10469,7 @@ var MediaHandler = function(session, options) {
1043510469 'userMedia' ,
1043610470 'userMediaFailed' ,
1043710471 'iceGathering' ,
10472+ 'iceCandidate' ,
1043810473 'iceComplete' ,
1043910474 'iceFailed' ,
1044010475 'getDescription' ,
@@ -10472,7 +10507,9 @@ var MediaHandler = function(session, options) {
1047210507 /* Change 'url' to 'urls' whenever this issue is solved:
1047310508 * https://code.google.com/p/webrtc/issues/detail?id=2096
1047410509 */
10475- servers . push ( { 'url' : stunServers } ) ;
10510+ [ ] . concat ( stunServers ) . forEach ( function ( server ) {
10511+ servers . push ( { 'url' : server } ) ;
10512+ } ) ;
1047610513
1047710514 length = turnServers . length ;
1047810515 for ( idx = 0 ; idx < length ; idx ++ ) {
@@ -10497,6 +10534,7 @@ var MediaHandler = function(session, options) {
1049710534 } ;
1049810535
1049910536 this . peerConnection . onicecandidate = function ( e ) {
10537+ self . emit ( 'iceCandidate' , e ) ;
1050010538 if ( e . candidate ) {
1050110539 self . logger . log ( 'ICE candidate received: ' + ( e . candidate . candidate === null ? null : e . candidate . candidate . trim ( ) ) ) ;
1050210540 } else if ( self . onIceCompleted !== undefined ) {
@@ -10831,6 +10869,7 @@ MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, {
1083110869
1083210870 sdp = SIP . Hacks . Chrome . needsExplicitlyInactiveSDP ( sdp ) ;
1083310871 sdp = SIP . Hacks . AllBrowsers . unmaskDtls ( sdp ) ;
10872+ sdp = SIP . Hacks . Firefox . hasIncompatibleCLineWithSomeSIPEndpoints ( sdp ) ;
1083410873
1083510874 var sdpWrapper = {
1083610875 type : methodName === 'createOffer' ? 'offer' : 'answer' ,
0 commit comments