Browse code

- extend presence API: add per-watcher callback function to modify the NOTIFY body separate for each watcher. Can either manipulate the original body buffer (return NULL) or create a new body (return pointer to new body, freed by the aux_free_body function) - idea together with Anca

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@4914 689a6050-402a-0410-94f2-e92a70836424

Klaus Darilion authored on 15/09/2008 14:58:35
Showing 5 changed files
... ...
@@ -1,3 +1,4 @@
1
+
1 2
 Presence Module
2 3
 
3 4
 Anca-Maria Vamanu
... ...
@@ -10,9 +11,9 @@ Anca-Maria Vamanu
10 11
 
11 12
    Copyright � 2006 voice-system.ro
12 13
    Revision History
13
-   Revision $Revision$ $Date: 2008-08-06 13:08:33 +0300
14
-                              (Wed, 06 Aug 2008) $
15
-     __________________________________________________________
14
+   Revision $Revision$ $Date: 2008-08-06 12:08:33 +0200
15
+   (Wed, 06 Aug 2008) $
16
+     _________________________________________________________
16 17
 
17 18
    Table of Contents
18 19
 
... ...
@@ -42,30 +43,32 @@ Anca-Maria Vamanu
42 43
 
43 44
         1.4. Exported Functions
44 45
 
45
-              1.4.1. handle_publish(char* sender_uri)
46
-              1.4.2. handle_subscribe()
46
+              1.4.1. handle_publish(char* sender_uri) 
47
+              1.4.2. handle_subscribe() 
47 48
 
48 49
         1.5. Exported MI Functions
49 50
 
50
-              1.5.1. refreshWatchers
51
+              1.5.1. refreshWatchers 
51 52
 
52 53
         1.6. Installation
53 54
 
54 55
    2. Developer Guide
55 56
 
56
-        2.1. bind_presence(presence_api_t* api)
57
-        2.2. add_event
58
-        2.3. get_rules_doc
59
-        2.4. get_auth_status
60
-        2.5. apply_auth_nbody
61
-        2.6. agg_nbody
62
-        2.7. free_body
63
-        2.8. evs_publ_handl
64
-        2.9. evs_subs_handl
65
-        2.10. contains_event
66
-        2.11. get_event_list
67
-        2.12. update_watchers_status
68
-        2.13. get_sphere
57
+        2.1. bind_presence(presence_api_t* api) 
58
+        2.2. add_event 
59
+        2.3. get_rules_doc 
60
+        2.4. get_auth_status 
61
+        2.5. apply_auth_nbody 
62
+        2.6. agg_nbody 
63
+        2.7. free_body 
64
+        2.8. aux_body_processing 
65
+        2.9. aux_free_body 
66
+        2.10. evs_publ_handl 
67
+        2.11. evs_subs_handl 
68
+        2.12. contains_event 
69
+        2.13. get_event_list 
70
+        2.14. update_watchers_status 
71
+        2.15. get_sphere 
69 72
 
70 73
    List of Examples
71 74
 
... ...
@@ -98,18 +101,19 @@ Chapter 1. Admin Guide
98 101
    presence, presence.winfo, dialog;sla from the presence_xml
99 102
    module and message-summary from the presence_mwi module.
100 103
 
101
-   The module uses database storage and memory caching (to improve
102
-   performance). The SIP SUBSCRIBE dialog information is stored in
103
-   memory and is periodically updated in the database, while for
104
-   PUBLISH only the presence or absence of stored info for a
105
-   certain resource is maintained in memory to avoid unnecessary,
106
-   costly database operations. It is possible to disable in-memory
107
-   caching by configurng a fallback to database mode (by setting
108
-   module parameter "fallback2db"). In this mode, in case a
109
-   searched record is not found in cache, the search is continued
110
-   in database. This is useful for an architecture in which
111
-   processing and memory load might be divided on several Kamailio
112
-   instances, maybe on different servers using the same database.
104
+   The module uses database storage and memory caching (to
105
+   improve performance). The SIP SUBSCRIBE dialog information is
106
+   stored in memory and is periodically updated in the database,
107
+   while for PUBLISH only the presence or absence of stored info
108
+   for a certain resource is maintained in memory to avoid
109
+   unnecessary, costly database operations. It is possible to
110
+   disable in-memory caching by configurng a fallback to database
111
+   mode (by setting module parameter "fallback2db"). In this
112
+   mode, in case a searched record is not found in cache, the
113
+   search is continued in database. This is useful for an
114
+   architecture in which processing and memory load might be
115
+   divided on several Kamailio instances, maybe on different
116
+   servers using the same database.
113 117
 
