Browse Source

Added support for max-time update of monitored calls

- updated example config file
- updated documentation
Carlos Ruiz Diaz 12 năm trước cách đây
mục cha
commit
0efe5a4d9a

+ 101 - 9
modules/cnxcc/README

@@ -1,11 +1,10 @@
-
 cnxcc Module
 
 Carlos Ruiz Diaz
 
-   ConexionGroup SA
+   ConexionGroup S.A.
 
-   Copyright © 2012 Carlos Ruiz Diaz, [email protected]
+   Copyright © 2013 Carlos Ruiz Diaz, [email protected]
      __________________________________________________________________
 
    Table of Contents
@@ -26,6 +25,9 @@ Carlos Ruiz Diaz
 
               4.1. cnxcc_set_max_credit()
               4.2. cnxcc_set_max_time()
+              4.3. cnxcc_update_max_time()
+              4.4. cnxcc_set_max_channel()
+              4.5. cnxcc_terminate_all()
 
         5. Exported RPC Commands
 
@@ -43,7 +45,10 @@ Carlos Ruiz Diaz
    1.2. credit_check_period
    1.3. cnxcc_set_max_credit()
    1.4. cnxcc_set_max_time()
-   1.5. kamailio-cnxcc.cfg
+   1.5. cnxcc_update_max_time()
+   1.6. cnxcc_set_max_channels()
+   1.7. cnxcc_set_max_time()
+   1.8. kamailio-cnxcc.cfg
 
 Chapter 1. Admin Guide
 
@@ -63,6 +68,9 @@ Chapter 1. Admin Guide
 
         4.1. cnxcc_set_max_credit()
         4.2. cnxcc_set_max_time()
+        4.3. cnxcc_update_max_time()
+        4.4. cnxcc_set_max_channel()
+        4.5. cnxcc_terminate_all()
 
    5. Exported RPC Commands
 
@@ -100,6 +108,9 @@ Chapter 1. Admin Guide
    If your accounting program does not maintain the state of the call in
    real time, this module can provide you that ability.
 
+   Cnxcc can also provide more common means of monitoring, i.e., by time
+   limit or by maximum simultaneous calls.
+
 2. Dependencies
 
    2.1. Modules
@@ -142,6 +153,9 @@ modparam("cnxcc", "credit_check_period", 1)
 
    4.1. cnxcc_set_max_credit()
    4.2. cnxcc_set_max_time()
+   4.3. cnxcc_update_max_time()
+   4.4. cnxcc_set_max_channel()
+   4.5. cnxcc_terminate_all()
 
 4.1.  cnxcc_set_max_credit()
 
@@ -152,6 +166,7 @@ modparam("cnxcc", "credit_check_period", 1)
    Return code:
      * 1 - successful
      * -1 - failed, error logged
+     * -2 - failed, credit value is less than initial pulse value
 
    Example 1.3. cnxcc_set_max_credit()
 ...
@@ -178,7 +193,84 @@ l_p)", "$var(final_p)");
 $var(customer) = "john-doe-123-basic";
 $var(max_time) = 120;
 
-cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
+cnxcc_set_max_time("$var(customer)", "$var(max_time)");
+...
+
+4.3.  cnxcc_update_max_time()
+
+   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.
+
+   Return code:
+     * 1 - successful
+     * -1 - failed, error logged
+
+   Example 1.5. cnxcc_update_max_time()
+...
+        $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;
+        }
+
+...
+
+4.4.  cnxcc_set_max_channel()
+
+   Specifies a limit for the number of simultaneous calls
+
+   Return code:
+     * 1 - successful
+     * -1 - failed, error logged
+     * -2 - failed, calls established plus calls being established result
+       in more than the limit you specified
+     * -3 - failed, number of calls established is more than the limit you
+       specified
+
+   Example 1.6. cnxcc_set_max_channels()
+...
+$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) < -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;
+}
+
+...
+
+4.5.  cnxcc_terminate_all()
+
+   Terminates all calls of the specified customer/profile
+
+   Return code:
+     * 1 - successful
+     * -1 - failed, error logged
+
+   Example 1.7. cnxcc_set_max_time()
+...
+$var(customer)  = "john-doe-123-basic";
+
+if (!cnxcc_terminate_all("$var(customer)")) {
+        xlog("Error terminating customer's calls");
+}
 ...
 
 5. Exported RPC Commands
