dlg_db_handler.c

Go to the documentation of this file.
00001 /*
00002  * $Id: dlg_db_handler.c 5648 2009-03-01 20:48:31Z miconda $
00003  *
00004  * Copyright (C) 2007 Voice System SRL
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  * 2007-05-10  initial version (ancuta)
00025  * 2007-07-06 additional information saved in the database: cseq, contact, 
00026  *          route set and socket_info for both caller and callee (ancuta)
00027  */
00028 
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <sys/time.h>
00032 
00033 #include "../../dprint.h"
00034 #include "../../ut.h"
00035 #include "../../timer.h"
00036 #include "../../db/db.h"
00037 #include "../../str.h"
00038 #include "../../socket_info.h"
00039 #include "dlg_hash.h"
00040 #include "dlg_db_handler.h"
00041 
00042 
00043 str call_id_column         =  str_init(CALL_ID_COL);
00044 str from_uri_column        =  str_init(FROM_URI_COL);
00045 str from_tag_column        =  str_init(FROM_TAG_COL);
00046 str to_uri_column       =  str_init(TO_URI_COL);
00047 str to_tag_column       =  str_init(TO_TAG_COL);
00048 str h_id_column            =  str_init(HASH_ID_COL);
00049 str h_entry_column         =  str_init(HASH_ENTRY_COL);
00050 str state_column        =  str_init(STATE_COL);
00051 str start_time_column      =  str_init(START_TIME_COL);
00052 str timeout_column         =  str_init(TIMEOUT_COL);
00053 str to_cseq_column         =  str_init(TO_CSEQ_COL);
00054 str from_cseq_column    =  str_init(FROM_CSEQ_COL);
00055 str to_route_column        =  str_init(TO_ROUTE_COL);
00056 str from_route_column      =  str_init(FROM_ROUTE_COL);
00057 str to_contact_column      =  str_init(TO_CONTACT_COL);
00058 str from_contact_column    =  str_init(FROM_CONTACT_COL);
00059 str to_sock_column         =  str_init(TO_SOCK_COL);
00060 str from_sock_column    =  str_init(FROM_SOCK_COL);
00061 str sflags_column       =  str_init(SFLAGS_COL);
00062 str toroute_column         =  str_init(TOROUTE_COL);
00063 str dialog_table_name      =  str_init(DIALOG_TABLE_NAME);
00064 int dlg_db_mode            =  DB_MODE_NONE;
00065 
00066 static db_con_t* dialog_db_handle    = 0; /* database connection handle */
00067 static db_func_t dialog_dbf;
00068 
00069 extern int dlg_enable_stats;
00070 extern int active_dlgs_cnt;
00071 extern int early_dlgs_cnt;
00072 
00073 #define SET_STR_VALUE(_val, _str)\
00074    do{\
00075          VAL_STR((_val)).s       = (_str).s;\
00076          VAL_STR((_val)).len  = (_str).len;\
00077    }while(0);
00078 
00079 #define SET_NULL_FLAG(_vals, _i, _max, _flag)\
00080    do{\
00081       for((_i) = 0;(_i)<(_max); (_i)++)\
00082          VAL_NULL((_vals)+(_i)) = (_flag);\
00083    }while(0);
00084 
00085 #define SET_PROPER_NULL_FLAG(_str, _vals, _index)\
00086    do{\
00087       if( (_str).len == 0)\
00088          VAL_NULL( (_vals)+(_index) ) = 1;\
00089       else\
00090          VAL_NULL( (_vals)+(_index) ) = 0;\
00091    }while(0);
00092 
00093 #define GET_STR_VALUE(_res, _values, _index, _not_null, _unref)\
00094    do{\
00095       if (VAL_NULL((_values)+ (_index))) { \
00096          if (_not_null) {\
00097             if (_unref) unref_dlg(dlg,1);\
00098             goto next_dialog; \
00099          } else { \
00100             (_res).s = 0; \
00101             (_res).len = 0; \
00102          }\
00103       } else { \
00104          (_res).s = VAL_STR((_values)+ (_index)).s;\
00105          (_res).len = strlen(VAL_STR((_values)+ (_index)).s);\
00106       } \
00107    }while(0);
00108 
00109 
00110 static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows);
00111 
00112 
00113 int dlg_connect_db(const str *db_url)
00114 {
00115    if (dialog_db_handle) {
00116       LM_CRIT("BUG - db connection found already open\n");
00117       return -1;
00118    }
00119    if ((dialog_db_handle = dialog_dbf.init(db_url)) == 0)
00120       return -1;
00121    return 0;
00122 }
00123 
00124 
00125 int init_dlg_db(const str *db_url, int dlg_hash_size , int db_update_period, int fetch_num_rows)
00126 {
00127    /* Find a database module */
00128    if (db_bind_mod(db_url, &dialog_dbf) < 0){
00129       LM_ERR("Unable to bind to a database driver\n");
00130       return -1;
00131    }
00132 
00133    if (dlg_connect_db(db_url)!=0){
00134       LM_ERR("unable to connect to the database\n");
00135       return -1;
00136    }
00137 
00138    if(db_check_table_version(&dialog_dbf, dialog_db_handle, &dialog_table_name, DLG_TABLE_VERSION) < 0) {
00139       LM_ERR("error during table version check.\n");
00140       return -1;
00141    }
00142 
00143    if( (dlg_db_mode==DB_MODE_DELAYED) && 
00144    (register_timer( dialog_update_db, 0, db_update_period)<0 )) {
00145       LM_ERR("failed to register update db\n");
00146       return -1;
00147    }
00148 
00149    if( (load_dialog_info_from_db(dlg_hash_size, fetch_num_rows) ) !=0 ){
00150       LM_ERR("unable to load the dialog data\n");
00151       return -1;
00152    }
00153 
00154    dialog_dbf.close(dialog_db_handle);
00155    dialog_db_handle = 0;
00156 
00157    return 0;
00158 }
00159 
00160 
00161 
00162 void destroy_dlg_db(void)
00163 {
00164    /* close the DB connection */
00165    if (dialog_db_handle) {
00166       dialog_dbf.close(dialog_db_handle);
00167       dialog_db_handle = 0;
00168    }
00169 }
00170 
00171 
00172 
00173 static int use_dialog_table(void)
00174 {
00175    if(!dialog_db_handle){
00176       LM_ERR("invalid database handle\n");
00177       return -1;
00178    }
00179 
00180    if (dialog_dbf.use_table(dialog_db_handle, &dialog_table_name) < 0) {
00181       LM_ERR("Error in use_table\n");
00182       return -1;
00183    }
00184 
00185    return 0;
00186 }
00187 
00188 
00189 
00190 static int select_entire_dialog_table(db_res_t ** res, int fetch_num_rows)
00191 {
00192    db_key_t query_cols[DIALOG_TABLE_COL_NO] = { &h_entry_column,
00193          &h_id_column,     &call_id_column,  &from_uri_column,
00194          &from_tag_column, &to_uri_column,      &to_tag_column,
00195          &start_time_column,  &state_column,    &timeout_column,
00196          &from_cseq_column,   &to_cseq_column,  &from_route_column,
00197          &to_route_column,    &from_contact_column, &to_contact_column,
00198          &from_sock_column,   &to_sock_column,    &sflags_column,
00199          &toroute_column };
00200 
00201    if(use_dialog_table() != 0){
00202       return -1;
00203    }
00204 
00205    /* select the whole tabel and all the columns */
00206    if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) {
00207       if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, 
00208       DIALOG_TABLE_COL_NO, 0, 0) < 0) {
00209          LM_ERR("Error while querying (fetch) database\n");
00210          return -1;
00211       }
00212       if(dialog_dbf.fetch_result(dialog_db_handle, res, fetch_num_rows) < 0) {
00213          LM_ERR("fetching rows failed\n");
00214          return -1;
00215       }
00216    } else {
00217       if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0,
00218       DIALOG_TABLE_COL_NO, 0, res) < 0) {
00219          LM_ERR("Error while querying database\n");
00220          return -1;
00221       }
00222    }
00223 
00224    return 0;
00225 }
00226 
00227 
00228 
00229 struct socket_info * create_socket_info(db_val_t * vals, int n){
00230 
00231    struct socket_info * sock;
00232    str host, p;
00233    int port, proto;
00234 
00235    /* socket name */
00236    p.s  = (VAL_STR(vals+n)).s;
00237    p.len = strlen(p.s);
00238 
00239    if (VAL_NULL(vals+n) || p.s==0 || p.s[0]==0){
00240       sock = 0;
00241    } else {
00242       if (parse_phostport( p.s, p.len, &host.s, &host.len, 
00243       &port, &proto)!=0) {
00244          LM_ERR("bad socket <%.*s>\n", p.len, p.s);
00245          return 0;
00246       }
00247       sock = grep_sock_info( &host, (unsigned short)port, proto);
00248       if (sock==0) {
00249          LM_WARN("non-local socket <%.*s>...ignoring\n", p.len, p.s);
00250          }
00251    }
00252 
00253    return sock;
00254 }
00255 
00256 
00257 
00258 static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
00259 {
00260    db_res_t * res;
00261    db_val_t * values;
00262    db_row_t * rows;
00263    int i, nr_rows;
00264    struct dlg_cell *dlg;
00265    str callid, from_uri, to_uri, from_tag, to_tag;
00266    str cseq1, cseq2, contact1, contact2, rroute1, rroute2;
00267    unsigned int next_id;
00268    
00269 
00270    res = 0;
00271    if((nr_rows = select_entire_dialog_table(&res, fetch_num_rows)) < 0)
00272       goto end;
00273 
00274    nr_rows = RES_ROW_N(res);
00275 
00276    LM_DBG("the database has information about %i dialogs\n", nr_rows);
00277 
00278    rows = RES_ROWS(res);
00279 
00280    do {
00281       /* for every row---dialog */
00282       for(i=0; i<nr_rows; i++){
00283 
00284          values = ROW_VALUES(rows + i);
00285 
00286          if (VAL_NULL(values) || VAL_NULL(values+1)) {
00287             LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
00288                h_entry_column.len, h_entry_column.s,
00289                h_id_column.len, h_id_column.s);
00290             continue;
00291          }
00292 
00293          if (VAL_NULL(values+7) || VAL_NULL(values+8)) {
00294             LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
00295                start_time_column.len, start_time_column.s,
00296                state_column.len, state_column.s);
00297             continue;
00298          }
00299 
00300          /*restore the dialog info*/
00301          GET_STR_VALUE(callid, values, 2, 1, 0);
00302          GET_STR_VALUE(from_uri, values, 3, 1, 0);
00303          GET_STR_VALUE(from_tag, values, 4, 1, 0);
00304          GET_STR_VALUE(to_uri, values, 5, 1, 0);
00305 
00306          if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){
00307             LM_ERR("failed to build new dialog\n");
00308             goto error;
00309          }
00310 
00311          if(dlg->h_entry != VAL_INT(values)){
00312             LM_ERR("inconsistent hash data in the dialog database: "
00313                "you may have restarted Kamailio using a different "
00314                "hash_size: please erase %.*s database and restart\n", 
00315                dialog_table_name.len, dialog_table_name.s);
00316             shm_free(dlg);
00317             goto error;
00318          }
00319 
00320          /*link the dialog*/
00321          link_dlg(dlg, 0);
00322 
00323          dlg->h_id = VAL_INT(values+1);
00324          next_id = d_table->entries[dlg->h_entry].next_id;
00325 
00326          d_table->entries[dlg->h_entry].next_id =
00327             (next_id < dlg->h_id) ? (dlg->h_id+1) : next_id;
00328 
00329          GET_STR_VALUE(to_tag, values, 6, 1, 1);
00330 
00331          dlg->start_ts  = VAL_INT(values+7);
00332 
00333          dlg->state     = VAL_INT(values+8);
00334          if (dlg->state==DLG_STATE_CONFIRMED_NA ||
00335          dlg->state==DLG_STATE_CONFIRMED) {
00336             active_dlgs_cnt++;
00337          } else if (dlg->state==DLG_STATE_EARLY) {
00338             early_dlgs_cnt++;
00339          }
00340 
00341          dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks();
00342          if (dlg->tl.timeout<=(unsigned int)time(0))
00343             dlg->tl.timeout = 0;
00344          else
00345             dlg->tl.timeout -= (unsigned int)time(0);
00346 
00347          GET_STR_VALUE(cseq1, values, 10 , 1, 1);
00348          GET_STR_VALUE(cseq2, values, 11 , 1, 1);
00349          GET_STR_VALUE(rroute1, values, 12, 0, 0);
00350          GET_STR_VALUE(rroute2, values, 13, 0, 0);
00351          GET_STR_VALUE(contact1, values, 14, 1, 1);
00352          GET_STR_VALUE(contact2, values, 15, 1, 1);
00353 
00354          if ( (dlg_set_leg_info( dlg, &from_tag, &rroute1, &contact1,
00355          &cseq1, DLG_CALLER_LEG)!=0) ||
00356          (dlg_set_leg_info( dlg, &to_tag, &rroute2, &contact2,
00357          &cseq2, DLG_CALLEE_LEG)!=0) ) {
00358             LM_ERR("dlg_set_leg_info failed\n");
00359             unref_dlg(dlg,1);
00360             continue;
00361          }
00362 
00363          dlg->bind_addr[DLG_CALLER_LEG] = create_socket_info(values, 16);
00364          dlg->bind_addr[DLG_CALLEE_LEG] = create_socket_info(values, 17);
00365          
00366          /*restore the timer values */
00367          if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) {
00368             LM_CRIT("Unable to insert dlg %p [%u:%u] "
00369                "with clid '%.*s' and tags '%.*s' '%.*s'\n",
00370                dlg, dlg->h_entry, dlg->h_id,
00371                dlg->callid.len, dlg->callid.s,
00372                dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
00373                dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
00374             unref_dlg(dlg,1);
00375             continue;
00376          }
00377          ref_dlg(dlg,1);
00378          LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout);
00379 
00380          dlg->lifetime = 0;
00381          dlg->dflags = 0;
00382          next_dialog:
00383          ;
00384       }
00385 
00386       /* any more data to be fetched ?*/
00387       if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) {
00388          if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) < 0) {
00389             LM_ERR("re-fetching rows failed\n");
00390             goto error;
00391          }
00392          nr_rows = RES_ROW_N(res);
00393          rows = RES_ROWS(res);
00394       } else {
00395          nr_rows = 0;
00396       }
00397 
00398    }while (nr_rows>0);
00399 
00400 end:
00401    dialog_dbf.free_result(dialog_db_handle, res);
00402    return 0;
00403 error:
00404    dialog_dbf.free_result(dialog_db_handle, res);
00405    return -1;
00406 
00407 }
00408 
00409 
00410 
00411 /*this is only called from destroy_dlg, where the cell's entry lock is acquired*/
00412 int remove_dialog_from_db(struct dlg_cell * cell)
00413 {
00414    db_val_t values[2];
00415    db_key_t match_keys[2] = { &h_entry_column, &h_id_column};
00416 
00417    /*if the dialog hasn 't been yet inserted in the database*/
00418    LM_DBG("trying to remove a dialog, update_flag is %i\n", cell->dflags);
00419    if (cell->dflags & DLG_FLAG_NEW) 
00420       return 0;
00421 
00422    if (use_dialog_table()!=0)
00423       return -1;
00424 
00425    VAL_TYPE(values) = VAL_TYPE(values+1) = DB_INT;
00426    VAL_NULL(values) = VAL_NULL(values+1) = 0;
00427 
00428    VAL_INT(values)   = cell->h_entry;
00429    VAL_INT(values+1)    = cell->h_id;
00430 
00431    if(dialog_dbf.delete(dialog_db_handle, match_keys, 0, values, 2) < 0) {
00432       LM_ERR("failed to delete database information\n");
00433       return -1;
00434    }
00435 
00436    LM_DBG("callid was %.*s\n", cell->callid.len, cell->callid.s );
00437 
00438    return 0;
00439 }
00440 
00441 
00442 
00443 int update_dialog_dbinfo(struct dlg_cell * cell)
00444 {
00445    int i;
00446    struct dlg_entry entry;
00447    db_val_t values[DIALOG_TABLE_COL_NO];
00448 
00449    db_key_t insert_keys[DIALOG_TABLE_COL_NO] = { &h_entry_column,
00450          &h_id_column,        &call_id_column,     &from_uri_column,
00451          &from_tag_column,    &to_uri_column,      &to_tag_column,
00452          &from_sock_column,   &to_sock_column,
00453          &start_time_column,  &state_column,       &timeout_column,
00454          &from_cseq_column,   &to_cseq_column,     &from_route_column,
00455          &to_route_column,    &from_contact_column,&to_contact_column,
00456          &sflags_column,      &toroute_column };
00457 
00458    if(use_dialog_table()!=0)
00459       return -1;
00460    
00461    if((cell->dflags & DLG_FLAG_NEW) != 0){
00462       /* save all the current dialogs information*/
00463       VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = 
00464       VAL_TYPE(values+10) = VAL_TYPE(values+11) = DB_INT;
00465 
00466       VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = 
00467       VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
00468       VAL_TYPE(values+8) = VAL_TYPE(values+12) = VAL_TYPE(values+13) = 
00469       VAL_TYPE(values+14) = VAL_TYPE(values+15) = VAL_TYPE(values+16)=
00470       VAL_TYPE(values+17) = DB_STR;
00471 
00472       SET_NULL_FLAG(values, i, DIALOG_TABLE_COL_NO-6, 0);
00473       VAL_TYPE(values+18) = VAL_TYPE(values+19) = DB_INT;
00474 
00475       /* lock the entry */
00476       entry = (d_table->entries)[cell->h_entry];
00477       dlg_lock( d_table, &entry);
00478 
00479       VAL_INT(values)         = cell->h_entry;
00480       VAL_INT(values+1)    = cell->h_id;
00481       VAL_INT(values+9)    = cell->start_ts;
00482       VAL_INT(values+10)      = cell->state;
00483       VAL_INT(values+11)      = (unsigned int)( (unsigned int)time(0) +
00484              cell->tl.timeout - get_ticks() );
00485 
00486       SET_STR_VALUE(values+2, cell->callid);
00487       SET_STR_VALUE(values+3, cell->from_uri);
00488       SET_STR_VALUE(values+4, cell->tag[DLG_CALLER_LEG]);
00489       SET_STR_VALUE(values+5, cell->to_uri);
00490       SET_STR_VALUE(values+6, cell->tag[DLG_CALLEE_LEG]);
00491       SET_PROPER_NULL_FLAG(cell->tag[DLG_CALLEE_LEG], values, 6);
00492 
00493       LM_DBG("sock_info is %.*s\n", 
00494          cell->bind_addr[DLG_CALLER_LEG]->sock_str.len,
00495          cell->bind_addr[DLG_CALLEE_LEG]->sock_str.s);
00496 
00497       SET_STR_VALUE(values+7, cell->bind_addr[DLG_CALLER_LEG]->sock_str);
00498       SET_STR_VALUE(values+8, cell->bind_addr[DLG_CALLEE_LEG]->sock_str);
00499 
00500       SET_STR_VALUE(values+12, cell->cseq[DLG_CALLER_LEG]);
00501       SET_STR_VALUE(values+13, cell->cseq[DLG_CALLEE_LEG]);
00502       SET_STR_VALUE(values+14, cell->route_set[DLG_CALLER_LEG]);
00503       SET_STR_VALUE(values+15, cell->route_set[DLG_CALLEE_LEG]);
00504       SET_STR_VALUE(values+16, cell->contact[DLG_CALLER_LEG]);
00505       SET_STR_VALUE(values+17, cell->contact[DLG_CALLEE_LEG]);
00506 
00507       SET_PROPER_NULL_FLAG(cell->route_set[DLG_CALLER_LEG],    values, 14);
00508       SET_PROPER_NULL_FLAG(cell->route_set[DLG_CALLEE_LEG],    values, 15);
00509       SET_PROPER_NULL_FLAG(cell->contact[DLG_CALLER_LEG],   values, 16);
00510       SET_PROPER_NULL_FLAG(cell->contact[DLG_CALLEE_LEG],   values, 17);
00511 
00512       VAL_INT(values+18)      = cell->sflags;
00513       VAL_INT(values+19)      = cell->toroute;
00514 
00515       if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, 
00516                         DIALOG_TABLE_COL_NO)) !=0){
00517          LM_ERR("could not add another dialog to db\n");
00518          goto error;
00519       }
00520       cell->dflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED);
00521       
00522    } else if((cell->dflags & DLG_FLAG_CHANGED) != 0) {
00523       /* save only dialog's state and timeout */
00524       VAL_TYPE(values) = VAL_TYPE(values+1) = 
00525       VAL_TYPE(values+10) = VAL_TYPE(values+11) = DB_INT;
00526 
00527       VAL_TYPE(values+12) = VAL_TYPE(values+13) =DB_STR;
00528 
00529       /* lock the entry */
00530       entry = (d_table->entries)[cell->h_entry];
00531       dlg_lock( d_table, &entry);
00532 
00533       VAL_INT(values)         = cell->h_entry;
00534       VAL_INT(values+1)    = cell->h_id;
00535       VAL_INT(values+10)      = cell->state;
00536       VAL_INT(values+11)      = (unsigned int)( (unsigned int)time(0) +
00537              cell->tl.timeout - get_ticks() );
00538 
00539       SET_STR_VALUE(values+12, cell->cseq[DLG_CALLER_LEG]);
00540       SET_STR_VALUE(values+13, cell->cseq[DLG_CALLEE_LEG]);
00541 
00542 
00543       VAL_NULL(values) = VAL_NULL(values+1) = 
00544       VAL_NULL(values+10) = VAL_NULL(values+11) = 
00545       VAL_NULL(values+12) = VAL_NULL(values+13) = 0;
00546 
00547       if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
00548                   (values), (insert_keys+10), (values+10), 2, 4)) !=0){
00549          LM_ERR("could not update database info\n");
00550          goto error;
00551       }
00552       cell->dflags &= ~(DLG_FLAG_CHANGED);
00553    } else {
00554       return 0;
00555    }
00556 
00557    dlg_unlock( d_table, &entry);
00558    return 0;
00559 
00560 error:
00561    dlg_unlock( d_table, &entry);
00562    return -1;
00563 }
00564 
00565 
00566 
00567 void dialog_update_db(unsigned int ticks, void * param)
00568 {
00569    int index, i;
00570    db_val_t values[DIALOG_TABLE_COL_NO];
00571    struct dlg_entry entry;
00572    struct dlg_cell  * cell; 
00573    
00574    db_key_t insert_keys[DIALOG_TABLE_COL_NO] = {      &h_entry_column,
00575          &h_id_column,     &call_id_column,     &from_uri_column,
00576          &from_tag_column, &to_uri_column,         &to_tag_column,
00577          &from_sock_column,   &to_sock_column,
00578          &start_time_column,  &state_column,       &timeout_column,
00579          &from_cseq_column,   &to_cseq_column,     &from_route_column,
00580          &to_route_column,    &from_contact_column,   &to_contact_column,
00581          &sflags_column,     &toroute_column };
00582 
00583    if(use_dialog_table()!=0)
00584       return;
00585 
00586    /*save the current dialogs information*/
00587    VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = 
00588    VAL_TYPE(values+10) = VAL_TYPE(values+11) = DB_INT;
00589 
00590    VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = 
00591    VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
00592    VAL_TYPE(values+8) = VAL_TYPE(values+12) = VAL_TYPE(values+13) = 
00593    VAL_TYPE(values+14) = VAL_TYPE(values+15) = VAL_TYPE(values+16) = 
00594    VAL_TYPE(values+17) = DB_STR;
00595 
00596    SET_NULL_FLAG(values, i, DIALOG_TABLE_COL_NO-6, 0);
00597 
00598    VAL_TYPE(values+18) = VAL_TYPE(values+19) = DB_INT;
00599 
00600    LM_DBG("saving current_info \n");
00601    
00602    for(index = 0; index< d_table->size; index++){
00603 
00604       /* lock the whole entry */
00605       entry = (d_table->entries)[index];
00606       dlg_lock( d_table, &entry);
00607 
00608       for(cell = entry.first; cell != NULL; cell = cell->next){
00609 
00610          if( (cell->dflags & DLG_FLAG_NEW) != 0 ) {
00611 
00612             VAL_INT(values)         = cell->h_entry;
00613             VAL_INT(values+1)    = cell->h_id;
00614 
00615             VAL_INT(values+9)    = cell->start_ts;
00616             VAL_INT(values+10)      = cell->state;
00617             VAL_INT(values+11)   = (unsigned int)( (unsigned int)time(0) +
00618                 cell->tl.timeout - get_ticks() );
00619 
00620             SET_STR_VALUE(values+2, cell->callid);
00621             SET_STR_VALUE(values+3, cell->from_uri);
00622             SET_STR_VALUE(values+4, cell->tag[DLG_CALLER_LEG]);
00623             SET_STR_VALUE(values+5, cell->to_uri);
00624             SET_STR_VALUE(values+6, cell->tag[DLG_CALLEE_LEG]);
00625             SET_PROPER_NULL_FLAG(cell->tag[DLG_CALLEE_LEG], values, 6);
00626 
00627             SET_STR_VALUE(values+7,
00628                cell->bind_addr[DLG_CALLER_LEG]->sock_str);
00629             SET_STR_VALUE(values+8,
00630                cell->bind_addr[DLG_CALLEE_LEG]->sock_str);
00631             
00632             SET_STR_VALUE(values+12, cell->cseq[DLG_CALLER_LEG]);
00633             SET_STR_VALUE(values+13, cell->cseq[DLG_CALLEE_LEG]);
00634 
00635             SET_STR_VALUE(values+14, cell->route_set[DLG_CALLER_LEG]);
00636             SET_STR_VALUE(values+15, cell->route_set[DLG_CALLEE_LEG]);
00637             SET_STR_VALUE(values+16, cell->contact[DLG_CALLER_LEG]);
00638             SET_STR_VALUE(values+17, cell->contact[DLG_CALLEE_LEG]);
00639          
00640             SET_PROPER_NULL_FLAG(cell->route_set[DLG_CALLER_LEG],
00641                values, 14);
00642             SET_PROPER_NULL_FLAG(cell->route_set[DLG_CALLEE_LEG],
00643                values, 15);
00644             SET_PROPER_NULL_FLAG(cell->contact[DLG_CALLER_LEG],
00645                values, 16);
00646             SET_PROPER_NULL_FLAG(cell->contact[DLG_CALLEE_LEG],
00647                values, 17);
00648             
00649             VAL_INT(values+18)      = cell->sflags;
00650             VAL_INT(values+19)      = cell->toroute;
00651 
00652             if((dialog_dbf.insert(dialog_db_handle, insert_keys, 
00653             values, DIALOG_TABLE_COL_NO)) !=0){
00654                LM_ERR("could not add another dialog to db\n");
00655                goto error;
00656             }
00657 
00658             cell->dflags &= ~(DLG_FLAG_NEW |DLG_FLAG_CHANGED);
00659 
00660          } else if( (cell->dflags & DLG_FLAG_CHANGED)!=0 ){
00661 
00662             VAL_INT(values)         = cell->h_entry;
00663             VAL_INT(values+1)    = cell->h_id;
00664 
00665             VAL_INT(values+10)      = cell->state;
00666             VAL_INT(values+11)   = (unsigned int)( (unsigned int)time(0) +
00667                 cell->tl.timeout - get_ticks() );
00668             SET_STR_VALUE(values+12, cell->cseq[0]);
00669             SET_STR_VALUE(values+13, cell->cseq[DLG_CALLEE_LEG]);
00670 
00671 
00672             if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
00673             (values), (insert_keys+10), (values+10), 2, 4)) !=0) {
00674                LM_ERR("could not update database info\n");
00675                goto error;
00676             }
00677 
00678             cell->dflags &= ~DLG_FLAG_CHANGED;
00679 
00680          }
00681 
00682       }
00683       dlg_unlock( d_table, &entry);
00684 
00685    }
00686 
00687    return;
00688 
00689 error:
00690    dlg_unlock( d_table, &entry);
00691 }
00692 

Generated on Tue May 22 16:00:26 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6