Selaa lähdekoodia

pua_dialoginfo: allow setting PUBLISH R-URIs via AVPs

- patch by Jasmin Schnatterbeck, FS#197
Daniel-Constantin Mierla 13 vuotta sitten
vanhempi
commit
785ff3ebc2

+ 80 - 7
modules_k/pua_dialoginfo/README

@@ -19,9 +19,9 @@ Klaus Darilion
 
    IPCom
 
-   Copyright © 2006 Voice Sistem SRL
+   Copyright © 2006 Voice Sistem SRL
 
-   Copyright © 2008 Klaus Darilion IPCom
+   Copyright © 2008 Klaus Darilion IPCom
      __________________________________________________________________
 
    Table of Contents
@@ -43,6 +43,10 @@ Klaus Darilion
               5.3. include_localremote (int)
               5.4. override_lifetime (int)
               5.5. caller_confirmed (int)
+              5.6. send_publish_flag (int)
+              5.7. use_pubruri_avps (int)
+              5.8. pubruri_caller_avp (int)
+              5.9. pubruri_callee_avp (int)
 
         6. Functions
 
@@ -53,6 +57,10 @@ Klaus Darilion
    1.3. Set include_localremote parameter
    1.4. Set override_lifetime parameter
    1.5. Set caller_confirmed parameter
+   1.6. Set send_publish_flag parameter
+   1.7. Set use_pubruri_avps parameter
+   1.8. Set pubruri_caller_avp parameter
+   1.9. Set pubruri_callee_avp parameter
 
 Chapter 1. Admin Guide
 
@@ -73,6 +81,10 @@ Chapter 1. Admin Guide
         5.3. include_localremote (int)
         5.4. override_lifetime (int)
         5.5. caller_confirmed (int)
+        5.6. send_publish_flag (int)
+        5.7. use_pubruri_avps (int)
+        5.8. pubruri_caller_avp (int)
+        5.9. pubruri_callee_avp (int)
 
    6. Functions
 
@@ -246,13 +258,17 @@ Chapter 1. Admin Guide
    5.3. include_localremote (int)
    5.4. override_lifetime (int)
    5.5. caller_confirmed (int)
+   5.6. send_publish_flag (int)
+   5.7. use_pubruri_avps (int)
+   5.8. pubruri_caller_avp (int)
+   5.9. pubruri_callee_avp (int)
 
 5.1. include_callid (int)
 
    If this parameter is set, the optional call-id will be put into the
    dialog element. This is needed for call-pickup features.
 
-   Default value is “1�.
+   Default value is "1".
 
    Example 1.1. Set include_callid parameter
 ...
@@ -264,7 +280,7 @@ modparam("pua_dialoginfo", "include_callid", 0)
    If this parameter is set, the local and remote tag will be put into the
    dialog element. This is needed for call-pickup features.
 
-   Default value is “1�.
+   Default value is "1".
 
    Example 1.2. Set include_tags parameter
 ...
@@ -277,7 +293,7 @@ modparam("pua_dialoginfo", "include_tags", 0)
    be put into the dialog element. This is needed for call-pickup
    features.
 
-   Default value is “1�.
+   Default value is "1".
 
    Example 1.3. Set include_localremote parameter
 ...
@@ -293,7 +309,7 @@ modparam("pua_dialoginfo", "include_localremote", 0)
    dialog module. If used, the value should at least be a few seconds more
    than the fr_inv_timer of the tm module.
 
-   Default value is “0�.
+   Default value is "0".
 
    Example 1.4. Set override_lifetime parameter
 ...
@@ -312,11 +328,68 @@ modparam("pua_dialoginfo", "override_lifetime", 300)
    the buggy Linksys SPA962 phones. SNOM phones work well with the default
    setting.
 
-   Default value is “0�.
+   Default value is "0".
 
    Example 1.5. Set caller_confirmed parameter
 ...
 modparam("pua_dialoginfo", "caller_confirmed", 1)
 ...
 
