Browse code

- Restructured the module to handle PUBLISH and SUBSCRIBE messages and generates NOTIFY messages in a general, event independentway. It allows registering events to it from other OpenSER modules. presence_xml module adds events: presence, presence.winfo, dialog;sla.

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

Anca Vamanu authored on 23/04/2007 07:28:35
Showing 18 changed files
... ...
@@ -16,35 +16,41 @@ Anca-Maria Vamanu
16 16
    1. User's Guide
17 17
 
18 18
         1.1. Overview
19
-        1.2. To-do
20
-        1.3. Dependencies
19
+        1.2. Dependencies
21 20
 
22
-              1.3.1. OpenSER Modules
23
-              1.3.2. External Libraries or Applications
21
+              1.2.1. OpenSER Modules
22
+              1.2.2. External Libraries or Applications
24 23
 
25
-        1.4. Exported Parameters
24
+        1.3. Exported Parameters
26 25
 
27
-              1.4.1. db_url(str)
28
-              1.4.2. presentity_table(str)
29
-              1.4.3. active_watchers_table(str)
30
-              1.4.4. watchers_table(str)
31
-              1.4.5. xcap_table(str)
32
-              1.4.6. clean_period (int)
33
-              1.4.7. to_tag_pref (str)
34
-              1.4.8. lock_set_size (int)
35
-              1.4.9. expires_offset (int)
36
-              1.4.10. force_active (int)
37
-              1.4.11. max_expires (int)
38
-              1.4.12. server_address (str)
26
+              1.3.1. db_url(str)
27
+              1.3.2. presentity_table(str)
28
+              1.3.3. active_watchers_table(str)
29
+              1.3.4. watchers_table(str)
30
+              1.3.5. clean_period (int)
31
+              1.3.6. to_tag_pref (str)
32
+              1.3.7. lock_set_size (int)
33
+              1.3.8. expires_offset (int)
34
+              1.3.9. max_expires (int)
35
+              1.3.10. server_address (str)
39 36
 
40
-        1.5. Exported Functions
37
+        1.4. Exported Functions
41 38
 
42
-              1.5.1. handle_publish(char* sender_uri)
43
-              1.5.2. handle_subscribe()
39
+              1.4.1. handle_publish(char* sender_uri)
40
+              1.4.2. handle_subscribe()
44 41
 
45
-        1.6. Installation
42
+        1.5. Installation
46 43
 
47 44
    2. Developer's Guide
45
+
46
+        2.1. bind_presence(event_api_t* api)
47
+        2.2. add_event(ev_t* event)
48
+        2.3. apply_auth_nbody
49
+        2.4. is_watcher_allowed
50
+        2.5. agg_nbody
51
+        2.6. evs_publ_handl
52
+        2.7. evs_subs_handl
53
+
48 54
    3. Frequently Asked Questions
49 55
 
50 56
    List of Examples
... ...
@@ -52,48 +58,38 @@ Anca-Maria Vamanu
52 58
    1-2. Set presentity_table parameter
53 59
    1-3. Set active_watchers_table parameter
54 60
    1-4. Set watchers_table parameter
55
-   1-5. Set xcap_table parameter
56
-   1-6. Set clean_period parameter
57
-   1-7. Set to_tag_pref parameter
58
-   1-8. Set lock_set_size parameter
59
-   1-9. Set expires_offset parameter
60
-   1-10. Set force_active parameter
61
-   1-11. Set max_expires parameter
62
-   1-12. Set server_address parameter
63
-   1-13. handle_publish usage
64
-   1-14. handle_subscribe usage
65
-   1-15. PRESENCE tables
61
+   1-5. Set clean_period parameter
62
+   1-6. Set to_tag_pref parameter
63
+   1-7. Set lock_set_size parameter
64
+   1-8. Set expires_offset parameter
65
+   1-9. Set max_expires parameter
66
+   1-10. Set server_address parameter
67
+   1-11. handle_publish usage
68
+   1-12. handle_subscribe usage
69
+   1-13. PRESENCE tables
70
+   2-1. event_api_t structure
66 71
      _________________________________________________________
67 72
 
68 73
 Chapter 1. User's Guide
69 74
 
70 75
 1.1. Overview
71 76
 
72
-   The modules implements a presence server. It handles PUBLISH
73
-   and SUBSCRIBE messages and generates NOTIFY messages. It
74
-   offers support for aggregation of published presence
75
-   information for the same presentity using more devices. It can
76
-   also filter the information provided to watchers according to
77
-   privacy rules.
77
+   The modules handles PUBLISH and SUBSCRIBE messages and
78
+   generates NOTIFY messages in a general, event independent way.
79
+   It allows registering events to it from other OpenSER modules.
80
+   Events that can currently be added to it are: presence,
81
+   presence.winfo, dialog;sla from presence_xml module.
78 82
 
79 83
    The modules works with database storage. It stores published
80 84
    information and Subscribe -Notify dialog characteristics.
81
-   There is also an extra table which stores xcap documents with
82
-   permission rules.
83 85
 
84 86
    The server follows the specifications in: RFC3265, RFC3856,
85 87
    RFC3857, RFC3858.
86 88
      _________________________________________________________
87 89
 
88
-1.2. To-do
89
-
90
-   Provide support for clients which implement end-to-end
91
-   presence.
92
-     _________________________________________________________
93
-
94
-1.3. Dependencies
90
+1.2. Dependencies
95 91
 
96
-1.3.1. OpenSER Modules
92
+1.2.1. OpenSER Modules
97 93
 
98 94
    The following modules must be loaded before this module:
99 95
 
... ...
@@ -102,17 +98,14 @@ Chapter 1. User's Guide
102 98
      * tm.
103 99
      _________________________________________________________
104 100
 
105
-1.3.2. External Libraries or Applications
106
-
107
-   The following libraries or applications must be installed
108
-   before running OpenSER with this module loaded:
101
+1.2.2. External Libraries or Applications
109 102
 
110
-     * libxml.
103
+   None.
111 104
      _________________________________________________________
112 105
 
113
-1.4. Exported Parameters
106
+1.3. Exported Parameters
114 107
 
115
-1.4.1. db_url(str)
108
+1.3.1. db_url(str)
116 109
 
117 110
    The database url.
118 111
 
