@babblevoice/babble-drachtio-callmanager 3.6.10 → 3.6.12

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
@@ -673,6 +673,12 @@ class call {
673
673
  other.#calledidforuac( startingpoint )
674
674
  }
675
675
  } else {
676
+
677
+ if ( this.options.partycaller ) {
678
+ this.#overridecalledid( startingpoint )
679
+ return startingpoint
680
+ }
681
+
676
682
  this.#calleridforuac( startingpoint )
677
683
  }
678
684
  }
@@ -1299,10 +1305,16 @@ class call {
1299
1305
 
1300
1306
  this.sdp.remote = sdpgen.create( this._dialog.remote.sdp )
1301
1307
 
1302
- if( !this.sdp.remote.intersection( this.options.preferedcodecs, true ) ) {
1308
+ const selectedcodec = this.sdp.remote.intersection( this.options.preferedcodecs, true )
1309
+ if( !selectedcodec ) {
1303
1310
  return this.hangup( hangupcodes.INCOMPATIBLE_DESTINATION )
1304
1311
  }
1305
1312
 
1313
+ this.sdp.local.select( selectedcodec )
1314
+ if( true === this.options.rfc2833 && this.sdp.remote.has( "2833" ) ) {
1315
+ this.sdp.local.addcodecs( "2833" )
1316
+ }
1317
+
1306
1318
  this.#parsesrtpsetup()
1307
1319
 
1308
1320
  this.sdp.remote.setdynamepayloadtypes( this.sdp.local )
@@ -3324,7 +3336,10 @@ class call {
3324
3336
  for( const contact of contactinfo.contacts ) {
3325
3337
  if( undefined === contact ) continue
3326
3338
  const newoptions = { ...options }
3327
-
3339
+
3340
+ if ( newoptions.clicktocall )
3341
+ newoptions.partycaller = true
3342
+
3328
3343
  if( contact.contact && "string" == typeof contact.contact ) {
3329
3344
  numcontacts++
3330
3345
  newoptions.contact = contact.contact
@@ -3515,11 +3530,13 @@ class call {
3515
3530
  }
3516
3531
 
3517
3532
  const callerid = this.callerid
3518
- const firsthalf = `"${callerid.name}"`
3533
+
3519
3534
  let calleridstr = `<sip:${callerid.user}@${callerid.host}>`
3520
3535
 
3521
3536
  if ( callerid.name )
3522
- calleridstr = firsthalf + " " + calleridstr
3537
+ calleridstr = `"${callerid.name}"` + " " + calleridstr
3538
+ else
3539
+ calleridstr = `"${callerid.user}"` + " " + calleridstr
3523
3540
 
3524
3541
  let privacy = ""
3525
3542
  if( true === this.options.privacy ) {
@@ -3621,9 +3638,10 @@ class call {
3621
3638
  * @property { object } [ headers ] - Object containing extra sip headers required.
3622
3639
  * @property { object } [ uactimeout ] - override the deault timeout
3623
3640
  * @property { true | number } [ autoanswer ] - if true add call-info to auto answer, if number delay to add
3624
- * @property { boolean } [ clicktocall ] - if set to true, will set autoanswer to true and swap the source and desination on caller ID
3625
- * @property { boolean } [ partycalled ] - reverses the direction of the call from the invite
3626
- * @property { boolean } [ late ] - late negotiation
3641
+ * @property { boolean } [ clicktocall ] - if set to true, will set autoanswer to true and swap the source and desination on caller ID, set to true for both caller and called
3642
+ * @property { boolean } [ partycalled ] - reverses the direction of the call from the invite, from the point of view of the called in a 3pcc context
3643
+ * @property { boolean } [ partycaller ] - reverses the direction of the call from the invite, from the point of view of the caller in a 3pcc context
3644
+ * @property { boolean } [ late ] - late negotiation
3627
3645
  * @property { boolean } [ privacy ] - sets the privacy
3628
3646
  * @property { entity } [ entity ] - used to store this call against and look up a contact string if not supplied.
3629
3647
  * @property { object } [ entity ]
package/lib/sdp.js CHANGED
@@ -355,13 +355,14 @@ class sdp {
355
355
  return false
356
356
  }
357
357
 
358
- /*
359
- select works in conjunction with getaudioremote and allows us to force the
360
- selection of the codec we send to our RTP server. This is used on the offered SDP.
361
- If intersect has been called with firstonly flag set then this has the same effect.
362
- */
358
+ /**
359
+ * select works in conjunction with getaudioremote and allows us to force the
360
+ * selection of the codec we send to our RTP server. This is used on the offered SDP.
361
+ * If intersect has been called with firstonly flag set then this has the same effect.
362
+ * @param { string } codec
363
+ */
363
364
  select( codec ) {
364
- if ( isNaN( codec ) ) {
365
+ if ( isNaN( parseInt( codec ) ) ) {
365
366
  if ( undefined === this.#dynamicpts.hascodec( codec ) ) return
366
367
  codec = this.#dynamicpts.getpt( codec )
367
368
  }
@@ -412,6 +413,11 @@ class sdp {
412
413
  return this
413
414
  }
414
415
 
416
+ /**
417
+ *
418
+ * @param { string } type
419
+ * @returns
420
+ */
415
421
  getmedia( type = "audio" ) {
416
422
  let m = this.sdp.media.find( mo => type === mo.type )
417
423
  if ( !m ) {
@@ -433,13 +439,14 @@ class sdp {
433
439
  return this
434
440
  }
435
441
 
436
- /*
437
- Add a CODEC or CODECs, formats:
438
- "pcma"
439
- "pcma pcmu"
440
- "pcma, pcmu"
441
- [ "pcma", pcmu ]
442
- */
442
+ /**
443
+ * Add a CODEC or CODECs, formats:
444
+ * "pcma"
445
+ * "pcma pcmu"
446
+ * "pcma, pcmu"
447
+ * [ "pcma", pcmu ]
448
+ * @param { string | Array< string > } codecs
449
+ */
443
450
  addcodecs( codecs ) {
444
451
  let codecarr = codecs
445
452
  if ( !Array.isArray( codecarr ) && "string" === typeof codecs ) {
@@ -722,9 +729,26 @@ class sdp {
722
729
 
723
730
  toString() {
724
731
 
725
- /* We need to convert payloads back to string to stop a , being added */
732
+
726
733
  const co = Object.assign( this.sdp )
727
734
 
735
+
736
+ let rfc2833 = ""
737
+ if( this.#dynamicpts.hascodec( "2833" ) ) {
738
+ rfc2833 = this.#dynamicpts.getpt( "2833" )
739
+ }
740
+
741
+ /** only return selected */
742
+ if( this.#selected ) {
743
+ co.media.forEach( ( media ) => {
744
+ media.rtp = media.rtp.filter( item => [ this.#selected, rfc2833 ].includes( item.payload ))
745
+ media.fmtp = media.fmtp.filter( item => [ this.#selected, rfc2833 ].includes( item.payload ))
746
+ media.payloads = [ this.#selected ]
747
+ if( rfc2833 ) media.payloads.push( rfc2833 )
748
+ } )
749
+ }
750
+
751
+ /* We need to convert payloads back to string to stop a , being added */
728
752
  co.media.forEach( ( media, i, a ) => {
729
753
  if( Array.isArray( media.payloads ) ) {
730
754
  a[ i ].payloads = media.payloads.join( " " )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babblevoice/babble-drachtio-callmanager",
3
- "version": "3.6.10",
3
+ "version": "3.6.12",
4
4
  "description": "Call processing to create a PBX",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -258,7 +258,7 @@ describe( "call object", function() {
258
258
  child.update()
259
259
 
260
260
  expect( requestoptions.method ).to.equal( "UPDATE" )
261
- expect( requestoptions.headers[ "remote-party-id" ] ).to.equal( "<sip:0123456789@someotherrealm.com>;party=calling;screen=yes" )
261
+ expect( requestoptions.headers[ "remote-party-id" ] ).to.equal( "\"0123456789\" <sip:0123456789@someotherrealm.com>;party=calling;screen=yes" )
262
262
 
263
263
  /* simulate wire to propogate hangup */
264
264
  await call.hangup( call.hangupcodes.NORMAL_CLEARING, false, "wire" )
@@ -790,7 +790,7 @@ describe( "call object", function() {
790
790
 
791
791
  await call.newuac( options, { "early": ( c ) => c.hangup() } )
792
792
 
793
- expect( createuacoptions.headers[ "remote-party-id" ] ).to.equal( "<sip:0000000000@localhost.localdomain>;party=calling;screen=yes" )
793
+ expect( createuacoptions.headers[ "remote-party-id" ] ).to.equal( "\"0000000000\" <sip:0000000000@localhost.localdomain>;party=calling;screen=yes" )
794
794
  expect( createuacoptions.late ).to.be.true
795
795
  } )
796
796
 
@@ -1173,7 +1173,7 @@ describe( "call object", function() {
1173
1173
 
1174
1174
 
1175
1175
  /* no default configured */
1176
- expect( c.options.headers[ "remote-party-id" ] ).to.equal( "<sip:012345789@localhost.localdomain>;party=calling;screen=yes" )
1176
+ expect( c.options.headers[ "remote-party-id" ] ).to.equal( "\"012345789\" <sip:012345789@localhost.localdomain>;party=calling;screen=yes" )
1177
1177
 
1178
1178
  c._onhangup( "wire" )
1179
1179
 
@@ -167,6 +167,7 @@ a=fmtp:18 annexb=no
167
167
  a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
168
168
 
169
169
  const remote = sdp.create( testsdp )
170
+ /* intersection with first only will call select */
170
171
  expect( remote.intersection( "g722 pcmu", true ) ).to.equal( "g722" )
171
172
 
172
173
  remote.setaudiodirection( "inactive" )
@@ -176,15 +177,9 @@ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
176
177
  "s=Z\r\n" +
177
178
  "c=IN IP4 127.0.0.1\r\n" +
178
179
  "t=0 0\r\n" +
179
- "m=audio 56858 RTP/AVP 106 9 98 101 0 8 18 3\r\n" +
180
- "a=rtpmap:106 opus/48000/2\r\n" +
181
- "a=rtpmap:98 telephone-event/48000\r\n" +
180
+ "m=audio 56858 RTP/AVP 9 101\r\n" +
182
181
  "a=rtpmap:101 telephone-event/8000\r\n" +
183
- "a=rtpmap:18 G729/8000\r\n" +
184
- "a=fmtp:106 maxplaybackrate=16000; sprop-maxcapturerate=16000; minptime=20; cbr=1; maxaveragebitrate=20000; useinbandfec=1\r\n" +
185
- "a=fmtp:98 0-16\r\n" +
186
182
  "a=fmtp:101 0-16\r\n" +
187
- "a=fmtp:18 annexb=no\r\n" +
188
183
  "a=inactive\r\n"
189
184
  )
190
185
  } )
@@ -1076,4 +1071,68 @@ a=ssrc:874678690 msid:283cd9e0-ac17-4a6b-b5bc-60fceb19b94f a3f88fda-444b-4d7b-b5
1076
1071
  expect( target.port ).to.equal( 61955 )
1077
1072
  }
1078
1073
  } )
1074
+
1075
+ it( "select codecs and regenerate sdp 1", async () => {
1076
+ const testsdp = `v=0
1077
+ o=Z 1608236465345 1 IN IP4 192.168.0.141
1078
+ s=Z
1079
+ c=IN IP4 192.168.0.141
1080
+ t=0 0
1081
+ m=audio 56802 RTP/AVP 8 0 9 97 106 98
1082
+ a=rtpmap:97 iLBC/8000
1083
+ a=fmtp:97 mode=20
1084
+ a=rtpmap:106 opus/48000/2
1085
+ a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
1086
+ a=rtpmap:98 telephone-event/48000
1087
+ a=fmtp:98 0-16
1088
+ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
1089
+
1090
+ const sdpobj = sdp.create( testsdp )
1091
+ sdpobj.select( "ilbc" )
1092
+ const oursdpstr = sdpobj.toString()
1093
+
1094
+ expect( oursdpstr ).to.include( "RTP/AVP 97 101\r\n" )
1095
+ } )
1096
+
1097
+ it( "select codecs and regenerate sdp 2", async () => {
1098
+ const testsdp = `v=0
1099
+ o=Z 1608236465345 1 IN IP4 192.168.0.141
1100
+ s=Z
1101
+ c=IN IP4 192.168.0.141
1102
+ t=0 0
1103
+ m=audio 56802 RTP/AVP 8 0 9 97 106 101
1104
+ a=rtpmap:97 iLBC/8000
1105
+ a=fmtp:97 mode=20
1106
+ a=rtpmap:106 opus/48000/2
1107
+ a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
1108
+ a=rtpmap:101 telephone-event/48000
1109
+ a=fmtp:101 0-16
1110
+ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
1111
+
1112
+ const sdpobj = sdp.create( testsdp )
1113
+ sdpobj.select( "ilbc" )
1114
+ const oursdpstr = sdpobj.toString()
1115
+
1116
+ expect( oursdpstr ).to.include( "RTP/AVP 97 101\r\n" )
1117
+ } )
1118
+
1119
+ it( "select codecs and regenerate sdp 3", async () => {
1120
+ const testsdp = `v=0
1121
+ o=Z 1608236465345 1 IN IP4 192.168.0.141
1122
+ s=Z
1123
+ c=IN IP4 192.168.0.141
1124
+ t=0 0
1125
+ m=audio 56802 RTP/AVP 8 0 9 97 106
1126
+ a=rtpmap:97 iLBC/8000
1127
+ a=fmtp:97 mode=20
1128
+ a=rtpmap:106 opus/48000/2
1129
+ a=fmtp:106 minptime=20; cbr=1; maxaveragebitrate=40000; useinbandfec=1
1130
+ a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
1131
+
1132
+ const sdpobj = sdp.create( testsdp )
1133
+ sdpobj.select( "ilbc" )
1134
+ const oursdpstr = sdpobj.toString()
1135
+
1136
+ expect( oursdpstr ).to.include( "RTP/AVP 97 101\r\n" )
1137
+ } )
1079
1138
  } )