فهرست منبع

Merge branch 'master' of ssh://git.sip-router.org/sip-router into 32plus

* 'master' of ssh://git.sip-router.org/sip-router:
  message shooter module added
  modules_k/acc: fix cdr documentation - using the correct names for the cdr commands(cdr_facility,cdr_start_on_confirmed,cdr_extra)
Juha Heinanen 14 سال پیش
والد
کامیت
5cbc4fa078

+ 16 - 0
modules/msg_shooter/Makefile

@@ -0,0 +1,16 @@
+#
+# msg_shooter module Makefile
+#
+# WARNING: do not run this directly, it should be run by the master Makefile
+
+COREPATH ?= ../..
+include $(COREPATH)/Makefile.defs
+
+NAME=msg_shooter.so
+
+auto_gen=
+
+DEFS += -I$(COREPATH) -DSER_MOD_INTERFACE
+
+include $(COREPATH)/Makefile.modules
+

+ 125 - 0
modules/msg_shooter/README

@@ -0,0 +1,125 @@
+msg shooter module
+
+   Copyright (C) 2011 iptelorg GmbH
+   Created and maintained by Miklos Tirpak
+
+        1.1. Overview
+        1.2. Dependencies
+
+              1.2.1. SER Modules
+
+        1.3. Exported Parameters
+
+        1.4. Exported Functions
+
+              1.4.1. smsg_from_to(from, to)
+              1.4.2. smsg_create(method)
+              1.4.3. smsg_append_hdrs(headers, [body])
+              1.4.4. smsg_on_reply(route_name)
+              1.4.5. shoot_msg([ruri, [destination] ])
+
+        1.5. Example
+
+     _________________________________________________________
+
+1.1. Overview
+
+   The module can be used to send SIP requests outside of the
+   current transaction. For example it can send REGISTER requests
+   to another registrar server as notifications.
+
+   The module creates a UAC and may append additional headers
+   and body to it. Finaly the constructed request can be sent to
+   several destinations.
+
+     _________________________________________________________
+
+1.2. Dependencies
+
+1.2.1. SER Modules
+
+   The following modules must be loaded before this module:
+
+     * tm module
+     _________________________________________________________
+
+1.3. Exported Parameters
+
+   None
+
+   _________________________________________________________
+   
+1.4. Exported Functions
+
+1.4.1. smsg_from_to(from, to)
+
+   Sets the From and To URIs of the UAC, must be called before
+   smsg_create(). Parameters can be string, AVP or select call.
+
+   _________________________________________________________
+
+1.4.2. smsg_create(method)
+
+   Creates an UAC and sets the method of the request.
+   method must be static string.
+
+   Can be called multiple times, but destroys the previously
+   created UAC.
+
+   _________________________________________________________
+
+1.4.3. smsg_append_hdrs(headers, [body])
+
+   Appends additional headers and body to the request.
+   Parameters can be string, AVP or select call.
+
+   _________________________________________________________
+
+1.4.4. smsg_on_reply(route_name)
+
+   Sets onreply_route block which will be executed upon a reply
+   is received for the shooted request. Must be called before
+   every shoot_msg() function if required.
+
+   Note that failure_route is curretly not supported (neither for
+   negative responses nor for timer hit)!
+
+   Also note that the transaction created by the new request does not
+   contain the AVPs of the old transaction, thus onreply_route will
+   not have any AVPs.
+
+   _________________________________________________________
+
+1.4.5. shoot_msg([ruri, [destination] ])
+
+   Shoots the request with the previously created UAC.
+   ruri and destination can be string, AVP or select call.
+   To HF is used for ruri when ruri parameter is not defined.
+
+   Can be called multiple times with the same UAC.
+
+   _________________________________________________________
+
+1.5. Example
+
+   The following example creates 2 UACs and sends the requests
+   to 3 different destinations
+
+onreply_route[notification] {
+
+	smsg_from_to("@from.uri", "@to.uri");
+	smsg_create("REGISTER");
+	$hdrs = "Contact: sip:[email protected]\r\nP-info: created by msg_shooter\r\n";
+	smsg_append_hdrs("$hdrs");
+
+	smsg_on_reply("first");
+	shoot_msg("sip:[email protected]", "sip:192.168.1.1");
+
+	smsg_on_reply("second");
+	shoot_msg("sip:[email protected]");
+
+	smsg_create("NOTIFY");
+	smsg_append_hdrs("P-info: another request\r\n", "Fake body\r\n");
+	shoot_msg("sip:[email protected]");
+
+}

