Module: sip-router
Branch: master
Commit: 2e466866468a71d4a6e7589cae69ae606b194716
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=2e46686…
Author: Jason Penton <jason.penton(a)smilecoms.com>
Committer: Jason Penton <jason.penton(a)smilecoms.com>
Date: Wed Jun 5 08:46:13 2013 +0200
modules/ims_isc: Add support for P-Serverd-User header
- This header allows a triggered Application Server to know the IMS user for who it was
triggered, and in what state (originating/terminating, registered/unregistered)
- Thanks to Camille Oudot for patch!
---
modules/ims_isc/doc/ims_isc_admin.xml | 20 +++++++++
modules/ims_isc/mark.c | 70 +++++++++++++++++++++++++++++++++
modules/ims_isc/mark.h | 1 +
modules/ims_isc/mod.c | 2 +
4 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/modules/ims_isc/doc/ims_isc_admin.xml
b/modules/ims_isc/doc/ims_isc_admin.xml
index adc6f5e..33dac0a 100644
--- a/modules/ims_isc/doc/ims_isc_admin.xml
+++ b/modules/ims_isc/doc/ims_isc_admin.xml
@@ -126,6 +126,26 @@ modparam("ims_isc", "isc_fr_inv_timeout", 20000)
</programlisting>
</example>
</section>
+
+ <section>
+ <title><varname>add_p_served_user</varname>
(integer)</title>
+
+ <para>This boolean indicates if a P-Served-User should be added on the ISC
+ interface, according to RFC 5502.</para>
+
+ <para><emphasis> Default value is 0
(false)</emphasis></para>
+
+ <example>
+ <title><varname>add_p_served_user</varname> parameter
usage</title>
+
+ <programlisting format="linespecific">
+...
+modparam("ims_isc", "add_p_served_user", 1)
+# p-served user header will be enabled
+...
+ </programlisting>
+ </example>
+ </section>
</section>
<section>
diff --git a/modules/ims_isc/mark.c b/modules/ims_isc/mark.c
index a1a73e4..c879604 100644
--- a/modules/ims_isc/mark.c
+++ b/modules/ims_isc/mark.c
@@ -44,6 +44,16 @@
*/
#include "mark.h"
+#include "../../str.h"
+#include "../../data_lump.h"
+
+const str psu_hdr_s = str_init("P-Served-User:
<%.*s>;sescase=%.*s;regstate=%.*s\r\n");
+const str sescase_orig = str_init("orig");
+const str sescase_term = str_init("term");
+const str regstate_reg = str_init("reg");
+const str regstate_unreg = str_init("unreg");
+
+extern int add_p_served_user;
/** base16 char constants */
char *hexchars = "0123456789abcdef";
@@ -243,6 +253,9 @@ int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark
*mark) {
if (match)
as = match->server_name;
isc_mark_write_route(msg, &as, &route);
+ if (add_p_served_user) {
+ isc_mark_write_psu(msg, mark);
+ }
LM_DBG("isc_mark_set: NEW mark <%s>\n", chr_mark);
return 1;
@@ -291,3 +304,60 @@ inline int isc_mark_write_route(struct sip_msg *msg, str *as, str
*iscmark) {
return 1;
}
+/**
+ * Inserts the P-Served-User header on a SIP message
+ * as specified in RFC 5502
+ * @param msg - SIP message
+ * @param mark - the mark containing all required information
+ * @returns 1 on success, else 0
+ */
+int isc_mark_write_psu(struct sip_msg *msg, isc_mark *mark) {
+ struct lump *l = msg->add_rm;
+ int hlen;
+ char * hstr = NULL;
+ const str *regstate, *sescase;
+
+ switch(mark->direction) {
+ case IFC_ORIGINATING_SESSION:
+ regstate = ®state_reg;
+ sescase = &sescase_orig;
+ break;
+ case IFC_TERMINATING_SESSION:
+ regstate = ®state_reg;
+ sescase = &sescase_term;
+ break;
+ case IFC_TERMINATING_UNREGISTERED:
+ regstate = ®state_unreg;
+ sescase = &sescase_term;
+ break;
+ default:
+ LM_ERR("isc_mark_write_psu: unknown direction: %d\n",
mark->direction);
+ return 0;
+ }
+
+ hlen = psu_hdr_s.len - /* 3 "%.*s" */ 12 + mark->aor.len +
regstate->len + sescase->len + 1;
+ hstr = pkg_malloc(hlen);
+ if (hstr == NULL) {
+ LM_ERR("isc_mark_write_psu: could not allocate %d bytes\n", hlen);
+ return 0;
+ }
+
+ int ret = snprintf(hstr, hlen, psu_hdr_s.s,
+ mark->aor.len, mark->aor.s,
+ sescase->len, sescase->s,
+ regstate->len, regstate->s);
+ if (ret >= hlen) {
+ LM_ERR("isc_mark_write_psu: invalid string buffer size: %d, required:
%d\n", hlen, ret);
+ pkg_free(hstr);
+ return 0;
+ }
+
+ LM_DBG("isc_mark_write_psu: %.*s\n", hlen - 3 /* don't print \r\n\0 */,
hstr);
+ if (append_new_lump(&l, hstr, hlen - 1, HDR_OTHER_T) == 0) {
+ LM_ERR("isc_mark_write_psu: append_new_lump(%p, \"%.*s\\\r\\n\",
%d, 0) failed\n", &l, hlen - 3 /* don't print \r\n\0 */, hstr, hlen - 1);
+ pkg_free(hstr);
+ return 0;
+ }
+ /* hstr will be deallocated when msg will be destroyed */
+ return 1;
+}
diff --git a/modules/ims_isc/mark.h b/modules/ims_isc/mark.h
index e6912f3..9121eaa 100644
--- a/modules/ims_isc/mark.h
+++ b/modules/ims_isc/mark.h
@@ -76,6 +76,7 @@ int base16_to_bin(char *from,int len, char *to);
inline int isc_mark_drop_route(struct sip_msg *msg);
int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark *mark);
inline int isc_mark_write_route(struct sip_msg *msg,str *as,str *iscmark);
+int isc_mark_write_psu(struct sip_msg *msg, isc_mark *mark);
int bin_to_base16(char *from,int len, char *to);
#endif
diff --git a/modules/ims_isc/mod.c b/modules/ims_isc/mod.c
index 3b69bbd..5c54453 100644
--- a/modules/ims_isc/mod.c
+++ b/modules/ims_isc/mod.c
@@ -62,6 +62,7 @@ str isc_my_uri_sip = {0, 0}; /**< Uri of myself to loop the message
in str with
int isc_expires_grace = 120; /**< expires value to add to the expires in the 3rd party
register*/
int isc_fr_timeout = 5000; /**< default ISC response timeout in ms */
int isc_fr_inv_timeout = 20000; /**< default ISC invite response timeout in ms */
+int add_p_served_user = 0; /**< should the P-Served-User header be inserted? */
/** module functions */
static int mod_init(void);
@@ -92,6 +93,7 @@ static param_export_t params[] = {
consider it dead. Has to be lower than SIP transaction
timeout
to prevent downstream timeouts. Not too small though
because
AS are usually slow as hell... */
+ { "add_p_served_user", INT_PARAM, &add_p_served_user}, /**< boolean
indicating if the P-Served-User (RFC5502) should be added on the ISC interface or not */
{ 0, 0, 0}
};