# 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/`. 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///` 4. The API returns either `"local"` (callee is on the same PBX — route back via `SIP/bridge1-pbx/`) or a full `IAX2/:@:/` 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::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.