<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;

]>
<!-- Module User's Guide -->

<chapter>
	<title>&adminguide;</title>

	<section>
	<title>Overview</title>
	<para> The Presence module implements the core functionality of SIP event notification.
	It handles PUBLISH and SUBSCRIBE messages and generates
	NOTIFY messages in a general, event independent way. It is extensible and allows registering
	events to it from other &kamailio; modules.
	Supported SIP event packages are presence, presence.winfo, dialog;sla from the presence_xml
	module and message-summary from the presence_mwi module.
	</para>
	<para>
	The module can use database and memory storage (to improve performance).
	For subscriptions it supports the 4 storage modes: Memory Only, Write Back,
	Write Through and DB Only. For publishes, it stores the state documents in
	database only (because of the large size) and it can store a publish cache in
	memory to avoid unnecessary database queries. Read the
	<emphasis>subs_db_mode</emphasis> and <emphasis>publ_cache</emphasis> parameter
	sections to decide which is the best storage configuration for you.
	</para>
	<para>The module implements several API functions, that can be used by other
	modules. In fact, it can be used only as a resource module, or "library".
	This mode of operation is enabled if the db_url parameter is not set to any value.
	</para>
	<para>
	The &kamailio; Presence module implements the specifications in: RFC3265, RFC3856, RFC3857,
	RFC3858.
	</para>
	</section>

	<section>
	<title>Dependencies</title>
	<section>
		<title>&kamailio; Modules</title>
		<para>
		The following modules must be loaded before this module:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>a database module</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>sl</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>tm</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>dmq (only if replication is enabled)</emphasis>.
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>

	<section>
		<title>External Libraries or Applications</title>
		<itemizedlist>
			<listitem>
			<para>
				<emphasis>libxml</emphasis>.
			</para>
			</listitem>
		</itemizedlist>

		</section>
	</section>

	<section>
	<title>Parameters</title>
	<section id="presence.p.db_url">
		<title><varname>db_url</varname>(str)</title>
		<para>
		The database url.
		</para>
		<para>If set, the module is a fully operational
		presence server. Otherwise, it is used as a 'library', for
		its exported functions.
		</para>
		<para>
		<emphasis>Default value is <quote>NULL</quote>.</emphasis>
		</para>
		<example>
		<title>Set <varname>db_url</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "db_url",
	"&defaultdb;")
...
</programlisting>
		</example>
	</section>
	<section id="presence.p.presentity_table">
		<title><varname>presentity_table</varname>(str)</title>
		<para>
		The name of the db table where PUBLISH presence information is stored.
		</para>
		<para>
		<emphasis>	Default value is <quote>presentity</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>presentity_table</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "presentity_table", "presentity")
...
</programlisting>
		</example>
	</section>
	<section id="presence.p.active_watchers_table">
		<title><varname>active_watchers_table</varname>(str)</title>
		<para>
		The name of the db table where active subscription information is stored.
		</para>
		<para>
		<emphasis>	Default value is <quote>active_watchers</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>active_watchers_table</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "active_watchers_table", "active_watchers")
...
</programlisting>
		</example>
	</section>
	<section id="presence.p.watchers_table">
		<title><varname>watchers_table</varname>(str)</title>
		<para>
		The name of the db table where subscription states are stored.
		</para>
		<para>
		<emphasis>	Default value is <quote>watchers</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>watchers_table</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "watchers_table", "watchers")
...
</programlisting>
		</example>
	</section>
	<section id="presence.p.clean_period">
		<title><varname>clean_period</varname> (int)</title>
		<para>
		The period in seconds between checks if there are expired messages stored in the database.
		</para>
		<para>
		<emphasis>Default value is <quote>100</quote>. A zero or negative value disables this activity.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>clean_period</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "clean_period", 100)
...
</programlisting>
		</example>
	</section>
    <section id="presence.p.cseq_offset">
        <title><varname>cseq_offset</varname> (int)</title>
        <para>
            The allowed offset between server and client cseq.
        </para>
        <para>
            <emphasis>Default value is <quote>0</quote>.
            </emphasis>
        </para>
        <example>
            <title>Set <varname>cseq_offset</varname> parameter</title>
            <programlisting format="linespecific">
