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

<chapter>

	<title>&adminguide;</title>

	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para>
	The dialog module provides dialog awareness to the &osips; proxy. Its
	functionality is to keep trace of the current dialogs, to offer information
	about them (like how many dialogs are active).
	</para>
	<para>
	Aside tracking, the dialog module offers functionalities like flags and
	attributes per dialog (persistent data across dialog), dialog profiling
	and dialog termination (on timeout base or external triggered).
	</para>
	<para>
	The module, via an internal API, also provide the foundation to build on
	top of it more complex dialog-based functionalities via other &osips;
	modules.
	</para>
	</section>

	<section>
	<title>How it works</title>
	<para>
	To create the dialog associated with an initial request, you must call
	the create_dialog() function, with or without parameter.
	</para>
	<para>
	The dialog is automatically terminated when a <quote>BYE</quote> is
	received. In case of no <quote>BYE</quote>, the dialog lifetime is
	controlled via the default timeout (see <quote>default_timeout</quote>
	- <xref linkend="param_default_timeout"/>) and custom timeout (see
	<quote>$DLG_timeout</quote> - <xref linkend="pv_DLG_timeout"/>).
	</para>
	<para>
	Once terminated, the in-memory dialog may be destroyed right away or, 
	depending on the <quote>delete_delay</quote>
	- <xref linkend="param_delete_delay"/>) setting, it may be kept for a
	while in memory, in a read-only state (no action, no changes, nothing).
	This delaying may be used to help with the routing of late in-dialog
	request that may be received after the dialog terminted (like late BYE's
	due retransmissions, cross BYE requests, auth'ed BYE request, slow ACK on
	re-INVITEs, etc).
	</para>
	</section>

	<section id="dialog-profiling" xreflabel="Dialog profiling">
	<title>Dialog profiling</title>
	<para>
	Dialog profiling is a mechanism that helps in classifying, sorting and
	keeping trace of certain types of dialogs, using whatever properties of
	the dialog (like caller, destination, type of calls, etc).
	Dialogs can be dynamically added in different (and several) profile
	tables - logically, each profile table can have a special meaning (like
	dialogs outside the domain, dialogs terminated to PSTN, etc).
	</para>
	<para>
	There are two types of profiles:
	<itemizedlist>
		<listitem>
		<para>
			<emphasis>with no value</emphasis> - a dialog simply belongs
			to a profile. (like outbound calls profile). There is no other
			additional information to describe the dialog's belonging to the
			profile;
		</para>
		</listitem>
		<listitem>
		<para>
			<emphasis>with value</emphasis> - a dialog belongs to a profile
			having a certain value (like in caller profile, where the value
			is the caller ID). The belonging of the dialog to the profile is
			strictly related to the value.
		</para>
		</listitem>
	</itemizedlist>
	</para>
	<para>
	A dialog can be added to multiple profiles in the same time.
	</para>
	<para>
	Profiles are visible (at the moment) in the request route (for initial
	and sequential requests) and in the branch, failure and reply routes of
	the original request.
	</para>
	<para>
	Dialog profiles can also be used in distributed systems, using the &osips;
	CacheDB Interface or the <emphasis>clusterer</emphasis> module. This feature
	allows you to share dialog profile information with multiple &osips; instaces
	that use the same CacheDB backend or are part of an &osips; cluster. In order
	to do that, the <emphasis role='bold'>cachedb_url</emphasis> or
	<emphasis role='bold'>profile_replication_cluster</emphasis> parameters must be defined.
	Also, the profile must be marked as shared, by adding one of the
	<emphasis>'/s'</emphasis> or <emphasis>'/b'</emphasis> suffixes to the name of
	the profile in the <emphasis>profiles_with_value</emphasis> or
	<emphasis>profiles_no_value</emphasis> parameters.
	</para>
	</section>

	<section id="dialog-clustering" xreflabel="Dialog clustering">
	<title>Dialog clustering</title>
	<para>
	<emphasis role='bold'>Dialog replication</emphasis> is a mechanism used to
	mirror all dialog changes taking place in one OpenSIPS instance to one or
	multiple other instances. The process is simplified by using the
	<emphasis>clusterer</emphasis> module which facilitates the management of a
	cluster of OpenSIPS nodes and the sending of replication-related BIN packets
	(binary-encoded, using <emphasis>proto_bin</emphasis>). This feature
	is useful in achieving High Availability and/or Load Balancing for ongoing calls.
	</para>
	<para>
	Configuring both receival and sending of dialog replication packets is trivial
	and can be done by using the
	<emphasis role='bold'>dialog_replication_cluster</emphasis> parameter. But in
	addition to just sharing data, in order to properly cluster dialogs you will
	need to manage which node in the cluster is doing certain actions on certain
	dialogs using the <emphasis role='bold'>sharing tags</emphasis> mechanism.
	For details and configuration examples on how this would work
	in different usage scenarios, see 
	<ulink url="https://blog.opensips.org/2018/03/23/clustering-ongoing-calls-with-opensips-2-4/">this article</ulink>.
	</para>
	<para>
	The following actions will <emphasis role='bold'>not</emphasis> be performed for a dialog
	marked with a sharing tag that is in the "<emphasis role='bold'>backup</emphasis>" state:
	<itemizedlist>
		<listitem><para>sending Re-Invite or OPTIONS pings to end-points</para></listitem>
		<listitem><para>generating BYE requests or any other actions(like producing CDRs)
			upon dialog expiration</para></listitem>
		<listitem><para>sending replication packets on dialog events(update, delete)</para></listitem>
		<listitem><para>counting the dialog in the profiles that it belongs; only if profile replication
			is also enabled</para></listitem>
	</itemizedlist>
	</para>
	<para>
	In addition to the event-driven replication, an OpenSIPS instance will first
	try to learn all the dialog information from antoher node in the cluster at startup.
	The data synchronization mechanism requires defining one of the nodes in the cluster
	as a "<emphasis role='bold'>seed</emphasis>" node.
	See the <ulink url="https://opensips.org/docs/modules/3.0.x/clusterer.html#capabilities">clusterer</ulink> 
	module for details on how to do this and why is it needed.
	</para>
	<para>
	In the context of dialog replication, using a database as a failsafe for obtaining
	restart persistency for dialog data is useful in case all nodes in the cluster are down.
	This approach makes the most sense if a separate, local DB is used for each node in the
	cluster. Dialogs loaded from the database at startup, which are not reconfirmed through
	syncing, are dropped and also deleted from the database once the sync from cluster is complete.
	</para>
	<para>
	Also configuring profile replication via the <emphasis>profile_replication_cluster</emphasis>
	parameter is not necessary when dialog replication is already configured. The profile information
	is included in the dialog updates sent in the dialog replication cluster. The profiles must still
	be marked for sharing though in the <emphasis>profiles_with_value</emphasis> or
	<emphasis>profiles_no_value</emphasis> parameters.
	</para>
	<para>
	A scenario were both profile and dialog replication should be configured is when a platform has
	multiple POPs, where separate dialog replication clusters are configured for HA purposes, and a
	cluster for globally shared profiles is also required. In this case, proper counting for dialogs
	is ensured by using the sharing tags mechanism(in order to avoid counting each dialog twice,
	both on the active and backup node for that dialog).
	</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>TM</emphasis> - Transaction module
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>RR</emphasis> - Record-Route module, optional, 
				if Dialog ID matching is used in non Topo Hiding cases
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>clusterer</emphasis> - if <emphasis>replication_cluster</emphasis>
				parameter is set (contact replication via clusterer
				module)
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>


	<section>
		<title>External Libraries or Applications</title>
		<para>
		The following libraries or applications must be installed before
		running &osips; with this module loaded:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>None</emphasis>.
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>
	</section>


	<section id="exported_parameters" xreflabel="Exported Parameters">
	<title>Exported Parameters</title>
	<section id="param_enable_stats" xreflabel="enable_stats">
		<title><varname>enable_stats</varname> (integer)</title>
		<para>
		If the statistics support should be enabled or not. Via statistic
		variables, the module provide information about the dialog processing.
		Set it to zero to disable or to non-zero to enable it.
		</para>
		<para>
		<emphasis>
			Default value is <quote>1 (enabled)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>enable_stats</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "enable_stats", 0)
...
</programlisting>
		</example>
	</section>

	<section id="param_hash_size" xreflabel="hash_size">
		<title><varname>hash_size</varname> (integer)</title>
		<para>
		The size of the hash table internally used to keep the dialogs. A
		larger table is much faster but consumes more memory. The hash size
		must be a power of 2 number.
		</para>
		<para>
		IMPORTANT: If dialogs' information should be stored in a database,
		a constant hash_size should be used, otherwise the restored process
		will not take place. If you really want to modify the hash_size you
		must delete all table's rows before restarting &osips;.
		</para>
		<para>
		<emphasis>
			Default value is <quote>4096</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>hash_size</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "hash_size", 1024)
...
</programlisting>
		</example>
	</section>

	<section id="param_log_profile_hash_size" xreflabel="log_profile_hash_size">
		<title><varname>log_profile_hash_size</varname> (integer)</title>
		<para>
		The size of the hash table internally used to store  profile->dialog
		associations. A larger table can provide more
		parallel operations but consumes more memory. The hash size
		is provided as the base 2 logarithm(e.g. log_profile_hash_size =4
		means the table has 2^4 entries).
		</para>

		<para>
		<emphasis>
			Default value is <quote>4</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>hash_size</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "log_profile_hash_size", 5) #set a table size of 32
...
</programlisting>
		</example>
	</section>

	<section id="param_rr_param" xreflabel="rr_param">
		<title><varname>rr_param</varname> (string)</title>
		<para>
		Name of the Record-Route parameter to be added with the dialog cookie.
		It is used for fast dialog matching of the sequential requests.
		</para>
		<para>
		<emphasis>
			Default value is <quote>did</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>rr_param</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "rr_param", "xyz")
...
</programlisting>
		</example>
	</section>

	<section id="param_default_timeout" xreflabel="default_timeout">
		<title><varname>default_timeout</varname> (integer)</title>
		<para>
		The default dialog timeout (in seconds) if no custom one is set.
		</para>
		<para>
		<emphasis>
			Default value is <quote>43200 (12 hours)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>default_timeout</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "default_timeout", 21600)
...
</programlisting>
		</example>
	</section>

	<section id="param_dlg_extra_hdrs" xreflabel="dlg_extra_hdrs">
		<title><varname>dlg_extra_hdrs</varname> (string)</title>
		<para>
		A string containing the extra headers (full format, with EOH)
		to be added in the requests generated by the module (like BYEs).
		</para>
		<para>
		<emphasis>
			Default value is <quote>NULL</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>dlf_extra_hdrs</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "dlg_extra_hdrs", "Hint: credit expired\r\n")
