Browse code

presence_xml: adds option to aggregate xml body with priorities

lazedo authored on 31/10/2019 18:44:18
Showing 3 changed files
... ...
@@ -333,7 +333,68 @@ modparam("presence_xml", "force_dummy_presence", 1)
333 333
 </programlisting>
334 334
         </example>
335 335
     </section>
336
-</section>
336
+    <section id="presence_xml.p.force_presence_single_body">
337
+        <title><varname>force_presence_single_body</varname>(int)</title>
338
+        <para>
339
+        Set this parameter to enable single body notify.
340
+        One presentity can have multiple dialogs and will by default notify all the dialogs and this can be a problem
341
+        when dealing with large ring-groups or attendants, use this parameter to only send one body.
342
+        Look at <varname>presence_single_body_priorities</varname> and <varname>presence_single_body_lookup_element</varname> to customize the behaviour.
343
+        </para>
344
+        <para>
345
+        <emphasis>Default value: <quote>0</quote>.
346
+        </emphasis>
347
+        </para>
348
+        <example>
349
+        <title>Set <varname>force_presence_single_body</varname> parameter</title>
350
+        <programlisting format="linespecific">
351
+...
352
+modparam("presence_xml", "force_presence_single_body", 1)
353
+...
354
+</programlisting>
355
+        </example>
356
+    </section>
357
+    <section id="presence_xml.p.presence_single_body_priorities">
358
+        <title><varname>presence_single_body_priorities</varname>(str)</title>
359
+        <para>
360
+        Change this parameter to set the priorities when choosing the dialog that will be the final.
361
+        </para>
362
+        <para>
363
+        Importance is left to right.
364
+        </para>
365
+        <para>
366
+        <emphasis>Default value: <quote>Available|Ringing|On the Phone</quote>.
367
+        </emphasis>
368
+        </para>
369
+        <example>
370
+        <title>Set <varname>presence_single_body_priorities</varname> parameter</title>
371
+        <programlisting format="linespecific">
372
+...
373
+modparam("presence_xml", "presence_single_body_priorities", "Offline|Online|Busy|Really Busy")
374
+...
375
+</programlisting>
376
+        </example>
377
+    </section>
378
+    <section id="presence_xml.p.presence_single_body_lookup_element">
379
+        <title><varname>presence_single_body_lookup_element</varname>(str)</title>
380
+        <para>
381
+        Set the name of the element that should be used to get the priority.
382
+        If the value obtained is not in the list of <varname>presence_single_body_priorities</varname> the priority is 0.
383
+        </para>
384
+        <para>
385
+        <emphasis>Default value: <quote>note</quote>.
386
+        </emphasis>
387
+        </para>
388
+        <example>
389
+        <title>Set <varname>presence_single_body_lookup_element</varname> parameter</title>
390
+        <programlisting format="linespecific">
391
+...
392
+modparam("presence_xml", "presence_single_body_lookup_element", "status")
393
+...
394
+</programlisting>
395
+        </example>
396
+    </section>
397
+	</section>
337 398
 
338 399
 
339 400
 <section>
... ...
@@ -39,9 +39,13 @@
39 39
 #include "presence_xml.h"
40 40
 
41 41
 extern int force_dummy_presence;
42
+extern int presence_force_single_body;
43
+extern str presence_single_body_priorities;
44
+extern str presence_single_body_lookup_element;
42 45
 
43 46
 str *offline_nbody(str *body);
44 47
 str *agregate_xmls(str *pres_user, str *pres_domain, str **body_array, int n);
48
+str *agregate_xmls_priority(str *pres_user, str *pres_domain, str **body_array, int n);
45 49
 str *get_final_notify_body(
46 50
 		subs_t *subs, str *notify_body, xmlNodePtr rule_node);
47 51
 
... ...
@@ -148,7 +152,11 @@ str *pres_agg_nbody(str *pres_user, str *pres_domain, str **body_array, int n,
148 148
 	}
149 149
 	LM_DBG("[user]=%.*s  [domain]= %.*s\n", pres_user->len, pres_user->s,
150 150
 			pres_domain->len, pres_domain->s);
151
-	n_body = agregate_xmls(pres_user, pres_domain, body_array, n);
151
+	if(presence_force_single_body == 0) {
152
+		n_body = agregate_xmls(pres_user, pres_domain, body_array, n);
153
+	} else {
154
+		n_body = agregate_xmls_priority(pres_user, pres_domain, body_array, n);
155
+	}
152 156
 	if(n_body == NULL && n != 0) {
153 157
 		LM_ERR("while aggregating body\n");
154 158
 	}
... ...
@@ -632,6 +640,108 @@ error:
632 632
 	return NULL;
633 633
 }
634 634
 
