rls_db.c

00001 /*
00002  * $Id$
00003  *
00004  * rls db - RLS database support 
00005  *
00006  * Copyright (C) 2011 Crocodile RCS Ltd
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 
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 
00030 #include "../../mem/mem.h"
00031 #include "../../mem/shm_mem.h"
00032 #include "../../dprint.h"
00033 #include "../../lib/srdb1/db.h"
00034 #include "../../parser/msg_parser.h"
00035 #include "../../parser/parse_from.h"
00036 #include "../../hashes.h"
00037 
00038 #include "rls.h"
00039 
00040 #define CONT_COPYDB(buf, dest, source)\
00041         do{ \
00042         dest.s= (char*)buf+ size;\
00043         memcpy(dest.s, source, strlen(source));\
00044         dest.len= strlen(source);\
00045         size+= strlen(source); \
00046         } while(0);
00047 
00048 /* database connection */
00049 extern db1_con_t *rls_db;
00050 extern db_func_t rls_dbf;
00051 
00052 extern void update_a_sub(subs_t *subs_copy );
00053 
00054 /******************************************************************************/
00055 
00056 shtable_t rls_new_shtable(int hash_size)
00057 {
00058   LM_ERR( "rls_new_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
00059   return(NULL);
00060 }
00061 
00062 /******************************************************************************/
00063 
00064 void rls_destroy_shtable(shtable_t htable, int hash_size)
00065 {
00066   LM_ERR( "rls_destroy_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
00067 }
00068 
00069 /******************************************************************************/
00070 
00071 int rls_insert_shtable(shtable_t htable,unsigned int hash_code, subs_t* subs)
00072 {
00073   LM_ERR( "rls_insert_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
00074   return(-1);
00075 }
00076 
00077 /******************************************************************************/
00078 
00079 subs_t* rls_search_shtable(shtable_t htable,str callid,str to_tag,
00080                 str from_tag,unsigned int hash_code)
00081 {
00082   LM_ERR( "rls_search_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
00083   return(NULL);
00084 }
00085 
00086 /******************************************************************************/
00087 
00088 int rls_delete_shtable(shtable_t htable,unsigned int hash_code,str to_tag)
00089 {
00090   LM_ERR( "rls_delete_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
00091   return(-1);
00092 }
00093 
00094 /******************************************************************************/
00095 
00096 int rls_update_shtable(shtable_t htable,unsigned int hash_code, 
00097                 subs_t* subs, int type)
00098 {
00099   LM_ERR( "rls_update_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
00100   return(-1);
00101 }
00102 
00103 /******************************************************************************/
00104 
00105 void rls_update_db_subs_timer(db1_con_t *db,db_func_t dbf, shtable_t hash_table,
00106         int htable_size, int no_lock, handle_expired_func_t handle_expired_func)
00107 {
00108   LM_ERR( "rls_update_db_subs_timer shouldn't be called in RLS_DB_ONLY mode\n" );
00109 }
00110 
00111 /******************************************************************************/
00112 /******************************************************************************/
00113 
00114 int delete_expired_subs_rlsdb( void )
00115 
00116 {
00117         db_key_t query_cols[3], result_cols[3], update_cols[1];
00118         db_val_t query_vals[3], update_vals[1], *values;
00119         db_op_t query_ops[1];
00120         db_row_t *rows;
00121         db1_res_t *result = NULL;
00122         int n_query_cols = 0, n_result_cols = 0;
00123         int r_callid_col = 0, r_to_tag_col = 0, r_from_tag_col = 0;
00124         int i;
00125         subs_t subs;
00126         str rlsubs_did = {0, 0};
00127 
00128         if(rls_db == NULL)
00129         {
00130                 LM_ERR("null database connection\n");
00131                 goto error;
00132         }
00133 
00134         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00135         {
00136                 LM_ERR("use table failed\n");
00137                 goto error;
00138         }
00139 
00140         query_cols[n_query_cols]= &str_expires_col;
00141         query_vals[n_query_cols].type = DB1_INT;
00142         query_vals[n_query_cols].nul = 0;
00143         query_vals[n_query_cols].val.int_val= (int)time(NULL) - rls_expires_offset;
00144         query_ops[n_query_cols]= OP_LT;
00145         n_query_cols++;
00146 
00147         result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
00148         result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
00149         result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
00150 
00151         if(rls_dbf.query(rls_db, query_cols, query_ops, query_vals, result_cols, 
00152                                 n_query_cols, n_result_cols, 0, &result )< 0)
00153         {
00154                 LM_ERR("Can't query db\n");
00155                 goto error;
00156         }
00157 
00158         if(result == NULL) goto error;
00159 
00160         for (i = 0; i <RES_ROW_N(result); i++)
00161         {
00162                 rows = RES_ROWS(result);
00163                 values = ROW_VALUES(rows);
00164 
00165                 subs.callid.s = (char *) VAL_STRING(&values[r_callid_col]);
00166                 subs.callid.len = strlen(subs.callid.s);
00167                 subs.to_tag.s = (char *) VAL_STRING(&values[r_to_tag_col]);
00168                 subs.to_tag.len = strlen(subs.to_tag.s);
00169                 subs.from_tag.s = (char *) VAL_STRING(&values[r_from_tag_col]);
00170                 subs.from_tag.len = strlen(subs.from_tag.s);
00171 
00172                 if (CONSTR_RLSUBS_DID(&subs, &rlsubs_did) < 0)
00173                 {
00174                         LM_ERR("cannot build rls subs did\n");
00175                         goto error;
00176                 }
00177                 subs.updated = core_hash(&rlsubs_did, NULL,
00178                         (waitn_time * rls_notifier_poll_rate * rls_notifier_processes) - 1);
00179 
00180                 n_query_cols = 0;
00181 
00182                 query_cols[n_query_cols] = &str_callid_col;
00183                 query_vals[n_query_cols].type = DB1_STR;
00184                 query_vals[n_query_cols].nul = 0;
00185                 query_vals[n_query_cols].val.str_val = subs.callid;
00186                 n_query_cols++;
00187 
00188                 query_cols[n_query_cols] = &str_to_tag_col;
00189                 query_vals[n_query_cols].type = DB1_STR;
00190                 query_vals[n_query_cols].nul = 0;
00191                 query_vals[n_query_cols].val.str_val = subs.to_tag;
00192                 n_query_cols++;
00193 
00194                 query_cols[n_query_cols] = &str_from_tag_col;
00195                 query_vals[n_query_cols].type = DB1_STR;
00196                 query_vals[n_query_cols].nul = 0;
00197                 query_vals[n_query_cols].val.str_val = subs.from_tag;
00198                 n_query_cols++;
00199 
00200                 update_cols[0] = &str_updated_col;
00201                 update_vals[0].type = DB1_INT;
00202                 update_vals[0].nul = 0;
00203                 update_vals[0].val.int_val = subs.updated;
00204 
00205                 if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
00206                         update_cols,update_vals,n_query_cols, 1) < 0)
00207                 {
00208                         LM_ERR("db update failed for expired subs\n");
00209                         goto error;
00210                 }
00211 
00212                 pkg_free(rlsubs_did.s);
00213         }
00214 
00215         rls_dbf.free_result(rls_db, result);
00216         return 1;
00217 
00218 error:
00219         if (result) rls_dbf.free_result(rls_db, result);
00220         if (rlsubs_did.s) pkg_free(rlsubs_did.s);
00221         return -1;
00222 }
00223 
00224 /******************************************************************************/
00225 
00226 int delete_rlsdb( str *callid, str *to_tag, str *from_tag ) 
00227 
00228 {
00229         int rval;
00230         db_key_t query_cols[3];
00231         db_val_t query_vals[3];
00232         int n_query_cols = 0;
00233 
00234         if(rls_db == NULL)
00235         {
00236                 LM_ERR("null database connection\n");
00237                 return(-1);
00238         }
00239 
00240         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00241         {
00242                 LM_ERR("use table failed\n");
00243                 return(-1);
00244         }
00245         
00246         query_cols[n_query_cols] = &str_callid_col;
00247         query_vals[n_query_cols].type = DB1_STR;
00248         query_vals[n_query_cols].nul = 0;
00249         query_vals[n_query_cols].val.str_val= *callid;
00250         n_query_cols++;
00251 
00252         query_cols[n_query_cols] = &str_to_tag_col;
00253         query_vals[n_query_cols].type = DB1_STR;
00254         query_vals[n_query_cols].nul = 0;
00255         query_vals[n_query_cols].val.str_val= *to_tag;
00256         n_query_cols++;
00257 
00258         if (from_tag)
00259         {
00260                 query_cols[n_query_cols] = &str_from_tag_col;
00261                 query_vals[n_query_cols].type = DB1_STR;
00262                 query_vals[n_query_cols].nul = 0;
00263                 query_vals[n_query_cols].val.str_val= *from_tag;
00264                 n_query_cols++;
00265         }
00266 
00267         rval = rls_dbf.delete(rls_db, query_cols, 0, query_vals, n_query_cols);
00268 
00269         if (rval < 0)
00270         {
00271                 LM_ERR("Can't delete in db\n");
00272                 return(-1);
00273         }
00274 
00275         return(1);
00276 }
00277 
00278 /******************************************************************************/
00279 
00280 int update_dialog_notify_rlsdb(subs_t *subs)
00281 
00282 {
00283         db_key_t query_cols[3];
00284         db_val_t query_vals[3];
00285         db_key_t data_cols[3];
00286         db_val_t data_vals[3];
00287         int n_query_cols = 0, n_data_cols=0;
00288 
00289         if (subs==NULL) return(-1);
00290 
00291         if(rls_db == NULL)
00292         {
00293                 LM_ERR("null database connection\n");
00294                 return(-1);
00295         }
00296 
00297         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00298         {
00299                 LM_ERR("use table failed\n");
00300                 return(-1);
00301         }
00302 
00303         subs->local_cseq++;
00304         subs->version++;
00305         
00306         query_cols[n_query_cols] = &str_callid_col;
00307         query_vals[n_query_cols].type = DB1_STR;
00308         query_vals[n_query_cols].nul = 0;
00309         query_vals[n_query_cols].val.str_val= subs->callid;
00310         n_query_cols++;
00311 
00312         query_cols[n_query_cols] = &str_to_tag_col;
00313         query_vals[n_query_cols].type = DB1_STR;
00314         query_vals[n_query_cols].nul = 0;
00315         query_vals[n_query_cols].val.str_val= subs->to_tag;
00316         n_query_cols++;
00317 
00318         query_cols[n_query_cols] = &str_from_tag_col;
00319         query_vals[n_query_cols].type = DB1_STR;
00320         query_vals[n_query_cols].nul = 0;
00321         query_vals[n_query_cols].val.str_val= subs->from_tag;
00322         n_query_cols++;
00323 
00324         data_cols[n_data_cols]=&str_local_cseq_col;
00325         data_vals[n_data_cols].type = DB1_INT;
00326         data_vals[n_data_cols].nul = 0;
00327         data_vals[n_data_cols].val.int_val= subs->local_cseq;
00328         n_data_cols++;
00329 
00330         data_cols[n_data_cols]=&str_version_col;
00331         data_vals[n_data_cols].type = DB1_INT;
00332         data_vals[n_data_cols].nul = 0;
00333         data_vals[n_data_cols].val.int_val= subs->version;
00334         n_data_cols++;
00335 
00336         data_cols[n_data_cols] =&str_status_col;
00337         data_vals[n_data_cols].type = DB1_INT;
00338         data_vals[n_data_cols].nul = 0;
00339         data_vals[n_data_cols].val.int_val= subs->status;
00340         n_data_cols++;
00341 
00342         if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
00343                     data_cols,data_vals,n_query_cols,n_data_cols) < 0)
00344         {
00345                 LM_ERR("Failed update db\n");
00346                 return(-1);
00347         }
00348 
00349         return(0);
00350 }
00351 
00352 /******************************************************************************/
00353 
00354 int update_all_subs_rlsdb(str *watcher_user, str *watcher_domain, str *evt)
00355 {
00356         db_key_t query_cols[3];
00357         db_val_t query_vals[3];
00358         db_key_t result_cols[20];
00359         int n_query_cols = 0, n_result_cols=0;
00360         int r_pres_uri_col, r_callid_col, r_to_tag_col, r_from_tag_col;
00361         int r_event_col, r_expires_col;
00362         db1_res_t *result= NULL;
00363         db_val_t *values;
00364         db_row_t *rows;
00365         int nr_rows, size, loop;
00366         subs_t *dest;
00367         event_t parsed_event;
00368 
00369         if(rls_db == NULL)
00370         {
00371                 LM_ERR("null database connection\n");
00372                 return(-1);
00373         }
00374 
00375         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00376         {
00377                 LM_ERR("use table failed\n");
00378                 return(-1);
00379         }
00380         
00381         query_cols[n_query_cols] = &str_watcher_username_col;
00382         query_vals[n_query_cols].type = DB1_STR;
00383         query_vals[n_query_cols].nul = 0;
00384         query_vals[n_query_cols].val.str_val= *watcher_user;
00385         n_query_cols++;
00386 
00387         query_cols[n_query_cols] = &str_watcher_domain_col;
00388         query_vals[n_query_cols].type = DB1_STR;
00389         query_vals[n_query_cols].nul = 0;
00390         query_vals[n_query_cols].val.str_val= *watcher_domain;
00391         n_query_cols++;
00392 
00393         query_cols[n_query_cols] = &str_event_col;
00394         query_vals[n_query_cols].type = DB1_STR;
00395         query_vals[n_query_cols].nul = 0;
00396         query_vals[n_query_cols].val.str_val= *evt;
00397         n_query_cols++;
00398 
00399         result_cols[r_pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
00400         result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
00401         result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
00402         result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
00403         result_cols[r_event_col=n_result_cols++] = &str_event_col;
00404         result_cols[r_expires_col=n_result_cols++] = &str_expires_col;
00405 
00406         if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols, 
00407                                 n_query_cols, n_result_cols, 0, &result )< 0)
00408         {
00409                 LM_ERR("Can't query db\n");
00410                 if(result) rls_dbf.free_result(rls_db, result);
00411                 return(-1);
00412         }
00413 
00414         if(result == NULL) return(-1);
00415 
00416         nr_rows = RES_ROW_N(result);
00417 
00418         /* get the results and fill in return data structure */
00419         for (loop=0; loop <nr_rows; loop++)
00420         {
00421                 rows = RES_ROWS(result);
00422                 values = ROW_VALUES(rows);
00423 
00424                 size= sizeof(subs_t) +
00425                         ( strlen(VAL_STRING(values+r_pres_uri_col))
00426                         + strlen(VAL_STRING(values+r_to_tag_col))
00427                         + strlen(VAL_STRING(values+r_from_tag_col))
00428                         + strlen(VAL_STRING(values+r_callid_col)))*sizeof(char);
00429 
00430                 dest= (subs_t*)pkg_malloc(size);
00431         
00432                 if(dest== NULL)
00433                 {
00434                         LM_ERR( "Can't allocate memory\n" );
00435                         rls_dbf.free_result(rls_db, result);
00436                         return(-1);
00437                 }
00438                 memset(dest, 0, size);
00439                 size= sizeof(subs_t);
00440 
00441                 CONT_COPYDB(dest, dest->pres_uri, VAL_STRING(values+r_pres_uri_col))
00442                 CONT_COPYDB(dest, dest->to_tag, VAL_STRING(values+r_to_tag_col))
00443                 CONT_COPYDB(dest, dest->from_tag, VAL_STRING(values+r_from_tag_col))
00444                 CONT_COPYDB(dest, dest->callid, VAL_STRING(values+r_callid_col))
00445 
00446                 dest->event = pres_contains_event(evt, &parsed_event);
00447                 if(dest->event == NULL)
00448                 {
00449                         LM_ERR("event not found and set to NULL\n");
00450                 }
00451 
00452                 dest->expires= VAL_INT(values+r_expires_col);
00453                 dest->watcher_user.s= watcher_user->s;
00454                 dest->watcher_user.len= watcher_user->len;
00455                 dest->watcher_domain.s= watcher_domain->s;
00456                 dest->watcher_domain.len= watcher_domain->len;
00457 
00458                 update_a_sub(dest);
00459         }
00460 
00461         rls_dbf.free_result(rls_db, result);
00462         return(1);      
00463 }
00464 
00465 /******************************************************************************/
00466 
00467 int update_dialog_subscribe_rlsdb(subs_t *subs)
00468 
00469 {
00470         db_key_t query_cols[3];
00471         db_val_t query_vals[3];
00472         db_key_t data_cols[3];
00473         db_val_t data_vals[3];
00474         int n_query_cols = 0, n_data_cols=0;
00475 
00476         if (subs==NULL) return(-1);
00477 
00478         if(rls_db == NULL)
00479         {
00480                 LM_ERR("null database connection\n");
00481                 return(-1);
00482         }
00483 
00484         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00485         {
00486                 LM_ERR("use table failed\n");
00487                 return(-1);
00488         }
00489         
00490         query_cols[n_query_cols] = &str_callid_col;
00491         query_vals[n_query_cols].type = DB1_STR;
00492         query_vals[n_query_cols].nul = 0;
00493         query_vals[n_query_cols].val.str_val= subs->callid;
00494         n_query_cols++;
00495 
00496         query_cols[n_query_cols] = &str_to_tag_col;
00497         query_vals[n_query_cols].type = DB1_STR;
00498         query_vals[n_query_cols].nul = 0;
00499         query_vals[n_query_cols].val.str_val= subs->to_tag;
00500         n_query_cols++;
00501 
00502         query_cols[n_query_cols] = &str_from_tag_col;
00503         query_vals[n_query_cols].type = DB1_STR;
00504         query_vals[n_query_cols].nul = 0;
00505         query_vals[n_query_cols].val.str_val= subs->from_tag;
00506         n_query_cols++;
00507 
00508         data_cols[n_data_cols] = &str_expires_col;
00509         data_vals[n_data_cols].type = DB1_INT;
00510         data_vals[n_data_cols].nul = 0;
00511         data_vals[n_data_cols].val.int_val = subs->expires + (int)time(NULL);
00512         n_data_cols++;
00513 
00514         data_cols[n_data_cols] = &str_remote_cseq_col;
00515         data_vals[n_data_cols].type = DB1_INT;
00516         data_vals[n_data_cols].nul = 0;
00517         data_vals[n_data_cols].val.int_val= subs->remote_cseq;
00518         n_data_cols++;
00519 
00520         data_cols[n_data_cols] = &str_updated_col;
00521         data_vals[n_data_cols].type = DB1_INT;
00522         data_vals[n_data_cols].nul = 0;
00523         data_vals[n_data_cols].val.int_val= subs->updated;
00524         n_data_cols++;
00525 
00526         if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
00527                     data_cols,data_vals,n_query_cols,n_data_cols) < 0)
00528         {
00529                 LM_ERR("Failed update db\n");
00530                 return(-1);
00531         }
00532         
00533         return(0);
00534 }
00535 
00536 /******************************************************************************/
00537 
00538 int insert_rlsdb( subs_t *s )
00539 
00540 {
00541         db_key_t data_cols[23];
00542         db_val_t data_vals[23];
00543         int n_data_cols = 0;
00544 
00545         if (s==NULL) return(-1);
00546 
00547         if(rls_db == NULL)
00548         {
00549                 LM_ERR("null database connection\n");
00550                 return(-1);
00551         }
00552 
00553         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00554         {
00555                 LM_ERR("use table failed\n");
00556                 return(-1);
00557         }
00558         
00559         data_cols[n_data_cols] = &str_presentity_uri_col;
00560         data_vals[n_data_cols].type = DB1_STR;
00561         data_vals[n_data_cols].nul = 0;
00562         data_vals[n_data_cols].val.str_val= s->pres_uri;
00563         n_data_cols++;
00564         
00565         data_cols[n_data_cols] = &str_callid_col;
00566         data_vals[n_data_cols].type = DB1_STR;
00567         data_vals[n_data_cols].nul = 0;
00568         data_vals[n_data_cols].val.str_val= s->callid;
00569         n_data_cols++;
00570 
00571         data_cols[n_data_cols] = &str_to_tag_col;
00572         data_vals[n_data_cols].type = DB1_STR;
00573         data_vals[n_data_cols].nul = 0;
00574         data_vals[n_data_cols].val.str_val= s->to_tag;
00575         n_data_cols++;
00576 
00577         data_cols[n_data_cols] = &str_from_tag_col;
00578         data_vals[n_data_cols].type = DB1_STR;
00579         data_vals[n_data_cols].nul = 0;
00580         data_vals[n_data_cols].val.str_val= s->from_tag;
00581         n_data_cols++;
00582 
00583         data_cols[n_data_cols] = &str_to_user_col;
00584         data_vals[n_data_cols].type = DB1_STR;
00585         data_vals[n_data_cols].nul = 0;
00586         data_vals[n_data_cols].val.str_val = s->to_user;
00587         n_data_cols++;
00588 
00589         data_cols[n_data_cols] = &str_to_domain_col;
00590         data_vals[n_data_cols].type = DB1_STR;
00591         data_vals[n_data_cols].nul = 0;
00592         data_vals[n_data_cols].val.str_val = s->to_domain;
00593         n_data_cols++;
00594 
00595         data_cols[n_data_cols] = &str_from_user_col;
00596         data_vals[n_data_cols].type = DB1_STR;
00597         data_vals[n_data_cols].nul = 0;
00598         data_vals[n_data_cols].val.str_val = s->from_user;
00599         n_data_cols++;
00600 
00601         data_cols[n_data_cols] = &str_from_domain_col;
00602         data_vals[n_data_cols].type = DB1_STR;
00603         data_vals[n_data_cols].nul = 0;
00604         data_vals[n_data_cols].val.str_val = s->from_domain;
00605         n_data_cols++;
00606 
00607         data_cols[n_data_cols] = &str_watcher_username_col;
00608         data_vals[n_data_cols].type = DB1_STR;
00609         data_vals[n_data_cols].nul = 0;
00610         data_vals[n_data_cols].val.str_val = s->watcher_user;
00611         n_data_cols++;
00612 
00613         data_cols[n_data_cols] = &str_watcher_domain_col;
00614         data_vals[n_data_cols].type = DB1_STR;
00615         data_vals[n_data_cols].nul = 0;
00616         data_vals[n_data_cols].val.str_val = s->watcher_domain;
00617         n_data_cols++;
00618 
00619         data_cols[n_data_cols] = &str_event_col;
00620         data_vals[n_data_cols].type = DB1_STR;
00621         data_vals[n_data_cols].nul = 0;
00622         data_vals[n_data_cols].val.str_val = s->event->name;
00623         n_data_cols++;  
00624 
00625         data_cols[n_data_cols] = &str_event_id_col;
00626         data_vals[n_data_cols].type = DB1_STR;
00627         data_vals[n_data_cols].nul = 0;
00628         data_vals[n_data_cols].val.str_val = s->event_id;
00629         n_data_cols++;
00630 
00631         data_cols[n_data_cols]=&str_local_cseq_col;
00632         data_vals[n_data_cols].type = DB1_INT;
00633         data_vals[n_data_cols].nul = 0;
00634         data_vals[n_data_cols].val.int_val= s->local_cseq;
00635         n_data_cols++;
00636 
00637         data_cols[n_data_cols]=&str_remote_cseq_col;
00638         data_vals[n_data_cols].type = DB1_INT;
00639         data_vals[n_data_cols].nul = 0;
00640         data_vals[n_data_cols].val.int_val= s->remote_cseq;
00641         n_data_cols++;
00642 
00643         data_cols[n_data_cols] =&str_expires_col;
00644         data_vals[n_data_cols].type = DB1_INT;
00645         data_vals[n_data_cols].nul = 0;
00646         data_vals[n_data_cols].val.int_val = s->expires + (int)time(NULL);
00647         n_data_cols++;
00648 
00649         data_cols[n_data_cols] =&str_status_col;
00650         data_vals[n_data_cols].type = DB1_INT;
00651         data_vals[n_data_cols].nul = 0;
00652         data_vals[n_data_cols].val.int_val= s->status;
00653         n_data_cols++;
00654 
00655         data_cols[n_data_cols] =&str_reason_col;
00656         data_vals[n_data_cols].type = DB1_STR;
00657         data_vals[n_data_cols].nul = 0;
00658         data_vals[n_data_cols].val.str_val= s->reason;
00659         n_data_cols++;
00660 
00661         data_cols[n_data_cols] =&str_record_route_col;
00662         data_vals[n_data_cols].type = DB1_STR;
00663         data_vals[n_data_cols].nul = 0;
00664         data_vals[n_data_cols].val.str_val = s->record_route;
00665         n_data_cols++;
00666         
00667         data_cols[n_data_cols] =&str_contact_col;
00668         data_vals[n_data_cols].type = DB1_STR;
00669         data_vals[n_data_cols].nul = 0;
00670         data_vals[n_data_cols].val.str_val = s->contact;
00671         n_data_cols++;
00672 
00673         data_cols[n_data_cols] =&str_local_contact_col;
00674         data_vals[n_data_cols].type = DB1_STR;
00675         data_vals[n_data_cols].nul = 0;
00676         data_vals[n_data_cols].val.str_val = s->local_contact;
00677         n_data_cols++;
00678 
00679         data_cols[n_data_cols] =&str_socket_info_col;
00680         data_vals[n_data_cols].type = DB1_STR;
00681         data_vals[n_data_cols].nul = 0;
00682         data_vals[n_data_cols].val.str_val= s->sockinfo_str;
00683         n_data_cols++;
00684 
00685         data_cols[n_data_cols]=&str_version_col;
00686         data_vals[n_data_cols].type = DB1_INT;
00687         data_vals[n_data_cols].nul = 0;
00688         data_vals[n_data_cols].val.int_val= s->version;
00689         n_data_cols++;
00690 
00691         data_cols[n_data_cols]=&str_updated_col;
00692         data_vals[n_data_cols].type = DB1_INT;
00693         data_vals[n_data_cols].nul = 0;
00694         data_vals[n_data_cols].val.int_val= s->updated;
00695         n_data_cols++;
00696         
00697         if(rls_dbf.insert(rls_db, data_cols, data_vals, n_data_cols) < 0)
00698         {
00699                 LM_ERR("db insert failed\n");
00700                 return(-1);
00701         }
00702 
00703         return(0);
00704 }
00705 
00706 /******************************************************************************/
00707 
00708 int get_dialog_subscribe_rlsdb(subs_t *subs) 
00709 
00710 {
00711         db1_res_t *result= NULL;
00712         db_key_t query_cols[3];
00713         db_val_t query_vals[3], *values;
00714         db_key_t result_cols[5];
00715         db_row_t *rows;
00716         int n_query_cols = 0, n_result_cols = 0;
00717         int pres_uri_col, rcseq_col, lcseq_col, version_col, rroute_col;
00718         int nr_rows;
00719         int r_remote_cseq, r_local_cseq, r_version;
00720         char *r_pres_uri, *r_record_route;
00721 
00722         if(rls_db == NULL)
00723         {
00724                 LM_ERR("null database connection\n");
00725                 return(-1);
00726         }
00727 
00728         if (subs == NULL)
00729         {
00730                 LM_ERR("null subscriptions\n");
00731                 return(-1);
00732         }
00733 
00734         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00735         {
00736                 LM_ERR("use table failed\n");
00737                 return(-1);
00738         }
00739         
00740         query_cols[n_query_cols] = &str_callid_col;
00741         query_vals[n_query_cols].type = DB1_STR;
00742         query_vals[n_query_cols].nul = 0;
00743         query_vals[n_query_cols].val.str_val= subs->callid;
00744         n_query_cols++;
00745 
00746         query_cols[n_query_cols] = &str_to_tag_col;
00747         query_vals[n_query_cols].type = DB1_STR;
00748         query_vals[n_query_cols].nul = 0;
00749         query_vals[n_query_cols].val.str_val= subs->to_tag;
00750         n_query_cols++;
00751 
00752         query_cols[n_query_cols] = &str_from_tag_col;
00753         query_vals[n_query_cols].type = DB1_STR;
00754         query_vals[n_query_cols].nul = 0;
00755         query_vals[n_query_cols].val.str_val= subs->from_tag;
00756         n_query_cols++;
00757         
00758         result_cols[pres_uri_col = n_result_cols++] = &str_presentity_uri_col;
00759         result_cols[rcseq_col = n_result_cols++] = &str_remote_cseq_col;
00760         result_cols[lcseq_col = n_result_cols++] = &str_local_cseq_col;
00761         result_cols[version_col = n_result_cols++] = &str_version_col;
00762         result_cols[rroute_col = n_result_cols++] = &str_record_route_col;
00763 
00764         if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols, 
00765                         n_query_cols, n_result_cols, 0, &result )< 0)
00766         {
00767                 LM_ERR("Can't query db\n");
00768                 if(result) rls_dbf.free_result(rls_db, result);
00769                 return(-1);
00770         }
00771 
00772         if(result == NULL) return(-1);
00773 
00774         nr_rows = RES_ROW_N(result);
00775 
00776         if (nr_rows == 0)
00777         {
00778                 /* no match - this error might not be for RLS */ 
00779                 LM_INFO( "update_subs_rlsdb: NO MATCH\n" );
00780                 rls_dbf.free_result(rls_db, result);
00781                 return(-1);
00782         }
00783 
00784         if (nr_rows != 1)
00785         {
00786                 LM_ERR( "update_subs_rlsdb: TOO MANY MATCHES=%d\n", nr_rows);
00787                 rls_dbf.free_result(rls_db, result);
00788                 return(-1);
00789         }
00790 
00791         /* get the results and fill in return data structure */
00792         rows = RES_ROWS(result);
00793         values = ROW_VALUES(rows);
00794 
00795         r_pres_uri = (char *)VAL_STRING(&values[pres_uri_col]);
00796         r_remote_cseq = VAL_INT(&values[rcseq_col]);
00797         r_local_cseq = VAL_INT(&values[lcseq_col]);
00798         r_version = VAL_INT(&values[version_col]);
00799         r_record_route = (char *)VAL_STRING(&values[rroute_col]);
00800 
00801         if(strlen(r_pres_uri) > 0)
00802         {
00803                 subs->pres_uri.s =
00804                                 (char*)pkg_malloc(strlen(r_pres_uri) * sizeof(char));
00805                 if(subs->pres_uri.s==NULL)
00806                 {
00807                         LM_ERR( "Out of Memory\n" );
00808                         pkg_free(subs->pres_uri.s);
00809                         rls_dbf.free_result(rls_db, result);
00810                         return(-1);
00811                 }
00812                 memcpy(subs->pres_uri.s, 
00813                         r_pres_uri, strlen(r_pres_uri));
00814                 subs->pres_uri.len= strlen(r_pres_uri);
00815         }
00816 
00817         if ( r_remote_cseq >= subs->remote_cseq)
00818         {
00819                 LM_DBG("stored cseq= %d\n", r_remote_cseq);
00820                 rls_dbf.free_result(rls_db, result);
00821                 return(401); /*stale cseq code */
00822         }
00823 
00824         if(strlen(r_record_route) > 0)
00825         {
00826                 subs->record_route.s =
00827                                 (char*)pkg_malloc(strlen(r_record_route) * sizeof(char));
00828                 if(subs->record_route.s==NULL)
00829                 {
00830                         LM_ERR( "Out of Memory\n" );
00831                         pkg_free(subs->record_route.s);
00832                         rls_dbf.free_result(rls_db, result);
00833                         return(-1);
00834                 }
00835                 memcpy(subs->record_route.s, 
00836                         r_record_route, strlen(r_record_route));
00837                 subs->record_route.len= strlen(r_record_route);
00838         }
00839 
00840         subs->local_cseq= r_local_cseq;
00841         subs->version= r_version;
00842 
00843         rls_dbf.free_result(rls_db, result);
00844         return 1;
00845 }
00846 
00847 /******************************************************************************/
00848 
00849 subs_t *get_dialog_notify_rlsdb(str callid, str to_tag, str from_tag) 
00850 {
00851         db_key_t query_cols[3];
00852         db_val_t query_vals[3];
00853         db_key_t result_cols[22];
00854         int n_query_cols = 0, n_result_cols=0;
00855         int r_pres_uri_col,r_to_user_col,r_to_domain_col;
00856         int r_from_user_col,r_from_domain_col,r_callid_col;
00857         int r_to_tag_col,r_from_tag_col,r_socket_info_col;
00858         int r_event_id_col,r_local_contact_col,r_contact_col;
00859         int r_record_route_col, r_reason_col, r_event_col;
00860         int r_local_cseq_col, r_remote_cseq_col, r_status_col;
00861         int r_version_col, r_watcher_user_col, r_watcher_domain_col;
00862         int r_expires_col;
00863         db1_res_t *result= NULL;
00864         db_val_t *values;
00865         db_row_t *rows;
00866         int nr_rows, size;
00867         subs_t *dest;
00868         event_t parsed_event;
00869         str ev_sname;
00870 
00871         if(rls_db == NULL)
00872         {
00873                 LM_ERR("null database connection\n");
00874                 return(NULL);
00875         }
00876 
00877         if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
00878         {
00879                 LM_ERR("use table failed\n");
00880                 return(NULL);
00881         }
00882         
00883         query_cols[n_query_cols] = &str_callid_col;
00884         query_vals[n_query_cols].type = DB1_STR;
00885         query_vals[n_query_cols].nul = 0;
00886         query_vals[n_query_cols].val.str_val= callid;
00887         n_query_cols++;
00888 
00889         query_cols[n_query_cols] = &str_to_tag_col;
00890         query_vals[n_query_cols].type = DB1_STR;
00891         query_vals[n_query_cols].nul = 0;
00892         query_vals[n_query_cols].val.str_val= to_tag;
00893         n_query_cols++;
00894 
00895         query_cols[n_query_cols] = &str_from_tag_col;
00896         query_vals[n_query_cols].type = DB1_STR;
00897         query_vals[n_query_cols].nul = 0;
00898         query_vals[n_query_cols].val.str_val= from_tag;
00899         n_query_cols++;
00900         
00901         result_cols[r_pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
00902         result_cols[r_to_user_col=n_result_cols++] = &str_to_user_col;
00903         result_cols[r_to_domain_col=n_result_cols++] = &str_to_domain_col;
00904         result_cols[r_from_user_col=n_result_cols++] = &str_from_user_col;
00905         result_cols[r_from_domain_col=n_result_cols++] = &str_from_domain_col;
00906         result_cols[r_watcher_user_col=n_result_cols++] = &str_watcher_username_col;
00907         result_cols[r_watcher_domain_col=n_result_cols++] = &str_watcher_domain_col;
00908         result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
00909         result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
00910         result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
00911         result_cols[r_socket_info_col=n_result_cols++] = &str_socket_info_col;
00912         result_cols[r_event_id_col=n_result_cols++] = &str_event_id_col;
00913         result_cols[r_local_contact_col=n_result_cols++] = &str_local_contact_col;
00914         result_cols[r_contact_col=n_result_cols++] = &str_contact_col;
00915         result_cols[r_record_route_col=n_result_cols++] = &str_record_route_col;
00916         result_cols[r_reason_col=n_result_cols++] = &str_reason_col;
00917         result_cols[r_event_col=n_result_cols++] = &str_event_col;
00918         result_cols[r_local_cseq_col=n_result_cols++] = &str_local_cseq_col;
00919         result_cols[r_remote_cseq_col=n_result_cols++] = &str_remote_cseq_col;
00920         result_cols[r_status_col=n_result_cols++] = &str_status_col;
00921         result_cols[r_version_col=n_result_cols++] = &str_version_col;
00922         result_cols[r_expires_col=n_result_cols++] = &str_expires_col;
00923 
00924         if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols, 
00925                                 n_query_cols, n_result_cols, 0, &result )< 0)
00926         {
00927                 LM_ERR("Can't query db\n");
00928                 if(result) rls_dbf.free_result(rls_db, result);
00929                 return(NULL);
00930         }
00931 
00932         if(result == NULL) return(NULL);
00933 
00934         nr_rows = RES_ROW_N(result);
00935 
00936         if (nr_rows == 0)
00937         {
00938                 /* no match */ 
00939                 LM_INFO( "get_dialog_rlsdb No matching records\n" );
00940                 rls_dbf.free_result(rls_db, result);
00941                 return(NULL);
00942         }
00943 
00944         if (nr_rows != 1)
00945         {
00946                 LM_ERR( "get_dialog_rlsdb multiple matching records\n" );
00947                 rls_dbf.free_result(rls_db, result);
00948                 return(NULL);
00949         }
00950 
00951         /* get the results and fill in return data structure */
00952         rows = RES_ROWS(result);
00953         values = ROW_VALUES(rows);
00954 
00955         size= sizeof(subs_t) +
00956                 ( strlen(VAL_STRING(values+r_pres_uri_col))
00957                 + strlen(VAL_STRING(values+r_to_user_col))
00958                 + strlen(VAL_STRING(values+r_to_domain_col))
00959                 + strlen(VAL_STRING(values+r_from_user_col))
00960                 + strlen(VAL_STRING(values+r_from_domain_col))
00961                 + strlen(VAL_STRING(values+r_watcher_user_col))
00962                 + strlen(VAL_STRING(values+r_watcher_domain_col))
00963                 + strlen(VAL_STRING(values+r_to_tag_col))
00964                 + strlen(VAL_STRING(values+r_from_tag_col))
00965                 + strlen(VAL_STRING(values+r_callid_col))
00966                 + strlen(VAL_STRING(values+r_socket_info_col))
00967                 + strlen(VAL_STRING(values+r_local_contact_col))
00968                 + strlen(VAL_STRING(values+r_contact_col))
00969                 + strlen(VAL_STRING(values+r_record_route_col))
00970                 + strlen(VAL_STRING(values+r_event_id_col))
00971                 + strlen(VAL_STRING(values+r_reason_col)))*sizeof(char);
00972 
00973         dest= (subs_t*)pkg_malloc(size);
00974         
00975         if(dest== NULL)
00976         {
00977                 LM_ERR( "Can't allocate memory\n" );
00978                 rls_dbf.free_result(rls_db, result);
00979                 return(NULL);
00980         }
00981         memset(dest, 0, size);
00982         size= sizeof(subs_t);
00983 
00984         CONT_COPYDB(dest, dest->pres_uri, VAL_STRING(values+r_pres_uri_col))
00985         CONT_COPYDB(dest, dest->to_user, VAL_STRING(values+r_to_user_col))
00986         CONT_COPYDB(dest, dest->to_domain, VAL_STRING(values+r_to_domain_col))
00987         CONT_COPYDB(dest, dest->from_user, VAL_STRING(values+r_from_user_col))
00988         CONT_COPYDB(dest, dest->from_domain, VAL_STRING(values+r_from_domain_col))
00989         CONT_COPYDB(dest, dest->watcher_user, VAL_STRING(values+r_watcher_user_col))
00990         CONT_COPYDB(dest, dest->watcher_domain, VAL_STRING(values+r_watcher_domain_col))
00991         CONT_COPYDB(dest, dest->to_tag, VAL_STRING(values+r_to_tag_col))
00992         CONT_COPYDB(dest, dest->from_tag, VAL_STRING(values+r_from_tag_col))
00993         CONT_COPYDB(dest, dest->callid, VAL_STRING(values+r_callid_col))
00994         CONT_COPYDB(dest, dest->sockinfo_str, VAL_STRING(values+r_socket_info_col))
00995         CONT_COPYDB(dest, dest->local_contact, VAL_STRING(values+r_local_contact_col))
00996         CONT_COPYDB(dest, dest->contact, VAL_STRING(values+r_contact_col))
00997         CONT_COPYDB(dest, dest->record_route, VAL_STRING(values+r_record_route_col))
00998 
00999         if(strlen(VAL_STRING(values+r_event_id_col)) > 0)
01000                 CONT_COPYDB(dest, dest->event_id, VAL_STRING(values+r_event_id_col))
01001 
01002         if(strlen(VAL_STRING(values+r_reason_col)) > 0)
01003                 CONT_COPYDB(dest, dest->reason, VAL_STRING(values+r_reason_col))
01004 
01005         ev_sname.s= (char *)VAL_STRING(values+r_event_col);
01006         ev_sname.len= strlen(ev_sname.s);
01007 
01008         dest->event = pres_contains_event(&ev_sname, &parsed_event);
01009 
01010         if(dest->event == NULL)
01011                 LM_ERR("event not found and set to NULL\n");
01012 
01013         dest->local_cseq= VAL_INT(values+r_local_cseq_col);
01014         dest->remote_cseq= VAL_INT(values+r_remote_cseq_col);
01015         dest->status= VAL_INT(values+r_status_col);
01016         dest->version= VAL_INT(values+r_version_col);
01017         dest->expires= VAL_INT(values+r_expires_col);
01018 
01019         rls_dbf.free_result(rls_db, result);
01020 
01021         return(dest);
01022 }
01023 
01024 /******************************************************************************/
01025