...
</programlisting>
		</example>
	</section>

	<section id="param_dlg_match_mode" xreflabel="dlg_match_mode">
		<title><varname>dlg_match_mode</varname> (integer)</title>
		<para>
		How the seqential requests should be matched against the known dialogs.
		The modes are a combination between matching based on a cookie (DID)
		stored as cookie in Record-Route header and the matching based on SIP
		elements (as in RFC3261).
		</para>
		<para>
		The supported modes are:
		</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>0 - DID_ONLY</emphasis> - the match is done
				exclusively based on DID;
			</para></listitem>
			<listitem><para>
				<emphasis>1 - DID_FALLBACK</emphasis> - the match is first
				tried based on DID and if not present, it will fallback to
				SIP matching;
			</para></listitem>
			<listitem><para>
				<emphasis>2 - DID_NONE</emphasis> - the match is done
				exclusively based on SIP elements; no DID information is added
				in RR.
			</para></listitem>
		</itemizedlist>
		<para>
		<emphasis>
			Default value is <quote>1 (DID_FALLBACK)</quote>.
		</emphasis>
		</para>
		<para>
		NOTE that if you have call looping on your OpenSIPS server (passing
		more than once through the same OpenSIPS instance), it is strongly
		suggested to use only DID_ONLY mode, as the SIP based matching will
		have an undefined behavior - from SIP perspective, a sequential
		dialog will match all the loops of the call, as the Call-ID, To and 
		From TAGs are the same.
		</para>
		<example>
		<title>Set <varname>dlg_match_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "dlg_match_mode", 0)
...
</programlisting>
		</example>
	</section>

<section id="param_delete_delay" xreflabel="delete_delay">
		<title><varname>delete_delay</varname> (integer)</title>
		<para>
			The interval (seconds) to delay a dialog deletion / removal from
			memory AFTER its termination. Once terminated, the dialog will
			be kept in a read only state (no action, no changes), but it will
			still be able to match and route late in-dialog requests.
		</para>
		<para>
			This global value may be per-call changed via the DLG_del_delay
			<quote>$DLG_del_delay</quote> (<xref linkend="pv_DLG_del_delay"/>)
			script variable.
		</para>
		<para>
		<emphasis>
			Default value is <quote>0</quote> (disabled).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>delete_delay</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "delete_delay", 10)
...
</programlisting>
		</example>
	</section>

	<section id="param_db_url" xreflabel="db_url">
		<title><varname>db_url</varname> (string)</title>
		<para>
		If you want to store the information about the dialogs in a database
		a database url must be specified.
		</para>
		<para>
		<emphasis>
			Default value is <quote>&defaultdb;</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_url</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "db_url", "&exampledb;")
...
</programlisting>
		</example>
	</section>

<section id="param_db_mode" xreflabel="db_mode">
		<title><varname>db_mode</varname> (integer)</title>
		<para>
		Describe how to push into the DB the dialogs' information from memory.
		</para>
		<para>
		The supported modes are:
		</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>0 - NO_DB</emphasis> - the memory content is not
				flushed into DB;
			</para></listitem>
			<listitem><para>
				<emphasis>1 - REALTIME</emphasis> - any dialog information
				changes will be reflected into the database immediately.
			</para></listitem>
			<listitem><para>
				<emphasis>2 - DELAYED</emphasis> - the dialog information
				changes will be flushed into the DB periodically, based on a
				timer routine.
			</para></listitem>
			<listitem><para>
				<emphasis>3 - SHUTDOWN</emphasis> - the dialog information
				will be flushed into DB only at shutdown - no runtime updates.
			</para></listitem>
		</itemizedlist>
		<para>
		<emphasis>
			Default value is <quote>0</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "db_mode", 1)
...
</programlisting>
		</example>
	</section>

<section id="param_db_update_period" xreflabel="db_update_period">
		<title><varname>db_update_period</varname> (integer)</title>
		<para>
			The interval (seconds) at which to update dialogs' information if you chose to store the dialogs' info at a given interval.
			A too short interval will generate intensive database operations, a too large one will not notice short dialogs.
		</para>
		<para>
		<emphasis>
			Default value is <quote>60</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_update_period</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "db_update_period", 120)
...
</programlisting>
		</example>
	</section>

<section id="param_options_ping_interval" xreflabel="options_ping_interval">
		<title><varname>options_ping_interval</varname> (integer)</title>
		<para>
		The interval (seconds) at which OpenSIPS will generate in-dialog
		OPTIONS pings for one or both of the involved parties.
		</para>
		<para>
		<emphasis>
			Default value is <quote>30</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>options_ping_interval</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "options_ping_interval", 20)
...
</programlisting>
		</example>
	</section>

<section id="param_reinvite_ping_interval" xreflabel="reinvite_ping_interval">
		<title><varname>reinvite_ping_interval</varname> (integer)</title>
		<para>
		The interval (seconds) at which OpenSIPS will generate in-dialog
		Re-INVITE pings for one or both of the involved parties.
		</para>
		<para>
		<emphasis role='bold'>Important:</emphasis> the ping timeout detection
		is performed every time this interval ticks, not when the re-INVITE
		transaction times out! Consequently, please make sure that the
		timeouts for re-INVITE transactions (e.g. the "fr_timeout"
		modparam of the "tm" module or its $T_fr_timeout variable) are
		always <emphasis role='bold'>lower</emphasis> than the value of this
		parameter! Failing to ensure this ordering of timeouts may possibly
		lead to re-INVITE pings never ending a disconnected dialog due to pings
		getting retried before getting a chance to properly time out.
		</para>
		<para>
		<emphasis>
			Default value is <quote>300</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>reinvite_ping_interval</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "reinvite_ping_interval", 600)
...
</programlisting>
		</example>
	</section>

	<section id="param_table_name" xreflabel="table_name">
		<title><varname>table_name</varname> (string)</title>
		<para>
		If you want to store the information about the dialogs in a
		database a table name must be specified.
		</para>
		<para>
		<emphasis>
			Default value is <quote>dialog</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>table_name</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "table_name", "my_dialog")
...
</programlisting>
		</example>
	</section>

	<section id="param_call_id_column" xreflabel="call_id_column">
		<title><varname>call_id_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' callid.
		</para>
		<para>
		<emphasis>
			Default value is <quote>callid</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>call_id_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "call_id_column", "callid_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_from_uri_column" xreflabel="from_uri_column">
		<title><varname>from_uri_column</varname> (string)</title>
		<para>
			The column's name in the database to store the caller's
			sip address.
		</para>
		<para>
		<emphasis>
			Default value is <quote>from_uri</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>from_uri_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "from_uri_column", "from_uri_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_from_tag_column" xreflabel="from_tag_column">
		<title><varname>from_tag_column</varname> (string)</title>
		<para>
			The column's name in the database to store the From tag from
			the Invite request.
		</para>
		<para>
		<emphasis>
			Default value is <quote>from_tag</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>from_tag_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "from_tag_column", "from_tag_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_to_uri_column" xreflabel="to_uri_column">
		<title><varname>to_uri_column</varname> (string)</title>
		<para>
			The column's name in the database to store the calee's sip address.
		</para>
		<para>
		<emphasis>
			Default value is <quote>to_uri</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>to_uri_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "to_uri_column", "to_uri_c_name")
...
</programlisting>
		</example>
	</section>


	<section id="param_to_tag_column" xreflabel="to_tag_column">
		<title><varname>to_tag_column</varname> (string)</title>
		<para>
			The column's name in the database to store the To tag from
			the 200 OK response to the Invite request, if present.
		</para>
		<para>
		<emphasis>
			Default value is <quote>to_tag</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>to_tag_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "to_tag_column", "to_tag_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_from_cseq_column" xreflabel="from_cseq_column">
		<title><varname>from_cseq_column</varname> (string)</title>
		<para>
			The column's name in the database to store the cseq from caller
			side.
		</para>
		<para>
		<emphasis>
			Default value is <quote>caller_cseq</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>from_cseq_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "from_cseq_column", "from_cseq_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_to_cseq_column" xreflabel="to_cseq_column">
		<title><varname>to_cseq_column</varname> (string)</title>
		<para>
			The column's name in the database to store the cseq from callee
			side.
		</para>
		<para>
		<emphasis>
			Default value is <quote>callee_cseq</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>to_cseq_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "to_cseq_column", "to_cseq_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_from_route_column" xreflabel="from_route_column">
		<title><varname>from_route_column</varname> (string)</title>
		<para>
			The column's name in the database to store the route records from
			caller side (proxy to caller).
		</para>
		<para>
		<emphasis>
			Default value is <quote>caller_route_set</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>from_route_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "from_route_column", "from_route_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_to_route_column" xreflabel="to_route_column">
		<title><varname>to_route_column</varname> (string)</title>
		<para>
			The column's name in the database to store the route records from
			callee side (proxy to callee).
		</para>
		<para>
		<emphasis>
			Default value is <quote>callee_route_set</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>to_route_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "to_route_column", "to_route_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_from_contact_column" xreflabel="from_contact_column">
		<title><varname>from_contact_column</varname> (string)</title>
		<para>
			The column's name in the database to store the caller's contact
			uri.
		</para>
		<para>
		<emphasis>
			Default value is <quote>caller_contact</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>from_contact_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "from_contact_column", "from_contact_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_to_contact_column" xreflabel="to_contact_column">
		<title><varname>to_contact_column</varname> (string)</title>
		<para>
			The column's name in the database to store the callee's contact
			uri.
		</para>
		<para>
		<emphasis>
			Default value is <quote>callee_contact</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>to_contact_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "to_contact_column", "to_contact_c_name")
...
</programlisting>
		</example>
	</section>

<section id="param_from_sock_column" xreflabel="from_sock_column">
		<title><varname>from_sock_column</varname> (string)</title>
		<para>
			The column's name in the database to store the information about
			the local interface receiving the traffic from caller.
		</para>
		<para>
		<emphasis>
			Default value is <quote>caller_sock</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>from_sock_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "from_sock_column", "from_sock_c_name")
...
</programlisting>
		</example>
	</section>

<section id="param_to_sock_column" xreflabel="to_sock_column">
		<title><varname>to_sock_column</varname> (string)</title>
		<para>
			The column's name in the database to store information about the
			local interface receiving the traffic from callee.
		</para>
		<para>
		<emphasis>
			Default value is <quote>callee_sock</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>to_sock_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "to_sock_column", "to_sock_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_dlg_id_column" xreflabel="dlg_id_column">
		<title><varname>dlg_id_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs'
			id information.
		</para>
		<para>
		<emphasis>
			Default value is <quote>dlg_id</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>dlg_id_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "dlg_id_column", "dlg_id_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_state_column" xreflabel="state_column">
		<title><varname>state_column</varname> (string)</title>
		<para>
			The column's name in the database to store the
			dialogs' state information.
		</para>
		<para>
		<emphasis>
			Default value is <quote>state</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>state_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "state_column", "state_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_start_time_column" xreflabel="start_time_column">
		<title><varname>start_time_column</varname> (string)</title>
		<para>
			The column's name in the database to store the
			dialogs' start time information.
		</para>
		<para>
		<emphasis>
			Default value is <quote>start_time</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>start_time_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "start_time_column", "start_time_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_timeout_column" xreflabel="timeout_column">
		<title><varname>timeout_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' timeout.
		</para>
		<para>
		<emphasis>
			Default value is <quote>timeout</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>timeout_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "timeout_column", "timeout_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_profiles_column" xreflabel="profiles_column">
		<title><varname>profiles_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' profiles.
		</para>
		<para>
		<emphasis>
			Default value is <quote>profiles</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profiles_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profiles_column", "profiles_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_vars_column" xreflabel="vars_column">
		<title><varname>vars_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' vars.
		</para>
		<para>
		<emphasis>
			Default value is <quote>vars</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>vars_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "vars_column", "vars_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_sflags_column" xreflabel="sflags_column">
		<title><varname>sflags_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' script flags.
		</para>
		<para>
		<emphasis>
			Default value is <quote>script_flags</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>sflags_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "sflags_column", "sflags_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_mflags_column" xreflabel="mflags_column">
		<title><varname>mflags_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' module flags.
		</para>
		<para>
		<emphasis>
			Default value is <quote>module_flags</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>mflags_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "mflags_column", "mflags_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_flags_column" xreflabel="flags_column">
		<title><varname>flags_column</varname> (string)</title>
		<para>
			The column's name in the database to store the dialogs' flags.
		</para>
		<para>
		<emphasis>
			Default value is <quote>flags</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>flags_column</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "flags_column", "flags_c_name")