635
+str *agregate_xmls_priority(str *pres_user, str *pres_domain, str **body_array, int n)
636
+{
637
+	int i, j = 0, idx = 0;
638
+	xmlNodePtr p_root = NULL, new_p_root = NULL;
639
+	xmlDocPtr *xml_array;
640
+	str *body = NULL;
641
+	char *cur = NULL, *cmp = NULL, *priority = NULL;
642
+
643
+	xml_array = (xmlDocPtr *)pkg_malloc((n + 2) * sizeof(xmlDocPtr));
644
+	if(xml_array == NULL) {
645
+
646
+		LM_ERR("while allocating memory");
647
+		return NULL;
648
+	}
649
+	memset(xml_array, 0, (n + 2) * sizeof(xmlDocPtr));
650
+
651
+	for(i = 0; i < n; i++) {
652
+		if(body_array[i] == NULL)
653
+			continue;
654
+
655
+		xml_array[j] = NULL;
656
+		xml_array[j] = xmlParseMemory(body_array[i]->s, body_array[i]->len);
657
+
658
+		if(xml_array[j] == NULL) {
659
+			LM_ERR("while parsing xml body message\n");
660
+			goto error;
661
+		}
662
+		j++;
663
+	}
664
+
665
+	if(j == 0) /* no body */
666
+	{
667
+		if(xml_array)
668
+			pkg_free(xml_array);
669
+		return NULL;
670
+	}
671
+
672
+	idx = --j;
673
+	if(strlen(presence_single_body_priorities.s) > 0 && strlen(presence_single_body_lookup_element.s) > 0) {
674
+		p_root = xmlDocGetNodeByName(xml_array[j], "presence", NULL);
675
+		if(p_root == NULL) {
676
+			LM_ERR("while getting the xml_tree root\n");
677
+			goto error;
678
+		}
679
+		cur = xmlNodeGetNodeContentByName(p_root, presence_single_body_lookup_element.s, NULL);
680
+		if(cur) {
681
+			priority = strstr(presence_single_body_priorities.s, cur);
682
+		}
683
+
684
+		for(i = j - 1; i >= 0; i--) {
685
+			new_p_root = xmlDocGetNodeByName(xml_array[i], "presence", NULL);
686
+			if(new_p_root == NULL) {
687
+				LM_ERR("while getting the xml_tree root\n");
688
+				goto error;
689
+			}
690
+
691
+			cmp = xmlNodeGetNodeContentByName(new_p_root, presence_single_body_lookup_element.s, NULL);
692
+			if(cur != NULL && cmp != NULL && strcasecmp(cur,cmp)) {
693
+				char *x1 = strstr(presence_single_body_priorities.s, cmp);
694
+				if(x1 > priority) {
695
+					idx = i;
696
+					cur = cmp;
697
+					priority = x1;
698
+				}
699
+			}
700
+		}
701
+	}
702
+
703
+	body = (str *)pkg_malloc(sizeof(str));
704
+	if(body == NULL) {
705
+		ERR_MEM(PKG_MEM_STR);
706
+	}
707
+
708
+	xmlDocDumpFormatMemory(
709
+			xml_array[idx], (xmlChar **)(void *)&body->s, &body->len, 1);
710
+
711
+	for(i = 0; i <= j; i++) {
712
+		if(xml_array[i] != NULL)
713
+			xmlFreeDoc(xml_array[i]);
714
+	}
715
+	if(xml_array != NULL)
716
+		pkg_free(xml_array);
717
+
718
+	xmlCleanupParser();
719
+	xmlMemoryDump();
720
+
721
+	return body;
722
+
723
+error:
724
+	if(xml_array != NULL) {
725
+		for(i = 0; i <= j; i++) {
726
+			if(xml_array[i] != NULL)
727
+				xmlFreeDoc(xml_array[i]);
728
+		}
729
+		pkg_free(xml_array);
730
+	}
731
+	if(body)
732
+		pkg_free(body);
733
+
734
+	return NULL;
735
+}
736
+
635 737
 str *offline_nbody(str *body)
636 738
 {
637 739
 	xmlDocPtr doc = NULL;
... ...
@@ -98,6 +98,10 @@ int passive_mode = 0;
98 98
 int disable_xcapdiff = 0;
99 99
 str xcapauth_userdel_reason = str_init("probation");
100 100
 
101
+int presence_force_single_body = 0;
102
+str presence_single_body_priorities = str_init("Available|Ringing|On the Phone");
103
+str presence_single_body_lookup_element = str_init("note");
104
+
101 105
 /** SL API structure */
102 106
 sl_api_t slb;
103 107
 
... ...
@@ -135,6 +139,9 @@ static param_export_t params[]={
135 135
 	{ "passive_mode",		INT_PARAM, &passive_mode },
136 136
 	{ "xcapauth_userdel_reason", PARAM_STR, &xcapauth_userdel_reason},
137 137
 	{ "force_dummy_presence",       INT_PARAM, &force_dummy_presence },
138
+	{ "force_presence_single_body", INT_PARAM, &presence_force_single_body },
139
+	{ "presence_single_body_priorities",  PARAM_STR, &presence_single_body_priorities },
140
+	{ "presence_single_body_lookup_element", PARAM_STR, &presence_single_body_lookup_element },
138 141
 	{ 0, 0, 0}
139 142
 };
140 143
 /* clang-format on */