sip-lab 1.30.0 → 1.31.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.
@@ -128,11 +128,9 @@ async function test() {
128
128
  {
129
129
  type: 'audio',
130
130
  local: {
131
- port: 10000,
132
131
  mode: 'recvonly'
133
132
  },
134
133
  remote: {
135
- port: 10002,
136
134
  mode: 'sendonly'
137
135
  }
138
136
  }
@@ -155,11 +153,9 @@ async function test() {
155
153
  {
156
154
  type: 'audio',
157
155
  local: {
158
- port: 10002,
159
156
  mode: 'sendonly'
160
157
  },
161
158
  remote: {
162
- port: 10000,
163
159
  mode: 'recvonly'
164
160
  }
165
161
  }
@@ -273,11 +269,9 @@ async function test() {
273
269
  {
274
270
  type: 'audio',
275
271
  local: {
276
- port: 10000,
277
272
  mode: 'recvonly'
278
273
  },
279
274
  remote: {
280
- port: 10002,
281
275
  mode: 'sendonly'
282
276
  }
283
277
  }
@@ -300,11 +294,9 @@ async function test() {
300
294
  {
301
295
  type: 'audio',
302
296
  local: {
303
- port: 10002,
304
297
  mode: 'sendonly'
305
298
  },
306
299
  remote: {
307
- port: 10000,
308
300
  mode: 'recvonly'
309
301
  }
310
302
  }
@@ -359,11 +351,9 @@ async function test() {
359
351
  {
360
352
  type: 'audio',
361
353
  local: {
362
- port: 10000,
363
354
  mode: 'recvonly'
364
355
  },
365
356
  remote: {
366
- port: 10002,
367
357
  mode: 'sendonly'
368
358
  }
369
359
  }
@@ -386,11 +376,9 @@ async function test() {
386
376
  {
387
377
  type: 'audio',
388
378
  local: {
389
- port: 10002,
390
379
  mode: 'sendonly'
391
380
  },
392
381
  remote: {
393
- port: 10000,
394
382
  mode: 'recvonly'
395
383
  }
396
384
  }
@@ -0,0 +1,268 @@
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 uuid = require('uuid')
6
+
7
+ // here we create our Zeq instance
8
+ var z = new Zeq()
9
+
10
+
11
+ async function test() {
12
+ z.trap_events(sip.event_source, 'event', (evt) => {
13
+ var e = evt.args[0]
14
+ return e
15
+ })
16
+
17
+ sip.set_codecs("pcmu/8000/1:128,pcma/8000/1:128,gsm/8000/1:128")
18
+
19
+ console.log(sip.start((data) => { console.log(data)} ))
20
+
21
+ const t1 = sip.transport.create({address: "127.0.0.1"})
22
+ const t2 = sip.transport.create({address: "127.0.0.1"})
23
+
24
+ console.log("t1", t1)
25
+ console.log("t2", t2)
26
+
27
+ const call_id = uuid.v4()
28
+
29
+ var oc = sip.call.create(t1.id, {
30
+ from_uri: 'sip:alice@test.com',
31
+ to_uri: `sip:bob@${t2.address}:${t2.port}`,
32
+ headers: {
33
+ 'Call-ID': call_id,
34
+ 'Supported': 'timer',
35
+ 'Min-SE': '180',
36
+ 'Session-Expires': '180',
37
+ },
38
+ })
39
+
40
+ await z.wait([
41
+ {
42
+ event: "incoming_call",
43
+ call_id: m.collect("call_id"),
44
+ transport_id: t2.id,
45
+ msg: sip_msg({
46
+ $rU: 'bob',
47
+ $fU: 'alice',
48
+ $tU: 'bob',
49
+ $fd: 'test.com',
50
+ $ci: call_id,
51
+ hdr_supported: 'timer',
52
+ hdr_min_se: '180',
53
+ hdr_session_expires: '180',
54
+ })
55
+ },
56
+ {
57
+ event: 'response',
58
+ call_id: oc.id,
59
+ method: 'INVITE',
60
+ msg: sip_msg({
61
+ $rs: '100',
62
+ $rr: 'Trying',
63
+ }),
64
+ },
65
+ ], 1000)
66
+
67
+
68
+ var ic = {
69
+ id: z.store.call_id,
70
+ sip_call_id: z.store.sip_call_id,
71
+ }
72
+
73
+ sip.call.respond(ic.id, {
74
+ code: 422,
75
+ reason: 'Session Timer Too Small',
76
+ headers: {
77
+ 'Supported': 'timer',
78
+ 'Min-SE': '300',
79
+ 'Session-Expires': '300;refresher=uac',
80
+ },
81
+ })
82
+
83
+ await z.wait([
84
+ {
85
+ event: 'call_ended',
86
+ call_id: ic.id,
87
+ },
88
+ {
89
+ event: 'call_ended',
90
+ call_id: oc.id,
91
+ },
92
+ {
93
+ event: 'response',
94
+ call_id: 0,
95
+ method: 'INVITE',
96
+ msg: sip_msg({
97
+ $rs: '422',
98
+ $rr: 'Session Timer Too Small',
99
+ hdr_supported: 'timer',
100
+ hdr_min_se: '300',
101
+ hdr_session_expires: '300;refresher=uac',
102
+ }),
103
+ },
104
+ ], 1000)
105
+
106
+ oc = sip.call.create(t1.id, {
107
+ from_uri: 'sip:alice@test.com',
108
+ to_uri: `sip:bob@${t2.address}:${t2.port}`,
109
+ headers: {
110
+ 'Call-ID': call_id,
111
+ 'Supported': 'timer',
112
+ 'Min-SE': '300',
113
+ 'Session-Expires': '300',
114
+ },
115
+ })
116
+
117
+ delete z.store.call_id
118
+
119
+ await z.wait([
120
+ {
121
+ event: "incoming_call",
122
+ call_id: m.collect("call_id"),
123
+ transport_id: t2.id,
124
+ msg: sip_msg({
125
+ $rU: 'bob',
126
+ $fU: 'alice',
127
+ $tU: 'bob',
128
+ $fd: 'test.com',
129
+ $ci: call_id,
130
+ hdr_supported: 'timer',
131
+ hdr_min_se: '300',
132
+ hdr_session_expires: '300',
133
+ })
134
+ },
135
+ {
136
+ event: 'response',
137
+ call_id: oc.id,
138
+ method: 'INVITE',
139
+ msg: sip_msg({
140
+ $rs: '100',
141
+ $rr: 'Trying',
142
+ }),
143
+ },
144
+ ], 1000)
145
+
146
+ ic = {
147
+ id: z.store.call_id,
148
+ sip_call_id: z.store.sip_call_id,
149
+ }
150
+
151
+ sip.call.respond(ic.id, {
152
+ code: 200,
153
+ reason: 'OK',
154
+ headers: {
155
+ 'Supported': 'timer',
156
+ 'Min-SE': '300',
157
+ 'Session-Expires': '300;refresher=uac',
158
+ },
159
+ })
160
+
161
+ await z.wait([
162
+ {
163
+ event: 'response',
164
+ call_id: oc.id,
165
+ method: 'INVITE',
166
+ msg: sip_msg({
167
+ $rs: '200',
168
+ $rr: 'OK',
169
+ hdr_supported: 'timer',
170
+ hdr_min_se: '300',
171
+ hdr_session_expires: '300;refresher=uac',
172
+ }),
173
+ },
174
+ {
175
+ event: 'media_update',
176
+ call_id: oc.id,
177
+ status: 'ok',
178
+ },
179
+ {
180
+ event: 'media_update',
181
+ call_id: ic.id,
182
+ status: 'ok',
183
+ },
184
+ ], 1000)
185
+
186
+ await z.sleep(1000)
187
+
188
+ sip.call.update(oc.id, {
189
+ headers: {
190
+ 'Supported': 'timer',
191
+ 'Min-SE': '300',
192
+ 'Session-Expires': '300',
193
+ },
194
+ })
195
+
196
+ await z.wait([
197
+ {
198
+ event: 'request',
199
+ call_id: ic.id,
200
+ msg: sip_msg({
201
+ $rm: 'UPDATE',
202
+ hdr_supported: 'timer',
203
+ hdr_min_se: '300',
204
+ hdr_session_expires: '300',
205
+ }),
206
+ },
207
+ ], 1000)
208
+
209
+ sip.call.respond(ic.id, {
210
+ code: 200,
211
+ reason: 'OK',
212
+ headers: {
213
+ 'Supported': 'timer',
214
+ 'Min-SE': '300',
215
+ 'Session-Expires': '300;refresher=uac',
216
+ },
217
+ })
218
+
219
+ await z.wait([
220
+ {
221
+ event: 'response',
222
+ call_id: oc.id,
223
+ msg: sip_msg({
224
+ $rm: 'UPDATE',
225
+ $rs: '200',
226
+ $rr: 'OK',
227
+ hdr_supported: 'timer',
228
+ hdr_min_se: '300',
229
+ hdr_session_expires: '300;refresher=uac',
230
+ }),
231
+ },
232
+ ], 1000)
233
+
234
+ sip.call.terminate(oc.id)
235
+
236
+ // and wait for termination events
237
+ await z.wait([
238
+ {
239
+ event: 'response',
240
+ call_id: oc.id,
241
+ method: 'BYE',
242
+ msg: sip_msg({
243
+ $rs: '200',
244
+ $rr: 'OK',
245
+ }),
246
+ },
247
+ {
248
+ event: 'call_ended',
249
+ call_id: oc.id,
250
+ },
251
+ {
252
+ event: 'call_ended',
253
+ call_id: ic.id,
254
+ },
255
+ ], 1000)
256
+
257
+ console.log("Success")
258
+
259
+ sip.stop()
260
+ }
261
+
262
+
263
+ test()
264
+ .catch(e => {
265
+ console.error(e)
266
+ process.exit(1)
267
+ })
268
+
@@ -0,0 +1,312 @@
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 uuid = require('uuid')
6
+
7
+ const sipjs = require('sipjs-lab')
8
+ const {endpoint, dialog} = require('sipjs-lab')
9
+
10
+ // here we create our Zeq instance
11
+
12
+ var z = new Zeq()
13
+
14
+ async function test() {
15
+ z.trap_events(sip.event_source, 'event', (evt) => {
16
+ var e = evt.args[0]
17
+ return e
18
+ })
19
+
20
+ z.trap_events(sipjs.event_source, 'event', (evt) => {
21
+ var e = evt.args[0]
22
+ return e
23
+ })
24
+
25
+ sip.set_codecs("pcmu/8000/1:128,pcma/8000/1:128,gsm/8000/1:128")
26
+
27
+ console.log(sip.start((data) => { console.log(data)} ))
28
+
29
+ const address = "127.0.0.1"
30
+
31
+ const t1 = sip.transport.create({address})
32
+
33
+ const e1_port = 7070
34
+ const e1 = endpoint.create({
35
+ address,
36
+ port: e1_port,
37
+ publicAddress: address
38
+ })
39
+
40
+ const sip_call_id = uuid.v4()
41
+
42
+ var oc = sip.call.create(t1.id, {
43
+ from_uri: 'sip:alice@test.com',
44
+ to_uri: `sip:bob@${address}:${e1_port}`,
45
+ headers: {
46
+ 'Call-ID': sip_call_id,
47
+ 'Supported': 'timer',
48
+ 'Min-SE': '180',
49
+ 'Session-Expires': '180',
50
+ },
51
+ })
52
+
53
+ await z.wait([
54
+ {
55
+ source: 'sip_endpoint',
56
+ req: m.collect('req', {
57
+ method: 'INVITE',
58
+ uri: `sip:bob@${address}:${e1_port}`,
59
+ headers: {
60
+ from: {
61
+ uri: 'sip:alice@test.com',
62
+ },
63
+ to: {
64
+ uri: `sip:bob@${address}`,
65
+ },
66
+ supported: 'timer',
67
+ 'min-se': '180',
68
+ 'session-expires': '180',
69
+ },
70
+ }),
71
+ event: 'dialog_offer',
72
+ dialog_id: m.collect('dialog_id'),
73
+ },
74
+ ], 1000)
75
+
76
+ dialog.send_reply(
77
+ z.store.dialog_id,
78
+ z.store.req,
79
+ {
80
+ status: 422,
81
+ reason: 'Session Timer Too Small',
82
+ headers: {
83
+ 'Min-SE': '300',
84
+ 'Server': 'TBSIP',
85
+ },
86
+ }
87
+ )
88
+
89
+ await z.wait([
90
+ {
91
+ event: 'response',
92
+ call_id: oc.id,
93
+ method: 'INVITE',
94
+ msg: sip_msg({
95
+ $rs: '422',
96
+ $rr: 'Session Timer Too Small',
97
+ hdr_min_se: '300',
98
+ }),
99
+ },
100
+ {
101
+ event: 'call_ended',
102
+ call_id: oc.id,
103
+ }
104
+ ], 1000)
105
+
106
+ dialog.destroy(z.store.dialog_id)
107
+
108
+ delete z.store.dialog_id
109
+
110
+ await z.sleep(1000)
111
+
112
+ oc = sip.call.create(t1.id, {
113
+ from_uri: 'sip:alice@test.com',
114
+ to_uri: `sip:bob@${address}:${e1_port}`,
115
+ headers: {
116
+ 'Call-ID': sip_call_id,
117
+ 'Supported': 'timer',
118
+ 'Min-SE': '300',
119
+ 'Session-Expires': '300',
120
+ },
121
+ })
122
+
123
+ delete z.store.req
124
+
125
+ await z.wait([
126
+ {
127
+ source: 'sip_endpoint',
128
+ req: m.collect('req', {
129
+ method: 'INVITE',
130
+ uri: `sip:bob@${address}:${e1_port}`,
131
+ headers: {
132
+ from: {
133
+ uri: 'sip:alice@test.com',
134
+ },
135
+ to: {
136
+ uri: `sip:bob@${address}`,
137
+ },
138
+ },
139
+ }),
140
+ event: 'dialog_offer',
141
+ dialog_id: m.collect('dialog_id'),
142
+ },
143
+ ], 1000)
144
+
145
+ const sdp_answer =`v=0
146
+ o=- 3933986675 3933986676 IN IP4 0.0.0.0
147
+ s=-
148
+ c=IN IP4 ${address}
149
+ t=0 0
150
+ m=audio 20000 RTP/AVP 0 101
151
+ a=sendrecv
152
+ a=rtpmap:0 PCMU/8000
153
+ a=rtpmap:101 telephone-event/8000
154
+ a=fmtp:101 0-15
155
+ a=ptime:20`.replace(/\n/g, "\r\n")
156
+
157
+ dialog.send_reply(
158
+ z.store.dialog_id,
159
+ z.store.req,
160
+ {
161
+ status: 200,
162
+ reason: 'OK',
163
+ headers: {
164
+ 'Supported': 'timer',
165
+ 'Min-SE': '300',
166
+ 'Session-Expires': '300;refresher=uac',
167
+ 'content-type': 'application/sdp',
168
+ },
169
+ content: sdp_answer,
170
+ }
171
+ )
172
+
173
+ await z.wait([
174
+ {
175
+ event: 'response',
176
+ call_id: oc.id,
177
+ method: 'INVITE',
178
+ msg: sip_msg({
179
+ $rs: '200',
180
+ $rr: 'OK',
181
+ hdr_supported: 'timer',
182
+ hdr_min_se: '300',
183
+ hdr_session_expires: '300;refresher=uac',
184
+ }),
185
+ },
186
+ {
187
+ event: 'media_update',
188
+ call_id: oc.id,
189
+ status: 'ok',
190
+ },
191
+ {
192
+ source: 'sip_endpoint',
193
+ endpoint_id: z.store.endpoint_id,
194
+ req: {
195
+ method: 'ACK',
196
+ },
197
+ event: 'in_dialog_request',
198
+ dialog_id: z.store.dialog_id
199
+ },
200
+ ], 1000)
201
+
202
+
203
+ for(var i=0 ; i<5 ; i++) {
204
+
205
+ sip.call.update(oc.id, {
206
+ headers: {
207
+ 'Supported': 'timer',
208
+ 'Min-SE': '300',
209
+ 'Session-Expires': '300',
210
+ },
211
+ })
212
+
213
+ delete z.store.req
214
+
215
+ await z.wait([
216
+ {
217
+ source: 'sip_endpoint',
218
+ req: m.collect('req', {
219
+ method: 'UPDATE',
220
+ headers: {
221
+ 'supported': 'timer',
222
+ 'min-se': '300',
223
+ 'session-expires': '300',
224
+ },
225
+ }),
226
+ event: 'in_dialog_request',
227
+ dialog_id: z.store.dialog_id
228
+ },
229
+ ], 1000)
230
+
231
+ dialog.send_reply(
232
+ z.store.dialog_id,
233
+ z.store.req,
234
+ {
235
+ status: 200,
236
+ reason: 'OK',
237
+ headers: {
238
+ 'Supported': 'timer',
239
+ 'Min-SE': '300',
240
+ 'Session-Expires': '300;refresher=uac',
241
+ },
242
+ }
243
+ )
244
+
245
+ await z.wait([
246
+ {
247
+ event: 'response',
248
+ call_id: oc.id,
249
+ method: 'UPDATE',
250
+ msg: sip_msg({
251
+ $rs: '200',
252
+ $rr: 'OK',
253
+ hdr_supported: 'timer',
254
+ hdr_min_se: '300',
255
+ hdr_session_expires: '300;refresher=uac',
256
+ }),
257
+ },
258
+ ], 1000)
259
+
260
+ }
261
+
262
+ sip.call.terminate(oc.id)
263
+
264
+ delete z.store.req
265
+
266
+ await z.wait([
267
+ {
268
+ source: 'sip_endpoint',
269
+ req: m.collect('req', {
270
+ method: 'BYE',
271
+ }),
272
+ },
273
+ ], 1000)
274
+
275
+ dialog.send_reply(
276
+ z.store.dialog_id,
277
+ z.store.req,
278
+ {
279
+ status: 200,
280
+ reason: 'OK',
281
+ }
282
+ )
283
+
284
+ await z.wait([
285
+ {
286
+ event: 'response',
287
+ call_id: oc.id,
288
+ method: 'BYE',
289
+ msg: sip_msg({
290
+ $rs: '200',
291
+ $rr: 'OK',
292
+ }),
293
+ },
294
+ {
295
+ event: 'call_ended',
296
+ call_id: oc.id,
297
+ },
298
+ ], 1000)
299
+
300
+ await z.sleep(100) // wait for any unexpected events
301
+
302
+ console.log("Success")
303
+
304
+ sip.stop()
305
+ }
306
+
307
+ test()
308
+ .catch(e => {
309
+ console.error(e)
310
+ process.exit(1)
311
+ })
312
+
package/src/addon.cpp CHANGED
@@ -467,6 +467,40 @@ Napi::Value call_reinvite(const Napi::CallbackInfo &info) {
467
467
  return env.Null();
468
468
  }
469
469
 
470
+ Napi::Value call_update(const Napi::CallbackInfo &info) {
471
+ Napi::Env env = info.Env();
472
+
473
+ if (info.Length() != 2) {
474
+ Napi::Error::New(env,
475
+ "Wrong number of arguments. Expected: call_id, params.")
476
+ .ThrowAsJavaScriptException();
477
+ return env.Null();
478
+ }
479
+
480
+ if (!info[0].IsNumber()) {
481
+ Napi::TypeError::New(env, "call_id must be number.")
482
+ .ThrowAsJavaScriptException();
483
+ return env.Null();
484
+ }
485
+ int call_id = info[0].As<Napi::Number>().Int32Value();
486
+
487
+ if (!info[1].IsString()) {
488
+ Napi::TypeError::New(env, "params must be a JSON string.")
489
+ .ThrowAsJavaScriptException();
490
+ return env.Null();
491
+ }
492
+ const string json = info[1].As<Napi::String>().Utf8Value();
493
+
494
+ int res = pjw_call_update(call_id, json.c_str());
495
+
496
+ if (res != 0) {
497
+ Napi::Error::New(env, pjw_get_error()).ThrowAsJavaScriptException();
498
+ return env.Null();
499
+ }
500
+
501
+ return env.Null();
502
+ }
503
+
470
504
  Napi::Value call_send_request(const Napi::CallbackInfo &info) {
471
505
  Napi::Env env = info.Env();
472
506
 
@@ -1566,6 +1600,7 @@ Napi::Object init(Napi::Env env, Napi::Object exports) {
1566
1600
  exports.Set("call_send_dtmf", Napi::Function::New(env, call_send_dtmf));
1567
1601
  exports.Set("call_send_bfsk", Napi::Function::New(env, call_send_bfsk));
1568
1602
  exports.Set("call_reinvite", Napi::Function::New(env, call_reinvite));
1603
+ exports.Set("call_update", Napi::Function::New(env, call_update));
1569
1604
  exports.Set("call_send_request", Napi::Function::New(env, call_send_request));
1570
1605
 
1571
1606
  exports.Set("call_start_record_wav", Napi::Function::New(env, call_start_record_wav));