@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 +14 -17
- package/package.json +1 -1
- package/test/interface/early.js +143 -2
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 =
|
|
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
|
-
|
|
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
|
|
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(
|
|
2948
|
-
this.channels.audio = await this.#openchannel( channeldef,
|
|
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
|
|
2951
|
+
this.channels.audio = await this.#openchannel( channeldef, other )
|
|
2955
2952
|
return
|
|
2956
2953
|
}
|
|
2957
2954
|
}
|
package/package.json
CHANGED
package/test/interface/early.js
CHANGED
|
@@ -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
|
/*
|