Browse code

- added 2 new files

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

Anca Vamanu authored on 16/08/2007 09:54:12
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,468 @@
1
+/*
2
+ * $Id: hash.c 2583 2007-08-08 11:33:25Z 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-08-20  initial version (anca)
27
+ */
28
+
29
+#include <stdio.h>
30
+#include <stdlib.h>
31
+#include "../../mem/shm_mem.h"
32
+#include "../../dprint.h"
33
+#include "../../str.h"
34
+#include "../pua/hash.h"
35
+#include "presence.h"
36
+#include "hash.h"
37
+#include "notify.h"
38
+
39
+shtable_t new_shtable()
40
+{
41
+	shtable_t htable= NULL;
42
+	int i, j;
43
+
44
+	htable= (subs_entry_t*)shm_malloc(shtable_size* sizeof(subs_entry_t));
45
+	if(htable== NULL)
46
+	{
47
+		ERR_MEM("new_shtable");
48
+	}
49
+	memset(htable, 0, shtable_size* sizeof(subs_entry_t));
50
+	for(i= 0; i< shtable_size; i++)
51
+	{
52
+		if(lock_init(&htable[i].lock)== 0)
53
+		{
54
+			LOG(L_ERR,"PRESENCE:new_shtable: ERROR initializing lock"
55
+					" [%d]\n", i);
56
+			goto error;
57
+		}
58
+		htable[i].entries= (subs_t*)shm_malloc(sizeof(subs_t));
59
+		if(htable[i].entries== NULL)
60
+		{
61
+			ERR_MEM("new_shtable");
62
+		}
63
+		memset(htable[i].entries, 0, sizeof(subs_t));
64
+		htable[i].entries->next= NULL;
65
+	}
66
+
67
+	return htable;
68
+
69
+error:
70
+	if(htable)
71
+	{
72
+		for(j=0; j< i; j++)
73
+		{
74
+			if(htable[i].entries)
75
+				shm_free(htable[i].entries);
76
+			else 
77
+				break;
78
+			lock_destroy(&htable[i].lock);
79
+		}
80
+		shm_free(htable);
81
+	}
82
+	return NULL;
83
+
84
+}
85
+
86
+void destroy_shtable()
87
+{
88
+	int i;
89
+
90
+	if(subs_htable== NULL)
91
+		return;
92
+
93
+	for(i= 0; i< shtable_size; i++)
94
+	{
95
+		lock_destroy(&subs_htable[i].lock);
96
+		free_subs_list(subs_htable[i].entries, SHM_MEM_TYPE);
97
+	}
98
+	shm_free(subs_htable);
99
+}
100
+
101
+subs_t* search_shtable(str callid,str to_tag,str from_tag,unsigned int hash_code)
102
+{
103
+	subs_t* s;
104
+
105
+	s= subs_htable[hash_code].entries->next;
106
+
107
+	while(s)
108
+	{
109
+		if(s->callid.len==callid.len &&
110
+				strncmp(s->callid.s, callid.s, callid.len)==0 &&
111
+			s->to_tag.len== to_tag.len &&
112
+				strncmp(s->to_tag.s, to_tag.s, to_tag.len)==0 &&
113
+			s->from_tag.len== from_tag.len &&
114
+				strncmp(s->from_tag.s, from_tag.s, from_tag.len)== 0)
115
+			return s;
116
+		s= s->next;
117
+	}
118
+
119
+	return NULL;
120
+}
121
+
122
+subs_t* mem_copy_subs(subs_t* s, int mem_type)
123
+{
124
+	int size;
125
+	subs_t* dest;
126
+
127
+	size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
128
+		+ s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
129
+		+ s->to_tag.len+ s->from_tag.len+ s->sockinfo_str.len+
130
+		+ s->local_contact.len+ s->contact.len+ s->record_route.len+ 1)*sizeof(char);
131
+
132
+	if(mem_type & PKG_MEM_TYPE)
133
+		dest= (subs_t*)pkg_malloc(size);
134
+	else
135
+		dest= (subs_t*)shm_malloc(size);
136
+
137
+	memset(dest, 0, size);
138
+	if(dest== NULL)
139
+	{
140
+		ERR_MEM("mem_copy_subs");
141
+	}
142
+	size= sizeof(subs_t);
143
+
144
+	CONT_COPY(dest, dest->pres_uri, s->pres_uri)
145
+	CONT_COPY(dest, dest->to_user, s->to_user)
146
+	CONT_COPY(dest, dest->to_domain, s->to_domain)
147
+	CONT_COPY(dest, dest->from_user, s->from_user)
148
+	CONT_COPY(dest, dest->from_domain, s->from_domain)
149
+	CONT_COPY(dest, dest->to_tag, s->to_tag)
150
+	CONT_COPY(dest, dest->from_tag, s->from_tag)
151
+	CONT_COPY(dest, dest->callid, s->callid)
152
+	CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
153
+	CONT_COPY(dest, dest->local_contact, s->local_contact)
154
+	CONT_COPY(dest, dest->contact, s->contact)
155
+	CONT_COPY(dest, dest->record_route, s->record_route)
156
+	if(s->event_id.s)
157
+		CONT_COPY(dest, dest->event_id, s->event_id)
158
+	if(s->reason.s)
159
+		CONT_COPY(dest, dest->reason, s->reason)
160
+
161
+	dest->event= s->event;
162
+	dest->local_cseq= s->local_cseq;
163
+	dest->remote_cseq= s->remote_cseq;
164
+	dest->status= s->status;
165
+	dest->version= s->version;
166
+	dest->send_on_cback= s->send_on_cback;
167
+	dest->expires= s->expires;
168
+
169
+	return dest;
170
+
171
+error:
172
+	if(dest)
173
+	{
174
+		if(mem_type & PKG_MEM_TYPE)
175
+			pkg_free(dest);
176
+		else
177
+			shm_free(dest);
178
+	}
179
+	return NULL;
180
+}
181
+
182
+int insert_shtable(subs_t* subs)
183
+{
184
+	subs_t* new_rec= NULL;
185
+	unsigned int hash_code;
186
+		
187
+	new_rec= mem_copy_subs(subs, SHM_MEM_TYPE);
188
+	if(new_rec== NULL)
189
+	{
190
+		LOG(L_ERR, "PRESENCE: insert_shtable: ERROR while copying in"
191
+				" share memory a subs_t structure\n");
192
+		goto error;
193
+	}
194
+
195
+	new_rec->expires+= (int)time(NULL);
196
+	new_rec->db_flag= INSERTDB_FLAG;
197
+
198
+	hash_code=core_hash(&subs->pres_uri,&subs->event->name,shtable_size);
199
+
200
+	lock_get(&subs_htable[hash_code].lock);
201
+	
202
+	new_rec->next= subs_htable[hash_code].entries->next;
203
+	
204
+	subs_htable[hash_code].entries->next= new_rec;
205
+	
206
+	lock_release(&subs_htable[hash_code].lock);
207
+	
208
+	return 0;
209
+
210
+error:
211
+	if(new_rec)
212
+		shm_free(new_rec);
213
+	return -1;
214
+}
215
+
216
+int delete_shtable(str pres_uri, str ev_stored_name, str to_tag)
217
+{
218
+	unsigned int hash_code;
219
+	subs_t* s= NULL, *ps= NULL;
220
+	int found= -1;
221
+
222
+	DBG("PRESENCE: delete_shtable..\n");
223
+	hash_code= core_hash(&pres_uri, &ev_stored_name, shtable_size);
224
+	lock_get(&subs_htable[hash_code].lock);
225
+	
226
+	ps= subs_htable[hash_code].entries;
227
+	s= ps->next;
228
+		
229
+	while(s)
230
+	{	
231
+		if(s->to_tag.len== to_tag.len &&
232
+				strncmp(s->to_tag.s, to_tag.s, to_tag.len)== 0)
233
+		{
234
+			found= 1;
235
+			ps->next= s->next;
236
+			shm_free(s);
237
+			break;
238
+		}
239
+		ps= s;
240
+		s= s->next;
241
+	}
242
+	lock_release(&subs_htable[hash_code].lock);
243
+	return found;
244
+}
245
+
246
+void free_subs_list(subs_t* s_array, int mem_type)
247
+{
248
+	subs_t* s;
249
+
250
+	while(s_array)
251
+	{
252
+		s= s_array;
253
+		s_array= s_array->next;
254
+		if(mem_type & PKG_MEM_TYPE)
255
+			pkg_free(s);
256
+		else
257
+			shm_free(s);
258
+	}
259
+	
260
+}
261
+
262
+int update_shtable(subs_t* subs, int type)
263
+{
264
+	unsigned int hash_code;
265
+	subs_t* s;
266
+
267
+	hash_code= core_hash(&subs->pres_uri, &subs->event->name, shtable_size);
268
+	lock_get(&subs_htable[hash_code].lock);
269
+
270
+	s= search_shtable(subs->callid, subs->to_tag, subs->from_tag, hash_code);
271
+	if(s== NULL)
272
+	{
273
+		DBG("PRESENCE: update_shtable: record not found in hash table\n");
274
+		lock_release(&subs_htable[hash_code].lock);
275
+		return -1;
276
+	}
277
+
278
+	if(type & REMOTE_TYPE)
279
+	{
280
+		s->expires= subs->expires+ (int)time(NULL);
281
+		s->remote_cseq= subs->remote_cseq;
282
+	}
283
+	else
284
+	{
285
+		s->local_cseq= subs->local_cseq;	
286
+		s->version= subs->version+ 1;
287
+	}
288
+	s->status= subs->status;
289
+	s->event= subs->event;
290
+	if(s->db_flag & NO_UPDATEDB_FLAG)
291
+		s->db_flag= UPDATEDB_FLAG;
292
+
293
+	lock_release(&subs_htable[hash_code].lock);
294
+	
295
+	return 0;
296
+}
297
+
298
+phtable_t* new_phtable()
299
+{
300
+	phtable_t* htable= NULL;
301
+	int i, j;
302
+
303
+	htable= (phtable_t*)shm_malloc(phtable_size* sizeof(phtable_t));
304
+	if(htable== NULL)
305
+	{
306
+		ERR_MEM("new_phtable");
307
+	}
308
+	memset(htable, 0, phtable_size* sizeof(phtable_t));
309
+
310
+	for(i= 0; i< phtable_size; i++)
311
+	{
312
+		if(lock_init(&htable[i].lock)== 0)
313
+		{
314
+			LOG(L_ERR,"PRESENCE:new_phtable: ERROR initializing lock"
315
+					" [%d]\n", i);
316
+			goto error;
317
+		}
318
+		htable[i].entries= (pres_entry_t*)shm_malloc(sizeof(pres_entry_t));
319
+		if(htable[i].entries== NULL)
320
+		{
321
+			ERR_MEM("new_phtable");
322
+		}
323
+		memset(htable[i].entries, 0, sizeof(pres_entry_t));
324
+		htable[i].entries->next= NULL;
325
+	}
326
+
327
+	return htable;
328
+
329
+error:
330
+	if(htable)
331
+	{
332
+		for(j=0; j< i; j++)
333
+		{
334
+			if(htable[i].entries)
335
+				shm_free(htable[i].entries);
336
+			else 
337
+				break;
338
+			lock_destroy(&htable[i].lock);
339
+		}
340
+		shm_free(htable);
341
+	}
342
+	return NULL;
343
+
344
+}
345
+
346
+void destroy_phtable()
347
+{
348
+	int i;
349
+	pres_entry_t* p, *prev_p;
350
+
351
+	if(subs_htable== NULL)
352
+		return;
353
+
354
+	for(i= 0; i< phtable_size; i++)
355
+	{
356
+		lock_destroy(&pres_htable[i].lock);
357
+		p= pres_htable[i].entries;
358
+		while(p)
359
+		{
360
+			prev_p= p;
361
+			p= p->next;
362
+			shm_free(prev_p);
363
+		}
364
+	}
365
+	shm_free(pres_htable);
366
+}
367
+/* entry must be locked before calling this function */
368
+
369
+pres_entry_t* search_phtable(str* pres_uri,int event, unsigned int hash_code)
370
+{
371
+	pres_entry_t* p;
372
+
373
+	p= pres_htable[hash_code].entries->next;
374
+	while(p)
375
+	{
376
+		if(p->event== event && p->pres_uri.len== pres_uri->len &&
377
+				strncmp(p->pres_uri.s, pres_uri->s, pres_uri->len)== 0 )
378
+			return p;
379
+		p= p->next;
380
+	}
381
+	return NULL;
382
+}
383
+
384
+int insert_phtable(str* pres_uri, int event)
385
+{
386
+	unsigned int hash_code;
387
+	pres_entry_t* p= NULL;
388
+	int size;
389
+
390
+	hash_code= core_hash(pres_uri, NULL, phtable_size);
391
+
392
+	lock_get(&pres_htable[hash_code].lock);
393
+	
394
+	p= search_phtable(pres_uri, event, hash_code);
395
+	if(p)
396
+	{
397
+		p->publ_count++;
398
+		lock_release(&pres_htable[hash_code].lock);
399
+		return 0;
400
+	}
401
+	size= sizeof(pres_entry_t)+ pres_uri->len* sizeof(char);
402
+	p= (pres_entry_t*)shm_malloc(size);
403
+	if(p== NULL)
404
+	{
405
+		lock_release(&pres_htable[hash_code].lock);
406
+		ERR_MEM("insert_phtable");
407
+	}
408
+	memset(p, 0, size);
409
+
410
+	size= sizeof(pres_entry_t);
411
+	p->pres_uri.s= (char*)p+ size;
412
+	memcpy(p->pres_uri.s, pres_uri->s, pres_uri->len);
413
+	p->pres_uri.len= pres_uri->len;
414
+	 
415
+	p->event= event;
416
+
417
+	p->next= pres_htable[hash_code].entries->next;
418
+	pres_htable[hash_code].entries->next= p;
419
+
420
+	lock_release(&pres_htable[hash_code].lock);
421
+	
422
+	return 0;
423
+
424
+error:
425
+	return -1;
426
+}
427
+int delete_phtable(str* pres_uri, int event)
428
+{
429
+	unsigned int hash_code;
430
+	pres_entry_t* p= NULL, *prev_p= NULL;
431
+
432
+	hash_code= core_hash(pres_uri, NULL, phtable_size);
433
+
434
+	lock_get(&pres_htable[hash_code].lock);
435
+	
436
+	p= search_phtable(pres_uri, event, hash_code);
437
+	if(p== NULL)
438
+	{
439
+		DBG("PRESENCE: delete_phtable: record not found\n");
440
+		lock_release(&pres_htable[hash_code].lock);
441
+		return 0;
442
+	}
443
+	
444
+	p->publ_count--;
445
+	if(p->publ_count== 0)
446
+	{
447
+		/* delete record */	
448
+		prev_p= pres_htable[hash_code].entries;
449
+		while(prev_p->next)
450
+		{
451
+			if(prev_p->next== p)
452
+				break;
453
+			prev_p= prev_p->next;
454
+		}
455
+		if(prev_p->next== NULL)
456
+		{
457
+			LOG(L_ERR, "PRESENCE: delete_phtable: ERROR "
458
+					"previous record not found\n");
459
+			lock_release(&pres_htable[hash_code].lock);
460
+			return -1;
461
+		}
462
+		prev_p->next= p->next;
463
+		shm_free(p);
464
+	}
465
+	lock_release(&pres_htable[hash_code].lock);
466
+
467
+	return 0;	
468
+}
0 469
new file mode 100644
... ...
@@ -0,0 +1,102 @@
1
+/*
2
+ * $Id: hash.h 2583 2007-08-08 11:33:25Z 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-08-20  initial version (anca)
27
+ */
28
+
29
+
30
+#ifndef PS_HASH_H
31
+#define PS_HASH_H
32
+
33
+#include "subscribe.h"
34
+
35
+#define REMOTE_TYPE   1<<1
36
+#define LOCAL_TYPE    1<<2
37
+
38
+#define ERR_MEM(func)  LOG(L_ERR, "PRESENCE: %s: ERROR No more memory\n", func);\
39
+						goto error
40
+
41
+#define CONT_COPY(buf, dest, source)\
42
+	dest.s= (char*)buf+ size;\
43
+	memcpy(dest.s, source.s, source.len);\
44
+	dest.len= source.len;\
45
+	size+= source.len;
46
+
47
+#define PKG_MEM_TYPE     1<< 1
48
+#define SHM_MEM_TYPE     1<< 2
49
+
50
+/* subscribe hash entry */
51
+
52
+typedef struct subs_entry
53
+{
54
+	subs_t* entries;
55
+	gen_lock_t lock;
56
+}subs_entry_t;	
57
+
58
+typedef subs_entry_t* shtable_t;
59
+
60
+shtable_t new_shtable();
61
+
62
+subs_t* search_shtable();
63
+
64
+int insert_shtable(subs_t* subs);
65
+
66
+int delete_shtable(str pres_uri, str ev_stored_name, str to_tag);
67
+
68
+int update_shtable(subs_t* subs, int type);
69
+
70
+subs_t* mem_copy_subs(subs_t* s, int mem_type);
71
+
72
+void free_subs_list(subs_t* s_array, int mem_type);
73
+
74
+void destroy_shtable();
75
+
76
+/* presentity hash table */
77
+typedef struct pres_entry
78
+{
79
+	str pres_uri;
80
+	int event;
81
+	int publ_count;
82
+	struct pres_entry* next;
83
+}pres_entry_t;
84
+
85
+typedef struct pres_htable
86
+{
87
+	pres_entry_t* entries;
88
+	gen_lock_t lock;
89
+}phtable_t;
90
+
91
+phtable_t* new_phtable();
92
+
93
+pres_entry_t* search_phtable(str* pres_uri, int event, unsigned int hash_code);
94
+
95
+int insert_phtable(str* pres_uri, int event);
96
+
97
+int delete_phtable(str* pres_uri, int event);
98
+
99
+void destroy_phtable();
100
+
101
+#endif
102
+