@wazo/sdk 1.0.0-alpha.0 → 1.0.0-alpha.10
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/README.md +16 -7
- package/dist/wazo-sdk.js +6 -6
- package/esm/__tests__/__voice__/call.test.js +57 -2
- package/esm/__tests__/api-client.test.js +20 -1
- package/esm/api/auth.js +16 -2
- package/esm/checker/checks/webrtc.js +2 -2
- package/esm/domain/CallLog.js +2 -3
- package/esm/domain/Phone/CTIPhone.js +2 -2
- package/esm/domain/Phone/WebRTCPhone.js +64 -63
- package/esm/index.js +5 -1
- package/esm/service/CallApi.js +4 -4
- package/esm/simple/Auth.js +19 -15
- package/esm/simple/Phone.js +6 -5
- package/esm/simple/__tests__/Auth.test.js +8 -64
- package/esm/simple/index.js +2 -1
- package/esm/simple/room/Room.js +2 -2
- package/esm/simple/room/SipRoom.js +2 -2
- package/esm/state-machine/call-state-machine.js +2 -2
- package/esm/state-machine/softphone-state-machine.js +1 -2
- package/esm/state-machine/utils.js +8 -3
- package/esm/types/api/auth.d.ts +3 -0
- package/esm/types/api/auth.d.ts.map +1 -1
- package/esm/types/checker/checks/index.d.ts +1 -1
- package/esm/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/esm/types/domain/CallLog.d.ts.map +1 -1
- package/esm/types/domain/CallSession.d.ts +3 -3
- package/esm/types/domain/CallSession.d.ts.map +1 -1
- package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/esm/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/esm/types/domain/types.d.ts +0 -4
- package/esm/types/domain/types.d.ts.map +1 -1
- package/esm/types/index.d.ts +5 -1
- package/esm/types/index.d.ts.map +1 -1
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/esm/types/service/CallApi.d.ts +5 -5
- package/esm/types/service/CallApi.d.ts.map +1 -1
- package/esm/types/simple/Auth.d.ts +6 -1
- package/esm/types/simple/Auth.d.ts.map +1 -1
- package/esm/types/simple/Phone.d.ts +8 -8
- package/esm/types/simple/Phone.d.ts.map +1 -1
- package/esm/types/simple/index.d.ts +3 -1
- package/esm/types/simple/index.d.ts.map +1 -1
- package/esm/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/esm/types/state-machine/utils.d.ts +2 -2
- package/esm/types/state-machine/utils.d.ts.map +1 -1
- package/esm/types/utils/api-requester.d.ts.map +1 -1
- package/esm/types/utils/sdp.d.ts +3 -2
- package/esm/types/utils/sdp.d.ts.map +1 -1
- package/esm/types/utils/webrtc.d.ts +1 -0
- package/esm/types/utils/webrtc.d.ts.map +1 -1
- package/esm/types/voice/call.d.ts +30 -12
- package/esm/types/voice/call.d.ts.map +1 -1
- package/esm/types/voice/softphone.d.ts +25 -13
- package/esm/types/voice/softphone.d.ts.map +1 -1
- package/esm/types/web-rtc-client.d.ts +39 -38
- package/esm/types/web-rtc-client.d.ts.map +1 -1
- package/esm/utils/__tests__/api-requester.test.js +17 -0
- package/esm/utils/api-requester.js +9 -1
- package/esm/utils/sdp.js +22 -9
- package/esm/utils/webrtc.js +24 -4
- package/esm/voice/call.js +130 -38
- package/esm/voice/softphone.js +145 -35
- package/esm/web-rtc-client.js +61 -58
- package/lib/__tests__/__voice__/call.test.js +56 -1
- package/lib/__tests__/api-client.test.js +20 -1
- package/lib/api/auth.js +16 -2
- package/lib/checker/checks/webrtc.js +1 -1
- package/lib/domain/CallLog.js +2 -3
- package/lib/domain/Phone/CTIPhone.js +2 -2
- package/lib/domain/Phone/WebRTCPhone.js +63 -62
- package/lib/index.js +11 -3
- package/lib/service/CallApi.js +2 -2
- package/lib/simple/Auth.js +21 -15
- package/lib/simple/Phone.js +3 -2
- package/lib/simple/__tests__/Auth.test.js +11 -64
- package/lib/simple/index.js +2 -1
- package/lib/simple/room/Room.js +1 -1
- package/lib/simple/room/SipRoom.js +1 -1
- package/lib/state-machine/call-state-machine.js +2 -2
- package/lib/state-machine/softphone-state-machine.js +1 -2
- package/lib/state-machine/utils.js +8 -3
- package/lib/types/api/auth.d.ts +3 -0
- package/lib/types/api/auth.d.ts.map +1 -1
- package/lib/types/checker/checks/index.d.ts +1 -1
- package/lib/types/checker/checks/webrtc-transport.d.ts +2 -2
- package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -1
- package/lib/types/domain/CallLog.d.ts.map +1 -1
- package/lib/types/domain/CallSession.d.ts +3 -3
- package/lib/types/domain/CallSession.d.ts.map +1 -1
- package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
- package/lib/types/domain/Phone/WebRTCPhone.d.ts +22 -22
- package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
- package/lib/types/domain/types.d.ts +0 -4
- package/lib/types/domain/types.d.ts.map +1 -1
- package/lib/types/index.d.ts +5 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
- package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
- package/lib/types/service/CallApi.d.ts +5 -5
- package/lib/types/service/CallApi.d.ts.map +1 -1
- package/lib/types/simple/Auth.d.ts +6 -1
- package/lib/types/simple/Auth.d.ts.map +1 -1
- package/lib/types/simple/Phone.d.ts +8 -8
- package/lib/types/simple/Phone.d.ts.map +1 -1
- package/lib/types/simple/index.d.ts +3 -1
- package/lib/types/simple/index.d.ts.map +1 -1
- package/lib/types/state-machine/softphone-state-machine.d.ts +1 -2
- package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
- package/lib/types/state-machine/utils.d.ts +2 -2
- package/lib/types/state-machine/utils.d.ts.map +1 -1
- package/lib/types/utils/api-requester.d.ts.map +1 -1
- package/lib/types/utils/sdp.d.ts +3 -2
- package/lib/types/utils/sdp.d.ts.map +1 -1
- package/lib/types/utils/webrtc.d.ts +1 -0
- package/lib/types/utils/webrtc.d.ts.map +1 -1
- package/lib/types/voice/call.d.ts +30 -12
- package/lib/types/voice/call.d.ts.map +1 -1
- package/lib/types/voice/softphone.d.ts +25 -13
- package/lib/types/voice/softphone.d.ts.map +1 -1
- package/lib/types/web-rtc-client.d.ts +39 -38
- package/lib/types/web-rtc-client.d.ts.map +1 -1
- package/lib/utils/__tests__/api-requester.test.js +17 -0
- package/lib/utils/api-requester.js +9 -1
- package/lib/utils/sdp.js +25 -10
- package/lib/utils/webrtc.js +25 -4
- package/lib/voice/call.js +131 -36
- package/lib/voice/softphone.js +150 -35
- package/lib/web-rtc-client.js +59 -57
- package/package.json +1 -1
- package/src/__tests__/__voice__/call.test.ts +63 -2
- package/src/__tests__/api-client.test.ts +22 -1
- package/src/api/auth.ts +30 -3
- package/src/checker/checks/webrtc-transport.ts +2 -2
- package/src/checker/checks/webrtc.ts +2 -2
- package/src/domain/CallLog.ts +2 -3
- package/src/domain/CallSession.ts +3 -3
- package/src/domain/Phone/CTIPhone.ts +3 -2
- package/src/domain/Phone/WebRTCPhone.ts +95 -93
- package/src/domain/types.ts +0 -5
- package/src/index.ts +6 -1
- package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
- package/src/service/CallApi.ts +7 -7
- package/src/simple/Auth.ts +21 -16
- package/src/simple/Phone.ts +12 -11
- package/src/simple/__tests__/Auth.test.ts +9 -87
- package/src/simple/index.ts +2 -1
- package/src/simple/room/Room.ts +3 -3
- package/src/simple/room/SipRoom.ts +3 -3
- package/src/state-machine/call-state-machine.ts +2 -2
- package/src/state-machine/softphone-state-machine.ts +1 -2
- package/src/state-machine/utils.ts +12 -5
- package/src/utils/__tests__/api-requester.test.ts +20 -0
- package/src/utils/api-requester.ts +9 -1
- package/src/utils/sdp.ts +26 -11
- package/src/utils/webrtc.ts +27 -5
- package/src/voice/call.ts +169 -50
- package/src/voice/softphone.ts +180 -41
- package/src/web-rtc-client.ts +106 -99
package/esm/voice/call.js
CHANGED
|
@@ -4,13 +4,17 @@ import { createActor } from 'xstate';
|
|
|
4
4
|
import { Invitation } from 'sip.js/lib/api/invitation';
|
|
5
5
|
import { SessionState } from 'sip.js/lib/api/session-state';
|
|
6
6
|
import callStateMachine, { Actions, EstablishedActions, States, EstablishedStates } from '../state-machine/call-state-machine';
|
|
7
|
+
import newFrom from '../utils/new-from';
|
|
8
|
+
import updateFrom from '../utils/update-from';
|
|
7
9
|
import IssueReporter from '../service/IssueReporter';
|
|
8
|
-
import
|
|
10
|
+
import softphone from './softphone';
|
|
11
|
+
import { getCallDisplayName, getCallNumber, getSipCallId } from '../utils/sdp';
|
|
9
12
|
import { assertCan, assertState, getState } from '../state-machine/utils';
|
|
10
|
-
import { downgradeToAudio, getLocalStream, getLocalVideoStream, getPeerConnection, getRemoteStream, getRemoteVideoStream, getStreamFromConstraints, getWebRtcStats, hasALocalVideoTrack, hasLocalVideo, hasRemoteVideo, isVideoRemotelyHeld, setLocalMediaStream, toggleVideo, upgradeToVideo } from '../utils/webrtc';
|
|
13
|
+
import { downgradeToAudio, getLocalStream, getLocalVideoStream, getPeerConnection, getRemoteStream, getRemoteVideoStream, getStreamFromConstraints, getWebRtcStats, hasALocalVideoTrack, hasLocalVideo, hasRemoteVideo, isVideoMuted, isVideoRemotelyHeld, setLocalMediaStream, toggleVideo, upgradeToVideo } from '../utils/webrtc';
|
|
11
14
|
const logger = IssueReporter.loggerFor('call');
|
|
12
15
|
// Events
|
|
13
|
-
export const
|
|
16
|
+
export const EVENT_CALL_REMOTLY_ACCEPTED = 'remotelyAccepted';
|
|
17
|
+
export const EVENT_CALL_LOCALLY_ACCEPTED = 'locallyAccepted';
|
|
14
18
|
export const EVENT_CALL_CANCELED = 'canceled';
|
|
15
19
|
export const EVENT_PROGRESS = 'progress';
|
|
16
20
|
export const EVENT_EARLY_MEDIA = 'earlyMedia';
|
|
@@ -33,12 +37,10 @@ export const EVENT_SHARE_SCREEN_ENDED = 'onScreenShareEnded';
|
|
|
33
37
|
export const EVENT_WEB_RTC_STATS = 'webRtcStats';
|
|
34
38
|
export const EVENT_CAMERA_RESUMED = 'onCameraResumed';
|
|
35
39
|
export const EVENT_CAMERA_DISABLED = 'onCameraDisabled';
|
|
36
|
-
export const EVENT_TERMINATE_SOUND = 'terminateSound';
|
|
37
40
|
export const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
38
41
|
export const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
39
42
|
export const MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
40
43
|
class Call extends EventEmitter {
|
|
41
|
-
eventEmitter;
|
|
42
44
|
callActor;
|
|
43
45
|
// Wazo call id, used in Wazo Websocket and API
|
|
44
46
|
apiId;
|
|
@@ -49,7 +51,54 @@ class Call extends EventEmitter {
|
|
|
49
51
|
endTime;
|
|
50
52
|
phone;
|
|
51
53
|
shouldSendReinvite = false;
|
|
54
|
+
recording = false;
|
|
55
|
+
displayName;
|
|
56
|
+
number;
|
|
52
57
|
currentScreenShare;
|
|
58
|
+
static newFrom(call) {
|
|
59
|
+
return newFrom(call, Call);
|
|
60
|
+
}
|
|
61
|
+
static parseCall(apiCall) {
|
|
62
|
+
const sipCall = {
|
|
63
|
+
id: apiCall.sipCallId,
|
|
64
|
+
stateChange: {
|
|
65
|
+
addListener: () => { },
|
|
66
|
+
},
|
|
67
|
+
remoteIdentity: {
|
|
68
|
+
uri: {
|
|
69
|
+
_normal: {
|
|
70
|
+
user: apiCall.calleeNumber,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
// Mock sdk so `hasLocalVideo` will return true.
|
|
75
|
+
sessionDescriptionHandler: {
|
|
76
|
+
localMediaStream: {
|
|
77
|
+
getTracks: () => (apiCall.isVideo ? [{ kind: 'video', readyState: 'live' }] : []),
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
const call = new Call(sipCall, softphone);
|
|
82
|
+
call.apiId = apiCall.id;
|
|
83
|
+
call.answerTime = new Date(+apiCall.startingTime);
|
|
84
|
+
// Update call state
|
|
85
|
+
const snapshot = call.callActor.getSnapshot();
|
|
86
|
+
if (apiCall.isUp()) {
|
|
87
|
+
snapshot.value = { [States.ESTABLISHED]: EstablishedStates.ONGOING };
|
|
88
|
+
}
|
|
89
|
+
if (apiCall.muted) {
|
|
90
|
+
snapshot.value = { [States.ESTABLISHED]: EstablishedStates.MUTED };
|
|
91
|
+
}
|
|
92
|
+
if (apiCall.isRinging()) {
|
|
93
|
+
snapshot.value = States.RINGING;
|
|
94
|
+
}
|
|
95
|
+
if (apiCall.isRecording()) {
|
|
96
|
+
call.recording = true;
|
|
97
|
+
}
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
call.callActor.update(snapshot);
|
|
100
|
+
return call;
|
|
101
|
+
}
|
|
53
102
|
constructor(sipCall, phone) {
|
|
54
103
|
super();
|
|
55
104
|
this.callActor = createActor(callStateMachine);
|
|
@@ -57,7 +106,8 @@ class Call extends EventEmitter {
|
|
|
57
106
|
this.creationTime = new Date();
|
|
58
107
|
this.phone = phone;
|
|
59
108
|
this.sipCall = sipCall;
|
|
60
|
-
this.
|
|
109
|
+
this.number = getCallNumber(sipCall);
|
|
110
|
+
this.displayName = getCallDisplayName(sipCall);
|
|
61
111
|
}
|
|
62
112
|
async accept(options = {}) {
|
|
63
113
|
assertCan(this.callActor, Actions.ACCEPT);
|
|
@@ -68,6 +118,7 @@ class Call extends EventEmitter {
|
|
|
68
118
|
this.answerTime = new Date();
|
|
69
119
|
return this.phone.client.answer(this.sipCall, options.withCamera).then(() => {
|
|
70
120
|
logger.info('call - accepted', { id: this.id, ...options });
|
|
121
|
+
this.emit(EVENT_CALL_LOCALLY_ACCEPTED, this);
|
|
71
122
|
return this.id;
|
|
72
123
|
}).catch(e => {
|
|
73
124
|
logger.error(e);
|
|
@@ -78,16 +129,18 @@ class Call extends EventEmitter {
|
|
|
78
129
|
async reject() {
|
|
79
130
|
assertCan(this.callActor, Actions.REJECT);
|
|
80
131
|
logger.info('call - reject', { id: this.id });
|
|
81
|
-
this.
|
|
82
|
-
this.shouldSendReinvite = false;
|
|
83
|
-
return this.hangup();
|
|
132
|
+
return this._terminate();
|
|
84
133
|
}
|
|
85
134
|
async hangup() {
|
|
86
135
|
assertCan(this.callActor, Actions.HANGUP);
|
|
87
136
|
logger.info('call - hangup', { id: this.id });
|
|
137
|
+
return this._terminate();
|
|
138
|
+
}
|
|
139
|
+
async _terminate() {
|
|
88
140
|
await this.phone.client.hangup(this.sipCall);
|
|
141
|
+
this.shouldSendReinvite = false;
|
|
89
142
|
// Remove this call from softphone's calls
|
|
90
|
-
this.phone.
|
|
143
|
+
this.phone.onCallTerminated(this);
|
|
91
144
|
return true;
|
|
92
145
|
}
|
|
93
146
|
forceCancel() {
|
|
@@ -99,7 +152,7 @@ class Call extends EventEmitter {
|
|
|
99
152
|
logger.info('call - force cancel, error', e);
|
|
100
153
|
}
|
|
101
154
|
}
|
|
102
|
-
startConference(withCalls) {
|
|
155
|
+
startConference( /* withCalls: Call[] */) {
|
|
103
156
|
// @TODO
|
|
104
157
|
// const participants = [this, ...withCalls].reduce((acc: Record<string, any>, call: Call) => {
|
|
105
158
|
// acc[call.talkingToIds[0]] = call;
|
|
@@ -117,14 +170,14 @@ class Call extends EventEmitter {
|
|
|
117
170
|
logger.info('call - mute', { id: this.id });
|
|
118
171
|
this._sendAction(EstablishedActions.MUTE);
|
|
119
172
|
this.phone.client.mute(this.sipCall);
|
|
120
|
-
this.
|
|
173
|
+
this.emit(EVENT_CALL_MUTED);
|
|
121
174
|
}
|
|
122
175
|
unMute() {
|
|
123
176
|
assertCan(this.callActor, EstablishedActions.UN_MUTE);
|
|
124
177
|
logger.info('call - un-mute', { id: this.id });
|
|
125
178
|
this._sendAction(EstablishedActions.UN_MUTE);
|
|
126
179
|
this.phone.client.unmute(this.sipCall);
|
|
127
|
-
this.
|
|
180
|
+
this.emit(EVENT_CALL_UN_MUTED);
|
|
128
181
|
}
|
|
129
182
|
async hold() {
|
|
130
183
|
assertCan(this.callActor, EstablishedActions.HOLD);
|
|
@@ -140,7 +193,7 @@ class Call extends EventEmitter {
|
|
|
140
193
|
await downgradeToAudio(this.sipCall);
|
|
141
194
|
}
|
|
142
195
|
const promise = this.phone.client.hold(this.sipCall, this.isConference(), hasVideo);
|
|
143
|
-
this.
|
|
196
|
+
this.emit(EVENT_CALL_HELD);
|
|
144
197
|
return promise;
|
|
145
198
|
}
|
|
146
199
|
async resume() {
|
|
@@ -167,7 +220,7 @@ class Call extends EventEmitter {
|
|
|
167
220
|
this._onScreenSharing(stream, hadVideo, wasDesktop);
|
|
168
221
|
}
|
|
169
222
|
};
|
|
170
|
-
this.
|
|
223
|
+
this.emit(EVENT_CALL_RESUMED);
|
|
171
224
|
return promise.then(() => {
|
|
172
225
|
const stream = this.getLocalVideoStream();
|
|
173
226
|
if (wasScreensharing) {
|
|
@@ -180,19 +233,37 @@ class Call extends EventEmitter {
|
|
|
180
233
|
assertState(this.callActor, States.ESTABLISHED);
|
|
181
234
|
logger.info('call - turn camera on', { id: this.id });
|
|
182
235
|
toggleVideo(this.sipCall, true);
|
|
183
|
-
this.
|
|
236
|
+
this.emit(EVENT_CAMERA_RESUMED);
|
|
184
237
|
}
|
|
185
238
|
turnCameraOff() {
|
|
186
239
|
assertState(this.callActor, States.ESTABLISHED);
|
|
187
240
|
logger.info('call - turn camera off', { id: this.id });
|
|
188
241
|
toggleVideo(this.sipCall, false);
|
|
189
|
-
this.
|
|
242
|
+
this.emit(EVENT_CAMERA_DISABLED);
|
|
243
|
+
}
|
|
244
|
+
isMuted() {
|
|
245
|
+
return this._hasEstablishedState(EstablishedStates.MUTED);
|
|
246
|
+
}
|
|
247
|
+
isCameraMuted() {
|
|
248
|
+
return isVideoMuted(this.sipCall);
|
|
190
249
|
}
|
|
191
250
|
isHeld() {
|
|
192
|
-
return
|
|
251
|
+
return this._hasEstablishedState(EstablishedStates.HELD);
|
|
252
|
+
}
|
|
253
|
+
isEstablishing() {
|
|
254
|
+
return this.sipCall.state === SessionState.Establishing;
|
|
193
255
|
}
|
|
194
256
|
isEstablished() {
|
|
195
|
-
return
|
|
257
|
+
return typeof this.state === 'object' && States.ESTABLISHED in this.state;
|
|
258
|
+
}
|
|
259
|
+
isRinging() {
|
|
260
|
+
return this.state === States.RINGING;
|
|
261
|
+
}
|
|
262
|
+
isOutgoing() {
|
|
263
|
+
return this.sipCall instanceof Invitation;
|
|
264
|
+
}
|
|
265
|
+
isIncoming() {
|
|
266
|
+
return !this.isOutgoing();
|
|
196
267
|
}
|
|
197
268
|
isConference() {
|
|
198
269
|
return getPeerConnection(this.sipCall)?.sfu;
|
|
@@ -200,7 +271,7 @@ class Call extends EventEmitter {
|
|
|
200
271
|
transfer(target) {
|
|
201
272
|
assertState(this.callActor, States.ESTABLISHED);
|
|
202
273
|
logger.info('call - transfer', { id: this.id, target });
|
|
203
|
-
this.phone.client.transfer(this.sipCall, target);
|
|
274
|
+
return this.phone.client.transfer(this.sipCall, target);
|
|
204
275
|
}
|
|
205
276
|
atxfer() {
|
|
206
277
|
assertState(this.callActor, States.ESTABLISHED);
|
|
@@ -320,7 +391,7 @@ class Call extends EventEmitter {
|
|
|
320
391
|
catch (e) {
|
|
321
392
|
console.warn(e);
|
|
322
393
|
}
|
|
323
|
-
this.
|
|
394
|
+
this.emit(EVENT_SHARE_SCREEN_ENDED);
|
|
324
395
|
this.currentScreenShare = null;
|
|
325
396
|
return reinvited;
|
|
326
397
|
}
|
|
@@ -329,9 +400,13 @@ class Call extends EventEmitter {
|
|
|
329
400
|
logger.info('call - updrading directly in screensharing mode', { id: this.id, tracks: localStream?.getTracks() });
|
|
330
401
|
this._onScreenSharing(localStream, false, desktop);
|
|
331
402
|
}
|
|
403
|
+
onMakeCall() {
|
|
404
|
+
this._bindEvents();
|
|
405
|
+
this._sendAction(Actions.MAKE_CALL);
|
|
406
|
+
}
|
|
332
407
|
onAccepted() {
|
|
333
408
|
this._sendAction(Actions.REMOTLY_ACCEPTED);
|
|
334
|
-
this.emit(
|
|
409
|
+
this.emit(EVENT_CALL_REMOTLY_ACCEPTED);
|
|
335
410
|
}
|
|
336
411
|
onProgress() {
|
|
337
412
|
this.emit(EVENT_PROGRESS);
|
|
@@ -345,10 +420,14 @@ class Call extends EventEmitter {
|
|
|
345
420
|
onError(error) {
|
|
346
421
|
this.emit(EVENT_CALL_ERROR, error);
|
|
347
422
|
}
|
|
423
|
+
onCallIncoming() {
|
|
424
|
+
this._bindEvents();
|
|
425
|
+
this._sendAction(Actions.INCOMING_CALL);
|
|
426
|
+
}
|
|
348
427
|
onRejected() {
|
|
349
428
|
this.endTime = new Date();
|
|
350
429
|
this.emit(EVENT_CALL_REJECTED);
|
|
351
|
-
this.phone.
|
|
430
|
+
this.phone.onCallTerminated(this);
|
|
352
431
|
}
|
|
353
432
|
onNetworkStats(stats, previousStats) {
|
|
354
433
|
this.emit(EVENT_WEB_RTC_STATS, stats, previousStats);
|
|
@@ -380,13 +459,24 @@ class Call extends EventEmitter {
|
|
|
380
459
|
onReinvite(request, updatedCalleeName, updatedNumber, hadRemoteVideo) {
|
|
381
460
|
this.emit(EVENT_REINVITE, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
|
|
382
461
|
}
|
|
462
|
+
updateFrom(call) {
|
|
463
|
+
updateFrom(this, call);
|
|
464
|
+
}
|
|
465
|
+
is(otherCall) {
|
|
466
|
+
return otherCall && this.id && this.id === otherCall.id;
|
|
467
|
+
}
|
|
468
|
+
shouldAutoAnswer() {
|
|
469
|
+
return !!this.sipCall.request?.getHeader('alert-info');
|
|
470
|
+
}
|
|
383
471
|
get id() {
|
|
384
|
-
return
|
|
472
|
+
return getSipCallId(this.sipCall);
|
|
473
|
+
}
|
|
474
|
+
get state() {
|
|
475
|
+
return getState(this.callActor);
|
|
385
476
|
}
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
return identity ? identity.uri._normal.user : null;
|
|
477
|
+
_hasEstablishedState(establishedState) {
|
|
478
|
+
const state = this.state;
|
|
479
|
+
return typeof state === 'object' && States.ESTABLISHED in state && state[States.ESTABLISHED] === establishedState;
|
|
390
480
|
}
|
|
391
481
|
_bindEvents() {
|
|
392
482
|
if (this.sipCall instanceof Invitation) {
|
|
@@ -396,21 +486,22 @@ class Call extends EventEmitter {
|
|
|
396
486
|
logger.trace('call - on sip session canceled', { callId: message.callId, id: this.id });
|
|
397
487
|
onCancel(message);
|
|
398
488
|
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
399
|
-
this.
|
|
489
|
+
this.emit(EVENT_CALL_CANCELED, elsewhere);
|
|
400
490
|
};
|
|
401
491
|
}
|
|
402
|
-
this.sipCall
|
|
492
|
+
this.sipCall?.stateChange?.addListener((newState) => {
|
|
403
493
|
switch (newState) {
|
|
404
494
|
case SessionState.Terminating:
|
|
405
495
|
logger.info('call - terminating', { id: this.id });
|
|
406
|
-
this.
|
|
496
|
+
this.emit(EVENT_CALL_TERMINATING);
|
|
407
497
|
break;
|
|
408
498
|
case SessionState.Terminated:
|
|
409
499
|
{
|
|
410
500
|
logger.info('call - terminated', { id: this.id });
|
|
411
501
|
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
412
502
|
this.endTime = new Date();
|
|
413
|
-
|
|
503
|
+
this.emit(EVENT_CALL_ENDED);
|
|
504
|
+
return this.phone.onCallTerminated(this);
|
|
414
505
|
}
|
|
415
506
|
default:
|
|
416
507
|
break;
|
|
@@ -437,18 +528,17 @@ class Call extends EventEmitter {
|
|
|
437
528
|
kind,
|
|
438
529
|
});
|
|
439
530
|
if (kind === 'audio') {
|
|
440
|
-
return this.
|
|
531
|
+
return this.emit(EVENT_AUDIO_STREAM, stream);
|
|
441
532
|
}
|
|
442
|
-
return this.
|
|
533
|
+
return this.emit(EVENT_VIDEO_STREAM, stream, event.track.id, event);
|
|
443
534
|
};
|
|
444
535
|
peerConnection.onremovestream = (event) => {
|
|
445
536
|
logger.info('call - on remove stream called on the peer connection', {
|
|
446
537
|
id: event.stream.id,
|
|
447
538
|
tracks: event.stream.getTracks(),
|
|
448
539
|
});
|
|
449
|
-
this.
|
|
540
|
+
this.emit(EVENT_REMOVE_STREAM, event.stream);
|
|
450
541
|
};
|
|
451
|
-
// Client events
|
|
452
542
|
}
|
|
453
543
|
_downgradeToAudio(withMessage = true) {
|
|
454
544
|
assertState(this.callActor, States.ESTABLISHED);
|
|
@@ -508,7 +598,7 @@ class Call extends EventEmitter {
|
|
|
508
598
|
if (screenTrack) {
|
|
509
599
|
screenTrack.onended = () => {
|
|
510
600
|
logger.info('call - on screenshare ended', { hadVideo, id: this.id, screenTrack });
|
|
511
|
-
this.
|
|
601
|
+
this.emit(EVENT_SHARE_SCREEN_ENDING);
|
|
512
602
|
};
|
|
513
603
|
}
|
|
514
604
|
this.currentScreenShare = {
|
|
@@ -518,10 +608,12 @@ class Call extends EventEmitter {
|
|
|
518
608
|
desktop,
|
|
519
609
|
};
|
|
520
610
|
setLocalMediaStream(this.sipCall, screenStream);
|
|
521
|
-
this.
|
|
611
|
+
this.emit(EVENT_SHARE_SCREEN_STARTED, screenStream);
|
|
522
612
|
}
|
|
523
613
|
_sendAction(action) {
|
|
614
|
+
const was = this.state;
|
|
524
615
|
this.callActor.send({ type: action });
|
|
616
|
+
logger.trace('call - send action', { action, was, state: this.state });
|
|
525
617
|
}
|
|
526
618
|
}
|
|
527
619
|
export default Call;
|