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

<chapter>
	<title>&adminguide;</title>
	
	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para> The modules handles PUBLISH and SUBSCRIBE messages and generates
	NOTIFY messages in a general, event independent way. It allows registering 
	events from other &osips; modules. Events that can currently be added are:
	<itemizedlist>
	<listitem><para>
		<emphasis>presence</emphasis>, <emphasis>presence.winfo</emphasis>,
		<emphasis>dialog;sla</emphasis> from presence_xml module
	</para></listitem>
	<listitem><para>
		<emphasis>message-summary</emphasis> from presence_mwi module
	</para></listitem>
	<listitem><para>
		<emphasis>call-info</emphasis>, <emphasis>line-seize</emphasis> from
		presence_callinfo module
	</para></listitem>
	<listitem><para>
		<emphasis>dialog</emphasis> from presence_dialoginfo module
	</para></listitem>
	<listitem><para>
		<emphasis>xcap-diff</emphasis> from presence_xcapdiff module
	</para></listitem>
	<listitem><para>
		<emphasis>as-feature-event</emphasis> from presence_dfks module
	</para></listitem>
	</itemizedlist>
	</para>
	<para>
	The module uses database storage. 
	It has later been improved with memory caching operations to improve
	performance. The Subscribe dialog information are stored in memory and 
	are periodically updated in database, while for Publish only the presence
	or absence of stored info for a certain resource is maintained in memory
	to avoid unnecessary, costly db operations. 
	It is possible to configure a fallback to database mode(by setting module
	parameter "fallback2db"). In this mode, in case a searched record is not 
	found in cache, the search is continued	in database. This is useful for
	an architecture in which processing and memory load might be divided on 
	more machines using the same database.
	</para>
	<para>The module can also work only with the functionality of a library,
	with no message processing and generation, but used only for the exported
	functions.
	This mode of operation is enabled if the db_url parameter is not set to any value.
	</para>
	<para>
	The server follows the specifications in: RFC3265, RFC3856, RFC3857, 
	RFC3858.
	</para>
	</section>

	<section id="presence_clustering">
	<title>Presence clustering</title>
	<para>
	To read and understand the presence clustering, its abilities and how to
	implement scenarios like High-Availability, Load Balancing or Federations,
	please refer to this article <ulink url="https://blog.opensips.org/2018/03/27/clustering-presence-services-with-opensips-2-4/">https://blog.opensips.org/2018/03/27/clustering-presence-services-with-opensips-2-4/</ulink>.
	</para>
	<para>
	As data synchronization at startup is performed when using the
	<emphasis>full-sharing</emphasis> <xref linkend="param_cluster_federation_mode"/>,
	you should define at least one "seed" node in the cluster in this case.
	</para>
	</section>

	<section id="dependencies" xreflabel="Dependencies">
	<title>Dependencies</title>
	<section>
		<title>&osips; 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>signaling</emphasis>.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>clusterer</emphasis>, if the cluster_id 
				module parameter is set and clustering support activated.
			</para>
			</listitem>

			</itemizedlist>
		</para>
	</section>

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

		</section>
	</section>
	
	<section id="exported_parameters" xreflabel="Exported Parameters">
	<title>Exported Parameters</title>
	<section id="param_db_url" xreflabel="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", 
	"mysql://opensips:opensipsrw@192.168.2.132/opensips")
...
</programlisting>
		</example>
	</section>

	<section id="param_fallback2db" xreflabel="fallback2db">
		<title><varname>fallback2db</varname> (int)</title>
		<para>
		Setting this parameter enables a fallback to db mode of operation.
		In this mode, in case a searched record is not found in cache, 
		the search is continued	in database. Useful for an architecture in
		which processing and memory load might be divided on more machines
		using the same database.
		</para>
		<example>
		<title>Set <varname>fallback2db</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "fallback2db", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_cluster_id" xreflabel="cluster_id">
		<title><varname>cluster_id</varname> (int)</title>
		<para>
		The ID of the cluster this presence server belongs to. This parameter
		is to be used only if clustering mode is needed. In order to
		understand th concept of a cluster ID, please see the 
		<emphasis>clusterer</emphasis> module.
		</para>

			&clusterer_sync_cap_para;

		<para>
		For more on presence clustering see the 
		<xref linkend="presence_clustering"/> chapter.
		</para>
		<para>
		<emphasis>Default value is <quote>None</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cluster_id</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "cluster_id", 2)
