@voicenter-team/opensips-js 1.0.20 → 1.0.22

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.
@@ -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
+ }