Develop stage
Trunks
Four processes, two on 192.168.71.9. Loopback only between Active Call and RustPBX. The gateway at 192.168.71.107 peers 192.168.71.9:5060, never localhost. Edit the INVITE table on Routing.
Trunk provider
Dialog B terminates here. Active Call still INVITEs RustPBX. Loopback is refused.
Gateway panel · 192.168.71.107
Two fields on the device currently kill inbound. Leave a-law. SIP server stays 192.168.71.9:5060.
| Field | Now | Set to |
|---|---|---|
| 禁止呼入 | 启用 | 禁用 |
| 呼入绑定号码 | 9955756 | 8619921256477 |
| 首选语音编码 | a Law | keep · PCMA first on the PBX |
Outbound on the box
Active Call originates to rustpbx on loopback. This preview cannot.
python3 place_call.py 18640804547 # ws://127.0.0.1:8081/call/sip?id=out-… # option.realtime.provider = ws://127.0.0.1:8765/v1/realtime # callee sip:[email protected]:5060
realtime is a CallOption, not playbook front matter. provider must be the 8765 URL — "openai" discards endpoint and dials api.openai.com.
Active Call URL
Dial originates from this browser to that HTTP. This preview cannot reach a private 192.168 address unless you are on the LAN.
EDGE. Peers 192.168.71.9:5060, never localhost. DID +8619921256477. Panel: 禁止呼入 = 禁用, 呼入绑定号码 = 8619921256477.
SWITCH. SIP 5060, HTTP 8080, RTP 20000-24999. Never opens 8765.
ADAPTER. Ext 1001. SIP 13050, HTTP 8081, RTP 25000-29999. Only client of 8765.
BRAIN. ws://127.0.0.1:8765/v1/realtime — loopback only, no auth. Aria does not open this socket.
Port map on 192.168.71.9
Gateway is a separate host. speech-to-speech is loopback only.
| Process | SIP | HTTP | RTP | Role |
|---|---|---|---|---|
| RustPBX | 5060 | 8080 | 20000-24999 | Never opens 8765 |
| Active Call | 13050 | 8081 | 25000-29999 | Only client of 8765 · ext 1001 |
| speech-to-speech | — | 8765 | — | Loopback, no auth |
| Gateway 192.168.71.107 | 5060 | — | — | Peers 192.168.71.9:5060 |
Inbound · +8619921256477
Someone on the mobile network dials the DID.
- 01PSTNGSM/LTE into the gateway
- 02GatewayINVITE 192.168.71.9:5060
- 03RustPBXB2BUA + dialplan → 1001:13050
- 04Active CallRealtime ws://127.0.0.1:8765/v1/realtime
Outbound · From 1001
The agent dials. From on the trunk is the DID.
- 01Active CallINVITE rustpbx as 1001
- 02RustPBXNew Call-ID · From +8619921256477
- 03GatewayPeers 192.168.71.9:5060, dials GSM
- 04PSTNCallee rings · 200 OK · PCMU
rustpbx config.toml
Drop on 192.168.71.9. HTTP router points at this app.
# Aria × rustpbx — on 192.168.71.9
http_addr = "0.0.0.0:8080"
[proxy]
addr = "0.0.0.0"
udp_port = 5060
external_ip = "192.168.71.9"
media_proxy = "all"
route_originated_calls = true
realms = ["127.0.0.1", "192.168.71.9"]
audio_codecs = ["pcma", "pcmu"]
[media]
rtp_start = 20000
rtp_end = 24999
[[proxy.user_backends]]
type = "memory"
users = [
{ username = "1001", password = "agent1001" },
{ username = "9955756", password = "gateway" },
]
[[proxy.routes]]
name = "did-in"
priority = 100
action = "forward"
dest = "sip:[email protected]:13050"
[proxy.routes.match]
"to.user" = "^\\+?(?:86)?19921256477$"
[[proxy.routes]]
name = "ext-agent"
priority = 99
action = "forward"
dest = "sip:[email protected]:13050"
[proxy.routes.match]
"to.user" = "^1001$"
[[proxy.routes]]
name = "trial-out"
priority = 98
action = "forward"
dest = "pstn"
[proxy.routes.match]
"to.user" = "^\\+?(?:86)?18640804547$"
[proxy.routes.rewrite]
"from.user" = "8619921256477"
"to.user" = "18640804547"
"to.host" = "192.168.71.107:5060"
[[proxy.routes]]
name = "pstn-out"
priority = 97
action = "reject"
[proxy.routes.match]
"to.user" = "^\\+?(?:86)?(\\d{5,})$"
[proxy.routes.rewrite]
"from.user" = "8619921256477"
[[trunks]]
name = "pstn"
addr = "192.168.71.107:5060"
transport = "udp"
codecs = ["PCMA", "PCMU"]
direction = "both"
# Gateway peers 192.168.71.9:5060, never localhost.
# DID +8619921256477 → sip:[email protected]:13050
# Brain stays loopback: ws://127.0.0.1:8765/v1/realtime
active-call config.toml
Same host. Registers as extension 1001 on SIP 13050.
# Aria × active-call — on 192.168.71.9 next to rustpbx http_addr = "0.0.0.0:8081" [ua] addr = "0.0.0.0" udp_port = 13050 [media] rtp_start = 25000 rtp_end = 29999 [[register_users]] server = "127.0.0.1:5060" username = "1001" [register_users.credential] username = "1001" password = "agent1001" realm = "127.0.0.1" # Outbound: POST /api/playbook/run then WS /call/sip # callee sip:[email protected]:5060 codec pcma # Brain — loopback only: # ws://127.0.0.1:8765/v1/realtime # Playbook front matter (hf-s2s.md): # realtime: # provider: "openai" # model: "local" # endpoint: "ws://127.0.0.1:8765/v1/realtime" # apiKey: "not-needed"