int read_transposition() { extern unsigned char transposition[]; unsigned char input; int i = 0; printf("This part of the program requires user input\n"); printf("Please, input below via your keyboard %d natural numbers without repetition\n", MATRIX_LENGTH); printf("Each number will be acquired by a single string of numbers without spaces, finishing with ENTER key\n"); printf("Enter numbers: "); for( i = 0; i < MATRIX_LENGTH; i++) { input = getchar(); if(convert_to_number(input) == ERROR) return ERROR; transposition[i] = (unsigned char)convert_to_number(input); } return 0; }
vm_value vm_execute(vm_instruction *program, int program_length, vm_value *ctable, int ctable_length) { ++invocation; vm_state state0; vm_state *state = &state0; reset(state); state->const_table = ctable; state->const_table_length = ctable_length; bool is_running = true; restart: while(is_running && state->program_pointer < program_length) { is_running = true; vm_value instr = program[state->program_pointer]; vm_opcode opcode = get_opcode(instr); ++state->program_pointer; switch (opcode) { case OP_LOAD_i: { int reg0 = get_arg_r0(instr); int val = get_arg_i(instr); check_reg(reg0); get_reg(reg0) = val; } break; case OP_LOAD_ps: { int reg0 = get_arg_r0(instr); int value = get_arg_i(instr); check_reg(reg0); get_reg(reg0) = make_tagged_val(value, vm_tag_plain_symbol); } break; case OP_LOAD_cs: { int reg0 = get_arg_r0(instr); int value = get_arg_i(instr); check_reg(reg0); get_reg(reg0) = make_tagged_val(value, vm_tag_compound_symbol); } break; case OP_LOAD_os: { int reg0 = get_arg_r0(instr); int value = get_arg_i(instr); check_reg(reg0); get_reg(reg0) = make_tagged_val(value, vm_tag_opaque_symbol); } break; case OP_LOAD_f: { int reg0 = get_arg_r0(instr); int value = get_arg_i(instr); check_reg(reg0); get_reg(reg0) = make_tagged_val(value, vm_tag_function); } break; case OP_LOAD_str: { int reg0 = get_arg_r0(instr); int value = get_arg_i(instr); check_reg(reg0); get_reg(reg0) = make_tagged_val(value, vm_tag_string); } break; case OP_ADD: { int reg1 = get_arg_r1(instr); int reg2 = get_arg_r2(instr); check_reg(reg1); int arg1 = get_reg(reg1); check_reg(reg2); int arg2 = get_reg(reg2); int reg0 = get_arg_r0(instr); if(get_tag(arg1) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(arg1)); } else if(get_tag(arg2) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(arg2)); } check_reg(reg0); int result = ((arg1 - int_bias) + (arg2 - int_bias)) + int_bias; if(result < min_biased_int || result > max_biased_int) { fail("Int overflow"); } get_reg(reg0) = result; } break; case OP_SUB: { int reg1 = get_arg_r1(instr); int reg2 = get_arg_r2(instr); check_reg(reg1); int arg1 = get_reg(reg1); check_reg(reg2); int arg2 = get_reg(reg2); int reg0 = get_arg_r0(instr); if(get_tag(arg1) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(arg1)); } if(get_tag(arg2) != vm_tag_number) { fail("Expected a number, but got %s ", value_to_type_string(arg2)); } check_reg(reg0); int result = ((arg1 - int_bias) - (arg2 - int_bias)) + int_bias; if(result < min_biased_int || result > max_biased_int) { fail("Int overflow"); } get_reg(reg0) = result; } break; case OP_MUL: { int reg1 = get_arg_r1(instr); int reg2 = get_arg_r2(instr); check_reg(reg1); int arg1 = get_reg(reg1); check_reg(reg2); int arg2 = get_reg(reg2); int reg0 = get_arg_r0(instr); if(get_tag(arg1) != vm_tag_number) { fail("Expected a number, but got %s ", value_to_type_string(arg1) ); } if(get_tag(arg2) != vm_tag_number) { fail("Expected a number, but got %s ", value_to_type_string(arg2) ); } check_reg(reg0); int result = ((arg1 - int_bias) * (arg2 - int_bias)) + int_bias; if(result < min_biased_int || result > max_biased_int) { panic_stop_vm_m("Int overflow"); } get_reg(reg0) = result; } break; case OP_DIV: { int reg1 = get_arg_r1(instr); int reg2 = get_arg_r2(instr); check_reg(reg1); int arg1 = get_reg(reg1); check_reg(reg2); int arg2 = get_reg(reg2); if(arg2 == 0) { fail("Division by 0"); } if(get_tag(arg1) != vm_tag_number) { fail("Expected a number, but got %s ", value_to_type_string(arg1) ); } if(get_tag(arg2) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(arg2) ); } int reg0 = get_arg_r0(instr); check_reg(reg0); int result = ((arg1 - int_bias) / (arg2 - int_bias)) + int_bias; if(result < min_biased_int || result > max_biased_int) { fail("Int overflow"); } get_reg(reg0) = result; } break; case OP_MOVE: { int reg0 = get_arg_r0(instr); int reg1 = get_arg_r1(instr); check_reg(reg0); check_reg(reg1); get_reg(reg0) = get_reg(reg1); } break; case OP_AP: { if (state->stack_pointer + 1 == stack_size) { fail("(call)!"); } // this macro will create `return_pointer` do_call((&next_frame), get_arg_r1(instr), instr); if (call_failed) { fail("call failed"); //TODO give a better error description } next_frame.return_address = return_pointer; next_frame.result_register = get_arg_r0(instr); ++state->stack_pointer; } break; case OP_TAIL_AP: { do_call((¤t_frame), get_arg_r1(instr), instr); if (call_failed) { fail("call failed"); //TODO give a better error description } } break; case OP_GEN_AP: { if (state->stack_pointer + 1 == stack_size) { printf("Stack overflow (call cl)!"); panic_stop_vm(); } int return_pointer = do_gen_ap(state, (&next_frame), instr, program); if (return_pointer != -1) { next_frame.return_address = return_pointer; next_frame.result_register = get_arg_r0(instr); ++state->stack_pointer; } } break; // TODO It's not entirely clear yet what happens when this returns a new PAP case OP_TAIL_GEN_AP: { do_gen_ap(state, ¤t_frame, instr, program); } break; op_ret: case OP_RET: { int return_val_reg = get_arg_r0(instr); if (state->stack_pointer == 0) { //We simply copy the result value to register 0, so that the runtime can find it current_frame.reg[0] = current_frame.reg[return_val_reg]; is_running = false; break; } --state->stack_pointer; current_frame.reg[next_frame.result_register] = next_frame.reg[return_val_reg]; state->program_pointer = next_frame.return_address; } break; case OP_JMP: { int offset = get_arg_i(instr) - int_bias; state->program_pointer += offset; if(state->program_pointer < 0 || state->program_pointer > program_length) { panic_stop_vm_m("Illegal address!"); } } break; case OP_JMP_TRUE: { check_reg(get_arg_r0(instr)); vm_value bool_value = get_reg(get_arg_r0(instr)); if( is_equal(state, bool_value, make_tagged_val(symbol_id_true, vm_tag_plain_symbol) )) { int offset = get_arg_i(instr) - int_bias; state->program_pointer += offset; if(state->program_pointer < 0 || state->program_pointer > program_length) { panic_stop_vm_m("Illegal address: %i", state->program_pointer); } } // else: do nothing } break; case OP_MATCH: { check_reg(get_arg_r0(instr)); int subject = get_reg(get_arg_r0(instr)); check_reg(get_arg_r1(instr)); int patterns_addr = get_reg(get_arg_r1(instr)); int capture_reg = get_arg_r2(instr); check_reg(capture_reg); check_ctable_index(patterns_addr) vm_value match_header = state->const_table[patterns_addr]; int number_of_patterns = from_match_value(match_header); int i = 0; for(i=0; i<number_of_patterns; ++i) { int rel_pat_addr = patterns_addr + 1 + i; check_ctable_index(rel_pat_addr) vm_value pat = state->const_table[rel_pat_addr]; if(does_value_match(state, pat, subject, capture_reg)) { break; } else { continue; } } if(i == number_of_patterns) { throw("Pattern match failed!"); } state->program_pointer += i; } break; case OP_SET_ARG: { int target_arg = get_arg_r0(instr); int source_reg = get_arg_r1(instr); int extra_amount = get_arg_r2(instr); memcpy(&next_frame.reg[target_arg], ¤t_frame.reg[source_reg], (1 + extra_amount) * sizeof(vm_value)); } break; case OP_SET_CL_VAL: { int cl_reg = get_arg_r0(instr); check_reg(cl_reg); vm_value closure = get_reg(cl_reg); if( get_tag(closure) != vm_tag_pap ) { fail("Expected a closure, but got %s", value_to_type_string(closure)); } heap_address cl_address = get_val(closure); check_reg(get_arg_r1(instr)); vm_value new_value = get_reg(get_arg_r1(instr)); int arg_index = get_arg_r2(instr); vm_value *cl_pointer = heap_get_pointer(cl_address); int header = *cl_pointer; int num_env_args = pap_var_count(header); if(arg_index >= num_env_args) { panic_stop_vm_m("Illegal closure modification (index: %i, num env vars: %i)", arg_index, num_env_args); } cl_pointer[pap_header_size + arg_index] = new_value; } break; case OP_PART_AP: { int reg0 = get_arg_r0(instr); int fun_reg = get_arg_r1(instr); check_reg(fun_reg); int func = get_reg(fun_reg); if( get_tag(func) != vm_tag_function ) { fail("Expected a function, but got %s", value_to_type_string(func)); } int fun_address = get_val(func); int num_args = get_arg_r2(instr); vm_value fun_header = program[fun_address]; //TODO check that it's actually a function int arity = get_arg_i(fun_header); // TODO this was >= earlier, which apparently gave false positives. Find out why, and find out if > is the correct choice if(num_args > arity) { panic_stop_vm_m("Illegal partial application (num args: %i, arity: %i)", num_args, arity); } int pap_arity = arity - num_args; build_pap(num_args, pap_arity, 0, num_args, fun_address); check_reg(reg0); get_reg(reg0) = pap_value; } break; case OP_EQ: { check_reg(get_arg_r1(instr)); check_reg(get_arg_r2(instr)); vm_value l = get_reg(get_arg_r1(instr)); vm_value r = get_reg(get_arg_r2(instr)); int result_reg = get_arg_r0(instr); check_reg(result_reg); if( is_equal(state, l, r)) { get_reg(result_reg) = make_tagged_val(symbol_id_true, vm_tag_plain_symbol); } else { get_reg(result_reg) = make_tagged_val(symbol_id_false, vm_tag_plain_symbol); } } break; case OP_LT: { check_reg(get_arg_r1(instr)); check_reg(get_arg_r2(instr)); vm_value l = get_reg(get_arg_r1(instr)); vm_value r = get_reg(get_arg_r2(instr)); int result_reg = get_arg_r0(instr); check_reg(result_reg); if(get_tag(l) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(l)); } else if(get_tag(r) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(r)); } if( l < r) { get_reg(result_reg) = make_tagged_val(symbol_id_true, vm_tag_plain_symbol); } else { get_reg(result_reg) = make_tagged_val(symbol_id_false, vm_tag_plain_symbol); } } break; case OP_GT: { check_reg(get_arg_r1(instr)); check_reg(get_arg_r2(instr)); vm_value l = get_reg(get_arg_r1(instr)); vm_value r = get_reg(get_arg_r2(instr)); int result_reg = get_arg_r0(instr); check_reg(result_reg); if(get_tag(l) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(l)); } else if(get_tag(r) != vm_tag_number) { fail("Expected a number, but got %s", value_to_type_string(r)); } if( l > r) { get_reg(result_reg) = make_tagged_val(symbol_id_true, vm_tag_plain_symbol); } else { get_reg(result_reg) = make_tagged_val(symbol_id_false, vm_tag_plain_symbol); } } break; case OP_COPY_SYM: { check_reg(get_arg_r0(instr)); check_reg(get_arg_r1(instr)); vm_value const_symbol = get_reg(get_arg_r1(instr)); if ( get_tag(const_symbol) != vm_tag_compound_symbol ) { panic_stop_vm_m("Expected a const symbol, but got %s", value_to_type_string(const_symbol)); } int c_addr = get_val(const_symbol); vm_value c_sym_header = state->const_table[c_addr]; int count = compound_symbol_count(c_sym_header); size_t total_size = compound_symbol_header_size + count; heap_address dyn_sym_address = heap_alloc(total_size); vm_value *sym_pointer = heap_get_pointer(dyn_sym_address); \ memcpy(sym_pointer, &(state->const_table[c_addr]), total_size * sizeof(vm_value)); get_reg(get_arg_r0(instr)) = make_tagged_val(dyn_sym_address, vm_tag_dynamic_compound_symbol); } break; case OP_SET_SYM_FIELD: { check_reg(get_arg_r0(instr)); check_reg(get_arg_r1(instr)); vm_value heap_symbol = get_reg(get_arg_r0(instr)); if ( get_tag(heap_symbol) != vm_tag_dynamic_compound_symbol ) { panic_stop_vm_m("Expected a dynamic symbol, but got %s", value_to_type_string(heap_symbol)); } int h_addr = get_val(heap_symbol); vm_value *p = heap_get_pointer(h_addr); vm_value h_sym_header = *p; int count = compound_symbol_count(h_sym_header); int index = get_arg_r2(instr); if(index < 0 || index >= count) { panic_stop_vm_m("Illegal index while setting symbol field: %d", index); } p[compound_symbol_header_size + index] = get_reg(get_arg_r1(instr)); } break; case OP_STR_LEN: { check_reg(get_arg_r0(instr)); check_reg(get_arg_r1(instr)); vm_value str = get_reg(get_arg_r1(instr)); int tag = get_tag(str); if (tag != vm_tag_string && tag != vm_tag_dynamic_string ) { fail("Expected a string, but got %s", value_to_type_string(str)); } int str_addr = get_val(str); vm_value *str_pointer; if(tag == vm_tag_string) { str_pointer = state->const_table + str_addr; } else { str_pointer = heap_get_pointer(str_addr); } vm_value str_header = *str_pointer; int count = string_length(str_header); get_reg(get_arg_r0(instr)) = make_tagged_val(count + int_bias, vm_tag_number); } break; case OP_NEW_STR: { int result_reg = get_arg_r0(instr); check_reg(result_reg); check_reg(get_arg_r1(instr)); vm_value length_value = get_reg(get_arg_r1(instr)); if(get_tag(length_value) != vm_tag_number) { panic_stop_vm_m("Expected a number, but got %s", value_to_type_string(length_value)); } int length = length_value - int_bias; if(length < 0) { panic_stop_vm_m("Negative length for new string, got: %d", length); } int adjusted_length = length + 1; // allow space for trailing '\0' int num_chunks = adjusted_length / char_per_string_chunk; if( (adjusted_length % char_per_string_chunk) != 0 ) { num_chunks += char_per_string_chunk - (adjusted_length % char_per_string_chunk); } size_t total_size = string_header_size + num_chunks; heap_address string_address = heap_alloc(total_size); vm_value *str_pointer = heap_get_pointer(string_address); memset(str_pointer, 0, total_size * sizeof(vm_value)); *str_pointer = string_header(length, num_chunks); get_reg(result_reg) = make_tagged_val(string_address, vm_tag_dynamic_string); } break; case OP_GET_CHAR: { int result_reg = get_arg_r0(instr); check_reg(result_reg); check_reg(get_arg_r1(instr)); check_reg(get_arg_r2(instr)); vm_value str = get_reg(get_arg_r1(instr)); vm_value str_tag = get_tag(str); if(str_tag != vm_tag_string && str_tag != vm_tag_dynamic_string) { panic_stop_vm_m("Expected a string, but got %s", value_to_type_string(str)); } int str_addr = get_val(str); vm_value *str_pointer; if(str_tag == vm_tag_string) { str_pointer = state->const_table + str_addr; } else { str_pointer = heap_get_pointer(str_addr); } vm_value str_header = *str_pointer; int index = get_reg(get_arg_r2(instr)) - int_bias; int str_length = string_length(str_header); if(index < 0 || index > str_length) { panic_stop_vm_m("Illegal string index: %d", index); } char *char_pointer = (char *) (str_pointer + string_header_size); int character = char_pointer[index]; get_reg(result_reg) = make_tagged_val(character, vm_tag_number); } break; case OP_PUT_CHAR: { check_reg(get_arg_r0(instr)); check_reg(get_arg_r1(instr)); check_reg(get_arg_r2(instr)); vm_value str = get_reg(get_arg_r1(instr)); vm_value str_tag = get_tag(str); if(str_tag != vm_tag_dynamic_string) { panic_stop_vm_m("Expected a dynamic string, but got %s", value_to_type_string(str)); } int character = get_reg(get_arg_r0(instr)); if(get_tag(character) != vm_tag_number) { panic_stop_vm_m("Expected a number, but got %s", value_to_type_string(character)); } int str_addr = get_val(str); vm_value *str_pointer = heap_get_pointer(str_addr); vm_value str_header = *str_pointer; int index = get_reg(get_arg_r2(instr)) - int_bias; int str_length = string_length(str_header); if(index < 0 || index > str_length) { panic_stop_vm_m("Illegal string index: %d", index); } char *char_pointer = (char *) (str_pointer + string_header_size); char_pointer[index] = (char) character; } break; case OP_OR: { int reg1 = get_arg_r1(instr); int reg2 = get_arg_r2(instr); check_reg(reg1); int arg1 = get_reg(reg1); check_reg(reg2); int arg2 = get_reg(reg2); int reg0 = get_arg_r0(instr); check_reg(reg0); vm_value result = make_tagged_val(symbol_id_false, vm_tag_plain_symbol); vm_value true_sym = make_tagged_val(symbol_id_true, vm_tag_plain_symbol); if(arg1 == true_sym || arg2 == true_sym) { result = true_sym; } get_reg(reg0) = result; } break; case OP_AND: { int reg1 = get_arg_r1(instr); int reg2 = get_arg_r2(instr); check_reg(reg1); int arg1 = get_reg(reg1); check_reg(reg2); int arg2 = get_reg(reg2); int reg0 = get_arg_r0(instr); check_reg(reg0); vm_value result = make_tagged_val(symbol_id_false, vm_tag_plain_symbol); vm_value true_sym = make_tagged_val(symbol_id_true, vm_tag_plain_symbol); if(arg1 == true_sym && arg2 == true_sym) { result = true_sym; } get_reg(reg0) = result; } break; case OP_NOT: { int reg1 = get_arg_r1(instr); check_reg(reg1); int arg1 = get_reg(reg1); int reg0 = get_arg_r0(instr); check_reg(reg0); vm_value result = make_tagged_val(symbol_id_false, vm_tag_plain_symbol); vm_value true_sym = make_tagged_val(symbol_id_true, vm_tag_plain_symbol); if(arg1 != true_sym) { result = true_sym; } //else: result is already set to false get_reg(reg0) = result; } break; case OP_GET_FIELD: { int result_reg = get_arg_r0(instr); int obj_reg = get_arg_r1(instr); int sym_reg = get_arg_r2(instr); check_reg(result_reg); check_reg(obj_reg); check_reg(sym_reg); vm_value obj_ref = get_reg(obj_reg); vm_value requested_name = get_reg(sym_reg); if(get_tag(requested_name) != vm_tag_plain_symbol) { panic_stop_vm_m("Malformed lookup!"); } vm_value obj_header = 0; vm_value *obj_fields = 0; if(get_tag(obj_ref) == vm_tag_opaque_symbol) { int obj_addr = get_val(obj_ref); vm_value *obj_pointer = state->const_table + obj_addr; vm_value obj_owner = obj_pointer[1]; if(obj_owner != make_tagged_val(0, vm_tag_plain_symbol)) { panic_stop_vm_m("Malformed module!"); } obj_header = obj_pointer[0]; obj_fields = obj_pointer + 2; } // TODO this branch is untested, as records are apparently always dynamic in this case (?!) else if(get_tag(obj_ref) == vm_tag_compound_symbol) { int obj_addr = get_val(obj_ref); vm_value *obj_pointer = state->const_table + obj_addr; obj_header = obj_pointer[0]; if(compound_symbol_id(obj_header) != symbol_id_record) { fail("Expected a module or record, got %s", value_to_type_string(obj_ref)); } obj_fields = obj_pointer + 1; } else if(get_tag(obj_ref) == vm_tag_dynamic_compound_symbol) { int obj_addr = get_val(obj_ref); vm_value *obj_pointer = heap_get_pointer(obj_addr); //vm_value *obj_pointer = state->const_table + obj_addr; obj_header = obj_pointer[0]; obj_fields = obj_pointer + 1; if(compound_symbol_id(obj_header) != symbol_id_record) { fail("Expected a module or record, got %s", value_to_type_string(obj_ref)); } } else { // exits subroutine here fail("Expected a module or record, got %s", value_to_type_string(obj_ref)); } int num_symbol_fields = compound_symbol_count(obj_header); bool found = false; for(int i=0; i < num_symbol_fields; i += 2) { vm_value name = obj_fields[i]; if(name == requested_name) { get_reg(result_reg) = obj_fields[i+1]; found = true; break; } } if(found == false) { //TODO change this to built-in nil type get_reg(result_reg) = make_tagged_val(symbol_id_nil, vm_tag_plain_symbol); } } break; case OP_CONVERT: { int result_reg = get_arg_r0(instr); int source_reg = get_arg_r1(instr); int type_reg = get_arg_r2(instr); check_reg(result_reg); check_reg(source_reg); check_reg(type_reg); vm_value source = get_reg(source_reg); vm_value target_type = get_reg(type_reg); if(get_tag(target_type) != vm_tag_plain_symbol) { fail("Expected a symbol, got %s", value_to_type_string(target_type)); } vm_value target_type_id = get_val(target_type); vm_value result; switch(target_type_id) { case symbol_id_number: result = convert_to_number(state, source); break; case symbol_id_string: result = convert_to_string(state, source); break; default: result = make_str_error("Unable to convert value"); } get_reg(result_reg) = result; } break; default: panic_stop_vm_m("UNKNOWN OPCODE: %04x", opcode); } } vm_value result = state->stack[state->stack_pointer].reg[0]; vm_value io_result_value = 0; vm_value next_action; io_action_result action_result = check_io_action(state, result, program, &io_result_value, &next_action); switch(action_result) { case no_io_action: // do nothing break; case intermediary_io_action: { state->stack_pointer = 0; current_frame.reg[0] = next_action; next_frame.reg[0] = io_result_value; // argument for next_action vm_instruction instr = op_gen_ap(0, 0, 1); int return_pointer = do_gen_ap(state, ¤t_frame, instr, program); if (return_pointer != -1) { current_frame.return_address = return_pointer; current_frame.result_register = 0; } else { // TODO is this malformed? panic_stop_vm_m("malformed bound lambda in io action"); } is_running = true; } goto restart; case final_io_action: result = io_result_value; break; default: panic_stop_vm_m("Unknown result of io action: %d", action_result); } return result; }
/************************************************************************ ** Function: ProcessUsgDetail ** ** Purpose: Read a detail usage record from usage file. ** ** returns: SUCCESS - no errors, or "soft" (minor) error. SUCCESS ** means that the record will be saved in either ** CDR_DATA or CDR_DATA_WORK. ** FAILURE - serious parsing error. return FAILURE implies ** "hard" error. Such records will be written to ** the bad image file. ** Note that records with hard errors will be ** written to bad image file as is. This means ** error codes are NOT saved. This is why we ** return immediately for FAILURE case. ** ** General idea is that missing data will be considered a "soft" error ** where as non-numeric data in a numeric field will be considered a ** hard error. ************************************************************************* */ int ProcessUsgDetail(CDR_DATA_STRUCT *cdr_data, RECORD_TYPE_STRUCT *rec_type, int minimize, int *checksum1, int *checksum2, int *checksum3) { char *ptr; char tmpstr[1024]; char gstrScratch1[1024]; int pos; /* floating pointer into cdr_data->usg_rec */ /* for time field, we need to convert to the usage time zone if ** it is provided. But sometime we do not have timezone in usage ** file, in this case we will convert to default timezone? ** To convert time, we need to wait after the whole usage record ** has been processed, then do conversion if necessary */ short trans_dt_type = -1; /* -1 means not supplied in usg file,no op */ short second_dt_type = -1;/* -1 means not supplied in usg file,no op */ short rate_dt_type = -1; /* -1 means not supplied in usg file,no op */ short new_timezone = FALSE; /* to indicate whether there is a timezone ** in the usage record */ char usage_tz[szUnixTZ+1+3]; char unix_tz[szUnixTZ+1]; short size; /* size of input field */ tiny isdst; /* ignored */ int i; int j; pos = 0; ptr = gstrScratch1; if(mpsIsLogLevelHigh()) { sprintf(tmpstr, "\nProcessing Record Type \'%s\'", rec_type->record_type); emit(ERRLOC,MPS_GENERIC_INFORM,tmpstr); sprintf(tmpstr, "==================================="); emit(ERRLOC,MPS_GENERIC_INFORM,tmpstr); sprintf(tmpstr, "%-20.20s %-20.20s %-12.12s %-5.5s %-15.12s", "Field Name From", "Field Name To","Field Type", "Size","Field Value"); emit(ERRLOC,MPS_GENERIC_INFORM,tmpstr); sprintf(tmpstr, "=============== =============== ============ ===== ==========="); emit(ERRLOC,MPS_GENERIC_INFORM,tmpstr); } for(i = rec_type->from_pos; i <= rec_type->to_pos; i++) { size = gsField_Mapping[i].field_from_size; /* Skip over some fields if in minimize / non-debug mode */ if ( minimize && !mpsIsLogLevelHigh() ) { switch(gsField_Mapping[i].field_to_id) { case to_type_id_usg: case to_point_origin: case to_point_target: case to_trans_dt: case to_timezone: case to_external_id: case to_external_id_type: case to_home_carrier_sid_bid: case to_num_tax_details: break; default: pos += size; continue; } } switch(gsField_Mapping[i].field_from_type) { case binary: j = ParseHex((char *)cdr_data->usg_rec+pos, (int) size); pos += size; if(mpsIsLogLevelHigh()) { sprintf(tmpstr, "%-20.20s %-20.20s %-12.12s %-6d%-12d", gsField_Mapping[i].field_from_name, gsField_Mapping[i].field_to_name, "(binary)", size, j); emit(ERRLOC,MPS_GENERIC_INFORM,tmpstr); } break; default: if((gsField_Mapping[i].field_to_id == to_annotation) || (gsField_Mapping[i].field_to_id == to_customer_tag) || (gsField_Mapping[i].field_to_id == to_roaming_detail)) { extract_field_no_strip(&ptr, (char *)cdr_data->usg_rec, &pos, (int) size); } else { extract_field(&ptr, (char *)cdr_data->usg_rec, &pos, (int) size); } if(mpsIsLogLevelHigh()) { sprintf(tmpstr, "%-20.20s %-20.20s %-12.12s %-6d%-s", gsField_Mapping[i].field_from_name, gsField_Mapping[i].field_to_name, "(a/n str)", size, ptr); emit(ERRLOC,MPS_GENERIC_INFORM,tmpstr); } break; } if(gsField_Mapping[i].is_ignored) { continue; } if(gsField_Mapping[i].is_required && ptr[0] == '\0' && gsField_Mapping[i].field_from_type != binary) { emit(ERRLOC,CAP_FIELD_MISSING_X,gsField_Mapping[i].field_from_name); set_cdr_error_code(cdr_data, CAP_FIELD_MISSING); sprintf(tmpstr, "%d,Field: \"%s\"", CAP_FIELD_MISSING,gsField_Mapping[i].field_to_name); emit(ERRLOC,MPS_GEN_ERROR,tmpstr ); set_mps_error_struct(tmpstr,""); } /* if we need to convert from string to a numeric field * ** we need to check no digital char and overflow */ if(gsField_Mapping[i].field_to_type != to_string) { if(gsField_Mapping[i].field_from_type != binary) { if(numeric_string(ptr)) { if(gsField_Mapping[i].field_to_type == to_numeric) { } else { if(convert_to_number(ptr,&j, (short) gsField_Mapping[i].field_to_type) == FAILURE) { /* conversion caused overflow */ j = 0; set_cdr_error_code(cdr_data, CAP_VALUE_OVERFLOW); sprintf(tmpstr, "%d,convert \"%s\" to \"%s\" caused overflow", CAP_VALUE_OVERFLOW, ptr, gsField_Mapping[i].field_to_name); set_mps_error_struct(tmpstr,""); } } } else { /* some non-numeric characters for numeric field */ j = 0; set_cdr_error_code(cdr_data, CAP_BAD_NUM_FIELD); sprintf(tmpstr, "%d,Field value: \"%s\"", CAP_BAD_NUM_FIELD, ptr); emit(ERRLOC,CAP_BAD_NUM_FIELD ); sprintf(tmpstr, "%-20.20s: \"%s\"", gsField_Mapping[i].field_from_name,gstrScratch1); emit(ERRLOC,MPS_GEN_ERROR,tmpstr ); set_mps_error_struct(tmpstr,""); } } else { /* when we get a binary field, we need to check overflow ** since we may get the int and try to convert to a tiny */ if(check_overflow(j, (short) gsField_Mapping[i].field_to_type) == FAILURE) { j = 0; /* conversion caused overflow */ set_cdr_error_code(cdr_data, CAP_VALUE_OVERFLOW); sprintf(tmpstr, "%d,convert %d to \"%s\" caused overflow", CAP_VALUE_OVERFLOW, j, gsField_Mapping[i].field_to_name); emit(ERRLOC,MPS_GEN_ERROR,tmpstr ); set_mps_error_struct(tmpstr,""); } } } switch(gsField_Mapping[i].field_to_id) { case to_ext_tracking_id: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->ext_tracking_id, ptr, szExtTrackingId); cdr_data->ext_tracking_id[szExtTrackingId] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->ext_tracking_id, tmpstr,szExtTrackingId); cdr_data->ext_tracking_id[szExtTrackingId] = '\0'; } break; case to_trans_id: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->trans_id, ptr, szTransID); cdr_data->trans_id[szTransID] = '\0'; } else { sprintf(cdr_data->trans_id,"%d",j); sprintf(tmpstr,"%d",j); strncpy(cdr_data->trans_id, tmpstr, szTransID); cdr_data->trans_id[szTransID] = '\0'; } break; case to_element_id: cdr_data->element_id = j; break; case to_type_id_usg: cdr_data->type_id_usg = j; cdr_data->orig_type_id_usg = j; break; case to_rate_class: cdr_data->rate_class = j; break; case to_bill_class: cdr_data->bill_class = j; break; case to_num_tax_details: cdr_data->num_tax_details = j; break; case to_provider_id: cdr_data->provider_id = j; break; case to_provider_class: cdr_data->provider_class = j; break; case to_jurisdiction: cdr_data->jurisdiction = j; break; case to_rate_currency_code: cdr_data->rate_currency_code = j; break; case to_emf_create_date: break; case to_point_origin: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->point_origin, ptr, szUsagePoint); cdr_data->point_origin[szUsagePoint] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->point_origin, tmpstr, szUsagePoint); cdr_data->point_origin[szUsagePoint] = '\0'; } break; case to_country_dial_code_origin: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->country_dial_code_origin, ptr, szDialCode); cdr_data->country_dial_code_origin[szDialCode] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->country_dial_code_origin, tmpstr, szDialCode); cdr_data->country_dial_code_origin[szDialCode] = '\0'; } break; case to_point_tax_code_origin: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->point_tax_code_origin, ptr, szTaxCode); cdr_data->point_tax_code_origin[szTaxCode] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->point_tax_code_origin, tmpstr, szTaxCode); cdr_data->point_tax_code_origin[szTaxCode] = '\0'; } break; case to_point_tax_code_type_origin: cdr_data->point_tax_code_type_origin = j; break; case to_point_target: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->point_target, ptr, szUsagePoint); cdr_data->point_target[szUsagePoint] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->point_target, tmpstr, szUsagePoint); cdr_data->point_target[szUsagePoint] = '\0'; } break; case to_point_tax_code_target: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->point_tax_code_target, ptr, szTaxCode); cdr_data->point_tax_code_target[szTaxCode] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->point_tax_code_target, tmpstr, szTaxCode); cdr_data->point_tax_code_target[szTaxCode] = '\0'; } break; case to_point_tax_code_type_target: cdr_data->point_tax_code_type_target = j; break; case to_trans_dt: /* if time comes in as unix time save it in the trans_time field ** and do conversion later by using a timezone */ if(gsField_Mapping[i].field_to_type == to_int) cdr_data->trans_time = j; else { /* if time comes in as char string save the string and convert ** to YYYYMMDD HH:MM:SS according the input format */ if(convert_date_string(cdr_data->trans_dt, gstrScratch1, gsField_Mapping[i].date_format_type) == FAILURE) { emit(ERRLOC, MPS_BAD_FIELD, "trans_dt", cdr_data->trans_dt); set_cdr_error_code(cdr_data, CAP_BAD_PRIMTIME); sprintf(tmpstr, "%d,%s: \"%s\"", CAP_BAD_PRIMTIME,gsField_Mapping[i].field_to_name, cdr_data->trans_dt); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); break; } } trans_dt_type = gsField_Mapping[i].field_to_type; break; case to_second_dt: /* if time comes in as unix time save it in the trans_time field ** and do conversion later by using a timezone */ if(gsField_Mapping[i].field_to_type == to_int) cdr_data->second_time = j; else { /* if time comes in as char string save the string and convert ** to YYYYMMDD HH:MM:SS according the input format later */ if(convert_date_string(cdr_data->second_dt, gstrScratch1, gsField_Mapping[i].date_format_type) == FAILURE) { emit(ERRLOC, MPS_BAD_FIELD,"second_dt",cdr_data->second_dt); set_cdr_error_code(cdr_data, CAP_BAD_SECONDTIME); sprintf(tmpstr, "%d,%s: \"%s\"", CAP_BAD_SECONDTIME, gsField_Mapping[i].field_to_name, cdr_data->second_dt); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); break; } } second_dt_type = gsField_Mapping[i].field_to_type; break; case to_timezone: cdr_data->timezone = j; new_timezone = TRUE; break; case to_primary_units: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->primary_units), j); } else { arb_numeric_from_string(&(cdr_data->primary_units), ptr); if ( arb_numeric_to_int( &(cdr_data->primary_units), &j) == FAILURE) { j = cdr_data->primary_units.low; } } *checksum1 += j; break; case to_primary_type: cdr_data->primary_type = j; break; case to_second_units: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->second_units), j); } else { arb_numeric_from_string(&(cdr_data->second_units), ptr); if ( arb_numeric_to_int( &(cdr_data->second_units), &j) == FAILURE) { j = cdr_data->second_units.low; } } *checksum2 += j; break; case to_second_type: cdr_data->second_type = j; break; case to_third_units: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->third_units), j); } else { arb_numeric_from_string(&(cdr_data->third_units), ptr); if ( arb_numeric_to_int( &(cdr_data->third_units), &j) == FAILURE) { j = cdr_data->third_units.low; } } *checksum3 += j; break; case to_third_type: cdr_data->third_type = j; break; case to_federal_tax: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->federal_tax), j); } else { arb_numeric_from_string(&(cdr_data->federal_tax), ptr); } break; case to_state_tax: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->state_tax), j); } else { arb_numeric_from_string(&(cdr_data->state_tax), ptr); } break; case to_county_tax: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->county_tax), j); } else { arb_numeric_from_string(&(cdr_data->county_tax), ptr); } break; case to_city_tax: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->city_tax), j); } else { arb_numeric_from_string(&(cdr_data->city_tax), ptr); } break; case to_other_tax: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->other_tax), j); } else { arb_numeric_from_string(&(cdr_data->other_tax), ptr); } break; case to_units_currency_code: cdr_data->units_currency_code = j; break; case to_annotation: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->annotation, ptr, size); cdr_data->annotation[size] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->annotation, tmpstr, size); cdr_data->annotation[size] = '\0'; } break; case to_customer_tag: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->customer_tag, ptr, szCustomerTag); cdr_data->customer_tag[szCustomerTag] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->customer_tag, tmpstr, szCustomerTag); cdr_data->customer_tag[szCustomerTag] = '\0'; } break; case to_geocode: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->geocode, ptr, szTaxCode); cdr_data->geocode[szTaxCode] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->geocode, tmpstr, szTaxCode); cdr_data->geocode[szTaxCode] = '\0'; } break; case to_roaming_detail: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->roaming_detail, ptr, size); cdr_data->roaming_detail[size] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->roaming_detail, tmpstr, size); cdr_data->roaming_detail[size] = '\0'; } break; case to_rated_units: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->rated_units), j); } else arb_numeric_from_string(&(cdr_data->rated_units), ptr); break; case to_total_amt: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->total_amt), j); } else arb_numeric_from_string(&(cdr_data->total_amt), ptr); break; case to_base_amt: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->base_amt), j); } else arb_numeric_from_string(&(cdr_data->base_amt), ptr); break; case to_unrounded_amount: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->unrounded_amount), j); } else arb_numeric_from_string(&(cdr_data->unrounded_amount), ptr); break; case to_foreign_amount: if(gsField_Mapping[i].field_from_type == binary) { arb_numeric_from_int(&(cdr_data->foreign_amount), j); } else arb_numeric_from_string(&(cdr_data->foreign_amount), ptr); break; case to_rate_period: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->rate_period, ptr, szRatePeriod); cdr_data->rate_period[szRatePeriod] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->rate_period, tmpstr, szRatePeriod); cdr_data->rate_period[szRatePeriod] = '\0'; } break; case to_rate_dt: /* if time comes in as unix time save it in the trans_time field ** and do conversion later by using a timezone */ if(gsField_Mapping[i].field_to_type == to_int) cdr_data->rate_time = j; else { if(convert_date_string(cdr_data->rate_dt, gstrScratch1, gsField_Mapping[i].date_format_type) == FAILURE) { emit(ERRLOC, MPS_BAD_FIELD,"rate_dt",cdr_data->rate_dt); set_cdr_error_code(cdr_data, CAP_BAD_RATETIME); sprintf(tmpstr, "%d,%s: \"%s\"", CAP_BAD_RATETIME, gsField_Mapping[i].field_to_name, cdr_data->rate_dt); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); break; } } rate_dt_type = gsField_Mapping[i].field_to_type; break; case to_no_bill: cdr_data->no_bill = j; break; case to_comp_status: cdr_data->comp_status = j; break; case to_cdr_status: cdr_data->cdr_status = j; break; case to_external_id: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->external_id, ptr, size); cdr_data->external_id[size] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->external_id, tmpstr, size); cdr_data->external_id[size] = '\0'; } break; case to_external_id_type: cdr_data->external_id_type = j; break; case to_account_no: cdr_data->account_no = j; break; case to_kp_subscr_no: cdr_data->kp_subscr_no = j; break; case to_kp_subscr_no_resets: cdr_data->kp_subscr_no_resets = j; break; case to_kp_server_id: cdr_data->kp_server_id = j; break; case to_ccard_account: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->miu_ccard_account, ptr, szCCardAcct); cdr_data->miu_ccard_account[szCCardAcct] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->miu_ccard_account, tmpstr, szCCardAcct); cdr_data->miu_ccard_account[szCCardAcct] = '\0'; } break; case to_ccard_carrier_code: cdr_data->miu_ccard_carrier_code = j; break; case to_ccard_ownr_fname: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->miu_ccard_ownr_fname, ptr, szCCardOwnr); cdr_data->miu_ccard_ownr_fname[szCCardOwnr] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->miu_ccard_ownr_fname, tmpstr, szCCardOwnr); cdr_data->miu_ccard_ownr_fname[szCCardOwnr] = '\0'; } break; case to_ccard_ownr_lname: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->miu_ccard_ownr_lname, ptr, szCCardOwnr); cdr_data->miu_ccard_ownr_lname[szCCardOwnr] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->miu_ccard_ownr_lname, tmpstr, szCCardOwnr); cdr_data->miu_ccard_ownr_lname[szCCardOwnr] = '\0'; } break; case to_ccard_expire: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->miu_ccard_expire, ptr, szCCardExpire); cdr_data->miu_ccard_expire[szCCardExpire] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->miu_ccard_expire, tmpstr, szCCardExpire); cdr_data->miu_ccard_expire[szCCardExpire] = '\0'; } break; case to_ccard_carrier: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->miu_ccard_carrier, ptr, szCCCarrier); cdr_data->miu_ccard_carrier[szCCCarrier] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->miu_ccard_carrier, tmpstr, szCCCarrier); cdr_data->miu_ccard_carrier[szCCCarrier] = '\0'; } break; case to_free_flag: cdr_data->free_flag = j; break; case to_home_carrier_sid_bid: cdr_data->home_carrier_sid_bid = j; break; case to_open_item_id: cdr_data->open_item_id = j; break; case to_cell_name_origin: if(gsField_Mapping[i].field_from_type != binary) { strncpy(cdr_data->cell_name_origin, ptr, szCellName); cdr_data->cell_name_origin[szCellName] = '\0'; } else { sprintf(tmpstr,"%d",j); strncpy(cdr_data->cell_name_origin, tmpstr, szCellName); cdr_data->cell_name_origin[szCellName] = '\0'; } break; } } if(new_timezone) { if(timezone_lookup(cdr_data->timezone,unix_tz,&isdst) != SUCCESS) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr,"%d,Timezone:%d",CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } /* if we get a unix time do conversion ** from int to arbor/bp date format */ if(trans_dt_type == to_int || second_dt_type == to_int || rate_dt_type == to_int) { if(mpsGetGuideTZ() == TIMEZONE_NOT_USED) { /* convert to input usage record's timezone ** (already saved in cdr_data) */ strcpy(usage_tz, unix_tz); } else { /* Use guiding timezone instead. ** NOTE: in this case, the timezone from the usage record ** IS DISCARDED !! */ strcpy(usage_tz, mpsGetGuideTZstr()); cdr_data->timezone = mpsGetGuideTZ(); /* int version of mpsGetGuideTZstr() */ } /* ---------------------------------------------------- ** Convert trans_dt & second_dt to appropriate timezone ** since we are converting a unix time_t, the "from_tz" arg ** of convert_timezone (arg 3) is not used. */ if(trans_dt_type == to_int) { if(convert_timezone(cdr_data->trans_time, cdr_data->trans_dt, "GMT0", usage_tz) == FAILURE) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr, "%d,Timezone:%d", CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } } if(second_dt_type == to_int) { if(convert_timezone(cdr_data->second_time, cdr_data->second_dt, "GMT0", usage_tz) == FAILURE) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr, "%d,Timezone:%d", CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } } if(rate_dt_type == to_int) { if(convert_timezone(cdr_data->rate_time, cdr_data->rate_dt, "GMT0", usage_tz) == FAILURE) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr, "%d,Timezone:%d", CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC, MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } } } } else { /* no timezone provided, get the default time zone later */ if(trans_dt_type == to_int || second_dt_type == to_int || rate_dt_type == to_int) { if(mpsGetGuideTZ() == TIMEZONE_NOT_USED) { /* no default set, do not know what to convert to, hard error */ emit(ERRLOC,CAP_NO_TIMEZONE); sprintf(tmpstr, "%d,No timezone", CAP_NO_TIMEZONE); emit(ERRLOC,MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } else { /* Use guiding timezone */ strcpy(usage_tz, mpsGetGuideTZstr()); cdr_data->timezone = mpsGetGuideTZ(); /* int version of mpsGetGuideTZstr() */ /* ---------------------------------------------------- ** Convert trans_dt & second_dt to appropriate timezone */ if(trans_dt_type == to_int) { if(convert_timezone(cdr_data->trans_time, cdr_data->trans_dt, "GMT0", usage_tz) == FAILURE) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr, "%d,Timezone:%d", CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC,MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } } if(second_dt_type == to_int) { if(convert_timezone(cdr_data->second_time, cdr_data->second_dt, "GMT0", usage_tz) == FAILURE) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr, "%d,Timezone:%d", CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC,MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } } if(rate_dt_type == to_int) { if(convert_timezone(cdr_data->rate_time, cdr_data->rate_dt, "GMT0", usage_tz) == FAILURE) { emit(ERRLOC, CAP_BAD_USG_TIMEZONE, cdr_data->timezone); set_cdr_error_code(cdr_data, CAP_BAD_TIMEZONE); sprintf(tmpstr, "%d,Timezone:%d", CAP_BAD_TIMEZONE,cdr_data->timezone); emit(ERRLOC,MPS_GEN_ERROR, tmpstr ); set_mps_error_struct(tmpstr,""); return(SUCCESS); } } } } } return(SUCCESS); } /* ProcessUsgDetail() */