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