2
0
Эх сурвалжийг харах

presence_xml: adds option to aggregate xml body with priorities

lazedo 5 жил өмнө
parent
commit
9d32561b15

+ 62 - 1
src/modules/presence_xml/doc/presence_xml_admin.xml

@@ -333,7 +333,68 @@ modparam("presence_xml", "force_dummy_presence", 1)
 </programlisting>
         </example>
     </section>
-</section>
+    <section id="presence_xml.p.force_presence_single_body">
+        <title><varname>force_presence_single_body</varname>(int)</title>
+        <para>
+        Set this parameter to enable single body notify.
+        One presentity can have multiple dialogs and will by default notify all the dialogs and this can be a problem
+        when dealing with large ring-groups or attendants, use this parameter to only send one body.
+        Look at <varname>presence_single_body_priorities</varname> and <varname>presence_single_body_lookup_element</varname> to customize the behaviour.
+        </para>
+        <para>
+        <emphasis>Default value: <quote>0</quote>.
+        </emphasis>
+        </para>
+        <example>
+        <title>Set <varname>force_presence_single_body</varname> parameter</title>
+        <programlisting format="linespecific">
+...
+modparam("presence_xml", "force_presence_single_body", 1)
+...
+</programlisting>
+        </example>
+    </section>
+    <section id="presence_xml.p.presence_single_body_priorities">
+        <title><varname>presence_single_body_priorities</varname>(str)</title>
+        <para>
+        Change this parameter to set the priorities when choosing the dialog that will be the final.
+        </para>
+        <para>
+        Importance is left to right.
+        </para>
+        <para>
+        <emphasis>Default value: <quote>Available|Ringing|On the Phone</quote>.
+        </emphasis>
+        </para>
+        <example>
+        <title>Set <varname>presence_single_body_priorities</varname> parameter</title>
+        <programlisting format="linespecific">
+...
+modparam("presence_xml", "presence_single_body_priorities", "Offline|Online|Busy|Really Busy")
+...
+</programlisting>
+        </example>
+    </section>
+    <section id="presence_xml.p.presence_single_body_lookup_element">
+        <title><varname>presence_single_body_lookup_element</varname>(str)</title>
+        <para>
+        Set the name of the element that should be used to get the priority.
+        If the value obtained is not in the list of <varname>presence_single_body_priorities</varname> the priority is 0.
+        </para>
+        <para>
+        <emphasis>Default value: <quote>note</quote>.
+        </emphasis>
+        </para>
+        <example>
+        <title>Set <varname>presence_single_body_lookup_element</varname> parameter</title>
+        <programlisting format="linespecific">
+...
+modparam("presence_xml", "presence_single_body_lookup_element", "status")
+...
+</programlisting>
+        </example>
+    </section>
+	</section>
 
 
 <section>

+ 111 - 1
src/modules/presence_xml/notify_body.c

@@ -39,9 +39,13 @@
 #include "presence_xml.h"
 
 extern int force_dummy_presence;
+extern int presence_force_single_body;
+extern str presence_single_body_priorities;
+extern str presence_single_body_lookup_element;
 
 str *offline_nbody(str *body);
 str *agregate_xmls(str *pres_user, str *pres_domain, str **body_array, int n);
+str *agregate_xmls_priority(str *pres_user, str *pres_domain, str **body_array, int n);
 str *get_final_notify_body(
 		subs_t *subs, str *notify_body, xmlNodePtr rule_node);
 
@@ -148,7 +152,11 @@ str *pres_agg_nbody(str *pres_user, str *pres_domain, str **body_array, int n,
 	}
 	LM_DBG("[user]=%.*s  [domain]= %.*s\n", pres_user->len, pres_user->s,
 			pres_domain->len, pres_domain->s);
-	n_body = agregate_xmls(pres_user, pres_domain, body_array, n);
+	if(presence_force_single_body == 0) {
+		n_body = agregate_xmls(pres_user, pres_domain, body_array, n);
+	} else {
+		n_body = agregate_xmls_priority(pres_user, pres_domain, body_array, n);
+	}
 	if(n_body == NULL && n != 0) {
 		LM_ERR("while aggregating body\n");
 	}
@@ -632,6 +640,108 @@ error:
 	return NULL;
 }
 