+5.6. send_publish_flag (int)
+
+   This message flag indicates whether to send PUBLISH requests or not. If
+   not set, PUBLISH requests are sent out only if their R-URI is local
+   (according to myself).
+
+   Default value is "-1".
+
+   Example 1.6. Set send_publish_flag parameter
+...
+modparam("pua_dialoginfo", "send_publish_flag", 8)
+...
+
+5.7. use_pubruri_avps (int)
+
+   Get Publish R-Uri from avps (see corresponding avp params), not from
+   reqeust to/from uri.
+
+   Default value is "0".
+
+   Example 1.7. Set use_pubruri_avps parameter
+...
+modparam("pua_dialoginfo", "use_pubruri_avps", 1)
+...
+
+5.8. pubruri_caller_avp (int)
+
+   If use_pubruri_avps is enabled, PUBLISH-requests reporting
+   dialog-information about the caller (entity=caller) are sent using the
+   value of the specified avp as R-Uri. If multiple AVPs with the same
+   name (but different indexes) are present, for each value a
+   corresponding PUBLISH-request is generated. If no AVP with the
+   specified name exists, no caller-related PUBLISH requests are sent.
+
+   Default value is "NULL".
+
+   Example 1.8. Set pubruri_caller_avp parameter
+...
+modparam("pua_dialoginfo", "pubruri_caller_avp", "$avp(s:puburis_caller)")
+...
+
+5.9. pubruri_callee_avp (int)
+
+   If use_pubruri_avps is enabled, PUBLISH-requests reporting
+   dialog-information about the callee (entity=callee) are sent using the
+   value of the specified avp as R-Uri. If multiple AVPs with the same
+   name (but different indexes) are present, for each value a
+   corresponding PUBLISH-request is generated. If no AVP with the
+   specified name exists, no callee-related PUBLISH requests are sent.
+
+   Default value is "NULL".
+
+   Example 1.9. Set pubruri_callee_avp parameter
+...
+modparam("pua_dialoginfo", "pubruri_callee_avp", "$avp(s:puburis_callee)")
+...
+
 6. Functions

+ 36 - 15
modules_k/pua_dialoginfo/dialog_publish.c

@@ -31,6 +31,7 @@
 #include "../../parser/parse_expires.h"
 #include "../../parser/msg_parser.h"
 #include "../../str.h"
+#include "../../str_list.h"
 #include "../../name_alias.h"
 #include "../../socket_info.h"
 #include "../usrloc/usrloc.h"
@@ -259,27 +260,33 @@ error:
 	return NULL;
 }	
 
