Browse Source

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!

Jason Penton 12 years ago
parent
commit
2e46686646
4 changed files with 93 additions and 0 deletions
  1. 20 0
      modules/ims_isc/doc/ims_isc_admin.xml
  2. 70 0
      modules/ims_isc/mark.c
  3. 1 0
      modules/ims_isc/mark.h
  4. 2 0
      modules/ims_isc/mod.c

+ 20 - 0
modules/ims_isc/doc/ims_isc_admin.xml

@@ -122,6 +122,26 @@ modparam("ims_isc", "isc_fr_timeout", 5000)
         <programlisting format="linespecific">
         <programlisting format="linespecific">
 ...
 ...
 modparam("ims_isc", "isc_fr_inv_timeout", 20000)
 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>
         </programlisting>
       </example>
       </example>

+ 70 - 0
modules/ims_isc/mark.c

@@ -44,6 +44,16 @@
  */
  */
 
 
 #include "mark.h"
 #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 */
 /** base16 char constants */
 char *hexchars = "0123456789abcdef";
 char *hexchars = "0123456789abcdef";
@@ -243,6 +253,9 @@ int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark *mark) {
 	if (match)
 	if (match)
 		as = match->server_name;
 		as = match->server_name;
 	isc_mark_write_route(msg, &as, &route);
 	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);
 	LM_DBG("isc_mark_set: NEW mark <%s>\n", chr_mark);
 
 
 	return 1;
 	return 1;
@@ -291,3 +304,60 @@ inline int isc_mark_write_route(struct sip_msg *msg, str *as, str *iscmark) {
 	return 1;
 	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 = &regstate_reg;
+        sescase = &sescase_orig;
+        break;
+    case IFC_TERMINATING_SESSION:
+        regstate = &regstate_reg;
+        sescase = &sescase_term;
+        break;
+    case IFC_TERMINATING_UNREGISTERED:
+        regstate = &regstate_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;
+}

+ 1 - 0
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);
 inline int isc_mark_drop_route(struct sip_msg *msg);
 int isc_mark_set(struct sip_msg *msg, isc_match *match, isc_mark *mark);
 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);
 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);
 int bin_to_base16(char *from,int len, char *to);
 
 
 #endif
 #endif

+ 2 - 0
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_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_timeout = 5000; /**< default ISC response timeout in ms */
 int isc_fr_inv_timeout = 20000; /**< default ISC invite 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 */
 /** module functions */
 static int mod_init(void);
 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
  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 consider it dead. Has to be lower than SIP transaction timeout
  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 to prevent downstream timeouts. Not too small though because
  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 to prevent downstream timeouts. Not too small though because
  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 AS are usually slow as hell... */
  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 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}
     { 0, 0, 0}
 };
 };