presence/event_list.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Voice Sistem S.R.L.
00003  *
00004  * This file is part of Kamailio, a free SIP server.
00005  *
00006  * Kamailio is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version
00010  *
00011  * Kamailio is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License 
00017  * along with this program; if not, write to the Free Software 
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  * History:
00021  * --------
00022  *  2007-04-04  initial version (Anca Vamanu)
00023  */
00024 
00032 #include <stdlib.h>
00033 #include<stdio.h>
00034 #include <string.h>
00035 #include "../../str.h"
00036 #include "../../dprint.h"
00037 #include "../../parser/parse_event.h" 
00038 #include "../../mem/shm_mem.h" 
00039 #include "../../mem/mem.h" 
00040 #include "event_list.h"
00041 #include "hash.h"
00042 
00043 #define MAX_EVNAME_SIZE 20
00044 
00045 int search_event_params(event_t* ev, event_t* searched_ev);
00046 
00047 event_t* shm_copy_event(event_t* e)
00048 {
00049         event_t* ev= NULL;
00050         param_t* p1, *p2;
00051         int size;
00052 
00053         ev= (event_t*)shm_malloc(sizeof(event_t));
00054         if(ev== NULL)
00055         {
00056                 ERR_MEM(SHARE_MEM);
00057         }
00058         memset(ev, 0, sizeof(event_t));
00059 
00060         ev->name.s= (char*)shm_malloc(e->name.len* sizeof(char));
00061         if(ev->name.s== NULL)
00062         {
00063                 ERR_MEM(SHARE_MEM);
00064         }
00065         memcpy(ev->name.s, e->name.s, e->name.len);
00066         ev->name.len= e->name.len;
00067 
00068         p1= e->params.list;
00069         while(p1)
00070         {
00071                 size= sizeof(param_t)+ (p1->name.len+ p1->body.len)* sizeof(char);
00072                 p2= (param_t*)shm_malloc(size);
00073                 if(p2== NULL)
00074                 {
00075                         ERR_MEM(SHARE_MEM);
00076                 }
00077                 memset(p2, 0, size);
00078 
00079                 size= sizeof(param_t);
00080                 CONT_COPY(p2, p2->name, p1->name);
00081                 if(p1->body.s && p1->body.len)
00082                         CONT_COPY(p2, p2->body, p1->body);
00083                 p2->next= ev->params.list;
00084                 ev->params.list= p2;
00085 
00086                 /* Update parameter hooks in the shmmem copy, this is needed so that
00087                  * we can test for the presence of the sla parameter even in the
00088                  * shared copy of the event */
00089                 if (e->params.hooks.event_dialog.call_id == p1)
00090                         ev->params.hooks.event_dialog.call_id = p2;
00091                 if (e->params.hooks.event_dialog.from_tag == p1)
00092                         ev->params.hooks.event_dialog.from_tag = p2;
00093                 if (e->params.hooks.event_dialog.to_tag == p1)
00094                         ev->params.hooks.event_dialog.to_tag = p2;
00095                 if (e->params.hooks.event_dialog.include_session_description == p1) 
00096                         ev->params.hooks.event_dialog.include_session_description = p2;
00097                 if (e->params.hooks.event_dialog.sla == p1)
00098                         ev->params.hooks.event_dialog.sla = p2;
00099 
00100                 p1= p1->next;
00101         }
00102         ev->type= e->type;
00103 
00104         return ev;
00105 
00106 error:
00107         shm_free_event(ev);
00108         return NULL;
00109 }
00110 
00111 void shm_free_event(event_t* ev)
00112 {
00113         if(ev== NULL)
00114                 return;
00115         
00116         if(ev->name.s)
00117                 shm_free(ev->name.s);
00118 
00119         free_event_params(ev->params.list, SHM_MEM_TYPE);
00120 
00121         shm_free(ev);
00122 }
00123 
00124 
00125 int add_event(pres_ev_t* event)
00126 {
00127         pres_ev_t* ev= NULL;
00128         event_t parsed_event;
00129         str wipeer_name;
00130         char* sep;
00131         char buf[50];
00132         int not_in_list= 0;
00133 
00134         memset(&parsed_event, 0, sizeof(event_t));
00135 
00136         if(event->name.s== NULL || event->name.len== 0)
00137         {
00138                 LM_ERR("NULL event name\n");
00139                 return -1;
00140         }
00141 
00142         if(event->content_type.s== NULL || event->content_type.len== 0)
00143         {
00144                 LM_ERR("NULL content_type param\n");
00145                 return -1;
00146         }
00147         
00148         ev= contains_event(&event->name, &parsed_event);
00149         if(ev== NULL)
00150         {
00151                 not_in_list= 1;
00152                 ev= (pres_ev_t*)shm_malloc(sizeof(pres_ev_t));
00153                 if(ev== NULL)
00154                 {
00155                         free_event_params(parsed_event.params.list, PKG_MEM_TYPE);
00156                         ERR_MEM(SHARE_MEM);
00157                 }
00158                 memset(ev, 0, sizeof(pres_ev_t));
00159                 ev->name.s= (char*)shm_malloc(event->name.len* sizeof(char));
00160                 if(ev->name.s== NULL)
00161                 {
00162                         ERR_MEM(SHARE_MEM);
00163                 }
00164                 memcpy(ev->name.s, event->name.s, event->name.len);
00165                 ev->name.len= event->name.len;
00166 
00167                 ev->evp= shm_copy_event(&parsed_event);
00168                 if(ev->evp== NULL)
00169                 {
00170                         LM_ERR("copying event_t structure\n");
00171                         goto error;
00172                 }
00173         }
00174         else
00175         {
00176                 if(ev->content_type.s)
00177                 {
00178                         LM_DBG("Event already registered\n");
00179                         goto done;
00180                 }
00181         }
00182 
00183         ev->content_type.s=
00184                         (char*)shm_malloc(event->content_type.len* sizeof(char)) ;
00185         if(ev->content_type.s== NULL)
00186         {
00187                 ERR_MEM(SHARE_MEM);
00188         }       
00189         ev->content_type.len= event->content_type.len;
00190         memcpy(ev->content_type.s, event->content_type.s, event->content_type.len);
00191 
00192         for(sep=parsed_event.name.s; sep<parsed_event.name.s+parsed_event.name.len;
00193                         sep++)
00194                 if(*sep=='.') break;
00195         if(sep>=parsed_event.name.s+parsed_event.name.len) sep=0;
00196         if(sep && strncmp(sep+1, "winfo", 5)== 0)
00197         {       
00198                 ev->type= WINFO_TYPE;
00199                 wipeer_name.s= parsed_event.name.s;
00200                 wipeer_name.len= sep - parsed_event.name.s;
00201                 ev->wipeer= contains_event(&wipeer_name, NULL);
00202                 if (ev->wipeer) {
00203                         LM_DBG("Found wipeer event [%.*s] for event [%.*s]\n",
00204                                         wipeer_name.len,wipeer_name.s,
00205                                         parsed_event.name.len,parsed_event.name.s);
00206                 }
00207         }
00208         else
00209         {       
00210                 ev->type= PUBL_TYPE;
00211                 if (parsed_event.name.len + 6 > 50) {
00212                         LM_ERR("buffer too small\n");
00213                         goto error;
00214                 }
00215                 wipeer_name.s= buf;
00216                 memcpy(wipeer_name.s, parsed_event.name.s, parsed_event.name.len);
00217                 wipeer_name.len= parsed_event.name.len;
00218                 memcpy(wipeer_name.s+ wipeer_name.len, ".winfo", 6);
00219                 wipeer_name.len+= 6;
00220                 ev->wipeer= contains_event(&wipeer_name, NULL);
00221                 if (ev->wipeer) {
00222                         LM_DBG("Found wipeer event [%.*s] for event [%.*s]\n",
00223                                         wipeer_name.len,wipeer_name.s,
00224                                         parsed_event.name.len,parsed_event.name.s);
00225                 }
00226         }
00227         
00228         if(ev->wipeer)  
00229                 ev->wipeer->wipeer= ev;
00230 
00231         if(event->req_auth && 
00232                 ( event->get_auth_status==0 ||event->get_rules_doc== 0))
00233         {
00234                 LM_ERR("bad event structure\n");
00235                 goto error;
00236         }
00237         ev->req_auth= event->req_auth;
00238         ev->agg_nbody= event->agg_nbody;
00239         ev->apply_auth_nbody= event->apply_auth_nbody;
00240         ev->get_auth_status= event->get_auth_status;
00241         ev->get_rules_doc= event->get_rules_doc;
00242         ev->evs_publ_handl= event->evs_publ_handl;
00243         ev->evs_subs_handl= event->evs_subs_handl;
00244         ev->etag_not_new= event->etag_not_new;
00245         ev->aux_body_processing= event->aux_body_processing;
00246         ev->aux_free_body= event->aux_free_body;
00247         ev->free_body= event->free_body;
00248         ev->default_expires= event->default_expires;
00249 
00250         if(not_in_list)
00251         {
00252                 ev->next= EvList->events;
00253                 EvList->events= ev;
00254         }
00255         EvList->ev_count++;
00256         
00257         LM_DBG("succesfully added event: %.*s - len= %d\n",ev->name.len,
00258                         ev->name.s, ev->name.len);
00259 done:
00260         free_event_params(parsed_event.params.list, PKG_MEM_TYPE);
00261         return 0;
00262 error:
00263         free_event_params(parsed_event.params.list, PKG_MEM_TYPE);
00264         if(ev && not_in_list)
00265         {
00266                 free_pres_event(ev);    
00267         }
00268         return -1;
00269 }
00270 
00271 void free_pres_event(pres_ev_t* ev)
00272 {
00273         if(ev== NULL)
00274                 return;
00275 
00276         if(ev->name.s)
00277                 shm_free(ev->name.s);
00278         if(ev->content_type.s)
00279                 shm_free(ev->content_type.s);
00280         if(ev->wipeer)
00281                 ev->wipeer->wipeer = 0;
00282         shm_free_event(ev->evp);
00283         shm_free(ev);
00284 
00285 }
00286 
00287 evlist_t* init_evlist(void)
00288 {
00289         evlist_t*  list= NULL;
00290 
00291         list= (evlist_t*)shm_malloc(sizeof(evlist_t));
00292         if(list== NULL)
00293         {
00294                 LM_ERR("no more share memory\n");
00295                 return NULL;
00296         }
00297         list->ev_count= 0;
00298         list->events= NULL;
00299         
00300         return list;
00301 }       
00302 
00303 pres_ev_t* contains_event(str* sname, event_t* parsed_event)
00304 {
00305         event_t event;
00306         event_t *pe;
00307         pres_ev_t* e;
00308         
00309         pe = (parsed_event)?parsed_event:&event;
00310 
00311         memset(pe, 0, sizeof(event_t));
00312         if(event_parser(sname->s, sname->len, pe)< 0)
00313         {
00314                 LM_ERR("parsing event\n");
00315                 return NULL;
00316         }
00317         e= search_event(pe);
00318         if(parsed_event==0)
00319         {
00320                 free_event_params(pe->params.list, PKG_MEM_TYPE);
00321                 pe->params.list = NULL;
00322         }
00323 
00324         return e;
00325 }
00326 
00327 void free_event_params(param_t* params, int mem_type)
00328 {
00329         param_t* t1, *t2;
00330         t2= t1= params;
00331 
00332         while(t1)
00333         {
00334                 t2= t1->next;
00335                 if(mem_type == SHM_MEM_TYPE)
00336                         shm_free(t1);
00337                 else
00338                         pkg_free(t1);
00339                 t1= t2;
00340         }
00341         
00342 }
00343 
00344 pres_ev_t* search_event(event_t* event)
00345 {
00346         pres_ev_t* pres_ev;
00347         pres_ev= EvList->events;
00348 
00349         LM_DBG("start event= [%.*s/%d]\n", event->name.len, event->name.s,
00350                         event->type);
00351 
00352         while(pres_ev)
00353         {
00354                 if((pres_ev->evp->type== event->type && event->type!=EVENT_OTHER)
00355                         || (pres_ev->evp->name.len== event->name.len &&
00356                                 strncasecmp(pres_ev->evp->name.s,event->name.s,
00357                                         pres_ev->evp->name.len)== 0))
00358                 {
00359                         if((event->params.list== NULL && pres_ev->evp->params.list== NULL) || event->type==EVENT_UA_PROFILE)
00360                         {
00361                                 return pres_ev;
00362                         }
00363         
00364                         /* search all parameters in event in ev */
00365                         if(search_event_params(event, pres_ev->evp)< 0)
00366                                 goto cont;
00367                         
00368                         /* search all parameters in ev in event */
00369                         if(search_event_params(pres_ev->evp, event)< 0)
00370                                 goto cont;
00371 
00372                         return pres_ev;
00373                 }
00374 cont:           pres_ev= pres_ev->next;
00375         }
00376         return NULL;
00377 
00378 }
00379 
00380 int search_event_params(event_t* ev, event_t* searched_ev)
00381 {
00382         param_t* ps, *p;
00383         int found;
00384 
00385         ps= ev->params.list;
00386 
00387         while(ps)
00388         {
00389                 p= searched_ev->params.list;
00390                 found= 0;
00391         
00392                 while(p)
00393                 {
00394                         if(p->name.len== ps->name.len && 
00395                                 strncmp(p->name.s,ps->name.s, ps->name.len)== 0)
00396                                 if((p->body.s== 0 && ps->body.s== 0) ||
00397                                         (p->body.len== ps->body.len && 
00398                                         strncmp(p->body.s,ps->body.s,ps->body.len)== 0))
00399                                 {
00400                                         found= 1;
00401                                         break;
00402                                 }
00403                                 p= p->next;
00404                 }
00405                 if(found== 0)
00406                         return -1;
00407                 ps= ps->next;
00408         }
00409 
00410         return 1;
00411 
00412 }
00413 int get_event_list(str** ev_list)
00414 {       
00415         pres_ev_t* ev= EvList->events;
00416         int i;
00417         str* list;
00418         *ev_list= NULL;
00419         
00420         if(EvList->ev_count== 0)
00421                 return 0;
00422         
00423         list= (str*)pkg_malloc(sizeof(str));
00424         if(list== NULL)
00425         {
00426                 LM_ERR("No more memory\n");
00427                 return -1;
00428         }
00429         memset(list, 0, sizeof(str));
00430         list->s= (char*)pkg_malloc(EvList->ev_count* MAX_EVNAME_SIZE);
00431         if(list->s== NULL)
00432         {
00433                 LM_ERR("No more memory\n");
00434                 pkg_free(list);
00435                 return -1;
00436         }
00437         list->s[0]= '\0';
00438         
00439         for(i= 0; i< EvList->ev_count; i++)
00440         {
00441                 if(i> 0)
00442                 {
00443                         memcpy(list->s+ list->len, ", ", 2);
00444                         list->len+= 2;
00445                 }       
00446                 memcpy(list->s+ list->len, ev->name.s, ev->name.len );
00447                 list->len+= ev->name.len ;
00448                 ev= ev->next;
00449         }
00450         
00451         *ev_list= list;
00452         return 0;
00453 }
00454 
00455 void destroy_evlist(void)
00456 {
00457     pres_ev_t* e1, *e2;
00458     if (EvList) 
00459         {
00460                 e1= EvList->events;
00461                 while(e1)
00462             {
00463                         e2= e1->next;
00464                         free_pres_event(e1);
00465                         e1= e2;
00466             }   
00467                 shm_free(EvList);
00468     }
00469 }
00470