@wazo/sdk 0.37.28 → 0.37.32

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.
Files changed (81) hide show
  1. package/README.md +2 -1
  2. package/dist/wazo-sdk.js +4 -4
  3. package/esm/__tests__/api-client.test.js +30 -0
  4. package/esm/__tests__/web-rtc-client.test.js +65 -6
  5. package/esm/api/calld.js +30 -0
  6. package/esm/api-client.js +30 -0
  7. package/esm/checker/Checker.js +65 -6
  8. package/esm/checker/checks/aor.js +30 -0
  9. package/esm/checker/checks/api.js +30 -0
  10. package/esm/checker/checks/index.js +65 -6
  11. package/esm/checker/checks/webrtc-transport.js +65 -6
  12. package/esm/checker/checks/webrtc.js +65 -6
  13. package/esm/domain/AdHocAPIConference.js +30 -0
  14. package/esm/domain/CallSession.js +15 -3
  15. package/esm/domain/Features.js +30 -0
  16. package/esm/domain/MeetingStatus.js +29 -0
  17. package/esm/domain/Phone/CTIPhone.js +45 -3
  18. package/esm/domain/Phone/WebRTCPhone.js +28 -6
  19. package/esm/domain/__tests__/CallSession.test.js +32 -3
  20. package/esm/domain/__tests__/IndirectTransfer.test.js +15 -3
  21. package/esm/domain/__tests__/Room.test.js +15 -3
  22. package/esm/index.js +93 -12
  23. package/esm/service/CallApi.js +30 -0
  24. package/esm/service/getApiClient.js +30 -0
  25. package/esm/simple/Auth.js +93 -12
  26. package/esm/simple/Configuration.js +93 -12
  27. package/esm/simple/Directory.js +30 -0
  28. package/esm/simple/Phone.js +93 -12
  29. package/esm/simple/index.js +93 -12
  30. package/esm/simple/room/LocalParticipant.js +93 -12
  31. package/esm/simple/room/Participant.js +93 -12
  32. package/esm/simple/room/RemoteParticipant.js +93 -12
  33. package/esm/simple/room/Room.js +93 -12
  34. package/esm/simple/room/SipRoom.js +93 -12
  35. package/esm/simple/room/Stream.js +93 -12
  36. package/esm/simple/room/__tests__/RemoteParticipant.test.js +93 -12
  37. package/esm/simple/utils.js +93 -12
  38. package/esm/web-rtc-client.js +65 -6
  39. package/lib/__tests__/api-client.test.js +30 -0
  40. package/lib/__tests__/web-rtc-client.test.js +65 -6
  41. package/lib/api/calld.js +30 -0
  42. package/lib/api-client.js +30 -0
  43. package/lib/checker/Checker.js +65 -6
  44. package/lib/checker/checks/aor.js +30 -0
  45. package/lib/checker/checks/api.js +30 -0
  46. package/lib/checker/checks/index.js +65 -6
  47. package/lib/checker/checks/webrtc-transport.js +65 -6
  48. package/lib/checker/checks/webrtc.js +65 -6
  49. package/lib/domain/AdHocAPIConference.js +30 -0
  50. package/lib/domain/CallSession.js +15 -3
  51. package/lib/domain/Features.js +30 -0
  52. package/lib/domain/MeetingStatus.js +31 -0
  53. package/lib/domain/Phone/CTIPhone.js +45 -3
  54. package/lib/domain/Phone/WebRTCPhone.js +28 -6
  55. package/lib/domain/__tests__/CallSession.test.js +32 -3
  56. package/lib/domain/__tests__/IndirectTransfer.test.js +15 -3
  57. package/lib/domain/__tests__/Room.test.js +15 -3
  58. package/lib/index.js +93 -12
  59. package/lib/service/CallApi.js +30 -0
  60. package/lib/service/getApiClient.js +30 -0
  61. package/lib/simple/Auth.js +93 -12
  62. package/lib/simple/Configuration.js +93 -12
  63. package/lib/simple/Directory.js +30 -0
  64. package/lib/simple/Phone.js +93 -12
  65. package/lib/simple/index.js +93 -12
  66. package/lib/simple/room/LocalParticipant.js +93 -12
  67. package/lib/simple/room/Participant.js +93 -12
  68. package/lib/simple/room/RemoteParticipant.js +93 -12
  69. package/lib/simple/room/Room.js +93 -12
  70. package/lib/simple/room/SipRoom.js +93 -12
  71. package/lib/simple/room/Stream.js +93 -12
  72. package/lib/simple/room/__tests__/RemoteParticipant.test.js +93 -12
  73. package/lib/simple/utils.js +93 -12
  74. package/lib/web-rtc-client.js +65 -6
  75. package/package.json +1 -1
  76. package/src/api/calld.js +3 -0
  77. package/src/domain/CallSession.js +16 -4
  78. package/src/domain/MeetingStatus.js +27 -0
  79. package/src/domain/Phone/WebRTCPhone.js +13 -3
  80. package/src/domain/__tests__/CallSession.test.js +17 -0
  81. package/src/web-rtc-client.js +35 -6
