sip-lab 1.12.39 → 1.13.1
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/DEV.md +19 -3
- package/README.md +8 -4
- package/binding.gyp +97 -86
- package/build_deps.sh +3 -2
- package/index.js +14 -7
- package/package.json +7 -2
- package/prebuilds/linux-x64/node.abi102.node +0 -0
- package/prebuilds/linux-x64/node.abi108.node +0 -0
- package/prebuilds/linux-x64/node.abi88.node +0 -0
- package/prebuilds/linux-x64/node.abi93.node +0 -0
- package/samples/16_audio_streams.js +179 -0
- package/samples/delayed_media.js +117 -81
- package/samples/g729.js +50 -28
- package/samples/mrcp_and_audio.js +445 -0
- package/samples/mrcp_and_audio.simplified_media.js +273 -0
- package/samples/mrcp_and_audio.switching_order.js +273 -0
- package/samples/options.js +82 -0
- package/samples/refer.js +247 -0
- package/samples/refuse_telephone_event.js +166 -0
- package/samples/register_no_expires.js +82 -0
- package/samples/register_subscribe.js +36 -4
- package/samples/reinvite_and_dtmf.js +236 -161
- package/samples/reinvite_audio_audio.js +320 -0
- package/samples/reinvite_with_hold_unhold.js +412 -0
- package/samples/send_and_receive_fax.js +4 -8
- package/samples/simple.js +5 -9
- package/samples/sip_cancel.js +4 -6
- package/samples/tcp_and_extra_headers.js +98 -45
- package/samples/two_audio_media.js +497 -0
- package/src/addon.cpp +488 -268
- package/src/event_templates.cpp +84 -35
- package/src/event_templates.hpp +22 -12
- package/src/idmanager.cpp +58 -57
- package/src/idmanager.hpp +10 -10
- package/src/log.cpp +9 -11
- package/src/log.hpp +4 -4
- package/src/sip.cpp +6841 -5040
- package/src/sip.hpp +26 -34
- package/src/packetdumper.cpp +0 -234
- package/src/packetdumper.hpp +0 -67
package/DEV.md
CHANGED
|
@@ -6,26 +6,42 @@ Basic tasks for development:
|
|
|
6
6
|
|
|
7
7
|
#### To build
|
|
8
8
|
```
|
|
9
|
+
sudo 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 cmake
|
|
10
|
+
|
|
9
11
|
npm install
|
|
10
12
|
```
|
|
11
13
|
|
|
14
|
+
Thne confirm it is working:
|
|
15
|
+
```
|
|
16
|
+
node samples/simple.js
|
|
17
|
+
```
|
|
18
|
+
|
|
12
19
|
#### To clean up (for a clean rebuild)
|
|
13
20
|
```
|
|
14
21
|
npx node-gyp clean
|
|
15
22
|
```
|
|
16
23
|
|
|
24
|
+
### To build the addon after changes in source files
|
|
25
|
+
```
|
|
26
|
+
npm run build
|
|
27
|
+
```
|
|
28
|
+
or force a full rebuild
|
|
29
|
+
```
|
|
30
|
+
npm run rebuild
|
|
31
|
+
```
|
|
32
|
+
|
|
17
33
|
#### To update pjproject, spandsp, bcg729 or rapidjson
|
|
18
34
|
Just delete the corresponding library subfolder in subfolder 3drParty.
|
|
19
35
|
|
|
20
36
|
|
|
21
|
-
Then temporarily change
|
|
37
|
+
Then temporarily change build_deps.sh to not checkout a specific version (or checkout a desired commit)
|
|
22
38
|
|
|
23
39
|
Then run
|
|
24
40
|
```
|
|
25
41
|
npm install
|
|
26
42
|
```
|
|
27
43
|
|
|
28
|
-
Then perform code changes and tests. When you are satisfied with them, update
|
|
44
|
+
Then perform code changes and tests. When you are satisfied with them, update build_deps.sh with the new commit IDs.
|
|
29
45
|
|
|
30
46
|
#### prebuild binaries
|
|
31
47
|
Previously we would do:
|
|
@@ -36,7 +52,7 @@ npx prebuildify --strip -t 15.0.0 -t 16.0.0 -t 17.0.0 -t 18.0.0
|
|
|
36
52
|
```
|
|
37
53
|
However the above will build the addon to run on the current OS.
|
|
38
54
|
|
|
39
|
-
Instead we will force the build on debian11 (using docker). So
|
|
55
|
+
Instead we will force the build on debian11 (using docker). So do this instead:
|
|
40
56
|
```
|
|
41
57
|
nvm use v16.13.1
|
|
42
58
|
npx prebuildify-cross -i mayamatakeshi/sip-lab-debian11:latest -t 15.0.0 -t 16.0.0 -t 17.0.0 -t 18.0.0 --strip
|
package/README.md
CHANGED
|
@@ -10,18 +10,22 @@ It permits to:
|
|
|
10
10
|
- send and receive DTMF inband/RFC2833/INFO.
|
|
11
11
|
- play/record wav file on a call
|
|
12
12
|
- send/receive fax (T.30 only)
|
|
13
|
+
- send/receive MRCPv2 messages (TCP only, no TLS)
|
|
13
14
|
|
|
14
15
|
TODO:
|
|
15
|
-
- add suport for T.38 fax
|
|
16
|
-
- add support for WebRTC
|
|
17
16
|
- add support for video playing/recording from/to file
|
|
17
|
+
- add support for T.38 fax
|
|
18
|
+
- add support for WebSocket
|
|
19
|
+
- add support for WebRTC
|
|
20
|
+
- add support for SRTP
|
|
21
|
+
- add support for MSRP
|
|
18
22
|
|
|
19
23
|
### Installation
|
|
20
24
|
|
|
21
|
-
This is
|
|
25
|
+
This is a node.js addon and it is known to work on Debian 11, Debian 10, Ubuntu 22.04 and Ubuntu 20.04.
|
|
22
26
|
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 built of the addon will be executed. Being the case, be patient as the build process will take several minutes to complete).
|
|
23
27
|
|
|
24
|
-
To install it, first install some dependencies
|
|
28
|
+
To install it, first install some build dependencies (you might not need them if your are on Debian 11).
|
|
25
29
|
```
|
|
26
30
|
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 cmake
|
|
27
31
|
```
|
package/binding.gyp
CHANGED
|
@@ -1,7 +1,102 @@
|
|
|
1
1
|
{
|
|
2
2
|
'targets': [
|
|
3
|
+
{
|
|
4
|
+
'target_name': 'all-settings',
|
|
5
|
+
'type': 'none',
|
|
6
|
+
'all_dependent_settings': {
|
|
7
|
+
'include_dirs': [
|
|
8
|
+
"3rdParty/pjproject/pjsip/include",
|
|
9
|
+
"3rdParty/pjproject/pjlib/include",
|
|
10
|
+
"3rdParty/pjproject/pjlib-util/include",
|
|
11
|
+
"3rdParty/pjproject/pjnath/include",
|
|
12
|
+
"3rdParty/pjproject/pjmedia/include",
|
|
13
|
+
"include",
|
|
14
|
+
"src",
|
|
15
|
+
"src/pjmedia/include",
|
|
16
|
+
"src/pjmedia/include/pjmedia",
|
|
17
|
+
"src/pjmedia/include/chainlink",
|
|
18
|
+
"3rdParty/rapidjson/include",
|
|
19
|
+
"3rdParty/spandsp/src",
|
|
20
|
+
"<!@(node -p \"require('node-addon-api').include\")",
|
|
21
|
+
],
|
|
22
|
+
'conditions': [
|
|
23
|
+
[ 'OS!="win"', {
|
|
24
|
+
'cflags_cc': [
|
|
25
|
+
'-g',
|
|
26
|
+
'-fexceptions',
|
|
27
|
+
'-Wno-maybe-uninitialized',
|
|
28
|
+
'-fPIC',
|
|
29
|
+
],
|
|
30
|
+
'ldflags_cc': [
|
|
31
|
+
'-all-static',
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
],
|
|
36
|
+
'link_settings': {
|
|
37
|
+
'libraries': [
|
|
38
|
+
'-L ../3rdParty/pjproject/pjnath/lib',
|
|
39
|
+
'-L ../3rdParty/pjproject/pjlib/lib',
|
|
40
|
+
'-L ../3rdParty/pjproject/pjlib-util/lib',
|
|
41
|
+
'-L ../3rdParty/pjproject/third_party/lib',
|
|
42
|
+
'-L ../3rdParty/pjproject/pjmedia/lib',
|
|
43
|
+
'-L ../3rdParty/pjproject/pjsip/lib',
|
|
44
|
+
'-L ../3rdParty/pjproject/third_party/lib',
|
|
45
|
+
'-l pjnath-x86_64-unknown-linux-gnu',
|
|
46
|
+
'-l ilbccodec-x86_64-unknown-linux-gnu',
|
|
47
|
+
'-l webrtc-x86_64-unknown-linux-gnu',
|
|
48
|
+
'-l yuv-x86_64-unknown-linux-gnu',
|
|
49
|
+
'-l speex-x86_64-unknown-linux-gnu',
|
|
50
|
+
'-l gsmcodec-x86_64-unknown-linux-gnu',
|
|
51
|
+
'-l g7221codec-x86_64-unknown-linux-gnu',
|
|
52
|
+
'-l resample-x86_64-unknown-linux-gnu',
|
|
53
|
+
'-l pjmedia-audiodev-x86_64-unknown-linux-gnu',
|
|
54
|
+
'-l pjmedia-codec-x86_64-unknown-linux-gnu',
|
|
55
|
+
'-l pjmedia-videodev-x86_64-unknown-linux-gnu',
|
|
56
|
+
'-l pjmedia-x86_64-unknown-linux-gnu',
|
|
57
|
+
'-l pjsdp-x86_64-unknown-linux-gnu',
|
|
58
|
+
'-l pjsip-x86_64-unknown-linux-gnu',
|
|
59
|
+
'-l pjsua2-x86_64-unknown-linux-gnu',
|
|
60
|
+
'-l pjsip-ua-x86_64-unknown-linux-gnu',
|
|
61
|
+
'-l pjsip-simple-x86_64-unknown-linux-gnu',
|
|
62
|
+
'-l pjsua-x86_64-unknown-linux-gnu',
|
|
63
|
+
'-l pj-x86_64-unknown-linux-gnu',
|
|
64
|
+
'-l pjlib-util-x86_64-unknown-linux-gnu',
|
|
65
|
+
'../3rdParty/spandsp/src/.libs/libspandsp.a',
|
|
66
|
+
'../3rdParty/bcg729/src/libbcg729.a',
|
|
67
|
+
'-lstdc++',
|
|
68
|
+
'-lopus',
|
|
69
|
+
'-lssl',
|
|
70
|
+
'-lcrypto',
|
|
71
|
+
'-luuid',
|
|
72
|
+
'-lm',
|
|
73
|
+
'-ldl',
|
|
74
|
+
'-ltiff',
|
|
75
|
+
'-lrt',
|
|
76
|
+
'-lpthread',
|
|
77
|
+
'-lasound',
|
|
78
|
+
'-lSDL2',
|
|
79
|
+
'-lavdevice',
|
|
80
|
+
'-lavformat',
|
|
81
|
+
'-lavcodec',
|
|
82
|
+
'-lswscale',
|
|
83
|
+
'-lavutil',
|
|
84
|
+
'-lv4l2',
|
|
85
|
+
'-lopencore-amrnb',
|
|
86
|
+
'-lopencore-amrwb',
|
|
87
|
+
'-lvo-amrwbenc',
|
|
88
|
+
'-lspeex',
|
|
89
|
+
'-l srtp-x86_64-unknown-linux-gnu',
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
|
|
3
95
|
{
|
|
4
96
|
'target_name': 'addon',
|
|
97
|
+
'type': 'loadable_module', # this is default for node-gyp but gyp will complain if absent.
|
|
98
|
+
'dependencies': ['all-settings'],
|
|
99
|
+
|
|
5
100
|
'actions': [
|
|
6
101
|
{
|
|
7
102
|
'action_name': 'build_deps',
|
|
@@ -11,6 +106,7 @@
|
|
|
11
106
|
'action': ['bash', './build_deps.sh'],
|
|
12
107
|
},
|
|
13
108
|
],
|
|
109
|
+
|
|
14
110
|
'sources': [
|
|
15
111
|
'src/log.cpp',
|
|
16
112
|
'src/event_templates.cpp',
|
|
@@ -24,91 +120,6 @@
|
|
|
24
120
|
'src/pjmedia/src/chainlink/chainlink_wire_port.c',
|
|
25
121
|
'src/pjmedia/src/chainlink/chainlink_fax.c',
|
|
26
122
|
],
|
|
27
|
-
'include_dirs': [
|
|
28
|
-
"3rdParty/pjproject/pjsip/include",
|
|
29
|
-
"3rdParty/pjproject/pjlib/include",
|
|
30
|
-
"3rdParty/pjproject/pjlib-util/include",
|
|
31
|
-
"3rdParty/pjproject/pjnath/include",
|
|
32
|
-
"3rdParty/pjproject/pjmedia/include",
|
|
33
|
-
"include",
|
|
34
|
-
"src",
|
|
35
|
-
"src/pjmedia/include",
|
|
36
|
-
"src/pjmedia/include/pjmedia",
|
|
37
|
-
"src/pjmedia/include/chainlink",
|
|
38
|
-
"3rdParty/rapidjson/include",
|
|
39
|
-
"3rdParty/spandsp/src",
|
|
40
|
-
"<!@(node -p \"require('node-addon-api').include\")",
|
|
41
|
-
],
|
|
42
|
-
'conditions': [
|
|
43
|
-
[ 'OS!="win"', {
|
|
44
|
-
'cflags_cc': [
|
|
45
|
-
'-g',
|
|
46
|
-
'-fexceptions',
|
|
47
|
-
'-Wno-maybe-uninitialized',
|
|
48
|
-
'-fPIC',
|
|
49
|
-
],
|
|
50
|
-
'ldflags_cc': [
|
|
51
|
-
'-all-static',
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
],
|
|
56
|
-
'link_settings': {
|
|
57
|
-
'libraries': [
|
|
58
|
-
'-L ../3rdParty/pjproject/pjnath/lib',
|
|
59
|
-
'-L ../3rdParty/pjproject/pjlib/lib',
|
|
60
|
-
'-L ../3rdParty/pjproject/pjlib-util/lib',
|
|
61
|
-
'-L ../3rdParty/pjproject/third_party/lib',
|
|
62
|
-
'-L ../3rdParty/pjproject/pjmedia/lib',
|
|
63
|
-
'-L ../3rdParty/pjproject/pjsip/lib',
|
|
64
|
-
'-L ../3rdParty/pjproject/third_party/lib',
|
|
65
|
-
'-l pjnath-x86_64-unknown-linux-gnu',
|
|
66
|
-
'-l ilbccodec-x86_64-unknown-linux-gnu',
|
|
67
|
-
'-l srtp-x86_64-unknown-linux-gnu',
|
|
68
|
-
'-l webrtc-x86_64-unknown-linux-gnu',
|
|
69
|
-
'-l yuv-x86_64-unknown-linux-gnu',
|
|
70
|
-
'-l speex-x86_64-unknown-linux-gnu',
|
|
71
|
-
'-l gsmcodec-x86_64-unknown-linux-gnu',
|
|
72
|
-
'-l g7221codec-x86_64-unknown-linux-gnu',
|
|
73
|
-
'-l resample-x86_64-unknown-linux-gnu',
|
|
74
|
-
'-l pjmedia-audiodev-x86_64-unknown-linux-gnu',
|
|
75
|
-
'-l pjmedia-codec-x86_64-unknown-linux-gnu',
|
|
76
|
-
'-l pjmedia-videodev-x86_64-unknown-linux-gnu',
|
|
77
|
-
'-l pjmedia-x86_64-unknown-linux-gnu',
|
|
78
|
-
'-l pjsdp-x86_64-unknown-linux-gnu',
|
|
79
|
-
'-l pjsip-x86_64-unknown-linux-gnu',
|
|
80
|
-
'-l pjsua2-x86_64-unknown-linux-gnu',
|
|
81
|
-
'-l pjsip-ua-x86_64-unknown-linux-gnu',
|
|
82
|
-
'-l pjsip-simple-x86_64-unknown-linux-gnu',
|
|
83
|
-
'-l pjsua-x86_64-unknown-linux-gnu',
|
|
84
|
-
'-l pj-x86_64-unknown-linux-gnu',
|
|
85
|
-
'-l pjlib-util-x86_64-unknown-linux-gnu',
|
|
86
|
-
'../3rdParty/spandsp/src/.libs/libspandsp.a',
|
|
87
|
-
'../3rdParty/bcg729/src/libbcg729.a',
|
|
88
|
-
'-lstdc++',
|
|
89
|
-
'-lopus',
|
|
90
|
-
'-lssl',
|
|
91
|
-
'-lcrypto',
|
|
92
|
-
'-luuid',
|
|
93
|
-
'-lm',
|
|
94
|
-
'-ldl',
|
|
95
|
-
'-ltiff',
|
|
96
|
-
'-lrt',
|
|
97
|
-
'-lpthread',
|
|
98
|
-
'-lasound',
|
|
99
|
-
'-lSDL2',
|
|
100
|
-
'-lavdevice',
|
|
101
|
-
'-lavformat',
|
|
102
|
-
'-lavcodec',
|
|
103
|
-
'-lswscale',
|
|
104
|
-
'-lavutil',
|
|
105
|
-
'-lv4l2',
|
|
106
|
-
'-lopencore-amrnb',
|
|
107
|
-
'-lopencore-amrwb',
|
|
108
|
-
'-lvo-amrwbenc',
|
|
109
|
-
'-lspeex',
|
|
110
|
-
],
|
|
111
|
-
},
|
|
112
123
|
},
|
|
113
|
-
]
|
|
124
|
+
],
|
|
114
125
|
}
|
package/build_deps.sh
CHANGED
|
@@ -53,7 +53,9 @@ then
|
|
|
53
53
|
cd pjproject
|
|
54
54
|
#git checkout de3d744c2e1188b59bb907b6ee32ef83740ebc64
|
|
55
55
|
#git checkout 33a3c9e0a5eb84426edef05a9aa98af17d8011c3 # required for bcg729
|
|
56
|
-
git checkout 797088ed133c98492519b7d042b75735f6f9388c # updated as part of #21
|
|
56
|
+
#git checkout 797088ed133c98492519b7d042b75735f6f9388c # updated as part of #21
|
|
57
|
+
#git checkout 651df5b50129b7c5a5feec8336dda4468d53d2b0 # updated to latest to see of crash issues improve
|
|
58
|
+
git checkout 043926a5846963a2c99378e8daa495230923eaab # update to try to solve ##49 (but issue remains)
|
|
57
59
|
|
|
58
60
|
cat > user.mak <<EOF
|
|
59
61
|
export CFLAGS += -fPIC -g
|
|
@@ -63,7 +65,6 @@ EOF
|
|
|
63
65
|
sed -i -r 's/BCG729_LIBS="-lbcg729"/BCG729_LIBS=''/' aconfigure
|
|
64
66
|
LIBS=`pwd`/../bcg729/src/libbcg729.a ./configure --with-bcg729=`pwd`/../bcg729
|
|
65
67
|
cat > pjlib/include/pj/config_site.h <<EOF
|
|
66
|
-
#define PJMEDIA_HAS_SRTP 0
|
|
67
68
|
EOF
|
|
68
69
|
make dep && make clean && make
|
|
69
70
|
fi
|
package/index.js
CHANGED
|
@@ -48,6 +48,11 @@ addon.account = {
|
|
|
48
48
|
unregister: addon.account_unregister,
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
addon.request = {
|
|
52
|
+
create: (t_id, params) => { return addon.request_create(t_id, JSON.stringify(params)) },
|
|
53
|
+
respond: (r_id, params) => { return addon.request_respond(r_id, JSON.stringify(params)) },
|
|
54
|
+
}
|
|
55
|
+
|
|
51
56
|
addon.call = {
|
|
52
57
|
create: (t_id, params) => { return addon.call_create(t_id, JSON.stringify(params)) },
|
|
53
58
|
respond: (c_id, params) => { return addon.call_respond(c_id, JSON.stringify(params)) },
|
|
@@ -55,16 +60,18 @@ addon.call = {
|
|
|
55
60
|
send_dtmf: (c_id, params) => { return addon.call_send_dtmf(c_id, JSON.stringify(params)) },
|
|
56
61
|
reinvite: (c_id, params) => { return addon.call_reinvite(c_id, JSON.stringify(params ? params : {})) },
|
|
57
62
|
send_request: (c_id, params) => { return addon.call_send_request(c_id, JSON.stringify(params)) },
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
start_record_wav: (c_id, params) => { return addon.call_start_record_wav(c_id, JSON.stringify(params)) },
|
|
64
|
+
start_play_wav: (c_id, params) => { return addon.call_start_play_wav(c_id, JSON.stringify(params)) },
|
|
65
|
+
stop_record_wav: (c_id, params) => { return addon.call_stop_record_wav(c_id, JSON.stringify(params ? params : {})) },
|
|
66
|
+
stop_play_wav: (c_id, params) => { return addon.call_stop_play_wav(c_id, JSON.stringify(params ? params : {})) },
|
|
62
67
|
start_fax: (c_id, params) => { return addon.call_start_fax(c_id, JSON.stringify(params)) },
|
|
63
|
-
stop_fax: addon.call_stop_fax,
|
|
64
|
-
get_stream_stat: addon.call_get_stream_stat,
|
|
65
|
-
refer: (c_id, params) => { return addon.call_refer(c_id, JSON.stringify(params)) },
|
|
68
|
+
stop_fax: (c_id, params) => { return addon.call_stop_fax(c_id, JSON.stringify(params ? params : {})) },
|
|
69
|
+
get_stream_stat: (c_id, params) => { return addon.call_get_stream_stat(c_id, JSON.stringify(params ? params : {})) },
|
|
70
|
+
//refer: (c_id, params) => { return addon.call_refer(c_id, JSON.stringify(params)) },
|
|
66
71
|
get_info: addon.call_get_info,
|
|
67
72
|
gen_string_replaces: addon.call_gen_string_replaces,
|
|
73
|
+
|
|
74
|
+
send_mrcp_msg: (c_id, params) => { return addon.call_send_tcp_msg(c_id, JSON.stringify(params ? params : {})) },
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
addon.subscriber = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sip-lab",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"install": "node-gyp-build",
|
|
11
|
+
"build": "node-gyp build",
|
|
12
|
+
"rebuild": "node-gyp rebuild",
|
|
11
13
|
"test": "./runtests"
|
|
12
14
|
},
|
|
13
15
|
"repository": {
|
|
@@ -19,10 +21,13 @@
|
|
|
19
21
|
"gypfile": true,
|
|
20
22
|
"homepage": "https://github.com/MayamaTakeshi/sip-lab",
|
|
21
23
|
"dependencies": {
|
|
22
|
-
"@mayama/zeq": "^4.1.
|
|
24
|
+
"@mayama/zeq": "^4.1.17",
|
|
25
|
+
"mrcp": "^1.4.0",
|
|
26
|
+
"mrcp-matching": "^1.0.0",
|
|
23
27
|
"node-addon-api": "^5.0.0",
|
|
24
28
|
"node-gyp": "^9.3.0",
|
|
25
29
|
"node-gyp-build": "^4.5.0",
|
|
30
|
+
"sdp-matching": "^1.2.0",
|
|
26
31
|
"sip-matching": "^1.3.34"
|
|
27
32
|
},
|
|
28
33
|
"devDependencies": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
const sip = require ('../index.js')
|
|
2
|
+
const Zeq = require('@mayama/zeq')
|
|
3
|
+
const m = require('data-matching')
|
|
4
|
+
const sip_msg = require('sip-matching')
|
|
5
|
+
const _ = require('lodash')
|
|
6
|
+
|
|
7
|
+
// here we create our Zeq instance
|
|
8
|
+
var z = new Zeq()
|
|
9
|
+
|
|
10
|
+
// here we are restricting codec to PCMU to avoid having the SDP to become too large
|
|
11
|
+
sip.set_codecs('pcmu/8000/1:128')
|
|
12
|
+
|
|
13
|
+
// here we asking for accumulated DTMF to be reported in case of no more digits after 500 ms
|
|
14
|
+
sip.dtmf_aggregation_on(500)
|
|
15
|
+
|
|
16
|
+
async function test() {
|
|
17
|
+
// here we set our Zeq instance to trap events generated by sip-lab event_source
|
|
18
|
+
z.trap_events(sip.event_source, 'event', (evt) => {
|
|
19
|
+
var e = evt.args[0]
|
|
20
|
+
return e
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
// here we start sip-lab
|
|
24
|
+
console.log(sip.start((data) => { console.log(data)} ))
|
|
25
|
+
|
|
26
|
+
// Here we create the SIP endpoints (transports).
|
|
27
|
+
// Since we don't specify the port, an available port will be allocated.
|
|
28
|
+
// Since we don't specify the type ('udp' or 'tcp' or 'tls'), 'udp' will be used by default.
|
|
29
|
+
const t1 = sip.transport.create({address: "127.0.0.1", type: 'tcp'})
|
|
30
|
+
const t2 = sip.transport.create({address: "127.0.0.1", type: 'tcp'})
|
|
31
|
+
|
|
32
|
+
// here we just print the transports
|
|
33
|
+
console.log("t1", t1)
|
|
34
|
+
console.log("t2", t2)
|
|
35
|
+
|
|
36
|
+
// make the call from t1 to t2 with 16 audio streams offering.
|
|
37
|
+
const oc = sip.call.create(t1.id, {from_uri: 'sip:alice@test.com', to_uri: `sip:bob@${t2.address}:${t2.port}`, media: 'audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio'})
|
|
38
|
+
|
|
39
|
+
// Here we will wait for the call to arrive at t2
|
|
40
|
+
// We will also get a '100 Trying' that is sent by sip-lab automatically
|
|
41
|
+
// We will wait for at most 1000ms. If all events don't arrive within 1000ms, an exception will be thrown and the test will fail due to timeout.
|
|
42
|
+
await z.wait([
|
|
43
|
+
{
|
|
44
|
+
event: "incoming_call",
|
|
45
|
+
call_id: m.collect("call_id"),
|
|
46
|
+
transport_id: t2.id,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
event: 'response',
|
|
50
|
+
call_id: oc.id,
|
|
51
|
+
method: 'INVITE',
|
|
52
|
+
msg: sip_msg({
|
|
53
|
+
$rs: '100',
|
|
54
|
+
$rr: 'Trying',
|
|
55
|
+
'$(hdrcnt(via))': 1,
|
|
56
|
+
'$hdr(call-id)': m.collect('sip_call_id'),
|
|
57
|
+
$fU: 'alice',
|
|
58
|
+
$fd: 'test.com',
|
|
59
|
+
$tU: 'bob',
|
|
60
|
+
'$hdr(l)': '0',
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
], 1000)
|
|
64
|
+
// Details about zeq wait(list_of_events_to_wait_for, timeout_in_ms):
|
|
65
|
+
// The order of events in the list is irrelevant.
|
|
66
|
+
// What matters is that all events arrive within the specified timeout.
|
|
67
|
+
// When specifying events, you can be as detailed or succinct as you need.
|
|
68
|
+
// For example, the above event 'response' is waiting for a SIP '100 Trying' to arrive,
|
|
69
|
+
// but we are specifying things to match just to show that we can be very detailed when performing a match.
|
|
70
|
+
// But it could have been just like this:
|
|
71
|
+
//
|
|
72
|
+
// {
|
|
73
|
+
// event: 'response',
|
|
74
|
+
// call_id: oc.id,
|
|
75
|
+
// method: 'INVITE',
|
|
76
|
+
// msg: sip_msg({
|
|
77
|
+
// $rs: '100',
|
|
78
|
+
// }),
|
|
79
|
+
// }
|
|
80
|
+
// Regarding the function sip_msg() this is a special matching function provided by https://github.com/MayamaTakeshi/sip-matching that makes it
|
|
81
|
+
// easy to match a SIP message using openser/kamailio/opensips pseudo-variables syntax.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// Here we store data for the incoming call
|
|
85
|
+
// just to organize our code (not really needed)
|
|
86
|
+
const ic = {
|
|
87
|
+
id: z.store.call_id,
|
|
88
|
+
sip_call_id: z.store.sip_call_id,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Now we answer the call at t2 side and accept all 16 streams
|
|
92
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK', media: 'audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio,audio'})
|
|
93
|
+
|
|
94
|
+
// Then we wait for the '200 OK' at the t1 side
|
|
95
|
+
// We will also get event 'media_update' for both sides indicating media streams (RTP) were set up successfully
|
|
96
|
+
await z.wait([
|
|
97
|
+
{
|
|
98
|
+
event: 'response',
|
|
99
|
+
call_id: oc.id,
|
|
100
|
+
method: 'INVITE',
|
|
101
|
+
msg: sip_msg({
|
|
102
|
+
$rs: '200',
|
|
103
|
+
$rr: 'OK',
|
|
104
|
+
'$(hdrcnt(VIA))': 1,
|
|
105
|
+
$fU: 'alice',
|
|
106
|
+
$fd: 'test.com',
|
|
107
|
+
$tU: 'bob',
|
|
108
|
+
'$hdr(content-type)': 'application/sdp',
|
|
109
|
+
$rb: '!{_}a=sendrecv',
|
|
110
|
+
}),
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
event: 'media_update',
|
|
114
|
+
call_id: oc.id,
|
|
115
|
+
status: 'ok',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
event: 'media_update',
|
|
119
|
+
call_id: ic.id,
|
|
120
|
+
status: 'ok',
|
|
121
|
+
},
|
|
122
|
+
], 1000)
|
|
123
|
+
|
|
124
|
+
sip.call.send_dtmf(oc.id, {digits: '1234', mode: 0})
|
|
125
|
+
|
|
126
|
+
await z.wait(_.chain(_.range(16)).map(n => ({
|
|
127
|
+
event: 'dtmf',
|
|
128
|
+
call_id: ic.id,
|
|
129
|
+
digits: '1234',
|
|
130
|
+
mode: 0,
|
|
131
|
+
media_id: n,
|
|
132
|
+
})).value(), 3000)
|
|
133
|
+
|
|
134
|
+
sip.call.send_dtmf(ic.id, {digits: '4321', mode: 1})
|
|
135
|
+
|
|
136
|
+
await z.wait(_.chain(_.range(16)).map(n => ({
|
|
137
|
+
event: 'dtmf',
|
|
138
|
+
call_id: oc.id,
|
|
139
|
+
digits: '4321',
|
|
140
|
+
mode: 1,
|
|
141
|
+
media_id: n,
|
|
142
|
+
})).value(), 3000)
|
|
143
|
+
|
|
144
|
+
// now we terminate the call from t1 side
|
|
145
|
+
sip.call.terminate(oc.id)
|
|
146
|
+
|
|
147
|
+
// and wait for termination events
|
|
148
|
+
await z.wait([
|
|
149
|
+
{
|
|
150
|
+
event: 'response',
|
|
151
|
+
call_id: oc.id,
|
|
152
|
+
method: 'BYE',
|
|
153
|
+
msg: sip_msg({
|
|
154
|
+
$rs: '200',
|
|
155
|
+
$rr: 'OK',
|
|
156
|
+
}),
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
event: 'call_ended',
|
|
160
|
+
call_id: oc.id,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
event: 'call_ended',
|
|
164
|
+
call_id: ic.id,
|
|
165
|
+
},
|
|
166
|
+
], 1000)
|
|
167
|
+
|
|
168
|
+
console.log("Success")
|
|
169
|
+
|
|
170
|
+
sip.stop()
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
test()
|
|
175
|
+
.catch(e => {
|
|
176
|
+
console.error(e)
|
|
177
|
+
process.exit(1)
|
|
178
|
+
})
|
|
179
|
+
|