...
modparam("presence", "cseq_offset", 1)
...
</programlisting>
        </example>
    </section>
    <section id="presence.p.db_update_period">
		<title><varname>db_update_period</varname> (int)</title>
		<para>
		The period at which to synchronize cached subscriber info with the
		database.
		</para>
		<para>
		<emphasis>Default value is <quote>100</quote>. A zero or negative value disables synchronization.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_update_period</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "db_update_period", 100)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.waitn_time">
		<title><varname>waitn_time</varname> (int)</title>
		<para>
		The maximum time period that NOTIFY requests will
		be buffered for.  The server will attempt to send
		NOTIFY requests within many seconds of a change occurring.
		</para>
		<para>
		Note: this parameter is only used when notifier_processes is
		greater than 0. When notifier_processes is less than or equal
		to 0 NOTIFY requests are sent immediately.
		</para>
		<para>
		<emphasis>Default value is <quote>5</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>waitn_time</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "waitn_time", 10)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.notifier_poll_rate">
		<title><varname>notifier_poll_rate</varname> (int)</title>
		<para>
		The number of times per second that the notifier processes
		should check for work.  Approximately
		1/(waitn_time * notifier_poll_rate * notifier_processes) of the
		pending updates will be sent each time a notifier process runs.
		</para>
		<para>
		Separate notifier processes are only run when subs_db_mode is 3
		(DB only mode).
		</para>
		<para>
		<emphasis>Default value is <quote>10</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>notifier_poll_rate</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "notifier_poll_rate", 20)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.notifier_processes">
		<title><varname>notifier_processes</varname> (int)</title>
		<para>
		The number of notifier processes that should be started.
		</para>
		<para>
		Separate notifier processes are only run when subs_db_mode is
		3 (DB only mode).
		</para>
		<para>
		Note: setting this parameter to 0 when subs_db_mode is 3
		keeps the old behaviour (sending NOTIFY requests immediately).
		This (old) behaviour is disabled by default in DB only mode
		because under load, when lots of NOTIFY requests can be sent
		on a dialog at the same time, there are race conditions which
		result in CSeq re-use.
		</para>
		<para>
		<emphasis>Default value is <quote>1</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>notifier_processes</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "notifier_processes", 2)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.force_delete">
		<title><varname>force_delete</varname> (int)</title>
		<para>
		Enabling this parameter will delete expired presentity records without updating watchers.
		</para>
		<para>
		Set this parameter to <quote>1</quote> to enable.
		</para>
		<para>
		<emphasis>Default value is <quote>0</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>force_delete</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "force_delete", 1)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.startup_mode">
		<title><varname>startup_mode</varname> (int)</title>
		<para>
		Setting this parameter to 0 will provide startup related backward compatibility for some modules. Setting to 0 fixes presentity requests with low expires (e.g. time() + 1)
		</para>
		<para>
		Set this parameter to <quote>0</quote> to enable backward compatibility.
		</para>
		<para>
		<emphasis>Default value is <quote>1</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>startup_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "startup_mode", 0)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.expires_offset">
		<title><varname>expires_offset</varname> (int)</title>
		<para>
		The value in seconds that should be subtracted from the expires value when
		sending a 200OK for a publish. It is used for forcing the client
		to send an update before the old publish expires.
		</para>
		<para>
		<emphasis>Default value is <quote>0</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>expires_offset</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "expires_offset", 10)
...
</programlisting>
		</example>

</section>
       <section id="presence.p.max_expires">
               <title><varname>max_expires</varname> (int)</title>
               <para>
               The maximum admissible expires value for PUBLISH/SUBSCRIBE
               message (in seconds).
               </para>
               <para>
               <emphasis>Default value is <quote>3600</quote>.
               </emphasis>
               </para>
               <example>
               <title>Set <varname>max_expires</varname> parameter</title>
               <programlisting format="linespecific">
...
modparam("presence", "max_expires", 3600)
...
</programlisting>
	</example>
</section>

<section id="presence.p.min_expires">
    <title><varname>min_expires</varname> (int)</title>
    <para>
        The minimum admissible expires value for PUBLISH/SUBSCRIBE
        message (in seconds).
    </para>
    <para>
        If &gt; 0 then min_expires_action parameter determines the response.
    </para>
    <para>
        <emphasis>Default value is <quote>0</quote>.
        </emphasis>
    </para>
    <example>
        <title>Set <varname>min_expires</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("presence", "min_expires", 1800)
...
</programlisting>
    </example>
</section>

<section id="presence.p.min_expires_action">
    <title><varname>min_expires_action</varname> (int)</title>
    <para>
        The action to take when UA sends an expires value less than min_expires.
    </para>
    <para>
        <itemizedlist>
            <title>Possible Values</title>
            <listitem>
                <para> 1 : RFC Compliant, returns <quote>423 Interval Too Brief</quote></para>
            </listitem>
            <listitem>
                <para> 2 : forces the min_expires value in the subscription</para>
            </listitem>
        </itemizedlist>
    </para>
    <para>
        If &gt; 0 then min_expires_action parameter determines the response.
    </para>
    <para>
        <emphasis>Default value is <quote>1</quote>.</emphasis>
    </para>
    <example>
        <title>Set <varname>min_expires</varname> parameter</title>
        <programlisting format="linespecific">
            ...
            modparam("presence", "min_expires", 1800)
            ...
        </programlisting>
    </example>
</section>

<section id="presence.p.server_address">
		<title><varname>server_address</varname> (str)</title>
		<para>
		The presence server address which will become the value of Contact header filed
		for 200 OK replies to SUBSCRIBE and PUBLISH and in NOTIFY messages.
		</para>
		<example>
		<title>Set <varname>server_address</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "server_address", "sip:10.10.10.10:5060")
