sip-lab 1.28.11 → 1.29.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.
Files changed (37) hide show
  1. package/DEV.md +55 -0
  2. package/README.md +9 -3
  3. package/binding.gyp +1 -0
  4. package/index.js +7 -0
  5. package/package.json +1 -1
  6. package/prebuilds/linux-x64/node.abi102.node +0 -0
  7. package/prebuilds/linux-x64/node.abi108.node +0 -0
  8. package/prebuilds/linux-x64/node.abi111.node +0 -0
  9. package/prebuilds/linux-x64/node.abi115.node +0 -0
  10. package/prebuilds/linux-x64/node.abi120.node +0 -0
  11. package/prebuilds/linux-x64/node.abi88.node +0 -0
  12. package/prebuilds/linux-x64/node.abi93.node +0 -0
  13. package/samples/100_calls.js +4 -0
  14. package/samples/16_audio_streams.js +2 -0
  15. package/samples/183_session_progress.js +2 -0
  16. package/samples/delayed_media.js +2 -0
  17. package/samples/four_audio_streams_two_refused.js +7 -4
  18. package/samples/mrcp_and_audio.simplified_media.js +2 -0
  19. package/samples/multiple_audio_streams.js +2 -0
  20. package/samples/refuse_telephone_event.js +3 -0
  21. package/samples/reinvite_and_dtmf.js +3 -0
  22. package/samples/reinvite_audio_audio.js +2 -0
  23. package/samples/reinvite_with_hold_unhold.js +2 -0
  24. package/samples/rtp_and_srtp.js +3 -0
  25. package/samples/rtp_and_srtp.rtp_refused.js +3 -0
  26. package/samples/srtp.js +3 -0
  27. package/samples/tcp.js +2 -0
  28. package/samples/text_to_speech.js +3 -0
  29. package/samples/two_audio_streams.js +4 -0
  30. package/samples/two_audio_streams.port_zero.js +4 -0
  31. package/src/addon.cpp +180 -10
  32. package/src/event_templates.cpp +8 -0
  33. package/src/event_templates.hpp +3 -0
  34. package/src/pjmedia/include/pjmedia/bfsk_det.h +25 -0
  35. package/src/pjmedia/src/pjmedia/bfsk_det.c +163 -0
  36. package/src/sip.cpp +520 -21
  37. package/src/sip.hpp +11 -0
package/DEV.md CHANGED
@@ -80,6 +80,61 @@ npx prebuildify-cross -i mayamatakeshi/sip-lab-debian11:latest -t 15.0.0 -t 16.0
80
80
  ```
81
81
  Obs: however the above will fail if you are behind proxy (solution pending).
82
82
 
83
+ #### Checking build using docker container
84
+
85
+ A quick check of the build can be done this way:
86
+ ```
87
+ docker run -it debian:bookworm-slim /bin/bash
88
+
89
+ # then inside the container
90
+
91
+ apt update
92
+ apt install curl
93
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
94
+ . ~/.nvm/nvm.sh
95
+ nvm i 19
96
+ mkdir -p /root/tmp/t1
97
+ cd /root/tmp/t1
98
+ npm init -y
99
+ apt install -y build-essential automake autoconf libtool libspeex-dev libopus-dev libsdl2-dev libavdevice-dev libswscale-dev libv4l-dev libopencore-amrnb-dev libopencore-amrwb-dev libvo-amrwbenc-dev libvo-amrwbenc-dev libboost-dev libtiff-dev libpcap-dev libssl-dev uuid-dev flite-dev cmake git wget
100
+ npm i sip-lab
101
+ ```
102
+
103
+ Sample build:
104
+ ```
105
+ root@636c5c5b0748:~/tmp/t2# nvm use 19
106
+ Now using node v19.9.0 (npm v9.6.3)
107
+
108
+ root@636c5c5b0748:~/tmp/t2# time npm i sip-lab
109
+ npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
110
+ npm WARN deprecated @npmcli/move-file@2.0.1: This functionality has been moved to @npmcli/fs
111
+ npm WARN deprecated npmlog@6.0.2: This package is no longer supported.
112
+ npm WARN deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
113
+ npm WARN deprecated are-we-there-yet@3.0.1: This package is no longer supported.
114
+ npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
115
+ npm WARN deprecated glob@8.1.0: Glob versions prior to v9 are no longer supported
116
+ npm WARN deprecated gauge@4.0.4: This package is no longer supported.
117
+
118
+ added 165 packages, and audited 166 packages in 6m
119
+
120
+ 11 packages are looking for funding
121
+ run `npm fund` for details
122
+
123
+ 4 moderate severity vulnerabilities
124
+
125
+ To address all issues, run:
126
+ npm audit fix
127
+
128
+ Run `npm audit` for details.
129
+
130
+ real 5m54.904s
131
+ user 4m32.643s
132
+ sys 0m54.272s
133
+
134
+ ```
135
+
136
+ So it is taking aboult 6 minutes to build the addon on a docker container.
137
+
83
138
  #### Running tests
84
139
  ```
