Skip to content

Commit

Permalink
- Do not allow reject-ing a Message or Session with an incorrect stat…
Browse files Browse the repository at this point in the history
…us code

- Extract 'accept()' and 'reject()' Message methods to the prototype
- Extract 'reject()' and 'cancel()' Session methods to the prototype
  • Loading branch information
jmillan committed Nov 23, 2012
1 parent 35e5874 commit 2c9a310
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 50 deletions.
48 changes: 36 additions & 12 deletions src/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,10 @@ JsSIP.Message.prototype.init_incoming = function(request) {
contentType = request.getHeader('content-type');

this.direction = 'incoming';
this.request = request;
this.local_identity = request.s('to').uri;
this.remote_identity = request.s('from').uri;

this.accept = function() {
request.reply(200);
};

this.reject = function(status_code, reason_phrase) {
if (status_code && reason_phrase) {
request.reply(status_code, reason_phrase);
} else {
request.reply(480);
}
};

if (contentType && (contentType.match(/^text\/plain(\s*;\s*.+)*$/i) || contentType.match(/^text\/html(\s*;\s*.+)*$/i))) {
this.ua.emit('newMessage', this.ua, {
originator: 'remote',
Expand All @@ -194,3 +183,38 @@ JsSIP.Message.prototype.init_incoming = function(request) {
request.reply(415, JsSIP.c.REASON_PHRASE[415], ["Accept: text/plain, text/html"]);
}
};

/**
* Accept the incoming Message
* Only valid for incoming Messages
*/
JsSIP.Message.prototype.accept = function() {
if (this.direction !== 'incoming') {
throw new JsSIP.exceptions.InvalidMethodError();
}

this.request.reply(200);
};

/**
* Reject the incoming Message
* Only valid for incoming Messages
*
* @param {Number} status_code
* @param {String} [reason_phrase]
*/
JsSIP.Message.prototype.reject = function(status_code, reason_phrase) {
if (this.direction !== 'incoming') {
throw new JsSIP.exceptions.InvalidMethodError();
}

if (status_code) {
if ((status_code < 300 || status_code >= 700)) {
throw new JsSIP.exceptions.InvalidValueError();
} else {
this.request.reply(status_code, reason_phrase);
}
} else {
this.request.reply(480);
}
};
98 changes: 65 additions & 33 deletions src/Session.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ JsSIP.Session = function(ua) {
];

this.ua = ua;
this.status = null;
this.status = JsSIP.c.SESSION_NULL;
this.dialog = null;
this.earlyDialogs = [];
this.mediaSession = null;
Expand Down Expand Up @@ -64,6 +64,7 @@ JsSIP.Session.prototype.init_incoming = function(request) {
this.from_tag = request.from_tag;
this.status = JsSIP.c.SESSION_INVITE_RECEIVED;
this.id = request.call_id + this.from_tag;
this.request = request;

//Save the session into the ua sessions collection.
this.ua.sessions[this.id] = this;
Expand All @@ -84,7 +85,7 @@ JsSIP.Session.prototype.connect = function(target, options) {
}

// Check Session Status
if (this.status !== null) {
if (this.status !== JsSIP.c.SESSION_NULL) {
throw new JsSIP.exceptions.InvalidStateError();
}

Expand Down Expand Up @@ -145,23 +146,6 @@ JsSIP.Session.prototype.connect = function(target, options) {
//Save the session into the ua sessions collection.
this.ua.sessions[this.id] = this;

/**
* @private
*/
this.cancel = function() {
if (this.status === JsSIP.c.SESSION_INVITE_SENT) {
if(this.received_100) {
request.cancel();
} else {
this.isCanceled = true;
}
} else if(this.status === JsSIP.c.SESSION_1XX_RECEIVED) {
request.cancel();
}

this.failed('local', null, JsSIP.c.causes.CANCELED);
};

this.newSession('local', request, target);
this.connecting('local', request, target);
this.sendInitialRequest(mediaType);
Expand Down Expand Up @@ -455,18 +439,6 @@ JsSIP.Session.prototype.receiveInitialRequest = function(ua, request) {
session.mediaSession.startCallee(onMediaSuccess, onMediaFailure, onSdpFailure, offer);
};

/**
* Reject the call
* @private
*/
this.reject = function() {
if (this.status === JsSIP.c.SESSION_WAITING_FOR_ANSWER) {
request.reply(486);

this.failed('local', null, JsSIP.c.causes.REJECTED);
}
};

// Fire 'call' event callback
this.newSession('remote', request);

Expand Down Expand Up @@ -498,7 +470,7 @@ JsSIP.Session.prototype.receiveResponse = function(response) {
// Proceed to cancelation if the user requested.
if(this.isCanceled) {
if(response.status_code >= 100 && response.status_code < 200) {
this.request.cancel();
this.request.cancel(this.cancelReason);
} else if(response.status_code >= 200 && response.status_code < 299) {
this.acceptAndTerminate(response);
}
Expand Down Expand Up @@ -885,6 +857,66 @@ JsSIP.Session.prototype.terminate = function() {
this.close();
};

/**
* Reject the incoming call
* Only valid for incoming Messages
*
* @param {Number} status_code
* @param {String} [reason_phrase]
*/
JsSIP.Session.prototype.reject = function(status_code, reason_phrase) {
// Check Session Direction and Status
if (this.direction !== 'incoming') {
throw new JsSIP.exceptions.InvalidMethodError();
} else if (this.status !== JsSIP.c.SESSION_WAITING_FOR_ANSWER) {
throw new JsSIP.exceptions.InvalidStateError();
}

if (status_code) {
if ((status_code < 300 || status_code >= 700)) {
throw new JsSIP.exceptions.InvalidValueError();
} else {
this.request.reply(status_code, reason_phrase);
}
} else {
this.request.reply(480);
}

this.failed('local', null, JsSIP.c.causes.REJECTED);
};

/**
* Cancel the outgoing call
*
* @param {String} [reason]
*/
JsSIP.Session.prototype.cancel = function(reason) {
// Check Session Direction
if (this.direction !== 'outgoing') {
throw new JsSIP.exceptions.InvalidMethodError();
}

// Check Session Status
if (this.status === JsSIP.c.SESSION_NULL) {
this.isCanceled = true;
this.cancelReason = reason;
} else if (this.status === JsSIP.c.SESSION_INVITE_SENT) {
if(this.received_100) {
this.request.cancel(reason);
} else {
this.isCanceled = true;
this.cancelReason = reason;
}
} else if(this.status === JsSIP.c.SESSION_1XX_RECEIVED) {
this.request.cancel(reason);
} else {
throw new JsSIP.exceptions.InvalidStateError();
}

this.failed('local', null, JsSIP.c.causes.CANCELED);
};



/**
* Initial Request Sender
Expand All @@ -899,7 +931,7 @@ JsSIP.Session.prototype.sendInitialRequest = function(mediaType) {
request_sender = new JsSIP.RequestSender(self, this.ua);

function onMediaSuccess() {
if (self.status === JsSIP.c.SESSION_TERMINATED) {
if (self.isCanceled || self.status === JsSIP.c.SESSION_TERMINATED) {
self.mediaSession.close();
return;
}
Expand Down
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ JsSIP.c = {
LOG_DIGEST_AUTHENTICATION: JsSIP.name() +' | '+ 'DIGEST AUTHENTICATION' +' | ',
LOG_SANITY_CHECK: JsSIP.name() +' | '+ 'SANITY CHECK' +' | ',
LOG_UTILS: JsSIP.name() +' | '+ 'UTILS' +' | ',
LOG_EXCEPTION: JsSIP.name() +' | '+ 'EXCEPTION' +' | ',

// Classes
LOG_TRANSPORT: JsSIP.name() +' | '+ 'TRANSPORT' +' | ',
Expand Down
30 changes: 25 additions & 5 deletions src/exceptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ JsSIP.exceptions = {
var exception = function() {
this.code = 1;
this.name = 'CONFIGURATION_ERROR';
this.message = this.name +': JsSIP Exception '+ this.code;
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
Expand All @@ -23,7 +23,7 @@ JsSIP.exceptions = {
var exception = function() {
this.code = 2;
this.name = 'NOT_READY_ERROR';
this.message = this.name +': JsSIP Exception '+ this.code;
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
Expand All @@ -33,7 +33,7 @@ JsSIP.exceptions = {
var exception = function() {
this.code = 3;
this.name = 'INVALID_TARGET_ERROR';
this.message = this.name +': JsSIP Exception '+ this.code;
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
Expand All @@ -43,7 +43,7 @@ JsSIP.exceptions = {
var exception = function(){
this.code = 4;
this.name = 'WEBRTC_NO_SUPPORTED_ERROR';
this.message = this.name +': JsSIP Exception '+ this.code;
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
Expand All @@ -53,7 +53,27 @@ JsSIP.exceptions = {
var exception = function() {
this.code = 5;
this.name = 'INVALID_STATE_ERROR';
this.message = this.name +': JsSIP Exception '+ this.code;
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
}()),

InvalidMethodError: (function(){
var exception = function() {
this.code = 6;
this.name = 'INVALID_METHOD_ERROR';
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
}()),

InvalidValueError: (function(){
var exception = function() {
this.code = 7;
this.name = 'INVALID_VALUE_ERROR';
this.message = JsSIP.c.LOG_EXCEPTION + this.code;
};
exception.prototype = new Error();
return exception;
Expand Down

0 comments on commit 2c9a310

Please sign in to comment.