-void dialog_publish(char *state, str *entity, str *peer, str *callid, 
+void dialog_publish(char *state, str* ruri, str *entity, str *peer, str *callid,
 	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
-	str *localtarget, str *remotetarget)
+	str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck)
 {
 	str* body= NULL;
 	str uri= {NULL, 0};
 	publ_info_t* publ= NULL;
 	int size= 0;
 	str content_type;
-    struct sip_uri entity_uri;
+    struct sip_uri ruri_uri;
 
-	/* send PUBLISH only if the receiver (entity, RURI) is local*/
-	if (parse_uri(entity->s, entity->len, &entity_uri) < 0) {
-		LM_ERR("failed to parse the entity URI\n");
-		return;
-	}
-	if (!check_self(&(entity_uri.host), 0, 0)) {
-		LM_DBG("do not send PUBLISH to external URI %.*s\n",entity->len, entity->s);
+
+    if (parse_uri(ruri->s, ruri->len, &ruri_uri) < 0) {
+		LM_ERR("failed to parse the PUBLISH R-URI\n");
 		return;
 	}
 
+    if(do_pubruri_localcheck) {
+
+		/* send PUBLISH only if the receiver PUBLISH R-URI is local*/
+		if (!check_self(&(ruri_uri.host), 0, 0)) {
+			LM_DBG("do not send PUBLISH to external URI %.*s\n",ruri->len, ruri->s);
+			return;
+		}
+
+    }
+
 	content_type.s= "application/dialog-info+xml";
 	content_type.len= 27;
 
@@ -287,11 +294,11 @@ void dialog_publish(char *state, str *entity, str *peer, str *callid,
 	if(body == NULL || body->s == NULL)
 		goto error;
 	
-	LM_DBG("publish uri= %.*s\n", entity->len, entity->s);
+	LM_DBG("publish uri= %.*s\n", ruri->len, ruri->s);
 	
 	size= sizeof(publ_info_t) 
 			+ sizeof(str) 			/* *pres_uri */
-			+ ( entity->len 		/* pres_uri->s */
+			+ ( ruri->len 		/* pres_uri->s */
 			  + callid->len + 16	/* id.s */
 			  + content_type.len	/* content_type.s */
 			)*sizeof(char); 
@@ -311,9 +318,9 @@ void dialog_publish(char *state, str *entity, str *peer, str *callid,
 	publ->pres_uri= (str*)((char*)publ + size);
 	size+= sizeof(str);
 	publ->pres_uri->s= (char*)publ+ size;
-	memcpy(publ->pres_uri->s, entity->s, entity->len);
-	publ->pres_uri->len= entity->len;
-	size+= entity->len;
+	memcpy(publ->pres_uri->s, ruri->s, ruri->len);
+	publ->pres_uri->len= ruri->len;
+	size+= ruri->len;
 
 	if(body)
 	{
@@ -368,3 +375,17 @@ error:
 
 	return;
 }
+
+
+
+void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid,
+	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
+	str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck) {
+
+	while(ruris) {
+		LM_INFO("CALLING dialog_publish for URI %.*s\n",ruris->s.len, ruris->s.s);
+		dialog_publish(state,&(ruris->s),entity,peer,callid,initiator,lifetime,localtag,remotetag,localtarget,remotetarget,do_pubruri_localcheck);
+		ruris=ruris->next;
+	}
+
+}

+ 78 - 1
modules_k/pua_dialoginfo/doc/pua_dialoginfo_admin.xml

@@ -339,7 +339,84 @@ modparam("pua_dialoginfo", "caller_confirmed", 1)
 </programlisting>
 		</example>
 		</section>
-
+	
+	<section>
+		<title><varname>send_publish_flag</varname> (int)</title>
+		<para>
+			This message flag indicates whether to send PUBLISH requests or not.
+			If not set, PUBLISH requests are sent out only if their R-URI is local (according to myself).
+		</para>
+		<para>
+			<emphasis>Default value is <quote>-1</quote>.</emphasis>
+		</para>
+		<example>
+			<title>Set <varname>send_publish_flag</varname> parameter</title>
+			<programlisting format="linespecific">
+...
+modparam("pua_dialoginfo", "send_publish_flag", 8)
+...
+</programlisting>
+		</example>
+		</section>
+	
+		<section>
+		<title><varname>use_pubruri_avps</varname> (int)</title>
+		<para>
+			Get Publish R-Uri from avps (see corresponding avp params), not from reqeust to/from uri. 
+		</para>
+		<para>
+			<emphasis>Default value is <quote>0</quote>.</emphasis>
+		</para>
+		<example>
+			<title>Set <varname>use_pubruri_avps</varname> parameter</title>
+			<programlisting format="linespecific">
+...
+modparam("pua_dialoginfo", "use_pubruri_avps", 1)
+...
+</programlisting>
+		</example>
+		</section>
+		
+		<section>
+		<title><varname>pubruri_caller_avp</varname> (int)</title>
+		<para>
+			If use_pubruri_avps is enabled, PUBLISH-requests reporting dialog-information about the caller (entity=caller) are sent using the value of the specified avp as R-Uri.  
+			If multiple AVPs with the same name (but different indexes) are present, for each value a corresponding PUBLISH-request is generated.
+			If no AVP with the specified name exists, no caller-related PUBLISH requests are sent.   
+		</para>
+		<para>
+			<emphasis>Default value is <quote>NULL</quote>.</emphasis>
+		</para>
+		<example>
+			<title>Set <varname>pubruri_caller_avp</varname> parameter</title>
+			<programlisting format="linespecific">
+...
+modparam("pua_dialoginfo", "pubruri_caller_avp", "$avp(s:puburis_caller)")
+...
+</programlisting>
+		</example>
+		</section>
+		
+		<section>
+		<title><varname>pubruri_callee_avp</varname> (int)</title>
+		<para>
+			If use_pubruri_avps is enabled, PUBLISH-requests reporting dialog-information about the callee (entity=callee) are sent using the value of the specified avp as R-Uri.  
+			If multiple AVPs with the same name (but different indexes) are present, for each value a corresponding PUBLISH-request is generated.
+			If no AVP with the specified name exists, no callee-related PUBLISH requests are sent.   
+		</para>
+		<para>
+			<emphasis>Default value is <quote>NULL</quote>.</emphasis>
+		</para>
+		<example>
+			<title>Set <varname>pubruri_callee_avp</varname> parameter</title>
+			<programlisting format="linespecific">
+...
+modparam("pua_dialoginfo", "pubruri_callee_avp", "$avp(s:puburis_callee)")
+...
+</programlisting>
+		</example>
+		</section>
+		
 	</section>
 
 	<section>

+ 177 - 17
modules_k/pua_dialoginfo/pua_dialoginfo.c

@@ -43,6 +43,7 @@
 #include "../../parser/parse_to.h"
 #include "../../parser/contact/parse_contact.h"
 #include "../../str.h"
+#include "../../str_list.h"
 #include "../../mem/mem.h"
 #include "../../pt.h"
 #include "../dialog/dlg_load.h"
@@ -59,6 +60,12 @@ MODULE_VERSION
 #define DEF_OVERRIDE_LIFETIME 0
 #define DEF_CALLER_ALWAYS_CONFIRMED 0
 #define DEF_INCLUDE_REQ_URI 0
+#define DEF_OVERRIDE_LIFETIME 0
+#define DEF_SEND_PUBLISH_FLAG -1
+#define DEF_USE_PUBRURI_AVPS 0
+#define DEF_PUBRURI_CALLER_AVP 0
+#define DEF_PUBRURI_CALLEE_AVP 0
+
 
 /* define PUA_DIALOGINFO_DEBUG to activate more verbose 
  * logging and dialog info callback debugging
@@ -69,6 +76,11 @@ pua_api_t pua;
 
 struct dlg_binds dlg_api;
 
+unsigned short pubruri_caller_avp_type;
+int_str pubruri_caller_avp_name;
+unsigned short pubruri_callee_avp_type;
+int_str pubruri_callee_avp_name;
+
 /* Module parameter variables */
 int include_callid      = DEF_INCLUDE_CALLID;
 int include_localremote = DEF_INCLUDE_LOCALREMOTE;
@@ -76,6 +88,10 @@ int include_tags        = DEF_INCLUDE_TAGS;
 int override_lifetime   = DEF_OVERRIDE_LIFETIME;
 int caller_confirmed    = DEF_CALLER_ALWAYS_CONFIRMED;
 int include_req_uri     = DEF_INCLUDE_REQ_URI;
+int send_publish_flag = DEF_SEND_PUBLISH_FLAG;
+int use_pubruri_avps    = DEF_USE_PUBRURI_AVPS;
+char * pubruri_caller_avp  = DEF_PUBRURI_CALLER_AVP;
+char * pubruri_callee_avp  = DEF_PUBRURI_CALLEE_AVP;
 
 
 send_publish_t pua_send_publish;
@@ -96,6 +112,10 @@ static param_export_t params[]={
 	{"override_lifetime",   INT_PARAM, &override_lifetime },
 	{"caller_confirmed",    INT_PARAM, &caller_confirmed },
 	{"include_req_uri",     INT_PARAM, &include_req_uri },
+	{"send_publish_flag"	,	 INT_PARAM, &send_publish_flag },
+	{"use_pubruri_avps",    INT_PARAM, &use_pubruri_avps },
+	{"pubruri_caller_avp",  STR_PARAM, &pubruri_caller_avp },
+	{"pubruri_callee_avp",  STR_PARAM, &pubruri_callee_avp },
 	{0, 0, 0 }
 };
 
@@ -212,9 +232,10 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
 	str uri = {0,0};
 	str target = {0,0};
 
+
 	struct dlginfo_cell *dlginfo = (struct dlginfo_cell*)*_params->param;
 
-	if (include_req_uri) {
+	if(include_req_uri) {
 		uri = dlginfo->req_uri;
 	} else {
 		uri = dlginfo->to_uri;
@@ -225,15 +246,15 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
 	case DLGCB_TERMINATED:
 	case DLGCB_EXPIRED:
 		LM_DBG("dialog over, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
-		dialog_publish("terminated", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
-		dialog_publish("terminated", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
+		dialog_publish_multi("terminated", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
+		dialog_publish_multi("terminated", dlginfo->pubruris_callee, &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact), send_publish_flag==-1?1:0);
 		break;
 	case DLGCB_CONFIRMED:
 	case DLGCB_REQ_WITHIN:
 	case DLGCB_CONFIRMED_NA:
 		LM_DBG("dialog confirmed, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
-		dialog_publish("confirmed", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
-		dialog_publish("confirmed", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
+		dialog_publish_multi("confirmed", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
+		dialog_publish_multi("confirmed", dlginfo->pubruris_callee, &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact), send_publish_flag==-1?1:0);
 		break;
 	case DLGCB_EARLY:
 		LM_DBG("dialog is early, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
@@ -264,31 +285,80 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
 				}
 			}
 			if (caller_confirmed) {
-				dialog_publish("confirmed", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target);
+				dialog_publish_multi("confirmed", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
 			} else {
-				dialog_publish("early", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target);
+				dialog_publish_multi("early", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
 			}
-			dialog_publish("early", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, &tag, &(dlginfo->from_tag), &target, &(dlginfo->from_contact));
+			dialog_publish_multi("early", dlginfo->pubruris_callee, &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, &tag, &(dlginfo->from_tag), &target, &(dlginfo->from_contact), send_publish_flag==-1?1:0);
 
 		} else {
 			if (caller_confirmed) {
-				dialog_publish("confirmed", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
+				dialog_publish_multi("confirmed", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
 
 			} else {
-				dialog_publish("early", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
+				dialog_publish_multi("early", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
 			}
-			dialog_publish("early", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
+			dialog_publish_multi("early", dlginfo->pubruris_callee, &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact), send_publish_flag==-1?1:0);
 
 		}
 		break;
 	default:
 		LM_ERR("unhandled dialog callback type %d received, from=%.*s\n", type, dlginfo->from_uri.len, dlginfo->from_uri.s);
-		dialog_publish("terminated", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
-		dialog_publish("terminated", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
+		dialog_publish_multi("terminated", dlginfo->pubruris_caller, &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target, send_publish_flag==-1?1:0);
+		dialog_publish_multi("terminated", dlginfo->pubruris_callee, &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact), send_publish_flag==-1?1:0);
 
 	}
 }
 
+/*
+ *  Writes all avps with name avp_name to new str_list (shm mem)
+ *  Be careful: returns NULL pointer if no avp present!
+ *
+ */
+struct str_list*  get_str_list(unsigned short avp_flags, int_str avp_name) {
+
+	int_str avp_value;
+	unsigned int len;
+	struct str_list* list_first = 0;
+	struct str_list* list_current = 0	;
+	struct search_state st;
+
+	if(!search_first_avp(avp_flags, avp_name, &avp_value, &st)) {
+		return NULL;
+	}
+
+	do {
+
+		LM_DBG("AVP found '%.*s'\n", avp_value.s.len, avp_value.s.s);
+
+		len = sizeof(struct str_list) + avp_value.s.len;
+
+		if(list_current) {
+			list_current->next = (struct str_list*) shm_malloc( len);
+			list_current=list_current->next;
+		} else {
+			list_current=list_first= (struct str_list*) shm_malloc( len);
+		}
+
+		if (list_current==0) {
+			LM_ERR("no more shm mem (%d)\n",len);
+			return 0;
+		}
+
+		memset( list_current, 0, len);
+
+		list_current->s.s = (char*)( (void*) list_current + sizeof(struct str_list));
+		list_current->s.len = avp_value.s.len;
+		memcpy(list_current->s.s,avp_value.s.s,avp_value.s.len);
+
+
+
+	} while(search_next_avp(&st, &avp_value));
+
+	return list_first;
+
+}
+
 static void
 __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 {
@@ -299,6 +369,9 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 	if (request->REQ_METHOD != METHOD_INVITE)
 		return;
 
+	if(send_publish_flag > -1 && !(request->flags & (1<<send_publish_flag)))
+		return;
+
 	LM_DBG("new INVITE dialog created: from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s);
 
 	/* create dlginfo structure to store important data inside the module*/
@@ -331,13 +404,48 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 	dlginfo->req_uri.len  = dlg->req_uri.len;
 	dlginfo->from_contact.s   = dlginfo->req_uri.s + dlginfo->req_uri.len;
 	dlginfo->from_contact.len = dlg->contact[0].len;
+
 	memcpy(dlginfo->from_uri.s, dlg->from_uri.s, dlg->from_uri.len);
 	memcpy(dlginfo->to_uri.s, dlg->to_uri.s, dlg->to_uri.len);
 	memcpy(dlginfo->callid.s, dlg->callid.s, dlg->callid.len);
 	memcpy(dlginfo->from_tag.s, dlg->tag[0].s, dlg->tag[0].len);
 	memcpy(dlginfo->req_uri.s, dlg->req_uri.s, dlg->req_uri.len);
 	memcpy(dlginfo->from_contact.s, dlg->contact[0].s, dlg->contact[0].len);
-	
+
+	if (use_pubruri_avps) {
+
+		dlginfo->pubruris_caller = get_str_list(pubruri_caller_avp_type,pubruri_caller_avp_name);
+		dlginfo->pubruris_callee = get_str_list(pubruri_callee_avp_type,pubruri_callee_avp_name);
+
+	} else {
+
+		dlginfo->pubruris_caller = (struct str_list*)shm_malloc( sizeof(struct str_list) );
+
+		if (dlginfo->pubruris_caller==0) {
+			LM_ERR("no more shm mem (%d)\n", (int) sizeof(struct str_list));
+			return;
+		}
+		memset( dlginfo->pubruris_caller, 0, sizeof(struct str_list));
+
+		dlginfo->pubruris_caller->s=dlginfo->from_uri;
+
+
+		dlginfo->pubruris_callee = (struct str_list*)shm_malloc( sizeof(struct str_list) );
+
+		if (dlginfo->pubruris_callee==0) {
+			LM_ERR("no more shm mem (%d)\n", (int) sizeof(struct str_list));
+			return;
+		}
+		memset( dlginfo->pubruris_callee, 0, sizeof(struct str_list));
+
+		if(include_req_uri) {
+			dlginfo->pubruris_callee->s = dlginfo->req_uri;
+		} else {
+			dlginfo->pubruris_callee->s = dlginfo->to_uri;
+		}
+
+	}
+
 	/* register dialog callbacks which triggers sending PUBLISH */
 	if (dlg_api.register_dlgcb(dlg, 
 		DLGCB_FAILED| DLGCB_CONFIRMED_NA | DLGCB_TERMINATED | DLGCB_EXPIRED |
@@ -359,7 +467,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 	}
 #endif
 
-	dialog_publish("Trying", &(dlg->from_uri), (include_req_uri)?&(dlg->req_uri):&(dlg->to_uri), &(dlg->callid), 1, dlginfo->lifetime, 0, 0, 0, 0);
+	dialog_publish_multi("Trying", dlginfo->pubruris_caller, &(dlg->from_uri), (include_req_uri)?&(dlg->req_uri):&(dlg->to_uri), &(dlg->callid), 1, dlginfo->lifetime, 0, 0, 0, 0, send_publish_flag==-1?1:0);
 }
 
 
@@ -371,6 +479,9 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 static int mod_init(void)
 {
 	bind_pua_t bind_pua;
+
+	str s;
+	pv_spec_t avp_spec;
 	
 	bind_pua= (bind_pua_t)find_export("bind_pua", 1,0);
 	if (!bind_pua)
@@ -402,13 +513,62 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if(use_pubruri_avps) {
+
+		if(!(pubruri_caller_avp && *pubruri_caller_avp) && (pubruri_callee_avp && *pubruri_callee_avp)) {
+			LM_ERR("pubruri_caller_avp and pubruri_callee_avp must be set, if use_pubruri_avps is enabled\n");
+			return -1;
+		}
+
+		s.s = pubruri_caller_avp; s.len = strlen(s.s);
+		if (pv_parse_spec(&s, &avp_spec)==0	|| avp_spec.type!=PVT_AVP) {
+			LM_ERR("malformed or non AVP %s AVP definition\n", pubruri_caller_avp);
+			return -1;
+		}
+		if(pv_get_avp_name(0, &avp_spec.pvp, &pubruri_caller_avp_name, &pubruri_caller_avp_type)!=0) {
+			LM_ERR("[%s]- invalid AVP definition\n", pubruri_caller_avp);
+			return -1;
+		}
+
+		s.s = pubruri_callee_avp; s.len = strlen(s.s);
+		if (pv_parse_spec(&s, &avp_spec)==0	|| avp_spec.type!=PVT_AVP) {
+			LM_ERR("malformed or non AVP %s AVP definition\n", pubruri_callee_avp);
+			return -1;
+		}
+		if(pv_get_avp_name(0, &avp_spec.pvp, &pubruri_callee_avp_name, &pubruri_callee_avp_type)!=0) {
+			LM_ERR("[%s]- invalid AVP definition\n", pubruri_callee_avp);
+			return -1;
+		}
+
+	}
+
 	return 0;
 }
 
 void free_dlginfo_cell(void *param) {
-/*	struct dlginfo_cell *cell = param;
-	if (cell->to_tag) {
+
+	struct dlginfo_cell *cell = param;
+
+	free_str_list_all(cell->pubruris_caller);
+	free_str_list_all(cell->pubruris_callee);
+
+	/*if (cell->to_tag) {
 		shm_free(cell->to_tag);
 	}*/
 	shm_free(param);
 }
+
+
+void free_str_list_all(struct str_list * del_current) {
+
+	struct str_list* del_next;
+
+	while(del_current) {
+
+		del_next = del_current->next;
+		shm_free(del_current);
+
+		del_current=del_next;
+	}
+
+}

+ 7 - 3
modules_k/pua_dialoginfo/pua_dialoginfo.h

@@ -29,9 +29,9 @@
 
 extern send_publish_t pua_send_publish;
 
-void dialog_publish(char *state, str *entity, str *peer, str *callid, 
+void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid,
 	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
-	str *localtarget, str *remotetarget);
+	str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck);
 
 /* store the important data locally to avoid reading the data from the 
    dlg_cell during the callback (as this could create a race condition 
@@ -44,9 +44,13 @@ struct dlginfo_cell {
 /*	str *to_tag; */
 	str req_uri;
 	str from_contact;
-	unsigned int lifetime;	
+	struct str_list* pubruris_caller;
+	struct str_list* pubruris_callee;
+	unsigned int lifetime;
 };
 
+
 void free_dlginfo_cell(void *param);
+void free_str_list_all(struct str_list * del_current);
 
 #endif