ソースを参照

Added support for max-time update of monitored calls

- updated example config file
- updated documentation
Carlos Ruiz Diaz 12 年 前
コミット
0efe5a4d9a

+ 101 - 9
modules/cnxcc/README

@@ -1,11 +1,10 @@
-
 cnxcc Module
 cnxcc Module
 
 
 Carlos Ruiz Diaz
 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
    Table of Contents
@@ -26,6 +25,9 @@ Carlos Ruiz Diaz
 
 
               4.1. cnxcc_set_max_credit()
               4.1. cnxcc_set_max_credit()
               4.2. cnxcc_set_max_time()
               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
         5. Exported RPC Commands
 
 
@@ -43,7 +45,10 @@ Carlos Ruiz Diaz
    1.2. credit_check_period
    1.2. credit_check_period
    1.3. cnxcc_set_max_credit()
    1.3. cnxcc_set_max_credit()
    1.4. cnxcc_set_max_time()
    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
 Chapter 1. Admin Guide
 
 
@@ -63,6 +68,9 @@ Chapter 1. Admin Guide
 
 
         4.1. cnxcc_set_max_credit()
         4.1. cnxcc_set_max_credit()
         4.2. cnxcc_set_max_time()
         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
    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
    If your accounting program does not maintain the state of the call in
    real time, this module can provide you that ability.
    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. Dependencies
 
 
    2.1. Modules
    2.1. Modules
@@ -142,6 +153,9 @@ modparam("cnxcc", "credit_check_period", 1)
 
 
    4.1. cnxcc_set_max_credit()
    4.1. cnxcc_set_max_credit()
    4.2. cnxcc_set_max_time()
    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()
 4.1.  cnxcc_set_max_credit()
 
 
@@ -152,6 +166,7 @@ modparam("cnxcc", "credit_check_period", 1)
    Return code:
    Return code:
      * 1 - successful
      * 1 - successful
      * -1 - failed, error logged
      * -1 - failed, error logged
+     * -2 - failed, credit value is less than initial pulse value
 
 
    Example 1.3. cnxcc_set_max_credit()
    Example 1.3. cnxcc_set_max_credit()
 ...
 ...
@@ -178,7 +193,84 @@ l_p)", "$var(final_p)");
 $var(customer) = "john-doe-123-basic";
 $var(customer) = "john-doe-123-basic";
 $var(max_time) = 120;
 $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
 5. Exported RPC Commands
@@ -194,7 +286,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
    Parameters: none
    Parameters: none
 
 
    Example:
    Example:
-            sercmd cnxcc.active_clients
+            kamcmd cnxcc.active_clients
 
 
 5.2. cnxcc.check_client
 5.2. cnxcc.check_client
 
 
@@ -203,7 +295,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
    Parameters: client/customer identifier
    Parameters: client/customer identifier
 
 
    Example:
    Example:
-            sercmd cnxcc.check_client john-doe-123-premium
+            kamcmd cnxcc.check_client john-doe-123-premium
 
 
 5.3. cnxcc.kill_call
 5.3. cnxcc.kill_call
 
 
@@ -212,7 +304,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
    Parameters: Call-ID
    Parameters: Call-ID
 
 
    Example:
    Example:
-            sercmd cnxcc.kill_call [email protected]
+            kamcmd cnxcc.kill_call [email protected]
 
 
 6. Events
 6. Events
 
 
@@ -242,7 +334,7 @@ event_route[cnxcc:call-shutdown]
 
 
 8. Sample
 8. Sample
 
 
-   Example 1.5. kamailio-cnxcc.cfg
+   Example 1.8. kamailio-cnxcc.cfg
 ...
 ...
 route[CNXCC]
 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
  * Billing management functions
  */
  */
 static int set_max_time(struct sip_msg* msg, char* number, char* str2);
 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_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 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);
 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[] =
 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_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_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_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},
 	{"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;
 	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)
 static int has_to_tag(struct sip_msg *msg)
 {
 {
 	if (msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0)
 	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>
             </example>
         </section>
         </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>
     	<section>
             <title>
             <title>
                 <function moreinfo="none">cnxcc_set_max_channel()</function>
                 <function moreinfo="none">cnxcc_set_max_channel()</function>
@@ -223,7 +266,7 @@ cnxcc_set_max_time("$var(customer)", "$var(max_time)");
                 </itemizedlist>
                 </itemizedlist>
             </para>
             </para>
             <example>
             <example>
-		<title>cnxcc_set_max_time()</title>
+		<title>cnxcc_set_max_channels()</title>
                 <programlisting format="linespecific">
                 <programlisting format="linespecific">
 ...
 ...
 $var(customer)  = "john-doe-123-basic";
 $var(customer)  = "john-doe-123-basic";

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

@@ -1,8 +1,8 @@
 #!KAMAILIO
 #!KAMAILIO
 
 
-##!define CNXCC_TIME
+#!define CNXCC_TIME
 ##!define CNXCC_MONEY
 ##!define CNXCC_MONEY
-#!define CNXCC_CHANNEL
+##!define CNXCC_CHANNEL
 
 
 #
 #
 # Kamailio (OpenSER) SIP Server v3.2 - default configuration script
 # 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", "db_mode", 0)
 modparam("dialog", "dlg_flag", DLG_FLAG)
 modparam("dialog", "dlg_flag", DLG_FLAG)
 
 
-#!ifdef CNXCC_CHANNEL
+
 loadmodule "rtimer.so";
 loadmodule "rtimer.so";
+#!ifdef CNXCC_CHANNEL
 modparam("rtimer", "timer", "name=ta;interval=1;mode=1;")
 modparam("rtimer", "timer", "name=ta;interval=1;mode=1;")
 modparam("rtimer", "exec", "timer=ta;route=SHOW_CHANNEL_COUNT")
 modparam("rtimer", "exec", "timer=ta;route=SHOW_CHANNEL_COUNT")
 #!endif
 #!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"
 loadmodule "cnxcc.so"
 modparam("cnxcc", "dlg_flag", CC_FLAG)
 modparam("cnxcc", "dlg_flag", CC_FLAG)
 modparam("cnxcc", "credit_check_period", 1) #check every 1 second
 modparam("cnxcc", "credit_check_period", 1) #check every 1 second
@@ -609,7 +615,7 @@ route[CNXCC]
 #!ifdef CNXCC_TIME
 #!ifdef CNXCC_TIME
 	xlog("L_INFO", "Setting up time based credit control");
 	xlog("L_INFO", "Setting up time based credit control");
 	
 	
-	$var(max_time)	= 10;
+	$var(max_time)	= 5;
 	
 	
 	if (!cnxcc_set_max_time("$var(client)",
 	if (!cnxcc_set_max_time("$var(client)",
                                   "$var(max_time)")) {
                                   "$var(max_time)")) {
@@ -635,6 +641,30 @@ route[SHOW_CHANNEL_COUNT]
 }
 }
 #!endif
 #!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] {
 route[RELAY] {
 
 
 	# enable additional event routes for forwarded requests
 	# enable additional event routes for forwarded requests