...
</programlisting>
		</example>
	</section>

<section id="presence.p.subs_db_mode">
		<title><varname>subs_db_mode</varname> (int)</title>
		<para>
		The presence module can utilize database for persistent subscription storage.
		If you use database, your subscriptions will survive machine restarts or
		SW crashes. The disadvantage is that accessing the database can be time consuming.
		Therefore, presence module implements four database accessing modes:
		</para>
		<itemizedlist>
		<listitem>
			<para>
			0 - This disables database completely. Only memory will be used.
			Subscriptions will not survive restart. Use this value if you need a
			really fast presence module and subscription persistence is not necessary or
			is provided by other means.
			</para>
		</listitem>
		<listitem>
			<para>
			1 - Write-Through scheme. Subscriptions are updated synchronously
			in database and in memory(used for read operations). Use this
			scheme if speed is not top priority, but it's important that no
			subscriptions will be lost during crash or reboot or if you have
			an external application that reads the state of the subscriptions
			from database and they need to be updated synchronously.
			</para>
		</listitem>
		<listitem>
			<para>
			2 - Write-Back scheme. This is a combination of previous two
			schemes. All changes are made to memory and database
			synchronization is done in the timer. The timer deletes all
			expired contacts and flushes all modified or new subscriptions to
			database. Use this scheme if you encounter high-load peaks
			and want them to process as fast as possible. Latency of this
			mode is much lower than latency of mode 1, but slightly higher
			than latency of mode 0. To control the interval at which data is
			flushed to database, set the <emphasis>db_update_period</emphasis>
			parameter.
			</para>
		</listitem>
		<listitem>
			<para>
			3 - DB-Only scheme. No memory cache is kept, all operations being
			directly performed with the database. The timer deletes all expired
			subscriptions from database. The mode is useful if you configure
			more servers sharing the same DB without any replication at SIP
			level. The mode may be slower due the high number of DB operation.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		<emphasis>Default value is 2 (Write-Back scheme).</emphasis>
		</para>

		<example>
		<title>Set <varname>subs_db_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "subs_db_mode", 1)
...
</programlisting>
		</example>
	</section>

	<section id="presence.p.publ_cache">
		<title><varname>publ_cache</varname> (int)</title>
		<para>
		To improve performance, the presence module can operate in a couple of
		modes related to how PUBLISH data is stored. If publ_cache is 0,
		then no information is stored in memory.
		</para>
		<para>
		If publ_cache is 1, then the module keeps in memory an index of the
		records stored in database, In this mode it keeps only the list of URIs
		and events, so it does not use much memory. The cache is used when a
		Subscription is received to check if there is any published state in
		database. This way unnecessary queries in presentity table are avoided.
		</para>
		<para>
		If publ_cache is 2, then the module keeps everything related to PUBLISH
		requests in memory, not storing anything in the database.
		</para>
		<para>
		Setting this parameter to 0 will disable the usage of the publish
		cache. This is desirable when you have more servers sharing the same
		database or there are other external entities inserting data into the
		presentity table.
		</para>
		<para>
		<emphasis>Default value is <quote>1</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>publ_cache</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "publ_cache", 0)
...
	</programlisting>
		</example>
	</section>

	<section id="presence.p.subs_htable_size">
		<title><varname>subs_htable_size</varname> (int)</title>
		<para>
		The size of the in-memory hash table to store subscription dialogs.
		This parameter will be used as the power of 2 when computing table size.
		</para>
		<para>
		<emphasis>Default value is <quote>9 (512)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>subs_htable_size</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "subs_htable_size", 11)
...
	</programlisting>
		</example>
	</section>

	<section id="presence.p.pres_htable_size">
		<title><varname>pres_htable_size</varname> (int)</title>
		<para>
        	The size of the in-memory hash table to store publish records.
        	This parameter will be used as the power of 2 when computing table size.
		</para>
		<para>
		<emphasis>Default value is <quote>9 (512)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>pres_htable_size</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "pres_htable_size", 11)
...
	</programlisting>
		</example>
	</section>
	<section id="presence.p.send_fast_notify">
		<title><varname>send_fast_notify</varname> (int)</title>
		<para>
		This parameter enables or disables the sending of an initial empty NOTIFY after a SUBSCRIBE/reSUBSCRIBE.
		This caused problems for MWI application, because some CPEs (like Samsung) fail to understand an empty
		NOTIFY to a message-summary event. This parameter is enabled by default, thus adhering to the standard.
		</para>
		<para>
		<emphasis>Default value is <quote>1 </quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>send_fast_notify</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "send_fast_notify", 0)
...
	</programlisting>
		</example>
	</section>

	<section id="presence.p.enable_sphere_check">
		<title><varname>enable_sphere_check</varname> (int)</title>
		<para>
		This parameter is a flag that should be set if permission rules include
		sphere checking.
		The sphere information is expected to be present in the RPID body
		published by the presentity. The flag is introduced as this check requires
		extra processing that should be avoided if this feature is not supported
		by the clients.
		</para>
		<para>
		<emphasis>Default value is <quote>0 </quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>enable_sphere_check</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "enable_sphere_check", 1)
