@webex/plugin-meetings 3.0.0-beta.37 → 3.0.0-beta.370
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/README.md +58 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +94 -15
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +671 -81
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +45 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.js +236 -33
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +117 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +366 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +383 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +57 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +61 -101
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +1 -204
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +86 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +4021 -2828
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +224 -136
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +173 -152
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +672 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +192 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +478 -118
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +73 -7
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +58 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +132 -25
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +102 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +17 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -446
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +228 -58
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +29 -16
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +39 -36
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +44 -18
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +60 -3
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +209 -59
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +233 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +263 -390
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +6 -4
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reconnection-manager/index.js +267 -200
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +51 -28
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +48 -64
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +220 -70
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +179 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +179 -215
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +35 -28
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/utils.d.ts +14 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +2 -7
- package/dist/types/constants.d.ts +200 -31
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -4
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +66 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -49
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -128
- package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
- package/dist/types/meeting/index.d.ts +559 -496
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +93 -25
- package/dist/types/meeting/request.d.ts +62 -43
- package/dist/types/meeting/util.d.ts +117 -1
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +17 -0
- package/dist/types/meetings/index.d.ts +112 -20
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +16 -0
- package/dist/types/metrics/index.d.ts +4 -111
- package/dist/types/multistream/mediaRequestManager.d.ts +72 -5
- package/dist/types/multistream/receiveSlot.d.ts +13 -11
- package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
- package/dist/types/multistream/remoteMedia.d.ts +8 -29
- package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
- package/dist/types/multistream/sendSlotManager.d.ts +61 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +60 -95
- package/dist/types/reachability/request.d.ts +3 -1
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reconnection-manager/index.d.ts +19 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +9 -8
- package/dist/types/roap/turnDiscovery.d.ts +39 -5
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +61 -0
- package/dist/types/statsAnalyzer/index.d.ts +29 -11
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +22 -19
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +35 -11
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +558 -59
- package/src/breakouts/utils.ts +42 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -9
- package/src/constants.ts +224 -21
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +44 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +332 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +414 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +64 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +97 -107
- package/src/media/properties.ts +88 -117
- package/src/mediaQualityMetrics/config.ts +0 -135
- package/src/meeting/in-meeting-actions.ts +171 -3
- package/src/meeting/index.ts +3363 -2453
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +223 -136
- package/src/meeting/request.ts +149 -120
- package/src/meeting/util.ts +685 -395
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +170 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +497 -126
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +81 -12
- package/src/member/index.ts +58 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +134 -8
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +16 -0
- package/src/metrics/index.ts +1 -469
- package/src/multistream/mediaRequestManager.ts +277 -82
- package/src/multistream/receiveSlot.ts +31 -17
- package/src/multistream/receiveSlotManager.ts +34 -24
- package/src/multistream/remoteMedia.ts +27 -2
- package/src/multistream/remoteMediaGroup.ts +59 -0
- package/src/multistream/remoteMediaManager.ts +148 -30
- package/src/multistream/sendSlotManager.ts +170 -0
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +229 -346
- package/src/reachability/request.ts +8 -4
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +139 -106
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +52 -23
- package/src/roap/request.ts +48 -67
- package/src/roap/turnDiscovery.ts +147 -49
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +166 -0
- package/src/statsAnalyzer/index.ts +219 -289
- package/src/statsAnalyzer/mqaUtil.ts +43 -44
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +118 -28
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1349 -114
- package/test/unit/spec/breakouts/utils.js +52 -1
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +589 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1352 -33
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +118 -37
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
- package/test/unit/spec/meeting/index.js +6722 -2200
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +402 -212
- package/test/unit/spec/meeting/request.js +471 -54
- package/test/unit/spec/meeting/utils.js +773 -67
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1393 -212
- package/test/unit/spec/meetings/utils.js +229 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +776 -162
- package/test/unit/spec/multistream/receiveSlot.ts +28 -20
- package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
- package/test/unit/spec/multistream/remoteMedia.ts +30 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +551 -14
- package/test/unit/spec/reachability/request.js +3 -1
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +153 -11
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +180 -83
- package/test/unit/spec/roap/request.ts +100 -62
- package/test/unit/spec/roap/turnDiscovery.ts +388 -96
- package/test/unit/spec/rtcMetrics/index.ts +122 -0
- package/test/unit/spec/stats-analyzer/index.js +664 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -57
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/metrics/config.d.ts +0 -169
- package/src/index.js +0 -16
- package/src/metrics/config.ts +0 -485
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
2
|
-
import {HTTP_VERBS, RESOURCE, API} from '../constants';
|
|
2
|
+
import {HTTP_VERBS, RESOURCE, API, IP_VERSION} from '../constants';
|
|
3
3
|
|
|
4
4
|
export interface ClusterNode {
|
|
5
5
|
isVideoMesh: boolean;
|
|
@@ -30,9 +30,10 @@ class ReachabilityRequest {
|
|
|
30
30
|
/**
|
|
31
31
|
* Gets the cluster information
|
|
32
32
|
*
|
|
33
|
+
* @param {IP_VERSION} ipVersion information about current ip network we're on
|
|
33
34
|
* @returns {Promise}
|
|
34
35
|
*/
|
|
35
|
-
getClusters = (): Promise<{clusters: ClusterList; joinCookie: any}> =>
|
|
36
|
+
getClusters = (ipVersion?: IP_VERSION): Promise<{clusters: ClusterList; joinCookie: any}> =>
|
|
36
37
|
this.webex
|
|
37
38
|
.request({
|
|
38
39
|
method: HTTP_VERBS.GET,
|
|
@@ -41,17 +42,20 @@ class ReachabilityRequest {
|
|
|
41
42
|
resource: RESOURCE.CLUSTERS,
|
|
42
43
|
qs: {
|
|
43
44
|
JCSupport: 1,
|
|
45
|
+
ipver: ipVersion,
|
|
44
46
|
},
|
|
45
47
|
})
|
|
46
48
|
.then((res) => {
|
|
47
49
|
const {clusters, joinCookie} = res.body;
|
|
48
50
|
|
|
49
51
|
Object.keys(clusters).forEach((key) => {
|
|
50
|
-
clusters[key].isVideoMesh = res.body.clusterClasses?.hybridMedia?.includes(key);
|
|
52
|
+
clusters[key].isVideoMesh = !!res.body.clusterClasses?.hybridMedia?.includes(key);
|
|
51
53
|
});
|
|
52
54
|
|
|
53
55
|
LoggerProxy.logger.log(
|
|
54
|
-
`Reachability:request#getClusters --> get clusters successful:${JSON.stringify(
|
|
56
|
+
`Reachability:request#getClusters --> get clusters (ipver=${ipVersion}) successful:${JSON.stringify(
|
|
57
|
+
clusters
|
|
58
|
+
)}`
|
|
55
59
|
);
|
|
56
60
|
|
|
57
61
|
return {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable import/prefer-default-export */
|
|
2
|
+
/**
|
|
3
|
+
* Converts a stun url to a turn url
|
|
4
|
+
*
|
|
5
|
+
* @param {string} stunUrl url of a stun server
|
|
6
|
+
* @param {'tcp'|'udp'} protocol what protocol to use for the turn server
|
|
7
|
+
* @returns {string} url of a turn server
|
|
8
|
+
*/
|
|
9
|
+
export function convertStunUrlToTurn(stunUrl: string, protocol: 'udp' | 'tcp') {
|
|
10
|
+
// stunUrl looks like this: "stun:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004"
|
|
11
|
+
// and we need it to be like this: "turn:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004?transport=tcp"
|
|
12
|
+
const url = new URL(stunUrl);
|
|
13
|
+
|
|
14
|
+
if (url.protocol !== 'stun:') {
|
|
15
|
+
throw new Error(`Not a STUN URL: ${stunUrl}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
url.protocol = 'turn:';
|
|
19
|
+
if (protocol === 'tcp') {
|
|
20
|
+
url.searchParams.append('transport', 'tcp');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return url.toString();
|
|
24
|
+
}
|
|
@@ -14,14 +14,14 @@ import {
|
|
|
14
14
|
_CALL_,
|
|
15
15
|
_LEFT_,
|
|
16
16
|
_ID_,
|
|
17
|
+
RECONNECTION_STATE,
|
|
17
18
|
} from '../constants';
|
|
18
19
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
19
|
-
import ReconnectionError from '../common/errors/reconnection';
|
|
20
20
|
import ReconnectInProgress from '../common/errors/reconnection-in-progress';
|
|
21
|
-
import {eventType, reconnection, errorObjects} from '../metrics/config';
|
|
22
|
-
import Media from '../media';
|
|
23
21
|
import Metrics from '../metrics';
|
|
24
22
|
import Meeting from '../meeting';
|
|
23
|
+
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
24
|
+
import ReconnectionError from '../common/errors/reconnection';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Used to indicate that the reconnect logic needs to be retried.
|
|
@@ -97,7 +97,7 @@ export default class ReconnectionManager {
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* @instance
|
|
100
|
-
* @type {
|
|
100
|
+
* @type {RECONNECTION_STATE}
|
|
101
101
|
* @private
|
|
102
102
|
* @memberof ReconnectionManager
|
|
103
103
|
*/
|
|
@@ -228,7 +228,32 @@ export default class ReconnectionManager {
|
|
|
228
228
|
*/
|
|
229
229
|
public cleanUp() {
|
|
230
230
|
this.reset();
|
|
231
|
-
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Stop the local share stream.
|
|
235
|
+
*
|
|
236
|
+
* @param {string} reason a {@link SHARE_STOPPED_REASON}
|
|
237
|
+
* @returns {undefined}
|
|
238
|
+
* @private
|
|
239
|
+
* @memberof ReconnectionManager
|
|
240
|
+
*/
|
|
241
|
+
private async stopLocalShareStream(reason: string) {
|
|
242
|
+
await this.meeting.unpublishStreams([
|
|
243
|
+
this.meeting.mediaProperties.shareVideoStream,
|
|
244
|
+
this.meeting.mediaProperties.shareAudioStream,
|
|
245
|
+
]);
|
|
246
|
+
Trigger.trigger(
|
|
247
|
+
this.meeting,
|
|
248
|
+
{
|
|
249
|
+
file: 'reconnection-manager/index',
|
|
250
|
+
function: 'stopLocalShareStream',
|
|
251
|
+
},
|
|
252
|
+
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
|
|
253
|
+
{
|
|
254
|
+
reason,
|
|
255
|
+
}
|
|
256
|
+
);
|
|
232
257
|
}
|
|
233
258
|
|
|
234
259
|
/**
|
|
@@ -240,6 +265,18 @@ export default class ReconnectionManager {
|
|
|
240
265
|
return this.status === RECONNECTION.STATE.IN_PROGRESS;
|
|
241
266
|
}
|
|
242
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Sets the reconnection status
|
|
270
|
+
*
|
|
271
|
+
* @public
|
|
272
|
+
* @param {RECONNECTION_STATE} status
|
|
273
|
+
* @memberof ReconnectionManager
|
|
274
|
+
* @returns {undefined}
|
|
275
|
+
*/
|
|
276
|
+
public setStatus(status: RECONNECTION_STATE) {
|
|
277
|
+
this.status = status;
|
|
278
|
+
}
|
|
279
|
+
|
|
243
280
|
/**
|
|
244
281
|
* @returns {Boolean}
|
|
245
282
|
* @throws {ReconnectionError}
|
|
@@ -302,72 +339,76 @@ export default class ReconnectionManager {
|
|
|
302
339
|
LoggerProxy.logger.info(
|
|
303
340
|
'ReconnectionManager:index#reconnect --> Sending reconnect start metric.'
|
|
304
341
|
);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
342
|
+
|
|
343
|
+
// @ts-ignore
|
|
344
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
345
|
+
name: 'client.media.reconnecting',
|
|
346
|
+
options: {
|
|
347
|
+
meetingId: this.meeting.id,
|
|
348
|
+
},
|
|
308
349
|
});
|
|
309
350
|
}
|
|
310
351
|
|
|
311
|
-
|
|
312
|
-
.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
meeting: this.meeting,
|
|
320
|
-
data: {recoveredBy: reconnection.RECOVERED_BY_NEW},
|
|
321
|
-
});
|
|
322
|
-
})
|
|
323
|
-
.catch((reconnectError) => {
|
|
324
|
-
if (reconnectError instanceof NeedsRetryError) {
|
|
325
|
-
LoggerProxy.logger.info(
|
|
326
|
-
'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
|
|
327
|
-
);
|
|
328
|
-
// Reset our reconnect status since we are looping back to the beginning
|
|
329
|
-
this.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
330
|
-
|
|
331
|
-
// This is a network retry, so we should not log START metrics again
|
|
332
|
-
return this.reconnect({networkDisconnect: true, networkRetry: true});
|
|
333
|
-
}
|
|
352
|
+
try {
|
|
353
|
+
await this.webex.meetings.startReachability();
|
|
354
|
+
} catch (err) {
|
|
355
|
+
LoggerProxy.logger.info(
|
|
356
|
+
'ReconnectionManager:index#reconnect --> Reachability failed, continuing with reconnection attempt, err: ',
|
|
357
|
+
err
|
|
358
|
+
);
|
|
359
|
+
}
|
|
334
360
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
361
|
+
try {
|
|
362
|
+
const media = await this.executeReconnection({networkDisconnect});
|
|
363
|
+
|
|
364
|
+
return media;
|
|
365
|
+
} catch (reconnectError) {
|
|
366
|
+
if (reconnectError instanceof NeedsRetryError) {
|
|
340
367
|
LoggerProxy.logger.info(
|
|
341
|
-
'ReconnectionManager:index#reconnect -->
|
|
368
|
+
'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
|
|
342
369
|
);
|
|
370
|
+
// Reset our reconnect status since we are looping back to the beginning
|
|
371
|
+
this.status = RECONNECTION.STATE.DEFAULT_STATUS;
|
|
343
372
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
],
|
|
357
|
-
},
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
Metrics.postEvent(reconnectMetric);
|
|
361
|
-
if (reconnectError instanceof NeedsRejoinError) {
|
|
362
|
-
// send call aborded event with catogery as expected as we are trying to rejoin
|
|
363
|
-
|
|
364
|
-
if (this.autoRejoinEnabled) {
|
|
365
|
-
return this.rejoinMeeting(reconnectError.wasSharing);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
373
|
+
// This is a network retry, so we should not log START metrics again
|
|
374
|
+
return this.reconnect({networkDisconnect: true, networkRetry: true});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Reconnect has failed
|
|
378
|
+
LoggerProxy.logger.error(
|
|
379
|
+
'ReconnectionManager:index#reconnect --> Reconnection failed.',
|
|
380
|
+
reconnectError.message
|
|
381
|
+
);
|
|
382
|
+
LoggerProxy.logger.info(
|
|
383
|
+
'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
|
|
384
|
+
);
|
|
368
385
|
|
|
369
|
-
|
|
386
|
+
// send call aborted event with catogery as expected as we are trying to rejoin
|
|
387
|
+
// @ts-ignore
|
|
388
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
389
|
+
name: 'client.call.aborted',
|
|
390
|
+
payload: {
|
|
391
|
+
errors: [
|
|
392
|
+
{
|
|
393
|
+
category: 'expected',
|
|
394
|
+
errorCode: 2008,
|
|
395
|
+
fatal: true,
|
|
396
|
+
name: 'media-engine',
|
|
397
|
+
shownToUser: false,
|
|
398
|
+
},
|
|
399
|
+
],
|
|
400
|
+
},
|
|
401
|
+
options: {
|
|
402
|
+
meetingId: this.meeting.id,
|
|
403
|
+
},
|
|
370
404
|
});
|
|
405
|
+
|
|
406
|
+
if (reconnectError instanceof NeedsRejoinError && this.autoRejoinEnabled) {
|
|
407
|
+
return this.rejoinMeeting(reconnectError.wasSharing);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
throw reconnectError;
|
|
411
|
+
}
|
|
371
412
|
}
|
|
372
413
|
|
|
373
414
|
/**
|
|
@@ -385,6 +426,12 @@ export default class ReconnectionManager {
|
|
|
385
426
|
'ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.'
|
|
386
427
|
);
|
|
387
428
|
|
|
429
|
+
const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
|
|
430
|
+
|
|
431
|
+
if (wasSharing) {
|
|
432
|
+
await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEDIA_RECONNECTION);
|
|
433
|
+
}
|
|
434
|
+
|
|
388
435
|
if (networkDisconnect) {
|
|
389
436
|
try {
|
|
390
437
|
await this.reconnectMercuryWebSocket();
|
|
@@ -401,29 +448,29 @@ export default class ReconnectionManager {
|
|
|
401
448
|
}
|
|
402
449
|
}
|
|
403
450
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
451
|
+
if (!this.webex.credentials.isUnverifiedGuest) {
|
|
452
|
+
try {
|
|
453
|
+
LoggerProxy.logger.info(
|
|
454
|
+
'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
|
|
455
|
+
);
|
|
456
|
+
await this.webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
|
|
457
|
+
} catch (syncError) {
|
|
458
|
+
LoggerProxy.logger.info(
|
|
459
|
+
'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
|
|
460
|
+
syncError
|
|
461
|
+
);
|
|
462
|
+
throw new NeedsRetryError(syncError);
|
|
463
|
+
}
|
|
417
464
|
}
|
|
418
465
|
|
|
419
466
|
// TODO: try to improve this logic as the reconnection manager saves the instance of deleted meeting object
|
|
420
467
|
// So that on rejoin it known what parametrs it was using
|
|
421
468
|
if (!this.meeting || !this.webex.meetings.getMeetingByType(_ID_, this.meeting.id)) {
|
|
422
469
|
LoggerProxy.logger.info(
|
|
423
|
-
'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely
|
|
470
|
+
'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely.'
|
|
424
471
|
);
|
|
425
472
|
|
|
426
|
-
throw new Error('Unable to rejoin a meeting already ended or inactive
|
|
473
|
+
throw new Error('Unable to rejoin a meeting already ended or inactive.');
|
|
427
474
|
}
|
|
428
475
|
|
|
429
476
|
LoggerProxy.logger.info(
|
|
@@ -443,14 +490,13 @@ export default class ReconnectionManager {
|
|
|
443
490
|
const media = await this.reconnectMedia();
|
|
444
491
|
|
|
445
492
|
LoggerProxy.logger.log(
|
|
446
|
-
'ReconnectionManager:index#executeReconnection -->
|
|
493
|
+
'ReconnectionManager:index#executeReconnection --> webRTC media connection renewed and local sdp offer sent'
|
|
447
494
|
);
|
|
448
|
-
this.status = RECONNECTION.STATE.COMPLETE;
|
|
449
495
|
|
|
450
496
|
return media;
|
|
451
497
|
} catch (error) {
|
|
452
498
|
LoggerProxy.logger.error(
|
|
453
|
-
'ReconnectionManager:index#executeReconnection -->
|
|
499
|
+
'ReconnectionManager:index#executeReconnection --> failed to renew webRTC media connection or initiate offer'
|
|
454
500
|
);
|
|
455
501
|
this.status = RECONNECTION.STATE.FAILURE;
|
|
456
502
|
|
|
@@ -475,24 +521,7 @@ export default class ReconnectionManager {
|
|
|
475
521
|
LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');
|
|
476
522
|
|
|
477
523
|
if (wasSharing) {
|
|
478
|
-
|
|
479
|
-
this.meeting.setLocalShareTrack(null);
|
|
480
|
-
this.meeting.isSharing = false;
|
|
481
|
-
if (this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE) {
|
|
482
|
-
this.meeting.shareStatus = SHARE_STATUS.NO_SHARE;
|
|
483
|
-
}
|
|
484
|
-
this.meeting.mediaProperties.mediaDirection.sendShare = false;
|
|
485
|
-
Trigger.trigger(
|
|
486
|
-
this.meeting,
|
|
487
|
-
{
|
|
488
|
-
file: 'reconnection-manager/index',
|
|
489
|
-
function: 'rejoinMeeting',
|
|
490
|
-
},
|
|
491
|
-
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
|
|
492
|
-
{
|
|
493
|
-
reason: SHARE_STOPPED_REASON.MEETING_REJOIN,
|
|
494
|
-
}
|
|
495
|
-
);
|
|
524
|
+
await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEETING_REJOIN);
|
|
496
525
|
}
|
|
497
526
|
} catch (joinError) {
|
|
498
527
|
this.rejoinAttempts += 1;
|
|
@@ -534,12 +563,10 @@ export default class ReconnectionManager {
|
|
|
534
563
|
* @memberof ReconnectionManager
|
|
535
564
|
*/
|
|
536
565
|
async reconnectMedia() {
|
|
537
|
-
LoggerProxy.logger.log(
|
|
538
|
-
'ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media'
|
|
539
|
-
);
|
|
566
|
+
LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> do turn discovery');
|
|
540
567
|
|
|
541
|
-
// do the TURN server discovery again since the TURN server might change
|
|
542
|
-
const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true);
|
|
568
|
+
// do the TURN server discovery again and ignore reachability results since the TURN server might change
|
|
569
|
+
const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true, true);
|
|
543
570
|
|
|
544
571
|
const iceServers = [];
|
|
545
572
|
|
|
@@ -551,13 +578,19 @@ export default class ReconnectionManager {
|
|
|
551
578
|
});
|
|
552
579
|
}
|
|
553
580
|
|
|
581
|
+
LoggerProxy.logger.log(
|
|
582
|
+
'ReconnectionManager:index#reconnectMedia --> renew webRTC media connection and send local sdp offer'
|
|
583
|
+
);
|
|
584
|
+
|
|
554
585
|
await this.meeting.mediaProperties.webrtcMediaConnection.reconnect(iceServers);
|
|
555
586
|
|
|
556
587
|
// resend media requests
|
|
557
588
|
if (this.meeting.isMultistream) {
|
|
558
|
-
Object.values(this.meeting.mediaRequestManagers).forEach(
|
|
559
|
-
|
|
560
|
-
|
|
589
|
+
Object.values(this.meeting.mediaRequestManagers).forEach(
|
|
590
|
+
(mediaRequestManager: MediaRequestManager) => {
|
|
591
|
+
mediaRequestManager.clearPreviousRequests();
|
|
592
|
+
mediaRequestManager.commit();
|
|
593
|
+
}
|
|
561
594
|
);
|
|
562
595
|
}
|
|
563
596
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import PermissionError from '../common/errors/permission';
|
|
2
|
-
import {CONTROLS, HTTP_VERBS} from '../constants';
|
|
2
|
+
import {CONTROLS, HTTP_VERBS, SELF_POLICY} from '../constants';
|
|
3
3
|
import MeetingRequest from '../meeting/request';
|
|
4
4
|
import RecordingAction from './enums';
|
|
5
5
|
import Util from './util';
|
|
@@ -28,6 +28,14 @@ export default class RecordingController {
|
|
|
28
28
|
*/
|
|
29
29
|
private displayHints: Array<string> = [];
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @instance
|
|
33
|
+
* @type {Object}
|
|
34
|
+
* @private
|
|
35
|
+
* @memberof RecordingInfo
|
|
36
|
+
*/
|
|
37
|
+
private selfUserPolicies: Record<SELF_POLICY, boolean>;
|
|
38
|
+
|
|
31
39
|
/**
|
|
32
40
|
* @instance
|
|
33
41
|
* @type {string}
|
|
@@ -81,7 +89,6 @@ export default class RecordingController {
|
|
|
81
89
|
|
|
82
90
|
/**
|
|
83
91
|
* @param {MeetingRequest} request
|
|
84
|
-
* @param {LocusInfo} info
|
|
85
92
|
* @returns {void}
|
|
86
93
|
* @private
|
|
87
94
|
* @memberof RecordingController
|
|
@@ -126,6 +133,16 @@ export default class RecordingController {
|
|
|
126
133
|
this.displayHints = hints;
|
|
127
134
|
}
|
|
128
135
|
|
|
136
|
+
/**
|
|
137
|
+
* @param {Object} selfUserPolicies
|
|
138
|
+
* @returns {void}
|
|
139
|
+
* @public
|
|
140
|
+
* @memberof RecordingController
|
|
141
|
+
*/
|
|
142
|
+
public setUserPolicy(selfUserPolicies: Record<SELF_POLICY, boolean>) {
|
|
143
|
+
this.selfUserPolicies = selfUserPolicies;
|
|
144
|
+
}
|
|
145
|
+
|
|
129
146
|
/**
|
|
130
147
|
* @param {string} id
|
|
131
148
|
* @returns {void}
|
|
@@ -264,7 +281,7 @@ export default class RecordingController {
|
|
|
264
281
|
);
|
|
265
282
|
|
|
266
283
|
// assumes action is proper cased (i.e., Example)
|
|
267
|
-
if (Util?.[`canUser${action}`](this.displayHints)) {
|
|
284
|
+
if (Util?.[`canUser${action}`](this.displayHints, this.selfUserPolicies)) {
|
|
268
285
|
if (this.serviceUrl) {
|
|
269
286
|
return this.recordingService(action);
|
|
270
287
|
}
|
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
import {DISPLAY_HINTS} from '../constants';
|
|
1
|
+
import {DISPLAY_HINTS, SELF_POLICY} from '../constants';
|
|
2
2
|
import RecordingAction from './enums';
|
|
3
|
+
import MeetingUtil from '../meeting/util';
|
|
3
4
|
|
|
4
|
-
const canUserStart = (
|
|
5
|
-
displayHints
|
|
5
|
+
const canUserStart = (
|
|
6
|
+
displayHints: Array<string>,
|
|
7
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
8
|
+
): boolean =>
|
|
9
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) &&
|
|
10
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
6
11
|
|
|
7
|
-
const canUserPause = (
|
|
8
|
-
displayHints
|
|
12
|
+
const canUserPause = (
|
|
13
|
+
displayHints: Array<string>,
|
|
14
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
15
|
+
): boolean =>
|
|
16
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) &&
|
|
17
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
9
18
|
|
|
10
|
-
const canUserResume = (
|
|
11
|
-
displayHints
|
|
19
|
+
const canUserResume = (
|
|
20
|
+
displayHints: Array<string>,
|
|
21
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
22
|
+
): boolean =>
|
|
23
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) &&
|
|
24
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
12
25
|
|
|
13
|
-
const canUserStop = (
|
|
14
|
-
displayHints
|
|
26
|
+
const canUserStop = (
|
|
27
|
+
displayHints: Array<string>,
|
|
28
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
29
|
+
): boolean =>
|
|
30
|
+
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) &&
|
|
31
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
15
32
|
|
|
16
33
|
const extractLocusId = (url: string) => {
|
|
17
34
|
return url?.split('/').pop();
|
package/src/roap/index.ts
CHANGED
|
@@ -7,6 +7,9 @@ import LoggerProxy from '../common/logs/logger-proxy';
|
|
|
7
7
|
import RoapRequest from './request';
|
|
8
8
|
import TurnDiscovery from './turnDiscovery';
|
|
9
9
|
import Meeting from '../meeting';
|
|
10
|
+
import MeetingUtil from '../meeting/util';
|
|
11
|
+
import Metrics from '../metrics';
|
|
12
|
+
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Roap options
|
|
@@ -98,11 +101,8 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
98
101
|
roapMessage,
|
|
99
102
|
locusSelfUrl: meeting.selfUrl,
|
|
100
103
|
mediaId: options.mediaId,
|
|
101
|
-
correlationId: options.correlationId,
|
|
102
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
103
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
104
104
|
meetingId: meeting.id,
|
|
105
|
-
|
|
105
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
106
106
|
})
|
|
107
107
|
.then(() => {
|
|
108
108
|
LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);
|
|
@@ -135,11 +135,8 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
135
135
|
roapMessage,
|
|
136
136
|
locusSelfUrl: meeting.selfUrl,
|
|
137
137
|
mediaId: options.mediaId,
|
|
138
|
-
correlationId: options.correlationId,
|
|
139
|
-
audioMuted: meeting.isAudioMuted(),
|
|
140
|
-
videoMuted: meeting.isVideoMuted(),
|
|
141
138
|
meetingId: meeting.id,
|
|
142
|
-
|
|
139
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
143
140
|
});
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -167,11 +164,8 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
167
164
|
roapMessage,
|
|
168
165
|
locusSelfUrl: meeting.selfUrl,
|
|
169
166
|
mediaId: options.mediaId,
|
|
170
|
-
correlationId: options.correlationId,
|
|
171
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
172
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
173
167
|
meetingId: meeting.id,
|
|
174
|
-
|
|
168
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
175
169
|
})
|
|
176
170
|
.then(() => {
|
|
177
171
|
LoggerProxy.logger.log(
|
|
@@ -187,37 +181,71 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
187
181
|
* @memberof Roap
|
|
188
182
|
*/
|
|
189
183
|
sendRoapMediaRequest(options: any) {
|
|
190
|
-
const {meeting, seq, sdp,
|
|
184
|
+
const {meeting, seq, sdp, tieBreaker} = options;
|
|
191
185
|
const roapMessage = {
|
|
192
186
|
messageType: ROAP.ROAP_TYPES.OFFER,
|
|
193
187
|
sdps: [sdp],
|
|
194
188
|
version: ROAP.ROAP_VERSION,
|
|
195
189
|
seq,
|
|
196
190
|
tieBreaker,
|
|
191
|
+
headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
|
|
197
192
|
};
|
|
198
193
|
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
const sendEmptyMediaId =
|
|
194
|
+
// The only time we want to send an empty media id is when we are reconnecting, because this way we tell Locus
|
|
195
|
+
// that it needs to create a new confluence, but when reconnecting we always send TURN_DISCOVERY_REQUEST first,
|
|
196
|
+
// so we don't need to ever send an empty media id here
|
|
197
|
+
const sendEmptyMediaId = false;
|
|
203
198
|
|
|
204
199
|
return this.roapRequest
|
|
205
200
|
.sendRoap({
|
|
206
201
|
roapMessage,
|
|
207
|
-
correlationId: meeting.correlationId,
|
|
208
202
|
locusSelfUrl: meeting.selfUrl,
|
|
209
203
|
mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
|
|
210
|
-
audioMuted: meeting.audio?.isLocallyMuted(),
|
|
211
|
-
videoMuted: meeting.video?.isLocallyMuted(),
|
|
212
204
|
meetingId: meeting.id,
|
|
213
205
|
preferTranscoding: !meeting.isMultistream,
|
|
206
|
+
locusMediaRequest: meeting.locusMediaRequest,
|
|
207
|
+
ipVersion: MeetingUtil.getIpVersion(meeting.webex),
|
|
214
208
|
})
|
|
215
209
|
.then(({locus, mediaConnections}) => {
|
|
216
210
|
if (mediaConnections) {
|
|
217
211
|
meeting.updateMediaConnections(mediaConnections);
|
|
218
212
|
}
|
|
219
213
|
|
|
220
|
-
|
|
214
|
+
let roapAnswer;
|
|
215
|
+
|
|
216
|
+
if (mediaConnections?.[0]?.remoteSdp) {
|
|
217
|
+
const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);
|
|
218
|
+
|
|
219
|
+
if (remoteSdp.roapMessage) {
|
|
220
|
+
const {
|
|
221
|
+
seq: answerSeq,
|
|
222
|
+
messageType,
|
|
223
|
+
sdps,
|
|
224
|
+
errorType,
|
|
225
|
+
errorCause,
|
|
226
|
+
headers,
|
|
227
|
+
} = remoteSdp.roapMessage;
|
|
228
|
+
|
|
229
|
+
roapAnswer = {
|
|
230
|
+
seq: answerSeq,
|
|
231
|
+
messageType,
|
|
232
|
+
sdp: sdps[0],
|
|
233
|
+
errorType,
|
|
234
|
+
errorCause,
|
|
235
|
+
headers,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (!roapAnswer) {
|
|
241
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {
|
|
242
|
+
correlationId: meeting.correlationId,
|
|
243
|
+
messageType: 'ANSWER',
|
|
244
|
+
isMultistream: meeting.isMultistream,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return {locus, roapAnswer};
|
|
221
249
|
});
|
|
222
250
|
}
|
|
223
251
|
|
|
@@ -229,9 +257,10 @@ export default class Roap extends StatelessWebexPlugin {
|
|
|
229
257
|
* @param {Meeting} meeting
|
|
230
258
|
* @param {Boolean} isReconnecting should be set to true if this is a new
|
|
231
259
|
* media connection just after a reconnection
|
|
260
|
+
* @param {Boolean} [isForced]
|
|
232
261
|
* @returns {Promise}
|
|
233
262
|
*/
|
|
234
|
-
doTurnDiscovery(meeting: Meeting, isReconnecting: boolean) {
|
|
235
|
-
return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting);
|
|
263
|
+
doTurnDiscovery(meeting: Meeting, isReconnecting: boolean, isForced?: boolean) {
|
|
264
|
+
return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting, isForced);
|
|
236
265
|
}
|
|
237
266
|
}
|