Browse Source

cnxcc: added Redis support for distributed cnxcc nodes

- works for all monitoring functions
Carlos Ruiz Diaz 11 years ago
parent
commit
c587ce0b17

+ 2 - 1
modules/cnxcc/Makefile

@@ -1,6 +1,6 @@
 # $Id$
 # $Id$
 #
 #
-# example module makefile
+# cnxcc module makefile
 #
 #
 # 
 # 
 # WARNING: do not run this directly, it should be run by the master Makefile
 # WARNING: do not run this directly, it should be run by the master Makefile
@@ -9,6 +9,7 @@ include ../../Makefile.defs
 auto_gen=
 auto_gen=
 NAME=cnxcc.so
 NAME=cnxcc.so
 
 
+LIBS=-lhiredis -levent
 DEFS+=-DOPENSER_MOD_INTERFACE
 DEFS+=-DOPENSER_MOD_INTERFACE
 SERLIBPATH=../../lib
 SERLIBPATH=../../lib
 SER_LIBS+=$(SERLIBPATH)/kmi/kmi
 SER_LIBS+=$(SERLIBPATH)/kmi/kmi

+ 20 - 10
modules/cnxcc/README

@@ -1,10 +1,12 @@
 cnxcc Module
 cnxcc Module
 
 
-Carlos Ruiz Diaz
+Carlos Ruiz Díaz
 
 
    ConexionGroup S.A.
    ConexionGroup S.A.
 
 
-   Copyright © 2013 Carlos Ruiz Diaz, [email protected]
+   Copyright © 2013 Carlos Ruiz Díaz, [email protected]
+
+   Copyright © 2014 Carlos Ruiz Díaz, [email protected]
      __________________________________________________________________
      __________________________________________________________________
 
 
    Table of Contents
    Table of Contents
@@ -15,10 +17,11 @@ Carlos Ruiz Diaz
         2. Dependencies
         2. Dependencies
 
 
               2.1. Modules
               2.1. Modules
+              2.2. Libraries
 
 
         3. Parameters
         3. Parameters
 
 
-              3.1. dlg_flag (integer)
+              3.1. redis (integer)
               3.2. credit_check_period (integer)
               3.2. credit_check_period (integer)
 
 
         4. Functions
         4. Functions
@@ -58,10 +61,11 @@ Chapter 1. Admin Guide
    2. Dependencies
    2. Dependencies
 
 
         2.1. Modules
         2.1. Modules
+        2.2. Libraries
 
 
    3. Parameters
    3. Parameters
 
 
-        3.1. dlg_flag (integer)
+        3.1. redis (integer)
         3.2. credit_check_period (integer)
         3.2. credit_check_period (integer)
 
 
    4. Functions
    4. Functions
@@ -106,7 +110,7 @@ Chapter 1. Admin Guide
    that are equal to the cost per second of both calls.
    that are equal to the cost per second of both calls.
 
 
    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 with that ability.
 
 
    Cnxcc can also provide more common means of monitoring, i.e., by time
    Cnxcc can also provide more common means of monitoring, i.e., by time
    limit or by maximum simultaneous calls.
    limit or by maximum simultaneous calls.
@@ -114,25 +118,31 @@ Chapter 1. Admin Guide
 2. Dependencies
 2. Dependencies
 
 
    2.1. Modules
    2.1. Modules
+   2.2. Libraries
 
 
 2.1. Modules
 2.1. Modules
 
 
    The following module must be loaded before this module:
    The following module must be loaded before this module:
      * dialog
      * dialog
 
 
+2.2. Libraries
+
+   The following module must be loaded before this module:
+     * hiredis-devel >= 0.11.0
+     * libevent-devel >= 2.0.18-2
+
 3. Parameters
 3. Parameters
 
 
-   3.1. dlg_flag (integer)
+   3.1. redis (integer)
    3.2. credit_check_period (integer)
    3.2. credit_check_period (integer)
 
 
-3.1.  dlg_flag (integer)
+3.1.  redis (integer)
 
 
-   Flag to indicate if the dialog must be monitored or not. Messages are
-   flagged with this value if we call one of the monitoring functions.
+   Redis datasource connection information
 
 
    Example 1.1. dlg_flag
    Example 1.1. dlg_flag
 ...
 ...
-modparam("cnxcc", "dlg_flag", 29)
+modparam("cnxcc", "redis", "addr=127.0.0.1;port=6379;db=1")
 ...
 ...
 
 
 3.2. credit_check_period (integer)
 3.2. credit_check_period (integer)

+ 4 - 4
modules/cnxcc/cnxcc.c

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 #include <time.h>
 #include <time.h>
@@ -28,17 +28,17 @@
 
 
 #include "cnxcc.h"
 #include "cnxcc.h"
 
 
-void get_datetime(str *dest)
+inline void get_datetime(str *dest)
 {
 {
 	timestamp2isodt(dest, get_current_timestamp());
 	timestamp2isodt(dest, get_current_timestamp());
 }
 }
 
 
-unsigned int get_current_timestamp()
+inline unsigned int get_current_timestamp()
 {
 {
 	return time(NULL);
 	return time(NULL);
 }
 }
 
 
