@babblevoice/babble-drachtio-callmanager 1.5.0 → 1.5.3

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
@@ -843,7 +843,7 @@ class call {
843
843
  "User-Agent": "project",
844
844
  "Supported": "replaces"
845
845
  },
846
- "body": this.sdp.local.toString()
846
+ "body": this.parent.sdp.local.toString()
847
847
  } )
848
848
  }
849
849
 
@@ -1045,6 +1045,14 @@ class call {
1045
1045
  this.sdp.local.addcodecs( "2833" )
1046
1046
  }
1047
1047
 
1048
+ if( this._iswebrtc ) {
1049
+ let ch = this.channels.audio
1050
+ this.sdp.local.addssrc( ch.local.ssrc )
1051
+ .secure( ch.local.dtls.fingerprint, channeldef.remote.dtls.mode )
1052
+ .addicecandidates( ch.local.address, ch.local.port, ch.local.icepwd )
1053
+ .rtcpmux()
1054
+ }
1055
+
1048
1056
  this._dialog = await this._dialog.ack( this.sdp.local.toString() )
1049
1057
  this._addevents( this._dialog )
1050
1058
 
@@ -1138,6 +1146,10 @@ class call {
1138
1146
  this._req = req
1139
1147
  this._res = res
1140
1148
 
1149
+ if( this._req.msg && this._req.msg.body ) {
1150
+ this.sdp.remote = sdpgen.create( this._req.msg.body )
1151
+ }
1152
+
1141
1153
  this._req.on( "cancel", () => this._oncanceled() )
1142
1154
 
1143
1155
  let authorization = this._auth.parseauthheaders( this._req )
@@ -1323,18 +1335,23 @@ class call {
1323
1335
  */
1324
1336
  get _iswebrtc() {
1325
1337
 
1326
- /* Have we received remote SDP? */
1327
- if( !this.sdp.remote ) {
1328
- return this.sip &&
1329
- this.sip.contact &&
1330
- -1 !== this.sip.contact.indexOf( ";transport=ws" )
1338
+ if( !this.sip || !this.sip.contact ) return false
1339
+
1340
+ let contactstr
1341
+ if( Array.isArray( this.sip.contact ) ) {
1342
+ contactstr = this.sip.contact[ 0 ].uri
1343
+ } else {
1344
+ contactstr = this.sip.contact
1331
1345
  }
1332
1346
 
1333
- return this.sip &&
1334
- this.sip.contact &&
1335
- -1 !== this.sip.contact[ 0 ].uri.indexOf( ";transport=ws" ) &&
1336
- this.sdp.remote.sdp.media[ 0 ] &&
1347
+ /* Have we received remote SDP? */
1348
+ if( this.sdp.remote ) {
1349
+ return this.sdp.remote.sdp.media[ 0 ] &&
1337
1350
  -1 !== this.sdp.remote.sdp.media[ 0 ].protocol.toLowerCase().indexOf( "savpf" ) /* 'UDP/TLS/RTP/SAVPF' */
1351
+ }
1352
+
1353
+ return -1 !== contactstr.indexOf( ";transport=ws" )
1354
+
1338
1355
  }
1339
1356
 
1340
1357
  /**
@@ -1352,7 +1369,6 @@ class call {
1352
1369
 
1353
1370
  let channeldef
1354
1371
  if( this._req.msg && this._req.msg.body ) {
1355
- this.sdp.remote = sdpgen.create( this._req.msg.body )
1356
1372
  /* options.preferedcodecs may have been narrowed down so we still check callmanager as well */
1357
1373
  this.selectedcodec = this.sdp.remote.intersection( options.preferedcodecs, true )
1358
1374
  if( false === this.selectedcodec ) {
@@ -2604,6 +2620,10 @@ class call {
2604
2620
  callmanager.options.em.emit( "call.new", c )
2605
2621
  } )
2606
2622
 
2623
+ if( c._req.msg && c._req.msg.body ) {
2624
+ c.sdp.remote = sdpgen.create( c._req.msg.body )
2625
+ }
2626
+
2607
2627
  return c
2608
2628
 
2609
2629
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babblevoice/babble-drachtio-callmanager",
3
- "version": "1.5.0",
3
+ "version": "1.5.3",
4
4
  "description": "Call processing to create a PBX",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,9 +22,159 @@ describe( "call early", function() {
22
22
  } )
23
23
 
24
24
 
25
- it( `Create call and send 183 - early`, async () => {
25
+ it( `Create call and send 183 - early basic`, async () => {
26
+
27
+ /*
28
+ Phone BV Gateway
29
+ |---------INVITE------>| |(1)
30
+ | |---------INVITE------>|(2)
31
+ | |<--------183 (w-sdp)--|(3)
32
+ |<--------183 (w-sdp)--| |(4)
33
+
34
+ Phone RTP: 192.168.0.200:18540
35
+ BV RTP: 192.168.0.141
36
+ Gateway RTP: 192.168.0.160:21000
37
+ */
38
+
39
+ /* Setup the mock RTP server */
26
40
  let srfscenario = new srf.srfscenario()
41
+ let rtpserver = callmanager.projectrtp.proxy.listen()
42
+
43
+ let connection = net.createConnection( 9002, "127.0.0.1" )
44
+ .on( "error", ( e ) => {
45
+ console.error( e )
46
+ } )
47
+
48
+ connection.on( "connect", () => {
49
+ /* announce our node */
50
+ connection.write( projectrtpmessage.createmessage( {"status":{"channel":{"available":5000,"current":0},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}} ) )
51
+ } )
52
+
53
+ let mixing
54
+ let messagestate = projectrtpmessage.newstate()
55
+ let channelmessages = []
56
+ let opencount = 0
57
+
58
+ connection.on( "data", ( data ) => {
59
+ projectrtpmessage.parsemessage( messagestate, data, ( msg ) => {
60
+ try{
61
+ channelmessages.push( msg )
62
+ if( "open" === msg.channel ) {
63
+ if( 0 == opencount ) {
64
+ setTimeout( () =>
65
+ connection.write(
66
+ projectrtpmessage.createmessage(
67
+ {"local":{"port":10008,"dtls":
68
+ {"fingerprint":"Some fingerprint","enabled":false},
69
+ "address":"192.168.0.141"},
70
+ "id": msg.id,
71
+ "uuid": uuidv4(),
72
+ "action":"open",
73
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
74
+ } ) ), 2 )
75
+ } else {
76
+ setTimeout( () =>
77
+ connection.write(
78
+ projectrtpmessage.createmessage(
79
+ {"local":{"port": 10010,"dtls":
80
+ {"fingerprint":"Some fingerprint","enabled":false},
81
+ "address":"192.168.0.141"},
82
+ "id": msg.id,
83
+ "uuid": uuidv4(),
84
+ "action":"open",
85
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
86
+ } ) ), 2 )
87
+ }
88
+ opencount++
89
+ } else if ( "close" === msg.channel ) {
90
+ 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}}} ) )
91
+ } else if ( "mix" === msg.channel ) {
92
+ mixing = true
93
+ }
94
+ } catch( e ) {
95
+ console.error( e )
96
+ }
97
+ } )
98
+ } )
99
+
100
+ /* ensure we are connected */
101
+ await new Promise( ( r ) => setTimeout( () => r(), 100 ) )
102
+
103
+ srfscenario.oncreateUAC( async ( contact, options, callbacks ) => {
104
+
105
+ /* Step 3. This is the mocked gateway message back to our newcall. */
106
+ callbacks.cbProvisional( {
107
+ "status": 183,
108
+ "msg": {
109
+ "body": `v=0
110
+ o=- 1608235282228 0 IN IP4 127.0.0.1
111
+ s=
112
+ c=IN IP4 192.168.0.160
113
+ t=0 0
114
+ m=audio 21000 RTP/AVP 0 101
115
+ a=rtpmap:101 telephone-event/8000
116
+ a=fmtp:101 0-16
117
+ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
118
+ }
119
+ } )
120
+
121
+ await new Promise( ( r ) => setTimeout( () => r(), 100 ) )
122
+ throw { "status": 503 }
123
+ } )
124
+
125
+ /* Step 1. Phone sends INVITE */
126
+ let call = await new Promise( ( resolve ) => {
127
+ srfscenario.oncall( async ( call ) => { resolve( call ) } )
128
+ srfscenario.inbound()
129
+ } )
130
+
131
+ /* Step 4. BV sends 183 back to phone */
132
+ let msgsent, msginfo
133
+ srfscenario.res.onsend( ( c, i ) => {
134
+ msgsent = c
135
+ msginfo = i
136
+ } )
137
+
138
+
139
+ /* Step 2. New INVITE to the remote Gateway */
140
+ let newcall = await call.newuac( { "contact": "callto" } )
141
+
142
+ await call._onhangup( "wire" )
143
+
144
+ expect( newcall.state.early ).to.be.true
145
+ expect( call.state.early ).to.be.true
146
+ expect( mixing ).to.be.true
147
+ expect( msgsent ).to.equal( 183 )
27
148
 
149
+ expect( channelmessages[ 0 ].channel ).to.equal( "open" )
150
+ expect( channelmessages[ 1 ].channel ).to.equal( "remote" )
151
+ expect( channelmessages[ 1 ].remote.port ).to.equal( 21000 )
152
+ expect( channelmessages[ 1 ].remote.address ).to.equal( "192.168.0.160" )
153
+ expect( channelmessages[ 2 ].channel ).to.equal( "open" )
154
+ expect( channelmessages[ 2 ].remote.port ).to.equal( 18540 )
155
+ expect( channelmessages[ 2 ].remote.address ).to.equal( "192.168.0.200" )
156
+ expect( channelmessages[ 3 ].channel ).to.equal( "mix" )
157
+ expect( channelmessages[ 4 ].channel ).to.equal( "close" )
158
+ expect( channelmessages[ 5 ].channel ).to.equal( "close" )
159
+
160
+ expect( msginfo.body ).to.include( "audio 10010 RTP/AVP" )
161
+
162
+ connection.destroy()
163
+ rtpserver.destroy()
164
+ } )
165
+
166
+ it( `Create call and send 183 - early - SAVPF`, async () => {
167
+
168
+ /*
169
+ Phone (SAVPF) BV Gateway
170
+ |---------INVITE------>| |(1)
171
+ | |---------INVITE------>|(2)
172
+ | |<--------183 (w-sdp)--|(3)
173
+ |<--------183 (w-sdp)--| |(4)
174
+ */
175
+
176
+ /* Setup the mock RTP server */
177
+ let srfscenario = new srf.srfscenario( { savpf: true } )
28
178
  let rtpserver = callmanager.projectrtp.proxy.listen()
29
179
 
30
180
  let connection = net.createConnection( 9002, "127.0.0.1" )
@@ -37,18 +187,49 @@ describe( "call early", function() {
37
187
  connection.write( projectrtpmessage.createmessage( {"status":{"channel":{"available":5000,"current":0},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}} ) )
38
188
  } )
39
189
 
40
- let msgid
41
190
  let mixing
42
191
  let messagestate = projectrtpmessage.newstate()
192
+ let channelmessages = []
193
+ let opencount = 0
194
+
43
195
  connection.on( "data", ( data ) => {
44
196
  projectrtpmessage.parsemessage( messagestate, data, ( msg ) => {
45
- if( "open" === msg.channel ) {
46
- msgid = msg.id
47
- setTimeout( () => connection.write( projectrtpmessage.createmessage( {"local":{"port":10008,"dtls":{"fingerprint":"Some fingerprint","enabled":false},"address":"192.168.0.141"},"id": msg.id, "uuid": uuidv4(),"action":"open","status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}} ) ), 2 )
48
- } else if ( "close" === msg.channel ) {
49
- 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}}} ) )
50
- } else if ( "mix" === msg.channel ) {
51
- mixing = true
197
+ try{
198
+ channelmessages.push( msg )
199
+ if( "open" === msg.channel ) {
200
+ if( 0 == opencount ) {
201
+ setTimeout( () =>
202
+ connection.write(
203
+ projectrtpmessage.createmessage(
204
+ {"local":{"port":10008,"dtls":
205
+ {"fingerprint":"Some fingerprint","enabled":false},
206
+ "address":"192.168.0.141"},
207
+ "id": msg.id,
208
+ "uuid": uuidv4(),
209
+ "action":"open",
210
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
211
+ } ) ), 2 )
212
+ } else {
213
+ setTimeout( () =>
214
+ connection.write(
215
+ projectrtpmessage.createmessage(
216
+ {"local":{"port": 10010,"dtls":
217
+ {"fingerprint":"Some fingerprint","enabled":false},
218
+ "address":"192.168.0.141"},
219
+ "id": msg.id,
220
+ "uuid": uuidv4(),
221
+ "action":"open",
222
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
223
+ } ) ), 2 )
224
+ }
225
+ opencount++
226
+ } else if ( "close" === msg.channel ) {
227
+ 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}}} ) )
228
+ } else if ( "mix" === msg.channel ) {
229
+ mixing = true
230
+ }
231
+ } catch( e ) {
232
+ console.error( e )
52
233
  }
53
234
  } )
54
235
  } )
@@ -57,6 +238,8 @@ describe( "call early", function() {
57
238
  await new Promise( ( r ) => setTimeout( () => r(), 100 ) )
58
239
 
59
240
  srfscenario.oncreateUAC( async ( contact, options, callbacks ) => {
241
+
242
+ /* Step 3. This is the mocked gateway message back to our newcall. */
60
243
  callbacks.cbProvisional( {
61
244
  "status": 183,
62
245
  "msg": {
@@ -76,16 +259,30 @@ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
76
259
  throw { "status": 503 }
77
260
  } )
78
261
 
79
- let msgsent
262
+ /* Step 1. Phone sends INVITE */
80
263
  let call = await new Promise( ( resolve ) => {
81
264
  srfscenario.oncall( async ( call ) => { resolve( call ) } )
82
- srfscenario.inbound()
83
- srfscenario.res.onsend( (c) => {
84
- msgsent = c
85
- })
265
+
266
+ let req = new srf.req( { savpf: true } )
267
+ req.setparsedheader( "contact", [ {
268
+ name: undefined,
269
+ uri: 'sip:u3s2etdo@pc3lfsq1oh86.invalid;transport=ws;ob',
270
+ params: {}
271
+ }
272
+ ] )
273
+
274
+ srfscenario.inbound( req )
275
+ } )
276
+
277
+ /* Step 4. BV sends 183 back to phone */
278
+ let msgsent, msginfo
279
+ srfscenario.res.onsend( ( c, i ) => {
280
+ msgsent = c
281
+ msginfo = i
86
282
  } )
87
283
 
88
284
 
285
+ /* Step 2. New INVITE to the remote Gateway */
89
286
  let newcall = await call.newuac( { "contact": "callto" } )
90
287
 
91
288
  await call._onhangup( "wire" )
@@ -95,6 +292,167 @@ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
95
292
  expect( mixing ).to.be.true
96
293
  expect( msgsent ).to.equal( 183 )
97
294
 
295
+ expect( channelmessages[ 0 ].channel ).to.equal( "open" )
296
+ expect( channelmessages[ 1 ].channel ).to.equal( "remote" )
297
+ expect( channelmessages[ 1 ].remote.port ).to.equal( 20000 )
298
+ expect( channelmessages[ 1 ].remote.address ).to.equal( "192.168.0.141" )
299
+ expect( channelmessages[ 2 ].channel ).to.equal( "open" )
300
+ expect( channelmessages[ 2 ].remote.port ).to.equal( 48356 )
301
+ expect( channelmessages[ 3 ].channel ).to.equal( "mix" )
302
+ expect( channelmessages[ 4 ].channel ).to.equal( "close" )
303
+ expect( channelmessages[ 5 ].channel ).to.equal( "close" )
304
+
305
+ expect( msginfo.body ).to.include( "UDP/TLS/RTP/SAVPF" )
306
+
307
+ connection.destroy()
308
+ rtpserver.destroy()
309
+ } )
310
+
311
+
312
+ it( `Create call and send 183 - early - SAVPF and 200 ok`, async () => {
313
+
314
+ /*
315
+ Phone (SAVPF) BV Gateway
316
+ |---------INVITE------>| |(1)
317
+ | |---------INVITE------>|(2)
318
+ | |<--------183 (w-sdp)--|(3)
319
+ |<--------183 (w-sdp)--| |(4)
320
+ | |<--------200 (w-sdp)--|(5)
321
+ |<--------200 (w-sdp)--| |(6)
322
+ */
323
+
324
+ /* Setup the mock RTP server */
325
+ let srfscenario = new srf.srfscenario( { savpf: true } )
326
+ let rtpserver = callmanager.projectrtp.proxy.listen()
327
+
328
+ let connection = net.createConnection( 9002, "127.0.0.1" )
329
+ .on( "error", ( e ) => {
330
+ console.error( e )
331
+ } )
332
+
333
+ connection.on( "connect", () => {
334
+ /* announce our node */
335
+ connection.write( projectrtpmessage.createmessage( {"status":{"channel":{"available":5000,"current":0},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}} ) )
336
+ } )
337
+
338
+ let mixing
339
+ let messagestate = projectrtpmessage.newstate()
340
+ let channelmessages = []
341
+ let opencount = 0
342
+
343
+ connection.on( "data", ( data ) => {
344
+ projectrtpmessage.parsemessage( messagestate, data, ( msg ) => {
345
+ try{
346
+ channelmessages.push( msg )
347
+ if( "open" === msg.channel ) {
348
+ if( 0 == opencount ) {
349
+ setTimeout( () =>
350
+ connection.write(
351
+ projectrtpmessage.createmessage(
352
+ {"local":{"port":10008,"dtls":
353
+ {"fingerprint":"Some fingerprint","enabled":false},
354
+ "address":"192.168.0.141"},
355
+ "id": msg.id,
356
+ "uuid": uuidv4(),
357
+ "action":"open",
358
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
359
+ } ) ), 2 )
360
+ } else {
361
+ setTimeout( () =>
362
+ connection.write(
363
+ projectrtpmessage.createmessage(
364
+ {"local":{"port": 10010,"dtls":
365
+ {"fingerprint":"Some fingerprint","enabled":false},
366
+ "address":"192.168.0.141"},
367
+ "id": msg.id,
368
+ "uuid": uuidv4(),
369
+ "action":"open",
370
+ "status":{"channel":{"available":4995,"current":5},"workercount":12,"instance":"ca0ef6a9-9174-444d-bdeb-4c9eb54d4566"}
371
+ } ) ), 2 )
372
+ }
373
+ opencount++
374
+ } else if ( "close" === msg.channel ) {
375
+ 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}}} ) )
376
+ } else if ( "mix" === msg.channel ) {
377
+ mixing = true
378
+ }
379
+ } catch( e ) {
380
+ console.error( e )
381
+ }
382
+ } )
383
+ } )
384
+
385
+ /* ensure we are connected */
386
+ await new Promise( ( r ) => setTimeout( () => r(), 100 ) )
387
+
388
+ let req = new srf.req( { savpf: true } )
389
+ req.setparsedheader( "contact", [ {
390
+ name: undefined,
391
+ uri: 'sip:u3s2etdo@pc3lfsq1oh86.invalid;transport=ws;ob',
392
+ params: {}
393
+ }
394
+ ] )
395
+
396
+ srfscenario.oncreateUAC( async ( contact, options, callbacks ) => {
397
+
398
+ /* Step 3. This is the mocked gateway message back to our newcall. */
399
+ callbacks.cbProvisional( {
400
+ "status": 183,
401
+ "msg": {
402
+ "body": `v=0
403
+ o=- 1608235282228 0 IN IP4 127.0.0.1
404
+ s=
405
+ c=IN IP4 192.168.0.141
406
+ t=0 0
407
+ m=audio 20000 RTP/AVP 0 101
408
+ a=rtpmap:101 telephone-event/8000
409
+ a=fmtp:101 0-16
410
+ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
411
+ }
412
+ } )
413
+
414
+ await new Promise( ( r ) => setTimeout( () => r(), 100 ) )
415
+ return new srf.dialog( req )
416
+ } )
417
+
418
+ /* Step 1. Phone sends INVITE */
419
+ let call = await new Promise( ( resolve ) => {
420
+ srfscenario.oncall( async ( call ) => { resolve( call ) } )
421
+ srfscenario.inbound( req )
422
+ } )
423
+
424
+ /* Step 4. BV sends 183 back to phone */
425
+ let msgsent, msginfo
426
+ srfscenario.res.onsend( ( c, i ) => {
427
+ msgsent = c
428
+ msginfo = i
429
+ } )
430
+
431
+
432
+ /* Step 2. New INVITE to the remote Gateway */
433
+ let newcall = await call.newuac( { "contact": "callto" } )
434
+
435
+ await new Promise( ( r ) => setTimeout( () => r(), 500 ) )
436
+ await call._onhangup( "wire" )
437
+
438
+ expect( newcall.state.early ).to.be.true
439
+ expect( call.state.early ).to.be.true
440
+ expect( mixing ).to.be.true
441
+ expect( msgsent ).to.equal( 183 )
442
+
443
+ expect( channelmessages[ 0 ].channel ).to.equal( "open" )
444
+ expect( channelmessages[ 1 ].channel ).to.equal( "remote" )
445
+ expect( channelmessages[ 1 ].remote.port ).to.equal( 20000 )
446
+ expect( channelmessages[ 2 ].channel ).to.equal( "open" )
447
+ expect( channelmessages[ 2 ].remote.port ).to.equal( 48356 )
448
+ expect( channelmessages[ 2 ].remote.address ).to.equal( "82.19.206.102" )
449
+ expect( channelmessages[ 3 ].channel ).to.equal( "mix" )
450
+
451
+ expect( channelmessages[ 7 ].channel ).to.equal( "close" )
452
+ expect( channelmessages[ 8 ].channel ).to.equal( "close" )
453
+
454
+ expect( msginfo.body ).to.include( "UDP/TLS/RTP/SAVPF" )
455
+
98
456
  connection.destroy()
99
457
  rtpserver.destroy()
100
458
  } )