114 118
    The module implements several API functions, that can be used
115 119
    by other modules. In fact, it can be used only as a resource
... ...
@@ -142,7 +146,7 @@ Chapter 1. Admin Guide
142 146
    Otherwise, it is used as a 'library', for its exported
143 147
    functions.
144 148
 
145
-   Default value is "NULL".
149
+   Default value is "NULL". 
146 150
 
147 151
    Example 1.1. Set db_url parameter
148 152
 ...
... ...
@@ -155,7 +159,7 @@ modparam("presence", "db_url",
155 159
    The name of the db table where PUBLISH presence information is
156 160
    stored.
157 161
 
158
-   Default value is "presentity".
162
+   Default value is "presentity". 
159 163
 
160 164
    Example 1.2. Set presentity_table parameter
161 165
 ...
... ...
@@ -167,7 +171,7 @@ modparam("presence", "presentity_table", "presentity")
167 171
    The name of the db table where active subscription information
168 172
    is stored.
169 173
 
170
-   Default value is "active_watchers".
174
+   Default value is "active_watchers". 
171 175
 
172 176
    Example 1.3. Set active_watchers_table parameter
173 177
 ...
... ...
@@ -178,7 +182,7 @@ modparam("presence", "active_watchers_table", "active_watchers")
178 182
 
179 183
    The name of the db table where subscription states are stored.
180 184
 
181
-   Default value is "watchers".
185
+   Default value is "watchers". 
182 186
 
183 187
    Example 1.4. Set watchers_table parameter
184 188
 ...
... ...
@@ -190,7 +194,7 @@ modparam("presence", "watchers_table", "watchers")
190 194
    The period in seconds between checks if there are expired
191 195
    messages stored in database.
192 196
 
193
-   Default value is "100".
197
+   Default value is "100". 
194 198
 
195 199
    Example 1.5. Set clean_period parameter
196 200
 ...
... ...
@@ -199,10 +203,10 @@ modparam("presence", "clean_period", 100)
199 203
 
200 204
 1.3.6. to_tag_pref (str)
201 205
 
202
-   The prefix used when generating to_tag when sending replies for
203
-   SUBSCRIBE requests.
206
+   The prefix used when generating to_tag when sending replies
207
+   for SUBSCRIBE requests.
204 208
 
205
-   Default value is "10".
209
+   Default value is "10". 
206 210
 
207 211
    Example 1.6. Set to_tag_pref parameter
208 212
 ...
... ...
@@ -211,12 +215,12 @@ modparam("presence", "to_tag_pref", 'pres')
211 215
 
212 216
 1.3.7. expires_offset (int)
213 217
 
214
-   The value in seconds that should be subtracted from the expires
215
-   value when sending a 200OK for a publish. It is used for
216
-   forcing the client cu send an update before the old publish
217
-   expires.
218
+   The value in seconds that should be subtracted from the
219
+   expires value when sending a 200OK for a publish. It is used
220
+   for forcing the client cu send an update before the old
221
+   publish expires.
218 222
 
219
-   Default value is "0".
223
+   Default value is "0". 
220 224
 
221 225
    Example 1.7. Set expires_offset parameter
222 226
 ...
... ...
@@ -228,7 +232,7 @@ modparam("presence", "expires_offset", 10)
228 232
    The the maximum admissible expires value for PUBLISH/SUBSCRIBE
229 233
    message (in seconds).
230 234
 
231
-   Default value is "3600".
235
+   Default value is "3600". 
232 236
 
233 237
    Example 1.8. Set max_expires parameter
234 238
 ...
... ...
@@ -238,8 +242,8 @@ modparam("presence", "max_expires", 3600)
238 242
 1.3.9. server_address (str)
239 243
 
240 244
    The presence server address which will become the value of
241
-   Contact header filed for 200OK replies to Subscribe and Publish
242
-   and in Notify messages.
245
+   Contact header filed for 200OK replies to Subscribe and
246
+   Publish and in Notify messages.
243 247
 
244 248
    Example 1.9. Set server_address parameter
245 249
 ...
... ...
@@ -249,10 +253,10 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060")
249 253
 1.3.10. fallback2db (int)
250 254
 
251 255
    Setting this parameter enables a fallback to db mode of
252
-   operation. In this mode, in case a searched record is not found
253
-   in cache, the search is continued in database. Useful for an
254
-   architecture in which processing and memory load might be
255
-   divided on more servers using the same database.
256
+   operation. In this mode, in case a searched record is not
257
+   found in cache, the search is continued in database. Useful
258
+   for an architecture in which processing and memory load might
259
+   be divided on more servers using the same database.
256 260
 
257 261
    Example 1.10. Set fallback2db parameter
258 262
 ...
... ...
@@ -265,7 +269,7 @@ modparam("presence", "fallback2db", 1)
265 269
    dialogs. This parameter will be used as the power of 2 when
266 270
    computing table size.
267 271
 
268
-   Default value is "9 (512)".
272
+   Default value is "9 (512)". 
269 273
 
270 274
    Example 1.11. Set subs_htable_size parameter
271 275
 ...
... ...
@@ -278,7 +282,7 @@ modparam("presence", "subs_htable_size", 11)
278 282
    This parameter will be used as the power of 2 when computing
279 283
    table size.
280 284
 
281
-   Default value is "9 (512)".
285
+   Default value is "9 (512)". 
282 286
 
283 287
    Example 1.12. Set pres_htable_size parameter
284 288
 ...
... ...
@@ -287,14 +291,14 @@ modparam("presence", "pres_htable_size", 11)
287 291
 
288 292
 1.3.13. enable_sphere_check (int)
289 293
 
290
-   This parameter is a flag that should be set if permission rules
291
-   include sphere checking. The sphere information is expected to
292
-   be present in the RPID body published by the presentity. The
293
-   flag is introduced as this check requires extra processing that
294
-   should be avoided if this feature is not supported by the
295
-   clients.
294
+   This parameter is a flag that should be set if permission
295
+   rules include sphere checking. The sphere information is
296
+   expected to be present in the RPID body published by the
297
+   presentity. The flag is introduced as this check requires
298
+   extra processing that should be avoided if this feature is not
299
+   supported by the clients.
296 300
 
297
-   Default value is "0 ".
301
+   Default value is "0 ". 
298 302
 
299 303
    Example 1.13. Set enable_sphere_check parameter
300 304
 ...
... ...
@@ -373,7 +377,8 @@ if(method=="SUBSCRIBE")
373 377
      * event : the event package
374 378
      * refresh type : it distinguishes between the two different
375 379
        types of events that can trigger a refresh:
376
-          + a change in watchers authentication: refresh type= 0 ;
380
+          + a change in watchers authentication: refresh type= 0
381
+            ;
377 382
           + a statical update in published state (either through
378 383
             direct update in db table or by modifying the pidf
379 384
             manipulation document, if pidf_manipulation parameter
... ...
@@ -398,8 +403,8 @@ if(method=="SUBSCRIBE")
398 403
 
399 404
 Chapter 2. Developer Guide
400 405
 
401
-   The module provides the following functions that can be used in
402
-   other Kamailio modules.
406
+   The module provides the following functions that can be used
407
+   in other Kamailio modules.
403 408
 
404 409
 2.1.  bind_presence(presence_api_t* api)
405 410
 
... ...
@@ -478,6 +483,25 @@ typedef struct pres_ev
478 483
         publ_handling_t  * evs_publ_handl;
479 484
         subs_handling_t  * evs_subs_handl;
480 485
         free_body_t* free_body;
486
+    /* sometimes it is necessary that a module make changes for a body
487
+for each
488
+     * active watcher (e.g. setting the "version" parameter in an XML d
489
+ocument.
490
+     * If a module registers the aux_body_processing callback, it gets
491
+called for
492
+     * each watcher. It either gets the body received by the PUBLISH, o
493
+r the body
494
+     * generated by the agg_nbody function.
495
+     * The module can deceide if it makes a copy of the original body,
496
+which is then
497
+     * manipulated, or if it works directly in the original body. If th
498
+e module makes a
499
+     * copy of the original body, it also has to register the aux_free_
500
+body() to
501
+     * free this "per watcher" body.
502
+     */
503
+    aux_body_processing_t* aux_body_processing;
504
+    free_body_t* aux_free_body;
481 505
         struct pres_ev* wipeer;
482 506
         struct pres_ev* next;
483 507
 
... ...
@@ -517,8 +541,8 @@ typedef int (is_allowed_t)(struct subscription* subs);
517 541
    This parameter should be a function to be called for an event
518 542
    that requires authorization, when constructing final body. The
519 543
    authorization document is taken from the auth_rules_doc field
520
-   of the subs_t structure given as a parameter. It is called only
521
-   if the req_auth field is not 0.
544
+   of the subs_t structure given as a parameter. It is called
545
+   only if the req_auth field is not 0.
522 546
 
523 547
    Filed type:
524 548
 ...
... ...
@@ -530,8 +554,9 @@ typedef int (apply_auth_t)(str* , struct subscription*, str** );
530 554
    If present, this field marks that the events requires
531 555
    aggregation of states. This function receives a body array and
532 556
    should return the final body. If not present, it is considered
533
-   that the event does not require aggregation and the most recent
534
-   published information is used when constructing Notifies.
557
+   that the event does not require aggregation and the most
558
+   recent published information is used when constructing
559
+   Notifies.
535 560
 
536 561
    Filed type:
537 562
 ...
... ...
@@ -543,16 +568,48 @@ str** body_array, int n, int off_index);
543 568
 
544 569
    This field must be field in if subsequent processing is
545 570
    performed on the info from database before being inserted in
546
-   Notify message body(if agg_nbody or apply_auth_nbody fields are
547
-   filled in). It should match the allocation function used when
548
-   processing the body.
571
+   Notify message body(if agg_nbody or apply_auth_nbody fields
572
+   are filled in). It should match the allocation function used
573
+   when processing the body.
574
+
575
+   Filed type:
576
+...
577
+typedef void(free_body_t)(char* body);
578
+..
579
+
580
+2.8.  aux_body_processing
581
+
582
+   This field must be set if the module needs to manipulate the
583
+   NOTIFY body for each watcher. E.g. if the XML body includes a
584
+   'version' parameter which will be increased for each NOTIFY,
585
+   on a "per watcher" basis. The module can either allocate a new
586
+   buffer for the new body an return it (aux_free_body function
587
+   must be set too) or it manipualtes the original body directly
588
+   and returns NULL.
589
+
590
+   Filed type:
591
+...
592
+typedef str* (aux_body_processing_t)(struct subscription *subs, str* bo
593
+dy);
594
+..
595
+
596
+2.9.  aux_free_body
597
+
598
+   This field must be set if the module registers the
599
+   aux_body_processing function and allocates memory for the new
600
+   modified body. Then, this function will be used to free the
601
+   pointer returned by the aux_body_processing function. If the
602
+   module does use the aux_body_processing, but does not allocate
603
+   new memory, but manipulates directly the original body buffer,
604
+   then the aux_body_processing must return NULL and this field
605
+   should not be set.
549 606
 
550 607
    Filed type:
551 608
 ...
552 609
 typedef void(free_body_t)(char* body);
553 610
 ..
554 611
 
555
-2.8.  evs_publ_handl
612
+2.10.  evs_publ_handl
556 613
 
557 614
    This function is called when handling Publish requests. Most
558 615
    contain body correctness check.
... ...
@@ -561,7 +618,7 @@ typedef void(free_body_t)(char* body);
561 618
 typedef int (publ_handling_t)(struct sip_msg*);
562 619
 ..
563 620
 
564
-2.9.  evs_subs_handl
621
+2.11.  evs_subs_handl
565 622
 
566 623
    It is not compulsory. Should contain event specific handling
567 624
    for Subscription requests.
... ...
@@ -571,7 +628,7 @@ typedef int (publ_handling_t)(struct sip_msg*);
571 628
 typedef int (subs_handling_t)(struct sip_msg*);
572 629
 ..
573 630
 
574
-2.10.  contains_event
631
+2.12.  contains_event
575 632
 
576 633
    Field type:
577 634
 ..
... ...
@@ -584,7 +641,7 @@ event_t* parsed_event);
584 641
    NULL, if not found. If the second argument is an allocated
