imc_mng.c

Go to the documentation of this file.
00001 /*
00002  * $Id: imc_mng.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * imc module - instant messaging conferencing implementation
00005  *
00006  * Copyright (C) 2006 Voice Sistem S.R.L.
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * ---------
00026  *  2006-10-06  first version (anca)
00027  */
00028 
00029 
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <stdio.h>
00033 
00034 #include "../../mem/mem.h"
00035 #include "../../mem/shm_mem.h"
00036 #include "../../dprint.h"
00037 
00038 #include "imc_mng.h"
00039 /* imc hash table */
00040 extern imc_hentry_p _imc_htable;
00041 extern int imc_hash_size;
00042 extern char imc_cmd_start_char;
00043 #define imc_get_hentry(_hid, _size) ((_hid)&(_size-1))
00044 
00045 /**
00046  * hash thable init
00047  */
00048 int imc_htable_init(void)
00049 {
00050    int i;
00051 
00052    if(imc_hash_size<=0)
00053    {
00054       LM_ERR("invalid hash table size\n");
00055       return -1;
00056    }
00057    _imc_htable = (imc_hentry_p)shm_malloc(imc_hash_size*sizeof(imc_hentry_t));
00058    if(_imc_htable == NULL)
00059    {
00060       LM_ERR("no more shm memory\n");
00061       return -1;
00062    }
00063    memset(_imc_htable, 0, imc_hash_size*sizeof(imc_hentry_t));
00064    for(i=0; i<imc_hash_size; i++)
00065    {
00066       if (lock_init(&_imc_htable[i].lock)==0)
00067       {
00068          LM_CRIT("failed to initialize lock [%d]\n", i);
00069          goto error;
00070       }
00071    }
00072    
00073    return 0;
00074 
00075 error:
00076    if(_imc_htable!=NULL)
00077    {
00078       shm_free(_imc_htable);
00079       _imc_htable = NULL;
00080    }
00081 
00082    return -1;
00083 }
00084 
00085 /**
00086  * destroy hash table
00087  */
00088 int imc_htable_destroy(void)
00089 {
00090    int i,room_deleted;
00091    imc_room_p irp = NULL, irp_temp=NULL;
00092    if(_imc_htable==NULL)
00093       return -1;
00094    
00095    for(i=0; i<imc_hash_size; i++)
00096    {
00097       lock_destroy(&_imc_htable[i].lock);
00098       if(_imc_htable[i].rooms==NULL)
00099          continue;
00100          irp = _imc_htable[i].rooms;
00101          while(irp){
00102             irp_temp = irp->next;
00103             room_deleted = imc_del_room(&irp->name, &irp->domain);
00104             irp = irp_temp;
00105          }
00106    }
00107    shm_free(_imc_htable);
00108    _imc_htable = NULL;
00109    return 0;
00110 }
00111 
00112 /**
00113  * add room
00114  */
00115 imc_room_p imc_add_room(str* name, str* domain, int flags)
00116 {
00117    imc_room_p irp = NULL;
00118    int size;
00119    int hidx;
00120    
00121    if(name == NULL || name->s==NULL || name->len<=0
00122          || domain == NULL || domain->s==NULL || domain->len<=0)
00123    {
00124       LM_ERR("invalid parameters\n");
00125       return NULL;
00126    }
00127 
00128    /* struct size + "sip:" + name len + "@" + domain len + '\0' */
00129    size = sizeof(imc_room_t) + (name->len+domain->len+6)*sizeof(char);
00130    irp = (imc_room_p)shm_malloc(size);
00131    if(irp==NULL)
00132    {
00133       LM_ERR("no more shm memory left\n");
00134       return NULL;
00135    }
00136    memset(irp, 0, size);
00137    
00138    irp->uri.len = 4 /*sip:*/ + name->len + 1 /*@*/ + domain->len;
00139    irp->uri.s = (char*)(((char*)irp)+sizeof(imc_room_t));
00140    memcpy(irp->uri.s, "sip:", 4);
00141    memcpy(irp->uri.s+4, name->s, name->len);
00142    irp->uri.s[4+name->len] = '@';
00143    memcpy(irp->uri.s+5+name->len, domain->s, domain->len);
00144    irp->uri.s[irp->uri.len] = '\0';
00145 
00146    irp->name.len = name->len;
00147    irp->name.s = irp->uri.s+4;
00148    irp->domain.len = domain->len;
00149    irp->domain.s = irp->uri.s+5+name->len;
00150    
00151    irp->flags  = flags;
00152    irp->hashid = core_case_hash(&irp->name, &irp->domain, 0);
00153    
00154    hidx = imc_get_hentry(irp->hashid, imc_hash_size);
00155 
00156    lock_get(&_imc_htable[hidx].lock);
00157    
00158    if(_imc_htable[hidx].rooms!=NULL)
00159    {
00160       irp->next = _imc_htable[hidx].rooms;
00161       _imc_htable[hidx].rooms->prev = irp;
00162       _imc_htable[hidx].rooms = irp;
00163    } else {
00164       _imc_htable[hidx].rooms = irp;
00165    }  
00166    
00167    return irp;
00168 }
00169 
00170 /**
00171  * release room
00172  */
00173 int imc_release_room(imc_room_p room)
00174 {
00175    unsigned int hidx;
00176    
00177    if(room==NULL)
00178    {
00179       LM_ERR("invalid parameters\n");
00180       return -1;
00181    }
00182    
00183    hidx = imc_get_hentry(room->hashid, imc_hash_size);
00184    lock_release(&_imc_htable[hidx].lock);
00185 
00186    return 0;
00187 }
00188 
00189 /**
00190  * search room
00191  */
00192 imc_room_p imc_get_room(str* name, str* domain)
00193 {
00194    imc_room_p irp = NULL;
00195    unsigned int hashid;
00196    int hidx;
00197    
00198    if(name == NULL || name->s==NULL || name->len<=0
00199          || domain == NULL || domain->s==NULL || domain->len<=0)
00200    {
00201       LM_ERR("invalid parameters\n");
00202       return NULL;
00203    }
00204    
00205    hashid = core_case_hash(name, domain, 0);
00206    
00207    hidx = imc_get_hentry(hashid, imc_hash_size);
00208 
00209    lock_get(&_imc_htable[hidx].lock);
00210    irp = _imc_htable[hidx].rooms;
00211 
00212    while(irp)
00213    {
00214       if(irp->hashid==hashid && irp->name.len==name->len
00215             && irp->domain.len==domain->len
00216             && !strncasecmp(irp->name.s, name->s, name->len)
00217             && !strncasecmp(irp->domain.s, domain->s, domain->len))
00218       {
00219          return irp;
00220       }
00221       irp = irp->next;
00222    }
00223 
00224    /* no room */
00225    lock_release(&_imc_htable[hidx].lock);
00226 
00227    return NULL;
00228 }
00229 
00230 /**
00231  * delete room
00232  */
00233 int imc_del_room(str* name, str* domain)
00234 {
00235    imc_room_p irp = NULL;
00236    imc_member_p imp=NULL, imp_temp=NULL;
00237    unsigned int hashid;
00238    int hidx;   
00239    
00240    if(name == NULL || name->s==NULL || name->len<=0
00241          || domain == NULL || domain->s==NULL || domain->len<=0)
00242    {
00243       LM_ERR("invalid parameters\n");
00244       return -1;
00245    }
00246    
00247    hashid = core_case_hash(name, domain, 0);
00248    
00249    hidx = imc_get_hentry(hashid, imc_hash_size);
00250    
00251    lock_get(&_imc_htable[hidx].lock);
00252    irp = _imc_htable[hidx].rooms;
00253    while(irp)
00254    {
00255       if(irp->hashid==hashid && irp->name.len==name->len
00256             && irp->domain.len==domain->len
00257             && !strncasecmp(irp->name.s, name->s, name->len)
00258             && !strncasecmp(irp->domain.s, domain->s, domain->len))
00259       {
00260          if(irp->prev==NULL)
00261             _imc_htable[hidx].rooms = irp->next;
00262          else
00263             irp->prev->next = irp->next;
00264          if(irp->next!=NULL)
00265             irp->next->prev = irp->prev;
00266 
00267          /* delete members */
00268          imp = irp->members;
00269          while(imp){
00270             imp_temp = imp->next;
00271             shm_free(imp);
00272             imp = imp_temp;
00273          }     
00274 
00275          shm_free(irp);
00276 
00277          goto done;
00278       }
00279       irp = irp->next;
00280    }
00281 
00282 done: 
00283    lock_release(&_imc_htable[hidx].lock);
00284 
00285    return 0;
00286 }
00287 
00288 /**
00289  * add member
00290  */
00291 imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags)
00292 {
00293    imc_member_p imp = NULL;
00294    int size;
00295    
00296    if(room==NULL || user == NULL || user->s==NULL || user->len<=0
00297          || domain == NULL || domain->s==NULL || domain->len<=0)
00298    {
00299       LM_ERR("invalid parameters\n");
00300       return NULL;
00301    }
00302    
00303    /* struct size + "sip:" + user name len + "@" + domain len + '\0' */
00304    size = sizeof(imc_member_t) + (user->len+domain->len+6)*sizeof(char);
00305    imp = (imc_member_p)shm_malloc(size);
00306    if(imp== NULL)
00307    {
00308       LM_ERR("out of shm memory\n");
00309       return NULL;
00310    }
00311    memset(imp, 0, size);
00312    
00313    imp->uri.len = 4 /*sip:*/ + user->len + 1 /*@*/ + domain->len;
00314    imp->uri.s = (char*)(((char*)imp)+sizeof(imc_member_t));
00315    memcpy(imp->uri.s, "sip:", 4);
00316    memcpy(imp->uri.s+4, user->s, user->len);
00317    imp->uri.s[4+user->len] = '@';
00318    memcpy(imp->uri.s+5+user->len, domain->s, domain->len);
00319    imp->uri.s[imp->uri.len] = '\0';
00320    
00321    LM_DBG("[uri]= %.*s\n", imp->uri.len, imp->uri.s);
00322    imp->user.len = user->len;
00323    imp->user.s = imp->uri.s+4;
00324    
00325    LM_DBG("[user]= %.*s\n", imp->user.len, imp->user.s);
00326    imp->domain.len = domain->len;
00327    imp->domain.s = imp->uri.s+5+user->len;
00328 
00329    imp->flags  = flags;
00330    imp->hashid = core_case_hash(&imp->user, &imp->domain, 0);
00331 
00332    room->nr_of_members++;
00333    
00334    if(room->members==NULL)
00335       room->members = imp;
00336    else {
00337       imp->next = room->members->next;
00338       if((room->members)->next!=NULL)
00339          ((room->members)->next)->prev = imp;
00340       imp->prev = room->members;
00341       
00342       room->members->next=imp;
00343    }
00344 
00345    return imp;
00346 }
00347 
00348 /**
00349  * search memeber
00350  */
00351 imc_member_p imc_get_member(imc_room_p room, str* user, str* domain)
00352 {
00353    imc_member_p imp = NULL;
00354    unsigned int hashid;
00355 
00356    if(room==NULL || user == NULL || user->s==NULL || user->len<=0
00357          || domain == NULL || domain->s==NULL || domain->len<=0)
00358    {
00359       LM_ERR("invalid parameters\n");
00360       return NULL;
00361    }
00362    
00363    hashid = core_case_hash(user, domain, 0);
00364    imp = room->members;
00365    while(imp)
00366    {
00367       if(imp->hashid==hashid && imp->user.len==user->len
00368             && imp->domain.len==domain->len
00369             && !strncasecmp(imp->user.s, user->s, user->len)
00370             && !strncasecmp(imp->domain.s, domain->s, domain->len))
00371       {
00372          LM_DBG("found member\n");
00373          return imp;
00374       }
00375       imp = imp->next;
00376    }
00377 
00378    return NULL;
00379 }
00380 
00381 /**
00382  * delete member
00383  */
00384 int imc_del_member(imc_room_p room, str* user, str* domain)
00385 {
00386    imc_member_p imp = NULL;
00387    unsigned int hashid;
00388    
00389    if(room==NULL || user == NULL || user->s==NULL || user->len<=0
00390          || domain == NULL || domain->s==NULL || domain->len<=0)
00391    {
00392       LM_ERR("invalid parameters\n");
00393       return -1;
00394    }
00395    
00396    hashid = core_case_hash(user, domain, 0);
00397    imp = room->members;
00398    while(imp)
00399    {
00400       if(imp->hashid==hashid && imp->user.len==user->len
00401             && imp->domain.len==domain->len
00402             && !strncasecmp(imp->user.s, user->s, user->len)
00403             && !strncasecmp(imp->domain.s, domain->s, domain->len))
00404       {
00405          if(imp->prev==NULL)
00406             room->members = imp->next;
00407          else
00408             imp->prev->next = imp->next;
00409          if(imp->next!=NULL)
00410             imp->next->prev = imp->prev;
00411          shm_free(imp);
00412          room->nr_of_members--;
00413          return 0;
00414       }
00415       imp = imp->next;
00416    }
00417    
00418    return 0;
00419 }

Generated on Wed May 23 06:00:46 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6