@@ -194,7 +286,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
    Parameters: none
 
    Example:
-            sercmd cnxcc.active_clients
+            kamcmd cnxcc.active_clients
 
 5.2. cnxcc.check_client
 
@@ -203,7 +295,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
    Parameters: client/customer identifier
 
    Example:
-            sercmd cnxcc.check_client john-doe-123-premium
+            kamcmd cnxcc.check_client john-doe-123-premium
 
 5.3. cnxcc.kill_call
 
@@ -212,7 +304,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
    Parameters: Call-ID
 
    Example:
-            sercmd cnxcc.kill_call [email protected]
+            kamcmd cnxcc.kill_call [email protected]
 
 6. Events
 
@@ -242,7 +334,7 @@ event_route[cnxcc:call-shutdown]
 
 8. Sample
 
-   Example 1.5. kamailio-cnxcc.cfg
+   Example 1.8. kamailio-cnxcc.cfg
 ...
 route[CNXCC]
 {

+ 93 - 0
modules/cnxcc/cnxcc_mod.c

@@ -104,6 +104,7 @@ static int pv_get_calls(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
  * Billing management functions
  */
 static int set_max_time(struct sip_msg* msg, char* number, char* str2);
+static int update_max_time(struct sip_msg* msg, char* number, char* str2);
 static int set_max_credit(struct sip_msg* msg, char *str_pv_client, char *str_pv_credit, char *str_pv_cps, char *str_pv_inip, char *str_pv_finp);
 static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_pv_max_chan);
 static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str_pv_max_chan);
@@ -142,6 +143,7 @@ static pv_export_t mod_pvs[] =
 static cmd_export_t cmds[] =
 {
 	{"cnxcc_set_max_time",   (cmd_function) set_max_time, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, ANY_ROUTE},
+	{"cnxcc_update_max_time",   (cmd_function) update_max_time, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, ANY_ROUTE},
 	{"cnxcc_set_max_credit",   (cmd_function) set_max_credit, 5, fixup_par, NULL, ANY_ROUTE},
 	{"cnxcc_set_max_channels",   (cmd_function) set_max_channels, 2, fixup_pvar_pvar, NULL, ANY_ROUTE},
 	{"cnxcc_get_channel_count",   (cmd_function) get_channel_count, 2, fixup_pvar_pvar, NULL, ANY_ROUTE},
@@ -1755,6 +1757,97 @@ static int set_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv_m
 	return 1;
 }
 
