@webex/calling 3.11.0-webex-services-ready.1 → 3.12.0-mobius-socket.1

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.
Files changed (110) hide show
  1. package/dist/CallHistory/CallHistory.js +68 -51
  2. package/dist/CallHistory/CallHistory.js.map +1 -1
  3. package/dist/CallingClient/CallingClient.js +489 -165
  4. package/dist/CallingClient/CallingClient.js.map +1 -1
  5. package/dist/CallingClient/CallingClient.test.js +207 -6
  6. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  7. package/dist/CallingClient/calling/call.js +20 -16
  8. package/dist/CallingClient/calling/call.js.map +1 -1
  9. package/dist/CallingClient/calling/call.test.js +467 -387
  10. package/dist/CallingClient/calling/call.test.js.map +1 -1
  11. package/dist/CallingClient/calling/callManager.js +53 -32
  12. package/dist/CallingClient/calling/callManager.js.map +1 -1
  13. package/dist/CallingClient/calling/callManager.test.js +35 -0
  14. package/dist/CallingClient/calling/callManager.test.js.map +1 -1
  15. package/dist/CallingClient/calling/types.js +2 -0
  16. package/dist/CallingClient/calling/types.js.map +1 -1
  17. package/dist/CallingClient/constants.js +11 -3
  18. package/dist/CallingClient/constants.js.map +1 -1
  19. package/dist/CallingClient/line/line.test.js +15 -0
  20. package/dist/CallingClient/line/line.test.js.map +1 -1
  21. package/dist/CallingClient/registration/register.js +114 -71
  22. package/dist/CallingClient/registration/register.js.map +1 -1
  23. package/dist/CallingClient/registration/register.test.js +21 -12
  24. package/dist/CallingClient/registration/register.test.js.map +1 -1
  25. package/dist/CallingClient/registration/types.js.map +1 -1
  26. package/dist/CallingClient/registration/webWorker.js +2 -0
  27. package/dist/CallingClient/registration/webWorker.js.map +1 -1
  28. package/dist/CallingClient/types.js.map +1 -1
  29. package/dist/CallingClient/utils/constants.js +46 -0
  30. package/dist/CallingClient/utils/constants.js.map +1 -0
  31. package/dist/CallingClient/utils/index.js +63 -0
  32. package/dist/CallingClient/utils/index.js.map +1 -0
  33. package/dist/CallingClient/utils/mobiusSocketMapper.js +106 -0
  34. package/dist/CallingClient/utils/mobiusSocketMapper.js.map +1 -0
  35. package/dist/CallingClient/utils/request.js +267 -0
  36. package/dist/CallingClient/utils/request.js.map +1 -0
  37. package/dist/CallingClient/utils/types.js +7 -0
  38. package/dist/CallingClient/utils/types.js.map +1 -0
  39. package/dist/CallingClient/utils/wsFeatureFlag.js +20 -0
  40. package/dist/CallingClient/utils/wsFeatureFlag.js.map +1 -0
  41. package/dist/Events/types.js +1 -11
  42. package/dist/Events/types.js.map +1 -1
  43. package/dist/SDKConnector/index.js +32 -0
  44. package/dist/SDKConnector/index.js.map +1 -1
  45. package/dist/SDKConnector/types.js.map +1 -1
  46. package/dist/common/Utils.js +69 -10
  47. package/dist/common/Utils.js.map +1 -1
  48. package/dist/common/testUtil.js +5 -0
  49. package/dist/common/testUtil.js.map +1 -1
  50. package/dist/common/types.js.map +1 -1
  51. package/dist/module/CallHistory/CallHistory.js +28 -17
  52. package/dist/module/CallingClient/CallingClient.js +157 -4
  53. package/dist/module/CallingClient/calling/call.js +12 -8
  54. package/dist/module/CallingClient/calling/callManager.js +29 -10
  55. package/dist/module/CallingClient/calling/types.js +2 -0
  56. package/dist/module/CallingClient/constants.js +8 -0
  57. package/dist/module/CallingClient/registration/register.js +46 -16
  58. package/dist/module/CallingClient/utils/constants.js +30 -0
  59. package/dist/module/CallingClient/utils/index.js +5 -0
  60. package/dist/module/CallingClient/utils/mobiusSocketMapper.js +56 -0
  61. package/dist/module/CallingClient/utils/request.js +112 -0
  62. package/dist/module/CallingClient/utils/types.js +1 -0
  63. package/dist/module/CallingClient/utils/wsFeatureFlag.js +5 -0
  64. package/dist/module/Events/types.js +0 -10
  65. package/dist/module/SDKConnector/index.js +17 -0
  66. package/dist/module/common/Utils.js +35 -4
  67. package/dist/module/common/testUtil.js +3 -0
  68. package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
  69. package/dist/types/CallingClient/CallingClient.d.ts +10 -1
  70. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  71. package/dist/types/CallingClient/calling/call.d.ts +1 -0
  72. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  73. package/dist/types/CallingClient/calling/callManager.d.ts +5 -4
  74. package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
  75. package/dist/types/CallingClient/calling/types.d.ts +21 -9
  76. package/dist/types/CallingClient/calling/types.d.ts.map +1 -1
  77. package/dist/types/CallingClient/constants.d.ts +8 -0
  78. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  79. package/dist/types/CallingClient/registration/register.d.ts +3 -1
  80. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  81. package/dist/types/CallingClient/registration/types.d.ts +2 -1
  82. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  83. package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -1
  84. package/dist/types/CallingClient/types.d.ts +3 -1
  85. package/dist/types/CallingClient/types.d.ts.map +1 -1
  86. package/dist/types/CallingClient/utils/constants.d.ts +30 -0
  87. package/dist/types/CallingClient/utils/constants.d.ts.map +1 -0
  88. package/dist/types/CallingClient/utils/index.d.ts +6 -0
  89. package/dist/types/CallingClient/utils/index.d.ts.map +1 -0
  90. package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts +4 -0
  91. package/dist/types/CallingClient/utils/mobiusSocketMapper.d.ts.map +1 -0
  92. package/dist/types/CallingClient/utils/request.d.ts +20 -0
  93. package/dist/types/CallingClient/utils/request.d.ts.map +1 -0
  94. package/dist/types/CallingClient/utils/types.d.ts +23 -0
  95. package/dist/types/CallingClient/utils/types.d.ts.map +1 -0
  96. package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts +4 -0
  97. package/dist/types/CallingClient/utils/wsFeatureFlag.d.ts.map +1 -0
  98. package/dist/types/Events/types.d.ts +0 -10
  99. package/dist/types/Events/types.d.ts.map +1 -1
  100. package/dist/types/SDKConnector/index.d.ts +2 -0
  101. package/dist/types/SDKConnector/index.d.ts.map +1 -1
  102. package/dist/types/SDKConnector/types.d.ts +11 -0
  103. package/dist/types/SDKConnector/types.d.ts.map +1 -1
  104. package/dist/types/common/Utils.d.ts +4 -1
  105. package/dist/types/common/Utils.d.ts.map +1 -1
  106. package/dist/types/common/testUtil.d.ts +3 -0
  107. package/dist/types/common/testUtil.d.ts.map +1 -1
  108. package/dist/types/common/types.d.ts +5 -0
  109. package/dist/types/common/types.d.ts.map +1 -1
  110. package/package.json +8 -4
