@babblevoice/babble-drachtio-callmanager 3.3.4 → 3.3.5

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/lib/call.js CHANGED
@@ -1721,7 +1721,7 @@ class call {
1721
1721
  this.channels.count--
1722
1722
 
1723
1723
  if ( 0 === this.channels.count ) {
1724
- this.channels.audio = false
1724
+ this.channels.audio = undefined
1725
1725
 
1726
1726
  if( this._state._onhangup ) {
1727
1727
  this._cleanup()
@@ -2072,24 +2072,21 @@ class call {
2072
2072
  Mix two calls. If the two calls are on a different node
2073
2073
  the second call is bonded and reinvited.
2074
2074
  @param { object } channeldef - our call object which is early
2075
- @param { call } bindcall - the call which will own the channel
2075
+ @param { call } [ bindcall ] - the call which will own the channel
2076
2076
  */
2077
2077
  async #openchannel( channeldef, bindcall ) {
2078
2078
 
2079
- let chan = undefined
2080
-
2081
- if ( !bindcall || !this.channels.audio ) {
2082
- chan = await projectrtp.openchannel(
2079
+ if ( bindcall && bindcall.channels.audio ) {
2080
+ const chan = await bindcall.channels.audio.openchannel(
2083
2081
  channeldef, this._handlechannelevents.bind( this ) )
2084
- } else {
2085
- chan = await this.channels.audio.openchannel(
2086
- channeldef, bindcall._handlechannelevents.bind( bindcall ) )
2087
- }
2088
2082
 
2089
- if ( bindcall )
2090
- bindcall.channels.count++
2091
- else
2092
2083
  this.channels.count++
2084
+ return chan
2085
+ }
2086
+
2087
+ const chan = await projectrtp.openchannel(
2088
+ channeldef, this._handlechannelevents.bind( this ) )
2089
+ this.channels.count++
2093
2090
 
2094
2091
  return chan
2095
2092
  }
@@ -2939,19 +2936,19 @@ class call {
2939
2936
 
2940
2937
  if( this.channels.audio ) return
2941
2938
 
2942
- const relatedcall = this.other
2939
+ const othercall = this.other
2943
2940
  /* TODO: this is a hack. projectrtp has become too complicated with both a listen and connect
2944
2941
  mechanism. This is causing problems in code like this. There is no interface to
2945
2942
  detect which mode the channel is in - but the channels property will exist on a connect
2946
2943
  style channel. projectrtp will getrelatives a rewrite to support only one. */
2947
- if( relatedcall && relatedcall.channels.audio && relatedcall.channels.audio.channels ) {
2948
- this.channels.audio = await this.#openchannel( channeldef, this )
2944
+ if( othercall && othercall.channels.audio ) {
2945
+ this.channels.audio = await this.#openchannel( channeldef, othercall )
2949
2946
  return
2950
2947
  }
2951
2948
 
2952
2949
  for( const other of this.relatives ) {
2953
2950
  if( other.channels && other.channels.audio ) {
2954
- this.channels.audio = await other.#openchannel( channeldef, this )
2951
+ this.channels.audio = await this.#openchannel( channeldef, other )
2955
2952
  return
2956
2953
  }
2957
2954
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babblevoice/babble-drachtio-callmanager",
3
- "version": "3.3.4",
3
+ "version": "3.3.5",
4
4
  "description": "Call processing to create a PBX",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -20,8 +20,7 @@ describe( "call early", function() {
20
20
  clearcallmanager()
21
21
  } )
22
22
 
23
-
24
- it( "Create call and send 183 - early basic", async () => {
23
+ it( "Create call and send 183 - early basic prtp - listen mode", async () => {
25
24
 
26
25
  /*
27
26
  Phone BV Gateway
@@ -163,6 +162,148 @@ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
163
162
  rtpserver.destroy()
164
163
  } )
165
164
 
165
+
166
+ it( "Create call and send 183 - early basic prtp connect mode", async () => {
167
+
168
+ /*
169
+ Phone BV Gateway
170
+ |---------INVITE------>| |(1)
171
+ | |---------INVITE------>|(2)
172
+ | |<--------183 (w-sdp)--|(3)
173
+ |<--------183 (w-sdp)--| |(4)
174
+
175
+ Phone RTP: 192.168.0.200:18540
176
+ BV RTP: 192.168.0.141
177
+ Gateway RTP: 192.168.0.160:21000
178
+ */
179
+
180
+ /* Setup the mock RTP server */
181
+ const srfscenario = new srf.srfscenario()
182
+ const rtpserver = callmanager.projectrtp.proxy.addnode( { host: "127.0.0.1", port: 9002 } )
183
+
184
+ let connection
185
+ const mockrtp = net.createServer()
186
+ mockrtp.on( "connection", ( c ) => {
187
+ connection = c
188
+
189
+ connection.on( "data", ( data ) => {
190
+ projectrtpmessage.parsemessage( messagestate, data, ( msg ) => {
191
+ try{
192
+ channelmessages.push( msg )
193
+ if( "open" === msg.channel ) {
194
+ if( 0 == opencount ) {
195
+ setTimeout( () =>
196
+ connection.write(
197
+ projectrtpmessage.createmessage(
198
+ {"local":{"port":10008,"dtls":
199
+ {"fingerprint":"Some fingerprint","enabled":false},
200
+ "address":"192.168.0.141"},
201
+ "id": msg.id,
202
+ "uuid": uuidv4(),
203
+ "action":"open",
204
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
205
+ } ) ), 2 )
206
+ } else {
207
+ setTimeout( () =>
208
+ connection.write(
209
+ projectrtpmessage.createmessage(
210
+ {"local":{"port": 10010,"dtls":
211
+ {"fingerprint":"Some fingerprint","enabled":false},
212
+ "address":"192.168.0.141"},
213
+ "id": msg.id,
214
+ "uuid": uuidv4(),
215
+ "action":"open",
216
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
217
+ } ) ), 2 )
218
+ }
219
+ opencount++
220
+ } else if ( "close" === msg.channel ) {
221
+ connection.write( projectrtpmessage.createmessage( {"id": msg.id,"uuid":msg.uuid,"action":"close","reason":"requested","stats":{"in":{"mos":4.5,"count":586,"dropped":0,"skip":0},"out":{"count":303,"skip":0},"tick":{"meanus":124,"maxus":508,"count":597}}, "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
222
+ } ) )
223
+ } else if ( "mix" === msg.channel ) {
224
+ mixing = true
225
+ }
226
+ } catch( e ) {
227
+ console.error( e )
228
+ }
229
+ } )
230
+ } )
231
+ } )
232
+
233
+ await new Promise( resolve => mockrtp.listen( 9002, resolve ) )
234
+
235
+ let mixing
236
+ const messagestate = projectrtpmessage.newstate()
237
+ const channelmessages = []
238
+ let opencount = 0
239
+
240
+ /* ensure we are connected */
241
+ await new Promise( ( resolve ) => setTimeout( () => resolve(), 100 ) )
242
+
243
+ srfscenario.oncreateUAC( async ( contact, options, callbacks ) => {
244
+
245
+ /* Step 3. This is the mocked gateway message back to our newcall. */
246
+ callbacks.cbProvisional( {
247
+ "status": 183,
248
+ "get": () => { return "INVITE, UPDATE, OPTIONS" },
249
+ "msg": {
250
+ "body": `v=0
251
+ o=- 1608235282228 0 IN IP4 127.0.0.1
252
+ s=
253
+ c=IN IP4 192.168.0.160
254
+ t=0 0
255
+ m=audio 21000 RTP/AVP 0 101
256
+ a=rtpmap:101 telephone-event/8000
257
+ a=fmtp:101 0-16
258
+ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
259
+ }
260
+ } )
261
+
262
+ await new Promise( ( resolve ) => setTimeout( () => resolve(), 100 ) )
263
+ throw { "status": 503 }
264
+ } )
265
+
266
+ /* Step 1. Phone sends INVITE */
267
+ const call = await new Promise( ( resolve ) => {
268
+ srfscenario.oncall( async ( call ) => { resolve( call ) } )
269
+ srfscenario.inbound()
270
+ } )
271
+
272
+ /* Step 4. BV sends 183 back to phone */
273
+ let msgsent, msginfo
274
+ srfscenario.res.onsend( ( c, i ) => {
275
+ msgsent = c
276
+ msginfo = i
277
+ } )
278
+
279
+
280
+ /* Step 2. New INVITE to the remote Gateway */
281
+ const newcall = await call.newuac( { "contact": "callto" } )
282
+
283
+ await call._onhangup( "wire" )
284
+ expect( newcall.state.early ).to.be.true
285
+ expect( call.state.early ).to.be.true
286
+ expect( mixing ).to.be.true
287
+ expect( msgsent ).to.equal( 183 )
288
+
289
+ expect( channelmessages[ 0 ].channel ).to.equal( "open" )
290
+ expect( channelmessages[ 1 ].channel ).to.equal( "remote" )
291
+ expect( channelmessages[ 1 ].remote.port ).to.equal( 21000 )
292
+ expect( channelmessages[ 1 ].remote.address ).to.equal( "192.168.0.160" )
293
+ expect( channelmessages[ 2 ].channel ).to.equal( "open" )
294
+ expect( channelmessages[ 2 ].remote.port ).to.equal( 18540 )
295
+ expect( channelmessages[ 2 ].remote.address ).to.equal( "192.168.0.200" )
296
+ expect( channelmessages[ 3 ].channel ).to.equal( "mix" )
297
+ expect( channelmessages[ 4 ].channel ).to.equal( "close" )
298
+ expect( channelmessages[ 5 ].channel ).to.equal( "close" )
299
+
300
+ expect( msginfo.body ).to.include( "audio 10010 RTP/AVP" )
301
+
302
+ connection.destroy()
303
+ mockrtp.close()
304
+ rtpserver.destroy()
305
+ } )
306
+
166
307
  it( "Create call and send 183 - early - SAVPF", async () => {
167
308
 
168
309
  /*