Technology sharing | interworking between Sip and WebRTC - explanation of SRProxy open source library

SRProxy introduction

At present, the interworking scenarios of WebRTC protocol and SIP protocol are mainly used in enterprise call center, enterprise internal communication, conference call (PSTN), intelligent access control and other scenarios. In order to interworking between WebRTC and sip, two levels of problems should be solved: signaling layer and media layer. The signaling mechanisms used by the two networks are different, so it is necessary to convert the signaling in order to complete the media negotiation and establish the session; The media layer should complete coding conversion, rtp/srtp conversion and other functions. The anyRTC open source SRProxy gateway solves the protocol conversion between WebRTC and sip. In conjunction with the anyRTC open source ARCall audio and video call demo, it demonstrates how to land calls through App/Web. The following describes how to use and deploy the SRProxy gateway and how to communicate with ARCall. After you are familiar with how to use it, you can integrate the SDK into your own application, Make corresponding scenarios with your own business.

Call flow

1, ARCall call logic

2, SRProxy forwarding logic

1. What can SRProxy do?

Briefly summarize from the above figure: SRProxy is not only a bridge to realize the business interworking between RTC and SIP, but also a key service to realize business expansion.

2. ARCall call process

1) State flow chart

In call invitation, the caller can query the relevant status of the current call invitation through the [getState] method provided by the [LocalInvitation] object; The callee can query the relevant status of the current call invitation through the [getState] method of the [remoteinvition] object returned by the SDK.

LocalInvitationState

The following figure describes the flow chart of call invitation status related to the caller:

RemoteInvitationState

The following figure describes the flow chart of call invitation status related to the called:

2) API sequence diagram

Cancel sent call invitation

Accept / reject call invitation

Precautions and restrictions

  • The string length of call invitation content set by the caller: 8 KB, in UTF-8 format.
  • The string length of the call invitation response set by the callee: 8 KB, in UTF-8 format.
  • The channelId of call invitation is only set when interworking with signaling. The set channelId must be the same as the signaling SDK setting to realize interworking. String length: 64 bytes in UTF-8 format.

Create an app

1, Registered account

reach anyRTC official website Register a developer account and create an application

2, Create app get AppId

Deploy freeswitch

1, Prepare

1, System

Centos 7.9 is better to be a pure server, otherwise there may be dependency failure or conflict

2, Firewall

Refer to freeswitch firewall: https://freeswitch.org/confluence/display/FREESWITCH/Firewall

# Open sip port tcp protocol
[root@localhost ~]# firewall-cmd --permanent --add-port=5060/tcp
# Open sip port udp protocol
[root@localhost ~]# firewall-cmd --permanent --add-port=5060/udp
# Open ws port
[root@localhost ~]# firewall-cmd --permanent --add-port=5066/tcp
# Open wss port
[root@localhost ~]# firewall-cmd --permanent --add-port=7443/tcp
# Open rtp port (range)
[root@localhost ~]# firewall-cmd --permanent --add-port=16384-32768/udp
# Make firewall configuration effective
[root@localhost ~]# firewall-cmd --reload

# You can also turn off the firewall directly
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld

2, Compilation environment and FreeSwitch dependency Libraries

# Update yum source
[root@localhost ~]# yum update -y
    
# Install lib related requirements and dependencies
[root@localhost ~]# yum install -y yum-utils git gcc gcc-c++ automake autoconf libtool libtiff-devel libjpeg-devel openssl-devel vim

# Add environment variable
[root@localhost ~]# vim /etc/profile
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
[root@localhost ~]# source /etc/profile
    
# Download the spandsp source code separately
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# git clone https://github.com/freeswitch/spandsp.git
[root@localhost src]# cd spandsp
[root@localhost spandsp]# ./bootstrap.sh
[root@localhost spandsp]# ./configure
[root@localhost spandsp]# make
[root@localhost spandsp]# make install
[root@localhost spandsp]# ldconfig
    