package/test/mock/srf.js CHANGED
@@ -86,13 +86,103 @@ a=fmtp:97 mode=20
86
86
  a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
87
87
  ]
88
88
 
89
+ let possiblesavpsdp = [
90
+ `v=0
91
+ o=- 6278233949897424941 2 IN IP4 127.0.0.1
92
+ s=-
93
+ t=0 0
94
+ a=group:BUNDLE 0
95
+ a=extmap-allow-mixed
96
+ a=msid-semantic: WMS Aq3uReW2RJFKkrlg942QblHcszboGZx9dhvK
97
+ m=audio 48356 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126
98
+ c=IN IP4 82.19.206.102
99
+ a=rtcp:9 IN IP4 0.0.0.0
100
+ a=candidate:79019993 1 udp 1686052607 82.19.206.102 48356 typ srflx raddr 172.17.0.1 rport 48356 generation 0 network-id 1
101
+ a=ice-ufrag:K8PO
102
+ a=ice-pwd:3RU9dMh3eDbYsfJIyQ4ki5va
103
+ a=ice-options:trickle
104
+ a=fingerprint:sha-256 73:D5:EC:C0:BF:A7:CA:42:1B:DE:B6:EA:CE:B9:D0:32:38:65:50:4A:27:BF:58:9A:DF:24:B2:10:53:58:88:B9
105
+ a=setup:actpass
106
+ a=mid:0
107
+ a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
108
+ a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
109
+ a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
110
+ a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
111
+ a=sendrecv
112
+ a=msid:Aq3uReW2RJFKkrlg942QblHcszboGZx9dhvK eaa81692-2187-4303-8e59-ed1bcb9591ee
113
+ a=rtcp-mux
114
+ a=rtpmap:111 opus/48000/2
115
+ a=rtcp-fb:111 transport-cc
116
+ a=fmtp:111 minptime=10;useinbandfec=1
117
+ a=rtpmap:63 red/48000/2
118
+ a=fmtp:63 111/111
119
+ a=rtpmap:103 ISAC/16000
120
+ a=rtpmap:104 ISAC/32000
121
+ a=rtpmap:9 G722/8000
122
+ a=rtpmap:0 PCMU/8000
123
+ a=rtpmap:8 PCMA/8000
124
+ a=rtpmap:106 CN/32000
125
+ a=rtpmap:105 CN/16000
126
+ a=rtpmap:13 CN/8000
127
+ a=rtpmap:110 telephone-event/48000
128
+ a=rtpmap:112 telephone-event/32000
129
+ a=rtpmap:113 telephone-event/16000
130
+ a=rtpmap:126 telephone-event/8000
131
+ a=ssrc:3789235955 cname:k129XMgcWznC/heR
132
+ a=ssrc:3789235955 msid:Aq3uReW2RJFKkrlg942QblHcszboGZx9dhvK eaa81692-2187-4303-8e59-ed1bcb9591ee`.replace(/(\r\n|\n|\r)/gm, "\r\n"),
133
+ `v=0
134
+ o=- 6278233949897424941 2 IN IP4 127.0.0.1
135
+ s=-
136
+ t=0 0
137
+ a=group:BUNDLE 0
138
+ a=extmap-allow-mixed
139
+ a=msid-semantic: WMS Aq3uReW2RJFKkrlg942QblHcszboGZx9dhvK
140
+ m=audio 30000 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126
141
+ c=IN IP4 8.8.8.8
142
+ a=rtcp:9 IN IP4 0.0.0.0
143
+ a=candidate:79019993 1 udp 1686052607 8.8.8.8 30000 typ srflx raddr 172.17.0.1 rport 30000 generation 0 network-id 1
144
+ a=ice-ufrag:K8PO
145
+ a=ice-pwd:3RU9dMh3eDbYsfJIyQ4ki5va
146
+ a=ice-options:trickle
147
+ a=fingerprint:sha-256 73:D5:EC:C0:BF:A7:CA:42:1B:DE:B6:EA:CE:B9:D0:32:38:65:50:4A:27:BF:58:9A:DF:24:B2:10:53:58:88:B9
148
+ a=setup:actpass
149
+ a=mid:0
150
+ a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
151
+ a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
152
+ a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
153
+ a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
154
+ a=sendrecv
155
+ a=msid:Aq3uReW2RJFKkrlg942QblHcszboGZx9dhvK eaa81692-2187-4303-8e59-ed1bcb9591ee
156
+ a=rtcp-mux
157
+ a=rtpmap:111 opus/48000/2
158
+ a=rtcp-fb:111 transport-cc
159
+ a=fmtp:111 minptime=10;useinbandfec=1
160
+ a=rtpmap:63 red/48000/2
161
+ a=fmtp:63 111/111
162
+ a=rtpmap:103 ISAC/16000
163
+ a=rtpmap:104 ISAC/32000
164
+ a=rtpmap:9 G722/8000
165
+ a=rtpmap:0 PCMU/8000
166
+ a=rtpmap:8 PCMA/8000
167
+ a=rtpmap:106 CN/32000
168
+ a=rtpmap:105 CN/16000
169
+ a=rtpmap:13 CN/8000
170
+ a=rtpmap:110 telephone-event/48000
171
+ a=rtpmap:112 telephone-event/32000
172
+ a=rtpmap:113 telephone-event/16000
173
+ a=rtpmap:126 telephone-event/8000
174
+ a=ssrc:3789235955 cname:k129XMgcWznC/heR
175
+ a=ssrc:3789235955 msid:Aq3uReW2RJFKkrlg942QblHcszboGZx9dhvK eaa81692-2187-4303-8e59-ed1bcb9591ee`.replace(/(\r\n|\n|\r)/gm, "\r\n")
176
+ ]
177
+
178
+
89
179
  let sdpid = 0
