Module: sip-router
Branch: master
Commit: 7f56004e206cf0f9ae7b3d500dd48407998802cd
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7f56004…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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