diff --git a/lib/session/call-session.js b/lib/session/call-session.js index beec54d9..668da628 100644 --- a/lib/session/call-session.js +++ b/lib/session/call-session.js @@ -796,9 +796,9 @@ class CallSession extends Emitter { } } - if (0 === this.tasks.length && ((this.requestor instanceof WsRequestor && !this.callGone) || - // Tasks are all done, but dialog is not establish yet, waiting for cancel/handup the call. - !this.dlg)) { + if (0 === this.tasks.length && ((this.requestor instanceof WsRequestor && !this.callGone)|| + // Tasks are all done, but outgoing dialog is not establish yet, waiting for cancel/handup the call. + !this.dlg && !this.isFinalStatus() && this.direction === CallDirection.Outbound)) { //let span; try { //const {span} = this.rootSpan.startChildSpan('waiting for commands'); @@ -1793,16 +1793,15 @@ class CallSession extends Emitter { this.updateCallStatus(Object.assign({}, this.callInfo.toJSON()), this.serviceUrl) .catch((err) => this.logger.error(err, 'redis error')); - if (this.wakeupResolver && !this.dlg && this.isCurrentCallStatusHigherThan(CallStatus.Failed)) { + if (this.wakeupResolver && !this.dlg && this.isFinalStatus()) { // Someone is waiting for call to be final this.wakeupResolver({reason: 'session ended'}); this.wakeupResolver = null; } } - isCurrentCallStatusHigherThan(target) { - const obj = Object.values(CallStatus); - return obj.indexOf(this.callStatus) >= obj.indexOf(target); + isFinalStatus() { + return [CallStatus.Failed, CallStatus.Busy, CallStatus.NoAnswer, CallStatus.Completed].includes(this.callStatus) } async executeStatusCallback(callStatus, sipStatus) { diff --git a/test/index.js b/test/index.js index 033f6c8b..e487496d 100644 --- a/test/index.js +++ b/test/index.js @@ -15,5 +15,6 @@ require('./sip-refer-tests'); require('./listen-tests'); require('./config-test'); require('./queue-test'); +require('./sip-decline-test'); require('./remove-test-db'); require('./docker_stop'); \ No newline at end of file diff --git a/test/sip-decline-test.js b/test/sip-decline-test.js new file mode 100644 index 00000000..94e8fe90 --- /dev/null +++ b/test/sip-decline-test.js @@ -0,0 +1,56 @@ +const test = require('tape'); +const { sippUac } = require('./sipp')('test_fs'); +const clearModule = require('clear-module'); +const {provisionCallHook} = require('./utils'); +const bent = require('bent'); +const getJSON = bent('json'); + +process.on('unhandledRejection', (reason, p) => { + console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); +}); + +function connect(connectable) { + return new Promise((resolve, reject) => { + connectable.on('connect', () => { + return resolve(); + }); + }); +} + + +test('\'sip:decline\' tests', async(t) => { + clearModule.all(); + const {srf, disconnect} = require('../app'); + + try { + await connect(srf); + + // GIVEN + const verbs = [ + { + "verb": "sip:decline", + "status": 480, + "reason": "Gone Fishing", + "headers" : { + "Retry-After": 1800 + } + } + + ]; + + const from = 'sip_delecine_success'; + await provisionCallHook(from, verbs) + + // THEN + await sippUac('uac-invite-expect-480.xml', '172.38.0.10', from); + + let obj = await getJSON(`http:127.0.0.1:3100/requests/${from}_callStatus`); + t.ok(obj.map((o) => o.body.call_status).includes('failed'), + 'sip:decline: status callback successfully executed'); + disconnect(); + } catch (err) { + console.log(`error received: ${err}`); + disconnect(); + t.error(err); + } +}); \ No newline at end of file