This guide explains how to connect iOS devices to your Asterisk server using Linphone.
┌─────────────────┐
│ iOS Device │
│ (Linphone) │
│ User: 1000 │
└────────┬────────┘
│ SIP (5060/UDP)
│ RTP (10000-10100/UDP)
│
▼
┌─────────────────────────────────────┐
│ Your Computer (Docker Host) │
│ │
│ ┌──────────────────────────────┐ │
│ │ Asterisk Container │ │
│ │ - SIP Server (5060) │ │
│ │ - RTP Media (10000-10100) │ │
│ │ - ARI Interface (8088) │ │
│ └──────────┬───────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────┐ │
│ │ Orchestrator Container │ │
│ │ - Chatbot Routing │ │
│ └──────────┬───────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────┐ │
│ │ Chatbot Containers │ │
│ │ - English Bot (2000) │ │
│ │ - Kinyarwanda Bot (3000) │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
- ✅ Open source (GPL v3)
- ✅ Available on iOS App Store
- ✅ Supports modern codecs (Opus, ulaw, alaw)
- ✅ Good NAT traversal (ICE, STUN)
- ✅ Active development
- ✅ Free to use
- iOS App: https://github.com/BelledonneCommunications/linphone-iphone
- SDK: https://github.com/BelledonneCommunications/linphone-sdk
- Core: https://github.com/BelledonneCommunications/liblinphone
Download from the App Store:
- Search for "Linphone"
- Install the app (free)
- Open the app
- Tap "Use SIP Account"
- Select "Use SIP account" (not "Create account")
- Fill in the form:
- Username:
1000 - Password:
user1000pass - Domain:
192.168.1.100:5060(replace with your server IP) - Display name: Your name (optional)
- Username:
- Tap "Login"
- Go to Settings → Accounts
- Tap "+" to add account
- Select "Use SIP account"
- Enter details:
Basic:
Username: 1000
Password: user1000pass
Domain: YOUR_SERVER_IP:5060
Display Name: Test User 1
Advanced:
Transport: UDP
Outbound Proxy: (leave empty)
Enable ICE: ON
STUN Server: stun.l.google.com (optional)
- Tap "Save"
Look for:
- Green dot next to account name
- Status: "Connected" or "Registered"
If you see "Connection failed" or red dot:
- Check server IP address
- Verify server is running:
docker-compose ps - Check firewall settings
Go to Settings → Audio:
Codecs (in order of preference):
- ✅ Opus (best quality, lowest bandwidth)
- ✅ PCMU (ulaw) - standard
- ✅ PCMA (alaw) - standard
- ❌ Disable others for simplicity
Other Settings:
- Echo Cancellation: ON
- Adaptive Rate Control: ON
- DTMF: RFC 4733
- Dial
600(if echo test is set up) - You should hear yourself
- Set up second device with user
1001 - From first device, dial
1001 - Second device should ring
- Dial
2000for English chatbot - Dial
3000for Kinyarwanda chatbot
Both your computer and iOS device must be on the same WiFi network.
Find your server IP:
# Linux
ip addr show | grep "inet " | grep -v 127.0.0.1
# macOS
ifconfig | grep "inet " | grep -v 127.0.0.1Use the IP that starts with:
192.168.x.x(most common)10.0.x.x172.16.x.xto172.31.x.x
To access from outside your network:
-
Port forward on your router:
- 5060/UDP → Your server's local IP
- 10000-10100/UDP → Your server's local IP
-
Update Asterisk config (
asterisk/config/pjsip.conf):[transport-udp] external_media_address=YOUR_PUBLIC_IP external_signaling_address=YOUR_PUBLIC_IP
-
Use your public IP in Linphone domain field
-
Security: Consider using a VPN instead of exposing ports
Symptom: Red dot, "Connection failed"
Solutions:
-
Verify server is running:
# Podman podman ps # Docker docker-compose ps
-
Check Asterisk logs:
# Podman podman logs asterisk-server | grep NOTICE # Docker docker logs asterisk-server | grep NOTICE
-
Verify IP address is correct
-
Check both devices are on same network
-
Try disabling iOS VPN if active
Symptom: Calls fail immediately
Solutions:
-
Check Asterisk endpoints:
docker exec asterisk-server asterisk -rx "pjsip show endpoints"
-
Verify extension exists (1000-1999 for users)
-
Check Asterisk logs during call attempt
Symptom: Call connects but no audio
Solutions:
-
Check RTP ports are open (10000-10100/UDP)
-
Enable ICE in Linphone settings
-
Add STUN server:
stun.l.google.com -
Check codec compatibility:
docker exec asterisk-server asterisk -rx "core show channels"
-
Verify firewall allows RTP:
sudo ufw allow 10000:10100/udp
Symptom: Can hear them, they can't hear you (or vice versa)
Solutions:
- NAT/firewall issue - enable ICE and STUN
- Check microphone permissions on iOS
- Verify symmetric RTP is enabled (it is by default)
Solutions:
- Ensure Opus codec is enabled and preferred
- Check network bandwidth
- Reduce background apps on iOS
- Check for packet loss:
docker exec asterisk-server asterisk -rx "rtp show stats"
You can connect multiple iOS devices:
Device 1:
- Username: 1000
- Password: user1000pass
Device 2:
- Username: 1001
- Password: user1001pass
Device 3:
- Username: 1002
- Password: user1002pass
Each device gets a unique extension number.
If you want to try other open-source options:
- Linphone (recommended) - Most feature-complete
- Telephone - Simpler, macOS focused
- Zoiper - Has free tier (not fully open source)
For production use:
- Change default passwords in
pjsip.conf - Use strong passwords (not
user1000pass) - Enable TLS for encrypted signaling
- Enable SRTP for encrypted audio
- Use VPN for remote access
- Implement fail2ban for brute force protection
- Limit registration attempts
Once you have Linphone working:
- Test user-to-user calls between devices
- Implement the orchestrator service (Task 3)
- Test chatbot extensions (2000, 3000)
- Add more users as needed
- Configure production security
If you're stuck:
- Check
QUICKSTART.mdfor basic setup - Review Asterisk logs:
docker logs asterisk-server - Check Linphone logs in the app (Settings → Advanced → Logs)
- Verify network connectivity with ping
- Test with a different SIP client to isolate issues
# Check if user is registered
docker exec asterisk-server asterisk -rx "pjsip show endpoints"
# View registration details
docker exec asterisk-server asterisk -rx "pjsip show registrations"
# Monitor calls in real-time
docker exec asterisk-server asterisk -rx "core show channels"
# View detailed call logs
docker logs asterisk-server | grep "User to User Call"
# Restart Asterisk if needed
docker-compose restart asterisk