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

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

]>
<!-- Module Admin Guide -->

<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
    <title>&adminguide;</title>

    <section>
	<title>Overview</title>
	<para>
		This module was designed to act as a mechanism to limit call duration based on credit information parameters.
		After getting the credit information of the call being set up, you can instruct the module to start monitoring
		the consumed credit to shutdown a single call or a group of calls in case of credit exhaustion.	
	</para>
	<para>
		Every call is associated to an unique client/customer identifier. If a credit event occurs, all calls hooked
	   	to this identifier are automatically shutdown.
	</para>
	<para>
		Cnxcc is dialog-aware so there's no need to explicitly allocate/deallocate the monitoring. Only a single function
		call inside the script is needed upon reception of the INVITE.
	</para>
	<para>
		The credit discount rate is proportional to the number of calls grouped inside an identifier. Once the setup
		of the first call is done, the information remains while the call is active. If the customer starts a new call with
		the same routing criteria, it will land in the same monitoring bag and it will consume the same pool of credit in
		rates that are equal to the cost per second of both calls.
	</para>
	<para>
		If your accounting program does not maintain the state of the call in real time, this module can provide you
		with that ability.
	</para>
	<para>
		Cnxcc can also provide more common means of monitoring, i.e., by time limit or by maximum simultaneous calls.
	</para>


    </section>

    <section>
	<title>Dependencies</title>
	<section>
	    <title>Modules</title>
	    <para>
		The following module must be loaded before this module: 
		<itemizedlist>
		    <listitem>
		    <para>
			<emphasis>dialog</emphasis>
		    </para>
		    </listitem>
		</itemizedlist>
	    </para>
	</section>
	<section>
	    <title>Libraries</title>
	    <para>
		The following module must be loaded before this module: 
		<itemizedlist>
		    <listitem>
		    <para>
			<emphasis> hiredis-devel >= 0.11.0 </emphasis>
		    </para>
		    </listitem>
		    <listitem>
		    <para>
			<emphasis> libevent-devel >= 2.0.18-2 </emphasis>
		    </para>
		    </listitem>

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

    </section>

    <section>
	<title>Parameters</title>
	<section>
		<title><varname> redis </varname> (integer)</title>
	    <para>
		Redis datasource connection information
	    </para>
	    <example>

		<title>dlg_flag</title>
		<programlisting format="linespecific">
...
modparam("cnxcc", "redis", "addr=127.0.0.1;port=6379;db=1")
...		
		</programlisting>
	    </example>
	</section>

	<section>
	    <title><varname>credit_check_period</varname> (integer)</title>
	    <para>
		Indicates how often the credit checking function should be called. It is directly related to the precison of the
		module. The maximum precision is 1, which means that every call is checked every one second.

	    </para>
	    <para>
		Values greater than 1 leads to precision lost but less CPU consumption.
	    </para>
	    <example>
		<title>credit_check_period</title>
		<programlisting format="linespecific">
...
modparam("cnxcc", "credit_check_period", 1)
...		
		</programlisting>
	    </example>
	</section> 
   </section>

    <section>
	<title>Functions</title>
	<section>
	    <title>
		<function moreinfo="none">cnxcc_set_max_credit()</function>
	    </title>
	    <para>
		Specifies the initial pulse, final pulse, max credit and cost per second of a call. The discount
		is calculated in pulses (30/6, 1/1, etc) and sustracted from the pool of credit.
	    </para>
	    <para>
		<emphasis>Return code:</emphasis>
		<itemizedlist>
		    <listitem>
		    <para>
			<emphasis>1 - successful</emphasis>
		    </para>
		    </listitem>

		    <listitem>
		    <para>
			<emphasis>-1 - failed, error logged</emphasis>
		    </para>
		    </listitem>

		    <listitem>
		    <para>
			<emphasis>-2 - failed, credit value is less than initial pulse value</emphasis>
		    </para>
		    </listitem>

		</itemizedlist>
	    </para>
	    <example>
		<title>cnxcc_set_max_credit()</title>
		<programlisting format="linespecific">
