Pārlūkot izejas kodu

pua_dialoginfo: allow setting PUBLISH R-URIs via AVPs

- patch by Jasmin Schnatterbeck, FS#197
Daniel-Constantin Mierla 13 gadi atpakaļ
vecāks
revīzija
785ff3ebc2

+ 80 - 7
modules_k/pua_dialoginfo/README

@@ -19,9 +19,9 @@ Klaus Darilion
 
 
    IPCom
    IPCom
 
 
-   Copyright © 2006 Voice Sistem SRL
+   Copyright © 2006 Voice Sistem SRL
 
 
-   Copyright © 2008 Klaus Darilion IPCom
+   Copyright © 2008 Klaus Darilion IPCom
      __________________________________________________________________
      __________________________________________________________________
 
 
    Table of Contents
    Table of Contents
@@ -43,6 +43,10 @@ Klaus Darilion
               5.3. include_localremote (int)
               5.3. include_localremote (int)
               5.4. override_lifetime (int)
               5.4. override_lifetime (int)
               5.5. caller_confirmed (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
         6. Functions
 
 
@@ -53,6 +57,10 @@ Klaus Darilion
    1.3. Set include_localremote parameter
    1.3. Set include_localremote parameter
    1.4. Set override_lifetime parameter
    1.4. Set override_lifetime parameter
    1.5. Set caller_confirmed 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
 Chapter 1. Admin Guide
 
 
@@ -73,6 +81,10 @@ Chapter 1. Admin Guide
         5.3. include_localremote (int)
         5.3. include_localremote (int)
         5.4. override_lifetime (int)
         5.4. override_lifetime (int)
         5.5. caller_confirmed (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
    6. Functions
 
 
@@ -246,13 +258,17 @@ Chapter 1. Admin Guide
    5.3. include_localremote (int)
    5.3. include_localremote (int)
    5.4. override_lifetime (int)
    5.4. override_lifetime (int)
    5.5. caller_confirmed (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)
 5.1. include_callid (int)
 
 
    If this parameter is set, the optional call-id will be put into the
    If this parameter is set, the optional call-id will be put into the
    dialog element. This is needed for call-pickup features.
    dialog element. This is needed for call-pickup features.
 
 
-   Default value is “1�.
+   Default value is "1".
 
 
    Example 1.1. Set include_callid parameter
    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
    If this parameter is set, the local and remote tag will be put into the
    dialog element. This is needed for call-pickup features.
    dialog element. This is needed for call-pickup features.
 
 
-   Default value is “1�.
+   Default value is "1".
 
 
    Example 1.2. Set include_tags parameter
    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
    be put into the dialog element. This is needed for call-pickup
    features.
    features.
 
 
-   Default value is “1�.
+   Default value is "1".
 
 
    Example 1.3. Set include_localremote parameter
    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
    dialog module. If used, the value should at least be a few seconds more
    than the fr_inv_timer of the tm module.
    than the fr_inv_timer of the tm module.
 
 
-   Default value is “0�.
+   Default value is "0".
 
 
    Example 1.4. Set override_lifetime parameter
    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
    the buggy Linksys SPA962 phones. SNOM phones work well with the default
    setting.
    setting.
 
 
-   Default value is “0�.
+   Default value is "0".
 
 
    Example 1.5. Set caller_confirmed parameter
    Example 1.5. Set caller_confirmed parameter
 ...
 ...
 modparam("pua_dialoginfo", "caller_confirmed", 1)
 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
 6. Functions

+ 36 - 15
modules_k/pua_dialoginfo/dialog_publish.c

@@ -31,6 +31,7 @@
 #include "../../parser/parse_expires.h"
 #include "../../parser/parse_expires.h"
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
 #include "../../str.h"
 #include "../../str.h"
+#include "../../str_list.h"
 #include "../../name_alias.h"
 #include "../../name_alias.h"
 #include "../../socket_info.h"
 #include "../../socket_info.h"
 #include "../usrloc/usrloc.h"
 #include "../usrloc/usrloc.h"
@@ -259,27 +260,33 @@ error:
 	return NULL;
 	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,
 	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* body= NULL;
 	str uri= {NULL, 0};
 	str uri= {NULL, 0};
 	publ_info_t* publ= NULL;
 	publ_info_t* publ= NULL;
 	int size= 0;
 	int size= 0;
 	str content_type;
 	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;
 		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.s= "application/dialog-info+xml";
 	content_type.len= 27;
 	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)
 	if(body == NULL || body->s == NULL)
 		goto error;
 		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) 
 	size= sizeof(publ_info_t) 
 			+ sizeof(str) 			/* *pres_uri */
 			+ sizeof(str) 			/* *pres_uri */
