From 0aa37a83ae8168b1d0acb29a8a6004541202332b Mon Sep 17 00:00:00 2001 From: Dave Horton Date: Thu, 12 Dec 2024 18:39:15 -0500 Subject: [PATCH] Feat/handle 3pcc invite (#1005) * wip * wip * linting --- lib/session/call-session.js | 61 ++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/lib/session/call-session.js b/lib/session/call-session.js index 0433da75..da884001 100644 --- a/lib/session/call-session.js +++ b/lib/session/call-session.js @@ -400,6 +400,13 @@ class CallSession extends Emitter { return this.application.transferredCall === true; } + /** + * returns true if this session is an inbound call session + */ + get isInboundCallSession() { + return this.constructor.name === 'InboundCallSession'; + } + /** * returns true if this session is a ConfirmCallSession */ @@ -428,6 +435,10 @@ class CallSession extends Emitter { return this.constructor.name === 'SmsCallSession'; } + get is3pccInvite() { + return this.isInboundCallSession && this.req?.body?.length === 0; + } + get webhook_secret() { return this.accountInfo?.account?.webhook_secret; } @@ -2098,7 +2109,6 @@ Duration=${duration} ` //ep.cs = this; this.ep = ep; this.logger.info(`allocated endpoint ${ep.uuid}`); - this._configMsEndpoint(); this.ep.on('destroy', () => { @@ -2260,22 +2270,43 @@ Duration=${duration} ` }, localSdp: this.ep.local.sdp }); - this.logger.debug('answered call'); - this.dlg.on('destroy', this._callerHungup.bind(this)); - this.wrapDialog(this.dlg); - this.dlg.callSid = this.callSid; - this.emit('callStatusChange', {sipStatus: 200, sipReason: 'OK', callStatus: CallStatus.InProgress}); - if (this.recordOptions && this.recordState === RecordState.RecordingOff) { - this.startRecording(); + const tidyUp = () => { + this.dlg.on('destroy', this._callerHungup.bind(this)); + this.wrapDialog(this.dlg); + this.dlg.callSid = this.callSid; + this.emit('callStatusChange', {sipStatus: 200, sipReason: 'OK', callStatus: CallStatus.InProgress}); + + if (this.recordOptions && this.recordState === RecordState.RecordingOff) { + this.startRecording(); + } + this.dlg.on('modify', this._onReinvite.bind(this)); + this.dlg.on('refer', this._onRefer.bind(this)); + if (this.sipRequestWithinDialogHook) { + this.dlg.on('info', this._onRequestWithinDialog.bind(this)); + this.dlg.on('message', this._onRequestWithinDialog.bind(this)); + } + this.logger.debug(`CallSession:propagateAnswer - answered callSid ${this.callSid}`); + }; + + if (this.is3pccInvite) { + return new Promise((resolve, reject) => { + this.dlg.once('ack', (ackRequest) => { + this.logger.debug({body: ackRequest.body}, 'received ACK for 3pcc invite'); + this.ep.modify(ackRequest.body) + .then(() => { + tidyUp(); + return resolve(); + }) + .catch((err) => { + this.logger.info({err}, 'Error modifying endpoint with ACK'); + reject(err); + }); + }); + this.logger.debug('this is a 3pcc invite'); + }); } - this.dlg.on('modify', this._onReinvite.bind(this)); - this.dlg.on('refer', this._onRefer.bind(this)); - if (this.sipRequestWithinDialogHook) { - this.dlg.on('info', this._onRequestWithinDialog.bind(this)); - this.dlg.on('message', this._onRequestWithinDialog.bind(this)); - } - this.logger.debug(`CallSession:propagateAnswer - answered callSid ${this.callSid}`); + tidyUp(); } else { this.logger.debug('CallSession:propagateAnswer - call already answered - re-anchor media with a reinvite');