...
</programlisting>
		</example>
	</section>

	<section id="param_cluster_federation_mode" xreflabel="cluster_federation_mode">
		<title><varname>cluster_federation_mode</varname> (str)</title>
		<para>
		When enabling the federation mode, nodes inside the presence
		cluster will start broadcasting the data to other nodes via the
		clustering support.
		</para>
		<para>
		<emphasis>Possible values:</emphasis>
		<itemizedlist>
			<listitem>
			<para>
				<emphasis>disabled</emphasis> - federation mode is disabled
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>on-demand-sharing</emphasis> - the minimum needed information is
				kept on each node. Replicated information for non local
				subscribers is discarded and queries are broadcasted
				in the cluster for new subscribers.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>full-sharing</emphasis> - published state is kept on all presence
				nodes even when there aren't any local subscribers.
			</para>
			</listitem>
		</itemizedlist>
		</para>
		<para>
		If you don't want to use a shared database (via
		<xref linkend="param_fallback2db"/>), but still want a
		complete data set everywhere, you may choose mode <emphasis>full-sharing</emphasis>.
		This mode allows you to switch PUBLISH endpoints,
		even for already published Event States, thus allowing
		you to add and remove presence servers without losing
		state.
		</para>
		<para>
		For more on presence clustering see the 
		<xref linkend="presence_clustering"/> chapter.
		</para>
		<para>
		<emphasis>Default value is <quote>disabled</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cluster_federation_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "cluster_federation_mode", "full-sharing")
...
</programlisting>
		</example>
	</section>

	<section id="param_cluster_pres_events" xreflabel="cluster_pres_events">
		<title><varname>cluster_pres_events</varname> (str)</title>
		<para>
		Comma Separated Value (CSV) list with the events to considered by the
		federated cluster - only presentities advertising one of these events
		will be broadcasted via the cluster.
		</para>
		<para>
		For more on presence clustering see the 
		<xref linkend="presence_clustering"/> chapter.
		</para>
		<para>
		<emphasis>Default value is <quote>empty</quote> (meaning all).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cluster_pres_events</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "cluster_pres_events" ,"presence, dialog;sla, message-summary")
...
</programlisting>
		</example>
	</section>

	<section id="param_cluster_be_active_shtag" xreflabel="cluster_be_active_shtag">
		<title><varname>cluster_be_active_shtag</varname> (str)</title>
		<para>
		The name of a cluster sharing tag to be used to indicate when this
		node (as part of the cluster) should be active or not. If the sharing
		tag is off (or as backup), the node will become inactive from 
		clustering perspective, meaning not sending and not accepting any
		presence related cluster traffic.
		</para>
		<para>
		This ability of a node to become inactive may be used when creating a
		federated cluster where 2 nodes are acting as a local active-backup 
		setup (for local High Availability purposes).
		</para>
		<para>
		This parameter has meaning only in clustering mode. If not defined, the
		node will be active all the time.
		</para>
		<para>
		For more on presence clustering see the 
		<xref linkend="presence_clustering"/> chapter.
		</para>
		<para>
		<emphasis>Default value is <quote>empty</quote> (not tag define).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cluster_be_active_shtag</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "cluster_be_active_shtag" ,"local_ha")
...
</programlisting>
		</example>
	</section>



	<section id="param_expires_offset" xreflabel="expires_offset">
		<title><varname>expires_offset</varname> (int)</title>
		<para>
			The extra time to store a subscription/publication.
		</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="param_max_expires_subscribe" xreflabel="max_expires_subscribe">
		<title><varname>max_expires_subscribe</varname> (int)</title>
		<para>
		The the maximum admissible expires value for SUBSCRIBE
		messages.
		</para>
		<para>
		<emphasis>Default value is <quote>3600</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>max_expires_subscribe</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "max_expires_subscribe", 3600)
...
</programlisting>
		</example>
	</section>

<section id="param_max_expires_publish" xreflabel="max_expires_publish">
		<title><varname>max_expires_publish</varname> (int)</title>
		<para>
		The the maximum admissible expires value for PUBLISH
		messages.
		</para>
		<para>
		<emphasis>Default value is <quote>3600</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>max_expires_publish</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "max_expires_publish", 3600)
...
</programlisting>
		</example>
	</section>


	<section id="param_contact_user" xreflabel="contact_user">
		<title><varname>contact_user</varname> (str)</title>
		<para>
		This is the username that will be used in the Contact header for the 200 OK
		replies to SUBSCRIBE and in the following in-dialog NOTIFY requests.
		The IP address, port and transport for the Contact will be automatically
		determined based on the interface where the SUBSCRIBE was received.
		</para>
		<para>
		If set to an empty string, no username will be added to the contact and
		the contact will be built just out of the IP, port and transport.
		</para>
		<para>
		<emphasis>Default value is <quote>presence</quote>.</emphasis>
		</para>
		<example>
		<title>Set <varname>contact_user</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "contact_user", "presence")
