/* initiate a report if we previously enabled accounting for this t */ static inline void acc_onreply( struct cell* t, struct sip_msg *req, struct sip_msg *reply, int code, unsigned long long *flags) { str new_uri_bk; str dst_uri_bk; struct dlg_cell *dlg = NULL; str flags_s; int_str table; struct usr_avp *avp; /* acc_onreply is bound to TMCB_REPLY which may be called from _reply, like when FR hits; we should not miss this event for missed calls either */ if (is_invite(t) && code>=300 && is_mc_acc_on(*flags) ) { on_missed(t, req, reply, code, flags); } if (!should_acc_reply(req, reply, code, flags)) return; /* for reply processing, set as new_uri the winning branch */ if (t->relaied_reply_branch>=0) { new_uri_bk = req->new_uri; dst_uri_bk = req->dst_uri; req->new_uri = t->uac[t->relaied_reply_branch].uri; req->dst_uri = t->uac[t->relaied_reply_branch].duri; req->parsed_uri_ok = 0; } else { new_uri_bk.len = dst_uri_bk.len = -1; new_uri_bk.s = dst_uri_bk.s = NULL; } /* set env variables */ env_set_to( get_rpl_to(t,reply) ); env_set_code_status( code, reply); /* search for table avp */ table.s = db_table_acc; if (db_table_name != -1 && is_db_acc_on(*flags)) { avp = search_first_avp(db_table_name_type, db_table_name, &table, 0); if (!avp) { LM_DBG("table not set: using default %.*s\n", db_table_acc.len, db_table_acc.s); } else { if (!(avp->flags & AVP_VAL_STR)) { LM_WARN("invalid integer table name: using default %.*s\n", db_table_acc.len, db_table_acc.s); table.s = db_table_acc; } } } if (is_invite(t) && !has_totag(req) && is_cdr_acc_on(*flags) && code >= 200 && code < 300 && (dlg=dlg_api.get_dlg()) != NULL) { /* if dialog module loaded and INVITE and success reply */ if (store_core_leg_values(dlg, req) < 0) { LM_ERR("cannot store core and leg values\n"); return; } if(is_log_acc_on(*flags) && store_log_extra_values(dlg,req,reply)<0){ LM_ERR("cannot store string values\n"); return; } if(is_aaa_acc_on(*flags) && store_aaa_extra_values(dlg, req, reply)<0){ LM_ERR("cannot store aaa extra values\n"); return; } if (is_db_acc_on(*flags) && store_db_extra_values(dlg,req,reply)<0) { LM_ERR("cannot store database extra values\n"); return; } if (is_evi_acc_on(*flags) && store_evi_extra_values(dlg,req,reply)<0) { LM_ERR("cannot store database extra values\n"); return; } flags_s.s = (char*)flags; flags_s.len = sizeof(unsigned long long); /* store flags into dlg */ if ( dlg_api.store_dlg_value(dlg, &flags_str, &flags_s) < 0) { LM_ERR("cannot store flag value into dialog\n"); return; } /* store flags into dlg */ if ( dlg_api.store_dlg_value(dlg, &table_str, &table.s) < 0) { LM_ERR("cannot store the table name into dialog\n"); return; } /* report that flags shall be freed only by dialog module * tm must never free it */ set_dialog_context(*flags); /* register database callbacks */ if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED | DLGCB_EXPIRED, acc_dlg_callback,flags, dlg_free_acc_mask) != 0) { LM_ERR("cannot register callback for database accounting\n"); return; } } else { /* do old accounting */ if ( is_evi_acc_on(*flags) ) { env_set_event(acc_event); acc_evi_request( req, reply, 0 ); } if ( is_log_acc_on(*flags) ) { env_set_text( ACC_ANSWERED, ACC_ANSWERED_LEN); acc_log_request( req, reply, 0 ); } if (is_aaa_acc_on(*flags)) acc_aaa_request( req, reply, 0 ); if (is_db_acc_on(*flags)) { env_set_text( table.s.s, table.s.len); acc_db_request( req, reply, &acc_ins_list, 0); } } /* DIAMETER */ #ifdef DIAM_ACC if (is_diam_acc_on(req)) acc_diam_request( req, reply ); #endif if (new_uri_bk.len>=0) { req->new_uri = new_uri_bk; req->dst_uri = dst_uri_bk; req->parsed_uri_ok = 0; } }
/* initiate a report if we previously enabled accounting for this t */ static inline void acc_onreply( struct cell* t, struct sip_msg *req, struct sip_msg *reply, int code, acc_ctx_t* ctx) { str new_uri_bk; str dst_uri_bk; struct dlg_cell *dlg = NULL; str ctx_s; str table; unsigned long long* flags = &ctx->flags; /* acc_onreply is bound to TMCB_REPLY which may be called from _reply, like when FR hits; we should not miss this event for missed calls either */ if (is_invite(t) && code>=300 && is_mc_acc_on(*flags) ) { on_missed(t, req, reply, code, ctx); } if (!should_acc_reply(req, reply, code, flags)) return; /* for reply processing, set as new_uri the winning branch */ if (t->relaied_reply_branch>=0) { new_uri_bk = req->new_uri; dst_uri_bk = req->dst_uri; req->new_uri = t->uac[t->relaied_reply_branch].uri; req->dst_uri = t->uac[t->relaied_reply_branch].duri; req->parsed_uri_ok = 0; } else { new_uri_bk.len = dst_uri_bk.len = -1; new_uri_bk.s = dst_uri_bk.s = NULL; } /* set env variables */ env_set_to( get_rpl_to(t,reply) ); env_set_code_status( code, reply); /* search for table avp */ if (is_db_acc_on(ctx->flags)) table = ctx->acc_table; else { table.s = 0; table.len = 0; } if (is_invite(t) && !has_totag(req) && is_cdr_acc_on(ctx->flags) && code >= 200 && code < 300 && (dlg=dlg_api.get_dlg()) != NULL) { /* if dialog module loaded and INVITE and success reply */ if (store_core_leg_values(dlg, req) < 0) { LM_ERR("cannot store core and leg values\n"); return; } ctx_s.s = (char*)&ctx; ctx_s.len = sizeof(acc_ctx_t *); /* store context pointer into dialog */ if (dlg_api.store_dlg_value(dlg, &acc_ctx_str, &ctx_s) < 0) { LM_ERR("cannot store context pointer into dlg val!\n"); return; } /* report that flags shall be freed only by dialog module * tm must never free it */ set_dialog_context(*flags); /* register program shutdown callback * won't register free function since TERMINATED|EXPIRED callback * free function will be called to free */ if (dlg_api.register_dlgcb(dlg, DLGCB_DB_WRITE_VP, acc_dlg_onshutdown, ctx, NULL) != 0) { LM_ERR("cannot register callback for program shutdown!\n"); return; } /* register database callbacks */ if (dlg_api.register_dlgcb(dlg, DLGCB_TERMINATED|DLGCB_EXPIRED, acc_dlg_callback, ctx, dlg_free_acc_ctx) != 0) { LM_ERR("cannot register callback for database accounting\n"); return; } } else { /* do old accounting */ if ( is_evi_acc_on(*flags) ) { env_set_event(acc_event); acc_evi_request( req, reply, 0 ); } if ( is_log_acc_on(*flags) ) { env_set_text( ACC_ANSWERED, ACC_ANSWERED_LEN); acc_log_request( req, reply, 0 ); } if (is_aaa_acc_on(*flags)) acc_aaa_request( req, reply, 0 ); if (is_db_acc_on(*flags)) { env_set_text( table.s, table.len); acc_db_request( req, reply, &acc_ins_list, 0); } } if (new_uri_bk.len>=0) { req->new_uri = new_uri_bk; req->dst_uri = dst_uri_bk; req->parsed_uri_ok = 0; } }