Maxim Sobolev wrote:
On Mon, Jan 13, 2003 at 02:38:37PM +0100, Jan Janak wrote:
On 13-01 14:46, Maxim Sobolev wrote:
I see, but IMO this would be not a generic
solution, as I'll have to adjust
the code for my particular needs. What I am looking for is some way to
allow it to be modified by properly constructing config file. Perhaps something
like t_on_negative() could be added, i.e. t_on_positive(): the specified
routing block will be called when the transaction is completed with positive
result but before sending final reply. What do you think?
Why is the callback not generic solution ?
Because as far as I understand then it will be called on each transaction,
or I am missing something? What if I need to apply my function only if the
reply match some pre-defined conditions (i.e. "Server: ATA.*")?
Attached please find the patch, which implements t_on_positive()
approach. Now my config looks like the following and everything now
works as expected:
route {
if (search("User-Agent: Cisco ATA.*")) {
add_rport();
fix_nated_contact();
};
rewriteFromRoute();
[REGISTRATION STUFF STRIPPED]
if (method=="INVITE") {
addRecordRoute();
};
t_on_positive("1")
# forward to current uri now
if (!t_relay()) {
sl_reply_error();
};
}
reply_route[1] {
if (search("Server: Cisco ATA.*") {
fix_nated_contact();
}
}
Please let me know what do you think about my patches.
Thank you for your help!
-Maxim
regards,
Jan.
> > First, you need to include t_hooks.h and tm_load.h from the tm module.
> >
> > Then, you need to register a callback function. The following code snippet
> > shows how to do it:
> >
> > static int mod_init( void )
> > {
> >
> > load_tm_f load_tm;
> >
> > /* import the TM auto-loading function */
> > if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT)))
{
> > LOG(L_ERR, "radius_acc: mod_init: can't import
load_tm\n");
> > return -1;
> > }
> > /* let the auto-loading function load all TM stuff */
> > if (load_tm( &tmb )==-1) return -1;
> >
> > /* register callback */
> > if (tmb.rngister_tmcb( TMCB_REPLY, rad_acc_onreply, 0) <= 0)
> > return -1;
> > }
> >
> > return 0;
> > }
> >
> > The mod_init function registers rad_acc_onreply function, the function will
> > be called when the tm module receives a response.
> >
> > The callback follows. Note that radius_acc module (from which the code
> > snippets were taken) registers TMCB_REPLY callback. This type of callback
> > will be called _AFTER_ the response was sent out - that means there is no way
> > how to modify it. Because of that, your module will have to register another
> > type of callback - TMCB_REPLY_IN. Such callback will be called before the
> > reply gets forwarded which means that you can modify it before it will be
> > sent out.
> >
> > See modules/tm/t_hooks.h file for more details ! There is a description of
> > the callbacks.
> >
> > /*
> > * Function that gets called on reply
> > * params: struct cell* t The callback structure
> > * struct sip_msg *msg The sip message.
> > * int code The status code
> > * void* param Passed parameter
> > * returns: nothing
> > */
> > static void rad_acc_onreply( struct cell* t, struct sip_msg *reply, int code,
> > void *param )
> > {
> >
> > struct sip_msg *rq;
> >
> > rq = t->uas.request;
> >
> > if (t->is_invite && missed_flag && isflagset( rq,
missed_flag)==1
> > && ((code>=400 && code<500) ||
code>=600))
> > rad_acc_missed_report( t, reply, code);
> >
> >
> > /* if acc enabled for flagged transaction, check if flag matches */
> > if (acc_flag && isflagset( rq, acc_flag )==-1) return;
> > /* early media is reported only if explicitely demanded,
> > other provisional responses are always dropped */
> > if (code < 200 && ! (early_media && code==183))
> > return;
> > /* negative transactions reported only if explicitely demanded */
> > if (!failed_transactions && code >=300) return;
> >
> > /* anything else, i.e., 2xx, always reported */
> > radius_log_reply(t, reply);
> >
> > }
> >
> > regards, Jan.
>
>
> _______________________________________________
> Serusers mailing list
> serusers(a)lists.iptel.org
>
http://lists.iptel.org/mailman/listinfo/serusers
>
_______________________________________________
Serusers mailing list
serusers(a)lists.iptel.org
http://lists.iptel.org/mailman/listinfo/serusers
--- modules/tm/h_table.h 2003/01/13 18:36:18 1.1
+++ modules/tm/h_table.h 2003/01/13 18:36:55
@@ -202,6 +202,8 @@
/* the route to take if no final positive reply arrived */
unsigned int on_negative;
+ /* the route to take if final positive reply arrived */
+ unsigned int on_positive;
/* set to one if you want to disallow silent transaction
dropping when C timer hits
*/
--- modules/tm/t_fwd.c 2003/01/13 18:35:29 1.1
+++ modules/tm/t_fwd.c 2003/01/13 18:36:09
@@ -415,6 +415,8 @@
/* if someone set on_negative, store in in T-context */
t->on_negative=get_on_negative();
+ /* if someone set on_positive, store in in T-context */
+ t->on_positive=get_on_positive();
/* send them out now */
for (i=first_branch; i<t->nr_of_outgoings; i++) {
--- modules/tm/t_reply.c.orig Tue Oct 22 00:24:43 2002
+++ modules/tm/t_reply.c Mon Jan 13 22:36:44 2003
@@ -56,6 +56,8 @@
/* where to go if there is no positive reply */
static int goto_on_negative=0;
+/* where to go if is a positive reply */
+static int goto_on_positive=0;
/* we store the reply_route # in private memory which is
then processed during t_relay; we cannot set this value
@@ -73,12 +75,23 @@
return 1;
}
+int t_on_positive( unsigned int go_to )
+{
+ goto_on_positive=go_to;
+ return 1;
+}
+
unsigned int get_on_negative()
{
return goto_on_negative;
}
+unsigned int get_on_positive()
+{
+ return goto_on_positive;
+}
+
void tm_init_tags()
{
init_tags(tm_tags, &tm_tag_suffix,
@@ -916,4 +929,26 @@
if (faked_msg.new_uri.s) pkg_free(faked_msg.new_uri.s);
}
+void on_positive_reply( struct cell* t, struct sip_msg* msg,
+ int code, void *param )
+{
+ int act_ret;
+ struct lump* tmp;
+ /* nobody cares about a positive transaction -- ok, return */
+ if (!t->on_positive) {
+ DBG("DBG: on_positive_reply: no on_positive\n");
+ return;
+ }
+
+ tmp = msg->add_rm;
+ msg->add_rm = msg->repl_add_rm;
+ act_ret=run_actions(reply_rlist[t->on_positive], msg);
+ msg->repl_add_rm = msg->add_rm;
+ msg->add_rm = tmp;
+ if (act_ret<0) {
+ LOG(L_ERR, "on_positive_reply: Error in do_action\n");
+ }
+
+ return;
+}
--- modules/tm/t_reply.h 2003/01/13 18:40:07 1.1
+++ modules/tm/t_reply.h 2003/01/13 18:41:53
@@ -101,11 +101,16 @@
void on_negative_reply( struct cell* t, struct sip_msg* msg,
int code, void *param );
+void on_positive_reply( struct cell* t, struct sip_msg* msg,
+ int code, void *param );
+
/* set which 'reply' structure to take if only negative
replies arrive
*/
int t_on_negative( unsigned int go_to );
unsigned int get_on_negative();
+int t_on_positive( unsigned int go_to );
+unsigned int get_on_positive();
int t_retransmit_reply( struct cell *t );
--- modules/tm/tm.c 2003/01/13 18:15:44 1.1
+++ modules/tm/tm.c 2003/01/13 18:43:19
@@ -95,6 +95,7 @@
inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
inline static int fixup_hostport2proxy(void** param, int param_no);
inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo );
+inline static int w_t_on_positive( struct sip_msg* msg, char *go_to, char *foo );
static int mod_init(void);
@@ -121,6 +122,7 @@
T_RELAY,
T_FORWARD_NONACK,
"t_on_negative",
+ "t_on_positive",
/* not applicable from script ... */
@@ -141,6 +143,7 @@
w_t_relay,
w_t_forward_nonack,
w_t_on_negative,
+ w_t_on_positive,
(cmd_function) register_tmcb,
(cmd_function) t_uac,
@@ -159,6 +162,7 @@
0, /* t_relay */
2, /* t_forward_nonack */
1, /* t_on_negative */
+ 1, /* t_on_positive */
NO_SCRIPT /* register_tmcb */,
NO_SCRIPT /* t_uac */,
NO_SCRIPT /* load_tm */,
@@ -176,13 +180,14 @@
0, /* t_relay */
fixup_hostport2proxy, /* t_forward_nonack */
fixup_str2int, /* t_on_negative */
+ fixup_str2int, /* t_on_positive */
0, /* register_tmcb */
0, /* t_uac */
0, /* load_tm */
0 /* t_newdlg */
},
- 15,
+ 16,
/* ------------ exported variables ---------- */
(char *[]) { /* Module parameter names */
@@ -266,6 +271,7 @@
message's t_on_negative value
*/
t_on_negative( 0 );
+ t_on_positive( 0 );
return 1;
}
@@ -332,6 +338,8 @@
}
register_tmcb( TMCB_ON_NEGATIVE, on_negative_reply,
0 /* empty param */);
+ register_tmcb( TMCB_REPLY_IN, on_positive_reply,
+ 0 /* empty param */);
/* register post-script clean-up function */
register_script_cb( w_t_unref, POST_SCRIPT_CB,
0 /* empty param */ );
@@ -533,6 +541,11 @@
inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo )
{
return t_on_negative( (unsigned int ) go_to );
+}
+
+inline static int w_t_on_positive( struct sip_msg* msg, char *go_to, char *foo )
+{
+ return t_on_positive( (unsigned int ) go_to );
}
inline static int w_t_relay_to( struct sip_msg *p_msg ,