Module: sip-router
Branch: master
Commit: 02ec00fbade29687566a158f20cb310a56346de6
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=02ec00f…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)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;
}