Open Source · Go · SIP · VoIP

BSNL Wings
SIP Client

A production-ready Go library for BSNL Wings VoIP — with outbound calling, bidirectional RTP audio, and a WebSocket bridge for voice AI frameworks like Pipecat.

Get Started View on GitHub
# Clone & run in 3 steps
$ git clone https://github.com/ashoksahoo/wings-client
$ make setup # creates .env, installs deps
$ make dev

Starting BSNL Wings SIP Client...
WebSocket server enabled on port 8080
✓ Successfully registered with authentication

> call +919876543210
Call ringing...
✓ Call answered! Bidirectional audio active.

Everything you need

Full SIP stack with audio, AI integration, and developer tooling.

📞

SIP Registration

Automatic digest authentication with BSNL Wings IMS servers. Handles 401/407 challenges and re-registration.

📡

Outbound Calling

Full INVITE/ACK/BYE flow with SDP negotiation. Supports PCMU & PCMA (G.711) codecs over UDP/RTP.

🔊

Bidirectional RTP

Real-time audio streaming in both directions. 8kHz, 16-bit PCM frames. No external media server needed.

🌐

WebSocket Bridge

Built-in WebSocket server exposes call audio to any client. Binary audio frames + JSON control messages.

🤖

AI Voice Integration

Native Pipecat compatibility. Connect OpenAI, ElevenLabs, or any LLM to handle real phone calls.

🔧

Developer Tools

sngrep integration for live SIP debugging, tmux split-screen mode, full structured logging.


Architecture

Wings Client sits between BSNL's SIP infrastructure and your AI application.

📱 Caller
Phone / SIP device
🏛 BSNL Wings IMS
SIP / RTP
⚡ Wings Client
Go · sipgo · UDP
🌐 WebSocket :8080
PCM audio + JSON events
🤖 Your AI App
Pipecat · OpenAI · etc.

SIP Path

REGISTER → Outbound Proxy (ir.bbsr.sbc.ims.bsnl.in:80) → IMS Core (or.voip.ims.bsnl.in). Digest auth on every registration.

Audio Path

RTP packets (PCMU) decoded in-process and forwarded as raw binary frames over WebSocket. Return audio re-wrapped as RTP and sent to remote.


Quick Start

Up and running in under 5 minutes.

1. Install & Configure

# Clone the repository
git clone https://github.com/ashoksahoo/wings-client
cd wings-client

# Create .env and install deps
make setup

# Edit .env with your credentials
# SIP_USERNAME=+91848XXXXXXX
# SIP_PASSWORD=your_password

2. Run

# Development mode (auto-loads .env)
make dev

# Or build and run
make build && ./wings-client

3. Make a Call

# Interactive CLI
> call +919876543210
Calling +919876543210...
✓ Call answered!

> status
Call abc123: answered - 42s

> hangup
Hung up.

4. Connect AI (Pipecat)

import asyncio, websockets, json

async def ai_agent():
    async with websockets.connect(
        "ws://localhost:8080/ws"
    ) as ws:
        async for msg in ws:
            if isinstance(msg, bytes):
                # PCM audio from caller
                response = await llm.respond(msg)
                await ws.send(response)

WebSocket API

Real-time audio + control via ws://localhost:8080/ws.

🔊 Audio Messages (binary)

Raw PCM frames sent as binary WebSocket messages in both directions.

  • Format: PCM 16-bit signed little-endian
  • Sample Rate: 8000 Hz
  • Channels: 1 (mono)
  • Frame: 160 samples (20ms)

📨 Control Messages (JSON)

JSON text frames for call control and events.

  • "type": "call" — initiate outbound call
  • "type": "hangup" — end active call
  • "type": "ping""pong"
  • "type": "event" — call_started / call_ended

❤️ Health Check

GET http://localhost:8080/health

{
  "status": "healthy",
  "clients": 1
}
JavaScript
const ws = new WebSocket('ws://localhost:8080/ws');

ws.onopen = () => {
  // Initiate an outbound call
  ws.send(JSON.stringify({ type: 'call', data: { number: '+919876543210' } }));
};

ws.onmessage = (event) => {
  if (event.data instanceof Blob) {
    // Binary: raw PCM audio from the SIP call
    event.data.arrayBuffer().then(buf => playAudio(buf));
  } else {
    // Text: JSON control/event message
    const msg = JSON.parse(event.data);
    console.log('Event:', msg);
  }
};

// Send audio to the active call
function sendAudio(pcmBuffer) {
  if (ws.readyState === WebSocket.OPEN) ws.send(pcmBuffer);
}

AI Voice Bot

Answer real phone calls with GPT-4o + ElevenLabs. Out of the box.

🧠 Stack

  • STT — ElevenLabs Scribe v1
  • LLM — OpenAI GPT-4o
  • TTS — ElevenLabs Turbo v2.5
  • VAD — Silero (real-time interruptions)
  • Transport — WingsWebSocketTransport

🛠️ Built-in Tools

  • get_weather(city) — live weather via Open-Meteo
  • hangup() — politely ends the call

Bot greets callers automatically and handles interruptions naturally.

🔑 Required API Keys

  • OPENAI_API_KEY
  • ELEVENLABS_API_KEY
  • WINGS_WS_URL (default: ws://localhost:8080/ws)
  • ELEVENLABS_VOICE_ID (optional)
# Terminal 1: start the Go SIP client
make dev

# Terminal 2: start the AI bot
cd pipecat
uv sync                     # or: pip install -r requirements.txt

export OPENAI_API_KEY="sk-..."
export ELEVENLABS_API_KEY="..."

python ai_bot.py

Call flow

Caller → BSNL IMS → wings-client (Go · SIP+RTP) → WebSocket :8080
                                                            ↕ PCMU binary
                                  WingsWebSocketTransport (Python · PCMU↔PCM)
                                                            ↕ PCM
                                  ElevenLabs STT → GPT-4o → ElevenLabs TTS

Configuration

All settings via environment variables or .env file.

Variable Description Default Status
SIP_USERNAME Your BSNL Wings number (with +91 prefix) Required
SIP_PASSWORD Your BSNL Wings password Required
SIP_SERVER Outbound proxy (SBC address) ir.bbsr.sbc.ims.bsnl.in Optional
SIP_PORT SIP server port 80 Optional
SIP_DISPLAY_NAME Caller ID display name BSNL Wings Client Optional
LOCAL_IP Local IP to bind SIP listener 0.0.0.0 Optional
LOCAL_PORT Local SIP port 5061 Optional
WEBSOCKET_ENABLED Enable WebSocket audio bridge true Optional
WEBSOCKET_PORT WebSocket server port 8080 Optional
BSNL Wings Endpoints

Register Server: or.voip.ims.bsnl.in
Outbound Proxy (Bhubaneswar): ir.bbsr.sbc.ims.bsnl.in:80
Outbound Proxy (Kolkata): ir.kol.sbc.ims.bsnl.in:80

Documentation

In-depth guides for every part of the system.

Makefile Reference

make setup — initial setup
make dev — run with .env
make build — build binary
make build-all — Linux/macOS/Windows
make test — run tests
make test-coverage — coverage report
make lint — golangci-lint
make sngrep — live SIP capture
make debug-sip — tmux split debug
make clean — remove artifacts