...
		</programlisting>
		</example>
	</section>

	<section id="param_enable_sphere_check" xreflabel="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="param_waiting_subs_daysno" xreflabel="waiting_subs_daysno">
		<title><varname>waiting_subs_daysno</varname> (int)</title>
		<para>
			The number of days to keep the record of a subscription in server
			database if the subscription is in pending or waiting state 
			(no authorization policy was defined for it or the target user 
			did not register sice the subscription and was not informed about
			it).
		</para>
		<para>
			<emphasis>Default value is <quote>3</quote> days. Maximum accepted
			value is 30 days.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>waiting_subs_daysno</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "waiting_subs_daysno", 2)
...
	</programlisting>
		</example>
	</section>
	<section id="param_mix_dialog_presence" xreflabel="mix_dialog_presence">
		<title><varname>mix_dialog_presence</varname> (int)</title>
		<para>
		This module parameter enables a very nice feature in the presence 
		server - generating presence information from dialogs state. If this 
		parameter is set, the presence server will tell you if a buddy is in 
		a call even if his phone did not send a presence Publish with this 
		information. You will need to load the dialoginfo modules, 
		presence_dialoginfo, pua_dialoginfo, dialog and pua.
		</para>
		<para>
			<emphasis>Default value is <quote>0</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>mix_dialog_presence</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "mix_dialog_presence", 1)
...
	</programlisting>
		</example>
	</section>
	<section id="param_bla_presentity_spec" xreflabel="bla_presentity_spec">
		<title><varname>bla_presentity_spec</varname> (str)</title>
		<para>
			By default the presentity uri for BLA subscribes (event=dialog;sla)
			is computed from contact username + from domain. In some cases 
			though, this way of computing the presentity might not be right 
			(for example if you have a SBC in front that masquerades the 
			contact). So we added this parameter that allows defining a custom 
			uri to be used as presentity uri for BLA subscribes. You should 
			set this parameter to the name of a pseudovariable and then set 
			this pseudovariable to the desired URI before calling the
			<xref linkend="func_handle_subscribe"/> function.
		</para>
		<para>
			<emphasis>Default value is <quote>NULL</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>bla_presentity_spec</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "bla_presentity_spec", "$var(bla_pres)")
...
	</programlisting>
		</example>
	</section>

	<section id="param_bla_fix_remote_target" xreflabel="bla_fix_remote_target">
		<title><varname>bla_fix_remote_target</varname> (int)</title>
		<para>
			Polycom has a bug in the bla implementation. It inserts the 
			remote IP contact in the Notify body and when a phone picks up a 
			call put on hold by another phone in the same BLA group, it sends 
			an Invite directly to the remote IP. OpenSIPS BLA server tries to 
			prevent this by replacing the IP contact with the
			domain, when this is possible.
		</para>
		<para>
			In some cases(configurations) however this is not desirable, so 
			this parameter was introduced to disable this behaviour when 
			needed.
		</para>
		<para>
			<emphasis>Default value is <quote>1</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>bla_fix_remote_target</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "bla_fix_remote_target", 0)
...
	</programlisting>
		</example>
	</section>


	<section id="param_notify_offline_body" xreflabel="notify_offline_body">
		<title><varname>notify_offline_body</varname> (int)</title>
		<para>
			If this parameter is set, when no published info is found for
			a user, the presence server will generate a dummy body with status
			'closed' and use it when sending Notify, instead of notifying with
			no body.
		</para>
		<para>
			<emphasis>Default value is <quote>0</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>notify_offline_body</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "notify_offline_body", 1)
...
	</programlisting>
		</example>
	</section>

	<section id="param_end_sub_on_timeout" xreflabel="end_sub_on_timeout">
		<title><varname>end_sub_on_timeout</varname> (int)</title>
		<para>
			If a presence subscription should be automatically terminated 
			(destroyed) when receiving a SIP timeout (408) for a sent
			NOTIFY requests.
		</para>
		<para>
			<emphasis>Default value is <quote>1</quote> (enabled).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>end_sub_on_timeout</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("presence", "end_sub_on_timeout", 0)
