reinvite changes

This commit is contained in:
Dave Horton
2020-04-26 09:59:38 -04:00
parent 521e540901
commit 160f888643
+75 -13
View File
@@ -87,6 +87,7 @@ class CallSession extends Emitter {
debug('sending offer command to rtpengine');
const response = await this.offer(this.rtpEngineOpts.offer);
debug(`response from rtpengine to offer ${JSON.stringify(response)}`);
this.logger.debug({offer: this.rtpEngineOpts.offer, 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');
@@ -113,8 +114,8 @@ class CallSession extends Emitter {
this.toTag = res.getParsedHeader('To').params.tag;
const opts = Object.assign({sdp, 'to-tag': this.toTag},
this.rtpEngineOpts.answer);
this.logger.debug({opts}, 'calling rtpengine answer with these opts');
const response = await this.answer(opts);
this.logger.debug({answer: opts, response}, 'rtpengine answer');
if ('ok' !== response.result) {
this.logger.error(`rtpengine answer failed with ${JSON.stringify(response)}`);
throw new Error('rtpengine failed: answer');
@@ -177,42 +178,103 @@ class CallSession extends Emitter {
this.logger.info('call ended');
this.rtpEngineResource.destroy();
this.activeCallIds.delete(this.req.get('Call-ID'));
dlg.other.destroy();
});
//re-invite
dlg.on('modify', this._onReinvite.bind(this, dlg));
});
uas.on('modify', this._onReinvite.bind(this, uas));
uac.on('modify', this._onNetworkReinvite.bind(this, uac));
uas.on('refer', this._onFeatureServerTransfer.bind(this, uas));
uac.on('hold', () => this.logger.info('invite on hold from network side'));
uac.on('unhold', () => this.logger.info('invite off hold from network side'));
// default forwarding of other request types
forwardInDialogRequests(uas);
forwardInDialogRequests(uac);
}
async _onReinvite(dlg, req, res) {
try {
const optOffer = Object.assign(this.rtpEngineOpts.offer, {sdp: req.body, 'to-tag': this.toTag});
this.logger.debug({opts: optOffer}, 'got reinvite, calling rtpengine offer with these opts');
let response = await this.offer(optOffer);
let response = await this.offer(Object.assign({sdp: req.body}, this.rtpEngineOpts.offer));
if ('ok' !== response.result) {
res.send(488);
throw new Error(`_onReinvite: rtpengine failed: offer: ${JSON.stringify(response)}`);
}
this.logger.debug({sdp: response.sdp}, 'rtpengine offer returned');
const sdp = await dlg.other.modify(response.sdp);
this.logger.debug({sdp}, 'reinvite to feature server returned');
const opts = Object.assign(this.rtpEngineOpts.answer, {sdp, 'to-tag': this.toTag});
this.logger.debug({opts}, 'in reinvite, calling rtpengine answer with these opts');
const opts = Object.assign({sdp, 'to-tag': res.getParsedHeader('To').params.tag},
this.rtpEngineOpts.answer);
response = await this.answer(opts);
if ('ok' !== response.result) {
res.send(488);
throw new Error(`_onReinvite: rtpengine failed: ${JSON.stringify(response)}`);
}
this.logger.debug({sdp: response.sdp}, 'rtpengine answer returned');
res.send(200, {body: response.sdp});
} catch (err) {
this.logger.error(err, 'Error handling reinvite');
}
}
async _onNetworkReinvite(dlg, req, res) {
try {
const opts = Object.assign({sdp: req.body, 'to-tag': this.toTag}, this.rtpEngineOpts.answer);
const response = await this.answer(opts);
this.logger.debug({answer: opts, response}, '_onNetworkReinvite: rtpengine answer');
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');
const uri = parseUri(referTo.uri);
this.logger.info({uri, referTo}, 'received REFER from feature server');
const arr = /context-(.*)/.exec(uri.user);
if (!arr) {
this.logger.info(`invalid Refer-To header: ${referTo.uri}`);
return res.send(501);
}
res.send(202);
// invite to new fs
const dlg = await this.srf.createUAC(referTo.uri, {localSdp: dlg.local.sdp});
this.uas.destroy();
this.uas = dlg;
this.uas.other = this.uac;
this.uac.other = this.uas;
this.uas.on('modify', this._onReinvite.bind(this, this.uas));
this.uas.on('refer', this._onFeatureServerTransfer.bind(this, this.uas));
this.uas.on('destroy', () => {
this.logger.info('call ended with normal termination');
this.rtpEngineResource.destroy();
this.activeCallIds.delete(this.req.get('Call-ID'));
this.uas.other.destroy();
});
// modify rtpengine to stream to new feature server
let response = await this.offer(Object.assign(this.rtpEngineOpts.offer, {sdp: this.uas.remote.sdp}));
if ('ok' !== response.result) {
throw new Error(`_onReinvite: rtpengine failed: offer: ${JSON.stringify(response)}`);
}
const sdp = await this.uas.other.modify(response.sdp);
const opts = Object.assign({sdp, 'to-tag': res.getParsedHeader('To').params.tag},
this.rtpEngineOpts.answer);
response = await this.answer(opts);
if ('ok' !== response.result) {
throw new Error(`_onReinvite: rtpengine failed: ${JSON.stringify(response)}`);
}
this.logger.info('successfully moved call to new feature server');
} catch (err) {
this.logger.error(err, 'Error handling refer from feature server');
}
}
}
module.exports = CallSession;