90
180
 
91
181
  /*
92
182
  Mock req object
93
183
  */
94
184
  class req {
95
- constructor( options ) {
185
+ constructor( options = {} ) {
96
186
  this.parsedheaders = {}
97
187
  this.headers = {}
98
188
 
@@ -109,8 +199,14 @@ class req {
109
199
 
110
200
  this.callbacks = {}
111
201
 
202
+ let sdp = possiblesdp[ sdpid % possiblesdp.length ]
203
+
204
+ if( options.savpf ) {
205
+ sdp = possiblesavpsdp[ sdpid % possiblesavpsdp.length ]
206
+ }
207
+
112
208
  this.msg = {
113
- "body": possiblesdp[ sdpid % possiblesdp.length ],
209
+ "body": sdp,
114
210
  method: "INVITE"
115
211
  }
116
212
  sdpid++
@@ -326,7 +422,7 @@ is bad testing.
326
422
  Our setup of the test and our mock objects need to look simple and are easily explainable.
327
423
  */
328
424
  class srfscenario {
329
- constructor( options ) {
425
+ constructor( options = {} ) {
330
426
  /* every scenario we restart spd */
331
427
  sdpid = 0
332
428
 
@@ -342,6 +438,11 @@ class srfscenario {
342
438
  "uassdp": possiblesdp[ 1 ]
343
439
  }
344
440
 
441
+ if( options.savpf ) {
442
+ defaultoptions.uacsdp = possiblesavpsdp[ 0 ]
443
+ defaultoptions.uassdp = possiblesavpsdp[ 1 ]
444
+ }
445
+
345
446
  this.options = { ...defaultoptions, ...options }
346
447
  this.options.srf = new srf()
347
448
 
@@ -373,9 +474,13 @@ class srfscenario {
373
474
  /*
374
475
  simulate a new inbound call
375
476
  */
376
- inbound() {
477
+ inbound( ureq ) {
377
478
  if( this.callbacks.call ) {
378
- this.req = new req( new options() )
479
+ if( ureq ) {
480
+ this.req = ureq
481
+ } else {
482
+ this.req = new req( new options() )
483
+ }
379
484
  this.res = new res()
380
485
 
381
486
  let newcall = call.frominvite( this.req, this.res )