# Download the source code of Sofia SIP (SIP protocol stack) separately and try to use the code cloud, but the freeswitch always reports an error when compiling. Sofia SIP is required
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# git clone https://github.com/freeswitch/sofia-sip.git
[root@localhost src]# cd sofia-sip
[root@localhost sofia-sip]# ./bootstrap.sh -j
[root@localhost sofia-sip]# ./configure
[root@localhost sofia-sip]# make
[root@localhost sofia-sip]# make install
[root@localhost sofia-sip]# ldconfig

# Download the libuuid source code separately
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# wget https://jaist.dl.sourceforge.net/project/libuuid/libuuid-1.0.3.tar.gz
[root@localhost src]# tar -zxvf libuuid-1.0.3.tar.gz
[root@localhost src]# cd libuuid-1.0.3
[root@localhost libuuid-1.0.3]#  ./configure
[root@localhost libuuid-1.0.3]#  make
[root@localhost libuuid-1.0.3]#  make install
    
# Compile and install cmake 3.8.2
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# wget https://cmake.org/files/v3.8/cmake-3.8.2.tar.gz
[root@localhost src]# tar zxvf cmake-3.8.2.tar.gz
[root@localhost cmake]# cd cmake-3.8.2
[root@localhost cmake-3.8.2]# ./bootstrap
[root@localhost cmake-3.8.2]# gmake
[root@localhost cmake-3.8.2]# gmake install

# Install libatomic
[root@localhost ~]# yum install -y libatomic
    
# Download libks source code separately (cmake version 3.7.2 or above is required)
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# git clone https://github.com/signalwire/libks.git
[root@localhost libks]# cmake .
## If there is a uuid error, recompile the libuuid source code, or if there is a uuid error, exit the terminal and re-enter the cmake
[root@localhost libks]# make
[root@localhost libks]# make install
    
# Install fs dependency
[root@localhost ~]# yum install -y http://files.freeswitch.org/freeswitch-release-1-6.noarch.rpm epel-release

# Installing ffmpeg requires
[root@localhost ~]# rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
[root@localhost ~]# rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm

# yum install related dependencies
[root@localhost ~]# yum install -y alsa-lib-devel bison broadvoice-devel bzip2 curl-devel libdb4-devel e2fsprogs-devel erlang flite-devel g722_1-devel gdbm-devel gnutls-devel ilbc2-devel ldns-devel libcodec2-devel libcurl-devel libedit-devel libidn-devel libmemcached-devel libogg-devel libsilk-devel libsndfile-devel libtheora-devel libuuid-devel libvorbis-devel libxml2-devel lua-devel lzo-devel ncurses-devel net-snmp-devel opus-devel pcre-devel perl perl-ExtUtils-Embed pkgconfig portaudio-devel postgresql-devel python-devel python-devel soundtouch-devel speex-devel sqlite-devel unbound-devel unixODBC-devel which yasm zlib-devel libshout-devel libmpg123-devel lame-devel rpm-build libX11-devel libyuv-devel swig wget ffmpeg ffmpeg-devel

# Installing python components
[root@localhost ~]# curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip-2.7.py
[root@localhost ~]# python get-pip-2.7.py
    
# Verify that pip is installed successfully
[root@localhost ~]# pip --version
    
# pip installing python components
[root@localhost ~]# pip install pydub python-ESL pika dbutils

3, Installing FreeSwitch

# git download freeswitch
[root@localhost ~]# git clone -b v1.10 https://github.com/signalwire/freeswitch.git freeswitch
# If the github connection is not smooth, you can try the code cloud image warehouse (the update is 1 day slow)
[root@localhost ~]# git clone -b v1.10 https://gitee.com/mirrors/FreeSWITCH.git freeswitch

# Compiling and installing the freeswitch Prelude
[root@localhost ~]# cd freeswitch
[root@localhost freeswitch]# ./bootstrap.sh -j
[root@localhost freeswitch]# vim modules.conf

Turn notes on or off as needed