+ 303 - 0
modules/msg_shooter/msg_shooter.c

@@ -0,0 +1,303 @@
+/*$Id$
+ *
+ * Copyright (C) 2011 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mem/mem.h"
+#include "str.h"
+#include "sr_module.h"
+#include "msg_shooter_mod.h"
+#include "smsg_routes.h"
+#include "msg_shooter.h"
+
+/* method points to a static char buffer, all of the others are
+dinamically allocated */
+static str	method = {0, 0};
+static str	from = {0, 0};
+static str	to = {0, 0};
+static str	hdrs = {0, 0};
+static str	body = {0, 0};
+static dlg_t	*UAC = 0;
+/* onreply route index */
+static int	onreply_idx = -1;
+
+/* get method of the request */
+int smsg_create(struct sip_msg *_msg, char *_param1, char *_param2)
+{
+	/* check the required information */
+	if (!from.len || !to.len) {
+		LOG(L_ERR, "ERROR: smsg_create(): mandatory headers are missing\n");
+		LOG(L_ERR, "ERROR: smsg_create(): have you forgot to call smsg_from_to() function?\n");
+		return -1;
+	}
+
+	if (get_str_fparam(&method, _msg, (fparam_t*)_param1)) {
+		LOG(L_ERR, "ERROR: smsg_create(): cannot get parameter\n");
+		return -1;
+	}
+	/* method is just a static char buffer, needless to copy it */
+
+	/* previous UAC still exists -- destroy it first */
+	if (UAC) {
+		LOG(L_DBG, "DEBUG: smsg_create(): destroying previous UAC\n");
+		tmb.free_dlg(UAC);
+		UAC = 0;
+		/* better to free also hdrs and body now */
+		if (hdrs.s) {
+			pkg_free(hdrs.s);
+			hdrs.s = 0;
+			hdrs.len = 0;
+		}
+		if (body.s) {
+			pkg_free(body.s);
+			body.s = 0;
+			body.len = 0;
+		}
+	}
+
+	/* create UAC */
+	if (tmb.new_dlg_uac(0, 0, 0, &from, &to, &UAC) < 0) {
+		LOG(L_ERR, "ERROR: smsg_create(): cannot create UAC\n");
+		return -1;
+	}
+	return 1;
+}
+
+/* free allocated memory */
+void smsg_destroy(void)
+{
+	method.s = 0;
+	method.len = 0;
+	if (from.s) {
+		pkg_free(from.s);
+		from.s = 0;
+		from.len = 0;
+	}
+	if (to.s) {
+		pkg_free(to.s);
+		to.s = 0;
+		to.len = 0;
+	}
+	if (hdrs.s) {
+		pkg_free(hdrs.s);
+		hdrs.s = 0;
+		hdrs.len = 0;
+	}
+	if (body.s) {
+		pkg_free(body.s);
+		body.s = 0;
+		body.len = 0;
+	}
+	if (UAC) {
+		tmb.free_dlg(UAC);
+		UAC = 0;
+	}
+	onreply_idx = -1;
+}
+
+/* clone an str structure */
+static int clone_str(str *_s, str *_d)
+{
+	if (_d->s) pkg_free(_d->s);
+
+	if (_s->len == 0) {
+		/* empty string */
+		_d->s = 0;
+		_d->len = 0;
+		return 0;
+	}
+
+	_d->s = (char *)pkg_malloc(_s->len * sizeof(char));
+	if (!_d->s) {
+		LOG(L_ERR, "ERROR: clone_str(): not enough memory\n");
+		return -1;
+	}
+	memcpy(_d->s, _s->s, _s->len);
+	_d->len = _s->len;
+
+	return 0;
+}
+
+/* set From and To headers of the request */
+int smsg_from_to(struct sip_msg *_msg, char *_param1, char *_param2)
+{
+	str	s;
+
+	if (get_str_fparam(&s, _msg, (fparam_t*)_param1)) {
+		LOG(L_ERR, "ERROR: smsg_from_to(): cannot get parameter\n");
+		return -1;
+	}
+	/* select and AVP result can change, we need a private copy of the buffer */
+	if (clone_str(&s, &from)) return -1;
+
+	if (get_str_fparam(&s, _msg, (fparam_t*)_param2)) {
+		LOG(L_ERR, "ERROR: smsg_from_to(): cannot get parameter\n");
+		return -1;
+	}
+	/* select and AVP result can change, we need a private copy of the buffer */
+	if (clone_str(&s, &to)) return -1;
+
+	return 1;
+}
+
+/* append headers and optionally body to the request */
+int smsg_append_hdrs(struct sip_msg *_msg, char *_param1, char *_param2)
+{
+	str	s;
+
+	if (get_str_fparam(&s, _msg, (fparam_t*)_param1)) {
+		LOG(L_ERR, "ERROR: smsg_append_hdrs(): cannot get parameter\n");
+		return -1;
+	}
+	/* select and AVP result can change, we need a private copy of the buffer */
+	if (clone_str(&s, &hdrs)) return -1;
+
+	if (_param2) {
+		if (get_str_fparam(&s, _msg, (fparam_t*)_param2)) {
+			LOG(L_ERR, "ERROR: smsg_append_hdrs(): cannot get parameter\n");
+			return -1;
+		}
+		/* select and AVP result can change, we need a private copy of the buffer */
+		if (clone_str(&s, &body)) return -1;
+	} else {
+		if (body.s) {
+			pkg_free(body.s);
+			body.s = 0;
+			body.len = 0;
+		}
+	}
+
+	return 1;
+}
+
+/*
+ * callback function for TM module
+ * it is called on TMCB_LOCAL_COMPLETED
+ */
+static void tmcb_func(struct cell *_t, int _type, struct tmcb_params *_ps)
+{
+	int	index;
+
+	if (_type & (TMCB_LOCAL_COMPLETED)) {
+		if ((!_ps->rpl) || (_ps->rpl == FAKED_REPLY)) {
+			/* timer hit  -- on_failure route is not supported */
+			LOG(L_DBG, "DEBUG: tmcb_func(): transaction completed with failure (timer hit),"
+				" but msg_shooter module does not support failure_route currently\n");
+		} else {
+			/* reply received */
+			if (_ps->code >= 400) {
+				LOG(L_DBG, "DEBUG: tmcb_func(): transaction completed with failure (code=%d),"
+					" but msg_shooter module does not support failure_route currently\n",
+					_ps->code);
+			}
+			if (!_ps->param) {
+				LOG(L_ERR, "ERROR: tmcb_func(): parameter is missing\n");
+				return;		
+			}
+			index = (int)(long)(*_ps->param);
+			run_reply_route(_ps->rpl, _t, index);
+		}
+	}
+}
+
+
+static avp_list_t def_avp_list = 0;
+
+/* shoots a request to a destination outside of a dialog */
+int smsg(struct sip_msg *_msg, char *_param1, char *_param2)
+{
+	int	ret = 1;
+	str	ruri = {0, 0};
+	str	dst = {0, 0};
+	avp_list_t	*backup_uri_from, *backup_uri_to;
+	avp_list_t	*backup_user_from, *backup_user_to;
+	avp_list_t	*backup_domain_from, *backup_domain_to;
+	uac_req_t	uac_r;
+
+	/* check the required information */
+	if (!UAC) {
+		LOG(L_ERR, "ERROR: smsg(): UAC is missing\n");
+		LOG(L_ERR, "ERROR: smsg(): have you forgot to call smsg_from_to() and smsg_create() functions?\n");
+		return -1;
+	}
+
+	if (_param1 && get_str_fparam(&ruri, _msg, (fparam_t*)_param1)) {
+		LOG(L_ERR, "ERROR: smsg(): cannot get parameter\n");
+		return -1;
+	}
+
+	if (_param2 && get_str_fparam(&dst, _msg, (fparam_t*)_param2)) {
+		LOG(L_ERR, "ERROR: smsg(): cannot get parameter\n");
+		return -1;
+	}
+
+	LOG(L_DBG, "DEBUG: smsg(): sending %.*s request "
+			"(from=%.*s, to=%.*s, ruri=%.*s, dst=%.*s)\n",
+			method.len, method.s,
+			from.len, from.s,
+			to.len, to.s,
+			ruri.len, ruri.s,
+			dst.len, dst.s);
+
+
+	if (ruri.len) {
+		if (tmb.set_dlg_target(UAC, &ruri, &dst) < 0) {
+			LOG(L_ERR, "ERROR: smsg(): cannot set remote target\n");
+			return -1;
+		}
+	}
+
+	/* reset user AVP lists, otherwise TM would free the memory twice cousing crash */
+	backup_uri_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &def_avp_list);
+	backup_uri_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &def_avp_list);
+	backup_user_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &def_avp_list);
+	backup_user_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &def_avp_list);
+	backup_domain_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &def_avp_list);
+	backup_domain_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &def_avp_list);
+
+	set_uac_req(&uac_r,
+			&method,
+			(hdrs.len) ? &hdrs : 0,
+			(body.len) ? &body : 0,
+			UAC,
+			(onreply_idx < 0) ? 0 : TMCB_LOCAL_COMPLETED,
+			(onreply_idx < 0) ? 0 : tmcb_func,
+			(onreply_idx < 0) ? 0 : (void *)(long)onreply_idx
+		);
+
+	if (tmb.t_uac(&uac_r) < 0) {
+		LOG(L_ERR, "ERROR: smsg(): request could not be sent\n");
+		ret = -1;
+	}
+
+	/* restore AVP lists */
+	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, backup_uri_from);
+	set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, backup_uri_to);
+	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, backup_user_from);
+	set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, backup_user_to);
+	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, backup_domain_from);
+	set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, backup_domain_to);
+
+	/* reset smsg_on_reply */
+	onreply_idx = -1;
+	return ret;
+}
+
+/* sents on_reply route which will be called later */
+int smsg_on_reply(struct sip_msg *_msg, char *_param1, char *_param2)
+{
+	onreply_idx = (int)(long)(_param1);
+	return 1;
+}

