@webex/calling 3.8.1 → 3.9.0-multi-llms.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CallHistory/CallHistory.js +51 -46
- package/dist/CallHistory/CallHistory.js.map +1 -1
- package/dist/CallHistory/CallHistory.test.js +146 -147
- package/dist/CallHistory/CallHistory.test.js.map +1 -1
- package/dist/CallHistory/callHistoryFixtures.js.map +1 -1
- package/dist/CallHistory/constants.js.map +1 -1
- package/dist/CallHistory/types.js.map +1 -1
- package/dist/CallSettings/CallSettings.js +8 -8
- package/dist/CallSettings/CallSettings.js.map +1 -1
- package/dist/CallSettings/CallSettings.test.js +1 -1
- package/dist/CallSettings/CallSettings.test.js.map +1 -1
- package/dist/CallSettings/UcmBackendConnector.js +12 -11
- package/dist/CallSettings/UcmBackendConnector.js.map +1 -1
- package/dist/CallSettings/UcmBackendConnector.test.js +9 -10
- package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -1
- package/dist/CallSettings/WxCallBackendConnector.js +68 -61
- package/dist/CallSettings/WxCallBackendConnector.js.map +1 -1
- package/dist/CallSettings/WxCallBackendConnector.test.js +168 -102
- package/dist/CallSettings/WxCallBackendConnector.test.js.map +1 -1
- package/dist/CallSettings/constants.js.map +1 -1
- package/dist/CallSettings/testFixtures.js.map +1 -1
- package/dist/CallSettings/types.js.map +1 -1
- package/dist/CallingClient/CallingClient.js +530 -219
- package/dist/CallingClient/CallingClient.js.map +1 -1
- package/dist/CallingClient/CallingClient.test.js +500 -291
- package/dist/CallingClient/CallingClient.test.js.map +1 -1
- package/dist/CallingClient/callRecordFixtures.js.map +1 -1
- package/dist/CallingClient/calling/CallerId/index.js +2 -2
- package/dist/CallingClient/calling/CallerId/index.js.map +1 -1
- package/dist/CallingClient/calling/CallerId/index.test.js +8 -7
- package/dist/CallingClient/calling/CallerId/index.test.js.map +1 -1
- package/dist/CallingClient/calling/CallerId/types.js.map +1 -1
- package/dist/CallingClient/calling/call.js +369 -333
- package/dist/CallingClient/calling/call.js.map +1 -1
- package/dist/CallingClient/calling/call.test.js +411 -410
- package/dist/CallingClient/calling/call.test.js.map +1 -1
- package/dist/CallingClient/calling/callManager.js +3 -4
- package/dist/CallingClient/calling/callManager.js.map +1 -1
- package/dist/CallingClient/calling/callManager.test.js +67 -68
- package/dist/CallingClient/calling/callManager.test.js.map +1 -1
- package/dist/CallingClient/calling/index.js.map +1 -1
- package/dist/CallingClient/calling/types.js.map +1 -1
- package/dist/CallingClient/callingClientFixtures.js.map +1 -1
- package/dist/CallingClient/constants.js +11 -8
- package/dist/CallingClient/constants.js.map +1 -1
- package/dist/CallingClient/line/index.js +10 -11
- package/dist/CallingClient/line/index.js.map +1 -1
- package/dist/CallingClient/line/line.test.js +12 -17
- package/dist/CallingClient/line/line.test.js.map +1 -1
- package/dist/CallingClient/line/types.js.map +1 -1
- package/dist/CallingClient/registration/index.js.map +1 -1
- package/dist/CallingClient/registration/register.js +557 -442
- package/dist/CallingClient/registration/register.js.map +1 -1
- package/dist/CallingClient/registration/register.test.js +526 -395
- package/dist/CallingClient/registration/register.test.js.map +1 -1
- package/dist/CallingClient/registration/registerFixtures.js.map +1 -1
- package/dist/CallingClient/registration/types.js.map +1 -1
- package/dist/CallingClient/registration/webWorker.js +116 -0
- package/dist/CallingClient/registration/webWorker.js.map +1 -0
- package/dist/CallingClient/registration/webWorker.test.js +256 -0
- package/dist/CallingClient/registration/webWorker.test.js.map +1 -0
- package/dist/CallingClient/registration/webWorkerStr.js +15 -0
- package/dist/CallingClient/registration/webWorkerStr.js.map +1 -0
- package/dist/CallingClient/types.js.map +1 -1
- package/dist/CallingClient/windowsChromiumIceWarmupUtils.js +142 -0
- package/dist/CallingClient/windowsChromiumIceWarmupUtils.js.map +1 -0
- package/dist/Contacts/ContactsClient.js +244 -238
- package/dist/Contacts/ContactsClient.js.map +1 -1
- package/dist/Contacts/ContactsClient.test.js +89 -90
- package/dist/Contacts/ContactsClient.test.js.map +1 -1
- package/dist/Contacts/constants.js +2 -2
- package/dist/Contacts/constants.js.map +1 -1
- package/dist/Contacts/contactFixtures.js.map +1 -1
- package/dist/Contacts/types.js.map +1 -1
- package/dist/Errors/catalog/CallError.js +2 -2
- package/dist/Errors/catalog/CallError.js.map +1 -1
- package/dist/Errors/catalog/CallingDeviceError.js +2 -2
- package/dist/Errors/catalog/CallingDeviceError.js.map +1 -1
- package/dist/Errors/catalog/ExtendedError.js +3 -3
- package/dist/Errors/catalog/ExtendedError.js.map +1 -1
- package/dist/Errors/catalog/LineError.js +2 -2
- package/dist/Errors/catalog/LineError.js.map +1 -1
- package/dist/Errors/index.js.map +1 -1
- package/dist/Errors/types.js +2 -0
- package/dist/Errors/types.js.map +1 -1
- package/dist/Events/impl/index.js +2 -2
- package/dist/Events/impl/index.js.map +1 -1
- package/dist/Events/types.js.map +1 -1
- package/dist/Logger/index.js.map +1 -1
- package/dist/Logger/index.test.js.map +1 -1
- package/dist/Logger/types.js.map +1 -1
- package/dist/Metrics/index.js +175 -86
- package/dist/Metrics/index.js.map +1 -1
- package/dist/Metrics/index.test.js +70 -4
- package/dist/Metrics/index.test.js.map +1 -1
- package/dist/Metrics/types.js +15 -1
- package/dist/Metrics/types.js.map +1 -1
- package/dist/SDKConnector/index.js +0 -1
- package/dist/SDKConnector/index.js.map +1 -1
- package/dist/SDKConnector/index.test.js.map +1 -1
- package/dist/SDKConnector/types.js.map +1 -1
- package/dist/SDKConnector/utils.js.map +1 -1
- package/dist/SDKConnector/utils.test.js.map +1 -1
- package/dist/Voicemail/BroadworksBackendConnector.js +42 -39
- package/dist/Voicemail/BroadworksBackendConnector.js.map +1 -1
- package/dist/Voicemail/BroadworksBackendConnector.test.js +119 -120
- package/dist/Voicemail/BroadworksBackendConnector.test.js.map +1 -1
- package/dist/Voicemail/UcmBackendConnector.js +54 -47
- package/dist/Voicemail/UcmBackendConnector.js.map +1 -1
- package/dist/Voicemail/UcmBackendConnector.test.js +73 -74
- package/dist/Voicemail/UcmBackendConnector.test.js.map +1 -1
- package/dist/Voicemail/Voicemail.js +12 -11
- package/dist/Voicemail/Voicemail.js.map +1 -1
- package/dist/Voicemail/Voicemail.test.js +2 -2
- package/dist/Voicemail/Voicemail.test.js.map +1 -1
- package/dist/Voicemail/WxCallBackendConnector.js +78 -70
- package/dist/Voicemail/WxCallBackendConnector.js.map +1 -1
- package/dist/Voicemail/WxCallBackendConnector.test.js +184 -185
- package/dist/Voicemail/WxCallBackendConnector.test.js.map +1 -1
- package/dist/Voicemail/constants.js.map +1 -1
- package/dist/Voicemail/types.js.map +1 -1
- package/dist/Voicemail/voicemailFixture.js.map +1 -1
- package/dist/api.js.map +1 -1
- package/dist/common/Utils.js +125 -99
- package/dist/common/Utils.js.map +1 -1
- package/dist/common/Utils.test.js +283 -143
- package/dist/common/Utils.test.js.map +1 -1
- package/dist/common/constants.js.map +1 -1
- package/dist/common/index.js.map +1 -1
- package/dist/common/testUtil.js +1 -1
- package/dist/common/testUtil.js.map +1 -1
- package/dist/common/types.js +8 -1
- package/dist/common/types.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/module/CallHistory/CallHistory.js +4 -0
- package/dist/module/CallSettings/UcmBackendConnector.js +1 -0
- package/dist/module/CallSettings/WxCallBackendConnector.js +8 -1
- package/dist/module/CallingClient/CallingClient.js +199 -42
- package/dist/module/CallingClient/calling/call.js +79 -43
- package/dist/module/CallingClient/constants.js +10 -6
- package/dist/module/CallingClient/line/index.js +3 -3
- package/dist/module/CallingClient/registration/register.js +111 -72
- package/dist/module/CallingClient/registration/webWorker.js +60 -0
- package/dist/module/CallingClient/registration/webWorkerStr.js +93 -0
- package/dist/module/CallingClient/windowsChromiumIceWarmupUtils.js +59 -0
- package/dist/module/Contacts/ContactsClient.js +23 -17
- package/dist/module/Contacts/constants.js +1 -1
- package/dist/module/Errors/types.js +2 -0
- package/dist/module/Metrics/index.js +94 -33
- package/dist/module/Metrics/types.js +14 -0
- package/dist/module/Voicemail/BroadworksBackendConnector.js +3 -0
- package/dist/module/Voicemail/UcmBackendConnector.js +6 -0
- package/dist/module/Voicemail/WxCallBackendConnector.js +8 -0
- package/dist/module/common/Utils.js +37 -12
- package/dist/module/common/types.js +7 -0
- package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
- package/dist/types/CallSettings/UcmBackendConnector.d.ts.map +1 -1
- package/dist/types/CallSettings/WxCallBackendConnector.d.ts.map +1 -1
- package/dist/types/CallSettings/types.d.ts +1 -1
- package/dist/types/CallSettings/types.d.ts.map +1 -1
- package/dist/types/CallingClient/CallingClient.d.ts +12 -1
- package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
- package/dist/types/CallingClient/calling/types.d.ts +2 -1
- package/dist/types/CallingClient/calling/types.d.ts.map +1 -1
- package/dist/types/CallingClient/constants.d.ts +10 -6
- package/dist/types/CallingClient/constants.d.ts.map +1 -1
- package/dist/types/CallingClient/line/index.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/register.d.ts +2 -2
- package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/types.d.ts.map +1 -1
- package/dist/types/CallingClient/registration/webWorker.d.ts +3 -0
- package/dist/types/CallingClient/registration/webWorker.d.ts.map +1 -0
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts +3 -0
- package/dist/types/CallingClient/registration/webWorkerStr.d.ts.map +1 -0
- package/dist/types/CallingClient/windowsChromiumIceWarmupUtils.d.ts +5 -0
- package/dist/types/CallingClient/windowsChromiumIceWarmupUtils.d.ts.map +1 -0
- package/dist/types/Contacts/ContactsClient.d.ts.map +1 -1
- package/dist/types/Contacts/constants.d.ts +1 -1
- package/dist/types/Contacts/constants.d.ts.map +1 -1
- package/dist/types/Errors/types.d.ts +2 -0
- package/dist/types/Errors/types.d.ts.map +1 -1
- package/dist/types/Metrics/index.d.ts.map +1 -1
- package/dist/types/Metrics/types.d.ts +20 -4
- package/dist/types/Metrics/types.d.ts.map +1 -1
- package/dist/types/Voicemail/BroadworksBackendConnector.d.ts.map +1 -1
- package/dist/types/Voicemail/UcmBackendConnector.d.ts.map +1 -1
- package/dist/types/Voicemail/WxCallBackendConnector.d.ts.map +1 -1
- package/dist/types/common/Utils.d.ts.map +1 -1
- package/dist/types/common/types.d.ts +13 -0
- package/dist/types/common/types.d.ts.map +1 -1
- package/package.json +10 -8
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { v4 as uuid } from 'uuid';
|
|
2
2
|
import { METHOD_START_MESSAGE } from '../../common/constants';
|
|
3
3
|
import { emitFinalFailure, handleRegistrationErrors, uploadLogs } from '../../common';
|
|
4
|
-
import
|
|
4
|
+
import webWorkerStr from './webWorkerStr';
|
|
5
|
+
import { METRIC_EVENT, METRIC_TYPE, REG_ACTION, } from '../../Metrics/types';
|
|
5
6
|
import { getMetricManager } from '../../Metrics';
|
|
6
7
|
import { getCallManager } from '../calling';
|
|
7
8
|
import log from '../../Logger';
|
|
8
9
|
import SDKConnector from '../../SDKConnector';
|
|
9
|
-
import { ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, ServiceIndicator, } from '../../common/types';
|
|
10
|
-
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,
|
|
10
|
+
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, } from '../constants';
|
|
11
12
|
import { LINE_EVENTS } from '../line/types';
|
|
12
13
|
export class Registration {
|
|
13
14
|
sdkConnector;
|
|
@@ -18,7 +19,6 @@ export class Registration {
|
|
|
18
19
|
registrationStatus;
|
|
19
20
|
failbackTimer;
|
|
20
21
|
activeMobiusUrl;
|
|
21
|
-
keepaliveTimer;
|
|
22
22
|
rehomingIntervalMin;
|
|
23
23
|
rehomingIntervalMax;
|
|
24
24
|
mutex;
|
|
@@ -35,6 +35,7 @@ export class Registration {
|
|
|
35
35
|
failoverImmediately = false;
|
|
36
36
|
retryAfter;
|
|
37
37
|
scheduled429Retry = false;
|
|
38
|
+
webWorker;
|
|
38
39
|
constructor(webex, serviceData, mutex, lineEmitter, logLevel, jwe) {
|
|
39
40
|
this.jwe = jwe;
|
|
40
41
|
this.sdkConnector = SDKConnector;
|
|
@@ -73,17 +74,6 @@ export class Registration {
|
|
|
73
74
|
this.primaryMobiusUris = primaryMobiusUris;
|
|
74
75
|
this.backupMobiusUris = backupMobiusUris;
|
|
75
76
|
}
|
|
76
|
-
async postKeepAlive(url) {
|
|
77
|
-
return this.webex.request({
|
|
78
|
-
uri: `${url}/status`,
|
|
79
|
-
method: HTTP_METHODS.POST,
|
|
80
|
-
headers: {
|
|
81
|
-
[CISCO_DEVICE_URL]: this.webex.internal.device.url,
|
|
82
|
-
[SPARK_USER_AGENT]: CALLING_USER_AGENT,
|
|
83
|
-
},
|
|
84
|
-
service: ALLOWED_SERVICES.MOBIUS,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
77
|
async deleteRegistration(url, deviceId, deviceUrl) {
|
|
88
78
|
let response;
|
|
89
79
|
try {
|
|
@@ -100,8 +90,9 @@ export class Registration {
|
|
|
100
90
|
catch (error) {
|
|
101
91
|
log.warn(`Delete failed with Mobius ${error}`, {
|
|
102
92
|
file: REGISTRATION_FILE,
|
|
103
|
-
method: METHODS.
|
|
93
|
+
method: METHODS.DELETE_REGISTRATION,
|
|
104
94
|
});
|
|
95
|
+
await uploadLogs();
|
|
105
96
|
}
|
|
106
97
|
this.setStatus(RegistrationStatus.INACTIVE);
|
|
107
98
|
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
@@ -167,9 +158,7 @@ export class Registration {
|
|
|
167
158
|
method: FAILOVER_UTIL,
|
|
168
159
|
};
|
|
169
160
|
let interval = this.getRegRetryInterval(attempt);
|
|
170
|
-
const TIMER_THRESHOLD =
|
|
171
|
-
? REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC
|
|
172
|
-
: REG_TRY_BACKUP_TIMER_VAL_IN_SEC;
|
|
161
|
+
const TIMER_THRESHOLD = REG_TRY_BACKUP_TIMER_VAL_IN_SEC;
|
|
173
162
|
if (timeElapsed + interval > TIMER_THRESHOLD) {
|
|
174
163
|
const excessVal = timeElapsed + interval - TIMER_THRESHOLD;
|
|
175
164
|
interval -= excessVal;
|
|
@@ -230,6 +219,40 @@ export class Registration {
|
|
|
230
219
|
this.failbackTimer = undefined;
|
|
231
220
|
}
|
|
232
221
|
}
|
|
222
|
+
async isPrimaryActive() {
|
|
223
|
+
let status;
|
|
224
|
+
for (const mobiusUrl of this.primaryMobiusUris) {
|
|
225
|
+
try {
|
|
226
|
+
const baseUri = mobiusUrl.replace(URL_ENDPOINT, '/');
|
|
227
|
+
const response = await this.webex.request({
|
|
228
|
+
uri: `${baseUri}ping`,
|
|
229
|
+
method: HTTP_METHODS.GET,
|
|
230
|
+
headers: {
|
|
231
|
+
[CISCO_DEVICE_URL]: this.webex.internal.device.url,
|
|
232
|
+
[SPARK_USER_AGENT]: CALLING_USER_AGENT,
|
|
233
|
+
},
|
|
234
|
+
service: ALLOWED_SERVICES.MOBIUS,
|
|
235
|
+
});
|
|
236
|
+
const { statusCode } = response;
|
|
237
|
+
if (statusCode === 200) {
|
|
238
|
+
log.info(`Ping successful for primary Mobius: ${mobiusUrl}`, {
|
|
239
|
+
file: REGISTRATION_FILE,
|
|
240
|
+
method: FAILBACK_UTIL,
|
|
241
|
+
});
|
|
242
|
+
status = 'up';
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
log.warn(`Ping failed for primary Mobius: ${mobiusUrl} with error: ${error}`, {
|
|
248
|
+
file: REGISTRATION_FILE,
|
|
249
|
+
method: FAILBACK_UTIL,
|
|
250
|
+
});
|
|
251
|
+
status = 'down';
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return status === 'up';
|
|
255
|
+
}
|
|
233
256
|
isFailbackRequired() {
|
|
234
257
|
return this.isDeviceRegistered() && this.primaryMobiusUris.indexOf(this.activeMobiusUrl) === -1;
|
|
235
258
|
}
|
|
@@ -260,7 +283,8 @@ export class Registration {
|
|
|
260
283
|
async executeFailback() {
|
|
261
284
|
await this.mutex.runExclusive(async () => {
|
|
262
285
|
if (this.isFailbackRequired()) {
|
|
263
|
-
|
|
286
|
+
const primaryServerStatus = await this.isPrimaryActive();
|
|
287
|
+
if (Object.keys(this.callManager.getActiveCalls()).length === 0 && primaryServerStatus) {
|
|
264
288
|
log.info(`Attempting failback to primary.`, {
|
|
265
289
|
file: REGISTRATION_FILE,
|
|
266
290
|
method: this.executeFailback.name,
|
|
@@ -284,7 +308,7 @@ export class Registration {
|
|
|
284
308
|
}
|
|
285
309
|
}
|
|
286
310
|
else {
|
|
287
|
-
log.info('Active calls present, deferring failback to next cycle.', {
|
|
311
|
+
log.info('Active calls present or primary Mobius is down, deferring failback to next cycle.', {
|
|
288
312
|
file: REGISTRATION_FILE,
|
|
289
313
|
method: this.executeFailback.name,
|
|
290
314
|
});
|
|
@@ -331,18 +355,18 @@ export class Registration {
|
|
|
331
355
|
});
|
|
332
356
|
await this.mutex.runExclusive(async () => {
|
|
333
357
|
if (retry) {
|
|
334
|
-
log.log('
|
|
358
|
+
log.log('Network is up again, re-registering with Webex Calling if needed', {
|
|
335
359
|
file: REGISTRATION_FILE,
|
|
336
|
-
method:
|
|
360
|
+
method: METHODS.HANDLE_CONNECTION_RESTORATION,
|
|
337
361
|
});
|
|
338
362
|
this.clearKeepaliveTimer();
|
|
339
363
|
if (this.isDeviceRegistered()) {
|
|
340
364
|
await this.deregister();
|
|
341
365
|
}
|
|
342
366
|
if (this.activeMobiusUrl) {
|
|
343
|
-
const abort = await this.restorePreviousRegistration(
|
|
367
|
+
const abort = await this.restorePreviousRegistration(METHODS.HANDLE_CONNECTION_RESTORATION);
|
|
344
368
|
if (!abort && !this.isDeviceRegistered()) {
|
|
345
|
-
await this.restartRegistration(
|
|
369
|
+
await this.restartRegistration(METHODS.HANDLE_CONNECTION_RESTORATION);
|
|
346
370
|
}
|
|
347
371
|
}
|
|
348
372
|
retry = false;
|
|
@@ -376,7 +400,7 @@ export class Registration {
|
|
|
376
400
|
}
|
|
377
401
|
async triggerRegistration() {
|
|
378
402
|
if (this.primaryMobiusUris.length > 0) {
|
|
379
|
-
const abort = await this.attemptRegistrationWithServers(
|
|
403
|
+
const abort = await this.attemptRegistrationWithServers(REGISTRATION_UTIL, this.primaryMobiusUris);
|
|
380
404
|
if (!this.isDeviceRegistered() && !abort) {
|
|
381
405
|
await this.startFailoverTimer();
|
|
382
406
|
}
|
|
@@ -396,6 +420,9 @@ export class Registration {
|
|
|
396
420
|
return abort;
|
|
397
421
|
}
|
|
398
422
|
for (const url of servers) {
|
|
423
|
+
const serverType = (this.primaryMobiusUris.includes(url) && 'PRIMARY') ||
|
|
424
|
+
(this.backupMobiusUris?.includes(url) && 'BACKUP') ||
|
|
425
|
+
'UNKNOWN';
|
|
399
426
|
try {
|
|
400
427
|
abort = false;
|
|
401
428
|
this.registrationStatus = RegistrationStatus.INACTIVE;
|
|
@@ -407,16 +434,16 @@ export class Registration {
|
|
|
407
434
|
const resp = await this.postRegistration(url);
|
|
408
435
|
this.deviceInfo = resp.body;
|
|
409
436
|
this.registrationStatus = RegistrationStatus.ACTIVE;
|
|
437
|
+
this.setActiveMobiusUrl(url);
|
|
410
438
|
this.lineEmitter(LINE_EVENTS.REGISTERED, resp.body);
|
|
411
|
-
log.log(`Registration successful for deviceId: ${this.deviceInfo.device?.deviceId} userId: ${this.userId}`, {
|
|
439
|
+
log.log(`Registration successful for deviceId: ${this.deviceInfo.device?.deviceId} userId: ${this.userId} responseTrackingId: ${resp.headers?.trackingid}`, {
|
|
412
440
|
file: REGISTRATION_FILE,
|
|
413
441
|
method: METHODS.REGISTER,
|
|
414
442
|
});
|
|
415
|
-
this.setActiveMobiusUrl(url);
|
|
416
443
|
this.setIntervalValues(this.deviceInfo);
|
|
417
444
|
this.metricManager.setDeviceInfo(this.deviceInfo);
|
|
418
|
-
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, undefined);
|
|
419
|
-
this.startKeepaliveTimer(this.deviceInfo.device?.uri, this.deviceInfo.keepaliveInterval);
|
|
445
|
+
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, caller, serverType, resp.headers?.trackingid ?? '', undefined, undefined);
|
|
446
|
+
this.startKeepaliveTimer(this.deviceInfo.device?.uri, this.deviceInfo.keepaliveInterval, serverType);
|
|
420
447
|
this.initiateFailback();
|
|
421
448
|
break;
|
|
422
449
|
}
|
|
@@ -429,7 +456,7 @@ export class Registration {
|
|
|
429
456
|
else {
|
|
430
457
|
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
431
458
|
}
|
|
432
|
-
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, clientError);
|
|
459
|
+
this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION_ERROR, REG_ACTION.REGISTER, METRIC_TYPE.BEHAVIORAL, caller, serverType, body.headers?.trackingid ?? '', undefined, clientError);
|
|
433
460
|
}, { method: caller, file: REGISTRATION_FILE }, (retryAfter, retryCaller) => this.handle429Retry(retryAfter, retryCaller), this.restoreRegistrationCallBack());
|
|
434
461
|
if (this.registrationStatus === RegistrationStatus.ACTIVE) {
|
|
435
462
|
log.info(`[${caller}] : Device is already restored, active mobius url: ${this.activeMobiusUrl}`, {
|
|
@@ -440,63 +467,75 @@ export class Registration {
|
|
|
440
467
|
}
|
|
441
468
|
if (abort) {
|
|
442
469
|
this.setStatus(RegistrationStatus.INACTIVE);
|
|
470
|
+
await uploadLogs();
|
|
443
471
|
break;
|
|
444
472
|
}
|
|
445
473
|
}
|
|
446
474
|
}
|
|
447
475
|
return abort;
|
|
448
476
|
}
|
|
449
|
-
startKeepaliveTimer(url, interval) {
|
|
450
|
-
let keepAliveRetryCount = 0;
|
|
477
|
+
async startKeepaliveTimer(url, interval, serverType) {
|
|
451
478
|
this.clearKeepaliveTimer();
|
|
452
479
|
const RETRY_COUNT_THRESHOLD = this.isCCFlow ? 4 : 5;
|
|
453
|
-
this.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
480
|
+
await this.mutex.runExclusive(async () => {
|
|
481
|
+
if (this.isDeviceRegistered()) {
|
|
482
|
+
const accessToken = await this.webex.credentials.getUserToken();
|
|
483
|
+
if (!this.webWorker) {
|
|
484
|
+
const blob = new Blob([webWorkerStr], { type: 'application/javascript' });
|
|
485
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
486
|
+
this.webWorker = new Worker(blobUrl);
|
|
487
|
+
URL.revokeObjectURL(blobUrl);
|
|
488
|
+
this.webWorker.postMessage({
|
|
489
|
+
type: WorkerMessageType.START_KEEPALIVE,
|
|
490
|
+
accessToken: String(accessToken),
|
|
491
|
+
deviceUrl: String(this.webex.internal.device.url),
|
|
492
|
+
interval,
|
|
493
|
+
retryCountThreshold: RETRY_COUNT_THRESHOLD,
|
|
494
|
+
url,
|
|
495
|
+
});
|
|
496
|
+
this.webWorker.onmessage = async (event) => {
|
|
497
|
+
const logContext = {
|
|
498
|
+
file: REGISTRATION_FILE,
|
|
499
|
+
method: this.startKeepaliveTimer.name,
|
|
500
|
+
};
|
|
501
|
+
if (event.data.type === WorkerMessageType.KEEPALIVE_SUCCESS) {
|
|
502
|
+
log.info(`Sent Keepalive, status: ${event.data.statusCode}`, logContext);
|
|
464
503
|
this.lineEmitter(LINE_EVENTS.RECONNECTED);
|
|
465
504
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
505
|
+
if (event.data.type === WorkerMessageType.KEEPALIVE_FAILURE) {
|
|
506
|
+
const error = event.data.err;
|
|
507
|
+
log.warn(`Keep-alive missed ${event.data.keepAliveRetryCount} times. Status -> ${error.statusCode} `, logContext);
|
|
508
|
+
const abort = await handleRegistrationErrors(error, (clientError, finalError) => {
|
|
509
|
+
if (finalError) {
|
|
510
|
+
this.lineEmitter(LINE_EVENTS.ERROR, undefined, clientError);
|
|
511
|
+
}
|
|
512
|
+
this.metricManager.submitRegistrationMetric(METRIC_EVENT.KEEPALIVE_ERROR, REG_ACTION.KEEPALIVE_FAILURE, METRIC_TYPE.BEHAVIORAL, KEEPALIVE_UTIL, serverType, error.headers?.trackingid ?? '', event.data.keepAliveRetryCount, clientError);
|
|
513
|
+
}, { method: KEEPALIVE_UTIL, file: REGISTRATION_FILE });
|
|
514
|
+
if (abort || event.data.keepAliveRetryCount >= RETRY_COUNT_THRESHOLD) {
|
|
515
|
+
this.failoverImmediately = this.isCCFlow;
|
|
516
|
+
this.setStatus(RegistrationStatus.INACTIVE);
|
|
517
|
+
this.clearKeepaliveTimer();
|
|
518
|
+
this.clearFailbackTimer();
|
|
519
|
+
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
520
|
+
await uploadLogs();
|
|
521
|
+
if (!abort) {
|
|
522
|
+
await this.reconnectOnFailure(KEEPALIVE_UTIL);
|
|
523
|
+
}
|
|
475
524
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if (abort || keepAliveRetryCount >= RETRY_COUNT_THRESHOLD) {
|
|
479
|
-
this.failoverImmediately = this.isCCFlow;
|
|
480
|
-
this.setStatus(RegistrationStatus.INACTIVE);
|
|
481
|
-
this.clearKeepaliveTimer();
|
|
482
|
-
this.clearFailbackTimer();
|
|
483
|
-
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
|
|
484
|
-
if (!abort) {
|
|
485
|
-
await this.reconnectOnFailure(this.startKeepaliveTimer.name);
|
|
525
|
+
else {
|
|
526
|
+
this.lineEmitter(LINE_EVENTS.RECONNECTING);
|
|
486
527
|
}
|
|
487
528
|
}
|
|
488
|
-
|
|
489
|
-
this.lineEmitter(LINE_EVENTS.RECONNECTING);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
529
|
+
};
|
|
492
530
|
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
531
|
+
}
|
|
532
|
+
});
|
|
495
533
|
}
|
|
496
534
|
clearKeepaliveTimer() {
|
|
497
|
-
if (this.
|
|
498
|
-
|
|
499
|
-
this.
|
|
535
|
+
if (this.webWorker) {
|
|
536
|
+
this.webWorker.postMessage({ type: WorkerMessageType.CLEAR_KEEPALIVE });
|
|
537
|
+
this.webWorker.terminate();
|
|
538
|
+
this.webWorker = undefined;
|
|
500
539
|
}
|
|
501
540
|
}
|
|
502
541
|
isReconnectPending() {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { v4 as uuid } from 'uuid';
|
|
2
|
+
import { HTTP_METHODS, WorkerMessageType } from '../../common/types';
|
|
3
|
+
let keepaliveTimer;
|
|
4
|
+
const messageHandler = (event) => {
|
|
5
|
+
const { type } = event.data;
|
|
6
|
+
const postKeepAlive = async (accessToken, deviceUrl, url) => {
|
|
7
|
+
const response = await fetch(`${url}/status`, {
|
|
8
|
+
method: HTTP_METHODS.POST,
|
|
9
|
+
headers: {
|
|
10
|
+
'cisco-device-url': deviceUrl,
|
|
11
|
+
'spark-user-agent': 'webex-calling/beta',
|
|
12
|
+
Authorization: `${accessToken}`,
|
|
13
|
+
trackingId: `web_worker_${uuid()}`,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new Error(`Keepalive failed with status: ${response.status}`);
|
|
18
|
+
}
|
|
19
|
+
return response;
|
|
20
|
+
};
|
|
21
|
+
if (type === WorkerMessageType.START_KEEPALIVE) {
|
|
22
|
+
let keepAliveRetryCount = 0;
|
|
23
|
+
const { accessToken, deviceUrl, interval, retryCountThreshold, url } = event.data;
|
|
24
|
+
if (keepaliveTimer) {
|
|
25
|
+
clearInterval(keepaliveTimer);
|
|
26
|
+
keepaliveTimer = undefined;
|
|
27
|
+
}
|
|
28
|
+
keepaliveTimer = setInterval(async () => {
|
|
29
|
+
if (keepAliveRetryCount < retryCountThreshold) {
|
|
30
|
+
try {
|
|
31
|
+
const res = await postKeepAlive(accessToken, deviceUrl, url);
|
|
32
|
+
const statusCode = res.status;
|
|
33
|
+
if (keepAliveRetryCount > 0) {
|
|
34
|
+
postMessage({
|
|
35
|
+
type: WorkerMessageType.KEEPALIVE_SUCCESS,
|
|
36
|
+
statusCode,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
keepAliveRetryCount = 0;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
keepAliveRetryCount += 1;
|
|
43
|
+
postMessage({
|
|
44
|
+
type: WorkerMessageType.KEEPALIVE_FAILURE,
|
|
45
|
+
err,
|
|
46
|
+
keepAliveRetryCount,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, interval * 1000);
|
|
51
|
+
}
|
|
52
|
+
if (type === WorkerMessageType.CLEAR_KEEPALIVE) {
|
|
53
|
+
if (keepaliveTimer) {
|
|
54
|
+
clearInterval(keepaliveTimer);
|
|
55
|
+
keepaliveTimer = undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
self.addEventListener('message', messageHandler);
|
|
60
|
+
export default messageHandler;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const webWorkerStr = `/* eslint-env worker */
|
|
2
|
+
|
|
3
|
+
const uuid = () => {
|
|
4
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
5
|
+
const r = (Math.random() * 16) | 0;
|
|
6
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
7
|
+
return v.toString(16);
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// Enum values from the original imports
|
|
12
|
+
const HTTP_METHODS = {
|
|
13
|
+
GET: 'GET',
|
|
14
|
+
POST: 'POST',
|
|
15
|
+
PUT: 'PUT',
|
|
16
|
+
DELETE: 'DELETE',
|
|
17
|
+
PATCH: 'PATCH',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const WorkerMessageType = {
|
|
21
|
+
START_KEEPALIVE: 'START_KEEPALIVE',
|
|
22
|
+
CLEAR_KEEPALIVE: 'CLEAR_KEEPALIVE',
|
|
23
|
+
KEEPALIVE_SUCCESS: 'KEEPALIVE_SUCCESS',
|
|
24
|
+
KEEPALIVE_FAILURE: 'KEEPALIVE_FAILURE',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
let keepaliveTimer;
|
|
28
|
+
|
|
29
|
+
const messageHandler = (event) => {
|
|
30
|
+
const {type} = event.data;
|
|
31
|
+
|
|
32
|
+
const postKeepAlive = async (accessToken, deviceUrl, url) => {
|
|
33
|
+
const response = await fetch(\`\${url}/status\`, {
|
|
34
|
+
method: HTTP_METHODS.POST,
|
|
35
|
+
headers: {
|
|
36
|
+
'cisco-device-url': deviceUrl,
|
|
37
|
+
'spark-user-agent': 'webex-calling/beta',
|
|
38
|
+
Authorization: \`\${accessToken}\`,
|
|
39
|
+
trackingId: \`web_worker_\${uuid()}\`,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(\`Keepalive failed with status: \${response.status}\`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (type === WorkerMessageType.START_KEEPALIVE) {
|
|
51
|
+
let keepAliveRetryCount = 0;
|
|
52
|
+
const {accessToken, deviceUrl, interval, retryCountThreshold, url} = event.data;
|
|
53
|
+
|
|
54
|
+
if (keepaliveTimer) {
|
|
55
|
+
clearInterval(keepaliveTimer);
|
|
56
|
+
keepaliveTimer = undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
keepaliveTimer = setInterval(async () => {
|
|
60
|
+
if (keepAliveRetryCount < retryCountThreshold) {
|
|
61
|
+
try {
|
|
62
|
+
const res = await postKeepAlive(accessToken, deviceUrl, url);
|
|
63
|
+
const statusCode = res.status;
|
|
64
|
+
if (keepAliveRetryCount > 0) {
|
|
65
|
+
self.postMessage({
|
|
66
|
+
type: WorkerMessageType.KEEPALIVE_SUCCESS,
|
|
67
|
+
statusCode,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
keepAliveRetryCount = 0;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
keepAliveRetryCount += 1;
|
|
73
|
+
self.postMessage({
|
|
74
|
+
type: WorkerMessageType.KEEPALIVE_FAILURE,
|
|
75
|
+
err,
|
|
76
|
+
keepAliveRetryCount,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, interval * 1000);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (type === WorkerMessageType.CLEAR_KEEPALIVE) {
|
|
84
|
+
if (keepaliveTimer) {
|
|
85
|
+
clearInterval(keepaliveTimer);
|
|
86
|
+
keepaliveTimer = undefined;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
self.addEventListener('message', messageHandler);
|
|
92
|
+
`;
|
|
93
|
+
export default webWorkerStr;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function waitForIceComplete(pc, timeoutMs) {
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
if (!pc) {
|
|
4
|
+
resolve({ ok: false, reason: 'no-pc' });
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
if (pc.iceGatheringState === 'complete') {
|
|
8
|
+
resolve({ ok: true, reached: 'already' });
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let done = false;
|
|
12
|
+
const onChange = () => {
|
|
13
|
+
if (pc.iceGatheringState === 'complete' && !done) {
|
|
14
|
+
done = true;
|
|
15
|
+
pc.removeEventListener('icegatheringstatechange', onChange);
|
|
16
|
+
resolve({ ok: true, reached: 'event' });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
pc.addEventListener('icegatheringstatechange', onChange);
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
if (done)
|
|
22
|
+
return;
|
|
23
|
+
done = true;
|
|
24
|
+
pc.removeEventListener('icegatheringstatechange', onChange);
|
|
25
|
+
resolve({ ok: pc.iceGatheringState === 'complete', reached: 'timeout' });
|
|
26
|
+
}, timeoutMs);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export default async function windowsChromiumIceWarmup({ iceServers = [], timeoutMs = 1000 }) {
|
|
30
|
+
const pc1 = new RTCPeerConnection({ iceServers, iceCandidatePoolSize: 1 });
|
|
31
|
+
const pc2 = new RTCPeerConnection({ iceServers, iceCandidatePoolSize: 1 });
|
|
32
|
+
const candidates = { pc1: [], pc2: [] };
|
|
33
|
+
pc1.onicecandidate = (e) => {
|
|
34
|
+
if (e.candidate && e.candidate.type !== 'host') {
|
|
35
|
+
candidates.pc1.push(e.candidate);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
await pc1.createDataChannel('warmup');
|
|
39
|
+
await pc1.addTransceiver('audio');
|
|
40
|
+
const offer = await pc1.createOffer();
|
|
41
|
+
await pc1.setLocalDescription(offer);
|
|
42
|
+
await waitForIceComplete(pc1, timeoutMs);
|
|
43
|
+
await pc2.setRemoteDescription(offer);
|
|
44
|
+
pc2.onicecandidate = (e) => {
|
|
45
|
+
if (e.candidate && e.candidate.type !== 'host') {
|
|
46
|
+
candidates.pc2.push(e.candidate);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const answer = await pc2.createAnswer();
|
|
50
|
+
await pc2.setLocalDescription(answer);
|
|
51
|
+
await pc1.setRemoteDescription(answer);
|
|
52
|
+
await waitForIceComplete(pc2, timeoutMs);
|
|
53
|
+
await Promise.all([
|
|
54
|
+
...candidates.pc1.map((candidate) => pc2.addIceCandidate(candidate).catch(console.error)),
|
|
55
|
+
...candidates.pc2.map((candidate) => pc1.addIceCandidate(candidate).catch(console.error)),
|
|
56
|
+
]);
|
|
57
|
+
pc1.close();
|
|
58
|
+
pc2.close();
|
|
59
|
+
}
|