{"id":21173632,"url":"https://github.com/systemcrash/rest-cc-routing-demo-1","last_synced_at":"2026-04-05T17:33:04.332Z","repository":{"id":142970839,"uuid":"299314499","full_name":"systemcrash/rest-cc-routing-demo-1","owner":"systemcrash","description":"REST CC (Call Control)","archived":false,"fork":false,"pushed_at":"2020-12-10T17:51:25.000Z","size":3,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-21T11:14:45.310Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/systemcrash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-28T13:16:46.000Z","updated_at":"2020-12-10T17:51:27.000Z","dependencies_parsed_at":"2023-06-11T11:30:28.773Z","dependency_job_id":null,"html_url":"https://github.com/systemcrash/rest-cc-routing-demo-1","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemcrash%2Frest-cc-routing-demo-1","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemcrash%2Frest-cc-routing-demo-1/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemcrash%2Frest-cc-routing-demo-1/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemcrash%2Frest-cc-routing-demo-1/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/systemcrash","download_url":"https://codeload.github.com/systemcrash/rest-cc-routing-demo-1/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243623923,"owners_count":20321025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T16:48:23.077Z","updated_at":"2025-12-29T17:36:02.465Z","avatar_url":"https://github.com/systemcrash.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# REST CC (Call Control) DB\n\nUse REST Call Control capabilities of your SBC together with a RESTful database to free your SBC of business logic. This example shows how to select a destination PBX IP from the RESTful JSON database, based on the Request-URI (i.e. the To: or B number).\n\nKeywords: REST, JSON, cURL, SBC\n\nRequired Firmware: v6.3.1\n\n## Description\n\nYou want to choose a destination IP based on the callee, or the Request-URI/To header (B number). \n\n\n## Detailed Overview \n\nYour SBC (remote to this repo and which has Internet access) captures a Request-URI from an ingress INVITE, and sends it in a concurrent cURL request to the endpoint hosting this JSON database. In this example database there are three fields for each entry:\n\n- `PBXIP` - holds the fake destination domain - this will be the outbound Request-URI domain portion\n- `RURI` - holds the number to match from the `Request-URI`\n- `Comment` \n\n\nSo for `RURI = 34915552345`:\n\n| Routing      | 0 |\n|---------|---|\n| RURI    |34915552345|\n| PBXIP   |fakedomain1|\n| Comment |PBX A (Madrid)|\n\n\nWhen the cURL request returns, the values in this example are supplied to regular expressions which direct egress requests based on these provided values. In effect, we rewrite our destination domain, based on the Request-URI, stored in a remote database.\n\n[Click here]( https://my-json-server.typicode.com/systemcrash/rest-cc-routing-demo-1/routing?RURI=34915552345 ) to see these example values for `RURI = 34915552345` returned by the RESTful database.\n\nThen, use a DNS Override to translate `fakedomainX` to an IP.\n\n## Resources and dependencies\n\nFirmware \u003e= 6.3.1\n\n[My JSON Server](https://my-json-server.typicode.com/) which describes itself as a `Fake Online REST server for teams`. Read more about it to understand how this demonstration works. For this demo, My JSON Server uses the `db.json` file in this repository.\n\nOn your Ingate SBC, under:\n- __SIP Services, Basic Settings__: You must have a SIP TCP port configured (only UDP or TLS is not sufficient). It does not need to be `Active`.\n\nNot required but a highly recommended guide if you do not understand Regular Expressions (regexp):\n\n[Regular Expressions for Regular Folk](https://github.com/shreyasminocha/regex-for-regular-folk)\n\n\nNote: hosting your own instance is a good option. TLS up to you. \n\n## Worked Example: Rewrite the destination domain\n\nVicent wants to divide regional Spanish numbers between two different PBX IPs. One PBX is not enough to handle the amount of extensions and phone numbers he has. But the SBC is not configured yet. So it's time to configure the SBC to use the RESTful database for destination selection. \n\n---\nUnder the Call Control tab, add a REST API Server row:\n\n| ... | ID  | Prefix | Suffix | ... |\n|-----|------|-----|--------|-----|\n|     | `2`  |`https://my-json-server.typicode.com/your-github-repo/rest-cc-routing-demo-1/routing?RURI=`|        |     |\n\nWhereby\n|Path|Description|\n|---|---|\n|`your-github-repo/` |your github account/org name|\n|`rest-cc-routing-demo-1/`|this repo path|\n\n\nYou can even try with this repo as your prefix - everything is ready to use: `https://my-json-server.typicode.com/systemcrash/rest-cc-routing-demo-1/routing?RURI=`\n\n\nNote: Later in the dial plan, the shortcut `$curl2` refers to the Server ID `2` above. To use `$curl3`, add a row with ID `3`, and so on.\n\nNote: to adjust cURL timeout on v6.2.2 cumulatively patched, add (basic,advanced,options) advanced option name (sip.cc-timeout) and a value. Firmware \u003e= 6.3.x has a dedicated field for this under REST CC.\n\n---\n\nIn the dial plan, add a new:\n* `Matching R-URI` row which captures a number from the Request-URI:\n\n| ... | Name | ... | Regexp | ... |\n|-----|------|-----|--------|-----|\n|     | `Any` |     | `sip:\\+?(.*)@.*` |     |\n\nNote: Capture group `$1` or `$r1` is `(.*)`.\n\n* `Forward To` row which invokes our cURL expression:\n\n| ... | Name | ... | Regexp | Trunk |...|\n|-----|------|-----|--------|-----|---|\n|  |`RESTCCrouting`| | `sip:$1@$curl2($r1_XPATH//PBXIP/text())`|-| |\n\n\nNote: `$r1` expresses the first capture group from our ingress Request-URI. In this example `$r1`, supplies the Request-URI to the `$curl2(...)` expression.\n\n* `Dial Plan` row: \n\n| ... | From | Request URI | Action | Forward To | ... |\n|-----|------|-----|--------|-----|---|\n|     | ...  | ... | ... | ... |\n|     | ...  | `Any` | Forward | `RESTCCrouting` |\n\n\n---\n\nUnder SIP Traffic -\u003e Routing -\u003e DNS Overrides, add these entries:\n\n\n| ... | Domain      | IP            | Transport | ... | Modify R-URI |\n|-----|-------------|---------------|-----------|-----|--------------|\n|     | fakedomain1 | 172.31.254.10 | UDP       | ... | Yes |\n|     | fakedomain2 | 172.31.254.11 | UDP       | ... | Yes |\n|     | fakedomain3 | 172.31.254.12 | UDP       | ... | Yes |\n|     | fakedomain4 | 172.31.254.13 | UDP       | ... | Yes |\n\nAdjust the values as appropriate for your environment.\n\nSIP Routing Order should read:\n\n* 1 DNS Override\n* 2 Local Registrar\n* 3 Dial Plan\n\n\nOur concurrent cURL request becomes [`https://my-json-server.typicode.com/systemcrash/rest-cc-routing-demo-1/routing?RURI=34915552345`]( https://my-json-server.typicode.com/systemcrash/rest-cc-routing-demo-1/routing?RURI=34915552345 ), to which the response comes \n```json\n[\n  {\n    \"RURI\": 34915552345,\n    \"PBXIP\": \"fakedomain1\",\n    \"comment\": \"PBX A (Madrid)\"\n  }\n]\n```\n\n\nNote: \n\nThe Call Control function converts received JSON to XML internally, whereupon XPATH expressions are available. Our `$curl2` expression has `XPATH//PBXIP/text()`. This takes the `PBXIP` field text (which is a *text* field in the JSON above, but everything gets converted to text anyway). \n\n\nWith everything configured and applied now, here is an ingress SIP INVITE to +34915552345:\n\n```http\nINVITE sip:+34915552345@192.0.2.5 SIP/2.0\nVia: SIP/2.0/UDP 192.0.2.254:5060;branch=z9hG4bK-909121779;received=192.0.2.254;rport=5060\nContent-Length: 0\nFrom: \"Vicen\" \u003csip:90501@192.0.2.254\u003e;tag=633\nAccept:\nUser-Agent: Vicens-phone\nTo: \"Madrid\" \u003csip:+34915552345@192.0.2.5\u003e\nContact: sip:90501@192.0.2.254:5060\nCSeq: 1 INVITE\nCall-ID: 355593493830278013560573\nMax-Forwards: 70\n```\n\nThe Request-URI contains the user portion `+34915552345`. An INVITE that egresses to our PBX might look like:\n\n```http\nINVITE sip:+34915552345@172.31.254.10 SIP/2.0\nVia: SIP/2.0/UDP 172.31.254.1:5060;branch=z9hG4bK-909121779\nContent-Length: 0\nFrom: \"John\" \u003csip:90501@172.31.254.1\u003e;tag=633\nUser-Agent: Franken-SBC\nTo: \"USA\" \u003csip:+34915552345@fakedomain1\u003e\nContact: sip:zyx123@172.31.254.1\nCSeq: 1 INVITE\nCall-ID: 1\nMax-Forwards: 70\n```\n\n\n## Code and Design (how to reproduce this JSON DB file)\n\nDraw up your javascript DB at the following location\n\n[https://beta5.objgen.com/json/local/design](https://beta5.objgen.com/json/local/design)\n\nClarification of the below JSON object design:\n\n```json\n\nrouting[]  \u003c-- An array [], named 'routing' which will hold all of the routing.\n  RURI n = 34915552345 \u003c-- Number, the caller ID from the Request-URI\n  PBXIP = fakedomain1 \u003c-- String, the fake destination domain\n  comment = PBX A (Madrid)\n\n```\n\nCopy the below example JSON object code and paste at the above URL to produce formatted JSON output which will make our database file `db.json`, ready for my-json-server. \n\n```json\nrouting[]\n  RURI n = 34915552345\n  PBXIP = fakedomain1\n  comment = PBX A (Madrid)\n\nrouting[]\n  RURI n = 34965552345\n  PBXIP = fakedomain2\n  comment = PBX B (Alicante)\n\nrouting[]\n  RURI n = 349575552345\n  PBXIP = fakedomain3\n  comment = PBX C (Cordoba)\n\nrouting[]\n  RURI n = 34955552345\n  PBXIP = fakedomain4\n  comment = PBX D (Malaga/Sevilla)\n\nprofile\n  name = typicode\n```\n\n---\n\nThe above JSON object model code should produce the following JSON:\n```json\n\n{\n  \"routing\": [\n    {\n      \"RURI\": 34915552345,\n      \"PBXIP\": \"fakedomain1\",\n      \"comment\": \"PBX A (Madrid)\"\n    },\n    {\n      \"RURI\": 34965552345,\n      \"PBXIP\": \"fakedomain2\",\n      \"comment\": \"PBX B (Alicante)\"\n    },\n    {\n      \"RURI\": 349575552345,\n      \"PBXIP\": \"fakedomain3\",\n      \"comment\": \"PBX C (Cordoba)\"\n    },\n    {\n      \"RURI\": 34955552345,\n      \"PBXIP\": \"fakedomain4\",\n      \"comment\": \"PBX D (Malaga/Sevilla)\"\n    }\n  ],\n  \"profile\": {\n    \"name\": \"typicode\"\n  }\n}\n\n```\n---\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsystemcrash%2Frest-cc-routing-demo-1","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsystemcrash%2Frest-cc-routing-demo-1","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsystemcrash%2Frest-cc-routing-demo-1/lists"}