00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <libxml/parser.h>
00040 #include <time.h>
00041
00042 #include "../../sr_module.h"
00043 #include "../../dprint.h"
00044 #include "../../str.h"
00045 #include "../../ut.h"
00046 #include "../../parser/msg_parser.h"
00047 #include "../../parser/parse_uri.h"
00048 #include "../../mem/mem.h"
00049 #include "../presence/bind_presence.h"
00050 #include "../presence/hash.h"
00051 #include "../presence/notify.h"
00052 #include "../xcap_client/xcap_functions.h"
00053 #include "../../modules/sl/sl.h"
00054 #include "../../lib/kmi/mi.h"
00055 #include "../../mod_fix.h"
00056 #include "pidf.h"
00057 #include "add_events.h"
00058 #include "presence_xml.h"
00059 #include "pres_check.h"
00060 #include "api.h"
00061
00062 MODULE_VERSION
00063 #define S_TABLE_VERSION 4
00064
00067 static int mod_init(void);
00068 static int child_init(int);
00069 static void destroy(void);
00070 static int pxml_add_xcap_server( modparam_t type, void* val);
00071 static int shm_copy_xcap_list(void);
00072 static void free_xs_list(xcap_serv_t* xs_list, int mem_type);
00073 static int xcap_doc_updated(int doc_type, str xid, char* doc);
00074 static int mi_child_init(void);
00075 static struct mi_root* dum(struct mi_root* cmd, void* param);
00076
00077 static int fixup_presxml_check(void **param, int param_no);
00078 static int w_presxml_check_basic(struct sip_msg *msg, char *presentity_uri, char *status);
00079 static int w_presxml_check_activities(struct sip_msg *msg, char *presentity_uri, char *activities);
00080
00082 add_event_t pres_add_event;
00083 update_watchers_t pres_update_watchers;
00084 pres_get_sphere_t pres_get_sphere;
00085
00086
00087
00088 str xcap_table= str_init("xcap");
00089 str db_url = str_init(DEFAULT_DB_URL);
00090 int force_active= 0;
00091 int pidf_manipulation= 0;
00092 int integrated_xcap_server= 0;
00093 xcap_serv_t* xs_list= NULL;
00094 int disable_presence = 0;
00095 int disable_winfo = 0;
00096 int disable_bla = 1;
00097 int passive_mode = 0;
00098
00100 sl_api_t slb;
00101
00102
00103 db1_con_t *pxml_db = NULL;
00104 db_func_t pxml_dbf;
00105
00106
00107
00108 xcapGetNewDoc_t xcap_GetNewDoc;
00109
00110 static cmd_export_t cmds[]={
00111 { "pres_check_basic", (cmd_function)w_presxml_check_basic, 2,
00112 fixup_presxml_check, 0, ANY_ROUTE},
00113 { "pres_check_activities", (cmd_function)w_presxml_check_activities, 2,
00114 fixup_presxml_check, 0, ANY_ROUTE},
00115 { "bind_presence_xml", (cmd_function)bind_presence_xml, 1,
00116 0, 0, 0},
00117 { 0, 0, 0, 0, 0, 0}
00118 };
00119
00120 static param_export_t params[]={
00121 { "db_url", STR_PARAM, &db_url.s},
00122 { "xcap_table", STR_PARAM, &xcap_table.s},
00123 { "force_active", INT_PARAM, &force_active },
00124 { "pidf_manipulation", INT_PARAM, &pidf_manipulation},
00125 { "integrated_xcap_server", INT_PARAM, &integrated_xcap_server},
00126 { "xcap_server", STR_PARAM|USE_FUNC_PARAM,(void*)pxml_add_xcap_server},
00127 { "disable_presence", INT_PARAM, &disable_presence },
00128 { "disable_winfo", INT_PARAM, &disable_winfo },
00129 { "disable_bla", INT_PARAM, &disable_bla },
00130 { "passive_mode", INT_PARAM, &passive_mode },
00131 { 0, 0, 0}
00132 };
00133
00134 static mi_export_t mi_cmds[] = {
00135 { "dum", dum, 0, 0, mi_child_init},
00136 { 0, 0, 0, 0, 0 }
00137 };
00138
00139
00141 struct module_exports exports= {
00142 "presence_xml",
00143 DEFAULT_DLFLAGS,
00144 cmds,
00145 params,
00146 0,
00147 mi_cmds,
00148 0,
00149 0,
00150 mod_init,
00151 0,
00152 destroy,
00153 child_init
00154 };
00155
00159 static int mod_init(void)
00160 {
00161 bind_presence_t bind_presence;
00162 presence_api_t pres;
00163
00164 if(passive_mode==1)
00165 return 0;
00166
00167 if(register_mi_mod(exports.name, mi_cmds)!=0)
00168 {
00169 LM_ERR("failed to register MI commands\n");
00170 return -1;
00171 }
00172
00173 db_url.len = db_url.s ? strlen(db_url.s) : 0;
00174 LM_DBG("db_url=%s/%d/%p\n",ZSW(db_url.s),db_url.len, db_url.s);
00175 xcap_table.len = xcap_table.s ? strlen(xcap_table.s) : 0;
00176
00177
00178
00179 if (sl_load_api(&slb)!=0) {
00180 LM_ERR("cannot bind to SL API\n");
00181 return -1;
00182 }
00183
00184 bind_presence= (bind_presence_t)find_export("bind_presence", 1,0);
00185 if (!bind_presence)
00186 {
00187 LM_ERR("Can't bind presence\n");
00188 return -1;
00189 }
00190 if (bind_presence(&pres) < 0)
00191 {
00192 LM_ERR("Can't bind to presence module\n");
00193 return -1;
00194 }
00195
00196 pres_get_sphere= pres.get_sphere;
00197 pres_add_event= pres.add_event;
00198 pres_update_watchers= pres.update_watchers_status;
00199 pres_contains_event= pres.contains_event;
00200 pres_get_presentity= pres.get_presentity;
00201 pres_free_presentity= pres.free_presentity;
00202 if (pres_add_event == NULL || pres_update_watchers== NULL)
00203 {
00204 LM_ERR("Can't import add_event\n");
00205 return -1;
00206 }
00207 if(xml_add_events()< 0)
00208 {
00209 LM_ERR("adding xml events\n");
00210 return -1;
00211 }
00212
00213 if(force_active== 0)
00214 {
00215
00216 if (db_bind_mod(&db_url, &pxml_dbf))
00217 {
00218 LM_ERR("Database module not found\n");
00219 return -1;
00220 }
00221
00222 if (!DB_CAPABILITY(pxml_dbf, DB_CAP_ALL)) {
00223 LM_ERR("Database module does not implement all functions"
00224 " needed by the module\n");
00225 return -1;
00226 }
00227
00228 pxml_db = pxml_dbf.init(&db_url);
00229 if (!pxml_db)
00230 {
00231 LM_ERR("while connecting to database\n");
00232 return -1;
00233 }
00234
00235 if(db_check_table_version(&pxml_dbf, pxml_db, &xcap_table, S_TABLE_VERSION) < 0) {
00236 LM_ERR("error during table version check.\n");
00237 return -1;
00238 }
00239 if(!integrated_xcap_server )
00240 {
00241 xcap_api_t xcap_api;
00242 bind_xcap_t bind_xcap;
00243
00244
00245 bind_xcap= (bind_xcap_t)find_export("bind_xcap", 1, 0);
00246 if (!bind_xcap)
00247 {
00248 LM_ERR("Can't bind xcap_client\n");
00249 return -1;
00250 }
00251
00252 if (bind_xcap(&xcap_api) < 0)
00253 {
00254 LM_ERR("Can't bind xcap_api\n");
00255 return -1;
00256 }
00257 xcap_GetNewDoc= xcap_api.getNewDoc;
00258 if(xcap_GetNewDoc== NULL)
00259 {
00260 LM_ERR("can't import get_elem from xcap_client module\n");
00261 return -1;
00262 }
00263
00264 if(xcap_api.register_xcb(PRES_RULES, xcap_doc_updated)< 0)
00265 {
00266 LM_ERR("registering xcap callback function\n");
00267 return -1;
00268 }
00269 }
00270 }
00271
00272 if(shm_copy_xcap_list()< 0)
00273 {
00274 LM_ERR("copying xcap server list in share memory\n");
00275 return -1;
00276 }
00277
00278 if(pxml_db)
00279 pxml_dbf.close(pxml_db);
00280 pxml_db = NULL;
00281
00282 return 0;
00283 }
00284
00285 static int mi_child_init(void)
00286 {
00287 if(passive_mode==1)
00288 return 0;
00289
00290 if(force_active== 0)
00291 {
00292 if(pxml_db)
00293 return 0;
00294 pxml_db = pxml_dbf.init(&db_url);
00295 if (pxml_db== NULL)
00296 {
00297 LM_ERR("while connecting database\n");
00298 return -1;
00299 }
00300 if (pxml_dbf.use_table(pxml_db, &xcap_table) < 0)
00301 {
00302 LM_ERR("in use_table SQL operation\n");
00303 return -1;
00304 }
00305 }
00306
00307 LM_DBG("Database connection opened successfully\n");
00308
00309 return 0;
00310 }
00311
00312 static int child_init(int rank)
00313 {
00314 LM_DBG("[%d] pid [%d]\n", rank, getpid());
00315
00316 if(passive_mode==1)
00317 return 0;
00318
00319 if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00320 return 0;
00321
00322 if(force_active== 0)
00323 {
00324 if(pxml_db)
00325 return 0;
00326 pxml_db = pxml_dbf.init(&db_url);
00327 if (pxml_db== NULL)
00328 {
00329 LM_ERR("while connecting database\n");
00330 return -1;
00331 }
00332 if (pxml_dbf.use_table(pxml_db, &xcap_table) < 0)
00333 {
00334 LM_ERR("in use_table SQL operation\n");
00335 return -1;
00336 }
00337 }
00338
00339 LM_DBG("child %d: Database connection opened successfully\n",rank);
00340
00341 return 0;
00342 }
00343
00344 static void destroy(void)
00345 {
00346 LM_DBG("start\n");
00347 if(pxml_db && pxml_dbf.close)
00348 pxml_dbf.close(pxml_db);
00349
00350 free_xs_list(xs_list, SHM_MEM_TYPE);
00351
00352 return ;
00353 }
00354
00355 static int pxml_add_xcap_server( modparam_t type, void* val)
00356 {
00357 xcap_serv_t* xs;
00358 int size;
00359 char* serv_addr= (char*)val;
00360 char* sep= NULL;
00361 unsigned int port= 80;
00362 str serv_addr_str;
00363
00364 serv_addr_str.s= serv_addr;
00365 serv_addr_str.len= strlen(serv_addr);
00366
00367 sep= strchr(serv_addr, ':');
00368 if(sep)
00369 {
00370 char* sep2= NULL;
00371 str port_str;
00372
00373 sep2= strchr(sep+ 1, ':');
00374 if(sep2)
00375 sep= sep2;
00376
00377
00378 port_str.s= sep+ 1;
00379 port_str.len= serv_addr_str.len- (port_str.s- serv_addr);
00380
00381 if(str2int(&port_str, &port)< 0)
00382 {
00383 LM_ERR("while converting string to int\n");
00384 goto error;
00385 }
00386 if(port< 0 || port> 65535)
00387 {
00388 LM_ERR("wrong port number\n");
00389 goto error;
00390 }
00391 *sep = '\0';
00392 serv_addr_str.len= sep- serv_addr;
00393 }
00394
00395 size= sizeof(xcap_serv_t)+ (serv_addr_str.len+ 1)* sizeof(char);
00396 xs= (xcap_serv_t*)pkg_malloc(size);
00397 if(xs== NULL)
00398 {
00399 ERR_MEM(PKG_MEM_STR);
00400 }
00401 memset(xs, 0, size);
00402 size= sizeof(xcap_serv_t);
00403
00404 xs->addr= (char*)xs+ size;
00405 strcpy(xs->addr, serv_addr);
00406
00407 xs->port= port;
00408
00409 xs->next= xs_list;
00410 xs_list= xs;
00411 return 0;
00412
00413 error:
00414 free_xs_list(xs_list, PKG_MEM_TYPE);
00415 return -1;
00416 }
00417
00418 static int shm_copy_xcap_list(void)
00419 {
00420 xcap_serv_t* xs, *shm_xs, *prev_xs;
00421 int size;
00422
00423 xs= xs_list;
00424 if(xs== NULL)
00425 {
00426 if(force_active== 0 && !integrated_xcap_server)
00427 {
00428 LM_ERR("no xcap_server parameter set\n");
00429 return -1;
00430 }
00431 return 0;
00432 }
00433 xs_list= NULL;
00434 size= sizeof(xcap_serv_t);
00435
00436 while(xs)
00437 {
00438 size+= (strlen(xs->addr)+ 1)* sizeof(char);
00439 shm_xs= (xcap_serv_t*)shm_malloc(size);
00440 if(shm_xs== NULL)
00441 {
00442 ERR_MEM(SHARE_MEM);
00443 }
00444 memset(shm_xs, 0, size);
00445 size= sizeof(xcap_serv_t);
00446
00447 shm_xs->addr= (char*)shm_xs+ size;
00448 strcpy(shm_xs->addr, xs->addr);
00449 shm_xs->port= xs->port;
00450 shm_xs->next= xs_list;
00451 xs_list= shm_xs;
00452
00453 prev_xs= xs;
00454 xs= xs->next;
00455
00456 pkg_free(prev_xs);
00457 }
00458 return 0;
00459
00460 error:
00461 free_xs_list(xs_list, SHM_MEM_TYPE);
00462 return -1;
00463 }
00464
00465 static void free_xs_list(xcap_serv_t* xsl, int mem_type)
00466 {
00467 xcap_serv_t* xs, *prev_xs;
00468
00469 xs= xsl;
00470
00471 while(xs)
00472 {
00473 prev_xs= xs;
00474 xs= xs->next;
00475 if(mem_type & SHM_MEM_TYPE)
00476 shm_free(prev_xs);
00477 else
00478 pkg_free(prev_xs);
00479 }
00480 xsl= NULL;
00481 }
00482
00483 static int xcap_doc_updated(int doc_type, str xid, char* doc)
00484 {
00485 pres_ev_t ev;
00486 str rules_doc;
00487
00488
00489 ev.name.s= "presence";
00490 ev.name.len= PRES_LEN;
00491
00492 rules_doc.s= doc;
00493 rules_doc.len= strlen(doc);
00494
00495 if(pres_update_watchers(xid, &ev, &rules_doc)< 0)
00496 {
00497 LM_ERR("updating watchers in presence\n");
00498 return -1;
00499 }
00500 return 0;
00501
00502 }
00503
00504 static struct mi_root* dum(struct mi_root* cmd, void* param)
00505 {
00506 return 0;
00507 }
00508
00509 int bind_presence_xml(struct presence_xml_binds *pxb)
00510 {
00511 if (pxb == NULL)
00512 {
00513 LM_WARN("bind_presence_xml: Cannot load presence_xml API into a NULL pointer\n");
00514 return -1;
00515 }
00516
00517 pxb->pres_check_basic = presxml_check_basic;
00518 pxb->pres_check_activities = presxml_check_activities;
00519 return 0;
00520 }
00521
00522 static int fixup_presxml_check(void **param, int param_no)
00523 {
00524 if(param_no==1)
00525 {
00526 return fixup_spve_null(param, 1);
00527 } else if(param_no==2) {
00528 return fixup_spve_null(param, 1);
00529 }
00530 return 0;
00531 }
00532
00533 static int w_presxml_check_basic(struct sip_msg *msg, char *presentity_uri, char *status)
00534 {
00535 str uri, basic;
00536
00537 if (fixup_get_svalue(msg, (gparam_p)presentity_uri, &uri) != 0)
00538 {
00539 LM_ERR("invalid presentity uri parameter\n");
00540 return -1;
00541 }
00542
00543 if (fixup_get_svalue(msg, (gparam_p)status, &basic) != 0)
00544 {
00545 LM_ERR("invalid status parameter\n");
00546 return -1;
00547 }
00548
00549 return presxml_check_basic(msg, uri, basic);
00550 }
00551
00552 static int w_presxml_check_activities(struct sip_msg *msg, char *presentity_uri, char *activity)
00553 {
00554 str uri, act;
00555
00556 if (fixup_get_svalue(msg, (gparam_p)presentity_uri, &uri) != 0)
00557 {
00558 LM_ERR("invalid presentity uri parameter\n");
00559 return -1;
00560 }
00561
00562 if (fixup_get_svalue(msg, (gparam_p)activity, &act) != 0)
00563 {
00564 LM_ERR("invalid activity parameter\n");
00565 return -1;
00566 }
00567
00568 return presxml_check_activities(msg, uri, act);
00569 }