[sr-dev] git:master: tmx: two new functions for transaction control

Daniel-Constantin Mierla miconda at gmail.com
Tue May 11 15:27:59 CEST 2010


Module: sip-router
Branch: master
Commit: 7f56004e206cf0f9ae7b3d500dd48407998802cd
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7f56004e206cf0f9ae7b3d500dd48407998802cd

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Tue May 11 15:03:19 2010 +0200

tmx: two new functions for transaction control

- t_cancel_callid(callid, cseq, flag) - cancel the INVITE transaction
  sharing the callid and cseq. It set the flag for invite transaction if
  the value is greater than 0
- t_reply_callid(callid, cseq, code, reason) - send a reply to an INVITE
  transaction sharing callid and csec
- the functions are useful for remote control of invite transaction (via
  xmlrpc or out-of-dialog sip request)
- an useful application - call pickup:
	- INVITE comes in, callee is in a pickup group
	- store callid, cseq, etc in database or notify the other phones in
	  the group (easy to do for snom phones and extra programmable
	  buttons) via uac_req_send()
	- send a remote control command telling which call to pickup
	  (callid, cseq) and where to redirect. In config, call
	  t_cancel_callid(). in failure route for INVITE catch the cancelled
	  transaction (flag is set), get the new destination (e.g., stored in
	  htable) and forward the invite there

---

 modules_k/tmx/tmx_mod.c |  139 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 139 insertions(+), 0 deletions(-)

diff --git a/modules_k/tmx/tmx_mod.c b/modules_k/tmx/tmx_mod.c
index 0c3af19..420cb30 100644
--- a/modules_k/tmx/tmx_mod.c
+++ b/modules_k/tmx/tmx_mod.c
@@ -46,6 +46,11 @@ 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 t_cancel_callid(struct sip_msg* msg, char *cid, char *cseq, char *flag);
+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);
 
 /* statistic variables */
 stat_var *tm_rcv_rpls;
@@ -125,6 +130,10 @@ static mi_export_t mi_cmds [] = {
 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)t_cancel_callid,  3,
+		fixup_cancel_callid, 0, ANY_ROUTE },
+	{"t_reply_callid", (cmd_function)t_reply_callid,  4,
+		fixup_reply_callid, 0, ANY_ROUTE },
 	{0,0,0,0,0,0}
 };
 
@@ -189,6 +198,9 @@ static void destroy(void)
 	return;
 }
 
+/**
+ *
+ */
 static int fixup_cancel_branches(void** param, int param_no)
 {
 	char *val;
@@ -215,6 +227,9 @@ static int fixup_cancel_branches(void** param, int param_no)
 	return 0;
 }
 
+/**
+ *
+ */
 static int t_cancel_branches(struct sip_msg* msg, char *k, char *s2)
 {
 	branch_bm_t cb = 0;
@@ -252,6 +267,130 @@ static int t_cancel_branches(struct sip_msg* msg, char *k, char *s2)
 	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)
+{
+	struct cell *trans;
+	branch_bm_t cancel_bm;
+	str cseq_s;
+	str callid_s;
+	int fl;
+
+	cancel_bm=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( _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);
+	_tmx_tmb.prepare_to_cancel(trans, &cancel_bm, 0);
+	_tmx_tmb.cancel_uacs(trans, cancel_bm, 0);
+
+	//_tmx_tmb.unref_cell(trans);
+
+	return 1;
+}
+
+/**
+ *
+ */
+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) {
+		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;
+}
 
 #ifdef STATISTICS
 




More information about the sr-dev mailing list