@webex/calling 3.10.0 → 3.11.0-webex-services-ready.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 (151) hide show
  1. package/dist/CallHistory/CallHistory.js +128 -133
  2. package/dist/CallHistory/CallHistory.js.map +1 -1
  3. package/dist/CallHistory/CallHistory.test.js +289 -186
  4. package/dist/CallHistory/CallHistory.test.js.map +1 -1
  5. package/dist/CallSettings/CallSettings.js +17 -18
  6. package/dist/CallSettings/CallSettings.js.map +1 -1
  7. package/dist/CallSettings/CallSettings.test.js +14 -14
  8. package/dist/CallSettings/CallSettings.test.js.map +1 -1
  9. package/dist/CallSettings/UcmBackendConnector.js +72 -25
  10. package/dist/CallSettings/UcmBackendConnector.js.map +1 -1
  11. package/dist/CallSettings/UcmBackendConnector.test.js +138 -48
  12. package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -1
  13. package/dist/CallSettings/WxCallBackendConnector.js +138 -145
  14. package/dist/CallSettings/WxCallBackendConnector.js.map +1 -1
  15. package/dist/CallSettings/WxCallBackendConnector.test.js +149 -150
  16. package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -1
  17. package/dist/CallingClient/CallingClient.js +298 -347
  18. package/dist/CallingClient/CallingClient.js.map +1 -1
  19. package/dist/CallingClient/CallingClient.test.js +267 -405
  20. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  21. package/dist/CallingClient/calling/CallerId/index.js +7 -8
  22. package/dist/CallingClient/calling/CallerId/index.js.map +1 -1
  23. package/dist/CallingClient/calling/CallerId/index.test.js +24 -24
  24. package/dist/CallingClient/calling/CallerId/index.test.js.map +1 -1
  25. package/dist/CallingClient/calling/call.js +657 -616
  26. package/dist/CallingClient/calling/call.js.map +1 -1
  27. package/dist/CallingClient/calling/call.test.js +864 -551
  28. package/dist/CallingClient/calling/call.test.js.map +1 -1
  29. package/dist/CallingClient/calling/callManager.js +22 -18
  30. package/dist/CallingClient/calling/callManager.js.map +1 -1
  31. package/dist/CallingClient/calling/callManager.test.js +114 -114
  32. package/dist/CallingClient/calling/callManager.test.js.map +1 -1
  33. package/dist/CallingClient/constants.js +5 -1
  34. package/dist/CallingClient/constants.js.map +1 -1
  35. package/dist/CallingClient/line/index.js +57 -74
  36. package/dist/CallingClient/line/index.js.map +1 -1
  37. package/dist/CallingClient/line/line.test.js +22 -22
  38. package/dist/CallingClient/line/line.test.js.map +1 -1
  39. package/dist/CallingClient/registration/register.js +659 -527
  40. package/dist/CallingClient/registration/register.js.map +1 -1
  41. package/dist/CallingClient/registration/register.test.js +657 -309
  42. package/dist/CallingClient/registration/register.test.js.map +1 -1
  43. package/dist/CallingClient/registration/types.js.map +1 -1
  44. package/dist/CallingClient/registration/webWorker.js +24 -24
  45. package/dist/CallingClient/registration/webWorker.js.map +1 -1
  46. package/dist/CallingClient/registration/webWorker.test.js +20 -20
  47. package/dist/CallingClient/registration/webWorker.test.js.map +1 -1
  48. package/dist/CallingClient/registration/webWorkerStr.js +1 -1
  49. package/dist/CallingClient/registration/webWorkerStr.js.map +1 -1
  50. package/dist/CallingClient/windowsChromiumIceWarmupUtils.js +28 -28
  51. package/dist/CallingClient/windowsChromiumIceWarmupUtils.js.map +1 -1
  52. package/dist/Contacts/ContactsClient.js +259 -268
  53. package/dist/Contacts/ContactsClient.js.map +1 -1
  54. package/dist/Contacts/ContactsClient.test.js +64 -63
  55. package/dist/Contacts/ContactsClient.test.js.map +1 -1
  56. package/dist/Errors/catalog/CallError.js +7 -10
  57. package/dist/Errors/catalog/CallError.js.map +1 -1
  58. package/dist/Errors/catalog/CallingDeviceError.js +6 -9
  59. package/dist/Errors/catalog/CallingDeviceError.js.map +1 -1
  60. package/dist/Errors/catalog/ExtendedError.js +6 -8
  61. package/dist/Errors/catalog/ExtendedError.js.map +1 -1
  62. package/dist/Errors/catalog/LineError.js +6 -9
  63. package/dist/Errors/catalog/LineError.js.map +1 -1
  64. package/dist/Events/impl/index.js +12 -14
  65. package/dist/Events/impl/index.js.map +1 -1
  66. package/dist/Logger/index.js +3 -3
  67. package/dist/Logger/index.js.map +1 -1
  68. package/dist/Logger/index.test.js +1 -1
  69. package/dist/Logger/index.test.js.map +1 -1
  70. package/dist/Metrics/index.js +1 -2
  71. package/dist/Metrics/index.js.map +1 -1
  72. package/dist/SDKConnector/index.js +1 -2
  73. package/dist/SDKConnector/index.js.map +1 -1
  74. package/dist/SDKConnector/types.js.map +1 -1
  75. package/dist/Voicemail/BroadworksBackendConnector.js +131 -139
  76. package/dist/Voicemail/BroadworksBackendConnector.js.map +1 -1
  77. package/dist/Voicemail/BroadworksBackendConnector.test.js +106 -98
  78. package/dist/Voicemail/BroadworksBackendConnector.test.js.map +1 -1
  79. package/dist/Voicemail/UcmBackendConnector.js +88 -92
  80. package/dist/Voicemail/UcmBackendConnector.js.map +1 -1
  81. package/dist/Voicemail/UcmBackendConnector.test.js +72 -72
  82. package/dist/Voicemail/UcmBackendConnector.test.js.map +1 -1
  83. package/dist/Voicemail/Voicemail.js +103 -131
  84. package/dist/Voicemail/Voicemail.js.map +1 -1
  85. package/dist/Voicemail/Voicemail.test.js +20 -20
  86. package/dist/Voicemail/Voicemail.test.js.map +1 -1
  87. package/dist/Voicemail/WxCallBackendConnector.js +117 -131
  88. package/dist/Voicemail/WxCallBackendConnector.js.map +1 -1
  89. package/dist/Voicemail/WxCallBackendConnector.test.js +180 -154
  90. package/dist/Voicemail/WxCallBackendConnector.test.js.map +1 -1
  91. package/dist/common/Utils.js +198 -166
  92. package/dist/common/Utils.js.map +1 -1
  93. package/dist/common/Utils.test.js +436 -191
  94. package/dist/common/Utils.test.js.map +1 -1
  95. package/dist/common/constants.js +3 -1
  96. package/dist/common/constants.js.map +1 -1
  97. package/dist/common/testUtil.js +5 -4
  98. package/dist/common/testUtil.js.map +1 -1
  99. package/dist/module/CallHistory/CallHistory.js +20 -11
  100. package/dist/module/CallSettings/UcmBackendConnector.js +21 -8
  101. package/dist/module/CallSettings/WxCallBackendConnector.js +10 -15
  102. package/dist/module/CallingClient/CallingClient.js +83 -123
  103. package/dist/module/CallingClient/calling/call.js +73 -58
  104. package/dist/module/CallingClient/calling/callManager.js +7 -0
  105. package/dist/module/CallingClient/constants.js +3 -0
  106. package/dist/module/CallingClient/registration/register.js +85 -5
  107. package/dist/module/CallingClient/registration/webWorker.js +2 -2
  108. package/dist/module/CallingClient/registration/webWorkerStr.js +2 -2
  109. package/dist/module/Contacts/ContactsClient.js +19 -25
  110. package/dist/module/Events/impl/index.js +1 -1
  111. package/dist/module/Logger/index.js +2 -2
  112. package/dist/module/Voicemail/BroadworksBackendConnector.js +10 -18
  113. package/dist/module/Voicemail/UcmBackendConnector.js +7 -11
  114. package/dist/module/Voicemail/Voicemail.js +42 -68
  115. package/dist/module/Voicemail/WxCallBackendConnector.js +14 -28
  116. package/dist/module/common/Utils.js +31 -5
  117. package/dist/module/common/constants.js +2 -0
  118. package/dist/module/common/testUtil.js +1 -0
  119. package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
  120. package/dist/types/CallSettings/UcmBackendConnector.d.ts +1 -0
  121. package/dist/types/CallSettings/UcmBackendConnector.d.ts.map +1 -1
  122. package/dist/types/CallSettings/WxCallBackendConnector.d.ts.map +1 -1
  123. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  124. package/dist/types/CallingClient/calling/call.d.ts +4 -0
  125. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  126. package/dist/types/CallingClient/calling/callManager.d.ts.map +1 -1
  127. package/dist/types/CallingClient/constants.d.ts +3 -0
  128. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  129. package/dist/types/CallingClient/registration/register.d.ts +4 -0
  130. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  131. package/dist/types/CallingClient/registration/types.d.ts +6 -0
  132. package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
  133. package/dist/types/CallingClient/registration/webWorkerStr.d.ts +1 -1
  134. package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -1
  135. package/dist/types/Contacts/ContactsClient.d.ts +1 -0
  136. package/dist/types/Contacts/ContactsClient.d.ts.map +1 -1
  137. package/dist/types/Logger/index.d.ts +1 -2
  138. package/dist/types/Logger/index.d.ts.map +1 -1
  139. package/dist/types/SDKConnector/types.d.ts +16 -0
  140. package/dist/types/SDKConnector/types.d.ts.map +1 -1
  141. package/dist/types/Voicemail/BroadworksBackendConnector.d.ts.map +1 -1
  142. package/dist/types/Voicemail/UcmBackendConnector.d.ts.map +1 -1
  143. package/dist/types/Voicemail/Voicemail.d.ts.map +1 -1
  144. package/dist/types/Voicemail/WxCallBackendConnector.d.ts.map +1 -1
  145. package/dist/types/common/Utils.d.ts +1 -1
  146. package/dist/types/common/Utils.d.ts.map +1 -1
  147. package/dist/types/common/constants.d.ts +2 -0
  148. package/dist/types/common/constants.d.ts.map +1 -1
  149. package/dist/types/common/testUtil.d.ts +1 -0
  150. package/dist/types/common/testUtil.d.ts.map +1 -1
  151. package/package.json +4 -4