...
	</programlisting>
		</example>
	</section>

	<section id="presence.p.timeout_rm_subs">
		<title><varname>timeout_rm_subs</varname> (int)</title>
		<para>
		This parameter is a flag that should be set if subscriptions should be
		removed from the active_watchers when a NOTIFY times out. RFC3265
		section 3.2.2 defines this behaviour as a SHOULD, so by default it is
		on. Disabling this will keep subscriptions active on unreliable
		networks.
		</para>
		<para>
		<emphasis>Default value is <quote>1</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>timeout_rm_subs</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "timeout_rm_subs", 0)
...
	</programlisting>
		</example>
	</section>
	<section id="presence.p.fetch_rows">
	    <title><varname>fetch_rows</varname> (integer)</title>
	    <para>
		Number of rows to be loaded in one step from database.
	    </para>
	    <para>
		<emphasis>
		    Default value is 500.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>fetch_rows</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "fetch_rows", 1000)
...
</programlisting>
	    </example>
	</section>
	<section id="presence.p.db_table_lock_type">
	    <title><varname>db_table_lock_type</varname> (integer)</title>
	    <para>
		Enable (=1) or disable (=0) the Locks for table during a
		transaction. Locking only the "current" table causes problems
		with a MySQL-Databases in "DB-Only" mode.
	    </para>
	    <para>
		In order to use the Presence-Module in "DB_ONLY"-mode with a
		MySQL-Backend, set this parameter to "0", otherwise the
		MySQL-Operations will fail. The Presence-Module will generate
		a "500 Server error" due to the failed MySQL-queries.
	    </para>
	    <para>
		<emphasis>
		    Default value is 1 (Write Lock for the Tables).
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>db_table_lock_type</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "db_table_lock_type", 0)
...
</programlisting>
	    </example>
	</section>
	<section id="presence.p.local_log_level">
	    <title><varname>local_log_level</varname> (int)</title>
	    <para>
		Control log level for some debug messages inside the module.
	    </para>
	    <para>
		<emphasis>
		    Default value is 2 (L_INFO).
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>local_log_level</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "local_log_level", 3)
...
</programlisting>
	    </example>
	</section>
	<section id="presence.p.local_log_facility">
	    <title><varname>local_log_facility</varname> (int)</title>
	    <para>
		Control syslog facility for some debug messages inside the module.
	    </para>
	    <para>
		<emphasis>
		    Default value is taken from the core log_facility configuration parameter.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>local_log_facility</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "local_log_facility", "LOG_LOCAL3")
...
</programlisting>
	    </example>
	</section>
	<section id="presence.p.subs_remove_match">
	    <title><varname>subs_remove_match</varname> (int)</title>
	    <para>
		Control how to match the subscriptions to remove from memory.
		If set to 0, then the match is done on To-Tag (local generated),
		if set to 1, then the match is done on all dialog attributes
		(Call-Id, From-Tag, To-Tag).
	    </para>
	    <para>
		<emphasis>
		    Default value is 0.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>subs_remove_match</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "subs_remove_match", 1)
...
</programlisting>
	    </example>
	</section>
	<section id="presence.p.xavp_cfg">
    <title><varname>xavp_cfg</varname> (str)</title>
    <para>
		The name of the xavp to be used to specify attributes for internal
		processing of presence module.
    </para>
    <para>
		Inner attributes inside xavp can be:
    </para>
    <itemizedlist>
        <listitem>
			<para><emphasis>priority</emphasis> - integer value to set the
			priority of the presence document (higher value, higher priority).
			It can set the order of the aggregated presence documents sent by
			NOTIFY (first the document with higher priority). If xavp_cfg
			parameter is set but this attribute is not in the avp,
			the priority of the presence document is based on timestamp,
			so newer documents have higher priority.</para>
        </listitem>
        <listitem>
			<para><emphasis>delete_subscription</emphasis> - integer value to
			give extra control of deleting the subscription after processing of
			event_route[presence:notify-reply]. If value = 1, it deletes the subscription.
			If xavp_cfg parameter is set but this attribute is not in the avp,
			the subscription is not deleted. This does not apply for codes 404, 481
			and 408 (when timeout_rm_subs = 1) where subscription is deleted.</para>
        </listitem>
     </itemizedlist>
    <para>
        Default value is <emphasis>empty</emphasis> (not set).
    </para>
    <example>
        <title>Set <varname>xavp_cfg</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("presence", "xavp_cfg", "pres")
...
if(is_method("PUBLISH")) {
    $xavp(pres=>priority) = 100;
}
...
</programlisting>
    </example>
	</section>

	<section id="presence.p.retrieve_order">
	    <title><varname>retrieve_order</varname> (int)</title>
	    <para>
		If set to 0, presentity records are retrieved by received_time order.
		If set to 1, presentity records are retrieved by the value of
		retrieve_order_by parameter.
	    </para>
	    <para>
		<emphasis>
		    Default value is 0.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>retrieve_order</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "retrieve_order", 1)
