Skip to content

Commit

Permalink
Merge branch 'termination-events'
Browse files Browse the repository at this point in the history
Implement termination event behavior according to Issue #68

#68
  • Loading branch information
Will Mitchell committed Jan 27, 2015
2 parents 9aee15c + 6e53867 commit 6d8d79b
Show file tree
Hide file tree
Showing 9 changed files with 1,006 additions and 208 deletions.
80 changes: 72 additions & 8 deletions src/Session.js
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,7 @@ Session.prototype = {
this.terminated(null, SIP.C.causes.CONNECTION_ERROR);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(null, SIP.C.causes.CONNECTION_ERROR);
this.terminated(null, SIP.C.causes.CONNECTION_ERROR);
}
},

Expand All @@ -873,6 +874,7 @@ Session.prototype = {
this.terminated(null, SIP.C.causes.REQUEST_TIMEOUT);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(null, SIP.C.causes.REQUEST_TIMEOUT);
this.terminated(null, SIP.C.causes.REQUEST_TIMEOUT);
}
},

Expand All @@ -881,6 +883,7 @@ Session.prototype = {
this.terminated(response, SIP.C.causes.DIALOG_ERROR);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(response, SIP.C.causes.DIALOG_ERROR);
this.terminated(response, SIP.C.causes.DIALOG_ERROR);
}
},

Expand Down Expand Up @@ -921,20 +924,20 @@ Session.prototype = {
},

failed: function(response, cause) {
this.close();
return this.emit('failed', response, cause);
if (this.status == C.STATUS_TERMINATED) {
return this;
}
return this.emit('failed', response || null, cause || null);
},

rejected: function(response, cause) {
this.close();
return this.emit('rejected',
response || null,
cause
cause || null
);
},

canceled: function() {
this.close();
return this.emit('cancel');
},

Expand All @@ -951,6 +954,10 @@ Session.prototype = {
},