@@ -1,19 +1,23 @@
1
1
  import * as Media from '@webex/internal-media-core';
2
+ import { getMobiusSocketInstance } from '@webex/internal-plugin-mobius-socket';
2
3
  import { Mutex } from 'async-mutex';
3
4
  import { METHOD_START_MESSAGE } from '../common/constants';
4
- import { filterMobiusUris, handleCallingClientErrors, uploadLogs, validateServiceData, } from '../common/Utils';
5
+ import { filterMobiusUris, handleCallingClientErrors, normalizeMobiusUris, uploadLogs, validateServiceData, } from '../common/Utils';
5
6
  import { LOGGER } from '../Logger/types';
6
7
  import SDKConnector from '../SDKConnector';
7
8
  import { Eventing } from '../Events/impl';
8
9
  import { MOBIUS_EVENT_KEYS, SessionType, CALLING_CLIENT_EVENT_KEYS, } from '../Events/types';
9
10
  import { ServiceIndicator, ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, } from '../common/types';
11
+ import { MobiusEventType } from './calling/types';
10
12
  import log from '../Logger';
11
13
  import { getCallManager } from './calling/callManager';
12
- import { CALLING_CLIENT_FILE, CALLS_CLEARED_HANDLER_UTIL, CALLING_USER_AGENT, CISCO_DEVICE_URL, DISCOVERY_URL, GET_MOBIUS_SERVERS_UTIL, SPARK_USER_AGENT, URL_ENDPOINT, API_V1, METHODS, NETWORK_FLAP_TIMEOUT, } from './constants';
14
+ import { CALLING_CLIENT_FILE, CALLS_CLEARED_HANDLER_UTIL, CALLING_USER_AGENT, CISCO_DEVICE_URL, DISCOVERY_URL, GET_MOBIUS_SERVERS_UTIL, SPARK_USER_AGENT, URL_ENDPOINT, API_V1, METHODS, NETWORK_FLAP_TIMEOUT, DEVICES_ENDPOINT_RESOURCE, } from './constants';
13
15
  import Line from './line';
14
16
  import { METRIC_EVENT, REG_ACTION, METRIC_TYPE, CONNECTION_ACTION, MOBIUS_SERVER_ACTION, } from '../Metrics/types';
15
17
  import { getMetricManager } from '../Metrics';
16
18
  import windowsChromiumIceWarmup from './windowsChromiumIceWarmupUtils';