@@ -3258,6 +3258,7 @@ var updateFrom = (instance , from ) => {
3258
3258
 
3259
3259
 
3260
3260
 
3261
+
3261
3262
 
3262
3263
 
3263
3264
 
@@ -3305,14 +3306,14 @@ class CallSession {
3305
3306
 
3306
3307
 
3307
3308
 
3309
+ // = creationTime
3310
+
3308
3311
 
3309
3312
 
3310
3313
 
3311
3314
 
3312
3315
 
3313
3316
 
3314
-
3315
-
3316
3317
 
3317
3318
 
3318
3319
 
@@ -3376,6 +3377,7 @@ class CallSession {
3376
3377
  recordingPaused,
3377
3378
  videoRemotelyDowngraded,
3378
3379
  sipSession,
3380
+ answerTime,
3379
3381
  } ) {
3380
3382
  this.callId = callId;
3381
3383
  this.sipCallId = sipCallId;
@@ -3403,6 +3405,7 @@ class CallSession {
3403
3405
  this.recordingPaused = recordingPaused || false;
3404
3406
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3405
3407
  this.sipSession = sipSession;
3408
+ this.answerTime = answerTime || this.answerTime;
3406
3409
 
3407
3410
  // Useful to compare instead of instanceof with minified code
3408
3411
  this.type = 'CallSession';
@@ -3433,7 +3436,7 @@ class CallSession {
3433
3436
  }
3434
3437
 
3435
3438
  answer() {
3436
- this.answered = true;
3439
+ this.answerTime = new Date();
3437
3440
  }
3438
3441
 
3439
3442
  systemAnswer() {
@@ -3589,6 +3592,15 @@ class CallSession {
3589
3592
  return newFrom(callSession, CallSession);
3590
3593
  }
3591
3594
 
3595
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3596
+ set answered(value ) {
3597
+ this.answerTime = value ? this.answerTime || new Date() : null;
3598
+ }
3599
+
3600
+ get answered() {
3601
+ return !!this.answerTime;
3602
+ }
3603
+
3592
3604
  static parseCall(call ) {
3593
3605
  return new CallSession({
3594
3606
  callId: call.id,
@@ -4840,6 +4852,34 @@ var chatdMethods = (client , baseUrl ) => ({
4840
4852
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4841
4853
  });
4842
4854
 
4855
+ //
4856
+
4857
+
4858
+
4859
+
4860
+
4861
+ class MeetingStatus {
4862
+
4863
+
4864
+
4865
+
4866
+ constructor({
4867
+ full,
4868
+ } = {}) {
4869
+ this.full = full;
4870
+
4871
+ // Useful to compare instead of instanceof with minified code
4872
+ this.type = 'MeetingStatus';
4873
+ }
4874
+
4875
+ static parse(plain ) {
4876
+ return new MeetingStatus({
4877
+ full: plain.full,
4878
+ });
4879
+ }
4880
+
4881
+ }
4882
+
4843
4883
  /* */
4844
4884
 
4845
4885
 
@@ -5034,6 +5074,8 @@ var calldMethods = (client , baseUrl ) => ({
5034
5074
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5035
5075
  ApiRequester.successResponseParser),
5036
5076
 
5077
+ guestGetMeetingStatus: (meetingUuid ) =>
5078
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5037
5079
  });
5038
5080
 
5039
5081
  //
@@ -6371,6 +6413,7 @@ const MAX_REGISTER_TRIES = 10;
6371
6413
 
6372
6414
 
6373
6415
 
6416
+
6374
6417
 
6375
6418
 
6376
6419
 
@@ -6412,6 +6455,7 @@ class WebRTCClient extends Emitter {
6412
6455
 
6413
6456
 
6414
6457
 
6458
+
6415
6459
 
6416
6460
  // sugar
6417
6461
 
@@ -6474,6 +6518,7 @@ class WebRTCClient extends Emitter {
6474
6518
  this.conferences = {};
6475
6519
  this.networkMonitoringInterval = {};
6476
6520
  this.sessionNetworkStats = {};
6521
+ this.forceClosed = false;
6477
6522
 
6478
6523
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6479
6524
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6595,6 +6640,8 @@ class WebRTCClient extends Emitter {
6595
6640
  skipRegister: this.skipRegister,
6596
6641
  };
6597
6642
 
6643
+ this.forceClosed = false;
6644
+
6598
6645
  if (this.skipRegister) {
6599
6646
  logger$9.info('sdk webrtc skip register...', logInfo);
6600
6647
  return Promise.resolve();
@@ -6619,7 +6666,15 @@ class WebRTCClient extends Emitter {
6619
6666
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6620
6667
 
6621
6668
  const onRegisterFailed = () => {
6622
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6669
+ logger$9.info('sdk webrtc registering failed', {
6670
+ tries,
6671
+ registerer: !!this.registerer,
6672
+ forceClosed: this.forceClosed,
6673
+ });
6674
+ if (this.forceClosed) {
6675
+ return;
6676
+ }
6677
+
6623
6678
  this.connectionPromise = null;
6624
6679
  if (this.registerer && this.registerer.waiting) {
6625
6680
  this.registerer.waitingToggle(false);
@@ -6897,8 +6952,9 @@ class WebRTCClient extends Emitter {
6897
6952
  }
6898
6953
  }
6899
6954
 
6900
- async close() {
6901
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6955
+ async close(force = false) {
6956
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6957
+ this.forceClosed = force;
6902
6958
  this._cleanupMedia();
6903
6959
  this.connectionPromise = null;
6904
6960
 
@@ -6917,7 +6973,7 @@ class WebRTCClient extends Emitter {
6917
6973
  this.userAgent.delegate = null;
6918
6974
  this.userAgent.stateChange.removeAllListeners();
6919
6975
 
6920
- await this._disconnectTransport();
6976
+ await this._disconnectTransport(force);
6921
6977
 
6922
6978
  this._cleanupRegister();
6923
6979
 
@@ -7987,6 +8043,13 @@ class WebRTCClient extends Emitter {
7987
8043
  }
7988
8044
 
7989
8045
  _createWebRTCConfiguration(configOverrides = {}) {
8046
+ let { host } = this.config;
8047
+ let port = this.config.port || 443;
8048
+
8049
+ if (this.config.websocketSip) {
8050
+ [host, port = 443] = this.config.websocketSip.split(':');
8051
+ }
8052
+
7990
8053
  const config = {
7991
8054
  authorizationUsername: this.config.authorizationUser,
7992
8055
  authorizationPassword: this.config.password,
@@ -8022,7 +8085,7 @@ class WebRTCClient extends Emitter {
8022
8085
  },
8023
8086
  transportOptions: {
8024
8087
  traceSip: configOverrides.traceSip || false,
8025
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8088
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8026
8089
  },
8027
8090
  sessionDescriptionHandlerFactoryOptions: {
8028
8091
  modifiers: [replaceLocalIpModifier],
@@ -8346,7 +8409,15 @@ class WebRTCClient extends Emitter {
8346
8409
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8347
8410
  }
8348
8411
 
8349
- async _disconnectTransport() {
8412
+ async _disconnectTransport(force = false) {
8413
+ if (force) {
8414
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8415
+ this.userAgent.transport.disconnectResolve = () => {};
8416
+ // eslint-disable-next-line
8417
+ this.userAgent.transport._ws.close(1000);
8418
+ return;
8419
+ }
8420
+
8350
8421
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8351
8422
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8352
8423
  try {
@@ -9082,6 +9153,8 @@ class WebRTCPhone extends Emitter {
9082
9153
  this.removeIncomingSessions(sipSessionId);
9083
9154
  }
9084
9155
 
9156
+ callSession.answerTime = new Date();
9157
+ this._updateCallSession(callSession);
9085
9158
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9086
9159
 
9087
9160
  return callSession;
@@ -9297,6 +9370,8 @@ class WebRTCPhone extends Emitter {
9297
9370
  }
9298
9371
 
9299
9372
  this.shouldSendReinvite = false;
9373
+ callSession.answerTime = new Date();
9374
+ this._updateCallSession(callSession);
9300
9375
  this.acceptedSessions[callSession.getId()] = true;
9301
9376
 
9302
9377
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9396,7 +9471,7 @@ class WebRTCPhone extends Emitter {
9396
9471
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9397
9472
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9398
9473
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9399
- this.holdSipSession(this.currentSipSession, callSession);
9474
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9400
9475
  }
9401
9476
 
9402
9477
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9607,6 +9682,7 @@ class WebRTCPhone extends Emitter {
9607
9682
  }
9608
9683
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9609
9684
  callSession.creationTime = new Date();
9685
+ this._updateCallSession(callSession);
9610
9686
 
9611
9687
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9612
9688
 
@@ -9748,7 +9824,7 @@ class WebRTCPhone extends Emitter {
9748
9824
  return this.client && this.client.isConference(callSession.sipCallId);
9749
9825
  }
9750
9826
 
9751
- async close() {
9827
+ async close(force = false) {
9752
9828
  logger$8.info('WebRTC close');
9753
9829
 
9754
9830
  try {
@@ -9760,7 +9836,7 @@ class WebRTCPhone extends Emitter {
9760
9836
  logger$8.error('WebRTC close, unregister error', e);
9761
9837
  }
9762
9838
 
9763
- this.client.close();
9839
+ this.client.close(force);
9764
9840
  this.unbind();
9765
9841
 
9766
9842
  this.incomingSessions = [];
@@ -9886,6 +9962,8 @@ class WebRTCPhone extends Emitter {
9886
9962
  }
9887
9963
 
9888
9964
  callSession.creationTime = new Date();
9965
+ this._updateCallSession(callSession);
9966
+
9889
9967
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9890
9968
  });
9891
9969
 
@@ -9929,6 +10007,8 @@ class WebRTCPhone extends Emitter {
9929
10007
  logger$8.info('WebRTC call rejected', session.id);
9930
10008
  const callSession = this._createCallSession(session);
9931
10009
  callSession.endTime = new Date();
10010
+ this._updateCallSession(callSession);
10011
+
9932
10012
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9933
10013
  });
9934
10014
 
@@ -10153,6 +10233,7 @@ class WebRTCPhone extends Emitter {
10153
10233
  displayName: identity ? identity.displayName || number : number,
10154
10234
  startTime: fromSession ? fromSession.startTime : new Date(),
10155
10235
  creationTime: fromSession ? fromSession.creationTime : null,
10236
+ answerTime: fromSession ? fromSession.answerTime : null,
10156
10237
  endTime: fromSession ? fromSession.endTime : null,
10157
10238
  answered: state === sessionState.SessionState.Established,
10158
10239
  paused: this.client.isCallHeld(sipSession),
@@ -4022,6 +4022,34 @@ var chatdMethods = (client , baseUrl ) => ({
4022
4022
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4023
4023
  });
4024
4024
 
4025
+ //
4026
+
4027
+
4028
+
4029
+
4030
+
4031
+ class MeetingStatus {
4032
+
4033
+
4034
+
4035
+
4036
+ constructor({
4037
+ full,
4038
+ } = {}) {
4039
+ this.full = full;
4040
+
4041
+ // Useful to compare instead of instanceof with minified code
4042
+ this.type = 'MeetingStatus';
4043
+ }
4044
+
4045
+ static parse(plain ) {
4046
+ return new MeetingStatus({
4047
+ full: plain.full,
4048
+ });
4049
+ }
4050
+
4051
+ }
4052
+
4025
4053
  /* */
4026
4054
 
4027
4055
 
@@ -4216,6 +4244,8 @@ var calldMethods = (client , baseUrl ) => ({
4216
4244
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4217
4245
  ApiRequester.successResponseParser),
4218
4246
 
4247
+ guestGetMeetingStatus: (meetingUuid ) =>
4248
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4219
4249
  });
4220
4250
 
4221
4251
  //
@@ -258,6 +258,7 @@ var updateFrom = (instance , from ) => {
258
258
 
259
259
 
260
260
 
261
+
261
262
 
262
263
 
263
264
 
@@ -305,14 +306,14 @@ class CallSession {
305
306
 
306
307
 
307
308
 
309
+ // = creationTime
310
+
308
311
 
309
312
 
310
313
 
311
314
 
312
315
 
313
316
 
314
-
315
-
316
317
 
317
318
 
318
319
 
@@ -376,6 +377,7 @@ class CallSession {
376
377
  recordingPaused,
377
378
  videoRemotelyDowngraded,
378
379
  sipSession,
380
+ answerTime,
379
381
  } ) {
380
382
  this.callId = callId;
381
383
  this.sipCallId = sipCallId;
@@ -403,6 +405,7 @@ class CallSession {
403
405
  this.recordingPaused = recordingPaused || false;
404
406
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
405
407
  this.sipSession = sipSession;
408
+ this.answerTime = answerTime || this.answerTime;
406
409
 
407
410
  // Useful to compare instead of instanceof with minified code
408
411
  this.type = 'CallSession';
@@ -433,7 +436,7 @@ class CallSession {
433
436
  }
434
437
 
435
438
  answer() {
436
- this.answered = true;
439
+ this.answerTime = new Date();
437
440
  }
438
441
 
439
442
  systemAnswer() {
@@ -589,6 +592,15 @@ class CallSession {
589
592
  return newFrom(callSession, CallSession);
590
593
  }
591
594
 
595
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
596
+ set answered(value ) {
597
+ this.answerTime = value ? this.answerTime || new Date() : null;
598
+ }
599
+
600
+ get answered() {
601
+ return !!this.answerTime;
602
+ }
603
+
592
604
  static parseCall(call ) {
593
605
  return new CallSession({
594
606
  callId: call.id,
@@ -4840,6 +4852,34 @@ var chatdMethods = (client , baseUrl ) => ({
4840
4852
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4841
4853
  });
4842
4854
 
4855
+ //
4856
+
4857
+
4858
+
4859
+
4860
+
4861
+ class MeetingStatus {
4862
+
4863
+
4864
+
4865
+
4866
+ constructor({
4867
+ full,
4868
+ } = {}) {
4869
+ this.full = full;
4870
+
4871
+ // Useful to compare instead of instanceof with minified code
4872
+ this.type = 'MeetingStatus';
4873
+ }
4874
+
4875
+ static parse(plain ) {
4876
+ return new MeetingStatus({
4877
+ full: plain.full,
4878
+ });
4879
+ }
4880
+
4881
+ }
4882
+
4843
4883
  /* */
4844
4884
 
4845
4885
 
@@ -5034,6 +5074,8 @@ var calldMethods = (client , baseUrl ) => ({
5034
5074
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5035
5075
  ApiRequester.successResponseParser),
5036
5076
 
5077
+ guestGetMeetingStatus: (meetingUuid ) =>
5078
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5037
5079
  });
5038
5080
 
5039
5081
  //
@@ -6371,6 +6413,7 @@ const MAX_REGISTER_TRIES = 10;
6371
6413
 
6372
6414
 
6373
6415
 
6416
+
6374
6417
 
6375
6418
 
6376
6419
 
@@ -6412,6 +6455,7 @@ class WebRTCClient extends Emitter {
6412
6455
 
6413
6456
 
6414
6457
 
6458
+
6415
6459
 
6416
6460
  // sugar
6417
6461
 
@@ -6474,6 +6518,7 @@ class WebRTCClient extends Emitter {
6474
6518
  this.conferences = {};
6475
6519
  this.networkMonitoringInterval = {};
6476
6520
  this.sessionNetworkStats = {};
6521
+ this.forceClosed = false;
6477
6522
 
6478
6523
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6479
6524
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6595,6 +6640,8 @@ class WebRTCClient extends Emitter {
6595
6640
  skipRegister: this.skipRegister,
6596
6641
  };
6597
6642
 
6643
+ this.forceClosed = false;
6644
+
6598
6645
  if (this.skipRegister) {
6599
6646
  logger$9.info('sdk webrtc skip register...', logInfo);
6600
6647
  return Promise.resolve();
@@ -6619,7 +6666,15 @@ class WebRTCClient extends Emitter {
6619
6666
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6620
6667
 
6621
6668
  const onRegisterFailed = () => {
6622
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6669
+ logger$9.info('sdk webrtc registering failed', {
6670
+ tries,
6671
+ registerer: !!this.registerer,
6672
+ forceClosed: this.forceClosed,
6673
+ });
6674
+ if (this.forceClosed) {
6675
+ return;
6676
+ }
6677
+
6623
6678
  this.connectionPromise = null;
6624
6679
  if (this.registerer && this.registerer.waiting) {
6625
6680
  this.registerer.waitingToggle(false);
@@ -6897,8 +6952,9 @@ class WebRTCClient extends Emitter {
6897
6952
  }
6898
6953
  }
6899
6954
 
6900
- async close() {
6901
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6955
+ async close(force = false) {
6956
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6957
+ this.forceClosed = force;
6902
6958
  this._cleanupMedia();
6903
6959
  this.connectionPromise = null;
6904
6960
 
@@ -6917,7 +6973,7 @@ class WebRTCClient extends Emitter {
6917
6973
  this.userAgent.delegate = null;
6918
6974
  this.userAgent.stateChange.removeAllListeners();
6919
6975
 
6920
- await this._disconnectTransport();
6976
+ await this._disconnectTransport(force);
6921
6977
 
6922
6978
  this._cleanupRegister();
6923
6979
 
@@ -7987,6 +8043,13 @@ class WebRTCClient extends Emitter {
7987
8043
  }
7988
8044
 
7989
8045
  _createWebRTCConfiguration(configOverrides = {}) {
8046
+ let { host } = this.config;
8047
+ let port = this.config.port || 443;
8048
+
8049
+ if (this.config.websocketSip) {
8050
+ [host, port = 443] = this.config.websocketSip.split(':');
8051
+ }
8052
+
7990
8053
  const config = {
7991
8054
  authorizationUsername: this.config.authorizationUser,
7992
8055
  authorizationPassword: this.config.password,
@@ -8022,7 +8085,7 @@ class WebRTCClient extends Emitter {
8022
8085
  },
8023
8086
  transportOptions: {
8024
8087
  traceSip: configOverrides.traceSip || false,
8025
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8088
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8026
8089
  },
8027
8090
  sessionDescriptionHandlerFactoryOptions: {
8028
8091
  modifiers: [replaceLocalIpModifier],
@@ -8346,7 +8409,15 @@ class WebRTCClient extends Emitter {
8346
8409
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8347
8410
  }
8348
8411
 
8349
- async _disconnectTransport() {
8412
+ async _disconnectTransport(force = false) {
8413
+ if (force) {
8414
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8415
+ this.userAgent.transport.disconnectResolve = () => {};
8416
+ // eslint-disable-next-line
8417
+ this.userAgent.transport._ws.close(1000);
8418
+ return;
8419
+ }
8420
+
8350
8421
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8351
8422
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8352
8423
  try {
@@ -9082,6 +9153,8 @@ class WebRTCPhone extends Emitter {
9082
9153
  this.removeIncomingSessions(sipSessionId);
9083
9154
  }
9084
9155
 
9156
+ callSession.answerTime = new Date();
9157
+ this._updateCallSession(callSession);
9085
9158
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9086
9159
 
9087
9160
  return callSession;
@@ -9297,6 +9370,8 @@ class WebRTCPhone extends Emitter {
9297
9370
  }
9298
9371
 
9299
9372
  this.shouldSendReinvite = false;
9373
+ callSession.answerTime = new Date();
9374
+ this._updateCallSession(callSession);
9300
9375
  this.acceptedSessions[callSession.getId()] = true;
9301
9376
 
9302
9377
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9396,7 +9471,7 @@ class WebRTCPhone extends Emitter {
9396
9471
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9397
9472
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9398
9473
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9399
- this.holdSipSession(this.currentSipSession, callSession);
9474
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9400
9475
  }
9401
9476
 
9402
9477
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9607,6 +9682,7 @@ class WebRTCPhone extends Emitter {
9607
9682
  }
9608
9683
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9609
9684
  callSession.creationTime = new Date();
9685
+ this._updateCallSession(callSession);
9610
9686
 
9611
9687
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9612
9688
 
@@ -9748,7 +9824,7 @@ class WebRTCPhone extends Emitter {
9748
9824
  return this.client && this.client.isConference(callSession.sipCallId);
9749
9825
  }
9750
9826
 
9751
- async close() {
9827
+ async close(force = false) {
9752
9828
  logger$8.info('WebRTC close');
9753
9829
 
9754
9830
  try {
@@ -9760,7 +9836,7 @@ class WebRTCPhone extends Emitter {
9760
9836
  logger$8.error('WebRTC close, unregister error', e);
9761
9837
  }
9762
9838
 
9763
- this.client.close();
9839
+ this.client.close(force);
9764
9840
  this.unbind();
9765
9841
 
9766
9842
  this.incomingSessions = [];
@@ -9886,6 +9962,8 @@ class WebRTCPhone extends Emitter {
9886
9962
  }
9887
9963
 
9888
9964
  callSession.creationTime = new Date();
9965
+ this._updateCallSession(callSession);
9966
+
9889
9967
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9890
9968
  });
9891
9969
 
@@ -9929,6 +10007,8 @@ class WebRTCPhone extends Emitter {
9929
10007
  logger$8.info('WebRTC call rejected', session.id);
9930
10008
  const callSession = this._createCallSession(session);
9931
10009
  callSession.endTime = new Date();
10010
+ this._updateCallSession(callSession);
10011
+
9932
10012
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9933
10013
  });
9934
10014
 
@@ -10153,6 +10233,7 @@ class WebRTCPhone extends Emitter {
10153
10233
  displayName: identity ? identity.displayName || number : number,
10154
10234
  startTime: fromSession ? fromSession.startTime : new Date(),
10155
10235
  creationTime: fromSession ? fromSession.creationTime : null,
10236
+ answerTime: fromSession ? fromSession.answerTime : null,
10156
10237
  endTime: fromSession ? fromSession.endTime : null,
10157
10238
  answered: state === sessionState.SessionState.Established,
10158
10239
  paused: this.client.isCallHeld(sipSession),