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 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <time.h>
00039
00040 #include "../../db/db.h"
00041 #include "../../dprint.h"
00042 #include "../../mem/shm_mem.h"
00043 #include "../../str.h"
00044 #include "../alias_db/alias_db.h"
00045 #include "../../data_lump_rpl.h"
00046 #include "presentity.h"
00047 #include "presence.h"
00048 #include "notify.h"
00049 #include "publish.h"
00050 #include "hash.h"
00051 #include "utils_func.h"
00052
00053
00054 xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name,
00055 const char *ns);
00056 static str pu_200_rpl = str_init("OK");
00057 static str pu_412_rpl = str_init("Conditional request failed");
00058
00059 #define ETAG_LEN 128
00060
00061 char* generate_ETag(int publ_count)
00062 {
00063 char* etag= NULL;
00064 int size = 0;
00065
00066 etag = (char*)pkg_malloc(ETAG_LEN*sizeof(char));
00067 if(etag ==NULL)
00068 {
00069 ERR_MEM(PKG_MEM_STR);
00070 }
00071 memset(etag, 0, ETAG_LEN*sizeof(char));
00072 size = snprintf (etag, ETAG_LEN, "%c.%d.%d.%d.%d",prefix, startup_time, pid, counter, publ_count);
00073 if( size <0 )
00074 {
00075 LM_ERR("unsuccessfull snprintf\n ");
00076 pkg_free(etag);
00077 return NULL;
00078 }
00079 if(size >= ETAG_LEN)
00080 {
00081 LM_ERR("buffer size overflown\n");
00082 pkg_free(etag);
00083 return NULL;
00084 }
00085
00086 etag[size] = '\0';
00087 LM_DBG("etag= %s / %d\n ",etag, size);
00088 return etag;
00089
00090 error:
00091 return NULL;
00092
00093 }
00094
00095 int publ_send200ok(struct sip_msg *msg, int lexpire, str etag)
00096 {
00097 char buf[128];
00098 int buf_len= 128, size;
00099 str hdr_append= {0, 0}, hdr_append2= {0, 0} ;
00100
00101 LM_DBG("send 200OK reply\n");
00102 LM_DBG("etag= %s - len= %d\n", etag.s, etag.len);
00103
00104 hdr_append.s = buf;
00105 hdr_append.s[0]='\0';
00106 hdr_append.len = snprintf(hdr_append.s, buf_len, "Expires: %d\r\n",
00107 ((lexpire==0)?0:(lexpire-expires_offset)));
00108 if(hdr_append.len < 0)
00109 {
00110 LM_ERR("unsuccessful snprintf\n");
00111 goto error;
00112 }
00113 if(hdr_append.len >= buf_len)
00114 {
00115 LM_ERR("buffer size overflown\n");
00116 goto error;
00117 }
00118 hdr_append.s[hdr_append.len]= '\0';
00119
00120 if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00121 {
00122 LM_ERR("unable to add lump_rl\n");
00123 goto error;
00124 }
00125
00126 size= sizeof(char)*(20+etag.len) ;
00127 hdr_append2.s = (char *)pkg_malloc(size);
00128 if(hdr_append2.s == NULL)
00129 {
00130 ERR_MEM(PKG_MEM_STR);
00131 }
00132 hdr_append2.s[0]='\0';
00133 hdr_append2.len = snprintf(hdr_append2.s, size, "SIP-ETag: %s\r\n", etag.s);
00134 if(hdr_append2.len < 0)
00135 {
00136 LM_ERR("unsuccessful snprintf\n ");
00137 goto error;
00138 }
00139 if(hdr_append2.len >= size)
00140 {
00141 LM_ERR("buffer size overflown\n");
00142 goto error;
00143 }
00144
00145 hdr_append2.s[hdr_append2.len]= '\0';
00146 if (add_lump_rpl(msg, hdr_append2.s, hdr_append2.len, LUMP_RPL_HDR)==0 )
00147 {
00148 LM_ERR("unable to add lump_rl\n");
00149 goto error;
00150 }
00151
00152 if( slb.send_reply( msg, 200, &pu_200_rpl)== -1)
00153 {
00154 LM_ERR("sending reply\n");
00155 goto error;
00156 }
00157
00158 pkg_free(hdr_append2.s);
00159 return 0;
00160
00161 error:
00162
00163 if(hdr_append2.s)
00164 pkg_free(hdr_append2.s);
00165
00166 return -1;
00167 }
00168 presentity_t* new_presentity( str* domain,str* user,int expires,
00169 pres_ev_t* event, str* etag, str* sender)
00170 {
00171 presentity_t *presentity= NULL;
00172 int size, init_len;
00173
00174
00175 size = sizeof(presentity_t)+ domain->len+ user->len+ etag->len +1;
00176 if(sender)
00177 size+= sizeof(str)+ sender->len* sizeof(char);
00178
00179 init_len= size;
00180
00181 presentity = (presentity_t*)pkg_malloc(size);
00182 if(presentity == NULL)
00183 {
00184 ERR_MEM(PKG_MEM_STR);
00185 }
00186 memset(presentity, 0, size);
00187 size= sizeof(presentity_t);
00188
00189 presentity->domain.s = (char*)presentity+ size;
00190 strncpy(presentity->domain.s, domain->s, domain->len);
00191 presentity->domain.len = domain->len;
00192 size+= domain->len;
00193
00194 presentity->user.s = (char*)presentity+size;
00195 strncpy(presentity->user.s, user->s, user->len);
00196 presentity->user.len = user->len;
00197 size+= user->len;
00198
00199 presentity->etag.s = (char*)presentity+ size;
00200 memcpy(presentity->etag.s, etag->s, etag->len);
00201 presentity->etag.s[etag->len]= '\0';
00202 presentity->etag.len = etag->len;
00203
00204 size+= etag->len+1;
00205
00206 if(sender)
00207 {
00208 presentity->sender= (str*)((char*)presentity+ size);
00209 size+= sizeof(str);
00210 presentity->sender->s= (char*)presentity + size;
00211 memcpy(presentity->sender->s, sender->s, sender->len);
00212 presentity->sender->len= sender->len;
00213 size+= sender->len;
00214 }
00215
00216 if(size> init_len)
00217 {
00218 LM_ERR("buffer size overflow init_len= %d, size= %d\n", init_len, size);
00219 goto error;
00220 }
00221 presentity->event= event;
00222 presentity->expires = expires;
00223 presentity->received_time= (int)time(NULL);
00224 return presentity;
00225
00226 error:
00227 if(presentity)
00228 pkg_free(presentity);
00229 return NULL;
00230 }
00231
00232 xmlNodePtr xmlNodeGetChildByName(xmlNodePtr node, const char *name)
00233 {
00234 xmlNodePtr cur = node->children;
00235 while (cur) {
00236 if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0)
00237 return cur;
00238 cur = cur->next;
00239 }
00240 return NULL;
00241 }
00242
00243 int check_if_dialog(str body, int *is_dialog)
00244 {
00245 xmlDocPtr doc;
00246 xmlNodePtr node;
00247
00248 doc = xmlParseMemory(body.s, body.len);
00249 if(doc== NULL)
00250 {
00251 LM_ERR("failed to parse xml document\n");
00252 return -1;
00253 }
00254
00255 node = doc->children;
00256 node = xmlNodeGetChildByName(node, "dialog");
00257
00258 if(node == NULL)
00259 *is_dialog = 0;
00260 else
00261 *is_dialog = 1;
00262
00263 xmlFreeDoc(doc);
00264 return 0;
00265 }
00266
00267
00268 int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body,
00269 int new_t, int* sent_reply, char* sphere)
00270 {
00271 db_key_t query_cols[12], update_keys[8], result_cols[5];
00272 db_op_t query_ops[12];
00273 db_val_t query_vals[12], update_vals[8];
00274 db_res_t *result= NULL;
00275 int n_query_cols = 0;
00276 int n_update_cols = 0;
00277 char* dot= NULL;
00278 str etag= {0, 0};
00279 str cur_etag= {0, 0};
00280 str* rules_doc= NULL;
00281 str pres_uri= {0, 0};
00282 int rez_body_col, rez_sender_col, n_result_cols= 0;
00283 db_row_t *row = NULL ;
00284 db_val_t *row_vals = NULL;
00285 str old_body, sender;
00286 int is_dialog= 0, bla_update_publish= 1;
00287
00288 *sent_reply= 0;
00289 if(presentity->event->req_auth)
00290 {
00291
00292 if(presentity->event->get_rules_doc(&presentity->user,
00293 &presentity->domain, &rules_doc))
00294 {
00295 LM_ERR("getting rules doc\n");
00296 goto error;
00297 }
00298 }
00299
00300 if(uandd_to_uri(presentity->user, presentity->domain, &pres_uri)< 0)
00301 {
00302 LM_ERR("constructing uri from user and domain\n");
00303 goto error;
00304 }
00305
00306
00307 query_cols[n_query_cols] = &str_domain_col;
00308 query_ops[n_query_cols] = OP_EQ;
00309 query_vals[n_query_cols].type = DB_STR;
00310 query_vals[n_query_cols].nul = 0;
00311 query_vals[n_query_cols].val.str_val = presentity->domain;
00312 n_query_cols++;
00313
00314 query_cols[n_query_cols] = &str_username_col;
00315 query_ops[n_query_cols] = OP_EQ;
00316 query_vals[n_query_cols].type = DB_STR;
00317 query_vals[n_query_cols].nul = 0;
00318 query_vals[n_query_cols].val.str_val = presentity->user;
00319 n_query_cols++;
00320
00321 query_cols[n_query_cols] = &str_event_col;
00322 query_ops[n_query_cols] = OP_EQ;
00323 query_vals[n_query_cols].type = DB_STR;
00324 query_vals[n_query_cols].nul = 0;
00325 query_vals[n_query_cols].val.str_val = presentity->event->name;
00326 n_query_cols++;
00327
00328 query_cols[n_query_cols] = &str_etag_col;
00329 query_ops[n_query_cols] = OP_EQ;
00330 query_vals[n_query_cols].type = DB_STR;
00331 query_vals[n_query_cols].nul = 0;
00332 query_vals[n_query_cols].val.str_val = presentity->etag;
00333 n_query_cols++;
00334
00335 result_cols[rez_body_col= n_result_cols++] = &str_body_col;
00336 result_cols[rez_sender_col= n_result_cols++] = &str_sender_col;
00337
00338 if(new_t)
00339 {
00340
00341
00342 if(insert_phtable(&pres_uri, presentity->event->evp->parsed, sphere)< 0)
00343 {
00344 LM_ERR("inserting record in hash table\n");
00345 goto error;
00346 }
00347
00348
00349 query_cols[n_query_cols] = &str_expires_col;
00350 query_vals[n_query_cols].type = DB_INT;
00351 query_vals[n_query_cols].nul = 0;
00352 query_vals[n_query_cols].val.int_val = presentity->expires+
00353 (int)time(NULL);
00354 n_query_cols++;
00355
00356 if( presentity->sender)
00357 {
00358 query_cols[n_query_cols] = &str_sender_col;
00359 query_vals[n_query_cols].type = DB_STR;
00360 query_vals[n_query_cols].nul = 0;
00361 query_vals[n_query_cols].val.str_val.s = presentity->sender->s;
00362 query_vals[n_query_cols].val.str_val.len = presentity->sender->len;
00363 n_query_cols++;
00364 }
00365
00366 query_cols[n_query_cols] = &str_body_col;
00367 query_vals[n_query_cols].type = DB_BLOB;
00368 query_vals[n_query_cols].nul = 0;
00369 query_vals[n_query_cols].val.str_val = *body;
00370 n_query_cols++;
00371
00372 query_cols[n_query_cols] = &str_received_time_col;
00373 query_vals[n_query_cols].type = DB_INT;
00374 query_vals[n_query_cols].nul = 0;
00375 query_vals[n_query_cols].val.int_val = presentity->received_time;
00376 n_query_cols++;
00377
00378 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00379 {
00380 LM_ERR("unsuccessful use_table\n");
00381 goto error;
00382 }
00383
00384 LM_DBG("inserting %d cols into table\n",n_query_cols);
00385
00386 if (pa_dbf.insert(pa_db, query_cols, query_vals, n_query_cols) < 0)
00387 {
00388 LM_ERR("inserting new record in database\n");
00389 goto error;
00390 }
00391 if( publ_send200ok(msg, presentity->expires, presentity->etag)< 0)
00392 {
00393 LM_ERR("sending 200OK\n");
00394 goto error;
00395 }
00396 *sent_reply= 1;
00397 goto send_notify;
00398 }
00399 else
00400 {
00401 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00402 {
00403 LM_ERR("unsuccessful sql use table\n");
00404 goto error;
00405 }
00406
00407 if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals,
00408 result_cols, n_query_cols, n_result_cols, 0, &result) < 0)
00409 {
00410 LM_ERR("unsuccessful sql query\n");
00411 goto error;
00412 }
00413 if(result== NULL)
00414 goto error;
00415
00416 if (result->n > 0)
00417 {
00418
00419 if(presentity->event->evp->parsed == EVENT_DIALOG_SLA)
00420 {
00421
00422 row = &result->rows[0];
00423 row_vals = ROW_VALUES(row);
00424
00425 old_body.s = (char*)row_vals[rez_body_col].val.string_val;
00426 old_body.len = strlen(old_body.s);
00427 if(check_if_dialog(*body, &is_dialog)< 0)
00428 {
00429 LM_ERR("failed to check if dialog stored\n");
00430 goto error;
00431 }
00432
00433 if(is_dialog== 1)
00434 goto after_dialog_check;
00435
00436 if(check_if_dialog(old_body, &is_dialog)< 0)
00437 {
00438 LM_ERR("failed to check if dialog stored\n");
00439 goto error;
00440 }
00441
00442 if(is_dialog==0 )
00443 goto after_dialog_check;
00444
00445 sender.s = (char*)row_vals[rez_sender_col].val.string_val;
00446 sender.len= strlen(sender.s);
00447
00448 LM_DBG("old_sender = %.*s\n", sender.len, sender.s );
00449 if(presentity->sender)
00450 {
00451 if(!(presentity->sender->len == sender.len &&
00452 strncmp(presentity->sender->s, sender.s, sender.len)== 0))
00453 bla_update_publish= 0;
00454 }
00455 }
00456 after_dialog_check:
00457
00458 pa_dbf.free_result(pa_db, result);
00459 result= NULL;
00460 if(presentity->expires == 0)
00461 {
00462 if( publ_send200ok(msg, presentity->expires, presentity->etag)< 0)
00463 {
00464 LM_ERR("sending 200OK reply\n");
00465 goto error;
00466 }
00467 *sent_reply= 1;
00468 if( publ_notify( presentity, pres_uri, body, &presentity->etag, rules_doc)< 0 )
00469 {
00470 LM_ERR("while sending notify\n");
00471 goto error;
00472 }
00473
00474 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00475 {
00476 LM_ERR("unsuccessful sql use table\n");
00477 goto error;
00478 }
00479
00480 LM_DBG("expires =0 -> deleting from database\n");
00481 if(pa_dbf.delete(pa_db,query_cols,0,query_vals,n_query_cols)<0)
00482 {
00483 LM_ERR("unsuccessful sql delete operation");
00484 goto error;
00485 }
00486 LM_DBG("deleted from db %.*s\n", presentity->user.len,
00487 presentity->user.s);
00488
00489
00490
00491 if(delete_phtable(&pres_uri, presentity->event->evp->parsed)< 0)
00492 {
00493 LM_ERR("deleting record from hash table\n");
00494 goto error;
00495 }
00496 goto done;
00497 }
00498
00499 n_update_cols= 0;
00500
00501
00502 if( (presentity->event->evp->parsed == EVENT_DIALOG_SLA) && bla_update_publish==0)
00503 {
00504 LM_DBG("drop Publish for BLA from a different sender that"
00505 " wants to overwrite an existing dialog\n");
00506 LM_DBG("sender = %.*s\n", presentity->sender->len, presentity->sender->s );
00507 if( publ_send200ok(msg, presentity->expires, presentity->etag)< 0)
00508 {
00509 LM_ERR("sending 200OK reply\n");
00510 goto error;
00511 }
00512 *sent_reply= 1;
00513 goto done;
00514 }
00515
00516 if(presentity->event->etag_not_new== 0)
00517 {
00518
00519 unsigned int publ_nr;
00520 str str_publ_nr= {0, 0};
00521
00522 dot= presentity->etag.s+ presentity->etag.len;
00523 while(*dot!= '.' && str_publ_nr.len< presentity->etag.len)
00524 {
00525 str_publ_nr.len++;
00526 dot--;
00527 }
00528 if(str_publ_nr.len== presentity->etag.len)
00529 {
00530 LM_ERR("wrong etag\n");
00531 goto error;
00532 }
00533 str_publ_nr.s= dot+1;
00534 str_publ_nr.len--;
00535
00536 if( str2int(&str_publ_nr, &publ_nr)< 0)
00537 {
00538 LM_ERR("converting string to int\n");
00539 goto error;
00540 }
00541 etag.s = generate_ETag(publ_nr+1);
00542 if(etag.s == NULL)
00543 {
00544 LM_ERR("while generating etag\n");
00545 goto error;
00546 }
00547 etag.len=(strlen(etag.s));
00548
00549 cur_etag= etag;
00550
00551 update_keys[n_update_cols] = &str_etag_col;
00552 update_vals[n_update_cols].type = DB_STR;
00553 update_vals[n_update_cols].nul = 0;
00554 update_vals[n_update_cols].val.str_val = etag;
00555 n_update_cols++;
00556
00557 }
00558 else
00559 cur_etag= presentity->etag;
00560
00561 update_keys[n_update_cols] = &str_expires_col;
00562 update_vals[n_update_cols].type = DB_INT;
00563 update_vals[n_update_cols].nul = 0;
00564 update_vals[n_update_cols].val.int_val= presentity->expires +
00565 (int)time(NULL);
00566 n_update_cols++;
00567
00568 update_keys[n_update_cols] = &str_received_time_col;
00569 update_vals[n_update_cols].type = DB_INT;
00570 update_vals[n_update_cols].nul = 0;
00571 update_vals[n_update_cols].val.int_val= presentity->received_time;
00572 n_update_cols++;
00573
00574 if(body && body->s)
00575 {
00576 update_keys[n_update_cols] = &str_body_col;
00577 update_vals[n_update_cols].type = DB_BLOB;
00578 update_vals[n_update_cols].nul = 0;
00579 update_vals[n_update_cols].val.str_val = *body;
00580 n_update_cols++;
00581
00582
00583 if(sphere_enable &&
00584 presentity->event->evp->parsed== EVENT_PRESENCE)
00585 {
00586 if(update_phtable(presentity, pres_uri, *body)< 0)
00587 {
00588 LM_ERR("failed to update sphere for presentity\n");
00589 goto error;
00590 }
00591 }
00592 }
00593
00594 if( presentity->sender)
00595 {
00596 update_keys[n_update_cols] = &str_sender_col;
00597 update_vals[n_update_cols].type = DB_STR;
00598 update_vals[n_update_cols].nul = 0;
00599 update_vals[n_update_cols].val.str_val = *presentity->sender;
00600 n_update_cols++;
00601 }
00602
00603 if( pa_dbf.update( pa_db,query_cols, query_ops, query_vals,
00604 update_keys, update_vals, n_query_cols, n_update_cols )<0)
00605 {
00606 LM_ERR("updating published info in database\n");
00607 goto error;
00608 }
00609
00610
00611 if( publ_send200ok(msg, presentity->expires, cur_etag)< 0)
00612 {
00613 LM_ERR("sending 200OK reply\n");
00614 goto error;
00615 }
00616 *sent_reply= 1;
00617
00618 if(etag.s)
00619 pkg_free(etag.s);
00620 etag.s= NULL;
00621
00622 if(!body)
00623 goto done;
00624
00625 goto send_notify;
00626 }
00627 else
00628 {
00629 pa_dbf.free_result(pa_db, result);
00630 result= NULL;
00631 LM_ERR("No E_Tag match\n");
00632 if (slb.send_reply(msg, 412, &pu_412_rpl) == -1)
00633 {
00634 LM_ERR("sending '412 Conditional request failed' reply\n");
00635 goto error;
00636 }
00637 *sent_reply= 1;
00638 goto done;
00639 }
00640 }
00641
00642 send_notify:
00643
00644
00645 if (publ_notify(presentity, pres_uri, body, NULL, rules_doc)<0)
00646 {
00647 LM_ERR("while sending Notify requests to watchers\n");
00648 goto error;
00649 }
00650
00651 done:
00652 if(rules_doc)
00653 {
00654 if(rules_doc->s)
00655 pkg_free(rules_doc->s);
00656 pkg_free(rules_doc);
00657 }
00658 if(pres_uri.s)
00659 pkg_free(pres_uri.s);
00660
00661 return 0;
00662
00663 error:
00664 if(result)
00665 pa_dbf.free_result(pa_db, result);
00666 if(etag.s)
00667 pkg_free(etag.s);
00668 if(rules_doc)
00669 {
00670 if(rules_doc->s)
00671 pkg_free(rules_doc->s);
00672 pkg_free(rules_doc);
00673 }
00674 if(pres_uri.s)
00675 pkg_free(pres_uri.s);
00676
00677 return -1;
00678
00679 }
00680
00681 int pres_htable_restore(void)
00682 {
00683
00684
00685 db_key_t result_cols[6];
00686 db_res_t *result= NULL;
00687 db_row_t *row= NULL ;
00688 db_val_t *row_vals;
00689 int i;
00690 str user, domain, ev_str, uri, body;
00691 int n_result_cols= 0;
00692 int user_col, domain_col, event_col, expires_col, body_col = 0;
00693 int event;
00694 event_t ev;
00695 char* sphere= NULL;
00696
00697 result_cols[user_col= n_result_cols++]= &str_username_col;
00698 result_cols[domain_col= n_result_cols++]= &str_domain_col;
00699 result_cols[event_col= n_result_cols++]= &str_event_col;
00700 result_cols[expires_col= n_result_cols++]= &str_expires_col;
00701 if(sphere_enable)
00702 result_cols[body_col= n_result_cols++]= &str_body_col;
00703
00704 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00705 {
00706 LM_ERR("unsuccessful use table sql operation\n");
00707 goto error;
00708 }
00709 static str query_str = str_init("username");
00710 if (pa_dbf.query (pa_db, 0, 0, 0,result_cols,0, n_result_cols,
00711 &query_str, &result) < 0)
00712 {
00713 LM_ERR("querying presentity\n");
00714 goto error;
00715 }
00716 if(result== NULL)
00717 goto error;
00718
00719 if(result->n<= 0)
00720 {
00721 pa_dbf.free_result(pa_db, result);
00722 return 0;
00723 }
00724
00725 for(i= 0; i< result->n; i++)
00726 {
00727 row = &result->rows[i];
00728 row_vals = ROW_VALUES(row);
00729
00730 if(row_vals[expires_col].val.int_val< (int)time(NULL))
00731 continue;
00732
00733 sphere= NULL;
00734 user.s= (char*)row_vals[user_col].val.string_val;
00735 user.len= strlen(user.s);
00736 domain.s= (char*)row_vals[domain_col].val.string_val;
00737 domain.len= strlen(domain.s);
00738 ev_str.s= (char*)row_vals[event_col].val.string_val;
00739 ev_str.len= strlen(ev_str.s);
00740
00741 if(event_parser(ev_str.s, ev_str.len, &ev)< 0)
00742 {
00743 LM_ERR("parsing event\n");
00744 free_event_params(ev.params, PKG_MEM_TYPE);
00745 goto error;
00746 }
00747 event= ev.parsed;
00748 free_event_params(ev.params, PKG_MEM_TYPE);
00749
00750 if(uandd_to_uri(user, domain, &uri)< 0)
00751 {
00752 LM_ERR("constructing uri\n");
00753 goto error;
00754 }
00755
00756
00757 if(sphere_enable && event== EVENT_PRESENCE )
00758 {
00759 body.s= (char*)row_vals[body_col].val.string_val;
00760 body.len= strlen(body.s);
00761 sphere= extract_sphere(body);
00762 }
00763
00764 if(insert_phtable(&uri, event, sphere)< 0)
00765 {
00766 LM_ERR("inserting record in presentity hash table");
00767 pkg_free(uri.s);
00768 if(sphere)
00769 pkg_free(sphere);
00770 goto error;
00771 }
00772 if(sphere)
00773 pkg_free(sphere);
00774 pkg_free(uri.s);
00775 }
00776 pa_dbf.free_result(pa_db, result);
00777
00778 return 0;
00779
00780 error:
00781 if(result)
00782 pa_dbf.free_result(pa_db, result);
00783 return -1;
00784 }
00785
00786 char* extract_sphere(str body)
00787 {
00788
00789
00790 xmlDocPtr doc= NULL;
00791 xmlNodePtr node;
00792 char* cont, *sphere= NULL;
00793
00794
00795 doc= xmlParseMemory(body.s, body.len);
00796 if(doc== NULL)
00797 {
00798 LM_ERR("failed to parse xml body\n");
00799 return NULL;
00800 }
00801
00802 node= xmlNodeGetNodeByName(doc->children, "sphere", "rpid");
00803
00804 if(node== NULL)
00805 node= xmlNodeGetNodeByName(doc->children, "sphere", "r");
00806
00807 if(node)
00808 {
00809 LM_DBG("found sphere definition\n");
00810 cont= (char*)xmlNodeGetContent(node);
00811 if(cont== NULL)
00812 {
00813 LM_ERR("failed to extract sphere node content\n");
00814 goto error;
00815 }
00816 sphere= (char*)pkg_malloc((strlen(cont)+ 1)*sizeof(char));
00817 if(sphere== NULL)
00818 {
00819 xmlFree(cont);
00820 ERR_MEM(PKG_MEM_STR);
00821 }
00822 strcpy(sphere, cont);
00823 xmlFree(cont);
00824 }
00825 else
00826 LM_DBG("didn't find sphere definition\n");
00827
00828 error:
00829 xmlFreeDoc(doc);
00830
00831 return sphere;
00832 }
00833
00834 xmlNodePtr xmlNodeGetNodeByName(xmlNodePtr node, const char *name,
00835 const char *ns)
00836 {
00837 xmlNodePtr cur = node;
00838 while (cur) {
00839 xmlNodePtr match = NULL;
00840 if (xmlStrcasecmp(cur->name, (unsigned char*)name) == 0) {
00841 if (!ns || (cur->ns && xmlStrcasecmp(cur->ns->prefix,
00842 (unsigned char*)ns) == 0))
00843 return cur;
00844 }
00845 match = xmlNodeGetNodeByName(cur->children, name, ns);
00846 if (match)
00847 return match;
00848 cur = cur->next;
00849 }
00850 return NULL;
00851 }
00852
00853 char* get_sphere(str* pres_uri)
00854 {
00855 unsigned int hash_code;
00856 char* sphere= NULL;
00857 pres_entry_t* p;
00858 db_key_t query_cols[6];
00859 db_val_t query_vals[6];
00860 db_key_t result_cols[6];
00861 db_res_t *result = NULL;
00862 db_row_t *row= NULL ;
00863 db_val_t *row_vals;
00864 int n_result_cols = 0;
00865 int n_query_cols = 0;
00866 struct sip_uri uri;
00867 str body;
00868
00869
00870 if(!sphere_enable)
00871 return NULL;
00872
00873
00874 hash_code= core_hash(pres_uri, NULL, phtable_size);
00875
00876 lock_get(&pres_htable[hash_code].lock);
00877
00878 p= search_phtable(pres_uri, EVENT_PRESENCE, hash_code);
00879
00880 if(p)
00881 {
00882 if(p->sphere)
00883 {
00884 sphere= (char*)pkg_malloc(strlen(p->sphere)* sizeof(char));
00885 if(sphere== NULL)
00886 {
00887 lock_release(&pres_htable[hash_code].lock);
00888 ERR_MEM(PKG_MEM_STR);
00889 }
00890 strcpy(sphere, p->sphere);
00891 }
00892 lock_release(&pres_htable[hash_code].lock);
00893 return sphere;
00894 }
00895 lock_release(&pres_htable[hash_code].lock);
00896
00897
00898
00899 if(!fallback2db)
00900 {
00901 return NULL;
00902 }
00903
00904 if(parse_uri(pres_uri->s, pres_uri->len, &uri)< 0)
00905 {
00906 LM_ERR("failed to parse presentity uri\n");
00907 goto error;
00908 }
00909
00910 query_cols[n_query_cols] = &str_domain_col;
00911 query_vals[n_query_cols].type = DB_STR;
00912 query_vals[n_query_cols].nul = 0;
00913 query_vals[n_query_cols].val.str_val = uri.host;
00914 n_query_cols++;
00915
00916 query_cols[n_query_cols] = &str_username_col;
00917 query_vals[n_query_cols].type = DB_STR;
00918 query_vals[n_query_cols].nul = 0;
00919 query_vals[n_query_cols].val.str_val = uri.user;
00920 n_query_cols++;
00921
00922 query_cols[n_query_cols] = &str_event_col;
00923 query_vals[n_query_cols].type = DB_STR;
00924 query_vals[n_query_cols].nul = 0;
00925 query_vals[n_query_cols].val.str_val.s= "presence";
00926 query_vals[n_query_cols].val.str_val.len= 8;
00927 n_query_cols++;
00928
00929 result_cols[n_result_cols++] = &str_body_col;
00930
00931 if (pa_dbf.use_table(pa_db, &presentity_table) < 0)
00932 {
00933 LM_ERR("in use_table\n");
00934 return NULL;
00935 }
00936
00937 static str query_str = str_init("received_time");
00938 if (pa_dbf.query (pa_db, query_cols, 0, query_vals,
00939 result_cols, n_query_cols, n_result_cols, &query_str , &result) < 0)
00940 {
00941 LM_ERR("failed to query %.*s table\n", presentity_table.len, presentity_table.s);
00942 if(result)
00943 pa_dbf.free_result(pa_db, result);
00944 return NULL;
00945 }
00946
00947 if(result== NULL)
00948 return NULL;
00949
00950 if (result->n<=0 )
00951 {
00952 LM_DBG("no published record found in database\n");
00953 pa_dbf.free_result(pa_db, result);
00954 return NULL;
00955 }
00956
00957 row = &result->rows[result->n-1];
00958 row_vals = ROW_VALUES(row);
00959 if(row_vals[0].val.string_val== NULL)
00960 {
00961 LM_ERR("NULL notify body record\n");
00962 goto error;
00963 }
00964
00965 body.s= (char*)row_vals[0].val.string_val;
00966 body.len= strlen(body.s);
00967 if(body.len== 0)
00968 {
00969 LM_ERR("Empty notify body record\n");
00970 goto error;
00971 }
00972
00973 sphere= extract_sphere(body);
00974
00975 pa_dbf.free_result(pa_db, result);
00976
00977 return sphere;
00978
00979 error:
00980 if(result)
00981 pa_dbf.free_result(pa_db, result);
00982 return NULL;
00983
00984 }
00985