-			+ ( entity->len 		/* pres_uri->s */
+			+ ( ruri->len 		/* pres_uri->s */
 			  + callid->len + 16	/* id.s */
 			  + callid->len + 16	/* id.s */
 			  + content_type.len	/* content_type.s */
 			  + content_type.len	/* content_type.s */
 			)*sizeof(char); 
 			)*sizeof(char); 
@@ -311,9 +318,9 @@ void dialog_publish(char *state, str *entity, str *peer, str *callid,
 	publ->pres_uri= (str*)((char*)publ + size);
 	publ->pres_uri= (str*)((char*)publ + size);
 	size+= sizeof(str);
 	size+= sizeof(str);
 	publ->pres_uri->s= (char*)publ+ size;
 	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)
 	if(body)
 	{
 	{
@@ -368,3 +375,17 @@ error:
 
 
 	return;
 	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>
 </programlisting>
 		</example>
 		</example>
 		</section>
 		</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>
 
 
 	<section>
 	<section>

+ 177 - 17
modules_k/pua_dialoginfo/pua_dialoginfo.c

@@ -43,6 +43,7 @@
 #include "../../parser/parse_to.h"
 #include "../../parser/parse_to.h"
 #include "../../parser/contact/parse_contact.h"
 #include "../../parser/contact/parse_contact.h"
 #include "../../str.h"
 #include "../../str.h"
+#include "../../str_list.h"
 #include "../../mem/mem.h"
 #include "../../mem/mem.h"
 #include "../../pt.h"
 #include "../../pt.h"
 #include "../dialog/dlg_load.h"
 #include "../dialog/dlg_load.h"
@@ -59,6 +60,12 @@ MODULE_VERSION
 #define DEF_OVERRIDE_LIFETIME 0
 #define DEF_OVERRIDE_LIFETIME 0
 #define DEF_CALLER_ALWAYS_CONFIRMED 0
 #define DEF_CALLER_ALWAYS_CONFIRMED 0
 #define DEF_INCLUDE_REQ_URI 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 
 /* define PUA_DIALOGINFO_DEBUG to activate more verbose 
  * logging and dialog info callback debugging
  * logging and dialog info callback debugging
@@ -69,6 +76,11 @@ pua_api_t pua;
 
 
 struct dlg_binds dlg_api;
 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 */
 /* Module parameter variables */
 int include_callid      = DEF_INCLUDE_CALLID;
 int include_callid      = DEF_INCLUDE_CALLID;
 int include_localremote = DEF_INCLUDE_LOCALREMOTE;
 int include_localremote = DEF_INCLUDE_LOCALREMOTE;
@@ -76,6 +88,10 @@ int include_tags        = DEF_INCLUDE_TAGS;
 int override_lifetime   = DEF_OVERRIDE_LIFETIME;
 int override_lifetime   = DEF_OVERRIDE_LIFETIME;
 int caller_confirmed    = DEF_CALLER_ALWAYS_CONFIRMED;
 int caller_confirmed    = DEF_CALLER_ALWAYS_CONFIRMED;
 int include_req_uri     = DEF_INCLUDE_REQ_URI;
 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;
 send_publish_t pua_send_publish;
@@ -96,6 +112,10 @@ static param_export_t params[]={
 	{"override_lifetime",   INT_PARAM, &override_lifetime },
 	{"override_lifetime",   INT_PARAM, &override_lifetime },
 	{"caller_confirmed",    INT_PARAM, &caller_confirmed },
 	{"caller_confirmed",    INT_PARAM, &caller_confirmed },
 	{"include_req_uri",     INT_PARAM, &include_req_uri },
 	{"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 }
 	{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 uri = {0,0};
 	str target = {0,0};
 	str target = {0,0};
 
 
+
 	struct dlginfo_cell *dlginfo = (struct dlginfo_cell*)*_params->param;
 	struct dlginfo_cell *dlginfo = (struct dlginfo_cell*)*_params->param;
 
 
-	if (include_req_uri) {
+	if(include_req_uri) {
 		uri = dlginfo->req_uri;
 		uri = dlginfo->req_uri;
 	} else {
 	} else {
 		uri = dlginfo->to_uri;
 		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_TERMINATED:
 	case DLGCB_EXPIRED:
 	case DLGCB_EXPIRED:
 		LM_DBG("dialog over, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
 		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;
 		break;
 	case DLGCB_CONFIRMED:
 	case DLGCB_CONFIRMED:
 	case DLGCB_REQ_WITHIN:
 	case DLGCB_REQ_WITHIN:
 	case DLGCB_CONFIRMED_NA:
 	case DLGCB_CONFIRMED_NA:
 		LM_DBG("dialog confirmed, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
 		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;
 		break;
 	case DLGCB_EARLY:
 	case DLGCB_EARLY:
 		LM_DBG("dialog is early, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
 		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) {
 			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 {
 			} 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 {
 		} else {
 			if (caller_confirmed) {
 			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 {
 			} 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;
 		break;
 	default:
 	default:
 		LM_ERR("unhandled dialog callback type %d received, from=%.*s\n", type, dlginfo->from_uri.len, dlginfo->from_uri.s);
 		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
 static void
 __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 __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)
 	if (request->REQ_METHOD != METHOD_INVITE)
 		return;
 		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);
 	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*/
 	/* 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->req_uri.len  = dlg->req_uri.len;
 	dlginfo->from_contact.s   = dlginfo->req_uri.s + dlginfo->req_uri.len;
 	dlginfo->from_contact.s   = dlginfo->req_uri.s + dlginfo->req_uri.len;
 	dlginfo->from_contact.len = dlg->contact[0].len;
 	dlginfo->from_contact.len = dlg->contact[0].len;
+
 	memcpy(dlginfo->from_uri.s, dlg->from_uri.s, dlg->from_uri.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->to_uri.s, dlg->to_uri.s, dlg->to_uri.len);
 	memcpy(dlginfo->callid.s, dlg->callid.s, dlg->callid.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->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->req_uri.s, dlg->req_uri.s, dlg->req_uri.len);
 	memcpy(dlginfo->from_contact.s, dlg->contact[0].s, dlg->contact[0].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 */
 	/* register dialog callbacks which triggers sending PUBLISH */
 	if (dlg_api.register_dlgcb(dlg, 
 	if (dlg_api.register_dlgcb(dlg, 
 		DLGCB_FAILED| DLGCB_CONFIRMED_NA | DLGCB_TERMINATED | DLGCB_EXPIRED |
 		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
 #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)
 static int mod_init(void)
 {
 {
 	bind_pua_t bind_pua;
 	bind_pua_t bind_pua;
+
+	str s;
+	pv_spec_t avp_spec;
 	
 	
 	bind_pua= (bind_pua_t)find_export("bind_pua", 1,0);
 	bind_pua= (bind_pua_t)find_export("bind_pua", 1,0);
 	if (!bind_pua)
 	if (!bind_pua)
@@ -402,13 +513,62 @@ static int mod_init(void)
 		return -1;
 		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;
 	return 0;
 }
 }
 
 
 void free_dlginfo_cell(void *param) {
 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(cell->to_tag);
 	}*/
 	}*/
 	shm_free(param);
 	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;
 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,
 	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 
 /* store the important data locally to avoid reading the data from the 
    dlg_cell during the callback (as this could create a race condition 
    dlg_cell during the callback (as this could create a race condition 
@@ -44,9 +44,13 @@ struct dlginfo_cell {
 /*	str *to_tag; */
 /*	str *to_tag; */
 	str req_uri;
 	str req_uri;
 	str from_contact;
 	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_dlginfo_cell(void *param);
+void free_str_list_all(struct str_list * del_current);
 
 
 #endif
 #endif