Skip to content
Permalink
Browse files

Improve late CANCEL (and fix #245).

  • Loading branch information
ibc committed Sep 24, 2014
1 parent 14c2ca1 commit 3789d5b6afde8b74fd334249262910bf893f148e
Showing with 33 additions and 38 deletions.
  1. +20 −22 src/RTCSession.js
  2. +13 −16 src/Transactions.js
@@ -151,7 +151,7 @@ RTCSession.prototype.terminate = function(options) {
case C.STATUS_NULL:
case C.STATUS_INVITE_SENT:
case C.STATUS_1XX_RECEIVED:
this.logger.log('canceling RTCSession');
this.logger.debug('canceling RTCSession');

if (status_code && (status_code < 200 || status_code >= 700)) {
throw new TypeError('Invalid status_code: '+ status_code);
@@ -165,13 +165,10 @@ RTCSession.prototype.terminate = function(options) {
this.isCanceled = true;
this.cancelReason = cancel_reason;
} else if (this.status === C.STATUS_INVITE_SENT) {
if(this.received_100) {
this.request.cancel(cancel_reason);
} else {
this.isCanceled = true;
this.cancelReason = cancel_reason;
}
this.isCanceled = true;
this.cancelReason = cancel_reason;
} else if(this.status === C.STATUS_1XX_RECEIVED) {
console.warn("---------- 176: request.cancel()");
this.request.cancel(cancel_reason);
}

@@ -183,7 +180,7 @@ RTCSession.prototype.terminate = function(options) {
// - UAS -
case C.STATUS_WAITING_FOR_ANSWER:
case C.STATUS_ANSWERED:
this.logger.log('rejecting RTCSession');
this.logger.debug('rejecting RTCSession');

status_code = status_code || 480;

@@ -197,7 +194,7 @@ RTCSession.prototype.terminate = function(options) {

case C.STATUS_WAITING_FOR_ACK:
case C.STATUS_CONFIRMED:
this.logger.log('terminating RTCSession');
this.logger.debug('terminating RTCSession');

reason_phrase = options.reason_phrase || JsSIP.C.REASON_PHRASE[status_code] || '';

@@ -796,7 +793,7 @@ RTCSession.prototype.setACKTimer = function() {

this.timers.ackTimer = window.setTimeout(function() {
if(self.status === C.STATUS_WAITING_FOR_ACK) {
self.logger.log('no ACK received, terminating the call');
self.logger.debug('no ACK received, terminating the call');
window.clearTimeout(self.timers.invite2xxTimer);
self.sendRequest(JsSIP.C.BYE);
self.ended('remote', null, JsSIP.C.causes.NO_ACK);
@@ -994,7 +991,6 @@ RTCSession.prototype.connect = function(target, options) {

// OutgoingSession specific parameters
this.isCanceled = false;
this.received_100 = false;

requestParams = {from_tag: this.from_tag};

@@ -1044,7 +1040,7 @@ RTCSession.prototype.close = function() {
return;
}

this.logger.log('closing INVITE session ' + this.id);
this.logger.debug('closing INVITE session ' + this.id);

// 1st Step. Terminate media.
if (this.rtcMediaHandler){
@@ -1246,7 +1242,7 @@ RTCSession.prototype.receiveRequest = function(request) {
break;
case JsSIP.C.INVITE:
if(this.status === C.STATUS_CONFIRMED) {
this.logger.log('re-INVITE received');
this.logger.debug('re-INVITE received');
this.receiveReinvite(request);
}
break;
@@ -1446,12 +1442,13 @@ RTCSession.prototype.receiveInviteResponse = function(response) {
return;
}

} else if(this.status !== C.STATUS_INVITE_SENT && this.status !== C.STATUS_1XX_RECEIVED) {
return;
}

// Proceed to cancellation if the user requested.
if(this.isCanceled) {
// Remove the flag. We are done.
this.isCanceled = false;

if(response.status_code >= 100 && response.status_code < 200) {
this.request.cancel(this.cancelReason);
} else if(response.status_code >= 200 && response.status_code < 299) {
@@ -1460,9 +1457,12 @@ RTCSession.prototype.receiveInviteResponse = function(response) {
return;
}

if(this.status !== C.STATUS_INVITE_SENT && this.status !== C.STATUS_1XX_RECEIVED) {
return;
}

switch(true) {
case /^100$/.test(response.status_code):
this.received_100 = true;
break;
case /^1[0-9]{2}$/.test(response.status_code):
if(this.status !== C.STATUS_INVITE_SENT && this.status !== C.STATUS_1XX_RECEIVED) {
@@ -1483,9 +1483,10 @@ RTCSession.prototype.receiveInviteResponse = function(response) {
}
}

this.status = C.STATUS_1XX_RECEIVED;
this.progress('remote', response);

if (!response.body) {
session.status = C.STATUS_1XX_RECEIVED;
session.progress('remote', response);
break;
}

@@ -1496,10 +1497,7 @@ RTCSession.prototype.receiveInviteResponse = function(response) {
* OnSuccess.
* SDP Answer fits with Offer.
*/
function() {
session.status = C.STATUS_1XX_RECEIVED;
session.progress('remote', response);
},
function() { },
/*
* OnFailure.
* SDP Answer does not fit with Offer.
@@ -83,7 +83,7 @@ NonInviteClientTransaction.prototype.send = function() {
};

NonInviteClientTransaction.prototype.onTransportError = function() {
this.logger.log('transport error occurred, deleting non-INVITE client transaction ' + this.id);
this.logger.debug('transport error occurred, deleting non-INVITE client transaction ' + this.id);
window.clearTimeout(this.F);
window.clearTimeout(this.K);
this.stateChanged(C.STATUS_TERMINATED);
@@ -92,7 +92,7 @@ NonInviteClientTransaction.prototype.onTransportError = function() {
};

NonInviteClientTransaction.prototype.timer_F = function() {
this.logger.log('Timer F expired for non-INVITE client transaction ' + this.id);
this.logger.debug('Timer F expired for non-INVITE client transaction ' + this.id);
this.stateChanged(C.STATUS_TERMINATED);
this.request_sender.ua.destroyTransaction(this);
this.request_sender.onRequestTimeout();
@@ -205,7 +205,7 @@ InviteClientTransaction.prototype.send = function() {
};

InviteClientTransaction.prototype.onTransportError = function() {
this.logger.log('transport error occurred, deleting INVITE client transaction ' + this.id);
this.logger.debug('transport error occurred, deleting INVITE client transaction ' + this.id);
window.clearTimeout(this.B);
window.clearTimeout(this.D);
window.clearTimeout(this.M);
@@ -219,7 +219,7 @@ InviteClientTransaction.prototype.onTransportError = function() {

// RFC 6026 7.2
InviteClientTransaction.prototype.timer_M = function() {
this.logger.log('Timer M expired for INVITE client transaction ' + this.id);
this.logger.debug('Timer M expired for INVITE client transaction ' + this.id);

if(this.state === C.STATUS_ACCEPTED) {
window.clearTimeout(this.B);
@@ -230,7 +230,7 @@ InviteClientTransaction.prototype.timer_M = function() {

// RFC 3261 17.1.1
InviteClientTransaction.prototype.timer_B = function() {
this.logger.log('Timer B expired for INVITE client transaction ' + this.id);
this.logger.debug('Timer B expired for INVITE client transaction ' + this.id);
if(this.state === C.STATUS_CALLING) {
this.stateChanged(C.STATUS_TERMINATED);
this.request_sender.ua.destroyTransaction(this);
@@ -239,7 +239,7 @@ InviteClientTransaction.prototype.timer_B = function() {
};

InviteClientTransaction.prototype.timer_D = function() {
this.logger.log('Timer D expired for INVITE client transaction ' + this.id);
this.logger.debug('Timer D expired for INVITE client transaction ' + this.id);
window.clearTimeout(this.B);
this.stateChanged(C.STATUS_TERMINATED);
this.request_sender.ua.destroyTransaction(this);
@@ -305,9 +305,6 @@ InviteClientTransaction.prototype.receiveResponse = function(response) {
case C.STATUS_CALLING:
this.stateChanged(C.STATUS_PROCEEDING);
this.request_sender.receiveResponse(response);
if(this.cancel) {
this.transport.send(this.cancel);
}
break;
case C.STATUS_PROCEEDING:
this.request_sender.receiveResponse(response);
@@ -385,7 +382,7 @@ AckClientTransaction.prototype.send = function() {
};

AckClientTransaction.prototype.onTransportError = function() {
this.logger.log('transport error occurred, for an ACK client transaction ' + this.id);
this.logger.debug('transport error occurred, for an ACK client transaction ' + this.id);
this.request_sender.onTransportError();
};

@@ -423,7 +420,7 @@ NonInviteServerTransaction.prototype.stateChanged = function(state) {
};

NonInviteServerTransaction.prototype.timer_J = function() {
this.logger.log('Timer J expired for non-INVITE server transaction ' + this.id);
this.logger.debug('Timer J expired for non-INVITE server transaction ' + this.id);
this.stateChanged(C.STATUS_TERMINATED);
this.ua.destroyTransaction(this);
};
@@ -432,7 +429,7 @@ NonInviteServerTransaction.prototype.onTransportError = function() {
if (!this.transportError) {
this.transportError = true;

this.logger.log('transport error occurred, deleting non-INVITE server transaction ' + this.id);
this.logger.debug('transport error occurred, deleting non-INVITE server transaction ' + this.id);

window.clearTimeout(this.J);
this.stateChanged(C.STATUS_TERMINATED);
@@ -529,10 +526,10 @@ InviteServerTransaction.prototype.stateChanged = function(state) {
};

InviteServerTransaction.prototype.timer_H = function() {
this.logger.log('Timer H expired for INVITE server transaction ' + this.id);
this.logger.debug('Timer H expired for INVITE server transaction ' + this.id);

if(this.state === C.STATUS_COMPLETED) {
this.logger.warn('transactions', 'ACK for INVITE server transaction was never received, call will be terminated');
this.logger.log('transactions', 'ACK for INVITE server transaction was never received, call will be terminated');
}

this.stateChanged(C.STATUS_TERMINATED);
@@ -546,7 +543,7 @@ InviteServerTransaction.prototype.timer_I = function() {

// RFC 6026 7.1
InviteServerTransaction.prototype.timer_L = function() {
this.logger.log('Timer L expired for INVITE server transaction ' + this.id);
this.logger.debug('Timer L expired for INVITE server transaction ' + this.id);

if(this.state === C.STATUS_ACCEPTED) {
this.stateChanged(C.STATUS_TERMINATED);
@@ -558,7 +555,7 @@ InviteServerTransaction.prototype.onTransportError = function() {
if (!this.transportError) {
this.transportError = true;

this.logger.log('transport error occurred, deleting INVITE server transaction ' + this.id);
this.logger.debug('transport error occurred, deleting INVITE server transaction ' + this.id);

if (this.resendProvisionalTimer !== null) {
window.clearInterval(this.resendProvisionalTimer);

0 comments on commit 3789d5b

Please sign in to comment.
You can’t perform that action at this time.