@wazo/sdk 0.37.30 → 0.37.34
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.
- package/dist/wazo-sdk.js +4 -4
- package/esm/__tests__/api-client.test.js +30 -0
- package/esm/__tests__/web-rtc-client.test.js +57 -6
- package/esm/api/calld.js +30 -0
- package/esm/api-client.js +30 -0
- package/esm/checker/Checker.js +57 -6
- package/esm/checker/checks/aor.js +30 -0
- package/esm/checker/checks/api.js +30 -0
- package/esm/checker/checks/index.js +57 -6
- package/esm/checker/checks/webrtc-transport.js +57 -6
- package/esm/checker/checks/webrtc.js +57 -6
- package/esm/domain/AdHocAPIConference.js +30 -0
- package/esm/domain/CallSession.js +9 -1
- package/esm/domain/Features.js +30 -0
- package/esm/domain/MeetingStatus.js +29 -0
- package/esm/domain/Phone/CTIPhone.js +39 -1
- package/esm/domain/Phone/WebRTCPhone.js +43 -8
- package/esm/domain/__tests__/CallSession.test.js +41 -5
- package/esm/domain/__tests__/IndirectTransfer.test.js +9 -1
- package/esm/domain/__tests__/Room.test.js +9 -1
- package/esm/index.js +100 -14
- package/esm/service/CallApi.js +30 -0
- package/esm/service/getApiClient.js +30 -0
- package/esm/simple/Auth.js +100 -14
- package/esm/simple/Configuration.js +100 -14
- package/esm/simple/Directory.js +30 -0
- package/esm/simple/Phone.js +100 -14
- package/esm/simple/index.js +100 -14
- package/esm/simple/room/LocalParticipant.js +100 -14
- package/esm/simple/room/Participant.js +100 -14
- package/esm/simple/room/RemoteParticipant.js +100 -14
- package/esm/simple/room/Room.js +100 -14
- package/esm/simple/room/SipRoom.js +100 -14
- package/esm/simple/room/Stream.js +100 -14
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +100 -14
- package/esm/simple/utils.js +100 -14
- package/esm/web-rtc-client.js +57 -6
- package/lib/__tests__/api-client.test.js +30 -0
- package/lib/__tests__/web-rtc-client.test.js +57 -6
- package/lib/api/calld.js +30 -0
- package/lib/api-client.js +30 -0
- package/lib/checker/Checker.js +57 -6
- package/lib/checker/checks/aor.js +30 -0
- package/lib/checker/checks/api.js +30 -0
- package/lib/checker/checks/index.js +57 -6
- package/lib/checker/checks/webrtc-transport.js +57 -6
- package/lib/checker/checks/webrtc.js +57 -6
- package/lib/domain/AdHocAPIConference.js +30 -0
- package/lib/domain/CallSession.js +9 -1
- package/lib/domain/Features.js +30 -0
- package/lib/domain/MeetingStatus.js +31 -0
- package/lib/domain/Phone/CTIPhone.js +39 -1
- package/lib/domain/Phone/WebRTCPhone.js +43 -8
- package/lib/domain/__tests__/CallSession.test.js +41 -5
- package/lib/domain/__tests__/IndirectTransfer.test.js +9 -1
- package/lib/domain/__tests__/Room.test.js +9 -1
- package/lib/index.js +100 -14
- package/lib/service/CallApi.js +30 -0
- package/lib/service/getApiClient.js +30 -0
- package/lib/simple/Auth.js +100 -14
- package/lib/simple/Configuration.js +100 -14
- package/lib/simple/Directory.js +30 -0
- package/lib/simple/Phone.js +100 -14
- package/lib/simple/index.js +100 -14
- package/lib/simple/room/LocalParticipant.js +100 -14
- package/lib/simple/room/Participant.js +100 -14
- package/lib/simple/room/RemoteParticipant.js +100 -14
- package/lib/simple/room/Room.js +100 -14
- package/lib/simple/room/SipRoom.js +100 -14
- package/lib/simple/room/Stream.js +100 -14
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +100 -14
- package/lib/simple/utils.js +100 -14
- package/lib/web-rtc-client.js +57 -6
- package/package.json +1 -1
- package/src/api/calld.js +3 -0
- package/src/domain/CallSession.js +9 -1
- package/src/domain/MeetingStatus.js +27 -0
- package/src/domain/Phone/WebRTCPhone.js +34 -7
- package/src/domain/__tests__/CallSession.test.js +32 -4
- package/src/web-rtc-client.js +27 -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
|
//
|
|
@@ -6635,7 +6673,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6635
6673
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6636
6674
|
class CanceledCallError extends Error {}
|
|
6637
6675
|
|
|
6638
|
-
const MAX_REGISTER_TRIES =
|
|
6676
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6639
6677
|
|
|
6640
6678
|
|
|
6641
6679
|
|
|
@@ -6689,6 +6727,7 @@ class WebRTCClient extends Emitter {
|
|
|
6689
6727
|
|
|
6690
6728
|
|
|
6691
6729
|
|
|
6730
|
+
|
|
6692
6731
|
|
|
6693
6732
|
// sugar
|
|
6694
6733
|
|
|
@@ -6751,6 +6790,7 @@ class WebRTCClient extends Emitter {
|
|
|
6751
6790
|
this.conferences = {};
|
|
6752
6791
|
this.networkMonitoringInterval = {};
|
|
6753
6792
|
this.sessionNetworkStats = {};
|
|
6793
|
+
this.forceClosed = false;
|
|
6754
6794
|
|
|
6755
6795
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6756
6796
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6872,6 +6912,8 @@ class WebRTCClient extends Emitter {
|
|
|
6872
6912
|
skipRegister: this.skipRegister,
|
|
6873
6913
|
};
|
|
6874
6914
|
|
|
6915
|
+
this.forceClosed = false;
|
|
6916
|
+
|
|
6875
6917
|
if (this.skipRegister) {
|
|
6876
6918
|
logger$8.info('sdk webrtc skip register...', logInfo);
|
|
6877
6919
|
return Promise.resolve();
|
|
@@ -6896,7 +6938,15 @@ class WebRTCClient extends Emitter {
|
|
|
6896
6938
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6897
6939
|
|
|
6898
6940
|
const onRegisterFailed = () => {
|
|
6899
|
-
logger$8.info('sdk webrtc registering failed', {
|
|
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
|
+
|
|
6900
6950
|
this.connectionPromise = null;
|
|
6901
6951
|
if (this.registerer && this.registerer.waiting) {
|
|
6902
6952
|
this.registerer.waitingToggle(false);
|
|
@@ -7174,8 +7224,9 @@ class WebRTCClient extends Emitter {
|
|
|
7174
7224
|
}
|
|
7175
7225
|
}
|
|
7176
7226
|
|
|
7177
|
-
async close() {
|
|
7178
|
-
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;
|
|
7179
7230
|
this._cleanupMedia();
|
|
7180
7231
|
this.connectionPromise = null;
|
|
7181
7232
|
|
|
@@ -7194,7 +7245,7 @@ class WebRTCClient extends Emitter {
|
|
|
7194
7245
|
this.userAgent.delegate = null;
|
|
7195
7246
|
this.userAgent.stateChange.removeAllListeners();
|
|
7196
7247
|
|
|
7197
|
-
await this._disconnectTransport();
|
|
7248
|
+
await this._disconnectTransport(force);
|
|
7198
7249
|
|
|
7199
7250
|
this._cleanupRegister();
|
|
7200
7251
|
|
|
@@ -8630,7 +8681,15 @@ class WebRTCClient extends Emitter {
|
|
|
8630
8681
|
return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8631
8682
|
}
|
|
8632
8683
|
|
|
8633
|
-
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
|
+
|
|
8634
8693
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8635
8694
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8636
8695
|
try {
|
|
@@ -9367,6 +9426,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9367
9426
|
}
|
|
9368
9427
|
|
|
9369
9428
|
callSession.answerTime = new Date();
|
|
9429
|
+
this._updateCallSession(callSession);
|
|
9370
9430
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
9371
9431
|
|
|
9372
9432
|
return callSession;
|
|
@@ -9576,6 +9636,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9576
9636
|
return Promise.resolve(null);
|
|
9577
9637
|
}
|
|
9578
9638
|
|
|
9639
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9640
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9641
|
+
logger$7.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9642
|
+
return Promise.resolve(null);
|
|
9643
|
+
}
|
|
9644
|
+
|
|
9579
9645
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9580
9646
|
logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9581
9647
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -9583,6 +9649,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9583
9649
|
|
|
9584
9650
|
this.shouldSendReinvite = false;
|
|
9585
9651
|
callSession.answerTime = new Date();
|
|
9652
|
+
this._updateCallSession(callSession);
|
|
9586
9653
|
this.acceptedSessions[callSession.getId()] = true;
|
|
9587
9654
|
|
|
9588
9655
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -9682,7 +9749,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9682
9749
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
9683
9750
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
9684
9751
|
logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
9685
|
-
this.holdSipSession(this.currentSipSession,
|
|
9752
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
9686
9753
|
}
|
|
9687
9754
|
|
|
9688
9755
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -9893,6 +9960,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9893
9960
|
}
|
|
9894
9961
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
9895
9962
|
callSession.creationTime = new Date();
|
|
9963
|
+
this._updateCallSession(callSession);
|
|
9896
9964
|
|
|
9897
9965
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
9898
9966
|
|
|
@@ -10034,7 +10102,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10034
10102
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
10035
10103
|
}
|
|
10036
10104
|
|
|
10037
|
-
async close() {
|
|
10105
|
+
async close(force = false) {
|
|
10038
10106
|
logger$7.info('WebRTC close');
|
|
10039
10107
|
|
|
10040
10108
|
try {
|
|
@@ -10046,7 +10114,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10046
10114
|
logger$7.error('WebRTC close, unregister error', e);
|
|
10047
10115
|
}
|
|
10048
10116
|
|
|
10049
|
-
this.client.close();
|
|
10117
|
+
this.client.close(force);
|
|
10050
10118
|
this.unbind();
|
|
10051
10119
|
|
|
10052
10120
|
this.incomingSessions = [];
|
|
@@ -10172,6 +10240,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10172
10240
|
}
|
|
10173
10241
|
|
|
10174
10242
|
callSession.creationTime = new Date();
|
|
10243
|
+
this._updateCallSession(callSession);
|
|
10244
|
+
|
|
10175
10245
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
10176
10246
|
});
|
|
10177
10247
|
|
|
@@ -10196,9 +10266,17 @@ class WebRTCPhone extends Emitter {
|
|
|
10196
10266
|
});
|
|
10197
10267
|
|
|
10198
10268
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
10199
|
-
|
|
10269
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10270
|
+
const hasSession = sessionId in this.callSessions;
|
|
10200
10271
|
|
|
10201
|
-
|
|
10272
|
+
logger$7.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10273
|
+
|
|
10274
|
+
if (!hasSession) {
|
|
10275
|
+
logger$7.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10276
|
+
return;
|
|
10277
|
+
}
|
|
10278
|
+
|
|
10279
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
10202
10280
|
|
|
10203
10281
|
if (this.audioOutputDeviceId) {
|
|
10204
10282
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -10215,6 +10293,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10215
10293
|
logger$7.info('WebRTC call rejected', session.id);
|
|
10216
10294
|
const callSession = this._createCallSession(session);
|
|
10217
10295
|
callSession.endTime = new Date();
|
|
10296
|
+
this._updateCallSession(callSession);
|
|
10297
|
+
|
|
10218
10298
|
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
10219
10299
|
});
|
|
10220
10300
|
|
|
@@ -10332,9 +10412,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10332
10412
|
return this.client.getSipSessionId(sipSession);
|
|
10333
10413
|
}
|
|
10334
10414
|
|
|
10335
|
-
|
|
10415
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10336
10416
|
const sipSession = this.findSipSession(callSession);
|
|
10337
|
-
|
|
10417
|
+
|
|
10418
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10419
|
+
}
|
|
10420
|
+
|
|
10421
|
+
_updateCallSession(callSession ) {
|
|
10422
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10338
10423
|
|
|
10339
10424
|
if (sipSessionId) {
|
|
10340
10425
|
this.callSessions[sipSessionId] = callSession;
|
|
@@ -10439,6 +10524,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10439
10524
|
displayName: identity ? identity.displayName || number : number,
|
|
10440
10525
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
10441
10526
|
creationTime: fromSession ? fromSession.creationTime : null,
|
|
10527
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
10442
10528
|
endTime: fromSession ? fromSession.endTime : null,
|
|
10443
10529
|
answered: state === sessionState.SessionState.Established,
|
|
10444
10530
|
paused: this.client.isCallHeld(sipSession),
|
package/lib/simple/room/Room.js
CHANGED
|
@@ -3596,13 +3596,21 @@ class CallSession {
|
|
|
3596
3596
|
|
|
3597
3597
|
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
3598
3598
|
set answered(value ) {
|
|
3599
|
-
this.answerTime = value ? new Date() : null;
|
|
3599
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
3600
3600
|
}
|
|
3601
3601
|
|
|
3602
3602
|
get answered() {
|
|
3603
3603
|
return !!this.answerTime;
|
|
3604
3604
|
}
|
|
3605
3605
|
|
|
3606
|
+
toJSON() {
|
|
3607
|
+
const jsonObj = { ...this };
|
|
3608
|
+
// $FlowFixMe
|
|
3609
|
+
jsonObj.answered = this.answered;
|
|
3610
|
+
|
|
3611
|
+
return jsonObj;
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3606
3614
|
static parseCall(call ) {
|
|
3607
3615
|
return new CallSession({
|
|
3608
3616
|
callId: call.id,
|
|
@@ -4854,6 +4862,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4854
4862
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4855
4863
|
});
|
|
4856
4864
|
|
|
4865
|
+
//
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
|
|
4869
|
+
|
|
4870
|
+
|
|
4871
|
+
class MeetingStatus {
|
|
4872
|
+
|
|
4873
|
+
|
|
4874
|
+
|
|
4875
|
+
|
|
4876
|
+
constructor({
|
|
4877
|
+
full,
|
|
4878
|
+
} = {}) {
|
|
4879
|
+
this.full = full;
|
|
4880
|
+
|
|
4881
|
+
// Useful to compare instead of instanceof with minified code
|
|
4882
|
+
this.type = 'MeetingStatus';
|
|
4883
|
+
}
|
|
4884
|
+
|
|
4885
|
+
static parse(plain ) {
|
|
4886
|
+
return new MeetingStatus({
|
|
4887
|
+
full: plain.full,
|
|
4888
|
+
});
|
|
4889
|
+
}
|
|
4890
|
+
|
|
4891
|
+
}
|
|
4892
|
+
|
|
4857
4893
|
/* */
|
|
4858
4894
|
|
|
4859
4895
|
|
|
@@ -5048,6 +5084,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5048
5084
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
5049
5085
|
ApiRequester.successResponseParser),
|
|
5050
5086
|
|
|
5087
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
5088
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
5051
5089
|
});
|
|
5052
5090
|
|
|
5053
5091
|
//
|
|
@@ -6637,7 +6675,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6637
6675
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6638
6676
|
class CanceledCallError extends Error {}
|
|
6639
6677
|
|
|
6640
|
-
const MAX_REGISTER_TRIES =
|
|
6678
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6641
6679
|
|
|
6642
6680
|
|
|
6643
6681
|
|
|
@@ -6691,6 +6729,7 @@ class WebRTCClient extends Emitter {
|
|
|
6691
6729
|
|
|
6692
6730
|
|
|
6693
6731
|
|
|
6732
|
+
|
|
6694
6733
|
|
|
6695
6734
|
// sugar
|
|
6696
6735
|
|
|
@@ -6753,6 +6792,7 @@ class WebRTCClient extends Emitter {
|
|
|
6753
6792
|
this.conferences = {};
|
|
6754
6793
|
this.networkMonitoringInterval = {};
|
|
6755
6794
|
this.sessionNetworkStats = {};
|
|
6795
|
+
this.forceClosed = false;
|
|
6756
6796
|
|
|
6757
6797
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6758
6798
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6874,6 +6914,8 @@ class WebRTCClient extends Emitter {
|
|
|
6874
6914
|
skipRegister: this.skipRegister,
|
|
6875
6915
|
};
|
|
6876
6916
|
|
|
6917
|
+
this.forceClosed = false;
|
|
6918
|
+
|
|
6877
6919
|
if (this.skipRegister) {
|
|
6878
6920
|
logger$8.info('sdk webrtc skip register...', logInfo);
|
|
6879
6921
|
return Promise.resolve();
|
|
@@ -6898,7 +6940,15 @@ class WebRTCClient extends Emitter {
|
|
|
6898
6940
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6899
6941
|
|
|
6900
6942
|
const onRegisterFailed = () => {
|
|
6901
|
-
logger$8.info('sdk webrtc registering failed', {
|
|
6943
|
+
logger$8.info('sdk webrtc registering failed', {
|
|
6944
|
+
tries,
|
|
6945
|
+
registerer: !!this.registerer,
|
|
6946
|
+
forceClosed: this.forceClosed,
|
|
6947
|
+
});
|
|
6948
|
+
if (this.forceClosed) {
|
|
6949
|
+
return;
|
|
6950
|
+
}
|
|
6951
|
+
|
|
6902
6952
|
this.connectionPromise = null;
|
|
6903
6953
|
if (this.registerer && this.registerer.waiting) {
|
|
6904
6954
|
this.registerer.waitingToggle(false);
|
|
@@ -7176,8 +7226,9 @@ class WebRTCClient extends Emitter {
|
|
|
7176
7226
|
}
|
|
7177
7227
|
}
|
|
7178
7228
|
|
|
7179
|
-
async close() {
|
|
7180
|
-
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
7229
|
+
async close(force = false) {
|
|
7230
|
+
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
7231
|
+
this.forceClosed = force;
|
|
7181
7232
|
this._cleanupMedia();
|
|
7182
7233
|
this.connectionPromise = null;
|
|
7183
7234
|
|
|
@@ -7196,7 +7247,7 @@ class WebRTCClient extends Emitter {
|
|
|
7196
7247
|
this.userAgent.delegate = null;
|
|
7197
7248
|
this.userAgent.stateChange.removeAllListeners();
|
|
7198
7249
|
|
|
7199
|
-
await this._disconnectTransport();
|
|
7250
|
+
await this._disconnectTransport(force);
|
|
7200
7251
|
|
|
7201
7252
|
this._cleanupRegister();
|
|
7202
7253
|
|
|
@@ -8632,7 +8683,15 @@ class WebRTCClient extends Emitter {
|
|
|
8632
8683
|
return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8633
8684
|
}
|
|
8634
8685
|
|
|
8635
|
-
async _disconnectTransport() {
|
|
8686
|
+
async _disconnectTransport(force = false) {
|
|
8687
|
+
if (force) {
|
|
8688
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
8689
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
8690
|
+
// eslint-disable-next-line
|
|
8691
|
+
this.userAgent.transport._ws.close(1000);
|
|
8692
|
+
return;
|
|
8693
|
+
}
|
|
8694
|
+
|
|
8636
8695
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8637
8696
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8638
8697
|
try {
|
|
@@ -9369,6 +9428,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9369
9428
|
}
|
|
9370
9429
|
|
|
9371
9430
|
callSession.answerTime = new Date();
|
|
9431
|
+
this._updateCallSession(callSession);
|
|
9372
9432
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
9373
9433
|
|
|
9374
9434
|
return callSession;
|
|
@@ -9578,6 +9638,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9578
9638
|
return Promise.resolve(null);
|
|
9579
9639
|
}
|
|
9580
9640
|
|
|
9641
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9642
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9643
|
+
logger$7.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9644
|
+
return Promise.resolve(null);
|
|
9645
|
+
}
|
|
9646
|
+
|
|
9581
9647
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9582
9648
|
logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9583
9649
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -9585,6 +9651,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9585
9651
|
|
|
9586
9652
|
this.shouldSendReinvite = false;
|
|
9587
9653
|
callSession.answerTime = new Date();
|
|
9654
|
+
this._updateCallSession(callSession);
|
|
9588
9655
|
this.acceptedSessions[callSession.getId()] = true;
|
|
9589
9656
|
|
|
9590
9657
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -9684,7 +9751,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9684
9751
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
9685
9752
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
9686
9753
|
logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
9687
|
-
this.holdSipSession(this.currentSipSession,
|
|
9754
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
9688
9755
|
}
|
|
9689
9756
|
|
|
9690
9757
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -9895,6 +9962,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9895
9962
|
}
|
|
9896
9963
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
9897
9964
|
callSession.creationTime = new Date();
|
|
9965
|
+
this._updateCallSession(callSession);
|
|
9898
9966
|
|
|
9899
9967
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
9900
9968
|
|
|
@@ -10036,7 +10104,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10036
10104
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
10037
10105
|
}
|
|
10038
10106
|
|
|
10039
|
-
async close() {
|
|
10107
|
+
async close(force = false) {
|
|
10040
10108
|
logger$7.info('WebRTC close');
|
|
10041
10109
|
|
|
10042
10110
|
try {
|
|
@@ -10048,7 +10116,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10048
10116
|
logger$7.error('WebRTC close, unregister error', e);
|
|
10049
10117
|
}
|
|
10050
10118
|
|
|
10051
|
-
this.client.close();
|
|
10119
|
+
this.client.close(force);
|
|
10052
10120
|
this.unbind();
|
|
10053
10121
|
|
|
10054
10122
|
this.incomingSessions = [];
|
|
@@ -10174,6 +10242,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10174
10242
|
}
|
|
10175
10243
|
|
|
10176
10244
|
callSession.creationTime = new Date();
|
|
10245
|
+
this._updateCallSession(callSession);
|
|
10246
|
+
|
|
10177
10247
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
10178
10248
|
});
|
|
10179
10249
|
|
|
@@ -10198,9 +10268,17 @@ class WebRTCPhone extends Emitter {
|
|
|
10198
10268
|
});
|
|
10199
10269
|
|
|
10200
10270
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
10201
|
-
|
|
10271
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10272
|
+
const hasSession = sessionId in this.callSessions;
|
|
10202
10273
|
|
|
10203
|
-
|
|
10274
|
+
logger$7.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10275
|
+
|
|
10276
|
+
if (!hasSession) {
|
|
10277
|
+
logger$7.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10278
|
+
return;
|
|
10279
|
+
}
|
|
10280
|
+
|
|
10281
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
10204
10282
|
|
|
10205
10283
|
if (this.audioOutputDeviceId) {
|
|
10206
10284
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -10217,6 +10295,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10217
10295
|
logger$7.info('WebRTC call rejected', session.id);
|
|
10218
10296
|
const callSession = this._createCallSession(session);
|
|
10219
10297
|
callSession.endTime = new Date();
|
|
10298
|
+
this._updateCallSession(callSession);
|
|
10299
|
+
|
|
10220
10300
|
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
10221
10301
|
});
|
|
10222
10302
|
|
|
@@ -10334,9 +10414,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10334
10414
|
return this.client.getSipSessionId(sipSession);
|
|
10335
10415
|
}
|
|
10336
10416
|
|
|
10337
|
-
|
|
10417
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10338
10418
|
const sipSession = this.findSipSession(callSession);
|
|
10339
|
-
|
|
10419
|
+
|
|
10420
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10421
|
+
}
|
|
10422
|
+
|
|
10423
|
+
_updateCallSession(callSession ) {
|
|
10424
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10340
10425
|
|
|
10341
10426
|
if (sipSessionId) {
|
|
10342
10427
|
this.callSessions[sipSessionId] = callSession;
|
|
@@ -10441,6 +10526,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10441
10526
|
displayName: identity ? identity.displayName || number : number,
|
|
10442
10527
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
10443
10528
|
creationTime: fromSession ? fromSession.creationTime : null,
|
|
10529
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
10444
10530
|
endTime: fromSession ? fromSession.endTime : null,
|
|
10445
10531
|
answered: state === sessionState.SessionState.Established,
|
|
10446
10532
|
paused: this.client.isCallHeld(sipSession),
|