Module: sip-router
Branch: tmp/tm_async_reply_support
Commit: f1bf9fa2f21a7c800c16f40b530e8f4042a280ae
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f1bf9fa…
Author: Richard Good <richard.good(a)smilecoms.com>
Committer: Richard Good <richard.good(a)smilecoms.com>
Date: Thu Mar 14 18:06:46 2013 +0200
tm: t_suspend/t_continue for replies 1st draft
- First attempt at allowing tm functions: t_continue and t_suspend to be used on SIP
responses (currently this only works on SIP requests)
---
modules/tm/h_table.h | 5 ++-
modules/tm/t_suspend.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h
index f30bd45..2c65906 100644
--- a/modules/tm/h_table.h
+++ b/modules/tm/h_table.h
@@ -196,6 +196,8 @@ typedef struct ua_server
for e2e cancels */
#endif /* CANCEL_REASON_SUPPORT */
unsigned int status;
+
+ int suspended_request;
}ua_server_type;
@@ -251,6 +253,7 @@ typedef struct ua_client
unsigned short on_failure;
/* the onreply_route to be processed if registered to do so */
unsigned short on_reply;
+ int suspended_reply;
}ua_client_type;
@@ -444,7 +447,7 @@ typedef struct cell
/* place holder for MD5checksum (meaningful only if syn_branch=0) */
char md5[0]; /* if syn_branch==0 then MD5_LEN bytes are extra alloc'ed*/
-
+
} tm_cell_t;
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c
index 35adcb1..387e628 100644
--- a/modules/tm/t_suspend.c
+++ b/modules/tm/t_suspend.c
@@ -56,7 +56,8 @@ int t_suspend(struct sip_msg *msg,
unsigned int *hash_index, unsigned int *label)
{
struct cell *t;
-
+ int branch;
+
t = get_t();
if (!t || t == T_UNDEFINED) {
LOG(L_ERR, "ERROR: t_suspend: " \
@@ -64,13 +65,14 @@ int t_suspend(struct sip_msg *msg,
return -1;
}
- if (t->flags & T_CANCELED) {
+ if (t->flags & T_CANCELED) {
/* The transaction has already been canceled */
LOG(L_DBG, "DEBUG: t_suspend: " \
"trying to suspend an already canceled transaction\n");
ser_error = E_CANCELED;
return 1;
}
+ if (msg->first_line.type==SIP_REQUEST){
/* send a 100 Trying reply, because the INVITE processing
will probably take a long time */
@@ -103,10 +105,47 @@ int t_suspend(struct sip_msg *msg,
"failed to add the blind UAC\n");
return -1;
}
-
+ /* set as suspend request for when we continue */
+ t->uas.suspended_request = 1;
+
+ return 0;
+
+ }else if (msg->first_line.type==SIP_REPLY){
+
+ LOG(L_DBG,"DBG: This is a suspend on reply - setting msg flag to
SUSPEND");
+ msg->flags &= FL_RPL_SUSPENDED;
+ //this is a reply suspend find which branch
+
+ if (t_check( msg , &branch )==-1){
+ LOG(L_ERR, "ERROR: t_suspend: " \
+ "failed find UAC branch\n");
+ return -1;
+ }
+ LOG(L_DBG,"DBG: Found a a match with branch id [%d]", branch);
+
+ LOG(L_DBG,"DBG: Assigning reply message to
t->uac[branch].reply");
+ t->uac[branch].reply=msg;
+
+ if (save_msg_lumps(t->uac[branch].reply, msg)) {
+ LOG(L_ERR, "ERROR: t_suspend: " \
+ "failed to save the message lumps\n");
+ return -1;
+ }
+
+ LOG(L_DBG,"DBG: Saving stuff to transaction");
+ /* set as suspend reply for when we continue */
+ t->uac[branch].suspended_reply=1;
+ /* save the message flags */
+ //TODO do we need this?
+ t->uac[branch].reply->flags = msg->flags;
+
+ LOG(L_DBG,"DBG: Saving transaction hash and label");
+ *hash_index = t->hash_index;
+ *label = t->label;
+ LOG(L_DBG,"DBG: Done");
+ }
return 0;
}
-
/* Continues the SIP request processing previously saved by
* t_suspend(). The script does not continue from the same
* point, but a separate route block is executed instead.
@@ -120,6 +159,7 @@ int t_continue(unsigned int hash_index, unsigned int label,
{
struct cell *t;
struct sip_msg faked_req;
+ struct sip_msg faked_reply;
int branch;
struct ua_client *uac =NULL;
int ret;
@@ -142,6 +182,7 @@ int t_continue(unsigned int hash_index, unsigned int label,
* form calling t_continue() multiple times simultaneously */
LOCK_REPLIES(t);
+ if (t->uas.suspended_request==1){
/* Try to find the blind UAC, and cancel its fr timer.
* We assume that the last blind uac called t_continue(). */
for ( branch = t->nr_of_outgoings-1;
@@ -223,9 +264,60 @@ int t_continue(unsigned int hash_index, unsigned int label,
goto kill_trans;
}
}
-
+
+ }else{
+ LOG(L_DBG,"This a continue from a reply suspend - getting the correct
branch as transaction has %d branches", t->nr_of_outgoings);
+ //this is a continue from a reply suspend!
+ for ( branch = 0;
+ branch < t->nr_of_outgoings;
+ branch++
+ ) {
+ //TODO not sure if this will work yet - think we need to pass which branch to continue
when we call t_continue!
+ if (t->uac[branch].suspended_reply==1){
+ LOG(L_DBG,"Found branch that has suspend reply
set!");
+
+ LOG(L_DBG,"Forwarding reply with status code %d",
t->uac[branch].reply->first_line.u.reply.statuscode);
+
+ //TODO forward message now
+ /* Not sure how to do this yet - probably need to fake the
environment and then send a fake reply similar to way done for requests */
+
+ //This might work:
+ //forward_reply(t->uac[branch].reply);
+
+ //Or we need to fake the environment and send:
+ //fake_reply(t, branch,
t->uac[branch].reply->first_line.u.reply.statuscode);
+
+ //faked_env( t, &faked_req);
+ //
+ /* The sip msg is a faked msg just like in failure route
+ * therefore execute the pre- and post-script callbacks
+ * of failure route (Miklos)
+ */
+// if (exec_pre_script_cb(&faked_rep,
FAILURE_CB_TYPE)>0) {
+// if (run_top_route(route, &faked_rep, 0)<0)
+// LOG(L_ERR, "ERROR: t_continue: Error
in run_top_route\n");
+// exec_post_script_cb(&faked_rep,
FAILURE_CB_TYPE);
+// }
+
+ //faked_env( t, 0);
+ //free_faked_rer(&faked_rep, t);
+
+ /* update the flags */
+ //t->uac[branch].reply->flags = faked_rep.flags;
+
+ }
+ }
+ if (branch == t->nr_of_outgoings) {
+ LOG(L_DBG,"Could not find a branch with suspend reply
set");
+ /* This is a continue on reply suspend but can not find a suspended reply!. */
+ ret = 0;
+ goto kill_trans;
+ }
+ }
+ LOG(L_DBG,"Unlocking transaction mutex");
UNLOCK_REPLIES(t);
-
+
+ LOG(L_DBG,"Unreffing the transaction");
/* unref the transaction */
t_unref(t->uas.request);