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 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <libxml/parser.h>
00032 #include "../../parser/parse_content.h"
00033 #include "../../parser/parse_from.h"
00034 #include "../../cmpapi.h"
00035 #include "../pua/hash.h"
00036 #include "rls.h"
00037 #include "notify.h"
00038 #include "resource_notify.h"
00039
00040
00041
00042
00043
00044
00045
00046
00047 static str su_200_rpl = str_init("OK");
00048
00049 #define CONT_COPY(buf, dest, source)\
00050 dest.s= (char*)buf+ size;\
00051 memcpy(dest.s, source.s, source.len);\
00052 dest.len= source.len;\
00053 size+= source.len;
00054
00055
00056 #define CONT_COPY_1 (buf, dest_s, dest_len, source_s, source_len)\
00057 dest_s= (char*)buf+ size;\
00058 memcpy(dest_s, source_s, source_len);\
00059 dest_len= source_len;\
00060 size+= source_len;
00061
00062 int parse_subs_state(str auth_state, str** reason, int* expires)
00063 {
00064 str str_exp;
00065 str* res= NULL;
00066 char* smc= NULL;
00067 int len, flag= -1;
00068
00069
00070 if( strncmp(auth_state.s, "active", 6)== 0)
00071 flag= ACTIVE_STATE;
00072
00073 if( strncmp(auth_state.s, "pending", 7)== 0)
00074 flag= PENDING_STATE;
00075
00076 if( strncmp(auth_state.s, "terminated", 10)== 0)
00077 {
00078 smc= strchr(auth_state.s, ';');
00079 if(smc== NULL)
00080 {
00081 LM_ERR("terminated state and no reason found");
00082 return -1;
00083 }
00084 if(strncmp(smc+1, "reason=", 7))
00085 {
00086 LM_ERR("terminated state and no reason found");
00087 return -1;
00088 }
00089 res= (str*)pkg_malloc(sizeof(str));
00090 if(res== NULL)
00091 {
00092 ERR_MEM(PKG_MEM_STR);
00093 }
00094 len= auth_state.len- 10- 1- 7;
00095 res->s= (char*)pkg_malloc(len* sizeof(char));
00096 if(res->s== NULL)
00097 {
00098 ERR_MEM(PKG_MEM_STR);
00099 }
00100 memcpy(res->s, smc+ 8, len);
00101 res->len= len;
00102 return TERMINATED_STATE;
00103 }
00104
00105 if(flag> 0)
00106 {
00107 smc= strchr(auth_state.s, ';');
00108 if(smc== NULL)
00109 {
00110 LM_ERR("active or pending state and no expires parameter found");
00111 return -1;
00112 }
00113 if(strncmp(smc+1, "expires=", 8))
00114 {
00115 LM_ERR("active or pending state and no expires parameter found");
00116 return -1;
00117 }
00118 str_exp.s= smc+ 9;
00119 str_exp.len= auth_state.s+ auth_state.len- smc- 9;
00120
00121 if( str2int(&str_exp, (unsigned int*)expires)< 0)
00122 {
00123 LM_ERR("while getting int from str\n");
00124 return -1;
00125 }
00126 return flag;
00127
00128 }
00129 return -1;
00130
00131 error:
00132 if(res)
00133 {
00134 if(res->s)
00135 pkg_free(res->s);
00136 pkg_free(res);
00137 }
00138 return -1;
00139 }
00140
00141 int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
00142 {
00143 struct to_body *pto, TO, *pfrom= NULL;
00144 str body= {0, 0};
00145 ua_pres_t dialog;
00146 str* res_id= NULL;
00147 db_key_t query_cols[9], result_cols[1];
00148 db_val_t query_vals[9];
00149 db_res_t* result= NULL;
00150 int n_query_cols= 0;
00151 str auth_state= {0, 0};
00152 int found= 0;
00153 str* reason= NULL;
00154 int auth_flag;
00155 struct hdr_field* hdr= NULL;
00156 int n, expires= -1;
00157 str content_type= {0, 0};
00158
00159
00160 LM_DBG("start\n");
00161
00162 if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00163 {
00164 LM_ERR("parsing headers\n");
00165 return -1;
00166 }
00167 if((!msg->event ) ||(msg->event->body.len<=0))
00168 {
00169 LM_ERR("Missing event header field value\n");
00170 return -1;
00171 }
00172 if( msg->to==NULL || msg->to->body.s==NULL)
00173 {
00174 LM_ERR("cannot parse TO header\n");
00175 return -1;
00176 }
00177 if(msg->to->parsed != NULL)
00178 {
00179 pto = (struct to_body*)msg->to->parsed;
00180 LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
00181 pto->uri.len, pto->uri.s );
00182 }
00183 else
00184 {
00185 memset( &TO , 0, sizeof(TO) );
00186 parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
00187 if(TO.uri.len <= 0)
00188 {
00189 LM_ERR(" 'To' header NOT parsed\n");
00190 return -1;
00191 }
00192 pto = &TO;
00193 }
00194 dialog.watcher_uri= &pto->uri;
00195 if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
00196 {
00197 LM_ERR("to tag value not parsed\n");
00198 goto error;
00199 }
00200 dialog.from_tag= pto->tag_value;
00201 if( msg->callid==NULL || msg->callid->body.s==NULL)
00202 {
00203 LM_ERR("cannot parse callid header\n");
00204 goto error;
00205 }
00206 dialog.call_id = msg->callid->body;
00207
00208 if (!msg->from || !msg->from->body.s)
00209 {
00210 LM_ERR("cannot find 'from' header!\n");
00211 goto error;
00212 }
00213 if (msg->from->parsed == NULL)
00214 {
00215 LM_DBG("'From' header not parsed\n");
00216
00217 if ( parse_from_header( msg )<0 )
00218 {
00219 LM_ERR("cannot parse From header\n");
00220 goto error;
00221 }
00222 }
00223 pfrom = (struct to_body*)msg->from->parsed;
00224 dialog.pres_uri= &pfrom->uri;
00225
00226 if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00227 {
00228 LM_ERR("no from tag value present\n");
00229 goto error;
00230 }
00231 dialog.to_tag= pfrom->tag_value;
00232 dialog.flag|= RLS_SUBSCRIBE;
00233
00234 dialog.event= get_event_flag(&msg->event->body);
00235 if(dialog.event< 0)
00236 {
00237 LM_ERR("unrecognized event package\n");
00238 goto error;
00239 }
00240 if(pua_get_record_id(&dialog, &res_id)< 0)
00241 {
00242 LM_ERR("occured when trying to get record id\n");
00243 goto error;
00244 }
00245 if(res_id== 0)
00246 {
00247 LM_ERR("record not found\n");
00248 goto error;
00249 }
00250
00251
00252 hdr = msg->headers;
00253 while (hdr!= NULL)
00254 {
00255 if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
00256 {
00257 found = 1;
00258 break;
00259 }
00260 hdr = hdr->next;
00261 }
00262 if(found==0 )
00263 {
00264 LM_ERR("'Subscription-State' header not found\n");
00265 goto error;
00266 }
00267 auth_state = hdr->body;
00268
00269
00270 auth_flag= parse_subs_state(auth_state, &reason, &expires);
00271 if(auth_flag< 0)
00272 {
00273 LM_ERR("while parsing 'Subscription-State' header\n");
00274 goto error;
00275 }
00276 if(msg->content_type== NULL || msg->content_type->body.s== NULL)
00277 {
00278 LM_DBG("cannot find content type header header\n");
00279 }
00280 else
00281 content_type= msg->content_type->body;
00282
00283
00284 if(get_content_length(msg) == 0 )
00285 {
00286 goto done;
00287 }
00288 else
00289 {
00290 if(content_type.s== 0)
00291 {
00292 LM_ERR("content length != 0 and no content type header found\n");
00293 goto error;
00294 }
00295 body.s=get_body(msg);
00296 if (body.s== NULL)
00297 {
00298 LM_ERR("cannot extract body from msg\n");
00299 goto error;
00300 }
00301 body.len = get_content_length( msg );
00302
00303 }
00304
00305
00306 LM_DBG("body= %.*s\n", body.len, body.s);
00307
00308 query_cols[n_query_cols]= &str_rlsubs_did_col;
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= *res_id;
00312 n_query_cols++;
00313
00314 query_cols[n_query_cols]= &str_resource_uri_col;
00315 query_vals[n_query_cols].type = DB_STR;
00316 query_vals[n_query_cols].nul = 0;
00317 query_vals[n_query_cols].val.str_val= *dialog.pres_uri;
00318 n_query_cols++;
00319
00320 query_cols[n_query_cols]= &str_updated_col;
00321 query_vals[n_query_cols].type = DB_INT;
00322 query_vals[n_query_cols].nul = 0;
00323 query_vals[n_query_cols].val.int_val= UPDATED_TYPE;
00324 n_query_cols++;
00325
00326 query_cols[n_query_cols]= &str_auth_state_col;
00327 query_vals[n_query_cols].type = DB_INT;
00328 query_vals[n_query_cols].nul = 0;
00329 query_vals[n_query_cols].val.int_val= auth_flag;
00330 n_query_cols++;
00331
00332 if(reason)
00333 {
00334 query_cols[n_query_cols]= &str_reason_col;
00335 query_vals[n_query_cols].type = DB_STR;
00336 query_vals[n_query_cols].nul = 0;
00337 query_vals[n_query_cols].val.str_val= *reason;
00338 n_query_cols++;
00339 }
00340 query_cols[n_query_cols]= &str_content_type_col;
00341 query_vals[n_query_cols].type = DB_STR;
00342 query_vals[n_query_cols].nul = 0;
00343 query_vals[n_query_cols].val.str_val= content_type;
00344 n_query_cols++;
00345
00346 query_cols[n_query_cols]= &str_presence_state_col;
00347 query_vals[n_query_cols].type = DB_STR;
00348 query_vals[n_query_cols].nul = 0;
00349 query_vals[n_query_cols].val.str_val= body;
00350 n_query_cols++;
00351
00352 query_cols[n_query_cols]= &str_expires_col;
00353 query_vals[n_query_cols].type = DB_INT;
00354 query_vals[n_query_cols].nul = 0;
00355 query_vals[n_query_cols].val.int_val= expires+ (int)time(NULL);
00356 n_query_cols++;
00357
00358 if (rls_dbf.use_table(rls_db, &rlpres_table) < 0)
00359 {
00360 LM_ERR("in use_table\n");
00361 goto error;
00362 }
00363
00364 result_cols[0]= &str_updated_col;
00365
00366 if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
00367 2, 1, 0, &result)< 0)
00368 {
00369 LM_ERR("in sql query\n");
00370 if(result)
00371 rls_dbf.free_result(rls_db, result);
00372 goto error;
00373 }
00374 if(result== NULL)
00375 goto error;
00376 n= result->n;
00377 rls_dbf.free_result(rls_db, result);
00378
00379 if(n<= 0)
00380 {
00381 if(rls_dbf.insert(rls_db, query_cols, query_vals, n_query_cols)< 0)
00382 {
00383 LM_ERR("in sql insert\n");
00384 goto error;
00385 }
00386 LM_DBG("Inserted in database table new record\n");
00387 }
00388 else
00389 {
00390 LM_DBG("Updated in db table already existing record\n");
00391 if(rls_dbf.update(rls_db, query_cols, 0, query_vals, query_cols+2,
00392 query_vals+2, 2, n_query_cols-2)< 0)
00393 {
00394 LM_ERR("in sql update\n");
00395 goto error;
00396 }
00397 }
00398
00399 LM_DBG("Updated rlpres_table\n");
00400
00401 done:
00402 if( slb.send_reply(msg, 200, &su_200_rpl)== -1)
00403 {
00404 LM_ERR("while sending reply\n");
00405 goto error;
00406 }
00407
00408 return 1;
00409
00410 error:
00411 return -1;
00412 }
00413
00414
00415 int parse_rlsubs_did(char* str_did, str* callid, str* from_tag, str* to_tag)
00416 {
00417 char* smc= NULL;
00418
00419 smc= strstr(str_did, DID_SEP);
00420 if(smc== NULL)
00421 {
00422 LM_ERR("bad format for resource list Subscribe dialog"
00423 " indentifier[rlsubs did]= %s\n", str_did);
00424 return -1;
00425 }
00426 callid->s= str_did;
00427 callid->len= smc- str_did;
00428
00429 from_tag->s= smc+ DID_SEP_LEN;
00430 smc= strstr(from_tag->s, DID_SEP);
00431 if(smc== NULL)
00432 {
00433 LM_ERR("bad format for resource list Subscribe dialog"
00434 " indentifier(rlsubs did)= %s\n", str_did);
00435 return -1;
00436 }
00437 from_tag->len= smc- from_tag->s;
00438
00439 to_tag->s= smc+ DID_SEP_LEN;
00440 to_tag->len= strlen(str_did)- 2* DID_SEP_LEN- callid->len- from_tag->len;
00441
00442 return 0;
00443 }
00444
00445 void timer_send_notify(unsigned int ticks,void *param)
00446 {
00447 db_key_t query_cols[2], update_cols[1], result_cols[7];
00448 db_val_t query_vals[2], update_vals[1];
00449 int did_col, resource_uri_col, auth_state_col, reason_col,
00450 pres_state_col, content_type_col;
00451 int n_result_cols= 0, i;
00452 db_res_t *result= NULL;
00453 char* prev_did= NULL, * curr_did= NULL;
00454 db_row_t *row;
00455 db_val_t *row_vals;
00456 char* resource_uri, *pres_state;
00457 str callid, to_tag, from_tag;
00458 xmlDocPtr rlmi_doc= NULL;
00459 xmlNodePtr list_node= NULL, instance_node= NULL, resource_node;
00460 unsigned int hash_code= 0;
00461 int len;
00462 int size= BUF_REALLOC_SIZE, buf_len= 0;
00463 char* buf= NULL, *auth_state= NULL, *boundary_string= NULL, *cid= NULL;
00464 int contor= 0, auth_state_flag, antet_len;
00465 str bstr= {0, 0};
00466 str rlmi_cont= {0, 0}, multi_cont;
00467 subs_t* s, *dialog= NULL;
00468 char* rl_uri= NULL;
00469
00470 query_cols[0]= &str_updated_col;
00471 query_vals[0].type = DB_INT;
00472 query_vals[0].nul = 0;
00473 query_vals[0].val.int_val= UPDATED_TYPE;
00474
00475 result_cols[did_col= n_result_cols++]= &str_rlsubs_did_col;
00476 result_cols[resource_uri_col= n_result_cols++]= &str_resource_uri_col;
00477 result_cols[auth_state_col= n_result_cols++]= &str_auth_state_col;
00478 result_cols[content_type_col= n_result_cols++]= &str_content_type_col;
00479 result_cols[reason_col= n_result_cols++]= &str_reason_col;
00480 result_cols[pres_state_col= n_result_cols++]= &str_presence_state_col;
00481
00482
00483
00484
00485 if (rls_dbf.use_table(rls_db, &rlpres_table) < 0)
00486 {
00487 LM_ERR("in use_table\n");
00488 goto done;
00489 }
00490
00491 if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
00492 1, n_result_cols, &str_rlsubs_did_col, &result)< 0)
00493 {
00494 LM_ERR("in sql query\n");
00495 goto done;
00496 }
00497 if(result== NULL || result->n<= 0)
00498 goto done;
00499
00500
00501 update_cols[0]= &str_updated_col;
00502 update_vals[0].type = DB_INT;
00503 update_vals[0].nul = 0;
00504 update_vals[0].val.int_val= NO_UPDATE_TYPE;
00505
00506 if (rls_dbf.use_table(rls_db, &rlpres_table) < 0)
00507 {
00508 LM_ERR("in use_table\n");
00509 goto error;
00510 }
00511 if(rls_dbf.update(rls_db, query_cols, 0, query_vals, update_cols,
00512 update_vals, 1, 1)< 0)
00513 {
00514 LM_ERR("in sql update\n");
00515 goto error;
00516 }
00517
00518
00519
00520 boundary_string= generate_string((int)time(NULL), BOUNDARY_STRING_LEN);
00521 bstr.len= strlen(boundary_string);
00522 bstr.s= (char*)pkg_malloc((bstr.len+ 1)* sizeof(char));
00523 if(bstr.s== NULL)
00524 {
00525 ERR_MEM(PKG_MEM_STR);
00526 }
00527 memcpy(bstr.s, boundary_string, bstr.len);
00528 bstr.s[bstr.len]= '\0';
00529
00530
00531
00532 buf= pkg_malloc(size* sizeof(char));
00533 if(buf== NULL)
00534 {
00535 ERR_MEM(PKG_MEM_STR);
00536 }
00537
00538 antet_len= COMPUTE_ANTET_LEN(bstr.s);
00539 LM_DBG("found %d records with updated state\n", result->n);
00540 for(i= 0; i< result->n; i++)
00541 {
00542 row = &result->rows[i];
00543 row_vals = ROW_VALUES(row);
00544
00545 curr_did= (char*)row_vals[did_col].val.string_val;
00546 resource_uri= (char*)row_vals[resource_uri_col].val.string_val;
00547 auth_state_flag= row_vals[auth_state_col].val.int_val;
00548 pres_state= (char*)row_vals[pres_state_col].val.string_val;
00549
00550 if(prev_did!= NULL && strcmp(prev_did, curr_did))
00551 {
00552 xmlDocDumpFormatMemory(rlmi_doc,(xmlChar**)(void*)&rlmi_cont.s,
00553 &rlmi_cont.len, 1);
00554
00555 multi_cont.s= buf;
00556 multi_cont.len= buf_len;
00557
00558 if(agg_body_sendn_update(&dialog->pres_uri, bstr.s, &rlmi_cont,
00559 (buf_len==0)?NULL:&multi_cont, dialog, hash_code)<0)
00560 {
00561 LM_ERR("in function agg_body_sendn_update\n");
00562 goto error;
00563 }
00564 xmlFree(rlmi_cont.s);
00565 if(buf_len)
00566 {
00567 pkg_free(buf);
00568 buf= NULL;
00569 }
00570 xmlFreeDoc(rlmi_doc);
00571 rlmi_doc= NULL;
00572 pkg_free(rl_uri);
00573 rl_uri= NULL;
00574 pkg_free(dialog);
00575 dialog= NULL;
00576 }
00577
00578 if(prev_did== NULL || strcmp(prev_did, curr_did))
00579 {
00580
00581 if( parse_rlsubs_did(curr_did, &callid, &from_tag, &to_tag)< 0)
00582 {
00583 LM_ERR("bad format for "
00584 "resource list Subscribe dialog indentifier(rlsubs did)\n");
00585 goto done;
00586
00587 }
00588 hash_code= core_hash(&callid, &to_tag, hash_size);
00589
00590 lock_get(&rls_table[hash_code].lock);
00591 s= pres_search_shtable(rls_table,callid,to_tag,from_tag,hash_code);
00592 if(s== NULL)
00593 {
00594 LM_DBG("record not found in hash_table [rlsubs_did]= %s\n",
00595 curr_did);
00596 LM_DBG("callid= %.*s\tfrom_tag= %.*s\tto_tag= %.*s\n",
00597 callid.len, callid.s,from_tag.len,from_tag.s,
00598 to_tag.len,to_tag.s);
00599 lock_release(&rls_table[hash_code].lock);
00600 continue;
00601 }
00602 LM_DBG("Found rl-subs record in hash table\n");
00603
00604
00605 dialog= pres_copy_subs(s, PKG_MEM_TYPE);
00606 if(dialog== NULL)
00607 {
00608 LM_ERR("while copying subs_t structure\n");
00609 lock_release(&rls_table[hash_code].lock);
00610 goto done;
00611 }
00612 lock_release(&rls_table[hash_code].lock);
00613
00614
00615 rlmi_doc= xmlNewDoc(BAD_CAST "1.0");
00616 if(rlmi_doc== NULL)
00617 {
00618 LM_ERR("when creating new xml doc\n");
00619 goto done;
00620 }
00621 list_node= xmlNewNode(NULL, BAD_CAST "list");
00622 if(list_node== NULL)
00623 {
00624 LM_ERR("while creating new xml node\n");
00625 goto done;
00626 }
00627 rl_uri= (char*)pkg_malloc((dialog->pres_uri.len+ 1)* sizeof(char));
00628 if(rl_uri== NULL)
00629 {
00630 ERR_MEM(PKG_MEM_STR);
00631 }
00632 memcpy(rl_uri, dialog->pres_uri.s, dialog->pres_uri.len);
00633 rl_uri[dialog->pres_uri.len]= '\0';
00634
00635 xmlNewProp(list_node, BAD_CAST "uri", BAD_CAST rl_uri);
00636 xmlNewProp(list_node, BAD_CAST "xmlns", BAD_CAST "urn:ietf:params:xml:ns:rlmi");
00637 xmlNewProp(list_node, BAD_CAST "version", BAD_CAST int2str(dialog->version, &len));
00638 xmlNewProp(list_node, BAD_CAST "fullState", BAD_CAST "false");
00639
00640 xmlDocSetRootElement(rlmi_doc, list_node);
00641 buf_len= 0;
00642
00643
00644
00645 }
00646
00647
00648
00649
00650 resource_node= xmlNewChild(list_node,NULL,BAD_CAST "resource", NULL);
00651 if(resource_node== NULL)
00652 {
00653 LM_ERR("when adding resource child\n");
00654 goto done;
00655 }
00656 xmlNewProp(resource_node, BAD_CAST "uri", BAD_CAST resource_uri);
00657
00658
00659
00660
00661 contor= 0;
00662 while(1)
00663 {
00664 contor++;
00665 cid= NULL;
00666 instance_node= xmlNewChild(resource_node, NULL,
00667 BAD_CAST "instance", NULL);
00668 if(instance_node== NULL)
00669 {
00670 LM_ERR("while adding instance child\n");
00671 goto error;
00672 }
00673 xmlNewProp(instance_node, BAD_CAST "id",
00674 BAD_CAST generate_string(contor, 8));
00675
00676 auth_state= get_auth_string(auth_state_flag);
00677 if(auth_state== NULL)
00678 {
00679 LM_ERR("bad authorization status flag\n");
00680 goto error;
00681 }
00682 xmlNewProp(instance_node, BAD_CAST "state", BAD_CAST auth_state);
00683
00684 if(auth_state_flag & ACTIVE_STATE)
00685 {
00686 cid= generate_cid(resource_uri, strlen(resource_uri));
00687 xmlNewProp(instance_node, BAD_CAST "cid", BAD_CAST cid);
00688 }
00689 else
00690 if(auth_state_flag & TERMINATED_STATE)
00691 {
00692 xmlNewProp(instance_node, BAD_CAST "reason",
00693 BAD_CAST row_vals[resource_uri_col].val.string_val);
00694 }
00695
00696
00697 if(cid)
00698 {
00699 if(buf_len+ antet_len+ strlen(pres_state)+ 4 > size)
00700 {
00701 REALLOC_BUF
00702 }
00703 buf_len+= sprintf(buf+ buf_len, "--%s\r\n\r\n", bstr.s);
00704 buf_len+= sprintf(buf+ buf_len, "Content-Transfer-Encoding: binary\r\n");
00705 buf_len+= sprintf(buf+ buf_len, "Content-ID: <%s>\r\n", cid);
00706 buf_len+= sprintf(buf+ buf_len, "Content-Type: %s\r\n\r\n",
00707 row_vals[content_type_col].val.string_val);
00708 buf_len+= sprintf(buf+buf_len,"%s\r\n\r\n", pres_state);
00709 }
00710
00711 i++;
00712 if(i== result->n)
00713 {
00714 i--;
00715 break;
00716 }
00717
00718 row = &result->rows[i];
00719 row_vals = ROW_VALUES(row);
00720
00721 if(strncmp(resource_uri, row_vals[resource_uri_col].val.string_val,
00722 strlen(resource_uri))
00723 || strncmp(curr_did, row_vals[did_col].val.string_val,
00724 strlen(curr_did)))
00725 {
00726 i--;
00727 break;
00728 }
00729 resource_uri= (char*)row_vals[resource_uri_col].val.string_val;
00730 auth_state_flag= row_vals[auth_state_col].val.int_val;
00731 pres_state= (char*)row_vals[pres_state_col].val.string_val;
00732 }
00733
00734 prev_did= curr_did;
00735 }
00736
00737 if(rlmi_doc)
00738 {
00739 xmlDocDumpFormatMemory( rlmi_doc,(xmlChar**)(void*)&rlmi_cont.s,
00740 &rlmi_cont.len, 1);
00741
00742 multi_cont.s= buf;
00743 multi_cont.len= buf_len;
00744
00745 if(agg_body_sendn_update(&dialog->pres_uri, bstr.s, &rlmi_cont,
00746 (buf_len==0)?NULL:&multi_cont, dialog, hash_code)<0)
00747 {
00748 LM_ERR("in function agg_body_sendn_update\n");
00749 goto error;
00750 }
00751 xmlFree(rlmi_cont.s);
00752 if(buf_len)
00753 {
00754 pkg_free(buf);
00755 buf= NULL;
00756 }
00757 pkg_free(rl_uri);
00758 rl_uri= NULL;
00759 pkg_free(dialog);
00760 dialog= NULL;
00761 }
00762
00763
00764 error:
00765 done:
00766 if(result)
00767 rls_dbf.free_result(rls_db, result);
00768 if(rlmi_doc)
00769 xmlFreeDoc(rlmi_doc);
00770 if(rl_uri)
00771 pkg_free(rl_uri);
00772 if(bstr.s)
00773 pkg_free(bstr.s);
00774
00775 if(buf)
00776 pkg_free(buf);
00777 if(dialog)
00778 pkg_free(dialog);
00779 return;
00780 }
00781
00782
00783
00784
00785 void rls_presentity_clean(unsigned int ticks,void *param)
00786 {
00787 db_key_t query_cols[2];
00788 db_op_t query_ops[2];
00789 db_val_t query_vals[2];
00790
00791 query_cols[0]= &str_expires_col;
00792 query_ops[0]= OP_LT;
00793 query_vals[0].nul= 0;
00794 query_vals[0].type= DB_INT;
00795 query_vals[0].val.int_val= (int)time(NULL) - 10;
00796
00797 if (rls_dbf.use_table(rls_db, &rlpres_table) < 0)
00798 {
00799 LM_ERR("in use_table\n");
00800 return ;
00801 }
00802
00803 if(rls_dbf.delete(rls_db, query_cols, query_ops, query_vals, 1)< 0)
00804 {
00805 LM_ERR("in sql delete\n");
00806 return ;
00807 }
00808
00809 }