...
</programlisting>
		</example>
	</section>

	<section id="param_profiles_with_value" xreflabel="profiles_with_value">
		<title><varname>profiles_with_value</varname> (string)</title>
		<para>
			List of names (alphanumerical/-/_) for profiles with values. Flags
			<emphasis>/b</emphasis> or <emphasis>/s</emphasis> allow sharing
			profiles between &osips; instances using the clusterer module or a
			CacheDB backend, respectively.
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profiles_with_value</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profiles_with_value", "callerCC; gatewayCC; clientChannels/s; codecUsed/b;")
...
</programlisting>
		</example>
	</section>

	<section id="param_profiles_no_value" xreflabel="profiles_no_value">
		<title><varname>profiles_no_value</varname> (string)</title>
		<para>
			List of names (alphanumerical/-/_) for profiles without values. Flags
			<emphasis>/b</emphasis> or <emphasis>/s</emphasis> allow sharing
			profiles between &osips; instances using the clusterer module or a
			CacheDB backend, respectively.
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profiles_no_value</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profiles_no_value", "inbound ; outbound ; shared/s; repl/b;")
...
</programlisting>
		</example>
	</section>

	<section id="param_db_flush_vals_profiles" xreflabel="db_flush_vals_profiles">
		<title><varname>db_flush_vals_profiles</varname> (int)</title>
		<para>
			Pushes dialog values, profiles and flags into the database
			along with other dialog state information (see db_mode 1 and 2).
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>db_flush_vals_profiles</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "db_flush_vals_profiles", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_timer_bulk_del_no" xreflabel="timer_bulk_del_no">
		<title><varname>timer_bulk_del_no</varname> (int)</title>
		<para>
			The number of dialogs that should be attempted to be
			deleted at the same time ( a single query ) from the
			DB back-end.
		</para>
		<para>
		<emphasis>
			Default value is <quote>1</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>timer_bulk_del_no</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "timer_bulk_del_no", 10)
...
</programlisting>
		</example>
	</section>

	<section id="race_condition_timeout" xreflabel="race_condition_timeout">
		<title><varname>race_condition_timeout</varname> (int)</title>
		<para>
		If dialog is created using the 'E' flag, and a SIP Race condition happens, then the dialog will be terminated after 'race_condition_timeout' seconds.
		Currently, the only supported race conditions are (200OK vs CANCEL) and (early BYE vs 200OK)
		</para>
		<para>
		<emphasis>
			Default value is <quote>5</quote> seconds.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>race_condition_timeout</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "race_condition_timeout", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_cachedb_url" xreflabel="cachedb_url">
		<title><varname>cachedb_url</varname> (string)</title>
		<para>
			Enables distributed dialog profiles and specifies the
			backend that should be used by the CacheDB interface.
		</para>
		<para>
		<emphasis>
			Default value is <quote>empty</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>cachedb_url</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "cachedb_url", "redis://127.0.0.1:6379")
...
</programlisting>
		</example>
	</section>

	<section id="param_profile_value_prefix" xreflabel="profile_value_prefix">
		<title><varname>profile_value_prefix</varname> (string)</title>
		<para>
			Specifies what prefix should be added to the profiles with
			value when they are inserted into CacheDB backed. This is
			only used when distributed profiles are enabled.
		</para>
		<para>
		<emphasis>
			Default value is <quote>dlg_val_</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profile_value_prefix</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profile_value_prefix", "dlgv_")
...
</programlisting>
		</example>
	</section>

	<section id="param_profile_no_value_prefix" xreflabel="profile_no_value_prefix">
		<title><varname>profile_no_value_prefix</varname> (string)</title>
		<para>
			Specifies what prefix should be added to the profiles without
			value when they are inserted into CacheDB backed. This is
			only used when distributed profiles are enabled.
		</para>
		<para>
		<emphasis>
			Default value is <quote>dlg_noval_</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profile_no_value_prefix</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profile_no_value_prefix", "dlgnv_")
...
</programlisting>
		</example>
	</section>

	<section id="param_profile_size_prefix" xreflabel="profile_size_prefix">
		<title><varname>profile_size_prefix</varname> (string)</title>
		<para>
			Specifies what prefix should be added to the entity that holds
			the profiles with value size in CacheDB backed. This is
			only used when distributed profiles are enabled.
		</para>
		<para>
		<emphasis>
			Default value is <quote>dlg_size_</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profile_size_prefix</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profile_size_prefix", "dlgs_")
...
</programlisting>
		</example>
	</section>

	<section id="param_profile_timeout" xreflabel="profile_timeout">
		<title><varname>profile_timeout</varname> (int)</title>
		<para>
			Specifies how long a dialog profile should be kept in the CacheDB
			until it expires. This is only used when distributed profiles are
			enabled.
		</para>
		<para>
		<emphasis>
			Default value is <quote>86400</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profile_timeout</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profile_timeout", "43200")
...
</programlisting>
		</example>
	</section>

	<section id="param_dialog_replication_cluster" xreflabel="dialog_replication_cluster">
		<title><varname>dialog_replication_cluster</varname> (int)</title>
		<para>
			Specifies the cluster ID for dialog replication using the
			<emphasis>clusterer</emphasis> module. This enables sending
			and receiving all the dialog-related events (creation, update and
			deletion) in the cluster.
		</para>

			&clusterer_sync_cap_para;

		<para>
		<emphasis>
			Default value is <quote>0</quote> (no replication).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>dialog_replication_cluster</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "dialog_replication_cluster", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_profile_replication_cluster" xreflabel="profile_replication_cluster">
		<title><varname>profile_replication_cluster</varname> (int)</title>
		<para>
			Specifies the cluster ID for profile replication using the
			<emphasis>clusterer</emphasis> module. This enables sending
			and receiving the profile information (value, dialog count)
			in the cluster.
		</para>
		<para>
		<emphasis>
			Default value is <quote>0</quote> (no replication).
		</emphasis>
		</para>
		<example>
		<title>Set <varname>profile_replication_cluster</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "profile_replication_cluster", 1)
...
</programlisting>
		</example>
	</section>

	<section id="param_replicate_profiles_buffer" xreflabel="replicate_profiles_buffer">
		<title><varname>replicate_profiles_buffer</varname> (string)</title>
		<para>
		Used to specify the length of the buffer used by the binary
		replication, in bytes. Usually this should be big enough to hold
		as much data as possible, but small enough to avoid UDP
		fragmentation. The recommended value is the smallest MTU between
		all the replication instances.
		</para>
		<para>
		<emphasis>
			Default value is 1400 bytes.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>replicate_profiles_buffer</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "replicate_profiles_buffer", 500)
...
</programlisting>
		</example>
	</section>
	<section id="param_replicate_profiles_check" xreflabel="replicate_profiles_check">
		<title><varname>replicate_profiles_check</varname> (string)</title>
		<para>
		Timer in seconds, used to specify how often the module should check
		whether old, replicated profiles values are obsolete and should be removed.
		should replicate its profiles to the other instances.
		</para>
		<para>
		<emphasis>
			Default value is 10 s.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>replicate_profiles_check</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "replicate_profiles_check", 100)
...
</programlisting>
		</example>
	</section>
	<section id="param_replicate_profiles_timer" xreflabel="replicate_profiles_timer">
		<title><varname>replicate_profiles_timer</varname> (string)</title>
		<para>
		Timer in milliseconds, used to specify how often the module
		should replicate its profiles to the other instances.
		</para>
		<para>
		<emphasis>
			Default value is 200 ms.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>replicate_profiles_timer</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "replicate_profiles_timer", 100)
...
</programlisting>
		</example>
	</section>
	<section id="param_replicate_profiles_expire" xreflabel="replicate_profiles_expire">
		<title><varname>replicate_profiles_expire</varname> (string)</title>
		<para>
		Timer in seconds, used to specify when the profiles counters received
		from a different instance should no longer be taken into account.
		This is used to prevent obsolete values, in case an instance stops
		replicating its counters.
		</para>
		<para>
		<emphasis>
			Default value is 10 s.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>replicate_profiles_expire</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "replicate_profiles_expire", 10)
...
</programlisting>
		</example>
	</section>
	<section id="param_cluster_auto_sync" xreflabel="cluster_auto_sync">
		<title><varname>cluster_auto_sync</varname> (string)</title>
		<para>
		Specifies whether to automatically issue a sync request (for dialogs
		marked with a sharing tag in backup state) when a node becomes reachable.
		A value of <emphasis>1</emphasis> means enabled and <emphasis>0</emphasis>
		disabled.
		</para>
		<para><emphasis>
			Default value is 1 (enabled).
		</emphasis></para>
		<example>
		<title>Set <varname>cluster_auto_sync</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("dialog", "cluster_auto_sync", 0)
...
</programlisting>
		</example>
	</section>
	</section>


	<section id="exported_functions" xreflabel="exported_functions">
	<title>Exported Functions</title>

	<section id="func_create_dialog" xreflabel="create_dialog()">
		<title>
		<function moreinfo="none">create_dialog([flags])</function>
		</title>
		<para>
		The function creats the dialog for the currently processed request. The
		request must be an initial request.

		Optionally,the function also receives a string parameter, which specifies
		special behavior to be done for the current dialog. 

		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>flags (string, optional)</emphasis>
				Possible values here are :
				<itemizedlist>
				<listitem><para>
				B - Upon reaching dialog lifetime, BYEs will be triggered
				both ways
				</para></listitem>
				<listitem><para>
				P - Ping caller side with OPTIONS messages, once every
				options_ping_interval seconds
				</para></listitem>
				<listitem><para>
				p - Ping callee side with OPTIONS messages, once every
				options_ping_interval seconds
				</para></listitem>
				<listitem><para>
				R - Ping caller side with RE-INVITE messages, once every
				reinvite_ping_interval seconds
				</para></listitem>
				<listitem><para>
				r - Ping callee side with RE-INVITE messages, once every
				reinvite_ping_interval seconds
				</para></listitem>
				<listitem><para>
				E - Upon detecting a SIP Race condition (see RFC 5407),
				end the call after race_condition_timeout seconds
				</para></listitem>
				</itemizedlist>
				Multiple string flags can be used at the same time,
				ie. passing "BPp" flags will enable all 3 flags.
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: both RE-INVITE and OPTIONS pinging cannot be enabled at the same time
		for a single dialog leg. If both flags ("<emphasis>PR</emphasis>" or
		"<emphasis>pr</emphasis>") are provided only RE-INVITE pinging will be used.
		</para>
		<para>
		The function returns true if the dialog was successfully created or
		if the dialog was previously created.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title><function>create_dialog()</function> usage</title>
		<programlisting format="linespecific">
