diff --git a/src/modules/cnxcc/cnxcc.c b/src/modules/cnxcc/cnxcc.c index 3d21b3dd7b1..3f0da8aff3c 100644 --- a/src/modules/cnxcc/cnxcc.c +++ b/src/modules/cnxcc/cnxcc.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -32,7 +30,7 @@ double str2double(str *string) { char buffer[string->len + 1]; - buffer[string->len] = '\0'; + buffer[string->len] = '\0'; memcpy(buffer, string->s, string->len); return atof(buffer); diff --git a/src/modules/cnxcc/cnxcc.h b/src/modules/cnxcc/cnxcc.h index 9dc07435002..31fb84ee891 100644 --- a/src/modules/cnxcc/cnxcc.h +++ b/src/modules/cnxcc/cnxcc.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -27,8 +25,8 @@ #include "../../core/str.h" -#define DATETIME_SIZE sizeof("0001-01-01 00:00:00") -#define DATETIME_LENGTH DATETIME_SIZE - 1 +#define DATETIME_SIZE sizeof("0001-01-01 00:00:00") +#define DATETIME_LENGTH DATETIME_SIZE - 1 static inline unsigned int get_current_timestamp() @@ -38,14 +36,14 @@ static inline unsigned int get_current_timestamp() static inline int timestamp2isodt(str *dest, unsigned int timestamp) { - time_t tim; - struct tm *tmPtr; + time_t tim; + struct tm *tmPtr; - tim = timestamp; - tmPtr = localtime(&tim); + tim = timestamp; + tmPtr = localtime(&tim); - strftime( dest->s, DATETIME_SIZE, "%Y-%m-%d %H:%M:%S", tmPtr); - dest->len = DATETIME_LENGTH; + strftime(dest->s, DATETIME_SIZE, "%Y-%m-%d %H:%M:%S", tmPtr); + dest->len = DATETIME_LENGTH; return 0; } diff --git a/src/modules/cnxcc/cnxcc_check.c b/src/modules/cnxcc/cnxcc_check.c index 656bf8346bc..47324e4089e 100644 --- a/src/modules/cnxcc/cnxcc_check.c +++ b/src/modules/cnxcc/cnxcc_check.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -32,85 +30,106 @@ extern data_t _data; -void check_calls_by_money(unsigned int ticks, void *param) { - struct str_hash_entry *h_entry = NULL, - *tmp = 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; cnxcc_lock(_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++) - 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; + 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*/; + 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); break; }*/ cnxcc_lock(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; - if (!call->confirmed) + if(!call->confirmed) continue; - consumed_time = get_current_timestamp() - call->start_timestamp; - - if (consumed_time > 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 * - ( (consumed_time - call->money_based.initial_pulse) / call->money_based.final_pulse + 1 ) * - call->money_based.final_pulse; + consumed_time = + get_current_timestamp() - call->start_timestamp; + + if(consumed_time > 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 + * ((consumed_time + - call->money_based + .initial_pulse) + / call->money_based + .final_pulse + + 1) + * call->money_based.final_pulse; } total_consumed_money += call->consumed_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); + 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); break; } - LM_DBG("CID [%.*s], start_timestamp [%d], seconds alive [%d], consumed credit [%f]\n", - call->sip_data.callid.len, call->sip_data.callid.s, - call->start_timestamp, - consumed_time, - call->consumed_amount - ); + LM_DBG("CID [%.*s], start_timestamp [%d], seconds alive " + "[%d], consumed credit [%f]\n", + call->sip_data.callid.len, call->sip_data.callid.s, + call->start_timestamp, consumed_time, + call->consumed_amount); } - if (credit_data->concurrent_calls == 0) { + if(credit_data->concurrent_calls == 0) { cnxcc_unlock(credit_data->lock); continue; } - if (_data.redis) { - LM_DBG("ec=%f, ca=%f, ca2=%f", credit_data->ended_calls_consumed_amount, total_consumed_money, credit_data->consumed_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(_data.redis) { + LM_DBG("ec=%f, ca=%f, ca2=%f", + credit_data->ended_calls_consumed_amount, + total_consumed_money, credit_data->consumed_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); } - credit_data->consumed_amount = credit_data->ended_calls_consumed_amount + total_consumed_money /* + distributed_consumption */; + 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); + 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) { + if(credit_data->consumed_amount >= credit_data->max_amount) { terminate_all_calls(credit_data); // make sure the rest of the servers kill the calls belonging to this customer - if (_data.redis) + if(_data.redis) redis_publish_to_kill_list(credit_data); cnxcc_unlock(credit_data->lock); break; @@ -122,7 +141,8 @@ void check_calls_by_money(unsigned int ticks, void *param) { cnxcc_unlock(_data.money.lock); } -void check_calls_by_time(unsigned int ticks, void *param) { +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; @@ -130,13 +150,15 @@ void check_calls_by_time(unsigned int ticks, void *param) { cnxcc_lock(_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++) - 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; + 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*/; + double consumption_diff = 0 /*, distributed_consumption = 0*/; cnxcc_lock(credit_data->lock); @@ -146,50 +168,64 @@ void check_calls_by_time(unsigned int ticks, void *param) { 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) { - if (!call->confirmed) + clist_foreach_safe(credit_data->call_list, call, tmp_call, next) + { + if(!call->confirmed) continue; - call->consumed_amount = get_current_timestamp() - call->start_timestamp; - total_consumed_secs += call->consumed_amount; + call->consumed_amount = + get_current_timestamp() - call->start_timestamp; + total_consumed_secs += call->consumed_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); + 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); break; } - LM_DBG("CID [%.*s], start_timestamp [%d], seconds alive [%d]\n", - call->sip_data.callid.len, call->sip_data.callid.s, - call->start_timestamp, - (int) call->consumed_amount - ); + LM_DBG("CID [%.*s], start_timestamp [%d], seconds alive " + "[%d]\n", + call->sip_data.callid.len, call->sip_data.callid.s, + call->start_timestamp, (int)call->consumed_amount); } - if (credit_data->concurrent_calls == 0) { + if(credit_data->concurrent_calls == 0) { cnxcc_unlock(credit_data->lock); continue; } - 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); + 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*/; + 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, - (int) credit_data->ended_calls_consumed_amount, - (int) credit_data->consumed_amount, - (int) credit_data->max_amount); + 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->consumed_amount, + (int)credit_data->max_amount); - if (credit_data->consumed_amount >= credit_data->max_amount) { + if(credit_data->consumed_amount >= credit_data->max_amount) { terminate_all_calls(credit_data); // make sure the rest of the servers kill the calls belonging to this customer - if (_data.redis) + if(_data.redis) redis_publish_to_kill_list(credit_data); cnxcc_unlock(credit_data->lock); break; diff --git a/src/modules/cnxcc/cnxcc_check.h b/src/modules/cnxcc/cnxcc_check.h index afb86543625..3668aebcdc5 100644 --- a/src/modules/cnxcc/cnxcc_check.h +++ b/src/modules/cnxcc/cnxcc_check.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * diff --git a/src/modules/cnxcc/cnxcc_mod.c b/src/modules/cnxcc/cnxcc_mod.c index 91a914f8d14..0a31f4757e7 100644 --- a/src/modules/cnxcc/cnxcc_mod.c +++ b/src/modules/cnxcc/cnxcc_mod.c @@ -67,16 +67,16 @@ MODULE_VERSION #define HT_SIZE 229 -#define MODULE_NAME "cnxcc" +#define MODULE_NAME "cnxcc" #define NUMBER_OF_TIMERS 2 -#define TRUE 1 -#define FALSE !TRUE +#define TRUE 1 +#define FALSE !TRUE data_t _data; struct dlg_binds _dlgbinds; -static int __fixup_pvar(void** param, int param_no); +static int __fixup_pvar(void **param, int param_no); /* * module core functions @@ -95,62 +95,77 @@ static void __free_credit_data_hash_entry(struct str_hash_entry *e); * PV management functions */ static int __pv_parse_calls_param(pv_spec_p sp, str *in); -static int __pv_get_calls(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); +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); -static int __terminate_all(struct sip_msg* msg, char* str_pv_client); - -static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]); -static void __setup_billing(str *callid, unsigned int h_entry, unsigned int h_id); +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); +static int __terminate_all(struct sip_msg *msg, char *str_pv_client); + +static void __start_billing( + str *callid, str *from_uri, str *to_uri, str tags[2]); +static void __setup_billing( + str *callid, unsigned int h_entry, unsigned int h_id); static void __stop_billing(str *callid); static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type); -static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_msg *msg, int max_secs); -static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_msg *msg, double credit, - double cost_per_second, int initial_pulse, int final_pulse); +static call_t *__alloc_new_call_by_time( + credit_data_t *credit_data, struct sip_msg *msg, int max_secs); +static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, + struct sip_msg *msg, double credit, double cost_per_second, + int initial_pulse, int final_pulse); static void __notify_call_termination(sip_msg_t *msg); static void __free_call(call_t *call); static int __has_to_tag(struct sip_msg *msg); -static credit_data_t *__alloc_new_credit_data(str *client_id, credit_type_t type); -static credit_data_t *__get_or_create_credit_data_entry(str *client_id, credit_type_t type); +static credit_data_t *__alloc_new_credit_data( + str *client_id, credit_type_t type); +static credit_data_t *__get_or_create_credit_data_entry( + str *client_id, credit_type_t type); /* * control interface */ -void rpc_credit_control_stats(rpc_t* rpc, void* ctx); +void rpc_credit_control_stats(rpc_t *rpc, void *ctx); /* * Dialog management callback functions */ -static void __dialog_terminated_callback(struct dlg_cell *cell, int type, struct dlg_cb_params *params); -static void __dialog_confirmed_callback(struct dlg_cell *cell, int type, struct dlg_cb_params *params); -static void __dialog_created_callback(struct dlg_cell *cell, int type, struct dlg_cb_params *params); - +static void __dialog_terminated_callback( + struct dlg_cell *cell, int type, struct dlg_cb_params *params); +static void __dialog_confirmed_callback( + struct dlg_cell *cell, int type, struct dlg_cb_params *params); +static void __dialog_created_callback( + struct dlg_cell *cell, int type, struct dlg_cb_params *params); + +/* clang-format off */ static pv_export_t mod_pvs[] = { - { {"cnxcc", sizeof("cnxcc")-1 }, PVT_OTHER, __pv_get_calls, 0, __pv_parse_calls_param, 0, 0, 0 }, + { {"cnxcc", sizeof("cnxcc")-1 }, PVT_OTHER, __pv_get_calls, 0, + __pv_parse_calls_param, 0, 0, 0 }, { {0, 0}, 0, 0, 0, 0, 0, 0, 0 } }; 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_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_terminate_all", (cmd_function) __terminate_all, 1, fixup_pvar_null, - NULL, 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_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_terminate_all", (cmd_function) __terminate_all, 1, + fixup_pvar_null, NULL, ANY_ROUTE}, {0,0,0,0,0,0} }; @@ -160,45 +175,37 @@ static param_export_t params[] = { {"redis", STR_PARAM, &_data.redis_cnn_str.s }, { 0, 0, 0 } }; +/* clang-format on */ -static const char* rpc_active_clients_doc[2] = { - "List of clients with active calls", - NULL -}; +static const char *rpc_active_clients_doc[2] = { + "List of clients with active calls", NULL}; -static const char* rpc_check_client_stats_doc[2] = { - "Check specific client calls", - NULL -}; +static const char *rpc_check_client_stats_doc[2] = { + "Check specific client calls", NULL}; -static const char* rpc_kill_call_doc[2] = { - "Kill call using its call ID", - NULL -}; - -static const char* rpc_credit_control_stats_doc[2] = { - "List credit control stats", - NULL -}; +static const char *rpc_kill_call_doc[2] = {"Kill call using its call ID", NULL}; +static const char *rpc_credit_control_stats_doc[2] = { + "List credit control stats", NULL}; +/* clang-format off */ rpc_export_t cnxcc_rpc[] = { - { "cnxcc.active_clients", rpc_active_clients, rpc_active_clients_doc, 0}, - { "cnxcc.check_client", rpc_check_client_stats, rpc_check_client_stats_doc, 0}, - { "cnxcc.kill_call", rpc_kill_call, rpc_kill_call_doc, 0}, + { "cnxcc.active_clients", rpc_active_clients, rpc_active_clients_doc, 0}, + { "cnxcc.check_client", rpc_check_client_stats, rpc_check_client_stats_doc, 0}, + { "cnxcc.kill_call", rpc_kill_call, rpc_kill_call_doc, 0}, { "cnxcc.stats", rpc_credit_control_stats, rpc_credit_control_stats_doc, 0}, - { NULL, NULL, NULL, 0} + { NULL, NULL, NULL, 0} }; /* selects declaration */ select_row_t sel_declaration[] = { - { NULL, SEL_PARAM_STR, STR_STATIC_INIT("cnxcc"), sel_root, - SEL_PARAM_EXPECTED}, - { sel_root, SEL_PARAM_STR, STR_STATIC_INIT("channels"), sel_channels, - SEL_PARAM_EXPECTED|CONSUME_NEXT_STR|FIXUP_CALL}, - { sel_channels, SEL_PARAM_STR, STR_STATIC_INIT("count"), sel_channels_count, - 0}, - { NULL, SEL_PARAM_STR, STR_NULL, NULL, 0} + { NULL, SEL_PARAM_STR, STR_STATIC_INIT("cnxcc"), sel_root, + SEL_PARAM_EXPECTED}, + { sel_root, SEL_PARAM_STR, STR_STATIC_INIT("channels"), sel_channels, + SEL_PARAM_EXPECTED|CONSUME_NEXT_STR|FIXUP_CALL}, + { sel_channels, SEL_PARAM_STR, STR_STATIC_INIT("count"), sel_channels_count, + 0}, + { NULL, SEL_PARAM_STR, STR_NULL, NULL, 0} }; /** module exports */ @@ -216,19 +223,20 @@ struct module_exports exports = { NULL, __child_init /* per-child init function */ }; +/* clang-format on */ -static int __fixup_pvar(void** param, int param_no) { +static int __fixup_pvar(void **param, int param_no) +{ str var; - var.s = (char *) *param; + var.s = (char *)*param; var.len = strlen(var.s); - if (fixup_pvar_null(param, 1)) - { + if(fixup_pvar_null(param, 1)) { LM_ERR("Invalid PV [%.*s] as parameter\n", var.len, var.s); return E_CFG; } -/* + /* if (((pv_spec_t*)(*param))->setf == NULL) { LM_ERR("[%.*s] has to be writable\n", var.len, var.s); @@ -238,7 +246,8 @@ static int __fixup_pvar(void** param, int param_no) { return 0; } -static int __mod_init(void) { +static int __mod_init(void) +{ int len; char *chr; @@ -246,39 +255,44 @@ static int __mod_init(void) { _data.cs_route_number = route_get(&event_rt, "cnxcc:call-shutdown"); - if (_data.cs_route_number < 0) + if(_data.cs_route_number < 0) LM_INFO("No cnxcc:call-shutdown event route found\n"); - if (_data.cs_route_number > 0 && event_rt.rlist[_data.cs_route_number] == NULL) { + if(_data.cs_route_number > 0 + && event_rt.rlist[_data.cs_route_number] == NULL) { LM_INFO("cnxcc:call-shutdown route is empty\n"); - _data.cs_route_number = -1; + _data.cs_route_number = -1; } - if (_data.check_period <= 0) { + if(_data.check_period <= 0) { LM_INFO("credit_check_period cannot be less than 1 second\n"); return -1; } - if (_data.redis_cnn_str.s) + if(_data.redis_cnn_str.s) _data.redis_cnn_str.len = strlen(_data.redis_cnn_str.s); - _data.time.credit_data_by_client = shm_malloc(sizeof(struct str_hash_table)); + _data.time.credit_data_by_client = + shm_malloc(sizeof(struct str_hash_table)); _data.time.call_data_by_cid = shm_malloc(sizeof(struct str_hash_table)); - _data.money.credit_data_by_client = shm_malloc(sizeof(struct str_hash_table)); + _data.money.credit_data_by_client = + shm_malloc(sizeof(struct str_hash_table)); _data.money.call_data_by_cid = shm_malloc(sizeof(struct str_hash_table)); - _data.channel.credit_data_by_client = shm_malloc(sizeof(struct str_hash_table)); + _data.channel.credit_data_by_client = + shm_malloc(sizeof(struct str_hash_table)); _data.channel.call_data_by_cid = shm_malloc(sizeof(struct str_hash_table)); memset(_data.time.credit_data_by_client, 0, sizeof(struct str_hash_table)); memset(_data.time.call_data_by_cid, 0, sizeof(struct str_hash_table)); memset(_data.money.credit_data_by_client, 0, sizeof(struct str_hash_table)); memset(_data.money.call_data_by_cid, 0, sizeof(struct str_hash_table)); - memset(_data.channel.credit_data_by_client, 0, sizeof(struct str_hash_table)); + memset(_data.channel.credit_data_by_client, 0, + sizeof(struct str_hash_table)); memset(_data.channel.call_data_by_cid, 0, sizeof(struct str_hash_table)); - _data.stats = (stats_t *) shm_malloc(sizeof(stats_t)); + _data.stats = (stats_t *)shm_malloc(sizeof(stats_t)); - if (!_data.stats) { + if(!_data.stats) { LM_ERR("Error allocating shared memory stats\n"); return -1; } @@ -287,22 +301,22 @@ static int __mod_init(void) { _data.stats->dropped = 0; _data.stats->total = 0; - if (__init_hashtable(_data.time.credit_data_by_client) != 0) + if(__init_hashtable(_data.time.credit_data_by_client) != 0) return -1; - if (__init_hashtable(_data.time.call_data_by_cid) != 0) + if(__init_hashtable(_data.time.call_data_by_cid) != 0) return -1; - if (__init_hashtable(_data.money.credit_data_by_client) != 0) + if(__init_hashtable(_data.money.credit_data_by_client) != 0) return -1; - if (__init_hashtable(_data.money.call_data_by_cid) != 0) + if(__init_hashtable(_data.money.call_data_by_cid) != 0) return -1; - if (__init_hashtable(_data.channel.credit_data_by_client) != 0) + if(__init_hashtable(_data.channel.credit_data_by_client) != 0) return -1; - if (__init_hashtable(_data.channel.call_data_by_cid) != 0) + if(__init_hashtable(_data.channel.call_data_by_cid) != 0) return -1; @@ -318,110 +332,115 @@ static int __mod_init(void) { */ register_dummy_timers(NUMBER_OF_TIMERS); - if (rpc_register_array(cnxcc_rpc) != 0) { + if(rpc_register_array(cnxcc_rpc) != 0) { LM_ERR("Failed registering RPC commands\n"); return -1; } - if (load_dlg_api(&_dlgbinds) != 0) { + if(load_dlg_api(&_dlgbinds) != 0) { LM_ERR("Error loading dialog API\n"); - return -1; + return -1; } - _dlgbinds.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created_callback, NULL, NULL); + _dlgbinds.register_dlgcb( + NULL, DLGCB_CREATED, __dialog_created_callback, NULL, NULL); register_select_table(sel_declaration); // redis configuration setup - if (_data.redis_cnn_str.len <= 0) + if(_data.redis_cnn_str.len <= 0) return 0; // replace ";" for " ", so we can use a simpler pattern in sscanf() for(chr = _data.redis_cnn_str.s; *chr; chr++) - if (*chr == ';') + if(*chr == ';') *chr = ' '; memset(_data.redis_cnn_info.host, 0, sizeof(_data.redis_cnn_info.host)); - sscanf(_data.redis_cnn_str.s, "addr=%s port=%d db=%d", _data.redis_cnn_info.host, - &_data.redis_cnn_info.port, - &_data.redis_cnn_info.db); + sscanf(_data.redis_cnn_str.s, "addr=%s port=%d db=%d", + _data.redis_cnn_info.host, &_data.redis_cnn_info.port, + &_data.redis_cnn_info.db); len = strlen(_data.redis_cnn_info.host); // // Redis modparam validations // - if (len == 0) { + if(len == 0) { LM_ERR("invalid host address [%s]", _data.redis_cnn_info.host); return -1; } - if (_data.redis_cnn_info.port <= 0) { + if(_data.redis_cnn_info.port <= 0) { LM_ERR("invalid port number [%d]", _data.redis_cnn_info.port); return -1; } - if (_data.redis_cnn_info.db < 0) { - LM_ERR("invalid db number [%d]",_data.redis_cnn_info.db); + if(_data.redis_cnn_info.db < 0) { + LM_ERR("invalid db number [%d]", _data.redis_cnn_info.db); return -1; } - LM_INFO("Redis connection info: ip=[%s], port=[%d], database=[%d]", _data.redis_cnn_info.host, - _data.redis_cnn_info.port, - _data.redis_cnn_info.db); + LM_INFO("Redis connection info: ip=[%s], port=[%d], database=[%d]", + _data.redis_cnn_info.host, _data.redis_cnn_info.port, + _data.redis_cnn_info.db); - register_procs(3/* 2 timers + 1 redis async receiver */); + register_procs(3 /* 2 timers + 1 redis async receiver */); return 0; } -static int __child_init(int rank) { +static int __child_init(int rank) +{ int pid = 0; - if (rank!=PROC_INIT && rank!=PROC_MAIN && rank!=PROC_TCP_MAIN) { - if (_data.redis_cnn_str.len <= 0) + if(rank != PROC_INIT && rank != PROC_MAIN && rank != PROC_TCP_MAIN) { + if(_data.redis_cnn_str.len <= 0) return 0; _data.redis = redis_connect(_data.redis_cnn_info.host, - _data.redis_cnn_info.port, - _data.redis_cnn_info.db); + _data.redis_cnn_info.port, _data.redis_cnn_info.db); return (!_data.redis) ? -1 : 0; } - if (rank != PROC_MAIN) + if(rank != PROC_MAIN) return 0; - if(fork_dummy_timer(PROC_TIMER, "CNXCC TB TIMER", 1, check_calls_by_money, NULL, _data.check_period) < 0) { + if(fork_dummy_timer(PROC_TIMER, "CNXCC TB TIMER", 1, check_calls_by_money, + NULL, _data.check_period) + < 0) { LM_ERR("Failed registering TB TIMER routine as process\n"); return -1; } - if(fork_dummy_timer(PROC_TIMER, "CNXCC MB TIMER", 1, check_calls_by_time, NULL, _data.check_period) < 0) { + if(fork_dummy_timer(PROC_TIMER, "CNXCC MB TIMER", 1, check_calls_by_time, + NULL, _data.check_period) + < 0) { LM_ERR("Failed registering MB TIMER routine as process\n"); return -1; } - if (_data.redis_cnn_str.len <= 0) + if(_data.redis_cnn_str.len <= 0) return 0; pid = fork_process(PROC_NOCHLDINIT, "Redis Async receiver", 1); - if (pid < 0) { + if(pid < 0) { LM_ERR("error forking Redis receiver\n"); return -1; - } - else if (pid == 0) { + } else if(pid == 0) { _data.redis = redis_connect_async(_data.redis_cnn_info.host, - _data.redis_cnn_info.port, - _data.redis_cnn_info.db); + _data.redis_cnn_info.port, _data.redis_cnn_info.db); - return (!_data.redis) ? -1 : 0;; + return (!_data.redis) ? -1 : 0; + ; } return 0; } -static int __init_hashtable(struct str_hash_table *ht) { - if (__shm_str_hash_alloc(ht, HT_SIZE) != 0) { +static int __init_hashtable(struct str_hash_table *ht) +{ + if(__shm_str_hash_alloc(ht, HT_SIZE) != 0) { LM_ERR("Error allocating shared memory hashtable\n"); return -1; } @@ -430,53 +449,66 @@ static int __init_hashtable(struct str_hash_table *ht) { return 0; } -static void __dialog_created_callback(struct dlg_cell *cell, int type, struct dlg_cb_params *params) { +static void __dialog_created_callback( + struct dlg_cell *cell, int type, struct dlg_cb_params *params) +{ struct sip_msg *msg = NULL; msg = params->direction == SIP_REPLY ? params->rpl : params->req; - if (msg == NULL) { + if(msg == NULL) { LM_ERR("Error getting direction of SIP msg\n"); return; } - if (isflagset(msg, _data.ctrl_flag) == -1) { + if(isflagset(msg, _data.ctrl_flag) == -1) { LM_DBG("Flag is not set for this message. Ignoring\n"); return; } LM_DBG("Dialog created for CID [%.*s]\n", cell->callid.len, cell->callid.s); - _dlgbinds.register_dlgcb(cell, DLGCB_CONFIRMED, __dialog_confirmed_callback, NULL, NULL); - _dlgbinds.register_dlgcb(cell, DLGCB_TERMINATED|DLGCB_FAILED|DLGCB_EXPIRED, __dialog_terminated_callback, NULL, NULL); + _dlgbinds.register_dlgcb( + cell, DLGCB_CONFIRMED, __dialog_confirmed_callback, NULL, NULL); + _dlgbinds.register_dlgcb(cell, + DLGCB_TERMINATED | DLGCB_FAILED | DLGCB_EXPIRED, + __dialog_terminated_callback, NULL, NULL); __setup_billing(&cell->callid, cell->h_entry, cell->h_id); } -static void __dialog_confirmed_callback(struct dlg_cell *cell, int type, struct dlg_cb_params *params) { - LM_DBG("Dialog confirmed for CID [%.*s]\n", cell->callid.len, cell->callid.s); +static void __dialog_confirmed_callback( + struct dlg_cell *cell, int type, struct dlg_cb_params *params) +{ + LM_DBG("Dialog confirmed for CID [%.*s]\n", cell->callid.len, + cell->callid.s); __start_billing(&cell->callid, &cell->from_uri, &cell->to_uri, cell->tag); } -static void __dialog_terminated_callback(struct dlg_cell *cell, int type, struct dlg_cb_params *params) { - LM_DBG("Dialog terminated for CID [%.*s]\n", cell->callid.len, cell->callid.s); +static void __dialog_terminated_callback( + struct dlg_cell *cell, int type, struct dlg_cb_params *params) +{ + LM_DBG("Dialog terminated for CID [%.*s]\n", cell->callid.len, + cell->callid.s); __stop_billing(&cell->callid); } -static void __notify_call_termination(sip_msg_t *msg) { +static void __notify_call_termination(sip_msg_t *msg) +{ struct run_act_ctx ra_ctx; init_run_actions_ctx(&ra_ctx); //run_top_route(event_rt.rlist[_data.cs_route_number], msg, &ra_ctx); - if (run_actions(&ra_ctx, event_rt.rlist[_data.cs_route_number], msg) < 0) + if(run_actions(&ra_ctx, event_rt.rlist[_data.cs_route_number], msg) < 0) LM_ERR("Error executing cnxcc:call-shutdown route\n"); } -int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) { - struct str_hash_entry *cd_entry = NULL; +int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) +{ + struct str_hash_entry *cd_entry = NULL; hash_tables_t *hts = NULL; *credit_data = NULL; @@ -484,10 +516,11 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) { hts = &_data.money; cnxcc_lock(hts->lock); - cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len); + cd_entry = str_hash_get( + hts->credit_data_by_client, client_id->s, client_id->len); - if (cd_entry != NULL) { - *credit_data = cd_entry->u.p; + if(cd_entry != NULL) { + *credit_data = cd_entry->u.p; cnxcc_unlock(hts->lock); return 0; } @@ -498,10 +531,11 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) { hts = &_data.time; cnxcc_lock(hts->lock); - cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len); + cd_entry = str_hash_get( + hts->credit_data_by_client, client_id->s, client_id->len); - if (cd_entry != NULL) { - *credit_data = cd_entry->u.p; + if(cd_entry != NULL) { + *credit_data = cd_entry->u.p; cnxcc_unlock(hts->lock); return 0; } @@ -512,10 +546,11 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) { hts = &_data.channel; cnxcc_lock(hts->lock); - cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len); + cd_entry = str_hash_get( + hts->credit_data_by_client, client_id->s, client_id->len); - if (cd_entry != NULL) { - *credit_data = cd_entry->u.p; + if(cd_entry != NULL) { + *credit_data = cd_entry->u.p; cnxcc_unlock(hts->lock); return 0; } @@ -524,7 +559,8 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data) { return -1; } -int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) { +int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) +{ struct str_hash_entry *call_entry = NULL; *call = NULL; @@ -535,7 +571,7 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) { call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len); - if (call_entry != NULL) { + if(call_entry != NULL) { *call = call_entry->u.p; cnxcc_unlock((*hts)->lock); return 0; @@ -549,7 +585,7 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) { call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len); - if (call_entry != NULL) { + if(call_entry != NULL) { *call = call_entry->u.p; cnxcc_unlock((*hts)->lock); return 0; @@ -563,7 +599,7 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) { call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len); - if (call_entry != NULL) { + if(call_entry != NULL) { *call = call_entry->u.p; cnxcc_unlock((*hts)->lock); return 0; @@ -573,27 +609,29 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts) { return -1; } -static void __stop_billing(str *callid) { - struct str_hash_entry *cd_entry = NULL; - call_t *call = NULL; - hash_tables_t *hts = NULL; - credit_data_t *credit_data = NULL; +static void __stop_billing(str *callid) +{ + struct str_hash_entry *cd_entry = NULL; + call_t *call = NULL; + hash_tables_t *hts = NULL; + credit_data_t *credit_data = NULL; /* * Search call data by call-id */ - if (try_get_call_entry(callid, &call, &hts) != 0) { + if(try_get_call_entry(callid, &call, &hts) != 0) { LM_ERR("Call [%.*s] not found\n", callid->len, callid->s); return; } - if (call == NULL) { + if(call == NULL) { LM_ERR("[%.*s] call pointer is null\n", callid->len, callid->s); return; } - if (hts == NULL) { - LM_ERR("[%.*s] result hashtable pointer is null\n", callid->len, callid->s); + if(hts == NULL) { + LM_ERR("[%.*s] result hashtable pointer is null\n", callid->len, + callid->s); return; } @@ -602,17 +640,19 @@ static void __stop_billing(str *callid) { /* * Search credit_data by client_id */ - cd_entry = str_hash_get(hts->credit_data_by_client, call->client_id.s, call->client_id.len); + cd_entry = str_hash_get( + hts->credit_data_by_client, call->client_id.s, call->client_id.len); - if (cd_entry == NULL) { - LM_ERR("Credit data not found for CID [%.*s], client-ID [%.*s]\n", callid->len, callid->s, call->client_id.len, call->client_id.s); + if(cd_entry == NULL) { + LM_ERR("Credit data not found for CID [%.*s], client-ID [%.*s]\n", + callid->len, callid->s, call->client_id.len, call->client_id.s); cnxcc_unlock(hts->lock); return; } - credit_data = (credit_data_t *) cd_entry->u.p; + credit_data = (credit_data_t *)cd_entry->u.p; - if (credit_data == NULL) { + if(credit_data == NULL) { LM_ERR("[%.*s]: credit_data pointer is null\n", callid->len, callid->s); cnxcc_unlock(hts->lock); return; @@ -632,43 +672,48 @@ static void __stop_billing(str *callid) { cnxcc_lock(credit_data->lock); - LM_DBG("Call [%.*s] of client-ID [%.*s], ended\n", callid->len, callid->s, call->client_id.len, call->client_id.s); + LM_DBG("Call [%.*s] of client-ID [%.*s], ended\n", callid->len, callid->s, + call->client_id.len, call->client_id.s); /* * This call just ended and we need to remove it from the summ. */ - if (call->confirmed) { + if(call->confirmed) { credit_data->concurrent_calls--; credit_data->ended_calls_consumed_amount += call->consumed_amount; - if (_data.redis) { + if(_data.redis) { redis_incr_by_int(credit_data, "concurrent_calls", -1); - redis_incr_by_double(credit_data, "ended_calls_consumed_amount", call->consumed_amount); + redis_incr_by_double(credit_data, "ended_calls_consumed_amount", + call->consumed_amount); } } credit_data->number_of_calls--; - if (_data.redis) + if(_data.redis) redis_incr_by_int(credit_data, "number_of_calls", -1); - if (credit_data->concurrent_calls < 0) { - LM_ERR("[BUG]: number of concurrent calls dropped to negative value: %d\n", credit_data->concurrent_calls); + if(credit_data->concurrent_calls < 0) { + LM_ERR("[BUG]: number of concurrent calls dropped to negative value: " + "%d\n", + credit_data->concurrent_calls); } - if (credit_data->number_of_calls < 0) { - LM_ERR("[BUG]: number of calls dropped to negative value: %d\n", credit_data->number_of_calls); + if(credit_data->number_of_calls < 0) { + LM_ERR("[BUG]: number of calls dropped to negative value: %d\n", + credit_data->number_of_calls); } /* * Remove (and free) the call from the list of calls of the current credit_data */ clist_rm(call, next, prev); - + /* return if credit_data is being deallocated. * the call and the credit data will be freed by terminate_all_calls() */ - if (credit_data->deallocating) { + if(credit_data->deallocating) { return; } @@ -678,13 +723,15 @@ static void __stop_billing(str *callid) { * This way, we can save memory for useful clients. * */ - if (credit_data->number_of_calls == 0) { - LM_DBG("Removing client [%.*s] and its calls from the list\n", credit_data->call_list->client_id.len, credit_data->call_list->client_id.s); + if(credit_data->number_of_calls == 0) { + LM_DBG("Removing client [%.*s] and its calls from the list\n", + credit_data->call_list->client_id.len, + credit_data->call_list->client_id.s); credit_data->deallocating = 1; cnxcc_lock(hts->lock); - if (_data.redis) { + if(_data.redis) { redis_clean_up_if_last(credit_data); shm_free(credit_data->str_id); } @@ -721,29 +768,33 @@ static void __stop_billing(str *callid) { cnxcc_unlock(credit_data->lock); } -static void __setup_billing(str *callid, unsigned int h_entry, unsigned int h_id) { - call_t *call = NULL; - hash_tables_t *hts = NULL; +static void __setup_billing( + str *callid, unsigned int h_entry, unsigned int h_id) +{ + call_t *call = NULL; + hash_tables_t *hts = NULL; - LM_DBG("Creating dialog for [%.*s], h_id [%u], h_entry [%u]\n", callid->len, callid->s, h_id, h_entry); + LM_DBG("Creating dialog for [%.*s], h_id [%u], h_entry [%u]\n", callid->len, + callid->s, h_id, h_entry); -// cnxcc_lock(&_data); + // cnxcc_lock(&_data); /* * Search call data by call-id */ - if (try_get_call_entry(callid, &call, &hts) != 0) { + if(try_get_call_entry(callid, &call, &hts) != 0) { LM_ERR("Call [%.*s] not found\n", callid->len, callid->s); return; } - if (call == NULL) { + if(call == NULL) { LM_ERR("[%.*s] call pointer is null\n", callid->len, callid->s); return; } - if (hts == NULL) { - LM_ERR("[%.*s] result hashtable pointer is null\n", callid->len, callid->s); + if(hts == NULL) { + LM_ERR("[%.*s] result hashtable pointer is null\n", callid->len, + callid->s); return; } @@ -759,39 +810,43 @@ static void __setup_billing(str *callid, unsigned int h_entry, unsigned int h_id cnxcc_lock(call->lock); - call->dlg_h_entry = h_entry; - call->dlg_h_id = h_id; + call->dlg_h_entry = h_entry; + call->dlg_h_id = h_id; - LM_DBG("Call [%.*s] from client [%.*s], created\n", callid->len, callid->s, call->client_id.len, call->client_id.s); + LM_DBG("Call [%.*s] from client [%.*s], created\n", callid->len, callid->s, + call->client_id.len, call->client_id.s); cnxcc_unlock(call->lock); } -static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2]) { - struct str_hash_entry *cd_entry = NULL; - call_t *call = NULL; - hash_tables_t *hts = NULL; - credit_data_t *credit_data = NULL; +static void __start_billing( + str *callid, str *from_uri, str *to_uri, str tags[2]) +{ + struct str_hash_entry *cd_entry = NULL; + call_t *call = NULL; + hash_tables_t *hts = NULL; + credit_data_t *credit_data = NULL; LM_DBG("Billing started for call [%.*s]\n", callid->len, callid->s); -// cnxcc_lock(&_data); + // cnxcc_lock(&_data); /* * Search call data by call-id */ - if (try_get_call_entry(callid, &call, &hts) != 0) { + if(try_get_call_entry(callid, &call, &hts) != 0) { LM_ERR("Call [%.*s] not found\n", callid->len, callid->s); return; } - if (call == NULL) { + if(call == NULL) { LM_ERR("[%.*s] call pointer is null\n", callid->len, callid->s); return; } - if (hts == NULL) { - LM_ERR("[%.*s] result hashtable pointer is null", callid->len, callid->s); + if(hts == NULL) { + LM_ERR("[%.*s] result hashtable pointer is null", callid->len, + callid->s); return; } @@ -800,17 +855,19 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2] /* * Search credit_data by client_id */ - cd_entry = str_hash_get(hts->credit_data_by_client, call->client_id.s, call->client_id.len); + cd_entry = str_hash_get( + hts->credit_data_by_client, call->client_id.s, call->client_id.len); - if (cd_entry == NULL) { - LM_ERR("Credit data not found for CID [%.*s], client-ID [%.*s]\n", callid->len, callid->s, call->client_id.len, call->client_id.s); + if(cd_entry == NULL) { + LM_ERR("Credit data not found for CID [%.*s], client-ID [%.*s]\n", + callid->len, callid->s, call->client_id.len, call->client_id.s); cnxcc_unlock(hts->lock); return; } - credit_data = (credit_data_t *) cd_entry->u.p; + credit_data = (credit_data_t *)cd_entry->u.p; - if (credit_data == NULL) { + if(credit_data == NULL) { LM_ERR("[%.*s]: credit_data pointer is null\n", callid->len, callid->s); cnxcc_unlock(hts->lock); return; @@ -827,23 +884,27 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2] */ credit_data->concurrent_calls++; - if (_data.redis) + if(_data.redis) redis_incr_by_int(credit_data, "concurrent_calls", 1); - if (credit_data->max_amount == 0) { - credit_data->max_amount = call->max_amount; // first time setup + if(credit_data->max_amount == 0) { + credit_data->max_amount = call->max_amount; // first time setup - if (_data.redis) - redis_insert_double_value(credit_data, "max_amount", credit_data->max_amount); + if(_data.redis) + redis_insert_double_value( + credit_data, "max_amount", credit_data->max_amount); } - if (call->max_amount > credit_data->max_amount) { - LM_ALERT("Maximum-talk-time/credit changed, maybe a credit reload? %f > %f. Client [%.*s]\n", call->max_amount, credit_data->max_amount, - call->client_id.len, call->client_id.s); + if(call->max_amount > credit_data->max_amount) { + LM_ALERT("Maximum-talk-time/credit changed, maybe a credit reload? %f " + "> %f. Client [%.*s]\n", + call->max_amount, credit_data->max_amount, call->client_id.len, + call->client_id.s); - if (_data.redis) - redis_insert_double_value(credit_data, "max_amount", call->max_amount - credit_data->max_amount); + if(_data.redis) + redis_insert_double_value(credit_data, "max_amount", + call->max_amount - credit_data->max_amount); credit_data->max_amount += call->max_amount - credit_data->max_amount; } @@ -860,7 +921,7 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2] /* * Store from-tag value */ - if (shm_str_dup(&call->sip_data.from_tag, &tags[0]) != 0) { + if(shm_str_dup(&call->sip_data.from_tag, &tags[0]) != 0) { LM_ERR("No more pkg memory\n"); goto exit; } @@ -868,21 +929,22 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2] /* * Store to-tag value */ - if (shm_str_dup(&call->sip_data.to_tag, &tags[1]) != 0) { + if(shm_str_dup(&call->sip_data.to_tag, &tags[1]) != 0) { LM_ERR("No more pkg memory\n"); goto exit; } - if(shm_str_dup(&call->sip_data.from_uri, from_uri) != 0 || - shm_str_dup(&call->sip_data.to_uri , to_uri) != 0) { + if(shm_str_dup(&call->sip_data.from_uri, from_uri) != 0 + || shm_str_dup(&call->sip_data.to_uri, to_uri) != 0) { LM_ERR("No more pkg memory\n"); goto exit; } - call->start_timestamp = get_current_timestamp(); - call->confirmed = TRUE; + call->start_timestamp = get_current_timestamp(); + call->confirmed = TRUE; - LM_DBG("Call [%.*s] from client [%.*s], confirmed. from=<%.*s>;tag=%.*s, to=<%.*s>;tag=%.*s\n", + LM_DBG("Call [%.*s] from client [%.*s], confirmed. from=<%.*s>;tag=%.*s, " + "to=<%.*s>;tag=%.*s\n", callid->len, callid->s, call->client_id.len, call->client_id.s, call->sip_data.from_uri.len, call->sip_data.from_uri.s, call->sip_data.from_tag.len, call->sip_data.from_tag.s, @@ -894,39 +956,40 @@ static void __start_billing(str *callid, str *from_uri, str *to_uri, str tags[2] // must be called with lock held on credit_data /* terminate all calls and remove credit_data */ -void terminate_all_calls(credit_data_t *credit_data) { - call_t *call = NULL, - *tmp = NULL; +void terminate_all_calls(credit_data_t *credit_data) +{ + call_t *call = NULL, *tmp = NULL; struct str_hash_entry *cd_entry = NULL; - hash_tables_t *hts = NULL; + hash_tables_t *hts = NULL; switch(credit_data->type) { - case CREDIT_MONEY: - hts = &_data.money; - break; - case CREDIT_TIME: - hts = &_data.time; - break; - case CREDIT_CHANNEL: - hts = &_data.channel; - break; - default: - LM_ERR("BUG: Something went terribly wrong\n"); - return; - } + case CREDIT_MONEY: + hts = &_data.money; + break; + case CREDIT_TIME: + hts = &_data.time; + break; + case CREDIT_CHANNEL: + hts = &_data.channel; + break; + default: + LM_ERR("BUG: Something went terribly wrong\n"); + return; + } cd_entry = str_hash_get(hts->credit_data_by_client, credit_data->call_list->client_id.s, credit_data->call_list->client_id.len); - if(cd_entry==NULL) { + if(cd_entry == NULL) { LM_WARN("credit data itme not found\n"); return; } credit_data->deallocating = 1; - clist_foreach_safe(credit_data->call_list, call, tmp, next) { - if(call->sip_data.callid.s!=NULL) { + clist_foreach_safe(credit_data->call_list, call, tmp, next) + { + if(call->sip_data.callid.s != NULL) { LM_DBG("Killing call with CID [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s); @@ -943,7 +1006,7 @@ void terminate_all_calls(credit_data_t *credit_data) { cnxcc_lock(hts->lock); - if (_data.redis) { + if(_data.redis) { redis_clean_up_if_last(credit_data); shm_free(credit_data->str_id); } @@ -975,23 +1038,30 @@ void terminate_all_calls(credit_data_t *credit_data) { /* * WARNING: When calling this function, the proper lock should have been acquired */ -static void __free_call(call_t *call) { +static void __free_call(call_t *call) +{ struct str_hash_entry *e = NULL; - if(call->sip_data.callid.s==NULL) + if(call->sip_data.callid.s == NULL) return; - LM_DBG("Freeing call [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s); - e = str_hash_get(_data.money.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len); + LM_DBG("Freeing call [%.*s]\n", call->sip_data.callid.len, + call->sip_data.callid.s); + e = str_hash_get(_data.money.call_data_by_cid, call->sip_data.callid.s, + call->sip_data.callid.len); - if (e == NULL) { - e = str_hash_get(_data.time.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len); + if(e == NULL) { + e = str_hash_get(_data.time.call_data_by_cid, call->sip_data.callid.s, + call->sip_data.callid.len); - if (e == NULL) { - e = str_hash_get(_data.channel.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len); + if(e == NULL) { + e = str_hash_get(_data.channel.call_data_by_cid, + call->sip_data.callid.s, call->sip_data.callid.len); - if (e == NULL) { - LM_ERR("Call [%.*s] not found. Couldn't be able to free it from hashtable", call->sip_data.callid.len, call->sip_data.callid.s); + if(e == NULL) { + LM_ERR("Call [%.*s] not found. Couldn't be able to free it " + "from hashtable", + call->sip_data.callid.len, call->sip_data.callid.s); return; } } @@ -1014,54 +1084,58 @@ static void __free_call(call_t *call) { /* * WARNING: When calling this function, the proper lock should have been acquired */ -static void __free_credit_data_hash_entry(struct str_hash_entry *e) { +static void __free_credit_data_hash_entry(struct str_hash_entry *e) +{ shm_free(e->key.s); -// shm_free(((credit_data_t *) e->u.p)->call); + // shm_free(((credit_data_t *) e->u.p)->call); shm_free(e->u.p); shm_free(e); } -static int __shm_str_hash_alloc(struct str_hash_table *ht, int size) { - ht->table = shm_malloc(sizeof(struct str_hash_head) * size); +static int __shm_str_hash_alloc(struct str_hash_table *ht, int size) +{ + ht->table = shm_malloc(sizeof(struct str_hash_head) * size); - if (!ht->table) + if(!ht->table) return -1; - ht->size = size; + ht->size = size; return 0; } -int terminate_call(call_t *call) { +int terminate_call(call_t *call) +{ sip_msg_t *dmsg = NULL; sip_data_t *data = NULL; dlg_cell_t *cell; - LM_DBG("Got kill signal for call [%.*s] client [%.*s] h_id [%u] h_entry [%u]. Dropping it now\n", - call->sip_data.callid.len, - call->sip_data.callid.s, - call->client_id.len, - call->client_id.s, - call->dlg_h_id, - call->dlg_h_entry); - - data = &call->sip_data; - if (faked_msg_init_with_dlg_info(&data->callid, &data->from_uri, &data->from_tag, - &data->to_uri, &data->to_tag, &dmsg) != 0) { - LM_ERR("[%.*s]: error generating faked sip message\n", data->callid.len, data->callid.s); + LM_DBG("Got kill signal for call [%.*s] client [%.*s] h_id [%u] h_entry " + "[%u]. Dropping it now\n", + call->sip_data.callid.len, call->sip_data.callid.s, + call->client_id.len, call->client_id.s, call->dlg_h_id, + call->dlg_h_entry); + + data = &call->sip_data; + if(faked_msg_init_with_dlg_info(&data->callid, &data->from_uri, + &data->from_tag, &data->to_uri, &data->to_tag, &dmsg) + != 0) { + LM_ERR("[%.*s]: error generating faked sip message\n", data->callid.len, + data->callid.s); goto error; } cell = _dlgbinds.get_dlg(dmsg); - if (!cell) { - LM_ERR("[%.*s]: cannot get dialog\n", data->callid.len, data->callid.s); - goto error; + if(!cell) { + LM_ERR("[%.*s]: cannot get dialog\n", data->callid.len, data->callid.s); + goto error; } - if (!_dlgbinds.terminate_dlg(cell, NULL)) { - LM_DBG("dlg_end_dlg sent to call [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s); + if(!_dlgbinds.terminate_dlg(cell, NULL)) { + LM_DBG("dlg_end_dlg sent to call [%.*s]\n", call->sip_data.callid.len, + call->sip_data.callid.s); - if (_data.cs_route_number >= 0) + if(_data.cs_route_number >= 0) __notify_call_termination(dmsg); return 0; } @@ -1071,28 +1145,30 @@ int terminate_call(call_t *call) { return -1; } -static credit_data_t *__get_or_create_credit_data_entry(str *client_id, credit_type_t type) { +static credit_data_t *__get_or_create_credit_data_entry( + str *client_id, credit_type_t type) +{ struct str_hash_table *sht = NULL; struct hash_tables *ht; struct str_hash_entry *e = NULL; credit_data_t *credit_data = NULL; switch(type) { - case CREDIT_MONEY: - sht = _data.money.credit_data_by_client; - ht = &_data.money; - break; - case CREDIT_TIME: - sht = _data.time.credit_data_by_client; - ht = &_data.time; - break; - case CREDIT_CHANNEL: - sht = _data.channel.credit_data_by_client; - ht = &_data.channel; - break; - default: - LM_ERR("BUG: Something went terribly wrong\n"); - return NULL; + case CREDIT_MONEY: + sht = _data.money.credit_data_by_client; + ht = &_data.money; + break; + case CREDIT_TIME: + sht = _data.time.credit_data_by_client; + ht = &_data.time; + break; + case CREDIT_CHANNEL: + sht = _data.channel.credit_data_by_client; + ht = &_data.channel; + break; + default: + LM_ERR("BUG: Something went terribly wrong\n"); + return NULL; } cnxcc_lock(ht->lock); @@ -1102,20 +1178,20 @@ static credit_data_t *__get_or_create_credit_data_entry(str *client_id, credit_t /* * Alloc new call_array_t if it doesn't exist */ - if (e != NULL) + if(e != NULL) LM_DBG("Found key %.*s in hash table\n", e->key.len, e->key.s); - else if (e == NULL) { + else if(e == NULL) { e = shm_malloc(sizeof(struct str_hash_entry)); - if (e == NULL) + if(e == NULL) goto no_memory; - if (shm_str_dup(&e->key, client_id) != 0) + if(shm_str_dup(&e->key, client_id) != 0) goto no_memory; e->u.p = credit_data = __alloc_new_credit_data(client_id, type); e->flags = 0; - if (credit_data == NULL) + if(credit_data == NULL) goto no_memory; cnxcc_lock(ht->lock); @@ -1125,26 +1201,29 @@ static credit_data_t *__get_or_create_credit_data_entry(str *client_id, credit_t LM_DBG("Credit entry didn't exist. Allocated new entry [%p]\n", e); } - return (credit_data_t *) e->u.p; + return (credit_data_t *)e->u.p; no_memory: LM_ERR("No shared memory left\n"); return NULL; } -static credit_data_t *__alloc_new_credit_data(str *client_id, credit_type_t type) { - credit_data_t *credit_data = shm_malloc(sizeof(credit_data_t));; +static credit_data_t *__alloc_new_credit_data( + str *client_id, credit_type_t type) +{ + credit_data_t *credit_data = shm_malloc(sizeof(credit_data_t)); + ; - if (credit_data == NULL) + if(credit_data == NULL) goto no_memory; - + memset(credit_data, 0, sizeof(credit_data_t)); cnxcc_lock_init(credit_data->lock); credit_data->call_list = shm_malloc(sizeof(call_t)); - if (credit_data->call_list == NULL) + if(credit_data->call_list == NULL) goto no_memory; clist_init(credit_data->call_list, next, prev); @@ -1154,87 +1233,90 @@ static credit_data_t *__alloc_new_credit_data(str *client_id, credit_type_t type * This will be used later to get the credit_data_t of the * call when it is being searched by call ID. */ - if (shm_str_dup(&credit_data->call_list->client_id, client_id) != 0) + if(shm_str_dup(&credit_data->call_list->client_id, client_id) != 0) goto no_memory; - if (_data.redis) { + if(_data.redis) { credit_data->str_id = shm_malloc(client_id->len + 1); - if (!credit_data->str_id) + if(!credit_data->str_id) goto no_memory; memset(credit_data->str_id, 0, client_id->len + 1); - snprintf(credit_data->str_id, client_id->len + 1, "%.*s", client_id->len, client_id->s); + snprintf(credit_data->str_id, client_id->len + 1, "%.*s", + client_id->len, client_id->s); } - credit_data->max_amount = 0; + credit_data->max_amount = 0; credit_data->concurrent_calls = 0; credit_data->consumed_amount = 0; - credit_data->ended_calls_consumed_amount= 0; + credit_data->ended_calls_consumed_amount = 0; credit_data->number_of_calls = 0; credit_data->type = type; credit_data->deallocating = 0; - if (!_data.redis) + if(!_data.redis) return credit_data; - if (redis_get_or_create_credit_data(credit_data) < 0) + if(redis_get_or_create_credit_data(credit_data) < 0) goto error; return credit_data; no_memory: - LM_ERR("No shared memory left\n"); + LM_ERR("No shared memory left\n"); error: - return NULL; + return NULL; } -static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_msg *msg, - double credit, double cost_per_second, int initial_pulse, int final_pulse) { +static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, + struct sip_msg *msg, double credit, double cost_per_second, + int initial_pulse, int final_pulse) +{ call_t *call = NULL; cnxcc_lock(credit_data->lock); - if (credit_data->call_list == NULL) { + if(credit_data->call_list == NULL) { LM_ERR("Credit data call list is NULL\n"); goto error; } call = shm_malloc(sizeof(call_t)); - if (call == NULL) { + if(call == NULL) { LM_ERR("No shared memory left\n"); goto error; } - if ((!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) != 0) || - shm_str_dup(&call->sip_data.callid, &msg->callid->body) != 0 ) { + if((!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) != 0) + || shm_str_dup(&call->sip_data.callid, &msg->callid->body) != 0) { LM_ERR("Error processing CALLID hdr\n"); goto error; } - call->sip_data.to_uri.s = NULL; - call->sip_data.to_uri.len = 0; - call->sip_data.to_tag.s = NULL; - call->sip_data.to_tag.len = 0; + call->sip_data.to_uri.s = NULL; + call->sip_data.to_uri.len = 0; + call->sip_data.to_tag.s = NULL; + call->sip_data.to_tag.len = 0; - call->sip_data.from_uri.s = NULL; - call->sip_data.from_uri.len = 0; - call->sip_data.from_tag.s = NULL; - call->sip_data.from_tag.len = 0; + call->sip_data.from_uri.s = NULL; + call->sip_data.from_uri.len = 0; + call->sip_data.from_tag.s = NULL; + call->sip_data.from_tag.len = 0; call->consumed_amount = initial_pulse * cost_per_second; - call->confirmed = FALSE; + call->confirmed = FALSE; call->max_amount = credit; - call->money_based.cost_per_second = cost_per_second; - call->money_based.initial_pulse = initial_pulse; - call->money_based.final_pulse = final_pulse; + call->money_based.cost_per_second = cost_per_second; + call->money_based.initial_pulse = initial_pulse; + call->money_based.final_pulse = final_pulse; /* * Reference the client_id from the root of the list */ - call->client_id.s = credit_data->call_list->client_id.s; - call->client_id.len = credit_data->call_list->client_id.len; + call->client_id.s = credit_data->call_list->client_id.s; + call->client_id.len = credit_data->call_list->client_id.len; /* * Insert the newly created call to the list of calls @@ -1247,12 +1329,13 @@ static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_ * Increase the number of calls for this client. This call is not yet confirmed. */ credit_data->number_of_calls++; - if (_data.redis) + if(_data.redis) redis_incr_by_int(credit_data, "number_of_calls", 1); cnxcc_unlock(credit_data->lock); - LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, call->client_id.s); + LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, + call->client_id.s); return call; @@ -1261,47 +1344,49 @@ static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_ return NULL; } -static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_msg *msg, int max_secs) { +static call_t *__alloc_new_call_by_time( + credit_data_t *credit_data, struct sip_msg *msg, int max_secs) +{ call_t *call = NULL; cnxcc_lock(credit_data->lock); - if (credit_data->call_list == NULL) { + if(credit_data->call_list == NULL) { LM_ERR("Credit data call list is NULL\n"); goto error; } call = shm_malloc(sizeof(call_t)); - if (call == NULL) { + if(call == NULL) { LM_ERR("No shared memory left\n"); goto error; } - if ( (!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) != 0) || - shm_str_dup(&call->sip_data.callid, &msg->callid->body) != 0 ) { + if((!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) != 0) + || shm_str_dup(&call->sip_data.callid, &msg->callid->body) != 0) { LM_ERR("Error processing CALLID hdr\n"); goto error; } - - call->sip_data.to_uri.s = NULL; - call->sip_data.to_uri.len = 0; - call->sip_data.to_tag.s = NULL; - call->sip_data.to_tag.len = 0; - call->sip_data.from_uri.s = NULL; - call->sip_data.from_uri.len = 0; - call->sip_data.from_tag.s = NULL; - call->sip_data.from_tag.len = 0; + call->sip_data.to_uri.s = NULL; + call->sip_data.to_uri.len = 0; + call->sip_data.to_tag.s = NULL; + call->sip_data.to_tag.len = 0; - call->consumed_amount = 0; - call->confirmed = FALSE; - call->max_amount = max_secs; + call->sip_data.from_uri.s = NULL; + call->sip_data.from_uri.len = 0; + call->sip_data.from_tag.s = NULL; + call->sip_data.from_tag.len = 0; + + call->consumed_amount = 0; + call->confirmed = FALSE; + call->max_amount = max_secs; /* * Reference the client_id from the root of the list */ - call->client_id.s = credit_data->call_list->client_id.s; - call->client_id.len = credit_data->call_list->client_id.len; + call->client_id.s = credit_data->call_list->client_id.s; + call->client_id.len = credit_data->call_list->client_id.len; /* * Insert the newly created call to the list of calls @@ -1314,12 +1399,13 @@ static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_m * Increase the number of calls for this client. This call is not yet confirmed. */ credit_data->number_of_calls++; - if (_data.redis) + if(_data.redis) redis_incr_by_int(credit_data, "number_of_calls", 1); cnxcc_unlock(credit_data->lock); - LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, call->client_id.s); + LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, + call->client_id.s); return call; @@ -1328,47 +1414,49 @@ static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_m return NULL; } -static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_msg *msg, int max_chan) { +static call_t *alloc_new_call_by_channel( + credit_data_t *credit_data, struct sip_msg *msg, int max_chan) +{ call_t *call = NULL; cnxcc_lock(credit_data->lock); - if (credit_data->call_list == NULL) { + if(credit_data->call_list == NULL) { LM_ERR("Credit data call list is NULL\n"); goto error; } call = shm_malloc(sizeof(call_t)); - if (call == NULL) { + if(call == NULL) { LM_ERR("No shared memory left\n"); goto error; } - if ( (!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) != 0) || - shm_str_dup(&call->sip_data.callid, &msg->callid->body) != 0 ) { + if((!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) != 0) + || shm_str_dup(&call->sip_data.callid, &msg->callid->body) != 0) { LM_ERR("Error processing CALLID hdr\n"); goto error; } - call->sip_data.to_uri.s = NULL; - call->sip_data.to_uri.len = 0; - call->sip_data.to_tag.s = NULL; - call->sip_data.to_tag.len = 0; + call->sip_data.to_uri.s = NULL; + call->sip_data.to_uri.len = 0; + call->sip_data.to_tag.s = NULL; + call->sip_data.to_tag.len = 0; - call->sip_data.from_uri.s = NULL; - call->sip_data.from_uri.len = 0; - call->sip_data.from_tag.s = NULL; - call->sip_data.from_tag.len = 0; + call->sip_data.from_uri.s = NULL; + call->sip_data.from_uri.len = 0; + call->sip_data.from_tag.s = NULL; + call->sip_data.from_tag.len = 0; - call->consumed_amount = 0; - call->confirmed = FALSE; - call->max_amount = max_chan; + call->consumed_amount = 0; + call->confirmed = FALSE; + call->max_amount = max_chan; /* * Reference the client_id from the root of the list */ - call->client_id.s = credit_data->call_list->client_id.s; - call->client_id.len = credit_data->call_list->client_id.len; + call->client_id.s = credit_data->call_list->client_id.s; + call->client_id.len = credit_data->call_list->client_id.len; /* * Insert the newly created call to the list of calls @@ -1381,12 +1469,13 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_ * Increase the number of calls for this client. This call is not yet confirmed. */ credit_data->number_of_calls++; - if (_data.redis) + if(_data.redis) redis_incr_by_int(credit_data, "number_of_calls", 1); cnxcc_unlock(credit_data->lock); - LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, call->client_id.s); + LM_DBG("New call allocated for client [%.*s]\n", call->client_id.len, + call->client_id.s); return call; @@ -1396,47 +1485,52 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_ return NULL; } -static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type) { - struct str_hash_table *ht = NULL; +static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type) +{ + struct str_hash_table *ht = NULL; cnxcc_lock_t lock; - struct str_hash_entry *e = NULL; + struct str_hash_entry *e = NULL; switch(type) { - case CREDIT_MONEY: - ht = _data.money.call_data_by_cid; - lock = _data.money.lock; - break; - case CREDIT_TIME: - ht = _data.time.call_data_by_cid; - lock = _data.time.lock; - break; - case CREDIT_CHANNEL: - ht = _data.channel.call_data_by_cid; - lock = _data.channel.lock; - break; - default: - LM_ERR("Something went terribly wrong\n"); - return -1; + case CREDIT_MONEY: + ht = _data.money.call_data_by_cid; + lock = _data.money.lock; + break; + case CREDIT_TIME: + ht = _data.time.call_data_by_cid; + lock = _data.time.lock; + break; + case CREDIT_CHANNEL: + ht = _data.channel.call_data_by_cid; + lock = _data.channel.lock; + break; + default: + LM_ERR("Something went terribly wrong\n"); + return -1; } e = str_hash_get(ht, cid->s, cid->len); - if (e != NULL) { + if(e != NULL) { LM_DBG("e != NULL\n"); - call_t *value = (call_t *) e->u.p; - if (value == NULL) { + call_t *value = (call_t *)e->u.p; + if(value == NULL) { LM_ERR("Value of CID [%.*s] is NULL\n", cid->len, cid->s); return -1; } - LM_WARN("value cid: len=%d | value [%.*s]", value->sip_data.callid.len, value->sip_data.callid.len, value->sip_data.callid.s); + LM_WARN("value cid: len=%d | value [%.*s]", value->sip_data.callid.len, + value->sip_data.callid.len, value->sip_data.callid.s); LM_WARN("added cid: len=%d | value [%.*s]", cid->len, cid->len, cid->s); - if (value->sip_data.callid.len != cid->len || - strncasecmp(value->sip_data.callid.s, cid->s, cid->len) != 0) { - LM_ERR("Value of CID is [%.*s] and differs from value being added [%.*s]\n", cid->len, cid->s, - value->sip_data.callid.len, value->sip_data.callid.s); + if(value->sip_data.callid.len != cid->len + || strncasecmp(value->sip_data.callid.s, cid->s, cid->len) + != 0) { + LM_ERR("Value of CID is [%.*s] and differs from value being added " + "[%.*s]\n", + cid->len, cid->s, value->sip_data.callid.len, + value->sip_data.callid.s); return -1; } @@ -1446,17 +1540,17 @@ static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type) { e = shm_malloc(sizeof(struct str_hash_entry)); - if (e == NULL) { + if(e == NULL) { LM_ERR("No shared memory left\n"); return -1; } - if (shm_str_dup(&e->key, cid) != 0) { + if(shm_str_dup(&e->key, cid) != 0) { LM_ERR("No shared memory left\n"); return -1; } - e->u.p = call; + e->u.p = call; cnxcc_lock(lock); str_hash_add(ht, e); @@ -1465,15 +1559,18 @@ static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type) { return 0; } -static inline void set_ctrl_flag(struct sip_msg* msg) { - if (_data.ctrl_flag != -1) { +static inline void set_ctrl_flag(struct sip_msg *msg) +{ + if(_data.ctrl_flag != -1) { LM_DBG("Flag set!\n"); setflag(msg, _data.ctrl_flag); } } -static inline int get_pv_value(struct sip_msg* msg, pv_spec_t* spec, pv_value_t* value) { - if (pv_get_spec_value(msg, spec, value) != 0) { +static inline int get_pv_value( + struct sip_msg *msg, pv_spec_t *spec, pv_value_t *value) +{ + if(pv_get_spec_value(msg, spec, value) != 0) { LM_ERR("Can't get PV's value\n"); return -1; } @@ -1481,115 +1578,122 @@ static inline int get_pv_value(struct sip_msg* msg, pv_spec_t* spec, pv_value_t* return 0; } -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) { - credit_data_t *credit_data = NULL; - call_t *call = NULL; - - pv_spec_t *client_id_spec = (pv_spec_t *) str_pv_client, - *credit_spec = (pv_spec_t *) str_pv_credit, - *cps_spec = (pv_spec_t *) str_pv_cps, - *initial_pulse_spec = (pv_spec_t *) str_pv_inip, - *final_pulse_spec = (pv_spec_t *) str_pv_finp; - - pv_value_t client_id_val, - credit_val, - cps_val, - initial_pulse_val, +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) +{ + credit_data_t *credit_data = NULL; + call_t *call = NULL; + + pv_spec_t *client_id_spec = (pv_spec_t *)str_pv_client, + *credit_spec = (pv_spec_t *)str_pv_credit, + *cps_spec = (pv_spec_t *)str_pv_cps, + *initial_pulse_spec = (pv_spec_t *)str_pv_inip, + *final_pulse_spec = (pv_spec_t *)str_pv_finp; + + pv_value_t client_id_val, credit_val, cps_val, initial_pulse_val, final_pulse_val; - double credit = 0, - cost_per_second = 0; + double credit = 0, cost_per_second = 0; - unsigned int initial_pulse = 0, - final_pulse = 0; + unsigned int initial_pulse = 0, final_pulse = 0; - if (msg->first_line.type == SIP_REQUEST && msg->first_line.u.request.method_value == METHOD_INVITE) { - if (__has_to_tag(msg)) { + if(msg->first_line.type == SIP_REQUEST + && msg->first_line.u.request.method_value == METHOD_INVITE) { + if(__has_to_tag(msg)) { LM_ERR("INVITE is a reINVITE\n"); return -1; } - if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { + if(pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { LM_ERR("Can't get client_id's value\n"); return -1; } - if (pv_get_spec_value(msg, credit_spec, &credit_val) != 0) { + if(pv_get_spec_value(msg, credit_spec, &credit_val) != 0) { LM_ERR("Can't get credit's value\n"); return -1; } - credit = str2double(&credit_val.rs); + credit = str2double(&credit_val.rs); - if (credit <= 0) { + if(credit <= 0) { LM_ERR("credit value must be > 0: %f", credit); return -1; } - if (pv_get_spec_value(msg, cps_spec, &cps_val) != 0) { + if(pv_get_spec_value(msg, cps_spec, &cps_val) != 0) { LM_ERR("Can't get cost_per_sec's value\n"); return -1; } - cost_per_second = str2double(&cps_val.rs); + cost_per_second = str2double(&cps_val.rs); - if (cost_per_second <= 0) { + if(cost_per_second <= 0) { LM_ERR("cost_per_second value must be > 0: %f\n", cost_per_second); return -1; } - if (pv_get_spec_value(msg, initial_pulse_spec, &initial_pulse_val) != 0) { + if(pv_get_spec_value(msg, initial_pulse_spec, &initial_pulse_val) + != 0) { LM_ERR("Can't get initial_pulse's value\n"); return -1; } - if (str2int(&initial_pulse_val.rs, &initial_pulse) != 0) { - LM_ERR("initial_pulse value is invalid: %.*s", initial_pulse_val.rs.len, initial_pulse_val.rs.s); + if(str2int(&initial_pulse_val.rs, &initial_pulse) != 0) { + LM_ERR("initial_pulse value is invalid: %.*s", + initial_pulse_val.rs.len, initial_pulse_val.rs.s); return -1; } - if (pv_get_spec_value(msg, final_pulse_spec, &final_pulse_val) != 0) { + if(pv_get_spec_value(msg, final_pulse_spec, &final_pulse_val) != 0) { LM_ERR("Can't get final_pulse's value\n"); return -1; } - if (str2int(&final_pulse_val.rs, &final_pulse) != 0) { - LM_ERR("final_pulse value is invalid: %.*s", final_pulse_val.rs.len, final_pulse_val.rs.s); + if(str2int(&final_pulse_val.rs, &final_pulse) != 0) { + LM_ERR("final_pulse value is invalid: %.*s", final_pulse_val.rs.len, + final_pulse_val.rs.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); + 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("Setting up new call for client [%.*s], max-credit[%f], " - "cost-per-sec[%f], initial-pulse [%d], " - "final-pulse [%d], call-id[%.*s]\n", client_id_val.rs.len, client_id_val.rs.s, - credit, - cost_per_second, initial_pulse, - final_pulse, msg->callid->body.len, msg->callid->body.s); + "cost-per-sec[%f], initial-pulse [%d], " + "final-pulse [%d], call-id[%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s, credit, + cost_per_second, initial_pulse, final_pulse, + msg->callid->body.len, msg->callid->body.s); set_ctrl_flag(msg); - if ((credit_data = __get_or_create_credit_data_entry(&client_id_val.rs, CREDIT_MONEY)) == NULL) { - LM_ERR("Error retrieving credit data from shared memory for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if((credit_data = __get_or_create_credit_data_entry( + &client_id_val.rs, CREDIT_MONEY)) + == NULL) { + LM_ERR("Error retrieving credit data from shared memory for client " + "[%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - if ((call = __alloc_new_call_by_money(credit_data, msg, credit, cost_per_second, initial_pulse, final_pulse)) == NULL) { - LM_ERR("Unable to allocate new call for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if((call = __alloc_new_call_by_money(credit_data, msg, credit, + cost_per_second, initial_pulse, final_pulse)) + == NULL) { + LM_ERR("Unable to allocate new call for client [%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - if (__add_call_by_cid(&call->sip_data.callid, call, CREDIT_MONEY) != 0) { - LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_MONEY) != 0) { + LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - } - else { + } else { LM_ALERT("MSG was not an INVITE\n"); return -1; } @@ -1597,24 +1701,28 @@ static int __set_max_credit(struct sip_msg* msg, return 1; } -static int __terminate_all(struct sip_msg* msg, char* str_pv_client) { - credit_data_t *credit_data = NULL; - pv_spec_t *client_id_spec = (pv_spec_t *) str_pv_client; +static int __terminate_all(struct sip_msg *msg, char *str_pv_client) +{ + credit_data_t *credit_data = NULL; + pv_spec_t *client_id_spec = (pv_spec_t *)str_pv_client; pv_value_t client_id_val; - if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { - LM_ERR("[%.*s]: can't get client_id pvar value\n", msg->callid->body.len, msg->callid->body.s); + if(pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { + LM_ERR("[%.*s]: can't get client_id pvar 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); + 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; } - if (try_get_credit_data_entry(&client_id_val.rs, &credit_data) != 0) { - LM_DBG("[%.*s] not found\n", msg->callid->body.len, msg->callid->body.s); + if(try_get_credit_data_entry(&client_id_val.rs, &credit_data) != 0) { + LM_DBG("[%.*s] not found\n", msg->callid->body.len, + msg->callid->body.s); return -1; } @@ -1622,30 +1730,35 @@ static int __terminate_all(struct sip_msg* msg, char* str_pv_client) { return 1; } -static int __get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str_pv_chan_count) { - credit_data_t *credit_data = NULL; - pv_spec_t *chan_count_spec = (pv_spec_t *) str_pv_chan_count, - *client_id_spec = (pv_spec_t *) str_pv_client; +static int __get_channel_count( + struct sip_msg *msg, char *str_pv_client, char *str_pv_chan_count) +{ + credit_data_t *credit_data = NULL; + pv_spec_t *chan_count_spec = (pv_spec_t *)str_pv_chan_count, + *client_id_spec = (pv_spec_t *)str_pv_client; pv_value_t chan_count_val, client_id_val; - int value = -1; + int value = -1; - if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { - LM_ERR("[%.*s]: can't get client_id pvar value\n", msg->callid->body.len, msg->callid->body.s); + if(pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { + LM_ERR("[%.*s]: can't get client_id pvar 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); + 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; } - if (try_get_credit_data_entry(&client_id_val.rs, &credit_data) == 0) - value = credit_data->number_of_calls; + if(try_get_credit_data_entry(&client_id_val.rs, &credit_data) == 0) + value = credit_data->number_of_calls; else - LM_ALERT("[%.*s] not found\n", msg->callid->body.len, msg->callid->body.s); + LM_ALERT("[%.*s] not found\n", msg->callid->body.len, + msg->callid->body.s); - if (!pv_is_w(chan_count_spec)) { + if(!pv_is_w(chan_count_spec)) { LM_ERR("pvar is not writable\n"); return -1; } @@ -1654,15 +1767,15 @@ static int __get_channel_count(struct sip_msg* msg, char* str_pv_client, char* s chan_count_val.flags = PV_VAL_STR; - if (value > 0) + if(value > 0) chan_count_val.rs.s = int2str(value, &chan_count_val.rs.len); else { - char buff[2] = { '-', '1' }; - chan_count_val.rs.s = buff; - chan_count_val.rs.len = 2; + char buff[2] = {'-', '1'}; + chan_count_val.rs.s = buff; + chan_count_val.rs.len = 2; } - if (pv_set_spec_value(msg, chan_count_spec, 0, &chan_count_val) != 0) { + if(pv_set_spec_value(msg, chan_count_spec, 0, &chan_count_val) != 0) { LM_ERR("Error writing value to pvar"); return -1; } @@ -1670,144 +1783,170 @@ static int __get_channel_count(struct sip_msg* msg, char* str_pv_client, char* s return 1; } -static int __set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_pv_max_chan) { - credit_data_t *credit_data = NULL; - call_t *call = NULL; - pv_spec_t *max_chan_spec = (pv_spec_t *) str_pv_max_chan, - *client_id_spec = (pv_spec_t *) str_pv_client; +static int __set_max_channels( + struct sip_msg *msg, char *str_pv_client, char *str_pv_max_chan) +{ + credit_data_t *credit_data = NULL; + call_t *call = NULL; + pv_spec_t *max_chan_spec = (pv_spec_t *)str_pv_max_chan, + *client_id_spec = (pv_spec_t *)str_pv_client; pv_value_t max_chan_val, client_id_val; - int max_chan = 0; + int max_chan = 0; set_ctrl_flag(msg); - if (parse_headers(msg, HDR_CALLID_F, 0) != 0) { + if(parse_headers(msg, HDR_CALLID_F, 0) != 0) { LM_ERR("Error parsing Call-ID"); return -1; } - if (msg->first_line.type == SIP_REQUEST && msg->first_line.u.request.method_value == METHOD_INVITE) { - if (__has_to_tag(msg)) - { + if(msg->first_line.type == SIP_REQUEST + && msg->first_line.u.request.method_value == METHOD_INVITE) { + if(__has_to_tag(msg)) { LM_ERR("INVITE is a reINVITE\n"); return -1; } - if (pv_get_spec_value(msg, max_chan_spec, &max_chan_val) != 0) { + if(pv_get_spec_value(msg, max_chan_spec, &max_chan_val) != 0) { LM_ERR("Can't get max_chan pvar value\n"); return -1; } max_chan = max_chan_val.ri; - if (max_chan <= 0) { - LM_ERR("[%.*s] MAX_CHAN cannot be less than or equal to zero: %d\n", msg->callid->body.len, msg->callid->body.s, max_chan); + if(max_chan <= 0) { + LM_ERR("[%.*s] MAX_CHAN cannot be less than or equal to zero: %d\n", + msg->callid->body.len, msg->callid->body.s, max_chan); return -1; } - if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { - LM_ERR("[%.*s]: can't get client_id pvar value\n", msg->callid->body.len, msg->callid->body.s); + if(pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0) { + LM_ERR("[%.*s]: can't get client_id pvar 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); + 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("Setting up new call for client [%.*s], max-chan[%d], call-id[%.*s]\n", client_id_val.rs.len, client_id_val.rs.s, - max_chan, - msg->callid->body.len, msg->callid->body.s); - - if ((credit_data = __get_or_create_credit_data_entry(&client_id_val.rs, CREDIT_CHANNEL)) == NULL) { - LM_ERR("Error retrieving credit data from shared memory for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + LM_DBG("Setting up new call for client [%.*s], max-chan[%d], " + "call-id[%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s, max_chan, + msg->callid->body.len, msg->callid->body.s); + + if((credit_data = __get_or_create_credit_data_entry( + &client_id_val.rs, CREDIT_CHANNEL)) + == NULL) { + LM_ERR("Error retrieving credit data from shared memory for client " + "[%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - if (credit_data->number_of_calls + 1 > max_chan) + if(credit_data->number_of_calls + 1 > max_chan) return -2; // you have, between calls being setup plus those established, more than you maximum quota - if (credit_data->concurrent_calls + 1 > max_chan) + if(credit_data->concurrent_calls + 1 > max_chan) return -3; // you have the max amount of established calls already - if ((call = alloc_new_call_by_channel(credit_data, msg, max_chan)) == NULL) { - LM_ERR("Unable to allocate new call for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if((call = alloc_new_call_by_channel(credit_data, msg, max_chan)) + == NULL) { + LM_ERR("Unable to allocate new call for client [%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - if (__add_call_by_cid(&call->sip_data.callid, call, CREDIT_CHANNEL) != 0) { - LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_CHANNEL) + != 0) { + LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } return 1; - } - else { + } else { LM_ALERT("MSG was not an INVITE\n"); return -1; } } -static int __set_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv_maxsecs) { - credit_data_t *credit_data = NULL; - call_t *call = NULL; - pv_spec_t *max_secs_spec = (pv_spec_t *) str_pv_maxsecs, - *client_id_spec = (pv_spec_t *) str_pv_client; +static int __set_max_time( + struct sip_msg *msg, char *str_pv_client, char *str_pv_maxsecs) +{ + credit_data_t *credit_data = NULL; + call_t *call = NULL; + pv_spec_t *max_secs_spec = (pv_spec_t *)str_pv_maxsecs, + *client_id_spec = (pv_spec_t *)str_pv_client; pv_value_t max_secs_val, client_id_val; - int max_secs = 0; + int max_secs = 0; set_ctrl_flag(msg); - if (parse_headers(msg, HDR_CALLID_F, 0) != 0) { + if(parse_headers(msg, HDR_CALLID_F, 0) != 0) { LM_ERR("Error parsing Call-ID"); return -1; } - if (msg->first_line.type == SIP_REQUEST && msg->first_line.u.request.method_value == METHOD_INVITE) { - if (__has_to_tag(msg)) { + if(msg->first_line.type == SIP_REQUEST + && msg->first_line.u.request.method_value == METHOD_INVITE) { + if(__has_to_tag(msg)) { LM_ERR("INVITE is a reINVITE\n"); return -1; } - if (pv_get_spec_value(msg, max_secs_spec, &max_secs_val) != 0) { + if(pv_get_spec_value(msg, max_secs_spec, &max_secs_val) != 0) { LM_ERR("Can't get max_secs PV value\n"); return -1; } max_secs = max_secs_val.ri; - if (max_secs <= 0) { - LM_ERR("[%.*s] MAXSECS cannot be less than or equal to zero: %d\n", msg->callid->body.len, msg->callid->body.s, max_secs); + if(max_secs <= 0) { + LM_ERR("[%.*s] MAXSECS cannot be less than or equal to zero: %d\n", + msg->callid->body.len, msg->callid->body.s, max_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); + 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); + 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("Setting up new call for client [%.*s], max-secs[%d], call-id[%.*s]\n", client_id_val.rs.len, client_id_val.rs.s, - max_secs, - msg->callid->body.len, msg->callid->body.s); - - if ((credit_data = __get_or_create_credit_data_entry(&client_id_val.rs, CREDIT_TIME)) == NULL) { - LM_ERR("Error retrieving credit data from shared memory for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + LM_DBG("Setting up new call for client [%.*s], max-secs[%d], " + "call-id[%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s, max_secs, + msg->callid->body.len, msg->callid->body.s); + + if((credit_data = __get_or_create_credit_data_entry( + &client_id_val.rs, CREDIT_TIME)) + == NULL) { + LM_ERR("Error retrieving credit data from shared memory for client " + "[%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - if ((call = __alloc_new_call_by_time(credit_data, msg, max_secs)) == NULL) { - LM_ERR("Unable to allocate new call for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if((call = __alloc_new_call_by_time(credit_data, msg, max_secs)) + == NULL) { + LM_ERR("Unable to allocate new call for client [%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - if (__add_call_by_cid(&call->sip_data.callid, call, CREDIT_TIME) != 0) { - LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n", client_id_val.rs.len, client_id_val.rs.s); + if(__add_call_by_cid(&call->sip_data.callid, call, CREDIT_TIME) != 0) { + LM_ERR("Unable to allocate new cid_by_client for client [%.*s]\n", + client_id_val.rs.len, client_id_val.rs.s); return -1; } - } - else { + } else { LM_ALERT("MSG was not an INVITE\n"); return -1; } @@ -1815,81 +1954,87 @@ static int __set_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv 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; +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; + int secs = 0; set_ctrl_flag(msg); - if (parse_headers(msg, HDR_CALLID_F, 0) != 0) { + 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) { + 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; + 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); + 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); + 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); + 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); + 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; + 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; cnxcc_lock(_data.time.lock); e = str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len); cnxcc_unlock(_data.time.lock); - if (e == NULL) { - LM_ERR("Client [%.*s] was not found\n", client_id_val.rs.len, client_id_val.rs.s); + if(e == NULL) { + LM_ERR("Client [%.*s] was not found\n", client_id_val.rs.len, + client_id_val.rs.s); return -1; } - - credit_data = (credit_data_t *) e->u.p; + + credit_data = (credit_data_t *)e->u.p; cnxcc_lock(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; + 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); - if (credit_data->number_of_calls > 0) - update_fraction = secs / credit_data->number_of_calls; + credit_data->max_amount += secs; - clist_foreach_safe(credit_data->call_list, call, tmp_call, next) { - if (!call->confirmed) + 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; + + call->max_amount += update_fraction; } -//redit_data->consumed_amount = 0; + //redit_data->consumed_amount = 0; cnxcc_unlock(credit_data->lock); @@ -1897,39 +2042,41 @@ static int __update_max_time(struct sip_msg* msg, char* str_pv_client, char* str return 1; } -static int __has_to_tag(struct sip_msg *msg) { - if (msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0) { +static int __has_to_tag(struct sip_msg *msg) +{ + if(msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0) { LM_ERR("Cannot parse to-tag\n"); return 0; } - return !(get_to(msg)->tag_value.s == NULL || get_to(msg)->tag_value.len == 0); + return !(get_to(msg)->tag_value.s == NULL + || get_to(msg)->tag_value.len == 0); } -static int __pv_parse_calls_param(pv_spec_p sp, str *in) { - if (sp == NULL || in == NULL || in->len == 0) +static int __pv_parse_calls_param(pv_spec_p sp, str *in) +{ + if(sp == NULL || in == NULL || in->len == 0) return -1; switch(in->len) { - case 5: - if (strncmp("total", in->s, in->len) == 0) - sp->pvp.pvn.u.isname.name.n = CNX_PV_TOTAL; - else - return -1; - break; - case 6: - if (strncmp("active", in->s, in->len) == 0) - sp->pvp.pvn.u.isname.name.n = CNX_PV_ACTIVE; - else - return -1; - break; - case 7: - if (strncmp("dropped", in->s, in->len) == 0) - sp->pvp.pvn.u.isname.name.n = CNX_PV_DROPPED; - else - return -1; - break; - + case 5: + if(strncmp("total", in->s, in->len) == 0) + sp->pvp.pvn.u.isname.name.n = CNX_PV_TOTAL; + else + return -1; + break; + case 6: + if(strncmp("active", in->s, in->len) == 0) + sp->pvp.pvn.u.isname.name.n = CNX_PV_ACTIVE; + else + return -1; + break; + case 7: + if(strncmp("dropped", in->s, in->len) == 0) + sp->pvp.pvn.u.isname.name.n = CNX_PV_DROPPED; + else + return -1; + break; } sp->pvp.pvn.type = PV_NAME_INTSTR; @@ -1938,35 +2085,34 @@ static int __pv_parse_calls_param(pv_spec_p sp, str *in) { return 0; } -static int __pv_get_calls(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { +static int __pv_get_calls( + struct sip_msg *msg, pv_param_t *param, pv_value_t *res) +{ switch(param->pvn.u.isname.name.n) { - case CNX_PV_ACTIVE: - return pv_get_uintval(msg, param, res, _data.stats->active); - case CNX_PV_TOTAL: - return pv_get_uintval(msg, param, res, _data.stats->total); - case CNX_PV_DROPPED: - return pv_get_uintval(msg, param, res, _data.stats->dropped); - default: - LM_ERR("Unknown PV type %d\n", param->pvn.u.isname.name.n); - break; + case CNX_PV_ACTIVE: + return pv_get_uintval(msg, param, res, _data.stats->active); + case CNX_PV_TOTAL: + return pv_get_uintval(msg, param, res, _data.stats->total); + case CNX_PV_DROPPED: + return pv_get_uintval(msg, param, res, _data.stats->dropped); + default: + LM_ERR("Unknown PV type %d\n", param->pvn.u.isname.name.n); + break; } return -1; } -void rpc_credit_control_stats(rpc_t* rpc, void* ctx) +void rpc_credit_control_stats(rpc_t *rpc, void *ctx) { void *rh; - if(rpc->add(ctx, "{", &rh)<0) { + if(rpc->add(ctx, "{", &rh) < 0) { rpc->fault(ctx, 500, "Server failure"); return; } - rpc->struct_add(rh, "sddd", - "info", "CNX Credit Control", - "active", _data.stats->active, - "dropped", _data.stats->dropped, - "total", _data.stats->total); - -} + rpc->struct_add(rh, "sddd", "info", "CNX Credit Control", "active", + _data.stats->active, "dropped", _data.stats->dropped, "total", + _data.stats->total); +} \ No newline at end of file diff --git a/src/modules/cnxcc/cnxcc_mod.h b/src/modules/cnxcc/cnxcc_mod.h index 620d70e99e1..13d7d1f492b 100644 --- a/src/modules/cnxcc/cnxcc_mod.h +++ b/src/modules/cnxcc/cnxcc_mod.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -29,56 +27,63 @@ #include "../../core/str_hash.h" #include "../../core/parser/parse_rr.h" -#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; \ + } /*! * \brief Init a cnxcc_lock * \param _entry locked entry */ #define cnxcc_lock_init(_entry) \ - lock_init(&(_entry).lock); \ + lock_init(&(_entry).lock); \ (_entry).rec_lock_level = 0; /*! * \brief Set a cnxcc lock (re-entrant) * \param _entry locked entry */ -#define cnxcc_lock(_entry) \ - do { \ - int mypid; \ - mypid = my_pid(); \ - if (likely(atomic_get( &(_entry).locker_pid) != mypid)) { \ - lock_get( &(_entry).lock); \ - atomic_set( &(_entry).locker_pid, mypid); \ - } else { \ - /* locked within the same process that executed us */ \ - (_entry).rec_lock_level++; \ - } \ - } while(0) +#define cnxcc_lock(_entry) \ + do { \ + int mypid; \ + mypid = my_pid(); \ + if(likely(atomic_get(&(_entry).locker_pid) != mypid)) { \ + lock_get(&(_entry).lock); \ + atomic_set(&(_entry).locker_pid, mypid); \ + } else { \ + /* locked within the same process that executed us */ \ + (_entry).rec_lock_level++; \ + } \ + } while(0) /*! * \brief Release a cnxcc lock * \param _entry locked entry */ -#define cnxcc_unlock(_entry) \ - do { \ - if (likely((_entry).rec_lock_level == 0)) { \ - atomic_set( &(_entry).locker_pid, 0); \ - lock_release( &(_entry).lock); \ - } else { \ - /* recursive locked => decrease lock count */ \ - (_entry).rec_lock_level--; \ - } \ - } while(0) - -typedef struct cnxcc_lock { +#define cnxcc_unlock(_entry) \ + do { \ + if(likely((_entry).rec_lock_level == 0)) { \ + atomic_set(&(_entry).locker_pid, 0); \ + lock_release(&(_entry).lock); \ + } else { \ + /* recursive locked => decrease lock count */ \ + (_entry).rec_lock_level--; \ + } \ + } while(0) + +typedef struct cnxcc_lock +{ gen_lock_t lock; atomic_t locker_pid; int rec_lock_level; } cnxcc_lock_t; -typedef struct stats { +typedef struct stats +{ unsigned int total; unsigned int active; unsigned int dropped; @@ -96,7 +101,8 @@ typedef enum credit_type { CREDIT_CHANNEL } credit_type_t; -typedef struct hash_tables { +typedef struct hash_tables +{ struct str_hash_table *credit_data_by_client; struct str_hash_table *call_data_by_cid; @@ -105,7 +111,8 @@ typedef struct hash_tables { struct redis; -typedef struct data { +typedef struct data +{ cnxcc_lock_t lock; hash_tables_t time; @@ -130,7 +137,8 @@ typedef struct data { int check_period; str redis_cnn_str; - struct { + struct + { char host[40]; int port; int db; @@ -139,7 +147,8 @@ typedef struct data { } data_t; -typedef struct sip_data { +typedef struct sip_data +{ str callid; str from_uri; str from_tag; @@ -147,7 +156,8 @@ typedef struct sip_data { str to_tag; } sip_data_t; -typedef struct money_spec_data { +typedef struct money_spec_data +{ double cost_per_second; int initial_pulse; int final_pulse; @@ -155,7 +165,8 @@ typedef struct money_spec_data { } money_spec_data_t; struct call; -typedef struct call { +typedef struct call +{ struct call *prev; struct call *next; @@ -176,13 +187,15 @@ typedef struct call { sip_data_t sip_data; } call_t; -typedef struct call_array { +typedef struct call_array +{ call_t *array; int length; } call_array_t; -typedef struct credit_data { +typedef struct credit_data +{ cnxcc_lock_t lock; double max_amount; @@ -197,7 +210,7 @@ typedef struct credit_data { char *str_id; // flag to mark this instance in the process of being eliminated - int deallocating:1; + int deallocating : 1; } credit_data_t; diff --git a/src/modules/cnxcc/cnxcc_redis.c b/src/modules/cnxcc/cnxcc_redis.c index cb074afb125..4aad3b48a82 100644 --- a/src/modules/cnxcc/cnxcc_redis.c +++ b/src/modules/cnxcc/cnxcc_redis.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2014 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -30,57 +28,71 @@ extern data_t _data; static int __redis_select_db(redisContext *ctxt, int db); -static int __redis_exec(credit_data_t *credit_data, const char *cmd, redisReply **rpl); +static int __redis_exec( + credit_data_t *credit_data, const char *cmd, redisReply **rpl); static struct redis *__redis_connect(struct redis *redis); static void __async_connect_cb(const redisAsyncContext *c, int status); static void __async_disconnect_cb(const redisAsyncContext *c, int status); static void __subscription_cb(redisAsyncContext *c, void *r, void *privdata); static struct redis *__redis_connect_async(struct redis *redis); static struct redis *__alloc_redis(char *ip, int port, int db); -static void __redis_subscribe_to_kill_list(struct redis *redis) ; +static void __redis_subscribe_to_kill_list(struct redis *redis); -static inline const char *__get_table_name(credit_type_t type) { +static inline const char *__get_table_name(credit_type_t type) +{ switch(type) { - case CREDIT_MONEY: - return "money"; - break; - case CREDIT_TIME: - return "time"; - break; - case CREDIT_CHANNEL: - return "channel"; - break; - default: - LM_ERR("BUG: Something went terribly wrong: invalid credit type\n"); - return NULL; + case CREDIT_MONEY: + return "money"; + break; + case CREDIT_TIME: + return "time"; + break; + case CREDIT_CHANNEL: + return "channel"; + break; + default: + LM_ERR("BUG: Something went terribly wrong: invalid credit type\n"); + return NULL; } } -int redis_get_or_create_credit_data(credit_data_t *credit_data) { +int redis_get_or_create_credit_data(credit_data_t *credit_data) +{ int exists = 0; // concurrent_calls is just a dummy key. It can be any of the valid keys - if (redis_get_int(credit_data, "HEXISTS", "concurrent_calls" , &exists) < 0) + if(redis_get_int(credit_data, "HEXISTS", "concurrent_calls", &exists) < 0) goto error; - if (!exists) { // doesn't exist - LM_DBG("credit_data with ID=[%s] DOES NOT exist in the cluster, creating it...\n", credit_data->str_id); + if(!exists) { // doesn't exist + LM_DBG("credit_data with ID=[%s] DOES NOT exist in the cluster, " + "creating it...\n", + credit_data->str_id); return redis_insert_credit_data(credit_data); } - LM_DBG("credit_data with ID=[%s] DOES exist in the cluster, retrieving it...\n", credit_data->str_id); + LM_DBG("credit_data with ID=[%s] DOES exist in the cluster, retrieving " + "it...\n", + credit_data->str_id); - if (redis_get_double(credit_data, "HGET", "consumed_amount", &credit_data->consumed_amount) < 0) + if(redis_get_double(credit_data, "HGET", "consumed_amount", + &credit_data->consumed_amount) + < 0) goto error; - if (redis_get_double(credit_data, "HGET", "ended_calls_consumed_amount", &credit_data->ended_calls_consumed_amount) < 0) + if(redis_get_double(credit_data, "HGET", "ended_calls_consumed_amount", + &credit_data->ended_calls_consumed_amount) + < 0) goto error; - if (redis_get_double(credit_data, "HGET", "max_amount", &credit_data->max_amount) < 0) + if(redis_get_double( + credit_data, "HGET", "max_amount", &credit_data->max_amount) + < 0) goto error; - if (redis_get_int(credit_data, "HGET", "type", (int *) &credit_data->type) < 0) + if(redis_get_int(credit_data, "HGET", "type", (int *)&credit_data->type) + < 0) goto error; return 1; @@ -88,29 +100,40 @@ int redis_get_or_create_credit_data(credit_data_t *credit_data) { return -1; } -int redis_insert_credit_data(credit_data_t *credit_data) { +int redis_insert_credit_data(credit_data_t *credit_data) +{ LM_DBG("Inserting credit_data_t using ID [%s]\n", credit_data->str_id); - if (redis_insert_int_value(credit_data, "concurrent_calls", credit_data->concurrent_calls) < 0) + if(redis_insert_int_value( + credit_data, "concurrent_calls", credit_data->concurrent_calls) + < 0) goto error; - if (redis_insert_double_value(credit_data, "consumed_amount", credit_data->consumed_amount) < 0) + if(redis_insert_double_value( + credit_data, "consumed_amount", credit_data->consumed_amount) + < 0) goto error; - if (redis_insert_double_value(credit_data, "ended_calls_consumed_amount", credit_data->ended_calls_consumed_amount) < 0) + if(redis_insert_double_value(credit_data, "ended_calls_consumed_amount", + credit_data->ended_calls_consumed_amount) + < 0) goto error; - if (redis_insert_double_value(credit_data, "max_amount", credit_data->max_amount) < 0) + if(redis_insert_double_value( + credit_data, "max_amount", credit_data->max_amount) + < 0) goto error; - if (redis_insert_int_value(credit_data, "number_of_calls", credit_data->number_of_calls) < 0) + if(redis_insert_int_value( + credit_data, "number_of_calls", credit_data->number_of_calls) + < 0) goto error; - if (redis_insert_int_value(credit_data, "type", credit_data->type) < 0) + if(redis_insert_int_value(credit_data, "type", credit_data->type) < 0) goto error; // make sure when don't have any leftover member on the kill list for this new entry - if (redis_remove_kill_list_member(credit_data) < 0) + if(redis_remove_kill_list_member(credit_data) < 0) goto error; return 1; @@ -118,7 +141,8 @@ int redis_insert_credit_data(credit_data_t *credit_data) { return -1; } -static struct redis *__alloc_redis(char *ip, int port, int db) { +static struct redis *__alloc_redis(char *ip, int port, int db) +{ struct redis *redis = pkg_malloc(sizeof(struct redis)); int len = strlen(ip); @@ -132,26 +156,30 @@ static struct redis *__alloc_redis(char *ip, int port, int db) { return redis; } -struct redis *redis_connect_all(char *ip, int port, int db) { +struct redis *redis_connect_all(char *ip, int port, int db) +{ return __redis_connect_async(__redis_connect(__alloc_redis(ip, port, db))); } -struct redis *redis_connect(char *ip, int port, int db) { +struct redis *redis_connect(char *ip, int port, int db) +{ return __redis_connect(__alloc_redis(ip, port, db)); } -struct redis *redis_connect_async(char *ip, int port, int db) { +struct redis *redis_connect_async(char *ip, int port, int db) +{ return __redis_connect_async(__alloc_redis(ip, port, db)); } -static struct redis *__redis_connect_async(struct redis *redis) { +static struct redis *__redis_connect_async(struct redis *redis) +{ redis->eb = event_base_new(); LM_INFO("Connecting (ASYNC) to Redis at %s:%d\n", redis->ip, redis->port); redis->async_ctxt = redisAsyncConnect(redis->ip, redis->port); - if (redis->async_ctxt->err) { + if(redis->async_ctxt->err) { LM_ERR("%s\n", redis->async_ctxt->errstr); return NULL; } @@ -168,18 +196,19 @@ static struct redis *__redis_connect_async(struct redis *redis) { return redis; } -static struct redis *__redis_connect(struct redis *redis) { - struct timeval timeout = { 1, 500000 }; // 1.5 seconds +static struct redis *__redis_connect(struct redis *redis) +{ + struct timeval timeout = {1, 500000}; // 1.5 seconds LM_INFO("Connecting to Redis at %s:%d\n", redis->ip, redis->port); - if (redis->ctxt) + if(redis->ctxt) redisFree(redis->ctxt); redis->ctxt = redisConnectWithTimeout(redis->ip, redis->port, timeout); - if (redis->ctxt == NULL || redis->ctxt->err) { - if (!redis->ctxt) + if(redis->ctxt == NULL || redis->ctxt->err) { + if(!redis->ctxt) LM_ERR("Connection error: can't allocate Redis context\n"); else { LM_ERR("Connection error: %s\n", redis->ctxt->errstr); @@ -189,18 +218,19 @@ static struct redis *__redis_connect(struct redis *redis) { return NULL; } - if (!__redis_select_db(redis->ctxt, redis->db)) + if(!__redis_select_db(redis->ctxt, redis->db)) return NULL; return redis; } -static int __redis_select_db(redisContext *ctxt, int db) { +static int __redis_select_db(redisContext *ctxt, int db) +{ redisReply *rpl; rpl = redisCommand(ctxt, "SELECT %d", db); - if (!rpl || rpl->type == REDIS_REPLY_ERROR) { - if (!rpl) + if(!rpl || rpl->type == REDIS_REPLY_ERROR) { + if(!rpl) LM_ERR("%s\n", ctxt->errstr); else { LM_ERR("%.*s\n", rpl->len, rpl->str); @@ -212,14 +242,16 @@ static int __redis_select_db(redisContext *ctxt, int db) { return 1; } -static int __redis_exec(credit_data_t *credit_data, const char *cmd, redisReply **rpl) { +static int __redis_exec( + credit_data_t *credit_data, const char *cmd, redisReply **rpl) +{ redisReply *rpl_aux; char cmd_buffer[1024]; *rpl = redisCommand(_data.redis->ctxt, cmd); - if (!(*rpl) || (*rpl)->type == REDIS_REPLY_ERROR) { - if (!*rpl) + if(!(*rpl) || (*rpl)->type == REDIS_REPLY_ERROR) { + if(!*rpl) LM_ERR("%s\n", _data.redis->ctxt->errstr); else { LM_ERR("%.*s\n", (*rpl)->len, (*rpl)->str); @@ -231,7 +263,7 @@ static int __redis_exec(credit_data_t *credit_data, const char *cmd, redisReply return -1; } - if (credit_data == NULL) { + if(credit_data == NULL) { freeReplyObject(*rpl); return 1; } @@ -241,32 +273,37 @@ static int __redis_exec(credit_data_t *credit_data, const char *cmd, redisReply // from Redis if no other client is updating the key, leaving us with some level of // consistency snprintf(cmd_buffer, sizeof(cmd_buffer), "EXPIRE cnxcc:%s:%s %d", - __get_table_name(credit_data->type), - credit_data->str_id, - DEFAULT_EXPIRE_SECS); + __get_table_name(credit_data->type), credit_data->str_id, + DEFAULT_EXPIRE_SECS); return __redis_exec(NULL, cmd_buffer, &rpl_aux); } -int redis_incr_by_double(credit_data_t *credit_data, const char *key, double value) { +int redis_incr_by_double( + credit_data_t *credit_data, const char *key, double value) +{ redisReply *rpl = NULL; int ret = -1; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "HINCRBYFLOAT cnxcc:%s:%s %s %f", __get_table_name(credit_data->type), credit_data->str_id, key, value); + snprintf(cmd_buffer, sizeof(cmd_buffer), "HINCRBYFLOAT cnxcc:%s:%s %s %f", + __get_table_name(credit_data->type), credit_data->str_id, key, + value); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_get_double(credit_data_t *credit_data, const char *instruction, const char *key, double *value) { +int redis_get_double(credit_data_t *credit_data, const char *instruction, + const char *key, double *value) +{ str str_double = {0, 0}; char buffer[128]; - if (redis_get_str(credit_data, instruction, key, &str_double) < 0) + if(redis_get_str(credit_data, instruction, key, &str_double) < 0) return -1; snprintf(buffer, sizeof(buffer), "%.*s", str_double.len, str_double.s); @@ -278,31 +315,37 @@ int redis_get_double(credit_data_t *credit_data, const char *instruction, const return 1; } -int redis_incr_by_int(credit_data_t *credit_data, const char *key, int value) { +int redis_incr_by_int(credit_data_t *credit_data, const char *key, int value) +{ redisReply *rpl = NULL; int ret = -1; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "HINCRBY cnxcc:%s:%s %s %d", __get_table_name(credit_data->type), credit_data->str_id, key, value); + snprintf(cmd_buffer, sizeof(cmd_buffer), "HINCRBY cnxcc:%s:%s %s %d", + __get_table_name(credit_data->type), credit_data->str_id, key, + value); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_get_int(credit_data_t *credit_data, const char *instruction, const char *key, int *value) { +int redis_get_int(credit_data_t *credit_data, const char *instruction, + const char *key, int *value) +{ redisReply *rpl = NULL; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "%s cnxcc:%s:%s %s", instruction, __get_table_name(credit_data->type), credit_data->str_id, key); + snprintf(cmd_buffer, sizeof(cmd_buffer), "%s cnxcc:%s:%s %s", instruction, + __get_table_name(credit_data->type), credit_data->str_id, key); - if (__redis_exec(credit_data, cmd_buffer, &rpl) < 0) + if(__redis_exec(credit_data, cmd_buffer, &rpl) < 0) return -1; - if (rpl->type == REDIS_REPLY_INTEGER) + if(rpl->type == REDIS_REPLY_INTEGER) *value = rpl->integer; - else if (rpl->type == REDIS_REPLY_NIL) + else if(rpl->type == REDIS_REPLY_NIL) *value = 0; else { *value = atoi(rpl->str); @@ -314,29 +357,33 @@ int redis_get_int(credit_data_t *credit_data, const char *instruction, const cha return 1; } -int redis_get_str(credit_data_t *credit_data, const char *instruction, const char *key, str *value) { +int redis_get_str(credit_data_t *credit_data, const char *instruction, + const char *key, str *value) +{ redisReply *rpl = NULL; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "%s cnxcc:%s:%s %s", instruction, __get_table_name(credit_data->type), credit_data->str_id, key); + snprintf(cmd_buffer, sizeof(cmd_buffer), "%s cnxcc:%s:%s %s", instruction, + __get_table_name(credit_data->type), credit_data->str_id, key); value->s = NULL; value->len = 0; - if (__redis_exec(credit_data, cmd_buffer, &rpl) < 0) + if(__redis_exec(credit_data, cmd_buffer, &rpl) < 0) return -1; - if (rpl->type != REDIS_REPLY_STRING && rpl->type != REDIS_REPLY_NIL) { - LM_ERR("Redis reply to [%s] is not a string/nil: type[%d]\n", cmd_buffer, rpl->type); + if(rpl->type != REDIS_REPLY_STRING && rpl->type != REDIS_REPLY_NIL) { + LM_ERR("Redis reply to [%s] is not a string/nil: type[%d]\n", + cmd_buffer, rpl->type); freeReplyObject(rpl); return -1; } - if (rpl->type == REDIS_REPLY_NIL) { + if(rpl->type == REDIS_REPLY_NIL) { LM_DBG("Value of %s is (nil)\n", key); goto done; } - if (rpl->len <= 0) { + if(rpl->len <= 0) { LM_ERR("RPL len is equal to %d\n", rpl->len); goto done; } @@ -352,111 +399,132 @@ int redis_get_str(credit_data_t *credit_data, const char *instruction, const cha return 1; } -int redis_remove_credit_data(credit_data_t *credit_data) { +int redis_remove_credit_data(credit_data_t *credit_data) +{ redisReply *rpl = NULL; char cmd_buffer[1024]; int ret; - snprintf(cmd_buffer, sizeof(cmd_buffer), "DEL cnxcc:%s:%s", __get_table_name(credit_data->type), credit_data->str_id); + snprintf(cmd_buffer, sizeof(cmd_buffer), "DEL cnxcc:%s:%s", + __get_table_name(credit_data->type), credit_data->str_id); ret = __redis_exec(NULL, cmd_buffer, &rpl); -// if (ret > 0) -// freeReplyObject(rpl); + // if (ret > 0) + // freeReplyObject(rpl); return ret; } -int redis_append_kill_list_member(credit_data_t *credit_data) { +int redis_append_kill_list_member(credit_data_t *credit_data) +{ redisReply *rpl = NULL; char cmd_buffer[1024]; int ret; - snprintf(cmd_buffer, sizeof(cmd_buffer), "SADD cnxcc:kill_list:%s \"%s\"", __get_table_name(credit_data->type), credit_data->str_id); + snprintf(cmd_buffer, sizeof(cmd_buffer), "SADD cnxcc:kill_list:%s \"%s\"", + __get_table_name(credit_data->type), credit_data->str_id); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_remove_kill_list_member(credit_data_t *credit_data) { +int redis_remove_kill_list_member(credit_data_t *credit_data) +{ redisReply *rpl = NULL; char cmd_buffer[1024]; int ret; - snprintf(cmd_buffer, sizeof(cmd_buffer), "SREM cnxcc:kill_list:%s \"%s\"", __get_table_name(credit_data->type), credit_data->str_id); + snprintf(cmd_buffer, sizeof(cmd_buffer), "SREM cnxcc:kill_list:%s \"%s\"", + __get_table_name(credit_data->type), credit_data->str_id); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_insert_str_value(credit_data_t *credit_data, const char* key, str *value) { +int redis_insert_str_value( + credit_data_t *credit_data, const char *key, str *value) +{ redisReply *rpl = NULL; int ret = -1; char cmd_buffer[2048]; - if (value == NULL) { + if(value == NULL) { LM_ERR("str value is null\n"); return -1; } - if (value->len == 0) { + if(value->len == 0) { LM_WARN("[%s] value is empty\n", key); return 1; } - snprintf(cmd_buffer, sizeof(cmd_buffer), "HSET cnxcc:%s:%s %s \"%.*s\"", __get_table_name(credit_data->type), credit_data->str_id, key, value->len, value->s); + snprintf(cmd_buffer, sizeof(cmd_buffer), "HSET cnxcc:%s:%s %s \"%.*s\"", + __get_table_name(credit_data->type), credit_data->str_id, key, + value->len, value->s); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_insert_int_value(credit_data_t *credit_data, const char* key, int value) { +int redis_insert_int_value( + credit_data_t *credit_data, const char *key, int value) +{ redisReply *rpl = NULL; int ret = -1; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "HSET cnxcc:%s:%s %s %d", __get_table_name(credit_data->type), credit_data->str_id, key, value); + snprintf(cmd_buffer, sizeof(cmd_buffer), "HSET cnxcc:%s:%s %s %d", + __get_table_name(credit_data->type), credit_data->str_id, key, + value); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_insert_double_value(credit_data_t *credit_data, const char* key, double value) { +int redis_insert_double_value( + credit_data_t *credit_data, const char *key, double value) +{ redisReply *rpl = NULL; int ret = -1; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "HSET cnxcc:%s:%s %s %f", __get_table_name(credit_data->type), credit_data->str_id, key, value); + snprintf(cmd_buffer, sizeof(cmd_buffer), "HSET cnxcc:%s:%s %s %f", + __get_table_name(credit_data->type), credit_data->str_id, key, + value); ret = __redis_exec(credit_data, cmd_buffer, &rpl); - if (ret > 0) + if(ret > 0) freeReplyObject(rpl); return ret; } -int redis_kill_list_member_exists(credit_data_t *credit_data) { +int redis_kill_list_member_exists(credit_data_t *credit_data) +{ redisReply *rpl; int exists = 0; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "SISMEMBER cnxcc:kill_list:%s \"%s\"", __get_table_name(credit_data->type), credit_data->str_id); + snprintf(cmd_buffer, sizeof(cmd_buffer), + "SISMEMBER cnxcc:kill_list:%s \"%s\"", + __get_table_name(credit_data->type), credit_data->str_id); - if (__redis_exec(credit_data, cmd_buffer, &rpl) < 0) + if(__redis_exec(credit_data, cmd_buffer, &rpl) < 0) return -1; exists = rpl->integer; @@ -466,29 +534,35 @@ int redis_kill_list_member_exists(credit_data_t *credit_data) { return exists; } -int redis_clean_up_if_last(credit_data_t *credit_data) { +int redis_clean_up_if_last(credit_data_t *credit_data) +{ int counter = 0; - if (redis_get_int(credit_data, "HGET", "number_of_calls", &counter) < 0) + if(redis_get_int(credit_data, "HGET", "number_of_calls", &counter) < 0) return -1; return counter > 0 ? 1 : redis_remove_credit_data(credit_data); } -static void __redis_subscribe_to_kill_list(struct redis *redis) { - redisAsyncCommand(redis->async_ctxt, __subscription_cb, NULL, "SUBSCRIBE cnxcc:kill_list"); +static void __redis_subscribe_to_kill_list(struct redis *redis) +{ + redisAsyncCommand(redis->async_ctxt, __subscription_cb, NULL, + "SUBSCRIBE cnxcc:kill_list"); } -int redis_publish_to_kill_list(credit_data_t *credit_data) { +int redis_publish_to_kill_list(credit_data_t *credit_data) +{ redisReply *rpl; char cmd_buffer[1024]; - snprintf(cmd_buffer, sizeof(cmd_buffer), "PUBLISH cnxcc:kill_list %s", credit_data->str_id); + snprintf(cmd_buffer, sizeof(cmd_buffer), "PUBLISH cnxcc:kill_list %s", + credit_data->str_id); return __redis_exec(NULL, cmd_buffer, &rpl) < 0; } -static void __async_connect_cb(const redisAsyncContext *c, int status) { - if (status != REDIS_OK) { +static void __async_connect_cb(const redisAsyncContext *c, int status) +{ + if(status != REDIS_OK) { LM_ERR("error connecting to Redis db in async mode\n"); abort(); } @@ -496,49 +570,50 @@ static void __async_connect_cb(const redisAsyncContext *c, int status) { LM_INFO("connected to Redis in async mode\n"); } -static void __async_disconnect_cb(const redisAsyncContext *c, int status) { +static void __async_disconnect_cb(const redisAsyncContext *c, int status) +{ LM_ERR("async DB connection was lost\n"); } -static void __subscription_cb(redisAsyncContext *c, void *r, void *privdata) { - redisReply *reply = r; - str key; - credit_data_t *credit_data; +static void __subscription_cb(redisAsyncContext *c, void *r, void *privdata) +{ + redisReply *reply = r; + str key; + credit_data_t *credit_data; - if (reply == NULL) { - LM_ERR("reply is NULL\n"); - return; - } + if(reply == NULL) { + LM_ERR("reply is NULL\n"); + return; + } - if ( reply->type != REDIS_REPLY_ARRAY || reply->elements != 3 ) - return; + if(reply->type != REDIS_REPLY_ARRAY || reply->elements != 3) + return; - if (strcmp(reply->element[1]->str, "cnxcc:kill_list" ) != 0) - return; + if(strcmp(reply->element[1]->str, "cnxcc:kill_list") != 0) + return; - if (!reply->element[2]->str) - return; + if(!reply->element[2]->str) + return; - key.len = strlen(reply->element[2]->str); + key.len = strlen(reply->element[2]->str); - if (key.len <= 0) { - LM_ERR("Invalid credit_data key\n"); - return; - } + if(key.len <= 0) { + LM_ERR("Invalid credit_data key\n"); + return; + } - key.s = reply->element[2]->str; + key.s = reply->element[2]->str; - if (try_get_credit_data_entry(&key, &credit_data) < 0) - return; + if(try_get_credit_data_entry(&key, &credit_data) < 0) + return; - cnxcc_lock(credit_data->lock); + cnxcc_lock(credit_data->lock); - if (credit_data->deallocating) - goto done; // no need to terminate the calls. They are already being terminated + if(credit_data->deallocating) + goto done; // no need to terminate the calls. They are already being terminated - LM_ALERT("Got kill list entry for key [%.*s]\n", key.len, key.s); - terminate_all_calls(credit_data); + LM_ALERT("Got kill list entry for key [%.*s]\n", key.len, key.s); + terminate_all_calls(credit_data); done: - cnxcc_unlock(credit_data->lock); - + cnxcc_unlock(credit_data->lock); } diff --git a/src/modules/cnxcc/cnxcc_redis.h b/src/modules/cnxcc/cnxcc_redis.h index bd10d90b64e..bd6496a1c98 100644 --- a/src/modules/cnxcc/cnxcc_redis.h +++ b/src/modules/cnxcc/cnxcc_redis.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2014 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -32,29 +30,37 @@ #include "../../core/str.h" #include "cnxcc_mod.h" -struct redis { - int db; - short port; - char* ip; - redisContext *ctxt; - redisAsyncContext *async_ctxt; - struct event_base *eb; +struct redis +{ + int db; + short port; + char *ip; + redisContext *ctxt; + redisAsyncContext *async_ctxt; + struct event_base *eb; }; struct redis *redis_connect(char *ip, int port, int db); struct redis *redis_connect_async(char *ip, int port, int db); struct redis *redis_connect_all(char *ip, int port, int db); -int redis_get_int(credit_data_t *credit_data, const char *instruction, const char *key, int *value); -int redis_get_str(credit_data_t *credit_data, const char *instruction, const char *key, str *value); -int redis_get_double(credit_data_t *credit_data, const char *instruction, const char *key, double *value); +int redis_get_int(credit_data_t *credit_data, const char *instruction, + const char *key, int *value); +int redis_get_str(credit_data_t *credit_data, const char *instruction, + const char *key, str *value); +int redis_get_double(credit_data_t *credit_data, const char *instruction, + const char *key, double *value); int redis_get_or_create_credit_data(credit_data_t *credit_data); int redis_insert_credit_data(credit_data_t *credit_data); -int redis_insert_int_value(credit_data_t *credit_data, const char* key, int value); -int redis_insert_double_value(credit_data_t *credit_data, const char* key, double value); -int redis_insert_str_value(credit_data_t *credit_data, const char* key, str *value); +int redis_insert_int_value( + credit_data_t *credit_data, const char *key, int value); +int redis_insert_double_value( + credit_data_t *credit_data, const char *key, double value); +int redis_insert_str_value( + credit_data_t *credit_data, const char *key, str *value); int redis_kill_list_member_exists(credit_data_t *credit_data); int redis_incr_by_int(credit_data_t *credit_data, const char *key, int value); -int redis_incr_by_double(credit_data_t *credit_data, const char *key, double value); +int redis_incr_by_double( + credit_data_t *credit_data, const char *key, double value); int redis_clean_up_if_last(credit_data_t *credit_data); int redis_remove_kill_list_member(credit_data_t *credit_data); int redis_append_kill_list_member(credit_data_t *credit_data); diff --git a/src/modules/cnxcc/cnxcc_rpc.c b/src/modules/cnxcc/cnxcc_rpc.c index 7a2b9103248..6685b1db80d 100644 --- a/src/modules/cnxcc/cnxcc_rpc.c +++ b/src/modules/cnxcc/cnxcc_rpc.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -31,24 +29,27 @@ 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; hash_tables_t *hts; str callid; - if (!rpc->scan(ctx, "S", &callid)) { + if(!rpc->scan(ctx, "S", &callid)) { LM_ERR("%s: error reading RPC param\n", __FUNCTION__); return; } - if (try_get_call_entry(&callid, &call, &hts) != 0) { - LM_ERR("%s: call [%.*s] not found\n", __FUNCTION__, callid.len, callid.s); + if(try_get_call_entry(&callid, &call, &hts) != 0) { + LM_ERR("%s: call [%.*s] not found\n", __FUNCTION__, callid.len, + callid.s); rpc->fault(ctx, 404, "CallID Not Found"); return; } - if (call == NULL) { - LM_ERR("%s: call [%.*s] is in null state\n", __FUNCTION__, callid.len, callid.s); + if(call == NULL) { + LM_ERR("%s: call [%.*s] is in null state\n", __FUNCTION__, callid.len, + callid.s); rpc->fault(ctx, 500, "Call is NULL"); return; } @@ -62,78 +63,81 @@ void rpc_kill_call(rpc_t* rpc, void* ctx) { cnxcc_unlock(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; - int index = 0; + int index = 0; str client_id, rows; char row_buffer[512]; 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__); return; } - 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); + 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); rpc->fault(ctx, 404, "Not Found"); return; } - if (credit_data == NULL) { - LM_ERR("%s: credit data for client [%.*s] is NULL\n", __FUNCTION__, client_id.len, client_id.s); + if(credit_data == NULL) { + 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"); return; } cnxcc_lock(credit_data->lock); - if (credit_data->number_of_calls <= 0) { + if(credit_data->number_of_calls <= 0) { cnxcc_unlock(credit_data->lock); LM_DBG("No calls for current client\n"); return; } rows.len = 0; - rows.s = pkg_malloc(10); + rows.s = pkg_malloc(10); - if (rows.s == NULL) + if(rows.s == NULL) 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; memset(row_buffer, 0, sizeof(row_buffer)); - 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" - ",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); + 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" + ",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 - 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); - - row_len = strlen(row_buffer); - rows.s = pkg_reallocxf(rows.s, rows.len + row_len); - - if (rows.s == NULL) { + 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); + + row_len = strlen(row_buffer); + rows.s = pkg_reallocxf(rows.s, rows.len + row_len); + + if(rows.s == NULL) { cnxcc_unlock(credit_data->lock); goto nomem; } @@ -146,11 +150,11 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx) { cnxcc_unlock(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__); } - if (rows.s != NULL) + if(rows.s != NULL) pkg_free(rows.s); return; @@ -160,69 +164,72 @@ void rpc_check_client_stats(rpc_t* rpc, void* ctx) { 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; char row_buffer[512]; int index = 0; cnxcc_lock(hts->lock); - 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++) - 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; + 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; cnxcc_lock(credit_data->lock); int row_len = 0; memset(row_buffer, 0, sizeof(row_buffer)); - if (type == CREDIT_TIME) { - 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); - } - else if (type == CREDIT_MONEY) { - 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); - } - else { + if(type == CREDIT_TIME) { + 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); + } else if(type == CREDIT_MONEY) { + 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); + } else { LM_ERR("Unknown credit type: %d\n", type); return -1; } cnxcc_unlock(credit_data->lock); - row_len = strlen(row_buffer); - result->s = pkg_reallocxf(result->s, result->len + row_len); + row_len = strlen(row_buffer); + result->s = pkg_reallocxf(result->s, result->len + row_len); - if (result->s == NULL) { + if(result->s == NULL) { cnxcc_unlock(hts->lock); goto nomem; } memcpy(result->s + result->len, row_buffer, row_len); result->len += row_len; - } cnxcc_unlock(hts->lock); @@ -234,12 +241,13 @@ static int iterate_over_table(hash_tables_t *hts, str *result, credit_type_t typ return -1; } -void rpc_active_clients(rpc_t* rpc, void* ctx) { +void rpc_active_clients(rpc_t *rpc, void *ctx) +{ str rows; - rows.s = pkg_malloc(10); + rows.s = pkg_malloc(10); - if (rows.s == NULL) + if(rows.s == NULL) goto nomem; rows.len = 0; @@ -247,11 +255,11 @@ void rpc_active_clients(rpc_t* rpc, void* ctx) { iterate_over_table(&_data.time, &rows, CREDIT_TIME); 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__); } - if (rows.s != NULL) + if(rows.s != NULL) pkg_free(rows.s); return; @@ -260,4 +268,3 @@ void rpc_active_clients(rpc_t* rpc, void* ctx) { LM_ERR("No more pkg memory\n"); rpc->fault(ctx, 500, "No more memory\n"); } - diff --git a/src/modules/cnxcc/cnxcc_rpc.h b/src/modules/cnxcc/cnxcc_rpc.h index 99dacfd7601..1723cc28a1c 100644 --- a/src/modules/cnxcc/cnxcc_rpc.h +++ b/src/modules/cnxcc/cnxcc_rpc.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -25,9 +23,9 @@ #ifndef CNXCC_RPC_H_ #define CNXCC_RPC_H_ -void rpc_active_clients(rpc_t* rpc, void* ctx); -void rpc_kill_call(rpc_t* rpc, void* ctx); -void rpc_active_clients(rpc_t* rpc, void* ctx); -void rpc_check_client_stats(rpc_t* rpc, void* ctx); +void rpc_active_clients(rpc_t *rpc, void *ctx); +void rpc_kill_call(rpc_t *rpc, void *ctx); +void rpc_active_clients(rpc_t *rpc, void *ctx); +void rpc_check_client_stats(rpc_t *rpc, void *ctx); #endif /* CNXCC_RPC_H_ */ diff --git a/src/modules/cnxcc/cnxcc_select.c b/src/modules/cnxcc/cnxcc_select.c index f5cd2c61421..7e83c80eb68 100644 --- a/src/modules/cnxcc/cnxcc_select.c +++ b/src/modules/cnxcc/cnxcc_select.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -29,36 +27,38 @@ extern data_t _data; -int sel_root(str* res, select_t* s, struct sip_msg* msg) /* dummy */ { +int sel_root(str *res, select_t *s, struct sip_msg *msg) /* dummy */ +{ return 0; } -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"); return 0; } -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); +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); - credit_data_t *credit_data = NULL; - int value = 0; + credit_data_t *credit_data = NULL; + 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"); 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; 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\n", s->params[2].v.s.len, + s->params[2].v.s.s); - res->s = int2str(value, &res->len); + res->s = int2str(value, &res->len); return 0; } - - diff --git a/src/modules/cnxcc/cnxcc_select.h b/src/modules/cnxcc/cnxcc_select.h index f1cd3f988c5..1c87650efa1 100644 --- a/src/modules/cnxcc/cnxcc_select.h +++ b/src/modules/cnxcc/cnxcc_select.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -25,8 +23,8 @@ #ifndef CNXCC_SELECT_H_ #define CNXCC_SELECT_H_ -int sel_root(str* res, select_t* s, struct sip_msg* msg); -int sel_channels(str* res, select_t* s, struct sip_msg* msg); -int sel_channels_count(str* res, select_t* s, struct sip_msg* msg); +int sel_root(str *res, select_t *s, struct sip_msg *msg); +int sel_channels(str *res, select_t *s, struct sip_msg *msg); +int sel_channels_count(str *res, select_t *s, struct sip_msg *msg); #endif /* CNXCC_SELECT_H_ */ diff --git a/src/modules/cnxcc/cnxcc_sip_msg_faker.c b/src/modules/cnxcc/cnxcc_sip_msg_faker.c index e2b856f5b8a..7b601d537a7 100644 --- a/src/modules/cnxcc/cnxcc_sip_msg_faker.c +++ b/src/modules/cnxcc/cnxcc_sip_msg_faker.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -27,30 +25,34 @@ #include -#define FAKED_SIP_MSG_FORMAT "OPTIONS sip:you@kamailio.org SIP/2.0\r\nVia: SIP/2.0/UDP 127.0.0.1\r\nFrom: <%.*s>;tag=%.*s\r\nTo: <%.*s>;tag=%.*s\r\nCall-ID: %.*s\r\nCSeq: 1 OPTIONS\r\nContent-Length: 0\r\n\r\n" +#define FAKED_SIP_MSG_FORMAT \ + "OPTIONS sip:you@kamailio.org SIP/2.0\r\nVia: SIP/2.0/UDP " \ + "127.0.0.1\r\nFrom: <%.*s>;tag=%.*s\r\nTo: <%.*s>;tag=%.*s\r\nCall-ID: " \ + "%.*s\r\nCSeq: 1 OPTIONS\r\nContent-Length: 0\r\n\r\n" -#define FAKED_SIP_MSG_BUF_LEN 1024 +#define FAKED_SIP_MSG_BUF_LEN 1024 char _faked_sip_msg_buf[FAKED_SIP_MSG_BUF_LEN]; 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); - sprintf(_faked_sip_msg_buf, FAKED_SIP_MSG_FORMAT, - from_uri->len, from_uri->s, from_tag->len, from_tag->s, - to_uri->len, to_uri->s, to_tag->len, to_tag->s, - callid->len, callid->s); - + sprintf(_faked_sip_msg_buf, FAKED_SIP_MSG_FORMAT, from_uri->len, + from_uri->s, from_tag->len, from_tag->s, to_uri->len, to_uri->s, + to_tag->len, to_tag->s, callid->len, callid->s); + LM_DBG("fake msg:\n%s\n", _faked_sip_msg_buf); _faked_msg.buf = _faked_sip_msg_buf; _faked_msg.len = strlen(_faked_sip_msg_buf); - _faked_msg.set_global_address = default_global_address; - _faked_msg.set_global_port = default_global_port; + _faked_msg.set_global_address = default_global_address; + _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"); return -1; } @@ -65,6 +67,6 @@ int faked_msg_init_with_dlg_info(str *callid, str *from_uri, str *from_tag, str _faked_msg.rcv.dst_ip.af = AF_INET; _faked_msg.rcv.dst_ip.len = 4; - *msg = &_faked_msg; + *msg = &_faked_msg; return 0; } diff --git a/src/modules/cnxcc/cnxcc_sip_msg_faker.h b/src/modules/cnxcc/cnxcc_sip_msg_faker.h index 6f79e5cc3f6..b3e7abbbca6 100644 --- a/src/modules/cnxcc/cnxcc_sip_msg_faker.h +++ b/src/modules/cnxcc/cnxcc_sip_msg_faker.h @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (C) 2012 Carlos Ruiz Díaz (caruizdiaz.com), * ConexionGroup (www.conexiongroup.com) * @@ -24,6 +22,7 @@ #ifndef CNXCC_SIP_MSG_FAKER_H_ #define CNXCC_SIP_MSG_FAKER_H_ -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); #endif /* CNXCC_SIP_MSG_FAKER_H_ */