+static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv_secs)
+{
+	credit_data_t *credit_data 	= NULL;
+	pv_spec_t *secs_spec		= (pv_spec_t *) str_pv_secs,
+		  *client_id_spec	= (pv_spec_t *) str_pv_client;
+	pv_value_t secs_val, client_id_val;
+	int secs				= 0;
+
+	set_ctrl_flag(msg);
+
+	if (parse_headers(msg, HDR_CALLID_F, 0) != 0)
+	{
+		LM_ERR("Error parsing Call-ID");
+		return -1;
+	}
+
+	if (pv_get_spec_value(msg, secs_spec, &secs_val) != 0)
+	{
+		LM_ERR("Can't get secs PV value\n");
+		return -1;
+	}
+	secs	= secs_val.ri;
+
+	if (secs <= 0)
+	{
+		LM_ERR("[%.*s] MAXSECS cannot be less than or equal to zero: %d\n", msg->callid->body.len, msg->callid->body.s, secs);
+		return -1;
+	}
+
+	if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0)
+	{
+		LM_ERR("[%.*s]: can't get client_id PV value\n", msg->callid->body.len, msg->callid->body.s);
+		return -1;
+	}
+
+	if (client_id_val.rs.len == 0 || client_id_val.rs.s == NULL)
+	{
+		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len, msg->callid->body.s);
+		return -1;
+	}
+
+	LM_DBG("Updating call for client [%.*s], max-secs[%d], call-id[%.*s]\n", client_id_val.rs.len, client_id_val.rs.s,
+													secs,
+													msg->callid->body.len, msg->callid->body.s);
+
+
+
+	struct str_hash_table *ht	= NULL;
+	struct str_hash_entry *e	= NULL;
+	ht				= _data.time.credit_data_by_client;
+	double update_fraction		= secs;
+	call_t *call			= NULL,
+	       *tmp_call		= NULL;
+
+	lock_get(&_data.time.lock);
+	e							= str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
+	lock_release(&_data.time.lock);
+
+	if (e == NULL)
+	{
+		LM_ERR("Client [%.*s] was not found\n", e->key.len, e->key.s);
+		return -1;
+	}
+		
+	credit_data					= (credit_data_t *) e->u.p;
+
+	lock_get(&credit_data->lock);
+
+	LM_DBG("Updating max-secs for [%.*s] from [%f] to [%f]\n", e->key.len, e->key.s, credit_data->max_amount, credit_data->max_amount + secs);
+	
+	credit_data->max_amount				+= secs;
+
+	if (credit_data->number_of_calls > 0)
+		update_fraction	= secs / credit_data->number_of_calls;
+
+	clist_foreach_safe(credit_data->call_list, call, tmp_call, next)
+	{
+		if (!call->confirmed)
+			continue;
+		
+		call->max_amount	+= update_fraction;
+	}
+
+//redit_data->consumed_amount			= 0;
+
+
+	lock_release(&credit_data->lock);
+
+	return 1;
+}
+
 static int has_to_tag(struct sip_msg *msg)
 {
 	if (msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0)

+ 44 - 1
modules/cnxcc/doc/cnxcc_admin.xml

@@ -186,6 +186,49 @@ cnxcc_set_max_time("$var(customer)", "$var(max_time)");
             </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>
@@ -223,7 +266,7 @@ cnxcc_set_max_time("$var(customer)", "$var(max_time)");
                 </itemizedlist>
             </para>
             <example>
-		<title>cnxcc_set_max_time()</title>
+		<title>cnxcc_set_max_channels()</title>
                 <programlisting format="linespecific">
 ...
 $var(customer)  = "john-doe-123-basic";

+ 34 - 4
modules/cnxcc/example/kamailio-cnxcc.cfg

@@ -1,8 +1,8 @@
 #!KAMAILIO
 
-##!define CNXCC_TIME
+#!define CNXCC_TIME
 ##!define CNXCC_MONEY
-#!define CNXCC_CHANNEL
+##!define CNXCC_CHANNEL
 
 #
 # Kamailio (OpenSER) SIP Server v3.2 - default configuration script
@@ -455,12 +455,18 @@ modparam("dialog", "default_timeout", 3600)
 modparam("dialog", "db_mode", 0)
 modparam("dialog", "dlg_flag", DLG_FLAG)
 
-#!ifdef CNXCC_CHANNEL
+
 loadmodule "rtimer.so";
+#!ifdef CNXCC_CHANNEL
 modparam("rtimer", "timer", "name=ta;interval=1;mode=1;")
 modparam("rtimer", "exec", "timer=ta;route=SHOW_CHANNEL_COUNT")
 #!endif
 
+#!ifdef CNXCC_TIME
+modparam("rtimer", "timer", "name=ta;interval=5;mode=1;")
+modparam("rtimer", "exec", "timer=ta;route=UPDATE_MAX_TIME")
+#!endif
+
 loadmodule "cnxcc.so"
 modparam("cnxcc", "dlg_flag", CC_FLAG)
 modparam("cnxcc", "credit_check_period", 1) #check every 1 second
@@ -609,7 +615,7 @@ route[CNXCC]
 #!ifdef CNXCC_TIME
 	xlog("L_INFO", "Setting up time based credit control");
 	
-	$var(max_time)	= 10;
+	$var(max_time)	= 5;
 	
 	if (!cnxcc_set_max_time("$var(client)",
                                   "$var(max_time)")) {
@@ -635,6 +641,30 @@ route[SHOW_CHANNEL_COUNT]
 }
 #!endif
 
+#!ifdef CNXCC_TIME
+route[UPDATE_MAX_TIME]
+{
+	if ($DLG_count == 0) // no active dialog? no time to be updated 
+		return;	
+	
+	if ($var(granted_units) == 4) // after 25 seconds, we will stop updating the granted time
+		return;
+
+	$var(granted_units) = $var(granted_units) + 1;
+	xlog("L_INFO", "Updating max-time. Granted units $var(granted_units)/4");
+
+        $var(update_time)  = 5;
+	$var(client)	   = "customer1";
+
+        if (!cnxcc_update_max_time("$var(client)",
+                                  "$var(update_time)")) {
+                xlog("Error updating max-time");
+                return;
+        }
+
+}
+#!endif
+
 route[RELAY] {
 
 	# enable additional event routes for forwarded requests