formats/mod_shout
languages/mod_python
#event_handlers/mod_cdr_pg_csv
asr_tts/mod_unimrcp
endpoints/mod_rtmp

Use mod if necessary_ xml_ Curl's words

xml_int/mod_xml_curl

Annotate unnecessary modules

#applications/mod_av
#applications/mod_signalwire

Compile and install

[root@localhost freeswitch]# ./configure --with-python=/usr/bin/python2.7 --with-lua=/usr/bin/lua --enable-core-pgsql-support

# If an error is reported at the spandsp position, you can try to execute the following sentence. / configure
[root@localhost freeswitch]# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

# Compile freeswitch
[root@localhost freeswitch]# make

# Compile and install mod_cdr_pg_csv-install
[root@localhost freeswitch]# make mod_unimrcp-install

# If you need an empty module
[root@localhost freeswitch]# make mod_xml_curl-install

# Compile and install audio files (English)
[root@localhost freeswitch]# make cd-sounds-install
[root@localhost freeswitch]# make cd-moh-install

# Compile and install freeswitch
[root@localhost freeswitch]# make install

Additional installation audio files (English)

[root@localhost freeswitch]# make uhd-sounds-install
[root@localhost freeswitch]# make uhd-moh-install
[root@localhost freeswitch]# make hd-sounds-install
[root@localhost freeswitch]# make hd-moh-install
[root@localhost freeswitch]# make sounds-install
[root@localhost freeswitch]# make moh-install

Establish soft connection

[root@localhost freeswitch]# sudo ln -sf /usr/local/freeswitch/bin/freeswitch /usr/local/bin/
[root@localhost freeswitch]# sudo ln -sf /usr/local/freeswitch/bin/fs_cli /usr/local/bin/

Configure mod

[root@localhost ~]# vim /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml

Open in the first 3 lines (the position may be wrong, can be found)

    <load module="mod_console"/>
    <load module="mod_logfile"/>
    <load module="mod_xml_curl"/>

Open comment

    <load module="mod_python"/>
    <load module="mod_shout"/>

Add configuration

    <load module="mod_cdr_pg_csv"/>
    <load module="mod_unimrcp"/>
    <!--<load module="mod_vad"/>-->

Comment out other unnecessary modules

    <!-- <load module="mod_av"/> -->
    <!-- <load module="mod_signalwire"/> -->

If there are no other requirements to deploy freeswitch to this point, it can be ended

Configure acl whitelist

[root@localhost ~]# vim /usr/local/freeswitch/conf/autoload_configs/acl.conf.xml
<!-- Configure according to the actual situation of your own network (copying is invalid) -->
<list name="domains" default="deny">
<!-- domain= is special it scans the domain from the directory to build t$ -->
    <node type="allow" domain="$${domain}"/>
<!-- ==================Add native here ip   127.0.0.1 ======================== -->
<!-- ==================Add local intranet here ip   ======================== -->
<!-- ==================Add local extranet here ip   ======================== -->
<!-- ==================Add here web Intranet ip   192.168.1.221======================== -->
<!-- ==================Add here web Extranet ip   Public network IP======================== -->
<!-- ==================Add here  runcall  Internal and external network Ip======================== -->
    <node type="allow" cidr="192.168.1.0/24"/>
    <node type="allow" cidr="Public network IP/32"/>
</list>
# After saving, in the freeswitch client, enter reload acl reload XML to reload the acl file
[root@localhost ~]# fs_cli
freeswitch@localhost>reloadacl reloadxml

Configure ESL

[root@localhost ~]# vim /usr/local/freeswitch/conf/autoload_configs/event_socket.conf.xml
<configuration name="event_socket.conf" description="Socket Client">
        <settings>
            <param name="nat-map" value="false"/>
            <!--ip Unified to 0.0.0.0-->
            <param name="listen-ip" value="0.0.0.0"/>
            <!-- The default port number is 8021 -->
            <param name="listen-port" value="8021"/>
            <!-- Password unification Aicyber -->
            <param name="password" value="Aicyber"/>
            <!-- allow acl White list IP visit -->
            <param name="apply-inbound-acl" value="domains"/>
            <!--<param name="apply-inbound-acl" value="loopback.auto"/>-->
            <!--<param name="stop-on-bind-error" value="true"/>-->
        </settings>
