@babblevoice/babble-drachtio-callmanager 1.3.7 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/call.js +51 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,14 +37,14 @@ const r = new Registrar( {
|
|
|
37
37
|
"staletime": 180, /* number of seconds we consider a client stale if we don't hear a response from an OPTIONS or REGISTER ping */
|
|
38
38
|
"expires": 3600, /* default expires */
|
|
39
39
|
"minexpires": 3600, /* Force the client with 423 to extend expires to this amount - conflicts with regping */
|
|
40
|
-
"
|
|
40
|
+
"userlookup": passwordLookup
|
|
41
41
|
} )
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
const cm = new CallManager( {
|
|
45
45
|
"srf": srf,
|
|
46
46
|
"registrar": r,
|
|
47
|
-
"
|
|
47
|
+
"userlookup": passwordLookup
|
|
48
48
|
} )
|
|
49
49
|
|
|
50
50
|
cm.on( "call", async ( c ) => {
|
|
@@ -59,7 +59,7 @@ CallManager takes an options object as part of its construction. srf and a passw
|
|
|
59
59
|
```json
|
|
60
60
|
{
|
|
61
61
|
"srf": srf,
|
|
62
|
-
"
|
|
62
|
+
"userlookup": passwordLookup,
|
|
63
63
|
"preferedcodecs": "pcmu pcma 2833",
|
|
64
64
|
"transcode": true
|
|
65
65
|
}
|
package/lib/call.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
const { v4: uuidv4 } = require( "uuid" )
|
|
3
3
|
const events = require( "events" )
|
|
4
|
+
const dns = require( "node:dns" )
|
|
4
5
|
|
|
5
6
|
const projectrtp = require( "@babblevoice/projectrtp" ).projectrtp
|
|
6
7
|
|
|
@@ -854,6 +855,25 @@ class call {
|
|
|
854
855
|
return this
|
|
855
856
|
}
|
|
856
857
|
|
|
858
|
+
/* A simple implimentation if we are offered candidates */
|
|
859
|
+
static async _parsesdpcandidates( target, sdp ) {
|
|
860
|
+
|
|
861
|
+
if( Array.isArray( sdp.media[ 0 ].candidates ) ) {
|
|
862
|
+
let candidates = sdp.media[ 0 ].candidates
|
|
863
|
+
if( candidates.length > 0 ) {
|
|
864
|
+
candidates.sort( ( l, r ) => { return r.priority - l.priority } )
|
|
865
|
+
target.port = candidates[ 0 ].port
|
|
866
|
+
|
|
867
|
+
await new Promise( ( r ) => {
|
|
868
|
+
dns.lookup( candidates[ 0 ].ip, ( err, result ) => {
|
|
869
|
+
if( !err ) target.address = result
|
|
870
|
+
r()
|
|
871
|
+
} )
|
|
872
|
+
} )
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
857
877
|
/**
|
|
858
878
|
On an early negotiation we have already sent our sdp without
|
|
859
879
|
knowing what the otherside is going to offer. We now have the
|
|
@@ -878,11 +898,13 @@ class call {
|
|
|
878
898
|
let channeldef
|
|
879
899
|
if( this._iswebrtc ) {
|
|
880
900
|
let actpass = "active"
|
|
881
|
-
if( "
|
|
901
|
+
if( "active" == this.sdp.remote.sdp.media[ 0 ].setup ) actpass = "passive" /* act|pass|actpass */
|
|
902
|
+
|
|
903
|
+
await call._parsesdpcandidates( target, this.sdp.remote.sdp )
|
|
882
904
|
|
|
883
905
|
channeldef = call._createchannelremotedef(
|
|
884
|
-
target.address,
|
|
885
|
-
target.port,
|
|
906
|
+
target.address,
|
|
907
|
+
target.port,
|
|
886
908
|
target.audio.payloads[ 0 ],
|
|
887
909
|
this.sdp.remote.sdp.media[ 0 ].fingerprint.hash,
|
|
888
910
|
actpass ).remote
|
|
@@ -1300,6 +1322,9 @@ class call {
|
|
|
1300
1322
|
if( !remoteaudio ) return
|
|
1301
1323
|
|
|
1302
1324
|
this.sdp.remote.select( this.selectedcodec )
|
|
1325
|
+
|
|
1326
|
+
await call._parsesdpcandidates( remoteaudio, this.sdp.remote.sdp )
|
|
1327
|
+
|
|
1303
1328
|
let channeldef = call._createchannelremotedef( remoteaudio.address, remoteaudio.port, remoteaudio.audio.payloads[ 0 ] )
|
|
1304
1329
|
|
|
1305
1330
|
let iswebrtc = this._iswebrtc
|
|
@@ -1440,6 +1465,8 @@ class call {
|
|
|
1440
1465
|
|
|
1441
1466
|
this._timers.anyevent = setTimeout( () => {
|
|
1442
1467
|
let r = this._promises.resolve.channelevent
|
|
1468
|
+
this._promises.promise.channelevent = false
|
|
1469
|
+
this._promises.resolve.channelevent = false
|
|
1443
1470
|
if( r ) r( "timeout" )
|
|
1444
1471
|
}, timeout * 1000 )
|
|
1445
1472
|
|
|
@@ -1633,6 +1660,26 @@ class call {
|
|
|
1633
1660
|
this._onhangup( "wire" )
|
|
1634
1661
|
} )
|
|
1635
1662
|
|
|
1663
|
+
dialog.on( "info", async ( req, res ) => {
|
|
1664
|
+
if( "application/dtmf-relay" === req.get( "Content-Type" ).toLowerCase() &&
|
|
1665
|
+
parseInt( req.get( "content-length" ) ) > 0 ) {
|
|
1666
|
+
|
|
1667
|
+
const matches = req.msg.body.match( /Signal=(.+?)/i )
|
|
1668
|
+
if( !matches || !Array.isArray( matches ) || matches.length < 2 ) return res.send( 415, "Badly formated SIP INFO" )
|
|
1669
|
+
|
|
1670
|
+
const digit = matches[ 1 ]
|
|
1671
|
+
this._tevent( digit )
|
|
1672
|
+
const other = this.other
|
|
1673
|
+
if( other && other.channels.audio ) {
|
|
1674
|
+
other.channels.audio.dtmf( digit )
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
return res.send( 200 )
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
return res.send( 415, "Unsupported Media Type" )
|
|
1681
|
+
} )
|
|
1682
|
+
|
|
1636
1683
|
dialog.on( "modify", ( req, res ) => {
|
|
1637
1684
|
// The application must respond, using the res parameter provided.
|
|
1638
1685
|
if( "INVITE" === req.msg.method ) {
|
|
@@ -2067,7 +2114,7 @@ class call {
|
|
|
2067
2114
|
|
|
2068
2115
|
} else if( "uac" === this.type ) {
|
|
2069
2116
|
try {
|
|
2070
|
-
this._req.cancel()
|
|
2117
|
+
if( this._req ) this._req.cancel()
|
|
2071
2118
|
} catch( e ) { console.error( e ) }
|
|
2072
2119
|
|
|
2073
2120
|
this.canceled = true
|