Software SIP - H.323 gateway
A short foreword:
Many installed PBX’s are capable of H.323, but it will be difficult to upgrade them to understand SIP. So a challenge to interconnect sipx with existing PBX via H.323 protocol appears. Below is an example implementation via freeswitch/mod_h323.
The principal idea (Thanks Josh) of how to do it documented here: http://wiki.sipfoundry.org/display/sipXecs/Custom+FreeSWITCH+programming
The goal:
The goal is to make the following scheme to work.
sipX =====sip===== FS =====h323===== PBX
Steps:
- Compile FS with mod_h323 on the sipx server.
- Create separate FS sofia profile and dial plan.
- Configure sipx dialplan.
Step 1. Compile FS with mod_h323.
The main idea of recompiling FS on the sipx server is documented here:
http://wiki.sipfoundry.org/display/sipXecs/HowTo+recompile+Freeswitch+on+a+CentOS+5+sipXecs+install
The difference is that before actually compiling FS with mod_h323 one should compile prerequisite libraries (ptlib, and h323plus). It is documented here: http://wiki.freeswitch.org/wiki/Mod_h323
So the whole sequence will be:
- Download FS source http://wiki.freeswitch.org/wiki/Download_FreeSWITCH
- Compile ptlib and h323plus libraries as described in http://wiki.freeswitch.org/wiki/Mod_h323
- In FS source directory edit file
modules.conf
and uncommentendpoints/mod_h323
line
- Configure FS with different prefix like this:
./configure \--prefix=/usr/local/freeswitch_custom
- Run
make
, verify that mod_h323 is compiled.
- Run
make install
to install FS into configured “prefix” directory.
- Edit file
/usr/bin/freeswitch.sh
so that sipx startup scripts will start this newly compiled FS.
/usr/local/freeswitch
should be changed to/usr/local/freeswitch_custom
on lines 47, 118, 120:47: {{FS_EXEC="/usr/local/freeswitch_custom/bin/freeswitch \}} 118: {{if \[WikiWelcome: \! \-x /usr/local/freeswitch_custom/bin/freeswitch \]}} 120: {{echo "Error: FreeSWITCH executable is not at /usr/local/freeswitch_custom/bin/freeswitch" >&2}}
- Backup original
/usr/bin/freeswitch.sh
file with different name, you’ll be able to return to default FS instance at any time.
Now you should be able to stop old and then start new FS instance by
sipxproc -k FreeSwITCH sipxproc -s FreeSwITCH
- For the FS to be able to load mod_h323 the following links should be created:
And
{{/usr/local/freeswitch_custom/lib/libh323_linux_x86_.so.1.22.0 \-> /usr/local/lib/libh323_linux_x86_.so.1.22.0}}
{{/usr/local/freeswitch_custom/lib/libpt.so.2.9-beta0 \-> /usr/local/lib/libpt.so.2.9-beta0}}
Now you should be able to load mod_h323 from fs_cli command line.
- Configure FS to autoload mod_h323:
In the directory/etc/sipxpbx/freeswitch/conf/autoload_configs
create fileh323.conf
:In the same directory edit file<configuration name="h323.conf" description="Opal Endpoints"> <settings> <param name="trace-level" value="4"/> <param name="context" value="h323gw"/> <param name="dialplan" value="XML"/> <param name="codec-prefs" value="PCMA"/> <param name="gk-address" value=""/> <!-- empty to disable, "*" to search LAN --> <param name="gk-identifer" value=""/> <!-- optional name of gk --> <param name="gk-interface" value=""/> <!-- optional listener interface name --> </settings> <listeners> <listener name="default"> <param name="h323-ip" value="$${local_ip_v4}"/> <param name="h323-port" value="1720"/> </listener> </listeners> </configuration>
modules.conf.xml
: add lineto the<load module="mod_h323"/>
endpoints
section.
Add the same line to the /etc/sipxpbx/freeswitch/modules.conf.xml.vm
file.
Now after restarting FreeSWITCH mod_h323 should be loaded.
I don’t know why, but I had to restart the whole sipxecs at this moment, because sipxproc --s “FreeSWITCH” did not start FS, it failed with “configuration check failed. After restarting the whole sipxecs, restarting of just fs, that is sipxproc --k FreeSWITCH and then sipxproc --s FreeSWITCH works ok.
- Check that mod_h323 is loaded:
runIt should show/usr/local/freeswitch_custom/bin/fs_cli -x "show modules" | grep 323
check that port 1720 “is being listened”, run:endpoint,h323,mod_h323,/usr/local/freeswitch_custom/mod/mod_h323.so
it should shownetstat -an | grep -i listen | grep 1720
tcp 0 0 172.23.9.2:1720 0.0.0.0:* LISTEN
Step 2: Create separate FS sofia profile and dial plan.
We want to be independent from the main (used by sipx) FS instance. That’s why we create separate sofia profile (named h323gw) and dialplan.
- Create sofia profile: in the directory
/etc/sipxpbx/freeswitch/conf/sip_profiles
create a fileh323gw.xml
:
<profile name="h323gw"> <!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files --> <gateways> </gateways> <aliases> </aliases> <domains> <domain name="all" alias="false" parse="true"/> </domains> <settings> <param name="debug" value="0"/> <param name="sip-trace" value="no"/> <param name="rfc2833-pt" value="101"/> <param name="sip-port" value="15080"/> <param name="dialplan" value="XML"/> <param name="context" value="h323gw"/> <param name="dtmf-duration" value="100"/> <param name="inbound-codec-prefs" value="$${global_codec_prefs}"/> <param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/> <param name="hold-music" value="$${hold_music}"/> <param name="rtp-timer-name" value="soft"/> <!--<param name="enable-100rel" value="true"/>--> <!-- This could be set to "passive" --> <param name="local-network-acl" value="localnet.auto"/> <param name="manage-presence" value="false"/> <!--<param name="aggressive-nat-detection" value="true"/>--> <param name="inbound-codec-negotiation" value="generous"/> <param name="nonce-ttl" value="60"/> <param name="auth-calls" value="false"/> <!-- added by kond --> <param name="accept-blind-auth" value="true"/> <!-- DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS! --> <param name="rtp-ip" value="$${local_ip_v4}"/> <param name="sip-ip" value="$${local_ip_v4}"/> <param name="ext-rtp-ip" value="auto-nat"/> <param name="ext-sip-ip" value="auto-nat"/> <param name="rtp-timeout-sec" value="300"/> <param name="rtp-hold-timeout-sec" value="1800"/> <!--<param name="enable-3pcc" value="true"/>--> <!-- TLS: disabled by default, set to "true" to enable --> <param name="tls" value="$${external_ssl_enable}"/> <!-- additional bind parameters for TLS --> <param name="tls-bind-params" value="transport=tls"/> <!-- Port to listen on for TLS requests. (5081 will be used if unspecified) --> <param name="tls-sip-port" value="$${external_tls_port}"/> <!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) --> <param name="tls-cert-dir" value="$${external_ssl_dir}"/> <!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 --> <param name="tls-version" value="$${sip_tls_version}"/> </settings> </profile>
We are especially interested in two lines
<param name="sip-port" value="15080"/>
- This profile will listen on port 1580, and we will route calls from sipx to it’s own address:15080
<param name="context" value="h323gw"/>
- FS will process this calls in context h323gw.
- Create separate dialplan: in the directory
/etc/sipxpbx/freeswitch/conf/dialplan
create fileh323gw.xml
:Create directory<!-- [http://wiki.freeswitch.org/wiki/Dialplan_XML] --> <include> <context name="h323gw"> <extension name="unloop"> <condition field="${unroll_loops}" expression="^true$"/> <condition field="${sip_looped_call}" expression="^true$"> <action application="deflect" data="${destination_number}"/> </condition> </extension> <!-- Tag anything pass thru here as an outside_call so you can make sure not to create any routing loops based on the conditions that it came from the outside of the switch. --> <extension name="outside_call" continue="true"> <condition> <action application="set" data="outside_call=true"/> </condition> </extension> <extension name="call_debug" continue="true"> <condition field="${call_debug}" expression="^true$" break="never"> <action application="info"/> </condition> </extension> <X-PRE-PROCESS cmd="include" data="h323gw/*.xml"/> </context> </include>
h323gw
. And two files with arbitrary names there.
One to route calls to h323:And the other to route calls to sipx:<include> <extension> <condition field="destination_number" expression="^(\d{7})$"> <action application="set" data="effective_caller_id_number=${ani}"/> <action application="set" data="PEER_IP=172.23.14.2"/> <action application="set" data="call_timeout=30"/> <action application="set" data="hangup_after_bridge=true"/> <action application="bridge" data="h323/$1@${PEER_IP}"/> </condition> </extension> </include>
<include> <extension> <condition field="destination_number" expression="^(28\[0-9\]{2})$\|^(3\d{3})$"> <action application="set" data="effective_caller_id_number=${outbound_caller_id_number}"/> <action application="set" data="effective_caller_id_name=${outbound_caller_id_name}"/> <action application="set" data="ringback=${us-ring}"/> <action application="bridge" data="sofia/h323gw/$0@beaver.sip.nstel.ru:5080"/> </condition> </extension> </include>
I route to sipxbridge (port 5080) in the above example .
Step 3:
In sipx configure a siptrunk gw with ip address of sipx itself and port 15080.
Route calls to this siptrunk as usual.
I decided to use siptrunk for now, albeit direct (sipxproxy - fs) connection should work fine also.