VOIP configuration for Asterisk13, PJSIP, chan_lantiq and Vodafone Germany

I've spent quite some time configuring Asterisk on my VGV7510KW22 and I want to share my configuration in case it might be useful for somebody. I can use this setup for my daily phone calls without problems.

Use these configurations with care, I'm still an Asterisk noob myself. It also might be a good idea to block international or special numbers by your SIP provider (I did). I have my system running for a few weeks now and so far I found no signs of abuse.

Thanks to Plonk34 and stefan-koch, their configs were my first starting point, I also learned a lot by reading some posts on the (German) IP phone forum and this great guide (also German) got me started with PJSIP.

lantiq.conf

[interfaces]
channels = 2
per_channel_context = on ;important - otherwise calls end up in default context!

pjsip.conf

[acl]
type = acl
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1
;permit = 192.168.1.0/24 ;uncomment if you want to connect clients from LAN
permit = 88.79.152.xxx ;nslookup <area_code>.sip.arcor.de

[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0:5060
local_net = 127.0.0.1
local_net = 192.168.1.0/24

[reg_arcor]
type = registration
transport = transport-udp
contact_user = <area_code><your_number>
client_uri = sip:<area_code><your_number>@<area_code>.sip.arcor.de
server_uri = sip:<area_code>.sip.arcor.de
outbound_auth = auth_arcor
line = yes
endpoint = in_arcor
retry_interval = 30
forbidden_retry_interval = 300
max_retries = 10
auth_rejection_permanent = false

[auth_arcor]
type = auth
auth_type = userpass
realm = arcor.de
username = <area_code><your_number>
password = <password>

[aor_arcor]
type = aor
contact = sip:<area_code>.sip.arcor.de

[in_arcor]
type = endpoint
transport = transport-udp
context = lantiq1_inbound
disallow = all
allow = alaw,g722,ulaw
disable_direct_media_on_nat = yes
rewrite_contact = yes

[out_arcor]
type = endpoint
transport = transport-udp
disallow = all
allow = alaw,g722,ulaw
disable_direct_media_on_nat = yes
callerid = <area_code><your_number>
from_user = <area_code><your_number>
from_domain = <area_code>.sip.arcor.de
outbound_auth = auth_arcor
aors = aor_arcor

EDIT: added line option to registration, see https://blogs.asterisk.org/2016/01/27/the-pjsip-outbound-registration-line-option/

extensions.conf

[general]
static=yes
writeprotect=yes
autofallthrough=yes

[default]
exten => _X.,1,Answer()
same => n,Verbose(1,${CALLERID(num)} reached context DEFAULT by calling ${EXTEN})
same => n,Hangup()

[out_arcor]
; national numbers with country code
exten => _+49ZXX!.,1,Dial(PJSIP/${EXTEN}@out_arcor,60,Trg)
same => n,Hangup()

; national numbers called with leading 0
exten => _0Z.,1,Dial(PJSIP/${EXTEN}@out_arcor,60,Trg)
same => n,Hangup()

; local area numbers
exten => _Z.,1,Dial(PJSIP/${EXTEN}@out_arcor,60,Trg)
same => n,Hangup()

; emergency calls
exten => 110,1,Dial(PJSIP/${EXTEN}@out_arcor,60,Trg)
exten => 110,n,Hangup()
exten => 112,1,Dial(PJSIP/${EXTEN}@out_arcor,60,Trg)
exten => 112,n,Hangup()

; add rules for expensive special numbers. Get German examples from:
; https://www.linuxmaker.com//asterisk-pbx/dialplan-extensionsconf.html
exten => _0137Z.,1,Verbose(1,Blocked: ${EXTEN})
;same => n,Playback(forbidden)
same => n,Hangup()

[lantiq1_inbound]
exten => <area_code><your_number>,1,Dial(TAPI/1,60,t)
same => n,Hangup

[lantiq1]
include => out_arcor

;[lantiq2]
;include => ltq2_out

You should also set your correct country code in indications.conf

If you see a lot of errors like
ERROR[2642]: chan_lantiq.c:844 lantiq_map_rtptype_to_format: unsupported rtptype received is 0xd, forcing ulaw
see post 7

EDIT: refactored/simplified the config a bit

1 Like

I use the following diffconfig for VGV7510KW22 with asterisk13, pjsip and chan_lantiq.
Without luci, dnsmasq, firewall, wifi, pppoe.
The image is about 6.3MB in size, the running system consumes about 32MB RAM.

CONFIG_TARGET_lantiq=y
CONFIG_TARGET_lantiq_xrx200=y
CONFIG_TARGET_lantiq_xrx200_DEVICE_VGV7510KW22NOR=y
# CONFIG_DRIVER_11N_SUPPORT is not set
# CONFIG_FSTOOLS_UBIFS_EXTROOT is not set
CONFIG_OPENSSL_WITH_DEPRECATED=y
CONFIG_OPENSSL_WITH_EC=y
CONFIG_OPENSSL_WITH_NPN=y
CONFIG_OPENSSL_WITH_PSK=y
CONFIG_OPENSSL_WITH_SRP=y
CONFIG_PACKAGE_asterisk13=y
CONFIG_PACKAGE_asterisk13-app-verbose=y
CONFIG_PACKAGE_asterisk13-bridge-simple=y
CONFIG_PACKAGE_asterisk13-cdr-csv=y
CONFIG_PACKAGE_asterisk13-chan-lantiq=y
CONFIG_PACKAGE_asterisk13-codec-a-mu=y
CONFIG_PACKAGE_asterisk13-codec-alaw=y
CONFIG_PACKAGE_asterisk13-codec-g722=y
CONFIG_PACKAGE_asterisk13-codec-ulaw=y
CONFIG_PACKAGE_asterisk13-pjsip=y
CONFIG_PACKAGE_asterisk13-res-pjproject=y
CONFIG_PACKAGE_asterisk13-res-rtp-asterisk=y
CONFIG_PACKAGE_asterisk13-res-sorcery=y
# CONFIG_PACKAGE_br2684ctl is not set
# CONFIG_PACKAGE_bspatch is not set
# CONFIG_PACKAGE_dnsmasq is not set
# CONFIG_PACKAGE_dsl-vrx200-firmware-xdsl-a is not set
# CONFIG_PACKAGE_dsl-vrx200-firmware-xdsl-b-patch is not set
# CONFIG_PACKAGE_firewall is not set
# CONFIG_PACKAGE_ip6tables is not set
# CONFIG_PACKAGE_iptables is not set
# CONFIG_PACKAGE_iw is not set
CONFIG_PACKAGE_jansson=y
# CONFIG_PACKAGE_kmod-atm is not set
# CONFIG_PACKAGE_kmod-cfg80211 is not set
# CONFIG_PACKAGE_kmod-ip6tables is not set
# CONFIG_PACKAGE_kmod-ipt-conntrack is not set
# CONFIG_PACKAGE_kmod-ipt-core is not set
# CONFIG_PACKAGE_kmod-ipt-nat is not set
# CONFIG_PACKAGE_kmod-ltq-atm-vr9 is not set
# CONFIG_PACKAGE_kmod-ltq-ptm-vr9 is not set
# CONFIG_PACKAGE_kmod-ltq-vdsl-vr9 is not set
# CONFIG_PACKAGE_kmod-ltq-vdsl-vr9-mei is not set
# CONFIG_PACKAGE_kmod-mac80211 is not set
# CONFIG_PACKAGE_kmod-nf-conntrack is not set
# CONFIG_PACKAGE_kmod-nf-conntrack6 is not set
# CONFIG_PACKAGE_kmod-nf-ipt is not set
# CONFIG_PACKAGE_kmod-nf-ipt6 is not set
# CONFIG_PACKAGE_kmod-nf-nat is not set
# CONFIG_PACKAGE_kmod-ppp is not set
# CONFIG_PACKAGE_kmod-rt2800-pci is not set
# CONFIG_PACKAGE_kmod-rt2x00-lib is not set
# CONFIG_PACKAGE_kmod-usb-core is not set
# CONFIG_PACKAGE_kmod-usb-dwc2 is not set
CONFIG_PACKAGE_libcap=y
CONFIG_PACKAGE_libedit=y
# CONFIG_PACKAGE_libip4tc is not set
# CONFIG_PACKAGE_libip6tc is not set
CONFIG_PACKAGE_liblua=y
CONFIG_PACKAGE_libncurses=y
CONFIG_PACKAGE_libopenssl=y
CONFIG_PACKAGE_libpcap=y
CONFIG_PACKAGE_libpj=y
CONFIG_PACKAGE_libpjlib-util=y
CONFIG_PACKAGE_libpjmedia=y
CONFIG_PACKAGE_libpjnath=y
CONFIG_PACKAGE_libpjsip=y
CONFIG_PACKAGE_libpjsip-simple=y
CONFIG_PACKAGE_libpjsip-ua=y
CONFIG_PACKAGE_libpjsua=y
CONFIG_PACKAGE_libpjsua2=y
CONFIG_PACKAGE_libpopt=y
CONFIG_PACKAGE_libsqlite3=y
CONFIG_PACKAGE_libsrtp2=y
CONFIG_PACKAGE_libstdcpp=y
CONFIG_PACKAGE_libuuid=y
CONFIG_PACKAGE_libxml2=y
CONFIG_PACKAGE_libxslt=y
# CONFIG_PACKAGE_libxtables is not set
# CONFIG_PACKAGE_linux-atm is not set
# CONFIG_PACKAGE_ltq-vdsl-app is not set
CONFIG_PACKAGE_lua=y
# CONFIG_PACKAGE_odhcp6c is not set
# CONFIG_PACKAGE_odhcpd-ipv6only is not set
# CONFIG_PACKAGE_ppp is not set
CONFIG_PACKAGE_rpcd=y
# CONFIG_PACKAGE_rt2800-pci-firmware is not set
CONFIG_PACKAGE_terminfo=y
# CONFIG_PACKAGE_u-boot-vgv7510kw22_brn is not set
# CONFIG_PACKAGE_u-boot-vgv7510kw22_nor is not set
# CONFIG_PACKAGE_u-boot-vgv7510kw22_ram is not set
# CONFIG_PACKAGE_wireless-regdb is not set
# CONFIG_PACKAGE_wpad-mini is not set
CONFIG_PACKAGE_zlib=y
# CONFIG_TARGET_ROOTFS_UBIFS is not set
CONFIG_PACKAGE_hostapd-common=y
CONFIG_PACKAGE_kmod-eeprom-93cx6=y
CONFIG_PACKAGE_kmod-lib-crc-ccitt=y
CONFIG_PACKAGE_kmod-lib-crc-itu-t=y
CONFIG_PACKAGE_kmod-nls-base=y
CONFIG_PACKAGE_libbz2=y

Asterisk can be further optimized to use less memory, there's ASTERISK13_LOW_MEMORY for example, which I didn't try so far, since the docs mention it can cause instabilities for some modules.

There's also the possibility to slim down Asterisk using modules.conf, see this (older) guide for example:
https://blog.wains.be/2008/2008-04-15-slimming-asterisk-for-the-nslu2-under-debian/

1 Like

chan_lantiq also works with asterisk15 now (I only tested it offline so far, my config isn't in a state where I'd dare to expose it to the internet yet).

Looking at your diffconfig, it should be possible to avoid including mbedtls (asterisk needs openssl anyways) and maybe the iwinfo libraries.

Maybe I'll try v15 to see if the mentioned error occurs with it or not. But for now I'm fine with v13 as it's the latest LTS version

Thanks! Yes, the diffconfig isn't fully optimized yet.

I added the suggestions from @slh to config, which saves another 200KB.

Cleaned the config up a bit and simplified the syntax of DIAL() in extensions.conf.

I tested the config with asterisk15 - worked fine without modifications.

I'm giving up on finding what's causing the RTP errors, I tried every possible RTP-related config option.
Does anyone know what's the best place to report a bug on chan_lantiq? I think about contacting stefan-koch directly.

I finally found out what's causing the RTP errors.
I had voiceactivitydetection = on in my lantiq.conf, which leads to separate comfort noise packages being sent, which chan_lantiq apparently can't handle correctly (yet?).
Either not setting voiceactivitydetection at all or setting it to sc (silence compression only) gets rid of this error.

stefan-koch's fork doesn't provide an issue tracker and the original repository by avlasic seems to be dead. Maybe we can ask stefan to enable issue tracking on his fork. IMHO a bug tracker is better than contacting the developer directly.

Hi Sebastian, hi Plonk,

Thank you for your excellent recipe. I succeeded in converting an 02 Box 6431 (Arcadyan VGV7510KW22) to a (mainly) OpenSource Alternative to a FritzBox (Router, DSL Modem with Vectoring, Analog telephony with asterisk13) in a single device. On LEDE 17.01.4 I installed asterisk from the official repositories with the relevant packages (+asterisk13-codec-g722) and added "chan-lantiq" from Plonk's repository. With your pjsip configuration outbound calls worked perfectly.

However, to enable successful inbound calls, I opened the respective TCP and UDP ports in LEDE's firewall:

root@LEDE:~# vi /etc/config/firewall

config rule                                  
        option target 'ACCEPT'                  
        option src 'wan'                        
        option dest_port '5060'              
        option name 'Allow VoIP Handling'       
        option dest_ip '192.168.1.1'            
        option proto 'tcp udp'               
                                                
config rule                                     
        option enabled '1'                   
        option target 'ACCEPT'                  
        option src 'wan'                        
        option proto 'udp'                   
        option name 'Allow VoIP Stream'         
        option dest_ip '192.168.1.1'            
        option dest_port '10000-20000'  

and additonally made my local vodafone sip server accessible from pjsip:

root@LEDE:~# vi /etc/asterisk/pjsip.conf

[acl]
type = acl
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1
permit = 178.15.xxx.xxx ;nslookup <area_code>.sip.arcor.de

[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0:5060
local_net = 127.0.0.1
local_net = 192.168.1.0/24
external_media_address = 178.15.xxx.xxx ; !!! Your <area_code>.sip.arcor.de IP
external_signaling_address = 178.15.xxx.xxx ; !!! Your <area_code>.sip.arcor.de IP

I just wanted to mention this extra to complete the successful usage of this nice router.

Best

So Di

1 Like

hi @somehow.different
I'm glad my config files were helpful to you.

Please don't open voip-related ports on your WAN interface, this is a huge security risk! If you really need to access your asterisk server from outside your network, do so via VPN.
If you're using a SIP registration like in my configuration it's not necessary to open any port on your firewall for incoming calls to work.
I have used this config behind OpenWrt/LEDE and OPNsense and it always worked without opening ports.

Hi @sebastian_de,

I need to admit, you are absolutely right. There's no need to open the ports. I removed these rules from /etc/config/firewall. Thank you for pointing this out so clearly.

However, I think I have successfully identified the consequence of my and your different configuration. Running asterisk on a dedicated device has the advantage of a valid internet connection being present when asterisk starts.

In my case however, the router start is followed by the DSL handshake upon boot which actually takes quiet some time. I am afraid there's no working internet connection when asterisk is starting, thus compromising the registration with the SIP server. Hence, I switched off the init.d start

root@LEDE:~# /etc/init.d/asterisk disable

and delayed the start of asterisk by 200 sec by a script in rc.local

root@LEDE:~# vi /etc/rc.local

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
/bin/sleep 200
/etc/init.d/asterisk start
exit 0

This made VoIP working even after reboot.

Best
So Di

I also had the problem that pjsip wouldn't re-register after the WAN connection was down for a while. In some cases it might help to add auth_rejection_permanent = false to your registration section, but as far as I understand, at least after retry_interval * max_retries asterisk won't try to re-register until it's reloaded.

I use a helper script that periodically checks for a desired registration. If asterisk isn't registered after 5 minutes while the box is online, asterisk gets restarted. I'm not perfectly happy with this script, as it relies on ping, but it works well for me so far. If your box is also your DSL modem there might be better solutions.

/usr/bin/asterisk_check_registration.sh

#/bin/sh

# Check asterisk registration every 5 minutes.
# When not registered, check internet connection.
# Restart asterisk after 5 minutes, when not
# registered although internet connection works.

registration=reg_arcor
ping_host=arcor.de	# must respond to ping

reg_failed_counter=0

while : ; do
	if ( asterisk -rx "pjsip show registration $registration" | grep -qw "Registered" ); then
		reg_failed_counter=0
		sleep 5m
	else
		if ( ping -c 1 $ping_host > /dev/null ); then	# are we online?
			let "reg_failed_counter++"
			if [ "$reg_failed_counter" -ge "5" ]; then
				/etc/init.d/asterisk restart
				reg_failed_counter=0	# gives asterisk at least 5 minutes to restart and register
			fi
		fi
		sleep 1m
	fi
done

If you add this script to rc.local, make it run in the background, so that exit 0 can be reached. Otherwise you would have to kill the script manually every time you wantedt to reboot

/usr/bin/asterisk_check_registration.sh &
exit 0