AstroCom-API/acSipBridge/theory.md

158 lines
6.8 KiB
Markdown

# AstroCom SIP Bridge — Design Notes
This directory contains a set of Asterisk configuration files that act as a
**protocol bridge** between IAX2 (used by AstroCom) and SIP (used by
downstream, non-Asterisk phone systems such as FreeSWITCH, 3CX, Cisco
UCM, or any generic SIP PBX).
---
## Files
| File | Purpose |
|------|---------|
| `iax.conf` | IAX2 peers — one per bridge, pointing at AstroCom |
| `pjsip.conf` | PJSIP endpoints — one triple (endpoint/auth/aor) per bridge |
| `extensions.conf` | Dialplan — contexts that wire IAX↔PJSIP for each bridge |
---
## Architecture
```
┌─────────────────────────────────┐
│ AstroCom Platform │
│ (IAX2 server, routes DB) │
└──────────┬──────────────────────-┘
│ IAX2 (port 4569)
┌───────────────┼────────────────┐
│ │ │
IAX2 peer IAX2 peer IAX2 peer
bridge1-astrocom bridge2-astrocom bridgeN-astrocom
│ │ │
┌───────┴───────────────┴────────────────┴──────┐
│ Bridge Server │
│ (this Asterisk instance) │
│ │
│ [bridge1-from-astrocom] [bridge1-from-pbx] │
│ [bridge2-from-astrocom] [bridge2-from-pbx] │
│ [bridgeN-from-astrocom] [bridgeN-from-pbx] │
└───────┬───────────────┬────────────────┬──────┘
│ │ │
SIP peer SIP peer SIP peer
bridge1-pbx bridge2-pbx bridgeN-pbx
│ │ │
▼ ▼ ▼
PBX / System 1 PBX / System 2 PBX / System N
```
### Inbound call (AstroCom → PBX)
1. AstroCom looks up the dialled number in its `routes` table and finds
the bridge server's IP (`routes.server`) and port (`routes.port`).
2. AstroCom dials over IAX2 using the shared secret (`routes.secret`)
and delivers the call to the context named in `routes.auth`
(e.g. `bridge1-from-astrocom`).
3. The bridge's dialplan receives the call in `[bridge1-from-astrocom]`
and dials `SIP/bridge1-pbx/<EXTEN>`. Because the PBX has already
registered (`host=dynamic`), Asterisk knows the current contact URI
and sends the INVITE directly to it.
### Outbound call (PBX → AstroCom)
1. The downstream PBX has registered to this server as `bridge1-pbx`.
It sends a SIP INVITE for the target number.
2. `sip.conf` authenticates the REGISTER/INVITE against `secret` and
lands the call in context `bridge1-from-pbx`.
3. The dialplan CURLs the AstroCom routing API:
`GET /api/v1/route/<apiKey>/<ANI>/<number>`
4. The API returns either `"local"` (callee is on the same PBX — route
back via `SIP/bridge1-pbx/<exten>`) or a full
`IAX2/<auth>:<secret>@<host>:<port>/<number>` URI which is dialled
verbatim.
---
## AstroCom Database Requirements
For each bridge you must create one row in the `routes` table:
| Column | Value |
|--------|-------|
| `server` | Bridge server's public IP |
| `port` | `4569` (IAX2) |
| `auth` | `bridgeN-from-astrocom` (must match context name) |
| `secret` | The shared IAX2 secret (`BRIDGEN_IAX_SECRET`) |
| `block_start` | First number in this bridge's number block |
| `block_length` | Size of the block (default 9999) |
| `apiKey` | Auto-generated by AstroCom on creation |
---
## Isolation Model
Each bridge is **completely isolated** by default:
- IAX2 peers use separate contexts (`bridge1-from-astrocom`, etc.)
- PJSIP endpoints use separate contexts (`bridge1-from-pbx`, etc.)
- No context includes or jumps to another bridge's context
- The `[default]` context drops all unmatched calls
### Calling between bridges
Calls between Bridge-1 and Bridge-2 work through AstroCom's normal
routing — Bridge-1's PBX dials a number, it travels to AstroCom via
IAX2, AstroCom routes it to Bridge-2's context, and it arrives at
Bridge-2's PBX via PJSIP. **No special config is needed for this.**
If you want **direct PJSIP** bridging (bypassing AstroCom for inter-bridge
calls), see the commented-out section at the bottom of `extensions.conf`.
---
## Adding a New Bridge
1. **`iax.conf`** — Copy the `[bridge1-from-astrocom]` block, rename it to
`[bridgeN-from-astrocom]`, and set a new `secret` and `context`.
2. **`pjsip.conf`** — Copy the three stanzas for `bridge1-pbx`, rename them
to `bridgeN-pbx` / `bridgeN-pbx-auth`, set a new `password`, and update
`context`. The downstream PBX must be configured to register with:
- **Registrar**: `sip:<bridge server IP>:5060`
- **Username**: `bridgeN-pbx`
- **Password**: the `password` value in `[bridgeN-pbx-auth]`
3. **`extensions.conf`** — Copy both the `[bridge1-from-astrocom]` and
`[bridge1-from-pbx]` context blocks, rename them to
`[bridgeN-from-astrocom]` / `[bridgeN-from-pbx]`, and update the
`Dial()` targets and global variable names.
Add `BRIDGEN_APIKEY` and `BRIDGEN_EXCHANGE` to `globals.conf`.
4. **AstroCom** — Create the route via the admin panel or API with
`auth = bridgeN-from-astrocom` and the matching `secret`.
5. Reload Asterisk:
```
asterisk -rx "pjsip reload"
asterisk -rx "iax2 reload"
asterisk -rx "dialplan reload"
```
---
## Notes
- **Codecs**: `ulaw`, `alaw`, and `g729` are negotiated; adjust per your
network and licensing constraints.
- **NAT**: If a downstream PBX is behind NAT, set `direct_media=no` (already
in the template) and add `local_net` / `external_signaling_address` /
`external_media_address` to `[bridge-transport]` in `pjsip.conf`.
- **No `register =>`** for IAX2: IP updates use `tools/astrocom_dynamic_ip.sh`
or the `/api/v1/user/update` API endpoint — not IAX2 registration.
- **Security**: Each bridge's IAX2 secret should be a long random string
(AstroCom generates one via `crypto.randomBytes(15).toString('hex')`
if none is specified during route creation).
- **`sip.conf`**: The old `chan_sip` config is superseded by `pjsip.conf`.
Ensure `chan_sip` is not loaded (`noload => chan_sip.so` in `modules.conf`)
to avoid both modules fighting over port 5060.