00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include "../../mem/shm_mem.h"
00037 #include "../../hashes.h"
00038 #include "../../dprint.h"
00039 #include "../../str.h"
00040 #include "../pua/hash.h"
00041 #include "presence.h"
00042 #include "hash.h"
00043 #include "notify.h"
00044
00045 shtable_t new_shtable(int hash_size)
00046 {
00047 shtable_t htable= NULL;
00048 int i, j;
00049
00050 i = 0;
00051 htable= (subs_entry_t*)shm_malloc(hash_size* sizeof(subs_entry_t));
00052 if(htable== NULL)
00053 {
00054 ERR_MEM(SHARE_MEM);
00055 }
00056 memset(htable, 0, hash_size* sizeof(subs_entry_t));
00057 for(i= 0; i< hash_size; i++)
00058 {
00059 if(lock_init(&htable[i].lock)== 0)
00060 {
00061 LM_ERR("initializing lock [%d]\n", i);
00062 goto error;
00063 }
00064 htable[i].entries= (subs_t*)shm_malloc(sizeof(subs_t));
00065 if(htable[i].entries== NULL)
00066 {
00067 lock_destroy(&htable[i].lock);
00068 ERR_MEM(SHARE_MEM);
00069 }
00070 memset(htable[i].entries, 0, sizeof(subs_t));
00071 htable[i].entries->next= NULL;
00072 }
00073
00074 return htable;
00075
00076 error:
00077 if(htable)
00078 {
00079 for(j=0; j< i; j++)
00080 {
00081 lock_destroy(&htable[j].lock);
00082 shm_free(htable[j].entries);
00083 }
00084 shm_free(htable);
00085 }
00086 return NULL;
00087
00088 }
00089
00090 void destroy_shtable(shtable_t htable, int hash_size)
00091 {
00092 int i;
00093
00094 if(htable== NULL)
00095 return;
00096
00097 for(i= 0; i< hash_size; i++)
00098 {
00099 lock_destroy(&htable[i].lock);
00100 free_subs_list(htable[i].entries->next, SHM_MEM_TYPE, 1);
00101 shm_free(htable[i].entries);
00102 }
00103 shm_free(htable);
00104 htable= NULL;
00105 }
00106
00107 subs_t* search_shtable(shtable_t htable,str callid,str to_tag,
00108 str from_tag,unsigned int hash_code)
00109 {
00110 subs_t* s;
00111
00112 s= htable[hash_code].entries->next;
00113
00114 while(s)
00115 {
00116 if(s->callid.len==callid.len &&
00117 strncmp(s->callid.s, callid.s, callid.len)==0 &&
00118 s->to_tag.len== to_tag.len &&
00119 strncmp(s->to_tag.s, to_tag.s, to_tag.len)==0 &&
00120 s->from_tag.len== from_tag.len &&
00121 strncmp(s->from_tag.s, from_tag.s, from_tag.len)== 0)
00122 return s;
00123 s= s->next;
00124 }
00125
00126 return NULL;
00127 }
00128
00129 subs_t* mem_copy_subs(subs_t* s, int mem_type)
00130 {
00131 int size;
00132 subs_t* dest;
00133
00134 size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
00135 + s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
00136 + s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len
00137 + s->local_contact.len+ s->contact.len+ s->record_route.len
00138 + s->reason.len+ s->watcher_user.len+ s->watcher_domain.len
00139 + 1)*sizeof(char);
00140
00141 if(mem_type & PKG_MEM_TYPE)
00142 dest= (subs_t*)pkg_malloc(size);
00143 else
00144 dest= (subs_t*)shm_malloc(size);
00145
00146 if(dest== NULL)
00147 {
00148 ERR_MEM((mem_type==PKG_MEM_TYPE)?PKG_MEM_STR:SHARE_MEM);
00149 }
00150 memset(dest, 0, size);
00151 size= sizeof(subs_t);
00152
00153 CONT_COPY(dest, dest->pres_uri, s->pres_uri)
00154 CONT_COPY(dest, dest->to_user, s->to_user)
00155 CONT_COPY(dest, dest->to_domain, s->to_domain)
00156 CONT_COPY(dest, dest->from_user, s->from_user)
00157 CONT_COPY(dest, dest->from_domain, s->from_domain)
00158 CONT_COPY(dest, dest->watcher_user, s->watcher_user)
00159 CONT_COPY(dest, dest->watcher_domain, s->watcher_domain)
00160 CONT_COPY(dest, dest->to_tag, s->to_tag)
00161 CONT_COPY(dest, dest->from_tag, s->from_tag)
00162 CONT_COPY(dest, dest->callid, s->callid)
00163 CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
00164 CONT_COPY(dest, dest->local_contact, s->local_contact)
00165 CONT_COPY(dest, dest->contact, s->contact)
00166 CONT_COPY(dest, dest->record_route, s->record_route)
00167 if(s->event_id.s)
00168 CONT_COPY(dest, dest->event_id, s->event_id)
00169 if(s->reason.s)
00170 CONT_COPY(dest, dest->reason, s->reason)
00171
00172 dest->event= s->event;
00173 dest->local_cseq= s->local_cseq;
00174 dest->remote_cseq= s->remote_cseq;
00175 dest->status= s->status;
00176 dest->version= s->version;
00177 dest->send_on_cback= s->send_on_cback;
00178 dest->expires= s->expires;
00179 dest->db_flag= s->db_flag;
00180
00181 return dest;
00182
00183 error:
00184 if(dest)
00185 {
00186 if(mem_type & PKG_MEM_TYPE)
00187 pkg_free(dest);
00188 else
00189 shm_free(dest);
00190 }
00191 return NULL;
00192 }
00193
00194
00195 subs_t* mem_copy_subs_noc(subs_t* s)
00196 {
00197 int size;
00198 subs_t* dest;
00199
00200 size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
00201 + s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
00202 + s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len
00203 + s->local_contact.len + s->record_route.len+
00204 + s->reason.len+ s->watcher_user.len+ s->watcher_domain.len
00205 + 1)*sizeof(char);
00206
00207 dest= (subs_t*)shm_malloc(size);
00208 if(dest== NULL)
00209 {
00210 ERR_MEM(SHARE_MEM);
00211 }
00212 memset(dest, 0, size);
00213 size= sizeof(subs_t);
00214
00215 CONT_COPY(dest, dest->pres_uri, s->pres_uri)
00216 CONT_COPY(dest, dest->to_user, s->to_user)
00217 CONT_COPY(dest, dest->to_domain, s->to_domain)
00218 CONT_COPY(dest, dest->from_user, s->from_user)
00219 CONT_COPY(dest, dest->from_domain, s->from_domain)
00220 CONT_COPY(dest, dest->watcher_user, s->watcher_user)
00221 CONT_COPY(dest, dest->watcher_domain, s->watcher_domain)
00222 CONT_COPY(dest, dest->to_tag, s->to_tag)
00223 CONT_COPY(dest, dest->from_tag, s->from_tag)
00224 CONT_COPY(dest, dest->callid, s->callid)
00225 CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
00226 CONT_COPY(dest, dest->local_contact, s->local_contact)
00227 CONT_COPY(dest, dest->record_route, s->record_route)
00228 if(s->event_id.s)
00229 CONT_COPY(dest, dest->event_id, s->event_id)
00230 if(s->reason.s)
00231 CONT_COPY(dest, dest->reason, s->reason)
00232
00233 dest->event= s->event;
00234 dest->local_cseq= s->local_cseq;
00235 dest->remote_cseq= s->remote_cseq;
00236 dest->status= s->status;
00237 dest->version= s->version;
00238 dest->send_on_cback= s->send_on_cback;
00239 dest->expires= s->expires;
00240 dest->db_flag= s->db_flag;
00241
00242 dest->contact.s= (char*)shm_malloc(s->contact.len* sizeof(char));
00243 if(dest->contact.s== NULL)
00244 {
00245 ERR_MEM(SHARE_MEM);
00246 }
00247 memcpy(dest->contact.s, s->contact.s, s->contact.len);
00248 dest->contact.len= s->contact.len;
00249
00250 return dest;
00251
00252 error:
00253 if(dest)
00254 shm_free(dest);
00255 return NULL;
00256 }
00257
00258 int insert_shtable(shtable_t htable,unsigned int hash_code, subs_t* subs)
00259 {
00260 subs_t* new_rec= NULL;
00261
00262 new_rec= mem_copy_subs_noc(subs);
00263 if(new_rec== NULL)
00264 {
00265 LM_ERR("copying in share memory a subs_t structure\n");
00266 return -1;
00267 }
00268 new_rec->expires+= (int)time(NULL);
00269
00270 lock_get(&htable[hash_code].lock);
00271 new_rec->next= htable[hash_code].entries->next;
00272 htable[hash_code].entries->next= new_rec;
00273 lock_release(&htable[hash_code].lock);
00274
00275 return 0;
00276 }
00277
00278 int delete_shtable(shtable_t htable,unsigned int hash_code,str to_tag)
00279 {
00280 subs_t* s= NULL, *ps= NULL;
00281 int found= -1;
00282
00283 lock_get(&htable[hash_code].lock);
00284
00285 ps= htable[hash_code].entries;
00286 s= ps->next;
00287
00288 while(s)
00289 {
00290 if(s->to_tag.len== to_tag.len &&
00291 strncmp(s->to_tag.s, to_tag.s, to_tag.len)== 0)
00292 {
00293 found= s->local_cseq +1;
00294 ps->next= s->next;
00295 if(s->contact.s!=NULL)
00296 shm_free(s->contact.s);
00297 shm_free(s);
00298 break;
00299 }
00300 ps= s;
00301 s= s->next;
00302 }
00303 lock_release(&htable[hash_code].lock);
00304 return found;
00305 }
00306
00307 void free_subs_list(subs_t* s_array, int mem_type, int ic)
00308 {
00309 subs_t* s;
00310
00311 while(s_array)
00312 {
00313 s= s_array;
00314 s_array= s_array->next;
00315 if(mem_type & PKG_MEM_TYPE)
00316 {
00317 if(ic)
00318 pkg_free(s->contact.s);
00319 pkg_free(s);
00320 }
00321 else
00322 {
00323 if(ic)
00324 shm_free(s->contact.s);
00325 shm_free(s);
00326 }
00327 }
00328
00329 }
00330
00331 int update_shtable(shtable_t htable,unsigned int hash_code,
00332 subs_t* subs, int type)
00333 {
00334 subs_t* s;
00335
00336 lock_get(&htable[hash_code].lock);
00337
00338 s= search_shtable(htable,subs->callid, subs->to_tag, subs->from_tag,
00339 hash_code);
00340 if(s== NULL)
00341 {
00342 LM_DBG("record not found in hash table\n");
00343 lock_release(&htable[hash_code].lock);
00344 return -1;
00345 }
00346
00347 if(type & REMOTE_TYPE)
00348 {
00349 s->expires= subs->expires+ (int)time(NULL);
00350 s->remote_cseq= subs->remote_cseq;
00351 }
00352 else
00353 {
00354 subs->local_cseq = ++s->local_cseq;
00355 subs->version = ++s->version;
00356 }
00357
00358 if(strncmp(s->contact.s, subs->contact.s, subs->contact.len))
00359 {
00360 shm_free(s->contact.s);
00361 s->contact.s= (char*)shm_malloc(subs->contact.len* sizeof(char));
00362 if(s->contact.s== NULL)
00363 {
00364 lock_release(&htable[hash_code].lock);
00365 LM_ERR("no more shared memory\n");
00366 return -1;
00367 }
00368 memcpy(s->contact.s, subs->contact.s, subs->contact.len);
00369 s->contact.len= subs->contact.len;
00370 }
00371
00372 s->status= subs->status;
00373 s->event= subs->event;
00374 subs->db_flag= s->db_flag;
00375
00376 if(s->db_flag & NO_UPDATEDB_FLAG)
00377 s->db_flag= UPDATEDB_FLAG;
00378
00379 lock_release(&htable[hash_code].lock);
00380
00381 return 0;
00382 }
00383
00384 phtable_t* new_phtable(void)
00385 {
00386 phtable_t* htable= NULL;
00387 int i, j;
00388
00389 i = 0;
00390 htable= (phtable_t*)shm_malloc(phtable_size* sizeof(phtable_t));
00391 if(htable== NULL)
00392 {
00393 ERR_MEM(SHARE_MEM);
00394 }
00395 memset(htable, 0, phtable_size* sizeof(phtable_t));
00396
00397 for(i= 0; i< phtable_size; i++)
00398 {
00399 if(lock_init(&htable[i].lock)== 0)
00400 {
00401 LM_ERR("initializing lock [%d]\n", i);
00402 goto error;
00403 }
00404 htable[i].entries= (pres_entry_t*)shm_malloc(sizeof(pres_entry_t));
00405 if(htable[i].entries== NULL)
00406 {
00407 ERR_MEM(SHARE_MEM);
00408 }
00409 memset(htable[i].entries, 0, sizeof(pres_entry_t));
00410 htable[i].entries->next= NULL;
00411 }
00412
00413 return htable;
00414
00415 error:
00416 if(htable)
00417 {
00418 for(j=0; j< i; j++)
00419 {
00420 if(htable[i].entries)
00421 shm_free(htable[i].entries);
00422 else
00423 break;
00424 lock_destroy(&htable[i].lock);
00425 }
00426 shm_free(htable);
00427 }
00428 return NULL;
00429
00430 }
00431
00432 void destroy_phtable(void)
00433 {
00434 int i;
00435 pres_entry_t* p, *prev_p;
00436
00437 if(pres_htable== NULL)
00438 return;
00439
00440 for(i= 0; i< phtable_size; i++)
00441 {
00442 lock_destroy(&pres_htable[i].lock);
00443 p= pres_htable[i].entries;
00444 while(p)
00445 {
00446 prev_p= p;
00447 p= p->next;
00448 if(prev_p->sphere)
00449 shm_free(prev_p->sphere);
00450 shm_free(prev_p);
00451 }
00452 }
00453 shm_free(pres_htable);
00454 }
00455
00456
00457 pres_entry_t* search_phtable(str* pres_uri,int event, unsigned int hash_code)
00458 {
00459 pres_entry_t* p;
00460
00461 LM_DBG("pres_uri= %.*s\n", pres_uri->len, pres_uri->s);
00462 p= pres_htable[hash_code].entries->next;
00463 while(p)
00464 {
00465 if(p->event== event && p->pres_uri.len== pres_uri->len &&
00466 strncmp(p->pres_uri.s, pres_uri->s, pres_uri->len)== 0 )
00467 return p;
00468 p= p->next;
00469 }
00470 return NULL;
00471 }
00472
00473 int insert_phtable(str* pres_uri, int event, char* sphere)
00474 {
00475 unsigned int hash_code;
00476 pres_entry_t* p= NULL;
00477 int size;
00478
00479 hash_code= core_hash(pres_uri, NULL, phtable_size);
00480
00481 lock_get(&pres_htable[hash_code].lock);
00482
00483 p= search_phtable(pres_uri, event, hash_code);
00484 if(p)
00485 {
00486 p->publ_count++;
00487 lock_release(&pres_htable[hash_code].lock);
00488 return 0;
00489 }
00490 size= sizeof(pres_entry_t)+ pres_uri->len* sizeof(char);
00491
00492 p= (pres_entry_t*)shm_malloc(size);
00493 if(p== NULL)
00494 {
00495 lock_release(&pres_htable[hash_code].lock);
00496 ERR_MEM(SHARE_MEM);
00497 }
00498 memset(p, 0, size);
00499
00500 size= sizeof(pres_entry_t);
00501 p->pres_uri.s= (char*)p+ size;
00502 memcpy(p->pres_uri.s, pres_uri->s, pres_uri->len);
00503 p->pres_uri.len= pres_uri->len;
00504
00505 if(sphere)
00506 {
00507 p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char));
00508 if(p->sphere== NULL)
00509 {
00510 lock_release(&pres_htable[hash_code].lock);
00511 ERR_MEM(SHARE_MEM);
00512 }
00513 strcpy(p->sphere, sphere);
00514 }
00515
00516 p->event= event;
00517
00518
00519 p->next= pres_htable[hash_code].entries->next;
00520 pres_htable[hash_code].entries->next= p;
00521
00522 lock_release(&pres_htable[hash_code].lock);
00523
00524 return 0;
00525
00526 error:
00527 return -1;
00528 }
00529
00530 int delete_phtable(str* pres_uri, int event)
00531 {
00532 unsigned int hash_code;
00533 pres_entry_t* p= NULL, *prev_p= NULL;
00534
00535 hash_code= core_hash(pres_uri, NULL, phtable_size);
00536
00537 lock_get(&pres_htable[hash_code].lock);
00538
00539 p= search_phtable(pres_uri, event, hash_code);
00540 if(p== NULL)
00541 {
00542 LM_DBG("record not found\n");
00543 lock_release(&pres_htable[hash_code].lock);
00544 return 0;
00545 }
00546
00547 p->publ_count--;
00548 if(p->publ_count== 0)
00549 {
00550
00551 prev_p= pres_htable[hash_code].entries;
00552 while(prev_p->next)
00553 {
00554 if(prev_p->next== p)
00555 break;
00556 prev_p= prev_p->next;
00557 }
00558 if(prev_p->next== NULL)
00559 {
00560 LM_ERR("record not found\n");
00561 lock_release(&pres_htable[hash_code].lock);
00562 return -1;
00563 }
00564 prev_p->next= p->next;
00565 if(p->sphere)
00566 shm_free(p->sphere);
00567
00568 shm_free(p);
00569 }
00570 lock_release(&pres_htable[hash_code].lock);
00571
00572 return 0;
00573 }
00574
00575 int update_phtable(presentity_t* presentity, str pres_uri, str body)
00576 {
00577 char* sphere= NULL;
00578 unsigned int hash_code;
00579 pres_entry_t* p;
00580 int ret= 0;
00581 str* xcap_doc= NULL;
00582
00583
00584 sphere= extract_sphere(body);
00585 if(sphere==NULL)
00586 {
00587 LM_DBG("no sphere defined in new body\n");
00588 return 0;
00589 }
00590
00591
00592 hash_code= core_hash(&pres_uri, NULL, phtable_size);
00593
00594 lock_get(&pres_htable[hash_code].lock);
00595
00596 p= search_phtable(&pres_uri, presentity->event->evp->type, hash_code);
00597 if(p== NULL)
00598 {
00599 lock_release(&pres_htable[hash_code].lock);
00600 goto done;
00601 }
00602
00603 if(p->sphere)
00604 {
00605 if(strcmp(p->sphere, sphere)!= 0)
00606 {
00607
00608 shm_free(p->sphere);
00609 }
00610 else
00611 {
00612
00613 lock_release(&pres_htable[hash_code].lock);
00614 pkg_free(sphere);
00615 return 0;
00616 }
00617
00618 }
00619
00620
00621 p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char));
00622 if(p->sphere== NULL)
00623 {
00624 lock_release(&pres_htable[hash_code].lock);
00625 ret= -1;
00626 goto done;
00627 }
00628 strcpy(p->sphere, sphere);
00629
00630 lock_release(&pres_htable[hash_code].lock);
00631
00632
00633
00634 if(presentity->event->get_rules_doc(&presentity->user, &presentity->domain,
00635 &xcap_doc)< 0)
00636 {
00637 LM_ERR("failed to retreive xcap document\n");
00638 ret= -1;
00639 goto done;
00640 }
00641
00642 update_watchers_status(pres_uri, presentity->event, xcap_doc);
00643
00644
00645 done:
00646
00647 if(xcap_doc)
00648 {
00649 if(xcap_doc->s)
00650 pkg_free(xcap_doc->s);
00651 pkg_free(xcap_doc);
00652 }
00653
00654 if(sphere)
00655 pkg_free(sphere);
00656 return ret;
00657 }