+ 42 - 0
modules/msg_shooter/msg_shooter.h

@@ -0,0 +1,42 @@
+/*$Id$
+ *
+ * Copyright (C) 2011 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#ifndef _MSG_SHOOTER_H
+#define _MSG_SHOOTER_H
+
+#include "parser/msg_parser.h"
+
+/* get method of the request */
+int smsg_create(struct sip_msg *_msg, char *_param1, char *_param2);
+
+/* free allocated memory */
+void smsg_destroy(void);
+
+/* set From and To headers of the request */
+int smsg_from_to(struct sip_msg *_msg, char *_param1, char *_param2);
+
+/* append headers and optionally body to the request */
+int smsg_append_hdrs(struct sip_msg *_msg, char *_param1, char *_param2);
+
+/* shoots a request to a destination outside of a dialog */
+int smsg(struct sip_msg *_msg, char *_param1, char *_param2);
+
+/* sents on_reply route which will be called later */
+int smsg_on_reply(struct sip_msg *_msg, char *_param1, char *_param2);
+
+#endif /* _MSG_SHOOTER_H */

+ 124 - 0
modules/msg_shooter/msg_shooter_mod.c

@@ -0,0 +1,124 @@
+/*$Id$
+ *
+ * Copyright (C) 2011 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include "sr_module.h"
+#include "script_cb.h"
+#include "route.h"
+#include "modules/tm/tm_load.h"
+#include "msg_shooter.h"
+#include "msg_shooter_mod.h"
+
+MODULE_VERSION
+
+struct tm_binds	tmb;
+
+/* Module management function prototypes */
+static int mod_init(void);
+static int w_smsg_destroy(struct sip_msg *_msg, unsigned int flags, void *_param);
+static int fixup_smsg_on_reply(void** _param, int _param_no);
+
+/* Exported functions */
+static cmd_export_t cmds[] = {
+	{"shoot_msg",	smsg,		0, 0,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"shoot_msg",	smsg,		1, fixup_var_str_1,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"shoot_msg",	smsg,		2, fixup_var_str_12,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"smsg_create",	smsg_create, 	1, fixup_str_1,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"smsg_from_to",	smsg_from_to, 2, fixup_var_str_12,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"smsg_append_hdrs", 	smsg_append_hdrs, 1, fixup_var_str_1,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"smsg_append_hdrs", 	smsg_append_hdrs, 2, fixup_var_str_12,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{"smsg_on_reply", 	smsg_on_reply,	1, fixup_smsg_on_reply,
+			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
+
+	{0, 0, 0, 0, 0}
+};
+
+/* Module interface */
+struct module_exports exports = {
+	"msg_shooter",
+	cmds,		/* Exported functions */
+	0,		/* RPC methods */	
+	0,		/* Exported parameters */
+	mod_init,	/* module initialization function */
+	0,		/* response function */
+	0,		/* destroy function */
+	0,		/* oncancel function */
+	0		/* child initialization function */
+};
+
+/* module initialization function */
+static int mod_init(void)
+{
+	load_tm_f	load_tm;
+
+	LOG(L_DBG, "DEBUG: mod_init(): Initializing msg_shooter module\n");
+
+	/* import the TM auto-loading function */
+	if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) {
+		LOG(L_ERR, "ERROR: 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;
+
+	if (register_script_cb(w_smsg_destroy,
+			REQUEST_CB | FAILURE_CB | ONREPLY_CB | BRANCH_CB | POST_SCRIPT_CB,
+			0) < 0
+	)
+		return -1;
+
+	return 0;
+}
+
+/* free allocated memory */
+static int w_smsg_destroy(struct sip_msg *_msg, unsigned int flags, void *_param)
+{
+	smsg_destroy();
+	return 1;
+}
+
+/* fixup function to convert route name to index */
+static int fixup_smsg_on_reply(void** _param, int _param_no)
+{
+	int index;
+
+	if (_param_no != 1) return 0;
+
+	index = route_lookup(&onreply_rt, (char*)(*_param));
+	if (index < 0) {
+		LOG(L_ERR, "ERROR: fixup_smsg_on_reply(): unknown on_reply route name: %s\n",
+				(char*)(*_param));
+		return -1;
+	}
+	pkg_free(*_param);
+	*_param = (void *)(long)index;
+	return 0;
+}

+ 26 - 0
modules/msg_shooter/msg_shooter_mod.h

@@ -0,0 +1,26 @@
+/*$Id$
+ *
+ * Copyright (C) 2011 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#ifndef _MSG_SHOOTER_MOD_H
+#define _MSG_SHOOTER_MOD_H
+
+#include "modules/tm/tm_load.h"
+
+extern struct tm_binds	tmb;
+
+#endif /* _MSG_SHOOTER_MOD_H */

+ 54 - 0
modules/msg_shooter/smsg_routes.c

@@ -0,0 +1,54 @@
+/*$Id$
+ *
+ * Copyright (C) 2011 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "action.h"
+#include "route.h"
+#include "modules/tm/h_table.h"
+#include "smsg_routes.h"
+
+/* run reply route functions */
+int run_reply_route(struct sip_msg *_rpl, struct cell *_t, int index)
+{
+	avp_list_t	*backup_uri_from, *backup_uri_to;
+	avp_list_t	*backup_user_from, *backup_user_to;
+	avp_list_t	*backup_domain_from, *backup_domain_to;
+	struct run_act_ctx	ra_ctx;
+
+	if (!_t || (index < 0)) return -1;
+
+	/* set the avp_list the one from transaction */
+	backup_uri_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &_t->uri_avps_from );
+	backup_uri_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &_t->uri_avps_to );
+	backup_user_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &_t->user_avps_from );
+	backup_user_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &_t->user_avps_to );
+	backup_domain_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &_t->domain_avps_from );
+	backup_domain_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &_t->domain_avps_to );
+
+	init_run_actions_ctx(&ra_ctx);
+	if (run_actions(&ra_ctx, onreply_rt.rlist[index], _rpl)<0)
+		LOG(L_ERR, "ERROR: run_reply_route(): on_reply processing failed\n");
+
+	/* restore original avp list */
+	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_URI, backup_uri_from );
+	set_avp_list( AVP_TRACK_TO | AVP_CLASS_URI, backup_uri_to );
+	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_USER, backup_user_from );
+	set_avp_list( AVP_TRACK_TO | AVP_CLASS_USER, backup_user_to );
+	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_DOMAIN, backup_domain_from );
+	set_avp_list( AVP_TRACK_TO | AVP_CLASS_DOMAIN, backup_domain_to );
+
+	return 0;
+}

