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