static int load_sca_info_from_db(void) { db_res_t * res = NULL; db_val_t * values; db_row_t * rows; int i, j, nr_rows; unsigned int valid_record; unsigned int n_result_cols = 0; unsigned int shared_line_col, watchers_col; unsigned int app_shared_entity_col[MAX_APPEARANCE_INDEX]; unsigned int app_call_state_col[MAX_APPEARANCE_INDEX]; unsigned int app_call_info_uri_col[MAX_APPEARANCE_INDEX]; unsigned int app_call_info_appearance_uri_col[MAX_APPEARANCE_INDEX]; unsigned int app_b2bl_key_col[MAX_APPEARANCE_INDEX]; db_key_t q_cols[SCA_TABLE_TOTAL_COL_NO]; str shared_line, watchers_csv; //str_lst_t *watchers; //unsigned int size, watcher_size, watchers_no; //unsigned int size; unsigned int hash_index; //char *p; b2b_sca_record_t *record; b2b_sca_call_t *call; unsigned int shared_entity, appearance_index, call_state; str call_info_uri, call_info_apperance_uri, b2bl_key; b2bl_cb_ctx_t *cb_params; if(use_sca_table()) return -1; q_cols[shared_line_col = n_result_cols++] = &shared_line_column; q_cols[watchers_col = n_result_cols++] = &watchers_column; for (i=0; i<MAX_APPEARANCE_INDEX; i++) { q_cols[app_shared_entity_col[i] = n_result_cols++] = &app_shared_entity_column[i]; q_cols[app_call_state_col[i] = n_result_cols++] = &app_call_state_column[i]; q_cols[app_call_info_uri_col[i] = n_result_cols++] = &app_call_info_uri_column[i]; q_cols[app_call_info_appearance_uri_col[i] = n_result_cols++] = &app_call_info_appearance_uri_column[i]; q_cols[app_b2bl_key_col[i] = n_result_cols++] = &app_b2bl_key_column[i]; } /* select the whole tabel and all the columns */ if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) { if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0, SCA_TABLE_TOTAL_COL_NO, 0, 0) < 0) { LM_ERR("Error while querying (fetch) database\n"); return -1; } if(sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0){ LM_ERR("fetching rows failed\n"); return -1; } } else { if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0, SCA_TABLE_TOTAL_COL_NO, 0, &res) < 0) { LM_ERR("Error while querying database\n"); return -1; } } nr_rows = RES_ROW_N(res); do { LM_DBG("loading [%i] records from db\n", nr_rows); rows = RES_ROWS(res); /* for every row/record */ for(i=0; i<nr_rows; i++){ values = ROW_VALUES(rows + i); if (VAL_NULL(values+shared_line_col) || VAL_NULL(values+watchers_col)) { LM_ERR("columns [%.*s] or/and [%.*s] cannot be null -> skipping\n", shared_line_column.len, shared_line_column.s, watchers_column.len, watchers_column.s); continue; } shared_line.s = (char*)values[shared_line_col].val.string_val; shared_line.len = strlen(shared_line.s); watchers_csv.s = (char*)values[watchers_col].val.string_val; watchers_csv.len = strlen(watchers_csv.s); record = restore_record(&shared_line, &watchers_csv); if (record == NULL) goto error; hash_index = core_hash(&shared_line, NULL, b2b_sca_hsize); j = 0; while (j < MAX_APPEARANCE_INDEX) { if( VAL_NULL(values + app_shared_entity_col[j]) || VAL_NULL(values + app_call_state_col[j]) || VAL_NULL(values + app_call_info_uri_col[j]) || VAL_NULL(values + app_call_info_appearance_uri_col[j]) || VAL_NULL(values + app_b2bl_key_col[j]) ) { goto cont; } appearance_index = j + 1; /* 1 - get shared_entity */ shared_entity = values[app_shared_entity_col[j]].val.int_val; if (shared_entity!=0 && shared_entity!=1) { LM_ERR("Unexpected shared_entity [%d] " "for shared_line [%.*s]\n", shared_entity, shared_line.len, shared_line.s); goto cont; } /* 2 - get call_state */ call_state = values[app_call_state_col[j]].val.int_val; if (call_state == IDLE_STATE) { LM_DBG("empty call[%d]\n", appearance_index); goto cont; } if (call_state > MAX_INDEX_STATE) { LM_ERR("Unexpected call_state [%d] for shared_line [%.*s]\n", call_state, shared_line.len, shared_line.s); goto cont; } /* 3 - get call_info_uri */ call_info_uri.s = (char*)values[app_call_info_uri_col[j]].val.string_val; if (call_info_uri.s) call_info_uri.len = strlen(call_info_uri.s); else { LM_ERR("Missing call_info_uri for shared_line [%.*s][%d]\n", shared_line.len, shared_line.s, appearance_index); goto cont; } LM_DBG("call_info_uri=[%.*s]\n", call_info_uri.len, call_info_uri.s); /* 4 - get call_info_apperance_uri */ call_info_apperance_uri.s = (char*) values[app_call_info_appearance_uri_col[j]].val.string_val; if (call_info_apperance_uri.s) call_info_apperance_uri.len = strlen(call_info_apperance_uri.s); else { LM_ERR("Missing call_info_apperance_uri for " "shared_line [%.*s][%d]\n", shared_line.len, shared_line.s, appearance_index); goto cont; } LM_DBG("call_info_apperance_uri=[%.*s]\n", call_info_apperance_uri.len, call_info_apperance_uri.s); /* 5 - get b2bl_key */ b2bl_key.s = (char*)values[app_b2bl_key_col[j]].val.string_val; if (b2bl_key.s) { b2bl_key.len = strlen(b2bl_key.s); if (b2bl_key.len > B2BL_MAX_KEY_LEN) { LM_ERR("buffer overflow on b2bl_key [%.*s]" " for shared_line [%.*s][%d]\n", b2bl_key.len, b2bl_key.s, shared_line.len, shared_line.s, appearance_index); goto cont; } LM_DBG("b2bl_key=[%.*s]\n", b2bl_key.len, b2bl_key.s); } else { LM_ERR("Missing b2bl_key for shared_line [%.*s][1]\n", shared_line.len, shared_line.s); goto cont; } /* restore the call */ call = restore_call(record, appearance_index, shared_entity, call_state, &call_info_uri, &call_info_apperance_uri); if (call == NULL) { goto error; } /* update record */ if (0!=b2b_sca_update_call_record_key(call, &b2bl_key)) { LM_ERR("Unable to update b2bl_key [%.*s]\n", b2bl_key.len, b2bl_key.s); shm_free(call); call = NULL; record->call[appearance_index-1] = NULL; goto cont; } /* Prepare b2b_logic callback params. */ cb_params = build_cb_params(hash_index, &shared_line, appearance_index); if (cb_params == NULL) { LM_ERR("Unable to build cb_params\n"); goto error; } /* re-register callbacks */ if(b2bl_api.register_cb(&b2bl_key, &sca_logic_notify, cb_params, B2B_RE_INVITE_CB|B2B_CONFIRMED_CB|B2B_DESTROY_CB) != 0){ LM_ERR("Unable register b2b cb\n"); shm_free(call); call = NULL; record->call[appearance_index-1] = NULL; goto cont; } cont: j++; } valid_record = j = 0; while (j < MAX_APPEARANCE_INDEX) { if (record->call[j]) { valid_record = 1; goto check_valid_record; } j++; } check_valid_record: if (valid_record) { b2b_sca_print_record(record); insert_record(hash_index, record); } else { LM_DBG("removing the record from db!\n"); delete_sca_info_from_db(record); } LM_DBG("Done\n"); } /* any more data to be fetched ?*/ if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) { if (sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0) { LM_ERR("fetching more rows failed\n"); goto error; } nr_rows = RES_ROW_N(res); } else { nr_rows = 0; } }while (nr_rows>0); sca_dbf.free_result(sca_db_handle, res); return 0; error: sca_dbf.free_result(sca_db_handle, res); return -1; }
int b2b_sca_add_call_record(int hash_index, str *shared_line, unsigned int shared_entity, unsigned int app_index, str *call_info_uri, str *call_info_apperance_uri, b2b_sca_record_t **record_ctx, b2b_sca_call_t **call_ctx) { //b2b_sca_record_t *rec, *prev_rec; b2b_sca_record_t *record; b2b_sca_call_t *call; unsigned int i, size, watcher_size, watchers_no; char *p; str_lst_t *watchers; if (app_index>=MAX_APPEARANCE_INDEX) { LM_ERR("Required app_index [%d] too big\n", app_index); return -1; } record = b2b_sca_search_record_safe(hash_index, shared_line); if (record) { /* We already have active calls for this shared line */ if (app_index) { i = app_index - 1; if (record->call[i]) { LM_DBG("Searching for a new slot\n"); for (i=0; i<MAX_APPEARANCE_INDEX; i++) { if (record->call[i] == NULL) break; } } } else { LM_DBG("no forced app_index\n"); for (i=0; i<MAX_APPEARANCE_INDEX; i++) { if (record->call[i] == NULL) break; } } if (i == MAX_APPEARANCE_INDEX) { LM_ERR("No available slots for this call\n"); return -1; } call = restore_call(record, i+1, shared_entity, ALERTING_STATE, call_info_uri, call_info_apperance_uri); if (call == NULL) { return -1; } } else { /* First call for this shared line */ /* Get the list of watchers */ get_watchers_from_avp(&watchers, &watcher_size, &watchers_no); size = sizeof(b2b_sca_record_t) + shared_line->len + watcher_size; record = (b2b_sca_record_t *)shm_malloc(size); if (record == NULL) { LM_ERR("OOM\n"); return -1; } memset(record, 0, size); p = (char*)(record + 1); record->watchers_no = watchers_no; record->shared_line.len = shared_line->len; record->shared_line.s = p; memcpy(p, shared_line->s, shared_line->len); p += shared_line->len; if (watchers && watcher_size) { record->watchers = (str_lst_t *)p; memcpy_watchers(record->watchers, watchers, watcher_size); if (watchers) free_watchers(watchers); } else { record->watchers = NULL; LM_WARN("We have no watchers: watchers=[%p] and watcher_size=[%d]\n", watchers, watcher_size); } /* Let's take care of the call now */ call = restore_call(record, app_index?app_index:1, shared_entity, ALERTING_STATE, call_info_uri, call_info_apperance_uri); if (call == NULL) goto error; /* Insert record into the table */ insert_record(hash_index, record); /* rec = b2b_sca_htable[hash_index].first; if (rec) { while(rec) { prev_rec = rec; rec = rec->next; } prev_rec->next = record; record->prev = prev_rec; } else { b2b_sca_htable[hash_index].first = record; record->prev = record->next = NULL; } */ } *record_ctx = record; *call_ctx = call; return 0; error: shm_free(record); return -1; }