... ...
@@ -125,7 +118,7 @@ modparam("presence", "db_url",
125 118
 ...
126 119
      _________________________________________________________
127 120
 
128
-1.4.2. presentity_table(str)
121
+1.3.2. presentity_table(str)
129 122
 
130 123
    The name of the db table where Publish information are stored.
131 124
 
... ...
@@ -137,7 +130,7 @@ modparam("presence", "presentity_table", "presentity");
137 130
 ...
138 131
      _________________________________________________________
139 132
 
140
-1.4.3. active_watchers_table(str)
133
+1.3.3. active_watchers_table(str)
141 134
 
142 135
    The name of the db table where active subscription information
143 136
    are stored.
... ...
@@ -150,7 +143,7 @@ modparam("presence", "active_watchers_table", "active_watchers")
150 143
 ...
151 144
      _________________________________________________________
152 145
 
153
-1.4.4. watchers_table(str)
146
+1.3.4. watchers_table(str)
154 147
 
155 148
    The name of the db table where subscription states are stored.
156 149
 
... ...
@@ -162,58 +155,46 @@ modparam("presence", "watchers_table", "watchers")
162 155
 ...
163 156
      _________________________________________________________
164 157
 
165
-1.4.5. xcap_table(str)
166
-
167
-   The name of the db table where XCAP XMLs are stored.
168
-
169
-   Default value is "scap_xml". 
170
-
171
-   Example 1-5. Set xcap_table parameter
172
-...
173
-modparam("presence", "xcap_table", "xcaps")
174
-...
175
-     _________________________________________________________
176
-
177
-1.4.6. clean_period (int)
158
+1.3.5. clean_period (int)
178 159
 
179 160
    The period at which to verify if there are expired messages
180 161
    stored in database.
181 162
 
182 163
    Default value is "100". 
183 164
 
184
-   Example 1-6. Set clean_period parameter
165
+   Example 1-5. Set clean_period parameter
185 166
 ...
186 167
 modparam("presence", "clean_period", 100)
187 168
 ...
188 169
      _________________________________________________________
189 170
 
190
-1.4.7. to_tag_pref (str)
171
+1.3.6. to_tag_pref (str)
191 172
 
192 173
    The prefix used when generating to_tag when sending replies
193 174
    for SUBSCRIBE requests.
194 175
 
195 176
    Default value is "10". 
196 177
 
197
-   Example 1-7. Set to_tag_pref parameter
178
+   Example 1-6. Set to_tag_pref parameter
198 179
 ...
199 180
 modparam("presence", "to_tag_pref", 'a')
200 181
 ...
201 182
      _________________________________________________________
202 183
 
203
-1.4.8. lock_set_size (int)
184
+1.3.7. lock_set_size (int)
204 185
 
205 186
    The size of the lock used for synchronizing updating
206 187
    information from database.
207 188
 
208 189
    Default value is "8". 
209 190
 
210
-   Example 1-8. Set lock_set_size parameter
191
+   Example 1-7. Set lock_set_size parameter
211 192
 ...
212 193
 modparam("presence", "lock_set_size", 8)
213 194
 ...
214 195
      _________________________________________________________
215 196
 
216
-1.4.9. expires_offset (int)
197
+1.3.8. expires_offset (int)
217 198
 
218 199
    The value that should be subtracted from the expires value
219 200
    when sending a 200OK for a publish. It is used for forcing the
... ...
@@ -221,75 +202,56 @@ modparam("presence", "lock_set_size", 8)
221 202
 
222 203
    Default value is "0". 
223 204
 
224
-   Example 1-9. Set expires_offset parameter
205
+   Example 1-8. Set expires_offset parameter
225 206
 ...
226 207
 modparam("presence", "expires_offset", 10)
227 208
 ...
228 209
      _________________________________________________________
229 210
 
230
-1.4.10. force_active (int)
231
-
232
-   This parameter is used for permissions when handling Subscribe
233
-   messages. If set to 1, subscription state is considered active
234
-   and the presentity is not queried for permissions. Otherwise,
235
-   the xcap_table is queried and the state is extracted from
236
-   there. If no record exists, the subscriptions remains in
237
-   pending state and the watcher receives Notify messages with no
238
-   body. ( If not using an xcap server, you should set this
239
-   parameter to 1).
240
-
241
-   Default value is "0". 
242
-
243
-   Example 1-10. Set force_active parameter
244
-...
245
-modparam("presence", "force_active", 1)
246
-...
247
-     _________________________________________________________
248
-
249
-1.4.11. max_expires (int)
211
+1.3.9. max_expires (int)
250 212
 
251 213
    The the maximum admissible expires value for PUBLISH/SUBSCRIBE
252 214
    message.
253 215
 
254 216
    Default value is "3600". 
255 217
 
256
-   Example 1-11. Set max_expires parameter
218
+   Example 1-9. Set max_expires parameter
257 219
 ...
258 220
 modparam("presence", "max_expires", 3600)
259 221
 ...
260 222
      _________________________________________________________
261 223
 
262
-1.4.12. server_address (str)
224
+1.3.10. server_address (str)
263 225
 
264 226
    The presence server address which will become the value of
265 227
    Contact header filed for 200OK replyes to Subscribe and
266 228
    Publish and in Notify messages.
267 229
 
268
-   Example 1-12. Set server_address parameter
230
+   Example 1-10. Set server_address parameter
269 231
 ...
270 232
 modparam("presence", "server_address", "sip:10.10.10.10:5060")
271 233
 ...
272 234
      _________________________________________________________
273 235
 
274
-1.5. Exported Functions
236
+1.4. Exported Functions
275 237
 
276
-1.5.1. handle_publish(char* sender_uri)
238
+1.4.1. handle_publish(char* sender_uri)
277 239
 
278 240
    The function handles PUBLISH requests. It stores and updates
279
-   presence information in database and calls functions to send
280
-   NOTIFY messages when changes in presence information occur. It
281
-   takes one argument -> sender_uri. The parameter was added for
282
-   enabling BLA implementation. If present, Notification of a
283
-   change in presence state is not sent to the respective uri
284
-   even though a subscription exists. It should be taken from the
285
-   Sender header. It was left at the decision of the
286
-   administrator whether or not to transmit the content of this
287
-   header as parameter for handle_publish, to prevent security
288
-   problems.
241
+   published information in database and calls functions to send
242
+   NOTIFY messages when changes in the published information
243
+   occur. It takes one argument -> sender_uri. The parameter was
244
+   added for enabling BLA implementation. If present,
245
+   Notification of a change in published state is not sent to the
246
+   respective uri even though a subscription exists. It should be
247
+   taken from the Sender header. It was left at the decision of
248
+   the administrator whether or not to transmit the content of
249
+   this header as parameter for handle_publish, to prevent
250
+   security problems.
289 251
 
290 252
    This function can be used from REQUEST_ROUTE.
291 253
 
292
-   Example 1-13. handle_publish usage
254
+   Example 1-11. handle_publish usage
293 255
 ...
294 256
         if(is_method("PUBLISH"))
295 257
         {
... ...
@@ -302,7 +264,7 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060")
302 264
 ...
303 265
      _________________________________________________________
304 266
 
305
-1.5.2. handle_subscribe()
267
+1.4.2. handle_subscribe()
306 268
 
307 269
    The function which handles SUBSCRIBE requests. It stores or
308 270
    updates information in database and calls functions to send
... ...
@@ -311,19 +273,19 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060")
311 273
 
312 274
    This function can be used from REQUEST_ROUTE.
313 275
 
314
-   Example 1-14. handle_subscribe usage
276
+   Example 1-12. handle_subscribe usage
315 277
 ...
316 278
 if(method=="SUBSCRIBE")
317 279
     handle_subscribe();
318 280
 ...
319 281
      _________________________________________________________
320 282
 
321
-1.6. Installation
283
+1.5. Installation
322 284
 
323
-   The module requires 4 table in OpenSER database. Next SQL
285
+   The module requires 3 table in OpenSER database. Next SQL
324 286
    statements shows the syntax to create them.
325 287
 
326
-   Example 1-15. PRESENCE tables
288
+   Example 1-13. PRESENCE tables
327 289
 ...
328 290
 
329 291
 use openser;
... ...
@@ -381,24 +343,121 @@ CREATE TABLE `watchers` (
381 343
 ) ENGINE=MyISAM;
382 344
 
383 345
 
346
+...
347
+     _________________________________________________________
384 348
 
385
-CREATE TABLE `xcap_xml` (
386
-  `id` int(10) NOT NULL auto_increment,
387
-  `username` varchar(66) NOT NULL,
388
-  `domain` varchar(128) NOT NULL,
389
-  `xcap` text NOT NULL,
390
-  `doc_type` int(11) NOT NULL,
391
-  UNIQUE KEY udd_xcap (`username`,`domain`,`doc_type`),
392
-  PRIMARY KEY (id)
393
-) ENGINE=MyISAM;
349
+Chapter 2. Developer's Guide
350
+
351
+   The module provides the following functions that can be used
352
+   in other OpenSER modules.
353
+     _________________________________________________________
354
+
355
+2.1. bind_presence(event_api_t* api)
356
+
357
+   This function binds the presence modules and fills the
358
+   structure with one exported function -> add_event, which when
359
+   called adds a new event to be handled by presence.
394 360
 
361
+   Example 2-1. event_api_t structure
362
+...
363
+typedef struct event_api {
364
+        add_event_t add_event;
365
+} event_api_t;
395 366
 ...
396 367
      _________________________________________________________
397 368
 
398
-Chapter 2. Developer's Guide
369
+2.2. add_event(ev_t* event)
370
+
371
+   This function receives as a parameter a structure with event
372
+   specific information and adds it to presence list.
373
+
374
+   The structure received as a parameter:
375
+...
376
+typedef struct ev
377
+{
378
+        str name;
379
+        str* param;         // required param
380
+        str stored_name;
381
+        str content_type;
382
+        int type;
383
+/*      it can be: PUBL_TYPE or WINFO_TYPE */
384
+        int req_auth;
385
+/* flag to mark if the event requires authorization*/
386
+        apply_auth_t*  apply_auth_nbody;
387
+        is_allowed_t*  is_watcher_allowed;
388
+
389
+        agg_nbody_t* agg_nbody;
390
+        publ_handling_t  * evs_publ_handl;
391
+        subs_handling_t  * evs_subs_handl;
392
+
393
+/* this two should not be filed when the structure is given as a
394
+        parmeter for add_event function */
395
+        struct ev* wipeer;
396
+        struct ev* next;
397
+
398
+}ev_t;
399
+...
400
+     _________________________________________________________
401
+
402
+2.3. apply_auth_nbody
403
+
404
+   This parameter should be a function to be calledfor an event
405
+   that requires authorization, when constructing final body. It
406
+   is called only if the req_auth field is not 0.
407
+
408
+   Filed type:
409
+...
410
+typedef int (apply_auth_t)(str* , struct subscription*, str* );
411
+..
412
+     _________________________________________________________
413
+
414
+2.4. is_watcher_allowed
415
+
416
+   This filed is a function to be called for a subscription
417
+   request to return the state for that subscription according to
418
+   authorization rules. It is called only if the req_auth field
419
+   is not 0.
420
+
421
+   Filed type:
422
+...
423
+typedef int (is_allowed_t)(struct subscription* subs);
424
+..
425
+     _________________________________________________________
426
+
427
+2.5. agg_nbody
428
+
429
+   If present, this field marks that the events requires
430
+   aggregation of states. This function receives a body array and
431
+   should return the final body. If not present, it is considered
432
+   that the event does not require aggregation and the most
433
+   recent published information is used when constructing
434
+   Notifies.
435
+
436
+   Filed type:
437
+...
438
+typedef str* (agg_nbody_t)(str** body_array, int n, int off_index);
439
+..
440
+     _________________________________________________________
441
+
442
+2.6. evs_publ_handl
399 443
 
400
-   The module does not provide any API to use in other OpenSER
401
-   modules.
444
+   This function is called when handling Publish requests. Most
445
+   contain body correctitude check.
446
+
447
+...
448
+typedef int (publ_handling_t)(struct sip_msg*);
449
+..
450
+     _________________________________________________________
451
+
452
+2.7. evs_subs_handl
453
+
454
+   It is not compulsory. Should contain event specific handling
455
+   for Subscription requests.
456
+
457
+   Filed type:
458
+...
459
+typedef int (subs_handling_t)(struct sip_msg*);
460
+..
402 461
      _________________________________________________________
403 462
 
404 463
 Chapter 3. Frequently Asked Questions
405 464
new file mode 100644
... ...
@@ -0,0 +1,48 @@
1
+/*
2
+ * $Id: bind_presence.c 1979 2007-04-06 13:24:12Z anca_vamanu $
3
+ *
4
+ * presence module - presence server implementation
5
+ *
6
+ * Copyright (C) 2006 Voice Sistem S.R.L.
7
+ *
8
+ * This file is part of openser, a free SIP server.
9
+ *
10
+ * openser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * openser is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License 
21
+ * along with this program; if not, write to the Free Software 
22
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
+ *
24
+ * History:
25
+ * --------
26
+ *  2007-04-17  initial version (anca)
27
+ */
28
+#include "bind_presence.h"
29
+#include "../../dprint.h"
30
+#include "../../sr_module.h"
31
+
32
+int bind_presence(event_api_t* api)
33
+{
34
+	if (!api) {
35
+		LOG(L_ERR, "NOTIFIER:bind_notifier: Invalid parameter value\n");
36
+		return -1;
37
+	}
38
+	api->add_event = (add_event_t )find_export("add_event", 1, 0);
39
+	if(!api->add_event)
40
+	{
41
+		LOG(L_ERR, "NOTIFIER:bind_notifier: Can't bind add_event\n");
42
+		return -1;
43
+	}
44
+
45
+	return 0;
46
+}
47
+
48
+
0 49
new file mode 100644
... ...
@@ -0,0 +1,43 @@
1
+/*
2
+ * $Id: bind_presence.h 1979 2007-04-06 13:24:12Z anca_vamanu $
3
+ *
4
+ * presence module - presence server implementation
5
+ *
6
+ * Copyright (C) 2007 Voice Sistem S.R.L.
7
+ *
8
+ * This file is part of openser, a free SIP server.
9
+ *
10
+ * openser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * openser is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License 
21
+ * along with this program; if not, write to the Free Software 
22
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
+ *
24
+ * History:
25
+ * --------
26
+ *  2007-04-17  initial version (anca)
27
+ */
28
+
29
+#ifndef _PRES_BIND_H_
30
+#define _PRES_BIND_H_
31
+
32
+#include "event_list.h"
33
+
34
+typedef struct event_api {
35
+	add_event_t add_event;
36
+} event_api_t;
37
+
38
+int bind_presence(event_api_t* api);
39
+
40
+typedef int (*bind_presence_t)(event_api_t* api);
41
+
42
+#endif
43
+
... ...
@@ -53,14 +53,3 @@ CREATE TABLE `watchers` (
53 53
   PRIMARY KEY (id)
54 54
 ) ENGINE=MyISAM;
55 55
 
56
-
57
-
58
-CREATE TABLE `xcap_xml` (
59
-  `id` int(10) NOT NULL auto_increment,
60
-  `username` varchar(66) NOT NULL,
61
-  `domain` varchar(128) NOT NULL,
62
-  `xcap` text NOT NULL,
63
-  `doc_type` int(11) NOT NULL,
64
-  UNIQUE KEY udd_xcap (`username`,`domain`,`doc_type`),
65
-  PRIMARY KEY (id)
66
-) ENGINE=MyISAM;
... ...
@@ -11,8 +11,164 @@
11 11
     </chapterinfo>
12 12
     <title>Developer's Guide</title>
13 13
     <para>
14
-	The module does not provide any <acronym>API</acronym> to use in other &ser; modules.
15
-    </para>
14
+		The module provides the following functions that can be used
15
+		in other &ser; modules.
16
+   </para>
17
+ 		<section>
18
+				<title>
19
+				<function moreinfo="none">bind_presence(event_api_t* api)</function>
20
+				</title>
21
+			<para>
22
+				This function binds the presence modules and fills the structure 
23
+				with one exported function -> add_event, which when called adds a 
24
+				new event to be handled by presence.
25
+			</para>
26
+		<example>
27
+		<title><function>event_api_t</function> structure</title>
28
+	<programlisting format="linespecific">
29
+...
30
+typedef struct event_api {
31
+	add_event_t add_event;
32
+} event_api_t;
33
+...
34
+</programlisting>
35
+		</example>
36
+
37
+		</section>
38
+	
39
+	<section>
40
+			<title>
41
+			<function moreinfo="none">add_event(ev_t* event)</function>
42
+			</title>
43
+		<para>
44
+			This function receives as a parameter a structure with event specific
45
+			information and adds it to presence list.
46
+		</para>
47
+		<para>
48
+		The structure received as a parameter:
49
+	<programlisting format="linespecific">
50
+...
51
+typedef struct ev
52
+{
53
+	str name;
54
+	str* param;         // required param 
55
+	str stored_name;
56
+	str content_type;
57
+	int type;
58
+/*	it can be: PUBL_TYPE or WINFO_TYPE */
59
+	int req_auth;
60
+/* flag to mark if the event requires authorization*/	
61
+	apply_auth_t*  apply_auth_nbody;
62
+	is_allowed_t*  is_watcher_allowed;
63
+	
64
+	agg_nbody_t* agg_nbody;
65
+	publ_handling_t  * evs_publ_handl;
66
+	subs_handling_t  * evs_subs_handl;
67
+
68
+/* this two should not be filed when the structure is given as a
69
+	parmeter for add_event function */
70
+	struct ev* wipeer;			
71
+	struct ev* next;
72
+	
73
+}ev_t;
74
+...
75
+</programlisting>
76
+		</section>
77
+
78
+<section>
79
+		<title>
80
+			<function moreinfo="none">apply_auth_nbody</function>
81
+		</title>
82
+		<para>
83
+			This parameter should be a function to be calledfor an event that requires
84
+			authorization, when constructing final body. It is called only if the
85
+			req_auth field is not 0.
86
+		</para>
87
+		<para>
88
+			Filed type:
89
+			<programlisting format="linespecific">
90
+...
91
+typedef int (apply_auth_t)(str* , struct subscription*, str* );
92
+..
93
+			</programlisting>
94
+			</para>
95
+</section>			
96
+
97
+<section>
98
+		<title>
99
+			<function moreinfo="none">is_watcher_allowed</function>
100
+		</title>
101
+		<para>
102
+			This filed is a function to be called for a subscription request to
103
+			return the state for that subscription according to authorization rules.
104
+			It is called only if the req_auth field is not 0.
105
+		</para>
106
+		<para>
107
+			Filed type:
108
+			<programlisting format="linespecific">
109
+...
110
+typedef int (is_allowed_t)(struct subscription* subs);
111
+..
112
+			</programlisting>
113
+			</para>
114
+</section>	
115
+
116
+<section>
117
+		<title>
118
+			<function moreinfo="none">agg_nbody</function>
119
+		</title>
120
+		<para>
121
+			If present, this field marks that the events requires aggregation of states.
122
+			This function receives a body array and should return the final body.
123
+			If not present, it is considered that the event does not require aggregation and
124
+			the most recent published information is used when constructing Notifies.
125
+		</para>
126
+		<para>
127
+		Filed type:
128
+			<programlisting format="linespecific">
129
+...
130
+typedef str* (agg_nbody_t)(str** body_array, int n, int off_index);
131
+..
132
+			</programlisting>
133
+			</para>
134
+</section>	
135
+
136
+<section>
137
+		<title>
138
+			<function moreinfo="none">evs_publ_handl</function>
139
+		</title>
140
+		<para>
141
+		This function is called when handling Publish requests. Most contain 
142
+		body correctitude check.
143
+		</para>
144
+		<para>
145
+			<programlisting format="linespecific">
146
+...
147
+typedef int (publ_handling_t)(struct sip_msg*);
148
+..
149
+			</programlisting>
150
+			</para>
151
+</section>	
152
+
153
+<section>
154
+		<title>
155
+			<function moreinfo="none">evs_subs_handl</function>
156
+		</title>
157
+		<para>
158
+		It is not compulsory. Should contain event specific handling for
159
+		Subscription requests.
160
+		</para>
161
+		<para>
162
+		Filed type:
163
+			<programlisting format="linespecific">
164
+...
165
+typedef int (subs_handling_t)(struct sip_msg*);
166
+..
167
+			</programlisting>
168
+			</para>
169
+</section>	
170
+
171
+
16 172
 </chapter>
17 173
 
18 174
 <!-- Keep this element at the end of the file
... ...
@@ -13,17 +13,14 @@
13 13
 	
14 14
 	<section>
15 15
 	<title>Overview</title>
16
-	<para> The modules implements a presence server. It handles PUBLISH
17
-	and SUBSCRIBE messages and generates NOTIFY messages. It
18
-	offers support for aggregation of published presence
19
-	information for the same presentity using more devices. It can
20
-	also filter the information provided to watchers according to
21
-	privacy rules.
16
+	<para> The modules handles PUBLISH and SUBSCRIBE messages and generates
17
+	NOTIFY messages in a general, event independent way. It allows registering 
18
+	events to it from other &ser modules. Events that can currently be added to
19
+	it are: presence, presence.winfo, dialog;sla from presence_xml module.
22 20
 	</para>
23 21
 	<para>
24 22
 	The modules works with database storage. It stores published information 
25
-	and Subscribe -Notify dialog characteristics. There is also an extra table
26
-	which stores xcap documents with permission rules. 
23
+	and Subscribe -Notify dialog characteristics.
27 24
 	</para>
28 25
 	<para>
29 26
 	The server follows the specifications in: RFC3265, RFC3856, RFC3857, 
... ...
@@ -31,14 +28,6 @@
31 28
 	</para>
32 29
 	</section>
33 30
 
34
-	<section>
35
-	<title>To-do</title>
36
-		<para>
37
-		Provide support for clients which implement 
38
-		end-to-end presence. 
39
-		</para>
40
-	</section>
41
-	
42 31
 	<section>
43 32
 	<title>Dependencies</title>
44 33
 	<section>
... ...
@@ -68,15 +57,7 @@
68 57
 	<section>
69 58
 		<title>External Libraries or Applications</title>
70 59
 		<para>
71
-		The following libraries or applications must be installed before running
72
-		&ser; with this module loaded:
73
-			<itemizedlist>
74
-			<listitem>
75
-			<para>
76
-				<emphasis>libxml</emphasis>.
77
-			</para>
78
-			</listitem>
79
-			</itemizedlist>
60
+			None.
80 61
 		</para>
81 62
 	</section>
82 63
 	</section>
... ...
@@ -154,24 +135,6 @@ modparam("presence", "active_watchers_table", "active_watchers")
154 135
 ...
155 136
 modparam("presence", "watchers_table", "watchers")
156 137
 ...
157
-</programlisting>
158
-		</example>
159
-	</section>
160
-	<section>
161
-		<title><varname>xcap_table</varname>(str)</title>
162
-		<para>
163
-		The name of the db table where XCAP XMLs are stored.
164
-		</para>
165
-		<para>
166
-		<emphasis>	Default value is <quote>scap_xml</quote>.
167
-		</emphasis>
168
-		</para>
169
-		<example>
170
-		<title>Set <varname>xcap_table</varname> parameter</title>
171
-		<programlisting format="linespecific">
172
-...
173
-modparam("presence", "xcap_table", "xcaps")
174
-...
175 138
 </programlisting>
176 139
 		</example>
177 140
 	</section>
... ...
@@ -257,30 +220,6 @@ modparam("presence", "expires_offset", 10)
257 220
 		</example>
258 221
 	</section>
259 222
 
260
-	<section>
261
-		<title><varname>force_active</varname> (int)</title>
262
-		<para>
263
-		This parameter is used for permissions when handling Subscribe messages.
264
-		If set to 1, subscription state is considered active and the presentity
265
-		is not queried for permissions. 
266
-		Otherwise, the xcap_table is queried and the state is extracted
267
-		from there. If no record exists, the subscriptions remains in pending
268
-		state and the watcher receives Notify messages with no body.
269
-		( If not using an xcap server, you should set this parameter to 1).
270
-		</para>
271
-		<para>
272
-		<emphasis>Default value is <quote>0</quote>.
273
-		</emphasis>
274
-		</para>
275
-		<example>
276
-		<title>Set <varname>force_active</varname> parameter</title>
277
-		<programlisting format="linespecific">
278
-...
279
-modparam("presence", "force_active", 1)
280
-...
281
-</programlisting>
282
-		</example>
283
-	</section>
284 223
 	<section>
285 224
 		<title><varname>max_expires</varname> (int)</title>
286 225
 		<para>
... ...
@@ -327,11 +266,11 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060")
327 266
 		</title>
328 267
 		<para>
329 268
 		The function handles PUBLISH requests. It stores and updates 
330
-		presence information in database and calls functions to send 
331
-		NOTIFY messages when changes in presence information occur.
269
+		published information in database and calls functions to send 
270
+		NOTIFY messages when changes in the published information occur.
332 271
 		It takes one argument -> sender_uri. The parameter was added 
333 272
 		for enabling BLA implementation. If present, Notification of
334
-		a change in presence state is not sent to the respective uri
273
+		a change in published state is not sent to the respective uri
335 274
 		even though a subscription exists.
336 275
 		It should be taken from the Sender header. It was left at the
337 276
 		decision of the administrator whether or not to transmit the 
... ...
@@ -385,7 +324,7 @@ if(method=="SUBSCRIBE")
385 324
 <section>
386 325
 	<title>Installation</title>
387 326
 	<para>
388
-	The module requires 4 table in OpenSER database. Next SQL statements
327
+	The module requires 3 table in OpenSER database. Next SQL statements
389 328
 	shows the syntax to create them.
390 329
 	</para>
391 330
 	<example>
... ...
@@ -33,45 +33,39 @@
33 33
 #include "../../dprint.h"
34 34
 #include "../../mem/shm_mem.h" 
35 35
 #include "event_list.h"
36
-#include "presence.h"
36
+//#include "presence.h"
37 37
 
38
-int add_event(char* name, char* param, char* content_type, int agg_body)
38
+int add_event(ev_t* event)
39 39
 {
40 40
 	ev_t* ev= NULL;
41 41
 	int size;
42
-	str str_name;
43
-	str* str_param= NULL;
44 42
 	char* sep= NULL;
45 43
 	str wipeer_name;
46 44
 	char buf[50];
47 45
 	int ret_code= 1;
48 46
 
49
-	str_name.s= name;
50
-	str_name.len= strlen(name);
47
+	if(event->name.s== NULL || event->name.len== 0)
48
+	{
49
+		LOG(L_ERR, "PRESENCE: add_event: NULL event name\n");
50
+		return -1;
51
+	}
51 52
 
52
-	if(param)
53
+	if(event->content_type.s== NULL || event->content_type.len== 0)
53 54
 	{
54
-		str_param= (str*)pkg_malloc(sizeof(str));
55
-		if(str_param== NULL)
56
-		{
57
-			LOG(L_ERR, "PRESENCE: add_event: ERROR No more memory\n");
58
-			return -1;
59
-		}
60
-		str_param->s= param;
61
-		str_param->len= strlen(param);
55
+		LOG(L_ERR, "PRESENCE: add_event: NULL content_type param\n");
56
+		return -1;
62 57
 	}
63 58
 
64
-	if(contains_event(&str_name, str_param))
59
+	if(contains_event(&event->name, event->param))
65 60
 	{
66 61
 		DBG("PRESENCE: add_event: Found prevoius record for event\n");
67 62
 		ret_code= -1;
68 63
 		goto done;
69 64
 	}	
70
-	size= sizeof(ev_t)+ (str_name.len+ strlen(content_type))
71
-		*sizeof(char);
65
+	size= sizeof(ev_t)+ (event->name.len+ event->content_type.len)*sizeof(char);
72 66
 
73
-	if(param)
74
-		size+= sizeof(str)+ ( 2*strlen(param) + str_name.len+ 1)* sizeof(char);
67
+	if(event->param)
68
+		size+= sizeof(str)+ ( 2*event->param->len + event->name.len+ 1)* sizeof(char);
75 69
 
76 70
 	ev= (ev_t*)shm_malloc(size);
77 71
 	if(ev== NULL)
... ...
@@ -84,26 +78,26 @@ int add_event(char* name, char* param, char* content_type, int agg_body)
84 78
 
85 79
 	size= sizeof(ev_t);
86 80
 	ev->name.s= (char*)ev+ size;
87
-	ev->name.len= str_name.len;
88
-	memcpy(ev->name.s, name, str_name.len);
89
-	size+= str_name.len;
81
+	ev->name.len= event->name.len;
82
+	memcpy(ev->name.s, event->name.s, event->name.len);
83
+	size+= event->name.len;
90 84
 
91
-	if(str_param)
85
+	if(event->param)
92 86
 	{	
93 87
 		ev->param= (str*)((char*)ev+ size);
94 88
 		size+= sizeof(str);
95 89
 		ev->param->s= (char*)ev+ size;
96
-		memcpy(ev->param->s, str_param->s, str_param->len);
97
-		ev->param->len= str_param->len;
98
-		size+= str_param->len;
99
-
90
+		memcpy(ev->param->s, event->param->s, event->param->len);
91
+		ev->param->len= event->param->len;
92
+		size+= event->param->len;
93
+	
100 94
 		ev->stored_name.s= (char*)ev+ size;
101
-		memcpy(ev->stored_name.s, name, str_name.len);
102
-		ev->stored_name.len= str_name.len;
95
+		memcpy(ev->stored_name.s, event->name.s, event->name.len);
96
+		ev->stored_name.len= event->name.len;
103 97
 		memcpy(ev->stored_name.s+ ev->stored_name.len, ";", 1);
104 98
 		ev->stored_name.len+= 1;
105
-		memcpy(ev->stored_name.s+ ev->stored_name.len, str_param->s, str_param->len);
106
-		ev->stored_name.len+= str_param->len;
99
+		memcpy(ev->stored_name.s+ ev->stored_name.len, event->param->s, event->param->len);
100
+		ev->stored_name.len+= event->param->len;
107 101
 		size+= ev->stored_name.len;
108 102
 	}
109 103
 	else
... ...
@@ -113,20 +107,18 @@ int add_event(char* name, char* param, char* content_type, int agg_body)
113 107
 	}	
114 108
 
115 109
 	ev->content_type.s= (char*)ev+ size;
116
-	ev->content_type.len= strlen(content_type);
117
-	memcpy(ev->content_type.s, content_type, ev->content_type.len);
110
+	ev->content_type.len= event->content_type.len;
111
+	memcpy(ev->content_type.s, event->content_type.s, event->content_type.len);
118 112
 	size+= ev->content_type.len;
119 113
 	
120
-	ev->agg_body= agg_body;
121
-	
122
-	sep= strchr(name, '.');
114
+	sep= strchr(event->name.s, '.');
123 115
 	if(sep)
124 116
 	{
125 117
 		if(strncmp(sep+1, "winfo", 5)== 0)
126 118
 		{	
127 119
 			ev->type= WINFO_TYPE;
128
-			wipeer_name.s= name;
129
-			wipeer_name.len= sep - name;
120
+			wipeer_name.s= event->name.s;
121
+			wipeer_name.len= sep - event->name.s;
130 122
 			
131 123
 			ev->wipeer= contains_event(&wipeer_name, ev->param );
132 124
 		}
... ...
@@ -134,7 +126,8 @@ int add_event(char* name, char* param, char* content_type, int agg_body)
134 126
 		{	
135 127
 			ev->type= PUBL_TYPE;
136 128
 			wipeer_name.s= buf;
137
-			wipeer_name.len= sprintf(wipeer_name.s, "%s", name);
129
+			memcpy(wipeer_name.s, event->name.s, event->name.len);
130
+			wipeer_name.len= event->name.len;
138 131
 			memcpy(wipeer_name.s+ wipeer_name.len, ".winfo", 5);
139 132
 			wipeer_name.len+= 5;
140 133
 			ev->wipeer= contains_event(&wipeer_name, ev->param);
... ...
@@ -144,13 +137,19 @@ int add_event(char* name, char* param, char* content_type, int agg_body)
144 137
 	else
145 138
 		ev->type= PUBL_TYPE;
146 139
 
140
+	ev->req_auth= event->req_auth;
141
+	ev->agg_nbody= event->agg_nbody;
142
+	ev->apply_auth_nbody= event->apply_auth_nbody;
143
+	ev->is_watcher_allowed= event->is_watcher_allowed;
144
+	ev->evs_publ_handl= event->evs_publ_handl;
145
+
147 146
 	ev->next= EvList->events;
148 147
 	EvList->events= ev;
149 148
 	EvList->ev_count++;
150 149
 
151 150
 done:
152
-	if(str_param)
153
-		pkg_free(str_param);
151
+	DBG("\n\n\nPRESENCE: add_event: SUCCESFULLY ADDED EVENT: %.*s\n\n", 
152
+			ev->stored_name.len, ev->stored_name.s);
154 153
 	return ret_code; 
155 154
 }
156 155
 
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- * $Id: event_list.c 1953 2007-04-04 08:50:33Z anca_vamanu $
2
+ * $Id: event_list.h 1953 2007-04-04 08:50:33Z anca_vamanu $
3 3
  *
4 4
  * presence module - presence server implementation
5 5
  *
... ...
@@ -26,28 +26,71 @@
26 26
  *  2007-04-05  initial version (anca)
27 27
  */
28 28
 
29
-#ifndef _PRES_EV_LST_
30
-#define  _PRES_EV_LST_
29
+#ifndef _PRES_EV_LST_H
30
+#define  _PRES_EV_LST_H
31 31
 
32
+#include "../../parser/msg_parser.h"
32 33
 #include "../../str.h"
34
+#include "subscribe.h"
33 35
 
34 36
 #define WINFO_TYPE			1<< 0
35 37
 #define PUBL_TYPE		    1<< 1
36 38
 
37
-typedef struct ev
39
+struct subscription;
40
+
41
+typedef int (apply_auth_t)(str* , struct subscription*, str* );
42
+
43
+typedef int (publ_handling_t)(struct sip_msg*);
44
+
45
+typedef int (subs_handling_t)(struct sip_msg*);
46
+
47
+typedef str* (agg_nbody_t)(str** body_array, int n, int off_index);
48
+/* params for agg_body_t 
49
+ *	body_array= an array with all the bodies stored for that resource
50
+ *	n= the number of bodies
51
+ *	off_index= the index of the registration(etag) for which a Publish
52
+ *				with Expires: 0 has just been received
53
+ *	*/
54
+typedef int (is_allowed_t)(struct subscription* subs);
55
+/* return code rules for is_allowed_t
56
+ *	< 0  if error occured
57
+ *	=0	 if no change in status(if no xcap document exists)
58
+ *	>0   if change in status
59
+ *	*/
60
+
61
+struct ev
38 62
 {
39 63
 	str name;
40 64
 	str* param;         // required param 
41 65
 	/* to do: transform it in a list ( for multimple param)*/
42 66
 	str stored_name;
43 67
 	str content_type;
44
-	int agg_body;
45 68
 	int type;
69
+
70
+	/* fileds that deal with authorization rules*/
71
+	/*
72
+	 *  req_auth -> flag 0  - if not require 
73
+	 *  is_watcher_allowed  - get subscription state from xcap rules
74
+	 *  apply_auth_nbody    - alter the body according to authorization rules
75
+	 */
46 76
 	int req_auth;
47
-	struct ev* wipeer; /* can be NULL or the name of teh winfo event */
77
+	apply_auth_t*  apply_auth_nbody;
78
+	is_allowed_t*  is_watcher_allowed;
79
+	
80
+	/* an agg_body_t function should be registered if the event permits having
81
+	 * multiple published states and requires an aggregation of the information
82
+	 * otherwise, this field should be NULL and the last published state is taken 
83
+	 * when constructing Notify msg 
84
+	 * */
85
+	agg_nbody_t* agg_nbody;
86
+	publ_handling_t  * evs_publ_handl;
87
+	subs_handling_t  * evs_subs_handl;
88
+
89
+	struct ev* wipeer;			
48 90
 	struct ev* next;
49 91
 	
50
-}ev_t;
92
+};
93
+typedef struct ev ev_t;
51 94
 
52 95
 typedef struct evlist
53 96
 {
... ...
@@ -57,10 +100,14 @@ typedef struct evlist
57 100
 
58 101
 evlist_t* init_evlist();
59 102
 
60
-int add_event(char* name, char* param, char* content_type, int agg_body);
103
+int add_event(ev_t* event);
104
+
105
+typedef int (*add_event_t)(ev_t* event);
61 106
 
62 107
 ev_t* contains_event(str* name, str* param);
63 108
 
64 109
 void destroy_evlist();
65 110
 
111
+extern evlist_t* EvList;
112
+
66 113
 #endif
... ...
@@ -29,6 +29,7 @@
29 29
 #include <stdio.h>
30 30
 #include <stdlib.h>
31 31
 #include <string.h>
32
+#include <libxml/parser.h>
32 33
 
33 34
 #include "../../trim.h"
34 35
 #include "../../ut.h"
... ...
@@ -42,7 +43,6 @@
42 43
 
43 44
 #include "presence.h"
44 45
 #include "notify.h"
45
-#include "pidf.h"
46 46
 #include "utils_func.h"
47 47
 
48 48
 extern struct tm_binds tmb;
... ...
@@ -65,6 +65,7 @@ void printf_subs(subs_t* subs)
65 65
 			subs->to_tag.len, subs->to_tag.s,	subs->from_tag.len, subs->from_tag.s);
66 66
 
67 67
 }
68
+str* create_winfo_xml(watcher_t* watchers,int n, char* version,char* resource, int STATE_FLAG );
68 69
 
69 70
 str* build_str_hdr(ev_t* event, str event_id, str status, int expires_t,
70 71
 		str reason,str* local_contact)
... ...
@@ -390,7 +391,7 @@ error:
390 391
 	return NULL;
391 392
 
392 393
 }
