mirror of
https://github.com/jambonz/sbc-outbound.git
synced 2026-10-04 02:04:19 +00:00
Compare commits
10
Commits
v0.9.6-rc4
..
v0.9.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffec713d62 | ||
|
|
6921c1cf31 | ||
|
|
37e4dea705 | ||
|
|
4fb5acaf40 | ||
|
|
865068f158 | ||
|
|
4f65b4b585 | ||
|
|
8ccd02aa1f | ||
|
|
0911032146 | ||
|
|
121ae75b39 | ||
|
|
57bc073ea3 |
@@ -29,9 +29,19 @@ Configuration is provided via environment variables:
|
||||
|JAMBONES_RTPENGINES| commans-separated list of ip:ng-port for rtpengines (e.g. '172.31.32.10:22222')|yes|
|
||||
|JAMBONES_TIME_SERIES_HOST| influxdb host |yes|
|
||||
|JAMBONES_RECORD_ALL_CALLS| enable auto record calls |no|
|
||||
|JAMBONES_CODEC_OFFER_WITH_ORDER| comma-separated codec list to use as the outbound offer toward the carrier; the original codecs from the feature server are stripped first (e.g. `'opus,PCMU,PCMA,telephone-event'`) |no|
|
||||
|JAMBONES_CODEC_TRANSCODE| comma-separated codec list that rtpengine should add to the outbound offer and transcode on the fly when the carrier selects them — used to support codecs the feature server does not speak (e.g. `'AMR-WB/16000'`). Requires an rtpengine build that includes the corresponding codec module. |no|
|
||||
|JAMBONES_ACCEPT_AND_TRANSCODE| comma-separated codec list to accept on the outbound leg and transcode to PCMU/PCMA toward the feature server |no|
|
||||
|JAMBONES_ACCEPT_G729| if set, accept G.729 on the outbound leg and transcode to PCMU/PCMA (shorthand for `JAMBONES_ACCEPT_AND_TRANSCODE=g729`) |no|
|
||||
|K8S| service running as kubernetes service |no|
|
||||
|K8S_RTPENGINE_SERVICE_NAME| rtpengine service name(required for K8S) |no|
|
||||
|
||||
#### Codec transcoding notes
|
||||
|
||||
`JAMBONES_CODEC_OFFER_WITH_ORDER` and `JAMBONES_CODEC_TRANSCODE` can be combined. When both are set, rtpengine first strips the original codecs from the SDP, then adds the codecs listed in `JAMBONES_CODEC_OFFER_WITH_ORDER` to the offer, and finally adds the codecs from `JAMBONES_CODEC_TRANSCODE` with transcoding enabled. When only `JAMBONES_CODEC_TRANSCODE` is set, the original codecs from the feature server are kept in the offer and the transcode codecs are appended.
|
||||
|
||||
Codecs that require licensed or optional rtpengine modules (AMR, AMR-WB, G.729, etc.) only work if rtpengine was compiled with support for them. Carrier-specific fmtp parameters (for example, `octet-align=1` for AMR-WB) can be appended to the codec name as needed (e.g. `AMR-WB/16000;octet-align=1`).
|
||||
|
||||
### running under pm2
|
||||
Typically, this application runs under [pm2](https://pm2.io) using an [ecosystem.config.js](https://pm2.keymetrics.io/docs/usage/application-declaration/) file similar to this:
|
||||
```js
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"ICE": "force",
|
||||
"SDES": "off",
|
||||
"flags": ["generate mid", "SDES-no", "port latching"],
|
||||
"rtcp-mux": ["require"]
|
||||
"rtcp-mux": ["offer"]
|
||||
},
|
||||
"teams": {
|
||||
"transport-protocol": "RTP/SAVP",
|
||||
|
||||
+28
-3
@@ -237,6 +237,11 @@ class CallSession extends Emitter {
|
||||
this.logger.info(`sending call to registered user ${destUri}`);
|
||||
}
|
||||
else if (this.req.locals.target === 'forward') {
|
||||
if (process.env.JAMBONES_SIPS_FORWARD_SRTP && this.req.uri.startsWith('sips:')) {
|
||||
this.logger.info({uri: this.req.uri}, 'using SRTP/TLS for forwarded sips: call');
|
||||
this.rtpEngineOpts = makeRtpEngineOpts(this.req, false, true, false, false);
|
||||
encryptedMedia = true;
|
||||
}
|
||||
uris = [{
|
||||
private_network: await isPrivateVoipNetwork(this.req.uri),
|
||||
uri: this.req.uri
|
||||
@@ -660,7 +665,21 @@ class CallSession extends Emitter {
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if ('abandonded' !== err.message) this.logger.error({err}, `Error setting up outbound call to: ${uris}`);
|
||||
if ('abandoned' !== err.message) this.logger.error({err}, `Error setting up outbound call to: ${uris}`);
|
||||
|
||||
/* the call count was incremented on 'init' but we bailed out before connecting (e.g. caller
|
||||
hung up before the B leg answered), so we must decrement it here - no failure response is
|
||||
sent on this path, so the res.once('end') safety net in middleware would not fire.
|
||||
nudgeCallCounts is a no-op if the count was already decremented elsewhere. */
|
||||
const {writeCallCount, writeCallCountSP, writeCallCountApp} = this.req.srf.locals;
|
||||
nudgeCallCounts(this.req, 'failure', {
|
||||
service_provider_sid: this.service_provider_sid,
|
||||
account_sid: this.account_sid,
|
||||
application_sid: this.application_sid,
|
||||
callId: this.req.locals.callId
|
||||
}, this.decrKey, {writeCallCountSP, writeCallCount, writeCallCountApp})
|
||||
.catch((err) => this.logger.error(err, 'Error decrementing call counts'));
|
||||
|
||||
this.emit('failed');
|
||||
this.srf.endSession(this.req);
|
||||
this.rtpEngineResource.destroy();
|
||||
@@ -887,8 +906,14 @@ Duration=${payload.duration} `
|
||||
process.env.JAMBONES_ACCEPT_G729 ? 'g729' : '';
|
||||
offerMedia = { ...offerMedia, ...(acceptCodecs && dlg.type === 'uac' &&
|
||||
{ codec: { mask: acceptCodecs, transcode: 'pcmu,pcma' } })};
|
||||
answerMedia = { ...answerMedia, ...(process.env.JAMBONES_CODEC_OFFER_WITH_ORDER && dlg.type === 'uac' &&
|
||||
{ codec: {offer: process.env.JAMBONES_CODEC_OFFER_WITH_ORDER.split(','), strip: 'all' }})};
|
||||
answerMedia = { ...answerMedia, ...((process.env.JAMBONES_CODEC_OFFER_WITH_ORDER ||
|
||||
process.env.JAMBONES_CODEC_TRANSCODE) && dlg.type === 'uac' &&
|
||||
{ codec: {
|
||||
...(process.env.JAMBONES_CODEC_OFFER_WITH_ORDER &&
|
||||
{ offer: process.env.JAMBONES_CODEC_OFFER_WITH_ORDER.split(','), strip: 'all' }),
|
||||
...(process.env.JAMBONES_CODEC_TRANSCODE &&
|
||||
{ transcode: process.env.JAMBONES_CODEC_TRANSCODE.split(',') })
|
||||
}})};
|
||||
let opts = {
|
||||
...this.rtpEngineOpts.common,
|
||||
...offerMedia,
|
||||
|
||||
@@ -58,6 +58,10 @@ function makeRtpEngineOpts(req, srcIsUsingSrtp, dstIsUsingSrtp, padCrypto, teams
|
||||
offer: process.env.JAMBONES_CODEC_OFFER_WITH_ORDER.split(','),
|
||||
strip: 'all'
|
||||
}),
|
||||
...(process.env.JAMBONES_CODEC_TRANSCODE &&
|
||||
{
|
||||
transcode: process.env.JAMBONES_CODEC_TRANSCODE.split(',')
|
||||
}),
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
Generated
+22
-20
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "sbc-outbound",
|
||||
"version": "0.9.5",
|
||||
"version": "0.9.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "sbc-outbound",
|
||||
"version": "0.9.5",
|
||||
"version": "0.9.7",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helpers": "^7.26.10",
|
||||
"@jambonz/db-helpers": "^0.9.18",
|
||||
"@jambonz/http-health-check": "^0.0.1",
|
||||
"@jambonz/mw-registrar": "0.2.7",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.13",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.21",
|
||||
"@jambonz/rtpengine-utils": "^0.4.4",
|
||||
"@jambonz/siprec-client-utils": "^0.2.10",
|
||||
"@jambonz/stats-collector": "^0.1.10",
|
||||
@@ -21,7 +21,7 @@
|
||||
"cidr-matcher": "^2.1.1",
|
||||
"debug": "^4.4.3",
|
||||
"drachtio-fn-b2b-sugar": "^0.2.1",
|
||||
"drachtio-srf": "^5.0.20",
|
||||
"drachtio-srf": "^5.0.21",
|
||||
"express": "^4.21.2",
|
||||
"pino": "^10.1.0",
|
||||
"sdp-transform": "^2.15.0"
|
||||
@@ -34,7 +34,7 @@
|
||||
"tape": "^5.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
"node": ">= 20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@@ -594,9 +594,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/realtimedb-helpers": {
|
||||
"version": "0.8.13",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.8.13.tgz",
|
||||
"integrity": "sha512-/7c8kCu/dMSk8CWTYdEv4xU/7+vmVL30VCjtHPRAXVBRIVejAPDf1xK5n0rXwG8Fda1Oa+0TFsymkiRpew8P6w==",
|
||||
"version": "0.8.21",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.8.21.tgz",
|
||||
"integrity": "sha512-Zn/Zw14U0L1pB2RlN5i160FwWqphonhQ7p880OzsKOuvg+wmj6qIkxdLjDXo6TSxFPXDHD25s33zfGOT6ZIfsw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"ioredis": "^5.3.2"
|
||||
@@ -1068,9 +1069,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"version": "1.1.13",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
|
||||
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1597,9 +1598,9 @@
|
||||
"integrity": "sha512-bMtje8GWVTze+UG6WSGnlUfBaYCuFiApNXl/XxWc+X9uATZiZkV2jIqhf+Y4SY3nS8dZclJIVKd9qwoCa+i+Vw=="
|
||||
},
|
||||
"node_modules/drachtio-srf": {
|
||||
"version": "5.0.20",
|
||||
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-5.0.20.tgz",
|
||||
"integrity": "sha512-gqWTfqFZhC93TVBaFtRseemmfHPASotMfHhCy/3wQUHZShUl+Zr7Vbq+pLD1kyTNr4/pzpMwEMLd0/6oq/fCtg==",
|
||||
"version": "5.0.21",
|
||||
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-5.0.21.tgz",
|
||||
"integrity": "sha512-9hkQ7LURI1ceTMs49Nh2aosAd2v0565eD8Ccho5sSzXEHuq0DE3epjStlThq6LvIGVVAOXuSQGXFmlMWK92R3w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.3",
|
||||
@@ -2269,9 +2270,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
|
||||
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -3998,9 +3999,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
||||
"integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "sbc-outbound",
|
||||
"version": "0.9.5",
|
||||
"version": "0.9.7",
|
||||
"main": "app.js",
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
"node": ">= 20.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"sip",
|
||||
@@ -31,7 +31,7 @@
|
||||
"@jambonz/db-helpers": "^0.9.18",
|
||||
"@jambonz/http-health-check": "^0.0.1",
|
||||
"@jambonz/mw-registrar": "0.2.7",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.13",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.21",
|
||||
"@jambonz/rtpengine-utils": "^0.4.4",
|
||||
"@jambonz/siprec-client-utils": "^0.2.10",
|
||||
"@jambonz/stats-collector": "^0.1.10",
|
||||
@@ -39,7 +39,7 @@
|
||||
"cidr-matcher": "^2.1.1",
|
||||
"debug": "^4.4.3",
|
||||
"drachtio-fn-b2b-sugar": "^0.2.1",
|
||||
"drachtio-srf": "^5.0.20",
|
||||
"drachtio-srf": "^5.0.21",
|
||||
"express": "^4.21.2",
|
||||
"pino": "^10.1.0",
|
||||
"sdp-transform": "^2.15.0"
|
||||
|
||||
Reference in New Issue
Block a user