@exotel-npm-dev/webrtc-client-sdk 2.0.5 → 3.0.2
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/Changelog +4 -4
- package/Makefile +2 -2
- package/dist/exotelsdk.js +1940 -1593
- package/dist/exotelsdk.js.map +1 -1
- package/index.js +2 -1
- package/package.json +2 -2
- package/src/api/callAPI/Call.js +17 -13
- package/src/api/omAPI/Diagnostics.js +48 -19
- package/src/api/omAPI/DiagnosticsListener.js +19 -8
- package/src/api/registerAPI/RegisterListener.js +2 -2
- package/src/listeners/CallListener.js +28 -31
- package/src/listeners/Callback.js +59 -50
- package/src/listeners/ExWebClient.js +224 -208
- package/src/listeners/ExotelVoiceClientListener.js +18 -7
- package/src/listeners/SessionListeners.js +114 -96
|
@@ -2,22 +2,21 @@ import { Call } from "../api/callAPI/Call";
|
|
|
2
2
|
import { DoRegister as DoRegisterRL, UnRegister as UnRegisterRL } from '../api/registerAPI/RegisterListener';
|
|
3
3
|
import { CallListener } from '../listeners/CallListener';
|
|
4
4
|
import { ExotelVoiceClientListener } from '../listeners/ExotelVoiceClientListener';
|
|
5
|
-
import { SessionListener
|
|
5
|
+
import { SessionListener } from '../listeners/SessionListeners';
|
|
6
6
|
import { CallController } from "./CallCtrlerDummy";
|
|
7
7
|
|
|
8
8
|
import { closeDiagnostics as closeDiagnosticsDL, initDiagnostics as initDiagnosticsDL, startMicDiagnosticsTest as startMicDiagnosticsTestDL, startNetworkDiagnostics as startNetworkDiagnosticsDL, startSpeakerDiagnosticsTest as startSpeakerDiagnosticsTestDL, stopMicDiagnosticsTest as stopMicDiagnosticsTestDL, stopNetworkDiagnostics as stopNetworkDiagnosticsDL, stopSpeakerDiagnosticsTest as stopSpeakerDiagnosticsTestDL } from '../api/omAPI/DiagnosticsListener';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { Callback, RegisterCallback, SessionCallback } from '../listeners/Callback';
|
|
11
11
|
import { webrtcTroubleshooterEventBus } from "./Callback";
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { WebrtcSIPPhone, getLogger } from "@exotel-npm-dev/webrtc-core-sdk";
|
|
14
14
|
import { CallDetails } from "../api/callAPI/CallDetails";
|
|
15
15
|
import LogManager from '../api/LogManager.js';
|
|
16
|
-
|
|
16
|
+
const phonePool = new Map();
|
|
17
17
|
var intervalId;
|
|
18
18
|
var intervalIDMap = new Map();
|
|
19
|
-
|
|
20
|
-
var logger = webrtcSIPPhone.getLogger();
|
|
19
|
+
const logger = getLogger();
|
|
21
20
|
|
|
22
21
|
function sleep(ms) {
|
|
23
22
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
@@ -27,136 +26,122 @@ function sleep(ms) {
|
|
|
27
26
|
* FQDN for fetching IP
|
|
28
27
|
*/
|
|
29
28
|
function fetchPublicIP(sipAccountInfo) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
var publicIp = "";
|
|
31
|
+
const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
|
|
32
|
+
pc.createDataChannel('');
|
|
33
|
+
pc.createOffer().then(offer => pc.setLocalDescription(offer))
|
|
34
|
+
pc.onicecandidate = (ice) => {
|
|
35
|
+
if (!ice || !ice.candidate || !ice.candidate.candidate) {
|
|
36
|
+
pc.close();
|
|
37
|
+
resolve();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
logger.log("iceCandidate =" + ice.candidate.candidate);
|
|
41
|
+
let split = ice.candidate.candidate.split(" ");
|
|
42
|
+
if (split[7] === "host") {
|
|
43
|
+
logger.log(`fetchPublicIP:Local IP : ${split[4]}`);
|
|
44
|
+
} else {
|
|
45
|
+
logger.log(`fetchPublicIP:External IP : ${split[4]}`);
|
|
46
|
+
publicIp = `${split[4]}`
|
|
47
|
+
logger.log("fetchPublicIP:Public IP :" + publicIp);
|
|
48
|
+
localStorage.setItem("contactHost", publicIp);
|
|
49
|
+
pc.close();
|
|
50
|
+
resolve();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
logger.log("fetchPublicIP: public ip = ", publicIp)
|
|
55
|
+
if (publicIp == "") {
|
|
56
|
+
sipAccountInfo.contactHost = window.localStorage.getItem('contactHost');
|
|
57
|
+
} else {
|
|
58
|
+
sipAccountInfo.contactHost = publicIp;
|
|
59
|
+
}
|
|
60
|
+
resolve();
|
|
61
|
+
}, 1000);
|
|
59
62
|
});
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
+
}
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
class ExDelegationHandler {
|
|
66
|
+
constructor(exClient) {
|
|
67
|
+
this.exClient = exClient;
|
|
68
|
+
this.sessionCallback = exClient.sessionCallback;
|
|
69
|
+
}
|
|
70
|
+
setTestingMode(mode) {
|
|
67
71
|
logger.log("delegationHandler: setTestingMode\n");
|
|
68
72
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
logger.log("delegationHandler: onCallStatSipJsSessionEvent",ev);
|
|
73
|
+
onCallStatSipJsSessionEvent(ev) {
|
|
74
|
+
logger.log("delegationHandler: onCallStatSipJsSessionEvent", ev);
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
this.sendWebRTCEventsToFSM = function (eventType, sipMethod) {
|
|
76
|
+
sendWebRTCEventsToFSM(eventType, sipMethod) {
|
|
75
77
|
logger.log("delegationHandler: sendWebRTCEventsToFSM\n");
|
|
76
78
|
logger.log("delegationHandler: eventType\n", eventType);
|
|
77
79
|
logger.log("delegationHandler: sipMethod\n", sipMethod);
|
|
80
|
+
|
|
78
81
|
if (sipMethod == "CONNECTION") {
|
|
79
|
-
exClient.registerEventCallback(eventType, exClient.userName)
|
|
82
|
+
this.exClient.registerEventCallback(eventType, this.exClient.userName);
|
|
80
83
|
} else if (sipMethod == "CALL") {
|
|
81
|
-
exClient.callEventCallback(eventType, exClient.callFromNumber, exClient.call)
|
|
84
|
+
this.exClient.callEventCallback(eventType, this.exClient.callFromNumber, this.exClient.call);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
|
-
|
|
85
|
-
this.playBeepTone = function () {
|
|
87
|
+
playBeepTone() {
|
|
86
88
|
logger.log("delegationHandler: playBeepTone\n");
|
|
87
89
|
}
|
|
88
|
-
|
|
89
|
-
this.onStatPeerConnectionIceGatheringStateChange = function (iceGatheringState) {
|
|
90
|
+
onStatPeerConnectionIceGatheringStateChange(iceGatheringState) {
|
|
90
91
|
logger.log("delegationHandler: onStatPeerConnectionIceGatheringStateChange\n");
|
|
91
|
-
sessionCallback.initializeSession(`ice_gathering_state_${iceGatheringState}`, exClient.callFromNumber);
|
|
92
|
-
sessionCallback.triggerSessionCallback();
|
|
92
|
+
this.sessionCallback.initializeSession(`ice_gathering_state_${iceGatheringState}`, this.exClient.callFromNumber);
|
|
93
|
+
this.sessionCallback.triggerSessionCallback();
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
-
this.onCallStatIceCandidate = function (ev, icestate) {
|
|
95
|
+
onCallStatIceCandidate(ev, icestate) {
|
|
96
96
|
logger.log("delegationHandler: onCallStatIceCandidate\n");
|
|
97
97
|
}
|
|
98
|
-
|
|
99
|
-
this.onCallStatNegoNeeded = function (icestate) {
|
|
98
|
+
onCallStatNegoNeeded(icestate) {
|
|
100
99
|
logger.log("delegationHandler: onCallStatNegoNeeded\n");
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
this.onCallStatSignalingStateChange = function (cstate) {
|
|
101
|
+
onCallStatSignalingStateChange(cstate) {
|
|
104
102
|
logger.log("delegationHandler: onCallStatSignalingStateChange\n");
|
|
105
103
|
}
|
|
106
|
-
|
|
107
|
-
this.onStatPeerConnectionIceConnectionStateChange = function (iceConnectionState) {
|
|
104
|
+
onStatPeerConnectionIceConnectionStateChange(iceConnectionState) {
|
|
108
105
|
logger.log("delegationHandler: onStatPeerConnectionIceConnectionStateChange\n");
|
|
109
|
-
sessionCallback.initializeSession(`ice_connection_state_${iceConnectionState}`, exClient.callFromNumber);
|
|
110
|
-
sessionCallback.triggerSessionCallback();
|
|
106
|
+
this.sessionCallback.initializeSession(`ice_connection_state_${iceConnectionState}`, this.exClient.callFromNumber);
|
|
107
|
+
this.sessionCallback.triggerSessionCallback();
|
|
111
108
|
}
|
|
112
|
-
|
|
113
|
-
this.onStatPeerConnectionConnectionStateChange = function () {
|
|
109
|
+
onStatPeerConnectionConnectionStateChange() {
|
|
114
110
|
logger.log("delegationHandler: onStatPeerConnectionConnectionStateChange\n");
|
|
115
111
|
}
|
|
116
|
-
|
|
117
|
-
this.onGetUserMediaSuccessCallstatCallback = function () {
|
|
112
|
+
onGetUserMediaSuccessCallstatCallback() {
|
|
118
113
|
logger.log("delegationHandler: onGetUserMediaSuccessCallstatCallback\n");
|
|
119
114
|
}
|
|
120
|
-
|
|
121
|
-
this.onGetUserMediaErrorCallstatCallback = function () {
|
|
115
|
+
onGetUserMediaErrorCallstatCallback() {
|
|
122
116
|
logger.log("delegationHandler: onGetUserMediaErrorCallstatCallback\n");
|
|
123
|
-
sessionCallback.initializeSession(`media_permission_denied`, exClient.callFromNumber);
|
|
124
|
-
sessionCallback.triggerSessionCallback();
|
|
125
|
-
|
|
117
|
+
this.sessionCallback.initializeSession(`media_permission_denied`, this.exClient.callFromNumber);
|
|
118
|
+
this.sessionCallback.triggerSessionCallback();
|
|
126
119
|
}
|
|
127
|
-
|
|
128
|
-
this.onCallStatAddStream = function () {
|
|
120
|
+
onCallStatAddStream() {
|
|
129
121
|
logger.log("delegationHandler: onCallStatAddStream\n");
|
|
130
122
|
}
|
|
131
|
-
|
|
132
|
-
this.onCallStatRemoveStream = function () {
|
|
123
|
+
onCallStatRemoveStream() {
|
|
133
124
|
logger.log("delegationHandler: onCallStatRemoveStream\n");
|
|
134
125
|
}
|
|
135
|
-
|
|
136
|
-
this.setWebRTCFSMMapper = function (stack) {
|
|
126
|
+
setWebRTCFSMMapper(stack) {
|
|
137
127
|
logger.log("delegationHandler: setWebRTCFSMMapper : Initialisation complete \n");
|
|
138
128
|
}
|
|
139
|
-
|
|
140
|
-
this.onCallStatSipJsTransportEvent = function () {
|
|
129
|
+
onCallStatSipJsTransportEvent() {
|
|
141
130
|
logger.log("delegationHandler: onCallStatSipJsTransportEvent\n");
|
|
142
131
|
}
|
|
143
|
-
|
|
144
|
-
this.onCallStatSipSendCallback = function () {
|
|
132
|
+
onCallStatSipSendCallback() {
|
|
145
133
|
logger.log("delegationHandler: onCallStatSipSendCallback\n");
|
|
146
134
|
}
|
|
147
|
-
|
|
148
|
-
this.onCallStatSipRecvCallback = function () {
|
|
135
|
+
onCallStatSipRecvCallback() {
|
|
149
136
|
logger.log("delegationHandler: onCallStatSipRecvCallback\n");
|
|
150
137
|
}
|
|
151
|
-
|
|
152
|
-
this.stopCallStat = function () {
|
|
138
|
+
stopCallStat() {
|
|
153
139
|
logger.log("delegationHandler: stopCallStat\n");
|
|
154
140
|
}
|
|
155
|
-
|
|
156
|
-
this.onRecieveInvite = function (incomingSession) {
|
|
141
|
+
onRecieveInvite(incomingSession) {
|
|
157
142
|
logger.log("delegationHandler: onRecieveInvite\n");
|
|
158
143
|
const obj = incomingSession.incomingInviteRequest.message.headers;
|
|
159
|
-
exClient.callFromNumber = incomingSession.incomingInviteRequest.message.from.displayName;
|
|
144
|
+
this.exClient.callFromNumber = incomingSession.incomingInviteRequest.message.from.displayName;
|
|
160
145
|
if (obj.hasOwnProperty("X-Exotel-Callsid")) {
|
|
161
146
|
CallDetails.callSid = obj['X-Exotel-Callsid'][0].raw;
|
|
162
147
|
}
|
|
@@ -178,45 +163,41 @@ export function ExDelegationHandler(exClient_) {
|
|
|
178
163
|
}
|
|
179
164
|
CallDetails.sipHeaders = result;
|
|
180
165
|
}
|
|
181
|
-
|
|
182
|
-
this.onPickCall = function () {
|
|
166
|
+
onPickCall() {
|
|
183
167
|
logger.log("delegationHandler: onPickCall\n");
|
|
184
168
|
}
|
|
185
|
-
|
|
186
|
-
this.onRejectCall = function () {
|
|
169
|
+
onRejectCall() {
|
|
187
170
|
logger.log("delegationHandler: onRejectCall\n");
|
|
188
171
|
}
|
|
189
|
-
|
|
190
|
-
this.onCreaterAnswer = function () {
|
|
172
|
+
onCreaterAnswer() {
|
|
191
173
|
logger.log("delegationHandler: onCreaterAnswer\n");
|
|
192
174
|
}
|
|
193
|
-
|
|
194
|
-
this.onSettingLocalDesc = function () {
|
|
175
|
+
onSettingLocalDesc() {
|
|
195
176
|
logger.log("delegationHandler: onSettingLocalDesc\n");
|
|
196
177
|
}
|
|
197
|
-
|
|
198
|
-
this.initGetStats = function (pc, callid, username) {
|
|
178
|
+
initGetStats(pc, callid, username) {
|
|
199
179
|
logger.log("delegationHandler: initGetStats\n");
|
|
200
180
|
}
|
|
201
|
-
|
|
202
|
-
this.onRegisterWebRTCSIPEngine = function (engine) {
|
|
181
|
+
onRegisterWebRTCSIPEngine(engine) {
|
|
203
182
|
logger.log("delegationHandler: onRegisterWebRTCSIPEngine, engine=\n", engine);
|
|
204
183
|
}
|
|
205
184
|
}
|
|
206
185
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
this.onFailure = function () {
|
|
186
|
+
class ExSynchronousHandler {
|
|
187
|
+
onFailure() {
|
|
210
188
|
logger.log("synchronousHandler: onFailure, phone is offline.\n");
|
|
211
189
|
}
|
|
212
|
-
|
|
213
|
-
this.onResponse = function () {
|
|
190
|
+
onResponse() {
|
|
214
191
|
logger.log("synchronousHandler: onResponse, phone is connected.\n");
|
|
215
192
|
}
|
|
216
193
|
}
|
|
217
194
|
|
|
218
|
-
export
|
|
195
|
+
export { ExDelegationHandler, ExSynchronousHandler };
|
|
219
196
|
|
|
197
|
+
export class ExotelWebClient {
|
|
198
|
+
/**
|
|
199
|
+
* @param {Object} sipAccntInfo
|
|
200
|
+
*/
|
|
220
201
|
|
|
221
202
|
|
|
222
203
|
ctrlr = null;
|
|
@@ -228,45 +209,74 @@ export class ExotelWebClient {
|
|
|
228
209
|
unregisterInitiated = false;
|
|
229
210
|
registrationInProgress = false;
|
|
230
211
|
isReadyToRegister = true;
|
|
231
|
-
|
|
232
|
-
//this.webRTCPhones = {};
|
|
212
|
+
|
|
233
213
|
|
|
234
214
|
sipAccountInfo = null;
|
|
235
215
|
clientSDKLoggerCallback = null;
|
|
236
|
-
|
|
216
|
+
callbacks = null;
|
|
217
|
+
registerCallback = null;
|
|
218
|
+
sessionCallback = null;
|
|
219
|
+
logger = getLogger();
|
|
220
|
+
|
|
237
221
|
constructor() {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
222
|
+
// Initialize properties
|
|
223
|
+
this.ctrlr = null;
|
|
224
|
+
this.call = null;
|
|
225
|
+
this.eventListener = null;
|
|
226
|
+
this.callListener = null;
|
|
227
|
+
this.callFromNumber = null;
|
|
228
|
+
this.shouldAutoRetry = false;
|
|
229
|
+
this.unregisterInitiated = false;
|
|
230
|
+
this.registrationInProgress = false;
|
|
231
|
+
this.currentSIPUserName = "";
|
|
232
|
+
this.isReadyToRegister = true;
|
|
233
|
+
this.sipAccountInfo = null;
|
|
234
|
+
this.clientSDKLoggerCallback = null;
|
|
235
|
+
this.callbacks = new Callback();
|
|
236
|
+
this.registerCallback = new RegisterCallback();
|
|
237
|
+
this.sessionCallback = new SessionCallback();
|
|
238
|
+
this.logger = getLogger();
|
|
239
|
+
|
|
240
|
+
// Register logger callback
|
|
242
241
|
let exwebClientOb = this;
|
|
243
|
-
logger.registerLoggerCallback(
|
|
244
|
-
|
|
242
|
+
this.logger.registerLoggerCallback((type, message, args) => {
|
|
245
243
|
LogManager.onLog(type, message, args);
|
|
246
|
-
if (exwebClientOb.clientSDKLoggerCallback)
|
|
244
|
+
if (exwebClientOb.clientSDKLoggerCallback) {
|
|
247
245
|
exwebClientOb.clientSDKLoggerCallback("log", message, args);
|
|
248
|
-
|
|
246
|
+
}
|
|
249
247
|
});
|
|
250
|
-
|
|
248
|
+
}
|
|
251
249
|
|
|
252
250
|
|
|
253
|
-
initWebrtc = (sipAccountInfo_,
|
|
251
|
+
initWebrtc = async (sipAccountInfo_,
|
|
254
252
|
RegisterEventCallBack, CallListenerCallback, SessionCallback, enableAutoAudioDeviceChangeHandling=false) => {
|
|
253
|
+
const userName = sipAccountInfo_?.userName;
|
|
254
|
+
if (!userName) return false;
|
|
255
|
+
|
|
256
|
+
// --- Duplicate registration guard ---
|
|
257
|
+
if (phonePool.has(userName)) {
|
|
258
|
+
if (this.currentSIPUserName == "" || this.currentSIPUserName !== userName) {
|
|
259
|
+
logger.warn(`ExWebClient: initWebrtc: [Dup‑Reg] ${userName} already in use – init rejected`);
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
this.currentSIPUserName = userName;
|
|
264
|
+
phonePool.set(userName, null);
|
|
255
265
|
|
|
256
266
|
if (!this.eventListener) {
|
|
257
|
-
this.eventListener = new ExotelVoiceClientListener();
|
|
267
|
+
this.eventListener = new ExotelVoiceClientListener(this.registerCallback);
|
|
258
268
|
}
|
|
259
269
|
|
|
260
270
|
if (!this.callListener) {
|
|
261
|
-
this.callListener = new CallListener();
|
|
271
|
+
this.callListener = new CallListener(this.callbacks);
|
|
262
272
|
}
|
|
263
273
|
|
|
264
|
-
if (!this.
|
|
265
|
-
this.
|
|
274
|
+
if (!this.sessionListener) {
|
|
275
|
+
this.sessionListener = new SessionListener(this.sessionCallback);
|
|
266
276
|
}
|
|
267
277
|
|
|
268
|
-
if (!this.
|
|
269
|
-
this.
|
|
278
|
+
if (!this.ctrlr) {
|
|
279
|
+
this.ctrlr = new CallController();
|
|
270
280
|
}
|
|
271
281
|
|
|
272
282
|
sipAccountInfo_.enableAutoAudioDeviceChangeHandling = enableAutoAudioDeviceChangeHandling;
|
|
@@ -276,12 +286,37 @@ export class ExotelWebClient {
|
|
|
276
286
|
return false;
|
|
277
287
|
}
|
|
278
288
|
this.sipAccountInfo["sipUri"] = "wss://" + this.sipAccountInfo["userName"] + "@" + this.sipAccountInfo["sipdomain"] + ":" + this.sipAccountInfo["port"];
|
|
279
|
-
|
|
280
|
-
callbacks
|
|
281
|
-
registerCallback
|
|
289
|
+
|
|
290
|
+
// Register callbacks using the correct methods
|
|
291
|
+
this.callbacks.registerCallback('call', CallListenerCallback);
|
|
292
|
+
this.registerCallback.initializeRegisterCallback(RegisterEventCallBack);
|
|
282
293
|
logger.log("ExWebClient: initWebrtc: Initializing session callback")
|
|
283
|
-
sessionCallback.initializeSessionCallback(SessionCallback);
|
|
294
|
+
this.sessionCallback.initializeSessionCallback(SessionCallback);
|
|
284
295
|
this.setEventListener(this.eventListener);
|
|
296
|
+
|
|
297
|
+
// Wait for public IP before registering
|
|
298
|
+
await fetchPublicIP(this.sipAccountInfo);
|
|
299
|
+
|
|
300
|
+
// Create phone instance if it wasn't created in constructor
|
|
301
|
+
if (!this.phone) {
|
|
302
|
+
this.userName = this.sipAccountInfo.userName;
|
|
303
|
+
let phone = phonePool.get(this.userName);
|
|
304
|
+
if (!phone) {
|
|
305
|
+
phone = new WebrtcSIPPhone(this.userName);
|
|
306
|
+
phonePool.set(this.userName, phone);
|
|
307
|
+
}
|
|
308
|
+
this.phone = phone;
|
|
309
|
+
this.webrtcSIPPhone = this.phone;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Initialize the phone with SIP engine
|
|
313
|
+
this.webrtcSIPPhone.registerPhone("sipjs", new ExDelegationHandler(this), this.sipAccountInfo.enableAutoAudioDeviceChangeHandling);
|
|
314
|
+
|
|
315
|
+
// Create call instance after phone is initialized
|
|
316
|
+
if (!this.call) {
|
|
317
|
+
this.call = new Call(this.webrtcSIPPhone);
|
|
318
|
+
}
|
|
319
|
+
|
|
285
320
|
return true;
|
|
286
321
|
};
|
|
287
322
|
|
|
@@ -309,11 +344,11 @@ export class ExotelWebClient {
|
|
|
309
344
|
};
|
|
310
345
|
|
|
311
346
|
startSpeakerDiagnosticsTest = () => {
|
|
312
|
-
startSpeakerDiagnosticsTestDL()
|
|
347
|
+
startSpeakerDiagnosticsTestDL(this.webrtcSIPPhone);
|
|
313
348
|
};
|
|
314
349
|
|
|
315
350
|
stopSpeakerDiagnosticsTest = (speakerTestResponse = 'none') => {
|
|
316
|
-
stopSpeakerDiagnosticsTestDL(speakerTestResponse)
|
|
351
|
+
stopSpeakerDiagnosticsTestDL(speakerTestResponse, this.webrtcSIPPhone);
|
|
317
352
|
};
|
|
318
353
|
|
|
319
354
|
startMicDiagnosticsTest = () => {
|
|
@@ -333,13 +368,9 @@ export class ExotelWebClient {
|
|
|
333
368
|
stopNetworkDiagnosticsDL()
|
|
334
369
|
};
|
|
335
370
|
|
|
336
|
-
|
|
337
|
-
SessionListenerSL()
|
|
371
|
+
SessionListenerMethod = () => {
|
|
338
372
|
};
|
|
339
373
|
|
|
340
|
-
/**
|
|
341
|
-
* function that returns the instance of the call controller object object
|
|
342
|
-
*/
|
|
343
374
|
|
|
344
375
|
getCallController = () => {
|
|
345
376
|
return this.ctrlr;
|
|
@@ -347,14 +378,12 @@ export class ExotelWebClient {
|
|
|
347
378
|
|
|
348
379
|
getCall = () => {
|
|
349
380
|
if (!this.call) {
|
|
350
|
-
this.call =
|
|
381
|
+
this.call = new Call(this.webrtcSIPPhone);
|
|
351
382
|
}
|
|
352
383
|
return this.call;
|
|
353
384
|
};
|
|
354
385
|
|
|
355
|
-
|
|
356
|
-
* Dummy function to set the event listener object
|
|
357
|
-
*/
|
|
386
|
+
|
|
358
387
|
setEventListener = (eventListener) => {
|
|
359
388
|
this.eventListener = eventListener;
|
|
360
389
|
};
|
|
@@ -368,38 +397,21 @@ export class ExotelWebClient {
|
|
|
368
397
|
*/
|
|
369
398
|
|
|
370
399
|
registerEventCallback = (event, phone, param) => {
|
|
400
|
+
logger.log("ExWebClient: registerEventCallback: Received ---> " +
|
|
401
|
+
event, [phone, param]);
|
|
402
|
+
|
|
403
|
+
const lowerCaseEvent = event.toLowerCase();
|
|
371
404
|
|
|
372
|
-
|
|
373
|
-
if (event === "connected") {
|
|
374
|
-
/**
|
|
375
|
-
* When registration is successful then send the phone number of the same to UI
|
|
376
|
-
*/
|
|
377
|
-
this.eventListener.onInitializationSuccess(phone);
|
|
405
|
+
if (lowerCaseEvent === "registered") {
|
|
378
406
|
this.registrationInProgress = false;
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
*/
|
|
388
|
-
this.eventListener.onInitializationFailure(phone);
|
|
389
|
-
if (this.unregisterInitiated) {
|
|
390
|
-
this.shouldAutoRetry = false;
|
|
391
|
-
this.unregisterInitiated = false;
|
|
392
|
-
this.isReadyToRegister = true;
|
|
393
|
-
}
|
|
394
|
-
if (this.shouldAutoRetry) {
|
|
395
|
-
logger.log("ExWebClient: registerEventCallback: Autoretrying");
|
|
396
|
-
DoRegisterRL(this.sipAccountInfo, this, 5000);
|
|
397
|
-
}
|
|
398
|
-
} else if (event === "sent_request") {
|
|
399
|
-
/**
|
|
400
|
-
* If registration request waiting...
|
|
401
|
-
*/
|
|
402
|
-
this.eventListener.onInitializationWaiting(phone);
|
|
407
|
+
this.unregisterInitiated = false;
|
|
408
|
+
this.isReadyToRegister = false;
|
|
409
|
+
this.eventListener.onRegistrationStateChanged("registered", phone);
|
|
410
|
+
} else if (lowerCaseEvent === "unregistered" || lowerCaseEvent === "terminated") {
|
|
411
|
+
this.registrationInProgress = false;
|
|
412
|
+
this.unregisterInitiated = false;
|
|
413
|
+
this.isReadyToRegister = true;
|
|
414
|
+
this.eventListener.onRegistrationStateChanged("unregistered", phone);
|
|
403
415
|
}
|
|
404
416
|
};
|
|
405
417
|
/**
|
|
@@ -411,12 +423,17 @@ export class ExotelWebClient {
|
|
|
411
423
|
callEventCallback = (event, phone, param) => {
|
|
412
424
|
logger.log("ExWebClient: callEventCallback: Received ---> " + event + 'param sent....' + param + 'for phone....' + phone)
|
|
413
425
|
if (event === "i_new_call") {
|
|
414
|
-
this.
|
|
426
|
+
if (!this.call) {
|
|
427
|
+
this.call = new Call(param); // param is the session
|
|
428
|
+
}
|
|
429
|
+
this.callListener.onIncomingCall(param, phone);
|
|
430
|
+
} else if (event === "ringing" || event === "accept_reject") {
|
|
431
|
+
this.callListener.onRinging(param, phone);
|
|
415
432
|
} else if (event === "connected") {
|
|
416
433
|
this.callListener.onCallEstablished(param, phone);
|
|
417
434
|
} else if (event === "terminated") {
|
|
418
435
|
this.callListener.onCallEnded(param, phone);
|
|
419
|
-
}
|
|
436
|
+
}
|
|
420
437
|
};
|
|
421
438
|
|
|
422
439
|
/**
|
|
@@ -438,20 +455,22 @@ export class ExotelWebClient {
|
|
|
438
455
|
this.shouldAutoRetry = false;
|
|
439
456
|
this.unregisterInitiated = true;
|
|
440
457
|
if (!this.registrationInProgress) {
|
|
441
|
-
setTimeout(
|
|
442
|
-
webrtcSIPPhone
|
|
443
|
-
|
|
458
|
+
setTimeout(() => {
|
|
459
|
+
const phone = phonePool[this.userName] || this.webrtcSIPPhone;
|
|
460
|
+
if (phone) {
|
|
461
|
+
phone.sipUnRegisterWebRTC();
|
|
462
|
+
phone.disconnect?.();
|
|
463
|
+
}
|
|
464
|
+
}, 500);
|
|
444
465
|
}
|
|
445
|
-
|
|
446
|
-
|
|
466
|
+
};
|
|
467
|
+
|
|
447
468
|
|
|
448
469
|
webRTCStatusCallbackHandler = (msg1, arg1) => {
|
|
449
470
|
logger.log("ExWebClient: webRTCStatusCallbackHandler: " + msg1 + " " + arg1)
|
|
450
471
|
};
|
|
451
472
|
|
|
452
|
-
|
|
453
|
-
* initialize function called when user wants to register client
|
|
454
|
-
*/
|
|
473
|
+
|
|
455
474
|
initialize = (uiContext, hostName, subscriberName,
|
|
456
475
|
displayName, accountSid, subscriberToken,
|
|
457
476
|
sipAccountInfo) => {
|
|
@@ -479,7 +498,6 @@ export class ExotelWebClient {
|
|
|
479
498
|
|
|
480
499
|
fetchPublicIP(sipAccountInfo);
|
|
481
500
|
|
|
482
|
-
/* Temporary till we figure out the arguments - Start */
|
|
483
501
|
this.domain = hostName = sipAccountInfo.domain;
|
|
484
502
|
this.sipdomain = sipAccountInfo.sipdomain;
|
|
485
503
|
this.accountName = this.userName = sipAccountInfo.userName;
|
|
@@ -495,9 +513,7 @@ export class ExotelWebClient {
|
|
|
495
513
|
this.sipWsPort = 5061;
|
|
496
514
|
this.sipPort = 5061;
|
|
497
515
|
this.sipSecurePort = 5062;
|
|
498
|
-
/* Temporary till we figure out the arguments - End */
|
|
499
516
|
|
|
500
|
-
/* This is permanent -Start */
|
|
501
517
|
let webrtcPort = wssPort;
|
|
502
518
|
|
|
503
519
|
if (this.security === 'ws') {
|
|
@@ -518,38 +534,28 @@ export class ExotelWebClient {
|
|
|
518
534
|
this.sipAccntInfo['port'] = webrtcPort;
|
|
519
535
|
this.sipAccntInfo['contactHost'] = this.contactHost;
|
|
520
536
|
localStorage.setItem('contactHost', this.contactHost);
|
|
521
|
-
/* This is permanent -End */
|
|
522
537
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
*/
|
|
526
|
-
var synchronousHandler = new ExSynchronousHandler(this);
|
|
538
|
+
|
|
539
|
+
var synchronousHandler = new ExSynchronousHandler();
|
|
527
540
|
var delegationHandler = new ExDelegationHandler(this);
|
|
528
541
|
|
|
529
542
|
var userName = this.userName;
|
|
530
|
-
/* OLD-Way to be revisited for multile phone support */
|
|
531
|
-
//webRTCPhones[userName] = webRTC;
|
|
532
543
|
|
|
533
|
-
/* New-Way */
|
|
534
|
-
webrtcSIPPhone.registerPhone("sipjs", delegationHandler, sipAccountInfo.enableAutoAudioDeviceChangeHandling);
|
|
535
|
-
webrtcSIPPhone.registerWebRTCClient(this.sipAccntInfo, synchronousHandler);
|
|
536
544
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
545
|
+
this.webrtcSIPPhone.registerPhone("sipjs", delegationHandler, this.sipAccountInfo.enableAutoAudioDeviceChangeHandling);
|
|
546
|
+
this.webrtcSIPPhone.registerWebRTCClient(this.sipAccntInfo, synchronousHandler);
|
|
547
|
+
phonePool[this.userName] = this.webrtcSIPPhone;
|
|
548
|
+
|
|
549
|
+
|
|
540
550
|
intervalIDMap.set(userName, intervalId);
|
|
541
551
|
};
|
|
542
552
|
|
|
543
553
|
checkClientStatus = (callback) => {
|
|
544
|
-
// using this function , first it will check mic permission is given or not
|
|
545
|
-
// then it will check if transport is intialize or not
|
|
546
|
-
// then it will check if user is registered or not
|
|
547
|
-
// based on this we can evaludate SDK is ready for call
|
|
548
554
|
var constraints = { audio: true, video: false };
|
|
549
555
|
navigator.mediaDevices
|
|
550
556
|
.getUserMedia(constraints)
|
|
551
557
|
.then(function (mediaStream) {
|
|
552
|
-
var transportState = webrtcSIPPhone.getTransportState();
|
|
558
|
+
var transportState = this.webrtcSIPPhone.getTransportState();
|
|
553
559
|
transportState = transportState.toLowerCase();
|
|
554
560
|
switch (transportState) {
|
|
555
561
|
case "":
|
|
@@ -561,7 +567,7 @@ export class ExotelWebClient {
|
|
|
561
567
|
break;
|
|
562
568
|
|
|
563
569
|
default:
|
|
564
|
-
var registerationState = webrtcSIPPhone.getRegistrationState();
|
|
570
|
+
var registerationState = this.webrtcSIPPhone.getRegistrationState();
|
|
565
571
|
registerationState = registerationState.toLowerCase();
|
|
566
572
|
switch (registerationState) {
|
|
567
573
|
case "":
|
|
@@ -590,12 +596,12 @@ export class ExotelWebClient {
|
|
|
590
596
|
|
|
591
597
|
changeAudioInputDevice(deviceId, onSuccess, onError, forceDeviceChange = false) {
|
|
592
598
|
logger.log(`ExWebClient: changeAudioInputDevice: Entry`);
|
|
593
|
-
webrtcSIPPhone.changeAudioInputDevice(deviceId, onSuccess, onError, forceDeviceChange);
|
|
599
|
+
this.webrtcSIPPhone.changeAudioInputDevice(deviceId, onSuccess, onError, forceDeviceChange);
|
|
594
600
|
}
|
|
595
601
|
|
|
596
602
|
changeAudioOutputDevice(deviceId, onSuccess, onError, forceDeviceChange = false) {
|
|
597
603
|
logger.log(`ExWebClient: changeAudioOutputDevice: Entry`);
|
|
598
|
-
webrtcSIPPhone.changeAudioOutputDevice(deviceId, onSuccess, onError, forceDeviceChange);
|
|
604
|
+
this.webrtcSIPPhone.changeAudioOutputDevice(deviceId, onSuccess, onError, forceDeviceChange);
|
|
599
605
|
}
|
|
600
606
|
|
|
601
607
|
downloadLogs() {
|
|
@@ -605,7 +611,11 @@ export class ExotelWebClient {
|
|
|
605
611
|
|
|
606
612
|
setPreferredCodec(codecName) {
|
|
607
613
|
logger.log("ExWebClient: setPreferredCodec: Entry");
|
|
608
|
-
webrtcSIPPhone.
|
|
614
|
+
if (!this.webrtcSIPPhone || !this.webrtcSIPPhone.phone) {
|
|
615
|
+
logger.warn("ExWebClient: setPreferredCodec: Phone not initialized");
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
this.webrtcSIPPhone.setPreferredCodec(codecName);
|
|
609
619
|
}
|
|
610
620
|
|
|
611
621
|
registerLoggerCallback(callback) {
|
|
@@ -613,7 +623,12 @@ export class ExotelWebClient {
|
|
|
613
623
|
}
|
|
614
624
|
|
|
615
625
|
registerAudioDeviceChangeCallback(audioInputDeviceChangeCallback, audioOutputDeviceChangeCallback, onDeviceChangeCallback) {
|
|
616
|
-
|
|
626
|
+
logger.log("ExWebClient: registerAudioDeviceChangeCallback: Entry");
|
|
627
|
+
if (!this.webrtcSIPPhone) {
|
|
628
|
+
logger.warn("ExWebClient: registerAudioDeviceChangeCallback: webrtcSIPPhone not initialized");
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
this.webrtcSIPPhone.registerAudioDeviceChangeCallback(audioInputDeviceChangeCallback, audioOutputDeviceChangeCallback, onDeviceChangeCallback);
|
|
617
632
|
}
|
|
618
633
|
|
|
619
634
|
setEnableConsoleLogging(enable) {
|
|
@@ -623,6 +638,7 @@ export class ExotelWebClient {
|
|
|
623
638
|
|
|
624
639
|
logger.setEnableConsoleLogging(enable);
|
|
625
640
|
}
|
|
641
|
+
|
|
626
642
|
}
|
|
627
643
|
|
|
628
644
|
export default ExotelWebClient;
|