+ 26 - 0
modules/msg_shooter/smsg_routes.h

@@ -0,0 +1,26 @@
+/*$Id$
+ *
+ * Copyright (C) 2011 iptelorg GmbH
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#ifndef _ROUTES_H
+#define _ROUTES_H
+
+/* run reply route functions */
+int run_reply_route(struct sip_msg *res, struct cell *t, int index);
+
+
+#endif /* _ROUTES_H */

+ 12 - 12
modules_k/acc/doc/acc_admin.xml

@@ -361,13 +361,13 @@ if (uri=~"sip:+40") /* calls to Romania */ {
 					</para>
 					<itemizedlist>
 						<listitem><para><emphasis>
-						cdr_log_extra = cdr_extra_definition (';'cdr_extra_definition)*
+						cdr_extra = cdr_extra_definition (';'cdr_extra_definition)*
 						</emphasis></para></listitem>
 						<listitem><para><emphasis>
 						cdr_extra_definition = cdr_log_name '=' pseudo_variable
 						</emphasis></para></listitem>
 					</itemizedlist>
-					See also <xref linkend="cdr_log_extra"/>.
+					See also <xref linkend="cdr_extra"/>.
 					<para>
 					The full list of supported pseudo-variables in Sip-Router is
 					available at:
@@ -1130,7 +1130,7 @@ modparam("acc", "cdr_enable", 1)
 		</example>
 	</section>
 	<section>
-		<title><varname>cdr_start_when_confirmed</varname> (integer)</title>
+		<title><varname>cdr_start_on_confirmed</varname> (integer)</title>
 		<para>
 		Should the start time be taken from the time when the dialog is created,
         or when the dialog is confirmed?
@@ -1140,14 +1140,14 @@ modparam("acc", "cdr_enable", 1)
 		1 - use time of dialog confirmation.
 		</para>
 		<example>
-		<title>cdr_start_when_confirmed example</title>
+		<title>cdr_start_on_confirmed example</title>
 		<programlisting format="linespecific">
-modparam("acc", "cdr_start_when_confirmed", 1)
+modparam("acc", "cdr_start_on_confirmed", 1)
 </programlisting>
 		</example>
 	</section>
 	<section>
-		<title><varname>cdr_log_facility</varname> (integer)</title>
+		<title><varname>cdr_facility</varname> (integer)</title>
 		<para>
 		Log facility to which CDR messages are issued to syslog.
 		This allows to easily seperate CDR-specific logging from
@@ -1157,14 +1157,14 @@ modparam("acc", "cdr_start_when_confirmed", 1)
 		Default value is LOG_DAEMON.
 		</para>
 		<example>
-		<title>cdr_log_facility example</title>
+		<title>cdr_facility example</title>
 		<programlisting format="linespecific">
-modparam("acc", "cdr_log_facility", "LOG_DAEMON")
+modparam("acc", "cdr_facility", "LOG_DAEMON")
 </programlisting>
 		</example>
 	</section>
-	<section id="cdr_log_extra">
-		<title><varname>cdr_log_extra</varname> (string)</title>
+	<section id="cdr_extra">
+		<title><varname>cdr_extra</varname> (string)</title>
 		<para>
 		Set of pseudo-variables defining custom CDR fields. See
         <xref linkend="cdr-extra-id"/> for more details.
@@ -1173,9 +1173,9 @@ modparam("acc", "cdr_log_facility", "LOG_DAEMON")
 		Default value is NULL.
 		</para>
 		<example>
-		<title>cdr_log_extra example</title>
+		<title>cdr_extra example</title>
 		<programlisting format="linespecific">
-modparam("acc", "cdr_log_extra", "c1=$dlg_var(caller);c2=$dlg_var(callee)"
+modparam("acc", "cdr_extra", "c1=$dlg_var(caller);c2=$dlg_var(callee)"
 </programlisting>
 		</example>
 	</section>