Merge '/examples' of kamailio svn into sip-router/examples
authorJan Janak <jan@iptel.org>
Mon, 22 Jun 2009 16:14:07 +0000 (18:14 +0200)
committerJan Janak <jan@iptel.org>
Mon, 22 Jun 2009 16:14:11 +0000 (18:14 +0200)
* '/examples' of kamailio svn:
  - renaming: openser -> kamailio
  - doubled $ sign for the env variables, otherwise they would be considered openser PVs
  - fix extra acc mysql example table
  - fix several errors in example configuration
  set proper SVN properties
  - send Message and click-to-dial scripts updated to current IM fifo syntax
  - fix for handling \r\n
  - ctd.sh version for 1.2.0+
  - added sample config to do accounting to MySQL based on default config file
  - examples updated
  - config scripts updated to reflect latest changes (mainly FIFO related)
  - 'break' replaced with 'return' in default config and example files
  Initial revision

20 files changed:
examples/kamailio/acc-mysql.cfg [new file with mode: 0644]
examples/kamailio/acc.cfg [new file with mode: 0644]
examples/kamailio/ctd.sh [new file with mode: 0644]
examples/kamailio/exec_s3.cfg [new file with mode: 0644]
examples/kamailio/exec_s4.cfg [new file with mode: 0644]
examples/kamailio/exec_s5.cfg [new file with mode: 0644]
examples/kamailio/flag_reply.cfg [new file with mode: 0644]
examples/kamailio/fork.cfg [new file with mode: 0644]
examples/kamailio/logging.cfg [new file with mode: 0644]
examples/kamailio/msilo.cfg [new file with mode: 0644]
examples/kamailio/nathelper.cfg [new file with mode: 0644]
examples/kamailio/pstn.cfg [new file with mode: 0644]
examples/kamailio/redirect.cfg [new file with mode: 0644]
examples/kamailio/replicate.cfg [new file with mode: 0644]
examples/kamailio/serial_183.cfg [new file with mode: 0644]
examples/kamailio/web_im/README [new file with mode: 0644]
examples/kamailio/web_im/click_to_dial.html [new file with mode: 0644]
examples/kamailio/web_im/click_to_dial.php [new file with mode: 0644]
examples/kamailio/web_im/send_im.html [new file with mode: 0644]
examples/kamailio/web_im/send_im.php [new file with mode: 0644]

