@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.
@@ -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 as SessionListenerSL } from '../listeners/SessionListeners';
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 { callbacks, registerCallback, sessionCallback } from '../listeners/Callback';
10
+ import { Callback, RegisterCallback, SessionCallback } from '../listeners/Callback';
11
11
  import { webrtcTroubleshooterEventBus } from "./Callback";
12
12
 
13
- import { webrtcSIPPhone } from '@exotel-npm-dev/webrtc-core-sdk';
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
- 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
- logger.log("all done.");
37
- pc.close();
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
- }
51
- };
52
- sleep(500).then(function () {
53
- logger.log("fetchPublicIP: public ip = ", publicIp)
54
- if (publicIp == "") {
55
- sipAccountInfo.contactHost = window.localStorage.getItem('contactHost');
56
- } else {
57
- sipAccountInfo.contactHost = publicIp;
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
- return;
61
- };
62
-
63
+ }
63
64
 
64
- export function ExDelegationHandler(exClient_) {
65
- var exClient = exClient_;
66
- this.setTestingMode = function (mode) {
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
- this.onCallStatSipJsSessionEvent = function (ev) {
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
- export function ExSynchronousHandler() {
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 class ExotelWebClient {
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
- /* OLD-Way to be revisited for multile phone support */
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
- Register the logger callback and emit the onLog event
233
- */
234
- logger.registerLoggerCallback(function (type, message, args) {
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", arg1, args);
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.ctrlr) {
256
- this.ctrlr = new CallController();
266
+ if (!this.sessionListener) {
267
+ this.sessionListener = new SessionListener(this.sessionCallback);
257
268
  }
258
269
 
259
- if (!this.call) {
260
- this.call = new Call();
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.initializeCallback(CallListenerCallback);
271
- registerCallback.initializeRegisterCallback(RegisterEventCallBack);
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
- SessionListener = () => {
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 = call = new 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
- logger.log("ExWebClient: registerEventCallback: Received ---> " + event + 'phone....', phone + 'param....', param)
363
- if (event === "connected") {
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
- if (this.unregisterInitiated) {
370
- logger.log("ExWebClient: registerEventCallback: unregistering due to unregisterInitiated");
371
- this.unregisterInitiated = false;
372
- this.unregister();
373
- }
374
- } else if (event === "failed_to_start" || event === "transport_error") {
375
- /**
376
- * If registration fails
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.callListener.onIncomingCall(param, phone)
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(function () {
432
- webrtcSIPPhone.sipUnRegisterWebRTC();
433
- }, 500);
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
- * Call the webclient function inside this and pass register and call callbacks as arg
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
- * Store the intervalID against a map
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.setPreferredCodec(codecName);
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
- webrtcSIPPhone.registerAudioDeviceChangeCallback(audioInputDeviceChangeCallback, audioOutputDeviceChangeCallback, onDeviceChangeCallback);
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