393
-str* get_p_notify_body(str user, str host, str* etag, ev_t* event)
394
+str* get_p_notify_body(str user, str host, str* etag, ev_t* event, subs_t* subs)
394 395
 {
395 396
 	db_key_t query_cols[6];
396 397
 	db_op_t  query_ops[6];
... ...
@@ -467,16 +468,10 @@ str* get_p_notify_body(str user, str host, str* etag, ev_t* event)
467 468
 	else
468 469
 	{
469 470
 		n= result->n;
470
-		if(!event->agg_body )
471
+		if(event->agg_nbody== NULL )
471 472
 		{
472 473
 			int len;
473
-		/*	if(n>1)
474
-			{
475
-				LOG(L_ERR, "PRESENCE:get_p_notify_body: ERROR multiple published" 
476
-					" dialog states stored for the same BLA AOR\n");
477
-				goto error;
478
-			}
479
-		*/
474
+			DBG("PRESENCE:get_p_notify_body: Event does not require aggregation\n");
480 475
 			row = &result->rows[0];
481 476
 			row_vals = ROW_VALUES(row);
482 477
 			if(row_vals[body_col].val.string_val== NULL)
... ...
@@ -510,6 +505,8 @@ str* get_p_notify_body(str user, str host, str* etag, ev_t* event)
510 505
 			goto done;
511 506
 		}
512 507
 		
508
+		DBG("PRESENCE:get_p_notify_body: Event requires aggregation\n");
509
+
513 510
 		body_array =(str**)pkg_malloc( (result->n)*sizeof(str*));
514 511
 		if(body_array == NULL)
515 512
 		{
... ...
@@ -537,17 +534,8 @@ str* get_p_notify_body(str user, str host, str* etag, ev_t* event)
537 534
 				{
538 535
 					DBG("PRESENCE:get_p_notify_body found etag  \n");
539 536
 					build_off_n= i;
540
-					
541
-					body_array[build_off_n]= offline_nbody(&row_vals[body_col].val.str_val);
542
-					if(body_array[i] == NULL)
543
-					{
544
-						DBG("PRESENCE: get_p_notify_body:The users's"
545
-								"status was already offline\n");
546
-						goto error;
547
-					}
548
-				}
549
-				else
550
-					body_array[i] =&row_vals[body_col].val.str_val;
537
+				}	
538
+				body_array[i] =&row_vals[body_col].val.str_val;
551 539
 			}
552 540
 		}	
