Skip to content

Commit

Permalink
wip (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
davehorton authored Nov 19, 2024
1 parent b976a62 commit 916d577
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 7 deletions.
4 changes: 4 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ const {
decrKey,
retrieveSet,
isMemberOfSet,
addKey,
retrieveKey
} = require('@jambonz/realtimedb-helpers')({}, logger);

const activeCallIds = new Map();
Expand Down Expand Up @@ -101,6 +103,8 @@ srf.locals = {...srf.locals,
},
realtimeDbHelpers: {
client: redisClient,
addKey,
retrieveKey,
createHash,
retrieveHash,
incrKey,
Expand Down
54 changes: 48 additions & 6 deletions lib/call-session.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
const Emitter = require('events');
const sdpTransform = require('sdp-transform');
const SrsClient = require('@jambonz/siprec-client-utils');
const {makeRtpEngineOpts, nudgeCallCounts, isPrivateVoipNetwork, isBlackListedSipGateway} = require('./utils');
const {
makeRtpEngineOpts,
nudgeCallCounts,
isPrivateVoipNetwork,
isBlackListedSipGateway,
makeFullMediaReleaseKey,
makePartnerFullMediaReleaseKey
} = require('./utils');
const { MediaPath } = require('./constants.json');
const {forwardInDialogRequests} = require('drachtio-fn-b2b-sugar');
const {SipError, stringifyUri, parseUri} = require('drachtio-srf');
const debug = require('debug')('jambonz:sbc-outbound');
Expand Down Expand Up @@ -111,6 +119,8 @@ class CallSession extends Emitter {
this.writeCdrs = this.srf.locals.writeCdrs;

this.decrKey = req.srf.locals.realtimeDbHelpers.decrKey;
this.addKey = req.srf.locals.realtimeDbHelpers.addKey;
this.retrieveKey = req.srf.locals.realtimeDbHelpers.retrieveKey;

const {
lookupOutboundCarrierForAccount,
Expand All @@ -123,7 +133,8 @@ class CallSession extends Emitter {
this.lookupSipGatewaysByCarrier = lookupSipGatewaysByCarrier;
this.lookupCarrierByAccountLcr = lookupCarrierByAccountLcr;

this._mediaReleased = false;
this._mediaPath = MediaPath.FullMedia;

this.recordingNoAnswerTimeout = (process.env.JAMBONES_RECORDING_NO_ANSWER_TIMEOUT || 2) * 1000;
}

Expand All @@ -144,7 +155,7 @@ class CallSession extends Emitter {
}

get isMediaReleased() {
return this._mediaReleased;
return this._mediaPath !== MediaPath.FullMedia;
}

subscribeForDTMF(dlg) {
Expand Down Expand Up @@ -651,6 +662,15 @@ class CallSession extends Emitter {
answered_at: callStart
};
}

/* save far end SDP for later use if we do a full media release */
if (process.env.JAMBONES_ENABLE_FULL_MEDIA_RELEASE) {
const key = makeFullMediaReleaseKey(this.req.get('X-CID'));
const sdp = uac.remote.sdp;
this.logger.info({key, sdp}, 'saving far end sdp for full media release feature');
this.addKey(key, sdp, 3600).catch((err) => this.logger.error(err, 'Error saving far end sdp'));
}

this.uas = uas;
this.uac = uac;
[uas, uac].forEach((dlg) => {
Expand Down Expand Up @@ -807,11 +827,32 @@ Duration=${payload.duration} `
try {
const reason = req.get('X-Reason');
const isReleasingMedia = reason && dlg.type === 'uas' && ['release-media', 'anchor-media'].includes(reason);
const isFullMediaRelease = reason === 'release-media-entirely' && process.env.JAMBONES_ENABLE_FULL_MEDIA_RELEASE;
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'];

if (isFullMediaRelease) {
const a_sdp = await this.retrieveKey(makePartnerFullMediaReleaseKey(this.req.get('X-CID')));
this.logger.info({a_sdp}, 'reinvite ourselves out of the media path with this reinvite offer');
const answerSdp = await dlg.other.modify(a_sdp);
this.logger.info({answerSdp}, 'far end response to full media release');
res.send(200, {
body: dlg.local.sdp,
headers: {
'Contact': this.contactHeader
}
});
/* no media going through us now we can destroy the rtpengine resource */
this.rtpEngineResource.destroy().catch((err) => {
this.logger.info({err}, 'Error destroying rtpengine resource after full media release');
});
this._mediaPath = MediaPath.NoMedia;
return;
}

if (isReleasingMedia) {
if (!offerMedia.flags.includes('port latching')) offerMedia.flags.push('port latching');
if (!offerMedia.flags.includes('asymmetric')) offerMedia.flags.push('asymmetric');
Expand Down Expand Up @@ -839,17 +880,18 @@ Duration=${payload.duration} `
let sdp;
//HL 2024-11-13: previously forwarded re-invites to webrtc clients but further testing has shown to be unnecessary
//if (isReleasingMedia && !this.calleeIsUsingSrtp) {
if (isReleasingMedia) {

//DH 2024-11- 18: if we are going from no-media to either partial or full media, we need reinvite the far end
if (isReleasingMedia && this._mediaPath !== MediaPath.NoMedia) {
this.logger.info(`got a reinvite from FS to ${reason}`);
sdp = dlg.other.remote.sdp;
if (!answerMedia.flags.includes('port latching')) answerMedia.flags.push('port latching');
if (!answerMedia.flags.includes('asymmetric')) answerMedia.flags.push('asymmetric');
answerMedia.flags = answerMedia.flags.filter((f) => f !== 'media handover');
this._mediaReleased = 'release-media' === reason;
this._mediaPath = 'release-media' === reason ? MediaPath.PartialMedia : MediaPath.FullMedia;
}
else {
sdp = await dlg.other.modify(response.sdp);
this.logger.info({sdp}, 'CallSession:_onReinvite: got sdp from 200 OK to invite we sent');
}
opts = {
...this.rtpEngineOpts.common,
Expand Down
7 changes: 7 additions & 0 deletions lib/constants.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"MediaPath": {
"NoMedia": "no-media",
"PartialMedia": "partial-media",
"FullMedia": "full-media"
}
}
11 changes: 10 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ async function isBlackListedSipGateway(client, logger, sip_gateway_sid) {
}
}

const makeFullMediaReleaseKey = (callId) => {
return `b_sdp:${callId}`;
};
const makePartnerFullMediaReleaseKey = (callId) => {
return `a_sdp:${callId}`;
};

module.exports = {
makeRtpEngineOpts,
selectHostPort,
Expand All @@ -244,5 +251,7 @@ module.exports = {
createHealthCheckApp,
nudgeCallCounts,
isPrivateVoipNetwork,
isBlackListedSipGateway
isBlackListedSipGateway,
makeFullMediaReleaseKey,
makePartnerFullMediaReleaseKey
};

0 comments on commit 916d577

Please sign in to comment.