@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/lib/voice/softphone.js
CHANGED
|
@@ -35,26 +35,31 @@ 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.Softphone = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.EVENT_ON_SIGNAL = exports.EVENT_ON_CHAT = exports.EVENT_ON_MESSAGE = exports.EVENT_VIDEO_INPUT_CHANGE = exports.EVENT_DISCONNECTED = exports.EVENT_UNREGISTERED = exports.EVENT_REGISTERED = exports.EVENT_HEARTBEAT_TIMEOUT = exports.EVENT_HEARTBEAT = exports.EVENT_INCOMING = void 0;
|
|
38
|
+
exports.Softphone = exports.MESSAGE_TYPE_SIGNAL = exports.MESSAGE_TYPE_CHAT = exports.EVENT_ON_SIGNAL = exports.EVENT_ON_CHAT = exports.EVENT_ON_MESSAGE = exports.EVENT_PLAY_INBOUND_CALL_SOUND = exports.EVENT_PLAY_RING_SOUND = exports.EVENT_PLAY_HANGUP_SOUND = exports.EVENT_TERMINATE_SOUND = exports.EVENT_VIDEO_INPUT_CHANGE = exports.EVENT_DISCONNECTED = exports.EVENT_UNREGISTERED = exports.EVENT_REGISTERED = exports.EVENT_HEARTBEAT_TIMEOUT = exports.EVENT_HEARTBEAT = exports.EVENT_OUTGOING = exports.EVENT_INCOMING = void 0;
|
|
39
39
|
/* eslint-disable no-underscore-dangle */
|
|
40
40
|
const events_1 = require("events");
|
|
41
41
|
const xstate_1 = require("xstate");
|
|
42
42
|
const InvalidState_1 = __importDefault(require("../domain/InvalidState"));
|
|
43
43
|
const __1 = __importDefault(require(".."));
|
|
44
44
|
const softphone_state_machine_1 = __importStar(require("../state-machine/softphone-state-machine"));
|
|
45
|
-
const call_state_machine_1 = require("../state-machine/call-state-machine");
|
|
46
45
|
const web_rtc_client_1 = __importDefault(require("../web-rtc-client"));
|
|
47
46
|
const IssueReporter_1 = __importDefault(require("../service/IssueReporter"));
|
|
48
47
|
const sip_logger_1 = __importDefault(require("../utils/sip-logger"));
|
|
49
48
|
const call_1 = __importDefault(require("./call"));
|
|
50
49
|
const utils_1 = require("../state-machine/utils");
|
|
50
|
+
const sdp_1 = require("../utils/sdp");
|
|
51
51
|
exports.EVENT_INCOMING = 'incoming';
|
|
52
|
+
exports.EVENT_OUTGOING = 'outgoing';
|
|
52
53
|
exports.EVENT_HEARTBEAT = 'heartbeat';
|
|
53
54
|
exports.EVENT_HEARTBEAT_TIMEOUT = 'heartbeatTimeout';
|
|
54
55
|
exports.EVENT_REGISTERED = 'registered';
|
|
55
56
|
exports.EVENT_UNREGISTERED = 'unregistered';
|
|
56
57
|
exports.EVENT_DISCONNECTED = 'disconnected';
|
|
57
58
|
exports.EVENT_VIDEO_INPUT_CHANGE = 'videoInputChange';
|
|
59
|
+
exports.EVENT_TERMINATE_SOUND = 'terminateSound';
|
|
60
|
+
exports.EVENT_PLAY_HANGUP_SOUND = 'playHangupSound';
|
|
61
|
+
exports.EVENT_PLAY_RING_SOUND = 'playRingSound';
|
|
62
|
+
exports.EVENT_PLAY_INBOUND_CALL_SOUND = 'playInboundCallSound';
|
|
58
63
|
exports.EVENT_ON_MESSAGE = 'message';
|
|
59
64
|
exports.EVENT_ON_CHAT = 'phone/ON_CHAT';
|
|
60
65
|
exports.EVENT_ON_SIGNAL = 'phone/ON_SIGNAL';
|
|
@@ -64,6 +69,7 @@ const logger = IssueReporter_1.default.loggerFor('softphone');
|
|
|
64
69
|
class Softphone extends events_1.EventEmitter {
|
|
65
70
|
constructor() {
|
|
66
71
|
super();
|
|
72
|
+
this.ringingEnabled = true;
|
|
67
73
|
this.calls = [];
|
|
68
74
|
this.softphoneActor = (0, xstate_1.createActor)(softphone_state_machine_1.default);
|
|
69
75
|
this.softphoneActor.start();
|
|
@@ -75,6 +81,7 @@ class Softphone extends events_1.EventEmitter {
|
|
|
75
81
|
this.audioRingVolume = 1;
|
|
76
82
|
const server = __1.default.Auth.getHost();
|
|
77
83
|
const session = __1.default.Auth.getSession();
|
|
84
|
+
logger.info('softphone - connect', { server, session: !!session });
|
|
78
85
|
if (!server || !session) {
|
|
79
86
|
throw new Error('Please connect to the server using `Wazo.Auth.logIn` or `Wazo.Auth.authenticate` before using Room.connect().');
|
|
80
87
|
}
|
|
@@ -86,14 +93,20 @@ class Softphone extends events_1.EventEmitter {
|
|
|
86
93
|
this.options.userUuid = session.uuid || '';
|
|
87
94
|
return this.connectWithCredentials(server, this.sipLine, session.displayName(), options);
|
|
88
95
|
}
|
|
96
|
+
hangupAllCalls() {
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
return Promise.all(this.calls.map(call => call.hangup()));
|
|
99
|
+
});
|
|
100
|
+
}
|
|
89
101
|
disconnect() {
|
|
90
102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
103
|
(0, utils_1.assertCan)(this.softphoneActor, softphone_state_machine_1.Actions.UNREGISTER);
|
|
92
104
|
if (!this.client) {
|
|
105
|
+
logger.info('softphone - disconnect, not client to disconnect, bailing');
|
|
93
106
|
return null;
|
|
94
107
|
}
|
|
95
108
|
// Terminate all calls
|
|
96
|
-
yield
|
|
109
|
+
yield this.hangupAllCalls();
|
|
97
110
|
return this.client.unregister();
|
|
98
111
|
});
|
|
99
112
|
}
|
|
@@ -104,7 +117,8 @@ class Softphone extends events_1.EventEmitter {
|
|
|
104
117
|
connectWithCredentials(server_1, sipLine_1, displayName_1) {
|
|
105
118
|
return __awaiter(this, arguments, void 0, function* (server, sipLine, displayName, rawOptions = {}) {
|
|
106
119
|
(0, utils_1.assertCan)(this.softphoneActor, softphone_state_machine_1.Actions.REGISTER);
|
|
107
|
-
|
|
120
|
+
logger.info('softphone - connect with credentials', { server, username: sipLine.username, displayName, options: rawOptions });
|
|
121
|
+
this._sendAction(softphone_state_machine_1.Actions.REGISTER);
|
|
108
122
|
const [host, port = 443] = server.split(':');
|
|
109
123
|
let options = Object.assign({}, rawOptions);
|
|
110
124
|
options.media = options.media || {
|
|
@@ -138,19 +152,22 @@ class Softphone extends events_1.EventEmitter {
|
|
|
138
152
|
logger.warn('softphone - calling with empty number, bailing.');
|
|
139
153
|
return Promise.resolve(null);
|
|
140
154
|
}
|
|
141
|
-
if (this.
|
|
142
|
-
throw new InvalidState_1.default(`Invalid state ${softphone_state_machine_1.States.UNREGISTERED}`, softphone_state_machine_1.States.UNREGISTERED);
|
|
143
|
-
}
|
|
144
|
-
if (this.getState() !== softphone_state_machine_1.States.REGISTERING) {
|
|
155
|
+
if (this.state === softphone_state_machine_1.States.REGISTERING) {
|
|
145
156
|
logger.info('softphone - calling when registering, waiting for Softphone to be registered ...');
|
|
146
157
|
yield (0, utils_1.waitUntilState)(this.softphoneActor, softphone_state_machine_1.States.REGISTERED);
|
|
147
158
|
}
|
|
159
|
+
if (this.state !== softphone_state_machine_1.States.REGISTERED) {
|
|
160
|
+
throw new InvalidState_1.default(`Invalid state ${softphone_state_machine_1.States.UNREGISTERED}`, softphone_state_machine_1.States.UNREGISTERED);
|
|
161
|
+
}
|
|
148
162
|
// Hold other calls
|
|
149
163
|
this.holdAllCalls();
|
|
150
164
|
let sipCall;
|
|
151
165
|
try {
|
|
152
166
|
sipCall = this.client.call(options.params.To, options.withCamera, options.audioOnly, options.conference, options);
|
|
153
167
|
const call = new call_1.default(sipCall, this);
|
|
168
|
+
call.onMakeCall();
|
|
169
|
+
this.calls.push(call);
|
|
170
|
+
this.emit(exports.EVENT_OUTGOING, call);
|
|
154
171
|
return call;
|
|
155
172
|
}
|
|
156
173
|
catch (error) {
|
|
@@ -162,11 +179,65 @@ class Softphone extends events_1.EventEmitter {
|
|
|
162
179
|
removeCall(callToRemove) {
|
|
163
180
|
this.calls = this.calls.filter((call) => call.id !== callToRemove.id);
|
|
164
181
|
}
|
|
182
|
+
onCallTerminated(call) {
|
|
183
|
+
logger.info('softphone - on call terminated', { id: call.id });
|
|
184
|
+
const currentCall = this.getCurrentCall();
|
|
185
|
+
const isCurrentCall = (currentCall === null || currentCall === void 0 ? void 0 : currentCall.id) === call.id;
|
|
186
|
+
const isRinging = call.isRinging();
|
|
187
|
+
const isCurrentIncomingCall = isCurrentCall && isRinging;
|
|
188
|
+
const incomingCalls = this.getIncomingCalls();
|
|
189
|
+
const nbIncomingCalls = incomingCalls.length;
|
|
190
|
+
// Send an event to terminate ringing sound
|
|
191
|
+
if (isCurrentIncomingCall) {
|
|
192
|
+
setTimeout(() => {
|
|
193
|
+
// Avoid race condition when the other is calling and hanging up immediately
|
|
194
|
+
this.emit(exports.EVENT_TERMINATE_SOUND, call, 'call terminated');
|
|
195
|
+
}, 5);
|
|
196
|
+
}
|
|
197
|
+
// If the terminated call was an incoming call, we have to re-trigger if it's was the first incoming call
|
|
198
|
+
// Otherwise, we have to re-trigger an incoming call event if another call is incoming
|
|
199
|
+
const shouldRetrigger = isCurrentCall ? nbIncomingCalls : isCurrentIncomingCall;
|
|
200
|
+
// Re-trigger incoming call event for remaining incoming calls
|
|
201
|
+
logger.info('Softphone - check to re-trigger incoming call', { shouldRetrigger, nbIncomingCalls });
|
|
202
|
+
if (shouldRetrigger && nbIncomingCalls > 1) {
|
|
203
|
+
const nextCall = incomingCalls.find(c => c.id !== call.id);
|
|
204
|
+
// Avoid race condition
|
|
205
|
+
setTimeout(() => {
|
|
206
|
+
if (this.ringingEnabled) {
|
|
207
|
+
if (currentCall) {
|
|
208
|
+
this.emit(exports.EVENT_PLAY_RING_SOUND, this.audioRingDeviceId, this.audioRingVolume, nextCall);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this.emit(exports.EVENT_PLAY_INBOUND_CALL_SOUND, this.audioOutputDeviceId, this.audioOutputVolume, nextCall);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this.emit(exports.EVENT_INCOMING, nextCall);
|
|
215
|
+
}, 100);
|
|
216
|
+
}
|
|
217
|
+
// @ts-ignore: does not exist
|
|
218
|
+
if (!call.sipCall.isCanceled) {
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
this.emit(exports.EVENT_PLAY_HANGUP_SOUND, this.audioOutputDeviceId, this.audioOutputVolume, call);
|
|
221
|
+
}, 10);
|
|
222
|
+
}
|
|
223
|
+
this.client.onCallEnded(call.sipCall);
|
|
224
|
+
this.removeCall(call);
|
|
225
|
+
}
|
|
226
|
+
enableRinging() {
|
|
227
|
+
logger.info('softphone - enable ringing');
|
|
228
|
+
this.ringingEnabled = true;
|
|
229
|
+
}
|
|
230
|
+
disableRinging() {
|
|
231
|
+
logger.info('softphone - disable ringing');
|
|
232
|
+
this.ringingEnabled = false;
|
|
233
|
+
}
|
|
165
234
|
holdAllCalls(exceptCall = null) {
|
|
166
|
-
|
|
235
|
+
logger.info('softphone - hold all calls', { exceptId: exceptCall === null || exceptCall === void 0 ? void 0 : exceptCall.id, ids: this.calls.map(call => call.id) });
|
|
236
|
+
this.calls.filter(call => !call.isHeld() && call.id !== (exceptCall === null || exceptCall === void 0 ? void 0 : exceptCall.id)).forEach(call => call.hold());
|
|
167
237
|
}
|
|
168
238
|
startHeartbeat() {
|
|
169
|
-
|
|
239
|
+
var _a;
|
|
240
|
+
logger.info('softphone - start heartbeat', { client: !!this.client, hasHeartbeat: (_a = this.client) === null || _a === void 0 ? void 0 : _a.hasHeartbeat() });
|
|
170
241
|
if (!this.client || this.client.hasHeartbeat()) {
|
|
171
242
|
return;
|
|
172
243
|
}
|
|
@@ -216,29 +287,54 @@ class Softphone extends events_1.EventEmitter {
|
|
|
216
287
|
logger.info('softphone - changing ring volume', { volume });
|
|
217
288
|
this.audioRingVolume = volume;
|
|
218
289
|
}
|
|
219
|
-
getCalls() {
|
|
220
|
-
return this.calls;
|
|
221
|
-
}
|
|
222
290
|
getCurrentCall() {
|
|
223
|
-
return this.
|
|
291
|
+
return this.getActiveCalls()[0];
|
|
292
|
+
}
|
|
293
|
+
getActiveCalls() {
|
|
294
|
+
return this.calls.filter(call => call.isEstablished());
|
|
295
|
+
}
|
|
296
|
+
getIncomingCalls() {
|
|
297
|
+
return this.calls.filter(call => call.isRinging());
|
|
298
|
+
}
|
|
299
|
+
get state() {
|
|
300
|
+
return (0, utils_1.getState)(this.softphoneActor);
|
|
224
301
|
}
|
|
225
|
-
|
|
226
|
-
|
|
302
|
+
get user() {
|
|
303
|
+
var _a, _b, _c, _d;
|
|
304
|
+
return (_d = (_c = (_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.contact) === null || _c === void 0 ? void 0 : _c.uri) === null || _d === void 0 ? void 0 : _d.user;
|
|
227
305
|
}
|
|
228
306
|
getUserAgent() {
|
|
229
307
|
var _a, _b;
|
|
230
308
|
return ((_b = (_a = this.client) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.userAgentString) || 'softphone';
|
|
231
309
|
}
|
|
310
|
+
isRegistering() {
|
|
311
|
+
return this.state === softphone_state_machine_1.States.REGISTERING;
|
|
312
|
+
}
|
|
313
|
+
isRegistered() {
|
|
314
|
+
return this.state === softphone_state_machine_1.States.REGISTERED;
|
|
315
|
+
}
|
|
316
|
+
isUnRegistered() {
|
|
317
|
+
return this.state === softphone_state_machine_1.States.UNREGISTERED;
|
|
318
|
+
}
|
|
232
319
|
_bindEvents() {
|
|
233
320
|
this.client.on(this.client.INVITE, (sipSession) => {
|
|
234
321
|
const call = new call_1.default(sipSession, this);
|
|
235
|
-
|
|
322
|
+
logger.info('softphone - on invite', { callId: call.id, number: call.number });
|
|
323
|
+
call.onCallIncoming();
|
|
236
324
|
this.calls.push(call);
|
|
237
|
-
this.
|
|
325
|
+
this.emit(exports.EVENT_INCOMING, call);
|
|
326
|
+
if (!this.getCurrentCall()) {
|
|
327
|
+
if (this.ringingEnabled) {
|
|
328
|
+
this.emit(exports.EVENT_PLAY_RING_SOUND, this.audioRingDeviceId, this.audioRingVolume, call);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
this.emit(exports.EVENT_PLAY_INBOUND_CALL_SOUND, this.audioOutputDeviceId, this.audioOutputVolume, call);
|
|
333
|
+
}
|
|
238
334
|
});
|
|
239
335
|
this.client.on(this.client.ON_REINVITE, (sipCall, request, updatedCalleeName, updatedNumber, hadRemoteVideo) => {
|
|
240
336
|
logger.info('softphone - on reinvite', {
|
|
241
|
-
callId: sipCall
|
|
337
|
+
callId: (0, sdp_1.getSipCallId)(sipCall),
|
|
242
338
|
inviteId: request.callId,
|
|
243
339
|
updatedCalleeName,
|
|
244
340
|
updatedNumber,
|
|
@@ -247,6 +343,8 @@ class Softphone extends events_1.EventEmitter {
|
|
|
247
343
|
this._onCallEvent(sipCall, 'onReinvite', request, updatedCalleeName, updatedNumber, hadRemoteVideo);
|
|
248
344
|
});
|
|
249
345
|
this.client.on(this.client.ACCEPTED, (sipCall) => __awaiter(this, void 0, void 0, function* () {
|
|
346
|
+
const call = this._getCall(sipCall);
|
|
347
|
+
this.emit(exports.EVENT_TERMINATE_SOUND, call, 'call accepted');
|
|
250
348
|
this._onCallEvent(sipCall, 'onAccepted');
|
|
251
349
|
if (this.audioOutputDeviceId) {
|
|
252
350
|
yield this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -276,23 +374,31 @@ class Softphone extends events_1.EventEmitter {
|
|
|
276
374
|
});
|
|
277
375
|
this.client.on(this.client.UNREGISTERED, () => {
|
|
278
376
|
logger.info('softphone - unregistered');
|
|
279
|
-
this.
|
|
280
|
-
|
|
377
|
+
if (!(0, utils_1.can)(this.softphoneActor, softphone_state_machine_1.Actions.UNREGISTER)) {
|
|
378
|
+
logger.warn('softphone - cannot unregister', { state: this.state });
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
this._sendAction(softphone_state_machine_1.Actions.UNREGISTER);
|
|
382
|
+
this.emit(exports.EVENT_UNREGISTERED);
|
|
281
383
|
});
|
|
282
384
|
this.client.on(this.client.ON_DISCONNECTED, () => {
|
|
283
385
|
logger.info('softphone - disconnected');
|
|
284
|
-
this.
|
|
386
|
+
if (!(0, utils_1.can)(this.softphoneActor, softphone_state_machine_1.Actions.TRANSPORT_CLOSED)) {
|
|
387
|
+
logger.warn('softphone - cannot disconnected', { state: this.state });
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
285
390
|
this._sendAction(softphone_state_machine_1.Actions.TRANSPORT_CLOSED);
|
|
391
|
+
this.emit(exports.EVENT_DISCONNECTED);
|
|
286
392
|
});
|
|
287
393
|
this.client.on(this.client.REGISTERED, () => {
|
|
288
394
|
logger.info('softphone - registered', { state: (0, utils_1.getState)(this.softphoneActor) });
|
|
289
395
|
if (!(0, utils_1.can)(this.softphoneActor, softphone_state_machine_1.Actions.REGISTER_DONE)) {
|
|
290
|
-
logger.warn('softphone - registered but not in REGISTERING state', { state:
|
|
396
|
+
logger.warn('softphone - registered but not in REGISTERING state', { state: this.state });
|
|
291
397
|
return;
|
|
292
398
|
}
|
|
293
399
|
this.stopHeartbeat();
|
|
294
400
|
this._sendAction(softphone_state_machine_1.Actions.REGISTER_DONE);
|
|
295
|
-
this.
|
|
401
|
+
this.emit(exports.EVENT_REGISTERED);
|
|
296
402
|
// If the phone registered with a current callSession (eg: when switching network):
|
|
297
403
|
// send a reinvite to renegociate ICE with new IP
|
|
298
404
|
if (this.shouldSendReinvite) {
|
|
@@ -303,12 +409,16 @@ class Softphone extends events_1.EventEmitter {
|
|
|
303
409
|
}
|
|
304
410
|
});
|
|
305
411
|
this.client.on(this.client.CONNECTED, () => {
|
|
306
|
-
logger.info('softphone - connected');
|
|
412
|
+
logger.info('softphone - connected', { state: this.state });
|
|
307
413
|
this.stopHeartbeat();
|
|
308
414
|
});
|
|
415
|
+
this.client.on(this.client.REGISTERING, () => {
|
|
416
|
+
logger.info('softphone - registering', { state: this.state });
|
|
417
|
+
this._sendAction(softphone_state_machine_1.Actions.REGISTER);
|
|
418
|
+
});
|
|
309
419
|
this.client.on(this.client.DISCONNECTED, () => {
|
|
310
420
|
logger.info('softphone - disconnected');
|
|
311
|
-
this.
|
|
421
|
+
this.emit(exports.EVENT_DISCONNECTED);
|
|
312
422
|
// Do not trigger heartbeat if already running
|
|
313
423
|
if (!this.client.hasHeartbeat()) {
|
|
314
424
|
this.startHeartbeat();
|
|
@@ -317,30 +427,35 @@ class Softphone extends events_1.EventEmitter {
|
|
|
317
427
|
this.shouldSendReinvite = this.calls.length > 0;
|
|
318
428
|
});
|
|
319
429
|
this.client.on('onVideoInputChange', stream => {
|
|
320
|
-
this.
|
|
430
|
+
this.emit(exports.EVENT_VIDEO_INPUT_CHANGE, stream);
|
|
321
431
|
});
|
|
322
432
|
this.client.on(this.client.MESSAGE, (message) => {
|
|
323
433
|
this._onMessage(message);
|
|
324
|
-
this.
|
|
434
|
+
this.emit(exports.EVENT_ON_MESSAGE, message);
|
|
325
435
|
});
|
|
326
436
|
this.client.setOnHeartbeatTimeout(() => {
|
|
327
|
-
this.
|
|
437
|
+
this.emit(exports.EVENT_HEARTBEAT_TIMEOUT);
|
|
328
438
|
});
|
|
329
439
|
this.client.setOnHeartbeatCallback(() => {
|
|
330
|
-
this.
|
|
440
|
+
this.emit(exports.EVENT_HEARTBEAT);
|
|
331
441
|
});
|
|
332
442
|
}
|
|
333
443
|
_sendAction(action) {
|
|
444
|
+
const was = this.state;
|
|
334
445
|
this.softphoneActor.send({ type: action });
|
|
446
|
+
logger.trace('softphone - send action', { action, was, state: this.state });
|
|
335
447
|
}
|
|
336
448
|
_getCall(sipCall) {
|
|
337
|
-
return this.calls.find(call => call.id ===
|
|
449
|
+
return this.calls.find(call => call.id === (0, sdp_1.getSipCallId)(sipCall));
|
|
450
|
+
}
|
|
451
|
+
_getCallIds() {
|
|
452
|
+
return this.calls.map(call => call.id);
|
|
338
453
|
}
|
|
339
454
|
_onCallEvent(sipCall, eventName, ...args) {
|
|
340
|
-
logger.
|
|
455
|
+
logger.info('softphone - received call event', { eventName, sipId: (0, sdp_1.getSipCallId)(sipCall) });
|
|
341
456
|
const call = this._getCall(sipCall);
|
|
342
457
|
if (!call) {
|
|
343
|
-
logger.warn('softphone - no call found to send the event', { eventName, sipId: sipCall.
|
|
458
|
+
logger.warn('softphone - no call found to send the event', { eventName, sipId: (0, sdp_1.getSipCallId)(sipCall), ids: this._getCallIds() });
|
|
344
459
|
return;
|
|
345
460
|
}
|
|
346
461
|
// @ts-ignore
|
|
@@ -360,11 +475,11 @@ class Softphone extends events_1.EventEmitter {
|
|
|
360
475
|
const { type, content, } = body;
|
|
361
476
|
switch (type) {
|
|
362
477
|
case exports.MESSAGE_TYPE_CHAT:
|
|
363
|
-
this.
|
|
478
|
+
this.emit(exports.EVENT_ON_CHAT, content);
|
|
364
479
|
break;
|
|
365
480
|
case exports.MESSAGE_TYPE_SIGNAL:
|
|
366
481
|
{
|
|
367
|
-
this.
|
|
482
|
+
this.emit(exports.EVENT_ON_SIGNAL, content);
|
|
368
483
|
break;
|
|
369
484
|
}
|
|
370
485
|
default:
|