Skip to content

Commit

Permalink
[acc]cancel_accounting function for acc
Browse files Browse the repository at this point in the history
This function allows unsetting parameters set by do accounting
function. It has the same parameters excepting the table name.
  • Loading branch information
ionutrazvanionita committed Mar 25, 2016
1 parent 29aa72f commit 0548384
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 68 deletions.
153 changes: 88 additions & 65 deletions modules/acc/acc_logic.c
Expand Up @@ -57,6 +57,8 @@ extern str table_str;
extern str acc_created_avp_name;
extern int acc_created_avp_id;

extern int acc_flags_ctx_idx;

struct acc_enviroment acc_env;

static query_list_t *acc_ins_list = NULL;
Expand Down Expand Up @@ -140,6 +142,7 @@ void free_acc_mask(void* param) {
shm_free((unsigned long long *)param);
}


static inline struct hdr_field* get_rpl_to( struct cell *t,
struct sip_msg *reply)
{
Expand Down Expand Up @@ -374,59 +377,6 @@ static inline int has_totag(struct sip_msg *msg)
}



/* prepare message and transaction context for later accounting */
void acc_onreq( struct cell* t, int type, struct tmcb_params *ps )
{
#if 0
int tmcb_types;
int is_invite;
int_str _avp_created_value;

if ( ps->req && !skip_cancel(ps->req) &&
(is_acc_on(ps->req) || is_mc_on(ps->req)) ) {
/* do some parsing in advance */
if (acc_preparse_req(ps->req)<0)
return;
is_invite = (ps->req->REQ_METHOD==METHOD_INVITE)?1:0;
/* install additional handlers */
tmcb_types =
/* report on completed transactions */
TMCB_RESPONSE_OUT |
/* get incoming replies ready for processing */
TMCB_RESPONSE_IN |
/* report on missed calls */
((is_invite && is_mc_on(ps->req))?TMCB_ON_FAILURE:0) ;

/* if cdr accounting is enabled */
if (is_cdr_acc_on(ps->req) && !has_totag(ps->req)) {
_avp_created_value.n = time(NULL);

if ( add_avp(0, acc_created_avp_id, _avp_created_value) != 0) {
LM_ERR("failed to add created avp value!\n");
return;
}

if (is_invite && create_acc_dlg(ps->req) < 0) {
LM_ERR("cannot use dialog accounting module\n");
return;
}
}
if (tmb.register_tmcb( 0, t, tmcb_types, tmcb_func, 0, 0 )<=0) {
LM_ERR("cannot register additional callbacks\n");
return;
}
/* if required, determine request direction */
if( detect_direction && !rrb.is_direction(ps->req,RR_FLOW_UPSTREAM) ) {
LM_DBG("detected an UPSTREAM req -> flaging it\n");
ps->req->msg_flags |= FL_REQ_UPSTREAM;
}
}
#endif
}



/* is this reply of interest for accounting ? */
static inline int should_acc_reply(struct sip_msg *req,struct sip_msg *rpl,
int code, unsigned long long* flags)
Expand Down Expand Up @@ -554,7 +504,7 @@ void acc_loaded_callback(struct dlg_cell *dlg, int type,

/* register database callbacks */
if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED |
DLGCB_EXPIRED, acc_dlg_callback, flags_s.s, free_acc_mask)){
DLGCB_EXPIRED, acc_dlg_callback, flags_s.s, 0)){
LM_ERR("cannot register callback for database accounting\n");
return;
}
Expand Down Expand Up @@ -658,7 +608,7 @@ static inline void acc_onreply( struct cell* t, struct sip_msg *req,

/* register database callbacks */
if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED |
DLGCB_EXPIRED, acc_dlg_callback,flags_s.s,0) != 0) {
DLGCB_EXPIRED, acc_dlg_callback,flags_s.s,free_acc_mask) != 0) {
LM_ERR("cannot register callback for database accounting\n");
return;
}
Expand Down Expand Up @@ -990,7 +940,7 @@ int w_do_acc_2(struct sip_msg* msg, char* type, char* flags)
int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)
{
unsigned long long type=0, flags=0;
unsigned long long *flag_mask;
unsigned long long *flag_mask_p, flag_mask;

acc_type_param_t* acc_param;

Expand Down Expand Up @@ -1022,13 +972,21 @@ int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)
}
}