+str *agregate_xmls_priority(str *pres_user, str *pres_domain, str **body_array, int n)
+{
+	int i, j = 0, idx = 0;
+	xmlNodePtr p_root = NULL, new_p_root = NULL;
+	xmlDocPtr *xml_array;
+	str *body = NULL;
+	char *cur = NULL, *cmp = NULL, *priority = NULL;
+
+	xml_array = (xmlDocPtr *)pkg_malloc((n + 2) * sizeof(xmlDocPtr));
+	if(xml_array == NULL) {
+
+		LM_ERR("while allocating memory");
+		return NULL;
+	}
+	memset(xml_array, 0, (n + 2) * sizeof(xmlDocPtr));
+
+	for(i = 0; i < n; i++) {
+		if(body_array[i] == NULL)
+			continue;
+
+		xml_array[j] = NULL;
+		xml_array[j] = xmlParseMemory(body_array[i]->s, body_array[i]->len);
+
+		if(xml_array[j] == NULL) {
+			LM_ERR("while parsing xml body message\n");
+			goto error;
+		}
+		j++;
+	}
+
+	if(j == 0) /* no body */
+	{
+		if(xml_array)
+			pkg_free(xml_array);
+		return NULL;
+	}
+
+	idx = --j;
+	if(strlen(presence_single_body_priorities.s) > 0 && strlen(presence_single_body_lookup_element.s) > 0) {
+		p_root = xmlDocGetNodeByName(xml_array[j], "presence", NULL);
+		if(p_root == NULL) {
+			LM_ERR("while getting the xml_tree root\n");
+			goto error;
+		}
+		cur = xmlNodeGetNodeContentByName(p_root, presence_single_body_lookup_element.s, NULL);
+		if(cur) {
+			priority = strstr(presence_single_body_priorities.s, cur);
+		}
+
+		for(i = j - 1; i >= 0; i--) {
+			new_p_root = xmlDocGetNodeByName(xml_array[i], "presence", NULL);
+			if(new_p_root == NULL) {
+				LM_ERR("while getting the xml_tree root\n");
+				goto error;
+			}
+
+			cmp = xmlNodeGetNodeContentByName(new_p_root, presence_single_body_lookup_element.s, NULL);
+			if(cur != NULL && cmp != NULL && strcasecmp(cur,cmp)) {
+				char *x1 = strstr(presence_single_body_priorities.s, cmp);
+				if(x1 > priority) {
+					idx = i;
+					cur = cmp;
+					priority = x1;
+				}
+			}
+		}
+	}
+
+	body = (str *)pkg_malloc(sizeof(str));
+	if(body == NULL) {
+		ERR_MEM(PKG_MEM_STR);
+	}
+
+	xmlDocDumpFormatMemory(
+			xml_array[idx], (xmlChar **)(void *)&body->s, &body->len, 1);
+
+	for(i = 0; i <= j; i++) {
+		if(xml_array[i] != NULL)
+			xmlFreeDoc(xml_array[i]);
+	}
+	if(xml_array != NULL)
+		pkg_free(xml_array);
+
+	xmlCleanupParser();
+	xmlMemoryDump();
+
+	return body;
+
+error:
+	if(xml_array != NULL) {
+		for(i = 0; i <= j; i++) {
+			if(xml_array[i] != NULL)
+				xmlFreeDoc(xml_array[i]);
+		}
+		pkg_free(xml_array);
+	}
+	if(body)
+		pkg_free(body);
+
+	return NULL;
+}
+
 str *offline_nbody(str *body)
 {
 	xmlDocPtr doc = NULL;

+ 7 - 0
src/modules/presence_xml/presence_xml.c

@@ -98,6 +98,10 @@ int passive_mode = 0;
 int disable_xcapdiff = 0;
 str xcapauth_userdel_reason = str_init("probation");
 
+int presence_force_single_body = 0;
+str presence_single_body_priorities = str_init("Available|Ringing|On the Phone");
+str presence_single_body_lookup_element = str_init("note");
+
 /** SL API structure */
 sl_api_t slb;
 
@@ -135,6 +139,9 @@ static param_export_t params[]={
 	{ "passive_mode",		INT_PARAM, &passive_mode },
 	{ "xcapauth_userdel_reason", PARAM_STR, &xcapauth_userdel_reason},
 	{ "force_dummy_presence",       INT_PARAM, &force_dummy_presence },
+	{ "force_presence_single_body", INT_PARAM, &presence_force_single_body },
+	{ "presence_single_body_priorities",  PARAM_STR, &presence_single_body_priorities },
+	{ "presence_single_body_lookup_element", PARAM_STR, &presence_single_body_lookup_element },
 	{ 0, 0, 0}
 };
 /* clang-format on */