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
00029
00030
00031
00032
00033
00034
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
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
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
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
00093 struct sl_binds slb;
00094
00095
00096 db_con_t *pxml_db = NULL;
00097 db_func_t pxml_dbf;
00098
00099
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
00122 struct module_exports exports= {
00123 "presence_xml",
00124 DEFAULT_DLFLAGS,
00125 0,
00126 params,
00127 0,
00128 mi_cmds,
00129 0,
00130 0,
00131 mod_init,
00132 0,
00133 destroy,
00134 child_init
00135 };
00136
00137
00138
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
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
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
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
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
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 }