|
@@ -1,2 +1,866 @@
|
|
|
+sca Module
|
|
|
|
|
|
+Andrew Mortensen
|
|
|
|
|
|
+ University of Pennsylvania
|
|
|
+
|
|
|
+ Copyright © 2012 Andrew Mortensen, [email protected]
|
|
|
+ __________________________________________________________________
|
|
|
+
|
|
|
+ Table of Contents
|
|
|
+
|
|
|
+ 1. Admin Guide
|
|
|
+
|
|
|
+ 1. Overview
|
|
|
+ 2. Dependencies
|
|
|
+
|
|
|
+ 2.1. Modules
|
|
|
+
|
|
|
+ 3. Parameters
|
|
|
+
|
|
|
+ 3.1. hash_table_size (integer)
|
|
|
+ 3.2. call_info_max_expires (integer)
|
|
|
+ 3.3. line_seize_max_expires (integer)
|
|
|
+ 3.4. purge_expired_interval (integer)
|
|
|
+ 3.5. db_url (str)
|
|
|
+ 3.6. subs_table (str)
|
|
|
+ 3.7. db_update_interval (integer)
|
|
|
+ 3.8. onhold_bflag (integer)
|
|
|
+
|
|
|
+ 4. Functions
|
|
|
+
|
|
|
+ 4.1. sca_handle_subscribe()
|
|
|
+ 4.2. sca_call_info_update([mask, to, from])
|
|
|
+
|
|
|
+ 5. Exported RPC Commands
|
|
|
+
|
|
|
+ 5.1. sca.all_subscriptions
|
|
|
+ 5.2. sca.all_appearances
|
|
|
+ 5.3. sca.seize_appearance
|
|
|
+ 5.4. sca.update_appearance
|
|
|
+ 5.5. sca.release_appearance
|
|
|
+
|
|
|
+ 6. Sample kamailio.cfg with SCA
|
|
|
+
|
|
|
+ List of Examples
|
|
|
+
|
|
|
+ 1.1. Set hash_table_size:
|
|
|
+ 1.2. Set call_info_max_expires:
|
|
|
+ 1.3. Set line_seize_max_expires:
|
|
|
+ 1.4. Set purge_expired_interval:
|
|
|
+ 1.5. Set db_url parameter:
|
|
|
+ 1.6. Set subs_table parameter:
|
|
|
+ 1.7. Set db_update_interval:
|
|
|
+ 1.8. Set onhold_bflag parameter
|
|
|
+ 1.9. sca_handle_subscribe usage:
|
|
|
+ 1.10. sca_call_info_update usage:
|
|
|
+ 1.11. kamailio.cfg
|
|
|
+
|
|
|
+Chapter 1. Admin Guide
|
|
|
+
|
|
|
+ Table of Contents
|
|
|
+
|
|
|
+ 1. Overview
|
|
|
+ 2. Dependencies
|
|
|
+
|
|
|
+ 2.1. Modules
|
|
|
+
|
|
|
+ 3. Parameters
|
|
|
+
|
|
|
+ 3.1. hash_table_size (integer)
|
|
|
+ 3.2. call_info_max_expires (integer)
|
|
|
+ 3.3. line_seize_max_expires (integer)
|
|
|
+ 3.4. purge_expired_interval (integer)
|
|
|
+ 3.5. db_url (str)
|
|
|
+ 3.6. subs_table (str)
|
|
|
+ 3.7. db_update_interval (integer)
|
|
|
+ 3.8. onhold_bflag (integer)
|
|
|
+
|
|
|
+ 4. Functions
|
|
|
+
|
|
|
+ 4.1. sca_handle_subscribe()
|
|
|
+ 4.2. sca_call_info_update([mask, to, from])
|
|
|
+
|
|
|
+ 5. Exported RPC Commands
|
|
|
+
|
|
|
+ 5.1. sca.all_subscriptions
|
|
|
+ 5.2. sca.all_appearances
|
|
|
+ 5.3. sca.seize_appearance
|
|
|
+ 5.4. sca.update_appearance
|
|
|
+ 5.5. sca.release_appearance
|
|
|
+
|
|
|
+ 6. Sample kamailio.cfg with SCA
|
|
|
+
|
|
|
+1. Overview
|
|
|
+
|
|
|
+ The sca module implements Shared Call Appearances. It handles SUBSCRIBE
|
|
|
+ messages for call-info and line-seize events, and sends call-info
|
|
|
+ NOTIFYs to line subscribers to implement line bridging. The module
|
|
|
+ implements SCA as defined in Broadworks SIP Access Side Extensions
|
|
|
+ Interface Specifications, Release 13.0, version 1, sections 2, 3 and 4.
|
|
|
+
|
|
|
+ SCA group members receive call state notifications when other group
|
|
|
+ members participate in calls. An SCA caller can place a call on hold,
|
|
|
+ and the call may be retrieved from hold by another member of the group.
|
|
|
+
|
|
|
+ Subscribers to SCA call-info events SUBSCRIBE to their
|
|
|
+ address-of-record (AoR), asking the application server to send
|
|
|
+ call-info NOTIFYs with line state information as lines in the
|
|
|
+ subscriber group are used.
|
|
|
+
|
|
|
+ For example, when an SCA subscriber takes the phone off hook, it sends
|
|
|
+ a line-seize SUBSCRIBE to the application server. The application
|
|
|
+ server acknowledges the request, and sends to the subscriber a
|
|
|
+ line-seize NOTIFY with the appearance index of the line claimed for the
|
|
|
+ subscriber. The application also sends call-info NOTIFYs to the other
|
|
|
+ SCA subscribers to the AoR, letting them know that an appearance within
|
|
|
+ the group has gone off hook. Subscribers update their display
|
|
|
+ appropriately.
|
|
|
+
|
|
|
+ Subscribers to an SCA address-of-record will receive call-info NOTIFYs
|
|
|
+ when a member of the group seizes a line (seized); receives a 180
|
|
|
+ ringing response from the remote party (ringing); receives a 183
|
|
|
+ progressing response from the remote party (progressing); when the
|
|
|
+ remote party answers the call (active); when either party in the call
|
|
|
+ places the call on hold (held); and when an SCA line goes back on hook
|
|
|
+ (idle).
|
|
|
+
|
|
|
+ The call-info subscriber information is stored in memory and is
|
|
|
+ periodically written to the database. Call state information is stored
|
|
|
+ in memory. A future release may periodically write call state to the
|
|
|
+ database, as well. The database is purely for restoring subscriptions
|
|
|
+ after a restart of the application server. Subscriber information is
|
|
|
+ also flushed to the database when the service is stopped.
|
|
|
+
|
|
|
+ At the time of this writing, Polycom and Cisco handsets are known to
|
|
|
+ implement the call-info and line-seize event packages defined in the
|
|
|
+ document, which may be found freely on the web.
|
|
|
+
|
|
|
+ To date, this module has only been tested with Polycom Soundpoint 550s
|
|
|
+ and 650s running Polycom SIP 3.3.4.
|
|
|
+
|
|
|
+2. Dependencies
|
|
|
+
|
|
|
+ 2.1. Modules
|
|
|
+
|
|
|
+2.1. Modules
|
|
|
+
|
|
|
+ The following modules must be loaded before this module:
|
|
|
+ * a database module
|
|
|
+ * sl
|
|
|
+ * tm
|
|
|
+
|
|
|
+3. Parameters
|
|
|
+
|
|
|
+ 3.1. hash_table_size (integer)
|
|
|
+ 3.2. call_info_max_expires (integer)
|
|
|
+ 3.3. line_seize_max_expires (integer)
|
|
|
+ 3.4. purge_expired_interval (integer)
|
|
|
+ 3.5. db_url (str)
|
|
|
+ 3.6. subs_table (str)
|
|
|
+ 3.7. db_update_interval (integer)
|
|
|
+ 3.8. onhold_bflag (integer)
|
|
|
+
|
|
|
+3.1. hash_table_size (integer)
|
|
|
+
|
|
|
+ Size, as a power of two, of the shared memory hash table containing the
|
|
|
+ call-info subscriptions and the appearance state. A larger power of two
|
|
|
+ means better performance (fewer collisions, making for fewer subscriber
|
|
|
+ URI comparisons) at the expense of increased shared memory use.
|
|
|
+
|
|
|
+ Default value is 9 (2 ^ 9 == 512).
|
|
|
+
|
|
|
+ Example 1.1. Set hash_table_size:
|
|
|
+...
|
|
|
+# create shared memory hash table with 2^8 (256) slots
|
|
|
+modparam( "sca", "hash_table_size", 8 )
|
|
|
+...
|
|
|
+
|
|
|
+3.2. call_info_max_expires (integer)
|
|
|
+
|
|
|
+ The maximum allowed call-info subscription time in seconds.
|
|
|
+
|
|
|
+ Default value is 3600 (1 hour).
|
|
|
+
|
|
|
+ Example 1.2. Set call_info_max_expires:
|
|
|
+...
|
|
|
+modparam( "sca", "call_info_max_expires", 1800 )
|
|
|
+...
|
|
|
+
|
|
|
+3.3. line_seize_max_expires (integer)
|
|
|
+
|
|
|
+ The maximum allowed line-seize subscription time in seconds.
|
|
|
+
|
|
|
+ Default value is 15 (15 seconds).
|
|
|
+
|
|
|
+ A maximum line-seize subscription time of 15 seconds is recommended in
|
|
|
+ the SIP Access Side Extensions document. This interval is purposely
|
|
|
+ short to prevent a client from seizing an appearance without making a
|
|
|
+ call for extended periods of time.
|
|
|
+
|
|
|
+ Example 1.3. Set line_seize_max_expires:
|
|
|
+...
|
|
|
+modparam( "sca", "line_seize_max_expires", 30 )
|
|
|
+...
|
|
|
+
|
|
|
+3.4. purge_expired_interval (integer)
|
|
|
+
|
|
|
+ The period of time in seconds between purges of expired call-info and
|
|
|
+ line-seize subscriptions.
|
|
|
+
|
|
|
+ Default value is 120 (2 minutes).
|
|
|
+
|
|
|
+ On finding an expired subscription, the module removes the subscription
|
|
|
+ from the shared memory hash table, and sends a NOTIFY with
|
|
|
+ Subscription-State "terminated;expired" header value to the subscriber.
|
|
|
+ It also NOTIFYs other members of the group, in the event that the
|
|
|
+ expired subscription was a line-seize.
|
|
|
+
|
|
|
+ Example 1.4. Set purge_expired_interval:
|
|
|
+...
|
|
|
+modparam( "sca", "purge_expired_interval", 60 )
|
|
|
+...
|
|
|
+
|
|
|
+3.5. db_url (str)
|
|
|
+
|
|
|
+ URL of database to which subscribers will be written.
|
|
|
+
|
|
|
+ Default value is mysql://kamailio:kamailiorw@localhost/kamailio
|
|
|
+
|
|
|
+ Example 1.5. Set db_url parameter:
|
|
|
+...
|
|
|
+modparam( "sca", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio" )
|
|
|
+...
|
|
|
+
|
|
|
+3.6. subs_table (str)
|
|
|
+
|
|
|
+ Name of the database table where call-info subscriptions are written.
|
|
|
+
|
|
|
+ Default value is “sca_subscriptions”.
|
|
|
+
|
|
|
+ Example 1.6. Set subs_table parameter:
|
|
|
+...
|
|
|
+modparam( "sca", "subs_table", "call_info_subscriptions" )
|
|
|
+...
|
|
|
+
|
|
|
+3.7. db_update_interval (integer)
|
|
|
+
|
|
|
+ Period in seconds between writes of call-info subscriber information to
|
|
|
+ the database.
|
|
|
+
|
|
|
+ Default value is 300 (5 minutes).
|
|
|
+
|
|
|
+ Example 1.7. Set db_update_interval:
|
|
|
+...
|
|
|
+modparam( "sca", "db_update_interval", 120 )
|
|
|
+...
|
|
|
+
|
|
|
+3.8. onhold_bflag (integer)
|
|
|
+
|
|
|
+ Which branch flag should be used by the module to identify if the call
|
|
|
+ is on-hold instead of parsing the sdp.
|
|
|
+
|
|
|
+ Default value is -1 (disabled).
|
|
|
+
|
|
|
+ Example 1.8. Set onhold_bflag parameter
|
|
|
+...
|
|
|
+modparam("sca", "onhold_bflag", 15)
|
|
|
+...
|
|
|
+
|
|
|
+4. Functions
|
|
|
+
|
|
|
+ 4.1. sca_handle_subscribe()
|
|
|
+ 4.2. sca_call_info_update([mask, to, from])
|
|
|
+
|
|
|
+4.1. sca_handle_subscribe()
|
|
|
+
|
|
|
+ The function handling call-info and line-seize SUBSCRIBE requests. It
|
|
|
+ stores or updates the subscriptions in shared memory, and sends NOTIFYs
|
|
|
+ to the subscriber and other members of the group as needed.
|
|
|
+
|
|
|
+ For example, a line-seize SUBSCRIBE will cause the module to reserve an
|
|
|
+ appearance index for the subscriber; send a line-seize NOTIFY to the
|
|
|
+ subscriber indicating which appearance index it must use; and send
|
|
|
+ call-info NOTIFYs to other subscribers to the address-of-record letting
|
|
|
+ them know the appearance is off hook.
|
|
|
+
|
|
|
+ This function can be used from the REQUEST_ROUTE.
|
|
|
+
|
|
|
+ Return code:
|
|
|
+ * 1 - successful
|
|
|
+ * -1 - failed, error logged
|
|
|
+
|
|
|
+ Example 1.9. sca_handle_subscribe usage:
|
|
|
+...
|
|
|
+if ( is_method( "SUBSCRIBE" )) {
|
|
|
+ if ( $hdr(Event) == "call-info" || $hdr(Event) == "line-seize" ) {
|
|
|
+ sca_handle_subscribe();
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+}
|
|
|
+...
|
|
|
+
|
|
|
+4.2. sca_call_info_update([mask, to, from])
|
|
|
+
|
|
|
+ * mask - integer (optional)
|
|
|
+ controls what to check as shared line (BOTH, CALLER, CALLEE)
|
|
|
+ + 0 - SCA_CALL_INFO_SHARED_NONE (default) check both
|
|
|
+ + 1 - SCA_CALL_INFO_SHARED_CALLER
|
|
|
+ + 2 - SCA_CALL_INFO_SHARED_CALLEE
|
|
|
+ * to - string (optional)
|
|
|
+ string to use as To and skip parsing To header from the message.
|
|
|
+ The parameter allows pseudo-variables usage
|
|
|
+ * from - string (optional)
|
|
|
+ string to use as From and skip parsing From header from the
|
|
|
+ message. The parameter allows pseudo-variables usage
|
|
|
+
|
|
|
+ The sca_call_info_update function updates call state for SCA
|
|
|
+ appearances. If a request or response packet contains a Call-Info
|
|
|
+ header, the function extracts call state from the header and sends
|
|
|
+ NOTIFYs to subscribers if needed. If no Call-Info header is included in
|
|
|
+ the packet, the module looks up the To and From URIs to see if either
|
|
|
+ are SCA addresses-of-record. If either the To or From URI are SCA AoRs,
|
|
|
+ the function looks up the appearance by dialog and updates call state
|
|
|
+ as needed, sending NOTIFYs to members of the group if the call state
|
|
|
+ has changed.
|
|
|
+
|
|
|
+ The sca_call_info_update function updates call state for INVITE,
|
|
|
+ CANCEL, BYE, PRACK and REFER requests and responses.
|
|
|
+
|
|
|
+ This function can be used from the REQUEST_ROUTE, REPLY_ROUTE, and
|
|
|
+ FAILURE_ROUTE.
|
|
|
+
|
|
|
+ Return code:
|
|
|
+ * 1 - successful
|
|
|
+ * -1 - failed, error logged
|
|
|
+
|
|
|
+ Example 1.10. sca_call_info_update usage:
|
|
|
+...
|
|
|
+route
|
|
|
+{
|
|
|
+...
|
|
|
+ sca_call_info_update(0, "$var(to)", "$var(from)@$var(domain)");
|
|
|
+...
|
|
|
+}
|
|
|
+
|
|
|
+onreply_route[REPLY_ROUTE]
|
|
|
+{
|
|
|
+...
|
|
|
+ if ( status =~ "[456][0-9][0-9]" ) {
|
|
|
+ # don't update SCA state here, since there may be
|
|
|
+ # failure route processing (e.g., call forwarding).
|
|
|
+ # update state in failure route instead.
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ sca_call_info_update();
|
|
|
+...
|
|
|
+}
|
|
|
+
|
|
|
+failure_route[FAILURE_ROUTE]
|
|
|
+{
|
|
|
+...
|
|
|
+ sca_call_info_update();
|
|
|
+...
|
|
|
+}
|
|
|
+...
|
|
|
+
|
|
|
+5. Exported RPC Commands
|
|
|
+
|
|
|
+ 5.1. sca.all_subscriptions
|
|
|
+ 5.2. sca.all_appearances
|
|
|
+ 5.3. sca.seize_appearance
|
|
|
+ 5.4. sca.update_appearance
|
|
|
+ 5.5. sca.release_appearance
|
|
|
+
|
|
|
+5.1. sca.all_subscriptions
|
|
|
+
|
|
|
+ List all current call-info and line-seize subscriptions.
|
|
|
+
|
|
|
+ Name: sca.all_subscriptions
|
|
|
+
|
|
|
+ Parameters: none
|
|
|
+
|
|
|
+ Example:
|
|
|
+ kamcmd sca.all_subscriptions
|
|
|
+
|
|
|
+5.2. sca.all_appearances
|
|
|
+
|
|
|
+ List all SCA appearances with non-idle state.
|
|
|
+
|
|
|
+ Name: sca.all_appearances
|
|
|
+
|
|
|
+ Parameters: none
|
|
|
+
|
|
|
+ Example:
|
|
|
+ kamcmd sca.all_appearances
|
|
|
+
|
|
|
+5.3. sca.seize_appearance
|
|
|
+
|
|
|
+ Seize an appearance index for a specific contact within an SCA group,
|
|
|
+ and notify other members of the group that the appearance is off hook.
|
|
|
+ Useful for testing SCA signaling.
|
|
|
+
|
|
|
+ Name: sca.seize_appearance
|
|
|
+
|
|
|
+ Parameters: 2
|
|
|
+ * SCA Address-of-Record
|
|
|
+ * SCA Contact URI
|
|
|
+
|
|
|
+ Example:
|
|
|
+ # seize next available appearance of sip:[email protected]
|
|
|
+ # for contact sip:[email protected]
|
|
|
+ kamcmd sca.seize_appearance sip:[email protected] si
|
|
|
+p:[email protected]
|
|
|
+
|
|
|
+5.4. sca.update_appearance
|
|
|
+
|
|
|
+ Update the state of an in-use appearance index, and notify other
|
|
|
+ members of the group. Useful for testing SCA signaling.
|
|
|
+
|
|
|
+ Name: sca.update_appearance
|
|
|
+
|
|
|
+ Parameters: 3 or 4
|
|
|
+ * SCA Address-of-Record
|
|
|
+ * Index of In-Use Appearance
|
|
|
+ * Appearance State (seized, ringing, progressing, active, held,
|
|
|
+ held-private)
|
|
|
+ * Appearance Display Info (Optional)
|
|
|
+
|
|
|
+ Example:
|
|
|
+ # update in-use appearance index 3 of sip:[email protected]
|
|
|
+ # state held.
|
|
|
+ kamcmd sca.update_appearance sip:[email protected] 3
|
|
|
+ held
|
|
|
+
|
|
|
+5.5. sca.release_appearance
|
|
|
+
|
|
|
+ Set a non-idle appearance index to idle and NOTIFY members of the
|
|
|
+ group.
|
|
|
+
|
|
|
+ Name: sca.release_appearance
|
|
|
+
|
|
|
+ Parameters: 2
|
|
|
+ * SCA Address-of-Record
|
|
|
+ * Appearance Index
|
|
|
+
|
|
|
+ Example:
|
|
|
+ # release appearance of sip:[email protected] with
|
|
|
+ # appearance index 3
|
|
|
+ kamcmd sca.release_appearance sip:[email protected]
|
|
|
+3
|
|
|
+
|
|
|
+6. Sample kamailio.cfg with SCA
|
|
|
+
|
|
|
+ The following is a basic kamailio.cfg providing Shared Call Appearances
|
|
|
+ to local subscribers. It has been tested with Polycom handsets.
|
|
|
+
|
|
|
+ Example 1.11. kamailio.cfg
|
|
|
+##
|
|
|
+#!KAMAILIO
|
|
|
+#
|
|
|
+# example kamailio.cfg with Shared Call Appearances (SCA)
|
|
|
+
|
|
|
+#!define WITH_AUTH
|
|
|
+#!define WITH_MYSQL
|
|
|
+#!define WITH_SCA
|
|
|
+
|
|
|
+####### Defined Values #########
|
|
|
+
|
|
|
+#!ifdef WITH_MYSQL
|
|
|
+# - database URL - used to connect to database server by modules such
|
|
|
+# as: auth_db, acc, usrloc, a.s.o.
|
|
|
+#!ifndef DBURL
|
|
|
+#!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
|
|
|
+#!endif
|
|
|
+#!endif
|
|
|
+
|
|
|
+####### Global Parameters #########
|
|
|
+
|
|
|
+#!ifdef WITH_DEBUG
|
|
|
+debug=4
|
|
|
+log_stderror=yes
|
|
|
+#!else
|
|
|
+debug=2
|
|
|
+log_stderror=no
|
|
|
+#!endif
|
|
|
+
|
|
|
+memdbg=5
|
|
|
+memlog=5
|
|
|
+
|
|
|
+log_facility=LOG_LOCAL0
|
|
|
+
|
|
|
+fork=yes
|
|
|
+children=4
|
|
|
+
|
|
|
+listen=udp:10.0.0.10:5060
|
|
|
+port=5060
|
|
|
+
|
|
|
+####### Modules Section ########
|
|
|
+
|
|
|
+# set paths to location of modules (to sources or installation folders)
|
|
|
+#!ifdef WITH_SRCPATH
|
|
|
+mpath="modules_k:modules"
|
|
|
+#!else
|
|
|
+mpath="/usr/local/kamailio/lib64/kamailio/modules_k/:/usr/local/kamailio/lib64/k
|
|
|
+amailio/modules/"
|
|
|
+#!endif
|
|
|
+
|
|
|
+#!ifdef WITH_MYSQL
|
|
|
+loadmodule "db_mysql.so"
|
|
|
+#!endif
|
|
|
+
|
|
|
+loadmodule "tm.so"
|
|
|
+loadmodule "sl.so"
|
|
|
+loadmodule "rr.so"
|
|
|
+loadmodule "pv.so"
|
|
|
+loadmodule "maxfwd.so"
|
|
|
+loadmodule "usrloc.so"
|
|
|
+loadmodule "registrar.so"
|
|
|
+loadmodule "textops.so"
|
|
|
+loadmodule "siputils.so"
|
|
|
+loadmodule "xlog.so"
|
|
|
+loadmodule "sanity.so"
|
|
|
+loadmodule "ctl.so"
|
|
|
+loadmodule "cfg_rpc.so"
|
|
|
+
|
|
|
+#!ifdef WITH_AUTH
|
|
|
+loadmodule "auth.so"
|
|
|
+loadmodule "auth_db.so"
|
|
|
+#!ifdef WITH_IPAUTH
|
|
|
+loadmodule "permissions.so"
|
|
|
+#!endif
|
|
|
+#!endif
|
|
|
+
|
|
|
+#!ifdef WITH_SCA
|
|
|
+loadmodule "sca.so"
|
|
|
+#!endif
|
|
|
+
|
|
|
+
|
|
|
+# ----------------- setting module-specific parameters ---------------
|
|
|
+
|
|
|
+
|
|
|
+# ----- tm params -----
|
|
|
+# auto-discard branches from previous serial forking leg
|
|
|
+modparam("tm", "failure_reply_mode", 3)
|
|
|
+# default retransmission timeout: 30sec
|
|
|
+modparam("tm", "fr_timer", 30000)
|
|
|
+# default invite retransmission timeout after 1xx: 120sec
|
|
|
+modparam("tm", "fr_inv_timer", 120000)
|
|
|
+
|
|
|
+
|
|
|
+# ----- rr params -----
|
|
|
+# add value to ;lr param to cope with most of the UAs
|
|
|
+modparam("rr", "enable_full_lr", 1)
|
|
|
+# do not append from tag to the RR (no need for this script)
|
|
|
+modparam("rr", "append_fromtag", 0)
|
|
|
+
|
|
|
+
|
|
|
+# ----- registrar params -----
|
|
|
+modparam("registrar", "method_filtering", 1)
|
|
|
+/* uncomment the next line to disable parallel forking via location */
|
|
|
+# modparam("registrar", "append_branches", 0)
|
|
|
+/* uncomment the next line not to allow more than 10 contacts per AOR */
|
|
|
+#modparam("registrar", "max_contacts", 10)
|
|
|
+# max value for expires of registrations
|
|
|
+modparam("registrar", "max_expires", 3600)
|
|
|
+# set it to 1 to enable GRUU
|
|
|
+modparam("registrar", "gruu_enabled", 0)
|
|
|
+
|
|
|
+
|
|
|
+# ----- usrloc params -----
|
|
|
+/* enable DB persistency for location entries */
|
|
|
+#!ifdef WITH_USRLOCDB
|
|
|
+modparam("usrloc", "db_url", DBURL)
|
|
|
+modparam("usrloc", "db_mode", 2)
|
|
|
+modparam("usrloc", "use_domain", 0)
|
|
|
+#!endif
|
|
|
+
|
|
|
+
|
|
|
+# ----- auth_db params -----
|
|
|
+#!ifdef WITH_AUTH
|
|
|
+modparam("auth_db", "db_url", DBURL)
|
|
|
+modparam("auth_db", "calculate_ha1", yes)
|
|
|
+modparam("auth_db", "password_column", "password")
|
|
|
+modparam("auth_db", "load_credentials", "")
|
|
|
+
|
|
|
+# ----- permissions params -----
|
|
|
+#!ifdef WITH_IPAUTH
|
|
|
+modparam("permissions", "db_url", DBURL)
|
|
|
+modparam("permissions", "db_mode", 1)
|
|
|
+#!endif
|
|
|
+
|
|
|
+#!endif
|
|
|
+
|
|
|
+# ----- sca params -----
|
|
|
+#!ifdef WITH_SCA
|
|
|
+modparam("sca", "call_info_max_expires", 300)
|
|
|
+modparam("sca", "db_url", DBURL)
|
|
|
+#!endif
|
|
|
+
|
|
|
+
|
|
|
+####### Routing Logic ########
|
|
|
+
|
|
|
+# Main SIP request routing logic
|
|
|
+# - processing of any incoming SIP request starts with this route
|
|
|
+# - note: this is the same as route { ... }
|
|
|
+request_route {
|
|
|
+
|
|
|
+ # per request initial checks
|
|
|
+ route(REQINIT);
|
|
|
+
|
|
|
+ # CANCEL processing
|
|
|
+ if (is_method("CANCEL"))
|
|
|
+ {
|
|
|
+ if (t_check_trans()) {
|
|
|
+ route(SCA);
|
|
|
+ t_relay();
|
|
|
+ }
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ # handle requests within SIP dialogs
|
|
|
+ route(WITHINDLG);
|
|
|
+
|
|
|
+ ### only initial requests (no To tag)
|
|
|
+
|
|
|
+ t_check_trans();
|
|
|
+
|
|
|
+ # authentication
|
|
|
+ route(AUTH);
|
|
|
+
|
|
|
+ # record routing for dialog forming requests (in case they are routed)
|
|
|
+ # - remove preloaded route headers
|
|
|
+ remove_hf("Route");
|
|
|
+ if (is_method("INVITE|SUBSCRIBE"))
|
|
|
+ record_route();
|
|
|
+
|
|
|
+ # dispatch requests to foreign domains
|
|
|
+ route(SIPOUT);
|
|
|
+
|
|
|
+ # handle registrations
|
|
|
+ route(REGISTRAR);
|
|
|
+
|
|
|
+ if ($rU==$null)
|
|
|
+ {
|
|
|
+ # request with no Username in RURI
|
|
|
+ sl_send_reply("484","Address Incomplete");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ # user location service
|
|
|
+ route(LOCATION);
|
|
|
+
|
|
|
+ route(RELAY);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+route[RELAY] {
|
|
|
+
|
|
|
+ # enable additional event routes for forwarded requests
|
|
|
+ if (is_method("INVITE|BYE|SUBSCRIBE|PRACK|REFER|UPDATE")) {
|
|
|
+ if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
|
|
|
+ }
|
|
|
+ if (is_method("INVITE")) {
|
|
|
+ if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
|
|
|
+ }
|
|
|
+
|
|
|
+ route(SCA);
|
|
|
+
|
|
|
+ if (!t_relay()) {
|
|
|
+ sl_reply_error();
|
|
|
+ }
|
|
|
+ exit;
|
|
|
+}
|
|
|
+
|
|
|
+# Per SIP request initial checks
|
|
|
+route[REQINIT] {
|
|
|
+ if (!mf_process_maxfwd_header("10")) {
|
|
|
+ sl_send_reply("483","Too Many Hops");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!sanity_check("1511", "7"))
|
|
|
+ {
|
|
|
+ xlog("Malformed SIP message from $si:$sp\n");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+# Handle requests within SIP dialogs
|
|
|
+route[WITHINDLG] {
|
|
|
+ if (has_totag()) {
|
|
|
+ # sequential request withing a dialog should
|
|
|
+ # take the path determined by record-routing
|
|
|
+ if (loose_route()) {
|
|
|
+ if ( is_method("NOTIFY") ) {
|
|
|
+ # Add Record-Route for in-dialog NOTIFY as per R
|
|
|
+FC 6665.
|
|
|
+ record_route();
|
|
|
+ }
|
|
|
+ route(RELAY);
|
|
|
+ } else {
|
|
|
+ if (is_method("SUBSCRIBE") && uri == myself) {
|
|
|
+ # in-dialog subscribe requests
|
|
|
+ route(SCA);
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ if ( is_method("ACK") ) {
|
|
|
+ if ( t_check_trans() ) {
|
|
|
+ # no loose-route, but stateful ACK;
|
|
|
+ # must be an ACK after a 487
|
|
|
+ # or e.g. 404 from upstream server
|
|
|
+ t_relay();
|
|
|
+ exit;
|
|
|
+ } else {
|
|
|
+ # ACK without matching transaction ... i
|
|
|
+gnore and discard
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sl_send_reply("404","Not here");
|
|
|
+ }
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+# Handle SIP registrations
|
|
|
+route[REGISTRAR] {
|
|
|
+ if (is_method("REGISTER"))
|
|
|
+ {
|
|
|
+ if (!save("location"))
|
|
|
+ sl_reply_error();
|
|
|
+
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+# USER location service
|
|
|
+route[LOCATION] {
|
|
|
+ $avp(oexten) = $rU;
|
|
|
+ if (!lookup("location")) {
|
|
|
+ $var(rc) = $rc;
|
|
|
+ t_newtran();
|
|
|
+ switch ($var(rc)) {
|
|
|
+ case -1:
|
|
|
+ case -3:
|
|
|
+ send_reply("404", "Not Found");
|
|
|
+ exit;
|
|
|
+ case -2:
|
|
|
+ send_reply("405", "Method Not Allowed");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+# Authentication route
|
|
|
+route[AUTH] {
|
|
|
+#!ifdef WITH_AUTH
|
|
|
+
|
|
|
+#!ifdef WITH_IPAUTH
|
|
|
+ if((!is_method("REGISTER")) && allow_source_address())
|
|
|
+ {
|
|
|
+ # source IP allowed
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#!endif
|
|
|
+
|
|
|
+ if (is_method("REGISTER") || from_uri==myself)
|
|
|
+ {
|
|
|
+ # authenticate requests
|
|
|
+ if (!auth_check("$fd", "subscriber", "1")) {
|
|
|
+ auth_challenge("$fd", "0");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ # user authenticated - remove auth header
|
|
|
+ if(!is_method("REGISTER|PUBLISH"))
|
|
|
+ consume_credentials();
|
|
|
+ }
|
|
|
+ # if caller is not local subscriber, then check if it calls
|
|
|
+ # a local destination, otherwise deny, not an open relay here
|
|
|
+ if (from_uri!=myself && uri!=myself)
|
|
|
+ {
|
|
|
+ sl_send_reply("403","Not relaying");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+#!endif
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+# Shared Call Appearances handling
|
|
|
+route[SCA] {
|
|
|
+#!ifdef WITH_SCA
|
|
|
+ if(is_method("SUBSCRIBE")) {
|
|
|
+ if ($hdr(Event) == "call-info" || $hdr(Event) == "line-seize") {
|
|
|
+ xdbg("SCA: $hdr(Event) SUBSCRIBE $ru from $si:$sp");
|
|
|
+ sca_handle_subscribe();
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!is_method("BYE|CANCEL|INVITE|PRACK|REFER")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ # this updates appearance state and NOTIFYs SCA subscribers as
|
|
|
+ # necessary. it also removes the Call-Info header, if found.
|
|
|
+ sca_call_info_update();
|
|
|
+#!endif
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+# Routing to foreign domains
|
|
|
+route[SIPOUT] {
|
|
|
+ if (!uri==myself)
|
|
|
+ {
|
|
|
+ append_hf("P-hint: outbound\r\n");
|
|
|
+ route(RELAY);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+# XMLRPC routing
|
|
|
+#!ifdef WITH_XMLRPC
|
|
|
+route[XMLRPC] {
|
|
|
+ # allow XMLRPC from localhost
|
|
|
+ if ((method=="POST" || method=="GET")
|
|
|
+ && (src_ip==127.0.0.1)) {
|
|
|
+ # close connection only for xmlrpclib user agents (there is a bu
|
|
|
+g in
|
|
|
+ # xmlrpclib: it waits for EOF before interpreting the response).
|
|
|
+ if ($hdr(User-Agent) =~ "xmlrpclib")
|
|
|
+ set_reply_close();
|
|
|
+ set_reply_no_connect();
|
|
|
+ dispatch_rpc();
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ send_reply("403", "Forbidden");
|
|
|
+ exit;
|
|
|
+}
|
|
|
+#!endif
|
|
|
+
|
|
|
+# manage incoming replies
|
|
|
+onreply_route[MANAGE_REPLY] {
|
|
|
+ xdbg("incoming reply\n");
|
|
|
+
|
|
|
+ if (status =~ "[456][0-9][0-9]") {
|
|
|
+ # don't update SCA state here, since there may be
|
|
|
+ # failure route processing (e.g., call forwarding).
|
|
|
+ # update state in failure route instead.
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ route(SCA);
|
|
|
+}
|
|
|
+
|
|
|
+# manage failure routing cases
|
|
|
+failure_route[MANAGE_FAILURE] {
|
|
|
+ if (t_is_canceled()) {
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ route(SCA);
|
|
|
+}
|