Skip to content

Commit

Permalink
INFO-based DTMF fixes
Browse files Browse the repository at this point in the history
Fixes #137
- Queue additional DTMF sends
- Fix inter-tone timing
- Insert a pause if the next tone is a comma
  • Loading branch information
Gavin Llewellyn committed Jul 22, 2013
1 parent d141864 commit a327be3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 39 deletions.
78 changes: 53 additions & 25 deletions src/RTCSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ RTCSession = function(ua) {
this.remote_identity = null;
this.start_time = null;
this.end_time = null;
this.tones = null;

// Custom session empty object for high level use
this.data = {};
Expand Down Expand Up @@ -298,12 +299,12 @@ RTCSession.prototype.answer = function(options) {
* @param {Object} [options]
*/
RTCSession.prototype.sendDTMF = function(tones, options) {
var timer, interToneGap,
possition = 0,
self = this,
ready = true;
var duration, interToneGap,
position = 0,
self = this;

options = options || {};
duration = options.duration || null;
interToneGap = options.interToneGap || null;

if (tones === undefined) {
Expand All @@ -316,12 +317,28 @@ RTCSession.prototype.sendDTMF = function(tones, options) {
}

// Check tones
if (!tones || (typeof tones !== 'string' && typeof tones !== 'number') || !tones.toString().match(/^[0-9A-D#*]+$/i)) {
if (!tones || (typeof tones !== 'string' && typeof tones !== 'number') || !tones.toString().match(/^[0-9A-D#*,]+$/i)) {
throw new TypeError('Invalid tones: '+ tones);
}

tones = tones.toString();

// Check duration
if (duration && !JsSIP.Utils.isDecimal(duration)) {
throw new TypeError('Invalid tone duration: '+ duration);
} else if (!duration) {
duration = DTMF.C.DEFAULT_DURATION;
} else if (duration < DTMF.C.MIN_DURATION) {
console.warn(LOG_PREFIX +'"duration" value is lower than the minimum allowed, setting it to '+ DTMF.C.MIN_DURATION+ ' milliseconds');
duration = DTMF.C.MIN_DURATION;
} else if (duration > DTMF.C.MAX_DURATION) {
console.warn(LOG_PREFIX +'"duration" value is greater than the maximum allowed, setting it to '+ DTMF.C.MAX_DURATION +' milliseconds');
duration = DTMF.C.MAX_DURATION;
} else {
duration = Math.abs(duration);
}
options.duration = duration;

// Check interToneGap
if (interToneGap && !JsSIP.Utils.isDecimal(interToneGap)) {
throw new TypeError('Invalid interToneGap: '+ interToneGap);
Expand All @@ -334,32 +351,43 @@ RTCSession.prototype.sendDTMF = function(tones, options) {
interToneGap = Math.abs(interToneGap);
}

function sendDTMF() {
var tone,
dtmf = new DTMF(self);
if (this.tones) {
// Tones are already queued, just add to the queue
this.tones += tones;
return;
}

// New set of tones to start sending
this.tones = tones;

dtmf.on('failed', function(){ready = false;});
var sendDTMF = function () {
var tone, timeout,
tones = self.tones;

tone = tones[possition];
possition += 1;
if (self.status === C.STATUS_TERMINATED || !tones || position >= tones.length) {
// Stop sending DTMF
self.tones = null;
return;
}

dtmf.send(tone, options);
}
tone = tones[position];
position += 1;

if (tone === ',') {
timeout = 2000;
} else {
var dtmf = new DTMF(self);
dtmf.on('failed', function(){self.tones = null;});
dtmf.send(tone, options);
timeout = duration + interToneGap;
}

// Set timeout for the next tone
window.setTimeout(sendDTMF, timeout);
};

// Send the first tone
sendDTMF();

// Send the following tones
timer = window.setInterval(
function() {
if (self.status !== C.STATUS_TERMINATED && ready && tones.length > possition) {
sendDTMF();
} else {
window.clearInterval(timer);
}
},
interToneGap
);
};


Expand Down
15 changes: 1 addition & 14 deletions src/RTCSession/DTMF.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,7 @@ DTMF.prototype.send = function(tone, options) {
this.tone = tone;
}

// Check duration
if (options.duration && !JsSIP.Utils.isDecimal(options.duration)) {
throw new TypeError('Invalid tone duration: '+ options.duration);
} else if (!options.duration) {
options.duration = C.DEFAULT_DURATION;
} else if (options.duration < C.MIN_DURATION) {
console.warn(LOG_PREFIX +'"duration" value is lower than the minimum allowed, setting it to '+ C.MIN_DURATION+ ' milliseconds');
options.duration = C.MIN_DURATION;
} else if (options.duration > C.MAX_DURATION) {
console.warn(LOG_PREFIX +'"duration" value is greater than the maximum allowed, setting it to '+ C.MAX_DURATION +' milliseconds');
options.duration = C.MAX_DURATION;
} else {
options.duration = Math.abs(options.duration);
}
// Duration is checked/corrected in RTCSession
this.duration = options.duration;

// Set event handlers
Expand Down

0 comments on commit a327be3

Please sign in to comment.