123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833 |
- /**
- * $Id$
- *
- * Copyright (C) 2009
- *
- * This file is part of SIP-Router.org, a free SIP server.
- *
- * SIP-Router is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * Kamailio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "../../sr_module.h"
- #include "../../dprint.h"
- #include "../../mod_fix.h"
- #include "../../route.h"
- #include "../../script_cb.h"
- #include "../../modules/tm/tm_load.h"
- #include "../../lib/kcore/kstats_wrapper.h"
- #include "../../dset.h"
- #include "t_var.h"
- #include "t_mi.h"
- #include "tmx_pretran.h"
- #include "api.h"
- MODULE_VERSION
- /** TM bind */
- struct tm_binds _tmx_tmb;
- /** parameters */
- /** module functions */
- static int mod_init(void);
- static int child_init(int rank);
- static void destroy(void);
- static int t_cancel_branches(struct sip_msg* msg, char *k, char *s2);
- static int fixup_cancel_branches(void** param, int param_no);
- static int w_t_cancel_callid_3(struct sip_msg* msg, char *cid, char *cseq,
- char *flag);
- static int w_t_cancel_callid_4(struct sip_msg* msg, char *cid, char *cseq,
- char *flag, char *creason);
- static int fixup_cancel_callid(void** param, int param_no);
- static int t_reply_callid(struct sip_msg* msg, char *cid, char *cseq,
- char *rc, char *rs);
- static int fixup_reply_callid(void** param, int param_no);
- static int t_flush_flags(struct sip_msg* msg, char*, char* );
- static int t_is_failure_route(struct sip_msg* msg, char*, char* );
- static int t_is_branch_route(struct sip_msg* msg, char*, char* );
- static int t_is_reply_route(struct sip_msg* msg, char*, char*);
- static int w_t_suspend(struct sip_msg* msg, char*, char*);
- static int w_t_continue(struct sip_msg* msg, char *idx, char *lbl, char *rtn);
- static int w_t_reuse_branch(struct sip_msg* msg, char*, char*);
- static int fixup_t_continue(void** param, int param_no);
- static int w_t_precheck_trans(sip_msg_t*, char*, char*);
- static int tmx_cfg_callback(sip_msg_t *msg, unsigned int flags, void *cbp);
- static int bind_tmx(tmx_api_t* api);
- static int _tmx_precheck_trans = 1;
- /* statistic variables */
- stat_var *tm_rcv_rpls;
- stat_var *tm_rld_rpls;
- stat_var *tm_loc_rpls;
- stat_var *tm_uas_trans;
- stat_var *tm_uac_trans;
- stat_var *tm_trans_2xx;
- stat_var *tm_trans_3xx;
- stat_var *tm_trans_4xx;
- stat_var *tm_trans_5xx;
- stat_var *tm_trans_6xx;
- stat_var *tm_trans_inuse;
- #ifdef STATISTICS
- unsigned long tmx_stats_uas_trans(void);
- unsigned long tmx_stats_uac_trans(void);
- unsigned long tmx_stats_trans_2xx(void);
- unsigned long tmx_stats_trans_3xx(void);
- unsigned long tmx_stats_trans_4xx(void);
- unsigned long tmx_stats_trans_5xx(void);
- unsigned long tmx_stats_trans_6xx(void);
- unsigned long tmx_stats_trans_inuse(void);
- unsigned long tmx_stats_trans_active(void);
- unsigned long tmx_stats_rcv_rpls(void);
- unsigned long tmx_stats_rld_rpls(void);
- unsigned long tmx_stats_loc_rpls(void);
- static stat_export_t mod_stats[] = {
- {"UAS_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_uas_trans },
- {"UAC_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_uac_trans },
- {"2xx_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_2xx },
- {"3xx_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_3xx },
- {"4xx_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_4xx },
- {"5xx_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_5xx },
- {"6xx_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_6xx },
- {"inuse_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_inuse },
- {"active_transactions" , STAT_IS_FUNC, (stat_var**)tmx_stats_trans_active},
- {"received_replies" , STAT_IS_FUNC, (stat_var**)tmx_stats_rcv_rpls },
- {"relayed_replies" , STAT_IS_FUNC, (stat_var**)tmx_stats_rld_rpls },
- {"local_replies" , STAT_IS_FUNC, (stat_var**)tmx_stats_loc_rpls },
- {0,0,0}
- };
- #endif
- /**
- * pseudo-variables exported by TM module
- */
- static pv_export_t mod_pvs[] = {
- { {"T_branch_idx", sizeof("T_branch_idx")-1}, PVT_OTHER,
- pv_get_tm_branch_idx, 0,
- 0, 0, 0, 0 },
- { {"T_reply_ruid", sizeof("T_reply_ruid")-1}, PVT_OTHER,
- pv_get_tm_reply_ruid, 0,
- 0, 0, 0, 0 },
- { {"T_reply_code", sizeof("T_reply_code")-1}, PVT_OTHER,
- pv_get_tm_reply_code, 0,
- 0, 0, 0, 0 },
- { {"T_reply_reason", sizeof("T_reply_reason")-1}, PVT_OTHER,
- pv_get_tm_reply_reason, 0,
- 0, 0, 0, 0 },
- { {"T_reply_last", sizeof("T_reply_last")-1}, PVT_OTHER,
- pv_get_tm_reply_last_received, 0,
- 0, 0, 0, 0 },
- { {"T_inv", sizeof("T_inv")-1}, PVT_OTHER, pv_get_t_var_inv, 0,
- pv_parse_t_var_name, 0, 0, 0 },
- { {"T_req", sizeof("T_req")-1}, PVT_OTHER, pv_get_t_var_req, 0,
- pv_parse_t_var_name, 0, 0, 0 },
- { {"T_rpl", sizeof("T_rpl")-1}, PVT_OTHER, pv_get_t_var_rpl, 0,
- pv_parse_t_var_name, 0, 0, 0 },
- { {"T", sizeof("T")-1}, PVT_OTHER, pv_get_t, 0,
- pv_parse_t_name, 0, 0, 0 },
- { {"T_branch", sizeof("T_branch")-1}, PVT_OTHER, pv_get_t_branch, 0,
- pv_parse_t_name, 0, 0, 0 },
- { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
- };
- static mi_export_t mi_cmds [] = {
- {MI_TM_UAC, mi_tm_uac_dlg, MI_ASYNC_RPL_FLAG, 0, 0 },
- {MI_TM_CANCEL, mi_tm_cancel, 0, 0, 0 },
- {MI_TM_HASH, mi_tm_hash, MI_NO_INPUT_FLAG, 0, 0 },
- {MI_TM_REPLY, mi_tm_reply, 0, 0, 0 },
- {MI_TM_REPLY_CALLID, mi_tm_reply_callid, 0, 0, 0 },
- {0,0,0,0,0}
- };
- static cmd_export_t cmds[]={
- {"t_cancel_branches", (cmd_function)t_cancel_branches, 1,
- fixup_cancel_branches, 0, ONREPLY_ROUTE },
- {"t_cancel_callid", (cmd_function)w_t_cancel_callid_3, 3,
- fixup_cancel_callid, 0, ANY_ROUTE },
- {"t_cancel_callid", (cmd_function)w_t_cancel_callid_4, 4,
- fixup_cancel_callid, 0, ANY_ROUTE },
- {"t_reply_callid", (cmd_function)t_reply_callid, 4,
- fixup_reply_callid, 0, ANY_ROUTE },
- {"t_flush_flags", (cmd_function)t_flush_flags, 0, 0,
- 0, ANY_ROUTE },
- {"t_is_failure_route", (cmd_function)t_is_failure_route, 0, 0,
- 0, ANY_ROUTE },
- {"t_is_branch_route", (cmd_function)t_is_branch_route, 0, 0,
- 0, ANY_ROUTE },
- {"t_is_reply_route", (cmd_function)t_is_reply_route, 0, 0,
- 0, ANY_ROUTE },
- {"t_suspend", (cmd_function)w_t_suspend, 0, 0,
- 0, ANY_ROUTE },
- {"t_continue", (cmd_function)w_t_continue, 3,
- fixup_t_continue, 0, ANY_ROUTE },
- {"t_reuse_branch", (cmd_function)w_t_reuse_branch, 0, 0, 0,
- EVENT_ROUTE },
- {"t_precheck_trans", (cmd_function)w_t_precheck_trans, 0, 0, 0,
- REQUEST_ROUTE },
- {"bind_tmx", (cmd_function)bind_tmx, 1,
- 0, 0, ANY_ROUTE },
- {0,0,0,0,0,0}
- };
- static param_export_t params[]={
- {"precheck_trans", PARAM_INT, &_tmx_precheck_trans},
- {0,0,0}
- };
- /** module exports */
- struct module_exports exports= {
- "tmx",
- DEFAULT_DLFLAGS, /* dlopen flags */
- cmds,
- params,
- #ifdef STATISTICS
- mod_stats, /* exported statistics */
- #else
- 0,
- #endif
- mi_cmds, /* exported MI functions */
- mod_pvs, /* exported pseudo-variables */
- 0, /* extra processes */
- mod_init, /* module initialization function */
- 0,
- (destroy_function) destroy,
- child_init /* per-child init function */
- };
- /**
- * init module function
- */
- static int mod_init(void)
- {
- /* load the TM API */
- if (load_tm_api(&_tmx_tmb)!=0) {
- LM_ERR("can't load TM API\n");
- return -1;
- }
- if(register_mi_mod(exports.name, mi_cmds)!=0)
- {
- LM_ERR("failed to register MI commands\n");
- return -1;
- }
- #ifdef STATISTICS
- /* register statistics */
- if (register_module_stats( exports.name, mod_stats)!=0 ) {
- LM_ERR("failed to register statistics\n");
- return -1;
- }
- #endif
- pv_tmx_data_init();
- if (register_script_cb(tmx_cfg_callback,
- POST_SCRIPT_CB|REQUEST_CB,0)<0) {
- LM_ERR("cannot register post-script callback\n");
- return -1;
- }
- return 0;
- }
- /**
- * child init function
- */
- static int child_init(int rank)
- {
- LM_DBG("rank is (%d)\n", rank);
- if (rank==PROC_INIT) {
- if(_tmx_precheck_trans!=0)
- return tmx_init_pretran_table();
- }
- return 0;
- }
- /**
- * destroy function
- */
- static void destroy(void)
- {
- return;
- }
- /**
- *
- */
- static int fixup_cancel_branches(void** param, int param_no)
- {
- char *val;
- int n = 0;
- if (param_no==1) {
- val = (char*)*param;
- if (strcasecmp(val,"all")==0) {
- n = 0;
- } else if (strcasecmp(val,"others")==0) {
- n = 1;
- } else if (strcasecmp(val,"this")==0) {
- n = 2;
- } else {
- LM_ERR("invalid param \"%s\"\n", val);
- return E_CFG;
- }
- pkg_free(*param);
- *param=(void*)(long)n;
- } else {
- LM_ERR("called with parameter != 1\n");
- return E_BUG;
- }
- return 0;
- }
- /**
- *
- */
- static int t_cancel_branches(struct sip_msg* msg, char *k, char *s2)
- {
- struct cancel_info cancel_data;
- struct cell *t = 0;
- tm_ctx_t *tcx = 0;
- int n=0;
- int idx = 0;
- t=_tmx_tmb.t_gett();
- if (t==NULL || t==T_UNDEFINED || !is_invite(t))
- return -1;
- tcx = _tmx_tmb.tm_ctx_get();
- if(tcx != NULL)
- idx = tcx->branch_index;
- n = (int)(long)k;
- init_cancel_info(&cancel_data);
- switch(n) {
- case 1:
- /* prepare cancel for every branch except idx */
- _tmx_tmb.prepare_to_cancel(t,
- &cancel_data.cancel_bitmap, 1<<idx);
- case 2:
- if(msg->first_line.u.reply.statuscode>=200)
- break;
- cancel_data.cancel_bitmap = 1<<idx;
- break;
- default:
- if (msg->first_line.u.reply.statuscode>=200)
- /* prepare cancel for every branch except idx */
- _tmx_tmb.prepare_to_cancel(t,
- &cancel_data.cancel_bitmap, 1<<idx);
- else
- _tmx_tmb.prepare_to_cancel(t,
- &cancel_data.cancel_bitmap, 0);
- }
- LM_DBG("canceling %d/%d\n", n, (int)cancel_data.cancel_bitmap);
- if(cancel_data.cancel_bitmap==0)
- return -1;
- _tmx_tmb.cancel_uacs(t, &cancel_data, 0);
- return 1;
- }
- /**
- *
- */
- static int fixup_cancel_callid(void** param, int param_no)
- {
- if (param_no==1 || param_no==2) {
- return fixup_spve_null(param, 1);
- }
- if (param_no==3) {
- return fixup_igp_null(param, 1);
- }
- return 0;
- }
- /**
- *
- */
- static int t_cancel_callid(struct sip_msg* msg, char *cid, char *cseq, char *flag, char *creason)
- {
- struct cell *trans;
- struct cell *bkt;
- int bkb;
- struct cancel_info cancel_data;
- str cseq_s;
- str callid_s;
- int fl;
- int rcode;
- rcode = 0;
- fl = -1;
- if(fixup_get_svalue(msg, (gparam_p)cid, &callid_s)<0)
- {
- LM_ERR("cannot get callid\n");
- return -1;
- }
- if(fixup_get_svalue(msg, (gparam_p)cseq, &cseq_s)<0)
- {
- LM_ERR("cannot get cseq\n");
- return -1;
- }
- if(fixup_get_ivalue(msg, (gparam_p)flag, &fl)<0)
- {
- LM_ERR("cannot get flag\n");
- return -1;
- }
- if(creason!=NULL && fixup_get_ivalue(msg, (gparam_p)creason, &rcode)<0)
- {
- LM_ERR("cannot get flag\n");
- return -1;
- }
- if(rcode<100 || rcode>699)
- rcode = 0;
- bkt = _tmx_tmb.t_gett();
- bkb = _tmx_tmb.t_gett_branch();
- if( _tmx_tmb.t_lookup_callid(&trans, callid_s, cseq_s) < 0 ) {
- DBG("Lookup failed - no transaction\n");
- return -1;
- }
- DBG("Now calling cancel_uacs\n");
- if(trans->uas.request && fl>0 && fl<32)
- setflag(trans->uas.request, fl);
- init_cancel_info(&cancel_data);
- cancel_data.reason.cause = rcode;
- cancel_data.cancel_bitmap = 0;
- _tmx_tmb.prepare_to_cancel(trans, &cancel_data.cancel_bitmap, 0);
- _tmx_tmb.cancel_uacs(trans, &cancel_data, 0);
- //_tmx_tmb.unref_cell(trans);
- _tmx_tmb.t_sett(bkt, bkb);
- return 1;
- }
- /**
- *
- */
- static int w_t_cancel_callid_3(struct sip_msg* msg, char *cid, char *cseq, char *flag)
- {
- return t_cancel_callid(msg, cid, cseq, flag, NULL);
- }
- /**
- *
- */
- static int w_t_cancel_callid_4(struct sip_msg* msg, char *cid, char *cseq, char *flag, char *creason)
- {
- return t_cancel_callid(msg, cid, cseq, flag, creason);
- }
- /**
- *
- */
- static int fixup_reply_callid(void** param, int param_no)
- {
- if (param_no==1 || param_no==2 || param_no==4) {
- return fixup_spve_null(param, 1);
- }
- if (param_no==3 || param_no==4) {
- return fixup_igp_null(param, 1);
- }
- return 0;
- }
- /**
- *
- */
- static int t_reply_callid(struct sip_msg* msg, char *cid, char *cseq,
- char *rc, char *rs)
- {
- struct cell *trans;
- str cseq_s;
- str callid_s;
- str status_s;
- unsigned int code;
- if(fixup_get_svalue(msg, (gparam_p)cid, &callid_s)<0)
- {
- LM_ERR("cannot get callid\n");
- return -1;
- }
- if(fixup_get_svalue(msg, (gparam_p)cseq, &cseq_s)<0)
- {
- LM_ERR("cannot get cseq\n");
- return -1;
- }
- if(fixup_get_ivalue(msg, (gparam_p)rc, (int*)&code)<0)
- {
- LM_ERR("cannot get reply code\n");
- return -1;
- }
- if(fixup_get_svalue(msg, (gparam_p)rs, &status_s)<0)
- {
- LM_ERR("cannot get reply status\n");
- return -1;
- }
- if(_tmx_tmb.t_lookup_callid(&trans, callid_s, cseq_s) < 0 )
- {
- DBG("Lookup failed - no transaction\n");
- return -1;
- }
- DBG("Now calling internal replay\n");
- if(_tmx_tmb.t_reply_trans(trans, trans->uas.request, code, status_s.s)>0)
- return 1;
- return -1;
- }
- /**
- *
- */
- static int t_flush_flags(struct sip_msg* msg, char *foo, char *bar)
- {
- struct cell *t;
- t=_tmx_tmb.t_gett();
- if ( t==0 || t==T_UNDEFINED) {
- LM_ERR("failed to flush flags - no transaction found\n");
- return -1;
- }
- t->uas.request->flags = msg->flags;
- return 1;
- }
- /**
- *
- */
- static int t_is_failure_route(struct sip_msg* msg, char *foo, char *bar)
- {
- if(route_type==FAILURE_ROUTE)
- return 1;
- return -1;
- }
- /**
- *
- */
- static int t_is_branch_route(struct sip_msg* msg, char *foo, char *bar)
- {
- if(route_type==BRANCH_ROUTE)
- return 1;
- return -1;
- }
- /**
- *
- */
- static int t_is_reply_route(struct sip_msg* msg, char *foo, char *bar)
- {
- if(route_type & ONREPLY_ROUTE)
- return 1;
- return -1;
- }
- /**
- *
- */
- static int w_t_suspend(struct sip_msg* msg, char *p1, char *p2)
- {
- unsigned int tindex;
- unsigned int tlabel;
- tm_cell_t *t = 0;
- t=_tmx_tmb.t_gett();
- if (t==NULL || t==T_UNDEFINED)
- {
- if(_tmx_tmb.t_newtran(msg)<0)
- {
- LM_ERR("cannot create the transaction\n");
- return -1;
- }
- t = _tmx_tmb.t_gett();
- if (t==NULL || t==T_UNDEFINED)
- {
- LM_ERR("cannot lookup the transaction\n");
- return -1;
- }
- }
- if(_tmx_tmb.t_suspend(msg, &tindex, &tlabel)<0)
- {
- LM_ERR("failed to suppend the processing\n");
- return -1;
- }
- LM_DBG("transaction suspended [%u:%u]\n", tindex, tlabel);
- return 1;
- }
- /**
- *
- */
- static int w_t_continue(struct sip_msg* msg, char *idx, char *lbl, char *rtn)
- {
- unsigned int tindex;
- unsigned int tlabel;
- str rtname;
- cfg_action_t *act;
- int ri;
- if(fixup_get_ivalue(msg, (gparam_p)idx, (int*)&tindex)<0)
- {
- LM_ERR("cannot get transaction index\n");
- return -1;
- }
- if(fixup_get_ivalue(msg, (gparam_p)lbl, (int*)&tlabel)<0)
- {
- LM_ERR("cannot get transaction label\n");
- return -1;
- }
- if(fixup_get_svalue(msg, (gparam_p)rtn, &rtname)<0)
- {
- LM_ERR("cannot get route block name\n");
- return -1;
- }
- ri = route_get(&main_rt, rtname.s);
- if(ri<0)
- {
- LM_ERR("unable to find route block [%.*s]\n", rtname.len, rtname.s);
- return -1;
- }
- act = main_rt.rlist[ri];
- if(act==NULL)
- {
- LM_ERR("empty action lists in route block [%.*s]\n",
- rtname.len, rtname.s);
- return -1;
- }
- if(_tmx_tmb.t_continue(tindex, tlabel, act)<0)
- {
- LM_ERR("resuming the processing of transaction [%u:%u] failed\n",
- tindex, tlabel);
- return -1;
- }
- return 1;
- }
- /**
- * Creates new "main" branch by making copy of branch-failure branch.
- * Currently the following branch attributes are included:
- * request-uri, ruid, path, instance, and branch flags.
- */
- static int w_t_reuse_branch(struct sip_msg* msg, char *p1, char *p2)
- {
- struct cell *t;
- int branch;
- if (msg == NULL) return -1;
- /* first get the transaction */
- if (_tmx_tmb.t_check(msg, 0) == -1) return -1;
- if ((t = _tmx_tmb.t_gett()) == 0) {
- LM_ERR("no transaction\n");
- return -1;
- }
- switch (get_route_type()) {
- case BRANCH_FAILURE_ROUTE:
- /* use the reason of the winning reply */
- if ((branch = _tmx_tmb.t_get_picked_branch()) < 0) {
- LM_CRIT("no picked branch (%d) for a final response"
- " in MODE_ONFAILURE\n", branch);
- return -1;
- }
- rewrite_uri(msg, &(t->uac[branch].uri));
- set_ruid(msg, &(t->uac[branch].ruid));
- if (t->uac[branch].path.len) {
- set_path_vector(msg, &(t->uac[branch].path));
- } else {
- reset_path_vector(msg);
- }
- setbflagsval(0, t->uac[branch].branch_flags);
- set_instance(msg, &(t->uac[branch].instance));
- return 1;
- default:
- LM_ERR("unsupported route_type %d\n", get_route_type());
- return -1;
- }
- }
- /**
- *
- */
- static int fixup_t_continue(void** param, int param_no)
- {
- if (param_no==1 || param_no==2) {
- return fixup_igp_null(param, 1);
- }
- if (param_no==3) {
- return fixup_spve_null(param, 1);
- }
- return 0;
- }
- /**
- *
- */
- static int w_t_precheck_trans(sip_msg_t *msg, char *p1, char *p2)
- {
- int ret;
- ret = tmx_check_pretran(msg);
- if(ret>0)
- return 1;
- return (ret-1);
- }
- /**
- *
- */
- static int tmx_cfg_callback(sip_msg_t *msg, unsigned int flags, void *cbp)
- {
- if(flags&POST_SCRIPT_CB) {
- tmx_pretran_unlink();
- }
- return 1;
- }
- static int bind_tmx(tmx_api_t* api)
- {
- if (!api)
- return -1;
- api->t_suspend = w_t_suspend;
- return 0;
- }
- #ifdef STATISTICS
- /*** tm stats ***/
- static struct t_proc_stats _tmx_stats_all;
- static ticks_t _tmx_stats_tm = 0;
- void tmx_stats_update(void)
- {
- ticks_t t;
- t = get_ticks();
- if(t>_tmx_stats_tm+1) {
- _tmx_tmb.get_stats(&_tmx_stats_all);
- _tmx_stats_tm = t;
- }
- }
- unsigned long tmx_stats_uas_trans(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.transactions;
- }
- unsigned long tmx_stats_uac_trans(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.client_transactions;
- }
- unsigned long tmx_stats_trans_2xx(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_2xx;
- }
- unsigned long tmx_stats_trans_3xx(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_3xx;
- }
- unsigned long tmx_stats_trans_4xx(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_4xx;
- }
- unsigned long tmx_stats_trans_5xx(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_5xx;
- }
- unsigned long tmx_stats_trans_6xx(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_6xx;
- }
- unsigned long tmx_stats_trans_inuse(void)
- {
- tmx_stats_update();
- return (_tmx_stats_all.transactions - _tmx_stats_all.deleted);
- }
- unsigned long tmx_stats_trans_active(void)
- {
- tmx_stats_update();
- return (_tmx_stats_all.transactions - _tmx_stats_all.waiting);
- }
- unsigned long tmx_stats_rcv_rpls(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_6xx
- + _tmx_stats_all.completed_5xx
- + _tmx_stats_all.completed_4xx
- + _tmx_stats_all.completed_3xx
- + _tmx_stats_all.completed_2xx;
- }
- unsigned long tmx_stats_rld_rpls(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.completed_6xx
- + _tmx_stats_all.completed_5xx
- + _tmx_stats_all.completed_4xx
- + _tmx_stats_all.completed_3xx
- + _tmx_stats_all.completed_2xx
- - _tmx_stats_all.replied_locally;
- }
- unsigned long tmx_stats_loc_rpls(void)
- {
- tmx_stats_update();
- return _tmx_stats_all.replied_locally;
- }
- #endif
|