[sr-dev] git:master: textops: change_reply_status() added

Miklos Tirpak miklos at iptel.org
Wed May 26 17:18:43 CEST 2010


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

Author: Miklos Tirpak <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at iptel.org>
Date:   Wed May 26 17:16:47 2010 +0200

textops: change_reply_status() added

change_reply_status(code, reason) can be used to change the
status code and the reason phrase of a SIP reply
from onreply_route.

---

 modules_s/textops/doc/functions.xml |   30 ++++++++++++++
 modules_s/textops/textops.c         |   74 +++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/modules_s/textops/doc/functions.xml b/modules_s/textops/doc/functions.xml
index 3a180a8..b0b528c 100644
--- a/modules_s/textops/doc/functions.xml
+++ b/modules_s/textops/doc/functions.xml
@@ -642,6 +642,36 @@ if (@hf_value_exists.supported.path == "1") {
 	</example>
     </section>
 
+    <section id="change_reply_status">
+	<title>
+	    <function>change_reply_status(code, reason)</function>
+	</title>
+	<para>
+		Change the status code and reason phrase of a SIP reply in onreply_route.
+	</para>
+	<para>Meaning of the parameters is as follows:</para>
+	<itemizedlist>
+	    <listitem>
+		<para><emphasis>code</emphasis> - Status code.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>reason</emphasis> - Reason phrase.
+		</para>
+	    </listitem>
+	</itemizedlist>
+	<example>
+	    <title><function>change_reply_status</function> usage</title>
+	    <programlisting>
+...
+if (@status == "603") {
+	change_reply_status(404, "Not Found")
+}
+...
+	    </programlisting>
+	</example>
+    </section>
+
     <section id="@hf_value">
 	<title>
 	    <function>@hf_value selects</function>
diff --git a/modules_s/textops/textops.c b/modules_s/textops/textops.c
index 73cd301..e217bc8 100644
--- a/modules_s/textops/textops.c
+++ b/modules_s/textops/textops.c
@@ -114,6 +114,7 @@ static int append_to_reply_f(struct sip_msg* msg, char* key, char* str);
 static int append_hf(struct sip_msg* msg, char* str1, char* str2);
 static int append_urihf(struct sip_msg* msg, char* str1, char* str2);
 static int append_time_f(struct sip_msg* msg, char* , char *);
+static int change_reply_status_f(struct sip_msg* msg, char* , char *);
 
 static int incexc_hf_value_f(struct sip_msg* msg, char* , char *);
 static int include_hf_value_fixup(void**, int);
@@ -129,6 +130,7 @@ static int remove_hf_value2_fixup(void** param, int param_no);
 static int assign_hf_value2_fixup(void** param, int param_no);
 static int fixup_xlstr(void** param, int param_no);
 static int fixup_regex_xlstr(void** param, int param_no);
+static int change_reply_status_fixup(void** param, int param_no);
 
 static int fixup_substre(void**, int);
 
@@ -188,6 +190,8 @@ static cmd_export_t cmds[]={
 			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
 	{"hf_value_exists",  incexc_hf_value_f,      2, hf_value_exists_fixup,
 			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
+	{"change_reply_status",	change_reply_status_f,	2, change_reply_status_fixup,
+			ONREPLY_ROUTE},
 
 	{0,0,0,0,0}
 };
@@ -1735,6 +1739,76 @@ static int assign_hf_value2_fixup(void** param, int param_no) {
 	return 0;
 }
 
+static int change_reply_status_fixup(void** param, int param_no)
+{
+	if (param_no == 1) {
+		return fixup_var_int_12(param, param_no);
+	} else if (param_no == 2)
+		return fixup_var_str_12(param, param_no);
+	else
+		return 0;
+}
+
+static int change_reply_status_f(struct sip_msg* msg, char* _code, char* _reason)
+{
+	int	code;
+	str	reason;
+	struct lump	*l;
+	char	*ch;
+
+	if (get_int_fparam(&code, msg, (fparam_t*)_code)
+		|| get_str_fparam(&reason, msg, (fparam_t*)_reason)
+		|| (reason.len == 0)
+	) {
+		LOG(L_ERR, "ERROR: textops: cannot get parameter\n");
+		return -1;
+	}
+
+	if ((code < 100) || (code > 699)) {
+		LOG(L_ERR, "ERROR: textops: wrong status code: %d\n",
+				code);
+		return -1;
+	}
+
+	if (((code < 300) || (msg->REPLY_STATUS < 300))
+		&& (code/100 != msg->REPLY_STATUS/100)
+	) {
+		LOG(L_ERR, "ERROR: textops: the class of provisional or "
+			"positive final replies cannot be changed\n");
+		return -1;
+	}
+
+	/* rewrite the status code directly in the message buffer */
+	msg->first_line.u.reply.statuscode = code;
+	msg->first_line.u.reply.status.s[2] = code % 10 + '0'; code /= 10;
+	msg->first_line.u.reply.status.s[1] = code % 10 + '0'; code /= 10;
+	msg->first_line.u.reply.status.s[0] = code + '0';
+
+	l = del_lump(msg,
+		msg->first_line.u.reply.reason.s - msg->buf,
+		msg->first_line.u.reply.reason.len,
+		0);
+	if (!l) {
+		LOG(L_ERR, "ERROR: textops(): Failed to add del lump\n");
+		return -1;
+	}
+	/* clone the reason phrase, the lumps need to be pkg allocated */
+	ch = (char *)pkg_malloc(reason.len);
+	if (!ch) {
+		LOG(L_ERR, "ERROR: textops: Not enough memory\n");
+		return -1;
+	}
+	memcpy(ch, reason.s, reason.len);
+	if (insert_new_lump_after(l, ch, reason.len, 0)==0){
+		LOG(L_ERR, "ERROR: textops: failed to add new lump: %.*s\n",
+			reason.len, ch);
+		pkg_free(ch);
+		return -1;
+	}
+
+	return 1;
+}
+
 static int sel_hf_value(str* res, select_t* s, struct sip_msg* msg) {  /* dummy */
 	return 0;
 }




More information about the sr-dev mailing list