bugfix: re-invite handling from UAC side now handled properly

This commit is contained in:
Dave Horton
2021-04-27 08:16:36 -04:00
parent 238f3fe05a
commit e3963bf057
2 changed files with 52 additions and 33 deletions

View File

@@ -79,7 +79,13 @@ class CallSession extends Emitter {
this.logger.info(`uri will be: ${uri}, proxy ${proxy}`);
try {
const opts = Object.assign(this.rtpEngineOpts.offer, {sdp: this.req.body});
const opts = {
...this.rtpEngineOpts.common,
...this.rtpEngineOpts.uac.mediaOpts,
'from-tag': this.rtpEngineOpts.uas.tag,
direction: ['public', 'private'],
sdp: this.req.body
};
const response = await this.offer(opts);
this.logger.debug({opts, response}, 'response from rtpengine to offer');
if ('ok' !== response.result) {
@@ -129,8 +135,14 @@ class CallSession extends Emitter {
proxyResponseHeaders: ['all'],
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);
if ('ok' !== response.result) {
this.logger.error(`rtpengine answer failed with ${JSON.stringify(response)}`);
@@ -190,8 +202,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._onFeatureServerReinvite.bind(this, uac));
uac.on('refer', this._onFeatureServerTransfer.bind(this, uac));
uas.on('refer', this._onRefer.bind(this, uas));
@@ -253,41 +265,44 @@ class CallSession extends Emitter {
async _onReinvite(dlg, req, res) {
try {
let opts = Object.assign(this.rtpEngineOpts.offer, {sdp: req.body, 'to-tag': this.toTag});
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)}`);
}
this.logger.info({opts, response}, 'sent offer for reinvite to rtpengine');
const sdp = await dlg.other.modify(response.sdp);
opts = Object.assign(this.rtpEngineOpts.answer, {sdp});
opts = {
...this.rtpEngineOpts.common,
...answerMedia,
'from-tag': fromTag,
'to-tag': toTag,
sdp
};
response = await this.answer(opts);
if ('ok' !== response.result) {
res.send(488);
throw new Error(`_onReinvite: rtpengine failed: ${JSON.stringify(response)}`);
}
this.logger.info({opts, response}, 'sent answer for reinvite to rtpengine');
res.send(200, {body: response.sdp});
} catch (err) {
this.logger.error(err, 'Error handling reinvite');
}
}
async _onFeatureServerReinvite(dlg, req, res) {
try {
const opts = Object.assign(this.rtpEngineOpts.answer, {sdp: req.body, 'to-tag': this.toTag});
const response = await this.answer(opts);
if ('ok' !== response.result) {
res.send(488);
throw new Error(`_onFeatureServerReinvite: rtpengine failed: ${JSON.stringify(response)}`);
}
res.send(200, {body: dlg.local.sdp});
} catch (err) {
this.logger.error(err, 'Error handling reinvite from feature server');
}
}
async _onFeatureServerTransfer(dlg, req, res) {
try {
const referTo = req.getParsedHeader('Refer-To');

View File

@@ -12,20 +12,24 @@ function getAppserver(srf) {
}
function makeRtpEngineOpts(req, srcIsUsingSrtp, dstIsUsingSrtp, teams = false) {
const srtpOpts = teams ? srtpCharacteristics['teams'] : srtpCharacteristics['default'];
const from = req.getParsedHeader('from');
const common = {'call-id': req.get('Call-ID'), 'from-tag': from.params.tag};
const srtpOpts = teams ? srtpCharacteristics['teams'] : srtpCharacteristics['default'];
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': [ 'public', 'private']},
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
}
};
}