@wazo/sdk 0.37.29 → 0.37.33

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 +9 -1
  15. package/esm/domain/Features.js +30 -0
  16. package/esm/domain/MeetingStatus.js +29 -0
  17. package/esm/domain/Phone/CTIPhone.js +39 -1
  18. package/esm/domain/Phone/WebRTCPhone.js +20 -4
  19. package/esm/domain/__tests__/CallSession.test.js +41 -5
  20. package/esm/domain/__tests__/IndirectTransfer.test.js +9 -1
  21. package/esm/domain/__tests__/Room.test.js +9 -1
  22. package/esm/index.js +85 -10
  23. package/esm/service/CallApi.js +30 -0
  24. package/esm/service/getApiClient.js +30 -0
  25. package/esm/simple/Auth.js +85 -10
  26. package/esm/simple/Configuration.js +85 -10
  27. package/esm/simple/Directory.js +30 -0
  28. package/esm/simple/Phone.js +85 -10
  29. package/esm/simple/index.js +85 -10
  30. package/esm/simple/room/LocalParticipant.js +85 -10
  31. package/esm/simple/room/Participant.js +85 -10
  32. package/esm/simple/room/RemoteParticipant.js +85 -10
  33. package/esm/simple/room/Room.js +85 -10
  34. package/esm/simple/room/SipRoom.js +85 -10
  35. package/esm/simple/room/Stream.js +85 -10
  36. package/esm/simple/room/__tests__/RemoteParticipant.test.js +85 -10
  37. package/esm/simple/utils.js +85 -10
  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 +9 -1
  51. package/lib/domain/Features.js +30 -0
  52. package/lib/domain/MeetingStatus.js +31 -0
  53. package/lib/domain/Phone/CTIPhone.js +39 -1
  54. package/lib/domain/Phone/WebRTCPhone.js +20 -4
  55. package/lib/domain/__tests__/CallSession.test.js +41 -5
  56. package/lib/domain/__tests__/IndirectTransfer.test.js +9 -1
  57. package/lib/domain/__tests__/Room.test.js +9 -1
  58. package/lib/index.js +85 -10
  59. package/lib/service/CallApi.js +30 -0
  60. package/lib/service/getApiClient.js +30 -0
  61. package/lib/simple/Auth.js +85 -10
  62. package/lib/simple/Configuration.js +85 -10
  63. package/lib/simple/Directory.js +30 -0
  64. package/lib/simple/Phone.js +85 -10
  65. package/lib/simple/index.js +85 -10
  66. package/lib/simple/room/LocalParticipant.js +85 -10
  67. package/lib/simple/room/Participant.js +85 -10
  68. package/lib/simple/room/RemoteParticipant.js +85 -10
  69. package/lib/simple/room/Room.js +85 -10
  70. package/lib/simple/room/SipRoom.js +85 -10
  71. package/lib/simple/room/Stream.js +85 -10
  72. package/lib/simple/room/__tests__/RemoteParticipant.test.js +85 -10
  73. package/lib/simple/utils.js +85 -10
  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 +9 -1
  78. package/src/domain/MeetingStatus.js +27 -0
  79. package/src/domain/Phone/WebRTCPhone.js +11 -3
  80. package/src/domain/__tests__/CallSession.test.js +32 -4
  81. package/src/web-rtc-client.js +35 -6