</configuration>

Adapting WebRTC (JSSIP/SIPJS)

[root@localhost ~]# vim /usr/local/freeswitch/conf/sip_profiles/internal.xml
    <param name="apply-candidate-acl" value="rfc1918.auto"/>
    <param name="apply-candidate-acl" value="localnet.auto"/>
    <param name="apply-candidate-acl" value="candidate"/>
    <!-- Uncomment this line (so that the front end can get the early media) -->
    <param name="enable-100rel" value="true"/>

Adapt to specific terminals (take yunyitong Android SDK as an example)

[root@localhost ~]# vim /usr/local/freeswitch/conf/sip_profiles/internal.xml
    <param name="user-agent-string" value="YunEasy"/>

dial plan

[root@localhost ~]# vim /usr/local/freeswitch/conf/sip_profiles/internal.xml
    <!-- The default is public -->
    <param name="context" value="default"/>

Turn off ipv6

[root@localhost ~]# cd /usr/local/freeswitch/conf/sip_profiles
[root@localhost sip_profiles]# mv internal-ipv6.xml internal-ipv6.xml.removed
[root@localhost sip_profiles]# mv external-ipv6.xml external-ipv6.xml.removed

4: Configure Proxy forwarding rules for Sip

[ root@localhost ~]#Add the following configuration to the VIM / usr / local / freeswitch / conf / dialplan / default.xml ## configuration file. Multiple srproxies are configured with multiple numbers

<extension name="group_dial_sip_proxy">        
    <condition field="destination_number" expression="^0(.*)$">                
        <action application="set"><![CDATA[sip_h_X-Number=<sip:$1@${domain_name}>]]></action>       
        <action application="bridge" data="user/1000@192.168.x.xx"/>        
    </condition>
</extension>

It means that if the SIP number of the call is preceded by 0, it will be automatically routed to the 1000 number; This 1000 number is the Proxy account configured in SRProxy, so that SRProxy can receive SIP outbound call requests and initiate calls from the sender to RTC.

Note: 192.168.x.xx in the configuration is the real IP of your machine. If there is a public EIP, fill in the public EIP address, and if there is a LAN, fill in the LAN IP address.

5, FreeSwitch call time modification

After installing freeswitch, it is found that sip calls can only be received after a delay of about 10 seconds. The main reason is that the delay time is configured by default in freeswitch. You can solve this problem by commenting it out

[root@localhost freeswitch]# vim /usr/local/freeswitch/conf/dialplan/default.xml

      <condition field="${default_password}" expression="^1234$" break="never">
        <action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNI    NG WARNING WARNING "/>
        <action application="log" data="CRIT Open $${conf_dir}/vars.xml and change the default_pas    sword."/>
        <action application="log" data="CRIT Once changed type 'reloadxml' at the console."/>
        <action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNI    NG WARNING WARNING "/>
	<!--<action application="sleep" data="10000"/>-->  #Just comment on this line
      </condition>

Start effective

6, FreeSwitch displays the calling number

[root@localhost freeswitch]# cd /usr/local/freeswitch/conf/directory/default [root@localhost default]# vim 1000.xml

<include>
  <user id="1000">
    <params>
      <param name="password" value="$${default_password}"/>
      <param name="vm-password" value="1000"/>
    </params>
    <variables>
      <variable name="toll_allow" value="domestic,international,local"/>
      <variable name="accountcode" value="1000"/>
      <variable name="user_context" value="default"/>
      <!--<variable name="effective_caller_id_name" value="Extension 1000"/>--> # notes
      <!--<variable name="effective_caller_id_number" value="1000"/>-->	# Comment on these two lines
      <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
      <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
      <variable name="callgroup" value="techsupport"/>
    </variables>
  </user>