...
$var(customer) = "john-doe-123-premium";
$var(credit) = "100";
$var(cps)   = "2.00";         # cost per second
$var(initial_p)   = "030";    # intial pulse
$var(final_p)   = "006";      # final pulse

cnxcc_set_max_credit("$var(customer)", "$var(credit)", "$var(cps)", "$var(initial_p)", "$var(final_p)");
...		
		</programlisting>
	    </example>
	</section>

        <section>
            <title>
                <function moreinfo="none">cnxcc_set_max_time()</function>
            </title>
            <para>
		Specifies the amount of time the call should last at most.
            </para>
            <para>
                <emphasis>Return code:</emphasis>
                <itemizedlist>
                    <listitem>
                    <para>
                        <emphasis>1 - successful</emphasis>
                    </para>
                    </listitem>
                     
                    <listitem>
                    <para>
                        <emphasis>-1 - failed, error logged</emphasis>
                    </para>
                    </listitem>
                </itemizedlist>
            </para>
            <example>
		<title>cnxcc_set_max_time()</title>
                <programlisting format="linespecific">
...
$var(customer) = "john-doe-123-basic";
$var(max_time) = 120;

cnxcc_set_max_time("$var(customer)", "$var(max_time)");
...
		</programlisting>
            </example>
        </section>

        <section>
            <title>
                <function moreinfo="none">cnxcc_update_max_time()</function>
            </title>
            <para>
		Updates max-time of an established and monitored call. This can be used to grant minimum values and to update them every short periods on time as a mean to prevent frauds and/or to mimic requested/granted units of time of Credit Control Application behavior.
            </para>
            <para>
                <emphasis>Return code:</emphasis>
                <itemizedlist>
                    <listitem>
                    <para>
                        <emphasis>1 - successful</emphasis>
                    </para>
                    </listitem>
                     
                    <listitem>
                    <para>
                        <emphasis>-1 - failed, error logged</emphasis>
                    </para>
                    </listitem>
                </itemizedlist>
            </para>
            <example>
		<title>cnxcc_update_max_time()</title>
                <programlisting format="linespecific">
...
        $var(update_time)  = 5;
        $var(client)       = "john-doe-123-basic";

        if (!cnxcc_update_max_time("$var(client)",
                                  "$var(update_time)")) {
                xlog("Error updating max-time");
                return;
        }

...
		</programlisting>
            </example>
        </section>



    	<section>
            <title>
                <function moreinfo="none">cnxcc_set_max_channel()</function>
            </title>
            <para>
		Specifies a limit for the number of simultaneous calls
            </para>
            <para>
                <emphasis>Return code:</emphasis>
                <itemizedlist>
                    <listitem>
                    <para>
                        <emphasis>1 - successful</emphasis>
                    </para>
                    </listitem>
                     
                    <listitem>
                    <para>
                        <emphasis>-1 - failed, error logged</emphasis>
                    </para>
                    </listitem>

                    <listitem>
                    <para>
                        <emphasis>-2 - failed, calls established plus calls being established result in more than the limit you specified</emphasis>
                    </para>
                    </listitem>
		    
		    <listitem>
                    <para>
                        <emphasis>-3 - failed, number of calls established is more than the limit you specified</emphasis>
                    </para>
                    </listitem>

                </itemizedlist>
            </para>
            <example>
		<title>cnxcc_set_max_channels()</title>
                <programlisting format="linespecific">
...
$var(customer)  = "john-doe-123-basic";
$var(max_chan)  = 2;
$var(retcode)   = cnxcc_set_max_channels("$var(customer)", "$var(max_chan)");

if ($var(retcode) == -1) {
	xlog("Error setting up credit control");
	return;
}

if ($var(retcode) &lt; -1) {
        xlog("Too many channels for customer");
        sl_send_reply(403, "Forbidden");

        if (!cnxcc_terminate_all("$var(customer)")) {
		xlog("Error terminating customer's calls");
	}

	exit;
}