85
140
  npm test
package/README.md CHANGED
@@ -25,12 +25,13 @@ TODO:
25
25
 
26
26
  ### Installation
27
27
 
28
- This is a node.js addon and it is known to work on Debian 11, Debian 10, Ubuntu 22.04 and Ubuntu 20.04.
29
- It is distributed with prebuild binaries for node.js 15.0.0 and above (but built for Debian 11. For other Debian versions or for Ubuntu a local build of the addon will be executed. Being the case, be patient as the build process will take several minutes to complete).
28
+ This is a node.js addon and it is known to work on Debian 11.
29
+
30
+ It is distributed with prebuild binaries for node.js 15.0.0 and above (but built for Debian 11. For other Debian versions or for Ubuntu a local build of the addon will be executed. Being the case, be patient as the build process will take several minutes to complete (about 6 minutes on a docker container)).
30
31
 
31
32
  To install it, first install build dependencies:
32
33
  ```
33
- apt install build-essential automake autoconf libtool libspeex-dev libopus-dev libsdl2-dev libavdevice-dev libswscale-dev libv4l-dev libopencore-amrnb-dev libopencore-amrwb-dev libvo-amrwbenc-dev libvo-amrwbenc-dev libboost-dev libtiff-dev libpcap-dev libssl-dev uuid-dev flite-dev cmake
34
+ apt install build-essential automake autoconf libtool libspeex-dev libopus-dev libsdl2-dev libavdevice-dev libswscale-dev libv4l-dev libopencore-amrnb-dev libopencore-amrwb-dev libvo-amrwbenc-dev libvo-amrwbenc-dev libboost-dev libtiff-dev libpcap-dev libssl-dev uuid-dev flite-dev cmake git wget
34
35
  ```
35
36
 
36
37
  Then install sip-lab (local build of the addon might be triggered here if this is not Debian 11):
@@ -47,6 +48,11 @@ The above script has detailed comments.
47
48
 
48
49
  Please read it to undestand how to write your own test scripts.
49
50
 
