|
|
|
|
@ -68,12 +68,12 @@
|
|
|
|
|
|
|
|
|
|
MODULE_VERSION
|
|
|
|
|
|
|
|
|
|
#define HT_SIZE 229
|
|
|
|
|
#define MODULE_NAME "cnxcc"
|
|
|
|
|
#define NUMBER_OF_TIMERS 2
|
|
|
|
|
#define HT_SIZE 229
|
|
|
|
|
#define MODULE_NAME "cnxcc"
|
|
|
|
|
#define NUMBER_OF_TIMERS 2
|
|
|
|
|
|
|
|
|
|
#define TRUE 1
|
|
|
|
|
#define FALSE 0
|
|
|
|
|
#define TRUE 1
|
|
|
|
|
#define FALSE 0
|
|
|
|
|
|
|
|
|
|
data_t _data;
|
|
|
|
|
struct dlg_binds _dlgbinds;
|
|
|
|
|
@ -154,7 +154,7 @@ static cmd_export_t cmds[] =
|
|
|
|
|
|
|
|
|
|
static param_export_t params[] =
|
|
|
|
|
{
|
|
|
|
|
{"dlg_flag", INT_PARAM, &_data.ctrl_flag },
|
|
|
|
|
{"dlg_flag", INT_PARAM, &_data.ctrl_flag },
|
|
|
|
|
{"credit_check_period", INT_PARAM, &_data.check_period },
|
|
|
|
|
{ 0, 0, 0 }
|
|
|
|
|
};
|
|
|
|
|
@ -198,17 +198,17 @@ select_row_t sel_declaration[] = {
|
|
|
|
|
struct module_exports exports =
|
|
|
|
|
{
|
|
|
|
|
MODULE_NAME,
|
|
|
|
|
DEFAULT_DLFLAGS, /* dlopen flags */
|
|
|
|
|
DEFAULT_DLFLAGS,/* dlopen flags */
|
|
|
|
|
cmds,
|
|
|
|
|
params,
|
|
|
|
|
0, /* exported statistics */
|
|
|
|
|
0, /* exported MI functions */
|
|
|
|
|
mod_pvs, /* exported pseudo-variables */
|
|
|
|
|
0, /* extra processes */
|
|
|
|
|
mod_init, /* module initialization function */
|
|
|
|
|
0, /* exported statistics */
|
|
|
|
|
0, /* exported MI functions */
|
|
|
|
|
mod_pvs, /* exported pseudo-variables */
|
|
|
|
|
0, /* extra processes */
|
|
|
|
|
mod_init, /* module initialization function */
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
child_init /* per-child init function */
|
|
|
|
|
child_init /* per-child init function */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int fixup_par(void** param, int param_no)
|
|
|
|
|
@ -261,7 +261,7 @@ static int mod_init(void)
|
|
|
|
|
_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));
|
|
|
|
|
|
|
|
|
|
_data.stats = (stats_t *) shm_malloc(sizeof(stats_t));
|
|
|
|
|
_data.stats = (stats_t *) shm_malloc(sizeof(stats_t));
|
|
|
|
|
|
|
|
|
|
if (!_data.stats)
|
|
|
|
|
{
|
|
|
|
|
@ -269,9 +269,9 @@ static int mod_init(void)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_data.stats->active = 0;
|
|
|
|
|
_data.stats->active = 0;
|
|
|
|
|
_data.stats->dropped = 0;
|
|
|
|
|
_data.stats->total = 0;
|
|
|
|
|
_data.stats->total = 0;
|
|
|
|
|
|
|
|
|
|
if (init_hashtable(_data.time.credit_data_by_client) != 0)
|
|
|
|
|
return -1;
|
|
|
|
|
@ -336,8 +336,7 @@ static int child_init(int rank)
|
|
|
|
|
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 to register MB TIMER routine as process\n");
|
|
|
|
|
return -1;
|
|
|
|
|
@ -423,11 +422,11 @@ static void notify_call_termination(str *callid, str *from_tag, str *to_tag)
|
|
|
|
|
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;
|
|
|
|
|
hash_tables_t *hts = NULL;
|
|
|
|
|
*credit_data = NULL;
|
|
|
|
|
|
|
|
|
|
/* by money */
|
|
|
|
|
hts = &_data.money;
|
|
|
|
|
hts = &_data.money;
|
|
|
|
|
lock_get(&hts->lock);
|
|
|
|
|
|
|
|
|
|
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
|
|
|
|
|
@ -442,7 +441,7 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
|
|
|
|
|
lock_release(&hts->lock);
|
|
|
|
|
|
|
|
|
|
/* by time */
|
|
|
|
|
hts = &_data.time;
|
|
|
|
|
hts = &_data.time;
|
|
|
|
|
lock_get(&hts->lock);
|
|
|
|
|
|
|
|
|
|
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
|
|
|
|
|
@ -457,7 +456,7 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
|
|
|
|
|
lock_release(&hts->lock);
|
|
|
|
|
|
|
|
|
|
/* by channel */
|
|
|
|
|
hts = &_data.channel;
|
|
|
|
|
hts = &_data.channel;
|
|
|
|
|
lock_get(&hts->lock);
|
|
|
|
|
|
|
|
|
|
cd_entry = str_hash_get(hts->credit_data_by_client, client_id->s, client_id->len);
|
|
|
|
|
@ -477,11 +476,10 @@ int try_get_credit_data_entry(str *client_id, credit_data_t **credit_data)
|
|
|
|
|
int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts)
|
|
|
|
|
{
|
|
|
|
|
struct str_hash_entry *call_entry = NULL;
|
|
|
|
|
|
|
|
|
|
*call = NULL;
|
|
|
|
|
|
|
|
|
|
/* by money */
|
|
|
|
|
*hts = &_data.money;
|
|
|
|
|
*hts = &_data.money;
|
|
|
|
|
lock_get(&(*hts)->lock);
|
|
|
|
|
|
|
|
|
|
call_entry = str_hash_get((*hts)->call_data_by_cid, callid->s, callid->len);
|
|
|
|
|
@ -531,9 +529,9 @@ int try_get_call_entry(str *callid, call_t **call, hash_tables_t **hts)
|
|
|
|
|
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;
|
|
|
|
|
call_t *call = NULL;
|
|
|
|
|
hash_tables_t *hts = NULL;
|
|
|
|
|
credit_data_t *credit_data = NULL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Search call data by call-id
|
|
|
|
|
@ -557,11 +555,10 @@ static void stop_billing(str *callid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lock_get(&hts->lock);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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)
|
|
|
|
|
{
|
|
|
|
|
@ -580,12 +577,12 @@ static void stop_billing(str *callid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lock_release(&hts->lock);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Update calls statistics
|
|
|
|
|
*/
|
|
|
|
|
lock_get(&_data.lock);
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
_data.stats->active--;
|
|
|
|
|
_data.stats->total--;
|
|
|
|
|
|
|
|
|
|
@ -831,7 +828,7 @@ exit:
|
|
|
|
|
void terminate_all_calls(credit_data_t *credit_data)
|
|
|
|
|
{
|
|
|
|
|
call_t *call = NULL,
|
|
|
|
|
*tmp = NULL;
|
|
|
|
|
*tmp = NULL;
|
|
|
|
|
|
|
|
|
|
clist_foreach_safe(credit_data->call_list, call, tmp, next)
|
|
|
|
|
{
|
|
|
|
|
@ -855,15 +852,15 @@ static void free_call(call_t *call)
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
e = str_hash_get(_data.channel.call_data_by_cid, call->sip_data.callid.s, call->sip_data.callid.len);
|
|
|
|
|
|
|
|
|
|
if (e == NULL)
|
|
|
|
|
{
|
|
|
|
|
@ -910,21 +907,21 @@ static int shm_str_hash_alloc(struct str_hash_table *ht, int size)
|
|
|
|
|
static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_type_t type)
|
|
|
|
|
{
|
|
|
|
|
struct str_hash_table *ht = NULL;
|
|
|
|
|
gen_lock_t *lock = NULL;
|
|
|
|
|
gen_lock_t *lock = NULL;
|
|
|
|
|
struct str_hash_entry *e = NULL;
|
|
|
|
|
|
|
|
|
|
switch(type)
|
|
|
|
|
{
|
|
|
|
|
case CREDIT_MONEY:
|
|
|
|
|
ht = _data.money.credit_data_by_client;
|
|
|
|
|
ht = _data.money.credit_data_by_client;
|
|
|
|
|
lock = &_data.money.lock;
|
|
|
|
|
break;
|
|
|
|
|
case CREDIT_TIME:
|
|
|
|
|
ht = _data.time.credit_data_by_client;
|
|
|
|
|
ht = _data.time.credit_data_by_client;
|
|
|
|
|
lock = &_data.time.lock;
|
|
|
|
|
break;
|
|
|
|
|
case CREDIT_CHANNEL:
|
|
|
|
|
ht = _data.channel.credit_data_by_client;
|
|
|
|
|
ht = _data.channel.credit_data_by_client;
|
|
|
|
|
lock = &_data.channel.lock;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
@ -934,7 +931,7 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lock_get(lock);
|
|
|
|
|
e = str_hash_get(ht, client_id->s, client_id->len);
|
|
|
|
|
e = str_hash_get(ht, client_id->s, client_id->len);
|
|
|
|
|
lock_release(lock);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@ -947,7 +944,7 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
credit_data_t *credit_data = NULL;
|
|
|
|
|
e = shm_malloc(sizeof(struct str_hash_entry));
|
|
|
|
|
e = shm_malloc(sizeof(struct str_hash_entry));
|
|
|
|
|
|
|
|
|
|
if (e == NULL)
|
|
|
|
|
{
|
|
|
|
|
@ -961,9 +958,9 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e->flags = 0;
|
|
|
|
|
e->u.p = (void *) shm_malloc(sizeof(credit_data_t));
|
|
|
|
|
credit_data = (credit_data_t *) e->u.p;
|
|
|
|
|
e->flags = 0;
|
|
|
|
|
e->u.p = (void *) shm_malloc(sizeof(credit_data_t));
|
|
|
|
|
credit_data = (credit_data_t *) e->u.p;
|
|
|
|
|
|
|
|
|
|
lock_init(&credit_data->lock);
|
|
|
|
|
|
|
|
|
|
@ -975,13 +972,13 @@ static credit_data_t *get_or_create_credit_data_entry(str *client_id, credit_typ
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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->type = type;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copy the client_id value to the root of the calls list.
|
|
|
|
|
@ -1018,7 +1015,7 @@ int terminate_call(call_t *call)
|
|
|
|
|
|
|
|
|
|
struct mi_root *root, *result = NULL;
|
|
|
|
|
struct mi_node *node, *node1 = NULL;
|
|
|
|
|
struct mi_cmd *end_dlg_cmd = NULL;
|
|
|
|
|
struct mi_cmd *end_dlg_cmd = NULL;
|
|
|
|
|
|
|
|
|
|
root = init_mi_tree(0, 0, 0);
|
|
|
|
|
if (root == NULL)
|
|
|
|
|
@ -1062,7 +1059,7 @@ int terminate_call(call_t *call)
|
|
|
|
|
LM_DBG("dlg_end_dlg sent to call [%.*s]\n", call->sip_data.callid.len, call->sip_data.callid.s);
|
|
|
|
|
free_mi_tree(root);
|
|
|
|
|
free_mi_tree(result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notify_call_termination(&call->sip_data.callid, &call->sip_data.from_tag, &call->sip_data.to_tag);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
@ -1076,8 +1073,7 @@ error:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
@ -1089,7 +1085,7 @@ static call_t *alloc_new_call_by_money(credit_data_t *credit_data,
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
call = shm_malloc(sizeof(call_t));
|
|
|
|
|
call = shm_malloc(sizeof(call_t));
|
|
|
|
|
if (call == NULL)
|
|
|
|
|
{
|
|
|
|
|
LM_ERR("No shared memory left\n");
|
|
|
|
|
@ -1106,11 +1102,11 @@ static call_t *alloc_new_call_by_money(credit_data_t *credit_data,
|
|
|
|
|
call->sip_data.to_tag.s = NULL;
|
|
|
|
|
call->sip_data.to_tag.len = 0;
|
|
|
|
|
call->sip_data.from_tag.s = NULL;
|
|
|
|
|
call->sip_data.from_tag.len = 0;
|
|
|
|
|
call->sip_data.from_tag.len = 0;
|
|
|
|
|
|
|
|
|
|
call->consumed_amount = initial_pulse * cost_per_second;
|
|
|
|
|
call->confirmed = FALSE;
|
|
|
|
|
call->max_amount = credit;
|
|
|
|
|
call->confirmed = FALSE;
|
|
|
|
|
call->max_amount = credit;
|
|
|
|
|
|
|
|
|
|
call->money_based.cost_per_second = cost_per_second;
|
|
|
|
|
call->money_based.initial_pulse = initial_pulse;
|
|
|
|
|
@ -1174,17 +1170,17 @@ static call_t *alloc_new_call_by_time(credit_data_t *credit_data, struct sip_msg
|
|
|
|
|
call->sip_data.to_tag.s = NULL;
|
|
|
|
|
call->sip_data.to_tag.len = 0;
|
|
|
|
|
call->sip_data.from_tag.s = NULL;
|
|
|
|
|
call->sip_data.from_tag.len = 0;
|
|
|
|
|
call->sip_data.from_tag.len = 0;
|
|
|
|
|
|
|
|
|
|
call->consumed_amount = 0;
|
|
|
|
|
call->confirmed = FALSE;
|
|
|
|
|
call->max_amount = max_secs;
|
|
|
|
|
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
|
|
|
|
|
@ -1211,7 +1207,7 @@ error:
|
|
|
|
|
|
|
|
|
|
static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_msg *msg, int max_chan)
|
|
|
|
|
{
|
|
|
|
|
call_t *call = NULL;
|
|
|
|
|
call_t *call = NULL;
|
|
|
|
|
|
|
|
|
|
lock_get(&credit_data->lock);
|
|
|
|
|
|
|
|
|
|
@ -1221,7 +1217,7 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
call = shm_malloc(sizeof(call_t));
|
|
|
|
|
call = shm_malloc(sizeof(call_t));
|
|
|
|
|
if (call == NULL)
|
|
|
|
|
{
|
|
|
|
|
LM_ERR("No shared memory left\n");
|
|
|
|
|
@ -1238,17 +1234,17 @@ static call_t *alloc_new_call_by_channel(credit_data_t *credit_data, struct sip_
|
|
|
|
|
call->sip_data.to_tag.s = NULL;
|
|
|
|
|
call->sip_data.to_tag.len = 0;
|
|
|
|
|
call->sip_data.from_tag.s = NULL;
|
|
|
|
|
call->sip_data.from_tag.len = 0;
|
|
|
|
|
call->sip_data.from_tag.len = 0;
|
|
|
|
|
|
|
|
|
|
call->consumed_amount = 0;
|
|
|
|
|
call->confirmed = FALSE;
|
|
|
|
|
call->max_amount = max_chan;
|
|
|
|
|
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
|
|
|
|
|
@ -1277,21 +1273,21 @@ error:
|
|
|
|
|
static int add_call_by_cid(str *cid, call_t *call, credit_type_t type)
|
|
|
|
|
{
|
|
|
|
|
struct str_hash_table *ht = NULL;
|
|
|
|
|
gen_lock_t *lock = NULL;
|
|
|
|
|
gen_lock_t *lock = NULL;
|
|
|
|
|
struct str_hash_entry *e = NULL;
|
|
|
|
|
|
|
|
|
|
switch(type)
|
|
|
|
|
{
|
|
|
|
|
case CREDIT_MONEY:
|
|
|
|
|
ht = _data.money.call_data_by_cid;
|
|
|
|
|
ht = _data.money.call_data_by_cid;
|
|
|
|
|
lock = &_data.money.lock;
|
|
|
|
|
break;
|
|
|
|
|
case CREDIT_TIME:
|
|
|
|
|
ht = _data.time.call_data_by_cid;
|
|
|
|
|
ht = _data.time.call_data_by_cid;
|
|
|
|
|
lock = &_data.time.lock;
|
|
|
|
|
break;
|
|
|
|
|
case CREDIT_CHANNEL:
|
|
|
|
|
ht = _data.channel.call_data_by_cid;
|
|
|
|
|
ht = _data.channel.call_data_by_cid;
|
|
|
|
|
lock = &_data.channel.lock;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
@ -1343,7 +1339,7 @@ static int add_call_by_cid(str *cid, call_t *call, credit_type_t type)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e->u.p = call;
|
|
|
|
|
e->u.p = call;
|
|
|
|
|
|
|
|
|
|
lock_get(lock);
|
|
|
|
|
str_hash_add(ht, e);
|
|
|
|
|
@ -1373,30 +1369,30 @@ static inline int get_pv_value(struct sip_msg* msg, pv_spec_t* spec, pv_value_t*
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
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;
|
|
|
|
|
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,
|
|
|
|
|
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;
|
|
|
|
|
*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;
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
@ -1539,10 +1535,10 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
*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)
|
|
|
|
|
{
|
|
|
|
|
@ -1556,14 +1552,14 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (try_get_credit_data_entry(&client_id_val.rs, &credit_data) == 0)
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (!pv_is_w(chan_count_spec))
|
|
|
|
|
{
|
|
|
|
|
LM_ERR("pvar is not writable");
|
|
|
|
|
LM_ERR("pvar is not writable\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1575,7 +1571,7 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
|
|
|
|
|
chan_count_val.rs.s = int2str(value, &chan_count_val.rs.len);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char buff[2] = { '-', '1' };
|
|
|
|
|
char buff[2] = { '-', '1' };
|
|
|
|
|
chan_count_val.rs.s = buff;
|
|
|
|
|
chan_count_val.rs.len = 2;
|
|
|
|
|
}
|
|
|
|
|
@ -1592,11 +1588,11 @@ static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
*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);
|
|
|
|
|
|
|
|
|
|
@ -1640,8 +1636,8 @@ static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
@ -1650,7 +1646,7 @@ static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
return -2; // you have, among calls being setup plus those established, more than you maximum quota
|
|
|
|
|
|
|
|
|
|
if (credit_data->concurrent_calls + 1 > max_chan)
|
|
|
|
|
return -3; // you have the max amount of established calls already
|
|
|
|
|
@ -1679,11 +1675,11 @@ static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_
|
|
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
*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);
|
|
|
|
|
|
|
|
|
|
@ -1812,7 +1808,7 @@ static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_p
|
|
|
|
|
*tmp_call = NULL;
|
|
|
|
|
|
|
|
|
|
lock_get(&_data.time.lock);
|
|
|
|
|
e = str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
|
|
|
|
|
e = str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
|
|
|
|
|
lock_release(&_data.time.lock);
|
|
|
|
|
|
|
|
|
|
if (e == NULL)
|
|
|
|
|
@ -1821,13 +1817,13 @@ static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_p
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
credit_data = (credit_data_t *) e->u.p;
|
|
|
|
|
credit_data = (credit_data_t *) e->u.p;
|
|
|
|
|
|
|
|
|
|
lock_get(&credit_data->lock);
|
|
|
|
|
|
|
|
|
|
LM_DBG("Updating max-secs for [%.*s] from [%f] to [%f]\n", e->key.len, e->key.s, credit_data->max_amount, credit_data->max_amount + secs);
|
|
|
|
|
|
|
|
|
|
credit_data->max_amount += secs;
|
|
|
|
|
credit_data->max_amount += secs;
|
|
|
|
|
|
|
|
|
|
if (credit_data->number_of_calls > 0)
|
|
|
|
|
update_fraction = secs / credit_data->number_of_calls;
|
|
|
|
|
@ -1840,7 +1836,7 @@ static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_p
|
|
|
|
|
call->max_amount += update_fraction;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//redit_data->consumed_amount = 0;
|
|
|
|
|
//redit_data->consumed_amount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lock_release(&credit_data->lock);
|
|
|
|
|
|