585 642
    event_t* structure it fills it with the result of the parsing.
586 643
 
587
-2.11.  get_event_list
644
+2.13.  get_event_list
588 645
 
589 646
    Field type:
590 647
 ...
... ...
@@ -595,7 +652,7 @@ typedef int (*get_event_list_t) (str** ev_list);
595 652
    registered in presence module.( used for Allowed-Events
596 653
    header).
597 654
 
598
-2.12.  update_watchers_status
655
+2.14.  update_watchers_status
599 656
 
600 657
    Field type:
601 658
 ...
... ...
@@ -610,14 +667,14 @@ str* rules_doc);
610 667
    notified through an MI command of a change in an xcap
611 668
    document).
612 669
 
613
-2.13.  get_sphere
670
+2.15.  get_sphere
614 671
 
615 672
    Field type:
616 673
 ...
617 674
 typedef char* (*pres_get_sphere_t)(str* pres_uri);
618 675
 ...
619 676
 
620
-   This function searches for a sphere definition in the published
621
-   information if this has type RPID. If not found returns NULL.
622
-   (the return value is allocated in private memory and should be
623
-   freed)
677
+   This function searches for a sphere definition in the
678
+   published information if this has type RPID. If not found
679
+   returns NULL. (the return value is allocated in private memory
680
+   and should be freed)
... ...
@@ -101,6 +101,18 @@ typedef struct pres_ev
101 101
 	publ_handling_t  * evs_publ_handl;