-int timestamp2isodt(str *dest, unsigned int timestamp)
+inline int timestamp2isodt(str *dest, unsigned int timestamp)
 {
 {
 	time_t  		tim;
 	time_t  		tim;
 	struct tm 		*tmPtr;
 	struct tm 		*tmPtr;

+ 4 - 4
modules/cnxcc/cnxcc.h

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 
@@ -31,9 +31,9 @@
 #define DATETIME_LENGTH		DATETIME_SIZE - 1
 #define DATETIME_LENGTH		DATETIME_SIZE - 1
 
 
 
 
-void get_datetime(str *dest);
-unsigned int get_current_timestamp();
-int timestamp2isodt(str *dest, unsigned int timestamp);
+inline void get_datetime(str *dest);
+inline unsigned int get_current_timestamp();
+inline int timestamp2isodt(str *dest, unsigned int timestamp);
 double str2double(str *string);
 double str2double(str *string);
 
 
 #endif /* _CNXCC_H */
 #endif /* _CNXCC_H */

+ 68 - 59
modules/cnxcc/cnxcc_check.c

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 
@@ -30,43 +30,41 @@
 #include "cnxcc_mod.h"
 #include "cnxcc_mod.h"
 #include "cnxcc.h"
 #include "cnxcc.h"
 #include "cnxcc_check.h"
 #include "cnxcc_check.h"
+#include "cnxcc_redis.h"
 
 
 extern data_t _data;
 extern data_t _data;
 
 
-void check_calls_by_money(unsigned int ticks, void *param)
-{
-	struct str_hash_entry *h_entry 	= NULL,
-			  *tmp		= NULL;
-	call_t *tmp_call		= NULL;
+void check_calls_by_money(unsigned int ticks, void *param) {
+	struct str_hash_entry *h_entry = NULL,
+	                      *tmp = NULL;
+	call_t *tmp_call = NULL;
 	int i;
 	int i;
 
 
 	lock_get(&_data.money.lock);
 	lock_get(&_data.money.lock);
+
 	if (_data.money.credit_data_by_client->table)
 	if (_data.money.credit_data_by_client->table)
 		for(i = 0; i < _data.money.credit_data_by_client->size; i++)
 		for(i = 0; i < _data.money.credit_data_by_client->size; i++)
-			clist_foreach_safe(&_data.money.credit_data_by_client->table[i], h_entry, tmp, next)
-			{
-				credit_data_t *credit_data	= (credit_data_t *) h_entry->u.p;
-				call_t *call			= NULL;
-				double total_consumed_money	= 0;
+			clist_foreach_safe(&_data.money.credit_data_by_client->table[i], h_entry, tmp, next) {
+				credit_data_t *credit_data = (credit_data_t *) h_entry->u.p;
+				call_t *call = NULL;
+				double total_consumed_money = 0, consumption_diff = 0/*, distributed_consumption = 0*/;
 
 
-				if (i > SAFE_ITERATION_THRESHOLD)
-				{
+/*				if (i > SAFE_ITERATION_THRESHOLD) {
 					LM_ERR("Too many iterations for this loop: %d\n", i);
 					LM_ERR("Too many iterations for this loop: %d\n", i);
 					break;
 					break;
-				}
+				}*/
+
 				lock_get(&credit_data->lock);
 				lock_get(&credit_data->lock);
 
 
-				clist_foreach_safe(credit_data->call_list, call, tmp_call, next)
-				{
+				clist_foreach_safe(credit_data->call_list, call, tmp_call, next) {
 					int consumed_time = 0;
 					int consumed_time = 0;
 
 
 					if (!call->confirmed)
 					if (!call->confirmed)
 						continue;
 						continue;
 
 
-					consumed_time 		= get_current_timestamp() - call->start_timestamp;
+					consumed_time = get_current_timestamp() - call->start_timestamp;
 
 
-					if (consumed_time > call->money_based.initial_pulse)
-					{
+					if (consumed_time > call->money_based.initial_pulse) {
 						call->consumed_amount = (call->money_based.cost_per_second * call->money_based.initial_pulse)
 						call->consumed_amount = (call->money_based.cost_per_second * call->money_based.initial_pulse)
 												+
 												+
 												call->money_based.cost_per_second *
 												call->money_based.cost_per_second *
@@ -74,10 +72,9 @@ void check_calls_by_money(unsigned int ticks, void *param)
 												call->money_based.final_pulse;
 												call->money_based.final_pulse;
 					}
 					}
 
 
-					total_consumed_money	+= call->consumed_amount;
+					total_consumed_money += call->consumed_amount;
 
 
-					if (call->consumed_amount > call->max_amount)
-					{
+					if (call->consumed_amount > call->max_amount) {
 						LM_ALERT("[%.*s] call has exhausted its credit. Breaking the loop\n", call->sip_data.callid.len, call->sip_data.callid.s);
 						LM_ALERT("[%.*s] call has exhausted its credit. Breaking the loop\n", call->sip_data.callid.len, call->sip_data.callid.s);
 						break;
 						break;
 					}
 					}
@@ -89,26 +86,35 @@ void check_calls_by_money(unsigned int ticks, void *param)
 																			call->consumed_amount
 																			call->consumed_amount
 																			);
 																			);
 				}
 				}
-				
-				if (credit_data->concurrent_calls == 0)
-				{
+
+				if (credit_data->concurrent_calls == 0) {
 					lock_release(&credit_data->lock);
 					lock_release(&credit_data->lock);
 					continue;
 					continue;
 				}
 				}
 
 
-				credit_data->consumed_amount	= credit_data->ended_calls_consumed_amount + total_consumed_money;
+				if (_data.redis) {
+					LM_INFO("ec=%f, ca=%f, ca2=%f", credit_data->ended_calls_consumed_amount, total_consumed_money, credit_data->consumed_amount);
 
 
-				LM_DBG("Client [%.*s] | Ended-Calls-Credit-Spent: %f  TotalCredit/MaxCredit: %f/%f\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
-																									credit_data->ended_calls_consumed_amount,
-																									credit_data->consumed_amount,
-																									credit_data->max_amount);
+					consumption_diff = credit_data->ended_calls_consumed_amount + total_consumed_money - credit_data->consumed_amount;
+					if (consumption_diff > 0)
+						redis_incr_by_double(credit_data, "consumed_amount", consumption_diff);
+				}
 
 
-				if (credit_data->consumed_amount >= credit_data->max_amount)
-				{
-					lock_release(&_data.money.lock);
+				credit_data->consumed_amount = credit_data->ended_calls_consumed_amount + total_consumed_money /* + distributed_consumption */;
+
+				LM_DBG("Client [%.*s] | Ended-Calls-Credit-Spent: %f  TotalCredit/MaxCredit: %f/%f\n",
+							credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
+							credit_data->ended_calls_consumed_amount,
+							credit_data->consumed_amount,
+							credit_data->max_amount);
+
+				if (credit_data->consumed_amount >= credit_data->max_amount) {
 					terminate_all_calls(credit_data);
 					terminate_all_calls(credit_data);
+
+					// make sure the rest of the servers kill the calls belonging to this customer
+					redis_publish_to_kill_list(credit_data);
 					lock_release(&credit_data->lock);
 					lock_release(&credit_data->lock);
-					return;
+					break;
 				}
 				}
 
 
 				lock_release(&credit_data->lock);
 				lock_release(&credit_data->lock);
@@ -117,43 +123,40 @@ void check_calls_by_money(unsigned int ticks, void *param)
 	lock_release(&_data.money.lock);
 	lock_release(&_data.money.lock);
 }
 }
 
 
-void check_calls_by_time(unsigned int ticks, void *param)
-{
-	struct str_hash_entry *h_entry 	= NULL,
-			*tmp		= NULL;
-	call_t *tmp_call		= NULL;
+void check_calls_by_time(unsigned int ticks, void *param) {
+	struct str_hash_entry *h_entry = NULL;
+	struct str_hash_entry *tmp = NULL;
+	call_t *tmp_call = NULL;
 	int i;
 	int i;
 
 
 	lock_get(&_data.time.lock);
 	lock_get(&_data.time.lock);
 
 
 	if (_data.time.credit_data_by_client->table)
 	if (_data.time.credit_data_by_client->table)
 		for(i = 0; i < _data.time.credit_data_by_client->size; i++)
 		for(i = 0; i < _data.time.credit_data_by_client->size; i++)
-			clist_foreach_safe(&_data.time.credit_data_by_client->table[i], h_entry, tmp, next)
-			{
-				credit_data_t *credit_data	= (credit_data_t *) h_entry->u.p;
-				call_t *call			= NULL;
-				int total_consumed_secs		= 0;
+			clist_foreach_safe(&_data.time.credit_data_by_client->table[i], h_entry, tmp, next) {
+				credit_data_t *credit_data = (credit_data_t *) h_entry->u.p;
+				call_t *call = NULL;
+				int total_consumed_secs = 0;
+				double consumption_diff = 0/*, distributed_consumption = 0*/;
 
 
 				lock_get(&credit_data->lock);
 				lock_get(&credit_data->lock);
 
 
-				if (i > SAFE_ITERATION_THRESHOLD)
+				/*if (i > SAFE_ITERATION_THRESHOLD)
 				{
 				{
-					LM_ERR("Too many iterations for this loop: %d\n", i);
+					LM_ERR("Too many iterations for this loop: %d", i);
 					break;
 					break;
-				}
+				} */
 
 
 				LM_DBG("Iterating through calls of client [%.*s]\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s);
 				LM_DBG("Iterating through calls of client [%.*s]\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s);
 
 
-				clist_foreach_safe(credit_data->call_list, call, tmp_call, next)
-				{
+				clist_foreach_safe(credit_data->call_list, call, tmp_call, next) {
 					if (!call->confirmed)
 					if (!call->confirmed)
 						continue;
 						continue;
 
 
-					call->consumed_amount	= get_current_timestamp() - call->start_timestamp;
+					call->consumed_amount = get_current_timestamp() - call->start_timestamp;
 					total_consumed_secs	+= call->consumed_amount;
 					total_consumed_secs	+= call->consumed_amount;
 
 
-					if (call->consumed_amount > call->max_amount)
-					{
+					if (call->consumed_amount > call->max_amount) {
 						LM_ALERT("[%.*s] call has exhausted its time. Breaking the loop\n", call->sip_data.callid.len, call->sip_data.callid.s);
 						LM_ALERT("[%.*s] call has exhausted its time. Breaking the loop\n", call->sip_data.callid.len, call->sip_data.callid.s);
 						break;
 						break;
 					}
 					}
@@ -165,25 +168,31 @@ void check_calls_by_time(unsigned int ticks, void *param)
 																			);
 																			);
 				}
 				}
 
 
-				if (credit_data->concurrent_calls == 0)
-				{
+				if (credit_data->concurrent_calls == 0) {
 					lock_release(&credit_data->lock);
 					lock_release(&credit_data->lock);
 					continue;
 					continue;
 				}
 				}
 
 
-				credit_data->consumed_amount	= credit_data->ended_calls_consumed_amount + total_consumed_secs;
+				if (_data.redis) {
+					consumption_diff = credit_data->ended_calls_consumed_amount + total_consumed_secs - credit_data->consumed_amount;
+					if (consumption_diff > 0)
+						redis_incr_by_double(credit_data, "consumed_amount", consumption_diff);
+				}
+
+				credit_data->consumed_amount = credit_data->ended_calls_consumed_amount + total_consumed_secs /*+ distributed_consumption*/;
 
 
 				LM_DBG("Client [%.*s] | Ended-Calls-Time: %d  TotalTime/MaxTime: %d/%d\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
 				LM_DBG("Client [%.*s] | Ended-Calls-Time: %d  TotalTime/MaxTime: %d/%d\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
 																									(int) credit_data->ended_calls_consumed_amount,
 																									(int) credit_data->ended_calls_consumed_amount,
 																									(int) credit_data->consumed_amount,
 																									(int) credit_data->consumed_amount,
 																									(int) credit_data->max_amount);
 																									(int) credit_data->max_amount);
 
 
-				if (credit_data->consumed_amount >= credit_data->max_amount)
-				{				
-					lock_release(&_data.time.lock);
+				if (credit_data->consumed_amount >= credit_data->max_amount) {
 					terminate_all_calls(credit_data);
 					terminate_all_calls(credit_data);
+
+					// make sure the rest of the servers kill the calls belonging to this customer
+					redis_publish_to_kill_list(credit_data);
 					lock_release(&credit_data->lock);
 					lock_release(&credit_data->lock);
-					return;
+					break;
 				}
 				}
 
 
 				lock_release(&credit_data->lock);
 				lock_release(&credit_data->lock);

+ 1 - 1
modules/cnxcc/cnxcc_check.h

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 

File diff suppressed because it is too large
+ 305 - 258
modules/cnxcc/cnxcc_mod.c


+ 24 - 21
modules/cnxcc/cnxcc_mod.h

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 #ifndef _CNXCC_MOD_H
 #ifndef _CNXCC_MOD_H
@@ -30,37 +30,34 @@
 
 
 #define str_shm_free_if_not_null(_var_) if (_var_.s != NULL)  { shm_free(_var_.s); _var_.s = NULL; _var_.len = 0; }
 #define str_shm_free_if_not_null(_var_) if (_var_.s != NULL)  { shm_free(_var_.s); _var_.s = NULL; _var_.len = 0; }
 
 
-typedef struct stats
-{
+typedef struct stats {
 	unsigned int total;
 	unsigned int total;
 	unsigned int active;
 	unsigned int active;
 	unsigned int dropped;
 	unsigned int dropped;
 } stats_t;
 } stats_t;
 
 
-typedef enum cnxpvtypes
-{
+typedef enum cnxpvtypes {
 	CNX_PV_ACTIVE = 1,
 	CNX_PV_ACTIVE = 1,
 	CNX_PV_TOTAL,
 	CNX_PV_TOTAL,
 	CNX_PV_DROPPED
 	CNX_PV_DROPPED
 } cnxpvtypes_t;
 } cnxpvtypes_t;
 
 
-typedef enum credit_type
-{
+typedef enum credit_type {
 	CREDIT_TIME,
 	CREDIT_TIME,
 	CREDIT_MONEY,
 	CREDIT_MONEY,
 	CREDIT_CHANNEL
 	CREDIT_CHANNEL
 } credit_type_t;
 } credit_type_t;
 
 
-typedef struct hash_tables
-{
+typedef struct hash_tables {
 	struct str_hash_table *credit_data_by_client;
 	struct str_hash_table *credit_data_by_client;
 	struct str_hash_table *call_data_by_cid;
 	struct str_hash_table *call_data_by_cid;
 
 
 	gen_lock_t lock;
 	gen_lock_t lock;
 } hash_tables_t;
 } hash_tables_t;
 
 
-typedef struct data
-{
+struct redis;
+
+typedef struct data {
 	gen_lock_t lock;
 	gen_lock_t lock;
 
 
 	hash_tables_t time;
 	hash_tables_t time;
@@ -84,10 +81,17 @@ typedef struct data
 
 
 	int check_period;
 	int check_period;
 
 
+	str redis_cnn_str;
+	struct {
+		char host[40];
+		int port;
+		int db;
+	} redis_cnn_info;
+	struct redis *redis;
+
 } data_t;
 } data_t;
 
 
-typedef struct sip_data
-{
+typedef struct sip_data {
 	str callid;
 	str callid;
 	str from_uri;
 	str from_uri;
 	str from_tag;
 	str from_tag;
@@ -95,8 +99,7 @@ typedef struct sip_data
 	str to_tag;
 	str to_tag;
 } sip_data_t;
 } sip_data_t;
 
 
-typedef struct money_spec_data
-{
+typedef struct money_spec_data {
 	double cost_per_second;
 	double cost_per_second;
 	int initial_pulse;
 	int initial_pulse;
 	int final_pulse;
 	int final_pulse;
@@ -104,8 +107,7 @@ typedef struct money_spec_data
 } money_spec_data_t;
 } money_spec_data_t;
 
 
 struct call;
 struct call;
-typedef struct call
-{
+typedef struct call {
 	struct call *prev;
 	struct call *prev;
 	struct call *next;
 	struct call *next;
 
 
@@ -126,15 +128,13 @@ typedef struct call
 	sip_data_t sip_data;
 	sip_data_t sip_data;
 } call_t;
 } call_t;
 
 
-typedef struct call_array
-{
+typedef struct call_array {
 	call_t *array;
 	call_t *array;
 	int length;
 	int length;
 
 
 } call_array_t;
 } call_array_t;
 
 
-typedef struct credit_data
-{
+typedef struct credit_data {
 	gen_lock_t lock;
 	gen_lock_t lock;
 
 
 	double max_amount;
 	double max_amount;
@@ -147,6 +147,9 @@ typedef struct credit_data
 
 
 	call_t *call_list;
 	call_t *call_list;
 
 
+	char *str_id;
+	// flag to mark this instance in the process of being eliminated
+	int deallocating:1;
 } credit_data_t;
 } credit_data_t;
 
 
 
 

+ 65 - 86
modules/cnxcc/cnxcc_rpc.c

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 
@@ -33,27 +33,23 @@
 
 
 extern data_t _data;
 extern data_t _data;
 
 
-void rpc_kill_call(rpc_t* rpc, void* ctx)
-{
+void rpc_kill_call(rpc_t* rpc, void* ctx) {
 	call_t *call;
 	call_t *call;
 	hash_tables_t *hts;
 	hash_tables_t *hts;
 	str callid;
 	str callid;
 
 
-	if (!rpc->scan(ctx, "S", &callid))
-	{
+	if (!rpc->scan(ctx, "S", &callid)) {
 		LM_ERR("%s: error reading RPC param\n", __FUNCTION__);
 		LM_ERR("%s: error reading RPC param\n", __FUNCTION__);
 		return;
 		return;
 	}
 	}
 
 
-	if (try_get_call_entry(&callid, &call, &hts) != 0)
-	{
+	if (try_get_call_entry(&callid, &call, &hts) != 0) {
 		LM_ERR("%s: call [%.*s] not found\n", __FUNCTION__, callid.len, callid.s);
 		LM_ERR("%s: call [%.*s] not found\n", __FUNCTION__, callid.len, callid.s);
 		rpc->fault(ctx, 404, "CallID Not Found");
 		rpc->fault(ctx, 404, "CallID Not Found");
 		return;
 		return;
 	}
 	}
 
 
-	if (call == NULL)
-	{
+	if (call == NULL) {
 		LM_ERR("%s: call [%.*s] is in null state\n", __FUNCTION__, callid.len, callid.s);
 		LM_ERR("%s: call [%.*s] is in null state\n", __FUNCTION__, callid.len, callid.s);
 		rpc->fault(ctx, 500, "Call is NULL");
 		rpc->fault(ctx, 500, "Call is NULL");
 		return;
 		return;
@@ -68,29 +64,25 @@ void rpc_kill_call(rpc_t* rpc, void* ctx)
 	lock_release(&call->lock);
 	lock_release(&call->lock);
 }
 }
 
 
-void rpc_check_client_stats(rpc_t* rpc, void* ctx)
-{
+void rpc_check_client_stats(rpc_t* rpc, void* ctx) {
 	call_t *call, *tmp;
 	call_t *call, *tmp;
 	int index	= 0;
 	int index	= 0;
 	str client_id, rows;
 	str client_id, rows;
 	char row_buffer[512];
 	char row_buffer[512];
 	credit_data_t *credit_data;
 	credit_data_t *credit_data;
 
 
-	if (!rpc->scan(ctx, "S", &client_id))
-	{
+	if (!rpc->scan(ctx, "S", &client_id)) {
 		LM_ERR("%s: error reading RPC param\n", __FUNCTION__);
 		LM_ERR("%s: error reading RPC param\n", __FUNCTION__);
 		return;
 		return;
 	}
 	}
 
 
-	if (try_get_credit_data_entry(&client_id, &credit_data) != 0)
-	{
+	if (try_get_credit_data_entry(&client_id, &credit_data) != 0) {
 		LM_ERR("%s: client [%.*s] not found\n", __FUNCTION__, client_id.len, client_id.s);
 		LM_ERR("%s: client [%.*s] not found\n", __FUNCTION__, client_id.len, client_id.s);
 		rpc->fault(ctx, 404, "Not Found");
 		rpc->fault(ctx, 404, "Not Found");
 		return;
 		return;
 	}
 	}
 
 
-	if (credit_data == NULL)
-	{
+	if (credit_data == NULL) {
 		LM_ERR("%s: credit data for client [%.*s] is NULL\n", __FUNCTION__, client_id.len, client_id.s);
 		LM_ERR("%s: credit data for client [%.*s] is NULL\n", __FUNCTION__, client_id.len, client_id.s);
 		rpc->fault(ctx, 500, "Internal Server Error");
 		rpc->fault(ctx, 500, "Internal Server Error");
 		return;
 		return;
@@ -98,8 +90,7 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx)
 
 
 	lock_get(&credit_data->lock);
 	lock_get(&credit_data->lock);
 
 
-	if (credit_data->number_of_calls <= 0)
-	{
+	if (credit_data->number_of_calls <= 0) {
 		lock_release(&credit_data->lock);
 		lock_release(&credit_data->lock);
 		LM_INFO("No calls for current client\n");
 		LM_INFO("No calls for current client\n");
 		return;
 		return;
@@ -111,43 +102,40 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx)
 	if (rows.s == NULL)
 	if (rows.s == NULL)
 		goto nomem;
 		goto nomem;
 
 
-	clist_foreach_safe(credit_data->call_list, call, tmp, next)
-	{
+	clist_foreach_safe(credit_data->call_list, call, tmp, next) {
 		int row_len = 0;
 		int row_len = 0;
 
 
 		memset(row_buffer, 0, sizeof(row_buffer));
 		memset(row_buffer, 0, sizeof(row_buffer));
 
 
 		if (credit_data->type == CREDIT_MONEY)
 		if (credit_data->type == CREDIT_MONEY)
 			snprintf(row_buffer, sizeof(row_buffer), "id:%d,confirmed:%s,local_consumed_amount:%f,global_consumed_amount:%f,local_max_amount:%f,global_max_amount:%f,call_id:%.*s,start_timestamp:%d"
 			snprintf(row_buffer, sizeof(row_buffer), "id:%d,confirmed:%s,local_consumed_amount:%f,global_consumed_amount:%f,local_max_amount:%f,global_max_amount:%f,call_id:%.*s,start_timestamp:%d"
-																",inip:%d,finp:%d,cps:%f;",
-																 index,
-																 call->confirmed ? "yes" : "no",
-																 call->consumed_amount,
-																 credit_data->consumed_amount,
-																 call->max_amount,
-																 credit_data->max_amount,
-																 call->sip_data.callid.len, call->sip_data.callid.s,
-																 call->start_timestamp,
-																 call->money_based.initial_pulse,
-																 call->money_based.final_pulse,
-																 call->money_based.cost_per_second
-																 );
+								",inip:%d,finp:%d,cps:%f;",
+								index,
+								call->confirmed ? "yes" : "no",
+								call->consumed_amount,
+								credit_data->consumed_amount,
+								call->max_amount,
+								credit_data->max_amount,
+								call->sip_data.callid.len, call->sip_data.callid.s,
+								call->start_timestamp,
+								call->money_based.initial_pulse,
+								call->money_based.final_pulse,
+								call->money_based.cost_per_second);
 		else
 		else
 			snprintf(row_buffer, sizeof(row_buffer), "id:%d,confirmed:%s,local_consumed_amount:%d,global_consumed_amount:%d,local_max_amount:%d,global_max_amount:%d,call_id:%.*s,start_timestamp:%d;",
 			snprintf(row_buffer, sizeof(row_buffer), "id:%d,confirmed:%s,local_consumed_amount:%d,global_consumed_amount:%d,local_max_amount:%d,global_max_amount:%d,call_id:%.*s,start_timestamp:%d;",
-					 	 	 	 	 	 	 	 	 	 	 	 index,
-																 call->confirmed ? "yes" : "no",
-																 (int) call->consumed_amount,
-																 (int) credit_data->consumed_amount,
-																 (int) call->max_amount,
-																 (int) credit_data->max_amount,
-																 call->sip_data.callid.len, call->sip_data.callid.s,
-																 call->start_timestamp);
+								index,
+								call->confirmed ? "yes" : "no",
+								(int) call->consumed_amount,
+								(int) credit_data->consumed_amount,
+								(int) call->max_amount,
+								(int) credit_data->max_amount,
+								call->sip_data.callid.len, call->sip_data.callid.s,
+								call->start_timestamp);
 
 
 		row_len 	= strlen(row_buffer);
 		row_len 	= strlen(row_buffer);
 		rows.s		= pkg_realloc(rows.s, rows.len + row_len);
 		rows.s		= pkg_realloc(rows.s, rows.len + row_len);
 
 
-		if (rows.s == NULL)
-		{
+		if (rows.s == NULL) {
 			lock_release(&credit_data->lock);
 			lock_release(&credit_data->lock);
 			goto nomem;
 			goto nomem;
 		}
 		}
@@ -160,8 +148,7 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx)
 
 
 	lock_release(&credit_data->lock);
 	lock_release(&credit_data->lock);
 
 
-	if (rpc->add(ctx, "S", &rows) < 0)
-	{
+	if (rpc->add(ctx, "S", &rows) < 0) {
 		LM_ERR("%s: error creating RPC struct\n", __FUNCTION__);
 		LM_ERR("%s: error creating RPC struct\n", __FUNCTION__);
 	}
 	}
 
 
@@ -175,8 +162,7 @@ nomem:
 	rpc->fault(ctx, 500, "No more memory\n");
 	rpc->fault(ctx, 500, "No more memory\n");
 }
 }
 
 
-static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t type)
-{
+static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t type) {
 	struct str_hash_entry *h_entry, *tmp;
 	struct str_hash_entry *h_entry, *tmp;
 	char row_buffer[512];
 	char row_buffer[512];
 	int index = 0;
 	int index = 0;
@@ -185,8 +171,7 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ
 
 
 	if (hts->credit_data_by_client->table)
 	if (hts->credit_data_by_client->table)
 		for(index = 0; index < hts->credit_data_by_client->size; index++)
 		for(index = 0; index < hts->credit_data_by_client->size; index++)
-			clist_foreach_safe(&hts->credit_data_by_client->table[index], h_entry, tmp, next)
-			{
+			clist_foreach_safe(&hts->credit_data_by_client->table[index], h_entry, tmp, next) {
 				credit_data_t *credit_data	= (credit_data_t *) h_entry->u.p;
 				credit_data_t *credit_data	= (credit_data_t *) h_entry->u.p;
 				lock_get(&credit_data->lock);
 				lock_get(&credit_data->lock);
 
 
@@ -194,39 +179,36 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ
 
 
 				memset(row_buffer, 0, sizeof(row_buffer));
 				memset(row_buffer, 0, sizeof(row_buffer));
 
 
-				if (type == CREDIT_TIME)
-				{
+				if (type == CREDIT_TIME) {
 					snprintf(row_buffer, sizeof(row_buffer), "client_id:%.*s,"
 					snprintf(row_buffer, sizeof(row_buffer), "client_id:%.*s,"
-															 "number_of_calls:%d,"
-															 "concurrent_calls:%d,"
-															 "type:%d,"
-															 "max_amount:%d,"
-															 "consumed_amount:%d;",
-															 credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
-															 credit_data->number_of_calls,
-															 credit_data->concurrent_calls,
-															 type,
-															 (int) credit_data->max_amount,
-															 (int) credit_data->consumed_amount);
+											"number_of_calls:%d,"
+											"concurrent_calls:%d,"
+											"type:%d,"
+											"max_amount:%d,"
+											"consumed_amount:%d;",
+											credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
+											credit_data->number_of_calls,
+											credit_data->concurrent_calls,
+											type,
+											(int) credit_data->max_amount,
+											(int) credit_data->consumed_amount);
 				}
 				}
-				else if (type == CREDIT_MONEY)
-				{
+				else if (type == CREDIT_MONEY) {
 					snprintf(row_buffer, sizeof(row_buffer), "client_id:%.*s,"
 					snprintf(row_buffer, sizeof(row_buffer), "client_id:%.*s,"
-															 "number_of_calls:%d,"
-															 "concurrent_calls:%d,"
-															 "type:%d,"
-															 "max_amount:%f,"
-															 "consumed_amount:%f;",
-															 credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
-															 credit_data->number_of_calls,
-															 credit_data->concurrent_calls,
-															 type,
-															 credit_data->max_amount,
-															 credit_data->consumed_amount);
+											"number_of_calls:%d,"
+											"concurrent_calls:%d,"
+											"type:%d,"
+											"max_amount:%f,"
+											"consumed_amount:%f;",
+											credit_data->call_list->client_id.len, credit_data->call_list->client_id.s,
+											credit_data->number_of_calls,
+											credit_data->concurrent_calls,
+											type,
+											credit_data->max_amount,
+											credit_data->consumed_amount);
 				}
 				}
-				else
-				{
-					LM_ERR("Unknown credit type: %d", type);
+				else {
+					LM_ERR("Unknown credit type: %d\n", type);
 					return -1;
 					return -1;
 				}
 				}
 
 
@@ -235,8 +217,7 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ
 				row_len 	= strlen(row_buffer);
 				row_len 	= strlen(row_buffer);
 				result->s	= pkg_realloc(result->s, result->len + row_len);
 				result->s	= pkg_realloc(result->s, result->len + row_len);
 
 
-				if (result->s == NULL)
-				{
+				if (result->s == NULL) {
 					lock_release(&hts->lock);
 					lock_release(&hts->lock);
 					goto nomem;
 					goto nomem;
 				}
 				}
@@ -255,8 +236,7 @@ nomem:
 	return -1;
 	return -1;
 }
 }
 
 
-void rpc_active_clients(rpc_t* rpc, void* ctx)
-{
+void rpc_active_clients(rpc_t* rpc, void* ctx) {
 	str rows;
 	str rows;
 
 
 	rows.s	 = pkg_malloc(10);
 	rows.s	 = pkg_malloc(10);
@@ -269,8 +249,7 @@ void rpc_active_clients(rpc_t* rpc, void* ctx)
 	iterate_over_table(&_data.time, &rows, CREDIT_TIME);
 	iterate_over_table(&_data.time, &rows, CREDIT_TIME);
 	iterate_over_table(&_data.money, &rows, CREDIT_MONEY);
 	iterate_over_table(&_data.money, &rows, CREDIT_MONEY);
 
 
-	if (!rpc->add(ctx, "S", &rows) < 0)
-	{
+	if (!rpc->add(ctx, "S", &rows) < 0) {
 		LM_ERR("%s: error creating RPC struct\n", __FUNCTION__);
 		LM_ERR("%s: error creating RPC struct\n", __FUNCTION__);
 	}
 	}
 
 
@@ -280,7 +259,7 @@ void rpc_active_clients(rpc_t* rpc, void* ctx)
 	return;
 	return;
 
 
 nomem:
 nomem:
-	LM_ERR("No more pkg memory");
+	LM_ERR("No more pkg memory\n");
 	rpc->fault(ctx, 500, "No more memory\n");
 	rpc->fault(ctx, 500, "No more memory\n");
 }
 }
 
 

+ 1 - 1
modules/cnxcc/cnxcc_rpc.h

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 

+ 7 - 7
modules/cnxcc/cnxcc_select.c

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 
@@ -36,28 +36,28 @@ int sel_root(str* res, select_t* s, struct sip_msg* msg)  /* dummy */
 
 
 int sel_channels(str* res, select_t* s, struct sip_msg* msg)
 int sel_channels(str* res, select_t* s, struct sip_msg* msg)
 {
 {
-	LM_DBG("sel_channels\n");
+	LM_DBG("sel_channels");
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 int sel_channels_count(str* res, select_t* s, struct sip_msg* msg)
 int sel_channels_count(str* res, select_t* s, struct sip_msg* msg)
 {
 {
-	LM_DBG("sel_channels_count for [%.*s]\n",  s->params[2].v.s.len, s->params[2].v.s.s);
+	LM_DBG("sel_channels_count for [%.*s]",  s->params[2].v.s.len, s->params[2].v.s.s);
 
 
 	credit_data_t *credit_data	= NULL;
 	credit_data_t *credit_data	= NULL;
-	int value			= 0;
+	int value					= 0;
 
 
 	if (s->params[2].v.s.len <= 0)
 	if (s->params[2].v.s.len <= 0)
 	{
 	{
-		LM_ERR("Client must be specified\n");
+		LM_ERR("Client must be specified");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if (try_get_credit_data_entry(&s->params[2].v.s, &credit_data) == 0)
+	if (try_get_credit_data_entry(&s->params[2].v.s, &credit_data) >= 0)
 		value = credit_data->number_of_calls;
 		value = credit_data->number_of_calls;
 	else
 	else
-		LM_DBG("Client [%.*s] not found\n", s->params[2].v.s.len, s->params[2].v.s.s);
+		LM_DBG("Client [%.*s] not found", s->params[2].v.s.len, s->params[2].v.s.s);
 
 
 	res->s 	= int2str(value, &res->len);
 	res->s 	= int2str(value, &res->len);
 
 

+ 1 - 1
modules/cnxcc/cnxcc_select.h

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 

+ 5 - 8
modules/cnxcc/cnxcc_sip_msg_faker.c

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 
 
@@ -34,26 +34,23 @@ char _faked_sip_msg_buf[FAKED_SIP_MSG_BUF_LEN];
 
 
 static struct sip_msg _faked_msg;
 static struct sip_msg _faked_msg;
 
 
-int faked_msg_init_with_dlg_info(str *callid, str *from_uri, str *from_tag, str *to_uri, str *to_tag, struct sip_msg **msg)
-{
+int faked_msg_init_with_dlg_info(str *callid, str *from_uri, str *from_tag, str *to_uri, str *to_tag, struct sip_msg **msg) {
 	memset(_faked_sip_msg_buf, 0, FAKED_SIP_MSG_BUF_LEN);
 	memset(_faked_sip_msg_buf, 0, FAKED_SIP_MSG_BUF_LEN);
 
 
 	sprintf(_faked_sip_msg_buf, FAKED_SIP_MSG_FORMAT,
 	sprintf(_faked_sip_msg_buf, FAKED_SIP_MSG_FORMAT,
 				from_uri->len, from_uri->s, from_tag->len, from_tag->s,
 				from_uri->len, from_uri->s, from_tag->len, from_tag->s,
 				to_uri->len, to_uri->s, to_tag->len, to_tag->s,
 				to_uri->len, to_uri->s, to_tag->len, to_tag->s,
 				callid->len, callid->s);
 				callid->len, callid->s);
-
+ 
 	LM_DBG("fake msg:\n%s\n", _faked_sip_msg_buf);
 	LM_DBG("fake msg:\n%s\n", _faked_sip_msg_buf);
-	memset(&_faked_msg, 0, sizeof(struct sip_msg));
 
 
 	_faked_msg.buf = _faked_sip_msg_buf;
 	_faked_msg.buf = _faked_sip_msg_buf;
 	_faked_msg.len = strlen(_faked_sip_msg_buf);
 	_faked_msg.len = strlen(_faked_sip_msg_buf);
 
 
 	_faked_msg.set_global_address	= default_global_address;
 	_faked_msg.set_global_address	= default_global_address;
-	_faked_msg.set_global_port		= default_global_port;
+	_faked_msg.set_global_port	= default_global_port;
 
 
-	if (parse_msg(_faked_msg.buf, _faked_msg.len, &_faked_msg) != 0)
-	{
+	if (parse_msg(_faked_msg.buf, _faked_msg.len, &_faked_msg) != 0) {
 		LM_ERR("parse_msg failed\n");
 		LM_ERR("parse_msg failed\n");
 		return -1;
 		return -1;
 	}
 	}

+ 1 - 1
modules/cnxcc/cnxcc_sip_msg_faker.h

@@ -18,7 +18,7 @@
  *
  *
  * You should have received a copy of the GNU General Public License
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
  */
  */
 #ifndef CNXCC_SIP_MSG_FAKER_H_
 #ifndef CNXCC_SIP_MSG_FAKER_H_

+ 7 - 2
modules/cnxcc/doc/cnxcc.xml

@@ -15,7 +15,7 @@
     <authorgroup>
     <authorgroup>
 	<author>
 	<author>
 	<firstname>Carlos</firstname>
 	<firstname>Carlos</firstname>
-	<surname>Ruiz Diaz</surname>
+	<surname>Ruiz Díaz</surname>
 	<affiliation>
 	<affiliation>
 	    <orgname>ConexionGroup S.A.</orgname>
 	    <orgname>ConexionGroup S.A.</orgname>
 	</affiliation>
 	</affiliation>
@@ -26,8 +26,13 @@
     </authorgroup>
     </authorgroup>
     <copyright>
     <copyright>
 	<year>2013</year>
 	<year>2013</year>
-	<holder>Carlos Ruiz Diaz, [email protected]</holder>
+	<holder>Carlos Ruiz Díaz, [email protected]</holder>
     </copyright>
     </copyright>
+    <copyright>
+	<year>2014</year>
+	<holder>Carlos Ruiz Díaz, [email protected]</holder>
+    </copyright>
+
     </bookinfo>
     </bookinfo>
 
 
     <toc></toc>
     <toc></toc>

+ 37 - 18
modules/cnxcc/doc/cnxcc_admin.xml

@@ -35,7 +35,7 @@
 	</para>
 	</para>
 	<para>
 	<para>
 		If your accounting program does not maintain the state of the call in real time, this module can provide you
 		If your accounting program does not maintain the state of the call in real time, this module can provide you
-		that ability.
+		with that ability.
 	</para>
 	</para>
 	<para>
 	<para>
 		Cnxcc can also provide more common means of monitoring, i.e., by time limit or by maximum simultaneous calls.
 		Cnxcc can also provide more common means of monitoring, i.e., by time limit or by maximum simultaneous calls.
@@ -59,22 +59,41 @@
 		</itemizedlist>
 		</itemizedlist>
 	    </para>
 	    </para>
 	</section>
 	</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>
 
 
     <section>
     <section>
 	<title>Parameters</title>
 	<title>Parameters</title>
 	<section>
 	<section>
-		<title><varname> dlg_flag </varname> (integer)</title>
+		<title><varname> redis </varname> (integer)</title>
 	    <para>
 	    <para>
-		Flag to indicate if the dialog must be monitored or not. Messages are flagged with this value if we call one of
-		the monitoring functions.
+		Redis datasource connection information
 	    </para>
 	    </para>
 	    <example>
 	    <example>
 
 
 		<title>dlg_flag</title>
 		<title>dlg_flag</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-modparam("cnxcc", "dlg_flag", 29)
+modparam("cnxcc", "redis", "addr=127.0.0.1;port=6379;db=1")
 ...		
 ...		
 		</programlisting>
 		</programlisting>
 	    </example>
 	    </example>
@@ -144,8 +163,7 @@ $var(cps)   = "2.00";         # cost per second
 $var(initial_p)   = "030";    # intial pulse
 $var(initial_p)   = "030";    # intial pulse
 $var(final_p)   = "006";      # final pulse
 $var(final_p)   = "006";      # final pulse
 
 
-cnxcc_set_max_credit("$var(customer)", "$var(credit)", "$var(cps)",
-                     "$var(initial_p)", "$var(final_p)");
+cnxcc_set_max_credit("$var(customer)", "$var(credit)", "$var(cps)", "$var(initial_p)", "$var(final_p)");
 ...		
 ...		
 		</programlisting>
 		</programlisting>
 	    </example>
 	    </example>
@@ -275,17 +293,17 @@ $var(max_chan)  = 2;
 $var(retcode)   = cnxcc_set_max_channels("$var(customer)", "$var(max_chan)");
 $var(retcode)   = cnxcc_set_max_channels("$var(customer)", "$var(max_chan)");
 
 
 if ($var(retcode) == -1) {
 if ($var(retcode) == -1) {
-    xlog("Error setting up credit control");
-    return;
+	xlog("Error setting up credit control");
+	return;
 }
 }
 
 
 if ($var(retcode) &lt; -1) {
 if ($var(retcode) &lt; -1) {
-    xlog("Too many channels for customer");
-    sl_send_reply(403, "Forbidden");
+        xlog("Too many channels for customer");
+        sl_send_reply(403, "Forbidden");
 
 
-    if (!cnxcc_terminate_all("$var(customer)")) {
-        xlog("Error terminating customer's calls");
-    }
+        if (!cnxcc_terminate_all("$var(customer)")) {
+		xlog("Error terminating customer's calls");
+	}
 
 
 	exit;
 	exit;
 }
 }
@@ -325,7 +343,7 @@ if ($var(retcode) &lt; -1) {
 $var(customer)  = "john-doe-123-basic";
 $var(customer)  = "john-doe-123-basic";
 
 
 if (!cnxcc_terminate_all("$var(customer)")) {
 if (!cnxcc_terminate_all("$var(customer)")) {
-    xlog("Error terminating customer's calls");
+	xlog("Error terminating customer's calls");
 }
 }
 ...
 ...
 		</programlisting>
 		</programlisting>
@@ -400,9 +418,9 @@ if (!cnxcc_terminate_all("$var(customer)")) {
 ...
 ...
 event_route[cnxcc:call-shutdown]
 event_route[cnxcc:call-shutdown]
 {
 {
-    xlog("L_INFO", "[$ci]: call killed");
+	xlog("L_INFO", "[$ci]: call killed");
 
 
-    # perform some kind of notification, database update, email sending, etc.
+        # perform some kind of notification, database update, email sending, etc.
 }
 }
 ...
 ...
 		</programlisting>
 		</programlisting>
@@ -439,7 +457,7 @@ route[CNXCC]
                           "$var(cost_per_sec)",
                           "$var(cost_per_sec)",
                           "$var(i_pulse)",
                           "$var(i_pulse)",
                           "$var(f_pulse)")) {
                           "$var(f_pulse)")) {
-             xlog("Error setting up credit control");
+		 xlog("Error setting up credit control");
       	}
       	}
 }
 }
 
 
@@ -447,6 +465,7 @@ event_route[cnxcc:call-shutdown]
 {
 {
 	xlog("L_INFO", "[$ci]: call killed");
 	xlog("L_INFO", "[$ci]: call killed");
 
 
+
 }	    
 }	    
 ...
 ...
 	    </programlisting>
 	    </programlisting>

Some files were not shown because too many files changed in this diff