51
+ Notes:
52
+ - It will not work on Debian 10 as cmake version is older than required.
53
+ - It will work on Debian 12 but a build process will be required. But you need to build using node v19 or older. Building with node v20 or v21 will fail (https://github.com/MayamaTakeshi/sip-lab/issues/107). But once you have it built, you can switch to a newer version of node.
54
+
55
+ So basically, if you stick with Debian 11 and any node version from 15 to 21, istallation should be smooth.
50
56
 
51
57
  ### Samples
52
58
 
package/binding.gyp CHANGED
@@ -119,6 +119,7 @@
119
119
  'src/sip.cpp',
120
120
  'src/addon.cpp',
121
121
  'src/pjmedia/src/pjmedia/dtmfdet.c',
122
+ 'src/pjmedia/src/pjmedia/bfsk_det.c',
122
123
  'src/pjmedia/src/pjmedia/fax_port.c',
123
124
  'src/pjmedia/src/pjmedia/flite_port.c',
124
125
  'src/pjmedia/src/pjmedia/pocketsphinx_port.c',
package/index.js CHANGED
@@ -58,6 +58,7 @@ addon.call = {
58
58
  respond: (c_id, params) => { return addon.call_respond(c_id, JSON.stringify(params)) },
59
59
  terminate: (c_id, params) => { return addon.call_terminate(c_id, JSON.stringify(params ? params : {})) },
60
60
  send_dtmf: (c_id, params) => { return addon.call_send_dtmf(c_id, JSON.stringify(params)) },
61
+ send_bfsk: (c_id, params) => { return addon.call_send_bfsk(c_id, JSON.stringify(params)) },
61
62
  reinvite: (c_id, params) => { return addon.call_reinvite(c_id, JSON.stringify(params ? params : {})) },
62
63
  send_request: (c_id, params) => { return addon.call_send_request(c_id, JSON.stringify(params)) },
63
64
  start_record_wav: (c_id, params) => { return addon.call_start_record_wav(c_id, JSON.stringify(params)) },
@@ -69,6 +70,12 @@ addon.call = {
69
70
  start_speech_synth: (c_id, params) => { return addon.call_start_speech_synth(c_id, JSON.stringify(params)) },
70
71
  stop_speech_synth: (c_id, params) => { return addon.call_stop_speech_synth(c_id, JSON.stringify(params ? params : {})) },
71
72
 
73
+ start_inband_dtmf_detection: (c_id, params) => { return addon.call_start_inband_dtmf_detection(c_id, JSON.stringify(params ? params : {})) },
74
+ stop_inband_dtmf_detection: (c_id, params) => { return addon.call_stop_inband_dtmf_detection(c_id, JSON.stringify(params ? params : {})) },
75
+
76
+ start_bfsk_detection: (c_id, params) => { return addon.call_start_bfsk_detection(c_id, JSON.stringify(params ? params : {})) },
77
+ stop_bfsk_dtmf_detection: (c_id, params) => { return addon.call_stop_bfsk_detection(c_id, JSON.stringify(params ? params : {})) },
78
+
72
79
  start_speech_recog: (c_id, params) => {
73
80
  var ps = {}
74
81
  if(params) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sip-lab",
3
- "version": "1.28.11",
3
+ "version": "1.29.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "engines": {
Binary file
Binary file
@@ -92,6 +92,10 @@ async function test() {
92
92
  media_id: 0,
93
93
  })).value(), 50000)
94
94
 
95
+ ocs.forEach(oc => {
96
+ sip.call.start_inband_dtmf_detection(oc.id)
97
+ })
98
+
95
99
  z.store.ic_ids.forEach(ic_id => {
96
100
  sip.call.send_dtmf(ic_id, {digits: '4321', mode: 1})
97
101
  })
@@ -100,6 +100,8 @@ async function test() {
100
100
  media_id: n,
101
101
  })).value(), 3000)
102
102
 
103
+ sip.call.start_inband_dtmf_detection(oc.id)
104
+
103
105
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
104
106
 
105
107
  await z.wait(_.chain(_.range(16)).map(n => ({
@@ -86,6 +86,8 @@ async function test() {
86
86
  },
87
87
  ], 1000)
88
88
 
89
+ sip.call.start_inband_dtmf_detection(oc.id)
90
+
89
91
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
90
92
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
91
93
 
@@ -107,6 +107,8 @@ async function test() {
107
107
 
108
108
  ], 1000)
109
109
 
110
+ sip.call.start_inband_dtmf_detection(oc.id)
111
+
110
112
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
111
113
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
112
114
 
@@ -38,8 +38,8 @@ async function test() {
38
38
  type: "audio",
39
39
  port: 0, // it means not in use
40
40
  },
41
- "audio",
42
- {
41
+ "audio",
42
+ {
43
43
  type: "audio",
44
44
  port: 0, // it means not in use
45
45
  }
@@ -63,8 +63,8 @@ async function test() {
63
63
  type: "audio",
64
64
  port: 0, // it means not in use
65
65
  },
66
- "audio",
67
- {
66
+ "audio",
67
+ {
68
68
  type: "audio",
69
69
  port: 0, // it means not in use
70
70
  }
@@ -128,6 +128,9 @@ async function test() {
128
128
  },
129
129
  ], 1000)
130
130
 
131
+ sip.call.start_inband_dtmf_detection(oc.id, {media_id: 0})
132
+ sip.call.start_inband_dtmf_detection(oc.id, {media_id: 2})
133
+
131
134
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
132
135
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
133
136
 
@@ -118,6 +118,8 @@ async function test() {
118
118
  },
119
119
  ], 1000)
120
120
 
121
+ sip.call.start_inband_dtmf_detection(oc.id)
122
+
121
123
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
122
124
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
123
125
 