...
	</programlisting>
		</example>
	</section>

	<section id="param_clean_period" xreflabel="clean_period">
		<title><varname>clean_period</varname> (int)</title>
		<para>
		The period at which to clean the expired subscription dialogs.
		</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="param_db_update_period" xreflabel="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="param_presentity_table" xreflabel="presentity_table">
		<title><varname>presentity_table</varname>(str)</title>
		<para>
		The name of the db table where Publish information are 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="param_active_watchers_table" xreflabel="active_watchers_table">
		<title><varname>active_watchers_table</varname>(str)</title>
		<para>
		The name of the db table where active subscription information are 
		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="param_watchers_table" xreflabel="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="param_subs_htable_size" xreflabel="subs_htable_size">
		<title><varname>subs_htable_size</varname> (int)</title>
		<para>
		The size of the 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="param_pres_htable_size" xreflabel="pres_htable_size">
		<title><varname>pres_htable_size</varname> (int)</title>
		<para>
	The size of the 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>

<section id="exported_functions" xreflabel="exported_functions">
	<title>Exported Functions</title>
	<section id="func_handle_publish" xreflabel="handle_publish()">
		<title>
		<function moreinfo="none">handle_publish([sender_uri])</function>
		</title>
		<para>
		The function handles PUBLISH requests. It stores and updates 
		published information in database and calls functions to send 
		NOTIFY messages when changes in the published information occur.
		</para>
		<para>
		It may takes one optional string argument, the 'sender_uri' SIP 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();
	} 
...
</programlisting>
		</example>
	</section>

	<section id="func_handle_subscribe" xreflabel="handle_subscribe()">
		<title>
		<function moreinfo="none">handle_subscribe([force_active] [,sharing_tag])</function>
		</title>
		<para>
		This function is to be used for handling SUBSCRIBE requests. It stores
		or updates the watcher/subscriber information in database. 
		Additionally, in response to initial SUBSCRIBE requests (creating a 
		new subscription session), the function also sends back the NOTIFY 
		(with the presence information) to the wathcer/subscriber.
		</para>
		<para>
		The function may take the following parameters:
		</para>
		<itemizedlist>
			<listitem>
				<para>
				<emphasis>force_active</emphasis> (int, optional) - optional parameter that 
				controls what is the default policy (of the presentity) on 
				accepting new subscriptions (accept or reject) - of course, 
				this parameter makes sense only when using a presence 
				configuration with privacy rules enabled (force_active 
				parameter in presence_xml module is not set).
				</para>
				<para>
				There are scenarios where the presentity (the party you 
				subscribe to) can not upload an XCAP document with its
				privacy rules (to control which watchers are allowed to 
				subscribe to it). In such cases, from script level, you can
				force the presence server to consider the current subscription
				allowed (with Subscription-Status:active) by calling the 
				handle_subscribe() function with the integer parameter "1".
				</para>
			</listitem>
			<listitem>
				<para>
				<emphasis>sharing_tag</emphasis> (string, optional) - optional parameter telling
				the owner tag (for the subscription) in clusetering scenarios 
				where the subscription data is shared between multiple 
				servers - see the <xref linkend="presence_clustering"/>
				chapter for more details.
				</para>
			</listitem>
		</itemizedlist>
		<programlisting format="linespecific">
   Ex: 
	if($ru =~ "kphone@opensips.org")
		handle_subscribe(1);
		</programlisting>
		<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($rm=="SUBSCRIBE")
    handle_subscribe();
...
</programlisting>
		</example>
	</section>
</section>

<section id="exported_mi_functions" xreflabel="Exported MI Functions">
	<title>Exported MI Functions</title>
	<section id="mi_refresh_watchers" xreflabel="refresh_watchers">
		<title>
		<function moreinfo="none">refresh_watchers</function>
		</title>
		<para>
		Triggers sending Notify messages to watchers if a change in watchers
		authorization or in published state occurred.
		</para>
		<para>
		Name: <emphasis>refresh_watchers</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>presentity_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>refresh type : it distinguishes between the two different types of events
									that can trigger a refresh: 
									<itemizedlist>
									<listitem>
									<para>
									a change in watchers authentication: refresh type= 0 ;
									</para>
									</listitem>
									<listitem>
									<para>
									a statical update in published state (either through direct 
									update in db table or by modifying the pidf manipulation document,
									if pidf_manipulation parameter is set): refresh type!= 0.
									</para>
									</listitem>
									</itemizedlist>
				</para>
			</listitem>
	</itemizedlist>

	<para>
		MI FIFO Command Format:
		</para>
	<programlisting  format="linespecific">
opensips-cli -x mi refresh_watchers sip:11@192.168.2.132 presence 1
	</programlisting>
	</section>

	<section id="mi_cleanup" xreflabel="cleanup">
	  <title>
		<function moreinfo="none">cleanup</function>
	  </title>
	  <para>
		Manually triggers the cleanup functions for watchers and presentity tables. Useful if you
		have set <varname>clean_period</varname> to zero or less.
	  </para>
	  <para>
		Name: <emphasis>cleanup</emphasis>
	  </para>
	  <para>Parameters: <emphasis>none</emphasis></para>

	  <para>
		MI FIFO Command Format:
	  </para>
	  <programlisting  format="linespecific">