...
</programlisting>
	    </example>
	</section>


	<section id="presence.p.retrieve_order_by">
	    <title><varname>retrieve_order_by</varname> (str)</title>
	    <para>
		Used to set the order-by of the db query for fetching the presence
		records when retrieve_order is set to 1.
	    </para>
	    <para>
		<emphasis>
			Default value is <quote>priority</quote>.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>retrieve_order_by</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "retrieve_order_by", "priority, received_time")
...
</programlisting>
	    </example>
	</section>

<section id="presence.p.sip_uri_match">
    <title><varname>sip_uri_match</varname> (int)</title>
    <para>
        The mode used when comparing uris.
    </para>
    <para>
        <itemizedlist>
            <title>Possible Values</title>
            <listitem>
                <para> 0 : case sensitive</para>
            </listitem>
            <listitem>
                <para> 1 : case insensitive</para>
            </listitem>
        </itemizedlist>
    </para>
    <para>
        <emphasis>Default value is <quote>0</quote>.</emphasis>
    </para>
    <example>
        <title>Set <varname>sip_uri_match</varname> parameter</title>
        <programlisting format="linespecific">
...
modparam("presence", "sip_uri_match", 1)
...
</programlisting>
    </example>
</section>

<section id="presence.p.enable_dmq">
	<title><varname>enable_dmq</varname> (integer)</title>
	<para>
		If set to 1, will enable DMQ replication of presentities between nodes. Use this instead of a shared DB
		to share state across a cluster and update local watchers in realtime (subs_db_mode &lt; 3) or on next
		notifier run (subs_db_mode = 3).
	</para>
	<para>
		<emphasis>
			If this parameter is enabled, the DMQ module must be loaded first - otherwise, startup will fail.
		</emphasis>
	</para>
	<para>
		<emphasis>
			Default value is 0.
		</emphasis>
	</para>
	<example>
		<title>Set <varname>enable_dmq</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "enable_dmq", 1)
...
</programlisting>
	</example>
</section>

<section id="presence.p.pres_subs_mode">
	<title><varname>pres_subs_mode</varname> (integer)</title>
	<para>
	Allow disabling cloning subscription structure for pv $subs(...), saving the
	pkg memory and copy operations for all its fields. If 1 the cloning is done;
	if 0, no cloning and $subs(...) returns $null.
	</para>
	<para>
		<emphasis>
			Default value is 1.
		</emphasis>
	</para>
	<example>
		<title>Set <varname>pres_subs_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "pres_subs_mode", 0)
...
</programlisting>
	</example>
</section>

<section id="presence.p.delete_same_subs">
	<title><varname>delete_same_subs</varname> (integer)</title>
	<para>
		Enable deleting of subscriptions with the same presence uri and callid.
	</para>
	<para>
		<emphasis>
			Default value is 0 (disabled behavior).
		</emphasis>
	</para>
	<example>
		<title>Set <varname>delete_same_subs</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "delete_same_subs", 1)
...
</programlisting>
	</example>
</section>

<section id="presence.p.timer_mode">
	<title><varname>timer_mode</varname> (integer)</title>
	<para>
	Specify what timer process to be used. If set to 0, the core main timer
	is used. If set to 1, the core secondary timer is used.
	</para>
	<para>
		<emphasis>
			Default value is 1.
		</emphasis>
	</para>
	<example>
		<title>Set <varname>timer_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "timer_mode", 0)
...
</programlisting>
	</example>
</section>

<section id="presence.p.subs_respond_200">
	<title><varname>subs_respond_200</varname> (integer)</title>
	<para>
	Specify the response code for accepted SUBSCRIBE requests. If set to 0,
	"202 Accepted" will be returned (default behaviour till version 5.5). If set
	to 1, "200 OK" will be returned instead, in conformance to RFC6665, which
	prohibits 202 responses.
	</para>
	<para>
		<emphasis>
			Default value is 1.
		</emphasis>
	</para>
	<example>
		<title>Set <varname>subs_respond_200</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "subs_respond_200", 0)
...
</programlisting>
	</example>
</section>

</section>

<section>
	<title>Functions</title>
	<section id="presence.f.handle_publish">
		<title>
		<function moreinfo="none">handle_publish([sender_uri])</function>
		</title>
		<para>
		Handles PUBLISH requests by storing and updating
		published information in memory cache and database, then calls functions to send
		NOTIFY messages when changes in the published information occur.
		It takes one argument -> sender_uri. The parameter was added
		for enabling BLA implementation. If present, notification of
		a change in published state is not sent to the respective uri
		even though a subscription exists.
		It should be taken from the Sender header. It was left at the
		decision of the administrator whether or not to transmit the
		content of this header as parameter for handle_publish, to
		prevent security problems.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<para>
		<emphasis>Return code:</emphasis>
		<itemizedlist>
			<listitem>
			<para>
				<emphasis> 1 - if success</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis> -1 - if error</emphasis>.
			</para>
			</listitem>
		</itemizedlist>
		</para>
		<para>
			The module sends an appropriate stateless reply
			in all cases.
		</para>

		<example>
		<title><function>handle_publish</function> usage</title>
		<programlisting format="linespecific">
