sip-lab 1.38.0 → 1.40.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.
- package/DEV.md +2 -2
- package/binding.gyp +6 -1
- package/build_deps.sh +2 -1
- package/index.js +2 -0
- package/package.json +2 -2
- package/prebuilds/linux-x64/node.abi102.node +0 -0
- package/prebuilds/linux-x64/node.abi108.node +0 -0
- package/prebuilds/linux-x64/node.abi111.node +0 -0
- package/prebuilds/linux-x64/node.abi115.node +0 -0
- package/prebuilds/linux-x64/node.abi120.node +0 -0
- package/prebuilds/linux-x64/node.abi88.node +0 -0
- package/prebuilds/linux-x64/node.abi93.node +0 -0
- package/runtests +112 -36
- package/samples/gsm.js +230 -0
- package/samples/ilbc.js +230 -0
- package/samples/mrcp_and_audio.no_rest_between_msgs.js +254 -0
- package/samples/opus.wideband.js +247 -0
- package/samples/secure_websocket.js +156 -0
- package/samples/secure_websocket_opus_srtp_ice.js +170 -0
- package/samples/simple.js +26 -0
- package/samples/t +239 -0
- package/samples/websocket.js +156 -0
- package/src/addon.cpp +27 -0
- package/src/pjsip/include/pjsip/sip_transport_ws.h +89 -0
- package/src/pjsip/src/pjsip/sip_transport_ws.c +867 -0
- package/src/sip.cpp +497 -61
- package/src/sip.hpp +2 -0
- package/samples/ic.wav +0 -0
- package/samples/oc.wav +0 -0
package/samples/t
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
var sip = require ('../index.js')
|
|
2
|
+
var Zeq = require('@mayama/zeq')
|
|
3
|
+
var z = new Zeq()
|
|
4
|
+
var m = require('data-matching')
|
|
5
|
+
var sip_msg = require('sip-matching')
|
|
6
|
+
var sdp = require('sdp-matching')
|
|
7
|
+
|
|
8
|
+
var assert = require('assert')
|
|
9
|
+
|
|
10
|
+
async function test() {
|
|
11
|
+
//sip.set_log_level(6)
|
|
12
|
+
sip.dtmf_aggregation_on(500)
|
|
13
|
+
|
|
14
|
+
z.trap_events(sip.event_source, 'event', (evt) => {
|
|
15
|
+
var e = evt.args[0]
|
|
16
|
+
return e
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
console.log(sip.start((data) => { console.log(data)} ))
|
|
20
|
+
|
|
21
|
+
t1 = sip.transport.create({address: "127.0.0.1", type: 'udp'})
|
|
22
|
+
t2 = sip.transport.create({address: "127.0.0.1", type: 'udp'})
|
|
23
|
+
|
|
24
|
+
console.log("t1", t1)
|
|
25
|
+
console.log("t2", t2)
|
|
26
|
+
|
|
27
|
+
console.log(sip.get_codecs())
|
|
28
|
+
sip.set_codecs("opus/48000/2:128")
|
|
29
|
+
|
|
30
|
+
flags = 0
|
|
31
|
+
|
|
32
|
+
oc = sip.call.create(t1.id, {from_uri: 'sip:alice@test.com', to_uri: `sip:bob@${t2.address}:${t2.port}`})
|
|
33
|
+
|
|
34
|
+
await z.wait([
|
|
35
|
+
{
|
|
36
|
+
event: "incoming_call",
|
|
37
|
+
call_id: m.collect("call_id"),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
event: 'response',
|
|
41
|
+
call_id: oc.id,
|
|
42
|
+
method: 'INVITE',
|
|
43
|
+
msg: sip_msg({
|
|
44
|
+
$rs: '100',
|
|
45
|
+
$rr: 'Trying',
|
|
46
|
+
}),
|
|
47
|
+
},
|
|
48
|
+
], 1000)
|
|
49
|
+
|
|
50
|
+
ic = {
|
|
51
|
+
id: z.$call_id,
|
|
52
|
+
sip_call_id: z.$sip_call_id,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK'})
|
|
56
|
+
|
|
57
|
+
await z.wait([
|
|
58
|
+
{
|
|
59
|
+
event: 'media_update',
|
|
60
|
+
call_id: oc.id,
|
|
61
|
+
status: 'ok',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
event: 'media_update',
|
|
65
|
+
call_id: ic.id,
|
|
66
|
+
status: 'ok',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
event: 'response',
|
|
70
|
+
call_id: oc.id,
|
|
71
|
+
method: 'INVITE',
|
|
72
|
+
msg: sip_msg({
|
|
73
|
+
$rs: '200',
|
|
74
|
+
$rr: 'OK',
|
|
75
|
+
'hdr_content_type': 'application/sdp',
|
|
76
|
+
$rb: '!{_}a=sendrecv!{_}',
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
], 1000)
|
|
80
|
+
|
|
81
|
+
sip.call.start_record_wav(oc.id, {file: './oc.wav'})
|
|
82
|
+
sip.call.start_record_wav(ic.id, {file: './ic.wav'})
|
|
83
|
+
|
|
84
|
+
sip.call.start_play_wav(oc.id, {file: 'samples/artifacts/hello_good_morning.wav', end_of_file_event: true, no_loop: true})
|
|
85
|
+
sip.call.start_play_wav(ic.id, {file: 'samples/artifacts/hello_good_morning.wav', end_of_file_event: true, no_loop: true})
|
|
86
|
+
|
|
87
|
+
await z.wait([
|
|
88
|
+
{
|
|
89
|
+
event: 'end_of_file',
|
|
90
|
+
call_id: oc.id,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
event: 'end_of_file',
|
|
94
|
+
call_id: ic.id,
|
|
95
|
+
},
|
|
96
|
+
], 5000)
|
|
97
|
+
|
|
98
|
+
sip.call.reinvite(oc.id)
|
|
99
|
+
|
|
100
|
+
await z.wait([
|
|
101
|
+
{
|
|
102
|
+
event: 'reinvite',
|
|
103
|
+
call_id: ic.id
|
|
104
|
+
},
|
|
105
|
+
], 1000)
|
|
106
|
+
|
|
107
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK'})
|
|
108
|
+
|
|
109
|
+
await z.wait([
|
|
110
|
+
{
|
|
111
|
+
event: 'response',
|
|
112
|
+
call_id: oc.id,
|
|
113
|
+
method: 'INVITE',
|
|
114
|
+
msg: sip_msg({
|
|
115
|
+
$rs: '100',
|
|
116
|
+
}),
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
event: 'response',
|
|
120
|
+
call_id: oc.id,
|
|
121
|
+
method: 'INVITE',
|
|
122
|
+
msg: sip_msg({
|
|
123
|
+
$rs: '200',
|
|
124
|
+
$rr: 'OK',
|
|
125
|
+
$rb: '!{_}a=sendrecv!{_}',
|
|
126
|
+
}),
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
event: 'media_update',
|
|
130
|
+
call_id: oc.id,
|
|
131
|
+
status: 'ok',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
event: 'media_update',
|
|
135
|
+
call_id: ic.id,
|
|
136
|
+
status: 'ok',
|
|
137
|
+
},
|
|
138
|
+
], 500)
|
|
139
|
+
|
|
140
|
+
sip.call.reinvite(oc.id, false, 0)
|
|
141
|
+
|
|
142
|
+
await z.wait([
|
|
143
|
+
{
|
|
144
|
+
event: 'reinvite',
|
|
145
|
+
call_id: ic.id
|
|
146
|
+
},
|
|
147
|
+
], 1000)
|
|
148
|
+
|
|
149
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK'})
|
|
150
|
+
|
|
151
|
+
await z.wait([
|
|
152
|
+
{
|
|
153
|
+
event: 'response',
|
|
154
|
+
call_id: oc.id,
|
|
155
|
+
method: 'INVITE',
|
|
156
|
+
msg: sip_msg({
|
|
157
|
+
$rs: '100',
|
|
158
|
+
}),
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
event: 'response',
|
|
162
|
+
call_id: oc.id,
|
|
163
|
+
method: 'INVITE',
|
|
164
|
+
msg: sip_msg({
|
|
165
|
+
$rs: '200',
|
|
166
|
+
$rr: 'OK',
|
|
167
|
+
$rb: '!{_}a=sendrecv!{_}',
|
|
168
|
+
}),
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
event: 'media_update',
|
|
172
|
+
call_id: oc.id,
|
|
173
|
+
status: 'ok',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
event: 'media_update',
|
|
177
|
+
call_id: ic.id,
|
|
178
|
+
status: 'ok',
|
|
179
|
+
},
|
|
180
|
+
], 500)
|
|
181
|
+
|
|
182
|
+
oc_stat = sip.call.get_stream_stat(oc.id, {media_id: 0})
|
|
183
|
+
ic_stat = sip.call.get_stream_stat(ic.id, {media_id: 0})
|
|
184
|
+
|
|
185
|
+
console.log(oc_stat)
|
|
186
|
+
console.log(ic_stat)
|
|
187
|
+
|
|
188
|
+
oc_stat = JSON.parse(oc_stat)
|
|
189
|
+
ic_stat = JSON.parse(ic_stat)
|
|
190
|
+
|
|
191
|
+
assert(oc_stat.CodecInfo == 'opus/8000/1')
|
|
192
|
+
assert(ic_stat.CodecInfo == 'opus/8000/1')
|
|
193
|
+
|
|
194
|
+
await z.sleep(100)
|
|
195
|
+
|
|
196
|
+
sip.call.start_inband_dtmf_detection(oc.id)
|
|
197
|
+
sip.call.start_inband_dtmf_detection(ic.id)
|
|
198
|
+
|
|
199
|
+
sip.call.send_dtmf(oc.id, {digits: '12', mode: 1})
|
|
200
|
+
sip.call.send_dtmf(ic.id, {digits: '21', mode: 1})
|
|
201
|
+
|
|
202
|
+
await z.sleep(1000)
|
|
203
|
+
|
|
204
|
+
sip.call.stop_record_wav(oc.id)
|
|
205
|
+
sip.call.stop_record_wav(ic.id)
|
|
206
|
+
|
|
207
|
+
sip.call.terminate(oc.id)
|
|
208
|
+
|
|
209
|
+
await z.wait([
|
|
210
|
+
{
|
|
211
|
+
event: 'call_ended',
|
|
212
|
+
call_id: oc.id,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
event: 'call_ended',
|
|
216
|
+
call_id: ic.id,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
event: 'response',
|
|
220
|
+
call_id: oc.id,
|
|
221
|
+
method: 'BYE',
|
|
222
|
+
msg: sip_msg({
|
|
223
|
+
$rs: '200',
|
|
224
|
+
$rr: 'OK',
|
|
225
|
+
}),
|
|
226
|
+
},
|
|
227
|
+
], 1000)
|
|
228
|
+
|
|
229
|
+
console.log("Success")
|
|
230
|
+
|
|
231
|
+
sip.stop()
|
|
232
|
+
process.exit(0)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
test()
|
|
236
|
+
.catch(e => {
|
|
237
|
+
console.error(e)
|
|
238
|
+
process.exit(1)
|
|
239
|
+
})
|
|
@@ -0,0 +1,156 @@
|
|
|
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
|
+
|
|
6
|
+
var z = new Zeq()
|
|
7
|
+
|
|
8
|
+
async function test() {
|
|
9
|
+
sip.dtmf_aggregation_on(500)
|
|
10
|
+
|
|
11
|
+
z.trap_events(sip.event_source, 'event', (evt) => {
|
|
12
|
+
return evt.args[0]
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
sip.set_codecs("pcmu/8000/1:128,pcma/8000/1:128")
|
|
16
|
+
|
|
17
|
+
console.log(sip.start((data) => { console.log(data) }))
|
|
18
|
+
|
|
19
|
+
// Create a WebSocket server transport (listener)
|
|
20
|
+
const t2 = sip.transport.create({
|
|
21
|
+
address: "127.0.0.1",
|
|
22
|
+
port: 6666,
|
|
23
|
+
type: "ws"
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Create a WebSocket client transport connecting to our server
|
|
27
|
+
const t1 = sip.transport.create({
|
|
28
|
+
address: "127.0.0.1",
|
|
29
|
+
type: "ws",
|
|
30
|
+
ws_url: "ws://127.0.0.1:6666/sip"
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
console.log("t1", t1)
|
|
34
|
+
console.log("t2", t2)
|
|
35
|
+
|
|
36
|
+
// Make the call from t1 to t2 over WebSocket
|
|
37
|
+
const oc = sip.call.create(t1.id, {
|
|
38
|
+
from_uri: 'sip:alice@test.com',
|
|
39
|
+
to_uri: 'sip:bob@127.0.0.1:8080',
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Wait for the call to arrive at t2 and 100 Trying response at t1
|
|
43
|
+
await z.wait([
|
|
44
|
+
{
|
|
45
|
+
event: "incoming_call",
|
|
46
|
+
call_id: m.collect("call_id"),
|
|
47
|
+
transport_id: t2.id,
|
|
48
|
+
msg: sip_msg({
|
|
49
|
+
$rU: 'bob',
|
|
50
|
+
$fU: 'alice',
|
|
51
|
+
$tU: 'bob',
|
|
52
|
+
$fd: 'test.com',
|
|
53
|
+
})
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
event: 'response',
|
|
57
|
+
call_id: oc.id,
|
|
58
|
+
method: 'INVITE',
|
|
59
|
+
msg: sip_msg({
|
|
60
|
+
$rs: '100',
|
|
61
|
+
$rr: 'Trying',
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
64
|
+
], 2000)
|
|
65
|
+
|
|
66
|
+
const ic = {
|
|
67
|
+
id: z.$call_id,
|
|
68
|
+
sip_call_id: z.$sip_call_id,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Answer the call at t2 side
|
|
72
|
+
sip.call.respond(ic.id, {
|
|
73
|
+
code: 200,
|
|
74
|
+
reason: 'OK',
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// Wait for 200 OK at t1 side and media setups
|
|
78
|
+
await z.wait([
|
|
79
|
+
{
|
|
80
|
+
event: 'response',
|
|
81
|
+
call_id: oc.id,
|
|
82
|
+
method: 'INVITE',
|
|
83
|
+
msg: sip_msg({
|
|
84
|
+
$rs: '200',
|
|
85
|
+
$rr: 'OK',
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
event: 'media_update',
|
|
90
|
+
call_id: oc.id,
|
|
91
|
+
status: 'ok',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
event: 'media_update',
|
|
95
|
+
call_id: ic.id,
|
|
96
|
+
status: 'ok',
|
|
97
|
+
},
|
|
98
|
+
], 2000)
|
|
99
|
+
|
|
100
|
+
sip.call.start_inband_dtmf_detection(oc.id)
|
|
101
|
+
sip.call.start_inband_dtmf_detection(ic.id)
|
|
102
|
+
|
|
103
|
+
sip.call.send_dtmf(oc.id, {digits: '1234', mode: 1})
|
|
104
|
+
sip.call.send_dtmf(ic.id, {digits: '1234', mode: 1})
|
|
105
|
+
|
|
106
|
+
await z.wait([
|
|
107
|
+
{
|
|
108
|
+
event: 'dtmf',
|
|
109
|
+
call_id: ic.id,
|
|
110
|
+
digits: '1234',
|
|
111
|
+
mode: 1,
|
|
112
|
+
media_id: 0,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
event: 'dtmf',
|
|
116
|
+
call_id: oc.id,
|
|
117
|
+
digits: '1234',
|
|
118
|
+
mode: 1,
|
|
119
|
+
media_id: 0,
|
|
120
|
+
},
|
|
121
|
+
], 2000)
|
|
122
|
+
|
|
123
|
+
// Terminate the call from t1 side
|
|
124
|
+
sip.call.terminate(oc.id)
|
|
125
|
+
|
|
126
|
+
// Wait for call termination
|
|
127
|
+
await z.wait([
|
|
128
|
+
{
|
|
129
|
+
event: 'response',
|
|
130
|
+
call_id: oc.id,
|
|
131
|
+
method: 'BYE',
|
|
132
|
+
msg: sip_msg({
|
|
133
|
+
$rs: '200',
|
|
134
|
+
$rr: 'OK',
|
|
135
|
+
}),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
event: 'call_ended',
|
|
139
|
+
call_id: oc.id,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
event: 'call_ended',
|
|
143
|
+
call_id: ic.id,
|
|
144
|
+
},
|
|
145
|
+
], 2000)
|
|
146
|
+
|
|
147
|
+
console.log("WebSocket test successful")
|
|
148
|
+
|
|
149
|
+
sip.stop()
|
|
150
|
+
process.exit(0)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
test().catch(e => {
|
|
154
|
+
console.error(e)
|
|
155
|
+
process.exit(1)
|
|
156
|
+
})
|
package/src/addon.cpp
CHANGED
|
@@ -1264,6 +1264,32 @@ Napi::Value set_codecs(const Napi::CallbackInfo &info) {
|
|
|
1264
1264
|
return env.Null();
|
|
1265
1265
|
}
|
|
1266
1266
|
|
|
1267
|
+
Napi::Value set_opus_config(const Napi::CallbackInfo &info) {
|
|
1268
|
+
Napi::Env env = info.Env();
|
|
1269
|
+
|
|
1270
|
+
if (info.Length() != 1) {
|
|
1271
|
+
Napi::Error::New(env, "Wrong number of arguments. Expected: config")
|
|
1272
|
+
.ThrowAsJavaScriptException();
|
|
1273
|
+
return env.Null();
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
if (!info[0].IsString()) {
|
|
1277
|
+
Napi::TypeError::New(env, "config must be a JSON string.")
|
|
1278
|
+
.ThrowAsJavaScriptException();
|
|
1279
|
+
return env.Null();
|
|
1280
|
+
}
|
|
1281
|
+
string json = info[0].As<Napi::String>().Utf8Value();
|
|
1282
|
+
|
|
1283
|
+
int res = pjw_set_opus_config(json.c_str());
|
|
1284
|
+
|
|
1285
|
+
if (res != 0) {
|
|
1286
|
+
Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
|
|
1287
|
+
return env.Null();
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
return env.Null();
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1267
1293
|
Napi::Value notify(const Napi::CallbackInfo &info) {
|
|
1268
1294
|
Napi::Env env = info.Env();
|
|
1269
1295
|
|
|
@@ -1649,6 +1675,7 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
|
|
|
1649
1675
|
|
|
1650
1676
|
exports.Set("get_codecs", Napi::Function::New(env, get_codecs));
|
|
1651
1677
|
exports.Set("set_codecs", Napi::Function::New(env, set_codecs));
|
|
1678
|
+
exports.Set("_set_opus_config", Napi::Function::New(env, set_opus_config));
|
|
1652
1679
|
|
|
1653
1680
|
exports.Set("notify", Napi::Function::New(env, notify));
|
|
1654
1681
|
exports.Set("notify_xfer", Napi::Function::New(env, notify_xfer));
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2024 MayamaTakeshi
|
|
3
|
+
*
|
|
4
|
+
* This program is free software; you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU General Public License as published by
|
|
6
|
+
* the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License
|
|
15
|
+
* along with this program; if not, write to the Free Software
|
|
16
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
*/
|
|
18
|
+
#ifndef __PJSIP_TRANSPORT_WS_H__
|
|
19
|
+
#define __PJSIP_TRANSPORT_WS_H__
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @file sip_transport_ws.h
|
|
23
|
+
* @brief SIP WebSocket Transport.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
#include <pjsip/sip_transport.h>
|
|
27
|
+
#include <websock.h>
|
|
28
|
+
|
|
29
|
+
PJ_BEGIN_DECL
|
|
30
|
+
|
|
31
|
+
/* Dynamic transport type IDs for WS and WSS */
|
|
32
|
+
PJ_DECL_DATA(pjsip_transport_type_e) PJSIP_TRANSPORT_WS;
|
|
33
|
+
PJ_DECL_DATA(pjsip_transport_type_e) PJSIP_TRANSPORT_WSS;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Initialize WebSocket transport module. Must be called once before
|
|
37
|
+
* any other pjsip_ws_* functions. Registers the WS and WSS transport
|
|
38
|
+
* types with PJSIP.
|
|
39
|
+
*
|
|
40
|
+
* @return PJ_SUCCESS on success.
|
|
41
|
+
*/
|
|
42
|
+
PJ_DECL(pj_status_t) pjsip_ws_transport_init(void);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Start a WebSocket listener (server mode). Creates a WebSocket listener
|
|
46
|
+
* on the specified address and port. When a WebSocket connection with
|
|
47
|
+
* SIP sub-protocol is accepted, a new PJSIP transport is automatically
|
|
48
|
+
* created and registered.
|
|
49
|
+
*
|
|
50
|
+
* @param endpt The SIP endpoint.
|
|
51
|
+
* @param ws_endpt The WebSocket endpoint.
|
|
52
|
+
* @param bind_addr Address and port to listen on.
|
|
53
|
+
* @param secure Use TLS (WSS) if PJ_TRUE, plain WS if PJ_FALSE.
|
|
54
|
+
* @param p_listener_tp Optional pointer to receive the listener transport.
|
|
55
|
+
*
|
|
56
|
+
* @return PJ_SUCCESS on success.
|
|
57
|
+
*/
|
|
58
|
+
PJ_DECL(pj_status_t) pjsip_ws_transport_start(
|
|
59
|
+
pjsip_endpoint *endpt,
|
|
60
|
+
pj_websock_endpoint *ws_endpt,
|
|
61
|
+
const pj_sockaddr *bind_addr,
|
|
62
|
+
pj_bool_t secure,
|
|
63
|
+
pjsip_transport **p_listener_tp);
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Create a WebSocket connection transport (client mode). Connects to the
|
|
67
|
+
* specified WebSocket URL and registers a PJSIP transport for it.
|
|
68
|
+
*
|
|
69
|
+
* @param endpt The SIP endpoint.
|
|
70
|
+
* @param ws_endpt The WebSocket endpoint.
|
|
71
|
+
* @param ws_url WebSocket URL (e.g. "ws://127.0.0.1:8080/sip").
|
|
72
|
+
* @param hdrs Additional HTTP headers for the upgrade request
|
|
73
|
+
* (can be NULL).
|
|
74
|
+
* @param hdr_cnt Number of headers in hdrs.
|
|
75
|
+
* @param p_transport Pointer to receive the created transport.
|
|
76
|
+
*
|
|
77
|
+
* @return PJ_SUCCESS on success.
|
|
78
|
+
*/
|
|
79
|
+
PJ_DECL(pj_status_t) pjsip_ws_transport_connect(
|
|
80
|
+
pjsip_endpoint *endpt,
|
|
81
|
+
pj_websock_endpoint *ws_endpt,
|
|
82
|
+
const char *ws_url,
|
|
83
|
+
const pj_websock_http_hdr *hdrs,
|
|
84
|
+
int hdr_cnt,
|
|
85
|
+
pjsip_transport **p_transport);
|
|
86
|
+
|
|
87
|
+
PJ_END_DECL
|
|
88
|
+
|
|
89
|
+
#endif /* __PJSIP_TRANSPORT_WS_H__ */
|