diff --git a/lib/call-session.js b/lib/call-session.js index ec2479c..aa1363d 100644 --- a/lib/call-session.js +++ b/lib/call-session.js @@ -129,9 +129,16 @@ class CallSession extends Emitter { // rtpengine 'offer' debug('sending offer command to rtpengine'); - const response = await this.offer(this.rtpEngineOpts.offer, {sdp: this.req.body}); + const opts = { + ...this.rtpEngineOpts.common, + ...this.rtpEngineOpts.uac.mediaOpts, + 'from-tag': this.rtpEngineOpts.uas.tag, + direction: ['private', 'public'], + sdp: this.req.body + }; + const response = await this.offer(opts); debug(`response from rtpengine to offer ${JSON.stringify(response)}`); - this.logger.debug({offer: this.rtpEngineOpts.offer, response}, 'initial offer to rtpengine'); + this.logger.debug({offer: opts, response}, 'initial offer to rtpengine'); if ('ok' !== response.result) { this.logger.error(`rtpengine offer failed with ${JSON.stringify(response)}`); throw new Error('rtpengine failed: answer'); @@ -171,8 +178,14 @@ class CallSession extends Emitter { auth, localSdpB: response.sdp, localSdpA: async(sdp, res) => { - this.toTag = res.getParsedHeader('To').params.tag; - const opts = Object.assign(this.rtpEngineOpts.answer, {sdp, 'to-tag': this.toTag}); + this.rtpEngineOpts.uac.tag = res.getParsedHeader('To').params.tag; + const opts = { + ...this.rtpEngineOpts.common, + ...this.rtpEngineOpts.uas.mediaOpts, + 'from-tag': this.rtpEngineOpts.uas.tag, + 'to-tag': this.rtpEngineOpts.uac.tag, + sdp + }; const response = await this.answer(opts); this.logger.debug({answer: opts, response}, 'rtpengine answer'); if ('ok' !== response.result) { @@ -254,8 +267,8 @@ class CallSession extends Emitter { }); uas.on('modify', this._onReinvite.bind(this, uas)); + uac.on('modify', this._onReinvite.bind(this, uac)); - uac.on('modify', this._onNetworkReinvite.bind(this, uac)); uas.on('refer', this._onFeatureServerTransfer.bind(this, uas)); @@ -265,13 +278,33 @@ class CallSession extends Emitter { async _onReinvite(dlg, req, res) { try { - let response = await this.offer(Object.assign(this.rtpEngineOpts.offer, {sdp: req.body})); + const fromTag = dlg.type === 'uas' ? this.rtpEngineOpts.uas.tag : this.rtpEngineOpts.uac.tag; + const toTag = dlg.type === 'uas' ? this.rtpEngineOpts.uac.tag : this.rtpEngineOpts.uas.tag; + const offerMedia = dlg.type === 'uas' ? this.rtpEngineOpts.uac.mediaOpts : this.rtpEngineOpts.uas.mediaOpts; + const answerMedia = dlg.type === 'uas' ? this.rtpEngineOpts.uas.mediaOpts : this.rtpEngineOpts.uac.mediaOpts; + const direction = dlg.type === 'uas' ? ['private', 'public'] : ['public', 'private']; + let opts = { + ...this.rtpEngineOpts.common, + ...offerMedia, + 'from-tag': fromTag, + 'to-tag': toTag, + direction, + sdp: req.body, + }; + + let response = await this.offer(opts); if ('ok' !== response.result) { res.send(488); throw new Error(`_onReinvite: rtpengine failed: offer: ${JSON.stringify(response)}`); } const sdp = await dlg.other.modify(response.sdp); - const opts = Object.assign(this.rtpEngineOpts.answer, {sdp, 'to-tag': res.getParsedHeader('To').params.tag}); + opts = { + ...this.rtpEngineOpts.common, + ...answerMedia, + 'from-tag': fromTag, + 'to-tag': toTag, + sdp + }; response = await this.answer(opts); if ('ok' !== response.result) { res.send(488); @@ -283,32 +316,6 @@ class CallSession extends Emitter { } } - async _onNetworkReinvite(dlg, req, res) { - try { - const newAnswerOpts = Object.assign({}, this.rtpEngineOpts.answer, {sdp: req.body}); - let response = await this.answer(newAnswerOpts); - this.logger.debug({answer: newAnswerOpts, response}, '_onNetworkReinvite: answer to rtpengine'); - if ('ok' !== response.result) { - res.send(488); - throw new Error(`_onReinvite: rtpengine failed: offer: ${JSON.stringify(response)}`); - } - - // reinvite feature server - const sdp = await dlg.other.modify(response.sdp); - - const newOfferOpts = Object.assign({}, this.rtpEngineOpts.offer, {sdp, 'to-tag': this.toTag}); - response = await this.offer(newOfferOpts); - this.logger.debug({answer: newOfferOpts, response}, '_onNetworkReinvite: offer to rtpengine'); - if ('ok' !== response.result) { - res.send(488); - throw new Error(`_onReinvite: rtpengine failed: ${JSON.stringify(response)}`); - } - res.send(200, {body: response.sdp}); - } catch (err) { - this.logger.error(err, 'Error handling reinvite'); - } - } - async _onFeatureServerTransfer(dlg, req, res) { try { const referTo = req.getParsedHeader('Refer-To'); diff --git a/lib/utils.js b/lib/utils.js index a6ca9a0..82126c4 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -5,18 +5,22 @@ const debug = require('debug')('jambonz:sbc-outbound'); function makeRtpEngineOpts(req, srcIsUsingSrtp, dstIsUsingSrtp, teams = false) { const from = req.getParsedHeader('from'); const srtpOpts = teams ? srtpCharacteristics['teams'] : srtpCharacteristics['default']; - const common = {'call-id': req.get('Call-ID'), 'from-tag': from.params.tag}; + const dstOpts = dstIsUsingSrtp ? srtpOpts : rtpCharacteristics; + const srctOpts = srcIsUsingSrtp ? srtpOpts : rtpCharacteristics; + const common = { + 'call-id': req.get('Call-ID'), + 'replace': ['origin', 'session-connection'] + }; return { common, - offer: Object.assign( - {'sdp': req.body, 'replace': ['origin', 'session-connection']}, - {'direction': [ 'private', 'public']}, - common, - dstIsUsingSrtp ? srtpOpts : rtpCharacteristics), - answer: Object.assign( - {'replace': ['origin', 'session-connection']}, - common, - srcIsUsingSrtp ? srtpOpts : rtpCharacteristics) + uas: { + tag: from.params.tag, + mediaOpts: srctOpts + }, + uac: { + tag: null, + mediaOpts: dstOpts + } }; }