Menu Close

Configuring CPL service support in Kamailio 3.1 – Howto

This article continue on series of articles about the Kamailio 3.1.x SIP proxy deployed on debian lenny and its features. In previous articles we have:

1) installed clear Kamailio 3.1.x server

2) added Mysql support for persistance location storage

3) SIREMIS web management interface for our kamailio server.

4) Configuring IM and presence service on Kamailio 3.1 – Howto

5) Configuring XCAP support for SIMPLE.

6) Configuring the TLS support

7) Configuring NAT traversal using Kamailio 3.1 and the Rtpproxy server

and now we are focusing on the CPL service API, for which the kamailio has support inside of its modules.

Prerequisities

  1. Installed and working Kamailio (OpenSER) 3.1.0 server with Mysql enabled.
  2. And from the kamailio web, following modules have to be loaded before the cpl module loading
  • any DB module- a DB module for interfacing the DB operations (modules like mysql, postgres, dbtext, etc)

  • TM (Transaction) module- used for proxying/forking requests

  • SL (StateLess) module – used for sending stateless reply when responding to REGISTER request or for sending back error responses

  • USRLOC (User Location) module – used for implementing lookup("registration") tag (adding into location set of the users' contact)

Following libraries or applications must be also installed before running Kamailio with CPL module loaded:

  • libxml2
  • libxml2-devel.
apt-get install libxml2 libxml2-dev

Preparation

First, we have to install kamailio cpl-c module with

apt-get install kamailio-cpl-modules

which implement the CPL interpreter.

 

Configuration of the Kamailio to use the CPL

The configuration will be inserted into the kamailio.cfg, so open the config file

Loading required modules

Inside of cfg file find sections where modules are loaded (many line which starts with loadmodule), and at the end, behind

loadmodule "db_mysql.so"
loadmodule "tm.so"
loadmodule "sl.so"
loadmodule "usrloc.so"

place line with CPL module loading:

loadmodule "cpl-c.so"

Setting up CPL module parameters

Now we will setup module parameters required for CPL module.

1. First, we have to tell to the module where (in which DB) the CPL scripts are loaded. Because we have enabled the mysql DB , and during its installation we have specified DBRUL parameter which may look like this for example:

#!define DBURL "mysql://openser:openserrw@localhost/kamailio"

we may write into our cfg file:

modparam("cpl-c","db_url",DBURL)

 

2. Now we specify the location of the DTD file which contain the CPL grammar.  The file have to be placed on the server. The questions is where to find such file. I have downloaded the CPLed, the CPL editor from sourceforge, which contain the CPL definition file. then I have extracted the cpl.dtd and upload to my /etc/kamailio folder.

As the other possibilities I found, the dtd file is located inside of the cpl-c module of the kamailio src package.

modparam("cpl-c","cpl_dtd_file","/etc/kamailio/cpl.dtd")

3. As the last step we will configure logging for better diagnostic, folders to which we are pointing on have to exist

modparam("cpl-c", "log_dir", "/var/log/kamamilio/cpl")

modparam("cpl-c","proxy_recurse",2)

Modifying route logic for using of CPL

As a first step we have to modify the REGISTER method handling. We react on the situation where the CPL script may be uploaded by the end user using the REGISTER method, for this purpose there is defined function cpl_process_register().

From the cpl-c module doc about cpl_process_register():

This function MUST be called only for REGISTER requests. It checks if the current REGISTER request is related or not with CPL script upload/download/ remove. If it is, all the needed operation will be done. For checking if the REGISTER is CPL related, the function looks fist to "Content-Type" header. If it exists and has a the mime type set to "application/cpl+xml" means this is a CPL script upload/remove operation. The distinction between to case is made by looking at "Content-Disposition" header; id its value is "script;action=store", means it's an upload; if it's "script;action=remove", means it's a remove operation; other values are considered to be errors. If no "Content-Type" header is present, the function looks to "Accept" header and if it contains the "*" or "application/cpl-xml" the request it will be consider one for downloading CPL scripts. The functions returns to script only if the REGISTER is not related to CPL. In other case, the function will send by itself the necessary replies (stateless – using sl), including for errors.

 

Therefore inside of your kamailio.cfg file find route logic route[REGISTRAR], which is reponsible for registration handling. For kamailio 3.1 should look, where we put line (in yellow)

route[REGISTRAR] {
        if (is_method("REGISTER"))
        {
                cpl_process_register();
                if(isflagset(FLT_NATS))
                {
                        setbflag(FLB_NATB);
                        # uncomment next line to do SIP NAT pinging
                        setbflag(FLB_NATSIPPING);
                }
                if (!save("location"))
                        sl_reply_error();

                exit;
        }
}

 Modifying INVITE message handling

 

Then we modify INVITE message handling to invoke CPL script for incomming calls. I've putted the line into main routing block of the Kamailio 3.1. cfg file.

# account only INVITEs
        if (is_method("INVITE"))
        {
                setflag(FLT_ACC); # do accounting
                # invoke a cpl script ....
                if(!cpl_run_script("incoming","is_statefull"))
                {
                        # script execution failed
                        t_reply("500","CPL script execution failed");
                 };
        } 

 

 And as the last step, restart the kamailio service.

Testing

I have prepared simple script which will reject any SIP call, it look like:

<?xml version="1.0" encoding="UTF-8"?>
<cpl xmlns="urn:ietf:params:xml:ns:cpl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:cpl cpl.xsd" >
  <incoming >
    <reject reason="CPL script reject the call" status="reject" />
  </incoming>
</cpl>

The script was made with the help of the CPLed editor, version 0.4, which should be downloaded from sourceforge.net.

The CPLed is the only one visual CPL editor which I know about, and it also source of some kind of problems.

1) CPLed support two possibilities how to upload a cpl script on a server, HTTP and SIP. For HTTP upload I did not configure the kamailio server yet. For SIP it is using REGISTER message, but the editor does not support SIP authentication, and upload of the script fail where the proxy challenge the editor for authentication (unauthorized fail).