...
	if(is_method("PUBLISH"))
	{
		if($hdr(Sender)!= NULL)
			handle_publish("$hdr(Sender)");
		else
			handle_publish();
		t_release();
	}
...
</programlisting>
		</example>
	</section>

	<section id="presence.f.handle_subscribe">
		<title>
		<function moreinfo="none">handle_subscribe([watcher_uri])</function>
		</title>
		<para>
		The function which handles SUBSCRIBE requests. It stores or
		updates information in memory and database and calls functions to send NOTIFY
		messages when a SUBSCRIBE which initiate a dialog is received.
		</para>
		<para>
		By default this function uses the From: URI from the SUBSCRIBE
		request as the Watcher URI.  The optional watcher_uri parameter
		can be used to specify a different Watcher URI, possibly taken
		from a SIP header like P-Asserted-Identity:.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<para>
		<emphasis>Return code:</emphasis>
		<itemizedlist>
			<listitem>
			<para>
				<emphasis> 1 - if success</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis> -1 - if error</emphasis>.
			</para>
			</listitem>
		</itemizedlist>
		</para>
		<para>
			The module sends an appropriate stateless reply
			in all cases.
		</para>

		<example>
		<title><function>handle_subscribe</function> usage</title>
		<programlisting format="linespecific">
...
if(method=="SUBSCRIBE")
    handle_subscribe();
...
</programlisting>
		</example>
	</section>

	<section id="presence.f.pres_auth_status">
		<title>
		<function moreinfo="none">pres_auth_status(watcher_uri, presentity_uri)</function>
		</title>
		<para>
		The function checks if watcher URI is authorized to subscribe
		event 'presence' of presentity URI.  Both watcher_uri and
		presentity_uri can be static strings or contain pseudo variables.
		</para>
		<para>The function returns ACTIVE_STATUS, if subscription is allowed,
		and PENDING_STATUS, TERMINATED_STATUS, or WAITING_STATUS otherwise.
		See presence/subscribe.h for the corresponding integer codes. In case
		of error, function returns -1.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>

		<example>
		<title><function>pres_auth_status</function> usage</title>
		<programlisting format="linespecific">