102 102
 	subs_handling_t  * evs_subs_handl;
103 103
 	free_body_t* free_body;
104
+    /* sometimes it is necessary that a module make changes for a body for each
105
+     * active watcher (e.g. setting the "version" parameter in an XML document.
106
+     * If a module registers the aux_body_processing callback, it gets called for
107
+     * each watcher. It either gets the body received by the PUBLISH, or the body
108
+     * generated by the agg_nbody function.
109
+     * The module can deceide if it makes a copy of the original body, which is then
110
+     * manipulated, or if it works directly in the original body. If the module makes a
111
+     * copy of the original body, it also has to register the aux_free_body() to
112
+     * free this "per watcher" body.
113
+     */
114
+    aux_body_processing_t* aux_body_processing;
115
+    free_body_t* aux_free_body;
104 116
 	struct pres_ev* wipeer;			
105 117
 	struct pres_ev* next;
106 118
 	
... ...
@@ -220,6 +232,49 @@ typedef void(free_body_t)(char* body);
220 232
 		</para>
221 233
 </section>	
222 234
 
235
+<section>
236
+		<title>
237
+			<function moreinfo="none">aux_body_processing</function>
238
+		</title>
239
+		<para>
240
+			This field must be set if the module needs to manipulate the NOTIFY body 
241
+			for each watcher. E.g. if the XML body includes a 'version' parameter which 
242
+			will be increased for each NOTIFY, on a "per watcher" basis.
243
+			The module can either allocate a new buffer for the new body an return it (aux_free_body
244
+			function must be set too) or it manipualtes the original body directly and returns NULL.
245
+		</para>
246
+		<para>
247
+		Filed type:
248
+			<programlisting format="linespecific">
249
+...
250
+typedef str* (aux_body_processing_t)(struct subscription *subs, str* body);
251
+..
252
+			</programlisting>
253
+		</para>
254
+</section>	
255
+
256
+<section>
257
+		<title>
258
+			<function moreinfo="none">aux_free_body</function>
259
+		</title>
260
+		<para>
261
+			This field must be set if the module registers the aux_body_processing function
262
+			and allocates memory for the new modified body. Then, this function will be used
263
+			to free the pointer returned by the aux_body_processing function.
264
+			If the module does use the aux_body_processing, but does not allocate new memory, but
265
+			manipulates directly the original body buffer, then the aux_body_processing
266
+			must return NULL and this field should not be set.
267
+		</para>
268
+		<para>
269
+		Filed type:
270
+			<programlisting format="linespecific">
271
+...
272
+typedef void(free_body_t)(char* body);
273
+..
274
+			</programlisting>
275
+		</para>
276
+</section>	
277
+
223 278
 <section>