...
		</programlisting>
            </example>
    	</section>
	
    	<section>
            <title>
                <function moreinfo="none">cnxcc_terminate_all()</function>
            </title>
            <para>
		Terminates all calls of the specified customer/profile
            </para>
            <para>
                <emphasis>Return code:</emphasis>
                <itemizedlist>
                    <listitem>
                    <para>
                        <emphasis>1 - successful</emphasis>
                    </para>
                    </listitem>
                     
                    <listitem>
                    <para>
                        <emphasis>-1 - failed, error logged</emphasis>
                    </para>
                    </listitem>
                </itemizedlist>
            </para>
            <example>
		<title>cnxcc_set_max_time()</title>
                <programlisting format="linespecific">
...
$var(customer)  = "john-doe-123-basic";

if (!cnxcc_terminate_all("$var(customer)")) {
	xlog("Error terminating customer's calls");
}
...
		</programlisting>
            </example>
        </section>
    </section>
   
    <section>
	<title>Exported RPC Commands</title>

	<section>
	    <title><varname>cnxcc.active_clients</varname></title>
	    <para>
		Retrieves all calls grouped by their identifiers.
	    </para>
	    <para>
		Parameters: <emphasis>none</emphasis>
	    </para>
	    <para>
		Example:
	    </para>
	    <programlisting format="linespecific">
	    &sercmd; cnxcc.active_clients
	    </programlisting>
	</section>

	<section>
            <title><varname>cnxcc.check_client</varname></title>
            <para>
		Retrives all calls from a particular identifier.
            </para>
            <para>
		    Parameters: <emphasis>client/customer identifier</emphasis>
            </para>
            <para>
                Example:
            </para>
            <programlisting format="linespecific">
	    &sercmd; cnxcc.check_client john-doe-123-premium
            </programlisting>
        </section>

        <section>
            <title><varname>cnxcc.kill_call</varname></title>
            <para>
		    Kills an active call using its call ID.
	    </para>
            <para>
                Parameters: <emphasis>Call-ID</emphasis>
            </para>
            <para>
                Example:
            </para>
            <programlisting format="linespecific">
            &sercmd; cnxcc.kill_call qumojlaahitafih@carlosrdcnx-laptop.site
            </programlisting>
        </section>
    </section>

    <section>
	    <title>Events</title>
	    
	    <para>
		When a call is forced to end an event route is automatically invoked. This route is suited with a fake OPTIONS
		message containing the call ID, ftag and ttag of the original call so it can be located somehow in the accounting
		database.
	    </para>
	    <para>
                Example:
            </para>
            	<programlisting format="linespecific">
...
event_route[cnxcc:call-shutdown]
{
	xlog("L_INFO", "[$ci]: call killed");

        # perform some kind of notification, database update, email sending, etc.
}
...
		</programlisting>
	    
    </section>
    <section>
            <title>Web Interface</title>

            <para>
		The module contains a web management interface completely optional. With it, you can review your calls in real time
		and hang them up if necessary.    
	    </para>
            <para>
                Link: https://github.com/caruizdiaz/cnxcc-web
            </para>
    </section>

    <section>
	<title>Sample</title>
	<example>
	    <title>kamailio-cnxcc.cfg</title>
	    <programlisting format="linespecific">
...
route[CNXCC]
{
	$var(client)              = "test-client-0-123-01";
      	$var(credit)              = "50";
      	$var(cost_per_sec)        = "0.5";
      	$var(i_pulse)             = "30";
      	$var(f_pulse)             = "6";

      	if (!cnxcc_set_max_credit("$var(client)",
                          "$var(credit)",
                          "$var(cost_per_sec)",
                          "$var(i_pulse)",
                          "$var(f_pulse)")) {
		 xlog("Error setting up credit control");
      	}
}

event_route[cnxcc:call-shutdown]
{
	xlog("L_INFO", "[$ci]: call killed");


}	    
...
	    </programlisting>
	</example>
    </section>

</chapter>