...
create_dialog();
...
#ping caller
create_dialog("P");
...
#ping caller and callee
create_dialog("Pp");

#bye on timeout
create_dialog("B");
...
</programlisting>
		</example>
	</section>

	<section id="func_match_dialog" xreflabel="match_dialog()">
		<title>
		<function moreinfo="none">match_dialog([dlg_match_mode])</function>
		</title>
		<para>
		This function is to be used to match a sequential (in-dialog) request
		to an ongoing dialog.
		</para>
		<para>
		By default, dialog matching is performed according to the
		<xref linkend="param_dlg_match_mode"/> module parameter. A specific
		matching mode may be enforced by specifying the optional
		"dlg_match_mode" parameter. Possible values for this parameter are
		"DID_ONLY", "DID_FALLBACK" and "DID_NONE".
		</para>
		<para>
		As sequential requests are automatically matched to the dialog when
		doing "loose_route()" from script, this function is intended to:
		(A) control the place in your script where the dialog matching is done
		and (B) to cope with bogus sequential requests that do not have Route
		headers, so they are not handled by loose_route().
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>dlg_match_mode (string, optional)</emphasis>
			</para></listitem>
		</itemizedlist>
		<para>
		The function returns true if a dialog exists for the request.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title><function>match_dialog()</function> usage</title>
		<programlisting format="linespecific">
...
    if (has_totag()) {
        loose_route();

        # example 1: match according to <xref linkend="param_dlg_match_mode"/>
        if ($DLG_status == NULL &amp;&amp; !match_dialog())
            xlog("cannot match request to a dialog\n");

        # example 2: override <xref linkend="param_dlg_match_mode"/>
        if ($DLG_status == NULL &amp;&amp; !match_dialog("DID_FALLBACK"))
            xlog("cannot match request to a dialog\n");
    }
...
</programlisting>
		</example>
	</section>


	<section id="func_validate_dialog" xreflabel="validate_dialog()">
		<title>
		<function moreinfo="none">validate_dialog()</function>
		</title>
		<para>
		The function checks the current received requests against the dialog
		(internal data) it belongs to.
		Performing several tests, the function will help to detect the bogus
		injected in-dialog requests (like malicious BYEs).
		</para>
		<para>
		The performed tests are related to CSEQ sequence checking and routing
		information checking (contact and route set).
		</para>
		<para>
		The function returns true if a dialog exists for the request and if
		the request is valid (according to dialog data). If the request is invalid,
		the following return codes are returned :
		<itemizedlist>
		<listitem>
			<para><emphasis>-1</emphasis> - invalid cseq
			</para>
		</listitem>
		<listitem>
			<para><emphasis>-2</emphasis> - invalid remote target
			</para>
		</listitem>
		<listitem>
			<para><emphasis>-3</emphasis> - invalid route set
			</para>
		</listitem>
		<listitem>
			<para><emphasis>-4</emphasis> - other errors ( parsing, no dlg, etc )
			</para>
		</listitem>
		</itemizedlist>

		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title><function>validate_dialog()</function> usage</title>
		<programlisting format="linespecific">
...
    if (has_totag()) {
        loose_route();
        if ($DLG_status!=NULL &amp;&amp; !validate_dialog() ) {
            xlog(" in-dialog bogus request \n");
        } else {
            xlog(" in-dialog valid request - $DLG_dir !\n");
        }
    }
...
</programlisting>
		</example>
	</section>

	<section id="func_fix_route_dialog" xreflabel="fix_route_dialog()">
		<title>
		<function moreinfo="none">fix_route_dialog()</function>
		</title>
		<para>
			The function forces an in dialog SIP message to contain the ruri, route headers and
			dst_uri, as specified by the internal data of the dialog it belongs to.
			The function will prevent the existence of bogus injected in-dialog
			requests ( like malicious BYEs )
		</para>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title><function>fix_route_dialog()</function> usage</title>
		<programlisting format="linespecific">
...
    if (has_totag()) {
        loose_route();
        if ($DLG_status!=NULL)
            if (!validate_dialog())
                fix_route_dialog();
    }
...
</programlisting>
		</example>
	</section>


	<section id="func_get_dialog_info" xreflabel="get_dialog_info()">
		<title>
		<function moreinfo="none">get_dialog_info(attr,avp,key,key_val,no_dlgs)</function>
		</title>
		<para>
		The function extracts a dialog value from another dialog. It first searches
		through all existing (ongoing) dialogs for all dialogs that have a dialog
		variable named "key" with the value "key_val"
		(so a dialog where $dlg_val(key)=="key_val"). If found, it returns
		the value of the dialog variable "attr" from all the
		founds dialog in the "avp" pseudo-variable, otherwise nothing is written
		in "avp", and a negative error code is returned.
		</para>
		<para>
		NOTE: the function does not require to be called in the context of
		a dialog - you can use it whenever / whereever for searching for other
		dialogs.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>attr (string)</emphasis> - the name of the dialog variable
			(from the found dialog) to be returned;
			</para>
		</listitem>
		<listitem>
			<para><emphasis>avp (var)</emphasis> - an avp where to store the values of
			the "attr" dialog variable.
			Since the function checks through all dialogs, this needs to be an actual
			AVP in order to support pushing values from all matched dialogs.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>key (string)</emphasis> - name of a dialog variable to be
			used a search key (when looking after the target dialog)
			</para>
		</listitem>
		<listitem>
			<para><emphasis>key_val (var)</emphasis> - the value of the dialog
			variable that is used as key in searching the target dialog.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>no_dlgs (var)</emphasis> - the total number of dialogs
			containing the key variable
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from ALL ROUTES.
		</para>
		<example>
		<title><function>get_dialog_info</function> usage</title>
		<programlisting format="linespecific">
...
if ( get_dialog_info("callee",$avp(callee_array),"caller",$fu,$var(dlg_no)) ) {
	xlog("caller $fu has $var(dlg_no) other ongoing calls, talking with :");	
	$var(it) = 0;
	while ($var(it) &lt; $var(dlg_no)) {
		$var(current_callee) = $(avp(callee_array)[$var(it)]);
		xlog(" $var(current_callee) ");
		$var(it) = $var(it) + 1;
	}

	xlog("\n");
}

# create dialog for current call and place the caller and callee attributes
create_dialog();
$dlg_val(caller) = $fu;
$dlg_val(callee) = $ru;
...
</programlisting>
		</example>
	</section>


	<section id="func_get_dialog_vals" xreflabel="get_dialog_vals()">
		<title>
		<function moreinfo="none">get_dialog_vals(names,vals,callid)</function>
		</title>
		<para>
		The function fetches all the dialog variables of another dialog.
		It first searches through all existing (ongoing) dialogs based on the 
		given SIP CallID. If found, it returns all the dialog variables as 
		two parallel arrays of names and values (using the given variables
		"names" and "vals"). As these variables have to hold arrays, they must
		be AVPs.
		</para>
		<para>
		NOTE: the function does not require to be called in the context of
		a dialog - you can use it whenever / whereever for searching for other
		dialogs.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>names (var)</emphasis> - an AVP variable to
			hold all the names of the variables from the found dialog.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>vals (var)</emphasis> - an AVP variable to
			hold all the values of the variables from the found dialog.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>callid (string)</emphasis> - the callid of a dialog
			to be searched (and have the variables fetched).
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from any type of route.
		</para>
		<example>
		<title><function>get_dialog_vals</function> usage</title>
		<programlisting format="linespecific">
