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.
Full SIP stack with audio, AI integration, and developer tooling.
Automatic digest authentication with BSNL Wings IMS servers. Handles 401/407 challenges and re-registration.
Full INVITE/ACK/BYE flow with SDP negotiation. Supports PCMU & PCMA (G.711) codecs over UDP/RTP.
Real-time audio streaming in both directions. 8kHz, 16-bit PCM frames. No external media server needed.
Built-in WebSocket server exposes call audio to any client. Binary audio frames + JSON control messages.
Native Pipecat compatibility. Connect OpenAI, ElevenLabs, or any LLM to handle real phone calls.
sngrep integration for live SIP debugging, tmux split-screen mode, full structured logging.
Wings Client sits between BSNL's SIP infrastructure and your AI application.
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.
Up and running in under 5 minutes.
# 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
# Development mode (auto-loads .env) make dev # Or build and run make build && ./wings-client
# Interactive CLI > call +919876543210 Calling +919876543210... ✓ Call answered! > status Call abc123: answered - 42s > hangup Hung up.
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)
Real-time audio + control via ws://localhost:8080/ws.
🔊 Audio Messages (binary)
Raw PCM frames sent as binary WebSocket messages in both directions.
📨 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
}
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); }
Answer real phone calls with GPT-4o + ElevenLabs. Out of the box.
🧠 Stack
🛠️ Built-in Tools
get_weather(city) — live weather via Open-Meteohangup() — politely ends the callBot greets callers automatically and handles interruptions naturally.
🔑 Required API Keys
OPENAI_API_KEYELEVENLABS_API_KEYWINGS_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 :8080All 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 |
or.voip.ims.bsnl.inir.bbsr.sbc.ims.bsnl.in:80ir.kol.sbc.ims.bsnl.in:80
In-depth guides for every part of the system.
Makefile Reference
make setup — initial setupmake dev — run with .envmake build — build binarymake build-all — Linux/macOS/Windowsmake test — run testsmake test-coverage — coverage reportmake lint — golangci-lintmake sngrep — live SIP capturemake debug-sip — tmux split debugmake clean — remove artifacts