|
|
@@ -279,19 +279,69 @@ JingleSessionPC.prototype.readSsrcInfo = function (contents) {
|
|
279
|
279
|
});
|
|
280
|
280
|
};
|
|
281
|
281
|
|
|
|
282
|
+/**
|
|
|
283
|
+ * Does accept incoming Jingle 'session-initiate' and should send
|
|
|
284
|
+ * 'session-accept' in result.
|
|
|
285
|
+ * @param jingleOffer jQuery selector pointing to the jingle element of
|
|
|
286
|
+ * the offer IQ
|
|
|
287
|
+ * @param success callback called when we accept incoming session successfully
|
|
|
288
|
+ * and receive RESULT packet to 'session-accept' sent.
|
|
|
289
|
+ * @param failure function(error) called if for any reason we fail to accept
|
|
|
290
|
+ * the incoming offer. 'error' argument can be used to log some details
|
|
|
291
|
+ * about the error.
|
|
|
292
|
+ */
|
|
282
|
293
|
JingleSessionPC.prototype.acceptOffer = function(jingleOffer,
|
|
283
|
294
|
success, failure) {
|
|
284
|
295
|
this.state = 'active';
|
|
285
|
|
- this.setRemoteDescription(jingleOffer, 'offer',
|
|
|
296
|
+ this.setOfferCycle(jingleOffer,
|
|
|
297
|
+ function() {
|
|
|
298
|
+ // setOfferCycle succeeded, now we have self.localSDP up to date
|
|
|
299
|
+ // Let's send an answer !
|
|
|
300
|
+ // FIXME we may not care about RESULT packet for session-accept
|
|
|
301
|
+ // then we should either call 'success' here immediately or
|
|
|
302
|
+ // modify sendSessionAccept method to do that
|
|
|
303
|
+ this.sendSessionAccept(this.localSDP, success, failure);
|
|
|
304
|
+ }.bind(this),
|
|
|
305
|
+ failure);
|
|
|
306
|
+};
|
|
|
307
|
+
|
|
|
308
|
+/**
|
|
|
309
|
+ * This is a setRemoteDescription/setLocalDescription cycle which starts at
|
|
|
310
|
+ * converting Strophe Jingle IQ into remote offer SDP. Once converted
|
|
|
311
|
+ * setRemoteDescription, createAnswer and setLocalDescription calls follow.
|
|
|
312
|
+ * @param jingleOfferIq jQuery selector pointing to the jingle element of
|
|
|
313
|
+ * the offer IQ
|
|
|
314
|
+ * @param success callback called when sRD/sLD cycle finishes successfully.
|
|
|
315
|
+ * @param failure callback called with an error object as an argument if we fail
|
|
|
316
|
+ * at any point during setRD, createAnswer, setLD.
|
|
|
317
|
+ */
|
|
|
318
|
+JingleSessionPC.prototype.setOfferCycle = function (jingleOfferIq,
|
|
|
319
|
+ success,
|
|
|
320
|
+ failure) {
|
|
|
321
|
+ // Set Jingle offer as RD
|
|
|
322
|
+ this.setOffer(jingleOfferIq,
|
|
286
|
323
|
function() {
|
|
287
|
|
- this.sendAnswer(success, failure);
|
|
|
324
|
+ // Set offer OK, now let's try create an answer
|
|
|
325
|
+ this.createAnswer(function(answer) {
|
|
|
326
|
+ // Create answer OK, set it as local SDP
|
|
|
327
|
+ this.setLocalDescription(answer, success, failure);
|
|
|
328
|
+ }.bind(this),
|
|
|
329
|
+ failure);
|
|
288
|
330
|
}.bind(this),
|
|
289
|
331
|
failure);
|
|
290
|
332
|
};
|
|
291
|
333
|
|
|
292
|
|
-JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype,
|
|
293
|
|
- success, failure) {
|
|
294
|
|
- //logger.log('setting remote description... ', desctype);
|
|
|
334
|
+/**
|
|
|
335
|
+ * Sets remote offer on PeerConnection by converting given Jingle offer IQ into
|
|
|
336
|
+ * SDP and setting it as remote description.
|
|
|
337
|
+ * @param jingleOfferIq jQuery selector pointing to the jingle element of
|
|
|
338
|
+ * the offer IQ
|
|
|
339
|
+ * @param success callback called when setRemoteDescription on PeerConnection
|
|
|
340
|
+ * succeeds
|
|
|
341
|
+ * @param failure callback called with an error argument when
|
|
|
342
|
+ * setRemoteDescription fails.
|
|
|
343
|
+ */
|
|
|
344
|
+JingleSessionPC.prototype.setOffer = function (jingleOfferIq, success, failure) {
|
|
295
|
345
|
this.remoteSDP = new SDP('');
|
|
296
|
346
|
if (this.webrtcIceTcpDisable) {
|
|
297
|
347
|
this.remoteSDP.removeTcpCandidates = true;
|
|
|
@@ -300,9 +350,10 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype,
|
|
300
|
350
|
this.remoteSDP.removeUdpCandidates = true;
|
|
301
|
351
|
}
|
|
302
|
352
|
|
|
303
|
|
- this.remoteSDP.fromJingle(elem);
|
|
304
|
|
- this.readSsrcInfo($(elem).find(">content"));
|
|
305
|
|
- var remotedesc = new RTCSessionDescription({type: desctype, sdp: this.remoteSDP.raw});
|
|
|
353
|
+ this.remoteSDP.fromJingle(jingleOfferIq);
|
|
|
354
|
+ this.readSsrcInfo($(jingleOfferIq).find(">content"));
|
|
|
355
|
+ var remotedesc
|
|
|
356
|
+ = new RTCSessionDescription({type: 'offer', sdp: this.remoteSDP.raw});
|
|
306
|
357
|
|
|
307
|
358
|
this.peerconnection.setRemoteDescription(remotedesc,
|
|
308
|
359
|
function () {
|
|
|
@@ -320,56 +371,39 @@ JingleSessionPC.prototype.setRemoteDescription = function (elem, desctype,
|
|
320
|
371
|
);
|
|
321
|
372
|
};
|
|
322
|
373
|
|
|
323
|
|
-JingleSessionPC.prototype.sendAnswer = function (success, failure) {
|
|
|
374
|
+/**
|
|
|
375
|
+ * This is a wrapper to PeerConnection.createAnswer in order to generate failure
|
|
|
376
|
+ * event when error occurs. It also includes "media_constraints" if any are set
|
|
|
377
|
+ * on this JingleSessionPC instance.
|
|
|
378
|
+ * @param success callback called when PC.createAnswer succeeds, SDP will be
|
|
|
379
|
+ * the first argument
|
|
|
380
|
+ * @param failure callback called with error argument when setAnswer fails
|
|
|
381
|
+ */
|
|
|
382
|
+JingleSessionPC.prototype.createAnswer = function (success, failure) {
|
|
324
|
383
|
//logger.log('createAnswer');
|
|
|
384
|
+ var self = this;
|
|
325
|
385
|
this.peerconnection.createAnswer(
|
|
326
|
|
- function (sdp) {
|
|
327
|
|
- this.createdAnswer(sdp, success, failure);
|
|
328
|
|
- }.bind(this),
|
|
|
386
|
+ success,
|
|
329
|
387
|
function (error) {
|
|
330
|
388
|
logger.error("createAnswer failed", error);
|
|
331
|
389
|
if (failure)
|
|
332
|
390
|
failure(error);
|
|
333
|
|
- this.room.eventEmitter.emit(
|
|
|
391
|
+ self.room.eventEmitter.emit(
|
|
334
|
392
|
XMPPEvents.CONFERENCE_SETUP_FAILED, error);
|
|
335
|
|
- }.bind(this),
|
|
|
393
|
+ },
|
|
336
|
394
|
this.media_constraints
|
|
337
|
395
|
);
|
|
338
|
396
|
};
|
|
339
|
397
|
|
|
340
|
|
-JingleSessionPC.prototype.createdAnswer = function (sdp, success, failure) {
|
|
341
|
|
- //logger.log('createAnswer callback');
|
|
|
398
|
+JingleSessionPC.prototype.setLocalDescription = function (sdp, success,
|
|
|
399
|
+ failure) {
|
|
342
|
400
|
var self = this;
|
|
343
|
401
|
this.localSDP = new SDP(sdp.sdp);
|
|
344
|
|
- var sendJingle = function (ssrcs) {
|
|
345
|
|
- var accept = $iq({to: self.peerjid,
|
|
346
|
|
- type: 'set'})
|
|
347
|
|
- .c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
|
348
|
|
- action: 'session-accept',
|
|
349
|
|
- initiator: self.initiator,
|
|
350
|
|
- responder: self.responder,
|
|
351
|
|
- sid: self.sid });
|
|
352
|
|
- if (self.webrtcIceTcpDisable) {
|
|
353
|
|
- self.localSDP.removeTcpCandidates = true;
|
|
354
|
|
- }
|
|
355
|
|
- if (self.webrtcIceUdpDisable) {
|
|
356
|
|
- self.localSDP.removeUdpCandidates = true;
|
|
357
|
|
- }
|
|
358
|
|
- self.localSDP.toJingle(
|
|
359
|
|
- accept,
|
|
360
|
|
- self.initiator == self.me ? 'initiator' : 'responder',
|
|
361
|
|
- ssrcs);
|
|
362
|
|
- self.fixJingle(accept);
|
|
363
|
|
- self.connection.sendIQ(accept,
|
|
364
|
|
- success,
|
|
365
|
|
- self.newJingleErrorHandler(accept, failure),
|
|
366
|
|
- IQ_TIMEOUT);
|
|
367
|
|
- };
|
|
368
|
402
|
sdp.sdp = this.localSDP.raw;
|
|
369
|
403
|
this.peerconnection.setLocalDescription(sdp,
|
|
370
|
404
|
function () {
|
|
371
|
|
- //logger.log('setLocalDescription success');
|
|
372
|
|
- sendJingle(success, failure);
|
|
|
405
|
+ if (success)
|
|
|
406
|
+ success();
|
|
373
|
407
|
},
|
|
374
|
408
|
function (error) {
|
|
375
|
409
|
logger.error('setLocalDescription failed', error);
|
|
|
@@ -378,6 +412,8 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, success, failure) {
|
|
378
|
412
|
self.room.eventEmitter.emit(XMPPEvents.CONFERENCE_SETUP_FAILED);
|
|
379
|
413
|
}
|
|
380
|
414
|
);
|
|
|
415
|
+ // Some checks for STUN and TURN candiates present in local SDP
|
|
|
416
|
+ // Eventually could be removed as we don't really care
|
|
381
|
417
|
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
|
|
382
|
418
|
for (var j = 0; j < cands.length; j++) {
|
|
383
|
419
|
var cand = SDPUtil.parse_icecandidate(cands[j]);
|
|
|
@@ -389,6 +425,45 @@ JingleSessionPC.prototype.createdAnswer = function (sdp, success, failure) {
|
|
389
|
425
|
}
|
|
390
|
426
|
};
|
|
391
|
427
|
|
|
|
428
|
+/**
|
|
|
429
|
+ * Sends Jingle 'session-accept' message.
|
|
|
430
|
+ * @param localSDP the 'SDP' object with local session description
|
|
|
431
|
+ * @param success callback called when we recive 'RESULT' packet for
|
|
|
432
|
+ * 'session-accept'
|
|
|
433
|
+ * @param failure function(error) called when we receive an error response or
|
|
|
434
|
+ * when the request has timed out.
|
|
|
435
|
+ */
|
|
|
436
|
+JingleSessionPC.prototype.sendSessionAccept = function (localSDP,
|
|
|
437
|
+ success, failure) {
|
|
|
438
|
+ var accept = $iq({to: this.peerjid,
|
|
|
439
|
+ type: 'set'})
|
|
|
440
|
+ .c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
|
|
441
|
+ action: 'session-accept',
|
|
|
442
|
+ initiator: this.initiator,
|
|
|
443
|
+ responder: this.responder,
|
|
|
444
|
+ sid: this.sid });
|
|
|
445
|
+ if (this.webrtcIceTcpDisable) {
|
|
|
446
|
+ localSDP.removeTcpCandidates = true;
|
|
|
447
|
+ }
|
|
|
448
|
+ if (this.webrtcIceUdpDisable) {
|
|
|
449
|
+ localSDP.removeUdpCandidates = true;
|
|
|
450
|
+ }
|
|
|
451
|
+ localSDP.toJingle(
|
|
|
452
|
+ accept,
|
|
|
453
|
+ this.initiator == this.me ? 'initiator' : 'responder',
|
|
|
454
|
+ null);
|
|
|
455
|
+ this.fixJingle(accept);
|
|
|
456
|
+
|
|
|
457
|
+ // Calling tree() to print something useful
|
|
|
458
|
+ accept = accept.tree();
|
|
|
459
|
+ logger.info("Sending session-accept", accept);
|
|
|
460
|
+
|
|
|
461
|
+ this.connection.sendIQ(accept,
|
|
|
462
|
+ success,
|
|
|
463
|
+ this.newJingleErrorHandler(accept, failure),
|
|
|
464
|
+ IQ_TIMEOUT);
|
|
|
465
|
+};
|
|
|
466
|
+
|
|
392
|
467
|
JingleSessionPC.prototype.terminate = function (reason, text,
|
|
393
|
468
|
success, failure) {
|
|
394
|
469
|
var term = $iq({to: this.peerjid,
|
|
|
@@ -404,6 +479,10 @@ JingleSessionPC.prototype.terminate = function (reason, text,
|
|
404
|
479
|
term.up().c('text').t(text);
|
|
405
|
480
|
}
|
|
406
|
481
|
|
|
|
482
|
+ // Calling tree() to print something useful
|
|
|
483
|
+ term = term.tree();
|
|
|
484
|
+ logger.info("Sending session-terminate", term);
|
|
|
485
|
+
|
|
407
|
486
|
this.connection.sendIQ(
|
|
408
|
487
|
term, success, this.newJingleErrorHandler(term, failure), IQ_TIMEOUT);
|
|
409
|
488
|
|