if (flags_p != NULL) {
flags= *(unsigned long long*)flags_p;
}

flag_mask=shm_malloc(sizeof(unsigned long long));
if (flag_mask==NULL) {
flag_mask = type + type * flags;

/* if already called the function once */
if ((flag_mask_p=ACC_GET_FLAGS) != NULL) {
*flag_mask_p |= flag_mask;
return 1;
}


flag_mask_p=shm_malloc(sizeof(unsigned long long));
if (flag_mask_p==NULL) {
LM_ERR("No more shm mem!\n");
return -1;
}
Expand All @@ -1041,8 +999,8 @@ int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)
* so we keep the first bits in each byte and on the following positions
* next flags
*/
*flag_mask = type + type*flags;

*flag_mask_p = flag_mask;
ACC_PUT_FLAGS(flag_mask_p);

if (table_p != NULL) {
if (fixup_get_svalue(msg, (gparam_p)table_p, &table_name) < 0) {
Expand All @@ -1053,7 +1011,7 @@ int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)


if ( msg && !skip_cancel(msg) &&
(is_acc_on(*flag_mask) || is_mc_acc_on(*flag_mask)) ) {
(is_acc_on(*flag_mask_p) || is_mc_acc_on(*flag_mask_p)) ) {
/* do some parsing in advance */
if (acc_preparse_req(msg)<0)
return -1;
Expand All @@ -1065,10 +1023,10 @@ int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)
/* get incoming replies ready for processing */
TMCB_RESPONSE_IN |
/* report on missed calls */
((is_invite && is_mc_acc_on(*flag_mask))?TMCB_ON_FAILURE:0) ;
((is_invite && is_mc_acc_on(*flag_mask_p))?TMCB_ON_FAILURE:0) ;

/* if cdr accounting is enabled */
if (is_cdr_acc_on(*flag_mask) && !has_totag(msg)) {
if (is_cdr_acc_on(*flag_mask_p) && !has_totag(msg)) {
_avp_created_value.n = time(NULL);

if ( add_avp(0, acc_created_avp_id, _avp_created_value) != 0) {
Expand All @@ -1083,11 +1041,12 @@ int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)
}

if (tmb.register_tmcb( msg, 0, tmcb_types, tmcb_func,
flag_mask, is_cdr_acc_on(*flag_mask) ? 0 : free_acc_mask)<=0) {
flag_mask_p, is_cdr_acc_on(*flag_mask_p) ? 0 : free_acc_mask)<=0) {
LM_ERR("cannot register additional callbacks\n");
return -1;
}


/* if required, determine request direction */
if( detect_direction && !rrb.is_direction(msg,RR_FLOW_UPSTREAM) ) {
LM_DBG("detected an UPSTREAM req -> flaging it\n");
Expand All @@ -1097,3 +1056,67 @@ int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p)

return 1;
}

/* reset all flags */
int w_cancel_acc_0(struct sip_msg* msg) {
return w_cancel_acc_2(msg, NULL, NULL);
}

int w_cancel_acc_1(struct sip_msg* msg, char* type)
{
return w_cancel_acc_2(msg, type, NULL);
}

