mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
10 KiB
270 lines
10 KiB
#include "ro_db_handler.h"
|
|
#include "../../lib/srdb1/db.h"
|
|
|
|
static db1_con_t* ro_db_handle = 0; /* database connection handle */
|
|
static db_func_t ro_dbf;
|
|
|
|
str ro_session_table_name = str_init(RO_SESSION_TABLE_NAME);
|
|
str id_column = str_init(ID_COL);
|
|
str h_entry_column = str_init(HASH_ENTRY_COL);
|
|
str h_id_column = str_init(HASH_ID_COL);
|
|
str session_id_column = str_init(SESSION_ID_COL);
|
|
str dlg_h_entry_column = str_init(DLG_HASH_ENTRY_COL);
|
|
str dlg_h_id_column = str_init(DLG_HASH_ID_COL);
|
|
str direction_column = str_init(DIRECTION_COL);
|
|
str asserted_column = str_init(ASSERTED_ID_COL);
|
|
str callee_column = str_init(CALLEE_COL);
|
|
str start_time_col = str_init(START_TIME_COL);
|
|
str last_event_ts_column = str_init(LAST_EVENT_TS_COL);
|
|
str reserved_sec_column = str_init(RESERVED_SECS_COL);
|
|
str valid_for_column = str_init(VALID_FOR_COL);
|
|
str state_column = str_init(STATE_COL);
|
|
str incoming_trunk_id_column = str_init(INCOMING_TRUNK_ID_COL);
|
|
str outgoing_trunk_id_column = str_init(OUTGOING_TRUNK_ID_COL);
|
|
str rating_group_column = str_init(RATING_GROUP_COL);
|
|
str service_identifier_column = str_init(SERVICE_IDENTIFIER_COL);
|
|
|
|
typedef enum ro_session_field_idx {
|
|
ID_COL_IDX = 0,
|
|
HASH_ENTRY_COL_IDX,
|
|
HASH_ID_COL_IDX,
|
|
SESSION_ID_COL_IDX,
|
|
DLG_HASH_ENTRY_COL_IDX,
|
|
DLG_HASH_ID_COL_IDX,
|
|
DIRECTION_COL_IDX,
|
|
ASSERTED_ID_COL_IDX,
|
|
CALLEE_COL_IDX,
|
|
START_TIME_COL_IDX,
|
|
LAST_EVENT_TS_COL_IDX,
|
|
RESERVED_SECS_COL_IDX,
|
|
VALID_FOR_COL_IDX,
|
|
STATE_COL_IDX,
|
|
INCOMING_TRUNK_ID_COL_IDX,
|
|
OUTGOING_TRUNK_ID_COL_IDX,
|
|
RATING_GROUP_COL_IDX,
|
|
SERVICE_IDENTIFIER_COL_IDX
|
|
|
|
} ro_session_field_idx_t;
|
|
|
|
#define GET_FIELD_IDX(_val, _idx)\
|
|
(_val + _idx)
|
|
|
|
#define SET_STR_VALUE(_val, _str)\
|
|
do{\
|
|
VAL_STR((_val)).s = (_str).s;\
|
|
VAL_STR((_val)).len = (_str).len;\
|
|
}while(0);
|
|
|
|
#define SET_NULL_FLAG(_vals, _i, _max, _flag)\
|
|
do{\
|
|
for((_i) = 0;(_i)<(_max); (_i)++)\
|
|
VAL_NULL((_vals)+(_i)) = (_flag);\
|
|
}while(0);
|
|
|
|
#define SET_PROPER_NULL_FLAG(_str, _vals, _index)\
|
|
do{\
|
|
if( (_str).len == 0)\
|
|
VAL_NULL( (_vals)+(_index) ) = 1;\
|
|
else\
|
|
VAL_NULL( (_vals)+(_index) ) = 0;\
|
|
}while(0);
|
|
|
|
#define GET_STR_VALUE(_res, _values, _index, _not_null, _unref)\
|
|
do{\
|
|
if (VAL_NULL((_values)+ (_index))) { \
|
|
if (_not_null) {\
|
|
if (_unref) unref_dlg(dlg,1);\
|
|
goto next_dialog; \
|
|
} else { \
|
|
(_res).s = 0; \
|
|
(_res).len = 0; \
|
|
}\
|
|
} else { \
|
|
(_res).s = VAL_STR((_values)+ (_index)).s;\
|
|
(_res).len = strlen(VAL_STR((_values)+ (_index)).s);\
|
|
} \
|
|
}while(0);
|
|
|
|
int init_ro_db(const str *db_url, int dlg_hash_size, int db_update_period, int fetch_num_rows) {
|
|
/* Find a database module */
|
|
if (db_bind_mod(db_url, &ro_dbf) < 0) {
|
|
LM_ERR("Unable to bind to a database driver\n");
|
|
return -1;
|
|
}
|
|
|
|
if (ro_connect_db(db_url) != 0) {
|
|
LM_ERR("unable to connect to the database\n");
|
|
return -1;
|
|
}
|
|
|
|
if (db_check_table_version(&ro_dbf, ro_db_handle, &ro_session_table_name, RO_TABLE_VERSION) < 0) {
|
|
LM_ERR("error during dialog-table version check.\n");
|
|
return -1;
|
|
}
|
|
|
|
// if( (dlg_db_mode==DB_MODE_DELAYED) &&
|
|
// (register_timer( dialog_update_db, 0, db_update_period)<0 )) {
|
|
// LM_ERR("failed to register update db\n");
|
|
// return -1;
|
|
// }
|
|
|
|
if ((load_ro_info_from_db(dlg_hash_size, fetch_num_rows)) != 0) {
|
|
LM_ERR("unable to load the dialog data\n");
|
|
return -1;
|
|
}
|
|
|
|
ro_dbf.close(ro_db_handle);
|
|
ro_db_handle = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int load_ro_info_from_db(int hash_size, int fetch_num_rows) {
|
|
LM_WARN("not supported yet");
|
|
return 0;
|
|
}
|
|
|
|
int ro_connect_db(const str *db_url) {
|
|
if (ro_db_handle) {
|
|
LM_CRIT("BUG - db connection found already open\n");
|
|
return -1;
|
|
}
|
|
if ((ro_db_handle = ro_dbf.init(db_url)) == 0)
|
|
return -1;
|
|
|
|
/* use default table */
|
|
if (ro_dbf.use_table(ro_db_handle, &ro_session_table_name) != 0) {
|
|
LM_ERR("Error in use table for table name [%.*s]\n", ro_session_table_name.len, ro_session_table_name.s);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void db_set_int_val(db_val_t* values, int index, int val) {
|
|
VAL_TYPE(GET_FIELD_IDX(values, index)) = DB1_INT;
|
|
VAL_NULL(GET_FIELD_IDX(values, index)) = 0;
|
|
VAL_INT(GET_FIELD_IDX(values, index)) = val;
|
|
}
|
|
|
|
void db_set_str_val(db_val_t* values, int index, str* val) {
|
|
VAL_TYPE(GET_FIELD_IDX(values, index)) = DB1_STR;
|
|
VAL_NULL(GET_FIELD_IDX(values, index)) = 0;
|
|
SET_STR_VALUE(GET_FIELD_IDX(values, index), *val);
|
|
}
|
|
|
|
void db_set_datetime_val(db_val_t* values, int index, time_t val) {
|
|
VAL_TYPE(GET_FIELD_IDX(values, index)) = DB1_DATETIME;
|
|
VAL_NULL(GET_FIELD_IDX(values, index)) = 0;
|
|
VAL_TIME(GET_FIELD_IDX(values, index)) = val;
|
|
}
|
|
|
|
int update_ro_dbinfo_unsafe(struct ro_session* ro_session) {
|
|
if ((ro_session->flags & RO_SESSION_FLAG_NEW) != 0 && (ro_session->flags & RO_SESSION_FLAG_INSERTED) == 0) {
|
|
|
|
db_val_t values[RO_SESSION_TABLE_COL_NUM];
|
|
db_key_t insert_keys[RO_SESSION_TABLE_COL_NUM] = {
|
|
&id_column, &h_entry_column, &h_id_column, &session_id_column, &dlg_h_entry_column, &dlg_h_id_column,
|
|
&direction_column, &asserted_column, &callee_column, &start_time_col, &last_event_ts_column,
|
|
&reserved_sec_column, &valid_for_column, &state_column, &incoming_trunk_id_column, &outgoing_trunk_id_column, &rating_group_column, &service_identifier_column
|
|
};
|
|
|
|
VAL_TYPE(GET_FIELD_IDX(values, ID_COL_IDX)) = DB1_INT;
|
|
VAL_NULL(GET_FIELD_IDX(values, ID_COL_IDX)) = 1;
|
|
|
|
db_set_int_val(values, HASH_ENTRY_COL_IDX, ro_session->h_entry);
|
|
db_set_int_val(values, HASH_ID_COL_IDX, ro_session->h_id);
|
|
db_set_str_val(values, SESSION_ID_COL_IDX, &ro_session->ro_session_id);
|
|
db_set_int_val(values, DLG_HASH_ENTRY_COL_IDX, ro_session->dlg_h_entry);
|
|
db_set_int_val(values, DLG_HASH_ID_COL_IDX, ro_session->dlg_h_id);
|
|
db_set_int_val(values, DIRECTION_COL_IDX, ro_session->direction);
|
|
db_set_str_val(values, ASSERTED_ID_COL_IDX, &ro_session->asserted_identity);
|
|
db_set_str_val(values, CALLEE_COL_IDX, &ro_session->called_asserted_identity);
|
|
db_set_datetime_val(values, START_TIME_COL_IDX, ro_session->start_time/1000000);
|
|
db_set_datetime_val(values, LAST_EVENT_TS_COL_IDX, ro_session->last_event_timestamp/1000000);
|
|
db_set_int_val(values, RESERVED_SECS_COL_IDX, ro_session->reserved_secs);
|
|
db_set_int_val(values, VALID_FOR_COL_IDX, ro_session->valid_for);
|
|
db_set_int_val(values, STATE_COL_IDX, ro_session->active);
|
|
db_set_str_val(values, INCOMING_TRUNK_ID_COL_IDX, &ro_session->incoming_trunk_id);
|
|
db_set_str_val(values, OUTGOING_TRUNK_ID_COL_IDX, &ro_session->outgoing_trunk_id);
|
|
db_set_int_val(values, RATING_GROUP_COL_IDX, ro_session->rating_group);
|
|
db_set_int_val(values, SERVICE_IDENTIFIER_COL_IDX, ro_session->service_identifier);
|
|
|
|
|
|
LM_DBG("Inserting ro_session into database\n");
|
|
if ((ro_dbf.insert(ro_db_handle, insert_keys, values, RO_SESSION_TABLE_COL_NUM)) != 0) {
|
|
LM_ERR("could not add new Ro session into DB.... continuing\n");
|
|
goto error;
|
|
}
|
|
ro_session->flags &= ~(RO_SESSION_FLAG_NEW | RO_SESSION_FLAG_CHANGED);
|
|
ro_session->flags |= RO_SESSION_FLAG_INSERTED;
|
|
|
|
} else if ((ro_session->flags & RO_SESSION_FLAG_CHANGED) != 0 && (ro_session->flags & RO_SESSION_FLAG_INSERTED) != 0) {
|
|
|
|
db_val_t values[RO_SESSION_TABLE_COL_NUM-1];
|
|
db_key_t update_keys[RO_SESSION_TABLE_COL_NUM-1] = {
|
|
&h_entry_column, &h_id_column, &session_id_column, &dlg_h_entry_column, &dlg_h_id_column,
|
|
&direction_column, &asserted_column, &callee_column, &start_time_col, &last_event_ts_column,
|
|
&reserved_sec_column, &valid_for_column, &state_column, &incoming_trunk_id_column, &outgoing_trunk_id_column, &rating_group_column, &service_identifier_column
|
|
};
|
|
|
|
db_set_int_val(values, HASH_ENTRY_COL_IDX - 1, ro_session->h_entry);
|
|
db_set_int_val(values, HASH_ID_COL_IDX - 1, ro_session->h_id);
|
|
db_set_str_val(values, SESSION_ID_COL_IDX - 1, &ro_session->ro_session_id);
|
|
db_set_int_val(values, DLG_HASH_ENTRY_COL_IDX - 1, ro_session->dlg_h_entry);
|
|
db_set_int_val(values, DLG_HASH_ID_COL_IDX - 1, ro_session->dlg_h_id);
|
|
db_set_int_val(values, DIRECTION_COL_IDX - 1, ro_session->direction);
|
|
db_set_str_val(values, ASSERTED_ID_COL_IDX - 1, &ro_session->asserted_identity);
|
|
db_set_str_val(values, CALLEE_COL_IDX - 1, &ro_session->called_asserted_identity);
|
|
db_set_datetime_val(values, START_TIME_COL_IDX - 1, ro_session->start_time/1000000);
|
|
db_set_datetime_val(values, LAST_EVENT_TS_COL_IDX - 1, ro_session->last_event_timestamp/1000000);
|
|
db_set_int_val(values, RESERVED_SECS_COL_IDX - 1, ro_session->reserved_secs);
|
|
db_set_int_val(values, VALID_FOR_COL_IDX - 1, ro_session->valid_for);
|
|
db_set_int_val(values, STATE_COL_IDX - 1, ro_session->active);
|
|
db_set_str_val(values, INCOMING_TRUNK_ID_COL_IDX - 1, &ro_session->incoming_trunk_id);
|
|
db_set_str_val(values, OUTGOING_TRUNK_ID_COL_IDX - 1, &ro_session->outgoing_trunk_id);
|
|
db_set_int_val(values, RATING_GROUP_COL_IDX - 1, ro_session->rating_group);
|
|
db_set_int_val(values, SERVICE_IDENTIFIER_COL_IDX - 1, ro_session->service_identifier);
|
|
|
|
LM_DBG("Updating ro_session in database\n");
|
|
if ((ro_dbf.update(ro_db_handle, update_keys/*match*/, 0/*match*/, values/*match*/, update_keys/*update*/, values/*update*/, 3/*match*/, 13/*update*/)) != 0) {
|
|
LM_ERR("could not update Ro session information in DB... continuing\n");
|
|
goto error;
|
|
}
|
|
ro_session->flags &= ~RO_SESSION_FLAG_CHANGED;
|
|
} else if ((ro_session->flags & RO_SESSION_FLAG_DELETED) != 0) {
|
|
db_val_t values[3];
|
|
db_key_t match_keys[3] = {&h_entry_column, &h_id_column, &session_id_column};
|
|
|
|
db_set_int_val(values, HASH_ENTRY_COL_IDX - 1, ro_session->h_entry);
|
|
db_set_int_val(values, HASH_ID_COL_IDX - 1, ro_session->h_id);
|
|
db_set_str_val(values, SESSION_ID_COL_IDX - 1, &ro_session->ro_session_id);
|
|
|
|
if(ro_dbf.delete(ro_db_handle, match_keys, 0, values, 3) < 0) {
|
|
LM_ERR("failed to delete ro session database information... continuing\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
LM_WARN("Asked to update Ro session in strange state [%d]\n", ro_session->flags);
|
|
}
|
|
|
|
return 0;
|
|
|
|
error:
|
|
return -1;
|
|
}
|
|
|
|
int update_ro_dbinfo(struct ro_session* ro_session) {
|
|
struct ro_session_entry entry;
|
|
/* lock the entry */
|
|
entry = (ro_session_table->entries)[ro_session->h_entry];
|
|
ro_session_lock(ro_session_table, &entry);
|
|
if (update_ro_dbinfo_unsafe(ro_session) != 0) {
|
|
LM_ERR("failed to update ro_session in DB\n");
|
|
ro_session_unlock(ro_session_table, &entry);
|
|
return -1;
|
|
}
|
|
ro_session_unlock(ro_session_table, &entry);
|
|
return 0;
|
|
}
|