224 279
 		<title>
225 280
 			<function moreinfo="none">evs_publ_handl</function>
... ...
@@ -226,6 +226,8 @@ int add_event(pres_ev_t* event)
226 226
 	ev->get_rules_doc= event->get_rules_doc;
227 227
 	ev->evs_publ_handl= event->evs_publ_handl;
228 228
 	ev->etag_not_new= event->etag_not_new;
229
+	ev->aux_body_processing= event->aux_body_processing;
230
+	ev->aux_free_body= event->aux_free_body;
229 231
 	ev->free_body= event->free_body;
230 232
 	ev->default_expires= event->default_expires;
231 233
 
... ...
@@ -58,6 +58,15 @@ typedef str* (agg_nbody_t)(str* pres_user, str* pres_domain, str** body_array, i
58 58
  *	off_index= the index of the registration(etag) for which a Publish
59 59
  *				with Expires: 0 has just been received
60 60
  *	*/
61
+typedef str* (aux_body_processing_t)(struct subscription *subs, str* body);
62
+/* params for agg_body_t 
63
+ *	subs= a subscription structure to manipulate the body for a certain watcher
64
+ *	body= the original body
65
+ *
66
+ * return value: 0: means that there was no manipulation or the manipulation was
67
+ *                  done directly in the original body
68
+ *           pointer: a pointer to str for the "per watcher" body. gets freed by aux_free_body()
69
+ *	*/
61 70
 typedef int (is_allowed_t)(struct subscription* subs);
62 71
 typedef int (get_rules_doc_t)(str* user, str* domain, str** rules_doc);
63 72
 /* return code rules for is_allowed_t
... ...
@@ -101,6 +110,18 @@ struct pres_ev
101 110
 	publ_handling_t  * evs_publ_handl;
102 111
 	subs_handling_t  * evs_subs_handl;
103 112
 	free_body_t* free_body;
113
+	/* sometimes it is necessary that a module make changes for a body for each 
114
+	 * active watcher (e.g. setting the "version" parameter in an XML document.
115
+	 * If a module registers the aux_body_processing callback, it gets called for
116
+	 * each watcher. It either gets the body received by the PUBLISH, or the body
117
+	 * generated by the agg_nbody function.
118
+	 * The module can deceide if it makes a copy of the original body, which is then
119
+	 * manipulated, or if it works directly in the original body. If the module makes a
120
+	 * copy of the original body, it also has to register the aux_free_body() to 
121
+	 * free this "per watcher" body.
122
+	 */
123
+	aux_body_processing_t* aux_body_processing;
124
+	free_body_t* aux_free_body;
104 125
 	struct pres_ev* wipeer;			
105 126
 	struct pres_ev* next;
106 127
 	
... ...
@@ -1335,7 +1335,7 @@ error:
1335 1335
 
1336 1336
 int publ_notify(presentity_t* p, str pres_uri, str* body, str* offline_etag, str* rules_doc)
1337 1337
 {
1338
-	str* notify_body = NULL;
1338
+	str *notify_body = NULL, *aux_body = NULL;
1339 1339
 	subs_t* subs_array= NULL, *s= NULL;
1340 1340
 	int ret_code= -1;
1341 1341
 
... ...
@@ -1357,16 +1357,27 @@ int publ_notify(presentity_t* p, str pres_uri, str* body, str* offline_etag, str
1357 1357
 			/* goto error; */
1358 1358
 		}
1359 1359
 	}
1360
-	
1360
+
1361 1361
 	s= subs_array;
1362 1362
 	while(s)
1363 1363
 	{
1364
+		if (p->event->aux_body_processing) {
1365
+			aux_body = p->event->aux_body_processing(s, notify_body?notify_body:body);
1366
+		}
1367
+
1364 1368
 		s->auth_rules_doc= rules_doc;
1365
-		if(notify(s, NULL, notify_body?notify_body:body, 0)< 0 )
1369
+		if(notify(s, NULL, aux_body?aux_body:(notify_body?notify_body:body), 0)< 0 )
1366 1370
 		{
1367 1371
 			LM_ERR("Could not send notify for %.*s\n",
1368 1372
 					p->event->name.len, p->event->name.s);
1369 1373
 		}
1374
+
1375
+		if(aux_body!=NULL) {
1376
+			if(aux_body->s)	{
1377
+				p->event->aux_free_body(aux_body->s);
1378
+			}
1379
+			pkg_free(aux_body);
1380
+		}
1370 1381
 		s= s->next;
1371 1382
 	}
1372 1383
 	ret_code= 0;
... ...
@@ -1391,7 +1402,7 @@ done:
1391 1402
 int query_db_notify(str* pres_uri, pres_ev_t* event, subs_t* watcher_subs )
1392 1403
 {
1393 1404
 	subs_t* subs_array = NULL, *s= NULL;
1394
-	str* notify_body = NULL;
1405
+	str* notify_body = NULL, *aux_body = NULL;
1395 1406
 	int ret_code= -1;
1396 1407
 
1397 1408
 	subs_array= get_subs_dialog(pres_uri, event , NULL);
... ...
@@ -1417,12 +1428,23 @@ int query_db_notify(str* pres_uri, pres_ev_t* event, subs_t* watcher_subs )
1417 1428
 	while(s)
1418 1429
 	{
1419 1430
 
1420
-		if(notify(s, watcher_subs, notify_body, 0)< 0 )
1431
+		if (event->aux_body_processing) {
1432
+			aux_body = event->aux_body_processing(s, notify_body);
1433
+		}
1434
+
1435
+		if(notify(s, watcher_subs, aux_body?aux_body:notify_body, 0)< 0 )
1421 1436
 		{
1422 1437
 			LM_ERR("Could not send notify for [event]=%.*s\n",
1423 1438
 					event->name.len, event->name.s);
1424 1439
 			goto done;
1425 1440
 		}
1441
+
1442
+		if(aux_body!=NULL) {
1443
+			if(aux_body->s)	{
1444
+				event->aux_free_body(aux_body->s);
1445
+			}
1446
+			pkg_free(aux_body);
1447
+		}
1426 1448
 		s= s->next;
1427 1449
 	}
1428 1450