553 541
 		else
... ...
@@ -559,20 +547,13 @@ str* get_p_notify_body(str user, str host, str* etag, ev_t* event)
559 547
 				body_array[i] =&row_vals[body_col].val.str_val;
560 548
 			}			
561 549
 		}
562
-		notify_body = agregate_xmls(body_array, result->n);
550
+	
551
+		notify_body = event->agg_nbody(body_array, result->n, build_off_n);
563 552
 	}
553
+
564 554
 done:	
565 555
 	if(result!=NULL)
566 556
 		pa_dbf.free_result(pa_db, result);
567
-	if(build_off_n >= 0)
568
-	{
569
-		if(body_array[build_off_n])
570
-		{
571
-			if(body_array[build_off_n]->s)
572
-				xmlFree(body_array[build_off_n]->s);
573
-			pkg_free(body_array[build_off_n]);
574
-		}
575
-	}	
576 557
 	if(body_array!=NULL)
577 558
 		pkg_free(body_array);
578 559
 	return notify_body;
... ...
@@ -580,15 +561,6 @@ done:
580 561
 error:
581 562
 	if(result!=NULL)
582 563
 		pa_dbf.free_result(pa_db, result);
583
-	if(build_off_n > 0)
584
-	{
585
-		if(body_array[build_off_n])
586
-		{
587
-			if(body_array[build_off_n]->s)
588
-				xmlFree(body_array[build_off_n]->s);
589
-			pkg_free(body_array[build_off_n]);
590
-		}
591
-	}	
592 564
 