int w_cancel_acc_2(struct sip_msg* msg, char* type_p, char* flags_p)
{
unsigned long long type=0;
/* if not set, we reset all flags for the type of accounting requested */
unsigned long long flags=ALL_ACC_FLAGS;
unsigned long long flag_mask;
unsigned long long *context_flags_p=ACC_GET_FLAGS;


acc_type_param_t* acc_param;

str in;

if (context_flags_p == NULL) {
LM_ERR("do_accounting() not used! This function resets flags in "
"do_accounting()!\n");
return -1;
}

if (type_p != NULL) {
acc_param = (acc_type_param_t *)type_p;
if (acc_param->t == DO_ACC_PARAM_TYPE_VALUE) {
type = acc_param->u.ival;
} else {
if (pv_printf_s(msg, acc_param->u.pval, &in) < 0) {
LM_ERR("failed to fetch type value!\n");
return -1;
}

if ((type=do_acc_parse(&in, do_acc_type_parser)) < 0) {
LM_ERR("Invalid expression <%.*s> for acc type!\n", in.len, in.s);
return -1;
}
}
}

if (flags_p != NULL) {
flags= *(unsigned long long*)flags_p;
}

flag_mask = type * flags;

/* reset all flags */
if (flag_mask == 0) {
*context_flags_p = 0;
} else {
reset_flags(*context_flags_p, flag_mask);
}

return 1;
}


17 changes: 15 additions & 2 deletions modules/acc/acc_logic.h
Expand Up @@ -42,6 +42,7 @@
#define DO_ACC_CDR (1<<1)
#define DO_ACC_MISSED (1<<2)
#define DO_ACC_FAILED (1<<3)
#define ALL_ACC_FLAGS (DO_ACC|DO_ACC_CDR|DO_ACC_MISSED|DO_ACC_FAILED)

#define DO_ACC_PARAM_TYPE_PV (1<<0)
#define DO_ACC_PARAM_TYPE_VALUE (1<<1)
Expand All @@ -58,6 +59,16 @@

#define DO_ACC_PARAM_DELIMITER '|'

#define ACC_PUT_FLAGS(_ptr) \
context_put_ptr(CONTEXT_GLOBAL, current_processing_ctx, \
acc_flags_ctx_idx, _ptr)


#define ACC_GET_FLAGS \
context_get_ptr(CONTEXT_GLOBAL, current_processing_ctx, \
acc_flags_ctx_idx)


typedef unsigned long long (*do_acc_parser)(str*);

typedef struct acc_type_param {
Expand Down Expand Up @@ -87,8 +98,6 @@ struct acc_param {
};


void acc_onreq( struct cell* t, int type, struct tmcb_params *ps );

int w_acc_log_request(struct sip_msg *rq, pv_elem_t* comment, char *foo);

int w_acc_aaa_request(struct sip_msg *rq, pv_elem_t* comment, char *foo);
Expand All @@ -114,4 +123,8 @@ int w_do_acc_1(struct sip_msg* msg, char* type);
int w_do_acc_2(struct sip_msg* msg, char* type, char* flags);
int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p);

int w_cancel_acc_0(struct sip_msg* msg);
int w_cancel_acc_1(struct sip_msg* msg, char* type);
int w_cancel_acc_2(struct sip_msg* msg, char* type, char* flags);

#endif
17 changes: 16 additions & 1 deletion modules/acc/acc_mod.c
Expand Up @@ -167,7 +167,8 @@ struct acc_extra *evi_extra_bye = 0;
str acc_created_avp_name = str_init("accX_created");
int acc_created_avp_id = -1;


/* acc context position */
int acc_flags_ctx_idx;

/* ------------- fixup function --------------- */
static int acc_fixup(void** param, int param_no);
Expand Down Expand Up @@ -209,6 +210,19 @@ static cmd_export_t cmds[] = {
do_acc_fixup, NULL,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},

{"cancel_accounting", (cmd_function)w_cancel_acc_0, 0, 0, NULL,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},

/* we use the same fixup function since the parameters
* have the same meanining as for do_accounting */
{"cancel_accounting", (cmd_function)w_cancel_acc_1, 1,
do_acc_fixup, NULL,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},

{"cancel_accounting", (cmd_function)w_cancel_acc_2, 2,
do_acc_fixup, NULL,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},

{0, 0, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -506,6 +520,7 @@ static int mod_init( void )

#endif

acc_flags_ctx_idx = context_register_ptr(CONTEXT_GLOBAL, NULL);

return 0;
}
Expand Down

0 comments on commit 0548384

Please sign in to comment.