opensips-cli -x mi cleanup
	  </programlisting>
	</section>

	<section id="mi_pres_phtable_list" xreflabel="pres_phtable_list">
	  <title>
		<function moreinfo="none">pres_phtable_list</function>
	  </title>
	  <para>
		Lists all the presentity records.
	  </para>
	  <para>
		Name: <emphasis>pres_phtable_list</emphasis>
	  </para>
	  <para>Parameters: <emphasis>none</emphasis></para>

	  <para>
		MI FIFO Command Format:
	  </para>
	  <programlisting  format="linespecific">
opensips-cli -x mi pres_phtable_list
	  </programlisting>
	</section>

	<section id="mi_subs_phtable_list" xreflabel="subs_phtable_list">
	  <title>
		<function moreinfo="none">subs_phtable_list</function>
	  </title>
	  <para>
		Lists all the subscription records, or the subscriptions for which the "To" and "From" URIs match the given parameters.
	  </para>
	  <para>
		Name: <emphasis>subs_phtable_list</emphasis>
	  </para>
	  <para>Parameters</para>
	  <itemizedlist>
		<listitem><para>
			<emphasis>from</emphasis>(optional) - wildcard for "From" URI
		</para></listitem>
		<listitem><para>
			<emphasis>to</emphasis>(optional) - wildcard for "To" URI
		</para></listitem>
	  </itemizedlist>
	  <para>
		MI FIFO Command Format:
	  </para>
	  <programlisting  format="linespecific">
opensips-cli -x mi subs_phtable_list sip:222@domain2.com sip:user_1@example.com
	  </programlisting>
	</section>

	<section id="mi_pres_expose" xreflabel="pres_expose">
	  <title>
		<function moreinfo="none">pres_expose</function>
	  </title>
	  <para>
		  Exposes in the script, by rasing an
		  <emphasis>E_PRESENCE_EXPOSED</emphasis> event, all the
		  presentities of a specific event that match a specified
		  filter.
	  </para>
	  <para>
		Name: <emphasis>pres_expose</emphasis>
	  </para>
	  <para>Parameters:</para>
	  <itemizedlist>
		<listitem><para>
			<emphasis>event</emphasis> - the desired presence
			event.
		</para></listitem>
		<listitem><para>
			<emphasis>filter</emphasis>(optional) - a regular
			expression (REGEXP) used for filtering the presentities
			for that event. Only the presentities that match will
			be exposed. If not specified, all presentities for that
			event are exposed.
		</para></listitem>
	  </itemizedlist>

	  <para>
		MI FIFO Command Format:
	  </para>
	  <programlisting  format="linespecific">
opensips-cli -x mi pres_expose presence ^sip:10\.0\.5\.[0-9]*
	  </programlisting>
	</section>
</section>


	<section id="exported_events" xreflabel="Exported Events">
	<title>Exported Events</title>
	<section id="event_E_PRESENCE_PUBLISH" xreflabel="E_PRESENCE_PUBLISH">
		<title>
		<function moreinfo="none">E_PRESENCE_PUBLISH</function>
		</title>
		<para>
			This event is raised when the presence module receives
			a PUBLISH message.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>user</emphasis> - the AOR of the user
			</para></listitem>
			<listitem><para>
				<emphasis>domain</emphasis> - the domain
			</para></listitem>
			<listitem><para>
				<emphasis>event</emphasis> - the type of the
					event published
			</para></listitem>
			<listitem><para>
				<emphasis>expires</emphasis> - the expire value
					of the publish
			</para></listitem>
			<listitem><para>
				<emphasis>etag</emphasis> - the entity tag
			</para></listitem>
			<listitem><para>
				<emphasis>old_etag</emphasis> - the entity tag to be refreshed
			</para></listitem>
			<listitem><para>
				<emphasis>body</emphasis> - the body of the
					PUBLISH request
			</para></listitem>
		</itemizedlist>
	</section>
	<section id="event_E_PRESENCE_EXPOSED" xreflabel="E_PRESENCE_EXPOSED">
		<title>
		<function moreinfo="none">E_PRESENCE_EXPOSED</function>
		</title>
		<para>
			This event is raised for each presentity exposeed
			by the <emphasis>pres_expose</emphasis>.
		</para>
		<para>Parameters:</para>
		<para>Same parameters as the
			<emphasis>E_PRESENCE_PUBLISH</emphasis> event.</para>
	</section>
	</section>

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

</chapter>