The solution is upload it manually with FTP or ssh (winscp) and then import it. Here for the user palo@ps.sip.uniza.sk. Command have to contain precisely defined SIP uri with sip: prefix (sip:palo@ps.sip.uniza.sk)

kamctl fifo LOAD_CPL sip:palo@ps.sip.uniza.sk /home/palo/cpl/skusk1-cpl.xml

2) Second problem is probably IT based.

Scripts made by the CPLed contain the line:

<cpl xmlns="urn:ietf:params:xml:ns:cpl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:cpl cpl.xsd" >

and during the manual import there is an error:

kamctl fifo LOAD_CPL sip:palo@ps.sip.uniza.sk /home/palo/cpl/skusk1-cpl.xml
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
entering fifo_cmd LOAD_CPL sip:palo@ps.sip.uniza.sk /home/palo/cpl/skusk1-cpl.xml
500 Bad CPL file Log:: Error: CPL script is not a valid XML document
FIFO command was:
:LOAD_CPL:openser_receiver_18437
sip:palo@ps.sip.uniza.sk
/home/palo/cpl/skusk1-cpl.xml

The solution discovered by our students (thanks to andrej) proposed to modify the line (delete it, for example manually), so the script will look:

<?xml version="1.0" encoding="UTF-8"?>
<cpl>
  <incoming >
    <reject reason="CPL script reject the call" status="reject" />
  </incoming>
</cpl>

after this smooth modification the import was sucessfull:

kamctl fifo LOAD_CPL sip:palo@ps.sip.uniza.sk /home/palo/cpl/skusk1-cpl.xml
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
entering fifo_cmd LOAD_CPL sip:palo@ps.sip.uniza.sk /home/palo/cpl/skusk1-cpl.xml
FIFO command was:
:LOAD_CPL:openser_receiver_18549
sip:palo@ps.sip.uniza.sk
/home/palo/cpl/skusk1-cpl.xml
 

 as the control I will get the script for user palo@ back by using GET_CPL:

pstest:/etc/kamailio# kamctl fifo GET_CPL sip:palo@ps.sip.uniza.sk
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
entering fifo_cmd GET_CPL sip:palo@ps.sip.uniza.sk
<?xml version="1.0" encoding="UTF-8"?> <cpl> <incoming >      <reject reason="CPL script reject the call" status="reject" />    </incoming> </cpl>
FIFO command was:
:GET_CPL:openser_receiver_18571
sip:palo@ps.sip.uniza.sk

 so, it have to be there.

Initiating the call on user palo@ps.sip.uniza.sk return message

CPL script reject the call

which declare that the script work!

 

Remove CPL script

The script is removed by:

kamctl fifo REMOVE_CPL sip:palo@ps.sip.uniza.sk
database engine 'MYSQL' loaded
Control engine 'FIFO' loaded
entering fifo_cmd REMOVE_CPL sip:palo@ps.sip.uniza.sk
FIFO command was:
:REMOVE_CPL:openser_receiver_19102
sip:palo@ps.sip.uniza.sk

Call flow

|Time     | 192.168.1.102                         |
|         |                   | 158.193.139.51    |                  
|0,004    |         INVITE SDP ( BV32 g711U g711A g729 telephone-e…t)          |SIP From: sip:pepe@ps.sip.uniza.sk To:sip:palo@ps.sip.uniza.sk
|         |(20018)  ——————>  (5060)   |
|0,061    |         407 Proxy Authentication Required          |SIP Status
|         |(20018)  <——————  (5060)   |
|0,170    |         ACK       |                   |SIP Request
|         |(20018)  ——————>  (5060)   |
|0,170    |         INVITE SDP ( BV32 g711U g711A g729 telephone-e…t)          |SIP From: sip:pepe@ps.sip.uniza.sk To:sip:palo@ps.sip.uniza.sk
|         |(20018)  ——————>  (5060)   |
|0,236    |         603 CPL script reject the call          |SIP Status
|         |(20018)  <——————  (5060)   |
|0,337    |         ACK       |                   |SIP Request
|         |(20018)  ——————>  (5060)   |

 

Rate this post

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.