@webex/plugin-meetings 3.0.0-beta.8 → 3.0.0-beta.9
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/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +7 -0
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +8 -0
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +8 -0
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +7 -0
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +7 -0
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +7 -0
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reconnection-in-progress.js.map +1 -1
- package/dist/common/errors/reconnection.js +7 -0
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +7 -0
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +5 -2
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +3 -0
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +43 -5
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +12 -3
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +12 -0
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/effectsState.js +8 -1
- package/dist/meeting/effectsState.js.map +1 -1
- package/dist/meeting/index.js +173 -50
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +6 -0
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +54 -24
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js +4 -1
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +5 -0
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +14 -2
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +3 -0
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +4 -1
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +72 -20
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +4 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +30 -7
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +2 -1
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +1 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +14 -1
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +19 -9
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/config.js.map +1 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +8 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +10 -2
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +11 -0
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +2 -1
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/index.js +17 -7
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +1 -0
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +21 -2
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +23 -13
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +5 -2
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +9 -1
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +19 -1
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +9 -3
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +10 -3
- package/dist/transcription/index.js.map +1 -1
- package/package.json +17 -17
- package/src/common/{browser-detection.js → browser-detection.ts} +1 -1
- package/src/common/collection.ts +6 -6
- package/src/common/{config.js → config.ts} +1 -1
- package/src/common/errors/{captcha-error.js → captcha-error.ts} +5 -1
- package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +6 -1
- package/src/common/errors/{join-meeting.js → join-meeting.ts} +6 -1
- package/src/common/errors/{media.js → media.ts} +5 -1
- package/src/common/errors/parameter.ts +3 -2
- package/src/common/errors/{password-error.js → password-error.ts} +5 -1
- package/src/common/errors/{permission.js → permission.ts} +5 -1
- package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
- package/src/common/errors/{reconnection.js → reconnection.ts} +5 -1
- package/src/common/errors/{stats.js → stats.ts} +5 -1
- package/src/common/errors/{webex-errors.js → webex-errors.ts} +1 -2
- package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +3 -1
- package/src/common/events/{events-scope.js → events-scope.ts} +1 -1
- package/src/common/events/{events.js → events.ts} +0 -0
- package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +1 -2
- package/src/common/events/{util.js → util.ts} +1 -1
- package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
- package/src/common/logs/{logger-proxy.js → logger-proxy.ts} +1 -1
- package/src/common/logs/{request.js → request.ts} +12 -2
- package/src/common/queue.ts +1 -2
- package/src/{config.js → config.ts} +1 -0
- package/src/constants.ts +2 -1
- package/src/locus-info/{controlsUtils.js → controlsUtils.ts} +4 -4
- package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
- package/src/locus-info/{fullState.js → fullState.ts} +1 -1
- package/src/locus-info/{hostUtils.js → hostUtils.ts} +5 -5
- package/src/locus-info/{index.js → index.ts} +67 -32
- package/src/locus-info/{infoUtils.js → infoUtils.ts} +3 -4
- package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +13 -13
- package/src/locus-info/{parser.js → parser.ts} +22 -12
- package/src/locus-info/{selfUtils.js → selfUtils.ts} +17 -19
- package/src/media/{index.js → index.ts} +62 -16
- package/src/media/{properties.js → properties.ts} +16 -4
- package/src/media/{util.js → util.ts} +1 -1
- package/src/mediaQualityMetrics/{config.js → config.ts} +1 -1
- package/src/meeting/{effectsState.js → effectsState.ts} +12 -6
- package/src/meeting/{index.js → index.ts} +341 -156
- package/src/meeting/{muteState.js → muteState.ts} +16 -11
- package/src/meeting/{request.js → request.ts} +124 -36
- package/src/meeting/{state.js → state.ts} +6 -6
- package/src/meeting/{util.js → util.ts} +4 -4
- package/src/meeting-info/{collection.js → collection.ts} +4 -1
- package/src/meeting-info/{index.js → index.ts} +10 -6
- package/src/meeting-info/{meeting-info-v2.js → meeting-info-v2.ts} +28 -10
- package/src/meeting-info/{request.js → request.ts} +6 -2
- package/src/meeting-info/{util.js → util.ts} +6 -5
- package/src/meeting-info/{utilv2.js → utilv2.ts} +8 -7
- package/src/meetings/{collection.js → collection.ts} +5 -2
- package/src/meetings/{index.js → index.ts} +88 -21
- package/src/meetings/{request.js → request.ts} +6 -1
- package/src/meetings/{util.js → util.ts} +5 -3
- package/src/member/{index.js → index.ts} +46 -15
- package/src/member/{util.js → util.ts} +17 -16
- package/src/members/{collection.js → collection.ts} +2 -1
- package/src/members/{index.js → index.ts} +46 -26
- package/src/members/{request.js → request.ts} +16 -5
- package/src/members/{util.js → util.ts} +7 -7
- package/src/metrics/{config.js → config.ts} +0 -2
- package/src/metrics/{constants.js → constants.ts} +0 -0
- package/src/metrics/{index.js → index.ts} +27 -8
- package/src/networkQualityMonitor/{index.js → index.ts} +18 -3
- package/src/personal-meeting-room/{index.js → index.ts} +17 -4
- package/src/personal-meeting-room/{request.js → request.ts} +3 -1
- package/src/personal-meeting-room/{util.js → util.ts} +1 -1
- package/src/reachability/{index.js → index.ts} +28 -17
- package/src/reachability/request.ts +4 -2
- package/src/reconnection-manager/{index.js → index.ts} +41 -12
- package/src/roap/{index.js → index.ts} +27 -18
- package/src/roap/{request.js → request.ts} +14 -2
- package/src/roap/turnDiscovery.ts +14 -5
- package/src/statsAnalyzer/{global.js → global.ts} +0 -0
- package/src/statsAnalyzer/{index.js → index.ts} +36 -17
- package/src/statsAnalyzer/{mqaUtil.js → mqaUtil.ts} +6 -1
- package/src/transcription/{index.js → index.ts} +16 -11
- package/test/integration/spec/space-meeting.js +1 -2
- package/test/unit/spec/meeting/index.js +26 -14
- package/test/unit/spec/reconnection-manager/index.js +1 -0
package/dist/roap/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Roap","attrs","options","roapRequest","RoapRequest","turnDiscovery","TurnDiscovery","resolve","then","meeting","webex","meetings","meetingCollection","getByKey","correlationId","roapMessage","messageType","ROAP","ROAP_TYPES","OK","version","ROAP_VERSION","seq","LoggerProxy","logger","log","sendRoap","locusSelfUrl","selfUrl","mediaId","audioMuted","isAudioMuted","videoMuted","isVideoMuted","meetingId","id","preferTranscoding","isMultistream","ANSWER","sdps","sdp","ERROR","errorType","reconnect","tieBreaker","OFFER","sendEmptyMediaId","config","experimental","enableTurnDiscovery","locus","mediaConnections","updateMediaConnections","isReconnecting","doTurnDiscovery","StatelessWebexPlugin"],"sources":["index.js"],"sourcesContent":["import {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {ROAP} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport RoapRequest from './request';\nimport TurnDiscovery from './turnDiscovery';\n\n/**\n * Roap options\n * @typedef {Object} RoapOptions\n * @property {String} sdp\n * @property {Meeting} meeting\n * @property {Number} seq\n * @property {Number} tieBreaker\n * @property {Boolean} reconnect\n */\n\n/**\n * @typedef {Object} SeqOptions\n * @property {String} correlationId\n * @property {String} mediaId\n * @property {Number} seq\n */\n\n/**\n * @class Roap\n * @export\n * @private\n */\nexport default class Roap extends StatelessWebexPlugin {\n /**\n *\n * @param {Object} attrs\n * @param {Object} options\n */\n constructor(attrs, options) {\n super({}, options);\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.attrs = attrs;\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.options = options;\n /**\n * The Roap Request Server Proxy Object\n * @instance\n * @type {RoapRequest}\n * @private\n * @memberof Roap\n */\n this.roapRequest = new RoapRequest({}, options);\n\n this.turnDiscovery = new TurnDiscovery(this.roapRequest);\n }\n\n /**\n *\n * @param {SeqOptions} options\n * @returns {null}\n * @private\n * @memberof Roap\n */\n sendRoapOK(options) {\n return Promise.resolve().then(() => {\n const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', options.correlationId);\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: options.seq\n };\n\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sending with seq ${options.seq}`);\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n correlationId: options.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(() => {\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);\n });\n });\n }\n\n /**\n * Sends a ROAP answer...\n * @param {SeqOptions} options\n * @param {Boolean} options.audioMuted\n * @param {Boolean} options.videoMuted\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapAnswer(options) {\n const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', options.correlationId);\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ANSWER,\n sdps: [options.sdp],\n version: ROAP.ROAP_VERSION,\n seq: options.seq\n };\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n correlationId: options.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n });\n }\n\n /**\n * Sends a ROAP error...\n * @param {Object} options\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapError(options) {\n const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', options.correlationId);\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ERROR,\n version: ROAP.ROAP_VERSION,\n errorType: options.errorType,\n seq: options.seq\n\n };\n\n return this.roapRequest.sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n correlationId: options.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(() => {\n LoggerProxy.logger.log(`Roap:index#sendRoapError --> ROAP ERROR sent with seq ${options.seq}`);\n });\n }\n\n /**\n * sends a roap media request\n * @param {RoapOptions} options\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapMediaRequest(options) {\n const {\n meeting, seq, sdp, reconnect, tieBreaker\n } = options;\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OFFER,\n sdps: [sdp],\n version: ROAP.ROAP_VERSION,\n seq,\n tieBreaker\n };\n\n // When reconnecting, it's important that the first roap message being sent out has empty media id.\n // Normally this is the roap offer, but when TURN discovery is enabled,\n // then this is the TURN discovery request message\n const sendEmptyMediaId = reconnect && !meeting.config.experimental.enableTurnDiscovery;\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n correlationId: meeting.correlationId,\n locusSelfUrl: meeting.selfUrl,\n mediaId: sendEmptyMediaId ? '' : meeting.mediaId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(({locus, mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n\n return locus;\n });\n }\n\n /**\n * Performs a TURN server discovery procedure, which involves exchanging\n * some roap messages with the server. This exchange has to be done before\n * any other roap messages are sent\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, isReconnecting) {\n return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["Roap","attrs","options","roapRequest","RoapRequest","turnDiscovery","TurnDiscovery","resolve","then","meeting","webex","meetings","meetingCollection","getByKey","correlationId","roapMessage","messageType","ROAP","ROAP_TYPES","OK","version","ROAP_VERSION","seq","LoggerProxy","logger","log","sendRoap","locusSelfUrl","selfUrl","mediaId","audioMuted","isAudioMuted","videoMuted","isVideoMuted","meetingId","id","preferTranscoding","isMultistream","ANSWER","sdps","sdp","ERROR","errorType","reconnect","tieBreaker","OFFER","sendEmptyMediaId","config","experimental","enableTurnDiscovery","locus","mediaConnections","updateMediaConnections","isReconnecting","doTurnDiscovery","StatelessWebexPlugin"],"sources":["index.ts"],"sourcesContent":["// @ts-ignore\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {ROAP} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\nimport RoapRequest from './request';\nimport TurnDiscovery from './turnDiscovery';\nimport Meeting from '../meeting';\n\n/**\n * Roap options\n * @typedef {Object} RoapOptions\n * @property {String} sdp\n * @property {Meeting} meeting\n * @property {Number} seq\n * @property {Number} tieBreaker\n * @property {Boolean} reconnect\n */\n\n/**\n * @typedef {Object} SeqOptions\n * @property {String} correlationId\n * @property {String} mediaId\n * @property {Number} seq\n */\n\n/**\n * @class Roap\n * @export\n * @private\n */\nexport default class Roap extends StatelessWebexPlugin {\n attrs: any;\n lastRoapOffer: any;\n options: any;\n roapHandler: any;\n roapRequest: any;\n turnDiscovery: any;\n\n /**\n *\n * @param {Object} attrs\n * @param {Object} options\n */\n constructor(attrs: any, options: any) {\n super({}, options);\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.attrs = attrs;\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof Roap\n */\n this.options = options;\n /**\n * The Roap Request Server Proxy Object\n * @instance\n * @type {RoapRequest}\n * @private\n * @memberof Roap\n */\n // @ts-ignore\n this.roapRequest = new RoapRequest({}, options);\n\n this.turnDiscovery = new TurnDiscovery(this.roapRequest);\n }\n\n /**\n *\n * @param {SeqOptions} options\n * @returns {null}\n * @memberof Roap\n */\n public sendRoapOK(options: any) {\n return Promise.resolve().then(() => {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', options.correlationId);\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: options.seq\n };\n\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sending with seq ${options.seq}`);\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n correlationId: options.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(() => {\n LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);\n });\n });\n }\n\n /**\n * Sends a ROAP answer...\n * @param {SeqOptions} options\n * @param {Boolean} options.audioMuted\n * @param {Boolean} options.videoMuted\n * @returns {Promise}\n * @memberof Roap\n */\n public sendRoapAnswer(options: any) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', options.correlationId);\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ANSWER,\n sdps: [options.sdp],\n version: ROAP.ROAP_VERSION,\n seq: options.seq\n };\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n correlationId: options.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n });\n }\n\n /**\n * Sends a ROAP error...\n * @param {Object} options\n * @returns {Promise}\n * @memberof Roap\n */\n sendRoapError(options) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', options.correlationId);\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.ERROR,\n version: ROAP.ROAP_VERSION,\n errorType: options.errorType,\n seq: options.seq\n\n };\n\n return this.roapRequest.sendRoap({\n roapMessage,\n locusSelfUrl: meeting.selfUrl,\n mediaId: options.mediaId,\n correlationId: options.correlationId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(() => {\n LoggerProxy.logger.log(`Roap:index#sendRoapError --> ROAP ERROR sent with seq ${options.seq}`);\n });\n }\n\n /**\n * sends a roap media request\n * @param {RoapOptions} options\n * @returns {Promise}\n * @memberof Roap\n */\n sendRoapMediaRequest(options: any) {\n const {\n meeting, seq, sdp, reconnect, tieBreaker\n } = options;\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.OFFER,\n sdps: [sdp],\n version: ROAP.ROAP_VERSION,\n seq,\n tieBreaker\n };\n\n // When reconnecting, it's important that the first roap message being sent out has empty media id.\n // Normally this is the roap offer, but when TURN discovery is enabled,\n // then this is the TURN discovery request message\n const sendEmptyMediaId = reconnect && !meeting.config.experimental.enableTurnDiscovery;\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n correlationId: meeting.correlationId,\n locusSelfUrl: meeting.selfUrl,\n mediaId: sendEmptyMediaId ? '' : meeting.mediaId,\n audioMuted: meeting.isAudioMuted(),\n videoMuted: meeting.isVideoMuted(),\n meetingId: meeting.id,\n preferTranscoding: !meeting.isMultistream,\n })\n .then(({locus, mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n\n return locus;\n });\n }\n\n /**\n * Performs a TURN server discovery procedure, which involves exchanging\n * some roap messages with the server. This exchange has to be done before\n * any other roap messages are sent\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 return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting);\n }\n}\n"],"mappings":"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"}
|
package/dist/roap/request.js
CHANGED
|
@@ -123,7 +123,8 @@ var RoapRequest = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
123
123
|
_loggerProxy.default.logger.info('Roap:request#sendRoap --> Race Condition /call mediaID not present');
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
var mediaUrl = "".concat(locusSelfUrl, "/").concat(_constants.MEDIA);
|
|
126
|
+
var mediaUrl = "".concat(locusSelfUrl, "/").concat(_constants.MEDIA); // @ts-ignore
|
|
127
|
+
|
|
127
128
|
var deviceUrl = this.webex.internal.device.url;
|
|
128
129
|
|
|
129
130
|
_loggerProxy.default.logger.info("Roap:request#sendRoap --> ".concat(mediaUrl, " \n ").concat(roapMessage.messageType, " \n seq:").concat(roapMessage.seq));
|
|
@@ -131,7 +132,8 @@ var RoapRequest = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
131
132
|
_metrics.default.postEvent({
|
|
132
133
|
event: _config.eventType.MEDIA_REQUEST,
|
|
133
134
|
meetingId: meetingId
|
|
134
|
-
});
|
|
135
|
+
}); // @ts-ignore
|
|
136
|
+
|
|
135
137
|
|
|
136
138
|
return this.webex.request({
|
|
137
139
|
uri: mediaUrl,
|
|
@@ -139,6 +141,7 @@ var RoapRequest = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
139
141
|
body: {
|
|
140
142
|
device: {
|
|
141
143
|
url: deviceUrl,
|
|
144
|
+
// @ts-ignore
|
|
142
145
|
deviceType: this.config.meetings.deviceType
|
|
143
146
|
},
|
|
144
147
|
correlationId: correlationId,
|
package/dist/roap/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RoapRequest","localSdp","reachabilityData","window","localStorage","getItem","REACHABILITY","reachabilityResult","JSON","parse","length","reachability","e","LoggerProxy","logger","error","options","roapMessage","locusSelfUrl","mediaId","correlationId","meetingId","info","mediaUrl","MEDIA","deviceUrl","webex","internal","device","url","messageType","seq","Metrics","postEvent","event","eventType","MEDIA_REQUEST","request","uri","method","HTTP_VERBS","PUT","body","deviceType","config","meetings","localMedias","attachRechabilityData","audioMuted","videoMuted","clientMediaPreferences","preferTranscoding","then","res","MEDIA_RESPONSE","mediaConnections","statusCode","locus","roapSeq","catch","err","data","parseLocusError","StatelessWebexPlugin"],"sources":["request.
|
|
1
|
+
{"version":3,"names":["RoapRequest","localSdp","reachabilityData","window","localStorage","getItem","REACHABILITY","reachabilityResult","JSON","parse","length","reachability","e","LoggerProxy","logger","error","options","roapMessage","locusSelfUrl","mediaId","correlationId","meetingId","info","mediaUrl","MEDIA","deviceUrl","webex","internal","device","url","messageType","seq","Metrics","postEvent","event","eventType","MEDIA_REQUEST","request","uri","method","HTTP_VERBS","PUT","body","deviceType","config","meetings","localMedias","attachRechabilityData","audioMuted","videoMuted","clientMediaPreferences","preferTranscoding","then","res","MEDIA_RESPONSE","mediaConnections","statusCode","locus","roapSeq","catch","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 {\n MEDIA,\n HTTP_VERBS,\n REACHABILITY\n} 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} options\n * @returns {Promise} returns a promise that resolves/rejects whatever the request does\n */\n\n\n attachRechabilityData(localSdp) {\n const reachabilityData = window.localStorage.getItem(REACHABILITY.localStorage);\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 }\n catch (e) {\n LoggerProxy.logger.error(`Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`);\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 * @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 {\n roapMessage, locusSelfUrl, mediaId, correlationId, meetingId\n } = 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(`Roap:request#sendRoap --> ${mediaUrl} \\n ${roapMessage.messageType} \\n seq:${roapMessage.seq}`);\n\n Metrics.postEvent({event: eventType.MEDIA_REQUEST, meetingId});\n\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(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 })),\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 = res.body.mediaConnections && res.body.mediaConnections.length > 0 && res.body.mediaConnections[0];\n\n LoggerProxy.logger.info(\n `Roap:request#sendRoap --> response:${JSON.stringify(mediaConnections, null, 2)}'\\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({event: eventType.MEDIA_RESPONSE, meetingId, data: {error: Metrics.parseLocusError(err, true)}});\n LoggerProxy.logger.error(`Roap:request#sendRoap --> Error:${JSON.stringify(err, null, 2)}`);\n LoggerProxy.logger.error(\n `Roap:request#sendRoapRequest --> errorBody:${JSON.stringify(roapMessage, null, 2)} + '\\\\n mediaId:'${options.mediaId}`\n );\n throw err;\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -30,6 +30,7 @@ var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy")
|
|
|
30
30
|
|
|
31
31
|
var _constants2 = require("../constants");
|
|
32
32
|
|
|
33
|
+
// @ts-ignore - Types not available for @webex/common
|
|
33
34
|
var TURN_DISCOVERY_TIMEOUT = 10; // in seconds
|
|
34
35
|
// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0
|
|
35
36
|
// and this is handy for us, because TURN discovery is always done before the first SDP exchange,
|
|
@@ -106,6 +107,7 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
106
107
|
value: function handleTurnDiscoveryResponse(roapMessage) {
|
|
107
108
|
var _this = this;
|
|
108
109
|
|
|
110
|
+
// @ts-ignore - Fix missing type
|
|
109
111
|
var headers = roapMessage.headers;
|
|
110
112
|
|
|
111
113
|
if (!this.defer) {
|
|
@@ -178,7 +180,9 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
178
180
|
return this.roapRequest.sendRoap({
|
|
179
181
|
roapMessage: roapMessage,
|
|
180
182
|
correlationId: meeting.correlationId,
|
|
183
|
+
// @ts-ignore - Fix missing type
|
|
181
184
|
locusSelfUrl: meeting.selfUrl,
|
|
185
|
+
// @ts-ignore - Fix missing type
|
|
182
186
|
mediaId: isReconnecting ? '' : meeting.mediaId,
|
|
183
187
|
audioMuted: meeting.isAudioMuted(),
|
|
184
188
|
videoMuted: meeting.isVideoMuted(),
|
|
@@ -210,7 +214,9 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
210
214
|
version: _constants2.ROAP.ROAP_VERSION,
|
|
211
215
|
seq: TURN_DISCOVERY_SEQ
|
|
212
216
|
},
|
|
217
|
+
// @ts-ignore - fix type
|
|
213
218
|
locusSelfUrl: meeting.selfUrl,
|
|
219
|
+
// @ts-ignore - fix type
|
|
214
220
|
mediaId: meeting.mediaId,
|
|
215
221
|
correlationId: meeting.correlationId,
|
|
216
222
|
audioMuted: meeting.isAudioMuted(),
|
|
@@ -241,6 +247,7 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
241
247
|
value: function doTurnDiscovery(meeting, isReconnecting) {
|
|
242
248
|
var _this2 = this;
|
|
243
249
|
|
|
250
|
+
// @ts-ignore - fix type
|
|
244
251
|
var isAnyClusterReachable = meeting.webex.meetings.reachability.isAnyClusterReachable();
|
|
245
252
|
|
|
246
253
|
if (isAnyClusterReachable) {
|
|
@@ -250,7 +257,8 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
250
257
|
turnServerInfo: undefined,
|
|
251
258
|
turnDiscoverySkippedReason: 'reachability'
|
|
252
259
|
});
|
|
253
|
-
}
|
|
260
|
+
} // @ts-ignore - fix type
|
|
261
|
+
|
|
254
262
|
|
|
255
263
|
if (!meeting.config.experimental.enableTurnDiscovery) {
|
|
256
264
|
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it');
|
|
@@ -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":["import {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';\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 /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n waitForTurnDiscoveryResponse() {\n if (!this.defer) {\n LoggerProxy.logger.warn('Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress');\n\n return Promise.reject(new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()'));\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(`Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`);\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info('Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...');\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 handleTurnDiscoveryResponse(roapMessage) {\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn('Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response');\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(expectedHeader.headerName.length + 1);\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(`Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received: ${JSON.stringify(headers)}`);\n this.defer.reject(new Error(`TURN_DISCOVERY_RESPONSE missing some headers: ${JSON.stringify(headers)}`));\n }\n else {\n LoggerProxy.logger.info(`Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response, url=${this.turnInfo.url}`);\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, isReconnecting) {\n if (this.defer) {\n LoggerProxy.logger.warn('Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress');\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('Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST');\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n correlationId: meeting.correlationId,\n locusSelfUrl: meeting.selfUrl,\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) {\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 locusSelfUrl: meeting.selfUrl,\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, isReconnecting) {\n const isAnyClusterReachable = meeting.webex.meetings.reachability.isAnyClusterReachable();\n\n if (isAnyClusterReachable) {\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery');\n return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: 'reachability'});\n }\n\n if (!meeting.config.experimental.enableTurnDiscovery) {\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it');\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(`Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`);\n\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE,\n {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack\n }\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","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 /**\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('Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress');\n\n return Promise.reject(new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()'));\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(`Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`);\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info('Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...');\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('Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response');\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(expectedHeader.headerName.length + 1);\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(`Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received: ${JSON.stringify(headers)}`);\n this.defer.reject(new Error(`TURN_DISCOVERY_RESPONSE missing some headers: ${JSON.stringify(headers)}`));\n }\n else {\n LoggerProxy.logger.info(`Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response, url=${this.turnInfo.url}`);\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('Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress');\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('Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST');\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('Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery');\n return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: 'reachability'});\n }\n\n // @ts-ignore - fix type\n if (!meeting.config.experimental.enableTurnDiscovery) {\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it');\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(`Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`);\n\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE,\n {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack\n }\n );\n\n return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: undefined});\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["STATS_DEFAULT","encryption","audio","send","trackLabel","maxPacketLossRatio","availableBandwidth","bytesSent","meanRemoteJitter","meanRoundTripTime","recv","bytesReceived","meanRtpJitter","video","totalPacketsLost","latency","packetsLost","share","bandwidth","systemBandwidth","sentPerSecond","encodedPerSecond","helper","audioBytesSent","videoBytestSent","speed","results","connectionType","systemNetworkType","systemIpAddress","local","candidateType","transport","ipAddress","networkType","remote","resolutions","width","height","internal","candidates"],"sources":["global.
|
|
1
|
+
{"version":3,"names":["STATS_DEFAULT","encryption","audio","send","trackLabel","maxPacketLossRatio","availableBandwidth","bytesSent","meanRemoteJitter","meanRoundTripTime","recv","bytesReceived","meanRtpJitter","video","totalPacketsLost","latency","packetsLost","share","bandwidth","systemBandwidth","sentPerSecond","encodedPerSecond","helper","audioBytesSent","videoBytestSent","speed","results","connectionType","systemNetworkType","systemIpAddress","local","candidateType","transport","ipAddress","networkType","remote","resolutions","width","height","internal","candidates"],"sources":["global.ts"],"sourcesContent":["const STATS_DEFAULT = {\n encryption: 'sha-256',\n audio: {\n send: {\n trackLabel: '',\n maxPacketLossRatio: 0,\n availableBandwidth: 0,\n bytesSent: 0,\n meanRemoteJitter: [],\n meanRoundTripTime: []\n },\n recv: {\n availableBandwidth: 0,\n bytesReceived: 0,\n meanRtpJitter: [],\n meanRoundTripTime: []\n }\n },\n video: {\n send: {\n trackLabel: '',\n maxPacketLossRatio: 0,\n availableBandwidth: 0,\n meanRemoteJitter: [],\n meanRoundTripTime: []\n },\n recv: {\n availableBandwidth: 0,\n totalPacketsLost: 0,\n meanRtpJitter: [],\n meanRoundTripTime: []\n\n },\n latency: 0,\n packetsLost: 0\n },\n share: {\n send: {\n maxPacketLossRatio: 0,\n availableBandwidth: 0,\n totalPacketsLost: 0,\n meanRemoteJitter: [],\n meanRoundTripTime: []\n },\n recv: {\n availableBandwidth: 0,\n meanRtpJitter: [],\n meanRoundTripTime: []\n },\n\n latency: 0,\n packetsLost: 0\n },\n bandwidth: {\n systemBandwidth: 0,\n sentPerSecond: 0,\n encodedPerSecond: 0,\n helper: {\n audioBytesSent: 0,\n videoBytestSent: 0\n },\n speed: 0\n },\n results: {},\n connectionType: {\n systemNetworkType: 'unknown',\n systemIpAddress: '0.0.0.0',\n local: {\n candidateType: [],\n transport: [],\n ipAddress: [],\n networkType: []\n },\n remote: {\n candidateType: [],\n transport: [],\n ipAddress: [],\n networkType: []\n }\n },\n resolutions: {\n audio: {\n send: {\n width: 0,\n height: 0\n },\n recv: {\n width: 0,\n height: 0\n }\n },\n video: {\n send: {\n width: 0,\n height: 0\n },\n recv: {\n width: 0,\n height: 0\n }\n },\n share: {\n send: {\n width: 0,\n height: 0\n },\n recv: {\n width: 0,\n height: 0\n }\n }\n },\n internal: {\n audio: {\n send: {},\n recv: {}\n },\n video: {\n send: {},\n recv: {}\n },\n share: {\n send: {},\n recv: {}\n },\n remote: {\n\n },\n candidates: {}\n }\n};\n\nexport default STATS_DEFAULT;\n"],"mappings":"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"}
|
|
@@ -87,6 +87,20 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
87
87
|
var statsResults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _global.default;
|
|
88
88
|
(0, _classCallCheck2.default)(this, StatsAnalyzer);
|
|
89
89
|
_this = _super.call(this);
|
|
90
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "config", void 0);
|
|
91
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "correlationId", void 0);
|
|
92
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "lastEmittedStartStopEvent", void 0);
|
|
93
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "lastMqaDataSent", void 0);
|
|
94
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "lastStatsResults", void 0);
|
|
95
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "localMQEStats", void 0);
|
|
96
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "meetingMediaStatus", void 0);
|
|
97
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mqaInterval", void 0);
|
|
98
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mqaSentCount", void 0);
|
|
99
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "networkQualityMonitor", void 0);
|
|
100
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mediaConnection", void 0);
|
|
101
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "statsInterval", void 0);
|
|
102
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "statsResults", void 0);
|
|
103
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "statsStarted", void 0);
|
|
90
104
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "emitStartStopEvents", function (mediaType, previousValue, currentValue, isLocal) {
|
|
91
105
|
if (mediaType !== 'audio' && mediaType !== 'video' && mediaType !== 'share') {
|
|
92
106
|
throw new Error("Unsupported mediaType: ".concat(mediaType));
|
|
@@ -402,7 +416,8 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
402
416
|
_config.default.intervals[0].intervalMetadata.peripherals.push({
|
|
403
417
|
information: this.statsResults[_constants.STATS.VIDEO_CORRELATE][_constants.STATS.SEND_DIRECTION].trackLabel || _constants._UNKNOWN_,
|
|
404
418
|
name: _constants.MEDIA_DEVICES.CAMERA
|
|
405
|
-
});
|
|
419
|
+
}); // @ts-ignore
|
|
420
|
+
|
|
406
421
|
|
|
407
422
|
_config.default.networkType = this.statsResults.connectionType.local.networkType;
|
|
408
423
|
this.mqaSentCount += 1;
|
|
@@ -416,6 +431,7 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
416
431
|
function: 'sendMqaData'
|
|
417
432
|
}, EVENTS.MEDIA_QUALITY, {
|
|
418
433
|
data: _config.default.intervals[0],
|
|
434
|
+
// @ts-ignore
|
|
419
435
|
networkType: _config.default.networkType
|
|
420
436
|
});
|
|
421
437
|
}
|
|
@@ -534,6 +550,7 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
534
550
|
|
|
535
551
|
case 'remote-inbound-rtp':
|
|
536
552
|
case 'remote-outbound-rtp':
|
|
553
|
+
// @ts-ignore
|
|
537
554
|
this.compareSentAndReceived(getStatsResult, type, isSender);
|
|
538
555
|
break;
|
|
539
556
|
|
|
@@ -547,6 +564,7 @@ var StatsAnalyzer = /*#__PURE__*/function (_EventsScope) {
|
|
|
547
564
|
break;
|
|
548
565
|
|
|
549
566
|
case 'media-source':
|
|
567
|
+
// @ts-ignore
|
|
550
568
|
this.parseAudioSource(getStatsResult, type);
|
|
551
569
|
break;
|
|
552
570
|
|