19
+ import { APIRequest } from './utils/request';
20
+ import { isMobiusWssEnabled } from './utils';
17
21
  export class CallingClient extends Eventing {
18
22
  sdkConnector;
19
23
  webex;
@@ -23,10 +27,15 @@ export class CallingClient extends Eventing {
23
27
  sdkConfig;
24
28
  primaryMobiusUris;
25
29
  backupMobiusUris;
30
+ primaryWssMobiusUris;
31
+ backupWssMobiusUris;
26
32
  mobiusClusters;
27
33
  mobiusHost;
28
34
  mediaEngine;
29
35
  lineDict = {};
36
+ apiRequest;
37
+ isMobiusSocketEnabled;
38
+ mobiusSocket;
30
39
  isNetworkDown = false;
31
40
  networkDownTimestamp = '';
32
41
  networkUpTimestamp = '';
@@ -51,7 +60,9 @@ export class CallingClient extends Eventing {
51
60
  const logLevel = this.sdkConfig?.logger?.level ? this.sdkConfig.logger.level : LOGGER.ERROR;
52
61
  log.setLogger(logLevel, CALLING_CLIENT_FILE);
53
62
  validateServiceData(serviceData);
54
- this.callManager = getCallManager(this.webex, serviceData.indicator);
63
+ this.isMobiusSocketEnabled =
64
+ isMobiusWssEnabled(this.webex) || (config?.isMobiusSocketEnabled ?? false);
65
+ this.callManager = getCallManager(this.webex, serviceData.indicator, this.isMobiusSocketEnabled);
55
66
  this.metricManager = getMetricManager(this.webex, serviceData.indicator);
56
67
  this.mediaEngine = Media;
57
68
  const adaptedLogger = {
@@ -65,8 +76,17 @@ export class CallingClient extends Eventing {
65
76
  this.mediaEngine.setLogger(adaptedLogger);
66
77
  this.primaryMobiusUris = [];
67
78
  this.backupMobiusUris = [];
79
+ this.primaryWssMobiusUris = [];
80
+ this.backupWssMobiusUris = [];
68
81
  this.mobiusClusters = this.webex.internal.services.getMobiusClusters();
69
82
  this.mobiusHost = '';
83
+ if (this.isMobiusSocketEnabled) {
84
+ this.mobiusSocket = getMobiusSocketInstance(this.webex);
85
+ }
86
+ this.apiRequest = APIRequest.getInstance({
87
+ webex: this.webex,
88
+ isMobiusSocketEnabled: this.isMobiusSocketEnabled,
89
+ });
70
90
  this.registerSessionsListener();
71
91
  this.registerCallsClearedListener();
72
92
  }
@@ -97,6 +117,10 @@ export class CallingClient extends Eventing {
97
117
  }
98
118
  }
99
119
  await this.getMobiusServers();
120
+ if (this.isMobiusSocketEnabled) {
121
+ await this.connectToMobiusSocket();
122
+ this.registerMobiusSocketListener();
123
+ }
100
124
  await this.createLine();
101
125
  this.setupNetworkEventListeners();
102
126
  }
@@ -311,6 +335,8 @@ export class CallingClient extends Eventing {
311
335
  const mobiusUris = filterMobiusUris(mobiusServers, this.mobiusHost);
312
336
  this.primaryMobiusUris = mobiusUris.primary;
313
337
  this.backupMobiusUris = mobiusUris.backup;
338
+ this.primaryWssMobiusUris = mobiusUris.primaryWss;
339
+ this.backupWssMobiusUris = mobiusUris.backupWss;
314
340
  log.log(`Final list of Mobius Servers, primary: ${mobiusUris.primary} and backup: ${mobiusUris.backup}`, {
315
341
  file: CALLING_CLIENT_FILE,
316
342
  method: GET_MOBIUS_SERVERS_UTIL,
@@ -346,6 +372,87 @@ export class CallingClient extends Eventing {
346
372
  this.primaryMobiusUris = [`${this.mobiusHost}${URL_ENDPOINT}`];
347
373
  }
348
374
  }
375
+ async connectToMobiusSocket() {
376
+ const loggerContext = {
377
+ file: CALLING_CLIENT_FILE,
378
+ method: METHODS.CONNECT_TO_MOBIUS_SOCKET,
379
+ };
380
+ log.info(METHOD_START_MESSAGE, loggerContext);
381
+ if (!this.primaryWssMobiusUris.length && !this.backupWssMobiusUris.length) {
382
+ log.warn('No WSS URIs available from Mobius discovery, skipping socket connection', loggerContext);
383
+ return;
384
+ }
385
+ if (this.primaryWssMobiusUris.length) {
386
+ log.log(`Attempting Mobius socket connection using primary WSS URIs (${this.primaryWssMobiusUris.length} available)`, loggerContext);
387
+ for (const wssUri of this.primaryWssMobiusUris) {
388
+ try {
389
+ log.log(`Trying primary WSS URI: ${wssUri}`, loggerContext);
390
+ await this.mobiusSocket.connect(wssUri);
391
+ log.log(`Successfully connected to Mobius socket on primary WSS URI: ${wssUri}`, loggerContext);
392
+ return;
393
+ }
394
+ catch (err) {
395
+ log.warn(`Primary WSS URI connection failed for ${wssUri}: ${err}`, loggerContext);
396
+ }
397
+ }
398
+ log.warn('All primary WSS URI connection attempts failed', loggerContext);
399
+ }
400
+ else {
401
+ log.warn('No primary WSS URIs available, skipping to backup', loggerContext);
402
+ }
403
+ if (this.backupWssMobiusUris.length) {
404
+ log.log(`Attempting Mobius socket connection using backup WSS URIs (${this.backupWssMobiusUris.length} available)`, loggerContext);
405
+ for (const wssUri of this.backupWssMobiusUris) {
406
+ try {
407
+ log.log(`Trying backup WSS URI: ${wssUri}`, loggerContext);
408
+ await this.mobiusSocket.connect(wssUri);
409
+ log.log(`Successfully connected to Mobius socket on backup WSS URI: ${wssUri}`, loggerContext);
410
+ return;
411
+ }
412
+ catch (err) {
413
+ log.warn(`Backup WSS URI connection failed for ${wssUri}: ${err}`, loggerContext);
414
+ }
415
+ }
416
+ log.warn('All backup WSS URI connection attempts failed', loggerContext);
417
+ }
418
+ else {
419
+ log.warn('No backup WSS URIs available', loggerContext);
420
+ }
421
+ log.warn('All Mobius socket connection attempts exhausted for both primary and backup, continuing without socket', loggerContext);
422
+ }
423
+ registerMobiusSocketListener() {
424
+ log.info(METHOD_START_MESSAGE, {
425
+ file: CALLING_CLIENT_FILE,
426
+ method: METHODS.REGISTER_MOBIUS_SOCKET_LISTENER,
427
+ });
428
+ this.sdkConnector.registerMobiusSocketListener('async_event', (event) => {
429
+ this.handleMobiusAsyncEvent(event);
430
+ });
431
+ log.info('Successfully registered listener for Mobius events', {
432
+ file: CALLING_CLIENT_FILE,
433
+ method: METHODS.REGISTER_MOBIUS_SOCKET_LISTENER,
434
+ });
435
+ }
436
+ handleMobiusAsyncEvent = async (event) => {
437
+ log.info(METHOD_START_MESSAGE, {
438
+ file: CALLING_CLIENT_FILE,
439
+ method: METHODS.HANDLE_MOBIUS_ASYNC_EVENT,
440
+ });
441
+ const eventType = event?.data.eventType;
442
+ if (!eventType) {
443
+ log.warn('Dropping unsupported mobius socket payload', {
444
+ file: CALLING_CLIENT_FILE,
445
+ method: METHODS.HANDLE_MOBIUS_ASYNC_EVENT,
446
+ });
447
+ return;
448
+ }
449
+ if (eventType === MobiusEventType.REGISTRATION_DOWN) {
450
+ return;
451
+ }
452
+ if (eventType.startsWith('mobius.')) {
453
+ this.callManager.dequeueWsEvents(event);
454
+ }
455
+ };
349
456
  registerCallsClearedListener() {
350
457
  log.info(METHOD_START_MESSAGE, {
351
458
  file: CALLING_CLIENT_FILE,
@@ -404,12 +511,58 @@ export class CallingClient extends Eventing {
404
511
  file: CALLING_CLIENT_FILE,
405
512
  method: METHODS.CREATE_LINE,
406
513
  });
407
- const line = new Line(this.webex.internal.device.userId, this.webex.internal.device.url, this.mutex, this.primaryMobiusUris, this.backupMobiusUris, this.getLoggingLevel(), this.sdkConfig?.serviceData, this.sdkConfig?.jwe);
514
+ const line = new Line(this.webex.internal.device.userId, this.webex.internal.device.url, this.mutex, this.apiRequest.isSocketEnabled()
515
+ ? normalizeMobiusUris(this.primaryWssMobiusUris)
516
+ : this.primaryMobiusUris, this.apiRequest.isSocketEnabled()
517
+ ? normalizeMobiusUris(this.backupWssMobiusUris)
518
+ : this.backupMobiusUris, this.getLoggingLevel(), this.sdkConfig?.serviceData, this.sdkConfig?.jwe);
408
519
  this.lineDict[line.lineId] = line;
409
520
  }
410
521
  getLines() {
411
522
  return this.lineDict;
412
523
  }
524
+ async getDevices(userId) {
525
+ const userid = userId || this.webex.internal.device.userId;
526
+ if (!userid) {
527
+ throw new Error('userId is required to fetch devices');
528
+ }
529
+ log.info(METHOD_START_MESSAGE, { file: CALLING_CLIENT_FILE, method: METHODS.GET_DEVICES });
530
+ const mobiusUrls = [...this.primaryMobiusUris, ...this.backupMobiusUris];
531
+ if (mobiusUrls.length === 0) {
532
+ throw new Error('Mobius URLs are not available');
533
+ }
534
+ let finalError;
535
+ for (const mobiusUrl of mobiusUrls) {
536
+ const normalizedMobiusUrl = mobiusUrl.replace(/\/+$/, '/');
537
+ const uri = `${normalizedMobiusUrl}${DEVICES_ENDPOINT_RESOURCE}?userid=${encodeURIComponent(userid)}`;
538
+ try {
539
+ const response = (await this.apiRequest.makeRequest({
540
+ uri,
541
+ method: HTTP_METHODS.GET,
542
+ service: ALLOWED_SERVICES.MOBIUS,
543
+ headers: {
544
+ [CISCO_DEVICE_URL]: this.webex.internal.device.url,
545
+ [SPARK_USER_AGENT]: CALLING_USER_AGENT,
546
+ },
547
+ }));
548
+ if (response.statusCode !== 200) {
549
+ throw new Error(`API call failed with ${response.statusCode}`);
550
+ }
551
+ const body = response.body;
552
+ Object.values(this.lineDict)[0].registration.setDeviceInfo(body);
553
+ Object.values(this.lineDict)[0].registration.setActiveMobiusUrl(normalizedMobiusUrl);
554
+ return body.devices ?? [];
555
+ }
556
+ catch (error) {
557
+ finalError = error;
558
+ }
559
+ }
560
+ log.error(`Failed to fetch devices for userId ${userId}: ${JSON.stringify(finalError)}`, {
561
+ file: CALLING_CLIENT_FILE,
562
+ method: METHODS.GET_DEVICES,
563
+ });
564
+ throw finalError;
565
+ }
413
566
  getActiveCalls() {
414
567
  const activeCalls = {};
415
568
  const calls = this.callManager.getActiveCalls();
@@ -1,7 +1,7 @@
1
1
  import { MediaConnectionEventNames, LocalStreamEventNames, RoapMediaConnection, } from '@webex/internal-media-core';
2
2
  import { createMachine, interpret } from 'xstate';
3
3
  import { v4 as uuid } from 'uuid';
4
- import { EffectEvent } from '@webex/web-media-effects';
4
+ import { EffectEvent } from '@webex/media-helpers';
5
5
  import { RtcMetrics } from '@webex/internal-plugin-metrics';
6
6
  import { ERROR_LAYER, ERROR_TYPE } from '../../Errors/types';
7
7
  import { handleCallErrors, modifySdpForIPv4, parseMediaQualityStatistics, serviceErrorCodeHandler, uploadLogs, } from '../../common/Utils';
@@ -17,6 +17,7 @@ import { createCallerId } from './CallerId';
17
17
  import { METRIC_TYPE, METRIC_EVENT, TRANSFER_ACTION } from '../../Metrics/types';
18
18
  import { getMetricManager } from '../../Metrics';
19
19
  import { METHOD_START_MESSAGE, SERVICES_ENDPOINT } from '../../common/constants';
20
+ import { APIRequest } from '../utils/request';
20
21
  export class Call extends Eventing {
21
22
  sdkConnector;
22
23
  webex;
@@ -52,6 +53,7 @@ export class Call extends Eventing {
52
53
  localAudioStream;
53
54
  rtcMetrics;
54
55
  callKeepaliveRetryCount = 0;
56
+ apiRequest;
55
57
  isMuted() {
56
58
  return this.muted;
57
59
  }
@@ -102,6 +104,7 @@ export class Call extends Eventing {
102
104
  this.remoteRoapMessage = null;
103
105
  this.disconnectReason = { code: DisconnectCode.NORMAL, cause: DisconnectCause.NORMAL };
104
106
  this.rtcMetrics = new RtcMetrics(this.webex, { callId: this.callId }, this.correlationId);
107
+ this.apiRequest = APIRequest.getInstance({ webex: this.webex });
105
108
  const callMachine = createMachine({
106
109
  schema: {
107
110
  context: {},
@@ -913,7 +916,7 @@ export class Call extends Eventing {
913
916
  this.mediaConnection.close();
914
917
  log.info('Closing media channel', {
915
918
  file: CALL_FILE,
916
- method: METHODS.HANDLE_OUTGOING_CALL_DISCONNECT,
919
+ method: METHODS.HANDLE_INCOMING_CALL_DISCONNECT,
917
920
  });
918
921
  }
919
922
  this.sendMediaStateMachineEvt({ type: 'E_ROAP_TEARDOWN' });
@@ -1006,6 +1009,7 @@ export class Call extends Eventing {
1006
1009
  file: CALL_FILE,
1007
1010
  method: 'scheduleCallKeepaliveInterval',
1008
1011
  };
1012
+ clearInterval(this.sessionTimer);
1009
1013
  this.sessionTimer = setInterval(async () => {
1010
1014
  try {
1011
1015
  const res = await this.postStatus();
@@ -1484,7 +1488,7 @@ export class Call extends Eventing {
1484
1488
  mediaId: uuid(),
1485
1489
  },
1486
1490
  };
1487
- return this.webex.request({
1491
+ return this.apiRequest.makeRequest({
1488
1492
  uri: `${this.mobiusUrl}${DEVICES_ENDPOINT_RESOURCE}/${this.deviceId}/${CALL_ENDPOINT_RESOURCE}`,
1489
1493
  method: HTTP_METHODS.POST,
1490
1494
  service: ALLOWED_SERVICES.MOBIUS,
@@ -1508,7 +1512,7 @@ export class Call extends Eventing {
1508
1512
  file: CALL_FILE,
1509
1513
  method: 'patch',
1510
1514
  });
1511
- return this.webex.request({
1515
+ return this.apiRequest.makeRequest({
1512
1516
  uri: `${this.mobiusUrl}${DEVICES_ENDPOINT_RESOURCE}/${this.deviceId}/${CALLS_ENDPOINT_RESOURCE}/${this.callId}`,
1513
1517
  method: HTTP_METHODS.PATCH,
1514
1518
  service: ALLOWED_SERVICES.MOBIUS,
@@ -1573,10 +1577,10 @@ export class Call extends Eventing {
1573
1577
  });
1574
1578
  }
1575
1579
  }
1576
- return this.webex.request(request);
1580
+ return this.apiRequest.makeRequest(request);
1577
1581
  }
1578
1582
  async postStatus() {
1579
- return this.webex.request({
1583
+ return this.apiRequest.makeRequest({
1580
1584
  uri: `${this.mobiusUrl}${DEVICES_ENDPOINT_RESOURCE}/${this.deviceId}/${CALLS_ENDPOINT_RESOURCE}/${this.callId}/${CALL_STATUS_RESOURCE}`,
1581
1585
  method: HTTP_METHODS.POST,
1582
1586
  service: ALLOWED_SERVICES.MOBIUS,
@@ -1687,7 +1691,7 @@ export class Call extends Eventing {
1687
1691
  file: CALL_FILE,
1688
1692
  method: METHODS.POST_MEDIA,
1689
1693
  });
1690
- return this.webex.request({
1694
+ return this.apiRequest.makeRequest({
1691
1695
  uri: `${this.mobiusUrl}${DEVICES_ENDPOINT_RESOURCE}/${this.deviceId}/${CALLS_ENDPOINT_RESOURCE}/${this.callId}/${MEDIA_ENDPOINT_RESOURCE}`,
1692
1696
  method: HTTP_METHODS.POST,
1693
1697
  service: ALLOWED_SERVICES.MOBIUS,
@@ -1808,7 +1812,7 @@ export class Call extends Eventing {
1808
1812
  }
1809
1813
  async delete() {
1810
1814
  const disconnectMetrics = await this.getCallStats();
1811
- return this.webex.request({
1815
+ return this.apiRequest.makeRequest({
1812
1816
  uri: `${this.mobiusUrl}${DEVICES_ENDPOINT_RESOURCE}/${this.deviceId}/${CALLS_ENDPOINT_RESOURCE}/${this.callId}`,
1813
1817
  method: HTTP_METHODS.DELETE,
1814
1818
  service: ALLOWED_SERVICES.MOBIUS,
@@ -11,14 +11,16 @@ let callManager;
11
11
  export class CallManager extends Eventing {
12
12
  sdkConnector;
13
13
  webex;
14
+ isMobiusSocketEnabled;
14
15
  callCollection;
15
16
  activeMobiusUrl;
16
17
  serviceIndicator;
17
18
  lineDict;
18
- constructor(webex, indicator) {
19
+ constructor(webex, indicator, isMobiusSocketEnabled) {
19
20
  super();
20
21
  this.sdkConnector = SDKConnector;
21
22
  this.serviceIndicator = indicator;
23
+ this.isMobiusSocketEnabled = isMobiusSocketEnabled;
22
24
  if (!this.sdkConnector.getWebex()) {
23
25
  SDKConnector.setWebex(webex);
24
26
  }
@@ -59,13 +61,15 @@ export class CallManager extends Eventing {
59
61
  });
60
62
  }
61
63
  listenForWsEvents() {
62
- this.sdkConnector.registerListener('event:mobius', async (event) => {
63
- this.dequeueWsEvents(event);
64
- });
65
- log.info('Successfully registered listener for Mobius events', {
66
- file: CALL_MANAGER_FILE,
67
- method: METHODS.REGISTER_SESSIONS_LISTENER,
68
- });
64
+ if (!this.isMobiusSocketEnabled) {
65
+ this.sdkConnector.registerListener('event:mobius', async (event) => {
66
+ this.dequeueWsEvents(event);
67
+ });
68
+ log.info('Successfully registered listener for Mobius events', {
69
+ file: CALL_MANAGER_FILE,
70
+ method: METHODS.REGISTER_SESSIONS_LISTENER,
71
+ });
72
+ }
69
73
  }
70
74
  dequeueWsEvents(event) {
71
75
  log.info(`${METHOD_START_MESSAGE} with event ${event}`, {
@@ -147,6 +151,21 @@ export class CallManager extends Eventing {
147
151
  call.sendCallStateMachineEvt({ type: 'E_RECV_CALL_PROGRESS', data: mobiusEvent.data });
148
152
  break;
149
153
  }
154
+ case MobiusEventType.CALL_INFO: {
155
+ log.log(`Received call info mobiusEvent for call: ${correlationId}`, {
156
+ file: CALL_MANAGER_FILE,
157
+ method: METHODS.DEQUEUE_WS_EVENTS,
158
+ });
159
+ const call = this.getCall(correlationId);
160
+ if (call && mobiusEvent.data.callerId) {
161
+ log.info('Processing Caller-Id data', {
162
+ file: CALL_MANAGER_FILE,
163
+ method: METHODS.DEQUEUE_WS_EVENTS,
164
+ });
165
+ call.startCallerIdResolution(mobiusEvent.data.callerId);
166
+ }
167
+ break;
168
+ }
150
169
  case MobiusEventType.CALL_MEDIA: {
151
170
  log.log(`Received call media mobiusEvent for call: ${correlationId}`, {
152
171
  file: CALL_MANAGER_FILE,
@@ -302,9 +321,9 @@ export class CallManager extends Eventing {
302
321
  return this.lineDict[deviceId].lineId;
303
322
  }
304
323
  }
305
- export const getCallManager = (webex, indicator) => {
324
+ export const getCallManager = (webex, indicator, isMobiusSocketEnabled = false) => {
306
325
  if (!callManager) {
307
- callManager = new CallManager(webex, indicator);
326
+ callManager = new CallManager(webex, indicator, isMobiusSocketEnabled);
308
327
  }
309
328
  return callManager;
310
329
  };
@@ -5,6 +5,8 @@ export var MobiusEventType;
5
5
  MobiusEventType["CALL_CONNECTED"] = "mobius.callconnected";
6
6
  MobiusEventType["CALL_MEDIA"] = "mobius.media";
7
7
  MobiusEventType["CALL_DISCONNECTED"] = "mobius.calldisconnected";
8
+ MobiusEventType["CALL_INFO"] = "mobius.callinfo";
9
+ MobiusEventType["REGISTRATION_DOWN"] = "registration.down";
8
10
  })(MobiusEventType || (MobiusEventType = {}));
9
11
  export var MediaState;
10
12
  (function (MediaState) {
@@ -69,6 +69,7 @@ export const CALL_FILE = 'call';
69
69
  export const CALL_MANAGER_FILE = 'callManager';
70
70
  export const METRIC_FILE = 'metric';
71
71
  export const REGISTRATION_FILE = 'register';
72
+ export const REQUEST_FILE = 'REQUEST';
72
73
  export const CODEC_ID = 'codecId';
73
74
  export const MEDIA_ID = 'id';
74
75
  export const RTC_ICE_CANDIDATE_PAIR = 'RTCIceCandidatePair_';
@@ -125,6 +126,7 @@ export const MOBIUS_EU_PROD = 'mobius-eu-central-1.prod.infra.webex.com';
125
126
  export const MOBIUS_US_INT = 'mobius-us-east-1.int.infra.webex.com';
126
127
  export const MOBIUS_EU_INT = 'mobius-eu-central-1.int.infra.webex.com';
127
128
  export const FAILOVER_CACHE_PREFIX = 'wxc-failover-state';
129
+ export const ACTIVE_MOBIUS_STORAGE_KEY = 'wxc-active-mobius';
128
130
  export const ICE_CANDIDATES_TIMEOUT = 3000;
129
131
  export const METHODS = {
130
132
  CONSTRUCTOR: 'constructor',
@@ -225,7 +227,13 @@ export const METHODS = {
225
227
  REGISTER_SESSIONS_LISTENER: 'registerSessionsListener',
226
228
  CREATE_LINE: 'createLine',
227
229
  GET_LINES: 'getLines',
230
+ GET_DEVICES: 'getDevices',
228
231
  UPLOAD_LOGS: 'uploadLogs',
229
232
  GET_SDK_CONNECTOR: 'getSDKConnector',
230
233
  GET_CONNECTED_CALL: 'getConnectedCall',
234
+ CONNECT_TO_MOBIUS_SOCKET: 'connectToMobiusSocket',
235
+ REGISTER_MOBIUS_SOCKET_LISTENER: 'registerMobiusSocketListener',
236
+ UNREGISTER_MOBIUS_SOCKET_LISTENER: 'unregisterMobiusSocketListener',
237
+ HANDLE_MOBIUS_ASYNC_EVENT: 'handleMobiusAsyncEvent',
238
+ HANDLE_REGISTRATION_DOWN_EVENT: 'handleRegistrationDownEvent',
231
239
  };
@@ -1,4 +1,3 @@
1
- import { v4 as uuid } from 'uuid';
2
1
  import { METHOD_START_MESSAGE } from '../../common/constants';
3
2
  import { emitFinalFailure, handleRegistrationErrors, uploadLogs } from '../../common';
4
3
  import webWorkerStr from './webWorkerStr';
@@ -8,8 +7,9 @@ import { getCallManager } from '../calling';
8
7
  import log from '../../Logger';
9
8
  import SDKConnector from '../../SDKConnector';
10
9
  import { ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, ServiceIndicator, WorkerMessageType, } from '../../common/types';
11
- import { CALLING_USER_AGENT, CISCO_DEVICE_URL, DEVICES_ENDPOINT_RESOURCE, SPARK_USER_AGENT, WEBEX_WEB_CLIENT, BASE_REG_RETRY_TIMER_VAL_IN_SEC, BASE_REG_TIMER_MFACTOR, SEC_TO_MSEC_MFACTOR, REG_RANDOM_T_FACTOR_UPPER_LIMIT, REG_TRY_BACKUP_TIMER_VAL_IN_SEC, MINUTES_TO_SEC_MFACTOR, REG_429_RETRY_UTIL, REG_FAILBACK_429_MAX_RETRIES, FAILBACK_UTIL, REGISTRATION_FILE, DEFAULT_REHOMING_INTERVAL_MIN, DEFAULT_REHOMING_INTERVAL_MAX, DEFAULT_KEEPALIVE_INTERVAL, FAILOVER_UTIL, REGISTER_UTIL, RETRY_TIMER_UPPER_LIMIT, KEEPALIVE_UTIL, REGISTRATION_UTIL, METHODS, URL_ENDPOINT, RECONNECT_ON_FAILURE_UTIL, FAILOVER_CACHE_PREFIX, } from '../constants';
10
+ import { CALLING_USER_AGENT, CISCO_DEVICE_URL, DEVICES_ENDPOINT_RESOURCE, SPARK_USER_AGENT, BASE_REG_RETRY_TIMER_VAL_IN_SEC, BASE_REG_TIMER_MFACTOR, SEC_TO_MSEC_MFACTOR, REG_RANDOM_T_FACTOR_UPPER_LIMIT, REG_TRY_BACKUP_TIMER_VAL_IN_SEC, MINUTES_TO_SEC_MFACTOR, REG_429_RETRY_UTIL, REG_FAILBACK_429_MAX_RETRIES, FAILBACK_UTIL, REGISTRATION_FILE, DEFAULT_REHOMING_INTERVAL_MIN, DEFAULT_REHOMING_INTERVAL_MAX, DEFAULT_KEEPALIVE_INTERVAL, FAILOVER_UTIL, REGISTER_UTIL, RETRY_TIMER_UPPER_LIMIT, KEEPALIVE_UTIL, REGISTRATION_UTIL, METHODS, URL_ENDPOINT, RECONNECT_ON_FAILURE_UTIL, FAILOVER_CACHE_PREFIX, } from '../constants';
12
11
  import { LINE_EVENTS } from '../line/types';
12
+ import { APIRequest } from '../utils/request';
13
13
  export class Registration {
14
14
  sdkConnector;
15
15
  webex;
@@ -36,6 +36,7 @@ export class Registration {
36
36
  retryAfter;
37
37
  scheduled429Retry = false;
38
38
  webWorker;
39
+ apiRequest;
39
40
  constructor(webex, serviceData, mutex, lineEmitter, logLevel, jwe) {
40
41
  this.jwe = jwe;
41
42
  this.sdkConnector = SDKConnector;
@@ -57,6 +58,7 @@ export class Registration {
57
58
  this.lineEmitter = lineEmitter;
58
59
  this.primaryMobiusUris = [];
59
60
  this.backupMobiusUris = [];
61
+ this.apiRequest = APIRequest.getInstance({ webex: this.webex });
60
62
  }
61
63
  getFailoverCacheKey() {
62
64
  return `${FAILOVER_CACHE_PREFIX}.${this.userId || 'unknown'}`;
@@ -116,6 +118,14 @@ export class Registration {
116
118
  this.activeMobiusUrl = url;
117
119
  this.callManager.updateActiveMobius(url);
118
120
  }
121
+ setDeviceInfo(devicesInfo) {
122
+ const [device] = devicesInfo.devices;
123
+ this.deviceInfo = {
124
+ userId: devicesInfo.userId,
125
+ device,
126
+ devices: devicesInfo.devices,
127
+ };
128
+ }
119
129
  setMobiusServers(primaryMobiusUris, backupMobiusUris) {
120
130
  log.log(METHOD_START_MESSAGE, { method: METHODS.SET_MOBIUS_SERVERS, file: REGISTRATION_FILE });
121
131
  this.primaryMobiusUris = primaryMobiusUris;
@@ -123,16 +133,22 @@ export class Registration {
123
133
  }
124
134
  async deleteRegistration(url, deviceId, deviceUrl) {
125
135
  let response;
136
+ const requestObj = {
137
+ uri: `${url}${DEVICES_ENDPOINT_RESOURCE}/${deviceId}`,
138
+ method: HTTP_METHODS.DELETE,
139
+ headers: {
140
+ [CISCO_DEVICE_URL]: deviceUrl,
141
+ [SPARK_USER_AGENT]: CALLING_USER_AGENT,
142
+ },
143
+ service: ALLOWED_SERVICES.MOBIUS,
144
+ };
145
+ if (this.apiRequest.isSocketEnabled()) {
146
+ requestObj.body = {
147
+ deviceId,
148
+ };
149
+ }
126
150
  try {
127
- response = await fetch(`${url}${DEVICES_ENDPOINT_RESOURCE}/${deviceId}`, {
128
- method: HTTP_METHODS.DELETE,
129
- headers: {
130
- [CISCO_DEVICE_URL]: deviceUrl,
131
- Authorization: await this.webex.credentials.getUserToken(),
132
- trackingId: `${WEBEX_WEB_CLIENT}_${uuid()}`,
133
- [SPARK_USER_AGENT]: CALLING_USER_AGENT,
134
- },
135
- });
151
+ response = await this.apiRequest.makeRequest(requestObj);
136
152
  }
137
153
  catch (error) {
138
154
  log.warn(`Delete failed with Mobius: ${JSON.stringify(error)}`, {
@@ -143,7 +159,7 @@ export class Registration {
143
159
  }
144
160
  this.setStatus(RegistrationStatus.INACTIVE);
145
161
  this.lineEmitter(LINE_EVENTS.UNREGISTERED);
146
- return response?.json();
162
+ return response;
147
163
  }
148
164
  async postRegistration(url) {
149
165
  const deviceInfo = {
@@ -151,7 +167,7 @@ export class Registration {
151
167
  clientDeviceUri: this.webex.internal.device.url,
152
168
  serviceData: this.jwe ? { ...this.serviceData, jwe: this.jwe } : this.serviceData,
153
169
  };
154
- return this.webex.request({
170
+ return this.apiRequest.makeRequest({
155
171
  uri: `${url}device`,
156
172
  method: HTTP_METHODS.POST,
157
173
  headers: {
@@ -303,7 +319,7 @@ export class Registration {
303
319
  await uploadLogs();
304
320
  emitFinalFailure((clientError) => {
305
321
  this.lineEmitter(LINE_EVENTS.ERROR, undefined, clientError);
306
- }, loggerContext);
322
+ }, loggerContext, interval < 0 ? 'Timer threshold exceeded during failover' : undefined);
307
323
  }
308
324
  }
309
325
  clearFailbackTimer() {
@@ -316,7 +332,7 @@ export class Registration {
316
332
  let status;
317
333
  for (const mobiusUrl of this.primaryMobiusUris) {
318
334
  try {
319
- const baseUri = mobiusUrl.replace(URL_ENDPOINT, '/');
335
+ const baseUri = mobiusUrl.replace(URL_ENDPOINT, '/').replace('wss://', 'https://');
320
336
  const response = await this.webex.request({
321
337
  uri: `${baseUri}ping`,
322
338
  method: HTTP_METHODS.GET,
@@ -383,6 +399,12 @@ export class Registration {
383
399
  method: this.executeFailback.name,
384
400
  });
385
401
  await this.deregister();
402
+ if (this.apiRequest.isSocketEnabled()) {
403
+ await this.apiRequest.disconnectFromMobiusSocket({
404
+ code: 3050,
405
+ reason: 'done (permanent)',
406
+ });
407
+ }
386
408
  const abort = await this.attemptRegistrationWithServers(FAILBACK_UTIL);
387
409
  if (this.scheduled429Retry || abort || this.isDeviceRegistered()) {
388
410
  return;
@@ -527,6 +549,10 @@ export class Registration {
527
549
  file: REGISTRATION_FILE,
528
550
  method: REGISTER_UTIL,
529
551
  });
552
+ if (this.apiRequest.isSocketEnabled()) {
553
+ const wssNormalizedUrl = url.endsWith('/') ? url.slice(0, -1) : url;
554
+ await this.apiRequest.connectToMobiusSocket(wssNormalizedUrl);
555
+ }
530
556
  const resp = await this.postRegistration(url);
531
557
  this.clearFailoverState();
532
558
  this.deviceInfo = resp.body;
@@ -545,6 +571,7 @@ export class Registration {
545
571
  break;
546
572
  }
547
573
  catch (err) {
574
+ await this.apiRequest.disconnectFromMobiusSocket({ code: 3050, reason: 'done (permanent)' });
548
575
  const body = err;
549
576
  abort = await handleRegistrationErrors(body, (clientError, finalError) => {
550
577
  if (finalError) {
@@ -675,7 +702,10 @@ export class Registration {
675
702
  rehomingIntervalMin: DEFAULT_REHOMING_INTERVAL_MIN,
676
703
  };
677
704
  const stringToReplace = `${DEVICES_ENDPOINT_RESOURCE}/${restoreData.devices[0].deviceId}`;
678
- const uri = restoreData.devices[0].uri.replace(stringToReplace, '');
705
+ let uri = restoreData.devices[0].uri.replace(stringToReplace, '');
706
+ if (this.apiRequest.isSocketEnabled()) {
707
+ uri = uri.replace('https://', 'wss://');
708
+ }
679
709
  this.setActiveMobiusUrl(uri);
680
710
  this.registrationStatus = RegistrationStatus.ACTIVE;
681
711
  return true;
@@ -0,0 +1,30 @@
1
+ export var MOBIUS_SOCKET_MESSAGE_TYPE;
2
+ (function (MOBIUS_SOCKET_MESSAGE_TYPE) {
3
+ MOBIUS_SOCKET_MESSAGE_TYPE["UNKNOWN"] = "UNKNOWN";
4
+ MOBIUS_SOCKET_MESSAGE_TYPE["REGISTER"] = "register";
5
+ MOBIUS_SOCKET_MESSAGE_TYPE["REGISTER_RESPONSE"] = "register.response";
6
+ MOBIUS_SOCKET_MESSAGE_TYPE["UNREGISTER"] = "unregister";
7
+ MOBIUS_SOCKET_MESSAGE_TYPE["UNREGISTER_RESPONSE"] = "unregister.response";
8
+ MOBIUS_SOCKET_MESSAGE_TYPE["DEVICE_STATUS"] = "device_status";
9
+ MOBIUS_SOCKET_MESSAGE_TYPE["DEVICE_STATUS_RESPONSE"] = "device_status.response";
10
+ MOBIUS_SOCKET_MESSAGE_TYPE["DEVICE_GET"] = "device_get";
11
+ MOBIUS_SOCKET_MESSAGE_TYPE["DEVICE_GET_RESPONSE"] = "device_get.response";
12
+ MOBIUS_SOCKET_MESSAGE_TYPE["DEVICE_LIST"] = "device_list";
13
+ MOBIUS_SOCKET_MESSAGE_TYPE["DEVICE_LIST_RESPONSE"] = "device_list.response";
14
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_SETUP"] = "call_setup";
15
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_SETUP_RESPONSE"] = "call_setup.response";
16
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_STATE"] = "call_state";
17
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_STATE_RESPONSE"] = "call_state.response";
18
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_STATUS"] = "call_status";
19
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_STATUS_RESPONSE"] = "call_status.response";
20
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_MEDIA"] = "call_media";
21
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_MEDIA_RESPONSE"] = "call_media.response";
22
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_HOLD"] = "call_hold";
23
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_HOLD_RESPONSE"] = "call_hold.response";
24
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_RESUME"] = "call_resume";
25
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_RESUME_RESPONSE"] = "call_resume.response";
26
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_TRANSFER"] = "call_transfer";
27
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_TRANSFER_RESPONSE"] = "call_transfer.response";
28
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_DELETE"] = "call_delete";
29
+ MOBIUS_SOCKET_MESSAGE_TYPE["CALL_DELETE_RESPONSE"] = "call_delete.response";
30
+ })(MOBIUS_SOCKET_MESSAGE_TYPE || (MOBIUS_SOCKET_MESSAGE_TYPE = {}));
@@ -0,0 +1,5 @@
1
+ export * from './request';
2
+ export * from './types';
3
+ export * from './mobiusSocketMapper';
4
+ export * from './constants';
5
+ export * from './wsFeatureFlag';