593 565
 	if(body_array!=NULL)
594 566
 		pkg_free(body_array);
... ...
@@ -838,7 +810,8 @@ subs_t** get_subs_dialog(str* p_user, str* p_domain, ev_t* event,str* sender, in
838 810
 	{
839 811
 		row = &result->rows[i];
840 812
 		row_vals = ROW_VALUES(row);		
841
-		
813
+	
814
+		memset(&status, 0, sizeof(str));
842 815
 		from_user.s= (char*)row_vals[from_user_col].val.string_val;
843 816
 		from_user.len= 	strlen(from_user.s);
844 817
 		from_domain.s= (char*)row_vals[from_domain_col].val.string_val;
... ...
@@ -865,17 +838,9 @@ subs_t** get_subs_dialog(str* p_user, str* p_domain, ev_t* event,str* sender, in
865 838
 		contact.s= (char*)row_vals[contact_col].val.string_val;
866 839
 		contact.len= strlen(contact.s);
867 840
 		
868
-		if(!force_active && row_vals[status_col].val.string_val)
869
-		{
870
-			status.s=  (char*)row_vals[status_col].val.string_val;
871
-			status.len= strlen(status.s);
872
-		}
873
-		else
874
-		{
875
-			status.s= NULL;
876
-			status.len= 0;
877
-		}
878
-		
841
+		status.s=  (char*)row_vals[status_col].val.string_val;
842
+		status.len= strlen(status.s);
843
+			
879 844
 		sockinfo_str.s = (char*)row_vals[sockinfo_col].val.string_val;
880 845
 		sockinfo_str.len = sockinfo_str.s?strlen (sockinfo_str.s):0;
881 846
 
... ...
@@ -884,15 +849,10 @@ subs_t** get_subs_dialog(str* p_user, str* p_domain, ev_t* event,str* sender, in
884 849
 		
885 850
 
886 851
 		size= sizeof(subs_t)+ (p_user->len+ p_domain->len+ from_user.len+ 
887
-				from_domain.len+ event_id.len+ to_tag.len+ 
852
+				from_domain.len+ event_id.len+ to_tag.len+ status.len+
888 853
 				from_tag.len+ callid.len+ record_route.len+ contact.len+
889 854
 				sockinfo_str.len+ local_contact.len)* sizeof(char);
890 855
 
891
-		if(force_active== 0)
892
-			size+= status.len* sizeof(char);
893
-		else
894
-			size+= 6;
895
-
896 856
 		subs= (subs_t*)pkg_malloc(size);
897 857
 		if(subs ==NULL)
898 858
 		{
... ...
@@ -913,7 +873,6 @@ subs_t** get_subs_dialog(str* p_user, str* p_domain, ev_t* event,str* sender, in
913 873
 		subs->to_domain.len = p_domain->len;
914 874
 		size+= p_domain->len;
915 875
 	
916
-
917 876
 		subs->event= event;
918 877
 
919 878
 		subs->from_user.s= (char*)subs+ size;
... ...
@@ -961,25 +920,12 @@ subs_t** get_subs_dialog(str* p_user, str* p_domain, ev_t* event,str* sender, in
961 920
 		memcpy(subs->contact.s, contact.s, contact.len);
962 921
 		subs->contact.len = contact.len;
963 922
 		size+= contact.len;
923
+	
924
+		subs->status.s= (char*)subs+ size;
925
+		memcpy(subs->status.s, status.s, status.len);
926
+		subs->status.len = status.len;
927
+		size+= status.len;
964 928
 		
965
-		if(force_active!=0)
966
-		{
967
-			subs->status.s=(char*)subs+ size;
968
-			memcpy(subs->status.s, "active", 6);
969
-			subs->status.len = 6;
970
-			size+= 6;
971
-		}
972
-		else
973
-		{
974
-			if(status.s && status.len)
975
-			{
976
-				subs->status.s= (char*)subs+ size;
977
-				memcpy(subs->status.s, status.s, status.len);
978
-				subs->status.len = status.len;
979
-				size+= status.len;
980
-			}
981
-		}
982
-
983 929
 		subs->sockinfo_str.s =(char*)subs+ size;
984 930
 		memcpy(subs->sockinfo_str.s, sockinfo_str.s, sockinfo_str.len);
985 931
 		subs->sockinfo_str.len = sockinfo_str.len;
... ...
@@ -1036,7 +982,7 @@ int query_db_notify(str* p_user, str* p_domain, ev_t* event,
1036 982
 	
1037 983
 	if(event->type & PUBL_TYPE)
1038 984
 	{
1039
-		notify_body = get_p_notify_body(*p_user, *p_domain, etag, event);
985
+		notify_body = get_p_notify_body(*p_user, *p_domain, etag, event, NULL);
1040 986
 		if(notify_body == NULL)
1041 987
 		{
1042 988
 			DBG( "PRESENCE:query_db_notify: Could not get the"
... ...
@@ -1091,328 +1037,6 @@ error:
1091 1037
 	return -1;
1092 1038
 }
1093 1039
 
1094
-xmlNodePtr is_watcher_allowed( subs_t* subs, xmlDocPtr xcap_tree )
1095
-{
1096
-	xmlNodePtr ruleset_node = NULL, node1= NULL, node2= NULL;
1097
-	xmlNodePtr cond_node = NULL, except_node = NULL, actions_node = NULL;
1098
-	xmlNodePtr identity_node = NULL, validity_node =NULL, sphere_node = NULL;
1099
-	xmlNodePtr sub_handling_node = NULL;
1100
-	int apply_rule = -1;
1101
-	char* id = NULL, *domain = NULL;
1102
-	str w_uri;
1103
-	char* sub_handling = NULL;
1104
-
1105
-	if(xcap_tree == NULL)
1106
-	{
1107
-		LOG(L_ERR, "PRESENCE: is_watcher_allowed: The authorization document"
1108
-				" is NULL\n");
1109
-		return NULL;
1110
-	}
1111
-	
1112
-	uandd_to_uri(subs->from_user, subs->from_domain, &w_uri);
1113
-	if(w_uri.s == NULL)
1114
-	{
1115
-		LOG(L_ERR, "PRESENCE: is_watcher_allowed:Error while creating uri\n");
1116
-		return NULL;
1117
-	}
1118
-	ruleset_node = xmlDocGetNodeByName(xcap_tree, "ruleset", NULL);
1119
-	if(ruleset_node == NULL)
1120
-	{
1121
-		DBG( "PRESENCE:is_watcher_allowed: ruleset_node NULL\n");
1122
-		goto error;
1123
-
1124