Dial: dtmf detection now based on SIP INFO events from sbcs and rtpengine

This commit is contained in:
Dave Horton
2021-10-12 12:22:52 -04:00
parent 05d85d96e2
commit 740c2b89b4

View File

@@ -131,7 +131,7 @@ class TaskDial extends Task {
get name() { return TaskName.Dial; } get name() { return TaskName.Dial; }
get canReleaseMedia() { get canReleaseMedia() {
return !process.env.ANCHOR_MEDIA_ALWAYS && !this.dtmfHook && !this.listenTask && !this.transcribeTask; return !process.env.ANCHOR_MEDIA_ALWAYS && !this.listenTask && !this.transcribeTask;
} }
async exec(cs) { async exec(cs) {
@@ -146,13 +146,12 @@ class TaskDial extends Task {
this.epOther.play(this.dialMusic).catch((err) => {}); this.epOther.play(this.dialMusic).catch((err) => {});
} }
} }
if (this.epOther) this._installDtmfDetection(cs, this.epOther, this.parentDtmfCollector);
await this._attemptCalls(cs); await this._attemptCalls(cs);
await this.awaitTaskDone(); await this.awaitTaskDone();
this.logger.debug({callSid: this.cs.callSid}, 'Dial:exec task is done, sending actionHook if any'); this.logger.debug({callSid: this.cs.callSid}, 'Dial:exec task is done, sending actionHook if any');
await this.performAction(this.results, this.killReason !== KillReason.Replaced); await this.performAction(this.results, this.killReason !== KillReason.Replaced);
this._removeDtmfDetection(cs, this.epOther); this._removeDtmfDetection(cs.dlg);
this._removeDtmfDetection(cs, this.ep); this._removeDtmfDetection(this.dlg);
} catch (err) { } catch (err) {
this.logger.error({err}, 'TaskDial:exec terminating with error'); this.logger.error({err}, 'TaskDial:exec terminating with error');
this.kill(cs); this.kill(cs);
@@ -162,8 +161,8 @@ class TaskDial extends Task {
async kill(cs, reason) { async kill(cs, reason) {
super.kill(cs); super.kill(cs);
this.killReason = reason || KillReason.Hangup; this.killReason = reason || KillReason.Hangup;
this._removeDtmfDetection(this.cs, this.epOther); this._removeDtmfDetection(cs.dlg);
this._removeDtmfDetection(this.cs, this.ep); this._removeDtmfDetection(this.dlg);
this._killOutdials(); this._killOutdials();
if (this.sd) { if (this.sd) {
this.sd.kill(); this.sd.kill();
@@ -236,35 +235,39 @@ class TaskDial extends Task {
this.dials.clear(); this.dials.clear();
} }
_installDtmfDetection(cs, ep, dtmfDetector) { _installDtmfDetection(cs, dlg) {
if (ep && this.dtmfHook && !ep.dtmfDetector) { dlg.on('info', this._onInfo.bind(this, cs, dlg));
ep.dtmfDetector = dtmfDetector;
ep.on('dtmf', this._onDtmf.bind(this, cs, ep));
}
} }
_removeDtmfDetection(cs, ep) { _removeDtmfDetection(dlg) {
if (ep) { dlg && dlg.removeAllListeners('info');
delete ep.dtmfDetector;
ep.removeAllListeners('dtmf');
}
} }
_onDtmf(cs, ep, evt) { _onInfo(cs, dlg, req, res) {
if (ep.dtmfDetector) { res.send(200);
const match = ep.dtmfDetector.keyPress(evt.dtmf); if (req.get('Content-Type') !== 'application/dtmf-relay') return;
if (match) {
this.logger.debug({callSid: this.cs.callSid}, `Dial:_onDtmf triggered dtmf match: ${match}`); const dtmfDetector = dlg === cs.dlg ? this.parentDtmfCollector : this.childDtmfCollector;
const requestor = ep.dtmfDetector === this.parentDtmfCollector ? if (!dtmfDetector) return;
cs.requestor : let requestor, callSid, callInfo;
(this.sd ? this.sd.requestor : null); if (dtmfDetector === this.parentDtmfCollector) {
if (!requestor) { requestor = cs.requestor;
this.logger.info(`Dial:_onDtmf got digits on B leg after adulting: ${evt.dtmf}`); callSid = cs.callSid;
} callInfo = cs.callInfo;
else { }
requestor.request(this.dtmfHook, {dtmf: match, ...cs.callInfo.toJSON()}) else {
.catch((err) => this.logger.info(err, 'Dial:_onDtmf - error')); requestor = this.sd?.requestor;
} callSid = this.sd?.callSid;
} callInfo = this.sd?.callInfo;
}
if (!requestor) return;
const arr = /Signal=([0-9#*])/.exec(req.body);
if (!arr) return;
const key = arr[1];
const match = dtmfDetector.keyPress(key);
if (match) {
this.logger.info({callSid}, `Dial:_onInfo triggered dtmf match: ${match}`);
requestor.request(this.dtmfHook, {dtmf: match, ...callInfo.toJSON()})
.catch((err) => this.logger.info(err, 'Dial:_onDtmf - error'));
} }
} }
@@ -274,7 +277,6 @@ class TaskDial extends Task {
debug(`Dial:__initializeInbound allocated ep for incoming call: ${ep.uuid}`); debug(`Dial:__initializeInbound allocated ep for incoming call: ${ep.uuid}`);
/* send outbound legs back to the same SBC (to support static IP feature) */ /* send outbound legs back to the same SBC (to support static IP feature) */
//if (!this.proxy) this.proxy = `${cs.req.source_address}:${cs.req.source_port};transport=tcp`;
if (!this.proxy) this.proxy = `${cs.req.source_address}:${cs.req.source_port}`; if (!this.proxy) this.proxy = `${cs.req.source_address}:${cs.req.source_port}`;
if (this.dialMusic) { if (this.dialMusic) {
@@ -478,7 +480,8 @@ class TaskDial extends Task {
dialCallSid: sd.callSid, dialCallSid: sd.callSid,
}); });
if (this.childDtmfCollector) this._installDtmfDetection(cs, this.ep, this.childDtmfCollector); if (this.parentDtmfCollector) this._installDtmfDetection(cs, cs.dlg);
if (this.childDtmfCollector) this._installDtmfDetection(cs, this.dlg);
if (this.transcribeTask) this.transcribeTask.exec(cs, this.ep); if (this.transcribeTask) this.transcribeTask.exec(cs, this.ep);
if (this.listenTask) this.listenTask.exec(cs, this.ep); if (this.listenTask) this.listenTask.exec(cs, this.ep);