@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
|
@@ -3610,13 +3610,21 @@ class CallSession {
|
|
|
3610
3610
|
|
|
3611
3611
|
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
3612
3612
|
set answered(value ) {
|
|
3613
|
-
this.answerTime = value ? new Date() : null;
|
|
3613
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
3614
3614
|
}
|
|
3615
3615
|
|
|
3616
3616
|
get answered() {
|
|
3617
3617
|
return !!this.answerTime;
|
|
3618
3618
|
}
|
|
3619
3619
|
|
|
3620
|
+
toJSON() {
|
|
3621
|
+
const jsonObj = { ...this };
|
|
3622
|
+
// $FlowFixMe
|
|
3623
|
+
jsonObj.answered = this.answered;
|
|
3624
|
+
|
|
3625
|
+
return jsonObj;
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3620
3628
|
static parseCall(call ) {
|
|
3621
3629
|
return new CallSession({
|
|
3622
3630
|
callId: call.id,
|
|
@@ -4842,6 +4850,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4842
4850
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4843
4851
|
});
|
|
4844
4852
|
|
|
4853
|
+
//
|
|
4854
|
+
|
|
4855
|
+
|
|
4856
|
+
|
|
4857
|
+
|
|
4858
|
+
|
|
4859
|
+
class MeetingStatus {
|
|
4860
|
+
|
|
4861
|
+
|
|
4862
|
+
|
|
4863
|
+
|
|
4864
|
+
constructor({
|
|
4865
|
+
full,
|
|
4866
|
+
} = {}) {
|
|
4867
|
+
this.full = full;
|
|
4868
|
+
|
|
4869
|
+
// Useful to compare instead of instanceof with minified code
|
|
4870
|
+
this.type = 'MeetingStatus';
|
|
4871
|
+
}
|
|
4872
|
+
|
|
4873
|
+
static parse(plain ) {
|
|
4874
|
+
return new MeetingStatus({
|
|
4875
|
+
full: plain.full,
|
|
4876
|
+
});
|
|
4877
|
+
}
|
|
4878
|
+
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4845
4881
|
/* */
|
|
4846
4882
|
|
|
4847
4883
|
|
|
@@ -5036,6 +5072,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5036
5072
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
5037
5073
|
ApiRequester.successResponseParser),
|
|
5038
5074
|
|
|
5075
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
5076
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
5039
5077
|
});
|
|
5040
5078
|
|
|
5041
5079
|
//
|
|
@@ -6625,7 +6663,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6625
6663
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6626
6664
|
class CanceledCallError extends Error {}
|
|
6627
6665
|
|
|
6628
|
-
const MAX_REGISTER_TRIES =
|
|
6666
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6629
6667
|
|
|
6630
6668
|
|
|
6631
6669
|
|
|
@@ -6679,6 +6717,7 @@ class WebRTCClient extends Emitter {
|
|
|
6679
6717
|
|
|
6680
6718
|
|
|
6681
6719
|
|
|
6720
|
+
|
|
6682
6721
|
|
|
6683
6722
|
// sugar
|
|
6684
6723
|
|
|
@@ -6741,6 +6780,7 @@ class WebRTCClient extends Emitter {
|
|
|
6741
6780
|
this.conferences = {};
|
|
6742
6781
|
this.networkMonitoringInterval = {};
|
|
6743
6782
|
this.sessionNetworkStats = {};
|
|
6783
|
+
this.forceClosed = false;
|
|
6744
6784
|
|
|
6745
6785
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6746
6786
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6862,6 +6902,8 @@ class WebRTCClient extends Emitter {
|
|
|
6862
6902
|
skipRegister: this.skipRegister,
|
|
6863
6903
|
};
|
|
6864
6904
|
|
|
6905
|
+
this.forceClosed = false;
|
|
6906
|
+
|
|
6865
6907
|
if (this.skipRegister) {
|
|
6866
6908
|
logger$8.info('sdk webrtc skip register...', logInfo);
|
|
6867
6909
|
return Promise.resolve();
|
|
@@ -6886,7 +6928,15 @@ class WebRTCClient extends Emitter {
|
|
|
6886
6928
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6887
6929
|
|
|
6888
6930
|
const onRegisterFailed = () => {
|
|
6889
|
-
logger$8.info('sdk webrtc registering failed', {
|
|
6931
|
+
logger$8.info('sdk webrtc registering failed', {
|
|
6932
|
+
tries,
|
|
6933
|
+
registerer: !!this.registerer,
|
|
6934
|
+
forceClosed: this.forceClosed,
|
|
6935
|
+
});
|
|
6936
|
+
if (this.forceClosed) {
|
|
6937
|
+
return;
|
|
6938
|
+
}
|
|
6939
|
+
|
|
6890
6940
|
this.connectionPromise = null;
|
|
6891
6941
|
if (this.registerer && this.registerer.waiting) {
|
|
6892
6942
|
this.registerer.waitingToggle(false);
|
|
@@ -7164,8 +7214,9 @@ class WebRTCClient extends Emitter {
|
|
|
7164
7214
|
}
|
|
7165
7215
|
}
|
|
7166
7216
|
|
|
7167
|
-
async close() {
|
|
7168
|
-
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
7217
|
+
async close(force = false) {
|
|
7218
|
+
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
7219
|
+
this.forceClosed = force;
|
|
7169
7220
|
this._cleanupMedia();
|
|
7170
7221
|
this.connectionPromise = null;
|
|
7171
7222
|
|
|
@@ -7184,7 +7235,7 @@ class WebRTCClient extends Emitter {
|
|
|
7184
7235
|
this.userAgent.delegate = null;
|
|
7185
7236
|
this.userAgent.stateChange.removeAllListeners();
|
|
7186
7237
|
|
|
7187
|
-
await this._disconnectTransport();
|
|
7238
|
+
await this._disconnectTransport(force);
|
|
7188
7239
|
|
|
7189
7240
|
this._cleanupRegister();
|
|
7190
7241
|
|
|
@@ -8620,7 +8671,15 @@ class WebRTCClient extends Emitter {
|
|
|
8620
8671
|
return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8621
8672
|
}
|
|
8622
8673
|
|
|
8623
|
-
async _disconnectTransport() {
|
|
8674
|
+
async _disconnectTransport(force = false) {
|
|
8675
|
+
if (force) {
|
|
8676
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
8677
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
8678
|
+
// eslint-disable-next-line
|
|
8679
|
+
this.userAgent.transport._ws.close(1000);
|
|
8680
|
+
return;
|
|
8681
|
+
}
|
|
8682
|
+
|
|
8624
8683
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8625
8684
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8626
8685
|
try {
|
|
@@ -9357,6 +9416,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9357
9416
|
}
|
|
9358
9417
|
|
|
9359
9418
|
callSession.answerTime = new Date();
|
|
9419
|
+
this._updateCallSession(callSession);
|
|
9360
9420
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
9361
9421
|
|
|
9362
9422
|
return callSession;
|
|
@@ -9566,6 +9626,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9566
9626
|
return Promise.resolve(null);
|
|
9567
9627
|
}
|
|
9568
9628
|
|
|
9629
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9630
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9631
|
+
logger$7.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9632
|
+
return Promise.resolve(null);
|
|
9633
|
+
}
|
|
9634
|
+
|
|
9569
9635
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9570
9636
|
logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9571
9637
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -9573,6 +9639,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9573
9639
|
|
|
9574
9640
|
this.shouldSendReinvite = false;
|
|
9575
9641
|
callSession.answerTime = new Date();
|
|
9642
|
+
this._updateCallSession(callSession);
|
|
9576
9643
|
this.acceptedSessions[callSession.getId()] = true;
|
|
9577
9644
|
|
|
9578
9645
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -9672,7 +9739,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9672
9739
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
9673
9740
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
9674
9741
|
logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
9675
|
-
this.holdSipSession(this.currentSipSession,
|
|
9742
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
9676
9743
|
}
|
|
9677
9744
|
|
|
9678
9745
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -9883,6 +9950,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9883
9950
|
}
|
|
9884
9951
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
9885
9952
|
callSession.creationTime = new Date();
|
|
9953
|
+
this._updateCallSession(callSession);
|
|
9886
9954
|
|
|
9887
9955
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
9888
9956
|
|
|
@@ -10024,7 +10092,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10024
10092
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
10025
10093
|
}
|
|
10026
10094
|
|
|
10027
|
-
async close() {
|
|
10095
|
+
async close(force = false) {
|
|
10028
10096
|
logger$7.info('WebRTC close');
|
|
10029
10097
|
|
|
10030
10098
|
try {
|
|
@@ -10036,7 +10104,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10036
10104
|
logger$7.error('WebRTC close, unregister error', e);
|
|
10037
10105
|
}
|
|
10038
10106
|
|
|
10039
|
-
this.client.close();
|
|
10107
|
+
this.client.close(force);
|
|
10040
10108
|
this.unbind();
|
|
10041
10109
|
|
|
10042
10110
|
this.incomingSessions = [];
|
|
@@ -10162,6 +10230,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10162
10230
|
}
|
|
10163
10231
|
|
|
10164
10232
|
callSession.creationTime = new Date();
|
|
10233
|
+
this._updateCallSession(callSession);
|
|
10234
|
+
|
|
10165
10235
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
10166
10236
|
});
|
|
10167
10237
|
|
|
@@ -10186,9 +10256,17 @@ class WebRTCPhone extends Emitter {
|
|
|
10186
10256
|
});
|
|
10187
10257
|
|
|
10188
10258
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
10189
|
-
|
|
10259
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10260
|
+
const hasSession = sessionId in this.callSessions;
|
|
10190
10261
|
|
|
10191
|
-
|
|
10262
|
+
logger$7.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10263
|
+
|
|
10264
|
+
if (!hasSession) {
|
|
10265
|
+
logger$7.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10266
|
+
return;
|
|
10267
|
+
}
|
|
10268
|
+
|
|
10269
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
10192
10270
|
|
|
10193
10271
|
if (this.audioOutputDeviceId) {
|
|
10194
10272
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -10205,6 +10283,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10205
10283
|
logger$7.info('WebRTC call rejected', session.id);
|
|
10206
10284
|
const callSession = this._createCallSession(session);
|
|
10207
10285
|
callSession.endTime = new Date();
|
|
10286
|
+
this._updateCallSession(callSession);
|
|
10287
|
+
|
|
10208
10288
|
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
10209
10289
|
});
|
|
10210
10290
|
|
|
@@ -10322,9 +10402,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10322
10402
|
return this.client.getSipSessionId(sipSession);
|
|
10323
10403
|
}
|
|
10324
10404
|
|
|
10325
|
-
|
|
10405
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10326
10406
|
const sipSession = this.findSipSession(callSession);
|
|
10327
|
-
|
|
10407
|
+
|
|
10408
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10409
|
+
}
|
|
10410
|
+
|
|
10411
|
+
_updateCallSession(callSession ) {
|
|
10412
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10328
10413
|
|
|
10329
10414
|
if (sipSessionId) {
|
|
10330
10415
|
this.callSessions[sipSessionId] = callSession;
|
|
@@ -10429,6 +10514,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10429
10514
|
displayName: identity ? identity.displayName || number : number,
|
|
10430
10515
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
10431
10516
|
creationTime: fromSession ? fromSession.creationTime : null,
|
|
10517
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
10432
10518
|
endTime: fromSession ? fromSession.endTime : null,
|
|
10433
10519
|
answered: state === SessionState.Established,
|
|
10434
10520
|
paused: this.client.isCallHeld(sipSession),
|
|
@@ -3584,13 +3584,21 @@ class CallSession {
|
|
|
3584
3584
|
|
|
3585
3585
|
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
3586
3586
|
set answered(value ) {
|
|
3587
|
-
this.answerTime = value ? new Date() : null;
|
|
3587
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
3588
3588
|
}
|
|
3589
3589
|
|
|
3590
3590
|
get answered() {
|
|
3591
3591
|
return !!this.answerTime;
|
|
3592
3592
|
}
|
|
3593
3593
|
|
|
3594
|
+
toJSON() {
|
|
3595
|
+
const jsonObj = { ...this };
|
|
3596
|
+
// $FlowFixMe
|
|
3597
|
+
jsonObj.answered = this.answered;
|
|
3598
|
+
|
|
3599
|
+
return jsonObj;
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3594
3602
|
static parseCall(call ) {
|
|
3595
3603
|
return new CallSession({
|
|
3596
3604
|
callId: call.id,
|
|
@@ -4842,6 +4850,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4842
4850
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4843
4851
|
});
|
|
4844
4852
|
|
|
4853
|
+
//
|
|
4854
|
+
|
|
4855
|
+
|
|
4856
|
+
|
|
4857
|
+
|
|
4858
|
+
|
|
4859
|
+
class MeetingStatus {
|
|
4860
|
+
|
|
4861
|
+
|
|
4862
|
+
|
|
4863
|
+
|
|
4864
|
+
constructor({
|
|
4865
|
+
full,
|
|
4866
|
+
} = {}) {
|
|
4867
|
+
this.full = full;
|
|
4868
|
+
|
|
4869
|
+
// Useful to compare instead of instanceof with minified code
|
|
4870
|
+
this.type = 'MeetingStatus';
|
|
4871
|
+
}
|
|
4872
|
+
|
|
4873
|
+
static parse(plain ) {
|
|
4874
|
+
return new MeetingStatus({
|
|
4875
|
+
full: plain.full,
|
|
4876
|
+
});
|
|
4877
|
+
}
|
|
4878
|
+
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4845
4881
|
/* */
|
|
4846
4882
|
|
|
4847
4883
|
|
|
@@ -5036,6 +5072,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5036
5072
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
5037
5073
|
ApiRequester.successResponseParser),
|
|
5038
5074
|
|
|
5075
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
5076
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
5039
5077
|
});
|
|
5040
5078
|
|
|
5041
5079
|
//
|
|
@@ -6625,7 +6663,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6625
6663
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6626
6664
|
class CanceledCallError extends Error {}
|
|
6627
6665
|
|
|
6628
|
-
const MAX_REGISTER_TRIES =
|
|
6666
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6629
6667
|
|
|
6630
6668
|
|
|
6631
6669
|
|
|
@@ -6679,6 +6717,7 @@ class WebRTCClient extends Emitter {
|
|
|
6679
6717
|
|
|
6680
6718
|
|
|
6681
6719
|
|
|
6720
|
+
|
|
6682
6721
|
|
|
6683
6722
|
// sugar
|
|
6684
6723
|
|
|
@@ -6741,6 +6780,7 @@ class WebRTCClient extends Emitter {
|
|
|
6741
6780
|
this.conferences = {};
|
|
6742
6781
|
this.networkMonitoringInterval = {};
|
|
6743
6782
|
this.sessionNetworkStats = {};
|
|
6783
|
+
this.forceClosed = false;
|
|
6744
6784
|
|
|
6745
6785
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6746
6786
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6862,6 +6902,8 @@ class WebRTCClient extends Emitter {
|
|
|
6862
6902
|
skipRegister: this.skipRegister,
|
|
6863
6903
|
};
|
|
6864
6904
|
|
|
6905
|
+
this.forceClosed = false;
|
|
6906
|
+
|
|
6865
6907
|
if (this.skipRegister) {
|
|
6866
6908
|
logger$8.info('sdk webrtc skip register...', logInfo);
|
|
6867
6909
|
return Promise.resolve();
|
|
@@ -6886,7 +6928,15 @@ class WebRTCClient extends Emitter {
|
|
|
6886
6928
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6887
6929
|
|
|
6888
6930
|
const onRegisterFailed = () => {
|
|
6889
|
-
logger$8.info('sdk webrtc registering failed', {
|
|
6931
|
+
logger$8.info('sdk webrtc registering failed', {
|
|
6932
|
+
tries,
|
|
6933
|
+
registerer: !!this.registerer,
|
|
6934
|
+
forceClosed: this.forceClosed,
|
|
6935
|
+
});
|
|
6936
|
+
if (this.forceClosed) {
|
|
6937
|
+
return;
|
|
6938
|
+
}
|
|
6939
|
+
|
|
6890
6940
|
this.connectionPromise = null;
|
|
6891
6941
|
if (this.registerer && this.registerer.waiting) {
|
|
6892
6942
|
this.registerer.waitingToggle(false);
|
|
@@ -7164,8 +7214,9 @@ class WebRTCClient extends Emitter {
|
|
|
7164
7214
|
}
|
|
7165
7215
|
}
|
|
7166
7216
|
|
|
7167
|
-
async close() {
|
|
7168
|
-
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
7217
|
+
async close(force = false) {
|
|
7218
|
+
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
7219
|
+
this.forceClosed = force;
|
|
7169
7220
|
this._cleanupMedia();
|
|
7170
7221
|
this.connectionPromise = null;
|
|
7171
7222
|
|
|
@@ -7184,7 +7235,7 @@ class WebRTCClient extends Emitter {
|
|
|
7184
7235
|
this.userAgent.delegate = null;
|
|
7185
7236
|
this.userAgent.stateChange.removeAllListeners();
|
|
7186
7237
|
|
|
7187
|
-
await this._disconnectTransport();
|
|
7238
|
+
await this._disconnectTransport(force);
|
|
7188
7239
|
|
|
7189
7240
|
this._cleanupRegister();
|
|
7190
7241
|
|
|
@@ -8620,7 +8671,15 @@ class WebRTCClient extends Emitter {
|
|
|
8620
8671
|
return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8621
8672
|
}
|
|
8622
8673
|
|
|
8623
|
-
async _disconnectTransport() {
|
|
8674
|
+
async _disconnectTransport(force = false) {
|
|
8675
|
+
if (force) {
|
|
8676
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
8677
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
8678
|
+
// eslint-disable-next-line
|
|
8679
|
+
this.userAgent.transport._ws.close(1000);
|
|
8680
|
+
return;
|
|
8681
|
+
}
|
|
8682
|
+
|
|
8624
8683
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8625
8684
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8626
8685
|
try {
|
|
@@ -9357,6 +9416,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9357
9416
|
}
|
|
9358
9417
|
|
|
9359
9418
|
callSession.answerTime = new Date();
|
|
9419
|
+
this._updateCallSession(callSession);
|
|
9360
9420
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
9361
9421
|
|
|
9362
9422
|
return callSession;
|
|
@@ -9566,6 +9626,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9566
9626
|
return Promise.resolve(null);
|
|
9567
9627
|
}
|
|
9568
9628
|
|
|
9629
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9630
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9631
|
+
logger$7.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9632
|
+
return Promise.resolve(null);
|
|
9633
|
+
}
|
|
9634
|
+
|
|
9569
9635
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9570
9636
|
logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9571
9637
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -9573,6 +9639,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9573
9639
|
|
|
9574
9640
|
this.shouldSendReinvite = false;
|
|
9575
9641
|
callSession.answerTime = new Date();
|
|
9642
|
+
this._updateCallSession(callSession);
|
|
9576
9643
|
this.acceptedSessions[callSession.getId()] = true;
|
|
9577
9644
|
|
|
9578
9645
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -9672,7 +9739,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9672
9739
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
9673
9740
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
9674
9741
|
logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
9675
|
-
this.holdSipSession(this.currentSipSession,
|
|
9742
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
9676
9743
|
}
|
|
9677
9744
|
|
|
9678
9745
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -9883,6 +9950,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9883
9950
|
}
|
|
9884
9951
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
9885
9952
|
callSession.creationTime = new Date();
|
|
9953
|
+
this._updateCallSession(callSession);
|
|
9886
9954
|
|
|
9887
9955
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
9888
9956
|
|
|
@@ -10024,7 +10092,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10024
10092
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
10025
10093
|
}
|
|
10026
10094
|
|
|
10027
|
-
async close() {
|
|
10095
|
+
async close(force = false) {
|
|
10028
10096
|
logger$7.info('WebRTC close');
|
|
10029
10097
|
|
|
10030
10098
|
try {
|
|
@@ -10036,7 +10104,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10036
10104
|
logger$7.error('WebRTC close, unregister error', e);
|
|
10037
10105
|
}
|
|
10038
10106
|
|
|
10039
|
-
this.client.close();
|
|
10107
|
+
this.client.close(force);
|
|
10040
10108
|
this.unbind();
|
|
10041
10109
|
|
|
10042
10110
|
this.incomingSessions = [];
|
|
@@ -10162,6 +10230,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10162
10230
|
}
|
|
10163
10231
|
|
|
10164
10232
|
callSession.creationTime = new Date();
|
|
10233
|
+
this._updateCallSession(callSession);
|
|
10234
|
+
|
|
10165
10235
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
10166
10236
|
});
|
|
10167
10237
|
|
|
@@ -10186,9 +10256,17 @@ class WebRTCPhone extends Emitter {
|
|
|
10186
10256
|
});
|
|
10187
10257
|
|
|
10188
10258
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
10189
|
-
|
|
10259
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10260
|
+
const hasSession = sessionId in this.callSessions;
|
|
10190
10261
|
|
|
10191
|
-
|
|
10262
|
+
logger$7.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10263
|
+
|
|
10264
|
+
if (!hasSession) {
|
|
10265
|
+
logger$7.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10266
|
+
return;
|
|
10267
|
+
}
|
|
10268
|
+
|
|
10269
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
10192
10270
|
|
|
10193
10271
|
if (this.audioOutputDeviceId) {
|
|
10194
10272
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -10205,6 +10283,8 @@ class WebRTCPhone extends Emitter {
|
|
|
10205
10283
|
logger$7.info('WebRTC call rejected', session.id);
|
|
10206
10284
|
const callSession = this._createCallSession(session);
|
|
10207
10285
|
callSession.endTime = new Date();
|
|
10286
|
+
this._updateCallSession(callSession);
|
|
10287
|
+
|
|
10208
10288
|
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
10209
10289
|
});
|
|
10210
10290
|
|
|
@@ -10322,9 +10402,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10322
10402
|
return this.client.getSipSessionId(sipSession);
|
|
10323
10403
|
}
|
|
10324
10404
|
|
|
10325
|
-
|
|
10405
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10326
10406
|
const sipSession = this.findSipSession(callSession);
|
|
10327
|
-
|
|
10407
|
+
|
|
10408
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10409
|
+
}
|
|
10410
|
+
|
|
10411
|
+
_updateCallSession(callSession ) {
|
|
10412
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10328
10413
|
|
|
10329
10414
|
if (sipSessionId) {
|
|
10330
10415
|
this.callSessions[sipSessionId] = callSession;
|
|
@@ -10429,6 +10514,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10429
10514
|
displayName: identity ? identity.displayName || number : number,
|
|
10430
10515
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
10431
10516
|
creationTime: fromSession ? fromSession.creationTime : null,
|
|
10517
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
10432
10518
|
endTime: fromSession ? fromSession.endTime : null,
|
|
10433
10519
|
answered: state === SessionState.Established,
|
|
10434
10520
|
paused: this.client.isCallHeld(sipSession),
|