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