@voicenter-team/opensips-js 1.0.20 → 1.0.22

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,621 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.MSRPSession = void 0;
30
+ const Utils = __importStar(require("jssip/lib/Utils"));
31
+ const RequestSender_1 = __importDefault(require("jssip/lib/RequestSender"));
32
+ const DigestAuthentication_1 = __importDefault(require("jssip/lib/DigestAuthentication"));
33
+ const message_1 = __importDefault(require("./message"));
34
+ const URI_1 = __importDefault(require("jssip/lib/URI"));
35
+ const SIPMessage = __importStar(require("jssip/lib/SIPMessage"));
36
+ const Constants_1 = __importDefault(require("jssip/lib/Constants"));
37
+ const events_1 = require("events");
38
+ const Dialog_1 = __importDefault(require("jssip/lib/Dialog"));
39
+ const Exceptions_1 = __importDefault(require("jssip/lib/Exceptions"));
40
+ const Transactions_1 = __importDefault(require("jssip/lib/Transactions"));
41
+ const C = {
42
+ // RTCSession states.
43
+ STATUS_NULL: 0,
44
+ STATUS_INVITE_SENT: 1,
45
+ STATUS_1XX_RECEIVED: 2,
46
+ STATUS_INVITE_RECEIVED: 3,
47
+ STATUS_WAITING_FOR_ANSWER: 4,
48
+ STATUS_ANSWERED: 5,
49
+ STATUS_WAITING_FOR_ACK: 6,
50
+ STATUS_CANCELED: 7,
51
+ STATUS_TERMINATED: 8,
52
+ STATUS_CONFIRMED: 9
53
+ };
54
+ class MSRPSession extends events_1.EventEmitter {
55
+ constructor(ua) {
56
+ super();
57
+ this._id = null;
58
+ this.my_ip = '127.0.0.1';
59
+ this._ua = ua;
60
+ console.log('session constructor configuration', ua.configuration);
61
+ console.log('session constructor uri ', ua.configuration.uri);
62
+ console.log('session constructor uri instanceof URI', ua.configuration.uri instanceof URI_1.default);
63
+ this.auth_id = Utils.createRandomToken(10);
64
+ this._status = C.STATUS_NULL;
65
+ this._dialog = null;
66
+ this._earlyDialogs = {};
67
+ this._contact = null;
68
+ this._from_tag = null;
69
+ this._to_tag = null;
70
+ this._msgHistory = [];
71
+ this.target_addr = [];
72
+ this.my_addr = [];
73
+ this.credentials = {
74
+ 'username': ua._configuration.authorization_user,
75
+ 'ha1': ua._configuration.ha1,
76
+ 'realm': ua._configuration.realm
77
+ };
78
+ this._request = null;
79
+ this.status = 'new';
80
+ this.target = '';
81
+ this.message = '';
82
+ this._timers = {
83
+ ackTimer: null,
84
+ expiresTimer: null,
85
+ invite2xxTimer: null,
86
+ userNoAnswerTimer: null
87
+ };
88
+ this._direction = null;
89
+ this._local_identity = null;
90
+ this._remote_identity = null;
91
+ this._start_time = null;
92
+ this._end_time = null;
93
+ this._tones = null;
94
+ this._sessionTimers = {
95
+ enabled: this._ua.configuration.session_timers,
96
+ refreshMethod: this._ua.configuration.session_timers_refresh_method,
97
+ defaultExpires: Constants_1.default.SESSION_EXPIRES,
98
+ currentExpires: null,
99
+ running: false,
100
+ refresher: false,
101
+ timer: null // A setTimeout.
102
+ };
103
+ }
104
+ /**
105
+ * Expose C object.
106
+ */
107
+ static get C() {
108
+ return C;
109
+ }
110
+ get direction() {
111
+ return this._direction;
112
+ }
113
+ get connection() {
114
+ return this._connection;
115
+ }
116
+ get id() {
117
+ return this._id;
118
+ }
119
+ connect(target = '') {
120
+ if (target !== '') {
121
+ this._direction = 'outgoing';
122
+ }
123
+ this.target = target;
124
+ this._connection = new WebSocket(`ws://${this._ua._configuration.realm}:2856`, 'msrp');
125
+ this._connection.binaryType = 'arraybuffer';
126
+ this._connection.onopen = (event) => {
127
+ console.log('open');
128
+ this.onopen();
129
+ };
130
+ this._connection.onclose = () => {
131
+ console.log('close');
132
+ this.onclose();
133
+ };
134
+ this._connection.onmessage = (msg) => {
135
+ console.log('msg', msg);
136
+ this.onmessage(msg);
137
+ };
138
+ this._connection.onerror = () => {
139
+ console.log('error');
140
+ this.onerror();
141
+ };
142
+ }
143
+ answer() {
144
+ this.connect();
145
+ }
146
+ acceptParty(msgObj) {
147
+ this._request.parseSDP(true);
148
+ // this.target_addr = this._request.sdp.media[0].invalid[1].value.replaceAll('path:', '');
149
+ this._request.reply(200, 'OK', [], 'v=0\n' +
150
+ `o=- 4232740119537112802 2 IN IP4 ${this.my_ip}\n` +
151
+ `c=IN IP4 ${this.my_ip}\n` +
152
+ 't=0 0\n' +
153
+ 'm=message 2856 TCP/TLS/MSRP *\n' +
154
+ 'a=accept-types:text/plain text/html\n' +
155
+ `a=path: ${msgObj.getHeader('Use-Path')} msrp://${this._ua._configuration.authorization_user}.${this._ua._configuration.realm}:2856/${this.auth_id};ws\n`);
156
+ }
157
+ terminate(options = {}) {
158
+ const cause = options.cause || Constants_1.default.causes.BYE;
159
+ const extraHeaders = Utils.cloneArray(options.extraHeaders);
160
+ const body = options.body;
161
+ let cancel_reason;
162
+ let status_code = options.status_code;
163
+ let reason_phrase = options.reason_phrase;
164
+ // Check Session Status.
165
+ if (this._status === C.STATUS_TERMINATED) {
166
+ throw new Exceptions_1.default.InvalidStateError(this._status);
167
+ }
168
+ this.status = 'terminated';
169
+ switch (this._status) {
170
+ // - UAC -
171
+ case C.STATUS_NULL:
172
+ case C.STATUS_INVITE_SENT:
173
+ case C.STATUS_1XX_RECEIVED:
174
+ if (status_code && (status_code < 200 || status_code >= 700)) {
175
+ throw new TypeError(`Invalid status_code: ${status_code}`);
176
+ }
177
+ else if (status_code) {
178
+ reason_phrase = reason_phrase || Constants_1.default.REASON_PHRASE[status_code] || '';
179
+ cancel_reason = `SIP ;cause=${status_code} ;text="${reason_phrase}"`;
180
+ }
181
+ // Check Session Status.
182
+ if (this._status === C.STATUS_NULL || this._status === C.STATUS_INVITE_SENT) {
183
+ this._is_canceled = true;
184
+ this._cancel_reason = cancel_reason;
185
+ }
186
+ else if (this._status === C.STATUS_1XX_RECEIVED) {
187
+ this._request.cancel(cancel_reason);
188
+ }
189
+ this._status = C.STATUS_CANCELED;
190
+ this._failed('local', null, Constants_1.default.causes.CANCELED);
191
+ break;
192
+ // - UAS -
193
+ case C.STATUS_WAITING_FOR_ANSWER:
194
+ case C.STATUS_ANSWERED:
195
+ status_code = status_code || 480;
196
+ console.log('REPLY 480');
197
+ if (status_code < 300 || status_code >= 700) {
198
+ throw new TypeError(`Invalid status_code: ${status_code}`);
199
+ }
200
+ this._request.reply(status_code, reason_phrase, extraHeaders, body);
201
+ this._failed('local', null, Constants_1.default.causes.REJECTED);
202
+ break;
203
+ case C.STATUS_WAITING_FOR_ACK:
204
+ case C.STATUS_CONFIRMED:
205
+ reason_phrase = options.reason_phrase || Constants_1.default.REASON_PHRASE[status_code] || '';
206
+ if (status_code && (status_code < 200 || status_code >= 700)) {
207
+ throw new TypeError(`Invalid status_code: ${status_code}`);
208
+ }
209
+ else if (status_code) {
210
+ extraHeaders.push(`Reason: SIP ;cause=${status_code}; text="${reason_phrase}"`);
211
+ }
212
+ /* RFC 3261 section 15 (Terminating a session):
213
+ *
214
+ * "...the callee's UA MUST NOT send a BYE on a confirmed dialog
215
+ * until it has received an ACK for its 2xx response or until the server
216
+ * transaction times out."
217
+ */
218
+ if (this._status === C.STATUS_WAITING_FOR_ACK &&
219
+ this._direction === 'incoming' &&
220
+ this._request.server_transaction.state !== Transactions_1.default.C.STATUS_TERMINATED) {
221
+ // Save the dialog for later restoration.
222
+ const dialog = this._dialog;
223
+ // Send the BYE as soon as the ACK is received...
224
+ this.receiveRequest = ({ method }) => {
225
+ if (method === Constants_1.default.ACK) {
226
+ this.sendRequest(Constants_1.default.BYE, {
227
+ extraHeaders,
228
+ body
229
+ });
230
+ dialog.terminate();
231
+ }
232
+ };
233
+ // .., or when the INVITE transaction times out
234
+ this._request.server_transaction.on('stateChanged', () => {
235
+ if (this._request.server_transaction.state ===
236
+ Transactions_1.default.C.STATUS_TERMINATED) {
237
+ this.sendRequest(Constants_1.default.BYE, {
238
+ extraHeaders,
239
+ body
240
+ });
241
+ dialog.terminate();
242
+ }
243
+ });
244
+ this._ended('local', null, cause);
245
+ // Restore the dialog into 'this' in order to be able to send the in-dialog BYE :-).
246
+ this._dialog = dialog;
247
+ // Restore the dialog into 'ua' so the ACK can reach 'this' session.
248
+ this._ua.newDialog(dialog);
249
+ }
250
+ else {
251
+ this.sendRequest(Constants_1.default.BYE, {
252
+ extraHeaders,
253
+ body
254
+ });
255
+ this._ended('local', null, cause);
256
+ }
257
+ }
258
+ }
259
+ sendRequest(method, options) {
260
+ return this._dialog.sendRequest(method, options);
261
+ }
262
+ authenticate(auth) {
263
+ this.status = 'auth';
264
+ let msgObj = new message_1.default('');
265
+ msgObj.method = 'AUTH';
266
+ msgObj.addHeader('To-Path', `msrp://${this._ua._configuration.realm}:2856;ws`);
267
+ msgObj.addHeader('From-Path', `msrp://${this.credentials.username}.${this.credentials.realm}:2856/${this.auth_id};ws`);
268
+ if (auth) {
269
+ msgObj.addHeader('Authorization', auth.toString());
270
+ }
271
+ this._connection.send(msgObj.toString());
272
+ }
273
+ onmessage(msg) {
274
+ console.log('onmessage', msg);
275
+ const msgObj = new message_1.default(msg.data);
276
+ if (this.status === 'auth' && msgObj.code === 401) {
277
+ const _challenge = this.parseAuth(msgObj.getHeader('WWW-Authenticate'));
278
+ const digestAuthentication = new DigestAuthentication_1.default(this.credentials);
279
+ digestAuthentication.authenticate({ method: 'AUTH', ruri: `msrp://${this._ua._configuration.realm}:2856;ws`, body: null }, _challenge, Utils.createRandomToken(12));
280
+ this.authenticate(digestAuthentication);
281
+ }
282
+ if (this.status === 'auth' && msgObj.code === 200 && this._direction === 'outgoing') {
283
+ this.my_addr.push(msgObj.getHeader('To-Path'));
284
+ this.my_addr.push(msgObj.getHeader('Use-Path'));
285
+ this.status = 'active';
286
+ this.inviteParty(msgObj);
287
+ }
288
+ else if (this.status === 'auth' && msgObj.code === 200 && this._direction === 'incoming') {
289
+ this.my_addr.push(msgObj.getHeader('To-Path'));
290
+ this.my_addr.push(msgObj.getHeader('Use-Path'));
291
+ this.status = 'active';
292
+ this.acceptParty(msgObj);
293
+ }
294
+ else if (msgObj.method === 'SEND') {
295
+ this._sendOk(msgObj);
296
+ this._sendReport(msgObj);
297
+ msgObj.direction = 'incoming';
298
+ this.emit('newMessage', msgObj);
299
+ this._msgHistory.push(msgObj);
300
+ this.emit('msgHistoryUpdate', this._msgHistory);
301
+ console.log('======================================================================');
302
+ }
303
+ if (msgObj.code === 480) {
304
+ console.log('---------------------------------');
305
+ this._close();
306
+ }
307
+ }
308
+ onclose() {
309
+ console.log('close');
310
+ }
311
+ onopen() {
312
+ const pc = new RTCPeerConnection({ iceServers: [] });
313
+ pc.createDataChannel('');
314
+ pc.createOffer().then(pc.setLocalDescription.bind(pc));
315
+ pc.onicecandidate = (ice) => {
316
+ if (!ice || !ice.candidate || !ice.candidate.candidate)
317
+ return;
318
+ const ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
319
+ const ipMatch = ice.candidate.candidate.match(ipRegex);
320
+ this.my_ip = ipMatch && ipMatch[1];
321
+ pc.onicecandidate = () => { };
322
+ this.authenticate(null);
323
+ };
324
+ }
325
+ onerror(e) {
326
+ console.log(e);
327
+ }
328
+ inviteParty(msgObj) {
329
+ const requestParams = {};
330
+ const extraHeaders = [];
331
+ requestParams.to_uri = new URI_1.default('sip', this.target, this._ua._configuration.realm);
332
+ requestParams.from_uri = new URI_1.default('sip', this._ua._configuration.uri.user, this._ua._configuration.uri.host);
333
+ // extraHeaders.push(`P-Preferred-Identity: ${this._ua._configuration.uri.toString()}`)
334
+ extraHeaders.push(`Contact: ${this._ua.contact.toString({
335
+ outbound: true
336
+ })}`);
337
+ extraHeaders.push('Content-Type: application/sdp');
338
+ this._request = new SIPMessage.InitialOutgoingInviteRequest(new URI_1.default('sip', this.target, this._ua._configuration.realm).clone(), this._ua, requestParams, extraHeaders, 'v=0\n' +
339
+ `o=- 4232740119537112802 2 IN IP4 ${this.my_ip}\n` +
340
+ `c=IN IP4 ${this.my_ip}\n` +
341
+ 't=0 0\n' +
342
+ 'm=message 2856 TCP/TLS/MSRP *\n' +
343
+ 'a=accept-types:text/plain text/html\n' +
344
+ `a=path:${msgObj.getHeader('Use-Path')} msrp://${this._ua._configuration.authorization_user}.${this._ua._configuration.realm}:2856/${this.auth_id};ws\n`);
345
+ this._newMSRPSession('local', this._request);
346
+ this._id = this._request.call_id + this._from_tag;
347
+ const request_sender = new RequestSender_1.default(this._ua, this._request, {
348
+ onRequestTimeout: () => {
349
+ console.log('to');
350
+ },
351
+ onTransportError: (err) => {
352
+ console.log(err);
353
+ },
354
+ // Update the request on authentication.
355
+ onAuthenticated: (request) => {
356
+ this._request = request;
357
+ },
358
+ onReceiveResponse: (response) => {
359
+ if (response.status_code === 200) {
360
+ response.parseSDP(true);
361
+ this._status = C.STATUS_CONFIRMED;
362
+ this.target_addr = response.sdp.media[0].invalid[1].value.replaceAll('path:', '').split(' ').reverse();
363
+ this.status = 'active';
364
+ this.emit('active');
365
+ this.emit('confirmed');
366
+ }
367
+ }
368
+ });
369
+ request_sender.send();
370
+ }
371
+ sendMSRP(message) {
372
+ const msgObj = new message_1.default('');
373
+ msgObj.method = 'SEND';
374
+ msgObj.addHeader('To-Path', `${this.my_addr[1]} ${this.target_addr[1]} ${this.target_addr[0]}`);
375
+ msgObj.addHeader('From-Path', `${this.my_addr[0]}`);
376
+ msgObj.addHeader('Message-ID', Utils.createRandomToken(10));
377
+ msgObj.addHeader('Byte-Range', '1-25/25');
378
+ msgObj.addHeader('Content-Type', 'text/plain');
379
+ msgObj.addHeader('Success-Report', 'yes');
380
+ msgObj.addHeader('Failure-Report', 'yes');
381
+ // msgObj.addHeader('To', this._to_tag)
382
+ // msgObj.addHeader('From', this._from_tag)
383
+ msgObj.body = message;
384
+ this._connection.send(msgObj.toString());
385
+ msgObj.direction = 'outgoing';
386
+ this.emit('newMessage', msgObj);
387
+ this._msgHistory.push(msgObj);
388
+ this.emit('msgHistoryUpdate', this._msgHistory);
389
+ }
390
+ _sendOk(msgObj) {
391
+ let _i = msgObj.ident;
392
+ let _mId = msgObj.getHeader('Message-ID');
393
+ let _ok = new message_1.default('');
394
+ _ok.method = '200 OK';
395
+ _ok.addHeader('To-Path', `${this.my_addr[1]}`);
396
+ _ok.addHeader('From-Path', `${this.my_addr[0]}`);
397
+ _ok.addHeader('Message-ID', _mId);
398
+ _ok.ident = _i;
399
+ this._connection.send(_ok.toString());
400
+ }
401
+ _sendReport(msgObj) {
402
+ let _i = msgObj.ident;
403
+ let _mId = msgObj.getHeader('Message-ID');
404
+ let _report = new message_1.default('');
405
+ _report.method = 'REPORT';
406
+ _report.addHeader('To-Path', `${msgObj.getHeader('From-Path')}`);
407
+ _report.addHeader('From-Path', `${this.my_addr[0]}`);
408
+ _report.addHeader('Message-ID', _mId);
409
+ _report.addHeader('Byte-Range', '1-25/25');
410
+ _report.addHeader('Status', '000 200 OK');
411
+ _report.ident = _i;
412
+ this._connection.send(_report.toString());
413
+ }
414
+ parseAuth(content) {
415
+ const _challenge = {};
416
+ const _challengeArray = content.replace('Digest', '').split(',');
417
+ for (const _authItem of _challengeArray) {
418
+ const _itemArray = _authItem.trim().split('=');
419
+ _challenge[_itemArray[0]] = _itemArray[1].match('^"(.+)"$')[1];
420
+ }
421
+ return _challenge;
422
+ }
423
+ init_incoming(request, initCallback) {
424
+ let expires;
425
+ const contentType = request.hasHeader('Content-Type') ?
426
+ request.getHeader('Content-Type').toLowerCase() : undefined;
427
+ // Check body and content type.
428
+ if (request.body && (contentType !== 'application/sdp')) {
429
+ request.reply(415);
430
+ return;
431
+ }
432
+ // Session parameter initialization.
433
+ this._status = C.STATUS_INVITE_RECEIVED;
434
+ this._from_tag = request.from_tag;
435
+ this._id = request.call_id + this._from_tag;
436
+ this._request = request;
437
+ this._contact = this._ua.contact.toString();
438
+ // Get the Expires header value if exists.
439
+ if (request.hasHeader('expires')) {
440
+ expires = request.getHeader('expires') * 1000;
441
+ }
442
+ /* Set the to_tag before
443
+ * replying a response code that will create a dialog.
444
+ */
445
+ request.to_tag = Utils.newTag();
446
+ // An error on dialog creation will fire 'failed' event.
447
+ if (!this._createDialog(request, 'UAS', true)) {
448
+ request.reply(500, 'Missing Contact header field');
449
+ return;
450
+ }
451
+ if (request.body) {
452
+ this._late_sdp = false;
453
+ }
454
+ else {
455
+ this._late_sdp = true;
456
+ }
457
+ this._status = C.STATUS_WAITING_FOR_ANSWER;
458
+ // Set userNoAnswerTimer.
459
+ this._timers.userNoAnswerTimer = setTimeout(() => {
460
+ request.reply(408);
461
+ this._failed('local', null, Constants_1.default.causes.NO_ANSWER);
462
+ }, this._ua.configuration.no_answer_timeout);
463
+ /* Set expiresTimer
464
+ * RFC3261 13.3.1
465
+ */
466
+ if (expires) {
467
+ this._timers.expiresTimer = setTimeout(() => {
468
+ if (this._status === C.STATUS_WAITING_FOR_ANSWER) {
469
+ request.reply(487);
470
+ this._failed('system', null, Constants_1.default.causes.EXPIRES);
471
+ }
472
+ }, expires);
473
+ }
474
+ // Set internal properties.
475
+ this._direction = 'incoming';
476
+ this._local_identity = request.to;
477
+ this._remote_identity = request.from;
478
+ // A init callback was specifically defined.
479
+ if (initCallback) {
480
+ initCallback(this);
481
+ }
482
+ request.parseSDP(true);
483
+ this.target_addr = request.sdp.media[0].invalid[1].value.replaceAll('path:', '').split(' ').reverse();
484
+ // Fire 'newMSRPSession' event.
485
+ this._newMSRPSession('remote', request);
486
+ // The user may have rejected the call in the 'newRTCSession' event.
487
+ if (this._status === C.STATUS_TERMINATED) {
488
+ return;
489
+ }
490
+ // Reply 180.
491
+ request.reply(180, null, [`Contact: ${this._ua._contact}`]);
492
+ // Fire 'progress' event.
493
+ // TODO: Document that 'response' field in 'progress' event is null for incoming calls.
494
+ this._progress('local', null);
495
+ }
496
+ _failed(originator, message, cause) {
497
+ this.emit('_failed', {
498
+ originator,
499
+ message: message || null,
500
+ cause
501
+ });
502
+ this._close();
503
+ this.emit('failed', {
504
+ originator,
505
+ message: message || null,
506
+ cause
507
+ });
508
+ }
509
+ _close() {
510
+ if (this._status === C.STATUS_TERMINATED) {
511
+ return;
512
+ }
513
+ this._status = C.STATUS_TERMINATED;
514
+ // Terminate RTC.
515
+ if (this._connection) {
516
+ try {
517
+ this._connection.close();
518
+ }
519
+ catch (error) {
520
+ console.log('close() | error closing the RTCPeerConnection: %o', error);
521
+ }
522
+ }
523
+ // Terminate signaling.
524
+ // Clear SIP timers.
525
+ for (const timer in this._timers) {
526
+ if (Object.prototype.hasOwnProperty.call(this._timers, timer)) {
527
+ clearTimeout(this._timers[timer]);
528
+ }
529
+ }
530
+ // Clear Session Timers.
531
+ clearTimeout(this._sessionTimers.timer);
532
+ // Terminate confirmed dialog.
533
+ if (this._dialog) {
534
+ this._dialog.terminate();
535
+ delete this._dialog;
536
+ }
537
+ // Terminate early dialogs.
538
+ for (const dialog in this._earlyDialogs) {
539
+ if (Object.prototype.hasOwnProperty.call(this._earlyDialogs, dialog)) {
540
+ this._earlyDialogs[dialog].terminate();
541
+ delete this._earlyDialogs[dialog];
542
+ }
543
+ }
544
+ // Terminate REFER subscribers.
545
+ for (const subscriber in this._referSubscribers) {
546
+ if (Object.prototype.hasOwnProperty.call(this._referSubscribers, subscriber)) {
547
+ delete this._referSubscribers[subscriber];
548
+ }
549
+ }
550
+ this._ua.destroyMSRPSession(this);
551
+ }
552
+ _createDialog(message, type, early) {
553
+ const local_tag = (type === 'UAS') ? message.to_tag : message.from_tag;
554
+ const remote_tag = (type === 'UAS') ? message.from_tag : message.to_tag;
555
+ const id = message.call_id + local_tag + remote_tag;
556
+ let early_dialog = this._earlyDialogs[id];
557
+ // Early Dialog.
558
+ if (early) {
559
+ if (early_dialog) {
560
+ return true;
561
+ }
562
+ else {
563
+ early_dialog = new Dialog_1.default(this, message, type, Dialog_1.default.C.STATUS_EARLY);
564
+ // Dialog has been successfully created.
565
+ if (early_dialog.error) {
566
+ this._failed('remote', message, Constants_1.default.causes.INTERNAL_ERROR);
567
+ return false;
568
+ }
569
+ else {
570
+ this._earlyDialogs[id] = early_dialog;
571
+ return true;
572
+ }
573
+ }
574
+ }
575
+ // Confirmed Dialog.
576
+ else {
577
+ this._from_tag = message.from_tag;
578
+ this._to_tag = message.to_tag;
579
+ // In case the dialog is in _early_ state, update it.
580
+ if (early_dialog) {
581
+ early_dialog.update(message, type);
582
+ this._dialog = early_dialog;
583
+ delete this._earlyDialogs[id];
584
+ return true;
585
+ }
586
+ // Otherwise, create a _confirmed_ dialog.
587
+ const dialog = new Dialog_1.default(this, message, type);
588
+ if (dialog.error) {
589
+ this._failed('remote', message, Constants_1.default.causes.INTERNAL_ERROR);
590
+ return false;
591
+ }
592
+ else {
593
+ this._dialog = dialog;
594
+ return true;
595
+ }
596
+ }
597
+ }
598
+ _newMSRPSession(originator, request) {
599
+ this._ua.newMSRPSession(this, {
600
+ originator,
601
+ session: this,
602
+ request
603
+ });
604
+ }
605
+ _progress(originator, response) {
606
+ this.emit('progress', {
607
+ originator,
608
+ response: response || null
609
+ });
610
+ }
611
+ isEnded() {
612
+ switch (this._status) {
613
+ case C.STATUS_CANCELED:
614
+ case C.STATUS_TERMINATED:
615
+ return true;
616
+ default:
617
+ return false;
618
+ }
619
+ }
620
+ }
621
+ exports.MSRPSession = MSRPSession;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voicenter-team/opensips-js",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "The JS package for opensips",
5
5
  "default": "src/index.ts",
6
6
  "main": "build/index.js",
@@ -49,7 +49,7 @@
49
49
  "dependencies": {
50
50
  "@types/mime": "^3.0.1",
51
51
  "generate-unique-id": "^2.0.1",
52
- "jssip": "^3.10.0",
52
+ "jssip": "3.10.0",
53
53
  "loglevel": "^1.8.1",
54
54
  "mime": "^3.0.0",
55
55
  "p-iteration": "^1.1.8"
@@ -0,0 +1,9 @@
1
+ declare module 'jssip/lib/Transactions' {
2
+ export const checkTransaction
3
+ export class InviteServerTransaction {
4
+ constructor(ua, transport, request)
5
+ }
6
+ export class NonInviteServerTransaction {
7
+ constructor(ua, transport, request)
8
+ }
9
+ }