@webex/plugin-meetings 3.0.0-beta.16 → 3.0.0-beta.18
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/breakouts/breakout.js +116 -0
- package/dist/breakouts/breakout.js.map +1 -0
- package/dist/breakouts/collection.js +23 -0
- package/dist/breakouts/collection.js.map +1 -0
- package/dist/breakouts/index.js +226 -0
- package/dist/breakouts/index.js.map +1 -0
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +43 -6
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +2 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +48 -0
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +1 -0
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +19 -11
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +3 -3
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +4 -4
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +5 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +652 -459
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +25 -44
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +22 -57
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -0
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +28 -18
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +14 -12
- package/dist/meetings/request.js.map +1 -1
- package/dist/member/index.js +9 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +14 -1
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +8 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +3 -1
- package/dist/members/request.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +46 -6
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/multistreamMedia.js +4 -0
- package/dist/multistream/multistreamMedia.js.map +1 -1
- package/dist/multistream/receiveSlot.js +3 -3
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +8 -6
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +168 -63
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reachability/index.js +63 -51
- package/dist/reachability/index.js.map +1 -1
- package/dist/reactions/constants.js +13 -0
- package/dist/reactions/constants.js.map +1 -0
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +25 -12
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js +17 -0
- package/dist/recording-controller/enums.js.map +1 -0
- package/dist/recording-controller/index.js +343 -0
- package/dist/recording-controller/index.js.map +1 -0
- package/dist/recording-controller/util.js +63 -0
- package/dist/recording-controller/util.js.map +1 -0
- package/dist/roap/request.js +88 -68
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +72 -47
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/index.js +3 -3
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +18 -6
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/package.json +24 -19
- package/src/breakouts/README.md +190 -0
- package/src/breakouts/breakout.ts +110 -0
- package/src/breakouts/collection.ts +19 -0
- package/src/breakouts/index.ts +225 -0
- package/src/config.ts +4 -1
- package/src/constants.ts +39 -1
- package/src/locus-info/controlsUtils.ts +2 -0
- package/src/locus-info/index.ts +59 -1
- package/src/locus-info/parser.ts +1 -0
- package/src/locus-info/selfUtils.ts +8 -0
- package/src/media/index.ts +1 -2
- package/src/media/properties.ts +6 -9
- package/src/meeting/in-meeting-actions.ts +8 -0
- package/src/meeting/index.ts +360 -111
- package/src/meeting/request.ts +9 -31
- package/src/meeting/request.type.ts +2 -0
- package/src/meeting/util.ts +25 -60
- package/src/meeting-info/meeting-info-v2.ts +2 -0
- package/src/meetings/index.ts +10 -5
- package/src/meetings/request.ts +1 -1
- package/src/member/index.ts +9 -0
- package/src/member/util.ts +14 -1
- package/src/members/index.ts +1 -0
- package/src/members/request.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +79 -15
- package/src/multistream/multistreamMedia.ts +4 -0
- package/src/multistream/receiveSlot.ts +17 -12
- package/src/multistream/receiveSlotManager.ts +22 -21
- package/src/multistream/remoteMedia.ts +1 -1
- package/src/multistream/remoteMediaGroup.ts +2 -2
- package/src/multistream/remoteMediaManager.ts +150 -37
- package/src/reachability/index.ts +16 -13
- package/src/reactions/constants.ts +4 -0
- package/src/reactions/reactions.type.ts +25 -0
- package/src/reconnection-manager/index.ts +18 -9
- package/src/recording-controller/enums.ts +8 -0
- package/src/recording-controller/index.ts +315 -0
- package/src/recording-controller/util.ts +58 -0
- package/src/roap/request.ts +78 -73
- package/src/roap/turnDiscovery.ts +8 -6
- package/src/statsAnalyzer/index.ts +4 -4
- package/src/statsAnalyzer/mqaUtil.ts +6 -0
- package/test/unit/spec/breakouts/breakout.ts +119 -0
- package/test/unit/spec/breakouts/collection.ts +15 -0
- package/test/unit/spec/breakouts/index.ts +293 -0
- package/test/unit/spec/locus-info/controlsUtils.js +20 -0
- package/test/unit/spec/locus-info/index.js +103 -0
- package/test/unit/spec/locus-info/selfConstant.js +25 -0
- package/test/unit/spec/locus-info/selfUtils.js +84 -0
- package/test/unit/spec/media/index.ts +1 -1
- package/test/unit/spec/media/properties.ts +9 -9
- package/test/unit/spec/meeting/effectsState.js +5 -1
- package/test/unit/spec/meeting/in-meeting-actions.ts +5 -1
- package/test/unit/spec/meeting/index.js +241 -50
- package/test/unit/spec/meeting/request.js +17 -0
- package/test/unit/spec/meeting/utils.js +28 -122
- package/test/unit/spec/meetings/index.js +1 -0
- package/test/unit/spec/member/util.js +26 -1
- package/test/unit/spec/multistream/mediaRequestManager.ts +312 -50
- package/test/unit/spec/multistream/receiveSlot.ts +6 -6
- package/test/unit/spec/multistream/receiveSlotManager.ts +13 -13
- package/test/unit/spec/multistream/remoteMedia.ts +2 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +5 -5
- package/test/unit/spec/multistream/remoteMediaManager.ts +354 -65
- package/test/unit/spec/reachability/index.ts +58 -24
- package/test/unit/spec/reconnection-manager/index.js +42 -13
- package/test/unit/spec/recording-controller/index.js +231 -0
- package/test/unit/spec/recording-controller/util.js +102 -0
- package/test/unit/spec/roap/index.ts +2 -1
- package/test/unit/spec/roap/request.ts +114 -0
- package/test/unit/spec/roap/turnDiscovery.ts +45 -29
- package/test/unit/spec/stats-analyzer/index.js +2 -2
- package/test/utils/webex-test-users.js +1 -0
- package/tsconfig.json +6 -0
- package/dist/media/internal-media-core-wrapper.js +0 -18
- package/dist/media/internal-media-core-wrapper.js.map +0 -1
- package/src/media/internal-media-core-wrapper.ts +0 -9
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
5
|
+
_Object$defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
var _constants = require("../constants");
|
|
10
|
+
var _enums = _interopRequireDefault(require("./enums"));
|
|
11
|
+
var canUserStart = function canUserStart(displayHints) {
|
|
12
|
+
return displayHints.includes(_constants.DISPLAY_HINTS.RECORDING_CONTROL_START);
|
|
13
|
+
};
|
|
14
|
+
var canUserPause = function canUserPause(displayHints) {
|
|
15
|
+
return displayHints.includes(_constants.DISPLAY_HINTS.RECORDING_CONTROL_PAUSE);
|
|
16
|
+
};
|
|
17
|
+
var canUserResume = function canUserResume(displayHints) {
|
|
18
|
+
return displayHints.includes(_constants.DISPLAY_HINTS.RECORDING_CONTROL_RESUME);
|
|
19
|
+
};
|
|
20
|
+
var canUserStop = function canUserStop(displayHints) {
|
|
21
|
+
return displayHints.includes(_constants.DISPLAY_HINTS.RECORDING_CONTROL_STOP);
|
|
22
|
+
};
|
|
23
|
+
var extractLocusId = function extractLocusId(url) {
|
|
24
|
+
return url === null || url === void 0 ? void 0 : url.split('/').pop();
|
|
25
|
+
};
|
|
26
|
+
var deriveRecordingStates = function deriveRecordingStates(action) {
|
|
27
|
+
var recording;
|
|
28
|
+
var paused;
|
|
29
|
+
switch (action) {
|
|
30
|
+
case _enums.default.Start:
|
|
31
|
+
recording = true;
|
|
32
|
+
paused = false;
|
|
33
|
+
break;
|
|
34
|
+
case _enums.default.Stop:
|
|
35
|
+
recording = false;
|
|
36
|
+
paused = false;
|
|
37
|
+
break;
|
|
38
|
+
case _enums.default.Resume:
|
|
39
|
+
recording = true;
|
|
40
|
+
paused = false;
|
|
41
|
+
break;
|
|
42
|
+
case _enums.default.Pause:
|
|
43
|
+
recording = true;
|
|
44
|
+
paused = true;
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
throw new Error("Recording state cannot be derived from invalid action: ".concat(action));
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
recording: recording,
|
|
51
|
+
paused: paused
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
var _default = {
|
|
55
|
+
canUserStart: canUserStart,
|
|
56
|
+
canUserPause: canUserPause,
|
|
57
|
+
canUserResume: canUserResume,
|
|
58
|
+
canUserStop: canUserStop,
|
|
59
|
+
deriveRecordingStates: deriveRecordingStates,
|
|
60
|
+
extractLocusId: extractLocusId
|
|
61
|
+
};
|
|
62
|
+
exports.default = _default;
|
|
63
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["canUserStart","displayHints","includes","DISPLAY_HINTS","RECORDING_CONTROL_START","canUserPause","RECORDING_CONTROL_PAUSE","canUserResume","RECORDING_CONTROL_RESUME","canUserStop","RECORDING_CONTROL_STOP","extractLocusId","url","split","pop","deriveRecordingStates","action","recording","paused","RecordingAction","Start","Stop","Resume","Pause","Error"],"sources":["util.ts"],"sourcesContent":["import {DISPLAY_HINTS} from '../constants';\nimport RecordingAction from './enums';\n\nconst canUserStart = (displayHints: Array<string>): boolean =>\n displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START);\n\nconst canUserPause = (displayHints: Array<string>): boolean =>\n displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE);\n\nconst canUserResume = (displayHints: Array<string>): boolean =>\n displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME);\n\nconst canUserStop = (displayHints: Array<string>): boolean =>\n displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP);\n\nconst extractLocusId = (url: string) => {\n return url?.split('/').pop();\n};\n\nconst deriveRecordingStates = (action: RecordingAction): {recording: boolean; paused: boolean} => {\n let recording;\n let paused;\n\n switch (action) {\n case RecordingAction.Start:\n recording = true;\n paused = false;\n break;\n case RecordingAction.Stop:\n recording = false;\n paused = false;\n break;\n case RecordingAction.Resume:\n recording = true;\n paused = false;\n break;\n case RecordingAction.Pause:\n recording = true;\n paused = true;\n break;\n default:\n throw new Error(`Recording state cannot be derived from invalid action: ${action}`);\n }\n\n return {\n recording,\n paused,\n };\n};\n\nexport default {\n canUserStart,\n canUserPause,\n canUserResume,\n canUserStop,\n deriveRecordingStates,\n extractLocusId,\n};\n"],"mappings":";;;;;;;;AAAA;AACA;AAEA,IAAMA,YAAY,GAAG,SAAfA,YAAY,CAAIC,YAA2B;EAAA,OAC/CA,YAAY,CAACC,QAAQ,CAACC,wBAAa,CAACC,uBAAuB,CAAC;AAAA;AAE9D,IAAMC,YAAY,GAAG,SAAfA,YAAY,CAAIJ,YAA2B;EAAA,OAC/CA,YAAY,CAACC,QAAQ,CAACC,wBAAa,CAACG,uBAAuB,CAAC;AAAA;AAE9D,IAAMC,aAAa,GAAG,SAAhBA,aAAa,CAAIN,YAA2B;EAAA,OAChDA,YAAY,CAACC,QAAQ,CAACC,wBAAa,CAACK,wBAAwB,CAAC;AAAA;AAE/D,IAAMC,WAAW,GAAG,SAAdA,WAAW,CAAIR,YAA2B;EAAA,OAC9CA,YAAY,CAACC,QAAQ,CAACC,wBAAa,CAACO,sBAAsB,CAAC;AAAA;AAE7D,IAAMC,cAAc,GAAG,SAAjBA,cAAc,CAAIC,GAAW,EAAK;EACtC,OAAOA,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEC,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,EAAE;AAC9B,CAAC;AAED,IAAMC,qBAAqB,GAAG,SAAxBA,qBAAqB,CAAIC,MAAuB,EAA4C;EAChG,IAAIC,SAAS;EACb,IAAIC,MAAM;EAEV,QAAQF,MAAM;IACZ,KAAKG,cAAe,CAACC,KAAK;MACxBH,SAAS,GAAG,IAAI;MAChBC,MAAM,GAAG,KAAK;MACd;IACF,KAAKC,cAAe,CAACE,IAAI;MACvBJ,SAAS,GAAG,KAAK;MACjBC,MAAM,GAAG,KAAK;MACd;IACF,KAAKC,cAAe,CAACG,MAAM;MACzBL,SAAS,GAAG,IAAI;MAChBC,MAAM,GAAG,KAAK;MACd;IACF,KAAKC,cAAe,CAACI,KAAK;MACxBN,SAAS,GAAG,IAAI;MAChBC,MAAM,GAAG,IAAI;MACb;IACF;MACE,MAAM,IAAIM,KAAK,kEAA2DR,MAAM,EAAG;EAAC;EAGxF,OAAO;IACLC,SAAS,EAATA,SAAS;IACTC,MAAM,EAANA;EACF,CAAC;AACH,CAAC;AAAC,eAEa;EACblB,YAAY,EAAZA,YAAY;EACZK,YAAY,EAAZA,YAAY;EACZE,aAAa,EAAbA,aAAa;EACbE,WAAW,EAAXA,WAAW;EACXM,qBAAqB,EAArBA,qBAAqB;EACrBJ,cAAc,EAAdA;AACF,CAAC;AAAA"}
|
package/dist/roap/request.js
CHANGED
|
@@ -12,9 +12,11 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
12
12
|
value: true
|
|
13
13
|
});
|
|
14
14
|
exports.default = void 0;
|
|
15
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
15
16
|
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
16
17
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
17
18
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
19
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
18
20
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
19
21
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
20
22
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
@@ -44,27 +46,42 @@ var RoapRequest = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
44
46
|
value:
|
|
45
47
|
/**
|
|
46
48
|
* Joins a meeting via ROAP
|
|
47
|
-
* @param {Object}
|
|
49
|
+
* @param {Object} localSdp
|
|
48
50
|
* @returns {Promise} returns a promise that resolves/rejects whatever the request does
|
|
49
51
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
function () {
|
|
53
|
+
var _attachRechabilityData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(localSdp) {
|
|
54
|
+
var reachabilityData, reachabilityResult;
|
|
55
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
56
|
+
while (1) switch (_context.prev = _context.next) {
|
|
57
|
+
case 0:
|
|
58
|
+
_context.next = 2;
|
|
59
|
+
return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorage).catch(function () {});
|
|
60
|
+
case 2:
|
|
61
|
+
reachabilityData = _context.sent;
|
|
62
|
+
if (reachabilityData) {
|
|
63
|
+
try {
|
|
64
|
+
reachabilityResult = JSON.parse(reachabilityData);
|
|
65
|
+
/* istanbul ignore else */
|
|
66
|
+
if (reachabilityResult && (0, _keys.default)(reachabilityResult).length) {
|
|
67
|
+
localSdp.reachability = reachabilityResult;
|
|
68
|
+
}
|
|
69
|
+
} catch (e) {
|
|
70
|
+
_loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return _context.abrupt("return", localSdp);
|
|
74
|
+
case 5:
|
|
75
|
+
case "end":
|
|
76
|
+
return _context.stop();
|
|
60
77
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
}, _callee, this);
|
|
79
|
+
}));
|
|
80
|
+
function attachRechabilityData(_x) {
|
|
81
|
+
return _attachRechabilityData.apply(this, arguments);
|
|
64
82
|
}
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
83
|
+
return attachRechabilityData;
|
|
84
|
+
}()
|
|
68
85
|
/**
|
|
69
86
|
* Sends a ROAP message
|
|
70
87
|
* @param {Object} options
|
|
@@ -75,12 +92,13 @@ var RoapRequest = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
75
92
|
* @param {Boolean} options.audioMuted
|
|
76
93
|
* @param {Boolean} options.videoMuted
|
|
77
94
|
* @param {String} options.meetingId
|
|
95
|
+
* @param {Boolean} options.preferTranscoding
|
|
78
96
|
* @returns {Promise} returns the response/failure of the request
|
|
79
97
|
*/
|
|
80
98
|
}, {
|
|
81
99
|
key: "sendRoap",
|
|
82
100
|
value: function sendRoap(options) {
|
|
83
|
-
var
|
|
101
|
+
var _this = this;
|
|
84
102
|
var roapMessage = options.roapMessage,
|
|
85
103
|
locusSelfUrl = options.locusSelfUrl,
|
|
86
104
|
mediaId = options.mediaId,
|
|
@@ -97,59 +115,61 @@ var RoapRequest = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
97
115
|
event: _config.eventType.MEDIA_REQUEST,
|
|
98
116
|
meetingId: meetingId
|
|
99
117
|
});
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
return this.attachRechabilityData({
|
|
119
|
+
roapMessage: roapMessage,
|
|
120
|
+
// eslint-disable-next-line no-warning-comments
|
|
121
|
+
// TODO: check whats the need for video and audiomute
|
|
122
|
+
audioMuted: !!options.audioMuted,
|
|
123
|
+
videoMuted: !!options.videoMuted
|
|
124
|
+
}).then(function (sdpWithReachability) {
|
|
125
|
+
var _options$preferTransc;
|
|
126
|
+
// @ts-ignore
|
|
127
|
+
return _this.webex.request({
|
|
128
|
+
uri: mediaUrl,
|
|
129
|
+
method: _constants.HTTP_VERBS.PUT,
|
|
130
|
+
body: {
|
|
131
|
+
device: {
|
|
132
|
+
url: deviceUrl,
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
deviceType: _this.config.meetings.deviceType
|
|
135
|
+
},
|
|
136
|
+
correlationId: correlationId,
|
|
137
|
+
localMedias: [{
|
|
138
|
+
localSdp: (0, _stringify.default)(sdpWithReachability),
|
|
139
|
+
mediaId: options.mediaId
|
|
140
|
+
}],
|
|
141
|
+
clientMediaPreferences: {
|
|
142
|
+
preferTranscoding: (_options$preferTransc = options.preferTranscoding) !== null && _options$preferTransc !== void 0 ? _options$preferTransc : true
|
|
143
|
+
}
|
|
124
144
|
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
145
|
+
}).then(function (res) {
|
|
146
|
+
_metrics.default.postEvent({
|
|
147
|
+
event: _config.eventType.MEDIA_RESPONSE,
|
|
148
|
+
meetingId: meetingId
|
|
149
|
+
});
|
|
131
150
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
// always it will be the first mediaConnection Object
|
|
152
|
+
var mediaConnections = res.body.mediaConnections && res.body.mediaConnections.length > 0 && res.body.mediaConnections[0];
|
|
153
|
+
_loggerProxy.default.logger.info("Roap:request#sendRoap --> response:".concat((0, _stringify.default)(mediaConnections, null, 2), "'\n StatusCode:'").concat(res.statusCode));
|
|
154
|
+
var locus = res.body.locus;
|
|
155
|
+
locus.roapSeq = options.roapMessage.seq;
|
|
156
|
+
return _objectSpread({
|
|
157
|
+
locus: locus
|
|
158
|
+
}, mediaConnections && {
|
|
159
|
+
mediaConnections: res.body.mediaConnections
|
|
160
|
+
});
|
|
161
|
+
}).catch(function (err) {
|
|
162
|
+
_metrics.default.postEvent({
|
|
163
|
+
event: _config.eventType.MEDIA_RESPONSE,
|
|
164
|
+
meetingId: meetingId,
|
|
165
|
+
data: {
|
|
166
|
+
error: _metrics.default.parseLocusError(err, true)
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
_loggerProxy.default.logger.error("Roap:request#sendRoap --> Error:".concat((0, _stringify.default)(err, null, 2)));
|
|
170
|
+
_loggerProxy.default.logger.error("Roap:request#sendRoapRequest --> errorBody:".concat((0, _stringify.default)(roapMessage, null, 2), " + '\\n mediaId:'").concat(options.mediaId));
|
|
171
|
+
throw err;
|
|
149
172
|
});
|
|
150
|
-
_loggerProxy.default.logger.error("Roap:request#sendRoap --> Error:".concat((0, _stringify.default)(err, null, 2)));
|
|
151
|
-
_loggerProxy.default.logger.error("Roap:request#sendRoapRequest --> errorBody:".concat((0, _stringify.default)(roapMessage, null, 2), " + '\\n mediaId:'").concat(options.mediaId));
|
|
152
|
-
throw err;
|
|
153
173
|
});
|
|
154
174
|
}
|
|
155
175
|
}]);
|
package/dist/roap/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RoapRequest","localSdp","
|
|
1
|
+
{"version":3,"names":["RoapRequest","localSdp","webex","boundedStorage","get","REACHABILITY","namespace","localStorage","catch","reachabilityData","reachabilityResult","JSON","parse","length","reachability","e","LoggerProxy","logger","error","options","roapMessage","locusSelfUrl","mediaId","correlationId","meetingId","info","mediaUrl","MEDIA","deviceUrl","internal","device","url","messageType","seq","Metrics","postEvent","event","eventType","MEDIA_REQUEST","attachRechabilityData","audioMuted","videoMuted","then","sdpWithReachability","request","uri","method","HTTP_VERBS","PUT","body","deviceType","config","meetings","localMedias","clientMediaPreferences","preferTranscoding","res","MEDIA_RESPONSE","mediaConnections","statusCode","locus","roapSeq","err","data","parseLocusError","StatelessWebexPlugin"],"sources":["request.ts"],"sourcesContent":["/* global window */\n// @ts-ignore\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {MEDIA, HTTP_VERBS, REACHABILITY} from '../constants';\nimport Metrics from '../metrics';\nimport {eventType} from '../metrics/config';\n\n/**\n * @class RoapRequest\n */\nexport default class RoapRequest extends StatelessWebexPlugin {\n /**\n * Joins a meeting via ROAP\n * @param {Object} localSdp\n * @returns {Promise} returns a promise that resolves/rejects whatever the request does\n */\n async attachRechabilityData(localSdp) {\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(REACHABILITY.namespace, REACHABILITY.localStorage)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResult = JSON.parse(reachabilityData);\n\n /* istanbul ignore else */\n if (reachabilityResult && Object.keys(reachabilityResult).length) {\n localSdp.reachability = reachabilityResult;\n }\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return localSdp;\n }\n\n /**\n * Sends a ROAP message\n * @param {Object} options\n * @param {Object} options.roapMessage\n * @param {String} options.locusSelfUrl\n * @param {String} options.mediaId\n * @param {String} options.correlationId\n * @param {Boolean} options.audioMuted\n * @param {Boolean} options.videoMuted\n * @param {String} options.meetingId\n * @param {Boolean} options.preferTranscoding\n * @returns {Promise} returns the response/failure of the request\n */\n sendRoap(options: {\n roapMessage: any;\n locusSelfUrl: string;\n mediaId: string;\n correlationId: string;\n audioMuted: boolean;\n videoMuted: boolean;\n meetingId: string;\n preferTranscoding?: boolean;\n }) {\n const {roapMessage, locusSelfUrl, mediaId, correlationId, meetingId} = options;\n\n if (!mediaId) {\n LoggerProxy.logger.info('Roap:request#sendRoap --> Race Condition /call mediaID not present');\n }\n\n const mediaUrl = `${locusSelfUrl}/${MEDIA}`;\n // @ts-ignore\n const deviceUrl = this.webex.internal.device.url;\n\n LoggerProxy.logger.info(\n `Roap:request#sendRoap --> ${mediaUrl} \\n ${roapMessage.messageType} \\n seq:${roapMessage.seq}`\n );\n\n Metrics.postEvent({event: eventType.MEDIA_REQUEST, meetingId});\n\n return this.attachRechabilityData({\n roapMessage,\n // eslint-disable-next-line no-warning-comments\n // TODO: check whats the need for video and audiomute\n audioMuted: !!options.audioMuted,\n videoMuted: !!options.videoMuted,\n }).then((sdpWithReachability) => {\n // @ts-ignore\n return this.webex\n .request({\n uri: mediaUrl,\n method: HTTP_VERBS.PUT,\n body: {\n device: {\n url: deviceUrl,\n // @ts-ignore\n deviceType: this.config.meetings.deviceType,\n },\n correlationId,\n localMedias: [\n {\n localSdp: JSON.stringify(sdpWithReachability),\n mediaId: options.mediaId,\n },\n ],\n clientMediaPreferences: {\n preferTranscoding: options.preferTranscoding ?? true,\n },\n },\n })\n .then((res) => {\n Metrics.postEvent({event: eventType.MEDIA_RESPONSE, meetingId});\n\n // always it will be the first mediaConnection Object\n const mediaConnections =\n res.body.mediaConnections &&\n res.body.mediaConnections.length > 0 &&\n res.body.mediaConnections[0];\n\n LoggerProxy.logger.info(\n `Roap:request#sendRoap --> response:${JSON.stringify(\n mediaConnections,\n null,\n 2\n )}'\\n StatusCode:'${res.statusCode}`\n );\n const {locus} = res.body;\n\n locus.roapSeq = options.roapMessage.seq;\n\n return {\n locus,\n ...(mediaConnections && {mediaConnections: res.body.mediaConnections}),\n };\n })\n .catch((err) => {\n Metrics.postEvent({\n event: eventType.MEDIA_RESPONSE,\n meetingId,\n data: {error: Metrics.parseLocusError(err, true)},\n });\n LoggerProxy.logger.error(\n `Roap:request#sendRoap --> Error:${JSON.stringify(err, null, 2)}`\n );\n LoggerProxy.logger.error(\n `Roap:request#sendRoapRequest --> errorBody:${JSON.stringify(\n roapMessage,\n null,\n 2\n )} + '\\\\n mediaId:'${options.mediaId}`\n );\n throw err;\n });\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -6,8 +6,10 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports.default = void 0;
|
|
9
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
9
10
|
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
10
11
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
12
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
11
13
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
12
14
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
13
15
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
@@ -156,7 +158,8 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
156
158
|
mediaId: isReconnecting ? '' : meeting.mediaId,
|
|
157
159
|
audioMuted: meeting.isAudioMuted(),
|
|
158
160
|
videoMuted: meeting.isVideoMuted(),
|
|
159
|
-
meetingId: meeting.id
|
|
161
|
+
meetingId: meeting.id,
|
|
162
|
+
preferTranscoding: !meeting.isMultistream
|
|
160
163
|
}).then(function (_ref) {
|
|
161
164
|
var mediaConnections = _ref.mediaConnections;
|
|
162
165
|
if (mediaConnections) {
|
|
@@ -189,7 +192,8 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
189
192
|
correlationId: meeting.correlationId,
|
|
190
193
|
audioMuted: meeting.isAudioMuted(),
|
|
191
194
|
videoMuted: meeting.isVideoMuted(),
|
|
192
|
-
meetingId: meeting.id
|
|
195
|
+
meetingId: meeting.id,
|
|
196
|
+
preferTranscoding: !meeting.isMultistream
|
|
193
197
|
});
|
|
194
198
|
}
|
|
195
199
|
|
|
@@ -212,52 +216,73 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
212
216
|
*/
|
|
213
217
|
}, {
|
|
214
218
|
key: "doTurnDiscovery",
|
|
215
|
-
value: function
|
|
216
|
-
var
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
219
|
+
value: function () {
|
|
220
|
+
var _doTurnDiscovery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(meeting, isReconnecting) {
|
|
221
|
+
var _this2 = this;
|
|
222
|
+
var isAnyClusterReachable;
|
|
223
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
224
|
+
while (1) switch (_context.prev = _context.next) {
|
|
225
|
+
case 0:
|
|
226
|
+
_context.next = 2;
|
|
227
|
+
return meeting.webex.meetings.reachability.isAnyClusterReachable();
|
|
228
|
+
case 2:
|
|
229
|
+
isAnyClusterReachable = _context.sent;
|
|
230
|
+
if (!isAnyClusterReachable) {
|
|
231
|
+
_context.next = 6;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery');
|
|
235
|
+
return _context.abrupt("return", {
|
|
236
|
+
turnServerInfo: undefined,
|
|
237
|
+
turnDiscoverySkippedReason: 'reachability'
|
|
238
|
+
});
|
|
239
|
+
case 6:
|
|
240
|
+
if (meeting.config.experimental.enableTurnDiscovery) {
|
|
241
|
+
_context.next = 9;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it');
|
|
245
|
+
return _context.abrupt("return", {
|
|
246
|
+
turnServerInfo: undefined,
|
|
247
|
+
turnDiscoverySkippedReason: 'config'
|
|
248
|
+
});
|
|
249
|
+
case 9:
|
|
250
|
+
return _context.abrupt("return", this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting).then(function () {
|
|
251
|
+
return _this2.waitForTurnDiscoveryResponse();
|
|
252
|
+
}).then(function () {
|
|
253
|
+
return _this2.sendRoapOK(meeting);
|
|
254
|
+
}).then(function () {
|
|
255
|
+
_this2.defer = undefined;
|
|
256
|
+
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');
|
|
257
|
+
return {
|
|
258
|
+
turnServerInfo: _this2.turnInfo,
|
|
259
|
+
turnDiscoverySkippedReason: undefined
|
|
260
|
+
};
|
|
261
|
+
}).catch(function (e) {
|
|
262
|
+
// we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN
|
|
263
|
+
_loggerProxy.default.logger.info("Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ".concat(e));
|
|
264
|
+
_metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_FAILURE, {
|
|
265
|
+
correlation_id: meeting.correlationId,
|
|
266
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
|
267
|
+
reason: e.message,
|
|
268
|
+
stack: e.stack
|
|
269
|
+
});
|
|
270
|
+
return {
|
|
271
|
+
turnServerInfo: undefined,
|
|
272
|
+
turnDiscoverySkippedReason: undefined
|
|
273
|
+
};
|
|
274
|
+
}));
|
|
275
|
+
case 10:
|
|
276
|
+
case "end":
|
|
277
|
+
return _context.stop();
|
|
278
|
+
}
|
|
279
|
+
}, _callee, this);
|
|
280
|
+
}));
|
|
281
|
+
function doTurnDiscovery(_x, _x2) {
|
|
282
|
+
return _doTurnDiscovery.apply(this, arguments);
|
|
234
283
|
}
|
|
235
|
-
return
|
|
236
|
-
|
|
237
|
-
}).then(function () {
|
|
238
|
-
return _this2.sendRoapOK(meeting);
|
|
239
|
-
}).then(function () {
|
|
240
|
-
_this2.defer = undefined;
|
|
241
|
-
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');
|
|
242
|
-
return {
|
|
243
|
-
turnServerInfo: _this2.turnInfo,
|
|
244
|
-
turnDiscoverySkippedReason: undefined
|
|
245
|
-
};
|
|
246
|
-
}).catch(function (e) {
|
|
247
|
-
// we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN
|
|
248
|
-
_loggerProxy.default.logger.info("Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ".concat(e));
|
|
249
|
-
_metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_FAILURE, {
|
|
250
|
-
correlation_id: meeting.correlationId,
|
|
251
|
-
locus_id: meeting.locusUrl.split('/').pop(),
|
|
252
|
-
reason: e.message,
|
|
253
|
-
stack: e.stack
|
|
254
|
-
});
|
|
255
|
-
return _promise.default.resolve({
|
|
256
|
-
turnServerInfo: undefined,
|
|
257
|
-
turnDiscoverySkippedReason: undefined
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
}
|
|
284
|
+
return doTurnDiscovery;
|
|
285
|
+
}()
|
|
261
286
|
}]);
|
|
262
287
|
return TurnDiscovery;
|
|
263
288
|
}();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TURN_DISCOVERY_TIMEOUT","TURN_DISCOVERY_SEQ","TurnDiscovery","roapRequest","turnInfo","url","username","password","defer","LoggerProxy","logger","warn","reject","Error","responseTimer","setTimeout","info","promise","roapMessage","headers","expectedHeaders","headerName","field","foundHeaders","forEach","receivedHeader","expectedHeader","startsWith","substring","length","clearTimeout","undefined","resolve","meeting","isReconnecting","Defer","messageType","ROAP","ROAP_TYPES","TURN_DISCOVERY_REQUEST","version","ROAP_VERSION","seq","sendRoap","correlationId","locusSelfUrl","selfUrl","mediaId","audioMuted","isAudioMuted","videoMuted","isVideoMuted","meetingId","id","then","mediaConnections","updateMediaConnections","OK","isAnyClusterReachable","webex","meetings","reachability","turnServerInfo","turnDiscoverySkippedReason","config","experimental","enableTurnDiscovery","sendRoapTurnDiscoveryRequest","waitForTurnDiscoveryResponse","sendRoapOK","catch","e","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","TURN_DISCOVERY_FAILURE","correlation_id","locus_id","locusUrl","split","pop","reason","message","stack"],"sources":["turnDiscovery.ts"],"sourcesContent":["// @ts-ignore - Types not available for @webex/common\nimport {Defer} from '@webex/common';\n\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ROAP} from '../constants';\n\nimport RoapRequest from './request';\nimport Meeting from '../meeting';\n\nconst TURN_DISCOVERY_TIMEOUT = 10; // in seconds\n\n// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0\n// and this is handy for us, because TURN discovery is always done before the first SDP exchange,\n// so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection\n// and do the SDP offer with seq=1\nconst TURN_DISCOVERY_SEQ = 0;\n\n/**\n * Handles the process of finding out TURN server information from Linus.\n * This is achieved by sending a TURN_DISCOVERY_REQUEST.\n */\nexport default class TurnDiscovery {\n private roapRequest: RoapRequest;\n\n private defer?: Defer; // used for waiting for the response\n\n private turnInfo: {\n url: string;\n username: string;\n password: string;\n };\n\n private responseTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Constructor\n *\n * @param {RoapRequest} roapRequest\n */\n constructor(roapRequest: RoapRequest) {\n this.roapRequest = roapRequest;\n this.turnInfo = {\n url: '',\n username: '',\n password: '',\n };\n }\n\n /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private waitForTurnDiscoveryResponse() {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress'\n );\n\n return Promise.reject(\n new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()')\n );\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`\n );\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...'\n );\n\n return defer.promise;\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message\n *\n * @param {Object} roapMessage\n * @returns {void}\n * @public\n * @memberof Roap\n */\n public handleTurnDiscoveryResponse(roapMessage: object) {\n // @ts-ignore - Fix missing type\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response'\n );\n\n return;\n }\n\n const expectedHeaders = [\n {headerName: 'x-cisco-turn-url', field: 'url'},\n {headerName: 'x-cisco-turn-username', field: 'username'},\n {headerName: 'x-cisco-turn-password', field: 'password'},\n ];\n\n let foundHeaders = 0;\n\n headers?.forEach((receivedHeader) => {\n // check if it matches any of our expected headers\n expectedHeaders.forEach((expectedHeader) => {\n if (receivedHeader.startsWith(`${expectedHeader.headerName}=`)) {\n this.turnInfo[expectedHeader.field] = receivedHeader.substring(\n expectedHeader.headerName.length + 1\n );\n foundHeaders += 1;\n }\n });\n });\n\n clearTimeout(this.responseTimer);\n this.responseTimer = undefined;\n\n if (foundHeaders !== expectedHeaders.length) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received: ${JSON.stringify(\n headers\n )}`\n );\n this.defer.reject(\n new Error(`TURN_DISCOVERY_RESPONSE missing some headers: ${JSON.stringify(headers)}`)\n );\n } else {\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response, url=${this.turnInfo.url}`\n );\n this.defer.resolve();\n }\n }\n\n /**\n * sends the TURN_DISCOVERY_REQUEST roap request\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapTurnDiscoveryRequest(meeting: Meeting, isReconnecting: boolean) {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress'\n );\n\n return Promise.resolve();\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST'\n );\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n correlationId: meeting.correlationId,\n // @ts-ignore - Fix missing type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - Fix missing type\n mediaId: isReconnecting ? '' : meeting.mediaId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n })\n .then(({mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n });\n }\n\n /**\n * Sends the OK message that server expects to receive\n * after it sends us TURN_DISCOVERY_RESPONSE\n *\n * @param {Meeting} meeting\n * @returns {Promise}\n */\n sendRoapOK(meeting: Meeting) {\n LoggerProxy.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');\n\n return this.roapRequest.sendRoap({\n roapMessage: {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n },\n // @ts-ignore - fix type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - fix type\n mediaId: meeting.mediaId,\n correlationId: meeting.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n });\n }\n\n /**\n * Retrieves TURN server information from the backend by doing\n * a roap message exchange:\n * client server\n * | -----TURN_DISCOVERY_REQUEST-----> |\n * | <----TURN_DISCOVERY_RESPONSE----- |\n * | --------------OK----------------> |\n *\n * This TURN discovery roap exchange is always done with seq=0.\n * The RoapMediaConnection SDP exchange always starts with seq=1,\n * so it works fine no matter if TURN discovery is done or not.\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting should be set to true if this is a new\n * media connection just after a reconnection\n * @returns {Promise}\n */\n doTurnDiscovery(meeting: Meeting, isReconnecting: boolean) {\n // @ts-ignore - fix type\n const isAnyClusterReachable = meeting.webex.meetings.reachability.isAnyClusterReachable();\n\n if (isAnyClusterReachable) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery'\n );\n\n return Promise.resolve({\n turnServerInfo: undefined,\n turnDiscoverySkippedReason: 'reachability',\n });\n }\n\n // @ts-ignore - fix type\n if (!meeting.config.experimental.enableTurnDiscovery) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it'\n );\n\n return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: 'config'});\n }\n\n return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting)\n .then(() => this.waitForTurnDiscoveryResponse())\n .then(() => this.sendRoapOK(meeting))\n .then(() => {\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n })\n .catch((e) => {\n // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack,\n });\n\n return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: undefined});\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["TURN_DISCOVERY_TIMEOUT","TURN_DISCOVERY_SEQ","TurnDiscovery","roapRequest","turnInfo","url","username","password","defer","LoggerProxy","logger","warn","reject","Error","responseTimer","setTimeout","info","promise","roapMessage","headers","expectedHeaders","headerName","field","foundHeaders","forEach","receivedHeader","expectedHeader","startsWith","substring","length","clearTimeout","undefined","resolve","meeting","isReconnecting","Defer","messageType","ROAP","ROAP_TYPES","TURN_DISCOVERY_REQUEST","version","ROAP_VERSION","seq","sendRoap","correlationId","locusSelfUrl","selfUrl","mediaId","audioMuted","isAudioMuted","videoMuted","isVideoMuted","meetingId","id","preferTranscoding","isMultistream","then","mediaConnections","updateMediaConnections","OK","webex","meetings","reachability","isAnyClusterReachable","turnServerInfo","turnDiscoverySkippedReason","config","experimental","enableTurnDiscovery","sendRoapTurnDiscoveryRequest","waitForTurnDiscoveryResponse","sendRoapOK","catch","e","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","TURN_DISCOVERY_FAILURE","correlation_id","locus_id","locusUrl","split","pop","reason","message","stack"],"sources":["turnDiscovery.ts"],"sourcesContent":["// @ts-ignore - Types not available for @webex/common\nimport {Defer} from '@webex/common';\n\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ROAP} from '../constants';\n\nimport RoapRequest from './request';\nimport Meeting from '../meeting';\n\nconst TURN_DISCOVERY_TIMEOUT = 10; // in seconds\n\n// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0\n// and this is handy for us, because TURN discovery is always done before the first SDP exchange,\n// so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection\n// and do the SDP offer with seq=1\nconst TURN_DISCOVERY_SEQ = 0;\n\n/**\n * Handles the process of finding out TURN server information from Linus.\n * This is achieved by sending a TURN_DISCOVERY_REQUEST.\n */\nexport default class TurnDiscovery {\n private roapRequest: RoapRequest;\n\n private defer?: Defer; // used for waiting for the response\n\n private turnInfo: {\n url: string;\n username: string;\n password: string;\n };\n\n private responseTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Constructor\n *\n * @param {RoapRequest} roapRequest\n */\n constructor(roapRequest: RoapRequest) {\n this.roapRequest = roapRequest;\n this.turnInfo = {\n url: '',\n username: '',\n password: '',\n };\n }\n\n /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private waitForTurnDiscoveryResponse() {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress'\n );\n\n return Promise.reject(\n new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()')\n );\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`\n );\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...'\n );\n\n return defer.promise;\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message\n *\n * @param {Object} roapMessage\n * @returns {void}\n * @public\n * @memberof Roap\n */\n public handleTurnDiscoveryResponse(roapMessage: object) {\n // @ts-ignore - Fix missing type\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response'\n );\n\n return;\n }\n\n const expectedHeaders = [\n {headerName: 'x-cisco-turn-url', field: 'url'},\n {headerName: 'x-cisco-turn-username', field: 'username'},\n {headerName: 'x-cisco-turn-password', field: 'password'},\n ];\n\n let foundHeaders = 0;\n\n headers?.forEach((receivedHeader) => {\n // check if it matches any of our expected headers\n expectedHeaders.forEach((expectedHeader) => {\n if (receivedHeader.startsWith(`${expectedHeader.headerName}=`)) {\n this.turnInfo[expectedHeader.field] = receivedHeader.substring(\n expectedHeader.headerName.length + 1\n );\n foundHeaders += 1;\n }\n });\n });\n\n clearTimeout(this.responseTimer);\n this.responseTimer = undefined;\n\n if (foundHeaders !== expectedHeaders.length) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received: ${JSON.stringify(\n headers\n )}`\n );\n this.defer.reject(\n new Error(`TURN_DISCOVERY_RESPONSE missing some headers: ${JSON.stringify(headers)}`)\n );\n } else {\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response, url=${this.turnInfo.url}`\n );\n this.defer.resolve();\n }\n }\n\n /**\n * sends the TURN_DISCOVERY_REQUEST roap request\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapTurnDiscoveryRequest(meeting: Meeting, isReconnecting: boolean) {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress'\n );\n\n return Promise.resolve();\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST'\n );\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n correlationId: meeting.correlationId,\n // @ts-ignore - Fix missing type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - Fix missing type\n mediaId: isReconnecting ? '' : meeting.mediaId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(({mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n });\n }\n\n /**\n * Sends the OK message that server expects to receive\n * after it sends us TURN_DISCOVERY_RESPONSE\n *\n * @param {Meeting} meeting\n * @returns {Promise}\n */\n sendRoapOK(meeting: Meeting) {\n LoggerProxy.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');\n\n return this.roapRequest.sendRoap({\n roapMessage: {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n },\n // @ts-ignore - fix type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - fix type\n mediaId: meeting.mediaId,\n correlationId: meeting.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n });\n }\n\n /**\n * Retrieves TURN server information from the backend by doing\n * a roap message exchange:\n * client server\n * | -----TURN_DISCOVERY_REQUEST-----> |\n * | <----TURN_DISCOVERY_RESPONSE----- |\n * | --------------OK----------------> |\n *\n * This TURN discovery roap exchange is always done with seq=0.\n * The RoapMediaConnection SDP exchange always starts with seq=1,\n * so it works fine no matter if TURN discovery is done or not.\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting should be set to true if this is a new\n * media connection just after a reconnection\n * @returns {Promise}\n */\n async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean) {\n // @ts-ignore - fix type\n const isAnyClusterReachable = await meeting.webex.meetings.reachability.isAnyClusterReachable();\n\n if (isAnyClusterReachable) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery'\n );\n\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason: 'reachability',\n };\n }\n\n // @ts-ignore - fix type\n if (!meeting.config.experimental.enableTurnDiscovery) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it'\n );\n\n return {turnServerInfo: undefined, turnDiscoverySkippedReason: 'config'};\n }\n\n return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting)\n .then(() => this.waitForTurnDiscoveryResponse())\n .then(() => this.sendRoapOK(meeting))\n .then(() => {\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n })\n .catch((e) => {\n // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack,\n });\n\n return {turnServerInfo: undefined, turnDiscoverySkippedReason: undefined};\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -406,7 +406,7 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
406
406
|
*
|
|
407
407
|
* @private
|
|
408
408
|
* @memberof StatsAnalyzer
|
|
409
|
-
* @param {
|
|
409
|
+
* @param {RoapMediaConnection} mediaConnection
|
|
410
410
|
* @returns {void}
|
|
411
411
|
*/
|
|
412
412
|
}, {
|
|
@@ -420,7 +420,7 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
420
420
|
*
|
|
421
421
|
* @public
|
|
422
422
|
* @memberof StatsAnalyzer
|
|
423
|
-
* @param {
|
|
423
|
+
* @param {RoapMediaConnection} mediaConnection
|
|
424
424
|
* @returns {Promise}
|
|
425
425
|
*/
|
|
426
426
|
}, {
|
|
@@ -708,7 +708,7 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
708
708
|
if (!this.mediaConnection) {
|
|
709
709
|
return _promise.default.resolve();
|
|
710
710
|
}
|
|
711
|
-
if (this.mediaConnection && this.mediaConnection.getConnectionState() === _internalMediaCore.
|
|
711
|
+
if (this.mediaConnection && this.mediaConnection.getConnectionState() === _internalMediaCore.ConnectionState.Failed) {
|
|
712
712
|
_loggerProxy.default.logger.trace('StatsAnalyzer:index#getStatsAndParse --> media connection is in failed state');
|
|
713
713
|
return _promise.default.resolve();
|
|
714
714
|
}
|