The Hidden Asterisk + PJSIP + IMS Trap (BSNL Case Study)
Why a perfectly registered SIP trunk can still make ZERO calls — and how to fix it
Most SIP engineers panic when they see this:
REGISTER → 401 → 200 OK
Status: Registered…and then nothing happens.
No outbound calls. No INVITE. No SIP logs. No errors.
I recently debugged a BSNL IMS SIP trunk on Asterisk 20 (PJSIP) that worked flawlessly on another PBX — yet refused to place calls here.
👉 Credentials were correct 👉 Registration was successful 👉 Network & NAT were fine
Still: no calls left the system
This article explains why this happens, how to diagnose it, and how to fix it permanently.
🔍 The Illusion of “Trunk Working”
In Asterisk, registration success does NOT mean call routing success.
You can have:
✅ pjsip show registrations → Registered ❌ Zero outbound SIP traffic
Because registration ≠ dialing.
🧠 The Real Root Cause (90% of Such Issues)
Your dialplan never dials the trunk
In modern PBX architectures (especially API-driven ones), outbound calls often flow like this:
Extension
→ Outbound policy
→ Stasis (Node.js / API)
→ (nothing originates a trunk call)So Asterisk happily waits… while the trunk sits idle.
No INVITE is ever generated.
🚫 The Silent Killer: Stasis Without Originate
In my case, the outbound dialplan ended with:
Stasis(clixxo,outbound,${ORIG_EXTEN},${DIALED_NUM})
Hangup()That looks “advanced” but unless your Stasis app explicitly originates a call, the trunk will never be used.
This is why:
- pjsip logger shows nothing
- Provider sees no traffic
- Engineers blame SIP credentials 😅
✅ Two Correct Ways to Fix It
Option 1 — Classic Asterisk Dialplan (Fastest Fix)
If you want Asterisk to control calls:
Dial(PJSIP/${DIALED_NUM}@tr_BSNL,60)This immediately generates:
INVITE sip:number@proxyPerfect for stable production PBXs.
Option 2 — API-Controlled PBX (Modern Architecture)
If you’re using Node.js / Stasis / ARI, then your app must originate the call:
ari.channels.originate({
endpoint: `PJSIP/${number}@tr_BSNL`,
callerId: '911202210100',
app: 'pbx'
});Without this, registration is meaningless.
📡 BSNL IMS-Specific Lessons (Very Important)
BSNL (and most IMS providers) are strict:
❌ Public DNS won’t resolve IMS domains
*.ims.bsnl.in often requires:
- Private DNS
- VPN DNS
- Or direct proxy IP
❌ +91 breaks many IMS trunks
Use:
911202210100NOT:
+911202210100❌ Realm in trunk auth
IMS trunks usually do NOT want a local PBX realm
🔥 Golden Rule of SIP Debugging
If auth works on another PBX but not on yours, 90% of the time it’s NOT credentials it’s headers or dialplan flow.
Compare:
- REGISTER headers
- INVITE headers
- From / Contact / Request-URI
Byte-for-byte.
🎯 Key Takeaways for PBX Architects
- Registration ≠ routing
- Stasis ≠ magic
- No Dial() or originate → no call
- IMS trunks are unforgiving
- Asterisk does exactly what you tell it nothing more
🚀 Why This Matters
Modern PBXs are no longer just dialplans. They’re distributed telecom systems with:
- APIs
- Web dashboards
- Policy engines
- Real-time analytics
If you don’t understand where SIP actually leaves the box, you’ll lose days debugging ghosts.
💬 Final Thought
If you’re building:
- Multi-tenant PBX platforms
- IMS-based SIP integrations
- Node.js + Asterisk systems
👉 Design outbound call flow explicitly don’t assume it.
