... | ... |
@@ -433,7 +433,25 @@ modparam("pua_dialoginfo", "use_pubruri_avps", 1) |
433 | 433 |
</programlisting> |
434 | 434 |
</example> |
435 | 435 |
</section> |
436 |
- |
|
436 |
+ |
|
437 |
+ <section id="pua_dialoginfo.p.refresh_pubruri_avps_flag"> |
|
438 |
+ <title><varname>refresh_pubruri_avps_flag</varname> (int)</title> |
|
439 |
+ <para> |
|
440 |
+ If use_pubruri_avps is enabled, this message flag indicates whether to refresh R-Uri from avps before sending the PUBLISH requests. |
|
441 |
+ </para> |
|
442 |
+ <para> |
|
443 |
+ <emphasis>Default value is <quote>-1</quote>.</emphasis> |
|
444 |
+ </para> |
|
445 |
+ <example> |
|
446 |
+ <title>Set <varname>refresh_pubruri_avps_flag</varname> parameter</title> |
|
447 |
+ <programlisting format="linespecific"> |
|
448 |
+... |
|
449 |
+modparam("pua_dialoginfo", "refresh_pubruri_avps_flag", 11) |
|
450 |
+... |
|
451 |
+</programlisting> |
|
452 |
+ </example> |
|
453 |
+ </section> |
|
454 |
+ |
|
437 | 455 |
<section> |
438 | 456 |
<title><varname>pubruri_caller_avp</varname> (str)</title> |
439 | 457 |
<para> |
... | ... |
@@ -602,6 +620,25 @@ modparam("pua_dialoginfo", "publish_dialog_req_within", 0) |
602 | 620 |
</example> |
603 | 621 |
</section> |
604 | 622 |
|
623 |
+ <section id="pua_dialoginfo.p.local_identity_dlg_var"> |
|
624 |
+ <title><varname>local_identity_dlg_var</varname> (str)</title> |
|
625 |
+ <para> |
|
626 |
+ PUBLISH-requests reporting dialog-information will use the value of |
|
627 |
+ the dialog variable if exists |
|
628 |
+ </para> |
|
629 |
+ <para> |
|
630 |
+ <emphasis>Default value is <quote>NULL</quote>.</emphasis> |
|
631 |
+ </para> |
|
632 |
+ <example> |
|
633 |
+ <title>Set <varname>local_identity_dlg_var</varname> parameter</title> |
|
634 |
+ <programlisting format="linespecific"> |
|
635 |
+... |
|
636 |
+modparam("pua_dialoginfo", "local_identity_dlg_var", "local_identity") |
|
637 |
+... |
|
638 |
+</programlisting> |
|
639 |
+ </example> |
|
640 |
+ </section> |
|
641 |
+ |
|
605 | 642 |
<section id="pua_dialoginfo.p.attribute_display"> |
606 | 643 |
<title><varname>attribute_display</varname> (int)</title> |
607 | 644 |
<para> |
... | ... |
@@ -41,6 +41,7 @@ |
41 | 41 |
#include "../../core/str_list.h" |
42 | 42 |
#include "../../core/mem/mem.h" |
43 | 43 |
#include "../../core/pt.h" |
44 |
+#include "../../core/ut.h" |
|
44 | 45 |
#include "../../core/utils/sruid.h" |
45 | 46 |
#include "../dialog/dlg_load.h" |
46 | 47 |
#include "../dialog/dlg_hash.h" |
... | ... |
@@ -59,6 +60,7 @@ MODULE_VERSION |
59 | 60 |
#define DEF_OVERRIDE_LIFETIME 0 |
60 | 61 |
#define DEF_SEND_PUBLISH_FLAG -1 |
61 | 62 |
#define DEF_USE_PUBRURI_AVPS 0 |
63 |
+#define DEF_REFRESH_PUBRURI_AVPS_FLAG -1 |
|
62 | 64 |
#define DEF_PUBRURI_CALLER_AVP 0 |
63 | 65 |
#define DEF_PUBRURI_CALLEE_AVP 0 |
64 | 66 |
#define DEF_CALLEE_TRYING 0 |
... | ... |
@@ -85,6 +87,7 @@ static str caller_dlg_var = {0, 0}; /* pubruri_caller */ |
85 | 87 |
static str callee_dlg_var = {0, 0}; /* pubruri_callee */ |
86 | 88 |
static str caller_entity_when_publish_disabled = {0, 0}; /* pubruri_caller */ |
87 | 89 |
static str callee_entity_when_publish_disabled = {0, 0}; /* pubruri_callee */ |
90 |
+static str local_identity_dlg_var = STR_NULL; |
|
88 | 91 |
|
89 | 92 |
/* Module parameter variables */ |
90 | 93 |
int include_callid = DEF_INCLUDE_CALLID; |
... | ... |
@@ -95,6 +98,7 @@ int caller_confirmed = DEF_CALLER_ALWAYS_CONFIRMED; |
95 | 98 |
int include_req_uri = DEF_INCLUDE_REQ_URI; |
96 | 99 |
int send_publish_flag = DEF_SEND_PUBLISH_FLAG; |
97 | 100 |
int use_pubruri_avps = DEF_USE_PUBRURI_AVPS; |
101 |
+int refresh_pubruri_avps_flag = DEF_REFRESH_PUBRURI_AVPS_FLAG; |
|
98 | 102 |
int callee_trying = DEF_CALLEE_TRYING; |
99 | 103 |
int disable_caller_publish_flag = DEF_DISABLE_CALLER_PUBLISH_FLAG; |
100 | 104 |
int disable_callee_publish_flag = DEF_DISABLE_CALLEE_PUBLISH_FLAG; |
... | ... |
@@ -124,10 +128,12 @@ static param_export_t params[]={ |
124 | 128 |
{"include_req_uri", INT_PARAM, &include_req_uri }, |
125 | 129 |
{"send_publish_flag", INT_PARAM, &send_publish_flag }, |
126 | 130 |
{"use_pubruri_avps", INT_PARAM, &use_pubruri_avps }, |
131 |
+ {"refresh_pubruri_avps_flag", INT_PARAM, &refresh_pubruri_avps_flag }, |
|
127 | 132 |
{"pubruri_caller_avp", PARAM_STRING, &pubruri_caller_avp }, |
128 | 133 |
{"pubruri_callee_avp", PARAM_STRING, &pubruri_callee_avp }, |
129 | 134 |
{"pubruri_caller_dlg_var", PARAM_STR, &caller_dlg_var }, |
130 | 135 |
{"pubruri_callee_dlg_var", PARAM_STR, &callee_dlg_var }, |
136 |
+ {"local_identity_dlg_var", PARAM_STR, &local_identity_dlg_var }, |
|
131 | 137 |
{"callee_trying", INT_PARAM, &callee_trying }, |
132 | 138 |
{"disable_caller_publish_flag", INT_PARAM, &disable_caller_publish_flag }, |
133 | 139 |
{"disable_callee_publish_flag", INT_PARAM, &disable_callee_publish_flag }, |
... | ... |
@@ -256,6 +262,69 @@ __dialog_cbtest(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) |
256 | 262 |
} |
257 | 263 |
#endif |
258 | 264 |
|
265 |
+static struct str_list* get_str_list(unsigned short avp_flags, int_str avp_name); |
|
266 |
+static int is_ruri_in_list(struct str_list *list, str *ruri); |
|
267 |
+ |
|
268 |
+void refresh_pubruri_avps(struct dlginfo_cell *dlginfo, str *uri) |
|
269 |
+{ |
|
270 |
+ struct str_list *pubruris = get_str_list(pubruri_caller_avp_type, |
|
271 |
+ pubruri_caller_avp_name); |
|
272 |
+ struct str_list *list, *next; |
|
273 |
+ str target = STR_NULL; |
|
274 |
+ |
|
275 |
+ if(pubruris) { |
|
276 |
+ list = dlginfo->pubruris_caller; |
|
277 |
+ while(list) { |
|
278 |
+ if(is_ruri_in_list(pubruris, &list->s) == 0) { |
|
279 |
+ LM_DBG("ruri:'%.*s' removed from pubruris_caller list\n", |
|
280 |
+ list->s.len, list->s.s); |
|
281 |
+ next = list->next; list->next = NULL; |
|
282 |
+ dialog_publish_multi("terminated", list, |
|
283 |
+ &(dlginfo->from_uri), uri, &(dlginfo->callid), 1, |
|
284 |
+ 10, 0, 0, &(dlginfo->from_contact), |
|
285 |
+ &target, send_publish_flag==-1?1:0, &(dlginfo->uuid)); |
|
286 |
+ list->next = next; |
|
287 |
+ } |
|
288 |
+ list = list->next; |
|
289 |
+ } |
|
290 |
+ free_str_list_all(dlginfo->pubruris_caller); |
|
291 |
+ dlginfo->pubruris_caller = pubruris; |
|
292 |
+ LM_DBG("refreshed pubruris_caller info from avp\n"); |
|
293 |
+ } |
|
294 |
+ pubruris = get_str_list(pubruri_callee_avp_type, |
|
295 |
+ pubruri_callee_avp_name); |
|
296 |
+ if(pubruris) { |
|
297 |
+ list = dlginfo->pubruris_callee; |
|
298 |
+ while(list) { |
|
299 |
+ if(is_ruri_in_list(pubruris, &list->s) == 0) { |
|
300 |
+ LM_DBG("ruri:'%.*s' removed from pubruris_callee list\n", |
|
301 |
+ list->s.len, list->s.s); |
|
302 |
+ next = list->next; list->next = NULL; |
|
303 |
+ dialog_publish_multi("terminated", list, |
|
304 |
+ uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, |
|
305 |
+ 10, 0, 0, &target, &(dlginfo->from_contact), |
|
306 |
+ send_publish_flag==-1?1:0, &(dlginfo->uuid)); |
|
307 |
+ list->next = next; |
|
308 |
+ } |
|
309 |
+ list = list->next; |
|
310 |
+ } |
|
311 |
+ free_str_list_all(dlginfo->pubruris_callee); |
|
312 |
+ dlginfo->pubruris_callee = pubruris; |
|
313 |
+ LM_DBG("refreshed pubruris_callee info from avp\n"); |
|
314 |
+ } |
|
315 |
+} |
|
316 |
+ |
|
317 |
+void refresh_local_identity(struct dlg_cell *dlg, str *uri) { |
|
318 |
+ str *s = dlg_api.get_dlg_var(dlg, &local_identity_dlg_var); |
|
319 |
+ |
|
320 |
+ if(s != NULL) { |
|
321 |
+ uri->s = s->s; |
|
322 |
+ uri->len = s->len; |
|
323 |
+ LM_DBG("Found local_identity in dialog '%.*s'\n", |
|
324 |
+ uri->len, uri->s); |
|
325 |
+ } |
|
326 |
+} |
|
327 |
+ |
|
259 | 328 |
static void |
260 | 329 |
__dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) |
261 | 330 |
{ |
... | ... |
@@ -294,6 +363,17 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para |
294 | 363 |
uri=callee_entity_when_publish_disabled; |
295 | 364 |
} |
296 | 365 |
|
366 |
+ if(use_pubruri_avps && (refresh_pubruri_avps_flag > -1 |
|
367 |
+ || (request->flags & (1<<refresh_pubruri_avps_flag)))) |
|
368 |
+ { |
|
369 |
+ lock_get(&dlginfo->lock); |
|
370 |
+ refresh_pubruri_avps(dlginfo, &uri); |
|
371 |
+ } |
|
372 |
+ |
|
373 |
+ if(local_identity_dlg_var.len > 0) { |
|
374 |
+ refresh_local_identity(dlg, &uri); |
|
375 |
+ } |
|
376 |
+ |
|
297 | 377 |
switch (type) { |
298 | 378 |
case DLGCB_FAILED: |
299 | 379 |
case DLGCB_TERMINATED: |
... | ... |
@@ -434,6 +514,12 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para |
434 | 514 |
send_publish_flag==-1?1:0,&(dlginfo->uuid)); |
435 | 515 |
} |
436 | 516 |
} |
517 |
+ |
|
518 |
+ if(use_pubruri_avps && (refresh_pubruri_avps_flag > -1 |
|
519 |
+ || (request->flags & (1<<refresh_pubruri_avps_flag)))) |
|
520 |
+ { |
|
521 |
+ lock_release(&dlginfo->lock); |
|
522 |
+ } |
|
437 | 523 |
} |
438 | 524 |
|
439 | 525 |
/* |
... | ... |
@@ -515,6 +601,12 @@ struct dlginfo_cell* get_dialog_data(struct dlg_cell *dlg, int type, int disable |
515 | 601 |
} |
516 | 602 |
memset( dlginfo, 0, len); |
517 | 603 |
|
604 |
+ if(use_pubruri_avps && lock_init(&dlginfo->lock) == 0) { |
|
605 |
+ LM_ERR("cannot init the lock\n"); |
|
606 |
+ free_dlginfo_cell(dlginfo); |
|
607 |
+ return NULL; |
|
608 |
+ } |
|
609 |
+ |
|
518 | 610 |
/* copy from dlg structure to dlginfo structure */ |
519 | 611 |
dlginfo->lifetime = override_lifetime ? override_lifetime : dlg->lifetime; |
520 | 612 |
dlginfo->disable_caller_publish = disable_caller_publish; |
... | ... |
@@ -694,20 +786,24 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) |
694 | 786 |
|
695 | 787 |
if ((!disable_caller_publish) && (disable_caller_publish_flag == -1 || !(request |
696 | 788 |
&& (request->flags & (1<<disable_caller_publish_flag))))) { |
789 |
+ if(use_pubruri_avps) lock_get(&dlginfo->lock); |
|
697 | 790 |
dialog_publish_multi("Trying", dlginfo->pubruris_caller, |
698 | 791 |
&identity_local, |
699 | 792 |
&identity_remote, |
700 | 793 |
&(dlg->callid), 1, dlginfo->lifetime, |
701 | 794 |
0, 0, 0, 0, (send_publish_flag==-1)?1:0,&(dlginfo->uuid)); |
795 |
+ if(use_pubruri_avps) lock_release(&dlginfo->lock); |
|
702 | 796 |
} |
703 | 797 |
|
704 | 798 |
if (callee_trying && ((!disable_callee_publish) && (disable_callee_publish_flag == -1 || !(request |
705 | 799 |
&& (request->flags & (1<<disable_callee_publish_flag)))))) { |
800 |
+ if(use_pubruri_avps) lock_get(&dlginfo->lock); |
|
706 | 801 |
dialog_publish_multi("Trying", dlginfo->pubruris_callee, |
707 | 802 |
&identity_remote, |
708 | 803 |
&identity_local, |
709 | 804 |
&(dlg->callid), 0, dlginfo->lifetime, |
710 | 805 |
0, 0, 0, 0, (send_publish_flag==-1)?1:0,&(dlginfo->uuid)); |
806 |
+ if(use_pubruri_avps) lock_release(&dlginfo->lock); |
|
711 | 807 |
} |
712 | 808 |
} |
713 | 809 |
|
... | ... |
@@ -877,13 +973,24 @@ void free_dlginfo_cell(void *param) { |
877 | 973 |
free_str_list_all(cell->pubruris_caller); |
878 | 974 |
free_str_list_all(cell->pubruris_callee); |
879 | 975 |
|
880 |
- /*if (cell->to_tag) { |
|
881 |
- shm_free(cell->to_tag); |
|
882 |
- }*/ |
|
976 |
+ if(use_pubruri_avps) lock_destroy(cell->lock); |
|
883 | 977 |
shm_free(param); |
884 | 978 |
} |
885 | 979 |
|
886 | 980 |
|
981 |
+int is_ruri_in_list(struct str_list *list, str *ruri) { |
|
982 |
+ struct str_list *pubruris = list; |
|
983 |
+ LM_DBG("search:'%.*s'\n", ruri->len, ruri->s); |
|
984 |
+ while(pubruris) { |
|
985 |
+ LM_DBG("compare with:'%.*s'\n", pubruris->s.len, pubruris->s.s); |
|
986 |
+ if(str_strcmp(&pubruris->s, ruri) == 0) { |
|
987 |
+ return 1; |
|
988 |
+ } |
|
989 |
+ pubruris = pubruris->next; |
|
990 |
+ } |
|
991 |
+ return 0; |
|
992 |
+} |
|
993 |
+ |
|
887 | 994 |
void free_str_list_all(struct str_list * del_current) { |
888 | 995 |
|
889 | 996 |
struct str_list* del_next; |
... | ... |
@@ -23,6 +23,7 @@ |
23 | 23 |
|
24 | 24 |
#ifndef _PUA_DLGINFO_H |
25 | 25 |
#define _PUA_DLGINFO_H |
26 |
+#include "../../core/locking.h" |
|
26 | 27 |
#include "../pua/pua_bind.h" |
27 | 28 |
|
28 | 29 |
extern send_publish_t pua_send_publish; |
... | ... |
@@ -35,6 +36,7 @@ void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str |
35 | 36 |
* dlg_cell during the callback (as this could create a race condition |
36 | 37 |
* if the dlg_cell gets meanwhile deleted) */ |
37 | 38 |
struct dlginfo_cell { |
39 |
+ gen_lock_t lock; |
|
38 | 40 |
str from_uri; |
39 | 41 |
str to_uri; |
40 | 42 |
str callid; |