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 <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;
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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