@webex/plugin-meetings 3.0.0-beta.0 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/errors/webex-errors.js +5 -29
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/constants.js +15 -74
- package/dist/constants.js.map +1 -1
- package/dist/media/index.js +68 -213
- package/dist/media/index.js.map +1 -1
- package/dist/media/internal-media-core-wrapper.js +22 -0
- package/dist/media/internal-media-core-wrapper.js.map +1 -0
- package/dist/media/properties.js +20 -25
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +0 -27
- package/dist/media/util.js.map +1 -1
- package/dist/meeting/index.js +742 -500
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +1 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +3 -44
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +64 -5
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +24 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/members/index.js +68 -0
- package/dist/members/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +132 -0
- package/dist/multistream/mediaRequestManager.js.map +1 -0
- package/dist/multistream/multistreamMedia.js +116 -0
- package/dist/multistream/multistreamMedia.js.map +1 -0
- package/dist/multistream/receiveSlot.js +209 -0
- package/dist/multistream/receiveSlot.js.map +1 -0
- package/dist/multistream/receiveSlotManager.js +195 -0
- package/dist/multistream/receiveSlotManager.js.map +1 -0
- package/dist/multistream/remoteMedia.js +284 -0
- package/dist/multistream/remoteMedia.js.map +1 -0
- package/dist/multistream/remoteMediaGroup.js +243 -0
- package/dist/multistream/remoteMediaGroup.js.map +1 -0
- package/dist/multistream/remoteMediaManager.js +1113 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -0
- package/dist/reconnection-manager/index.js +109 -130
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +57 -240
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +2 -114
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +11 -5
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/global.js +2 -0
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js +39 -36
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/package.json +20 -19
- package/src/common/errors/webex-errors.js +0 -18
- package/src/constants.ts +139 -180
- package/src/media/index.js +60 -194
- package/src/media/internal-media-core-wrapper.ts +9 -0
- package/src/media/properties.js +19 -25
- package/src/media/util.js +0 -22
- package/src/meeting/index.js +622 -398
- package/src/meeting/request.js +1 -0
- package/src/meeting/util.js +3 -46
- package/src/meetings/index.js +30 -1
- package/src/meetings/util.js +23 -2
- package/src/members/index.js +48 -0
- package/src/multistream/mediaRequestManager.ts +164 -0
- package/src/multistream/multistreamMedia.ts +92 -0
- package/src/multistream/receiveSlot.ts +141 -0
- package/src/multistream/receiveSlotManager.ts +142 -0
- package/src/multistream/remoteMedia.ts +219 -0
- package/src/multistream/remoteMediaGroup.ts +224 -0
- package/src/multistream/remoteMediaManager.ts +911 -0
- package/src/reconnection-manager/index.js +40 -53
- package/src/roap/index.js +47 -207
- package/src/roap/request.js +1 -72
- package/src/roap/turnDiscovery.ts +12 -6
- package/src/statsAnalyzer/global.js +2 -0
- package/src/statsAnalyzer/index.js +32 -46
- package/test/integration/spec/journey.js +1 -1
- package/test/unit/spec/media/index.ts +223 -0
- package/test/unit/spec/media/properties.ts +73 -82
- package/test/unit/spec/meeting/effectsState.js +1 -3
- package/test/unit/spec/meeting/index.js +420 -228
- package/test/unit/spec/meeting/muteState.js +7 -0
- package/test/unit/spec/meeting/utils.js +61 -2
- package/test/unit/spec/meetings/index.js +0 -4
- package/test/unit/spec/members/index.js +164 -2
- package/test/unit/spec/multistream/mediaRequestManager.ts +511 -0
- package/test/unit/spec/multistream/receiveSlot.ts +104 -0
- package/test/unit/spec/multistream/receiveSlotManager.ts +173 -0
- package/test/unit/spec/multistream/remoteMedia.ts +217 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +396 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +1251 -0
- package/test/unit/spec/roap/index.ts +63 -35
- package/test/unit/spec/stats-analyzer/index.js +19 -22
- package/dist/peer-connection-manager/index.js +0 -794
- package/dist/peer-connection-manager/index.js.map +0 -1
- package/dist/roap/collection.js +0 -73
- package/dist/roap/collection.js.map +0 -1
- package/dist/roap/handler.js +0 -337
- package/dist/roap/handler.js.map +0 -1
- package/dist/roap/state.js +0 -164
- package/dist/roap/state.js.map +0 -1
- package/dist/roap/util.js +0 -102
- package/dist/roap/util.js.map +0 -1
- package/src/peer-connection-manager/index.js +0 -723
- package/src/roap/collection.js +0 -63
- package/src/roap/handler.js +0 -252
- package/src/roap/state.js +0 -149
- package/src/roap/util.js +0 -93
- package/test/unit/spec/peerconnection-manager/index.js +0 -188
- package/test/unit/spec/peerconnection-manager/utils.js +0 -48
- package/test/unit/spec/roap/util.js +0 -30
package/src/roap/collection.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import RoapStateMachine from '../roap/state';
|
|
2
|
-
|
|
3
|
-
/* eslint-disable */
|
|
4
|
-
const RoapCollection = {
|
|
5
|
-
sessions: {},
|
|
6
|
-
|
|
7
|
-
getSession(id) {
|
|
8
|
-
if (!this.sessions[id]) {
|
|
9
|
-
this.sessions[id] = {
|
|
10
|
-
activeSequences: 0,
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
return this.sessions[id];
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
deleteSession(id) {
|
|
17
|
-
if (this.getSession(id)) {
|
|
18
|
-
delete this.sessions[id];
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
getSessionSequence(id, seqId) {
|
|
23
|
-
const session = this.getSession(id);
|
|
24
|
-
if (!session[seqId]) {
|
|
25
|
-
session[seqId] = {
|
|
26
|
-
state: RoapStateMachine.createState(),
|
|
27
|
-
finished: false,
|
|
28
|
-
};
|
|
29
|
-
session.activeSequences += 1;
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
return session[seqId];
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
deleteSessionSequence(id, seqId) {
|
|
36
|
-
const seq = this.getSessionSequence(id, seqId);
|
|
37
|
-
if (seq) {
|
|
38
|
-
if (!seq.finished) {
|
|
39
|
-
session.activeSequences -= 1;
|
|
40
|
-
}
|
|
41
|
-
delete this.sessions[id][seqId];
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
isBusy(id) {
|
|
46
|
-
const session = this.getSession(id);
|
|
47
|
-
if (!session) return false;
|
|
48
|
-
|
|
49
|
-
return session.activeSequences > 0;
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
onSessionSequenceFinish(id, seqId) {
|
|
53
|
-
const session = this.getSession(id);
|
|
54
|
-
const seq = session[seqId];
|
|
55
|
-
if (seq && !seq.finished) {
|
|
56
|
-
seq.finished = true;
|
|
57
|
-
session.activeSequences -= 1;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export default RoapCollection;
|
package/src/roap/handler.js
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
/* no-param-reassign */
|
|
2
|
-
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
3
|
-
|
|
4
|
-
import LoggerProxy from '../common/logs/logger-proxy';
|
|
5
|
-
import {ROAP, _OFFER_} from '../constants';
|
|
6
|
-
import Metrics from '../metrics';
|
|
7
|
-
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
8
|
-
|
|
9
|
-
import RoapUtil from './util';
|
|
10
|
-
import RoapCollection from './collection';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const checkForAndHandleErrors = (action, meeting, correlationId) => {
|
|
14
|
-
if (action && action.type) {
|
|
15
|
-
if (action.msg && action.msg.messageType && action.msg.errorType) {
|
|
16
|
-
if (RoapUtil.findError(action.msg.messageType, action.msg.errorType, action.type)) {
|
|
17
|
-
RoapUtil.handleError(meeting.mediaProperties.peerConnection)
|
|
18
|
-
.then((res) => {
|
|
19
|
-
if (res) {
|
|
20
|
-
RoapCollection.deleteSessionSequence(correlationId, action.msg.seq);
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
.catch((err) => {
|
|
24
|
-
LoggerProxy.logger.warn(`Roap:handler#checkForAndHandleErrors --> Cannot reset the peer connection with error: ${err}`);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
if (!RoapUtil.ensureMeeting(meeting, action.type)) {
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return false;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const compareWithLastRoapMessage = (lastRoapMessage, currentRoapMessage) => lastRoapMessage?.msg?.seq === currentRoapMessage.msg.seq && lastRoapMessage?.msg?.messageType === currentRoapMessage.msg.messageType;
|
|
39
|
-
|
|
40
|
-
const handleSessionStep = ({
|
|
41
|
-
roap, session, locusUrl, correlationId
|
|
42
|
-
}) => {
|
|
43
|
-
const {seq: sequenceId, messageType} = roap.msg;
|
|
44
|
-
|
|
45
|
-
if (session.OFFER && messageType === _OFFER_) {
|
|
46
|
-
session.GLARE_OFFER = roap.msg;
|
|
47
|
-
session.GLARE_OFFER.remote = !!roap.remote;
|
|
48
|
-
const metricName = BEHAVIORAL_METRICS.ROAP_GLARE_CONDITION;
|
|
49
|
-
const data = {
|
|
50
|
-
correlation_id: correlationId,
|
|
51
|
-
locus_id: locusUrl.split('/').pop(),
|
|
52
|
-
sequence: sequenceId
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
Metrics.sendBehavioralMetric(metricName, data);
|
|
56
|
-
|
|
57
|
-
LoggerProxy.logger.warn(`Roap:handler#handleSessionStep --> Glare condition occurred with new mercury event, sequenceId: ${sequenceId}`);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
LoggerProxy.logger.info(`Roap:handler#handleSessionStep --> Save OFFER/ANSWER seq:${sequenceId} new mercury event ${messageType}local state: ${JSON.stringify(session.state.state, null, 2)}`);
|
|
61
|
-
session[messageType] = roap.msg;
|
|
62
|
-
session[messageType].remote = !!roap.remote;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @class RoapHandler
|
|
68
|
-
*/
|
|
69
|
-
export default class RoapHandler extends StatelessWebexPlugin {
|
|
70
|
-
constructor(attrs, options, roapOk, roapAnswer, roapFinished) {
|
|
71
|
-
super({}, options);
|
|
72
|
-
this.attrs = attrs;
|
|
73
|
-
this.options = options;
|
|
74
|
-
this.roapOk = roapOk;
|
|
75
|
-
this.roapFinished = roapFinished;
|
|
76
|
-
this.roapAnswer = roapAnswer;
|
|
77
|
-
this.lastRoapMessage = null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
*
|
|
82
|
-
* @param {Object} session
|
|
83
|
-
* @param {Meeting} meeting
|
|
84
|
-
* @param {Object} action
|
|
85
|
-
* @returns {null}
|
|
86
|
-
*/
|
|
87
|
-
perform(session, meeting, action) {
|
|
88
|
-
switch (session.state.state) {
|
|
89
|
-
case ROAP.ROAP_STATE.INIT:
|
|
90
|
-
this.roapFinished(meeting.correlationId, action.msg.seq);
|
|
91
|
-
break;
|
|
92
|
-
|
|
93
|
-
// TODO: (important )handle roap state for sending offers as well
|
|
94
|
-
// case ROAP.ROAP_STATE.WAIT_RX_OFFER:
|
|
95
|
-
// case ROAP.ROAP_STATE.WAIT_RX_ANSWER:
|
|
96
|
-
// case ROAP.ROAP_STATE.WAIT_RX_OK:
|
|
97
|
-
case ROAP.ROAP_STATE.WAIT_TX_ANSWER:
|
|
98
|
-
// eslint-disable-next-line no-warning-comments
|
|
99
|
-
// TODO: sometime the you get an answer while you are creating an offer so SKIP
|
|
100
|
-
// Server will send the mercury event comes back
|
|
101
|
-
if (RoapUtil.shouldHandleMedia(meeting)) {
|
|
102
|
-
RoapUtil.updatePeerConnection(meeting, session)
|
|
103
|
-
.then((answerSdps) => {
|
|
104
|
-
this.roapAnswer({
|
|
105
|
-
mediaId: meeting.mediaId,
|
|
106
|
-
sdps: answerSdps,
|
|
107
|
-
seq: session.OFFER.seq,
|
|
108
|
-
correlationId: meeting.correlationId,
|
|
109
|
-
audioMuted: meeting.isAudioMuted(),
|
|
110
|
-
videoMuted: meeting.isVideoMuted()
|
|
111
|
-
});
|
|
112
|
-
})
|
|
113
|
-
.catch((error) => {
|
|
114
|
-
const metricName = BEHAVIORAL_METRICS.ROAP_ANSWER_FAILURE;
|
|
115
|
-
const data = {
|
|
116
|
-
correlation_id: meeting.correlationId,
|
|
117
|
-
locus_id: meeting.locusUrl.split('/').pop(),
|
|
118
|
-
reason: error.message,
|
|
119
|
-
stack: error.stack
|
|
120
|
-
};
|
|
121
|
-
const metadata = {
|
|
122
|
-
type: error.name
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
Metrics.sendBehavioralMetric(metricName, data, metadata);
|
|
126
|
-
LoggerProxy.logger.error(`Roap:handler#perform --> Error occured during wait receive answer, continuing, ${error}`);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
break;
|
|
130
|
-
case ROAP.ROAP_STATE.WAIT_TX_OK:
|
|
131
|
-
if (!RoapUtil.shouldHandleMedia(meeting)) {
|
|
132
|
-
RoapUtil.setRemoteDescription(meeting, session).then((res) => {
|
|
133
|
-
this.roapOk(res);
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
break;
|
|
137
|
-
// case ROAP.ROAP_STATE.IDLE_LOCAL_OFFER:
|
|
138
|
-
case ROAP.ROAP_STATE.ERROR:
|
|
139
|
-
LoggerProxy.logger.error(`Roap:handler#perform --> Roap State ERROR for session: ${session}`);
|
|
140
|
-
break;
|
|
141
|
-
case ROAP.ROAP_STATE.GLARE:
|
|
142
|
-
session.GLARE_OFFER.tieBreaker = session.GLARE_OFFER.tieBreaker || 0;
|
|
143
|
-
session.OFFER.tieBreaker = session.OFFER.tieBreaker || 0;
|
|
144
|
-
LoggerProxy.logger.warn('Roap:handler#perform --> Roap State resolved the GLARE condition.');
|
|
145
|
-
if (session.GLARE_OFFER.tieBreaker < session.OFFER.tieBreaker) {
|
|
146
|
-
// 2
|
|
147
|
-
LoggerProxy.logger.log('Roap:handler#perform --> Roap State local offer won after GLARE.');
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
LoggerProxy.logger.log('Roap:handler#perform --> Roap State remote offer won after GLARE.');
|
|
151
|
-
}
|
|
152
|
-
session.state.step(ROAP.ROAP_SIGNAL.GLARE_RESOLVED, meeting, action);
|
|
153
|
-
this.perform(session, meeting);
|
|
154
|
-
break;
|
|
155
|
-
default:
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
*
|
|
162
|
-
* @param {String} signal
|
|
163
|
-
* @param {Object} session
|
|
164
|
-
* @param {Object} action
|
|
165
|
-
* @param {Meeting} meeting
|
|
166
|
-
* @param {String} prefix
|
|
167
|
-
* @returns {null}
|
|
168
|
-
*/
|
|
169
|
-
execute(signal, session, action, meeting, prefix) {
|
|
170
|
-
if (session && session.state) {
|
|
171
|
-
handleSessionStep({
|
|
172
|
-
roap: action,
|
|
173
|
-
locusUrl: meeting.locusUrl,
|
|
174
|
-
correlationId: meeting.correlationId,
|
|
175
|
-
session
|
|
176
|
-
});
|
|
177
|
-
signal = ROAP.ROAP_SIGNAL[`${prefix}${action.msg.messageType}`];
|
|
178
|
-
session.state.step(signal, meeting, action);
|
|
179
|
-
this.perform(session, meeting, action);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
*
|
|
185
|
-
* @param {Object} session
|
|
186
|
-
* @param {Object} action
|
|
187
|
-
* @param {Meeting} meeting
|
|
188
|
-
* @param {String} correlationId
|
|
189
|
-
* @returns {Boolean}
|
|
190
|
-
*/
|
|
191
|
-
handleAction(session, action, meeting, correlationId) {
|
|
192
|
-
let signal;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
switch (action.type) {
|
|
196
|
-
case ROAP.RECEIVE_ROAP_MSG:
|
|
197
|
-
LoggerProxy.logger.log(`Roap:handler#handleAction --> RECEIVE_ROAP_MSG event captured, reciving a roap message : ${JSON.stringify(action)}`);
|
|
198
|
-
if (compareWithLastRoapMessage(this.lastRoapMessage, action)) {
|
|
199
|
-
LoggerProxy.logger.warn(`Roap:handler#handleAction --> duplicate roap offer from server: ${action.msg.seq}`);
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
this.lastRoapMessage = action;
|
|
203
|
-
action.remote = true;
|
|
204
|
-
this.execute(signal, session, action, meeting, ROAP.RX_);
|
|
205
|
-
}
|
|
206
|
-
break;
|
|
207
|
-
case ROAP.SEND_ROAP_MSG:
|
|
208
|
-
LoggerProxy.logger.log(`Roap:handler#handleAction --> SEND_ROAP_MSG event captured, sending roap message ${JSON.stringify(action)}`);
|
|
209
|
-
|
|
210
|
-
action.local = true;
|
|
211
|
-
this.execute(signal, session, action, meeting, ROAP.TX_);
|
|
212
|
-
break;
|
|
213
|
-
case ROAP.SEND_ROAP_MSG_SUCCESS:
|
|
214
|
-
// NOTE: When server send back an answer via mercury the
|
|
215
|
-
// remote SDP is already saved sent and ok message is sent back
|
|
216
|
-
// We dont have to indicate the roapHandler about the RX_ANSWER via SEND_ROAP_MSG_SUCCESS
|
|
217
|
-
break;
|
|
218
|
-
case ROAP.RECEIVE_CALL_LEAVE:
|
|
219
|
-
RoapCollection.deleteSession(correlationId);
|
|
220
|
-
LoggerProxy.logger.log(`Roap:handler#handleAction --> RECEIVE_CALL_LEAVE event captured, cleaning up the RoapHandler for correlationId: ${correlationId}`); break;
|
|
221
|
-
case ROAP.RESET_ROAP_STATE:
|
|
222
|
-
RoapCollection.deleteSessionSequence(correlationId, action.msg.seq);
|
|
223
|
-
LoggerProxy.logger.log(`Roap:handler#handleAction --> RESET_ROAP_STATE event captured, resetting the RoapHandler state based on sequenceId: ${action.msg.seq}`); break;
|
|
224
|
-
default:
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
*
|
|
233
|
-
* @param {Object} action
|
|
234
|
-
* @returns {Boolean}
|
|
235
|
-
*/
|
|
236
|
-
submit(action) {
|
|
237
|
-
const {correlationId} = action;
|
|
238
|
-
let {seq} = action;
|
|
239
|
-
|
|
240
|
-
if (!seq && action.msg) {
|
|
241
|
-
seq = action.msg.seq;
|
|
242
|
-
}
|
|
243
|
-
const session = RoapCollection.getSessionSequence(correlationId, seq);
|
|
244
|
-
const meeting = this.webex.meetings.meetingCollection.getByKey('correlationId', correlationId);
|
|
245
|
-
|
|
246
|
-
if (checkForAndHandleErrors(action, meeting, correlationId)) {
|
|
247
|
-
return true;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return this.handleAction(session, action, meeting, correlationId);
|
|
251
|
-
}
|
|
252
|
-
}
|
package/src/roap/state.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import StateMachine from 'javascript-state-machine';
|
|
2
|
-
|
|
3
|
-
import LoggerProxy from '../common/logs/logger-proxy';
|
|
4
|
-
import {ROAP, _OFFER_, _ANSWER_, _REQUESTED_} from '../constants';
|
|
5
|
-
|
|
6
|
-
const shouldStep = (roap, meeting) => {
|
|
7
|
-
const {messageType} = roap.msg;
|
|
8
|
-
|
|
9
|
-
if (meeting) {
|
|
10
|
-
if (messageType === _OFFER_ && roap.remote && meeting.shareStatus === _REQUESTED_) {
|
|
11
|
-
// The peer-connection is waiting for answer but got an offer Reset. Try to
|
|
12
|
-
// send the offer later after you accept the answer
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
// Assuming the mercury event has come first before the response for the event
|
|
16
|
-
// we have to wait for the response and trigger the ROAP request later on
|
|
17
|
-
if (!meeting.mediaProperties.peerConnection && messageType === _ANSWER_) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
LoggerProxy.logger.log('Roap:state#shouldStep --> RoapStateMachine: PeerConnectionState, ', meeting.mediaProperties.peerConnection.signalingState);
|
|
22
|
-
LoggerProxy.logger.log('Roap:state#shouldStep --> RoapStateMachine: success save proceeding with transition, ', roap.msg);
|
|
23
|
-
|
|
24
|
-
return true;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const handleTransition = (value, signal, meeting) => {
|
|
28
|
-
LoggerProxy.logger.log(`Roap:state#handleTransition --> current ${value} to ${signal}`);
|
|
29
|
-
|
|
30
|
-
switch (value) {
|
|
31
|
-
case ROAP.ROAP_STATE.INIT:
|
|
32
|
-
if (signal === ROAP.ROAP_SIGNAL.RX_OFFER) {
|
|
33
|
-
return ROAP.ROAP_STATE.WAIT_TX_ANSWER;
|
|
34
|
-
}
|
|
35
|
-
if (signal === ROAP.ROAP_SIGNAL.TX_OFFER) {
|
|
36
|
-
return ROAP.ROAP_STATE.WAIT_RX_ANSWER;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return value;
|
|
40
|
-
|
|
41
|
-
case ROAP.ROAP_STATE.WAIT_RX_OFFER:
|
|
42
|
-
return value;
|
|
43
|
-
|
|
44
|
-
case ROAP.ROAP_STATE.WAIT_RX_ANSWER:
|
|
45
|
-
if (signal === ROAP.ROAP_SIGNAL.RX_ANSWER) {
|
|
46
|
-
// There is a race condition where the /call response comes after mercury event from the server
|
|
47
|
-
// As mercury sends roap event if it didnt get back a response. We can send the roap ok after that
|
|
48
|
-
if (meeting.mediaId) {
|
|
49
|
-
return ROAP.ROAP_STATE.WAIT_TX_OK;
|
|
50
|
-
}
|
|
51
|
-
LoggerProxy.logger.error('Roap:state#handleTransition --> Race Condition no mediaId, continuing.');
|
|
52
|
-
|
|
53
|
-
return value;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (signal === ROAP.ROAP_SIGNAL.RX_OFFER) {
|
|
57
|
-
return ROAP.ROAP_STATE.GLARE;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return value;
|
|
61
|
-
|
|
62
|
-
case ROAP.ROAP_STATE.WAIT_TX_OFFER:
|
|
63
|
-
return value;
|
|
64
|
-
|
|
65
|
-
case ROAP.ROAP_STATE.WAIT_TX_ANSWER:
|
|
66
|
-
if (signal === ROAP.ROAP_SIGNAL.TX_ANSWER) {
|
|
67
|
-
return ROAP.ROAP_STATE.WAIT_RX_OK;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return value;
|
|
71
|
-
|
|
72
|
-
case ROAP.ROAP_STATE.WAIT_TX_OK:
|
|
73
|
-
if (signal === ROAP.ROAP_SIGNAL.TX_OK) {
|
|
74
|
-
return ROAP.ROAP_STATE.INIT;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return value;
|
|
78
|
-
|
|
79
|
-
case ROAP.ROAP_STATE.WAIT_RX_OK:
|
|
80
|
-
if (signal === ROAP.ROAP_SIGNAL.RX_OK) {
|
|
81
|
-
return ROAP.ROAP_STATE.INIT;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return value;
|
|
85
|
-
|
|
86
|
-
case ROAP.ROAP_STATE.ERROR:
|
|
87
|
-
// eslint-disable-next-line no-warning-comments
|
|
88
|
-
// TODO: resolve error state. Add a signal constant and handle the cleanup
|
|
89
|
-
return ROAP.ROAP_STATE.INIT;
|
|
90
|
-
|
|
91
|
-
case ROAP.ROAP_STATE.GLARE:
|
|
92
|
-
return ROAP.ROAP_STATE.WAIT_RX_ANSWER;
|
|
93
|
-
default:
|
|
94
|
-
return value;
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const RoapStateMachine = {
|
|
99
|
-
/**
|
|
100
|
-
* @param {Roap} roapRef
|
|
101
|
-
* initializes the state machine
|
|
102
|
-
* @returns {StateMachine} an instance of a state machine
|
|
103
|
-
*/
|
|
104
|
-
createState() {
|
|
105
|
-
const RoapState = StateMachine.factory({
|
|
106
|
-
init: ROAP.ROAP_STATE.INIT,
|
|
107
|
-
transitions: [
|
|
108
|
-
{
|
|
109
|
-
name: ROAP.ROAP_TRANSITIONS.STEP,
|
|
110
|
-
from: '*',
|
|
111
|
-
/**
|
|
112
|
-
* Method to handle the transitions between states
|
|
113
|
-
* @param {String} signal
|
|
114
|
-
* @param {Meeting} meeting instance of a Meeting
|
|
115
|
-
* @param {Object} roap
|
|
116
|
-
* @returns {String} new state value
|
|
117
|
-
*/
|
|
118
|
-
to(signal, meeting, roap) {
|
|
119
|
-
const value = this.state;
|
|
120
|
-
|
|
121
|
-
if (!shouldStep(roap, meeting)) {
|
|
122
|
-
return value;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return handleTransition(value, signal, meeting);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
],
|
|
129
|
-
methods: {
|
|
130
|
-
/**
|
|
131
|
-
* Event that fires after we've transitioned to a new state
|
|
132
|
-
* @param {Object} transition
|
|
133
|
-
* @returns {null}
|
|
134
|
-
*/
|
|
135
|
-
onAfterStep(transition) {
|
|
136
|
-
LoggerProxy.logger.log(
|
|
137
|
-
`Roap:state#onAfterStep --> RoapStateMachine->onAfterStep#fired! State changed from '${transition.from}' to '${
|
|
138
|
-
transition.to
|
|
139
|
-
}' with transition '${transition.transition}''.`
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
return new RoapState();
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export default RoapStateMachine;
|
package/src/roap/util.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import PeerConnectionManager from '../peer-connection-manager';
|
|
3
|
-
import {
|
|
4
|
-
_ANSWER_,
|
|
5
|
-
_ERROR_,
|
|
6
|
-
_CONFLICT_,
|
|
7
|
-
ROAP,
|
|
8
|
-
SDP
|
|
9
|
-
} from '../constants';
|
|
10
|
-
import LoggerProxy from '../common/logs/logger-proxy';
|
|
11
|
-
import ParameterError from '../common/errors/parameter';
|
|
12
|
-
|
|
13
|
-
const RoapUtil = {};
|
|
14
|
-
const ROAP_ANSWER = _ANSWER_.toLowerCase();
|
|
15
|
-
|
|
16
|
-
RoapUtil.shouldHandleMedia = (meeting) => {
|
|
17
|
-
const offer =
|
|
18
|
-
meeting.mediaProperties.peerConnection &&
|
|
19
|
-
meeting.mediaProperties.peerConnection.signalingState === SDP.HAVE_LOCAL_OFFER;
|
|
20
|
-
|
|
21
|
-
if (offer) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return true;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
RoapUtil.handleError = (pc) =>
|
|
29
|
-
PeerConnectionManager.rollBackLocalDescription({peerConnection: pc})
|
|
30
|
-
.then(() => Promise.resolve(true))
|
|
31
|
-
.catch((err) => {
|
|
32
|
-
LoggerProxy.logger.error(`Roap:util#handleError --> ${err}`);
|
|
33
|
-
|
|
34
|
-
return Promise.reject(err);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
RoapUtil.findError = (messageType, errorType, type) =>
|
|
38
|
-
(type === ROAP.RECEIVE_ROAP_MSG || type === ROAP.SEND_ROAP_MSG) && messageType === _ERROR_ && errorType === _CONFLICT_;
|
|
39
|
-
|
|
40
|
-
RoapUtil.ensureMeeting = (meeting, type) => {
|
|
41
|
-
if (type === ROAP.RECEIVE_ROAP_MSG || type === ROAP.SEND_ROAP_MSG || type === ROAP.SEND_ROAP_MSG_SUCCESS) {
|
|
42
|
-
if (!meeting) {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return true;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
RoapUtil.updatePeerConnection = (meeting, session) => PeerConnectionManager.updatePeerConnection({
|
|
51
|
-
offerSdp: session.OFFER.sdps,
|
|
52
|
-
peerConnection: meeting.mediaProperties.peerConnection
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
meetingId: meeting.id,
|
|
56
|
-
remoteQualityLevel: meeting.mediaProperties.remoteQualityLevel
|
|
57
|
-
})
|
|
58
|
-
.then((res) => {
|
|
59
|
-
meeting.roap.lastRoapOffer = session.OFFER.sdps;
|
|
60
|
-
|
|
61
|
-
return res;
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
RoapUtil.setRemoteDescription = (meeting, session) => {
|
|
66
|
-
LoggerProxy.logger.info(`Roap:util#setRemoteDescription --> Transmit WAIT_TX_OK, correlationId: ${meeting.correlationId}`);
|
|
67
|
-
if (!(meeting && (meeting.mediaProperties.peerConnection))) {
|
|
68
|
-
LoggerProxy.logger.error(`Roap:util#setRemoteDescription --> DANGER no media or screen peer connection, correlationId: ${meeting.correlationId}`);
|
|
69
|
-
|
|
70
|
-
return Promise.reject(new ParameterError('Must provide a media or screen peer connection'));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return PeerConnectionManager.setRemoteSessionDetails(
|
|
74
|
-
meeting.mediaProperties.peerConnection,
|
|
75
|
-
ROAP_ANSWER,
|
|
76
|
-
session.ANSWER.sdps[0],
|
|
77
|
-
meeting.id
|
|
78
|
-
).then(() => {
|
|
79
|
-
LoggerProxy.logger.info(`Roap:util#setRemoteDescription --> Success for correlationId: ${meeting.correlationId}`);
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
seq: session.ANSWER.seq,
|
|
83
|
-
mediaId: meeting.mediaId,
|
|
84
|
-
correlationId: meeting.correlationId
|
|
85
|
-
};
|
|
86
|
-
})
|
|
87
|
-
.catch((err) => {
|
|
88
|
-
LoggerProxy.logger.error(`Roap:util#setRemoteDescription --> ${err}`);
|
|
89
|
-
throw err;
|
|
90
|
-
});
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export default RoapUtil;
|