Skip to content

streamcoreai/sip-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StreamCoreAI SIP Server

A SIP server that bridges SIP phone calls to the StreamCoreAI server. It handles incoming calls (e.g., from a phone network) and outgoing calls (initiated via REST API), converting audio between G.711 μ-law (PCMU) used by SIP and Opus used by StreamCoreAI's WebRTC transport.

For splitting this tree into its own Git repository and publishing github.com/streamcoreai/go-sdk, see Repository layout.

Architecture

Phone Network ←→ SIP (PCMU/RTP) ←→ SIP Server ←→ WHIP (Opus/WebRTC) ←→ StreamCoreAI Server

Each call creates:

  • A local RTP listener for SIP-side audio (PCMU at 8kHz)
  • A StreamCoreAI SDK client connection via WHIP (Opus at 48kHz)
  • A bidirectional audio bridge that transcodes and resamples between the two

Prerequisites

  • Go 1.23+
  • A running StreamCoreAI server with a WHIP endpoint

Configuration

Copy and edit the config file:

cp config.toml.example config.toml

Key settings in config.toml:

[sip]
listen_addr = "0.0.0.0:5060"   # SIP UDP listen address
external_ip = ""                 # Public IP for SDP (auto-detected if empty)
rtp_port_min = 10000
rtp_port_max = 20000

[streamcoreai]
whip_endpoint = "http://localhost:8080/whip"

[api]
listen_addr = "0.0.0.0:8090"

[providers.twilio]
enabled = false
trunk_domain = "your-trunk.pstn.twilio.com"

[providers.ringcentral]
enabled = false
outbound_proxy = "sip.ringcentral.com:5060"

Running

go build -o sip-server .
./sip-server                    # uses config.toml in current directory
./sip-server /path/to/config.toml

REST API

Health Check

GET /health

List Providers

GET /providers

List Calls

GET /calls

Get Call

GET /calls/{id}

Initiate Outgoing Call

POST /calls
Content-Type: application/json

{
  "to": "+15551234567",
  "provider": "twilio"
}

Hang Up Call

DELETE /calls/{id}

Providers

Asterisk (Local Testing)

A local Asterisk PBX is included for end-to-end testing — see Local Testing with Asterisk below.

Twilio

Configure your Twilio Elastic SIP Trunk domain. Point the trunk's origination URI to your SIP server's address.

RingCentral

Configure the RingCentral outbound proxy and credentials.


Local Testing with Asterisk

A Dockerized Asterisk PBX is included so you can test the full call flow locally without any external SIP providers.

Prerequisites

  • Docker & Docker Compose
  • A running StreamCoreAI server on localhost:8080 (or via the root docker-compose.yml)
  • A SIP softphone app (e.g. Oher, Zoiper, Oher Mobile, Linphone)

Architecture

Softphone (6001)                          StreamCoreAI Server
     │                                          │
     │  SIP/RTP (PCMU)                          │ WHIP (Opus/WebRTC)
     ▼                                          ▼
┌──────────┐    SIP/RTP (PCMU)    ┌──────────────────┐
│ Asterisk │◄────────────────────►│   SIP Server     │
│  (PBX)   │                     │  (this project)  │
└──────────┘                     └──────────────────┘
 172.20.0.10                       172.20.0.20

Quick Start

1. Start Asterisk + SIP Server:

cd sip-server
docker compose up --build

This starts:

  • Asterisk on 172.20.0.10:5060 (mapped to host localhost:5060/udp)
  • SIP Server on 172.20.0.20:5060 (mapped to host localhost:5061/udp) with REST API on localhost:8090

Make sure your StreamCoreAI server is running on localhost:8080 before starting.

2. Configure your softphone:

Register with the Asterisk server using these credentials:

Setting Value
SIP Server localhost (or your machine IP)
SIP Port 5060
Username 6001
Password test123
Transport UDP

A second extension 6002 / test123 is also available.

3. Test an incoming call (phone → StreamCoreAI):

From your softphone, dial 7000. Asterisk routes the call to the SIP server, which connects to StreamCoreAI. You should hear the AI agent respond.

4. Test an outgoing call (StreamCoreAI → phone):

Use the REST API to initiate a call from StreamCoreAI to your softphone:

curl -X POST http://localhost:8090/calls \
  -H "Content-Type: application/json" \
  -d '{"to": "6001", "provider": "asterisk"}'

Your softphone should ring. Answer it to talk to the AI agent.

5. Manage calls:

# List active calls
curl http://localhost:8090/calls

# Get call details
curl http://localhost:8090/calls/<call-id>

# Hang up a call
curl -X DELETE http://localhost:8090/calls/<call-id>

# Check health
curl http://localhost:8090/health

# List providers
curl http://localhost:8090/providers

Running Without Docker

If you want to run just Asterisk in Docker and the SIP server natively:

# Start only Asterisk
docker compose up asterisk --build

# Run SIP server locally (uses config.toml which points to localhost)
go build -o sip-server .
./sip-server

The default config.toml has the asterisk provider pointing to localhost:5060.

Asterisk Extensions

Extension Description
7000 Routes to the StreamCoreAI SIP server
6001 Test softphone extension 1
6002 Test softphone extension 2
9999 Echo test (plays back your audio for debugging)

Troubleshooting

  • No audio: Make sure the RTP port ranges don't conflict. Asterisk uses 10000-10100, SIP server uses 10200-10300 in Docker mode.
  • Registration failed: Check that Asterisk is running (docker compose logs asterisk) and the credentials match.
  • "provider not configured": Make sure providers.asterisk.enabled = true in your config.
  • StreamCoreAI connection fails: Verify StreamCoreAI is running at the configured WHIP endpoint. In Docker, it uses host.docker.internal:8080.

How It Works

Incoming Calls

  1. SIP INVITE arrives → server sends 100 Trying
  2. Parses remote SDP for RTP address
  3. Creates a StreamCoreAI SDK connection via WHIP
  4. Allocates a local RTP port and responds with 200 OK + SDP
  5. Starts bidirectional audio bridge (PCMU ↔ Opus)

Outgoing Calls

  1. REST API request triggers POST /calls
  2. Creates a StreamCoreAI SDK connection
  3. Sends SIP INVITE to the provider's trunk with local SDP
  4. On 200 OK, sends ACK and starts audio bridge

Audio Bridge

  • SIP → StreamCoreAI: Decode G.711 μ-law → upsample 8kHz to 48kHz → encode Opus → send via WebRTC
  • StreamCoreAI → SIP: Decode Opus → downsample 48kHz to 8kHz → encode G.711 μ-law → send via RTP

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors