@wazo/sdk 1.0.0-alpha.1 → 1.0.0-alpha.11
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/api/auth.js +3 -0
- 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 +3 -1
- package/esm/service/CallApi.js +4 -4
- package/esm/simple/Auth.js +13 -3
- package/esm/simple/Phone.js +6 -5
- 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 +10 -4
- 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 +3 -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/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/sdp.js +22 -9
- package/esm/utils/webrtc.js +23 -3
- package/esm/voice/call.js +131 -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/api/auth.js +3 -0
- 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 +7 -3
- package/lib/service/CallApi.js +2 -2
- package/lib/simple/Auth.js +15 -3
- package/lib/simple/Phone.js +3 -2
- 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 +10 -4
- 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 +3 -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/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/sdp.js +25 -10
- package/lib/utils/webrtc.js +24 -3
- package/lib/voice/call.js +132 -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/api/auth.ts +5 -0
- 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 +4 -1
- package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
- package/src/service/CallApi.ts +7 -7
- package/src/simple/Auth.ts +15 -3
- package/src/simple/Phone.ts +12 -11
- 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 +14 -6
- package/src/utils/sdp.ts +26 -11
- package/src/utils/webrtc.ts +26 -4
- package/src/voice/call.ts +170 -50
- package/src/voice/softphone.ts +180 -41
- package/src/web-rtc-client.ts +106 -99
package/lib/utils/sdp.js
CHANGED
|
@@ -3,11 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.makeURI = exports.replaceLocalIpModifier = exports.
|
|
6
|
+
exports.getCallDisplayName = exports.getCallNumber = exports.makeURI = exports.replaceLocalIpModifier = exports.getSipCallId = exports.addIcesInAllBundles = exports.fixSdp = exports.hasAnActiveVideo = exports.activateVideoModifier = exports.deactivateVideoModifier = exports.getVideoDirection = exports.toggleVideoDirection = exports.fixBundle = exports.isSdpValid = exports.areCandidateValid = exports.parseCandidate = exports.getCandidates = void 0;
|
|
7
|
+
/* eslint-disable no-underscore-dangle */
|
|
7
8
|
const sdp_transform_1 = __importDefault(require("sdp-transform"));
|
|
8
9
|
const user_agent_1 = require("sip.js/lib/api/user-agent");
|
|
9
10
|
const api_1 = require("sip.js/lib/api");
|
|
10
|
-
exports.SIP_ID_LENGTH = 36;
|
|
11
11
|
const getCandidates = (rawSdp) => {
|
|
12
12
|
if (!rawSdp) {
|
|
13
13
|
return [];
|
|
@@ -116,26 +116,41 @@ const addIcesInAllBundles = (sdp) => {
|
|
|
116
116
|
return sdp_transform_1.default.write(parsedSdp);
|
|
117
117
|
};
|
|
118
118
|
exports.addIcesInAllBundles = addIcesInAllBundles;
|
|
119
|
-
const
|
|
119
|
+
const getSipCallId = (sipSession) => {
|
|
120
120
|
if (!sipSession) {
|
|
121
121
|
return '';
|
|
122
122
|
}
|
|
123
|
-
const message = sipSession.message;
|
|
124
|
-
if (message === null || message === void 0 ? void 0 : message.callId) {
|
|
125
|
-
return message.callId.substring(0, exports.SIP_ID_LENGTH);
|
|
126
|
-
}
|
|
127
123
|
// For Inviter
|
|
128
124
|
// @ts-ignore: private
|
|
129
125
|
if (sipSession instanceof api_1.Inviter && sipSession.outgoingRequestMessage) {
|
|
130
126
|
// @ts-ignore: private
|
|
131
|
-
return sipSession.outgoingRequestMessage.callId
|
|
127
|
+
return sipSession.outgoingRequestMessage.callId;
|
|
132
128
|
}
|
|
133
129
|
// For Invitation
|
|
134
|
-
|
|
130
|
+
// @ts-ignore: private
|
|
131
|
+
if (sipSession instanceof api_1.Invitation && sipSession.incomingInviteRequest.message) {
|
|
132
|
+
// @ts-ignore: private
|
|
133
|
+
return sipSession.incomingInviteRequest.message.callId;
|
|
134
|
+
}
|
|
135
|
+
return sipSession.id;
|
|
135
136
|
};
|
|
136
|
-
exports.
|
|
137
|
+
exports.getSipCallId = getSipCallId;
|
|
137
138
|
// We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
|
|
138
139
|
const replaceLocalIpModifier = (description) => Promise.resolve(Object.assign(Object.assign({}, JSON.parse(JSON.stringify(description))), { sdp: description.sdp.replace('c=IN IP4 0.0.0.0', 'c=IN IP4 127.0.0.1') }));
|
|
139
140
|
exports.replaceLocalIpModifier = replaceLocalIpModifier;
|
|
140
141
|
const makeURI = (target, host) => user_agent_1.UserAgent.makeURI(`sip:${target}@${host}`);
|
|
141
142
|
exports.makeURI = makeURI;
|
|
143
|
+
const getCallNumber = (sipCall) => {
|
|
144
|
+
// eslint-disable-next-line
|
|
145
|
+
const identity = sipCall ? sipCall.remoteIdentity || sipCall.assertedIdentity : null;
|
|
146
|
+
// @ts-ignore: private
|
|
147
|
+
return identity ? identity.uri._normal.user : null;
|
|
148
|
+
};
|
|
149
|
+
exports.getCallNumber = getCallNumber;
|
|
150
|
+
const getCallDisplayName = (sipCall) => {
|
|
151
|
+
// eslint-disable-next-line
|
|
152
|
+
const identity = sipCall ? sipCall.remoteIdentity || sipCall.assertedIdentity : null;
|
|
153
|
+
const number = (0, exports.getCallNumber)(sipCall);
|
|
154
|
+
return identity ? identity.displayName || number : number;
|
|
155
|
+
};
|
|
156
|
+
exports.getCallDisplayName = getCallDisplayName;
|
package/lib/utils/webrtc.js
CHANGED
|
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.fetchNetworkStats = exports.upgradeToVideo = exports.downgradeToAudio = exports.createUaOptions = exports.getStreamFromConstraints = exports.getMediaConfiguration = exports.getVideoConstraints = exports.getAudioConstraints = exports.isAudioOnly = exports.updateRemoteStream = exports.setLocalMediaStream = exports.cleanupStream = exports.toggleVideo = exports.toggleAudio = exports.getWebRtcStats = exports.sessionWantsToDoVideo = exports.hasAVideoTrack = exports.hasVideoTrack = exports.getRemoteVideoStreamFromPc = exports.getRemoteVideoStream = exports.hasARemoteVideoTrack = exports.hasRemoteVideo = exports.isVideoRemotelyHeld = exports.getRemoteTracks = exports.getLocalVideoStream = exports.hasALocalVideoTrack = exports.hasLocalVideo = exports.isVideoTrack = exports.getRemoteStream = exports.getLocalTracks = exports.getLocalStream = exports.getPeerConnection = exports.parseCandidate = exports.getIceServers = exports.isAPrivateIp = exports.isFirefox = exports.isWeb = void 0;
|
|
38
|
+
exports.fetchNetworkStats = exports.upgradeToVideo = exports.downgradeToAudio = exports.createUaOptions = exports.getStreamFromConstraints = exports.getMediaConfiguration = exports.getVideoConstraints = exports.getAudioConstraints = exports.isAudioOnly = exports.updateRemoteStream = exports.setLocalMediaStream = exports.cleanupStream = exports.isVideoMuted = exports.toggleVideo = exports.toggleAudio = exports.getWebRtcStats = exports.sessionWantsToDoVideo = exports.hasAVideoTrack = exports.hasVideoTrack = exports.getRemoteVideoStreamFromPc = exports.getRemoteVideoStream = exports.hasARemoteVideoTrack = exports.hasRemoteVideo = exports.isVideoRemotelyHeld = exports.getRemoteTracks = exports.getLocalVideoStream = exports.hasALocalVideoTrack = exports.hasLocalVideo = exports.isVideoTrack = exports.getRemoteStream = exports.getLocalTracks = exports.getLocalStream = exports.getPeerConnection = exports.parseCandidate = exports.getIceServers = exports.isAPrivateIp = exports.isFirefox = exports.isWeb = void 0;
|
|
39
39
|
const peer_connection_configuration_default_1 = require("sip.js/lib/platform/web/session-description-handler/peer-connection-configuration-default");
|
|
40
40
|
const web_1 = require("sip.js/lib/platform/web");
|
|
41
41
|
const WazoSessionDescriptionHandler_1 = __importStar(require("../lib/WazoSessionDescriptionHandler"));
|
|
@@ -238,13 +238,34 @@ const toggleVideo = (sipCall, muteCamera) => {
|
|
|
238
238
|
}
|
|
239
239
|
};
|
|
240
240
|
exports.toggleVideo = toggleVideo;
|
|
241
|
+
const isVideoMuted = (sipCall) => {
|
|
242
|
+
const sdh = sipCall.sessionDescriptionHandler;
|
|
243
|
+
const pc = sdh === null || sdh === void 0 ? void 0 : sdh.peerConnection;
|
|
244
|
+
if (pc === null || pc === void 0 ? void 0 : pc.getSenders) {
|
|
245
|
+
for (const sender of pc.getSenders()) {
|
|
246
|
+
if (sender && sender.track && sender.track.kind === 'video') {
|
|
247
|
+
return !sender.track.enabled;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
for (const stream of pc.getLocalStreams()) {
|
|
253
|
+
// eslint-disable-next-line no-unreachable-loop
|
|
254
|
+
for (const track of stream.getVideoTracks()) {
|
|
255
|
+
return !track.enabled;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return true;
|
|
260
|
+
};
|
|
261
|
+
exports.isVideoMuted = isVideoMuted;
|
|
241
262
|
const cleanupStream = (stream) => {
|
|
242
263
|
stream.getTracks().filter(track => track.enabled).forEach(track => track.stop());
|
|
243
264
|
};
|
|
244
265
|
exports.cleanupStream = cleanupStream;
|
|
245
266
|
const setLocalMediaStream = (sipCall, newStream) => {
|
|
246
267
|
logger.info('setting local media stream', {
|
|
247
|
-
id: sipCall
|
|
268
|
+
id: (0, sdp_1.getSipCallId)(sipCall),
|
|
248
269
|
tracks: newStream ? newStream.getTracks() : null,
|
|
249
270
|
});
|
|
250
271
|
if (sipCall.sessionDescriptionHandler) {
|
|
@@ -258,7 +279,7 @@ const updateRemoteStream = (sipCall, allTracks = true) => {
|
|
|
258
279
|
const remoteStream = (0, exports.getRemoteStream)(sipCall);
|
|
259
280
|
const pc = (0, exports.getPeerConnection)(sipCall);
|
|
260
281
|
logger.info('Updating remote stream', {
|
|
261
|
-
id: sipCall
|
|
282
|
+
id: (0, sdp_1.getSipCallId)(sipCall),
|
|
262
283
|
tracks: remoteStream ? remoteStream.getTracks() : null,
|
|
263
284
|
receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map((receiver) => receiver.track) : null,
|
|
264
285
|
});
|
package/lib/voice/call.js
CHANGED
|
@@ -35,20 +35,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.MESSAGE_TRACK_UPDATED = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.
|
|
38
|
+
exports.MESSAGE_TRACK_UPDATED = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.EVENT_CAMERA_DISABLED = exports.EVENT_CAMERA_RESUMED = exports.EVENT_WEB_RTC_STATS = exports.EVENT_SHARE_SCREEN_ENDED = exports.EVENT_SHARE_SCREEN_STARTED = exports.EVENT_SHARE_SCREEN_ENDING = exports.EVENT_REMOVE_STREAM = exports.EVENT_VIDEO_STREAM = exports.EVENT_AUDIO_STREAM = exports.EVENT_TRACK = exports.EVENT_REINVITE = exports.EVENT_CALL_RESUMED = exports.EVENT_CALL_HELD = exports.EVENT_CALL_UN_MUTED = exports.EVENT_CALL_MUTED = exports.EVENT_CALL_ENDED = exports.EVENT_CALL_TERMINATING = exports.EVENT_CALL_REJECTED = exports.EVENT_CALL_ERROR = exports.EVENT_EARLY_MEDIA = exports.EVENT_PROGRESS = exports.EVENT_CALL_CANCELED = exports.EVENT_CALL_LOCALLY_ACCEPTED = exports.EVENT_CALL_REMOTLY_ACCEPTED = void 0;
|
|
39
39
|
/* eslint-disable no-underscore-dangle */
|
|
40
40
|
const events_1 = require("events");
|
|
41
41
|
const xstate_1 = require("xstate");
|
|
42
|
+
const inviter_1 = require("sip.js/lib/api/inviter");
|
|
42
43
|
const invitation_1 = require("sip.js/lib/api/invitation");
|
|
43
44
|
const session_state_1 = require("sip.js/lib/api/session-state");
|
|
44
45
|
const call_state_machine_1 = __importStar(require("../state-machine/call-state-machine"));
|
|
46
|
+
const new_from_1 = __importDefault(require("../utils/new-from"));
|
|
47
|
+
const update_from_1 = __importDefault(require("../utils/update-from"));
|
|
45
48
|
const IssueReporter_1 = __importDefault(require("../service/IssueReporter"));
|
|
49
|
+
const softphone_1 = __importDefault(require("./softphone"));
|
|
46
50
|
const sdp_1 = require("../utils/sdp");
|
|
47
51
|
const utils_1 = require("../state-machine/utils");
|
|
48
52
|
const webrtc_1 = require("../utils/webrtc");
|
|
49
53
|
const logger = IssueReporter_1.default.loggerFor('call');
|
|
50
54
|
// Events
|
|
51
|
-
exports.
|
|
55
|
+
exports.EVENT_CALL_REMOTLY_ACCEPTED = 'remotelyAccepted';
|
|
56
|
+
exports.EVENT_CALL_LOCALLY_ACCEPTED = 'locallyAccepted';
|
|
52
57
|
exports.EVENT_CALL_CANCELED = 'canceled';
|
|
53
58
|
exports.EVENT_PROGRESS = 'progress';
|
|
54
59
|
exports.EVENT_EARLY_MEDIA = 'earlyMedia';
|
|
@@ -71,20 +76,65 @@ exports.EVENT_SHARE_SCREEN_ENDED = 'onScreenShareEnded';
|
|
|
71
76
|
exports.EVENT_WEB_RTC_STATS = 'webRtcStats';
|
|
72
77
|
exports.EVENT_CAMERA_RESUMED = 'onCameraResumed';
|
|
73
78
|
exports.EVENT_CAMERA_DISABLED = 'onCameraDisabled';
|
|
74
|
-
exports.EVENT_TERMINATE_SOUND = 'terminateSound';
|
|
75
79
|
exports.MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
|
|
76
80
|
exports.MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
|
|
77
81
|
exports.MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
|
|
78
82
|
class Call extends events_1.EventEmitter {
|
|
83
|
+
static newFrom(call) {
|
|
84
|
+
return (0, new_from_1.default)(call, Call);
|
|
85
|
+
}
|
|
86
|
+
static parseCall(apiCall) {
|
|
87
|
+
const sipCall = {
|
|
88
|
+
id: apiCall.sipCallId,
|
|
89
|
+
stateChange: {
|
|
90
|
+
addListener: () => { },
|
|
91
|
+
},
|
|
92
|
+
remoteIdentity: {
|
|
93
|
+
uri: {
|
|
94
|
+
_normal: {
|
|
95
|
+
user: apiCall.calleeNumber,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
// Mock sdk so `hasLocalVideo` will return true.
|
|
100
|
+
sessionDescriptionHandler: {
|
|
101
|
+
localMediaStream: {
|
|
102
|
+
getTracks: () => (apiCall.isVideo ? [{ kind: 'video', readyState: 'live' }] : []),
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const call = new Call(sipCall, softphone_1.default);
|
|
107
|
+
call.apiId = apiCall.id;
|
|
108
|
+
call.answerTime = new Date(+apiCall.startingTime);
|
|
109
|
+
// Update call state
|
|
110
|
+
const snapshot = call.callActor.getSnapshot();
|
|
111
|
+
if (apiCall.isUp()) {
|
|
112
|
+
snapshot.value = { [call_state_machine_1.States.ESTABLISHED]: call_state_machine_1.EstablishedStates.ONGOING };
|
|
113
|
+
}
|
|
114
|
+
if (apiCall.muted) {
|
|
115
|
+
snapshot.value = { [call_state_machine_1.States.ESTABLISHED]: call_state_machine_1.EstablishedStates.MUTED };
|
|
116
|
+
}
|
|
117
|
+
if (apiCall.isRinging()) {
|
|
118
|
+
snapshot.value = call_state_machine_1.States.RINGING;
|
|
119
|
+
}
|
|
120
|
+
if (apiCall.isRecording()) {
|
|
121
|
+
call.recording = true;
|
|
122
|
+
}
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
call.callActor.update(snapshot);
|
|
125
|
+
return call;
|
|
126
|
+
}
|
|
79
127
|
constructor(sipCall, phone) {
|
|
80
128
|
super();
|
|
81
129
|
this.shouldSendReinvite = false;
|
|
130
|
+
this.recording = false;
|
|
82
131
|
this.callActor = (0, xstate_1.createActor)(call_state_machine_1.default);
|
|
83
132
|
this.callActor.start();
|
|
84
133
|
this.creationTime = new Date();
|
|
85
134
|
this.phone = phone;
|
|
86
135
|
this.sipCall = sipCall;
|
|
87
|
-
this.
|
|
136
|
+
this.number = (0, sdp_1.getCallNumber)(sipCall);
|
|
137
|
+
this.displayName = (0, sdp_1.getCallDisplayName)(sipCall);
|
|
88
138
|
}
|
|
89
139
|
accept() {
|
|
90
140
|
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
@@ -96,6 +146,7 @@ class Call extends events_1.EventEmitter {
|
|
|
96
146
|
this.answerTime = new Date();
|
|
97
147
|
return this.phone.client.answer(this.sipCall, options.withCamera).then(() => {
|
|
98
148
|
logger.info('call - accepted', Object.assign({ id: this.id }, options));
|
|
149
|
+
this.emit(exports.EVENT_CALL_LOCALLY_ACCEPTED, this);
|
|
99
150
|
return this.id;
|
|
100
151
|
}).catch(e => {
|
|
101
152
|
logger.error(e);
|
|
@@ -108,18 +159,22 @@ class Call extends events_1.EventEmitter {
|
|
|
108
159
|
return __awaiter(this, void 0, void 0, function* () {
|
|
109
160
|
(0, utils_1.assertCan)(this.callActor, call_state_machine_1.Actions.REJECT);
|
|
110
161
|
logger.info('call - reject', { id: this.id });
|
|
111
|
-
this.
|
|
112
|
-
this.shouldSendReinvite = false;
|
|
113
|
-
return this.hangup();
|
|
162
|
+
return this._terminate();
|
|
114
163
|
});
|
|
115
164
|
}
|
|
116
165
|
hangup() {
|
|
117
166
|
return __awaiter(this, void 0, void 0, function* () {
|
|
118
167
|
(0, utils_1.assertCan)(this.callActor, call_state_machine_1.Actions.HANGUP);
|
|
119
168
|
logger.info('call - hangup', { id: this.id });
|
|
169
|
+
return this._terminate();
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
_terminate() {
|
|
173
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
174
|
yield this.phone.client.hangup(this.sipCall);
|
|
175
|
+
this.shouldSendReinvite = false;
|
|
121
176
|
// Remove this call from softphone's calls
|
|
122
|
-
this.phone.
|
|
177
|
+
this.phone.onCallTerminated(this);
|
|
123
178
|
return true;
|
|
124
179
|
});
|
|
125
180
|
}
|
|
@@ -132,7 +187,7 @@ class Call extends events_1.EventEmitter {
|
|
|
132
187
|
logger.info('call - force cancel, error', e);
|
|
133
188
|
}
|
|
134
189
|
}
|
|
135
|
-
startConference(withCalls) {
|
|
190
|
+
startConference( /* withCalls: Call[] */) {
|
|
136
191
|
// @TODO
|
|
137
192
|
// const participants = [this, ...withCalls].reduce((acc: Record<string, any>, call: Call) => {
|
|
138
193
|
// acc[call.talkingToIds[0]] = call;
|
|
@@ -150,14 +205,14 @@ class Call extends events_1.EventEmitter {
|
|
|
150
205
|
logger.info('call - mute', { id: this.id });
|
|
151
206
|
this._sendAction(call_state_machine_1.EstablishedActions.MUTE);
|
|
152
207
|
this.phone.client.mute(this.sipCall);
|
|
153
|
-
this.
|
|
208
|
+
this.emit(exports.EVENT_CALL_MUTED);
|
|
154
209
|
}
|
|
155
210
|
unMute() {
|
|
156
211
|
(0, utils_1.assertCan)(this.callActor, call_state_machine_1.EstablishedActions.UN_MUTE);
|
|
157
212
|
logger.info('call - un-mute', { id: this.id });
|
|
158
213
|
this._sendAction(call_state_machine_1.EstablishedActions.UN_MUTE);
|
|
159
214
|
this.phone.client.unmute(this.sipCall);
|
|
160
|
-
this.
|
|
215
|
+
this.emit(exports.EVENT_CALL_UN_MUTED);
|
|
161
216
|
}
|
|
162
217
|
hold() {
|
|
163
218
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -174,7 +229,7 @@ class Call extends events_1.EventEmitter {
|
|
|
174
229
|
yield (0, webrtc_1.downgradeToAudio)(this.sipCall);
|
|
175
230
|
}
|
|
176
231
|
const promise = this.phone.client.hold(this.sipCall, this.isConference(), hasVideo);
|
|
177
|
-
this.
|
|
232
|
+
this.emit(exports.EVENT_CALL_HELD);
|
|
178
233
|
return promise;
|
|
179
234
|
});
|
|
180
235
|
}
|
|
@@ -203,7 +258,7 @@ class Call extends events_1.EventEmitter {
|
|
|
203
258
|
this._onScreenSharing(stream, hadVideo, wasDesktop);
|
|
204
259
|
}
|
|
205
260
|
};
|
|
206
|
-
this.
|
|
261
|
+
this.emit(exports.EVENT_CALL_RESUMED);
|
|
207
262
|
return promise.then(() => {
|
|
208
263
|
const stream = this.getLocalVideoStream();
|
|
209
264
|
if (wasScreensharing) {
|
|
@@ -217,19 +272,37 @@ class Call extends events_1.EventEmitter {
|
|
|
217
272
|
(0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
|
|
218
273
|
logger.info('call - turn camera on', { id: this.id });
|
|
219
274
|
(0, webrtc_1.toggleVideo)(this.sipCall, true);
|
|
220
|
-
this.
|
|
275
|
+
this.emit(exports.EVENT_CAMERA_RESUMED);
|
|
221
276
|
}
|
|
222
277
|
turnCameraOff() {
|
|
223
278
|
(0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
|
|
224
279
|
logger.info('call - turn camera off', { id: this.id });
|
|
225
280
|
(0, webrtc_1.toggleVideo)(this.sipCall, false);
|
|
226
|
-
this.
|
|
281
|
+
this.emit(exports.EVENT_CAMERA_DISABLED);
|
|
282
|
+
}
|
|
283
|
+
isMuted() {
|
|
284
|
+
return this._hasEstablishedState(call_state_machine_1.EstablishedStates.MUTED);
|
|
285
|
+
}
|
|
286
|
+
isCameraMuted() {
|
|
287
|
+
return (0, webrtc_1.isVideoMuted)(this.sipCall);
|
|
227
288
|
}
|
|
228
289
|
isHeld() {
|
|
229
|
-
return
|
|
290
|
+
return this._hasEstablishedState(call_state_machine_1.EstablishedStates.HELD);
|
|
291
|
+
}
|
|
292
|
+
isEstablishing() {
|
|
293
|
+
return this.sipCall.state === session_state_1.SessionState.Establishing;
|
|
230
294
|
}
|
|
231
295
|
isEstablished() {
|
|
232
|
-
return
|
|
296
|
+
return typeof this.state === 'object' && call_state_machine_1.States.ESTABLISHED in this.state;
|
|
297
|
+
}
|
|
298
|
+
isRinging() {
|
|
299
|
+
return this.state === call_state_machine_1.States.RINGING;
|
|
300
|
+
}
|
|
301
|
+
isOutgoing() {
|
|
302
|
+
return this.sipCall instanceof inviter_1.Inviter;
|
|
303
|
+
}
|
|
304
|
+
isIncoming() {
|
|
305
|
+
return !this.isOutgoing();
|
|
233
306
|
}
|
|
234
307
|
isConference() {
|
|
235
308
|
var _a;
|
|
@@ -238,7 +311,7 @@ class Call extends events_1.EventEmitter {
|
|
|
238
311
|
transfer(target) {
|
|
239
312
|
(0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
|
|
240
313
|
logger.info('call - transfer', { id: this.id, target });
|
|
241
|
-
this.phone.client.transfer(this.sipCall, target);
|
|
314
|
+
return this.phone.client.transfer(this.sipCall, target);
|
|
242
315
|
}
|
|
243
316
|
atxfer() {
|
|
244
317
|
(0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
|
|
@@ -366,7 +439,7 @@ class Call extends events_1.EventEmitter {
|
|
|
366
439
|
catch (e) {
|
|
367
440
|
console.warn(e);
|
|
368
441
|
}
|
|
369
|
-
this.
|
|
442
|
+
this.emit(exports.EVENT_SHARE_SCREEN_ENDED);
|
|
370
443
|
this.currentScreenShare = null;
|
|
371
444
|
return reinvited;
|
|
372
445
|
});
|
|
@@ -376,9 +449,13 @@ class Call extends events_1.EventEmitter {
|
|
|
376
449
|
logger.info('call - updrading directly in screensharing mode', { id: this.id, tracks: localStream === null || localStream === void 0 ? void 0 : localStream.getTracks() });
|
|
377
450
|
this._onScreenSharing(localStream, false, desktop);
|
|
378
451
|
}
|
|
452
|
+
onMakeCall() {
|
|
453
|
+
this._bindEvents();
|
|
454
|
+
this._sendAction(call_state_machine_1.Actions.MAKE_CALL);
|
|
455
|
+
}
|
|
379
456
|
onAccepted() {
|
|
380
457
|
this._sendAction(call_state_machine_1.Actions.REMOTLY_ACCEPTED);
|
|
381
|
-
this.emit(exports.
|
|
458
|
+
this.emit(exports.EVENT_CALL_REMOTLY_ACCEPTED);
|
|
382
459
|
}
|
|
383
460
|
onProgress() {
|
|
384
461
|
this.emit(exports.EVENT_PROGRESS);
|
|
@@ -392,10 +469,14 @@ class Call extends events_1.EventEmitter {
|
|
|
392
469
|
onError(error) {
|
|
393
470
|
this.emit(exports.EVENT_CALL_ERROR, error);
|
|
394
471
|
}
|
|
472
|
+
onCallIncoming() {
|
|
473
|
+
this._bindEvents();
|
|
474
|
+
this._sendAction(call_state_machine_1.Actions.INCOMING_CALL);
|
|
475
|
+
}
|
|
395
476
|
onRejected() {
|
|
396
477
|
this.endTime = new Date();
|
|
397
478
|
this.emit(exports.EVENT_CALL_REJECTED);
|
|
398
|
-
this.phone.
|
|
479
|
+
this.phone.onCallTerminated(this);
|
|
399
480
|
}
|
|
400
481
|
onNetworkStats(stats, previousStats) {
|
|
401
482
|
this.emit(exports.EVENT_WEB_RTC_STATS, stats, previousStats);
|
|
@@ -427,15 +508,28 @@ class Call extends events_1.EventEmitter {
|
|
|
427
508
|
onReinvite(request, updatedCalleeName, updatedNumber, hadRemoteVideo) {
|
|
428
509
|
this.emit(exports.EVENT_REINVITE, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
|
|
429
510
|
}
|
|
511
|
+
updateFrom(call) {
|
|
512
|
+
(0, update_from_1.default)(this, call);
|
|
513
|
+
}
|
|
514
|
+
is(otherCall) {
|
|
515
|
+
return otherCall && this.id && this.id === otherCall.id;
|
|
516
|
+
}
|
|
517
|
+
shouldAutoAnswer() {
|
|
518
|
+
var _a;
|
|
519
|
+
return !!((_a = this.sipCall.request) === null || _a === void 0 ? void 0 : _a.getHeader('alert-info'));
|
|
520
|
+
}
|
|
430
521
|
get id() {
|
|
431
|
-
return (0, sdp_1.
|
|
522
|
+
return (0, sdp_1.getSipCallId)(this.sipCall);
|
|
523
|
+
}
|
|
524
|
+
get state() {
|
|
525
|
+
return (0, utils_1.getState)(this.callActor);
|
|
432
526
|
}
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
return identity ? identity.uri._normal.user : null;
|
|
527
|
+
_hasEstablishedState(establishedState) {
|
|
528
|
+
const state = this.state;
|
|
529
|
+
return typeof state === 'object' && call_state_machine_1.States.ESTABLISHED in state && state[call_state_machine_1.States.ESTABLISHED] === establishedState;
|
|
437
530
|
}
|
|
438
531
|
_bindEvents() {
|
|
532
|
+
var _a, _b;
|
|
439
533
|
if (this.sipCall instanceof invitation_1.Invitation) {
|
|
440
534
|
// Monkey patch to know when canceled with the CANCEL message
|
|
441
535
|
const onCancel = this.sipCall._onCancel.bind(this.sipCall);
|
|
@@ -443,21 +537,22 @@ class Call extends events_1.EventEmitter {
|
|
|
443
537
|
logger.trace('call - on sip session canceled', { callId: message.callId, id: this.id });
|
|
444
538
|
onCancel(message);
|
|
445
539
|
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
446
|
-
this.
|
|
540
|
+
this.emit(exports.EVENT_CALL_CANCELED, elsewhere);
|
|
447
541
|
};
|
|
448
542
|
}
|
|
449
|
-
this.sipCall.stateChange.addListener((newState) => {
|
|
543
|
+
(_b = (_a = this.sipCall) === null || _a === void 0 ? void 0 : _a.stateChange) === null || _b === void 0 ? void 0 : _b.addListener((newState) => {
|
|
450
544
|
switch (newState) {
|
|
451
545
|
case session_state_1.SessionState.Terminating:
|
|
452
546
|
logger.info('call - terminating', { id: this.id });
|
|
453
|
-
this.
|
|
547
|
+
this.emit(exports.EVENT_CALL_TERMINATING);
|
|
454
548
|
break;
|
|
455
549
|
case session_state_1.SessionState.Terminated:
|
|
456
550
|
{
|
|
457
551
|
logger.info('call - terminated', { id: this.id });
|
|
458
552
|
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
459
553
|
this.endTime = new Date();
|
|
460
|
-
|
|
554
|
+
this.emit(exports.EVENT_CALL_ENDED);
|
|
555
|
+
return this.phone.onCallTerminated(this);
|
|
461
556
|
}
|
|
462
557
|
default:
|
|
463
558
|
break;
|
|
@@ -484,18 +579,17 @@ class Call extends events_1.EventEmitter {
|
|
|
484
579
|
kind,
|
|
485
580
|
});
|
|
486
581
|
if (kind === 'audio') {
|
|
487
|
-
return this.
|
|
582
|
+
return this.emit(exports.EVENT_AUDIO_STREAM, stream);
|
|
488
583
|
}
|
|
489
|
-
return this.
|
|
584
|
+
return this.emit(exports.EVENT_VIDEO_STREAM, stream, event.track.id, event);
|
|
490
585
|
};
|
|
491
586
|
peerConnection.onremovestream = (event) => {
|
|
492
587
|
logger.info('call - on remove stream called on the peer connection', {
|
|
493
588
|
id: event.stream.id,
|
|
494
589
|
tracks: event.stream.getTracks(),
|
|
495
590
|
});
|
|
496
|
-
this.
|
|
591
|
+
this.emit(exports.EVENT_REMOVE_STREAM, event.stream);
|
|
497
592
|
};
|
|
498
|
-
// Client events
|
|
499
593
|
}
|
|
500
594
|
_downgradeToAudio(withMessage = true) {
|
|
501
595
|
(0, utils_1.assertState)(this.callActor, call_state_machine_1.States.ESTABLISHED);
|
|
@@ -558,7 +652,7 @@ class Call extends events_1.EventEmitter {
|
|
|
558
652
|
if (screenTrack) {
|
|
559
653
|
screenTrack.onended = () => {
|
|
560
654
|
logger.info('call - on screenshare ended', { hadVideo, id: this.id, screenTrack });
|
|
561
|
-
this.
|
|
655
|
+
this.emit(exports.EVENT_SHARE_SCREEN_ENDING);
|
|
562
656
|
};
|
|
563
657
|
}
|
|
564
658
|
this.currentScreenShare = {
|
|
@@ -568,10 +662,12 @@ class Call extends events_1.EventEmitter {
|
|
|
568
662
|
desktop,
|
|
569
663
|
};
|
|
570
664
|
(0, webrtc_1.setLocalMediaStream)(this.sipCall, screenStream);
|
|
571
|
-
this.
|
|
665
|
+
this.emit(exports.EVENT_SHARE_SCREEN_STARTED, screenStream);
|
|
572
666
|
}
|
|
573
667
|
_sendAction(action) {
|
|
668
|
+
const was = this.state;
|
|
574
669
|
this.callActor.send({ type: action });
|
|
670
|
+
logger.trace('call - send action', { action, was, state: this.state });
|
|
575
671
|
}
|
|
576
672
|
}
|
|
577
673
|
exports.default = Call;
|