git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@2604 689a6050-402a-0410-94f2-e92a70836424
... | ... |
@@ -33,6 +33,7 @@ Anca-Maria Vamanu |
33 | 33 |
1.3.8. expires_offset (int) |
34 | 34 |
1.3.9. max_expires (int) |
35 | 35 |
1.3.10. server_address (str) |
36 |
+ 1.3.11. fallback2db (int) |
|
36 | 37 |
|
37 | 38 |
1.4. Exported Functions |
38 | 39 |
|
... | ... |
@@ -65,8 +66,9 @@ Anca-Maria Vamanu |
65 | 66 |
1-8. Set expires_offset parameter |
66 | 67 |
1-9. Set max_expires parameter |
67 | 68 |
1-10. Set server_address parameter |
68 |
- 1-11. handle_publish usage |
|
69 |
- 1-12. handle_subscribe usage |
|
69 |
+ 1-11. Set fallback2db parameter |
|
70 |
+ 1-12. handle_publish usage |
|
71 |
+ 1-13. handle_subscribe usage |
|
70 | 72 |
2-1. event_api_t structure |
71 | 73 |
_________________________________________________________ |
72 | 74 |
|
... | ... |
@@ -81,14 +83,23 @@ Chapter 1. User's Guide |
81 | 83 |
presence.winfo, dialog;sla from presence_xml module and |
82 | 84 |
message-summary from presence_mwi module. |
83 | 85 |
|
84 |
- The presence server works with database storage. It stores |
|
85 |
- published information and Subscribe -Notify dialog |
|
86 |
- characteristics. |
|
87 |
- |
|
88 |
- It can also work only with the functionality of a library, |
|
89 |
- with no message processing and generation, but used only for |
|
90 |
- the exported functions. This mode of operation is enabled if |
|
91 |
- the db_url parameter is not set to any value. |
|
86 |
+ The modules uses database storage. It has later been improved |
|
87 |
+ with memory caching operations to improve performance. The |
|
88 |
+ Subscribe dialog information are stored in memory and are |
|
89 |
+ periodically updated in database, while for Publish only the |
|
90 |
+ presence or absence of stored info for a certain resource is |
|
91 |
+ maintained in memory to avoid unnecessary, costly db |
|
92 |
+ operations. It is possible to configure a fallback to database |
|
93 |
+ mode(by setting module parameter "fallback2db"). In this mode, |
|
94 |
+ in case a searched record is not found in cache, the search is |
|
95 |
+ continued in database. This is useful for an architecture in |
|
96 |
+ which processing and memory load might be divided on more |
|
97 |
+ machines using the same database. |
|
98 |
+ |
|
99 |
+ The module can also work only with the functionality of a |
|
100 |
+ library, with no message processing and generation, but used |
|
101 |
+ only for the exported functions. This mode of operation is |
|
102 |
+ enabled if the db_url parameter is not set to any value. |
|
92 | 103 |
|
93 | 104 |
The server follows the specifications in: RFC3265, RFC3856, |
94 | 105 |
RFC3857, RFC3858. |
... | ... |
@@ -244,6 +255,20 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060") |
244 | 255 |
... |
245 | 256 |
_________________________________________________________ |
246 | 257 |
|
258 |
+1.3.11. fallback2db (int) |
|
259 |
+ |
|
260 |
+ Setting this parameter enables a fallback to db mode of |
|
261 |
+ operation. In this mode, in case a searched record is not |
|
262 |
+ found in cache, the search is continued in database. Useful |
|
263 |
+ for an architecture in which processing and memory load might |
|
264 |
+ be divided on more machines using the same database. |
|
265 |
+ |
|
266 |
+ Example 1-11. Set fallback2db parameter |
|
267 |
+... |
|
268 |
+modparam("presence", "fallback2db", 1) |
|
269 |
+... |
|
270 |
+ _________________________________________________________ |
|
271 |
+ |
|
247 | 272 |
1.4. Exported Functions |
248 | 273 |
|
249 | 274 |
1.4.1. handle_publish(char* sender_uri) |
... | ... |
@@ -262,7 +287,7 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060") |
262 | 287 |
|
263 | 288 |
This function can be used from REQUEST_ROUTE. |
264 | 289 |
|
265 |
- Example 1-11. handle_publish usage |
|
290 |
+ Example 1-12. handle_publish usage |
|
266 | 291 |
... |
267 | 292 |
if(is_method("PUBLISH")) |
268 | 293 |
{ |
... | ... |
@@ -284,7 +309,7 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060") |
284 | 309 |
|
285 | 310 |
This function can be used from REQUEST_ROUTE. |
286 | 311 |
|
287 |
- Example 1-12. handle_subscribe usage |
|
312 |
+ Example 1-13. handle_subscribe usage |
|
288 | 313 |
... |
289 | 314 |
if(method=="SUBSCRIBE") |
290 | 315 |
handle_subscribe(); |
... | ... |
@@ -20,11 +20,21 @@ |
20 | 20 |
module and message-summary from presence_mwi module. |
21 | 21 |
</para> |
22 | 22 |
<para> |
23 |
- The presence server works with database storage. It stores published information |
|
24 |
- and Subscribe -Notify dialog characteristics. |
|
23 |
+ The modules uses database storage. |
|
24 |
+ It has later been improved with memory caching operations to improve |
|
25 |
+ performance. The Subscribe dialog information are stored in memory and |
|
26 |
+ are periodically updated in database, while for Publish only the presence |
|
27 |
+ or absence of stored info for a certain resource is maintained in memory |
|
28 |
+ to avoid unnecessary, costly db operations. |
|
29 |
+ It is possible to configure a fallback to database mode(by setting module |
|
30 |
+ parameter "fallback2db"). In this mode, in case a searched record is not |
|
31 |
+ found in cache, the search is continued in database. This is useful for |
|
32 |
+ an architecture in which processing and memory load might be divided on |
|
33 |
+ more machines using the same database. |
|
25 | 34 |
</para> |
26 |
- <para>It can also work only with the functionality of a library, with no message |
|
27 |
- processing and generation, but used only for the exported functions. |
|
35 |
+ <para>The module can also work only with the functionality of a library, |
|
36 |
+ with no message processing and generation, but used only for the exported |
|
37 |
+ functions. |
|
28 | 38 |
This mode of operation is enabled if the db_url parameter is not set to any value. |
29 | 39 |
</para> |
30 | 40 |
<para> |
... | ... |
@@ -264,6 +274,24 @@ modparam("presence", "server_address", "sip:10.10.10.10:5060") |
264 | 274 |
</programlisting> |
265 | 275 |
</example> |
266 | 276 |
</section> |
277 |
+<section> |
|
278 |
+ <title><varname>fallback2db</varname> (int)</title> |
|
279 |
+ <para> |
|
280 |
+ Setting this parameter enables a fallback to db mode of operation. |
|
281 |
+ In this mode, in case a searched record is not found in cache, |
|
282 |
+ the search is continued in database. Useful for an architecture in |
|
283 |
+ which processing and memory load might be divided on more machines |
|
284 |
+ using the same database. |
|
285 |
+ </para> |
|
286 |
+ <example> |
|
287 |
+ <title>Set <varname>fallback2db</varname> parameter</title> |
|
288 |
+ <programlisting format="linespecific"> |
|
289 |
+... |
|
290 |
+modparam("presence", "fallback2db", 1) |
|
291 |
+... |
|
292 |
+</programlisting> |
|
293 |
+ </example> |
|
294 |
+ </section> |
|
267 | 295 |
|
268 | 296 |
|
269 | 297 |
</section> |
... | ... |
@@ -31,19 +31,93 @@ |
31 | 31 |
#include <string.h> |
32 | 32 |
#include "../../str.h" |
33 | 33 |
#include "../../dprint.h" |
34 |
+#include "../../parser/parse_event.h" |
|
34 | 35 |
#include "../../mem/shm_mem.h" |
36 |
+#include "../../mem/mem.h" |
|
35 | 37 |
#include "event_list.h" |
38 |
+#include "hash.h" |
|
36 | 39 |
|
37 | 40 |
#define MAX_EVNAME_SIZE 20 |
38 | 41 |
|
39 |
-int add_event(ev_t* event) |
|
42 |
+event_t* shm_copy_event(event_t* e) |
|
40 | 43 |
{ |
41 |
- ev_t* ev= NULL; |
|
44 |
+ event_t* ev= NULL; |
|
45 |
+ param_t* p1, *p2; |
|
42 | 46 |
int size; |
43 |
- char* sep= NULL; |
|
47 |
+ |
|
48 |
+ ev= (event_t*)shm_malloc(sizeof(event_t)); |
|
49 |
+ if(ev== NULL) |
|
50 |
+ { |
|
51 |
+ ERR_MEM("shm_copy_event"); |
|
52 |
+ } |
|
53 |
+ memset(ev, 0, sizeof(event_t)); |
|
54 |
+ |
|
55 |
+ ev->text.s= (char*)shm_malloc(e->text.len* sizeof(char)); |
|
56 |
+ if(ev->text.s== NULL) |
|
57 |
+ { |
|
58 |
+ ERR_MEM("shm_copy_event"); |
|
59 |
+ } |
|
60 |
+ memcpy(ev->text.s, e->text.s, e->text.len); |
|
61 |
+ ev->text.len= e->text.len; |
|
62 |
+ |
|
63 |
+ p1= e->params; |
|
64 |
+ while(p1) |
|
65 |
+ { |
|
66 |
+ size= sizeof(param_t)+ (p1->name.len+ p1->body.len)* sizeof(char); |
|
67 |
+ p2= (param_t*)shm_malloc(size); |
|
68 |
+ if(p2== NULL) |
|
69 |
+ { |
|
70 |
+ ERR_MEM("shm_copy_event"); |
|
71 |
+ } |
|
72 |
+ memset(p2, 0, size); |
|
73 |
+ |
|
74 |
+ size= sizeof(param_t); |
|
75 |
+ CONT_COPY(p2, p2->name, p1->name); |
|
76 |
+ if(p1->body.s && p1->body.len) |
|
77 |
+ CONT_COPY(p2, p2->body, p1->body); |
|
78 |
+ p2->next= ev->params; |
|
79 |
+ ev->params= p2; |
|
80 |
+ p1= p1->next; |
|
81 |
+ } |
|
82 |
+ ev->parsed= e->parsed; |
|
83 |
+ |
|
84 |
+ return ev; |
|
85 |
+ |
|
86 |
+error: |
|
87 |
+ shm_free_event(ev); |
|
88 |
+ return NULL; |
|
89 |
+} |
|
90 |
+ |
|
91 |
+void shm_free_event(event_t* ev) |
|
92 |
+{ |
|
93 |
+ param_t* p1, *p2; |
|
94 |
+ |
|
95 |
+ if(ev== NULL) |
|
96 |
+ return; |
|
97 |
+ |
|
98 |
+ if(ev->text.s) |
|
99 |
+ shm_free(ev->text.s); |
|
100 |
+ p1= ev->params; |
|
101 |
+ while(p1) |
|
102 |
+ { |
|
103 |
+ p2= p1; |
|
104 |
+ p1= p1->next; |
|
105 |
+ shm_free(p2); |
|
106 |
+ } |
|
107 |
+ shm_free(ev); |
|
108 |
+} |
|
109 |
+ |
|
110 |
+ |
|
111 |
+int add_event(pres_ev_t* event) |
|
112 |
+{ |
|
113 |
+ pres_ev_t* ev= NULL; |
|
114 |
+ event_t parsed_event; |
|
44 | 115 |
str wipeer_name; |
116 |
+ char* sep; |
|
45 | 117 |
char buf[50]; |
46 |
- int ret_code= 1; |
|
118 |
+ int not_in_list= 0; |
|
119 |
+ |
|
120 |
+ memset(&parsed_event, 0, sizeof(event_t)); |
|
47 | 121 |
|
48 | 122 |
if(event->name.s== NULL || event->name.len== 0) |
49 | 123 |
{ |
... | ... |
@@ -56,70 +130,56 @@ int add_event(ev_t* event) |
56 | 130 |
LOG(L_ERR, "PRESENCE: add_event: NULL content_type param\n"); |
57 | 131 |
return -1; |
58 | 132 |
} |
59 |
- |
|
60 |
- if(contains_event(&event->name, event->param)) |
|
61 |
- { |
|
62 |
- DBG("PRESENCE: add_event: Found prevoius record for event\n"); |
|
63 |
- ret_code= -1; |
|
64 |
- goto done; |
|
65 |
- } |
|
66 |
- size= sizeof(ev_t)+ (event->name.len+ event->content_type.len)*sizeof(char); |
|
67 |
- |
|
68 |
- if(event->param) |
|
69 |
- size+= sizeof(str)+ ( 2*event->param->len + event->name.len+ 2)* sizeof(char); |
|
70 |
- |
|
71 |
- ev= (ev_t*)shm_malloc(size); |
|
133 |
+ |
|
134 |
+ ev= contains_event(&event->name, &parsed_event); |
|
72 | 135 |
if(ev== NULL) |
73 | 136 |
{ |
74 |
- LOG(L_ERR, "PRESENCE: add_event: ERROR while allocating memory\n"); |
|
75 |
- ret_code= -1; |
|
76 |
- goto done; |
|
77 |
- } |
|
78 |
- memset(ev, 0, size); |
|
79 |
- |
|
80 |
- size= sizeof(ev_t); |
|
81 |
- ev->name.s= (char*)ev+ size; |
|
82 |
- ev->name.len= event->name.len; |
|
83 |
- memcpy(ev->name.s, event->name.s, event->name.len); |
|
84 |
- size+= event->name.len; |
|
137 |
+ not_in_list= 1; |
|
138 |
+ ev= (pres_ev_t*)shm_malloc(sizeof(pres_ev_t)); |
|
139 |
+ if(ev== NULL) |
|
140 |
+ { |
|
141 |
+ ERR_MEM("add_event"); |
|
142 |
+ } |
|
143 |
+ memset(ev, 0, sizeof(pres_ev_t)); |
|
144 |
+ ev->name.s= (char*)shm_malloc(event->name.len* sizeof(char)); |
|
145 |
+ if(ev->name.s== NULL) |
|
146 |
+ { |
|
147 |
+ ERR_MEM("add_events"); |
|
148 |
+ } |
|
149 |
+ memcpy(ev->name.s, event->name.s, event->name.len); |
|
150 |
+ ev->name.len= event->name.len; |
|
85 | 151 |
|
86 |
- if(event->param) |
|
87 |
- { |
|
88 |
- ev->param= (str*)((char*)ev+ size); |
|
89 |
- size+= sizeof(str); |
|
90 |
- ev->param->s= (char*)ev+ size; |
|
91 |
- memcpy(ev->param->s, event->param->s, event->param->len); |
|
92 |
- ev->param->len= event->param->len; |
|
93 |
- size+= event->param->len; |
|
94 |
- |
|
95 |
- ev->stored_name.s= (char*)ev+ size; |
|
96 |
- memcpy(ev->stored_name.s, event->name.s, event->name.len); |
|
97 |
- ev->stored_name.len= event->name.len; |
|
98 |
- memcpy(ev->stored_name.s+ ev->stored_name.len, ";", 1); |
|
99 |
- ev->stored_name.len+= 1; |
|
100 |
- memcpy(ev->stored_name.s+ ev->stored_name.len, event->param->s, event->param->len); |
|
101 |
- ev->stored_name.len+= event->param->len; |
|
102 |
- size+= ev->stored_name.len; |
|
152 |
+ ev->evp= shm_copy_event(&parsed_event); |
|
153 |
+ if(ev->evp== NULL) |
|
154 |
+ { |
|
155 |
+ LOG(L_ERR, "PRESENCE:add_event:ERROR copying event_t structure\n"); |
|
156 |
+ goto error; |
|
157 |
+ } |
|
103 | 158 |
} |
104 | 159 |
else |
105 | 160 |
{ |
106 |
- ev->stored_name.s= ev->name.s; |
|
107 |
- ev->stored_name.len= ev->name.len; |
|
108 |
- } |
|
161 |
+ if(ev->content_type.s) |
|
162 |
+ { |
|
163 |
+ DBG("PRESENCE: add_event: Event already registered\n"); |
|
164 |
+ return 0; |
|
165 |
+ } |
|
166 |
+ } |
|
109 | 167 |
|
110 |
- ev->content_type.s= (char*)ev+ size; |
|
168 |
+ ev->content_type.s=(char*)shm_malloc(event->content_type.len* sizeof(char)) ; |
|
169 |
+ if(ev->content_type.s== NULL) |
|
170 |
+ { |
|
171 |
+ ERR_MEM("add_event"); |
|
172 |
+ } |
|
111 | 173 |
ev->content_type.len= event->content_type.len; |
112 | 174 |
memcpy(ev->content_type.s, event->content_type.s, event->content_type.len); |
113 |
- size+= ev->content_type.len; |
|
114 | 175 |
|
115 | 176 |
sep= strchr(event->name.s, '.'); |
116 |
- |
|
117 | 177 |
if(sep && strncmp(sep+1, "winfo", 5)== 0) |
118 | 178 |
{ |
119 | 179 |
ev->type= WINFO_TYPE; |
120 | 180 |
wipeer_name.s= event->name.s; |
121 | 181 |
wipeer_name.len= sep - event->name.s; |
122 |
- ev->wipeer= contains_event(&wipeer_name, ev->param ); |
|
182 |
+ ev->wipeer= contains_event(&wipeer_name, NULL); |
|
123 | 183 |
} |
124 | 184 |
else |
125 | 185 |
{ |
... | ... |
@@ -129,7 +189,7 @@ int add_event(ev_t* event) |
129 | 189 |
wipeer_name.len= event->name.len; |
130 | 190 |
memcpy(wipeer_name.s+ wipeer_name.len, ".winfo", 6); |
131 | 191 |
wipeer_name.len+= 6; |
132 |
- ev->wipeer= contains_event(&wipeer_name, ev->param); |
|
192 |
+ ev->wipeer= contains_event(&wipeer_name, NULL); |
|
133 | 193 |
} |
134 | 194 |
|
135 | 195 |
if(ev->wipeer) |
... | ... |
@@ -144,15 +204,36 @@ int add_event(ev_t* event) |
144 | 204 |
ev->free_body= event->free_body; |
145 | 205 |
ev->default_expires= event->default_expires; |
146 | 206 |
|
147 |
- ev->next= EvList->events; |
|
148 |
- EvList->events= ev; |
|
207 |
+ if(not_in_list) |
|
208 |
+ { |
|
209 |
+ ev->next= EvList->events; |
|
210 |
+ EvList->events= ev; |
|
211 |
+ } |
|
149 | 212 |
EvList->ev_count++; |
150 |
- |
|
151 |
- DBG("PRESENCE: add_event: succesfully added event: %.*s - len= %d\n", |
|
152 |
- ev->stored_name.len, ev->stored_name.s, ev->stored_name.len); |
|
153 |
-done: |
|
154 | 213 |
|
155 |
- return ret_code; |
|
214 |
+ DBG("PRESENCE: add_event: succesfully added event: %.*s - len= %d\n", |
|
215 |
+ ev->name.len, ev->name.s, ev->name.len); |
|
216 |
+ return 0; |
|
217 |
+error: |
|
218 |
+ if(ev && not_in_list) |
|
219 |
+ { |
|
220 |
+ free_pres_event(ev); |
|
221 |
+ } |
|
222 |
+ return -1; |
|
223 |
+} |
|
224 |
+ |
|
225 |
+void free_pres_event(pres_ev_t* ev) |
|
226 |
+{ |
|
227 |
+ if(ev== NULL) |
|
228 |
+ return; |
|
229 |
+ |
|
230 |
+ if(ev->name.s) |
|
231 |
+ shm_free(ev->name.s); |
|
232 |
+ if(ev->content_type.s) |
|
233 |
+ shm_free(ev->content_type.s); |
|
234 |
+ shm_free_event(ev->evp); |
|
235 |
+ shm_free(ev); |
|
236 |
+ |
|
156 | 237 |
} |
157 | 238 |
|
158 | 239 |
evlist_t* init_evlist() |
... | ... |
@@ -171,52 +252,74 @@ evlist_t* init_evlist() |
171 | 252 |
return list; |
172 | 253 |
} |
173 | 254 |
|
174 |
-ev_t* contains_event(str* name, str* param) |
|
255 |
+pres_ev_t* contains_event(str* sname, event_t* parsed_event) |
|
175 | 256 |
{ |
176 |
- ev_t* event; |
|
177 |
- event= EvList->events; |
|
257 |
+ event_t event; |
|
258 |
+ pres_ev_t* e; |
|
178 | 259 |
|
179 |
- while(event) |
|
260 |
+ if(event_parser(sname->s, sname->len, &event)< 0) |
|
180 | 261 |
{ |
181 |
- if(event->name.len== name->len && |
|
182 |
- strncmp(event->name.s, name->s, name->len)== 0) |
|
183 |
- { |
|
184 |
- // verify if there is a restrictive params and if it equals the given one |
|
185 |
- if(!event->param) |
|
186 |
- return event; |
|
187 |
- |
|
188 |
- if(!param) |
|
189 |
- return NULL; |
|
190 |
- |
|
191 |
- if(event->param->len== param->len && |
|
192 |
- strncmp(event->param->s, param->s, param->len)== 0) |
|
193 |
- return event; |
|
262 |
+ LOG(L_ERR, "PRESENCE:contains_event: ERROR parsing event\n"); |
|
263 |
+ return NULL; |
|
264 |
+ } |
|
265 |
+ if(parsed_event) |
|
266 |
+ *parsed_event= event; |
|
194 | 267 |
|
195 |
- } |
|
196 |
- |
|
197 |
- event= event->next; |
|
198 |
- } |
|
268 |
+ e= search_event(&event); |
|
199 | 269 |
|
200 |
- return NULL; |
|
270 |
+ return e; |
|
201 | 271 |
} |
272 |
+ |
|
202 | 273 |
|
203 |
-ev_t* get_sname_event(str* stored_name) |
|
274 |
+pres_ev_t* search_event(event_t* event) |
|
204 | 275 |
{ |
205 |
- ev_t* event; |
|
206 |
- event= EvList->events; |
|
276 |
+ pres_ev_t* pres_ev; |
|
277 |
+ pres_ev= EvList->events; |
|
278 |
+ param_t* ps, *p; |
|
279 |
+ int found; |
|
207 | 280 |
|
208 |
- while(event) |
|
281 |
+ DBG("PRESENCE:search_event...\n"); |
|
282 |
+ while(pres_ev) |
|
209 | 283 |
{ |
210 |
- if(stored_name->len== event->stored_name.len && |
|
211 |
- strncmp(stored_name->s,event->stored_name.s,stored_name->len)==0) |
|
212 |
- return event; |
|
213 |
- event= event->next; |
|
284 |
+ if(pres_ev->evp->parsed== event->parsed) |
|
285 |
+ { |
|
286 |
+ if(event->params== NULL) |
|
287 |
+ return pres_ev; |
|
288 |
+ |
|
289 |
+ /* search all parameters in event in ev */ |
|
290 |
+ ps= event->params; |
|
291 |
+ while(ps) |
|
292 |
+ { |
|
293 |
+ p= pres_ev->evp->params; |
|
294 |
+ found= 0; |
|
295 |
+ while(p) |
|
296 |
+ { |
|
297 |
+ if(p->name.len== ps->name.len && |
|
298 |
+ strncmp(p->name.s,ps->name.s, ps->name.len)== 0) |
|
299 |
+ if((p->body.s== 0 && ps->body.s== 0) || |
|
300 |
+ (p->body.len== ps->body.len && |
|
301 |
+ strncmp(p->body.s,ps->body.s,ps->body.len)== 0)) |
|
302 |
+ { |
|
303 |
+ found= 1; |
|
304 |
+ break; |
|
305 |
+ } |
|
306 |
+ p= p->next; |
|
307 |
+ } |
|
308 |
+ if(found== 0) |
|
309 |
+ return NULL; |
|
310 |
+ ps= ps->next; |
|
311 |
+ } |
|
312 |
+ return pres_ev; |
|
313 |
+ } |
|
314 |
+ pres_ev= pres_ev->next; |
|
214 | 315 |
} |
215 | 316 |
return NULL; |
317 |
+ |
|
216 | 318 |
} |
319 |
+ |
|
217 | 320 |
int get_event_list(str** ev_list) |
218 | 321 |
{ |
219 |
- ev_t* ev= EvList->events; |
|
322 |
+ pres_ev_t* ev= EvList->events; |
|
220 | 323 |
int i; |
221 | 324 |
str* list; |
222 | 325 |
*ev_list= NULL; |
... | ... |
@@ -247,8 +350,8 @@ int get_event_list(str** ev_list) |
247 | 350 |
memcpy(list->s+ list->len, ", ", 2); |
248 | 351 |
list->len+= 2; |
249 | 352 |
} |
250 |
- memcpy(list->s+ list->len, ev->stored_name.s, ev->stored_name.len ); |
|
251 |
- list->len+= ev->stored_name.len ; |
|
353 |
+ memcpy(list->s+ list->len, ev->name.s, ev->name.len ); |
|
354 |
+ list->len+= ev->name.len ; |
|
252 | 355 |
ev= ev->next; |
253 | 356 |
} |
254 | 357 |
|
... | ... |
@@ -258,14 +361,14 @@ int get_event_list(str** ev_list) |
258 | 361 |
|
259 | 362 |
void destroy_evlist() |
260 | 363 |
{ |
261 |
- ev_t* e1, *e2; |
|
364 |
+ pres_ev_t* e1, *e2; |
|
262 | 365 |
if (EvList) |
263 | 366 |
{ |
264 | 367 |
e1= EvList->events; |
265 | 368 |
while(e1) |
266 | 369 |
{ |
267 | 370 |
e2= e1->next; |
268 |
- shm_free(e1); |
|
371 |
+ free_pres_event(e1); |
|
269 | 372 |
e1= e2; |
270 | 373 |
} |
271 | 374 |
shm_free(EvList); |
... | ... |
@@ -30,6 +30,7 @@ |
30 | 30 |
#define _PRES_EV_LST_H |
31 | 31 |
|
32 | 32 |
#include "../../parser/msg_parser.h" |
33 |
+#include "../../parser/parse_event.h" |
|
33 | 34 |
#include "../../str.h" |
34 | 35 |
#include "subscribe.h" |
35 | 36 |
|
... | ... |
@@ -61,12 +62,10 @@ typedef int (is_allowed_t)(struct subscription* subs); |
61 | 62 |
/* event specific body free function */ |
62 | 63 |
typedef void(free_body_t)(char* body); |
63 | 64 |
|
64 |
-struct ev |
|
65 |
+struct pres_ev |
|
65 | 66 |
{ |
66 | 67 |
str name; |
67 |
- str* param; // required param |
|
68 |
- /* to do: transform it in a list ( for multimple param)*/ |
|
69 |
- str stored_name; |
|
68 |
+ event_t* evp; |
|
70 | 69 |
str content_type; |
71 | 70 |
int default_expires; |
72 | 71 |
int type; |
... | ... |
@@ -94,31 +93,27 @@ struct ev |
94 | 93 |
publ_handling_t * evs_publ_handl; |
95 | 94 |
subs_handling_t * evs_subs_handl; |
96 | 95 |
free_body_t* free_body; |
97 |
- struct ev* wipeer; |
|
98 |
- struct ev* next; |
|
96 |
+ struct pres_ev* wipeer; |
|
97 |
+ struct pres_ev* next; |
|
99 | 98 |
|
100 | 99 |
}; |
101 |
-typedef struct ev ev_t; |
|
100 |
+typedef struct pres_ev pres_ev_t; |
|
102 | 101 |
|
103 | 102 |
typedef struct evlist |
104 | 103 |
{ |
105 | 104 |
int ev_count; |
106 |
- ev_t* events; |
|
105 |
+ pres_ev_t* events; |
|
107 | 106 |
}evlist_t; |
108 | 107 |
|
109 | 108 |
evlist_t* init_evlist(); |
110 | 109 |
|
111 |
-int add_event(ev_t* event); |
|
110 |
+int add_event(pres_ev_t* event); |
|
112 | 111 |
|
113 |
-typedef int (*add_event_t)(ev_t* event); |
|
112 |
+typedef int (*add_event_t)(pres_ev_t* event); |
|
114 | 113 |
|
115 |
-ev_t* contains_event(str* name, str* param); |
|
114 |
+pres_ev_t* contains_event(str* name, event_t* parsed_event); |
|
116 | 115 |
|
117 |
-typedef ev_t* (*contains_event_t) (str* name, str* param); |
|
118 |
- |
|
119 |
-ev_t* get_sname_event(str* stored_name); |
|
120 |
- |
|
121 |
-typedef ev_t* (*get_sname_event_t)(str* stored_name); |
|
116 |
+typedef pres_ev_t* (*contains_event_t)(str* name, event_t* parsed_event); |
|
122 | 117 |
|
123 | 118 |
int get_event_list(str** ev_list); |
124 | 119 |
|
... | ... |
@@ -128,4 +123,13 @@ void destroy_evlist(); |
128 | 123 |
|
129 | 124 |
extern evlist_t* EvList; |
130 | 125 |
|
126 |
+pres_ev_t* search_event(event_t* event); |
|
127 |
+ |
|
128 |
+event_t* shm_copy_event(event_t* e); |
|
129 |
+ |
|
130 |
+void shm_free_event(event_t* ev); |
|
131 |
+ |
|
132 |
+void free_pres_event(pres_ev_t* ev); |
|
133 |
+ |
|
134 |
+ |
|
131 | 135 |
#endif |
... | ... |
@@ -38,8 +38,9 @@ |
38 | 38 |
#include "../../str.h" |
39 | 39 |
#include "../../db/db.h" |
40 | 40 |
#include "../../db/db_val.h" |
41 |
-#include "../tm/tm_load.h" |
|
42 | 41 |
#include "../../socket_info.h" |
42 |
+#include "../tm/tm_load.h" |
|
43 |
+#include "../pua/hash.h" |
|
43 | 44 |
#include "presentity.h" |
44 | 45 |
#include "presence.h" |
45 | 46 |
#include "notify.h" |
... | ... |
@@ -49,38 +50,47 @@ |
49 | 50 |
#define MAX_FORWARD 70 |
50 | 51 |
|
51 | 52 |
extern struct tm_binds tmb; |
52 |
-c_back_param* shm_dup_subs(subs_t* subs, str to_tag); |
|
53 |
+c_back_param* shm_dup_cbparam(subs_t* , subs_t*); |
|
54 |
+void free_cbparam(c_back_param* cb_param); |
|
53 | 55 |
|
54 | 56 |
void p_tm_callback( struct cell *t, int type, struct tmcb_params *ps); |
55 | 57 |
|
58 |
+char* get_status_str(int status_flag) |
|
59 |
+{ |
|
60 |
+ switch(status_flag) |
|
61 |
+ { |
|
62 |
+ case ACTIVE_STATUS: return "active"; |
|
63 |
+ case PENDING_STATUS: return "pending"; |
|
64 |
+ case TERMINATED_STATUS: return "terminated"; |
|
65 |
+ } |
|
66 |
+ return NULL; |
|
67 |
+} |
|
68 |
+ |
|
56 | 69 |
void printf_subs(subs_t* subs) |
57 | 70 |
{ |
58 |
- DBG("\n\tpres_user= %.*s - len: %d\tpres_domain= %.*s - len: %d", |
|
59 |
- subs->pres_user.len, subs->pres_user.s, subs->pres_user.len, |
|
60 |
- subs->pres_domain.len, subs->pres_domain.s, subs->pres_domain.len); |
|
61 |
- DBG("\n\t[p_user]= %.*s [p_domain]= %.*s\n\t[w_user]= %.*s " |
|
62 |
- "[w_domain]= %.*s\n", |
|
63 |
- subs->to_user.len, subs->to_user.s, subs->to_domain.len, |
|
64 |
- subs->to_domain.s, |
|
65 |
- subs->from_user.len, subs->from_user.s, subs->from_domain.len, |
|
66 |
- subs->from_domain.s); |
|
67 |
- DBG("[event]= %.*s\n\t[status]= %.*s\n\t[expires]= %d\n", |
|
68 |
- subs->event->stored_name.len, subs->event->stored_name.s, subs->status.len, subs->status.s, |
|
69 |
- subs->expires ); |
|
70 |
- DBG("[to_tag]= %.*s\n\t[from_tag]= %.*s\n", |
|
71 |
- subs->to_tag.len, subs->to_tag.s, subs->from_tag.len, subs->from_tag.s); |
|
72 |
- DBG("[contact]= %.*s\n", |
|
73 |
- subs->contact.len, subs->contact.s); |
|
71 |
+ DBG("\t[pres_uri]= %.*s - len: %d", |
|
72 |
+ subs->pres_uri.len, subs->pres_uri.s, subs->pres_uri.len); |
|
73 |
+ DBG("\n\t[to_user]= %.*s\t[to_domain]= %.*s\n\t[w_user]= %.*s" |
|
74 |
+ "\t[w_domain]= %.*s",subs->to_user.len,subs->to_user.s, |
|
75 |
+ subs->to_domain.len,subs->to_domain.s,subs->from_user.len, |
|
76 |
+ subs->from_user.s, subs->from_domain.len,subs->from_domain.s); |
|
77 |
+ DBG("\n\t[event]= %.*s\n\t[status]= %s\n\t[expires]= %u", |
|
78 |
+ subs->event->name.len, subs->event->name.s, |
|
79 |
+ get_status_str(subs->status), subs->expires ); |
|
80 |
+ DBG("\n\t[to_tag]= %.*s\n\t[from_tag]= %.*s",subs->to_tag.len, |
|
81 |
+ subs->to_tag.s, subs->from_tag.len, subs->from_tag.s); |
|
82 |
+ DBG("\n\t[contact]= %.*s\n",subs->contact.len, subs->contact.s); |
|
74 | 83 |
} |
75 |
-str* create_winfo_xml(watcher_t* watchers,int n, char* version,char* resource, int STATE_FLAG ); |
|
84 |
+str* create_winfo_xml(watcher_t* watchers, char* version,str resource, int STATE_FLAG ); |
|
76 | 85 |
|
77 | 86 |
int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
78 | 87 |
{ |
79 | 88 |
str* str_hdr = NULL; |
80 | 89 |
char* subs_expires = NULL; |
81 | 90 |
int len = 0; |
82 |
- ev_t* event= subs->event; |
|
91 |
+ pres_ev_t* event= subs->event; |
|
83 | 92 |
int expires_t; |
93 |
+ char* status= NULL; |
|
84 | 94 |
|
85 | 95 |
str_hdr =(str*)pkg_malloc(sizeof(str)); |
86 | 96 |
if(str_hdr== NULL) |
... | ... |
@@ -114,9 +124,9 @@ int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
114 | 124 |
|
115 | 125 |
strncpy(str_hdr->s+str_hdr->len ,"Event: ", 7); |
116 | 126 |
str_hdr->len+= 7; |
117 |
- strncpy(str_hdr->s+str_hdr->len, event->stored_name.s, event->stored_name.len); |
|
118 |
- str_hdr->len+= event->stored_name.len; |
|
119 |
- if (subs->event_id.len) |
|
127 |
+ strncpy(str_hdr->s+str_hdr->len, event->name.s, event->name.len); |
|
128 |
+ str_hdr->len+= event->name.len; |
|
129 |
+ if(subs->event_id.len && subs->event_id.s) |
|
120 | 130 |
{ |
121 | 131 |
strncpy(str_hdr->s+str_hdr->len, ";id=", 4); |
122 | 132 |
str_hdr->len += 4; |
... | ... |
@@ -126,7 +136,6 @@ int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
126 | 136 |
strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN); |
127 | 137 |
str_hdr->len += CRLF_LEN; |
128 | 138 |
|
129 |
- |
|
130 | 139 |
strncpy(str_hdr->s+str_hdr->len ,"Contact: <", 10); |
131 | 140 |
str_hdr->len += 10; |
132 | 141 |
strncpy(str_hdr->s+str_hdr->len, subs->local_contact.s, subs->local_contact.len); |
... | ... |
@@ -135,15 +144,34 @@ int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
135 | 144 |
str_hdr->len += 1; |
136 | 145 |
strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN); |
137 | 146 |
str_hdr->len += CRLF_LEN; |
138 |
- |
|
139 |
- if(strncmp(subs->status.s, "terminated",10) == 0) |
|
147 |
+ |
|
148 |
+ strncpy(str_hdr->s+str_hdr->len,"Subscription-State: ", 20); |
|
149 |
+ str_hdr->len+= 20; |
|
150 |
+ status= get_status_str(subs->status); |
|
151 |
+ if(status== NULL) |
|
152 |
+ { |
|
153 |
+ LOG(L_ERR,"PRESENCE: build_str_hdr: ERROR bad status flag= %d\n", |
|
154 |
+ subs->status); |
|
155 |
+ pkg_free(str_hdr->s); |
|
156 |
+ pkg_free(str_hdr); |
|
157 |
+ return -1; |
|
158 |
+ } |
|
159 |
+ strcpy(str_hdr->s+str_hdr->len, status); |
|
160 |
+ str_hdr->len+= strlen(status); |
|
161 |
+ |
|
162 |
+ if(subs->expires <= 0) |
|
163 |
+ { |
|
164 |
+ expires_t = 0; |
|
165 |
+ subs->status= TERMINATED_STATUS; |
|
166 |
+ subs->reason.s= "timeout"; |
|
167 |
+ subs->reason.len= 7; |
|
168 |
+ } |
|
169 |
+ else |
|
170 |
+ expires_t= subs->expires; |
|
171 |
+ |
|
172 |
+ if(subs->status== TERMINATED_STATUS) |
|
140 | 173 |
{ |
141 | 174 |
DBG( "PRESENCE: build_str_hdr: state = terminated \n"); |
142 |
- |
|
143 |
- strncpy(str_hdr->s+str_hdr->len,"Subscription-State: ", 20); |
|
144 |
- str_hdr->len+= 20; |
|
145 |
- strncpy(str_hdr->s+str_hdr->len, subs->status.s ,subs->status.len ); |
|
146 |
- str_hdr->len+= subs->status.len; |
|
147 | 175 |
|
148 | 176 |
strncpy(str_hdr->s+str_hdr->len,";reason=", 8); |
149 | 177 |
str_hdr->len+= 8; |
... | ... |
@@ -151,22 +179,12 @@ int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
151 | 179 |
str_hdr->len+= subs->reason.len; |
152 | 180 |
strncpy(str_hdr->s+str_hdr->len, CRLF, CRLF_LEN); |
153 | 181 |
str_hdr->len+= CRLF_LEN; |
154 |
- |
|
155 | 182 |
} |
156 | 183 |
else |
157 | 184 |
{ |
158 |
- strncpy(str_hdr->s+str_hdr->len,"Subscription-State: ", 20); |
|
159 |
- str_hdr->len += 20; |
|
160 |
- strncpy(str_hdr->s+str_hdr->len, subs->status.s ,subs->status.len ); |
|
161 |
- str_hdr->len += subs->status.len; |
|
162 | 185 |
strncpy(str_hdr->s+str_hdr->len,";expires=", 9); |
163 | 186 |
str_hdr->len+= 9; |
164 | 187 |
|
165 |
- if(subs->expires < 0) |
|
166 |
- expires_t = 0; |
|
167 |
- else |
|
168 |
- expires_t= subs->expires; |
|
169 |
- |
|
170 | 188 |
subs_expires= int2str(expires_t, &len); |
171 | 189 |
|
172 | 190 |
if(subs_expires == NULL || len == 0) |
... | ... |
@@ -196,7 +214,14 @@ int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
196 | 214 |
str_hdr->len += CRLF_LEN; |
197 | 215 |
} |
198 | 216 |
} |
217 |
+ if(str_hdr->len> ALLOC_SIZE) |
|
218 |
+ { |
|
219 |
+ LOG(L_ERR, "PRESENCE:build_str_hdr:ERROR buffer size overflown\n"); |
|
220 |
+ pkg_free(str_hdr->s); |
|
221 |
+ pkg_free(str_hdr); |
|
222 |
+ return -1; |
|
199 | 223 |
|
224 |
+ } |
|
200 | 225 |
str_hdr->s[str_hdr->len] = '\0'; |
201 | 226 |
*hdr= str_hdr; |
202 | 227 |
|
... | ... |
@@ -204,8 +229,9 @@ int build_str_hdr(subs_t* subs, int is_body, str** hdr) |
204 | 229 |
|
205 | 230 |
} |
206 | 231 |
|
207 |
-str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs) |
|
208 |
-{ |
|
232 |
+int get_wi_subs_db(subs_t* subs, watcher_t** watchers) |
|
233 |
+{ |
|
234 |
+ watcher_t *w; |
|
209 | 235 |
db_key_t query_cols[6]; |
210 | 236 |
db_op_t query_ops[6]; |
211 | 237 |
db_val_t query_vals[6]; |
... | ... |
@@ -213,209 +239,293 @@ str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs) |
213 | 239 |
db_res_t *result = NULL; |
214 | 240 |
db_row_t *row = NULL ; |
215 | 241 |
db_val_t *row_vals = NULL; |
216 |
- str* notify_body = NULL; |
|
217 |
- str p_uri; |
|
218 |
- char* version_str; |
|
219 |
- watcher_t *watchers = NULL; |
|
220 |
- watcher_t swatchers; |
|
221 | 242 |
int n_result_cols = 0; |
222 | 243 |
int n_query_cols = 0; |
223 |
- int i , len = 0; |
|
244 |
+ int i; |
|
224 | 245 |
int status_col, expires_col, from_user_col, from_domain_col; |
225 |
- |
|
226 |
- uandd_to_uri(subs->to_user, subs->to_domain, &p_uri); |
|
227 |
- if(p_uri.s == NULL) |
|
228 |
- { |
|
229 |
- LOG(L_ERR,"PRESENCE:get_wi_notify_body: ERROR while creating uri\n"); |
|
230 |
- return NULL; |
|
231 |
- } |
|
232 |
- |
|
233 |
- memset(&swatchers, 0, sizeof(watcher_t)); |
|
234 |
- version_str = int2str(subs->version, &len); |
|
235 |
- |
|
236 |
- if(version_str ==NULL) |
|
237 |
- { |
|
238 |
- LOG(L_ERR,"PRESENCE:get_wi_notify_body: ERROR while converting int" |
|
239 |
- " to str\n "); |
|
240 |
- goto error; |
|
241 |
- } |
|
242 |
- |
|
243 |
- if(watcher_subs != NULL) /*no need to query data base */ |
|
244 |
- { |
|
245 |
- |
|
246 |
- swatchers.status= watcher_subs->status; |
|
247 |
- uandd_to_uri( watcher_subs->from_user,watcher_subs->from_domain, |
|
248 |
- &swatchers.uri); |
|
249 |
- if(swatchers.uri.s== NULL) |
|
250 |
- goto error; |
|
251 |
- |
|
252 |
- swatchers.id.s = (char *)pkg_malloc(swatchers.uri.len *2 +1); |
|
253 |
- if(swatchers.id.s==0) |
|
254 |
- { |
|
255 |
- LOG(L_ERR,"PRESENCE:get_wi_notify_body: ERROR no more pkg mem\n"); |
|
256 |
- pkg_free(swatchers.uri.s); |
|
257 |
- goto error; |
|
258 |
- } |
|
259 |
- to64frombits((unsigned char *)swatchers.id.s, |
|
260 |
- (const unsigned char*) swatchers.uri.s, swatchers.uri.len ); |
|
261 |
- |
|
262 |
- swatchers.id.len = strlen(swatchers.id.s); |
|
263 |
- |
|
264 |
- swatchers.event= watcher_subs->event->stored_name; |
|
265 |
- |
|
266 |
- notify_body = create_winfo_xml(&swatchers, 1, version_str,p_uri.s, |
|
267 |
- PARTIAL_STATE_FLAG ); |
|
268 |
- |
|
269 |
- if(swatchers.uri.s !=NULL) |
|
270 |
- pkg_free(swatchers.uri.s ); |
|
271 |
- if(swatchers.id.s !=NULL) |
|
272 |
- pkg_free(swatchers.id.s ); |
|
273 |
- |
|
274 |
- pkg_free(p_uri.s); |
|
275 |
- return notify_body; |
|
276 |
- } |
|
277 |
- |
|
278 |
- query_cols[n_query_cols] = "pres_user"; |
|
279 |
- query_ops[n_query_cols] = OP_EQ; |
|
280 |
- query_vals[n_query_cols].type = DB_STR; |
|
281 |
- query_vals[n_query_cols].nul = 0; |
|
282 |
- query_vals[n_query_cols].val.str_val= subs->pres_user; |
|
283 |
- n_query_cols++; |
|
246 |
+ str from_user, from_domain; |
|
284 | 247 |
|
285 |
- query_cols[n_query_cols] = "pres_domain"; |
|
248 |
+ query_cols[n_query_cols] = "pres_uri"; |
|
286 | 249 |
query_ops[n_query_cols] = OP_EQ; |
287 | 250 |
query_vals[n_query_cols].type = DB_STR; |
288 | 251 |
query_vals[n_query_cols].nul = 0; |
289 |
- query_vals[n_query_cols].val.str_val = subs->pres_domain; |
|
252 |
+ query_vals[n_query_cols].val.str_val= subs->pres_uri; |
|
290 | 253 |
n_query_cols++; |
291 | 254 |
|
292 |
- |
|
293 | 255 |
query_cols[n_query_cols] = "event"; |
294 | 256 |
query_ops[n_query_cols] = OP_EQ; |
295 | 257 |
query_vals[n_query_cols].type = DB_STR; |
296 | 258 |
query_vals[n_query_cols].nul = 0; |
297 |
- query_vals[n_query_cols].val.str_val = subs->event->wipeer->stored_name; |
|
259 |
+ query_vals[n_query_cols].val.str_val = subs->event->wipeer->name; |
|
298 | 260 |
n_query_cols++; |
299 | 261 |
|
300 | 262 |
result_cols[status_col=n_result_cols++] = "status" ; |
301 | 263 |
result_cols[expires_col=n_result_cols++] = "expires"; |
302 | 264 |
result_cols[from_user_col=n_result_cols++] = "from_user"; |
303 | 265 |
result_cols[from_domain_col=n_result_cols++] = "from_domain"; |
304 |
- |
|
305 | 266 |
|
306 | 267 |
if (pa_dbf.use_table(pa_db, active_watchers_table) < 0) |
307 | 268 |
{ |
308 |
- LOG(L_ERR, "PRESENCE:get_wi_notify_body: Error in use_table\n"); |
|
269 |
+ LOG(L_ERR, "PRESENCE:get_wi_subs_db: Error in use_table\n"); |
|
309 | 270 |
goto error; |
310 | 271 |
} |
311 | 272 |
|
312 |
- DBG("PRESENCE:get_wi_notify_body: querying database \n"); |
|
313 | 273 |
if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals, |
314 | 274 |
result_cols, n_query_cols, n_result_cols, 0, &result) < 0) |
315 | 275 |
{ |
316 |
- LOG(L_ERR, "PRESENCE:get_wi_notify_body: Error while querying" |
|
317 |
- " presentity\n"); |
|
276 |
+ LOG(L_ERR, "PRESENCE:get_wi_subs_db: Error while querying" |
|
277 |
+ " watchers\n"); |
|
318 | 278 |
goto error; |
319 | 279 |
} |
320 | 280 |
|
321 |
- if (result== NULL ) |
|
281 |
+ if(result== NULL ) |
|
322 | 282 |
{ |
323 |
- LOG(L_ERR, "PRESENCE: get_wi_notify_body:The query returned no" |
|
283 |
+ LOG(L_ERR, "PRESENCE: get_wi_subs_db:The query returned no" |
|
324 | 284 |
" result\n"); |
325 | 285 |
goto error; |
326 | 286 |
} |
327 |
- else |
|
328 |
- if(result->n >0) |
|
287 |
+ |
|
288 |
+ if(result->n <= 0) |
|
289 |
+ { |
|
290 |
+ DBG("PRESENCEget_wi_subs_db:The query in databse returned no result\n"); |
|
291 |
+ pa_dbf.free_result(pa_db, result); |
|
292 |
+ return 0; |
|
293 |
+ } |
|
294 |
+ |
|
295 |
+ for(i=0; i<result->n; i++) |
|
329 | 296 |
{ |
330 |
- str from_user; |
|
331 |
- str from_domain; |
|
297 |
+ row = &result->rows[i]; |
|
298 |
+ row_vals = ROW_VALUES(row); |
|
299 |
+ |
|
300 |
+ from_user.s= (char*)row_vals[from_user_col].val.string_val; |
|
301 |
+ from_user.len= strlen(from_user.s); |
|
332 | 302 |
|
333 |
- watchers =(watcher_t*)pkg_malloc( (result->n+1)*sizeof(watcher_t)); |
|
334 |
- if(watchers == NULL) |
|
303 |
+ from_domain.s= (char*)row_vals[from_domain_col].val.string_val; |
|
304 |
+ from_domain.len= strlen(from_domain.s); |
|
305 |
+ |
|
306 |
+ w= (watcher_t*)pkg_malloc(sizeof(watcher_t)); |
|
307 |
+ if(w== NULL) |
|
335 | 308 |
{ |
336 |
- LOG(L_ERR, "PRESENCE:get_wi_notify_body:ERROR while allocating" |
|
337 |
- " memory\n"); |
|
309 |
+ ERR_MEM("get_wi_subs_db"); |
|
310 |
+ } |
|
311 |
+ w->status= row_vals[status_col].val.int_val; |
|
312 |
+ if(uandd_to_uri(from_user, from_domain, &w->uri)<0) |
|
313 |
+ { |
|
314 |
+ pkg_free(w); |
|
315 |
+ LOG(L_ERR, "PRESENCE:get_wi_subs_db:ERROR while creating" |
|
316 |
+ " uri\n"); |
|
317 |
+ goto error; |
|
318 |
+ } |
|
319 |
+ w->id.s = (char*)pkg_malloc(w->uri.len*2 +1); |
|
320 |
+ if(w->id.s== NULL) |
|
321 |
+ { |
|
322 |
+ LOG(L_ERR,"PRESENCE:get_wi_notify_body: ERROR no more pkg mem\n"); |
|
323 |
+ pkg_free(w->uri.s); |
|
324 |
+ pkg_free(w); |
|
338 | 325 |
goto error; |
339 | 326 |
} |
340 |
- memset(watchers, 0, (result->n+1)*sizeof(watcher_t)); |
|
341 | 327 |
|
342 |
- for(i=0; i<result->n; i++) |
|
343 |
- { |
|
344 |
- row = &result->rows[i]; |
|
345 |
- row_vals = ROW_VALUES(row); |
|
346 |
- watchers[i].status.s = (char*)row_vals[status_col].val.string_val; |
|
347 |
- watchers[i].status.len= strlen(watchers[i].status.s); |
|
328 |
+ to64frombits((unsigned char *)w->id.s, |
|
329 |
+ (const unsigned char*)w->uri.s, w->uri.len); |
|
330 |
+ |
|
331 |
+ w->id.len = strlen(w->id.s); |
|
332 |
+ w->event= subs->event->wipeer->name; |
|
333 |
+ |
|
334 |
+ w->next= (*watchers)->next; |
|
335 |
+ (*watchers)->next= w; |
|
336 |
+ } |
|
337 |
+ |
|
338 |
+ pa_dbf.free_result(pa_db, result); |
|
339 |
+ return 0; |
|
348 | 340 |
|
349 |
- from_user.s= (char*)row_vals[from_user_col].val.string_val; |
|
350 |
- from_user.len= strlen(from_user.s); |
|
341 |
+error: |
|
342 |
+ if(result) |
|
343 |
+ pa_dbf.free_result(pa_db, result); |
|
344 |
+ return -1; |
|
345 |
+} |
|
351 | 346 |
|
352 |
- from_domain.s= (char*)row_vals[from_domain_col].val.string_val; |
|
353 |
- from_domain.len= strlen(from_domain.s); |
|
347 |
+str* get_wi_notify_body(subs_t* subs, subs_t* watcher_subs) |
|
348 |
+{ |
|
349 |
+ str* notify_body = NULL; |
|
350 |
+ char* version_str; |
|
351 |
+ watcher_t *watchers = NULL, *w= NULL; |
|
352 |
+ int len = 0; |
|
353 |
+ unsigned int hash_code; |
|
354 |
+ subs_t* s= NULL; |
|
354 | 355 |
|
355 |
- if(uandd_to_uri(from_user, from_domain, &watchers[i].uri)<0) |
|
356 |
- { |
|
357 |
- LOG(L_ERR, "PRESENCE:get_wi_notify_body:ERROR while creating" |
|
358 |
- " uri\n"); |
|
359 |
- goto error; |
|
360 |
- } |
|
361 |
- watchers[i].id.s = (char*)pkg_malloc(watchers[i].uri.len*2 +1); |
|
362 |
- to64frombits((unsigned char *)watchers[i].id.s, |
|
363 |
- (const unsigned char*) watchers[i].uri.s,watchers[i].uri.len ); |
|
356 |
+ version_str = int2str(subs->version, &len); |
|
357 |
+ if(version_str ==NULL) |
|
358 |
+ { |
|
359 |
+ LOG(L_ERR,"PRESENCE:get_wi_notify_body: ERROR while converting int" |
|
360 |
+ " to str\n "); |
|
361 |
+ goto error; |
|
362 |
+ } |
|
363 |
+ |
|
364 |
+ watchers= (watcher_t*)pkg_malloc(sizeof(watcher_t)); |
|
365 |
+ if(watchers== NULL) |
|
366 |
+ { |
|
367 |
+ ERR_MEM("get_wi_notify_body"); |
|
368 |
+ } |
|
369 |
+ memset(watchers, 0, sizeof(watcher_t)); |
|
370 |
+ |
|
371 |
+ if(watcher_subs != NULL) |
|
372 |
+ { |
|
373 |
+ w= (watcher_t *)pkg_malloc(sizeof(watcher_t)); |
|
374 |
+ if(w== NULL) |
|
375 |
+ { |
|
376 |
+ ERR_MEM("get_wi_notify_body"); |
|
377 |
+ } |
|
378 |
+ memset(w, 0, sizeof(watcher_t)); |
|
379 |
+ |
|
380 |
+ w->status= watcher_subs->status; |
|
381 |
+ uandd_to_uri( watcher_subs->from_user,watcher_subs->from_domain, |
|
382 |
+ &w->uri); |
|
383 |
+ if(w->uri.s== NULL) |
|
384 |
+ { |
|
385 |
+ pkg_free(w); |
|
386 |
+ goto error; |
|
387 |
+ } |
|
388 |
+ |
|
389 |
+ w->id.s = (char *)pkg_malloc(w->uri.len *2 +1); |
|
390 |
+ if(w->id.s== NULL) |
|
391 |
+ { |
|
392 |
+ pkg_free(w->uri.s); |
|
393 |
+ pkg_free(w); |
|
394 |
+ ERR_MEM("get_wi_notify_body"); |
|
395 |
+ } |
|
396 |
+ to64frombits((unsigned char *)w->id.s, |
|
397 |
+ (const unsigned char*)w->uri.s, w->uri.len ); |
|
364 | 398 |
|
365 |
- watchers[i].id.len = strlen(watchers[i].id.s); |
|
366 |
- watchers[i].event= subs->event->wipeer->stored_name; |
|
399 |
+ w->id.len = strlen(w->id.s); |
|
400 |
+ |
|
401 |
+ w->event= watcher_subs->event->name; |
|
402 |
+ |
|
403 |
+ w->next= watchers->next; |
|
404 |
+ watchers->next= w; |
|
405 |
+ |
|
406 |
+ goto done; |
|
407 |
+ } |
|
408 |
+ |
|
409 |
+ if(fallback2db) |
|
410 |
+ { |
|
411 |
+ if(get_wi_subs_db(subs, &watchers)< 0) |
|
412 |
+ { |
|
413 |
+ LOG(L_ERR, "PRESENCE:get_wi_notify_body: ERROR getting watchers" |
|
414 |
+ "from database\n"); |
|
415 |
+ goto error; |
|
367 | 416 |
} |
368 | 417 |
} |
369 | 418 |
|
370 |
- DBG( "PRESENCE:get_wi_notify_body: the query returned no result\n"); |
|
371 |
- notify_body = create_winfo_xml(watchers, result->n, version_str, p_uri.s, |
|
372 |
- FULL_STATE_FLAG ); |
|
419 |
+ hash_code= core_hash(&subs->pres_uri, &subs->event->name, shtable_size); |
|
420 |
+ DBG("PRESENCE:get_wi_notify_body:hash_code= %u\n", hash_code); |
|
421 |
+ lock_get(&subs_htable[hash_code].lock); |
|
422 |
+ |
|
423 |
+ s= subs_htable[hash_code].entries; |
|
373 | 424 |
|
374 |
- if(watchers!=NULL) |
|
425 |
+ while(s->next) |
|
375 | 426 |
{ |
376 |
- for(i = 0; i<result->n; i++) |
|
427 |
+ s= s->next; |
|
428 |
+ |
|
429 |
+ if(s->expires< (int)time(NULL)) |
|
430 |
+ { |
|
431 |
+ DBG("PRESENCE:get_wi_notify_body:expired record\n"); |
|
432 |
+ continue; |
|
433 |
+ } |
|
434 |
+ |
|
435 |
+ if(fallback2db && s->db_flag!= INSERTDB_FLAG) |
|
377 | 436 |
{ |
378 |
- if(watchers[i].uri.s !=NULL) |
|
379 |
- pkg_free(watchers[i].uri.s ); |
|
380 |
- if(watchers[i].id.s !=NULL) |
|
381 |
- pkg_free(watchers[i].id.s ); |
|
437 |
+ DBG("PRESENCE:get_wi_notify_body:record already taken" |
|
438 |
+ " from database\n"); |
|
439 |
+ continue; |
|
440 |
+ } |
|
441 |
+ |
|
442 |
+ if(s->event== subs->event->wipeer && |
|
443 |
+ s->pres_uri.len== subs->pres_uri.len && |
|
444 |
+ strncmp(s->pres_uri.s, subs->pres_uri.s,subs->pres_uri.len)== 0) |
|
445 |
+ { |
|
446 |
+ w= (watcher_t*)pkg_malloc(sizeof(watcher_t)); |
|
447 |
+ if(w== NULL) |
|
448 |
+ { |
|
449 |
+ lock_release(&subs_htable[hash_code].lock); |
|
450 |
+ ERR_MEM("get_wi_notify_body"); |
|
451 |
+ } |
|
452 |
+ w->status= s->status; |
|
453 |
+ if(uandd_to_uri(s->from_user, s->from_domain, &w->uri)<0) |
|
454 |
+ { |
|
455 |
+ lock_release(&subs_htable[hash_code].lock); |
|
456 |
+ pkg_free(w); |
|
457 |
+ LOG(L_ERR, "PRESENCE:get_wi_notify_body:ERROR while creating" |
|
458 |
+ " uri\n"); |
|
459 |
+ goto error; |
|
460 |
+ } |
|
461 |
+ w->id.s = (char*)pkg_malloc(w->uri.len*2 +1); |
|
462 |
+ if(w->id.s== NULL) |
|
463 |
+ { |
|
464 |
+ LOG(L_ERR,"PRESENCE:get_wi_notify_body: ERROR no more pkg mem\n"); |
|
465 |
+ lock_release(&subs_htable[hash_code].lock); |
|
466 |
+ pkg_free(w->uri.s); |
|
467 |
+ pkg_free(w); |
|
468 |
+ goto error; |
|
469 |
+ } |
|
470 |
+ |
|
471 |
+ to64frombits((unsigned char *)w->id.s, |
|
472 |
+ (const unsigned char*)w->uri.s, w->uri.len); |
|
473 |
+ |
|
474 |
+ w->id.len = strlen(w->id.s); |
|
475 |
+ w->event= subs->event->wipeer->name; |
|
476 |
+ |
|
477 |
+ w->next= watchers->next; |
|
478 |
+ watchers->next= w; |
|
382 | 479 |
} |
383 |
- pkg_free(watchers); |
|
384 | 480 |
} |
385 |
- pa_dbf.free_result(pa_db, result); |
|
386 |
- if(p_uri.s) |
|
387 |
- pkg_free(p_uri.s); |
|
481 |
+ |
|
482 |
+done: |
|
483 |
+ notify_body = create_winfo_xml(watchers,version_str,subs->pres_uri, |
|
484 |
+ FULL_STATE_FLAG ); |
|
485 |
+ |
|
486 |
+ if(watcher_subs == NULL) |
|
487 |
+ lock_release(&subs_htable[hash_code].lock); |
|
388 | 488 |
|
489 |
+ if(notify_body== NULL) |
|
490 |
+ { |
|
491 |
+ LOG(L_ERR, "PRESENCE: get_wi_notify_body: Error in function" |
|
492 |
+ " create_winfo_xml\n"); |
|
493 |
+ goto error; |
|
494 |
+ } |
|
495 |
+ while(watchers) |
|
496 |
+ { |
|
497 |
+ w= watchers; |
|
498 |
+ if(w->uri.s !=NULL) |
|
499 |
+ pkg_free(w->uri.s); |
|
500 |
+ if(w->id.s !=NULL) |
|
501 |
+ pkg_free(w->id.s); |
|
502 |
+ watchers= watchers->next; |
|
503 |
+ pkg_free(w); |
|
504 |
+ } |
|
389 | 505 |
return notify_body; |
390 | 506 |
|
391 | 507 |
error: |
392 |
- if(result!=NULL) |
|
393 |
- pa_dbf.free_result(pa_db, result); |
|
394 |
- |
|
395 | 508 |
if(notify_body) |
396 | 509 |
{ |
397 | 510 |
if(notify_body->s) |
398 | 511 |
xmlFree(notify_body->s); |
399 | 512 |
pkg_free(notify_body); |
400 | 513 |
} |
401 |
- if(watchers!=NULL) |
|
402 |
- { |
|
403 |
- for(i = 0; i<result->n; i++) |
|
404 |
- { |
|
405 |
- if(watchers[i].uri.s !=NULL) |
|
406 |
- pkg_free(watchers[i].uri.s ); |
|
407 |
- if(watchers[i].id.s !=NULL) |
|
408 |
- pkg_free(watchers[i].id.s ); |
|
409 |
- } |
|
410 |
- pkg_free(watchers); |
|
514 |
+ while(watchers) |
|
515 |
+ { |
|
516 |
+ w= watchers; |
|
517 |
+ if(w->uri.s !=NULL) |
|
518 |
+ pkg_free(w->uri.s); |
|
519 |
+ if(w->id.s !=NULL) |
|
520 |
+ pkg_free(w->id.s); |
|
521 |
+ watchers= watchers->next; |
|
522 |
+ pkg_free(w); |
|
411 | 523 |
} |
412 |
- if(p_uri.s) |
|
413 |
- pkg_free(p_uri.s); |
|
414 | 524 |
|
415 | 525 |
return NULL; |
416 |
- |
|
417 | 526 |
} |
418 |
-str* get_p_notify_body(str user, str host, ev_t* event, str* etag) |
|
527 |
+ |
|
528 |
+str* get_p_notify_body(str pres_uri, pres_ev_t* event, str* etag) |
|
419 | 529 |
{ |
420 | 530 |
db_key_t query_cols[6]; |
421 | 531 |
db_val_t query_vals[6]; |
... | ... |
@@ -433,23 +543,51 @@ str* get_p_notify_body(str user, str host, ev_t* event, str* etag) |
433 | 543 |
str etags; |
434 | 544 |
str* body; |
435 | 545 |
int size= 0; |
546 |
+ struct sip_uri uri; |
|
547 |
+ unsigned int hash_code; |
|
548 |
+ |
|
549 |
+ if(parse_uri(pres_uri.s, pres_uri.len, &uri)< 0) |
|
550 |
+ { |
|
551 |
+ LOG(L_ERR, "PRESENCE: get_p_notify_body: ERROR while parsing uri\n"); |
|
552 |
+ return NULL; |
|
553 |
+ } |
|
554 |
+ |
|
555 |
+ /* search in hash table if any record exists */ |
|
556 |
+ hash_code= core_hash(&pres_uri, NULL, phtable_size); |
|
557 |
+ if(search_phtable(&pres_uri, event->evp->parsed, hash_code)== NULL) |
|
558 |
+ { |
|
559 |
+ DBG("PRESENCE: get_p_notify_body: No record exists in hash_table\n"); |
|
560 |
+ if(fallback2db) |
|
561 |
+ goto db_query; |
|
562 |
+ |
|
563 |
+ /* for pidf manipulation */ |
|
564 |
+ if(event->agg_nbody) |
|
565 |
+ { |
|
566 |
+ notify_body = event->agg_nbody(&uri.user, &uri.host, NULL, 0, -1); |
|
567 |
+ if(notify_body) |
|
568 |
+ goto done; |
|
569 |
+ } |
|
570 |
+ return NULL; |
|
571 |
+ } |
|
572 |
+ |
|
573 |
+db_query: |
|
436 | 574 |
|
437 | 575 |
query_cols[n_query_cols] = "domain"; |
438 | 576 |
query_vals[n_query_cols].type = DB_STR; |
439 | 577 |
query_vals[n_query_cols].nul = 0; |
440 |
- query_vals[n_query_cols].val.str_val = host; |
|
578 |
+ query_vals[n_query_cols].val.str_val = uri.host; |
|
441 | 579 |
n_query_cols++; |
442 | 580 |
|
443 | 581 |
query_cols[n_query_cols] = "username"; |
444 | 582 |
query_vals[n_query_cols].type = DB_STR; |
445 | 583 |
query_vals[n_query_cols].nul = 0; |
446 |
- query_vals[n_query_cols].val.str_val = user; |
|
584 |
+ query_vals[n_query_cols].val.str_val = uri.user; |
|
447 | 585 |
n_query_cols++; |
448 | 586 |
|
449 | 587 |
query_cols[n_query_cols] = "event"; |
450 | 588 |
query_vals[n_query_cols].type = DB_STR; |
451 | 589 |
query_vals[n_query_cols].nul = 0; |
452 |
- query_vals[n_query_cols].val.str_val= event->stored_name; |
|
590 |
+ query_vals[n_query_cols].val.str_val= event->name; |
|
453 | 591 |
n_query_cols++; |
454 | 592 |
|
455 | 593 |
result_cols[body_col=n_result_cols++] = "body" ; |
... | ... |
@@ -476,22 +614,22 @@ str* get_p_notify_body(str user, str host, ev_t* event, str* etag) |
476 | 614 |
if(result== NULL) |
477 | 615 |
return NULL; |
478 | 616 |
|
479 |
- if (result && result->n<=0 ) |
|
617 |
+ if (result->n<=0 ) |
|
480 | 618 |
{ |
481 | 619 |
DBG("PRESENCE: get_p_notify_body: The query returned no" |
482 | 620 |
" result\n[username]= %.*s\t[domain]= %.*s\t[event]= %.*s\n", |
483 |
- user.len, user.s, host.len, host.s, event->stored_name.len, event->stored_name.s); |
|
621 |
+ uri.user.len, uri.user.s, uri.host.len, uri.host.s, |
|
622 |
+ event->name.len, event->name.s); |
|
484 | 623 |
|
485 | 624 |
pa_dbf.free_result(pa_db, result); |
486 | 625 |
result= NULL; |
487 | 626 |
|
488 | 627 |
if(event->agg_nbody) |
489 | 628 |
{ |
490 |
- notify_body = event->agg_nbody(&user, &host, NULL, 0, -1); |
|
629 |
+ notify_body = event->agg_nbody(&uri.user, &uri.host, NULL, 0, -1); |
|
491 | 630 |
if(notify_body) |
492 | 631 |
goto done; |
493 |
- } |
|
494 |
- |
|
632 |
+ } |
|
495 | 633 |
return NULL; |
496 | 634 |
} |
497 | 635 |
else |
... | ... |
@@ -620,7 +758,7 @@ str* get_p_notify_body(str user, str host, ev_t* event, str* etag) |
620 | 758 |
pa_dbf.free_result(pa_db, result); |
621 | 759 |
result= NULL; |
622 | 760 |
|
623 |
- notify_body = event->agg_nbody(&user, &host, body_array, n, build_off_n); |
|
761 |
+ notify_body = event->agg_nbody(&uri.user, &uri.host, body_array, n, build_off_n); |
|
624 | 762 |
} |
625 | 763 |
|
626 | 764 |
done: |
... | ... |
@@ -660,6 +798,11 @@ int free_tm_dlg(dlg_t *td) |
660 | 798 |
{ |
661 | 799 |
if(td) |
662 | 800 |
{ |
801 |
+ if(td->loc_uri.s) |
|
802 |
+ pkg_free(td->loc_uri.s); |
|
803 |
+ if(td->rem_uri.s) |
|
804 |
+ pkg_free(td->rem_uri.s); |
|
805 |
+ |
|
663 | 806 |
if(td->route_set) |
664 | 807 |
free_rr(&td->route_set); |
665 | 808 |
pkg_free(td); |
... | ... |
@@ -667,10 +810,9 @@ int free_tm_dlg(dlg_t *td) |
667 | 810 |
return 0; |
668 | 811 |
} |
669 | 812 |
|
670 |
-dlg_t* build_dlg_t (str p_uri, subs_t* subs) |
|
813 |
+dlg_t* build_dlg_t(subs_t* subs) |
|
671 | 814 |
{ |
672 | 815 |
dlg_t* td =NULL; |
673 |
- str w_uri; |
|
674 | 816 |
int found_contact = 1; |
675 | 817 |
|
676 | 818 |
td = (dlg_t*)pkg_malloc(sizeof(dlg_t)); |
... | ... |
@@ -687,7 +829,13 @@ dlg_t* build_dlg_t (str p_uri, subs_t* subs) |
687 | 829 |
td->id.call_id = subs->callid; |
688 | 830 |
td->id.rem_tag = subs->from_tag; |
689 | 831 |
td->id.loc_tag =subs->to_tag; |
690 |
- td->loc_uri = p_uri; |
|
832 |
+ |
|
833 |
+ uandd_to_uri(subs->to_user, subs->to_domain, &td->loc_uri); |
|
834 |
+ if(td->loc_uri.s== NULL) |
|
835 |
+ { |
|
836 |
+ LOG(L_ERR, "PRESENCE:build_dlg_t :ERROR while creating uri\n"); |
|
837 |
+ goto error; |
|
838 |
+ } |
|
691 | 839 |
|
692 | 840 |
if(subs->contact.len ==0 || subs->contact.s == NULL ) |
693 | 841 |
{ |
... | ... |
@@ -696,21 +844,19 @@ dlg_t* build_dlg_t (str p_uri, subs_t* subs) |
696 | 844 |
else |
697 | 845 |
{ |
698 | 846 |
DBG("CONTACT = %.*s\n", subs->contact.len , subs->contact.s); |
699 |
- |
|
700 | 847 |
td->rem_target = subs->contact; |
701 | 848 |
} |
702 | 849 |
|
703 |
- uandd_to_uri(subs->from_user, subs->from_domain, &w_uri); |
|
704 |
- if(w_uri.s ==NULL) |
|
850 |
+ uandd_to_uri(subs->from_user, subs->from_domain, &td->rem_uri); |
|
851 |
+ if(td->rem_uri.s ==NULL) |
|
705 | 852 |
{ |
706 | 853 |
LOG(L_ERR, "PRESENCE:build_dlg_t :ERROR while creating uri\n"); |
707 | 854 |
goto error; |
708 | 855 |
} |
709 | 856 |
|
710 |
- td->rem_uri = w_uri; |
|
711 | 857 |
if(found_contact == 0) |
712 | 858 |
{ |
713 |
- td->rem_target = w_uri; |
|
859 |
+ td->rem_target = td->rem_uri; |
|
714 | 860 |
} |
715 | 861 |
if(subs->record_route.s && subs->record_route.len) |
716 | 862 |
{ |
... | ... |
@@ -739,24 +885,15 @@ dlg_t* build_dlg_t (str p_uri, subs_t* subs) |
739 | 885 |
return td; |
740 | 886 |
|
741 | 887 |
error: |
742 |
- if(w_uri.s) |
|
743 |
- { |
|
744 |
- pkg_free(w_uri.s); |
|
745 |
- w_uri.s= NULL; |
|
746 |
- } |
|
747 |
- if(td!=NULL) |
|
748 |
- free_tm_dlg(td); |
|
888 |
+ |
|
889 |
+ free_tm_dlg(td); |
|
749 | 890 |
|
750 | 891 |
return NULL; |
751 | 892 |
} |
752 | 893 |
|
753 |
- |
|
754 |
-int get_subs_dialog(str* p_user, str* p_domain, ev_t* event,str* sender, |
|
755 |
- subs_t*** array, int *n) |
|
894 |
+int get_subs_db(str* pres_uri, pres_ev_t* event, str* sender, |
|
895 |
+ subs_t** s_array, int* n) |
|
756 | 896 |
{ |
757 |