diff --git a/examples/kamailio/acc-mysql.cfg b/examples/kamailio/acc-mysql.cfg
new file mode 100644 (file)
index 0000000..fa187dd
--- /dev/null
@@ -0,0 +1,242 @@
+# $Id$
+#
+# Sample config for MySQL accouting with Kamailio 1.2.0
+#
+# - mysql module must be compiled and installed
+#
+# - new columns have to be added since by default only few are recorded
+# - here are full SQL statements to create acc and missed_calls tables
+#
+# CREATE TABLE `acc` (
+#   `id` int(10) unsigned NOT NULL auto_increment,
+#   `method` varchar(16) NOT NULL default '',
+#   `from_tag` varchar(64) NOT NULL default '',
+#   `to_tag` varchar(64) NOT NULL default '',
+#   `callid` varchar(128) NOT NULL default '',
+#   `sip_code` char(3) NOT NULL default '',
+#   `sip_reason` varchar(32) NOT NULL default '',
+#   `time` datetime NOT NULL default '0000-00-00 00:00:00',
+#   `src_ip` varchar(64) NOT NULL default '',
+#   `dst_user` varchar(64) NOT NULL default '',
+#   `dst_domain` varchar(128) NOT NULL default '',
+#   `src_user` varchar(64) NOT NULL default '',
+#   `src_domain` varchar(128) NOT NULL default '',
+#   INDEX acc_callid (`callid`),
+#   PRIMARY KEY  (`id`)
+# );
+#
+# CREATE TABLE `missed_calls` (
+#   `id` int(10) unsigned NOT NULL auto_increment,
+#   `method` varchar(16) NOT NULL default '',
+#   `from_tag` varchar(64) NOT NULL default '',
+#   `to_tag` varchar(64) NOT NULL default '',
+#   `callid` varchar(128) NOT NULL default '',
+#   `sip_code` char(3) NOT NULL default '',
+#   `sip_reason` varchar(32) NOT NULL default '',
+#   `time` datetime NOT NULL default '0000-00-00 00:00:00',
+#   `src_ip` varchar(64) NOT NULL default '',
+#   `dst_user` varchar(64) NOT NULL default '',
+#   `dst_domain` varchar(128) NOT NULL default '',
+#   `src_user` varchar(64) NOT NULL default '',
+#   `src_domain` varchar(128) NOT NULL default '',
+#   INDEX acc_callid (`callid`),
+#   PRIMARY KEY  (`id`)
+# );
+#
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3            # debug level (cmd line: -dddddddddd)
+fork=yes
+log_stderror=no    # (cmd line: -E)
+
+/* Uncomment these lines to enter debugging mode 
+fork=no
+log_stderror=yes
+*/
+
+check_via=no   # (cmd. line: -v)
+dns=no          # (cmd. line: -r)
+rev_dns=no      # (cmd. line: -R)
+port=5060
+children=4
+
+#
+# uncomment the following lines for TLS support
+#disable_tls = 0
+#listen = tls:your_IP:5061
+#tls_verify_server = 1
+#tls_verify_client = 1
+#tls_require_client_certificate = 0
+#tls_method = TLSv1
+#tls_certificate = "/usr/local/etc/kamailio/tls/user/user-cert.pem"
+#tls_private_key = "/usr/local/etc/kamailio/tls/user/user-privkey.pem"
+#tls_ca_list = "/usr/local/etc/kamailio/tls/user/user-calist.pem"
+
+# ------------------ module loading ----------------------------------
+
+# set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+# Uncomment this if you want to use SQL database
+# - MySQL loaded for accounting as well
+loadmodule "db_mysql.so"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "acc.so"
+loadmodule "mi_fifo.so"
+
+# Uncomment this if you want digest authentication
+# db_mysql.so must be loaded !
+#loadmodule "auth.so"
+#loadmodule "auth_db.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- mi_fifo params --
+
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# -- usrloc params --
+
+#modparam("usrloc", "db_mode",   0)
+
+# Uncomment this if you want to use SQL database 
+# for persistent storage and comment the previous line
+modparam("usrloc", "db_mode", 2)
+
+# -- auth params --
+# Uncomment if you are using auth module
+#
+#modparam("auth_db", "calculate_ha1", yes)
+#
+# If you set "calculate_ha1" parameter to yes (which true in this config), 
+# uncomment also the following parameter)
+#
+#modparam("auth_db", "password_column", "password")
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# -- acc params --
+modparam("acc", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
+# flag to record to db
+modparam("acc", "db_flag", 1)
+modparam("acc", "db_missed_flag", 2)
+# flag to log to syslog
+modparam("acc", "log_flag", 1)
+modparam("acc", "log_missed_flag", 2)
+# use extra accounting to record caller and callee username/domain
+# - take them from From URI and R-URI
+modparam("acc", "log_extra", "src_user=$fU;src_domain=$fd;dst_user=$rU;dst_domain=$rd")
+modparam("acc", "db_extra", "src_user=$fU;src_domain=$fd;dst_user=$rU;dst_domain=$rd")
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+       # initial sanity checks -- messages with
+       # max_forwards==0, or excessively long requests
+       if (!mf_process_maxfwd_header("10")) {
+               sl_send_reply("483","Too Many Hops");
+               exit;
+       };
+
+       if (msg:len >=  2048 ) {
+               sl_send_reply("513", "Message too big");
+               exit;
+       };
+
+       # we record-route all messages -- to make sure that
+       # subsequent messages will go through our proxy; that's
+       # particularly good if upstream and downstream entities
+       # use different transport protocol
+       if (!is_method("REGISTER"))
+               record_route();
+
+       # subsequent messages withing a dialog should take the
+       # path determined by record-routing
+       if (loose_route()) {
+               # mark routing logic in request
+               append_hf("P-hint: rr-enforced\r\n");
+               if(is_method("BYE")) {
+                       # account BYE for STOP record
+                       setflag(1);
+               }
+               route(1);
+       };
+
+       # account all calls
+       if(is_method("INVITE")) {
+               # set accounting on for INVITE (success or missed call)
+               setflag(1);
+               setflag(2);
+       }
+
+       if (!uri==myself) {
+               # mark routing logic in request
+               append_hf("P-hint: outbound\r\n"); 
+               # if you have some interdomain connections via TLS
+               #if(uri=~"@tls_domain1.net") {
+               #       t_relay("tls:domain1.net");
+               #       exit;
+               #} else if(uri=~"@tls_domain2.net") {
+               #       t_relay("tls:domain2.net");
+               #       exit;
+               #}
+               route(1);
+       };
+
+       # if the request is for other domain use UsrLoc
+       # (in case, it does not work, use the following command
+       # with proper names and addresses in it)
+       if (uri==myself) {
+
+               if (is_method("REGISTER")) {
+
+                       # Uncomment this if you want to use digest authentication
+                       #if (!www_authorize("kamailio.org", "subscriber")) {
+                       #       www_challenge("kamailio.org", "0");
+                       #       exit;
+                       #};
+
+                       save("location");
+                       exit;
+               };
+
+               if (!uri==myself) {
+                       append_hf("P-hint: outbound alias\r\n"); 
+                       route(1);
+               };
+
+               # native SIP destinations are handled using our USRLOC DB
+               if (!lookup("location")) {
+                       sl_send_reply("404", "Not Found");
+                       exit;
+               };
+               append_hf("P-hint: usrloc applied\r\n"); 
+       };
+
+       route(1);
+}
+
+
+route[1] {
+       # send it out now; use stateful forwarding as it works reliably
+       # even for UDP2TCP
+       if (!t_relay()) {
+               sl_reply_error();
+       };
+       exit;
+}
+
diff --git a/examples/kamailio/acc.cfg b/examples/kamailio/acc.cfg
new file mode 100644 (file)
index 0000000..90a6244
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# $Id$
+#
+# example: accounting calls to nummerical destinations
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "tm.so"
+loadmodule "acc.so"
+loadmodule "sl.so"
+loadmodule "maxfwd.so"
+loadmodule "rr.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- acc params --
+# set the reporting log level
+modparam("acc", "log_level", 1)
+# number of flag, which will be used for accounting; if a message is
+# labeled with this flag, its completion status will be reported
+modparam("acc", "log_flag", 1 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+       /* ********* ROUTINE CHECKS  ********************************** */
+
+       # filter too old messages
+       if (!mf_process_maxfwd_header("10")) {
+               log("LOG: Too many hops\n");
+               sl_send_reply("483","Too Many Hops");
+               exit;
+       };
+       if (msg:len >=  2048 ) {
+               sl_send_reply("513", "Message too big");
+               exit;
+       };
+
+    #  Process record-routing
+    if (loose_route()) { 
+               # label BYEs for accounting
+               if (method=="BYE") 
+                       setflag(1);
+               t_relay();
+               exit;
+       };
+
+
+       # labeled all transaction for accounting
+       setflag(1);
+
+       # record-route INVITES to make sure BYEs will visit our server too
+       if (method=="INVITE") record_route();
+
+       # forward the request statefuly now; (we need *stateful* forwarding,
+       # because the stateful mode correlates requests with replies and
+       # drops retranmissions; otherwise, we would have to report on
+       # every single message received)
+       if (!t_relay()) {
+               sl_reply_error(); 
+               exit; 
+       };
+
+}
diff --git a/examples/kamailio/ctd.sh b/examples/kamailio/ctd.sh
new file mode 100644 (file)
index 0000000..f792aac
--- /dev/null
@@ -0,0 +1,224 @@
+#!/bin/sh
+#
+# $Id$
+#
+# Usage: ctd.sh $FROM $TARGET
+# 
+# click-to-dial example using REFER
+#----------------------------------
+#
+# About:
+# ------
+# this script initiates a call from SIP user $FROM to SIP
+# user $TARGET; it works as follows: a dummy user invites
+# $FROM to a dummy "call on hold"; as soon as it is set up, the
+# dummy user transfers $FROM to $TARGET  (REFER transaction)
+# and terminates the dummy session established previously
+# (BYE transaction). Note: the "dummy call" is used to
+# make $FROM accept $REFER -- most of SIP phones do not
+# accept REFER if no call has not been established yet.
+#
+# Requirements: 
+# -------------
+# - SER with FIFO server turned on and TM module loaded
+#
+# Limitations: 
+# ------------
+# it only works with UAs supporting REFER; it has been tested 
+# with Cisco 7960, Mitel 5055, Grandstream and Pingtel; Windows 
+# Messenger does not support REFER. Never tested on solaris. 
+# Some cisco 7960 images don't work (in particular, POS30202
+# doesnt, POS3-03-8-21 does)
+#
+# History:
+# --------
+# 2003-03-01 bug_fix: route set reversed
+# 2003-02-27 dialog support completed (jiri)
+# 2003-04-28 dialog info precomputed in SER (jiri)
+# 2007-04-06 updated for Kamailio 1.2.0+ (daniel)
+
+#--------------------------------
+# config: who with whom
+# address of the final destination to which we want to transfer
+# initial CSeq and CallId
+if [ -z "$2" ]; then
+       TARGET="sip:23@192.168.2.16"
+       echo "destination unspecified -- taking default value $TARGET"
+else
+       TARGET="$2"
+fi
+# address of user wishing to initiate conversation
+if [ -z "$1" ] ; then
+       URI="sip:44@192.168.2.16"
+       echo "caller unspecified -- taking default value $URI"
+else
+       URI="$1"
+fi
+
+#---------------------------------
+# fixed config data
+FIFO="/tmp/kamailio_fifo"
+# address of controller
+FROM="<sip:controller@foo.bar>"
+CSEQ="1"
+CALLIDNR=`date '+%s'`$$
+CALLID="${CALLIDNR}.fifouacctd"
+name="ctd_fifo_$$"
+fifo_reply="/tmp/$name"
+dlg="/tmp/$CALLID.dlg"
+FIXED_DLG="From: $FROM;tag=$CALLIDNR\r\nCall-ID: $CALLID\r\nContact: <sip:caller@!!>\r\n"
+#----------------------------------
+
+# generate parts of FIFO-request essential to forming
+# subsequent in-dialog reuqests
+# 
+# limitations: parsing broken if <> in display names or
+# line-folding used
+filter_fl()
+{
+
+awk -F ' ' '
+BEGIN { IGNORECASE=1; line=0; eoh=0;ret=1 }
+END { exit ret; }
+
+{line++; }
+
+# line 2: status code
+line==2 && /^2[0-9][0-9] / { ret=0;next; }
+line==2 && /^[3-6][0-9][0-9] / { print; print $0 > "/dev/stderr"; next; }
+line==2 { print "reply error"; print; next; } 
+
+# skip body
+/^$/ { eoh=1 }
+eoh==1 { next }
+
+# uri and outbound uri at line 2,3: copy and paste
+line==3 { print $0; next; }
+line==4 { print $0; print "."; printf("\""); next; }
+# line 5: Route; empty if ".", copy and paste otherwise
+line==5 && /^\.$/ { next; }
+# if non-empty, copy and paste it
+line==5 { printf("%s\n", $0); next; }
+# filter out to header field for use in next requests
+/^(To|t):/ { printf("%s\n", $0); next; }
+# anything else will be ignored
+{next} 
+       ' # end of awk script
+} # end of filter_fl
+
+#---------------------------
+# main
+
+# set up exit cleaner
+trap "rm -f $dlg $fifo_reply; exit 1" 0
+
+# set up FIFO communication
+
+if [ ! -w $FIFO ] ; then # can I write to FIFO server?
+       echo "Error opening ser's FIFO $FIFO"
+       exit 1
+fi
+mkfifo $fifo_reply # create a reply FIFO
+if [ $? -ne 0 ] ; then
+       echo "error opening reply fifo $fifo_reply"
+       exit 1
+fi
+chmod a+w $fifo_reply
+# start reader now so that it is ready for replies
+# immediately after a request is out
+
+cat < $fifo_reply | filter_fl > $dlg  &
+fifo_job="$!"
+
+# initiate dummy INVITE with pre-3261 "on-hold"
+# (note the dots -- they mean in order of appearance:
+# outbound uri, end of headers, end of body; eventualy
+# the FIFO request must be terminated with an empty line)
+#cat <<EOF
+cat > $FIFO <<EOF
+:t_uac_dlg:$name
+INVITE 
+$URI
+.
+.
+"`printf "${FIXED_DLG}To: <$URI>\r\nCSeq: $CSEQ INVITE\r\nContent-Type: application/sdp\r\n"`
+"
+"`printf "v=0\r\no=click-to-dial 0 0 IN IP4 0.0.0.0\r\ns=session\r\nc=IN IP4 0.0.0.0\r\nb=CT:1000\r\nt=0 0\r\nm=audio 9 RTP/AVP 8 0\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:0 PCMU/8000\r\n"`
+"
+
+EOF
+#exit
+
+# wait for reply 
+wait $fifo_job # returns completion status of filter_fl
+if [ "$?" -ne "0" ] ; then
+       echo "invitation failed"
+       exit 1
+fi
+
+echo "invitation succeeded"
+
+# proceed to REFER now
+if [ \! -r $dlg ] ; then
+       echo "dialog broken"
+       exit 1
+fi
+CSEQ=`expr $CSEQ + 1`
+
+# start reader now so that it is ready for replies
+# immediately after a request is out
+
+cat < $fifo_reply | filter_fl > /dev/null  &
+fifo_job="$!"
+
+# dump the REFER request to FIFO server 
+cat > $FIFO <<EOF
+:t_uac_dlg:$name
+REFER
+`cat $dlg; printf "${FIXED_DLG}CSeq: $CSEQ REFER\r\nReferred-By: $FROM\r\nRefer-To: $TARGET\r\n"`
+"
+
+EOF
+
+# report REFER status
+wait $fifo_job
+ref_ret="$?"
+
+if [ "$ref_ret" -ne "0" ] ; then
+       echo "refer failed"
+else
+       echo "refer succeeded"
+fi
+
+
+# well, URI is trying to call TARGET but still maintains the
+# dummy call we established with previous INVITE transaction:
+# tear it down
+
+
+# dump the BYE request to FIFO server 
+CSEQ=`expr $CSEQ + 1`
+cat < $fifo_reply | filter_fl > /dev/null  &
+fifo_job="$!"
+cat > $FIFO <<EOF
+:t_uac_dlg:$name
+BYE
+`cat $dlg; printf "${FIXED_DLG}CSeq: $CSEQ BYE\r\n"`
+"
+
+EOF
+
+# report BYE status
+wait $fifo_job
+ret="$?"
+
+if [ "$ret" -ne "0" ] ; then
+       echo "bye failed"
+       exit 1
+fi
+echo "bye succeeded"
+
+# clean-up
+trap 0
+rm -f $dlg $fifo_reply
+exit $ref_ret
diff --git a/examples/kamailio/exec_s3.cfg b/examples/kamailio/exec_s3.cfg
new file mode 100644 (file)
index 0000000..fd7346d
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# $Id$
+#
+# email notification to email address from mysql database
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "exec.so"
+loadmodule "sl.so"
+
+# send email if a request arrives
+route[0] {
+     if (!exec_msg('
+       QUERY="select email_address from subscriber 
+               where user=\"$$SIP_OUSER\"";
+       EMAIL=`mysql  -Bsuser -pheslo -e "$$QUERY" kamailio`;
+       if [ -z "$$EMAIL" ] ; then exit 1; fi ;
+       echo "SIP request received from $$SIP_HF_FROM for $$SIP_OUSER" |
+       mail -s "request for you" $$EMAIL ')) {
+               # exec returned error ... user does not exist
+               sl_send_reply("404", "User does not exist");
+       } else {
+               sl_send_reply("600", "No messages for this user");
+       };
+               
+}
diff --git a/examples/kamailio/exec_s4.cfg b/examples/kamailio/exec_s4.cfg
new file mode 100644 (file)
index 0000000..92dd1dc
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# $Id$
+#
+# email notification to email address from mysql database
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+loadmodule "exec.so"
+loadmodule "sl.so"
+loadmodule "tm.so"
+
+# send email if a request arrives; process statefully
+# to avoid multiple execution on request retransmissions
+route[0] {
+       # stop script processing if transaction exists
+       if ( !t_newtran()) {
+               sl_reply_error();
+               return;
+       };
+
+       if (!exec_msg('
+               QUERY="select email_address from subscriber 
+                       where user=\"$$SIP_OUSER\"";
+               EMAIL=`mysql  -Bsuser -pheslo -e "$$QUERY" ser`;
+               if [ -z "$EMAIL" ] ; then exit 1; fi ;
+               echo "SIP request received from $$SIP_HF_FROM for $$SIP_OUSER" |
+               mail -s "request for you" $$EMAIL ')) 
+       {
+               # exec returned error ... user does not exist
+               # send a stateful reply
+               t_reply("404", "User does not exist");
+       } else {
+               t_reply("600", "No messages for this user");
+       };
+               
+}
diff --git a/examples/kamailio/exec_s5.cfg b/examples/kamailio/exec_s5.cfg
new file mode 100644 (file)
index 0000000..2d769c5
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# $Id$
+#
+# simple quick-start config script
+#
+
+# ----------- global configuration parameters ------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "exec.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+route{
+       # uri for my domain ?
+       if (uri==myself) {
+
+               if (method=="REGISTER") {
+                       save("location");
+                       return;
+               };
+
+               # native SIP destinations are handled using our USRLOC DB
+               if (!lookup("location")) {
+                       # proceed to email notification
+                       if (method=="INVITE") route(1)
+                       else sl_send_reply("404", "Not Found");
+                       exit;
+               };
+       };
+       # user found, forward to his current uri now
+       if (!t_relay()) {
+               sl_reply_error();
+       };
+}
+
+/* handling of missed calls */
+route[1] {
+       # don't continue if it is a retransmission
+       if ( !t_newtran()) {
+               sl_reply_error();
+               exit;
+       };
+       # external script: lookup user, if user exists, send 
+       # an email notification to him
+    if (!exec_msg('
+               QUERY="select email_address from subscriber 
+                       where user=\"$$SIP_OUSER\"";
+               EMAIL=`mysql  -Bsuser -pheslo -e "$$QUERY" ser`;
+               if [ -z "$$EMAIL" ] ; then exit 1; fi ;
+               echo "SIP request received from $$SIP_HF_FROM for $$SIP_OUSER" |
+               mail -s "request for you" $$EMAIL ')) 
+       {
+               # exec returned error ... user does not exist
+               # send a stateful reply
+               t_reply("404", "User does not exist");
+       } else {
+               t_reply("600", "No messages for this user");
+       };
+       exit;
+}
diff --git a/examples/kamailio/flag_reply.cfg b/examples/kamailio/flag_reply.cfg
new file mode 100644 (file)
index 0000000..9fe730c
--- /dev/null
@@ -0,0 +1,103 @@
+#
+# $Id$
+#
+# simple quick-start config script
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3         # debug level (cmd line: -dddddddddd)
+fork=yes
+log_stderror=no        # (cmd line: -E)
+
+fork=no
+log_stderror=yes
+
+check_via=no   # (cmd. line: -v)
+dns=no           # (cmd. line: -r)
+rev_dns=no      # (cmd. line: -R)
+children=4
+
+port=5060
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+# Uncomment this if you want to use SQL database
+#loadmodule "db_mysql.so"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "mi_fifo.so"
+
+# Uncomment this if you want digest authentication
+# mysql.so must be loaded !
+#loadmodule "auth.so"
+#loadmodule "auth_db.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- mi_fifo params --
+
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# -- usrloc params --
+
+modparam("usrloc", "db_mode",   0)
+
+# Uncomment this if you want to use SQL database 
+# for persistent storage and comment the previous line
+#modparam("usrloc", "db_mode", 2)
+
+# -- auth params --
+# Uncomment if you are using auth module
+#
+#modparam("auth_db", "calculate_ha1", yes)
+#
+# If you set "calculate_ha1" parameter to yes (which true in this config), 
+# uncomment also the following parameter)
+#
+#modparam("auth_db", "password_column", "password")
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+       setflag(1);
+       t_on_failure("1");
+       t_on_reply("1");
+       log(1, "message received\n");
+       t_relay("udp:kamailio.org:5060");
+}
+
+onreply_route[1]
+{
+       if (isflagset(1)) {
+               log(1, "onreply: flag set\n");
+       } else {
+               log(1, "onreply: flag unset\n");
+       };
+}
+
+failure_route[1] 
+{
+       if (isflagset(1)) {
+               log(1, "failure: flag set\n");
+       } else {
+               log(1, "failure: flag unset\n");
+       };
+}
+
diff --git a/examples/kamailio/fork.cfg b/examples/kamailio/fork.cfg
new file mode 100644 (file)
index 0000000..887981f
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# $Id$
+#
+# example script showing both types of forking;
+# incoming message is forked in parallel to
+# 'nobody' and 'parallel', if no positive reply
+# appears with final_response timer, nonsense
+# is retried (serial forking); than, destination
+# 'foo' is given last chance
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- tm params --
+# set time for which ser will be waiting for a final response;
+# fr_inv_timer sets value for INVITE transactions, fr_timer
+# for all others
+modparam("tm", "fr_inv_timer", 15 )
+modparam("tm", "fr_timer", 10 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+       # for testing purposes, simply okay all REGISTERs
+       if (method=="REGISTER") {
+               log("REGISTER");
+               sl_send_reply("200", "ok");
+               exit;
+       };
+       # try these two destinations first in parallel; the second
+       # destination is targeted to sink port -- that will make ser
+       # wait until timer hits
+       seturi("sip:nobody@kamailio.org");
+       append_branch("sip:parallel@kamailio.org:9");
+       # if we do not get a positive reply, continue at reply_route[1]
+       t_on_failure("1");
+       # forward the request to all destinations in destination set now 
+       t_relay();
+}
+
+failure_route[1] {
+       # forwarding failed -- try again at another destination 
+       append_branch("sip:nonsense@kamailio.org");
+       log(1,"first redirection\n");
+       # if this alternative destination fails too, proceed to reply_route[2] 
+       t_on_failure("2");
+       t_relay();
+}
+
+failure_route[2] {
+       # try out the last resort destination
+       append_branch("sip:foo@kamailio.org");
+       log(1, "second redirection\n");
+       # we no more call t_on_negative here; if this destination
+       # fails too, transaction will complete
+       t_relay();
+}
diff --git a/examples/kamailio/logging.cfg b/examples/kamailio/logging.cfg
new file mode 100644 (file)
index 0000000..c56bb2f
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# $Id$
+#
+# logging example
+#
+
+# ------------------ module loading ----------------------------------
+
+fork=no
+port=5060
+log_stderror=yes
+debug=3
+
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+       # for testing purposes, simply okay all REGISTERs
+       if (method=="REGISTER") {
+               log(1, "REGISTER received\n");
+       } else {
+               log(1, "non-REGISTER received\n");
+       };
+       if (uri=~"sip:.*[@:]siphub.net") {
+               log(1, "request for siphub.net received\n");
+       } else {
+               log(1, "request for other domain received\n");
+       };
+}
diff --git a/examples/kamailio/msilo.cfg b/examples/kamailio/msilo.cfg
new file mode 100644 (file)
index 0000000..2a02fbf
--- /dev/null
@@ -0,0 +1,146 @@
+#
+# MSILO usage example
+#
+# $ID: daniel $
+#
+
+
+
+children=2
+check_via=no      # (cmd. line: -v)
+dns=off           # (cmd. line: -r)
+rev_dns=off       # (cmd. line: -R)
+
+
+# ------------------ module loading ----------------------------------
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "textops.so"
+
+loadmodule "sl.so"
+loadmodule "db_mysql.so"
+loadmodule "maxfwd.so"
+loadmodule "tm.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "msilo.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- registrar params --
+
+modparam("registrar", "default_expires", 120)
+
+# -- registrar params --
+
+modparam("usrloc", "db_mode", 0)
+
+# -- msilo params --
+
+modparam("msilo", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
+
+# -- tm params --
+
+modparam("tm", "fr_timer", 10 )
+modparam("tm", "fr_inv_timer", 15 )
+modparam("tm", "wt_timer", 10 )
+
+
+route{
+       if ( !mf_process_maxfwd_header("10") )
+       {
+               sl_send_reply("483","To Many Hops");
+               exit;
+       };
+
+
+       if (uri==myself) {
+               # for testing purposes, simply okay all REGISTERs
+               # is_method("XYZ") is faster than (method=="XYZ")
+               #  but requires textops module
+               if (is_method("REGISTER"))
+               {
+                       save("location");
+                       log("REGISTER received -> dumping messages with MSILO\n");
+
+                       # MSILO - dumping user's offline messages
+                       if (m_dump())
+                       {
+                               log("MSILO: offline messages dumped - if they were\n");
+                       }else{
+                               log("MSILO: no offline messages dumped\n");
+                       };
+                       exit;
+               };
+
+               # backup r-uri for m_dump() in case of delivery failure
+               $avp(i:11) = $ru;
+
+               # domestic SIP destinations are handled using our USRLOC DB
+               
+               if(!lookup("location")) 
+               {
+                       if (! t_newtran())
+                       {
+                               sl_reply_error();
+                               exit;
+                       };
+                       # we do not care about anything else but MESSAGEs
+                       if (!is_method("MESSAGE"))
+                       {
+                               if (!t_reply("404", "Not found")) 
+                               {
+                                       sl_reply_error();
+                               };
+                               exit;
+                       };
+                       log("MESSAGE received -> storing using MSILO\n");
+                       # MSILO - storing as offline message
+                       if (m_store("$ru"))
+                       {
+                               log("MSILO: offline message stored\n");
+                               if (!t_reply("202", "Accepted")) 
+                               {
+                                       sl_reply_error();
+                               };
+                       }else{
+                               log("MSILO: offline message NOT stored\n");
+                               if (!t_reply("503", "Service Unavailable")) 
+                               {
+                                       sl_reply_error();
+                               };
+                       };
+                       exit;
+               };
+               # if the downstream UA does not support MESSAGE requests
+               # go to failure_route[1]
+               t_on_failure("1");
+               t_relay();
+               exit;
+       };
+
+       # forward anything else
+       t_relay();
+}
+
+failure_route[1] {
+       # forwarding failed -- check if the request was a MESSAGE 
+       if (!is_method("MESSAGE"))
+       {
+               exit;
+       };
+       
+       log(1,"MSILO: the downstream UA does not support MESSAGE requests ...\n");
+       # we have changed the R-URI with the contact address -- ignore it now
+       if (m_store("$avp(i:11)"))
+       {
+               log("MSILO: offline message stored\n");
+               t_reply("202", "Accepted"); 
+       }else{
+               log("MSILO: offline message NOT stored\n");
+               t_reply("503", "Service Unavailable");
+       };
+}
+
+
diff --git a/examples/kamailio/nathelper.cfg b/examples/kamailio/nathelper.cfg
new file mode 100644 (file)
index 0000000..56c0cae
--- /dev/null
@@ -0,0 +1,237 @@
+#
+# $Id$
+#
+# simple quick-start config script including nathelper support
+
+# This default script includes nathelper support. To make it work
+# you will also have to install Maxim's RTP proxy. The proxy is enforced
+# if one of the parties is behind a NAT.
+#
+# If you have an endpoing in the public internet which is known to
+# support symmetric RTP (Cisco PSTN gateway or voicemail, for example),
+# then you don't have to force RTP proxy. If you don't want to enforce
+# RTP proxy for some destinations than simply use t_relay() instead of
+# route(1)
+#
+# Sections marked with !! Nathelper contain modifications for nathelper
+#
+# NOTE !! This config is EXPERIMENTAL !
+#
+# ----------- global configuration parameters ------------------------
+
+debug=3         # debug level (cmd line: -dddddddddd)
+fork=yes
+log_stderror=no        # (cmd line: -E)
+
+/* Uncomment these lines to enter debugging mode 
+fork=no
+log_stderror=yes
+*/
+
+check_via=no   # (cmd. line: -v)
+dns=no           # (cmd. line: -r)
+rev_dns=no      # (cmd. line: -R)
+port=5060
+children=4
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+# Uncomment this if you want to use SQL database
+#loadmodule "mysql.so"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "textops.so"
+loadmodule "mi_fifo.so"
+
+# Uncomment this if you want digest authentication
+# db_mysql.so must be loaded !
+#loadmodule "auth.so"
+#loadmodule "auth_db.so"
+
+# !! Nathelper
+loadmodule "nathelper.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# -- mi_fifo params --
+
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# -- usrloc params --
+
+modparam("usrloc", "db_mode",   0)
+
+# Uncomment this if you want to use SQL database 
+# for persistent storage and comment the previous line
+#modparam("usrloc", "db_mode", 2)
+
+# -- auth params --
+# Uncomment if you are using auth module
+#
+#modparam("auth_db", "calculate_ha1", yes)
+#
+# If you set "calculate_ha1" parameter to yes (which true in this config), 
+# uncomment also the following parameter)
+#
+#modparam("auth_db", "password_column", "password")
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# !! Nathelper
+modparam("usrloc","nat_bflag",6)
+modparam("nathelper","sipping_bflag",8)
+modparam("nathelper", "ping_nated_only", 1)   # Ping only clients behind NAT
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+       # initial sanity checks -- messages with
+       # max_forwards==0, or excessively long requests
+       if (!mf_process_maxfwd_header("10")) {
+               sl_send_reply("483","Too Many Hops");
+               exit;
+       };
+       if (msg:len >=  2048 ) {
+               sl_send_reply("513", "Message too big");
+               exit;
+       };
+
+       # !! Nathelper
+       # Special handling for NATed clients; first, NAT test is
+       # executed: it looks for via!=received and RFC1918 addresses
+       # in Contact (may fail if line-folding is used); also,
+       # the received test should, if completed, should check all
+       # vias for rpesence of received
+       if (nat_uac_test("3")) {
+               # Allow RR-ed requests, as these may indicate that
+               # a NAT-enabled proxy takes care of it; unless it is
+               # a REGISTER
+
+               if (is_method("REGISTER") || !is_present_hf("Record-Route")) {
+                   log("LOG: Someone trying to register from private IP, rewriting\n");
+
+                   # This will work only for user agents that support symmetric
+                   # communication. We tested quite many of them and majority is
+                   # smart enough to be symmetric. In some phones it takes a configuration
+                   # option. With Cisco 7960, it is called NAT_Enable=Yes, with kphone it is
+                   # called "symmetric media" and "symmetric signalling".
+
+                   fix_nated_contact(); # Rewrite contact with source IP of signalling
+                   if ( is_method("INVITE") ) {
+                       fix_nated_sdp("1"); # Add direction=active to SDP
+                   };
+                   force_rport(); # Add rport parameter to topmost Via
+                   setbflag(6);    # Mark as NATed
+                       
+                       # if you want sip nat pinging
+                       # setbflag(8);
+               };
+       };
+
+       # we record-route all messages -- to make sure that
+       # subsequent messages will go through our proxy; that's
+       # particularly good if upstream and downstream entities
+       # use different transport protocol
+       if (!is_method("REGISTER")) record_route();
+
+       # subsequent messages withing a dialog should take the
+       # path determined by record-routing
+       if (loose_route()) {
+               # mark routing logic in request
+               append_hf("P-hint: rr-enforced\r\n"); 
+               route(1);
+               exit;
+       };
+
+       if (!uri==myself) {
+               # mark routing logic in request
+               append_hf("P-hint: outbound\r\n"); 
+               route(1);
+               exit;
+       };
+
+       # if the request is for other domain use UsrLoc
+       # (in case, it does not work, use the following command
+       # with proper names and addresses in it)
+       if (uri==myself) {
+
+               if (method=="REGISTER") {
+
+# Uncomment this if you want to use digest authentication
+#                      if (!www_authorize("siphub.org", "subscriber")) {
+#                              www_challenge("siphub.org", "0");
+#                              return;
+#                      };
+
+                       save("location");
+                       exit;
+               };
+
+               lookup("aliases");
+               if (!uri==myself) {
+                       append_hf("P-hint: outbound alias\r\n"); 
+                       route(1);
+                       exit;
+               };
+
+               # native SIP destinations are handled using our USRLOC DB
+               if (!lookup("location")) {
+                       sl_send_reply("404", "Not Found");
+                       exit;
+               };
+       };
+       append_hf("P-hint: usrloc applied\r\n"); 
+       route(1);
+}
+
+route[1] 
+{
+       # !! Nathelper
+       if (uri=~"[@:](192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" && !search("^Route:")){
+               sl_send_reply("479", "We don't forward to private IP addresses");
+               exit;
+       };
+
+       # if client or server know to be behind a NAT, enable relay
+       if (isbflagset(6)) {
+               force_rtp_proxy();
+       };
+
+       # NAT processing of replies; apply to all transactions (for example,
+       # re-INVITEs from public to private UA are hard to identify as
+       # NATed at the moment of request processing); look at replies
+       t_on_reply("1");
+
+       # send it out now; use stateful forwarding as it works reliably
+       # even for UDP2TCP
+       if (!t_relay()) {
+               sl_reply_error();
+       };
+}
+
+# !! Nathelper
+onreply_route[1] {
+       # NATed transaction ?
+       if (isbflagset(6) && status =~ "(183)|2[0-9][0-9]") {
+               fix_nated_contact();
+               force_rtp_proxy();
+       # otherwise, is it a transaction behind a NAT and we did not
+       # know at time of request processing ? (RFC1918 contacts)
+       } else if (nat_uac_test("1")) {
+               fix_nated_contact();
+       };
+}
+
diff --git a/examples/kamailio/pstn.cfg b/examples/kamailio/pstn.cfg
new file mode 100644 (file)
index 0000000..e13524c
--- /dev/null
@@ -0,0 +1,148 @@
+#
+# $Id$
+#
+# example: ser configured as PSTN gateway guard; PSTN gateway is located
+# at 192.168.0.10
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "acc.so"
+loadmodule "rr.so"
+loadmodule "maxfwd.so"
+loadmodule "db_mysql.so"
+loadmodule "auth.so"
+loadmodule "auth_db.so"
+loadmodule "group.so"
+loadmodule "uri.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+modparam("auth_db", "db_url","mysql://kamailio:kamailiorw@localhost/kamailio")
+modparam("auth_db", "calculate_ha1", yes)
+modparam("auth_db", "password_column", "password")
+
+# -- acc params --
+modparam("acc", "log_level", 1)
+# that is the flag for which we will account -- don't forget to
+# set the same one :-)
+modparam("acc", "log_flag", 1 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+       /* ********* ROUTINE CHECKS  ********************************** */
+
+       # filter too old messages
+       if (!mf_process_maxfwd_header("10")) {
+               log("LOG: Too many hops\n");
+               sl_send_reply("483","Too Many Hops");
+               exit;
+       };
+       if (msg:len >=  2048 ) {
+               sl_send_reply("513", "Message too big");
+               exit;
+       };
+
+       /* ********* RR ********************************** */
+
+       /* grant Route routing if route headers present */
+       if (loose_route()) { t_relay(); exit; };
+       
+       /* record-route INVITEs -- all subsequent requests must visit us */
+       if (method=="INVITE") {
+               record_route();
+       };
+
+       # now check if it really is a PSTN destination which should be handled
+       # by our gateway; if not, and the request is an invitation, drop it --
+       # we cannot terminate it in PSTN; relay non-INVITE requests -- it may
+       # be for example BYEs sent by gateway to call originator
+       if (!uri=~"sip:\+?[0-9]+@.*") {
+               if (method=="INVITE") {
+                       sl_send_reply("403", "Call cannot be served here");
+               } else {
+                       forward();
+               };
+               exit;
+       }; 
+
+       # account completed transactions via syslog
+       setflag(1);
+
+       # free call destinations ... no authentication needed
+       if ( is_user_in("Request-URI", "free-pstn")  /* free destinations */
+                       ||  uri=~"sip:[79][0-9][0-9][0-9]@.*"  /* local PBX */
+                       || uri=~"sip:98[0-9][0-9][0-9][0-9]") {
+               log("free call");
+       } else if (src_ip==192.168.0.10) {
+               # our gateway doesn't support digest authentication;
+               # verify that a request is coming from it by source
+               # address
+               log("gateway-originated request");
+       } else {
+               # in all other cases, we need to check the request against
+               # access control lists; first of all, verify request
+               # originator's identity
+
+               if (!proxy_authorize(   "gateway" /* realm */,
+                               "subscriber" /* table name */))  {
+                       proxy_challenge( "gateway" /* realm */, "0" /* no qop */ );
+                       exit;
+               };
+
+               # authorize only for INVITEs -- RR/Contact may result in weird
+               # things showing up in d-uri that would break our logic; our
+               # major concern is INVITE which causes PSTN costs 
+
+               if (method=="INVITE") {
+
+                       # does the authenticated user have a permission for local
+                       # calls (destinations beginning with a single zero)? 
+                       # (i.e., is he in the "local" group?)
+                       if (uri=~"sip:0[1-9][0-9]+@.*") {
+                               if (!is_user_in("credentials", "local")) {
+                                       sl_send_reply("403", "No permission for local calls"); 
+                                       exit;
+                               };
+                       # the same for long-distance (destinations begin with two zeros")
+                       } else if (uri=~"sip:00[1-9][0-9]+@.*") {
+                               if (!is_user_in("credentials", "ld")) {
+                                       sl_send_reply("403", " no permission for LD ");
+                                       exit;
+                               };
+                       # the same for international calls (three zeros)
+                       } else if (uri=~"sip:000[1-9][0-9]+@.*") {
+                               if (!is_user_in("credentials", "int")) {
+                                       sl_send_reply("403", "International permissions needed");
+                                       exit;
+                               };
+                       # everything else (e.g., interplanetary calls) is denied
+                       } else {
+                               sl_send_reply("403", "Forbidden");
+                               exit;
+                       };
+
+               }; # INVITE to authorized PSTN
+
+       }; # authorized PSTN
+
+       # if you have passed through all the checks, let your call go to GW!
+
+       rewritehostport("192.168.0.10:5060");
+
+       # forward the request now
+       if (!t_relay()) {
+               sl_reply_error(); 
+               exit; 
+       };
+
+}
diff --git a/examples/kamailio/redirect.cfg b/examples/kamailio/redirect.cfg
new file mode 100644 (file)
index 0000000..223cde0
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# $Id$
+#
+# this example shows use of ser as stateless redirect server
+#
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "sl.so"
+
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+       # for testing purposes, simply okay all REGISTERs
+       if (method=="REGISTER") {
+               log("REGISTER");
+               sl_send_reply("200", "ok");
+               return;
+       };
+       # rewrite current URI, which is always part of destination ser
+       rewriteuri("sip:parallel@siphub.net:9");
+       # append one more URI to the destination ser
+       append_branch("sip:redirect@siphub.net:9");
+       # redirect now
+       sl_send_reply("300", "Redirect");
+}
+
diff --git a/examples/kamailio/replicate.cfg b/examples/kamailio/replicate.cfg
new file mode 100644 (file)
index 0000000..e310d2e
--- /dev/null
@@ -0,0 +1,76 @@
+#
+# $Id$
+#
+# demo script showing how to set-up usrloc replication
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3          # debug level (cmd line: -dddddddddd)
+fork=no
+log_stderror=yes # (cmd line: -E)
+
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+loadmodule "db_mysql.so"
+loadmodule "sl.so"
+loadmodule "tm.so"
+loadmodule "maxfwd.so"
+loadmodule "usrloc.so"
+loadmodule "registrar.so"
+loadmodule "auth.so"
+loadmodule "auth_db.so"
+
+# ----------------- setting module-specific parameters ---------------
+
+# digest generation secret; use the same in backup server;
+# also, make sure that the backup server has sync'ed time
+modparam("auth", "secret", "alsdkhglaksdhfkloiwr")
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+       # initial sanity checks -- messages with
+       # max_forwars==0, or excessively long requests
+       if (!mf_process_maxfwd_header("10")) {
+               sl_send_reply("483","Too Many Hops");
+               exit;
+       };
+       if (msg:len >=  2048 ) {
+               sl_send_reply("513", "Message too big");
+               exit;
+       };
+
+       # if the request is for other domain use UsrLoc
+       # (in case, it does not work, use the following command
+       # with proper names and addresses in it)
+       if (uri==myself) {
+
+               if (method=="REGISTER") {
+
+                       # verify credentials
+                       if (!www_authorize("foo.bar", "subscriber")) {
+                               www_challenge("foo.bar", "0");
+                               exit;
+                       };
+
+                       # if ok, update contacts and ...
+                       save("location");
+                       # ... if this REGISTER is not a replica from our
+                       # peer server, replicate to the peer server
+                       if (!src_ip==backup.foo.bar) {
+                               t_replicate("sip:backup.foo.bar:5060");
+                       };
+                       exit;
+               };
+               # do whatever else appropriate for your domain
+               log("non-REGISTER\n");
+       };
+}
+
diff --git a/examples/kamailio/serial_183.cfg b/examples/kamailio/serial_183.cfg
new file mode 100644 (file)
index 0000000..eb34cef
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# $Id$
+#
+# this example shows how to use forking on failure
+#
+
+log_stderror=1
+fork=no
+listen=192.168.2.16
+debug=3
+# ------------------ module loading ----------------------------------
+
+#set module path
+mpath="/usr/local/lib/kamailio/modules/"
+
+# Uncomment this if you want to use SQL database
+loadmodule "tm.so"
+loadmodule "sl.so"
+loadmodule "maxfwd.so"
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+       # initial sanity checks -- messages with
+       # max_forwards==0, or excessively long requests
+       if (!mf_process_maxfwd_header("10")) {
+               sl_send_reply("483","Too Many Hops");
+               exit;
+       };
+       if (msg:len >=  2048 ) {
+               sl_send_reply("513", "Message too big");
+               exit;
+       };
+
+       /* skip register for testing purposes */
+       if (method=="REGISTER") { sl_send_reply("200", "ok"); exit; };
+
+       if (!method=="ACK")
+               log(1, "forwarding now to primary destination\n");
+       if (method=="INVITE") {
+               rewriteuri("sip:xxx@192.168.2.16:5064");
+               # if transaction broken, try other an alternative
+               # route
+               t_on_failure("1");
+               # if a provisional came, stop alternating
+               t_on_reply("1");
+       };
+       t_relay();
+}
+
+failure_route[1] {
+       log(1, "trying at alternate destination\n");
+       append_branch("sip:yyy@192.168.2.16:5064");
+       t_relay();
+}
+
+onreply_route[1] {
+       log(1, "reply came in\n");
+       if (status=~"18[0-9]")  {
+               log(1, "provisional -- resetting negative failure\n");
+               t_on_failure("0");
+       };
+}
diff --git a/examples/kamailio/web_im/README b/examples/kamailio/web_im/README
new file mode 100644 (file)
index 0000000..216f45d
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# $Id$
+#
+
+This examle illustrate how to use ser's FIFO interface
+to initate sending an instant message from a webpage.
+
+To enable this example, you need
+- web server with PHP support
+- install the example webpages on the server
+- have running ser with enabled fifo
diff --git a/examples/kamailio/web_im/click_to_dial.html b/examples/kamailio/web_im/click_to_dial.html
new file mode 100644 (file)
index 0000000..16d6c59
--- /dev/null
@@ -0,0 +1,40 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Click-To-Dial
+</title>
+</header>
+
+<body>
+<h1>
+Click-To-Dial (using REFER)
+</h1>
+
+<i>Unfortunately, this example does not work. The reason is use of
+REFER for third-party call-control has not been standardized due
+to resistance of proponents of B2BUA use (which is somewhat bloated
+and not always operational).
+</i>
+
+<form method=POST action=click_to_dial.php>
+<table>
+<tr>
+<td>
+Caller's SIP Address
+<td>
+<input name=caller>
+<tr>
+<td>
+Callee's SIP Address
+<td>
+<input name=callee>
+<tr>
+<td>Click to dial
+<td>
+<input type=submit value=now>
+</table>
+</form>
+
+
+</body>
diff --git a/examples/kamailio/web_im/click_to_dial.php b/examples/kamailio/web_im/click_to_dial.php
new file mode 100644 (file)
index 0000000..6093f75
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Click-To-Dial
+</title>
+</header>
+
+<body>
+<h1>
+Click-To-Dial
+</h1>
+
+<?php
+
+/* config values */
+$web_contact="sip:daemon@mydomain.net";
+$fifo="/tmp/kamailio_fifo";
+$signature="web_dialer_0.1.0";
+
+/* open reply fifo */
+$myfilename="webfifo_".rand();
+$mypath="/tmp/".$myfilename;
+$outbound_proxy=".";
+
+
+$caller = $_POST['caller'];
+$callee = $_POST['callee'];
+
+echo "Initiating your request...<p>";
+/* open fifo now */
+$fifo_handle=fopen( $fifo, "w" );
+if (!$fifo_handle) {
+    exit ("Sorry -- cannot open fifo: ".$fifo);
+}
+
+/* construct FIFO command */
+
+$fifo_cmd=":t_uac_dlg:".$myfilename."\n".
+    "REFER\n".
+     $caller."\n".
+        $outbound_proxy."\n".
+        ".\n".
+     "\"From: ".$web_contact."\r\n".
+     "To: ".$callee."\r\n".
+     "p-version: ".$signature."\r\n".
+    "Contact: ".$web_contact."\r\n".
+    "Referred-By: ".$web_contact."\r\n".
+       "Refer-To: ".$callee."\r\n".
+       "\"\n\n";
+       
+    
+/* create fifo for replies */
+system("mkfifo -m 666 ".$mypath );
+
+/* write fifo command */
+if (fwrite( $fifo_handle, $fifo_cmd)==-1) {
+    unlink($mypath);
+    fclose($fifo_handle);
+    exit("Sorry -- fifo writing error");
+}
+fclose($fifo_handle);
+
+/* read output now */
+if (readfile( $mypath )==-1) {
+    unlink($mypath);
+       exit("Sorry -- fifo reading error");
+}
+unlink($mypath);
+echo "<p>Thank you for using click-to-dial<p>";
+
+?>
+
+</body>
+</html>
+
diff --git a/examples/kamailio/web_im/send_im.html b/examples/kamailio/web_im/send_im.html
new file mode 100644 (file)
index 0000000..b63f38e
--- /dev/null
@@ -0,0 +1,37 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Send IM
+</title>
+</header>
+
+<body>
+<h1>
+Send IM
+</h1>
+
+<form method=POST action=send_im.php>
+<table>
+<tr>
+<td>
+SIP Address
+<br>
+Example: john@siphub.net
+<td>
+<input name=sip_address>
+<tr>
+<td>
+Message
+<td>
+<textarea name=instant_message rows=6 cols=40>
+</textarea>
+<tr>
+<td>Click to send
+<td>
+<input type=submit value=submit>
+</table>
+</form>
+
+
+</body>
diff --git a/examples/kamailio/web_im/send_im.php b/examples/kamailio/web_im/send_im.php
new file mode 100644 (file)
index 0000000..360a2d6
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+<!-- $Id$ -->
+<header>
+<title>
+Send IM Status
+</title>
+</header>
+
+<body>
+<h1>
+Send IM Status
+</h1>
+
+<?php
+
+/* config values */
+$web_contact="sip:daemon@mydomain.net";
+$fifo="/tmp/kamailio_fifo";
+$signature="web_im_0.1.0";
+
+/* open reply fifo */
+$myfilename="webfifo_".rand();
+$mypath="/tmp/".$myfilename;
+$outbound_proxy=".";
+
+
+$sip_address = $_POST['sip_address'];
+$instant_message = $_POST['instant_message'];
+
+
+echo "Initiating your request...<p>";
+
+/* open fifo now */
+$fifo_handle=fopen( $fifo, "w" );
+if (!$fifo_handle) {
+    exit ("Sorry -- cannot open fifo: ".$fifo);
+}
+
+/* construct FIFO command */
+$fifo_cmd=":t_uac_dlg:".$myfilename."\n".
+    "MESSAGE\n".
+    $sip_address."\n".
+       $outbound_proxy."\n".
+    ".\n".
+    "\"From: ".$web_contact."\r\n".
+       "To: ".$sip_address."\r\n".
+       "p-version: ".$signature."\r\n".
+    "Contact: ".$web_contact."\r\n".
+    "Content-Type: text/plain; charset=UTF-8\r\n".
+    "\"\n".
+    "\"".$instant_message."\"".
+       "\n\n";  
+
+/* create fifo for replies */
+system("mkfifo -m 666 ".$mypath );
+
+/* write fifo command */
+if (fwrite( $fifo_handle, $fifo_cmd)==-1) {
+    unlink($mypath);
+    fclose($fifo_handle);
+    exit("Sorry -- fifo writing error");
+}
+fclose($fifo_handle);
+
+/* read output now */
+if (readfile( $mypath )==-1) {
+    unlink($mypath);
+       exit("Sorry -- fifo reading error");
+}
+unlink($mypath);
+echo "<p>Thank you for using IM<p>";
+
+?>
+
+</body>
+</html>
+