@babblevoice/babble-drachtio-callmanager 1.0.2 → 1.1.0

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/index.js CHANGED
@@ -3,7 +3,7 @@ const assert = require( "assert" )
3
3
  const callmanager = require( "./lib/callmanager.js" )
4
4
  const store = require( "./lib/store.js" )
5
5
 
6
- const projectrtp = require( "projectrtp" ).projectrtp
6
+ const projectrtp = require( "@babblevoice/projectrtp" ).projectrtp
7
7
 
8
8
  const default_options = {
9
9
  "preferedcodecs": "g722 ilbc pcmu pcma",
package/lib/call.js CHANGED
@@ -2,13 +2,13 @@
2
2
  const { v4: uuidv4 } = require( "uuid" )
3
3
  const events = require( "events" )
4
4
 
5
- const projectrtp = require( "projectrtp" ).projectrtp
5
+ const projectrtp = require( "@babblevoice/projectrtp" ).projectrtp
6
6
 
7
7
  const parseuri = require( "drachtio-srf" ).parseUri
8
8
  const sdpgen = require( "./sdp.js" )
9
9
  const callstore = require( "./store.js" )
10
10
 
11
- const sipauth = require( "babble-drachtio-auth" )
11
+ const sipauth = require( "@babblevoice/babble-drachtio-auth" )
12
12
 
13
13
  /*
14
14
  Enum for different reasons for hangup.
@@ -65,7 +65,9 @@ const inboundsiperros = {
65
65
  404: hangupcodes.UNALLOCATED_NUMBER
66
66
  }
67
67
 
68
- var callmanager
68
+ var callmanager = {
69
+ "options": {}
70
+ }
69
71
 
70
72
  /** @class */
71
73
  class call {
@@ -110,6 +112,14 @@ class call {
110
112
  "refered": false
111
113
  }
112
114
 
115
+ /**
116
+ * @private
117
+ */
118
+ this._state = {
119
+ "_onhangup": false,
120
+ "_hangup": false
121
+ }
122
+
113
123
  /**
114
124
  @member
115
125
  @summary Channels which have been created
@@ -240,6 +250,10 @@ class call {
240
250
  }
241
251
  }
242
252
 
253
+ this._promises.promise.hangup = new Promise( ( r ) => {
254
+ this._promises.resolve.hangup = r
255
+ } )
256
+
243
257
  /**
244
258
  @member {object}
245
259
  @private
@@ -1025,7 +1039,9 @@ class call {
1025
1039
 
1026
1040
  }, 50000 )
1027
1041
 
1028
- if( !this._auth.requestauth( this._req, this._res ) ) return this.hangup( hangupcodes.FORBIDDEN )
1042
+ if( !this._auth.requestauth( this._req, this._res ) ) {
1043
+ reject( this.hangup( hangupcodes.FORBIDDEN ) )
1044
+ }
1029
1045
  } )
1030
1046
  }
1031
1047
 
@@ -1060,7 +1076,10 @@ class call {
1060
1076
  return this._auth.requestauth( this._req, this._res )
1061
1077
  }
1062
1078
 
1063
- this.hangup( hangupcodes.FORBIDDEN )
1079
+ this._em.emit( "call.authed.failed", this )
1080
+ callmanager.options.em.emit( "call.authed.failed", this )
1081
+
1082
+ await this.hangup( hangupcodes.FORBIDDEN )
1064
1083
 
1065
1084
  let r = this._promises.reject.auth
1066
1085
  this._promises.resolve.auth = false
@@ -1071,9 +1090,6 @@ class call {
1071
1090
 
1072
1091
  if( r ) r()
1073
1092
 
1074
- this._em.emit( "call.authed.failed", this )
1075
- callmanager.options.em.emit( "call.authed.failed", this )
1076
-
1077
1093
  return
1078
1094
  }
1079
1095
 
@@ -1323,16 +1339,20 @@ class call {
1323
1339
  this._em.emit( "channel", { "call": this, "event": e } )
1324
1340
  } catch ( e ) { console.error( e ) }
1325
1341
 
1326
- if( "close" === e.action && this.destroyed ) {
1342
+ if( "close" === e.action ) {
1327
1343
  /* keep a record */
1328
- this.channels.closed.audio.push( e )
1329
-
1330
- if( "requested" == e.reason ) {
1344
+ if( this.channels.audio.history ) {
1345
+ this.channels.closed.audio.push( this.channels.audio.history )
1346
+ } else {
1347
+ this.channels.closed.audio.push( e )
1348
+ }
1349
+
1350
+ this.channels.audio = false
1351
+ if( this._state._onhangup ) {
1331
1352
  this._cleanup()
1332
1353
  return
1333
1354
  }
1334
1355
 
1335
- this.channels.audio = false
1336
1356
  this.hangup() /* ? */
1337
1357
  return
1338
1358
  }
@@ -1567,8 +1587,8 @@ class call {
1567
1587
 
1568
1588
  }, callmanager.options.seexpire )
1569
1589
 
1570
- dialog.on( "destroy", async ( req ) => {
1571
- await this._onhangup( "wire" )
1590
+ dialog.on( "destroy", ( req ) => {
1591
+ this._onhangup( "wire" )
1572
1592
  } )
1573
1593
 
1574
1594
  dialog.on( "modify", ( req, res ) => {
@@ -1770,11 +1790,21 @@ class call {
1770
1790
  b_1.detach()
1771
1791
  b_2.detach()
1772
1792
 
1793
+ a_1.channels.audio.unmix()
1794
+ b_1.channels.audio.unmix()
1795
+ b_2.channels.audio.unmix()
1796
+ c_1.channels.audio.unmix()
1797
+
1773
1798
  /* Swap channels and update */
1799
+
1800
+ /* copy all first */
1774
1801
  let a_1_audio = a_1.channels.audio
1775
1802
  let a_1_sdp = a_1.sdp.local
1803
+ let a_1_chem = a_1.channels.audio.em
1804
+ let b_2_chem = b_2.channels.audio.em
1776
1805
 
1777
1806
  a_1.channels.audio = b_2.channels.audio
1807
+ a_1.channels.audio.em = a_1_chem
1778
1808
  a_1.sdp.local = b_2.sdp.local
1779
1809
 
1780
1810
  a_1.sdp.local
@@ -1788,11 +1818,11 @@ class call {
1788
1818
  }
1789
1819
 
1790
1820
  /* Link logically */
1791
- a_1.children.add( c_1 )
1792
- c_1.parent = a_1
1821
+ a_1.adopt( c_1 )
1793
1822
 
1794
1823
  /* this one will be hung up soon anyway - so it to has to close the correct one */
1795
1824
  b_2.channels.audio = a_1_audio
1825
+ b_2.channels.audio.em = b_2_chem
1796
1826
  b_2.sdp.local = a_1_sdp
1797
1827
 
1798
1828
  failed = false
@@ -1879,54 +1909,8 @@ class call {
1879
1909
  }
1880
1910
 
1881
1911
  /**
1882
- When our dialog has confirmed we have hung up
1883
- @param {string} [us] - "us"|"wire"
1884
- @param {object} reason - one of the reasons from the hangupcodes enum - only used if we havn't alread set our reason
1885
- @private
1886
- */
1887
- async _onhangup( src = "us", reason ) {
1888
-
1889
- if( this.destroyed ) return
1890
- this.destroyed = true
1891
-
1892
- this._sethangupcause( src, reason )
1893
- await callstore.delete( this )
1894
-
1895
- let r = this._promises.resolve.hangup
1896
- this._promises.promise.hangup = false
1897
- this._promises.resolve.hangup = false
1898
- try{
1899
- if( r ) r()
1900
- } catch( e ) {
1901
- console.error( e )
1902
- }
1903
-
1904
- let hangups = []
1905
- for( let child of this.children ) {
1906
- hangups.push( child.hangup( this.hangup_cause ) )
1907
- }
1908
-
1909
- if( hangups.length > 0 ) {
1910
- await Promise.all( hangups )
1911
- }
1912
-
1913
- this._em.emit( "call.destroyed", this )
1914
- callmanager.options.em.emit( "call.destroyed", this )
1915
- let audiochannel = this.channels.audio
1916
- this.channels.audio = false
1917
- if( audiochannel ) {
1918
- audiochannel.close()
1919
- this._timers.cleanup = setTimeout( () => {
1920
- console.error( "Timeout waiting for channel close, cleaning up anyway" )
1921
- this._cleanup()
1922
- }, 60000 )
1923
- } else {
1924
- this._cleanup()
1925
- }
1926
- }
1927
-
1928
- /**
1929
- Use this as our destructor. This may get called more than once depending on what is going on
1912
+ Use this as our destructor. This may get called more than once depending on what is going on.
1913
+ Clean up all timers and tidy up any outstanding promises.
1930
1914
  @private
1931
1915
  */
1932
1916
  _cleanup() {
@@ -1951,25 +1935,82 @@ class call {
1951
1935
  this._promises.resolve[ key ] = false
1952
1936
  }
1953
1937
 
1938
+ /* Call outstanding resolves for promises - this will trigger out hangup promise also */
1954
1939
  resolves.forEach( r => r( this ) )
1955
1940
 
1956
1941
  this.removealllisteners()
1957
1942
 
1943
+ this._em.emit( "call.destroyed", this )
1944
+ callmanager.options.em.emit( "call.destroyed", this )
1945
+
1958
1946
  this._em.emit( "call.reporting", this )
1959
1947
  callmanager.options.em.emit( "call.reporting", this )
1960
1948
  }
1961
1949
 
1962
1950
  /**
1963
- Hangup the call with reason.
1964
- @param {object} reason - one of the reasons from the hangupcodes enum
1951
+ * Used by our frame to a) continue a hangup which has been initiated by either us or the network.
1952
+ * Complete the hangup, including hanging up all children and waiting for them to complete their
1953
+ * hangup.
1954
+ * @param {string} [us] - "us"|"wire"
1955
+ * @param {object} reason - one of the reasons from the hangupcodes enum - only used if we havn't alread set our reason
1956
+ * @private
1957
+ */
1958
+ async _onhangup( src = "us", reason ) {
1959
+
1960
+ if( this._state._onhangup ) {
1961
+ await this.waitforhangup()
1962
+ return
1963
+ }
1964
+ this._state._onhangup = true
1965
+
1966
+ /* hangup our children */
1967
+ let hangups = []
1968
+ for( let child of this.children ) {
1969
+ hangups.push( child.hangup( this.hangup_cause ) )
1970
+ }
1971
+
1972
+ /* wait for all children to have completed their hangup */
1973
+ if( hangups.length > 0 ) {
1974
+ await Promise.all( hangups )
1975
+ }
1976
+
1977
+ await callstore.delete( this )
1978
+
1979
+ this._sethangupcause( src, reason )
1980
+
1981
+ let audiochannel = this.channels.audio
1982
+ this.channels.audio = false
1983
+ /* flag destroyed so when we receive our close event we know what to do */
1984
+ this.destroyed = true
1985
+ if( audiochannel ) {
1986
+ audiochannel.close()
1987
+ this._timers.cleanup = setTimeout( () => {
1988
+ console.error( "Timeout waiting for channel close, cleaning up anyway", this.uuid )
1989
+ this._cleanup()
1990
+ }, 60 * 1000 )
1991
+
1992
+ await this.waitforhangup()
1993
+ } else {
1994
+ this._cleanup()
1995
+ }
1996
+ }
1997
+
1998
+ /**
1999
+ * Hangup the call with reason. Public interface for callers to use.
2000
+ * @param {object} reason - one of the reasons from the hangupcodes enum
1965
2001
  */
1966
2002
  async hangup( reason ) {
1967
2003
 
1968
- if( this.destroyed ) return
2004
+ if( this._state._hangup || this._state._onhangup ) {
2005
+ await this.waitforhangup()
2006
+ return
2007
+ }
2008
+ this._state._hangup = true
1969
2009
 
1970
- this._sethangupcause( "us", reason )
1971
2010
  await callstore.delete( this )
1972
2011
 
2012
+ this._sethangupcause( "us", reason )
2013
+
1973
2014
  if( this.established ) {
1974
2015
  try {
1975
2016
  await this._dialog.destroy()
@@ -1992,15 +2033,12 @@ class call {
1992
2033
  }
1993
2034
 
1994
2035
  async waitforhangup() {
1995
- if( this.destroyed ) return
1996
2036
 
1997
2037
  if( !this._promises.promise.hangup ) {
1998
- this._promises.promise.hangup = new Promise( ( resolve ) => {
1999
- this._promises.resolve.hangup = resolve
2000
- } )
2038
+ return
2001
2039
  }
2002
2040
 
2003
- await this._promises.resolve.hangup
2041
+ await this._promises.promise.hangup
2004
2042
  this._promises.promise.hangup = false
2005
2043
  this._promises.resolve.hangup = false
2006
2044
 
@@ -2149,6 +2187,8 @@ class call {
2149
2187
  */
2150
2188
  static async newuac( options, callbacks = {} ) {
2151
2189
 
2190
+ if( !options.contact && !options.entity ) return false
2191
+
2152
2192
  /* If we don't have a contact we need to look up the entity */
2153
2193
  if( undefined === options.contact ) {
2154
2194
 
@@ -2204,9 +2244,10 @@ class call {
2204
2244
  for( let contact of contactinfo.contacts ) {
2205
2245
  if( undefined === contact ) continue
2206
2246
  let newoptions = { ...options }
2207
-
2208
- newoptions.contact = contact.contact
2209
- call.newuac( newoptions, ourcallbacks )
2247
+ if( contact.contact && "string" == typeof contact.contact ) {
2248
+ newoptions.contact = contact.contact
2249
+ call.newuac( newoptions, ourcallbacks )
2250
+ }
2210
2251
  }
2211
2252
 
2212
2253
  let child = await waitonchildrenpromise
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babblevoice/babble-drachtio-callmanager",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Call processing to create a PBX",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -20,11 +20,15 @@
20
20
  ],
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
+ "@babblevoice/babble-drachtio-auth": "^1.0.0",
23
24
  "chai": "^4.3.4",
24
25
  "drachtio-srf": "^4.4.47",
25
26
  "mocha": "^9.2.2",
26
27
  "uuid": "^8.3.2"
27
28
  },
29
+ "optionalDependencies": {
30
+ "@babblevoice/projectrtp": "^2.2.0"
31
+ },
28
32
  "bugs": {
29
33
  "url": "https://github.com/tinpotnick/babble-drachtio-callmanager/issues"
30
34
  },
@@ -32,6 +36,5 @@
32
36
  "directories": {
33
37
  "lib": "lib",
34
38
  "test": "test"
35
- },
36
- "devDependencies": {}
39
+ }
37
40
  }
@@ -3,8 +3,8 @@ const expect = require( "chai" ).expect
3
3
  const callmanager = require( "../../index.js" )
4
4
  const call = require( "../../lib/call.js" )
5
5
  const srf = require( "../mock/srf.js" )
6
- const projectrtp = require( "projectrtp" ).projectrtp
7
- const projectrtpmessage = require( "projectrtp/lib/message.js" )
6
+ const projectrtp = require( "@babblevoice/projectrtp" ).projectrtp
7
+ const projectrtpmessage = require( "@babblevoice/projectrtp/lib/message.js" )
8
8
  const net = require( "net" )
9
9
 
10
10
  /* These DO NOT form part of our interface */
@@ -77,10 +77,11 @@ describe( "call object", function() {
77
77
  expect( call.channels ).to.have.property( "audio" ).to.be.false
78
78
 
79
79
  /* if uas */
80
- expect( call ).to.have.property( "source" ).that.is.a( "object" )
81
- expect( call.source ).to.have.property( "address" ).that.is.a( "string" )
82
- expect( call.source ).to.have.property( "port" ).that.is.a( "number" )
83
- expect( call.source ).to.have.property( "protocol" ).that.is.a( "string" )
80
+ expect( call ).to.have.property( "network" ).that.is.a( "object" )
81
+ expect( call.network ).to.have.property( "remote" ).that.is.a( "object" )
82
+ expect( call.network.remote ).to.have.property( "address" ).that.is.a( "string" )
83
+ expect( call.network.remote ).to.have.property( "port" ).that.is.a( "number" )
84
+ expect( call.network.remote ).to.have.property( "protocol" ).that.is.a( "string" )
84
85
  expect( call ).to.have.property( "sip" ).that.is.a( "object" )
85
86
  expect( call.sip ).to.have.property( "callid" ).that.is.a( "string" )
86
87
  expect( call.sip ).to.have.property( "tags" ).that.is.a( "object" )
@@ -90,6 +91,8 @@ describe( "call object", function() {
90
91
  expect( call.hangup_cause.reason ).to.equal( "NORMAL_CLEARING" )
91
92
  expect( call.hangup_cause.sip ).to.equal( 487 )
92
93
 
94
+ expect( call.state.cleaned ).to.be.true
95
+
93
96
  } )
94
97
 
95
98
  it( `uas.newuac - create uac`, async function() {
@@ -160,6 +163,9 @@ describe( "call object", function() {
160
163
 
161
164
  expect( child.state ).to.have.property( "destroyed" ).that.is.a( "boolean" ).to.be.true
162
165
 
166
+ expect( call.state.cleaned ).to.be.true
167
+ expect( child.state.cleaned ).to.be.true
168
+
163
169
  } )
164
170
 
165
171
  it( `uas.newuac - create uac by entity no registrar`, async function() {
@@ -180,9 +186,17 @@ describe( "call object", function() {
180
186
  } )
181
187
 
182
188
  await call.hangup()
189
+
190
+ expect( await callstore.stats() ).to.deep.include( {
191
+ "storebycallid": 0,
192
+ "storebyuuid": 0,
193
+ "storebyentity": 0
194
+ } )
195
+
196
+ expect( call.state.cleaned ).to.be.true
183
197
  } )
184
198
 
185
- it( `uas.newuac - create uac by entity with registrar`, async function() {
199
+ it( `uas.newuac - create uac by entity with registrar #123`, async function() {
186
200
 
187
201
  let options = {
188
202
  "registrar": {
@@ -192,7 +206,7 @@ describe( "call object", function() {
192
206
  "realm": "dummy.com",
193
207
  "display": "Bob",
194
208
  "uri": "1000@dummy.com",
195
- "contacts": [ "sip:1000@dummy.com:5060", "sip:1000@dummy.com:5060;transport=blah" ]
209
+ "contacts": [ { "contact": "sip:1000@dummy.com:5060" }, { "contact": "sip:1000@dummy.com:5060;transport=blah" } ]
196
210
  }
197
211
  }
198
212
  }
@@ -237,6 +251,9 @@ describe( "call object", function() {
237
251
 
238
252
  expect( srfscenario.options.srf._createuaccount ).to.equal( 2 )
239
253
 
254
+ expect( call.state.cleaned ).to.be.true
255
+ expect( child.state.cleaned ).to.be.true
256
+
240
257
  } )
241
258
 
242
259
  it( `uas.newuac - create uac by entity with max limit and registrar`, async function() {
@@ -249,7 +266,7 @@ describe( "call object", function() {
249
266
  "realm": "dummy.com",
250
267
  "display": "Bob",
251
268
  "uri": "1000@dummy.com",
252
- "contacts": [ "sip:1000@dummy.com:5060", "sip:1000@dummy.com:5060;transport=blah" ]
269
+ "contacts": [ { "contact": "sip:1000@dummy.com:5060" }, { "contact": "sip:1000@dummy.com:5060;transport=blah" } ]
253
270
  }
254
271
  }
255
272
  }
@@ -291,6 +308,9 @@ describe( "call object", function() {
291
308
  expect( srfscenario.options.srf._createuaccount ).to.equal( 4 )
292
309
  expect( child2 ).to.be.false
293
310
 
311
+ expect( child.state.cleaned ).to.be.true
312
+ expect( child3.state.cleaned ).to.be.true
313
+
294
314
  } )
295
315
 
296
316
  it( `uas.newuac detatch from parent`, async function() {
@@ -332,6 +352,9 @@ describe( "call object", function() {
332
352
  "storebyuuid": 0,
333
353
  "storebyentity": 0
334
354
  } )
355
+
356
+ expect( call.state.cleaned ).to.be.true
357
+ expect( child.state.cleaned ).to.be.true
335
358
  } )
336
359
 
337
360
  it( `uas.newuac - 486`, async function() {
@@ -369,6 +392,9 @@ describe( "call object", function() {
369
392
  "storebyuuid": 0,
370
393
  "storebyentity": 0
371
394
  } )
395
+
396
+ expect( call.state.cleaned ).to.be.true
397
+ expect( child.state.cleaned ).to.be.true
372
398
  } )
373
399
 
374
400
 
@@ -388,7 +414,7 @@ describe( "call object", function() {
388
414
  }
389
415
  } ) /* overide default - very short */
390
416
 
391
- expect( child ).to.be.false
417
+ expect( child.destroyed ).to.be.true
392
418
  expect( children.length ).to.equal( 1 )
393
419
  expect( children[ 0 ].destroyed ).to.be.true
394
420
 
@@ -409,6 +435,9 @@ describe( "call object", function() {
409
435
  "storebyuuid": 0,
410
436
  "storebyentity": 0
411
437
  } )
438
+
439
+ expect( call.state.cleaned ).to.be.true
440
+ expect( child.state.cleaned ).to.be.true
412
441
  } )
413
442
 
414
443
  it( `uas.newuac - child remote hangup`, async function() {
@@ -461,6 +490,9 @@ describe( "call object", function() {
461
490
 
462
491
  expect( child.state ).to.have.property( "destroyed" ).that.is.a( "boolean" ).to.be.true
463
492
 
493
+ expect( call.state.cleaned ).to.be.true
494
+ expect( child.state.cleaned ).to.be.true
495
+
464
496
  } )
465
497
 
466
498
  it( `uas.newuac - new call event`, async function() {
@@ -511,23 +543,20 @@ describe( "call object", function() {
511
543
 
512
544
  let srfscenario = new srf.srfscenario()
513
545
 
514
- let waitforcallresolve
515
- let waitforcall = new Promise( ( resolve ) => waitforcallresolve = resolve )
516
-
517
- let ourcall
518
- call.newuac( { "contact": "1000@dummy.com" }, { "early": ( c ) => { ourcall = c; waitforcallresolve(); } } )
546
+ let eventhappened = false
519
547
 
520
- await waitforcall
548
+ let c = await new Promise( ( resolve ) => {
549
+ srfscenario.oncall( async ( call ) => { resolve( call ) } )
550
+ srfscenario.inbound()
551
+ } )
521
552
 
522
- let eventhappened = false
523
- ourcall.on( "call.destroyed", ( c ) => {
553
+ c.on( "call.destroyed", ( c ) => {
524
554
  eventhappened = true
525
555
  } )
526
556
 
527
- /* immediately hangup */
528
- await ourcall.hangup()
557
+ await c.hangup()
529
558
 
530
- expect( eventhappened ).to.be.true
559
+ expect( eventhappened ).to.be.false
531
560
  } )
532
561
 
533
562
  it( `uas.newuac - answered and destroyed event`, async function() {
@@ -692,6 +721,8 @@ describe( "call object", function() {
692
721
  srfscenario.inbound()
693
722
  } )
694
723
 
724
+ await c.waitforhangup()
725
+
695
726
  expect( eventhappened ).to.be.true
696
727
  expect( c.hangup_cause.reason ).to.equal( "FORBIDDEN" )
697
728
  expect( c.hangup_cause.src ).to.equal( "us" )
@@ -1,13 +1,7 @@
1
1
 
2
2
  const expect = require( "chai" ).expect
3
- const callmanager = require( "../../index.js" )
4
3
  const call = require( "../../lib/call.js" )
5
4
  const srf = require( "../mock/srf.js" )
6
- const projectrtp = require( "projectrtp" ).projectrtp
7
-
8
- /* These DO NOT form part of our interface */
9
- const clearcallmanager = require( "../../lib/callmanager.js" )._clear
10
- const callstore = require( "../../lib/store.js" )
11
5
 
12
6
  describe( "events", function() {
13
7
 
@@ -3,7 +3,7 @@ const expect = require( "chai" ).expect
3
3
  const callmanager = require( "../../index.js" )
4
4
  const call = require( "../../lib/call.js" )
5
5
  const srf = require( "../mock/srf.js" )
6
- const projectrtp = require( "projectrtp" ).projectrtp
6
+ const projectrtp = require( "@babblevoice/projectrtp" ).projectrtp
7
7
 
8
8
  /* These DO NOT form part of our interface */
9
9
  const clearcallmanager = require( "../../lib/callmanager.js" )._clear
@@ -3,11 +3,10 @@ const expect = require( "chai" ).expect
3
3
  const callmanager = require( "../../index.js" )
4
4
  const call = require( "../../lib/call.js" )
5
5
  const srf = require( "../mock/srf.js" )
6
- const projectrtp = require( "projectrtp" ).projectrtp
6
+ const projectrtp = require( "@babblevoice/projectrtp" ).projectrtp
7
7
 
8
8
  /* These DO NOT form part of our interface */
9
9
  const clearcallmanager = require( "../../lib/callmanager.js" )._clear
10
- const callstore = require( "../../lib/store.js" )
11
10
 
12
11
  describe( "xfer", function() {
13
12
 
@@ -131,16 +130,17 @@ describe( "xfer", function() {
131
130
  await b_2._dialog.callbacks.refer( req, res )
132
131
 
133
132
  /* As part of the process the b_2 client will send us a hangup */
134
- b_2.hangup()
133
+ await b_2._onhangup( "wire" )
135
134
 
136
135
  /* these two now have a chat before hanging up */
137
- a_1.hangup()
138
- c_1.hangup()
136
+ await a_1.hangup()
137
+ await c_1.hangup()
139
138
 
140
139
  expect( b_1.hangup_cause.sip ).equal( 487 )
141
140
  expect( b_1.hangup_cause.src ).equal( "us" )
142
141
  expect( b_1.hangup_cause.reason ).equal( "ATTENDED_TRANSFER" )
143
142
 
143
+ expect( b_2.state.cleaned ).to.be.true
144
144
  expect( b_2.hangup_cause.sip ).equal( 487 )
145
145
  expect( b_2.hangup_cause.src ).equal( "wire" )
146
146
  expect( b_2.hangup_cause.reason ).equal( "ATTENDED_TRANSFER" )
package/test/mock/srf.js CHANGED
@@ -375,6 +375,7 @@ class srfscenario {
375
375
 
376
376
  let newcall = call.frominvite( this.req, this.res )
377
377
  this.callbacks.call( newcall )
378
+ .catch( () => newcall.hangup() )
378
379
  }
379
380
  }
380
381
  }