|
|
@@ -11,6 +11,13 @@ var XMPPEvents = require("../../service/xmpp/XMPPEvents");
|
|
11
|
11
|
var RTCBrowserType = require("../RTC/RTCBrowserType");
|
|
12
|
12
|
var RTC = require("../RTC/RTC");
|
|
13
|
13
|
|
|
|
14
|
+/**
|
|
|
15
|
+ * Constant tells how long we're going to wait for IQ response, before timeout
|
|
|
16
|
+ * error is triggered.
|
|
|
17
|
+ * @type {number}
|
|
|
18
|
+ */
|
|
|
19
|
+const IQ_TIMEOUT = 10000;
|
|
|
20
|
+
|
|
14
|
21
|
// Jingle stuff
|
|
15
|
22
|
function JingleSessionPC(me, sid, connection, service) {
|
|
16
|
23
|
JingleSession.call(this, me, sid, connection, service);
|
|
|
@@ -238,15 +245,8 @@ JingleSessionPC.prototype.accept = function () {
|
|
238
|
245
|
ack.source = 'answer';
|
|
239
|
246
|
$(document).trigger('ack.jingle', [self.sid, ack]);
|
|
240
|
247
|
},
|
|
241
|
|
- function (stanza) {
|
|
242
|
|
- var error = ($(stanza).find('error').length) ? {
|
|
243
|
|
- code: $(stanza).find('error').attr('code'),
|
|
244
|
|
- reason: $(stanza).find('error :first')[0].tagName
|
|
245
|
|
- }:{};
|
|
246
|
|
- error.source = 'answer';
|
|
247
|
|
- JingleSessionPC.onJingleError(self.sid, error);
|
|
248
|
|
- },
|
|
249
|
|
- 10000);
|
|
|
248
|
+ self.newJingleErrorHandler(accept),
|
|
|
249
|
+ IQ_TIMEOUT);
|
|
250
|
250
|
},
|
|
251
|
251
|
function (e) {
|
|
252
|
252
|
logger.error('setLocalDescription failed', e);
|
|
|
@@ -323,24 +323,12 @@ JingleSessionPC.prototype.sendIceCandidate = function (candidate) {
|
|
323
|
323
|
init,
|
|
324
|
324
|
self.initiator == self.me ? 'initiator' : 'responder',
|
|
325
|
325
|
ssrc);
|
|
326
|
|
- self.connection.sendIQ(init,
|
|
327
|
|
- function () {
|
|
328
|
|
- //logger.log('session initiate ack');
|
|
329
|
|
- var ack = {};
|
|
330
|
|
- ack.source = 'offer';
|
|
331
|
|
- $(document).trigger('ack.jingle', [self.sid, ack]);
|
|
332
|
|
- },
|
|
333
|
|
- function (stanza) {
|
|
|
326
|
+ self.connection.sendIQ(init, null,
|
|
|
327
|
+ self.newJingleErrorHandler(init, function (error) {
|
|
334
|
328
|
self.state = 'error';
|
|
335
|
329
|
self.peerconnection.close();
|
|
336
|
|
- var error = ($(stanza).find('error').length) ? {
|
|
337
|
|
- code: $(stanza).find('error').attr('code'),
|
|
338
|
|
- reason: $(stanza).find('error :first')[0].tagName,
|
|
339
|
|
- }:{};
|
|
340
|
|
- error.source = 'offer';
|
|
341
|
|
- JingleSessionPC.onJingleError(self.sid, error);
|
|
342
|
|
- },
|
|
343
|
|
- 10000);
|
|
|
330
|
+ }),
|
|
|
331
|
+ IQ_TIMEOUT);
|
|
344
|
332
|
};
|
|
345
|
333
|
sendJingle();
|
|
346
|
334
|
}
|
|
|
@@ -392,21 +380,8 @@ JingleSessionPC.prototype.sendIceCandidates = function (candidates) {
|
|
392
|
380
|
}
|
|
393
|
381
|
// might merge last-candidate notification into this, but it is called alot later. See webrtc issue #2340
|
|
394
|
382
|
//logger.log('was this the last candidate', this.lasticecandidate);
|
|
395
|
|
- this.connection.sendIQ(cand,
|
|
396
|
|
- function () {
|
|
397
|
|
- var ack = {};
|
|
398
|
|
- ack.source = 'transportinfo';
|
|
399
|
|
- $(document).trigger('ack.jingle', [this.sid, ack]);
|
|
400
|
|
- },
|
|
401
|
|
- function (stanza) {
|
|
402
|
|
- var error = ($(stanza).find('error').length) ? {
|
|
403
|
|
- code: $(stanza).find('error').attr('code'),
|
|
404
|
|
- reason: $(stanza).find('error :first')[0].tagName,
|
|
405
|
|
- }:{};
|
|
406
|
|
- error.source = 'transportinfo';
|
|
407
|
|
- JingleSessionPC.onJingleError(this.sid, error);
|
|
408
|
|
- },
|
|
409
|
|
- 10000);
|
|
|
383
|
+ this.connection.sendIQ(
|
|
|
384
|
+ cand, null, this.newJingleErrorHandler(cand), IQ_TIMEOUT);
|
|
410
|
385
|
};
|
|
411
|
386
|
|
|
412
|
387
|
JingleSessionPC.prototype.readSsrcInfo = function (contents) {
|
|
|
@@ -477,8 +452,8 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype) {
|
|
477
|
452
|
},
|
|
478
|
453
|
function (e) {
|
|
479
|
454
|
logger.error('setRemoteDescription error', e);
|
|
480
|
|
- JingleSessionPC.onJingleFatalError(self, e);
|
|
481
|
|
- }
|
|
|
455
|
+ JingleSessionPC.onJingleFatalError(this, e);
|
|
|
456
|
+ }.bind(this)
|
|
482
|
457
|
);
|
|
483
|
458
|
};
|
|
484
|
459
|
|
|
|
@@ -635,7 +610,6 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, provisional) {
|
|
635
|
610
|
this.localSDP.raw = this.localSDP.session + '\r\n' + this.localSDP.media.join('');
|
|
636
|
611
|
}
|
|
637
|
612
|
}
|
|
638
|
|
- var self = this;
|
|
639
|
613
|
var sendJingle = function (ssrcs) {
|
|
640
|
614
|
// FIXME why do we generate session-accept in 3 different places ?
|
|
641
|
615
|
var accept = $iq({to: self.peerjid,
|
|
|
@@ -657,21 +631,10 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, provisional) {
|
|
657
|
631
|
ssrcs);
|
|
658
|
632
|
self.fixJingle(accept);
|
|
659
|
633
|
self.connection.sendIQ(accept,
|
|
660
|
|
- function () {
|
|
661
|
|
- var ack = {};
|
|
662
|
|
- ack.source = 'answer';
|
|
663
|
|
- $(document).trigger('ack.jingle', [self.sid, ack]);
|
|
664
|
|
- },
|
|
665
|
|
- function (stanza) {
|
|
666
|
|
- var error = ($(stanza).find('error').length) ? {
|
|
667
|
|
- code: $(stanza).find('error').attr('code'),
|
|
668
|
|
- reason: $(stanza).find('error :first')[0].tagName,
|
|
669
|
|
- }:{};
|
|
670
|
|
- error.source = 'answer';
|
|
671
|
|
- JingleSessionPC.onJingleError(self.sid, error);
|
|
672
|
|
- },
|
|
673
|
|
- 10000);
|
|
674
|
|
- }
|
|
|
634
|
+ null,
|
|
|
635
|
+ self.newJingleErrorHandler(accept),
|
|
|
636
|
+ IQ_TIMEOUT);
|
|
|
637
|
+ };
|
|
675
|
638
|
sdp.sdp = this.localSDP.raw;
|
|
676
|
639
|
this.peerconnection.setLocalDescription(sdp,
|
|
677
|
640
|
function () {
|
|
|
@@ -717,18 +680,9 @@ JingleSessionPC.prototype.sendTerminate = function (reason, text) {
|
|
717
|
680
|
self.peerconnection.close();
|
|
718
|
681
|
self.peerconnection = null;
|
|
719
|
682
|
self.terminate();
|
|
720
|
|
- var ack = {};
|
|
721
|
|
- ack.source = 'terminate';
|
|
722
|
|
- $(document).trigger('ack.jingle', [self.sid, ack]);
|
|
723
|
683
|
},
|
|
724
|
|
- function (stanza) {
|
|
725
|
|
- var error = ($(stanza).find('error').length) ? {
|
|
726
|
|
- code: $(stanza).find('error').attr('code'),
|
|
727
|
|
- reason: $(stanza).find('error :first')[0].tagName,
|
|
728
|
|
- }:{};
|
|
729
|
|
- $(document).trigger('ack.jingle', [self.sid, error]);
|
|
730
|
|
- },
|
|
731
|
|
- 10000);
|
|
|
684
|
+ this.newJingleErrorHandler(term),
|
|
|
685
|
+ IQ_TIMEOUT);
|
|
732
|
686
|
};
|
|
733
|
687
|
|
|
734
|
688
|
/**
|
|
|
@@ -1158,14 +1112,8 @@ JingleSessionPC.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
|
|
1158
|
1112
|
|
|
1159
|
1113
|
if (removed && remove) {
|
|
1160
|
1114
|
logger.info("Sending source-remove", remove.tree());
|
|
1161
|
|
- this.connection.sendIQ(remove,
|
|
1162
|
|
- function (res) {
|
|
1163
|
|
- logger.info('got remove result', res);
|
|
1164
|
|
- },
|
|
1165
|
|
- function (err) {
|
|
1166
|
|
- logger.error('got remove error', err);
|
|
1167
|
|
- }
|
|
1168
|
|
- );
|
|
|
1115
|
+ this.connection.sendIQ(
|
|
|
1116
|
+ remove, null, this.newJingleErrorHandler(remove), IQ_TIMEOUT);
|
|
1169
|
1117
|
} else {
|
|
1170
|
1118
|
logger.log('removal not necessary');
|
|
1171
|
1119
|
}
|
|
|
@@ -1186,29 +1134,45 @@ JingleSessionPC.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
|
|
1186
|
1134
|
|
|
1187
|
1135
|
if (added && add) {
|
|
1188
|
1136
|
logger.info("Sending source-add", add.tree());
|
|
1189
|
|
- this.connection.sendIQ(add,
|
|
1190
|
|
- function (res) {
|
|
1191
|
|
- logger.info('got add result', res);
|
|
1192
|
|
- },
|
|
1193
|
|
- function (err) {
|
|
1194
|
|
- logger.error('got add error', err);
|
|
1195
|
|
- }
|
|
1196
|
|
- );
|
|
|
1137
|
+ this.connection.sendIQ(
|
|
|
1138
|
+ add, null, this.newJingleErrorHandler(add), IQ_TIMEOUT);
|
|
1197
|
1139
|
} else {
|
|
1198
|
1140
|
logger.log('addition not necessary');
|
|
1199
|
1141
|
}
|
|
1200
|
1142
|
};
|
|
1201
|
1143
|
|
|
1202
|
|
-JingleSessionPC.onJingleError = function (session, error)
|
|
1203
|
|
-{
|
|
1204
|
|
- logger.error("Jingle error", error);
|
|
1205
|
|
-}
|
|
|
1144
|
+JingleSessionPC.prototype.newJingleErrorHandler = function(request, failureCb) {
|
|
|
1145
|
+ return function (errResponse) {
|
|
|
1146
|
+
|
|
|
1147
|
+ var error = { };
|
|
|
1148
|
+
|
|
|
1149
|
+ // Get XMPP error code and condition(reason)
|
|
|
1150
|
+ const errorElSel = $(errResponse).find('error');
|
|
|
1151
|
+ if (errorElSel.length) {
|
|
|
1152
|
+ error.code = errorElSel.attr('code');
|
|
|
1153
|
+ const errorReasonSel = $(errResponse).find('error :first');
|
|
|
1154
|
+ if (errorReasonSel.length)
|
|
|
1155
|
+ error.reason = errorReasonSel[0].tagName;
|
|
|
1156
|
+ }
|
|
|
1157
|
+
|
|
|
1158
|
+ error.source = request ? request.tree() : null;
|
|
|
1159
|
+ error.session = this;
|
|
|
1160
|
+
|
|
|
1161
|
+ logger.error("Jingle error", error);
|
|
|
1162
|
+ if (failureCb) {
|
|
|
1163
|
+ failureCb(error);
|
|
|
1164
|
+ }
|
|
|
1165
|
+
|
|
|
1166
|
+ this.room.eventEmitter.emit(XMPPEvents.JINGLE_ERROR, error);
|
|
|
1167
|
+
|
|
|
1168
|
+ }.bind(this);
|
|
|
1169
|
+};
|
|
1206
|
1170
|
|
|
1207
|
1171
|
JingleSessionPC.onJingleFatalError = function (session, error)
|
|
1208
|
1172
|
{
|
|
1209
|
1173
|
this.room.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
|
|
1210
|
1174
|
this.room.eventEmitter.emit(XMPPEvents.JINGLE_FATAL_ERROR, session, error);
|
|
1211
|
|
-}
|
|
|
1175
|
+};
|
|
1212
|
1176
|
|
|
1213
|
1177
|
JingleSessionPC.prototype.remoteStreamAdded = function (data, times) {
|
|
1214
|
1178
|
var self = this;
|
|
|
@@ -1249,7 +1213,7 @@ JingleSessionPC.prototype.remoteStreamAdded = function (data, times) {
|
|
1249
|
1213
|
}
|
|
1250
|
1214
|
|
|
1251
|
1215
|
this.room.remoteStreamAdded(data, this.sid, thessrc);
|
|
1252
|
|
-}
|
|
|
1216
|
+};
|
|
1253
|
1217
|
|
|
1254
|
1218
|
/**
|
|
1255
|
1219
|
* Handles remote stream removal.
|
|
|
@@ -1263,7 +1227,7 @@ JingleSessionPC.prototype.remoteStreamRemoved = function (event) {
|
|
1263
|
1227
|
} else if (streamId && streamId.indexOf('mixedmslabel') === -1) {
|
|
1264
|
1228
|
this.room.eventEmitter.emit(XMPPEvents.REMOTE_STREAM_REMOVED, streamId);
|
|
1265
|
1229
|
}
|
|
1266
|
|
-}
|
|
|
1230
|
+};
|
|
1267
|
1231
|
|
|
1268
|
1232
|
/**
|
|
1269
|
1233
|
* Returns the ice connection state for the peer connection.
|
|
|
@@ -1271,7 +1235,7 @@ JingleSessionPC.prototype.remoteStreamRemoved = function (event) {
|
|
1271
|
1235
|
*/
|
|
1272
|
1236
|
JingleSessionPC.prototype.getIceConnectionState = function () {
|
|
1273
|
1237
|
return this.peerconnection.iceConnectionState;
|
|
1274
|
|
-}
|
|
|
1238
|
+};
|
|
1275
|
1239
|
|
|
1276
|
1240
|
|
|
1277
|
1241
|
/**
|
|
|
@@ -1297,7 +1261,7 @@ JingleSessionPC.prototype.fixJingle = function(jingle) {
|
|
1297
|
1261
|
|
|
1298
|
1262
|
var sources = $(jingle.tree()).find(">jingle>content>description>source");
|
|
1299
|
1263
|
return sources && sources.length > 0;
|
|
1300
|
|
-}
|
|
|
1264
|
+};
|
|
1301
|
1265
|
|
|
1302
|
1266
|
/**
|
|
1303
|
1267
|
* Fixes the outgoing jingle packets with action source-add by removing the
|
|
|
@@ -1360,7 +1324,7 @@ JingleSessionPC.prototype.fixSourceAddJingle = function (jingle) {
|
|
1360
|
1324
|
});
|
|
1361
|
1325
|
});
|
|
1362
|
1326
|
}
|
|
1363
|
|
-}
|
|
|
1327
|
+};
|
|
1364
|
1328
|
|
|
1365
|
1329
|
/**
|
|
1366
|
1330
|
* Fixes the outgoing jingle packets with action source-remove by removing the
|
|
|
@@ -1415,7 +1379,7 @@ JingleSessionPC.prototype.fixSourceRemoveJingle = function(jingle) {
|
|
1415
|
1379
|
}
|
|
1416
|
1380
|
});
|
|
1417
|
1381
|
});
|
|
1418
|
|
-}
|
|
|
1382
|
+};
|
|
1419
|
1383
|
|
|
1420
|
1384
|
/**
|
|
1421
|
1385
|
* Returns the description node related to the passed content type. If the node
|