@webex/plugin-meetings 1.146.1 → 1.149.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"names":["NeedsRetryError","Error","NeedsRejoinError","wasSharing","error","ReconnectionManager","meeting","iceState","disconnected","resolve","timer","undefined","timeoutDuration","config","reconnection","iceReconnectionTimeout","status","RECONNECTION","STATE","DEFAULT_STATUS","tryCount","DEFAULT_TRY_COUNT","webex","maxRejoinAttempts","rejoinAttempts","autoRejoinEnabled","autoRejoin","reset","LoggerProxy","logger","log","clearTimeout","reject","setTimeout","enabled","COMPLETE","info","ReconnectInProgress","ReconnectionError","networkDisconnect","networkRetry","id","validate","Metrics","postEvent","event","eventType","MEDIA_RECONNECTING","executeReconnection","then","MEDIA_RECOVERED","data","recoveredBy","RECOVERED_BY_NEW","catch","reconnectError","reconnect","message","reconnectMetric","CALL_ABORTED","errors","category","errorObjects","expected","errorCode","fatal","name","mediaEngine","shownToUser","rejoinMeeting","IN_PROGRESS","reconnectMercuryWebSocket","internal","device","url","FAILURE","shareStatus","SHARE_STATUS","LOCAL_SHARE_ACTIVE","meetings","syncMeetings","getMeetingByType","_ID_","state","_LEFT_","type","_CALL_","reconnectMedia","media","previousCorrelationId","correlationId","join","rejoin","RoapCollection","deleteSession","Media","stopTracks","mediaProperties","shareTrack","isSharing","NO_SHARE","mediaDirection","sendShare","Trigger","trigger","file","function","EVENT_TRIGGERS","MEETING_STOPPED_SHARING_LOCAL","reason","SHARE_STOPPED_REASON","MEETING_REJOIN","sendOperationalMetric","METRICS_OPERATIONAL_MEASURES","MEETING_MAX_REJOIN_FAILURE","locus_id","locusUrl","split","pop","stack","setupPeerConnection","attachMedia","meetingId","remoteQualityLevel","enableRtx","peerConnection","setRemoteStream","roap","sendRoapMediaRequest","sdp","roapSeq","mercury","connected","disconnect","connect","PeerConnectionManager","close","unsetPeerConnection","reInitiatePeerconnection","setPeerConnectionEvents","statsAnalyzer","updatePeerconnection"],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable no-warning-comments */\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport Trigger from '../common/events/trigger-proxy';\nimport {\n EVENT_TRIGGERS,\n METRICS_OPERATIONAL_MEASURES,\n RECONNECTION,\n SHARE_STATUS,\n SHARE_STOPPED_REASON,\n _CALL_,\n _LEFT_,\n _ID_\n} from '../constants';\nimport ReconnectionError from '../common/errors/reconnection';\nimport ReconnectInProgress from '../common/errors/reconnection-in-progress';\nimport PeerConnectionManager from '../peer-connection-manager';\nimport {eventType, reconnection, errorObjects} from '../metrics/config';\nimport Media from '../media';\nimport Metrics from '../metrics';\nimport RoapCollection from '../roap/collection';\n\n/**\n * Used to indicate that the reconnect logic needs to be retried.\n *\n * @class NeedsRetryError\n * @extends {Error}\n */\nclass NeedsRetryError extends Error {}\n\n/**\n * Used to indicate that the meeting needs to be rejoined, not just media reconnected\n *\n * @class NeedsRejoinError\n * @extends {Error}\n */\nclass NeedsRejoinError extends Error {\n /**\n * Creates an instance of NeedsRejoinError.\n * @param {Object} params\n * @param {boolean} params.wasSharing\n * @param {Error} params.error\n * @memberof NeedsRejoinError\n */\n constructor({wasSharing, error = new Error('Meeting needs to be rejoined')}) {\n super(error);\n\n this.wasSharing = wasSharing;\n }\n}\n\n/**\n * @export\n * @class ReconnectionManager\n*/\nexport default class ReconnectionManager {\n /**\n * @param {Meeting} meeting\n */\n constructor(meeting) {\n /**\n * Stores ICE reconnection state data.\n *\n * @instance\n * @type {Object}\n * @private\n * @memberof ReconnectionManager\n */\n this.iceState = {\n disconnected: false,\n resolve: () => {},\n timer: undefined,\n timeoutDuration: meeting.config.reconnection.iceReconnectionTimeout\n };\n\n /**\n * @instance\n * @type {String}\n * @private\n * @memberof ReconnectionManager\n */\n this.status = RECONNECTION.STATE.DEFAULT_STATUS;\n /**\n * @instance\n * @type {Number}\n * @private\n * @memberof ReconnectionManager\n */\n this.tryCount = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof ReconnectionManager\n */\n // TODO : change this logic to not save the meeting instance\n // It gets complicated when meeting ends on remote side , We have a old meeting instance which is not up to date\n this.webex = meeting.webex;\n /**\n * @instance\n * @type {Meeting}\n * @private\n * @memberof ReconnectionManager\n */\n // TODO: try removing the circular dependency for meeting and reconnection manager\n // try moving this to meetings collection\n this.meeting = meeting;\n\n this.maxRejoinAttempts = meeting.config.reconnection.maxRejoinAttempts;\n this.rejoinAttempts = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n this.autoRejoinEnabled = meeting.config.reconnection.autoRejoin;\n\n\n // Make sure reconnection state is in default\n this.reset();\n }\n\n /**\n * Sets the iceState to connected and clears any disconnect timeouts and\n * related timeout data within the iceState.\n *\n * @returns {undefined}\n * @public\n * @memberof ReconnectionManager\n */\n iceReconnected() {\n if (this.iceState.disconnected) {\n LoggerProxy.logger.log('ReconnectionManager:index#iceReconnected --> ice has reconnected');\n\n this.iceState.resolve();\n this.iceState.resolve = () => {};\n\n if (this.iceState.timer) {\n clearTimeout(this.iceState.timer);\n delete this.iceState.timer;\n }\n\n this.iceState.disconnected = false;\n }\n }\n\n /**\n * Set the iceState to disconnected and generates a timeout that waits for the\n * iceState to reconnect and then resolves. If the ice state is already\n * processing a reconnect, it immediately resolves. Rejects if the timeout\n * duration is reached.\n *\n * @returns {Promise<undefined>}\n * @public\n * @memberof ReconnectionManager\n */\n waitForIceReconnect() {\n if (!this.iceState.disconnected) {\n LoggerProxy.logger.log('ReconnectionManager:index#waitForIceReconnect --> waiting for ice reconnect');\n\n this.iceState.disconnected = true;\n\n return new Promise((resolve, reject) => {\n this.iceState.timer = setTimeout(() => {\n if (this.iceState.disconnected === false) {\n resolve();\n }\n else {\n this.iceState.disconnected = false;\n reject(new Error(`ice reconnection did not occur in ${this.iceState.timeoutDuration}ms`));\n }\n }, this.iceState.timeoutDuration);\n\n this.iceState.resolve = resolve;\n });\n }\n\n // return a resolved promise to prevent multiple catch executions of reconnect\n return Promise.resolve();\n }\n\n /**\n * @returns {undefined}\n * @public\n * @memberof ReconnectionManager\n */\n reset() {\n this.status = RECONNECTION.STATE.DEFAULT_STATUS;\n this.tryCount = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n this.rejoinAttempts = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n }\n\n /**\n * @returns {undefined}\n * @public\n * @memberof ReconnectionManager\n */\n cleanUp() {\n this.reset();\n this.meeting = null;\n }\n\n /**\n * @returns {Boolean}\n * @throws {ReconnectionError}\n * @private\n * @memberof ReconnectionManager\n */\n validate() {\n if (this.meeting.config.reconnection.enabled) {\n if (\n this.status === RECONNECTION.STATE.DEFAULT_STATUS ||\n this.status === RECONNECTION.STATE.COMPLETE\n ) {\n return true;\n }\n\n LoggerProxy.logger.info('ReconnectionManager:index#validate --> Reconnection already in progress.');\n\n throw new ReconnectInProgress('Reconnection already in progress.');\n }\n\n LoggerProxy.logger.info('ReconnectionManager:index#validate --> Reconnection is not enabled.');\n\n throw new ReconnectionError('Reconnection is not enabled.');\n }\n\n /**\n * Initiates a media reconnect for the active meeting\n * @param {Object} reconnectOptions\n * @param {boolean} [reconnectOptions.networkDisconnect=false] indicates if a network disconnect event happened\n * @param {boolean} [reconnectOptions.networkRetry=false] indicates if we are retrying the reconnect\n * @returns {Promise}\n * @public\n * @memberof ReconnectionManager\n */\n async reconnect({networkDisconnect = false, networkRetry = false} = {}) {\n LoggerProxy.logger.info(`ReconnectionManager:index#reconnect --> Reconnection start for meeting ${this.meeting.id}.`);\n // First, validate that we can reconnect, if not, it will throw an error\n try {\n this.validate();\n }\n catch (error) {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection unable to begin.', error);\n throw error;\n }\n\n if (!networkRetry) {\n // Only log START metrics on the initial reconnect\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Sending reconnect start metric.');\n Metrics.postEvent({\n event: eventType.MEDIA_RECONNECTING,\n meeting: this.meeting\n });\n }\n\n return this.executeReconnection({networkDisconnect})\n .then(() => {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection successful.');\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Sending reconnect success metric.');\n Metrics.postEvent({\n event: eventType.MEDIA_RECOVERED,\n meeting: this.meeting,\n data: {recoveredBy: reconnection.RECOVERED_BY_NEW}\n });\n })\n .catch((reconnectError) => {\n if (reconnectError instanceof NeedsRetryError) {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.');\n // Reset our reconnect status since we are looping back to the beginning\n this.status = RECONNECTION.STATE.DEFAULT_STATUS;\n\n // This is a network retry, so we should not log START metrics again\n return this.reconnect({networkDisconnect: true, networkRetry: true});\n }\n\n // Reconnect has failed\n LoggerProxy.logger.error('ReconnectionManager:index#reconnect --> Reconnection failed.', reconnectError.message);\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Sending reconnect abort metric.');\n\n const reconnectMetric = {\n event: eventType.CALL_ABORTED,\n meeting: this.meeting,\n data: {\n errors: [\n {\n category: errorObjects.category.expected,\n errorCode: 2008,\n fatal: true,\n name: errorObjects.name.mediaEngine,\n shownToUser: false\n }\n ]\n }\n };\n\n Metrics.postEvent(reconnectMetric);\n if (reconnectError instanceof NeedsRejoinError) {\n // send call aborded event with catogery as expected as we are trying to rejoin\n\n if (this.autoRejoinEnabled) {\n return this.rejoinMeeting(reconnectError.wasSharing);\n }\n }\n\n\n throw reconnectError;\n });\n }\n\n /**\n * @param {Object} reconnectOptions\n * @param {boolean} [reconnectOptions.networkDisconnect=false] indicates if a network disconnect event happened\n * @returns {Promise}\n * @throws {NeedsRetryError}\n * @private\n * @memberof ReconnectionManager\n */\n async executeReconnection({networkDisconnect = false}) {\n this.status = RECONNECTION.STATE.IN_PROGRESS;\n\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.');\n\n if (networkDisconnect) {\n try {\n await this.reconnectMercuryWebSocket();\n LoggerProxy.logger.error('ReconnectionManager:index#executeReconnection --> Websocket reconnected.', this.webex.internal.device.url);\n }\n catch (error) {\n LoggerProxy.logger.error('ReconnectionManager:index#executeReconnection --> Unable to reconnect to websocket, giving up.');\n this.status = RECONNECTION.STATE.FAILURE;\n throw (error);\n }\n }\n\n const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;\n\n try {\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Updating meeting data from server.');\n await this.webex.meetings.syncMeetings();\n }\n catch (syncError) {\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.', syncError);\n throw (new NeedsRetryError(syncError));\n }\n\n // TODO: try to improve this logic as the reconnection manager saves the instance of deleted meeting object\n // So that on rejoin it known what parametrs it was using\n if (!this.meeting || !this.webex.meetings.getMeetingByType(_ID_, this.meeting.id)) {\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely ');\n\n throw new Error('Unable to rejoin a meeting already ended or inactive .');\n }\n\n LoggerProxy.logger.info(`ReconnectionManager:index#executeReconnection --> Current state of meeting is ${this.meeting.state}`);\n\n // If the meeting state was left, no longer reconnect media\n if (this.meeting.state === _LEFT_) {\n if (this.meeting.type === _CALL_) {\n throw new Error('Unable to rejoin a call in LEFT state.');\n }\n\n throw (new NeedsRejoinError({wasSharing}));\n }\n\n try {\n const media = await this.reconnectMedia();\n\n LoggerProxy.logger.log('ReconnectionManager:index#executeReconnection --> Media reestablished');\n this.status = RECONNECTION.STATE.COMPLETE;\n\n return media;\n }\n catch (error) {\n LoggerProxy.logger.error('ReconnectionManager:index#executeReconnection --> Media reestablishment failed');\n this.status = RECONNECTION.STATE.FAILURE;\n\n throw (error);\n }\n }\n\n /**\n * Rejoins a meeting after detecting the member was in a LEFT state\n *\n * @async\n * @param {boolean} wasSharing\n * @returns {Promise}\n */\n async rejoinMeeting(wasSharing = false) {\n try {\n LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> attemping meeting rejoin');\n const previousCorrelationId = this.meeting.correlationId;\n\n await this.meeting.join({rejoin: true});\n LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');\n\n RoapCollection.deleteSession(previousCorrelationId);\n\n if (wasSharing) {\n // Stop the share streams if user tried to rejoin\n Media.stopTracks(this.meeting.mediaProperties.shareTrack);\n this.meeting.isSharing = false;\n if (this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE) {\n this.meeting.shareStatus = SHARE_STATUS.NO_SHARE;\n }\n this.meeting.mediaProperties.mediaDirection.sendShare = false;\n Trigger.trigger(\n this.meeting,\n {\n file: 'reconnection-manager/index',\n function: 'rejoinMeeting'\n },\n EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,\n {\n reason: SHARE_STOPPED_REASON.MEETING_REJOIN\n }\n );\n }\n }\n catch (joinError) {\n this.rejoinAttempts += 1;\n if (this.rejoinAttempts <= this.maxRejoinAttempts) {\n LoggerProxy.logger.info(`ReconnectionManager:index#rejoinMeeting --> Unable to rejoin meeting, attempt #${this.rejoinAttempts}, retrying.`, joinError);\n this.rejoinMeeting();\n }\n else {\n LoggerProxy.logger.error('ReconnectionManager:index#rejoinMeeting --> Unable to rejoin meeting after max attempts.', joinError);\n Metrics.sendOperationalMetric(\n METRICS_OPERATIONAL_MEASURES.MEETING_MAX_REJOIN_FAILURE,\n {\n locus_id: this.meeting.locusUrl.split('/').pop(),\n reason: joinError.message,\n stack: joinError.stack\n }\n );\n this.status = RECONNECTION.STATE.FAILURE;\n throw joinError;\n }\n }\n\n try {\n await this.reconnectMedia();\n }\n catch (mediaError) {\n LoggerProxy.logger.error('ReconnectionManager:index#rejoinMeeting --> Unable to reestablish media after rejoining.', mediaError);\n throw mediaError;\n }\n }\n\n /**\n * @returns {Promise}\n * @private\n * @memberof ReconnectionManager\n */\n reconnectMedia() {\n LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media');\n\n ReconnectionManager.setupPeerConnection(this.meeting);\n\n return Media.attachMedia(this.meeting.mediaProperties, {\n meetingId: this.meeting.id,\n remoteQualityLevel: this.meeting.mediaProperties.remoteQualityLevel,\n enableRtx: this.meeting.config.enableRtx\n })\n .then((peerConnection) => this.meeting.setRemoteStream(peerConnection))\n .then(() => {\n LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> Sending ROAP media request');\n\n return this.meeting.roap\n .sendRoapMediaRequest({\n sdp: this.meeting.mediaProperties.peerConnection.sdp,\n roapSeq: this.meeting.roapSeq,\n meeting: this.meeting,\n reconnect: true\n });\n });\n }\n\n /**\n * Attempt to Reconnect Mercury Websocket\n * @returns {Promise}\n * @private\n * @memberof ReconnectionManager\n */\n async reconnectMercuryWebSocket() {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Reconnecting websocket.');\n // First, attempt to disconnect if we think we are already connected.\n if (this.webex.internal.mercury.connected) {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Disconnecting existing websocket.');\n try {\n await this.webex.internal.mercury.disconnect();\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Websocket disconnected successfully.');\n }\n catch (disconnectError) {\n // If we can't disconnect, the sdk is in such a bad state that reconnecting is not going to happen.\n LoggerProxy.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to disconnect from websocket, giving up.', disconnectError);\n throw disconnectError;\n }\n }\n\n try {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Connecting websocket.');\n await this.webex.internal.mercury.connect();\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Websocket connected successfully.');\n }\n catch (connectError) {\n LoggerProxy.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to connect to websocket, giving up.', connectError);\n\n throw (connectError);\n }\n }\n\n /**\n * @param {Meeting} meeting\n * @returns {undefined}\n * @private\n * @memberof ReconnectionManager\n */\n static setupPeerConnection(meeting) {\n LoggerProxy.logger.log('ReconnectionManager:index#setupPeerConnection --> Begin resetting peer connection');\n // close pcs, unset to null and create a new one with out closing any streams\n PeerConnectionManager.close(meeting.mediaProperties.peerConnection);\n meeting.mediaProperties.unsetPeerConnection();\n meeting.mediaProperties.reInitiatePeerconnection();\n PeerConnectionManager.setPeerConnectionEvents(meeting);\n // update the peerconnection in the stats manager when ever we reconnect\n meeting.statsAnalyzer.updatePeerconnection(meeting.mediaProperties.peerConnection);\n }\n}\n"]}
1
+ {"version":3,"sources":["index.js"],"names":["NeedsRetryError","Error","NeedsRejoinError","wasSharing","error","ReconnectionManager","meeting","iceState","disconnected","resolve","timer","undefined","timeoutDuration","config","reconnection","iceReconnectionTimeout","status","RECONNECTION","STATE","DEFAULT_STATUS","tryCount","DEFAULT_TRY_COUNT","webex","maxRejoinAttempts","rejoinAttempts","autoRejoinEnabled","autoRejoin","reset","LoggerProxy","logger","log","clearTimeout","reject","setTimeout","enabled","COMPLETE","info","ReconnectInProgress","ReconnectionError","networkDisconnect","networkRetry","id","validate","Metrics","postEvent","event","eventType","MEDIA_RECONNECTING","executeReconnection","then","MEDIA_RECOVERED","data","recoveredBy","RECOVERED_BY_NEW","catch","reconnectError","reconnect","message","reconnectMetric","CALL_ABORTED","errors","category","errorObjects","expected","errorCode","fatal","name","mediaEngine","shownToUser","rejoinMeeting","IN_PROGRESS","reconnectMercuryWebSocket","internal","device","url","FAILURE","shareStatus","SHARE_STATUS","LOCAL_SHARE_ACTIVE","meetings","syncMeetings","getMeetingByType","_ID_","state","_LEFT_","type","_CALL_","reconnectMedia","media","previousCorrelationId","correlationId","join","rejoin","RoapCollection","deleteSession","Media","stopTracks","mediaProperties","shareTrack","isSharing","NO_SHARE","mediaDirection","sendShare","Trigger","trigger","file","function","EVENT_TRIGGERS","MEETING_STOPPED_SHARING_LOCAL","reason","SHARE_STOPPED_REASON","MEETING_REJOIN","sendOperationalMetric","METRICS_OPERATIONAL_MEASURES","MEETING_MAX_REJOIN_FAILURE","locus_id","locusUrl","split","pop","stack","setupPeerConnection","attachMedia","meetingId","remoteQualityLevel","enableRtx","enableExtmap","peerConnection","setRemoteStream","roap","sendRoapMediaRequest","sdp","roapSeq","mercury","connected","disconnect","connect","PeerConnectionManager","close","unsetPeerConnection","reInitiatePeerconnection","setPeerConnectionEvents","statsAnalyzer","updatePeerconnection"],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable no-warning-comments */\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport Trigger from '../common/events/trigger-proxy';\nimport {\n EVENT_TRIGGERS,\n METRICS_OPERATIONAL_MEASURES,\n RECONNECTION,\n SHARE_STATUS,\n SHARE_STOPPED_REASON,\n _CALL_,\n _LEFT_,\n _ID_\n} from '../constants';\nimport ReconnectionError from '../common/errors/reconnection';\nimport ReconnectInProgress from '../common/errors/reconnection-in-progress';\nimport PeerConnectionManager from '../peer-connection-manager';\nimport {eventType, reconnection, errorObjects} from '../metrics/config';\nimport Media from '../media';\nimport Metrics from '../metrics';\nimport RoapCollection from '../roap/collection';\n\n/**\n * Used to indicate that the reconnect logic needs to be retried.\n *\n * @class NeedsRetryError\n * @extends {Error}\n */\nclass NeedsRetryError extends Error {}\n\n/**\n * Used to indicate that the meeting needs to be rejoined, not just media reconnected\n *\n * @class NeedsRejoinError\n * @extends {Error}\n */\nclass NeedsRejoinError extends Error {\n /**\n * Creates an instance of NeedsRejoinError.\n * @param {Object} params\n * @param {boolean} params.wasSharing\n * @param {Error} params.error\n * @memberof NeedsRejoinError\n */\n constructor({wasSharing, error = new Error('Meeting needs to be rejoined')}) {\n super(error);\n\n this.wasSharing = wasSharing;\n }\n}\n\n/**\n * @export\n * @class ReconnectionManager\n*/\nexport default class ReconnectionManager {\n /**\n * @param {Meeting} meeting\n */\n constructor(meeting) {\n /**\n * Stores ICE reconnection state data.\n *\n * @instance\n * @type {Object}\n * @private\n * @memberof ReconnectionManager\n */\n this.iceState = {\n disconnected: false,\n resolve: () => {},\n timer: undefined,\n timeoutDuration: meeting.config.reconnection.iceReconnectionTimeout\n };\n\n /**\n * @instance\n * @type {String}\n * @private\n * @memberof ReconnectionManager\n */\n this.status = RECONNECTION.STATE.DEFAULT_STATUS;\n /**\n * @instance\n * @type {Number}\n * @private\n * @memberof ReconnectionManager\n */\n this.tryCount = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n /**\n * @instance\n * @type {Object}\n * @private\n * @memberof ReconnectionManager\n */\n // TODO : change this logic to not save the meeting instance\n // It gets complicated when meeting ends on remote side , We have a old meeting instance which is not up to date\n this.webex = meeting.webex;\n /**\n * @instance\n * @type {Meeting}\n * @private\n * @memberof ReconnectionManager\n */\n // TODO: try removing the circular dependency for meeting and reconnection manager\n // try moving this to meetings collection\n this.meeting = meeting;\n\n this.maxRejoinAttempts = meeting.config.reconnection.maxRejoinAttempts;\n this.rejoinAttempts = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n this.autoRejoinEnabled = meeting.config.reconnection.autoRejoin;\n\n\n // Make sure reconnection state is in default\n this.reset();\n }\n\n /**\n * Sets the iceState to connected and clears any disconnect timeouts and\n * related timeout data within the iceState.\n *\n * @returns {undefined}\n * @public\n * @memberof ReconnectionManager\n */\n iceReconnected() {\n if (this.iceState.disconnected) {\n LoggerProxy.logger.log('ReconnectionManager:index#iceReconnected --> ice has reconnected');\n\n this.iceState.resolve();\n this.iceState.resolve = () => {};\n\n if (this.iceState.timer) {\n clearTimeout(this.iceState.timer);\n delete this.iceState.timer;\n }\n\n this.iceState.disconnected = false;\n }\n }\n\n /**\n * Set the iceState to disconnected and generates a timeout that waits for the\n * iceState to reconnect and then resolves. If the ice state is already\n * processing a reconnect, it immediately resolves. Rejects if the timeout\n * duration is reached.\n *\n * @returns {Promise<undefined>}\n * @public\n * @memberof ReconnectionManager\n */\n waitForIceReconnect() {\n if (!this.iceState.disconnected) {\n LoggerProxy.logger.log('ReconnectionManager:index#waitForIceReconnect --> waiting for ice reconnect');\n\n this.iceState.disconnected = true;\n\n return new Promise((resolve, reject) => {\n this.iceState.timer = setTimeout(() => {\n if (this.iceState.disconnected === false) {\n resolve();\n }\n else {\n this.iceState.disconnected = false;\n reject(new Error(`ice reconnection did not occur in ${this.iceState.timeoutDuration}ms`));\n }\n }, this.iceState.timeoutDuration);\n\n this.iceState.resolve = resolve;\n });\n }\n\n // return a resolved promise to prevent multiple catch executions of reconnect\n return Promise.resolve();\n }\n\n /**\n * @returns {undefined}\n * @public\n * @memberof ReconnectionManager\n */\n reset() {\n this.status = RECONNECTION.STATE.DEFAULT_STATUS;\n this.tryCount = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n this.rejoinAttempts = RECONNECTION.STATE.DEFAULT_TRY_COUNT;\n }\n\n /**\n * @returns {undefined}\n * @public\n * @memberof ReconnectionManager\n */\n cleanUp() {\n this.reset();\n this.meeting = null;\n }\n\n /**\n * @returns {Boolean}\n * @throws {ReconnectionError}\n * @private\n * @memberof ReconnectionManager\n */\n validate() {\n if (this.meeting.config.reconnection.enabled) {\n if (\n this.status === RECONNECTION.STATE.DEFAULT_STATUS ||\n this.status === RECONNECTION.STATE.COMPLETE\n ) {\n return true;\n }\n\n LoggerProxy.logger.info('ReconnectionManager:index#validate --> Reconnection already in progress.');\n\n throw new ReconnectInProgress('Reconnection already in progress.');\n }\n\n LoggerProxy.logger.info('ReconnectionManager:index#validate --> Reconnection is not enabled.');\n\n throw new ReconnectionError('Reconnection is not enabled.');\n }\n\n /**\n * Initiates a media reconnect for the active meeting\n * @param {Object} reconnectOptions\n * @param {boolean} [reconnectOptions.networkDisconnect=false] indicates if a network disconnect event happened\n * @param {boolean} [reconnectOptions.networkRetry=false] indicates if we are retrying the reconnect\n * @returns {Promise}\n * @public\n * @memberof ReconnectionManager\n */\n async reconnect({networkDisconnect = false, networkRetry = false} = {}) {\n LoggerProxy.logger.info(`ReconnectionManager:index#reconnect --> Reconnection start for meeting ${this.meeting.id}.`);\n // First, validate that we can reconnect, if not, it will throw an error\n try {\n this.validate();\n }\n catch (error) {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection unable to begin.', error);\n throw error;\n }\n\n if (!networkRetry) {\n // Only log START metrics on the initial reconnect\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Sending reconnect start metric.');\n Metrics.postEvent({\n event: eventType.MEDIA_RECONNECTING,\n meeting: this.meeting\n });\n }\n\n return this.executeReconnection({networkDisconnect})\n .then(() => {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection successful.');\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Sending reconnect success metric.');\n Metrics.postEvent({\n event: eventType.MEDIA_RECOVERED,\n meeting: this.meeting,\n data: {recoveredBy: reconnection.RECOVERED_BY_NEW}\n });\n })\n .catch((reconnectError) => {\n if (reconnectError instanceof NeedsRetryError) {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.');\n // Reset our reconnect status since we are looping back to the beginning\n this.status = RECONNECTION.STATE.DEFAULT_STATUS;\n\n // This is a network retry, so we should not log START metrics again\n return this.reconnect({networkDisconnect: true, networkRetry: true});\n }\n\n // Reconnect has failed\n LoggerProxy.logger.error('ReconnectionManager:index#reconnect --> Reconnection failed.', reconnectError.message);\n LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Sending reconnect abort metric.');\n\n const reconnectMetric = {\n event: eventType.CALL_ABORTED,\n meeting: this.meeting,\n data: {\n errors: [\n {\n category: errorObjects.category.expected,\n errorCode: 2008,\n fatal: true,\n name: errorObjects.name.mediaEngine,\n shownToUser: false\n }\n ]\n }\n };\n\n Metrics.postEvent(reconnectMetric);\n if (reconnectError instanceof NeedsRejoinError) {\n // send call aborded event with catogery as expected as we are trying to rejoin\n\n if (this.autoRejoinEnabled) {\n return this.rejoinMeeting(reconnectError.wasSharing);\n }\n }\n\n\n throw reconnectError;\n });\n }\n\n /**\n * @param {Object} reconnectOptions\n * @param {boolean} [reconnectOptions.networkDisconnect=false] indicates if a network disconnect event happened\n * @returns {Promise}\n * @throws {NeedsRetryError}\n * @private\n * @memberof ReconnectionManager\n */\n async executeReconnection({networkDisconnect = false}) {\n this.status = RECONNECTION.STATE.IN_PROGRESS;\n\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.');\n\n if (networkDisconnect) {\n try {\n await this.reconnectMercuryWebSocket();\n LoggerProxy.logger.error('ReconnectionManager:index#executeReconnection --> Websocket reconnected.', this.webex.internal.device.url);\n }\n catch (error) {\n LoggerProxy.logger.error('ReconnectionManager:index#executeReconnection --> Unable to reconnect to websocket, giving up.');\n this.status = RECONNECTION.STATE.FAILURE;\n throw (error);\n }\n }\n\n const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;\n\n try {\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Updating meeting data from server.');\n await this.webex.meetings.syncMeetings();\n }\n catch (syncError) {\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.', syncError);\n throw (new NeedsRetryError(syncError));\n }\n\n // TODO: try to improve this logic as the reconnection manager saves the instance of deleted meeting object\n // So that on rejoin it known what parametrs it was using\n if (!this.meeting || !this.webex.meetings.getMeetingByType(_ID_, this.meeting.id)) {\n LoggerProxy.logger.info('ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely ');\n\n throw new Error('Unable to rejoin a meeting already ended or inactive .');\n }\n\n LoggerProxy.logger.info(`ReconnectionManager:index#executeReconnection --> Current state of meeting is ${this.meeting.state}`);\n\n // If the meeting state was left, no longer reconnect media\n if (this.meeting.state === _LEFT_) {\n if (this.meeting.type === _CALL_) {\n throw new Error('Unable to rejoin a call in LEFT state.');\n }\n\n throw (new NeedsRejoinError({wasSharing}));\n }\n\n try {\n const media = await this.reconnectMedia();\n\n LoggerProxy.logger.log('ReconnectionManager:index#executeReconnection --> Media reestablished');\n this.status = RECONNECTION.STATE.COMPLETE;\n\n return media;\n }\n catch (error) {\n LoggerProxy.logger.error('ReconnectionManager:index#executeReconnection --> Media reestablishment failed');\n this.status = RECONNECTION.STATE.FAILURE;\n\n throw (error);\n }\n }\n\n /**\n * Rejoins a meeting after detecting the member was in a LEFT state\n *\n * @async\n * @param {boolean} wasSharing\n * @returns {Promise}\n */\n async rejoinMeeting(wasSharing = false) {\n try {\n LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> attemping meeting rejoin');\n const previousCorrelationId = this.meeting.correlationId;\n\n await this.meeting.join({rejoin: true});\n LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');\n\n RoapCollection.deleteSession(previousCorrelationId);\n\n if (wasSharing) {\n // Stop the share streams if user tried to rejoin\n Media.stopTracks(this.meeting.mediaProperties.shareTrack);\n this.meeting.isSharing = false;\n if (this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE) {\n this.meeting.shareStatus = SHARE_STATUS.NO_SHARE;\n }\n this.meeting.mediaProperties.mediaDirection.sendShare = false;\n Trigger.trigger(\n this.meeting,\n {\n file: 'reconnection-manager/index',\n function: 'rejoinMeeting'\n },\n EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,\n {\n reason: SHARE_STOPPED_REASON.MEETING_REJOIN\n }\n );\n }\n }\n catch (joinError) {\n this.rejoinAttempts += 1;\n if (this.rejoinAttempts <= this.maxRejoinAttempts) {\n LoggerProxy.logger.info(`ReconnectionManager:index#rejoinMeeting --> Unable to rejoin meeting, attempt #${this.rejoinAttempts}, retrying.`, joinError);\n this.rejoinMeeting();\n }\n else {\n LoggerProxy.logger.error('ReconnectionManager:index#rejoinMeeting --> Unable to rejoin meeting after max attempts.', joinError);\n Metrics.sendOperationalMetric(\n METRICS_OPERATIONAL_MEASURES.MEETING_MAX_REJOIN_FAILURE,\n {\n locus_id: this.meeting.locusUrl.split('/').pop(),\n reason: joinError.message,\n stack: joinError.stack\n }\n );\n this.status = RECONNECTION.STATE.FAILURE;\n throw joinError;\n }\n }\n\n try {\n await this.reconnectMedia();\n }\n catch (mediaError) {\n LoggerProxy.logger.error('ReconnectionManager:index#rejoinMeeting --> Unable to reestablish media after rejoining.', mediaError);\n throw mediaError;\n }\n }\n\n /**\n * @returns {Promise}\n * @private\n * @memberof ReconnectionManager\n */\n reconnectMedia() {\n LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media');\n\n ReconnectionManager.setupPeerConnection(this.meeting);\n\n return Media.attachMedia(this.meeting.mediaProperties, {\n meetingId: this.meeting.id,\n remoteQualityLevel: this.meeting.mediaProperties.remoteQualityLevel,\n enableRtx: this.meeting.config.enableRtx,\n enableExtmap: this.meeting.config.enableExtmap\n })\n .then((peerConnection) => this.meeting.setRemoteStream(peerConnection))\n .then(() => {\n LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> Sending ROAP media request');\n\n return this.meeting.roap\n .sendRoapMediaRequest({\n sdp: this.meeting.mediaProperties.peerConnection.sdp,\n roapSeq: this.meeting.roapSeq,\n meeting: this.meeting,\n reconnect: true\n });\n });\n }\n\n /**\n * Attempt to Reconnect Mercury Websocket\n * @returns {Promise}\n * @private\n * @memberof ReconnectionManager\n */\n async reconnectMercuryWebSocket() {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Reconnecting websocket.');\n // First, attempt to disconnect if we think we are already connected.\n if (this.webex.internal.mercury.connected) {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Disconnecting existing websocket.');\n try {\n await this.webex.internal.mercury.disconnect();\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Websocket disconnected successfully.');\n }\n catch (disconnectError) {\n // If we can't disconnect, the sdk is in such a bad state that reconnecting is not going to happen.\n LoggerProxy.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to disconnect from websocket, giving up.', disconnectError);\n throw disconnectError;\n }\n }\n\n try {\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Connecting websocket.');\n await this.webex.internal.mercury.connect();\n LoggerProxy.logger.info('ReconnectionManager:index#reconnectMercuryWebSocket --> Websocket connected successfully.');\n }\n catch (connectError) {\n LoggerProxy.logger.error('ReconnectionManager:index#reconnectMercuryWebSocket --> Unable to connect to websocket, giving up.', connectError);\n\n throw (connectError);\n }\n }\n\n /**\n * @param {Meeting} meeting\n * @returns {undefined}\n * @private\n * @memberof ReconnectionManager\n */\n static setupPeerConnection(meeting) {\n LoggerProxy.logger.log('ReconnectionManager:index#setupPeerConnection --> Begin resetting peer connection');\n // close pcs, unset to null and create a new one with out closing any streams\n PeerConnectionManager.close(meeting.mediaProperties.peerConnection);\n meeting.mediaProperties.unsetPeerConnection();\n meeting.mediaProperties.reInitiatePeerconnection();\n PeerConnectionManager.setPeerConnectionEvents(meeting);\n // update the peerconnection in the stats manager when ever we reconnect\n meeting.statsAnalyzer.updatePeerconnection(meeting.mediaProperties.peerConnection);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "1.146.1",
3
+ "version": "1.149.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "contributors": [
@@ -24,17 +24,17 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@babel/runtime-corejs2": "^7.14.8",
27
- "@webex/webex-core": "1.146.1",
28
- "@webex/internal-plugin-mercury": "1.146.1",
27
+ "@webex/webex-core": "1.149.0",
28
+ "@webex/internal-plugin-mercury": "1.149.0",
29
29
  "webrtc-adapter": "^7.7.0",
30
30
  "lodash": "^4.17.21",
31
31
  "uuid": "^3.3.2",
32
32
  "global": "^4.4.0",
33
- "@webex/common": "1.146.1",
33
+ "@webex/common": "1.149.0",
34
34
  "bowser": "^2.11.0",
35
35
  "sdp-transform": "^2.12.0",
36
36
  "readable-stream": "^3.6.0",
37
- "@webex/common-timers": "1.146.1",
37
+ "@webex/common-timers": "1.149.0",
38
38
  "btoa": "^1.2.1",
39
39
  "javascript-state-machine": "^3.1.0",
40
40
  "envify": "^4.1.0"
package/src/config.js CHANGED
@@ -85,6 +85,7 @@ export default {
85
85
  autoUploadLogs: true,
86
86
  enableRtx: true,
87
87
  receiveTranscription: false,
88
+ enableExtmap: false,
88
89
  experimental: {
89
90
  enableMediaNegotiatedEvent: false,
90
91
  enableUnifiedMeetings: false
package/src/constants.js CHANGED
@@ -185,7 +185,7 @@ export const MODERATOR_FALSE = false;
185
185
 
186
186
  // ******************** NUMBERS ********************
187
187
 
188
- export const INTENT_TO_JOIN = 2423005;
188
+ export const INTENT_TO_JOIN = [2423005, 2423006, 2423016, 2423017, 2423018];
189
189
  export const ICE_TIMEOUT = 2000;
190
190
  export const ICE_FAIL_TIMEOUT = 3000;
191
191
 
@@ -1220,6 +1220,7 @@ export const METRICS_OPERATIONAL_MEASURES = {
1220
1220
  SET_MEETING_QUALITY_FAILURE: 'js_sdk_set_meeting_quality_failures',
1221
1221
  STOP_FLOOR_REQUEST_FAILURE: 'js_sdk_stop_floor_request_failures',
1222
1222
  ADD_DIAL_IN_FAILURE: 'js_sdk_add_dial_in_failure',
1223
+ ADD_DIAL_OUT_FAILURE: 'js_sdk_add_dial_out_failure',
1223
1224
  UPDATE_MEDIA_FAILURE: 'js_sdk_update_media_failures',
1224
1225
  UNMUTE_AUDIO_FAILURE: 'js_sdk_unmute_audio_failures',
1225
1226
  UNMUTE_VIDEO_FAILURE: 'js_sdk_unmute_video_failures',
@@ -1232,3 +1233,12 @@ export const METRICS_OPERATIONAL_MEASURES = {
1232
1233
  UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',
1233
1234
  RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure'
1234
1235
  };
1236
+
1237
+ export const PSTN_STATUS = {
1238
+ JOINED: 'JOINED', // we have provisioned a pstn device, which can be used to connect
1239
+ CONNECTED: 'CONNECTED', // user is connected to audio with pstn device
1240
+ LEFT: 'LEFT', // user has disconnected from the pstn device
1241
+ TRANSFERRING: 'TRANSFERRING', // usually happens in dial-out after the CONNECTED state
1242
+ SUCCESS: 'SUCCESS', // happens after the transfer (TRANSFERRING) is successful
1243
+ UNKNOWN: '' // placeholder if we haven't been told what the status is
1244
+ };
@@ -71,13 +71,23 @@ Media.setLocalTrack = (enabled, track) => {
71
71
  * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH
72
72
  * @returns {Promise}
73
73
  */
74
- Media.reconnectMedia = (peerConnection, {meetingId, remoteQualityLevel, enableRtx}) => {
74
+ Media.reconnectMedia = (peerConnection, {
75
+ meetingId,
76
+ remoteQualityLevel,
77
+ enableRtx,
78
+ enableExtmap
79
+ }) => {
75
80
  if (peerConnection.connectionState === PEER_CONNECTION_STATE.CLOSED ||
76
81
  peerConnection.connectionState === PEER_CONNECTION_STATE.FAILED) {
77
82
  return Promise.reject(new ReconnectionError('Reinitiate peerconnection'));
78
83
  }
79
84
 
80
- return PeerConnectionManager.createOffer(peerConnection, {meetingId, remoteQualityLevel, enableRtx});
85
+ return PeerConnectionManager.createOffer(peerConnection, {
86
+ meetingId,
87
+ remoteQualityLevel,
88
+ enableRtx,
89
+ enableExtmap
90
+ });
81
91
  };
82
92
 
83
93
  /**
@@ -165,9 +175,18 @@ Media.checkTracks = (trackType, track, receiveTracks) => {
165
175
  * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH
166
176
  * @returns {Array} [peerConnection, ]
167
177
  */
168
- Media.attachMedia = (mediaProperties, {meetingId, remoteQualityLevel, enableRtx}) => {
178
+ Media.attachMedia = (mediaProperties, {
179
+ meetingId,
180
+ remoteQualityLevel,
181
+ enableRtx,
182
+ enableExtmap
183
+ }) => {
169
184
  const {
170
- mediaDirection, audioTrack, videoTrack, shareTrack, peerConnection
185
+ mediaDirection,
186
+ audioTrack,
187
+ videoTrack,
188
+ shareTrack,
189
+ peerConnection
171
190
  } = mediaProperties;
172
191
 
173
192
  let result = null;
@@ -188,7 +207,12 @@ Media.attachMedia = (mediaProperties, {meetingId, remoteQualityLevel, enableRtx}
188
207
  LoggerProxy.logger.info(`Media:index#attachMedia --> onnegotiationneeded#PeerConnection: ${event}`);
189
208
  };
190
209
 
191
- return PeerConnectionManager.createOffer(peerConnection, {meetingId, remoteQualityLevel, enableRtx});
210
+ return PeerConnectionManager.createOffer(peerConnection, {
211
+ meetingId,
212
+ remoteQualityLevel,
213
+ enableRtx,
214
+ enableExtmap
215
+ });
192
216
  };
193
217
 
194
218
  /**
@@ -199,9 +223,18 @@ Media.attachMedia = (mediaProperties, {meetingId, remoteQualityLevel, enableRtx}
199
223
  * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH
200
224
  * @returns {Promise}
201
225
  */
202
- Media.updateMedia = (mediaProperties, {meetingId, remoteQualityLevel, enableRtx}) => {
226
+ Media.updateMedia = (mediaProperties, {
227
+ meetingId,
228
+ remoteQualityLevel,
229
+ enableRtx,
230
+ enableExtmap
231
+ }) => {
203
232
  const {
204
- mediaDirection, audioTrack, videoTrack, shareTrack, peerConnection
233
+ mediaDirection,
234
+ audioTrack,
235
+ videoTrack,
236
+ shareTrack,
237
+ peerConnection
205
238
  } = mediaProperties;
206
239
 
207
240
  // update audio transceiver
@@ -231,7 +264,12 @@ Media.updateMedia = (mediaProperties, {meetingId, remoteQualityLevel, enableRtx}
231
264
  LoggerProxy.logger.info(`Media:index#updateMedia --> onnegotiationneeded#PeerConnection: ${event}`);
232
265
  };
233
266
 
234
- return PeerConnectionManager.createOffer(peerConnection, {meetingId, remoteQualityLevel, enableRtx});
267
+ return PeerConnectionManager.createOffer(peerConnection, {
268
+ meetingId,
269
+ remoteQualityLevel,
270
+ enableRtx,
271
+ enableExtmap
272
+ });
235
273
  };
236
274
 
237
275
  /**
@@ -269,10 +307,20 @@ Media.setTrackOnTransceiver = (transceiver, options) => {
269
307
  * @param {Object} options see #Media.setTrackOnTransceiver
270
308
  * @returns {Promise}
271
309
  */
272
- Media.updateTransceiver = ({meetingId, remoteQualityLevel, enableRtx}, peerConnection, transceiver, options) => {
310
+ Media.updateTransceiver = ({
311
+ meetingId,
312
+ remoteQualityLevel,
313
+ enableRtx,
314
+ enableExtmap
315
+ }, peerConnection, transceiver, options) => {
273
316
  Media.setTrackOnTransceiver(transceiver, options);
274
317
 
275
- return PeerConnectionManager.createOffer(peerConnection, {meetingId, remoteQualityLevel, enableRtx});
318
+ return PeerConnectionManager.createOffer(peerConnection, {
319
+ meetingId,
320
+ remoteQualityLevel,
321
+ enableRtx,
322
+ enableExtmap
323
+ });
276
324
  };
277
325
 
278
326
  /**
@@ -57,6 +57,7 @@ import {
57
57
  ONLINE,
58
58
  OFFLINE,
59
59
  PC_BAIL_TIMEOUT,
60
+ PSTN_STATUS,
60
61
  QUALITY_LEVELS,
61
62
  RECORDING_STATE,
62
63
  ROAP_SEQ_PRE,
@@ -710,13 +711,14 @@ export default class Meeting extends StatelessWebexPlugin {
710
711
  */
711
712
  this.floorGrantPending = false;
712
713
  /**
713
- * The latest status of the dial in device (can be "JOINED", "CONNECTED", "LEFT" or "")
714
+ * The latest status of the dial in device (can be "JOINED", "CONNECTED", "LEFT",
715
+ * "TRANSFERRING", "SUCCESS" or "")
714
716
  * @instance
715
717
  * @type {String}
716
718
  * @private
717
719
  * @memberof Meeting
718
720
  */
719
- this.dialInDeviceStatus = '';
721
+ this.dialInDeviceStatus = PSTN_STATUS.UNKNOWN;
720
722
  /**
721
723
  * the url for provisioned device used to dial in
722
724
  * @instance
@@ -725,6 +727,23 @@ export default class Meeting extends StatelessWebexPlugin {
725
727
  * @memberof Meeting
726
728
  */
727
729
  this.dialInUrl = '';
730
+ /**
731
+ * The latest status of the dial out device (can be "JOINED", "CONNECTED", "LEFT",
732
+ * "TRANSFERRING", "SUCCESS" or "")
733
+ * @instance
734
+ * @type {String}
735
+ * @private
736
+ * @memberof Meeting
737
+ */
738
+ this.dialOutDeviceStatus = PSTN_STATUS.UNKNOWN;
739
+ /**
740
+ * the url for provisioned device used to dial out
741
+ * @instance
742
+ * @type {String}
743
+ * @private
744
+ * @memberof Meeting
745
+ */
746
+ this.dialOutUrl = '';
728
747
  /**
729
748
  * @instance
730
749
  * @type {MediaMetrics}
@@ -1028,6 +1047,24 @@ export default class Meeting extends StatelessWebexPlugin {
1028
1047
  };
1029
1048
  }
1030
1049
 
1050
+ const joinRespTxStartAudio = this.getSendingMediaDelayDuration('audio');
1051
+
1052
+ if (joinRespTxStartAudio) {
1053
+ options.audioSetupDelay = {
1054
+ ...options.audioSetupDelay,
1055
+ joinRespTxStart: joinRespTxStartAudio
1056
+ };
1057
+ }
1058
+
1059
+ const joinRespTxStartVideo = this.getSendingMediaDelayDuration('video');
1060
+
1061
+ if (joinRespTxStartVideo) {
1062
+ options.videoSetupDelay = {
1063
+ ...options.videoSetupDelay,
1064
+ joinRespTxStart: joinRespTxStartVideo
1065
+ };
1066
+ }
1067
+
1031
1068
  if (options.type === MQA_STATS.CA_TYPE) {
1032
1069
  payload = Metrics.initMediaPayload(options.event, identifiers, options);
1033
1070
  }
@@ -1144,9 +1181,28 @@ export default class Meeting extends StatelessWebexPlugin {
1144
1181
  pstnUpdate(payload) {
1145
1182
  if (this.locusInfo.self) {
1146
1183
  const dialInPstnDevice = payload.newSelf?.pstnDevices.find((device) => device.url === this.dialInUrl);
1184
+ const dialOutPstnDevice = payload.newSelf?.pstnDevices.find((device) => device.url === this.dialOutUrl);
1185
+ let changed = false;
1147
1186
 
1148
1187
  if (dialInPstnDevice) {
1149
- this.dialInDeviceStatus = dialInPstnDevice.dialingStatus ?? dialInPstnDevice.state;
1188
+ const newStatus = dialInPstnDevice.dialingStatus ?? dialInPstnDevice.state;
1189
+
1190
+ if (newStatus !== this.dialInDeviceStatus) {
1191
+ this.dialInDeviceStatus = newStatus;
1192
+ changed = true;
1193
+ }
1194
+ }
1195
+
1196
+ if (dialOutPstnDevice) {
1197
+ const newStatus = dialOutPstnDevice.dialingStatus ?? dialOutPstnDevice.state;
1198
+
1199
+ if (newStatus !== this.dialOutDeviceStatus) {
1200
+ this.dialOutDeviceStatus = newStatus;
1201
+ changed = true;
1202
+ }
1203
+ }
1204
+
1205
+ if (changed) {
1150
1206
  Trigger.trigger(
1151
1207
  this,
1152
1208
  {
@@ -1157,7 +1213,11 @@ export default class Meeting extends StatelessWebexPlugin {
1157
1213
  {
1158
1214
  dialIn: {
1159
1215
  status: this.dialInDeviceStatus,
1160
- attendeeId: dialInPstnDevice.attendeeId
1216
+ attendeeId: dialInPstnDevice?.attendeeId
1217
+ },
1218
+ dialOut: {
1219
+ status: this.dialOutDeviceStatus,
1220
+ attendeeId: dialOutPstnDevice?.attendeeId
1161
1221
  }
1162
1222
  }
1163
1223
  );
@@ -3313,7 +3373,7 @@ export default class Meeting extends StatelessWebexPlugin {
3313
3373
  /**
3314
3374
  * Use phone for meeting audio
3315
3375
  * @param {String} phoneNumber If provided, it will dial-out using this number. If not provided, dial-in will be used
3316
- * @returns {Promise} Resolves once the dial-in or dial-out request has completed
3376
+ * @returns {Promise} Resolves once the dial-in or dial-out request has completed, or rejects if it failed
3317
3377
  * @public
3318
3378
  * @memberof Meeting
3319
3379
  */
@@ -3322,17 +3382,28 @@ export default class Meeting extends StatelessWebexPlugin {
3322
3382
  return this.dialInPstn();
3323
3383
  }
3324
3384
 
3325
- return Promise.reject(new Error('Dial-out is not supported yet'));
3385
+ return this.dialOutPstn(phoneNumber);
3386
+ }
3387
+
3388
+ /**
3389
+ * Determines if the given pstnStatus is in a state which implies the phone is provisioned
3390
+ * @param {String} pstnStatus
3391
+ * @returns {Boolean}
3392
+ * @private
3393
+ * @memberof Meeting
3394
+ */
3395
+ isPhoneProvisioned(pstnStatus) {
3396
+ return [PSTN_STATUS.JOINED, PSTN_STATUS.CONNECTED, PSTN_STATUS.SUCCESS].includes(pstnStatus);
3326
3397
  }
3327
3398
 
3328
3399
  /**
3329
3400
  * Enable dial-in for audio
3330
- * @returns {Promise} Resolves once the dial-in request has completed
3401
+ * @returns {Promise} Resolves once the dial-in request has completed, or rejects if it failed
3331
3402
  * @private
3332
3403
  * @memberof Meeting
3333
3404
  */
3334
3405
  dialInPstn() {
3335
- if (this.dialInDeviceStatus === 'CONNECTED' || this.dialInDeviceStatus === 'JOINED') return Promise.resolve(); // prevent multiple dial in devices from being provisioned
3406
+ if (this.isPhoneProvisioned(this.dialInDeviceStatus)) return Promise.resolve(); // prevent multiple dial in devices from being provisioned
3336
3407
 
3337
3408
  const {correlationId, locusUrl} = this;
3338
3409
 
@@ -3357,6 +3428,47 @@ export default class Meeting extends StatelessWebexPlugin {
3357
3428
  stack: error.stack
3358
3429
  }
3359
3430
  );
3431
+
3432
+ return Promise.reject(error);
3433
+ });
3434
+ }
3435
+
3436
+ /**
3437
+ * Enable dial-out for audio
3438
+ * @param {String} phoneNumber Phone number to dial out to
3439
+ * @returns {Promise} Resolves once the dial-out request has completed (it doesn't wait for the user to answer the phone), or rejects if it failed
3440
+ * @private
3441
+ * @memberof Meeting
3442
+ */
3443
+ dialOutPstn(phoneNumber) {
3444
+ if (this.isPhoneProvisioned(this.dialOutDeviceStatus)) return Promise.resolve(); // prevent multiple dial out devices from being provisioned
3445
+
3446
+ const {correlationId, locusUrl} = this;
3447
+
3448
+ if (!this.dialOutUrl) this.dialOutUrl = `dialout:///${uuid.v4()}`;
3449
+
3450
+ return this.meetingRequest.dialOut({
3451
+ correlationId,
3452
+ dialOutUrl: this.dialOutUrl,
3453
+ phoneNumber,
3454
+ locusUrl,
3455
+ clientUrl: this.deviceUrl
3456
+ }).then((res) => {
3457
+ this.locusInfo.onFullLocus(res.body.locus);
3458
+ }).catch((error) => {
3459
+ Metrics.sendOperationalMetric(
3460
+ METRICS_OPERATIONAL_MEASURES.ADD_DIAL_OUT_FAILURE,
3461
+ {
3462
+ correlation_id: this.correlationId,
3463
+ dial_out_url: this.dialOutUrl,
3464
+ locus_id: locusUrl.split('/').pop(),
3465
+ client_url: this.deviceUrl,
3466
+ reason: error.error?.message,
3467
+ stack: error.stack
3468
+ }
3469
+ );
3470
+
3471
+ return Promise.reject(error);
3360
3472
  });
3361
3473
  }
3362
3474
 
@@ -3368,13 +3480,14 @@ export default class Meeting extends StatelessWebexPlugin {
3368
3480
  * @returns {Promise}
3369
3481
  */
3370
3482
  disconnectPhoneAudio() {
3371
- if (this.dialInDeviceStatus === 'CONNECTED') {
3372
- return MeetingUtil.leavePstn(this, this.dialInUrl);
3373
- }
3374
-
3375
- // TODO: handle dial out
3376
-
3377
- return Promise.resolve();
3483
+ return Promise.all([
3484
+ this.isPhoneProvisioned(this.dialInDeviceStatus) ?
3485
+ MeetingUtil.disconnectPhoneAudio(this, this.dialInUrl) :
3486
+ Promise.resolve(),
3487
+ this.isPhoneProvisioned(this.dialOutDeviceStatus) ?
3488
+ MeetingUtil.disconnectPhoneAudio(this, this.dialOutUrl) :
3489
+ Promise.resolve()
3490
+ ]);
3378
3491
  }
3379
3492
 
3380
3493
  /**
@@ -3676,7 +3789,8 @@ export default class Meeting extends StatelessWebexPlugin {
3676
3789
  .then(() => Media.attachMedia(this.mediaProperties, {
3677
3790
  meetingId: this.id,
3678
3791
  remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
3679
- enableRtx: this.config.enableRtx
3792
+ enableRtx: this.config.enableRtx,
3793
+ enableExtmap: this.config.enableExtmap
3680
3794
  })
3681
3795
  .then((peerConnection) => this.getDevices().then((devices) => {
3682
3796
  MeetingUtil.handleDeviceLogging(devices);
@@ -3950,7 +4064,8 @@ export default class Meeting extends StatelessWebexPlugin {
3950
4064
  .then(() => Media.updateMedia(this.mediaProperties, {
3951
4065
  meetingId: this.id,
3952
4066
  remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
3953
- enableRtx: this.config.enableRtx
4067
+ enableRtx: this.config.enableRtx,
4068
+ enableExtmap: this.config.enableExtmap
3954
4069
  })
3955
4070
  .then((peerConnection) => {
3956
4071
  LoggerProxy.logger.info(`${LOG_HEADER} PeerConnection received from updateMedia, ${peerConnection}`);
@@ -4952,4 +5067,32 @@ export default class Meeting extends StatelessWebexPlugin {
4952
5067
 
4953
5068
  return (start && end) ? end - start : undefined;
4954
5069
  }
5070
+
5071
+ /**
5072
+ * @param {string} typeMedia 'audio' or 'video'
5073
+ * @returns {undefined}
5074
+ */
5075
+ setStartSendingMediaDelay(typeMedia) {
5076
+ this[`startSendingMediaDelay${typeMedia}`] = performance.now();
5077
+ this[`endSendingMediaDelay${typeMedia}`] = undefined;
5078
+ }
5079
+
5080
+ /**
5081
+ * @param {string} typeMedia 'audio' or 'video'
5082
+ * @returns {undefined}
5083
+ */
5084
+ setEndSendingMediaDelay(typeMedia) {
5085
+ this[`endSendingMediaDelay${typeMedia}`] = performance.now();
5086
+ }
5087
+
5088
+ /**
5089
+ * @param {string} typeMedia 'audio' or 'video'
5090
+ * @returns {string} duration between join response and first media tx
5091
+ */
5092
+ getSendingMediaDelayDuration(typeMedia) {
5093
+ const start = this[`startSendingMediaDelay${typeMedia}`];
5094
+ const end = this[`endSendingMediaDelay${typeMedia}`];
5095
+
5096
+ return (start && end) ? end - start : undefined;
5097
+ }
4955
5098
  }