@@ -103,6 +103,8 @@ async function test() {
103
103
  media_id: n,
104
104
  })).value(), 3000)
105
105
 
106
+ sip.call.start_inband_dtmf_detection(oc.id)
107
+
106
108
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
107
109
 
108
110
  await z.wait(_.chain(_.range(NUM_AUDIO_STREAMS)).map(n => ({
@@ -100,6 +100,9 @@ async function test() {
100
100
  },
101
101
  ], 1000)
102
102
 
103
+ sip.call.start_inband_dtmf_detection(oc.id)
104
+ sip.call.start_inband_dtmf_detection(ic.id)
105
+
103
106
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 1})
104
107
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
105
108
 
@@ -111,6 +111,9 @@ async function test() {
111
111
  },
112
112
  ], 1000)
113
113
 
114
+ sip.call.start_inband_dtmf_detection(oc.id)
115
+ sip.call.start_inband_dtmf_detection(ic.id)
116
+
114
117
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
115
118
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
116
119
 
@@ -88,6 +88,8 @@ async function test() {
88
88
  },
89
89
  ], 1000)
90
90
 
91
+ sip.call.start_inband_dtmf_detection(oc.id)
92
+
91
93
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
92
94
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
93
95
 
@@ -98,6 +98,8 @@ async function test() {
98
98
  },
99
99
  ], 1000)
100
100
 
101
+ sip.call.start_inband_dtmf_detection(oc.id)
102
+
101
103
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
102
104
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
103
105
 
@@ -89,6 +89,9 @@ async function test() {
89
89
  },
90
90
  ], 1000)
91
91
 
92
+ sip.call.start_inband_dtmf_detection(oc.id)
93
+ sip.call.start_inband_dtmf_detection(ic.id)
94
+
92
95
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 1})
93
96
  sip.call.send_dtmf(ic.id, {digits: '1234', mode: 1})
94
97
 
@@ -131,6 +131,9 @@ async function test() {
131
131
  },
132
132
  ], 1000)
133
133
 
134
+ sip.call.start_inband_dtmf_detection(oc.id, {media_id: 1})
135
+ sip.call.start_inband_dtmf_detection(ic.id, {media_id: 1})
136
+
134
137
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 1})
135
138
  sip.call.send_dtmf(ic.id, {digits: '1234', mode: 1})
136
139
 
package/samples/srtp.js CHANGED
@@ -81,6 +81,9 @@ async function test() {
81
81
  },
82
82
  ], 1000)
83
83
 
84
+ sip.call.start_inband_dtmf_detection(oc.id)
85
+ sip.call.start_inband_dtmf_detection(ic.id)
86
+
84
87
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 1})
85
88
  sip.call.send_dtmf(ic.id, {digits: '1234', mode: 1})
86
89
 
package/samples/tcp.js CHANGED
@@ -85,6 +85,8 @@ async function test() {
85
85
  sip.call.start_record_wav(oc.id, {file: './oc.wav'})
86
86
  sip.call.start_record_wav(ic.id, {file: './ic.wav'})
87
87
 
88
+ sip.call.start_inband_dtmf_detection(oc.id)
89
+
88
90
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
89
91
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
90
92
 
@@ -87,6 +87,9 @@ async function test() {
87
87
  sip.call.start_record_wav(oc.id, {file: './oc.wav'})
88
88
  sip.call.start_record_wav(ic.id, {file: './ic.wav'})
89
89
 
90
+ sip.call.start_inband_dtmf_detection(oc.id)
91
+ sip.call.start_inband_dtmf_detection(ic.id)
92
+
90
93
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 1})
91
94
  sip.call.send_dtmf(ic.id, {digits: '1234', mode: 1})
92
95
 
@@ -95,6 +95,8 @@ async function test() {
95
95
  },
96
96
  ], 1000)
97
97
 
98
+ sip.call.start_inband_dtmf_detection(oc.id)
99
+
98
100
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
99
101
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
100
102
 
@@ -414,6 +416,8 @@ async function test() {
414
416
  },
415
417
  ], 1000)
416
418
 
419
+ sip.call.start_inband_dtmf_detection(oc.id)
420
+
417
421
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
418
422
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
419
423
 
@@ -95,6 +95,8 @@ async function test() {
95
95
  },
96
96
  ], 1000)