</include>

Start effective

## Background quick start
[root@localhost ~]# freeswitch -nc -nonat

## Console startup (service shutdown upon exiting)
[root@localhost ~]# freeswitch

7, FreeSwitch automatically adds numbers

freeswitch is an open source call center service. The default number is 1000-1019. When there are only 20 numbers, you need to add numbers

[root@localhost ~]# vim /usr/local/freeswitch/conf/dialplan/default.xml

 <extension name="Local_Extension">
   <!--<condition field="destination_number" expression="^(10[01][0-9])$">--> # Comment this line or modify it
   <condition field="destination_number" expression="^(1[0-9][0-9][0-9]|20[0-9][0-9])$"> # Redefine the number range as 1000 ~ 2099
     <action application="export" data="dialed_extension=$1"/>
     <!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> -->
     <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>

[root@localhost ~]# freeswitch.sh

#!/bin/bash
# Author:  lzy
# data:   2021-11-16

# set variable
# freeswitch number directory
TARGET_FREESWITCH_PREFIX=/usr/local/freeswitch/conf/directory/default/
# Since there are already 1000-1019 by default, the setting starts from 1020 and can be changed at any time
i=1020

# Set the cycle to end when - le is less than or equal to 2099
while [ $i -le 2599 ]
do
    # I = $I + 1 $I = 1020 step up + 1
    let i=$i+1
    # cp copy 1000.xml rename $i step by step + 1
    cp $TARGET_FREESWITCH_PREFIX/1000.xml  $TARGET_FREESWITCH_PREFIX/$i.xml
    # sed changes 1000 in the 1000.xml file to the value of the file itself
    sed -i "s/1000/$i/" $TARGET_FREESWITCH_PREFIX/$i.xml
done
## Script authorization to execute scripts
[root@localhost ~]# chmod +x freeswitch.sh
[root@localhost ~]# ./freeswitch.sh

## After saving, in the freeswitch client, enter reload xml to reload the. xml file
[root@localhost ~]# fs_cli
freeswitch@localhost>reloadxml

Deploy SRProxy

Source address: https://github.com/anyRTC-UseCase/SipRtcProxy

1, Windows 7+

Double click SipRtcProxy.sln to run directly

The project is created by VS2017, and VS2015 and VS2019 can be verified by themselves.

2, Linux - CentOS 7.0+

Download code to local

[root@localhost ~]# git clone https://github.com/anyRTC-UseCase/SipRtcProxy.git

[root@localhost ~]# cd SipRtcProxy.git

environment variable

[root@localhost SipRtcProxy]# vim  /etc/profile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/SipRtcProxy/so/
[root@localhost SipRtcProxy]# source /etc/profile

implement

[root@localhost SipRtcProxy]# make

configuration file

[root@localhost SipRtcProxy]# vim rtx.conf

[global]
appid=XXXXX			             ## Appid registered when creating an app 
sip_svr=IP:5060      			 ## freeswitch_IP address and port. Currently, only freeswitch default port is supported

## Configure private cloud RTC environment note default connection to public network environment
#[rtc]
#ip=RTC_IP
#port=6080

## Configure private cloud RTM environment note default connection to public network environment
#[rtm]
#ip=RTM_IP
#port=7080

[rtm2sip]
on=1                              ## Whether rtm2sip is enabled; 0: not on 1: on
acc_rule=1005;10[06-19]           ## The number range is adjusted according to freeswitch; Number status: there are 15 numbers in 10051006-1019, which cannot conflict with multiple SRProxy numbers under Appid

[proxy]
on=1                              ## Whether to enable SIP proxy; 0: not on 1: on
sip_account=1000                  ## freeswitch proxy account: 1000. The client cannot conflict with this number; In addition, an SRProxy can only use one number. For another environment, you need to change the number, such as 1001
sip_pwd=1234                      ## freeswitch password
rtm_account=1086                  ## When logging in the RTM account, the client cannot conflict with this number, and only one number can be used for an appid. For another environment, you need to change a number, such as 1087