...
if (method=="MESSAGE") {
    pres_auth_status("$fu", $ru");
    if ($retcode == 1) {
        t_relay();
    } else {
        send_reply("403", "Forbidden");
    }
}
...
</programlisting>
		</example>
	</section>

<section id="presence.f.pres_has_subscribers">
    <title>
        <function moreinfo="none">pres_has_subscribers(presentity_uri, event)</function>
    </title>
    <para>
        Allows to check if presentity has any subscribers of event.
    </para>
    <para>
        This function can be used from ANY_ROUTE.
    </para>
    <example>
        <title><function>pres_has_subscribers</function> usage</title>
        <programlisting format="linespecific">
...
if(pres_has_subscribers($var(uri), "message-summary"))
    # do something...;
...
</programlisting>
    </example>
</section>

	<section id="presence.f.pres_refresh_watchers">
		<title>
		<function moreinfo="none">pres_refresh_watchers(uri, event, type[, file_uri, filename])</function>
		</title>
		<para>
			The function can be used in configuration to trigger notifies to watchers
			if a change in watchers authorization or in published state occurred
			(i.e., updates of xcap documents).
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>uri - the uri of the user who made the change
				and whose watchers should be informed.</para>
			</listitem>
			<listitem>
				<para>event - the event package.</para>
			</listitem>
			<listitem>
				<para>type - it distinguishes between the three different types of events
						that can trigger the refresh, depending on its value:
						<itemizedlist>
							<listitem>
								<para>0 - a change in watchers authentication.</para>
							</listitem>
							<listitem>
								<para>1 - a statical update in published state through direct
								update in db table.
								</para>
							</listitem>
							<listitem>
								<para>2 - a statical update in published state by modifying
								the pidf manipulation document.
								</para>
							</listitem>
						</itemizedlist>
				</para>
			</listitem>
			<listitem>
				<para>file_uri - the uri of the pidf-manipulation file on
				the XCAP server (only used for type 2).</para>
			</listitem>
			<listitem>
				<para>filename - the name of the pidf-manipulation file on
				the XCAP server (only used for type 2).</para>
			</listitem>
        	</itemizedlist>
		<para>
		This function can be used from ANY_ROUTE.
		</para>
		<example>
		<title><function>pres_refresh_watchers</function> usage</title>
		<programlisting format="linespecific">
...
pres_refresh_watchers("sip:test@kamailio.org", "presence", 1);
...
</programlisting>
		</example>
	</section>

	<section id="presence.f.pres_update_watchers">
		<title>
		<function moreinfo="none">pres_update_watchers(uri, event)</function>
		</title>
		<para>
			The function can be used in configuration to trigger updates to watchers
			status if a change in watchers authorization state occurred
			(i.e., updates of xcap documents change state from pending to active).
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>uri - the uri of the user who made the change
				and whose watchers should be informed. Can be PV.</para>
			</listitem>
			<listitem>
				<para>event - the event package (e.g., presence).</para>
			</listitem>
        </itemizedlist>
		<para>
		This function can be used from ANY_ROUTE.
		</para>
		<example>
		<title><function>pres_update_watchers</function> usage</title>
		<programlisting format="linespecific">
...
pres_update_watchers("sip:test@kamailio.org", "presence");
...
</programlisting>
		</example>
	</section>
</section>

<section>
	<title>RPC Commands</title>
	<section id="presence.r.cleanup">
	  <title>presence.cleanup</title>
	  <para>
		Manually triggers the cleanup functions for the active_watchers, presentity,
		and watchers tables. Useful if you have set <varname>clean_period</varname>
		and/or <varname>db_update_period</varname> to zero or less.
	  </para>
	  <para>
		Name: <emphasis>presence.cleanup</emphasis>
	  </para>
	  <para>Parameters: <emphasis>none</emphasis></para>
	  <para>
		RPC Command Format:
	  </para>
	  <programlisting  format="linespecific">
...
&kamcmd; presence.cleanup
...
</programlisting>
    </section>

	<section id="presence.r.publish_cache_sync">
	  <title>presence.publish_cache_sync</title>
	  <para>
	  	Synchronize changes made to the presentity table with the publish cache.
	  </para>
	  <para>
		Name: <emphasis>presence.publish_cache_sync</emphasis>
	  </para>
	  <para>Parameters: <emphasis>none</emphasis></para>
	  <para>
		RPC Command Format:
	  </para>
	  <programlisting  format="linespecific">
...
&kamcmd; presence.publish_cache_sync
...
</programlisting>
    </section>

	<section id="presence.r.refreshWatchers">
		<title>presence.refreshWatchers</title>
		<para>
		Triggers sending Notify messages to watchers if a change in watchers
		authorization or in published state occurred.
		</para>
		<para>
		Name: <emphasis>presence.refreshWatchers</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>uri - the uri of the user who made the change
				and whose watchers should be informed</para>
			</listitem>
			<listitem>
				<para>event - the event package.</para>
			</listitem>
			<listitem>
				<para>type - it distinguishes between the three different types of events
						that can trigger the refresh, depending on its value:
						<itemizedlist>
							<listitem>
								<para>0 - a change in watchers authentication.</para>
							</listitem>
							<listitem>
								<para>1 - a statical update in published state through direct
								update in db table.
								</para>
							</listitem>
							<listitem>
								<para>2 - a statical update in published state by modifying
								the pidf manipulation document.
								</para>
							</listitem>
						</itemizedlist>
				</para>
			</listitem>
			<listitem>
				<para>file_uri - the uri of the pidf-manipulation file on
				the XCAP server (only used for type 2).</para>
			</listitem>
			<listitem>
				<para>filename - the name of the pidf-manipulation file on
				the XCAP server (only used for type 2).</para>
			</listitem>
        	</itemizedlist>
        <para>
		RPC Command Format:
		</para>
		<programlisting  format="linespecific">
...
&kamcmd; presence.refreshWatchers sip:test@kamailio.org presence 1
...
</programlisting>
	</section>
	<section id="presence.rpc.updateWatchers">
	  <title>presence.updateWatchers</title>
	  <para>
		Manually triggers updates to watchers (for example,
		after the contents of XCAP docs has been updated).
	  </para>
	  <para>
		Name: <emphasis>presence.updateWatchers</emphasis>
	  </para>
	  <para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>uri - the uri of the user who made the changes
				and whose watchers should be updated.</para>
			</listitem>
			<listitem>
				<para>event - the event package (e.g. presence).
				</para>
			</listitem>
		</itemizedlist>
	  <para>
		RPC Command Format:
	  </para>
	  <programlisting  format="linespecific">
...
&kamcmd; presence.updateWatchers sip:alice@domain.com presence
...
	  </programlisting>
	</section>
	<section id="presence.rpc.presentity_list">
	  <title>presence.presentity_list</title>
	  <para>
		List the presentity records stored in memory.
	  </para>
	  <para>
		Name: <emphasis>presence.presentity_list</emphasis>
	  </para>
	  <para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>mode - (optional) it can be 'full' to print all the
				fields of presentity record. If missing, only a selected
				set of fields are printed in the response.</para>
			</listitem>
		</itemizedlist>
	  <para>
		RPC Command Format:
	  </para>
	  <programlisting  format="linespecific">
...
kamctl rpc presence.presentity_list
kamctl rpc presence.presentity_list full
...
	  </programlisting>
	</section>
	<section id="presence.rpc.presentity_show">
	  <title>presence.presentity_show</title>
	  <para>
		Return the presentity records stored in memory by filtering with username
		and/or domain.
	  </para>
	  <para>
		Name: <emphasis>presence.presentity_show</emphasis>
	  </para>
	  <para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>mode - it can be  'basic' or 'full' to print a selection or
				all the fields of presentity record.</para>
			</listitem>
			<listitem>
				<para>user - username to match presentity records, use '*' to
				match any username.</para>
			</listitem>
			<listitem>
				<para>domain - the value to match the domain of the presentity
				records, use '*' to match any domain.</para>
			</listitem>
		</itemizedlist>
	  <para>
		RPC Command Format:
	  </para>
	  <programlisting  format="linespecific">
...
kamctl rpc presence.presentity_show basic alice sipserver.com
kamctl rpc presence.presentity_show full * sipserver.com
...
	  </programlisting>
	</section>
	<section id="presence.rpc.watcher_list">
	  <title>presence.watcher_list</title>
	  <para>
		Return the watcher records for a specific presentity uri.
	  </para>
	  <para>
		Name: <emphasis>presence.watcher_list</emphasis>
	  </para>
	  <para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>mode - it can be  'basic' or 'full' to print a selection or
				all the fields of watcher record.</para>
			</listitem>
			<listitem>
				<para>uri - the presentity uri.</para>
			</listitem>
		</itemizedlist>
	  <para>
		RPC Command Format:
	  </para>
	  <programlisting  format="linespecific">
...
kamctl rpc presence.watcher_list basic sip:alice@sipserver.com
...
	  </programlisting>
	</section>

</section>

<section>
	<title>Exported Variables</title>

		<section>
			<title><varname>$subs(attr)</varname></title>
			<para>
				Access the attributes of handled subscription.
				It must be used after a successful call of
				<quote>handle_subscription()</quote> or in the following events.
			<itemizedlist>
				<listitem>
				<para><emphasis>tm:local-request</emphasis> - before notify is sent
				</para>
				</listitem>
				<listitem>
				<para><emphasis>presence:notify-reply</emphasis> - after notify is sent
				</para>
				</listitem>
			</itemizedlist>
			</para>
			<para>
			The <quote>attr</quote> can be:
			</para>
			<itemizedlist>
				<listitem>
				<para><emphasis>uri</emphasis> - subscription presentity uri
				</para>
				</listitem>
				<listitem>
				<para><emphasis>pres_uri</emphasis> - alias for presentity uri
				</para>
				</listitem>
				<listitem>
				<para><emphasis>to_user</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>to_domain</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>from_user</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>from_domain</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>watcher_username</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>watcher_domain</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>event</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>event_id</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>to_tag</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>from_tag</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>callid</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>remote_cseq</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>local_cseq</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>contact</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>local_contact</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>record_route</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>expires</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>status</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>reason</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>version</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>flags</emphasis>
				</para>
				</listitem>
				<listitem>
				<para><emphasis>user_agent</emphasis>
				</para>
				</listitem>
			</itemizedlist>

			<example>
			<title><function moreinfo="none">$subs(name)</function> usage</title>
<programlisting format="linespecific">
...
if(handle_subscription())
{
  xlog("presentity=$subs(uri)\n");
}
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>$notify_reply(attr)</varname></title>
			<para>
				Access the reply message received when notifying subscriber.
				It must be used in the following events.
			<itemizedlist>
				<listitem>
				<para><emphasis>presence:notify-reply</emphasis> - after notify is sent
				</para>
				</listitem>
			</itemizedlist>
			</para>
			<para>
			The <quote>attr</quote> can be any pseudo var that accesses attributes of msg
			</para>

			<example>
			<title><function moreinfo="none">$notify_reply(name)</function> usage</title>
<programlisting format="linespecific">
...
event_route[presence:notify-reply]
{
  xlog("received message = $notify_reply($mb)\n");
}
...
</programlisting>
			</example>
		</section>
</section>

<section>
	<title>Events</title>
		<section>
			<title><varname>presence:notify-reply</varname></title>
			<para>
				Fired after notify reply is received or timeout.
			</para>

			<example>
			<title><function moreinfo="none">$notify_reply(name)</function> usage</title>
<programlisting format="linespecific">
...
event_route[presence:notify-reply]
{
  xlog("received message = $notify_reply($mb)\n");
}
...
</programlisting>
			</example>
		</section>
</section>

<section>
	<title>Installation</title>
	<para>
	The module requires 3 tables in the &kamailio; database: "presentity",
	"active_watchers" and "watchers". The SQL
	syntax to create them can be found in presence-create.sql
	script in the database directories in the kamailio/scripts folder.
	You can also find the complete database documentation on the
	project webpage, &kamailiodbdocslink;.
	</para>
</section>

</chapter>