@@ -3594,13 +3594,21 @@ class CallSession {
3594
3594
 
3595
3595
  // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3596
3596
  set answered(value ) {
3597
- this.answerTime = value ? new Date() : null;
3597
+ this.answerTime = value ? this.answerTime || new Date() : null;
3598
3598
  }
3599
3599
 
3600
3600
  get answered() {
3601
3601
  return !!this.answerTime;
3602
3602
  }
3603
3603
 
3604
+ toJSON() {
3605
+ const jsonObj = { ...this };
3606
+ // $FlowFixMe
3607
+ jsonObj.answered = this.answered;
3608
+
3609
+ return jsonObj;
3610
+ }
3611
+
3604
3612
  static parseCall(call ) {
3605
3613
  return new CallSession({
3606
3614
  callId: call.id,
@@ -4852,6 +4860,34 @@ var chatdMethods = (client , baseUrl ) => ({
4852
4860
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4853
4861
  });
4854
4862
 
4863
+ //
4864
+
4865
+
4866
+
4867
+
4868
+
4869
+ class MeetingStatus {
4870
+
4871
+
4872
+
4873
+
4874
+ constructor({
4875
+ full,
4876
+ } = {}) {
4877
+ this.full = full;
4878
+
4879
+ // Useful to compare instead of instanceof with minified code
4880
+ this.type = 'MeetingStatus';
4881
+ }
4882
+
4883
+ static parse(plain ) {
4884
+ return new MeetingStatus({
4885
+ full: plain.full,
4886
+ });
4887
+ }
4888
+
4889
+ }
4890
+
4855
4891
  /* */
4856
4892
 
4857
4893
 
@@ -5046,6 +5082,8 @@ var calldMethods = (client , baseUrl ) => ({
5046
5082
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5047
5083
  ApiRequester.successResponseParser),
5048
5084
 
5085
+ guestGetMeetingStatus: (meetingUuid ) =>
5086
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5049
5087
  });
5050
5088
 
5051
5089
  //
@@ -6647,6 +6685,7 @@ const MAX_REGISTER_TRIES = 10;
6647
6685
 
6648
6686
 
6649
6687
 
6688
+
6650
6689
 
6651
6690
 
6652
6691
 
@@ -6688,6 +6727,7 @@ class WebRTCClient extends Emitter {
6688
6727
 
6689
6728
 
6690
6729
 
6730
+
6691
6731
 
6692
6732
  // sugar
6693
6733
 
@@ -6750,6 +6790,7 @@ class WebRTCClient extends Emitter {
6750
6790
  this.conferences = {};
6751
6791
  this.networkMonitoringInterval = {};
6752
6792
  this.sessionNetworkStats = {};
6793
+ this.forceClosed = false;
6753
6794
 
6754
6795
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6755
6796
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6871,6 +6912,8 @@ class WebRTCClient extends Emitter {
6871
6912
  skipRegister: this.skipRegister,
6872
6913
  };
6873
6914
 
6915
+ this.forceClosed = false;
6916
+
6874
6917
  if (this.skipRegister) {
6875
6918
  logger$8.info('sdk webrtc skip register...', logInfo);
6876
6919
  return Promise.resolve();
@@ -6895,7 +6938,15 @@ class WebRTCClient extends Emitter {
6895
6938
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6896
6939
 
6897
6940
  const onRegisterFailed = () => {
6898
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6941
+ logger$8.info('sdk webrtc registering failed', {
6942
+ tries,
6943
+ registerer: !!this.registerer,
6944
+ forceClosed: this.forceClosed,
6945
+ });
6946
+ if (this.forceClosed) {
6947
+ return;
6948
+ }
6949
+
6899
6950
  this.connectionPromise = null;
6900
6951
  if (this.registerer && this.registerer.waiting) {
6901
6952
  this.registerer.waitingToggle(false);
@@ -7173,8 +7224,9 @@ class WebRTCClient extends Emitter {
7173
7224
  }
7174
7225
  }
7175
7226
 
7176
- async close() {
7177
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
7227
+ async close(force = false) {
7228
+ logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
7229
+ this.forceClosed = force;
7178
7230
  this._cleanupMedia();
7179
7231
  this.connectionPromise = null;
7180
7232
 
@@ -7193,7 +7245,7 @@ class WebRTCClient extends Emitter {
7193
7245
  this.userAgent.delegate = null;
7194
7246
  this.userAgent.stateChange.removeAllListeners();
7195
7247
 
7196
- await this._disconnectTransport();
7248
+ await this._disconnectTransport(force);
7197
7249
 
7198
7250
  this._cleanupRegister();
7199
7251
 
@@ -8263,6 +8315,13 @@ class WebRTCClient extends Emitter {
8263
8315
  }
8264
8316
 
8265
8317
  _createWebRTCConfiguration(configOverrides = {}) {
8318
+ let { host } = this.config;
8319
+ let port = this.config.port || 443;
8320
+
8321
+ if (this.config.websocketSip) {
8322
+ [host, port = 443] = this.config.websocketSip.split(':');
8323
+ }
8324
+
8266
8325
  const config = {
8267
8326
  authorizationUsername: this.config.authorizationUser,
8268
8327
  authorizationPassword: this.config.password,
@@ -8298,7 +8357,7 @@ class WebRTCClient extends Emitter {
8298
8357
  },
8299
8358
  transportOptions: {
8300
8359
  traceSip: configOverrides.traceSip || false,
8301
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8360
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8302
8361
  },
8303
8362
  sessionDescriptionHandlerFactoryOptions: {
8304
8363
  modifiers: [replaceLocalIpModifier],
@@ -8622,7 +8681,15 @@ class WebRTCClient extends Emitter {
8622
8681
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8623
8682
  }
8624
8683
 
8625
- async _disconnectTransport() {
8684
+ async _disconnectTransport(force = false) {
8685
+ if (force) {
8686
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8687
+ this.userAgent.transport.disconnectResolve = () => {};
8688
+ // eslint-disable-next-line
8689
+ this.userAgent.transport._ws.close(1000);
8690
+ return;
8691
+ }
8692
+
8626
8693
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8627
8694
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8628
8695
  try {
@@ -9359,6 +9426,7 @@ class WebRTCPhone extends Emitter {
9359
9426
  }
9360
9427
 
9361
9428
  callSession.answerTime = new Date();
9429
+ this._updateCallSession(callSession);
9362
9430
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9363
9431
 
9364
9432
  return callSession;
@@ -9575,6 +9643,7 @@ class WebRTCPhone extends Emitter {
9575
9643
 
9576
9644
  this.shouldSendReinvite = false;
9577
9645
  callSession.answerTime = new Date();
9646
+ this._updateCallSession(callSession);
9578
9647
  this.acceptedSessions[callSession.getId()] = true;
9579
9648
 
9580
9649
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9674,7 +9743,7 @@ class WebRTCPhone extends Emitter {
9674
9743
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9675
9744
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9676
9745
  logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9677
- this.holdSipSession(this.currentSipSession, callSession);
9746
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9678
9747
  }
9679
9748
 
9680
9749
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9885,6 +9954,7 @@ class WebRTCPhone extends Emitter {
9885
9954
  }
9886
9955
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9887
9956
  callSession.creationTime = new Date();
9957
+ this._updateCallSession(callSession);
9888
9958
 
9889
9959
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9890
9960
 
@@ -10026,7 +10096,7 @@ class WebRTCPhone extends Emitter {
10026
10096
  return this.client && this.client.isConference(callSession.sipCallId);
10027
10097
  }
10028
10098
 
10029
- async close() {
10099
+ async close(force = false) {
10030
10100
  logger$7.info('WebRTC close');
10031
10101
 
10032
10102
  try {
@@ -10038,7 +10108,7 @@ class WebRTCPhone extends Emitter {
10038
10108
  logger$7.error('WebRTC close, unregister error', e);
10039
10109
  }
10040
10110
 
10041
- this.client.close();
10111
+ this.client.close(force);
10042
10112
  this.unbind();
10043
10113
 
10044
10114
  this.incomingSessions = [];
@@ -10164,6 +10234,8 @@ class WebRTCPhone extends Emitter {
10164
10234
  }
10165
10235
 
10166
10236
  callSession.creationTime = new Date();
10237
+ this._updateCallSession(callSession);
10238
+
10167
10239
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10168
10240
  });
10169
10241
 
@@ -10207,6 +10279,8 @@ class WebRTCPhone extends Emitter {
10207
10279
  logger$7.info('WebRTC call rejected', session.id);
10208
10280
  const callSession = this._createCallSession(session);
10209
10281
  callSession.endTime = new Date();
10282
+ this._updateCallSession(callSession);
10283
+
10210
10284
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10211
10285
  });
10212
10286
 
@@ -10431,6 +10505,7 @@ class WebRTCPhone extends Emitter {
10431
10505
  displayName: identity ? identity.displayName || number : number,
10432
10506
  startTime: fromSession ? fromSession.startTime : new Date(),
10433
10507
  creationTime: fromSession ? fromSession.creationTime : null,
10508
+ answerTime: fromSession ? fromSession.answerTime : null,
10434
10509
  endTime: fromSession ? fromSession.endTime : null,
10435
10510
  answered: state === sessionState.SessionState.Established,
10436
10511
  paused: this.client.isCallHeld(sipSession),
@@ -3594,13 +3594,21 @@ class CallSession {
3594
3594
 
3595
3595
  // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3596
3596
  set answered(value ) {
3597
- this.answerTime = value ? new Date() : null;
3597
+ this.answerTime = value ? this.answerTime || new Date() : null;
3598
3598
  }
3599
3599
 
3600
3600
  get answered() {
3601
3601
  return !!this.answerTime;
3602
3602
  }
3603
3603
 
3604
+ toJSON() {
3605
+ const jsonObj = { ...this };
3606
+ // $FlowFixMe
3607
+ jsonObj.answered = this.answered;
3608
+
3609
+ return jsonObj;
3610
+ }
3611
+
3604
3612
  static parseCall(call ) {
3605
3613
  return new CallSession({
3606
3614
  callId: call.id,
@@ -4852,6 +4860,34 @@ var chatdMethods = (client , baseUrl ) => ({
4852
4860
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4853
4861
  });
4854
4862
 
4863
+ //
4864
+
4865
+
4866
+
4867
+
4868
+
4869
+ class MeetingStatus {
4870
+
4871
+
4872
+
4873
+
4874
+ constructor({
4875
+ full,
4876
+ } = {}) {
4877
+ this.full = full;
4878
+
4879
+ // Useful to compare instead of instanceof with minified code
4880
+ this.type = 'MeetingStatus';
4881
+ }
4882
+
4883
+ static parse(plain ) {
4884
+ return new MeetingStatus({
4885
+ full: plain.full,
4886
+ });
4887
+ }
4888
+
4889
+ }
4890
+
4855
4891
  /* */
4856
4892
 
4857
4893
 
@@ -5046,6 +5082,8 @@ var calldMethods = (client , baseUrl ) => ({
5046
5082
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5047
5083
  ApiRequester.successResponseParser),
5048
5084
 
5085
+ guestGetMeetingStatus: (meetingUuid ) =>
5086
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5049
5087
  });
5050
5088
 
5051
5089
  //
@@ -6647,6 +6685,7 @@ const MAX_REGISTER_TRIES = 10;
6647
6685
 
6648
6686
 
6649
6687
 
6688
+
6650
6689
 
6651
6690
 
6652
6691
 
@@ -6688,6 +6727,7 @@ class WebRTCClient extends Emitter {
6688
6727
 
6689
6728
 
6690
6729
 
6730
+
6691
6731
 
6692
6732
  // sugar
6693
6733
 
@@ -6750,6 +6790,7 @@ class WebRTCClient extends Emitter {
6750
6790
  this.conferences = {};
6751
6791
  this.networkMonitoringInterval = {};
6752
6792
  this.sessionNetworkStats = {};
6793
+ this.forceClosed = false;
6753
6794
 
6754
6795
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6755
6796
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6871,6 +6912,8 @@ class WebRTCClient extends Emitter {
6871
6912
  skipRegister: this.skipRegister,
6872
6913
  };
6873
6914
 
6915
+ this.forceClosed = false;
6916
+
6874
6917
  if (this.skipRegister) {
6875
6918
  logger$8.info('sdk webrtc skip register...', logInfo);
6876
6919
  return Promise.resolve();
@@ -6895,7 +6938,15 @@ class WebRTCClient extends Emitter {
6895
6938
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6896
6939
 
6897
6940
  const onRegisterFailed = () => {
6898
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6941
+ logger$8.info('sdk webrtc registering failed', {
6942
+ tries,
6943
+ registerer: !!this.registerer,
6944
+ forceClosed: this.forceClosed,
6945
+ });
6946
+ if (this.forceClosed) {
6947
+ return;
6948
+ }
6949
+
6899
6950
  this.connectionPromise = null;
6900
6951
  if (this.registerer && this.registerer.waiting) {
6901
6952
  this.registerer.waitingToggle(false);
@@ -7173,8 +7224,9 @@ class WebRTCClient extends Emitter {
7173
7224
  }
7174
7225
  }
7175
7226
 
7176
- async close() {
7177
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
7227
+ async close(force = false) {
7228
+ logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
7229
+ this.forceClosed = force;
7178
7230
  this._cleanupMedia();
7179
7231
  this.connectionPromise = null;
7180
7232
 
@@ -7193,7 +7245,7 @@ class WebRTCClient extends Emitter {
7193
7245
  this.userAgent.delegate = null;
7194
7246
  this.userAgent.stateChange.removeAllListeners();
7195
7247
 
7196
- await this._disconnectTransport();
7248
+ await this._disconnectTransport(force);
7197
7249
 
7198
7250
  this._cleanupRegister();
7199
7251
 
@@ -8263,6 +8315,13 @@ class WebRTCClient extends Emitter {
8263
8315
  }
8264
8316
 
8265
8317
  _createWebRTCConfiguration(configOverrides = {}) {
8318
+ let { host } = this.config;
8319
+ let port = this.config.port || 443;
8320
+
8321
+ if (this.config.websocketSip) {
8322
+ [host, port = 443] = this.config.websocketSip.split(':');
8323
+ }
8324
+
8266
8325
  const config = {
8267
8326
  authorizationUsername: this.config.authorizationUser,
8268
8327
  authorizationPassword: this.config.password,
@@ -8298,7 +8357,7 @@ class WebRTCClient extends Emitter {
8298
8357
  },
8299
8358
  transportOptions: {
8300
8359
  traceSip: configOverrides.traceSip || false,
8301
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8360
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8302
8361
  },
8303
8362
  sessionDescriptionHandlerFactoryOptions: {
8304
8363
  modifiers: [replaceLocalIpModifier],
@@ -8622,7 +8681,15 @@ class WebRTCClient extends Emitter {
8622
8681
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8623
8682
  }
8624
8683
 
8625
- async _disconnectTransport() {
8684
+ async _disconnectTransport(force = false) {
8685
+ if (force) {
8686
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8687
+ this.userAgent.transport.disconnectResolve = () => {};
8688
+ // eslint-disable-next-line
8689
+ this.userAgent.transport._ws.close(1000);
8690
+ return;
8691
+ }
8692
+
8626
8693
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8627
8694
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8628
8695
  try {
@@ -9359,6 +9426,7 @@ class WebRTCPhone extends Emitter {
9359
9426
  }
9360
9427
 
9361
9428
  callSession.answerTime = new Date();
9429
+ this._updateCallSession(callSession);
9362
9430
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9363
9431
 
9364
9432
  return callSession;
@@ -9575,6 +9643,7 @@ class WebRTCPhone extends Emitter {
9575
9643
 
9576
9644
  this.shouldSendReinvite = false;
9577
9645
  callSession.answerTime = new Date();
9646
+ this._updateCallSession(callSession);
9578
9647
  this.acceptedSessions[callSession.getId()] = true;
9579
9648
 
9580
9649
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9674,7 +9743,7 @@ class WebRTCPhone extends Emitter {
9674
9743
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9675
9744
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9676
9745
  logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9677
- this.holdSipSession(this.currentSipSession, callSession);
9746
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9678
9747
  }
9679
9748
 
9680
9749
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9885,6 +9954,7 @@ class WebRTCPhone extends Emitter {
9885
9954
  }
9886
9955
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9887
9956
  callSession.creationTime = new Date();
9957
+ this._updateCallSession(callSession);
9888
9958
 
9889
9959
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9890
9960
 
@@ -10026,7 +10096,7 @@ class WebRTCPhone extends Emitter {
10026
10096
  return this.client && this.client.isConference(callSession.sipCallId);
10027
10097
  }
10028
10098
 
10029
- async close() {
10099
+ async close(force = false) {
10030
10100
  logger$7.info('WebRTC close');
10031
10101
 
10032
10102
  try {
@@ -10038,7 +10108,7 @@ class WebRTCPhone extends Emitter {
10038
10108
  logger$7.error('WebRTC close, unregister error', e);
10039
10109
  }
10040
10110
 
10041
- this.client.close();
10111
+ this.client.close(force);
10042
10112
  this.unbind();
10043
10113
 
10044
10114
  this.incomingSessions = [];
@@ -10164,6 +10234,8 @@ class WebRTCPhone extends Emitter {
10164
10234
  }
10165
10235
 
10166
10236
  callSession.creationTime = new Date();
10237
+ this._updateCallSession(callSession);
10238
+
10167
10239
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10168
10240
  });
10169
10241
 
@@ -10207,6 +10279,8 @@ class WebRTCPhone extends Emitter {
10207
10279
  logger$7.info('WebRTC call rejected', session.id);
10208
10280
  const callSession = this._createCallSession(session);
10209
10281
  callSession.endTime = new Date();
10282
+ this._updateCallSession(callSession);
10283
+
10210
10284
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10211
10285
  });
10212
10286
 
@@ -10431,6 +10505,7 @@ class WebRTCPhone extends Emitter {
10431
10505
  displayName: identity ? identity.displayName || number : number,
10432
10506
  startTime: fromSession ? fromSession.startTime : new Date(),
10433
10507
  creationTime: fromSession ? fromSession.creationTime : null,
10508
+ answerTime: fromSession ? fromSession.answerTime : null,
10434
10509
  endTime: fromSession ? fromSession.endTime : null,
10435
10510
  answered: state === sessionState.SessionState.Established,
10436
10511
  paused: this.client.isCallHeld(sipSession),