[log]
#* 0:SENSITIVE 1:VERBOSE 2:INFO 3:WARNING 4:ERROR 5:NONE
level=2
file=rtc_sip.log
max_file_size=100

Foreground start

[root@localhost SipRtcProxy]# ./SRProxy rtx.conf

3, Linux - Centos7.0 + compiled

Download address: https://pan.baidu.com/s/1QhhIsO3NEf9olX19xVxBKg Extraction code: l1f2

Create directory

[root@localhost ~]# mkdir /usr/local/ar4/

[root@localhost ~]# tar zxvf SRProxy.tar.gz

Unzip srproxy.tar.gz in / usr/local/ar4 /

[root@localhost ~]# cd /usr/local/ar4/

[root@localhost ar4]# tar zxvf srproxy.tar.gz

Put the rtx.sh script under / usr/bin and grant permissions

[root@localhost ~]# chmod +x /usr/bin/rtx.sh

Enter directory

[root@localhost ~]# cd /usr/local/ar4/srproxy/ [root@localhost srproxy]# vim conf/rtx.conf

[global]
appid=XXXXX			             ## Appid registered when creating an app 
sip_svr=IP:5060      			 ## freeswitch_IP address and port. Currently, only freeswitch default port is supported

## Configure private cloud RTC environment note default connection to public network environment
#[rtc]
#ip=RTC_IP
#port=6080

## Configure private cloud RTM environment note default connection to public network environment
#[rtm]
#ip=RTM_IP
#port=7080

[rtm2sip]
on=1                              ## Whether rtm2sip is enabled; 0: not on 1: on
acc_rule=1005;10[06-19]           ## The number range is adjusted according to freeswitch; Number status: there are 15 numbers in 10051006-1019, which cannot conflict with multiple SRProxy numbers under Appid

[proxy]
on=1                              ## Whether to enable SIP proxy; 0: not on 1: on
sip_account=1000                  ## freeswitch proxy account: 1000. The client cannot conflict with this number; In addition, an SRProxy can only use one number. For another environment, you need to change the number, such as 1001
sip_pwd=1234                      ## freeswitch password
rtm_account=1086                  ## When logging in the RTM account, the client cannot conflict with this number, and only one number can be used for an appid. For another environment, you need to change a number, such as 1087

[log]
#* 0:SENSITIVE 1:VERBOSE 2:INFO 3:WARNING 4:ERROR 5:NONE
level=2
file=rtc_sip.log
max_file_size=100

Start SRProxy after there is no problem with the configuration

Enter Directory:

[root@localhost ~]# cd /usr/local/ar4/srproxy/

[ root@localhost srproxy]# rtx.sh start SRProxy ## start

[ root@localhost srproxy]# rtx.sh restart SRProxy ## restart

[ root@localhost srproxy]# rtx.sh stop SRProxy ## stop

Add task plan to realize self start

[root@localhost ~]# crontab -e

*/1 * * * * sh /usr/local/ar4/srproxy/moni_srp.sh >/dev/null 2>&1

Demo demo

1, Log in to ARCall (connect to public network RTC and RTM)

Download address of ARCall source code: https://github.com/anyRTC-UseCase/ARCall

The configuration AppId must be consistent with the SRProxy configuration file

2, Login sip (analog phone connection FreeSwitch)

Download address: https://www.microsip.org/downloads

The freeswitch of the connection must be consistent with the SRProxy configuration

To add an account, click menu - > Add account

3, ARCall dials sip

ARCall can dial sip using the normal process, and you can dial as many numbers as you want

Note: the dialing device must have a microphone before dialing

Call succeeded

4, sip dialing ARCall

When SIP calls ARCall, it needs to be preceded by 0, which depends on the configured SIP forwarding rules

Note: the dialing device must have a microphone before dialing

Call succeeded

Tags: cmake git rtc v-im FreeSwitch

Posted on Tue, 30 Nov 2021 05:24:48 -0500 by wacook