terminated: function(message, cause) {
if (this.status == C.STATUS_TERMINATED) {
return this;
}

this.endTime = new Date();

this.close();
Expand Down Expand Up @@ -1052,6 +1059,7 @@ InviteServerContext = function(ua, request) {
self.timers.userNoAnswerTimer = SIP.Timers.setTimeout(function() {
request.reply(408);
self.failed(request, SIP.C.causes.NO_ANSWER);
self.terminated(request, SIP.C.causes.NO_ANSWER);
}, self.ua.configuration.noAnswerTimeout);

/* Set expiresTimer
Expand All @@ -1062,6 +1070,7 @@ InviteServerContext = function(ua, request) {
if(self.status === C.STATUS_WAITING_FOR_ANSWER) {
request.reply(487);
self.failed(request, SIP.C.causes.EXPIRES);
self.terminated(request, SIP.C.causes.EXPIRES);
}
}, expires);
}
Expand Down Expand Up @@ -1248,6 +1257,7 @@ InviteServerContext.prototype = {

function onFailure () {
this.failed(null, SIP.C.causes.WEBRTC_ERROR);
this.terminated(null, SIP.C.causes.WEBRTC_ERROR);
}.bind(this)
);
} // end do100rel
Expand Down Expand Up @@ -1299,6 +1309,7 @@ InviteServerContext.prototype = {
// run for reply failure callback
replyFailed = function() {
self.failed(null, SIP.C.causes.CONNECTION_ERROR);
self.terminated(null, SIP.C.causes.CONNECTION_ERROR);
};

// Chrome might call onaddstream before accept() is called, which means
Expand Down Expand Up @@ -1335,6 +1346,7 @@ InviteServerContext.prototype = {
//response = request.reply(480);
//self.failed(response, SIP.C.causes.USER_DENIED_MEDIA_ACCESS);
self.failed(null, SIP.C.causes.WEBRTC_ERROR);
self.terminated(null, SIP.C.causes.WEBRTC_ERROR);
};

// Check Session Status
Expand Down Expand Up @@ -1447,6 +1459,7 @@ InviteServerContext.prototype = {
this.canceled(request);
this.rejected(request, SIP.C.causes.CANCELED);
this.failed(request, SIP.C.causes.CANCELED);
this.terminated(request, SIP.C.causes.CANCELED);
}
break;
case SIP.C.ACK:
Expand All @@ -1468,13 +1481,15 @@ InviteServerContext.prototype = {
reasonPhrase: 'Bad Media Description'
});
this.failed(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
this.terminated(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
}.bind(this)
);
} else if (this.early_sdp) {
confirmSession.apply(this);
} else {
//TODO: Pass to mediahandler
this.failed(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
this.terminated(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
}
} else {
confirmSession.apply(this);
Expand Down Expand Up @@ -1509,6 +1524,7 @@ InviteServerContext.prototype = {
reasonPhrase: 'Bad Media Description'
});
this.failed(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
this.terminated(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
}.bind(this)
);
} else {
Expand All @@ -1517,6 +1533,7 @@ InviteServerContext.prototype = {
reasonPhrase: 'Bad Media Description'
});
this.failed(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
this.terminated(request, SIP.C.causes.BAD_MEDIA_DESCRIPTION);
}
} else {
SIP.Timers.clearTimeout(this.timers.rel1xxTimer);
Expand All @@ -1539,7 +1556,26 @@ InviteServerContext.prototype = {
Session.prototype.receiveRequest.apply(this, [request]);
break;
}
},

onTransportError: function() {
if (this.status === C.STATUS_CONFIRMED) {
this.terminated(null, SIP.C.causes.CONNECTION_ERROR);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(null, SIP.C.causes.CONNECTION_ERROR);
this.terminated(null, SIP.C.causes.CONNECTION_ERROR);
}
},

onRequestTimeout: function() {
if (this.status === C.STATUS_CONFIRMED) {
this.terminated(null, SIP.C.causes.REQUEST_TIMEOUT);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(null, SIP.C.causes.REQUEST_TIMEOUT);
this.terminated(null, SIP.C.causes.REQUEST_TIMEOUT);
}
}

};

SIP.InviteServerContext = InviteServerContext;
Expand Down Expand Up @@ -1702,6 +1738,7 @@ InviteClientContext.prototype = {
//self.failed(null, SIP.C.causes.USER_DENIED_MEDIA_ACCESS);
//self.failed(null, SIP.C.causes.WEBRTC_ERROR);
self.failed(null, SIP.C.causes.WEBRTC_ERROR);
self.terminated(null, SIP.C.causes.WEBRTC_ERROR);
}
);
}
Expand Down Expand Up @@ -1737,6 +1774,7 @@ InviteClientContext.prototype = {
*/
if(this.status !== C.STATUS_CONFIRMED) {
this.failed(response, SIP.C.causes.WEBRTC_ERROR);
this.terminated(response, SIP.C.causes.WEBRTC_ERROR);
}
return;
} else if (this.status === C.STATUS_CONFIRMED) {
Expand Down Expand Up @@ -1776,6 +1814,11 @@ InviteClientContext.prototype = {
} else if(response.status_code >= 200 && response.status_code < 299) {
this.acceptAndTerminate(response);
this.emit('bye', this.request);
} else if (response.status_code >= 300) {
cause = SIP.C.REASON_PHRASE[response.status_code] || SIP.C.causes.CANCELED;
this.rejected(response, cause);
this.failed(response, cause);
this.terminated(response, cause);
}
return;
}
Expand Down Expand Up @@ -1888,6 +1931,7 @@ InviteClientContext.prototype = {
// TODO - fail out on error
// session.failed(gum error);
session.failed(null, SIP.C.causes.WEBRTC_ERROR);
session.terminated(null, SIP.C.causes.WEBRTC_ERROR);
} else {
earlyDialog.pracked.splice(earlyDialog.pracked.indexOf(response.getHeader('rseq')), 1);
// Could not set remote description
Expand Down Expand Up @@ -2056,16 +2100,17 @@ InviteClientContext.prototype = {
break;
default:
cause = SIP.Utils.sipErrorCause(response.status_code);
this.failed(response, cause);
this.rejected(response, cause);
this.failed(response, cause);
this.terminated(response, cause);
}
},

cancel: function(options) {
options = options || {};

// Check Session Status
if (this.status === C.STATUS_TERMINATED) {
if (this.status === C.STATUS_TERMINATED || this.status === C.STATUS_CONFIRMED) {
throw new SIP.Exceptions.InvalidStateError(this.status);
}

Expand Down Expand Up @@ -2098,7 +2143,7 @@ InviteClientContext.prototype = {
this.cancel(options);
}

return this.terminated();
return this;
},

receiveRequest: function(request) {
Expand All @@ -2119,7 +2164,26 @@ InviteClientContext.prototype = {
}

return Session.prototype.receiveRequest.apply(this, [request]);
},

onTransportError: function() {
if (this.status === C.STATUS_CONFIRMED) {
this.terminated(null, SIP.C.causes.CONNECTION_ERROR);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(null, SIP.C.causes.CONNECTION_ERROR);
this.terminated(null, SIP.C.causes.CONNECTION_ERROR);
}
},

onRequestTimeout: function() {
if (this.status === C.STATUS_CONFIRMED) {
this.terminated(null, SIP.C.causes.REQUEST_TIMEOUT);
} else if (this.status !== C.STATUS_TERMINATED) {
this.failed(null, SIP.C.causes.REQUEST_TIMEOUT);
this.terminated(null, SIP.C.causes.REQUEST_TIMEOUT);
}
}

};

SIP.InviteClientContext = InviteClientContext;
Expand Down
47 changes: 47 additions & 0 deletions test/helpers/SIPMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
window.SIPHelper = {
createResponse: function createResponse(request, status_code, reason_phrase, body) {
var response = new SIP.IncomingResponse(request.ua);
var parsed, header, length, idx;

response.status_code = status_code;
response.reason_phrase = (reason_phrase || '').toString();

// Let's hope we don't actually need a raw string of the response.
response.data = null;

response.body = (body || 'foo').toString();

/*
* We aren't going to parse a bunch of strings,
* so just copy the headers over from the request.
*/
response.method = request.method;
response.from = request.from;
response.to = request.to;
response.call_id = request.call_id;
response.cseq = request.cseq;
response.from_tag = request.from.getParam('tag');
response.to_tag = 'uas-to-tag';

/*
* In addition to properties, some other headers are
* deemed "important" by the Session.
*/
response.setHeader('cseq', request.cseq.toString() + ' ' + request.method);

// Contact
parsed = SIP.Grammar.parse(request.getHeader('contact'), 'Contact');
length = parsed.length;
for (idx = 0; idx < length; idx++) {
header = parsed[idx];
response.addHeader('contact', request.getHeader('contact').substring(header.position, header.offset));
response.headers['Contact'][response.getHeaders('contact').length - 1].parsed = header.parsed;
}

// From/To
response.setHeader('from', request.getHeader('from'));
response.setHeader('to', request.getHeader('to'));

return response;
}
};
Loading

0 comments on commit 6d8d79b

Please sign in to comment.