97
97
 
98
+ sip.call.start_inband_dtmf_detection(oc.id)
99
+
98
100
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
99
101
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
100
102
 
@@ -426,6 +428,8 @@ async function test() {
426
428
  },
427
429
  ], 1000)
428
430
 
431
+ sip.call.start_inband_dtmf_detection(oc.id)
432
+
429
433
  sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
430
434
  sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
431
435
 
package/src/addon.cpp CHANGED
@@ -399,6 +399,40 @@ Napi::Value call_send_dtmf(const Napi::CallbackInfo &info) {
399
399
  return env.Null();
400
400
  }
401
401
 
402
+ Napi::Value call_send_bfsk(const Napi::CallbackInfo &info) {
403
+ Napi::Env env = info.Env();
404
+
405
+ if (info.Length() != 2) {
406
+ Napi::Error::New(env,
407
+ "Wrong number of arguments. Expected: call_id, params.")
408
+ .ThrowAsJavaScriptException();
409
+ return env.Null();
410
+ }
411
+
412
+ if (!info[0].IsNumber()) {
413
+ Napi::TypeError::New(env, "call_id must be number.")
414
+ .ThrowAsJavaScriptException();
415
+ return env.Null();
416
+ }
417
+ int call_id = info[0].As<Napi::Number>().Int32Value();
418
+
419
+ if (!info[1].IsString()) {
420
+ Napi::TypeError::New(env, "params must be a JSON string.")
421
+ .ThrowAsJavaScriptException();
422
+ return env.Null();
423
+ }
424
+ const string json = info[1].As<Napi::String>().Utf8Value();
425
+
426
+ int res = pjw_call_send_bfsk(call_id, json.c_str());
427
+
428
+ if (res != 0) {
429
+ Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
430
+ return env.Null();
431
+ }
432
+
433
+ return env.Null();
434
+ }
435
+
402
436
  Napi::Value call_reinvite(const Napi::CallbackInfo &info) {
403
437
  Napi::Env env = info.Env();
404
438
 
@@ -637,6 +671,141 @@ Napi::Value call_start_speech_recog(const Napi::CallbackInfo &info) {
637
671
  return env.Null();
638
672
  }
639
673
 
674
+ Napi::Value call_start_inband_dtmf_detection(const Napi::CallbackInfo &info) {
675
+ Napi::Env env = info.Env();
676
+
677
+ if (info.Length() != 2) {
678
+ Napi::Error::New(env,
679
+ "Wrong number of arguments. Expected: call_id, params.")
680
+ .ThrowAsJavaScriptException();
681
+ return env.Null();
682
+ }
683
+
684
+ if (!info[0].IsNumber()) {
685
+ Napi::TypeError::New(env, "call_id must be number.")
686
+ .ThrowAsJavaScriptException();
687
+ return env.Null();
688
+ }
689
+ int call_id = info[0].As<Napi::Number>().Int32Value();
690
+
691
+ if (!info[1].IsString()) {
692
+ Napi::TypeError::New(env, "params must be a JSON string.")
693
+ .ThrowAsJavaScriptException();
694
+ return env.Null();
695
+ }
696
+ const string json = info[1].As<Napi::String>().Utf8Value();
697
+
698
+ int res = pjw_call_start_inband_dtmf_detection(call_id, json.c_str());
699
+
700
+ if (res != 0) {
701
+ Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
702
+ return env.Null();
703
+ }
704
+
705
+ return env.Null();
706
+ }
707
+
708
+ Napi::Value call_stop_inband_dtmf_detection(const Napi::CallbackInfo &info) {
709
+ Napi::Env env = info.Env();
710
+
711
+ if (info.Length() != 2) {
712
+ Napi::Error::New(env, "Wrong number of arguments. Expected: call_id")
713
+ .ThrowAsJavaScriptException();
714
+ return env.Null();
715
+ }
716
+
717
+ if (!info[0].IsNumber()) {
718
+ Napi::TypeError::New(env, "call_id must be number.")
719
+ .ThrowAsJavaScriptException();
720
+ return env.Null();
721
+ }
722
+ int call_id = info[0].As<Napi::Number>().Int32Value();
723
+
724
+ if (!info[1].IsString()) {
725
+ Napi::TypeError::New(env, "params must be a JSON string.")
726
+ .ThrowAsJavaScriptException();
727
+ return env.Null();
728
+ }
729
+ const string json = info[1].As<Napi::String>().Utf8Value();
730
+
731
+ int res = pjw_call_stop_inband_dtmf_detection(call_id, json.c_str());
732
+
733
+ if (res != 0) {
734
+ Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
735
+ return env.Null();
736
+ }
737
+
738
+ return env.Null();
739
+ }
740
+
741
+ Napi::Value call_start_bfsk_detection(const Napi::CallbackInfo &info) {
742
+ Napi::Env env = info.Env();
743
+
744
+ if (info.Length() != 2) {
745
+ Napi::Error::New(env,
746
+ "Wrong number of arguments. Expected: call_id, params.")
747
+ .ThrowAsJavaScriptException();
748
+ return env.Null();
749
+ }
750
+
751
+ if (!info[0].IsNumber()) {
752
+ Napi::TypeError::New(env, "call_id must be number.")
753
+ .ThrowAsJavaScriptException();
754
+ return env.Null();
755
+ }
756
+ int call_id = info[0].As<Napi::Number>().Int32Value();
757
+
758
+ if (!info[1].IsString()) {
759
+ Napi::TypeError::New(env, "params must be a JSON string.")
760
+ .ThrowAsJavaScriptException();
761
+ return env.Null();
762
+ }
763
+ const string json = info[1].As<Napi::String>().Utf8Value();
764
+
765
+ int res = pjw_call_start_bfsk_detection(call_id, json.c_str());
766
+
767
+ if (res != 0) {
768
+ Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
769
+ return env.Null();
770
+ }
771
+
772
+ return env.Null();
773
+ }
774
+
775
+ Napi::Value call_stop_bfsk_detection(const Napi::CallbackInfo &info) {
776
+ Napi::Env env = info.Env();
777
+
778
+ if (info.Length() != 2) {
779
+ Napi::Error::New(env, "Wrong number of arguments. Expected: call_id")
780
+ .ThrowAsJavaScriptException();
781
+ return env.Null();
782
+ }
783
+
784
+ if (!info[0].IsNumber()) {
785
+ Napi::TypeError::New(env, "call_id must be number.")
786
+ .ThrowAsJavaScriptException();
787
+ return env.Null();
788
+ }
789
+ int call_id = info[0].As<Napi::Number>().Int32Value();
790
+
791
+ if (!info[1].IsString()) {
792
+ Napi::TypeError::New(env, "params must be a JSON string.")
793
+ .ThrowAsJavaScriptException();
794
+ return env.Null();
795
+ }
796
+ const string json = info[1].As<Napi::String>().Utf8Value();
797
+
798
+ int res = pjw_call_stop_bfsk_detection(call_id, json.c_str());
799
+
800
+ if (res != 0) {
801
+ Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
802
+ return env.Null();
803
+ }
804
+
805
+ return env.Null();
806
+ }
807
+
808
+
640
809
 
641
810
  Napi::Value call_stop_record_wav(const Napi::CallbackInfo &info) {
642
811
  Napi::Env env = info.Env();
@@ -1395,25 +1564,26 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
1395
1564
  exports.Set("call_respond", Napi::Function::New(env, call_respond));
1396
1565
  exports.Set("call_terminate", Napi::Function::New(env, call_terminate));
1397
1566
  exports.Set("call_send_dtmf", Napi::Function::New(env, call_send_dtmf));
1567
+ exports.Set("call_send_bfsk", Napi::Function::New(env, call_send_bfsk));
1398
1568
  exports.Set("call_reinvite", Napi::Function::New(env, call_reinvite));
1399
1569
  exports.Set("call_send_request", Napi::Function::New(env, call_send_request));
1400
- exports.Set("call_start_record_wav",
1401
- Napi::Function::New(env, call_start_record_wav));
1402
- exports.Set("call_start_play_wav",
1403
- Napi::Function::New(env, call_start_play_wav));
1404
- exports.Set("call_start_fax", Napi::Function::New(env, call_start_fax));
1405
1570
 
1571
+ exports.Set("call_start_record_wav", Napi::Function::New(env, call_start_record_wav));
1572
+ exports.Set("call_start_play_wav", Napi::Function::New(env, call_start_play_wav));
1573
+ exports.Set("call_start_fax", Napi::Function::New(env, call_start_fax));
1406
1574
  exports.Set("call_start_speech_synth", Napi::Function::New(env, call_start_speech_synth));
1407
-
1408
1575
  exports.Set("call_start_speech_recog", Napi::Function::New(env, call_start_speech_recog));
1576
+ exports.Set("call_start_inband_dtmf_detection", Napi::Function::New(env, call_start_inband_dtmf_detection));
1577
+ exports.Set("call_start_bfsk_detection", Napi::Function::New(env, call_start_bfsk_detection));
1409
1578
 
1410
- exports.Set("call_stop_record_wav",
1411
- Napi::Function::New(env, call_stop_record_wav));
1412
- exports.Set("call_stop_play_wav",
1413
- Napi::Function::New(env, call_stop_play_wav));
1579
+ exports.Set("call_stop_record_wav", Napi::Function::New(env, call_stop_record_wav));
1580
+ exports.Set("call_stop_play_wav", Napi::Function::New(env, call_stop_play_wav));
1414
1581
  exports.Set("call_stop_fax", Napi::Function::New(env, call_stop_fax));
1415
1582
  exports.Set("call_stop_speech_synth", Napi::Function::New(env, call_stop_speech_synth));
1416
1583
  exports.Set("call_stop_speech_recog", Napi::Function::New(env, call_stop_speech_recog));
1584
+ exports.Set("call_stop_inband_dtmf_detection", Napi::Function::New(env, call_stop_inband_dtmf_detection));
1585
+ exports.Set("call_stop_bfsk_detection", Napi::Function::New(env, call_stop_bfsk_detection));
1586
+
1417
1587
  exports.Set("call_get_stream_stat",
1418
1588
  Napi::Function::New(env, call_get_stream_stat));
1419
1589
  // exports.Set("call_refer", Napi::Function::New(env, call_refer));
@@ -47,6 +47,14 @@ int make_evt_dtmf(char *dest, int size, long call_id, int digits_len,
47
47
  call_id, digits_len, digits, mode, media_id);
48
48
  }
49
49
 
50
+ int make_evt_bfsk(char *dest, int size, long call_id, int bits_len,
51
+ const char *bits, int media_id) {
52
+ return snprintf(dest, size,
53
+ "{\"event\": \"bfsk\", \"call_id\": %ld, \"bits\": "
54
+ "\"%.*s\", \"media_id\": %i}",
55
+ call_id, bits_len, bits, media_id);
56
+ }
57
+
50
58
  int make_evt_call_ended(char *dest, int size, long call_id, int sip_msg_len,
51
59
  const char *sip_msg) {
52
60
  printf("make_evt_call_ended sip_msg_len=%i sip_msg=%p\n", sip_msg_len,
@@ -17,6 +17,9 @@ int make_evt_media_update(char *dest, int size, long call_id,
17
17
  int make_evt_dtmf(char *dest, int size, long call_id, int digits_len,
18
18
  const char *digits, int mode, int media_id);
19
19
 
20
+ int make_evt_bfsk(char *dest, int size, long call_id, int bits_len,
21
+ const char *bits, int media_id);
22
+
20
23
  int make_evt_call_ended(char *dest, int size, long call_id, int sip_msg_len,
21
24
  const char *sip_msg);
22
25
 
@@ -0,0 +1,25 @@
1
+ #ifndef __PJMEDIA_BFSK_DET_H__
2
+ #define __PJMEDIA_BFSK_DET_H__
3
+
4
+ #include <pjmedia/port.h>
5
+
6
+ PJ_BEGIN_DECL
7
+
8
+ PJ_DEF(pj_status_t) pjmedia_bfsk_det_create( pj_pool_t *pool,
9
+ unsigned clock_rate,
10
+ unsigned channel_count,
11
+ unsigned samples_per_frame,
12
+ unsigned bits_per_sample,
13
+ void (*cb)(pjmedia_port*,
14
+ void *user_data,
15
+ int bit),
16
+ void *user_data,
17
+ int freq_zero,
18
+ int freq_one,
19
+ int min_level,
20
+ int baud_rate,
21
+ pjmedia_port **p_port);
22
+
23
+ PJ_END_DECL
24
+
25
+ #endif /* __PJMEDIA_BFSK_DET_H__ */