@@ -19,7 +19,9 @@ export class WxCallBackendConnector {
19
19
  SDKConnector.setWebex(webex);
20
20
  }
21
21
  this.webex = this.sdkConnector.getWebex();
22
- this.hydraEndpoint = this.webex.internal.services._serviceUrls.hydra;
22
+ this.hydraEndpoint =
23
+ this.webex.internal.services._serviceUrls?.hydra ||
24
+ this.webex.internal.services.get(this.webex.internal.services._activeServices.hydra);
23
25
  log.setLogger(logger.level, WEBEX_CALLING_CONNECTOR_FILE);
24
26
  this.userId = this.webex.internal.device.userId;
25
27
  this.personId = inferIdFromUuid(this.webex.internal.device.userId, DecodeType.PEOPLE);
@@ -66,8 +68,7 @@ export class WxCallBackendConnector {
66
68
  return responseDetails;
67
69
  }
68
70
  catch (err) {
69
- const extendedError = new Error(`Failed to get call waiting setting: ${err}`);
70
- log.error(extendedError, loggerContext);
71
+ log.error(`Failed to get call waiting setting: ${JSON.stringify(err)}`, loggerContext);
71
72
  await uploadLogs();
72
73
  const errorInfo = {
73
74
  statusCode: err instanceof Error ? Number(err.message) : '',
@@ -100,8 +101,7 @@ export class WxCallBackendConnector {
100
101
  return responseDetails;
101
102
  }
102
103
  catch (err) {
103
- const extendedError = new Error(`Failed to get DoNotDisturb setting: ${err}`);
104
- log.error(extendedError, loggerContext);
104
+ log.error(`Failed to get DoNotDisturb setting: ${JSON.stringify(err)}`, loggerContext);
105
105
  await uploadLogs();
106
106
  const errorInfo = err;
107
107
  const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
@@ -136,8 +136,7 @@ export class WxCallBackendConnector {
136
136
  return responseDetails;
137
137
  }
138
138
  catch (err) {
139
- const extendedError = new Error(`Failed to set DoNotDisturb setting: ${err}`);
140
- log.error(extendedError, loggerContext);
139
+ log.error(`Failed to set DoNotDisturb setting: ${JSON.stringify(err)}`, loggerContext);
141
140
  await uploadLogs();
142
141
  const errorInfo = err;
143
142
  const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
@@ -168,8 +167,7 @@ export class WxCallBackendConnector {
168
167
  return responseDetails;
169
168
  }
170
169
  catch (err) {
171
- const extendedError = new Error(`Failed to get Call Forward setting: ${err}`);
172
- log.error(extendedError, loggerContext);
170
+ log.error(`Failed to get Call Forward setting: ${JSON.stringify(err)}`, loggerContext);
173
171
  await uploadLogs();
174
172
  const errorInfo = err;
175
173
  const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
@@ -200,8 +198,7 @@ export class WxCallBackendConnector {
200
198
  return responseDetails;
201
199
  }
202
200
  catch (err) {
203
- const extendedError = new Error(`Failed to set Call Forward setting: ${err}`);
204
- log.error(extendedError, loggerContext);
201
+ log.error(`Failed to set Call Forward setting: ${JSON.stringify(err)}`, loggerContext);
205
202
  await uploadLogs();
206
203
  const errorInfo = err;
207
204
  const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
@@ -232,8 +229,7 @@ export class WxCallBackendConnector {
232
229
  return responseDetails;
233
230
  }
234
231
  catch (err) {
235
- const extendedError = new Error(`Failed to get Voicemail setting: ${err}`);
236
- log.error(extendedError, loggerContext);
232
+ log.error(`Failed to get Voicemail setting: ${JSON.stringify(err)}`, loggerContext);
237
233
  await uploadLogs();
238
234
  const errorInfo = err;
239
235
  const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
@@ -264,8 +260,7 @@ export class WxCallBackendConnector {
264
260
  return responseDetails;
265
261
  }
266
262
  catch (err) {
267
- const extendedError = new Error(`Failed to set Voicemail setting: ${err}`);
268
- log.error(extendedError, loggerContext);
263
+ log.error(`Failed to set Voicemail setting: ${JSON.stringify(err)}`, loggerContext);
269
264
  await uploadLogs();
270
265
  const errorInfo = err;
271
266
  const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
@@ -9,7 +9,7 @@ import { MOBIUS_EVENT_KEYS, SessionType, CALLING_CLIENT_EVENT_KEYS, } from '../E
9
9
  import { ServiceIndicator, ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, } from '../common/types';
10
10
  import log from '../Logger';
11
11
  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, IP_ENDPOINT, SPARK_USER_AGENT, URL_ENDPOINT, API_V1, MOBIUS_US_PROD, MOBIUS_EU_PROD, MOBIUS_US_INT, MOBIUS_EU_INT, METHODS, NETWORK_FLAP_TIMEOUT, } from './constants';
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';
13
13
  import Line from './line';
14
14
  import { METRIC_EVENT, REG_ACTION, METRIC_TYPE, CONNECTION_ACTION, MOBIUS_SERVER_ACTION, } from '../Metrics/types';
15
15
  import { getMetricManager } from '../Metrics';
@@ -65,28 +65,7 @@ export class CallingClient extends Eventing {
65
65
  this.mediaEngine.setLogger(adaptedLogger);
66
66
  this.primaryMobiusUris = [];
67
67
  this.backupMobiusUris = [];
68
- let mobiusServiceHost = '';
69
- try {
70
- mobiusServiceHost = new URL(this.webex.internal.services._serviceUrls.mobius).host;
71
- }
72
- catch (error) {
73
- log.warn(`Failed to parse mobius service URL`, {
74
- file: CALLING_CLIENT_FILE,
75
- method: this.constructor.name,
76
- });
77
- }
78
- if (this.webex.internal.services._hostCatalog) {
79
- this.mobiusClusters =
80
- (mobiusServiceHost && this.webex.internal.services._hostCatalog[mobiusServiceHost]) ||
81
- this.webex.internal.services._hostCatalog[MOBIUS_US_PROD] ||
82
- this.webex.internal.services._hostCatalog[MOBIUS_EU_PROD] ||
83
- this.webex.internal.services._hostCatalog[MOBIUS_US_INT] ||
84
- this.webex.internal.services._hostCatalog[MOBIUS_EU_INT];
85
- }
86
- else {
87
- const mobiusObject = this.webex.internal.services._services.find((item) => item.serviceName === 'mobius');
88
- this.mobiusClusters = [mobiusObject.serviceUrls[0].baseUrl];
89
- }
68
+ this.mobiusClusters = this.webex.internal.services.getMobiusClusters();
90
69
  this.mobiusHost = '';
91
70
  this.registerSessionsListener();
92
71
  this.registerCallsClearedListener();
@@ -237,68 +216,38 @@ export class CallingClient extends Eventing {
237
216
  method: METHODS.GET_CLIENT_REGION_INFO,
238
217
  });
239
218
  const regionInfo = {};
240
- for (const mobius of this.mobiusClusters) {
241
- if (mobius.host) {
242
- this.mobiusHost = `https://${mobius.host}${API_V1}`;
243
- }
244
- else {
245
- this.mobiusHost = mobius;
246
- }
247
- try {
248
- const temp = await this.webex.request({
249
- uri: `${this.mobiusHost}${URL_ENDPOINT}${IP_ENDPOINT}`,
250
- method: HTTP_METHODS.GET,
251
- headers: {
252
- [CISCO_DEVICE_URL]: this.webex.internal.device.url,
253
- [SPARK_USER_AGENT]: CALLING_USER_AGENT,
254
- },
255
- service: ALLOWED_SERVICES.MOBIUS,
256
- });
257
- log.log(`Response trackingId: ${temp?.headers?.trackingid}`, {
258
- file: CALLING_CLIENT_FILE,
259
- method: METHODS.GET_CLIENT_REGION_INFO,
260
- });
261
- const myIP = temp.body.ipv4;
262
- const response = await this.webex.request({
263
- uri: `${DISCOVERY_URL}/${myIP}`,
264
- method: HTTP_METHODS.GET,
265
- addAuthHeader: false,
266
- headers: {
267
- [SPARK_USER_AGENT]: null,
268
- },
269
- });
270
- log.log(`Response trackingId: ${response?.headers?.trackingid}`, {
271
- file: CALLING_CLIENT_FILE,
272
- method: METHODS.GET_CLIENT_REGION_INFO,
273
- });
274
- const clientRegionInfo = response.body;
275
- regionInfo.clientRegion = clientRegionInfo?.clientRegion
276
- ? clientRegionInfo.clientRegion
277
- : '';
278
- regionInfo.countryCode = clientRegionInfo?.countryCode ? clientRegionInfo.countryCode : '';
279
- log.log(`Successfully fetched Client region info: ${regionInfo.clientRegion}, countryCode: ${regionInfo.countryCode}, and response trackingid: ${response?.headers?.trackingid}`, {
280
- file: CALLING_CLIENT_FILE,
281
- method: METHODS.GET_CLIENT_REGION_INFO,
282
- });
283
- this.metricManager.submitRegionInfoMetric(METRIC_EVENT.MOBIUS_DISCOVERY, MOBIUS_SERVER_ACTION.REGION_INFO, METRIC_TYPE.BEHAVIORAL, this.mobiusHost, clientRegionInfo.clientRegion, clientRegionInfo.countryCode, response?.headers?.trackingid ?? '');
284
- break;
285
- }
286
- catch (err) {
287
- const extendedError = new Error(`Failed to get client region info: ${err}`);
288
- log.error(extendedError, {
289
- method: METHODS.GET_CLIENT_REGION_INFO,
290
- file: CALLING_CLIENT_FILE,
291
- });
292
- abort = await handleCallingClientErrors(err, (clientError) => {
293
- this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, GET_MOBIUS_SERVERS_UTIL, 'UNKNOWN', err.headers?.trackingId ?? '', undefined, clientError);
294
- this.emit(CALLING_CLIENT_EVENT_KEYS.ERROR, clientError);
295
- }, { method: GET_MOBIUS_SERVERS_UTIL, file: CALLING_CLIENT_FILE });
296
- regionInfo.clientRegion = '';
297
- regionInfo.countryCode = '';
298
- if (abort) {
299
- await uploadLogs();
300
- return regionInfo;
301
- }
219
+ try {
220
+ const response = await this.webex.request({
221
+ uri: `${DISCOVERY_URL}`,
222
+ method: HTTP_METHODS.GET,
223
+ addAuthHeader: false,
224
+ headers: {
225
+ [SPARK_USER_AGENT]: null,
226
+ },
227
+ });
228
+ const clientRegionInfo = response.body;
229
+ regionInfo.clientRegion = clientRegionInfo?.clientRegion || '';
230
+ regionInfo.countryCode = clientRegionInfo?.countryCode || '';
231
+ log.log(`Successfully fetched Client region info: ${regionInfo.clientRegion}, countryCode: ${regionInfo.countryCode}, and response trackingid: ${response?.headers?.trackingid}`, {
232
+ file: CALLING_CLIENT_FILE,
233
+ method: METHODS.GET_CLIENT_REGION_INFO,
234
+ });
235
+ this.metricManager.submitRegionInfoMetric(METRIC_EVENT.MOBIUS_DISCOVERY, MOBIUS_SERVER_ACTION.REGION_INFO, METRIC_TYPE.BEHAVIORAL, this.mobiusHost, clientRegionInfo.clientRegion, clientRegionInfo.countryCode, response?.headers?.trackingid ?? '');
236
+ }
237
+ catch (err) {
238
+ log.error(`Failed to get client region info: ${JSON.stringify(err)}`, {
239
+ method: METHODS.GET_CLIENT_REGION_INFO,
240
+ file: CALLING_CLIENT_FILE,
241
+ });
242
+ abort = await handleCallingClientErrors(err, (clientError) => {
243
+ this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, GET_MOBIUS_SERVERS_UTIL, 'UNKNOWN', err.headers?.trackingId ?? '', undefined, clientError);
244
+ this.emit(CALLING_CLIENT_EVENT_KEYS.ERROR, clientError);
245
+ }, { method: GET_MOBIUS_SERVERS_UTIL, file: CALLING_CLIENT_FILE });
246
+ regionInfo.clientRegion = '';
247
+ regionInfo.countryCode = '';
248
+ if (abort) {
249
+ await uploadLogs();
250
+ return regionInfo;
302
251
  }
303
252
  }
304
253
  return regionInfo;
@@ -318,7 +267,9 @@ export class CallingClient extends Eventing {
318
267
  });
319
268
  clientRegion = this.sdkConfig?.discovery?.region;
320
269
  countryCode = this.sdkConfig?.discovery?.country;
321
- this.mobiusHost = this.webex.internal.services._serviceUrls.mobius;
270
+ this.mobiusHost =
271
+ this.webex.internal.services._serviceUrls?.mobius ||
272
+ this.webex.internal.services.get(this.webex.internal.services._activeServices.mobius);
322
273
  }
323
274
  else {
324
275
  log.log('Updating region and country through Region discovery', {
@@ -334,44 +285,53 @@ export class CallingClient extends Eventing {
334
285
  file: CALLING_CLIENT_FILE,
335
286
  method: GET_MOBIUS_SERVERS_UTIL,
336
287
  });
337
- try {
338
- const response = await this.webex.request({
339
- uri: `${this.mobiusHost}${URL_ENDPOINT}?regionCode=${clientRegion}&countryCode=${countryCode}`,
340
- method: HTTP_METHODS.GET,
341
- headers: {
342
- [CISCO_DEVICE_URL]: this.webex.internal.device.url,
343
- [SPARK_USER_AGENT]: CALLING_USER_AGENT,
344
- },
345
- service: ALLOWED_SERVICES.MOBIUS,
346
- });
347
- log.log(`Mobius Server found for the region. Response trackingId: ${response?.headers?.trackingid}`, {
348
- file: CALLING_CLIENT_FILE,
349
- method: GET_MOBIUS_SERVERS_UTIL,
350
- });
351
- const mobiusServers = response.body;
352
- this.metricManager.submitMobiusServersMetric(METRIC_EVENT.MOBIUS_DISCOVERY, MOBIUS_SERVER_ACTION.MOBIUS_SERVERS, METRIC_TYPE.BEHAVIORAL, mobiusServers, response?.headers?.trackingid ?? '');
353
- const mobiusUris = filterMobiusUris(mobiusServers, this.mobiusHost);
354
- this.primaryMobiusUris = mobiusUris.primary;
355
- this.backupMobiusUris = mobiusUris.backup;
356
- log.log(`Final list of Mobius Servers, primary: ${mobiusUris.primary} and backup: ${mobiusUris.backup}`, {
357
- file: CALLING_CLIENT_FILE,
358
- method: GET_MOBIUS_SERVERS_UTIL,
359
- });
360
- }
361
- catch (err) {
362
- const extendedError = new Error(`Failed to get Mobius servers: ${err}`);
363
- log.error(extendedError, {
364
- method: METHODS.GET_MOBIUS_SERVERS,
365
- file: CALLING_CLIENT_FILE,
366
- });
367
- const abort = await handleCallingClientErrors(err, (clientError) => {
368
- this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, GET_MOBIUS_SERVERS_UTIL, 'UNKNOWN', err.headers?.trackingId ?? '', undefined, clientError);
369
- this.emit(CALLING_CLIENT_EVENT_KEYS.ERROR, clientError);
370
- }, { method: GET_MOBIUS_SERVERS_UTIL, file: CALLING_CLIENT_FILE });
371
- if (abort) {
372
- await uploadLogs();
288
+ for (const mobius of this.mobiusClusters) {
289
+ if (mobius.host) {
290
+ this.mobiusHost = `https://${mobius.host}${API_V1}`;
291
+ }
292
+ else {
293
+ this.mobiusHost = mobius;
294
+ }
295
+ try {
296
+ const response = await this.webex.request({
297
+ uri: `${this.mobiusHost}${URL_ENDPOINT}?regionCode=${clientRegion}&countryCode=${countryCode}`,
298
+ method: HTTP_METHODS.GET,
299
+ headers: {
300
+ [CISCO_DEVICE_URL]: this.webex.internal.device.url,
301
+ [SPARK_USER_AGENT]: CALLING_USER_AGENT,
302
+ },
303
+ service: ALLOWED_SERVICES.MOBIUS,
304
+ });
305
+ log.log(`Mobius Server found for the region. Response trackingId: ${response?.headers?.trackingid}`, {
306
+ file: CALLING_CLIENT_FILE,
307
+ method: GET_MOBIUS_SERVERS_UTIL,
308
+ });
309
+ const mobiusServers = response.body;
310
+ this.metricManager.submitMobiusServersMetric(METRIC_EVENT.MOBIUS_DISCOVERY, MOBIUS_SERVER_ACTION.MOBIUS_SERVERS, METRIC_TYPE.BEHAVIORAL, mobiusServers, response?.headers?.trackingid ?? '');
311
+ const mobiusUris = filterMobiusUris(mobiusServers, this.mobiusHost);
312
+ this.primaryMobiusUris = mobiusUris.primary;
313
+ this.backupMobiusUris = mobiusUris.backup;
314
+ log.log(`Final list of Mobius Servers, primary: ${mobiusUris.primary} and backup: ${mobiusUris.backup}`, {
315
+ file: CALLING_CLIENT_FILE,
316
+ method: GET_MOBIUS_SERVERS_UTIL,
317
+ });
318
+ break;
319
+ }
320
+ catch (err) {
321
+ log.error(`Failed to get Mobius servers: ${JSON.stringify(err)}`, {
322
+ method: METHODS.GET_MOBIUS_SERVERS,
323
+ file: CALLING_CLIENT_FILE,
324
+ });
325
+ const abort = await handleCallingClientErrors(err, (clientError) => {
326
+ this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, GET_MOBIUS_SERVERS_UTIL, 'UNKNOWN', err.headers?.trackingId ?? '', undefined, clientError);
327
+ this.emit(CALLING_CLIENT_EVENT_KEYS.ERROR, clientError);
328
+ }, { method: GET_MOBIUS_SERVERS_UTIL, file: CALLING_CLIENT_FILE });
329
+ if (abort) {
330
+ useDefault = true;
331
+ await uploadLogs();
332
+ break;
333
+ }
373
334
  }
374
- useDefault = true;
375
335
  }
376
336
  }
377
337
  else {
@@ -7,7 +7,7 @@ import { ERROR_LAYER, ERROR_TYPE } from '../../Errors/types';
7
7
  import { handleCallErrors, modifySdpForIPv4, parseMediaQualityStatistics, serviceErrorCodeHandler, uploadLogs, } from '../../common/Utils';
8
8
  import { ALLOWED_SERVICES, CallDirection, HTTP_METHODS, } from '../../common/types';
9
9
  import { createCallError } from '../../Errors/catalog/CallError';
10
- import { CALL_ENDPOINT_RESOURCE, CALL_FILE, CALL_HOLD_SERVICE, CALL_STATUS_RESOURCE, CALL_TRANSFER_SERVICE, CALLING_USER_AGENT, CALLS_ENDPOINT_RESOURCE, CISCO_DEVICE_URL, DEFAULT_LOCAL_CALL_ID, DEFAULT_SESSION_TIMER, DEVICES_ENDPOINT_RESOURCE, HOLD_ENDPOINT, ICE_CANDIDATES_TIMEOUT, INITIAL_SEQ_NUMBER, MEDIA_ENDPOINT_RESOURCE, METHODS, NOISE_REDUCTION_EFFECT, RESUME_ENDPOINT, SPARK_USER_AGENT, SUPPLEMENTARY_SERVICES_TIMEOUT, TRANSFER_ENDPOINT, } from '../constants';
10
+ import { CALL_ENDPOINT_RESOURCE, CALL_FILE, CALL_HOLD_SERVICE, CALL_STATUS_RESOURCE, CALL_TRANSFER_SERVICE, CALLING_USER_AGENT, CALLS_ENDPOINT_RESOURCE, CISCO_DEVICE_URL, DEFAULT_LOCAL_CALL_ID, DEFAULT_SESSION_TIMER, DEVICES_ENDPOINT_RESOURCE, HOLD_ENDPOINT, ICE_CANDIDATES_TIMEOUT, INITIAL_SEQ_NUMBER, MAX_CALL_KEEPALIVE_RETRY_COUNT, MEDIA_ENDPOINT_RESOURCE, METHODS, NOISE_REDUCTION_EFFECT, RESUME_ENDPOINT, SPARK_USER_AGENT, SUPPLEMENTARY_SERVICES_TIMEOUT, TRANSFER_ENDPOINT, } from '../constants';
11
11
  import SDKConnector from '../../SDKConnector';
12
12
  import { Eventing } from '../../Events/impl';
13
13
  import { CALL_EVENT_KEYS, MEDIA_CONNECTION_EVENT_KEYS, MOBIUS_MIDCALL_STATE, SUPPLEMENTARY_SERVICES, } from '../../Events/types';
@@ -51,6 +51,7 @@ export class Call extends Eventing {
51
51
  receivedRoapOKSeq;
52
52
  localAudioStream;
53
53
  rtcMetrics;
54
+ callKeepaliveRetryCount = 0;
54
55
  isMuted() {
55
56
  return this.muted;
56
57
  }
@@ -639,8 +640,7 @@ export class Call extends Eventing {
639
640
  });
640
641
  }
641
642
  catch (e) {
642
- const extendedError = new Error(`Failed to setup the call: ${e}`);
643
- log.error(extendedError, {
643
+ log.error(`Failed to setup the call: ${JSON.stringify(e)}`, {
644
644
  file: CALL_FILE,
645
645
  method: METHODS.HANDLE_OUTGOING_CALL_SETUP,
646
646
  });
@@ -682,8 +682,7 @@ export class Call extends Eventing {
682
682
  }
683
683
  }
684
684
  catch (e) {
685
- const extendedError = new Error(`Failed to put the call on hold: ${e}`);
686
- log.error(extendedError, {
685
+ log.error(`Failed to put the call on hold: ${JSON.stringify(e)}`, {
687
686
  file: CALL_FILE,
688
687
  method: METHODS.HANDLE_CALL_HOLD,
689
688
  });
@@ -725,8 +724,7 @@ export class Call extends Eventing {
725
724
  }
726
725
  }
727
726
  catch (e) {
728
- const extendedError = new Error(`Failed to resume the call: ${e}`);
729
- log.error(extendedError, {
727
+ log.error(`Failed to resume the call: ${JSON.stringify(e)}`, {
730
728
  file: CALL_FILE,
731
729
  method: METHODS.HANDLE_CALL_RESUME,
732
730
  });
@@ -814,13 +812,12 @@ export class Call extends Eventing {
814
812
  method: METHODS.HANDLE_OUTGOING_CALL_ALERTING,
815
813
  });
816
814
  }
817
- catch (err) {
818
- const extendedError = new Error(`Failed to signal call progression: ${err}`);
819
- log.error(extendedError, {
815
+ catch (e) {
816
+ log.error(`Failed to signal call progression: ${JSON.stringify(e)}`, {
820
817
  file: CALL_FILE,
821
818
  method: METHODS.HANDLE_OUTGOING_CALL_ALERTING,
822
819
  });
823
- const errData = err;
820
+ const errData = e;
824
821
  handleCallErrors((error) => {
825
822
  this.emit(CALL_EVENT_KEYS.CALL_ERROR, error);
826
823
  this.submitCallErrorMetric(error);
@@ -864,13 +861,12 @@ export class Call extends Eventing {
864
861
  method: METHODS.HANDLE_OUTGOING_CALL_CONNECT,
865
862
  });
866
863
  }
867
- catch (err) {
868
- const extendedError = new Error(`Failed to connect the call: ${err}`);
869
- log.error(extendedError, {
864
+ catch (e) {
865
+ log.error(`Failed to connect the call: ${JSON.stringify(e)}`, {
870
866
  file: CALL_FILE,
871
867
  method: METHODS.HANDLE_OUTGOING_CALL_CONNECT,
872
868
  });
873
- const errData = err;
869
+ const errData = e;
874
870
  handleCallErrors((error) => {
875
871
  this.emit(CALL_EVENT_KEYS.CALL_ERROR, error);
876
872
  this.submitCallErrorMetric(error);
@@ -886,20 +882,21 @@ export class Call extends Eventing {
886
882
  async handleIncomingCallDisconnect(event) {
887
883
  log.info(`${METHOD_START_MESSAGE} with: ${this.getCorrelationId()}`, {
888
884
  file: CALL_FILE,
889
- method: METHODS.HANDLE_OUTGOING_CALL_DISCONNECT,
885
+ method: METHODS.HANDLE_INCOMING_CALL_DISCONNECT,
890
886
  });
887
+ this.emit(CALL_EVENT_KEYS.DISCONNECT, this.correlationId);
891
888
  this.setDisconnectReason();
892
889
  try {
893
890
  const response = await this.delete();
894
891
  log.log(`Response code: ${response.statusCode}`, {
895
892
  file: CALL_FILE,
896
- method: METHODS.HANDLE_OUTGOING_CALL_DISCONNECT,
893
+ method: METHODS.HANDLE_INCOMING_CALL_DISCONNECT,
897
894
  });
898
895
  }
899
896
  catch (e) {
900
- log.warn('Failed to delete the call', {
897
+ log.warn(`Failed to delete the call: ${JSON.stringify(e)}`, {
901
898
  file: CALL_FILE,
902
- method: METHODS.HANDLE_OUTGOING_CALL_DISCONNECT,
899
+ method: METHODS.HANDLE_INCOMING_CALL_DISCONNECT,
903
900
  });
904
901
  uploadLogs({
905
902
  correlationId: this.correlationId,
@@ -921,7 +918,6 @@ export class Call extends Eventing {
921
918
  }
922
919
  this.sendMediaStateMachineEvt({ type: 'E_ROAP_TEARDOWN' });
923
920
  this.sendCallStateMachineEvt({ type: 'E_CALL_CLEARED' });
924
- this.emit(CALL_EVENT_KEYS.DISCONNECT, this.correlationId);
925
921
  }
926
922
  async handleOutgoingCallDisconnect(event) {
927
923
  log.info(`${METHOD_START_MESSAGE} with: ${this.getCorrelationId()}`, {
@@ -966,50 +962,70 @@ export class Call extends Eventing {
966
962
  this.sendMediaStateMachineEvt({ type: 'E_ROAP_TEARDOWN' });
967
963
  this.sendCallStateMachineEvt({ type: 'E_CALL_CLEARED' });
968
964
  }
969
- handleCallEstablished(event) {
970
- log.info(`${METHOD_START_MESSAGE} with: ${this.getCorrelationId()}`, {
971
- file: CALL_FILE,
972
- method: METHODS.HANDLE_CALL_ESTABLISHED,
973
- });
974
- this.emit(CALL_EVENT_KEYS.ESTABLISHED, this.correlationId);
975
- this.earlyMedia = false;
976
- this.connected = true;
977
- if (this.sessionTimer) {
978
- log.log('Resetting session timer', {
965
+ callKeepaliveRetryCallback = (interval) => {
966
+ if (this.callKeepaliveRetryCount === MAX_CALL_KEEPALIVE_RETRY_COUNT) {
967
+ log.warn(`Max keepalive retry attempts reached. Aborting call keepalive for callId: ${this.callId}`, {
979
968
  file: CALL_FILE,
980
- method: METHODS.HANDLE_CALL_ESTABLISHED,
969
+ method: 'keepaliveRetryCallback',
981
970
  });
971
+ return;
972
+ }
973
+ this.callKeepaliveRetryCount += 1;
974
+ setTimeout(async () => {
975
+ try {
976
+ await this.postStatus();
977
+ this.scheduleCallKeepaliveInterval();
978
+ }
979
+ catch (err) {
980
+ await this.handleCallKeepaliveError(err);
981
+ }
982
+ }, interval * 1000);
983
+ };
984
+ handleCallKeepaliveError = async (err) => {
985
+ const error = err;
986
+ if (this.sessionTimer) {
982
987
  clearInterval(this.sessionTimer);
983
988
  }
989
+ const abort = await handleCallErrors((callError) => {
990
+ this.emit(CALL_EVENT_KEYS.CALL_ERROR, callError);
991
+ this.submitCallErrorMetric(callError);
992
+ }, ERROR_LAYER.CALL_CONTROL, this.callKeepaliveRetryCallback, this.getCorrelationId(), error, 'handleCallEstablished', CALL_FILE);
993
+ if (abort) {
994
+ this.sendCallStateMachineEvt({ type: 'E_SEND_CALL_DISCONNECT' });
995
+ this.emit(CALL_EVENT_KEYS.DISCONNECT, this.getCorrelationId());
996
+ this.callKeepaliveRetryCount = 0;
997
+ }
998
+ await uploadLogs({
999
+ correlationId: this.correlationId,
1000
+ callId: this.callId,
1001
+ broadworksCorrelationInfo: this.broadworksCorrelationInfo,
1002
+ });
1003
+ };
1004
+ scheduleCallKeepaliveInterval = () => {
1005
+ const loggerContext = {
1006
+ file: CALL_FILE,
1007
+ method: 'scheduleCallKeepaliveInterval',
1008
+ };
984
1009
  this.sessionTimer = setInterval(async () => {
985
1010
  try {
986
1011
  const res = await this.postStatus();
987
- log.info(`Session refresh successful`, {
988
- file: CALL_FILE,
989
- method: METHODS.HANDLE_CALL_ESTABLISHED,
990
- });
1012
+ log.info(`Session refresh successful`, loggerContext);
991
1013
  }
992
1014
  catch (err) {
993
- const error = err;
994
- if (this.sessionTimer) {
995
- clearInterval(this.sessionTimer);
996
- }
997
- handleCallErrors((callError) => {
998
- this.emit(CALL_EVENT_KEYS.CALL_ERROR, callError);
999
- this.submitCallErrorMetric(callError);
1000
- }, ERROR_LAYER.CALL_CONTROL, (interval) => {
1001
- setTimeout(() => {
1002
- this.postStatus();
1003
- this.sendCallStateMachineEvt({ type: 'E_CALL_ESTABLISHED' });
1004
- }, interval * 1000);
1005
- }, this.getCorrelationId(), error, this.handleCallEstablished.name, CALL_FILE);
1006
- await uploadLogs({
1007
- correlationId: this.correlationId,
1008
- callId: this.callId,
1009
- broadworksCorrelationInfo: this.broadworksCorrelationInfo,
1010
- });
1015
+ await this.handleCallKeepaliveError(err);
1011
1016
  }
1012
1017
  }, DEFAULT_SESSION_TIMER);
1018
+ };
1019
+ handleCallEstablished(event) {
1020
+ const loggerContext = {
1021
+ file: CALL_FILE,
1022
+ method: METHODS.HANDLE_CALL_ESTABLISHED,
1023
+ };
1024
+ log.info(`${METHOD_START_MESSAGE} with: ${this.getCorrelationId()}`, loggerContext);
1025
+ this.emit(CALL_EVENT_KEYS.ESTABLISHED, this.correlationId);
1026
+ this.earlyMedia = false;
1027
+ this.connected = true;
1028
+ this.scheduleCallKeepaliveInterval();
1013
1029
  }
1014
1030
  async handleUnknownState(event) {
1015
1031
  log.info(`${METHOD_START_MESSAGE} with: ${this.getCorrelationId()}`, {
@@ -1164,7 +1180,7 @@ export class Call extends Eventing {
1164
1180
  method: METHODS.HANDLE_ROAP_ERROR,
1165
1181
  });
1166
1182
  const message = event.data;
1167
- if (message) {
1183
+ if (message && message.messageType === 'ERROR') {
1168
1184
  try {
1169
1185
  const res = await this.postMedia(message);
1170
1186
  log.info(`Response code: ${res.statusCode}`, {
@@ -1219,7 +1235,7 @@ export class Call extends Eventing {
1219
1235
  });
1220
1236
  }
1221
1237
  catch (err) {
1222
- log.warn('Failed to process MediaOk request', {
1238
+ log.warn('Failed to send MediaOffer request', {
1223
1239
  file: CALL_FILE,
1224
1240
  method: METHODS.HANDLE_OUTGOING_ROAP_OFFER,
1225
1241
  });
@@ -1332,9 +1348,8 @@ export class Call extends Eventing {
1332
1348
  }
1333
1349
  catch (error) {
1334
1350
  const errorInfo = error;
1335
- const errorStatus = serviceErrorCodeHandler(errorInfo, loggerContext);
1336
- const errorLog = new Error(`Failed to upload webrtc telemetry statistics. ${errorStatus}`);
1337
- log.error(errorLog, loggerContext);
1351
+ const errorStatus = await serviceErrorCodeHandler(errorInfo, loggerContext);
1352
+ log.error(`Failed to upload webrtc telemetry statistics. ${JSON.stringify(errorStatus)}`, loggerContext);
1338
1353
  await uploadLogs({
1339
1354
  correlationId: this.correlationId,
1340
1355
  callId: this.callId,
@@ -137,6 +137,13 @@ export class CallManager extends Eventing {
137
137
  method: METHODS.DEQUEUE_WS_EVENTS,
138
138
  });
139
139
  const call = this.getCall(correlationId);
140
+ if (mobiusEvent.data.callerId) {
141
+ log.info('Processing Caller-Id data', {
142
+ file: CALL_MANAGER_FILE,
143
+ method: METHODS.DEQUEUE_WS_EVENTS,
144
+ });
145
+ call.startCallerIdResolution(mobiusEvent.data.callerId);
146
+ }
140
147
  call.sendCallStateMachineEvt({ type: 'E_RECV_CALL_PROGRESS', data: mobiusEvent.data });
141
148
  break;
142
149
  }
@@ -12,6 +12,7 @@ export const DEFAULT_LOCAL_CALL_ID = 'DefaultLocalId';
12
12
  export const DEFAULT_REHOMING_INTERVAL_MAX = 120;
13
13
  export const DEFAULT_REHOMING_INTERVAL_MIN = 60;
14
14
  export const DEFAULT_SESSION_TIMER = 1000 * 60 * 10;
15
+ export const MAX_CALL_KEEPALIVE_RETRY_COUNT = 4;
15
16
  export const DEVICES_ENDPOINT_RESOURCE = 'devices';
16
17
  export const DISCOVERY_URL = 'https://ds.ciscospark.com/v1/region';
17
18
  export const DUMMY_METRICS = {
@@ -112,6 +113,7 @@ export const REGISTRATION_UTIL = 'triggerRegistration';
112
113
  export const REGISTER_UTIL = 'attemptRegistrationWithServers';
113
114
  export const GET_MOBIUS_SERVERS_UTIL = 'getMobiusServers';
114
115
  export const KEEPALIVE_UTIL = 'startKeepaliveTimer';
116
+ export const RECONNECT_ON_FAILURE_UTIL = 'reconnectOnFailure';
115
117
  export const FAILBACK_UTIL = 'executeFailback';
116
118
  export const REG_429_RETRY_UTIL = 'handle429Retry';
117
119
  export const FAILOVER_UTIL = 'startFailoverTimer';
@@ -122,6 +124,7 @@ export const MOBIUS_US_PROD = 'mobius-us-east-1.prod.infra.webex.com';
122
124
  export const MOBIUS_EU_PROD = 'mobius-eu-central-1.prod.infra.webex.com';
123
125
  export const MOBIUS_US_INT = 'mobius-us-east-1.int.infra.webex.com';
124
126
  export const MOBIUS_EU_INT = 'mobius-eu-central-1.int.infra.webex.com';
127
+ export const FAILOVER_CACHE_PREFIX = 'wxc-failover-state';
125
128
  export const ICE_CANDIDATES_TIMEOUT = 3000;
126
129
  export const METHODS = {
127
130
  CONSTRUCTOR: 'constructor',