...
if ( get_dialog_vals($avp(d_names),$avp(d_vals),$var(callid)) ) {
	xlog("the call $var(callid) has the variables:\n);
	$var(i) = 0;
	while ( $(avp(d_names)[$var(i)])!=NULL ) {
		xlog("var $var(i) is $(avp(d_names)[$var(i)])='$(avp(d_vals)[$var(i)])'\n");
		$var(i) = $var(i) + 1;
	}
}
...
</programlisting>
		</example>
	</section>

	<section id="func_get_dialog_by_val" xreflabel="get_dialogs_by_val()">
		<title>
		<function moreinfo="none">get_dialogs_by_val(name,value,out_avp,out_dlg_no)</function>
		</title>
		<para>
		The function looks up through the whole dialog table for dialogs containing a $dlg_val with the provided name and value, and returns all the $DLG_ctx_json variables for the matched dialogs, storing them in the provided out_avp. The total number of matched dialogs is returned in the out_dlgs_no variable
		</para>
		<para>
		NOTE: the function does not require to be called in the context of
		a dialog - you can use it whenever / whereever for searching for other
		dialogs.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>name (string)</emphasis> - the name of the dialog variable used for the lookup
			</para>
		</listitem>
		<listitem>
			<para><emphasis>value (var)</emphasis> - the value of the above dialog val
			</para>
		</listitem>
		<listitem>
			<para><emphasis>out_avp (var)</emphasis> - the AVP which will be populated will the dialog JSONs for all the matched calls
			</para>
		</listitem>
		<listitem>
			<para><emphasis>dlg_no (var)</emphasis> - the out var which will contain the total number of matched dialogs
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from any type of route.
		</para>
		<example>
		<title><function>get_dialog_vals</function> usage</title>
		<programlisting format="linespecific">
...
if ( get_dialogs_by_val("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) {
	xlog("Caller $fU has $avp(dlg_no) other calls \n);
	$var(i) = 0;
	while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) {
		$json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); 
		# fetch any info for the above call and process it
		$var(i) = $var(i) + 1;
	}
}
...
</programlisting>
		</example>
	</section>

	<section id="func_get_dialog_by_profile" xreflabel="get_dialogs_by_profile()">
		<title>
		<function moreinfo="none">get_dialogs_by_profile(name,value,out_avp,out_dlg_no)</function>
		</title>
		<para>
		The function looks up through the whole dialog table for dialogs configured to be within the provided dialog profile name, and optionally with the provided profile value. The function returns all the $DLG_ctx_json variables for the matched dialogs, storing them in the provided out_avp. The total number of matched dialogs is returned in the out_dlgs_no variable
		</para>
		<para>
		NOTE: the function does not require to be called in the context of
		a dialog - you can use it whenever / whereever for searching for other
		dialogs.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>name (string)</emphasis> - the name of the dialog profile used for the lookup
			</para>
		</listitem>
		<listitem>
			<para><emphasis>value (string)</emphasis> - the value of the above dialog profile ( optional )
			</para>
		</listitem>
		<listitem>
			<para><emphasis>out_avp (var)</emphasis> - the AVP which will be populated will the dialog JSONs for all the matched calls
			</para>
		</listitem>
		<listitem>
			<para><emphasis>dlg_no (var)</emphasis> - the out var which will contain the total number of matched dialogs
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from any type of route.
		</para>
		<example>
		<title><function>get_dialog_vals</function> usage</title>
		<programlisting format="linespecific">
...
if ( get_dialogs_by_profile("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) {
	xlog("Caller $fU has $avp(dlg_no) other calls \n);
	$var(i) = 0;
	while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) {
		$json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); 
		# fetch any info for the above call and process it
		$var(i) = $var(i) + 1;
	}
}
...
</programlisting>
		</example>
	</section>


	<section id="func_load_dialog_ctx" xreflabel="load_dialog_ctx()">
		<title>
		<function moreinfo="none">load_dialog_ctx( dialog [, id_type])</function>
		</title>
		<para>
		The function loads and switches to the context of the given dialog.
		The context of a dialog is given by the dialog flags, variables,
		profiles and any other value/state related to the dialog. By 
		switching to the context of another dialog, you will see at the script
		level, by default, all the data from the new dialog.
		</para>
		<para>
		NOTE: you cannot perform a new load until doing an unload - no nested
		loadings are possible.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>dialog (string)</emphasis> - the identifier of the
			dialog to be loaded, it may be a SIP Call-ID or a Dialog ID.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>id_type (string,optional)</emphasis> - what kind of
			dialog identified was used in the first parameter. It can be
			<emphasis>callid</emphasis> (SIP Call-ID) or 
			<emphasis>did</emphasis> (internal Dialog ID). By default callid
			will be assumed.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from any type of route.
		</para>
		<example>
		<title><function>load_dialog_ctx</function> usage</title>
		<programlisting format="linespecific">
...
if (load_dialog_ctx("$var(callid)")) {
	xlog("The dialog '$var(callid)' already has a duration "
	     "of $DLG_lifetime seconds\n");
	if (is_in_profile("inboundCall"))
		xlog("this dialog is an inbound call\n");
	unload_dialog_ctx();
}
...
</programlisting>
		</example>
	</section>


	<section id="func_unload_dialog_ctx" xreflabel="unload_dialog_ctx()">
		<title>
		<function moreinfo="none">unload_dialog_ctx()</function>
		</title>
		<para>
		The function off-loads the loaded context of another dialog, exposing
		whatever dialog context was present before doing the load.
		</para>
		<para>
		NOTE: you MUST perform from script an explicit unload for each load
		you did, otherwise the loaded dialog will remain hanged for ever.
		</para>
		<para>
		This function can be used from any type of route.
		</para>
		<para>
		For usage example, see the <xref linkend="func_load_dialog_ctx"/>
		</para>
	</section>


	<section id="func_set_dlg_profile" xreflabel="set_dlg_profile()">
		<title>
		<function moreinfo="none">set_dlg_profile(profile, [value], [clear_values])</function>
		</title>
		<para>
		Inserts the current dialog into a profile. Note that if the profile does
		not support values, this will be silently discarded. A dialog may be
		inserted in the same profile multiple times.
		</para>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>profile (string)</emphasis> - name of the profile to be
			added to.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>value (string, optional)</emphasis> - string value to
			define the belonging of the dialog to the profile - note that the
			profile must support values.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>clear_values (boolean, optional)</emphasis> - if set to
				<emphasis>true</emphasis> (1), all values of the profile will be cleared
				before setting the given value.  Default: <emphasis>false</emphasis>.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>set_dlg_profile</function> usage</title>
		<programlisting format="linespecific">
...
set_dlg_profile("inboundCall");

# Set a new value (all other values are kept intact)
set_dlg_profile("caller", $fu);

# Set a new value while removing all previous values
set_dlg_profile("caller", $fu, true);
...
</programlisting>
		</example>
	</section>


	<section id="func_unset_dlg_profile" xreflabel="unset_dlg_profile()">
		<title>
		<function moreinfo="none">unset_dlg_profile(profile, [value])</function>
		</title>
		<para>
		Removes the current dialog from a profile.
		</para>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>profile (string)</emphasis> - name of the profile to be
			removed from.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>value (string, optional)</emphasis> - string value to
			define the belonging of the dialog to the profile - note that the
			profile must support values.
			</para>
			<para>NEW in 3.4: for profiles with value, by omitting this parameter
				you can now clear all values of the given profile.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>unset_dlg_profile</function> usage</title>
		<programlisting format="linespecific">
...
unset_dlg_profile("inboundCall");
unset_dlg_profile("caller", $fu);
...
# Remove all values in a profile
unset_dlg_profile("caller");
...
</programlisting>
		</example>
	</section>


	<section id="func_is_in_profile" xreflabel="is_in_profile()">
		<title>
		<function moreinfo="none">is_in_profile(profile,[value])</function>
		</title>
		<para>
		Checks if the current dialog belongs to a profile. If the profile
		supports values, the check can be reinforced to take into account a
		specific value - if the dialog was inserted into the profile for a
		specific value. If no value is passed, only simply belonging of the
		dialog to the profile is checked. Note that if the profile does not
		support values, this will be silently discarded.
		</para>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>profile (string)</emphasis> - name of the profile to be
			checked against.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>value (string. optional)</emphasis> - string value to
			toughen the check.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>is_in_profile</function> usage</title>
		<programlisting format="linespecific">
...
if (is_in_profile("inboundCall")) {
	log("this request belongs to a inbound call\n");
}
...
if (is_in_profile("caller","XX")) {
	log("this request belongs to a call of user XX\n");
}
...
</programlisting>
		</example>
	</section>

	<section id="func_get_profile_size" xreflabel="get_profile_size()">
		<title>
		<function moreinfo="none">get_profile_size(profile,[value],size)</function>
		</title>
		<para>
		Returns the number of dialogs belonging to a profile. If the profile
		supports values, the check can be reinforced to take into account a
		specific value - how many dialogs were inserted into the profile with
		a specific value. If not value is passed, only simply belonging of the
		dialog to the profile is checked. Note that the profile does not
		supports values, this will be silently discarded.
		</para>
		<para>Meaning of the parameters is as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>profile (string)</emphasis> - name of the profile to get
			the size for.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>value (string, optional)</emphasis> - string value to
			toughen the check.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>size (var)</emphasis> - an AVP or script variable to
			return the profile size in.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>get_profile_size</function> usage</title>
		<programlisting format="linespecific">
modparam("dialog", "profiles_no_value", "inboundCalls")
modparam("dialog", "profiles_with_value", "caller")
...
get_profile_size("inboundCalls",,$var(size));
xlog("inboundCalls: $var(size)\n");
...
get_profile_size("caller", $fu, $var(size));
xlog("currently, the user $fu has $var(size) active outgoing calls\n");
...
</programlisting>
		</example>
	</section>

	<section id="func_set_dlg_flag" xreflabel="set_dlg_flag()">
		<title>
		<function moreinfo="none">set_dlg_flag(flag)</function>
		</title>
		<para>
		Sets the dialog flag named <emphasis>flag</emphasis> to true. The dialog
		flags are dialog persistent and they can be accessed (set and test)
		for all requests belonging to the dialog.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>flag (string, static)</emphasis> - The flag name.
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>set_dlg_flag</function> usage</title>
		<programlisting format="linespecific">
...
set_dlg_flag("MY_DLG_FLAG");
...
</programlisting>
		</example>
	</section>

	<section id="func_test_and_set_dlg_flag" xreflabel="test_and_set_dlg_flag()">
		<title>
		<function moreinfo="none">test_and_set_dlg_flag(flag, value)</function>
		</title>
		<para>
		Atomically checks if the dialog flag named <emphasis>flag</emphasis> is
		equal to <emphasis>value</emphasis>. If true, changes the value with the
		opposite one. This operation is done under the dialog lock.
		</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>flag (string, static)</emphasis> - The flag name.
			</para></listitem>
			<listitem><para>
				<emphasis>value (int)</emphasis> - The value should be 0 (false) or 1 (true).
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>test_and_set_dlg_flag</function> usage</title>
		<programlisting format="linespecific">
...
test_and_set_dlg_flag("MY_DLG_FLAG", 0);
...
</programlisting>
		</example>
	</section>

	<section id="func_reset_dlg_flag" xreflabel="reset_dlg_flag()">
		<title>
		<function moreinfo="none">reset_dlg_flag(flag)</function>
		</title>
		<para>
		Resets the dialog flag named <emphasis>flag</emphasis> to false.
		The dialog flags are dialog persistent and they can be accessed
		(set and test) for all requests belonging to the dialog.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>flag (string, static)</emphasis> - The flag name.
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>reset_dlg_flag</function> usage</title>
		<programlisting format="linespecific">
...
reset_dlg_flag("MY_DLG_FLAG");
...
</programlisting>
		</example>
	</section>

	<section id="func_is_dlg_flag_set" xreflabel="is_dlg_flag_set()">
		<title>
		<function moreinfo="none">is_dlg_flag_set(flag)</function>
		</title>
		<para>
		Returns true if the dialog flag named <emphasis>flag</emphasis> is set.
		The dialog flags are dialog persistent and they can be accessed
		(set and test) for all requests belonging to the dialog.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>flag (string, static)</emphasis> - The flag name.
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>is_dlg_flag_set</function> usage</title>
		<programlisting format="linespecific">
...
if (is_dlg_flag_set("MY_DLG_FLAG")) {
	xlog("dialog flag MY_DLG_FLAG is set\n");
}
...
</programlisting>
		</example>
	</section>

	<section id="func_store_dlg_value" xreflabel="store_dlg_value()">
		<title>
		<function moreinfo="none">store_dlg_value(name,val)</function>
		</title>
		<para>
		Attaches to the dialog the value from the variable <emphasis>val</emphasis>
		under the name <emphasis>name</emphasis>. The values attached to dialogs are
		dialog persistent and they can be accessed (read and write) for all
		requests belonging to the dialog.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>name (string)</emphasis>
			</para></listitem>
			<listitem><para>
				<emphasis>val (var)</emphasis>
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		Same functionality may be obtain by assigning a value to pseudo
		variable <emphasis>$dlg_val(name)</emphasis>.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>store_dlg_value</function> usage</title>
		<programlisting format="linespecific">
...
store_dlg_value("inv_src_ip",$si);
store_dlg_value("account type",$var(account));
# or
$dlg_val(account_type) = "prepaid";
...
</programlisting>
		</example>
	</section>

	<section id="func_fetch_dlg_value" xreflabel="fetch_dlg_value()">
		<title>
		<function moreinfo="none">fetch_dlg_value(name,val)</function>
		</title>
		<para>
		Fetches from the dialog the value of attribute named
		<emphasis>name</emphasis>. The values attached to dialogs are
		dialog persistent and they can be accessed (read and write) for all
		requests belonging to the dialog.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>name (string)</emphasis>
			</para></listitem>
			<listitem><para>
				<emphasis>val (var)</emphasis>
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		Same functionality may be obtain by reading the pseudo
		variable <emphasis>$dlg_val(name)</emphasis>.
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>fetch_dlg_value</function> usage</title>
		<programlisting format="linespecific">
...
fetch_dlg_value("inv_src_ip",$avp(2));
fetch_dlg_value("account type",$var(account));
# or
$var(account) = $dlg_val(account_type);
...
</programlisting>
		</example>
	</section>

	<section id="func_set_dlg_sharing_tag" xreflabel="set_dlg_sharing_tag()">
		<title>
		<function moreinfo="none">set_dlg_sharing_tag(tag_name)</function>
		</title>
		<para>
		Marks the current dialog with the sharing tag <emphasis>tag_name</emphasis>.
		From this point on, actions like in-dialog pinging, BYEs on timeout etc.
		will depend on the tag state(no action in "backup" state, normal operation
		in "active" state).
		</para>
		<para>
		For more details see the <xref linkend="dialog-clustering"/> chapter.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>tag_name (string)</emphasis>
			</para></listitem>
		</itemizedlist>
		<para>
		NOTE: the dialog must be created before using this function (use
		create_dialog() function before).
		</para>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>set_dlg_sharing_tag</function> usage</title>
		<programlisting format="linespecific">
...
set_dlg_sharing_tag("vip1");
...
</programlisting>
		</example>
	</section>

	<section id="func_dlg_on_answer" xreflabel="dlg_on_answer()">
		<title>
		<function moreinfo="none">dlg_on_answer([route_name])</function>
		</title>
		<para>
		The function arms a script route to be executed when the current
		dialog will be later answered. When the route will be executed, the
		dialog context will be exposed, but with no valid SIP message (just
		a phony one).
		</para>
		<para>
		You must use this function AFTER creating the dialog and before the
		dialog being answered.
		</para>
		<para>
		If the parameter is missing, the function does a reset of any route
		previously set; there will be no triggering.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>route_name (string,optional)</emphasis> - the name
				of the script route to be executed.
			</para></listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>dlg_on_answer</function> usage</title>
		<programlisting format="linespecific">
...
create_dialog();
dlg_on_answer("dlg_answered");
...
route[dlg_answered] {
	xlog("The dialog $DLG_did was answered\n");
}
</programlisting>
		</example>
	</section>

	<section id="func_dlg_on_timeout" xreflabel="dlg_on_timeout()">
		<title>
		<function moreinfo="none">dlg_on_timeout([route_name])</function>
		</title>
		<para>
		The function arms a script route to be executed when (and if) the 
		current dialog will timeout (as duration). When the route will be 
		executed, the dialog context will be exposed, but with no valid SIP
		message (just a phony one)
		</para>
		<para>
		When the route is executed, the dialog is not yet terminated, just its
		lifetime reached the set limit. In the timeout route you can increase 
		the dialog expiration timeout (and the dialog will continue) or you
		can let the dialog to be terminated (after the end of this route).
		</para>
		<para>
		You must use this function AFTER creating the dialog and before the
		dialog being answered.
		</para>
		<para>
		You must use this function AFTER creating the dialog and before the
		dialog being answered.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>route_name (string,optional)</emphasis> - the name
				of the script route to be executed.
			</para></listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>dlg_on_timeout</function> usage</title>
		<programlisting format="linespecific">
...
create_dialog();
$DLG_timeout=120;
dlg_on_timeout("dlg_timeout");
...
route[dlg_timeout] {
	xlog("The dialog $DLG_did timed out\n");
	if (_some_prolongation_condition)
		$DLG_timeout = 60; # give it 1 min more
}
</programlisting>
		</example>
	</section>

	<section id="func_dlg_on_hangup" xreflabel="dlg_on_hangup()">
		<title>
		<function moreinfo="none">dlg_on_hangup([route_name])</function>
		</title>
		<para>
		The function arms a script route to be executed when the current
		dialog will be terminated. When the route will be executed, the
		dialog context will be exposed, but with no valid SIP message (just
		a phony one). Note that the dialog will be already terminated and there
		is nothing you can do about it besides reading data from its context.
		</para>
		<para>
		You must use this function AFTER creating the dialog and before the
		dialog being answered.
		<para>
		</para>
		If the parameter is missing, the function does a reset of any route
		previously set; there will be no triggering.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>route_name (string,optional)</emphasis> - the name
				of the script route to be executed.
			</para></listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
			REPLY_ROUTE and FAILURE_ROUTE.
		</para>
		<example>
		<title><function>dlg_on_hangup</function> usage</title>
		<programlisting format="linespecific">
...
create_dialog();
dlg_on_hangup("dlg_hangup");
...
route[dlg_hangup] {
	xlog("The dialog $DLG_did terminated after $DLG_lifetime secs\n");
}
</programlisting>
		</example>
	</section>

	<section id="func_dlg_send_sequential" xreflabel="dlg_send_sequential()">
		<title>
			<function moreinfo="none">dlg_send_sequential(method, leg, [, body] [, content-type] [, headers])</function>
		</title>
		<para>
		Used to send an in-dialog request towards one if the dialog's legs.
		The function assumes that is runs inside a dialog context - if you
		are running it from a different context (such as an event_route),
		make sure you first load the dialog context using the
			<xref linkend="func_load_dialog_ctx"/> function.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para><emphasis>method (string)</emphasis> -
				the method of the request sent.
			</para></listitem>
			<listitem><para><emphasis>leg (string)</emphasis> - the leg
				where the request is sent. Must be either
				<emphasis>caller</emphasis> or <emphasis>callee</emphasis>.
			</para></listitem>
			<listitem><para><emphasis>body (string, optional)</emphasis> - an
				optional body sent in the request. If missing, no body is sent.
			</para></listitem>
			<listitem><para><emphasis>content-type (string, optional)</emphasis> -
				the content type of the body sent. Make sure you specify this
				every time you send a request with a body, otherwise there are high
				changes that your UAC will reject the request.
			</para></listitem>
			<listitem><para><emphasis>headers (string, optional)</emphasis> -
				additional headers attached to the request sent.
			</para></listitem>
		</itemizedlist>
		<para>
		This function can be used from ANY route.
		</para>
		<example>
		<title><function>dlg_send_sequential</function> usage to convert DTMF codes</title>
		<programlisting format="linespecific">
...
event_route[E_RTPPROXY_DTMF] {
    if (load_dialog_ctx("$param(id)", "did")) {
        if ($param(stream) == 0) {
            $var(direction) = "callee";
        } else {
            $var(direction) = "caller";
        }
        dlg_send_sequential($var(direction), "INFO",
                "Signal=$param(digit)\nDuration=160",
                "application/dtmf-relay");
        unload_dialog_ctx();
    }
}
...
</programlisting>
		</example>
	</section>

	</section>


	<section id="exported_statistics">
	<title>Exported Statistics</title>
		<section id="stat_active_dialogs" xreflabel="active_dialogs">
			<title><varname>active_dialogs</varname></title>
			<para>
			Returns the number of current active dialogs (may be confirmed or
			not).
			</para>
		</section>
		<section id="stat_early_dialogs" xreflabel="early_dialogs">
			<title><varname>early_dialogs</varname></title>
			<para>
			Returns the number of early dialogs.
			</para>
		</section>
		<section id="stat_processed_dialogs" xreflabel="processed_dialogs">
			<title><varname>processed_dialogs</varname></title>
			<para>
			Returns the total number of processed dialogs (terminated,
			expired or active) from the startup.
			</para>
		</section>
		<section id="stat_expired_dialogs" xreflabel="expired_dialogs">
			<title><varname>expired_dialogs</varname></title>
			<para>
			Returns the total number of expired dialogs from the startup.
			</para>
		</section>
		<section id="stat_failed_dialogs" xreflabel="failed_dialogs">
			<title><varname>failed_dialogs</varname></title>
			<para>
			Returns the number of failed dialogs ( dialogs were
			never established due to whatever reasons - internal error,
			negative reply, cancelled, etc )
			</para>
		</section>
		<section id="stat_create_sent" xreflabel="create_sent">
			<title><varname>create_sent</varname></title>
			<para>
				Returns the number of replicated dialog
			<emphasis role='bold'>create</emphasis> requests send to other OpenSIPS
			instances.
			</para>
		</section>
		<section id="stat_update_sent" xreflabel="update_sent">
			<title><varname>update_sent</varname></title>
			<para>
				Returns the number of replicated dialog
			<emphasis role='bold'>update</emphasis> requests send to other OpenSIPS
			instances.
			</para>
		</section>
		<section id="stat_delete_sent" xreflabel="delete_sent">
			<title><varname>delete_sent</varname></title>
			<para>
				Returns the number of replicated dialog
			<emphasis role='bold'>delete</emphasis> requests send to other OpenSIPS
			instances.
			</para>
		</section>
		<section id="stat_create_recv" xreflabel="create_recv">
			<title><varname>create_recv</varname></title>
			<para>
				Returns the number of dialog
			<emphasis role='bold'>create</emphasis> events received from other
			OpenSIPS instances.
			</para>
		</section>
		<section id="stat_update_recv" xreflabel="update_recv">
			<title><varname>update_recv</varname></title>
			<para>
				Returns the number of dialog
			<emphasis role='bold'>update</emphasis> events received from other
			OpenSIPS instances.
			</para>
		</section>
		<section id="stat_delete_recv" xreflabel="delete_recv">
			<title><varname>delete_recv</varname></title>
			<para>
				Returns the number of dialog
			<emphasis role='bold'>delete</emphasis> events received from other
			OpenSIPS instances.
			</para>
		</section>
	</section>

	<section id="exported_mi_functions" xreflabel="Exported MI Functions">
	<title>Exported MI Functions</title>

		<section id="mi_dlg_list" xreflabel="dlg_list">
		<title>
		<function moreinfo="none">dlg_list</function>
		</title>
		<para>
		Lists the description of the dialogs (calls). If no parameter is given,
		all dialogs will be listed. If a dialog identifier is passed
		as parameter (callid and fromtag), only that dialog will be listed. If
		a index and conter parameter is passed, it will list only a number of
		"counter" dialogs starting with index (as offset) - this is used to
		get only section of dialogs.
		</para>
		<para>
		Name: <emphasis>dlg_list</emphasis>
		</para>
		<para>Parameters (with dialog idetification):</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>callid</emphasis> (optional) - callid if a single
				dialog to be listed.
			</para></listitem>
			<listitem><para>
				<emphasis>from_tag</emphasis> (optional, but cannot be present
				without the callid parameter) - fromtag (as per initial request)
				of the dialog to be listed.
				entry
			</para></listitem>
		</itemizedlist>
		<para>Parameters (with dialog counting):</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>index</emphasis> - offset where the dialog listing
				should start.
			</para></listitem>
			<listitem><para>
				<emphasis>counter</emphasis> - how many dialogs should be
				listed (starting from the offset)
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		## list all ongoing dialogs
		opensips-cli -x mi dlg_list
		## list the dialog by callid and From TAG
		opensips-cli -x mi dlg_list callid=abcdrssfrs122444@192.168.1.1 from_tag=AAdfeEFF33
		## list 10 dialogs, starting from the position 40
		## (in the list of all ongoing dialogs)
		opensips-cli -x mi dlg_list index=40 counter=10
		</programlisting>
		</section>

		<section id="mi_dlg_list_ctx" xreflabel="dlg_list_ctx">
		<title><function moreinfo="none">dlg_list_ctx</function></title>
		<para>
		The same as the <quote>dlg_list</quote> but including in the
		dialog description
		the associated context from modules sitting on top of
		the dialog module.
		This function also prints the dialog's values. In case of
		binary values, the non-printable chars are represented in hex
		(e.g. \x00)
		</para>
		<para>
		Name: <emphasis>dlg_list_ctx</emphasis>
		</para>
		<para>Parameters: <emphasis>see <quote>dlg_list</quote></emphasis>
		</para>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi dlg_list_ctx
		</programlisting>
		</section>

		<section id='mi_dlg_end_dlg' xreflabel="dlg_end_dlg">
			<title><function moreinfo="none">dlg_end_dlg</function></title>
			<para>
				Terminates an ongoing dialog.
				If dialog is established, BYEs are sent in both directions.
				If dialog is in unconfirmed or early state, a CANCEL will be
				sent to the callee side, that will trigger a 487 from the
				callee, which, when relayed, will also end the dialog on 
				the caller's side.
			</para>
		<para>
		Name: <emphasis>dlg_end_dlg</emphasis>
		</para>
		<para>Parameters are:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>dialog_id</emphasis> - this is an identifier
				of the dialog - it can be either (1) the unique ID 
				of the dialog (as provided by dlg_list), either (2) the 
				SIP Call-ID of the dialog.
			</para></listitem>
			<listitem><para>
				<emphasis>extra_hdrs</emphasis> - (optional) string containg
				the extra headers (full format) to be added to the BYE
				requests.
			</para></listitem>
		</itemizedlist>
		<para>
		The "dialog_id" value can be get via the "dlg_list" MI command.
		</para>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		# terminate the dialog via the internal Dialog-ID
		opensips-cli -x mi dlg_end_dlg 6ae.4b38d013
		# terminate the dialog via its SIP Call-ID
		opensips-cli -x mi dlg_end_dlg Y2IwYjQ2YmE2ZDg5MWVkNDNkZGIwZjAzNGM1ZDY
		</programlisting>
		</section>

		<section id="mi_profile_get_size" xreflabel="profile_get_size">
		<title><function moreinfo="none">profile_get_size</function></title>
		<para>
		Returns the number of dialogs belonging to a profile. If the profile
		supports values, the check can be reinforced to take into account a
		specific value - how many dialogs were inserted into the profile with
		a specific value. If not value is passed, only simply belonging of the
		dialog to the profile is checked. Note that the profile does not
		supports values, this will be silently discarded.
		</para>
		<para>
		Name: <emphasis>profile_get_size</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>profile</emphasis> - name of the profile to get the
				value for.
			</para></listitem>
			<listitem><para>
				<emphasis>value</emphasis> (optional)- string value to
				toughen the check;
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi profile_get_size inboundCalls
		</programlisting>
		</section>

		<section id="mi_profile_list_dlgs" xreflabel="profile_list_dlgs">
		<title><function moreinfo="none">profile_list_dlgs</function></title>
		<para>
		Lists all the dialogs belonging to a profile. If the profile
		supports values, the check can be reinforced to take into account a
		specific value - list only the dialogs that were inserted into the
		profile with that specific value. If not value is passed, all dialogs
		belonging to the profile will be listed. Note that the profile does
		not supports values, this will be silently discarded. Also, when using
		shared profiles using the CacheDB interface, this command will only
		display the local dialogs.
		</para>
		<para>
		Name: <emphasis>profile_list_dlgs</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>profile</emphasis> - name of the profile to list the
				dialog for.
			</para></listitem>
			<listitem><para>
				<emphasis>value</emphasis> (optional)- string value to
				toughen the check;
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi profile_list_dlgs inboundCalls
		</programlisting>
		</section>

		<section id="mi_profile_get_values" xreflabel="profile_get_values">
		<title><function moreinfo="none">profile_get_values</function></title>
		<para>
		Lists all the values belonging to a profile along with their
		count. If the profile does not support values a total count
		will be returned. Note that this function does not work for shared
		profiles over the CacheDB interface.
		</para>
		<para>
		Name: <emphasis>profile_get_values</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>profile</emphasis> - name of the profile to list the
				dialog for.
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi profile_get_values inboundCalls
		</programlisting>
		</section>
		<section id="mi_profile_end_dlgs" xreflabel="profile_end_dlgs">
		<title><function moreinfo="none">profile_end_dlgs</function></title>
		<para>
		Terminate all ongoing dialogs from a specified profile, on a single dialog it
		performs the same operations as the command <emphasis role='bold'><xref linkend="mi_dlg_end_dlg"/></emphasis>
		</para>
		<para>
		Name: <emphasis>profile_end_dlgs</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>profile</emphasis> - name of the profile that will have its dialogs termianted
			</para></listitem>
			<listitem><para>
				<emphasis>value</emphasis> - (optional) if the profile supports values terminate only the dialogs
				with the specified value
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi profile_end_dlgs inboundCalls
		</programlisting>
		</section>
		<section id="mi_dlg_db_sync" xreflabel="dlg_db_sync">
		<title><function moreinfo="none">dlg_db_sync</function></title>
		<para>
		Will load all the information about the dialogs from the database
		in the OpenSIPS internal memory. If a dialog is already found in memory
		and has the same/an older state, it will be updated with the values from
		DB. Otherwise, the newer in-memory version will not be changed.
		</para>
		<para>
		Name: <emphasis>dlg_db_sync</emphasis>
		</para>
		<para>It takes no parameters</para>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi dlg_db_sync
		</programlisting>
		</section>

		<section id="mi_dlg_cluster_sync" xreflabel="dlg_cluster_sync">
		<title><function moreinfo="none">dlg_cluster_sync</function></title>
		<para>
		This command will only take effect if dialog replication is enabled.
		</para>
		<para>
		Fully synchronize the dialog information in memory from a suitable donor
		node within the <xref linkend="param_dialog_replication_cluster"/>. Dialogs
		that already exist in memory which are not reconfirmed through syncing will
		be discarded. A sharing tag can be specified in order to sync only dialogs
		marked with that sharing tag.
		</para>
		<para>
		Name: <emphasis>dlg_cluster_sync</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>sharing_tag</emphasis> - name of the sharing tag that
				dialogs have to be marked with in order to be synced
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi dlg_cluster_sync vip1
		</programlisting>
		</section>

		<section id="mi_dlg_restore_db" xreflabel="dlg_restore_db">
		<title><function moreinfo="none">dlg_restore_db</function></title>
		<para>
		Restores the dialog table after a potential desynchronization event.
		The table is truncated, then populated with CONFIRMED dialogs from memory.
		</para>
		<para>
		Name: <emphasis>dlg_restore_db</emphasis>
		</para>
		<para>It takes no parameters</para>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi dlg_restore_db
		</programlisting>
		</section>

		<section id="mi_list_all_profiles" xreflabel="list_all_profiles">
		<title><function moreinfo="none">list_all_profiles</function></title>
		<para>
		Lists all the dialog profiles, along with 1 or 0 if
		the given profile has/does not have an associated value.
		</para>
		<para>
		Name: <emphasis>list_all_profiles</emphasis>
		</para>
		<para>Parameters: <emphasis>It takes no parameters</emphasis>
		</para>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi list_all_profiles
		</programlisting>
		</section>

		<section id="dlg_push_var" xreflabel="dlg_push_var">
		<title><function moreinfo="none">dlg_push_var</function></title>
		<para>
		Push or update a dialog value for the given list of dialog IDs / Call-IDs.
		</para>
		<para>
		Name: <emphasis>dlg_push_var</emphasis>
		</para>
		<para>Parameters: <emphasis>It takes 3 or more parameters</emphasis>
		</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>dlg_val_name</emphasis> - name of the dialog value that needs to be inserted/updated
			</para></listitem>
			<listitem><para>
				<emphasis>dlg_val_value</emphasis> - value to be inserted/updated
			</para></listitem>
			<listitem><para>
				<emphasis>DID</emphasis> - dialog identifier. Can be either the $DLG_did or the actual Call-ID. 
			</para></listitem>
		</itemizedlist>
		<para>
		MI FIFO Command Format:
		</para>
		<programlisting  format="linespecific">
		opensips-cli -x mi dlg_push_var var_name var_value DID1 [ DID2 DID3 ...  DIDN ]
		</programlisting>
		</section>

		<section id="mi_dlg_send_sequential" xreflabel="dlg_send_sequential">
		<title><function moreinfo="none">dlg_send_sequential</function></title>
		<para>
		Sends a sequential request within an ongoing dialog.
		</para>
		<para>
		Name: <emphasis>dlg_send_sequential</emphasis>
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
				<emphasis>callid</emphasis> - the callid of the dialog you need to trigger
					the sequential message for.
			</para></listitem>
			<listitem><para>
				<emphasis>method</emphasis> - (optional) the method used for the sequential
					message. Default value is <emphasis>INVITE</emphasis>.
			</para></listitem>
			<listitem><para>
				<emphasis>mode</emphasis> - (optional) can be used to tune the behavior of
					the sequential message. Possible values for the <emphasis>mode</emphasis> are:
				<itemizedlist>
					<listitem><para>
					<emphasis>caller</emphasis> - (default) sends the sequential message
						to the caller. This mode can be useful in high availability scenarios
						when you want to update the upstream's routing set, specifically the contact.
					</para></listitem>
					<listitem><para>
						<emphasis>callee</emphasis> - same as caller, but sends the sequential
							message to the callee.
					</para></listitem>
					<listitem><para>
						<emphasis>challenge</emphasis> - sends a sequential INVITE (or UPDATE)
						to the caller to challenge it for its advertised SDP body. When the
						body is received, it is forwarded to the callee. This mode is useful
						when trying to change both endpoints (upstream and downstream) routing
						set. It can also be useful when trying to trigger a re-negotiation for
						SDP body.
					</para></listitem>
					<listitem><para>
						<emphasis>challenge-caller</emphasis> - same as <emphasis>challenge</emphasis>
					</para></listitem>
					<listitem><para>
						<emphasis>challenge-callee</emphasis> - same as
							<emphasis>challenge-caller</emphasis>, only that it first challenges
							the callee, instead of the caller.
					</para></listitem>
				</itemizedlist>
			</para></listitem>
			<listitem><para>
				<emphasis>body</emphasis> - (optional) can be used to specify a body for
					the initial sequential message. Possible values for the <emphasis>body</emphasis>
					parameter are:
				<itemizedlist>
					<listitem><para>
						<emphasis>none</emphasis> - (default) no body added to the sequential message.
					</para></listitem>
					<listitem><para>
						<emphasis>inbound</emphasis> - advertises in the body of the sequential
							message generated the last body received from its pair. For example,
							if the <emphasis>mode=challenge-caller</emphasis>, the message will
							contain the body sent to &osips; by the callee. This is useful when
							you need to alter the body previously sent to the caller, because you
							want to re-negotiate a different media proxy for the call. This can
							be achieved by catching the generated request in
							<emphasis>local_route</emphasis>, and re-engage the Media proxy.
					</para></listitem>
					<listitem><para>
						<emphasis>outbound</emphasis> - advertises in the body of the sequential
							message generated the last body sent to that UAC. For example,
							if the <emphasis>mode=challenge-caller</emphasis>, the message will
							contain the last body sent by &osips; to the caller. This is useful
							in a high availability scenario when trying to re-negotiate the
							contact of the server, but there is no need to alter the body sent
							earlier.
					</para></listitem>
					<listitem><para>
							<emphasis>custom:CONTENT_TYPE:BODY</emphasis> - this can be used to
								specify a specific Content-Type ehader and body for the
								sequential message generated.
					</para></listitem>
				</itemizedlist>
			</para></listitem>
			<listitem><para>
				<emphasis>headers</emphasis> - (optional) can be used to specify some headers for
					the initial sequential message.
			</para></listitem>
		</itemizedlist>
		<para>
			This functions runs asynchronously and returns the status code and reason
			of the last reply received for either the <emphasis>challenge</emphasis> or normal mode.
		</para>
		<para>
		MI Command Format:
		</para>
		<programlisting  format="linespecific">
			opensips-cli -x mi dlg_send_sequential \
				callid=5291231-testing@127.0.0.1
		</programlisting>

		<para>
		MI Command used to trigger media re-negotiation:
		</para>
		<programlisting  format="linespecific">
			opensips-cli -x mi dlg_send_sequential \
				callid=5291231-testing@127.0.0.1 \
				mode=challenge \
				body=inbound
		</programlisting>

		<para>
		MI Command used to UPDATE the callee's remote Contact after a server failover:
		</para>
		<programlisting  format="linespecific">
			opensips-cli -x mi dlg_send_sequential \
				callid=5291231-testing@127.0.0.1 \
				mode=challenge-callee \
				body=outbound \
				method=UPDATE
		</programlisting>

		<para>
		MI Command used to send REFER to the callee, and add Refer-To header:
		</para>
		<programlisting  format="linespecific">
			opensips-cli -x mi dlg_send_sequential \
				callid=usR8FlGOSMfCTAIHebHCOQ.. \
				method=REFER \
				body=none \
				mode=callee \
				headers='Refer-To: sip:user@domain:50060'
		</programlisting>

		</section>
	</section>

	<section id="exported_pseudo_variables">
	<title>Exported Pseudo-Variables</title>
		<section id="pv_DLG_count" xreflabel="$DLG_count">
			<title><varname>$DLG_count</varname></title>
			<para>
			Returns the number of current active dialogs (may be confirmed or
			not).
			</para>
		</section>

		<section id="pv_DLG_status" xreflabel="$DLG_status">
			<title><varname>$DLG_status</varname></title>
			<para>
			Returns the status of the dialog corresponding to the processed
			sequential request. This PV will be available only for sequential
			requests, after doing loose_route().
			</para>
			<para>
			Value may be:
			</para>
			<itemizedlist>
				<listitem><para>
					<emphasis>NULL</emphasis> - Dialog not found.
				</para></listitem>
				<listitem><para>
					<emphasis>1</emphasis> - Dialog unconfirmed (created
					but no reply received at all)
				</para></listitem>
				<listitem><para>
					<emphasis>2</emphasis> - Dialog in early state (created
					provisional reply received, but no final reply received
					yet)
				</para></listitem>
				<listitem><para>
					<emphasis>3</emphasis> - Confirmed by a final reply but
					no ACK received yet.
				</para></listitem>
				<listitem><para>
					<emphasis>4</emphasis> - Confirmed by a final reply and
					ACK received.
				</para></listitem>
				<listitem><para>
					<emphasis>5</emphasis> - Dialog ended.
				</para></listitem>
			</itemizedlist>
		</section>

		<section id="pv_DLG_lifetime" xreflabel="$DLG_lifetime">
			<title><varname>$DLG_lifetime</varname></title>
			<para>
			Returns the duration (in seconds) of the dialog corresponding to
			the processed sequential request. The duration is calculated from
			the dialog confirmation and the current moment. This PV will be
			available only for sequential requests, after doing loose_route().
			</para>
			<para>
			NULL will be returned if there is no dialog for the request.
			</para>
		</section>

		<section id="pv_DLG_flags" xreflabel="$DLG_flags">
			<title><varname>$DLG_flags</varname></title>
			<para>
			Returns the dialog flags (as a list of flag names separted by space)
			of the dialog corresponding to the processed sequential request.
			This PV will be available only for sequential requests,
			after doing loose_route().
			</para>
			<para>
			NULL will be returned if there is no dialog for the request.
			</para>
		</section>

		<section id="pv_DLG_dir" xreflabel="$DLG_dir">
			<title><varname>$DLG_dir</varname></title>
			<para>
			Returns the direction of the request in dialog (as "upstream" string
			if the request is generated by callee or "downstream" string if the
			request is generated by caller) - to be used for sequential request.
			This PV will be available only for sequential requests (not for
			replies), after doing loose_route().
			</para>
			<para>
			NULL will be returned if there is no dialog for the request.
			</para>
		</section>

		<section id="pv_DLG_did" xreflabel="$DLG_did">
			<title><varname>$DLG_did</varname></title>
			<para>
			Returns the id of the dialog corresponding to
			the processed sequential request. The output format is a string
			identical to the one returned by the dlg_list MI function. This PV will be
			available only for sequential requests, after doing loose_route().
			</para>
			<para>
			NULL will be returned if there is no dialog for the request.
			</para>
		</section>

		<section id="pv_DLG_end_reason" xreflabel="$DLG_end_reason">
			<title><varname>$DLG_end_reason</varname></title>
			<para>
				Returns the reason for the dialog termination. It can be
				one of the following :

				<itemizedlist>
					<listitem>
						<para><emphasis>Upstream BYE</emphasis> - Callee has sent a BYE
						</para>
					</listitem>
					<listitem>
						<para><emphasis>Downstream BYE</emphasis> - Caller has sent a BYE
						</para>
					</listitem>
					<listitem>
						<para><emphasis>Lifetime Timeout</emphasis> - Dialog lifetime expired
						</para>
					</listitem>
					<listitem>
						<para><emphasis>MI Termination</emphasis> - Dialog ended via the MI interface
						</para>
					</listitem>
					<listitem>
						<para><emphasis>Ping Timeout</emphasis> - Dialog ended because no reply to option pings
						</para>
					</listitem>
					<listitem>
						<para><emphasis>ReINVITE Ping Timeout</emphasis> - Dialog ended because no reply to reinvite pings
						</para>
					</listitem>
					<listitem>
						<para><emphasis>RTPProxy Timeout</emphasis> - Media timeout signaled by RTPProxy
						</para>
					</listitem>
					<listitem>
						<para><emphasis>SIP Race Condition</emphasis> - SIP Race Condition occurred
						</para>
					</listitem>
				</itemizedlist>
			</para>
			<para>
				NULL will be returned if there is no dialog for the request,
				or if the dialog is not ended in the current context.
			</para>
		</section>

		<section id="pv_DLG_timeout" xreflabel="$DLG_timeout">
			<title><varname>$DLG_timeout</varname></title>
			<para>
				Used to set the dialog lifetime (in seconds). When read, the variable
				returns the number of seconds until the dialog expires and is destroyed.
				Note that reading the variable is only possible after the dialog is created
				(for initial requests) or after doing loose_route() (for sequential requests).
				Important notice: using this variable with a REALTIME db_mode is very inefficient,
				because every time the dialog value is changed, a database update is done.
			</para>
			<para>
				NULL will be returned if there is no dialog for the request, otherwise the
				number of seconds until the dialog expiration.
			</para>
		</section>

		<section id="pv_DLG_del_delay" xreflabel="$DLG_del_delay">
			<title><varname>$DLG_del_delay</varname></title>
			<para>
				Used to set the dialog deletion delay (in seconds) for the
				current dialog (in a per-call manner). When read, the variable
				returns the number of seconds that were set for the call or
				the default value ( see the
				<quote>delete_delay</quote> - <xref linkend="param_delete_delay"/>)
				module param) for the delete delaying.
			</para>
			<para>
				The variable must be used when the context of a dialog is
				available in script.
			</para>
		</section>


		<section id="pv_DLG_json" xreflabel="$DLG_json">
			<title><varname>$DLG_json</varname></title>
			<para>
			The variable is read-only and exposes a JSON variable containing all the information that the dlg_list MI function contains
			</para>
			<para>
				NULL will be returned if there is no dialog for the request, otherwise the JSON will be returned.
			</para>
		</section>

		<section id="pv_DLG_ctx_json" xreflabel="$DLG_ctx_json">
			<title><varname>$DLG_ctx_json</varname></title>
			<para>
			The variable is read-only and exposes a JSON variable containing all the information that the dlg_list_ctx MI function contains ( on top of $DLG_json, this will expose the full list of dialog vars and profile links for the current dialog )
			</para>
			<para>
				NULL will be returned if there is no dialog for the request, otherwise the JSON will be returned.
			</para>
		</section>

		<section id="pv_dlg_val" xreflabel="$dlg_val">
			<title><varname>$dlg_val(name)</varname></title>
			<para>
			This is a read/write variable that allows access to the dialog
			attribute named <emphasis>name</emphasis>. It can hold a string or
			integer value. This PV will be available only for sequential requests,
			after doing loose_route().
			</para>
			<para>
			NULL will be returned if there is no dialog for the request.
			</para>
		</section>

	</section>

	<section id="exported_events" xreflabel="Exported Events">
	<title>Exported Events</title>
	<section id="event_E_DLG_STATE_CHANGED" xreflabel="E_DLG_STATE_CHANGED">
		<title>
		<function moreinfo="none">E_DLG_STATE_CHANGED</function>
		</title>
		<para>
			This event is raised when the dialog state is changed.
		</para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem><para>
					<emphasis>id</emphasis> - the hex representation of the dialog id.
			</para></listitem>
			<listitem><para>
					<emphasis>db_id</emphasis> - the integer representation of the dialog id,
					as it is stored in the database <emphasis>dlg_id</emphasis> field.
			</para></listitem>
			<listitem><para>
					<emphasis>callid</emphasis> - the callid.
			</para></listitem>
			<listitem><para>
					<emphasis>from_tag</emphasis> - the From tag.
			</para></listitem>
			<listitem><para>
					<emphasis>to_tag</emphasis> - the To tag.
			</para></listitem>
			<listitem><para>
				<emphasis>old_state</emphasis> - the old state of the dialog.
			</para></listitem>
			<listitem><para>
				<emphasis>new_state</emphasis> - the new state of the dialog.
			</para></listitem>
		</itemizedlist>
	</section>
	</section>


</chapter>

