presence_xml.c

Go to the documentation of this file.
00001 /*
00002  * $Id: presence_xml.c 2006-12-07 18:05:05Z anca_vamanu$
00003  *
00004  * presence_xml module - Presence Handling XML bodies module
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  *  2007-04-12  initial version (anca)
00027  */
00028 
00029 /*! \file
00030  * \brief Kamailio Presence_XML :: Core
00031  * \ingroup presence_xml
00032  */
00033 
00034 /*! \defgroup presence_xml Presence_xml :: This module implements a range of XML-based SIP event packages for presence
00035  */
00036 
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <libxml/parser.h>
00042 #include <time.h>
00043 
00044 #include "../../sr_module.h"
00045 #include "../../dprint.h"
00046 #include "../../str.h"
00047 #include "../../ut.h"
00048 #include "../../parser/msg_parser.h"
00049 #include "../../parser/parse_uri.h"
00050 #include "../../mem/mem.h"
00051 #include "../presence/bind_presence.h"
00052 #include "../presence/hash.h"
00053 #include "../presence/notify.h"
00054 #include "../xcap_client/xcap_functions.h"
00055 #include "../sl/sl_api.h"
00056 #include "pidf.h"
00057 #include "add_events.h"
00058 #include "presence_xml.h"
00059 
00060 MODULE_VERSION
00061 #define S_TABLE_VERSION 3
00062 
00063 /** module functions */
00064 
00065 static int mod_init(void);
00066 static int child_init(int);
00067 static void destroy(void);
00068 static int pxml_add_xcap_server( modparam_t type, void* val);
00069 static int shm_copy_xcap_list(void);
00070 static void free_xs_list(xcap_serv_t* xs_list, int mem_type);
00071 static int xcap_doc_updated(int doc_type, str xid, char* doc);
00072 static int mi_child_init(void);
00073 static struct mi_root* dum(struct mi_root* cmd, void* param);
00074 
00075 /** module variables ***/
00076 add_event_t pres_add_event;
00077 update_watchers_t pres_update_watchers;
00078 pres_get_sphere_t pres_get_sphere;
00079 
00080 
00081 /* Module parameter variables */
00082 str xcap_table= str_init("xcap");
00083 str db_url = str_init(DEFAULT_DB_URL);
00084 int force_active= 0;
00085 int pidf_manipulation= 0;
00086 int integrated_xcap_server= 0;
00087 xcap_serv_t* xs_list= NULL;
00088 int disable_presence = 0;
00089 int disable_winfo    = 0;
00090 int disable_bla      = 0;
00091 
00092 /* SL bind */
00093 struct sl_binds slb;
00094 
00095 /* database connection */
00096 db_con_t *pxml_db = NULL;
00097 db_func_t pxml_dbf;
00098 
00099 /* functions imported from xcap_client module */
00100 
00101 xcapGetNewDoc_t xcap_GetNewDoc;
00102 
00103 static param_export_t params[]={
00104    { "db_url",    STR_PARAM, &db_url.s},
00105    { "xcap_table",      STR_PARAM, &xcap_table.s},
00106    { "force_active", INT_PARAM, &force_active },
00107    { "pidf_manipulation",  INT_PARAM, &pidf_manipulation},
00108    { "integrated_xcap_server", INT_PARAM, &integrated_xcap_server},
00109    { "xcap_server",        STR_PARAM|USE_FUNC_PARAM,(void*)pxml_add_xcap_server},
00110    { "disable_presence",   INT_PARAM, &disable_presence },
00111    { "disable_winfo",      INT_PARAM, &disable_winfo },
00112    { "disable_bla",     INT_PARAM, &disable_bla },
00113    { 0, 0, 0}
00114 };
00115 
00116 static mi_export_t mi_cmds[] = {
00117    { "dum",             dum,          0,  0,  mi_child_init},
00118    {  0,                0,            0,  0,        0      }
00119 };
00120 
00121 /** module exports */
00122 struct module_exports exports= {
00123    "presence_xml",      /* module name */
00124     DEFAULT_DLFLAGS, /* dlopen flags */
00125     0,         /* exported functions */
00126     params,    /* exported parameters */
00127     0,            /* exported statistics */
00128     mi_cmds,      /* exported MI functions */
00129     0,            /* exported pseudo-variables */
00130     0,            /* extra processes */
00131     mod_init,     /* module initialization function */
00132     0,            /* response handling function */
00133     destroy,      /* destroy function */
00134     child_init    /* per-child init function */
00135 };
00136    
00137 /**
00138  * init module function
00139  */
00140 static int mod_init(void)
00141 {
00142    bind_presence_t bind_presence;
00143    presence_api_t pres;
00144       
00145    db_url.len = db_url.s ? strlen(db_url.s) : 0;
00146    LM_DBG("db_url=%s/%d/%p\n",ZSW(db_url.s),db_url.len, db_url.s);
00147    xcap_table.len = xcap_table.s ? strlen(xcap_table.s) : 0;
00148    
00149    /* binding to mysql module  */
00150    if (db_bind_mod(&db_url, &pxml_dbf))
00151    {
00152       LM_ERR("Database module not found\n");
00153       return -1;
00154    }
00155    
00156    if (!DB_CAPABILITY(pxml_dbf, DB_CAP_ALL)) {
00157       LM_ERR("Database module does not implement all functions"
00158             " needed by the module\n");
00159       return -1;
00160    }
00161 
00162    pxml_db = pxml_dbf.init(&db_url);
00163    if (!pxml_db)
00164    {
00165       LM_ERR("while connecting to database\n");
00166       return -1;
00167    }
00168 
00169    if(db_check_table_version(&pxml_dbf, pxml_db, &xcap_table, S_TABLE_VERSION) < 0) {
00170       LM_ERR("error during table version check.\n");
00171       return -1;
00172    }
00173    /* load SL API */
00174    if(load_sl_api(&slb)==-1)
00175    {
00176       LM_ERR("can't load sl functions\n");
00177       return -1;
00178    }
00179 
00180    bind_presence= (bind_presence_t)find_export("bind_presence", 1,0);
00181    if (!bind_presence)
00182    {
00183       LM_ERR("Can't bind presence\n");
00184       return -1;
00185    }
00186    if (bind_presence(&pres) < 0)
00187    {
00188       LM_ERR("Can't bind module pua\n");
00189       return -1;
00190    }
00191    
00192    pres_get_sphere= pres.get_sphere;
00193    pres_add_event= pres.add_event;
00194    pres_update_watchers= pres.update_watchers_status;
00195    if (pres_add_event == NULL || pres_update_watchers== NULL)
00196    {
00197       LM_ERR("Can't import add_event\n");
00198       return -1;
00199    }
00200    if(xml_add_events()< 0)
00201    {
00202       LM_ERR("adding xml events\n");
00203       return -1;     
00204    }
00205    
00206    if(force_active== 0 && !integrated_xcap_server )
00207    {
00208       xcap_api_t xcap_api;
00209       bind_xcap_t bind_xcap;
00210 
00211       /* bind xcap */
00212       bind_xcap= (bind_xcap_t)find_export("bind_xcap", 1, 0);
00213       if (!bind_xcap)
00214       {
00215          LM_ERR("Can't bind xcap_client\n");
00216          return -1;
00217       }
00218    
00219       if (bind_xcap(&xcap_api) < 0)
00220       {
00221          LM_ERR("Can't bind xcap_api\n");
00222          return -1;
00223       }
00224       xcap_GetNewDoc= xcap_api.getNewDoc;
00225       if(xcap_GetNewDoc== NULL)
00226       {
00227          LM_ERR("can't import get_elem from xcap_client module\n");
00228          return -1;
00229       }
00230    
00231       if(xcap_api.register_xcb(PRES_RULES, xcap_doc_updated)< 0)
00232       {
00233          LM_ERR("registering xcap callback function\n");
00234          return -1;
00235       }
00236    }
00237 
00238    if(shm_copy_xcap_list()< 0)
00239    {
00240       LM_ERR("copying xcap server list in share memory\n");
00241       return -1;
00242    }
00243 
00244    if(pxml_db)
00245       pxml_dbf.close(pxml_db);
00246    pxml_db = NULL;
00247 
00248    return 0;
00249 }
00250 
00251 static int mi_child_init(void)
00252 {  
00253    if (pxml_dbf.init==0)
00254    {
00255       LM_CRIT("database not bound\n");
00256       return -1;
00257    }
00258    pxml_db = pxml_dbf.init(&db_url);
00259    if (pxml_db== NULL)
00260    {
00261       LM_ERR("while connecting database\n");
00262       return -1;
00263    }
00264       
00265    if (pxml_dbf.use_table(pxml_db, &xcap_table) < 0)
00266    {
00267       LM_ERR("in use_table SQL operation\n");
00268       return -1;
00269    }
00270    
00271    LM_DBG("Database connection opened successfully\n");
00272 
00273    return 0;
00274 }  
00275 
00276 static int child_init(int rank)
00277 {
00278    LM_DBG("[%d]  pid [%d]\n", rank, getpid());
00279    
00280    if (pxml_dbf.init==0)
00281    {
00282       LM_CRIT("database not bound\n");
00283       return -1;
00284    }
00285    pxml_db = pxml_dbf.init(&db_url);
00286    if (pxml_db== NULL)
00287    {
00288       LM_ERR("child %d: ERROR while connecting database\n",rank);
00289       return -1;
00290    }
00291    if (pxml_dbf.use_table(pxml_db, &xcap_table) < 0)
00292    {
00293       LM_ERR("child %d: ERROR in use_table\n", rank);
00294       return -1;
00295    }
00296    
00297    LM_DBG("child %d: Database connection opened successfully\n",rank);
00298 
00299    return 0;
00300 }  
00301 
00302 static void destroy(void)
00303 {  
00304    LM_DBG("start\n");
00305    if(pxml_db && pxml_dbf.close)
00306       pxml_dbf.close(pxml_db);
00307 
00308    free_xs_list(xs_list, SHM_MEM_TYPE);
00309 
00310    return ;
00311 }
00312 
00313 static int pxml_add_xcap_server( modparam_t type, void* val)
00314 {
00315    xcap_serv_t* xs;
00316    int size;
00317    char* serv_addr= (char*)val;
00318    char* sep= NULL;
00319    unsigned int port= 80;
00320    str serv_addr_str;
00321       
00322    serv_addr_str.s= serv_addr;
00323    serv_addr_str.len= strlen(serv_addr);
00324 
00325    sep= strchr(serv_addr, ':');
00326    if(sep)
00327    {  
00328       char* sep2= NULL;
00329       str port_str;
00330       
00331       sep2= strchr(sep+ 1, ':');
00332       if(sep2)
00333          sep= sep2;
00334       
00335 
00336       port_str.s= sep+ 1;
00337       port_str.len= serv_addr_str.len- (port_str.s- serv_addr);
00338 
00339       if(str2int(&port_str, &port)< 0)
00340       {
00341          LM_ERR("while converting string to int\n");
00342          goto error;
00343       }
00344       if(port< 0 || port> 65535)
00345       {
00346          LM_ERR("wrong port number\n");
00347          goto error;
00348       }
00349       *sep = '\0';
00350       serv_addr_str.len= sep- serv_addr;
00351    }
00352 
00353    size= sizeof(xcap_serv_t)+ (serv_addr_str.len+ 1)* sizeof(char);
00354    xs= (xcap_serv_t*)pkg_malloc(size);
00355    if(xs== NULL)
00356    {
00357       ERR_MEM(PKG_MEM_STR);
00358    }
00359    memset(xs, 0, size);
00360    size= sizeof(xcap_serv_t);
00361 
00362    xs->addr= (char*)xs+ size;
00363    strcpy(xs->addr, serv_addr);
00364 
00365    xs->port= port;
00366    /* check for duplicates */
00367    xs->next= xs_list;
00368    xs_list= xs;
00369    return 0;
00370 
00371 error:
00372    free_xs_list(xs_list, PKG_MEM_TYPE);
00373    return -1;
00374 }
00375 
00376 static int shm_copy_xcap_list(void)
00377 {
00378    xcap_serv_t* xs, *shm_xs, *prev_xs;
00379    int size;
00380 
00381    xs= xs_list;
00382    if(xs== NULL)
00383    {
00384       if(force_active== 0 && !integrated_xcap_server)
00385       {
00386          LM_ERR("no xcap_server parameter set\n");
00387          return -1;
00388       }
00389       return 0;
00390    }
00391    xs_list= NULL;
00392    size= sizeof(xcap_serv_t);
00393    
00394    while(xs)
00395    {
00396       size+= (strlen(xs->addr)+ 1)* sizeof(char);
00397       shm_xs= (xcap_serv_t*)shm_malloc(size);
00398       if(shm_xs== NULL)
00399       {
00400          ERR_MEM(SHARE_MEM);
00401       }
00402       memset(shm_xs, 0, size);
00403       size= sizeof(xcap_serv_t);
00404 
00405       shm_xs->addr= (char*)shm_xs+ size;
00406       strcpy(shm_xs->addr, xs->addr);
00407       shm_xs->port= xs->port;
00408       shm_xs->next= xs_list; 
00409       xs_list= shm_xs;
00410 
00411       prev_xs= xs;
00412       xs= xs->next;
00413 
00414       pkg_free(prev_xs);
00415    }
00416    return 0;
00417 
00418 error:
00419    free_xs_list(xs_list, SHM_MEM_TYPE);
00420    return -1;
00421 }
00422 
00423 static void free_xs_list(xcap_serv_t* xsl, int mem_type)
00424 {
00425    xcap_serv_t* xs, *prev_xs;
00426 
00427    xs= xsl;
00428 
00429    while(xs)
00430    {
00431       prev_xs= xs;
00432       xs= xs->next;
00433       if(mem_type & SHM_MEM_TYPE)
00434          shm_free(prev_xs);
00435       else
00436          pkg_free(prev_xs);
00437    }
00438    xsl= NULL;
00439 }
00440 
00441 static int xcap_doc_updated(int doc_type, str xid, char* doc)
00442 {
00443    pres_ev_t ev;
00444    str rules_doc;
00445 
00446    /* call updating watchers */
00447    ev.name.s= "presence";
00448    ev.name.len= PRES_LEN;
00449 
00450    rules_doc.s= doc;
00451    rules_doc.len= strlen(doc);
00452 
00453    if(pres_update_watchers(xid, &ev, &rules_doc)< 0)
00454    {
00455       LM_ERR("updating watchers in presence\n");
00456       return -1;  
00457    }
00458    return 0;
00459 
00460 }
00461 
00462 static struct mi_root* dum(struct mi_root* cmd, void* param)
00463 {
00464    return 0;
00465 }

Generated on Thu May 24 08:00:52 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6