diff --git a/src/mod/applications/mod_lcr/mod_lcr.c b/src/mod/applications/mod_lcr/mod_lcr.c index c0d99dfc35..272745b6dc 100644 --- a/src/mod/applications/mod_lcr/mod_lcr.c +++ b/src/mod/applications/mod_lcr/mod_lcr.c @@ -127,6 +127,7 @@ struct callback_obj { int matches; switch_memory_pool_t *pool; char *lookup_number; + char *lrn_number; char *cid; switch_bool_t intrastate; switch_bool_t intralata; @@ -622,6 +623,8 @@ static int route_add_callback(void *pArg, int argc, char **argv, char **columnNa additional->carrier_name = switch_core_strdup(pool, switch_str_nil(argv[i])); } else if (CF("lcr_rate_field")) { if (!argv[i] || zstr(argv[i])) { + /* maybe we want to consider saying which carriers have null rate fields... maybe they can run the query and find out */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "rate field is null, skipping\n"); goto end; } additional->rate = (float)atof(switch_str_nil(argv[i])); @@ -798,7 +801,7 @@ static switch_status_t is_intrastatelata(callback_t *cb_struct) cb_struct->lookup_number+1, cb_struct->lookup_number+4, cb_struct->cid+1, cb_struct->cid+4); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "SQL: %s\n", sql); return(lcr_execute_sql_callback(sql, intrastatelata_callback, cb_struct)); @@ -808,8 +811,9 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) { switch_stream_handle_t sql_stream = { 0 }; char *digits = cb_struct->lookup_number; - char *digits_copy; - char *digits_expanded; + char *digits_copy = NULL; + char *digits_expanded = NULL; + char *lrn_digits_expanded = NULL; profile_t *profile = cb_struct->profile; switch_bool_t lookup_status; switch_channel_t *channel; @@ -832,6 +836,11 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) } digits_expanded = expand_digits(cb_struct->pool, digits_copy, cb_struct->profile->quote_in_list); + if (cb_struct->lrn_number) { + lrn_digits_expanded = expand_digits(cb_struct->pool, cb_struct->lrn_number, cb_struct->profile->quote_in_list); + } else { + lrn_digits_expanded = switch_core_strdup(cb_struct->pool, digits_expanded); + } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(cb_struct->session), SWITCH_LOG_DEBUG, "Has NPA NXX: [%u == %u]\n", profile->profile_has_npanxx, SWITCH_TRUE); if (profile->profile_has_npanxx == SWITCH_TRUE) { @@ -866,6 +875,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) id_str = switch_core_sprintf(cb_struct->pool, "%d", cb_struct->profile->id); switch_channel_set_variable_var_check(channel, "lcr_query_profile", id_str, SWITCH_FALSE); switch_channel_set_variable_var_check(channel, "lcr_query_expanded_digits", digits_expanded, SWITCH_FALSE); + switch_channel_set_variable_var_check(channel, "lcr_query_expanded_lrn_digits", lrn_digits_expanded, SWITCH_FALSE); + if ( cb_struct->lrn_number ) { + switch_channel_set_variable_var_check(channel, "lcr_lrn", cb_struct->lrn_number, SWITCH_FALSE); + } } } if (cb_struct->event) { @@ -876,6 +889,10 @@ static switch_status_t lcr_do_lookup(callback_t *cb_struct) id_str = switch_core_sprintf(cb_struct->pool, "%d", cb_struct->profile->id); switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_query_profile", id_str); switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_query_expanded_digits", digits_expanded); + switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_query_expanded_lrn_digits", lrn_digits_expanded); + if ( cb_struct->lrn_number ) { + switch_event_add_header_string(cb_struct->event, SWITCH_STACK_BOTTOM, "lcr_lrn", cb_struct->lrn_number); + } } /* set up the query to be executed */ @@ -998,7 +1015,7 @@ static switch_status_t lcr_load_config() char *export_fields = NULL; char *limit_type = NULL; int argc, x = 0; - char *argv[4] = { 0 }; + char *argv[32] = { 0 }; SWITCH_STANDARD_STREAM(order_by); @@ -1078,29 +1095,48 @@ static switch_status_t lcr_load_config() SWITCH_STANDARD_STREAM(sql_stream); if (zstr(custom_sql)) { /* use default sql */ + + /* Checking for codec field, adding if needed */ + if (db_check("SELECT codec FROM carrier_gateway LIMIT 1") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n"); + } else { + if (db_check("ALTER TABLE carrier_gateway add codec varchar(255);") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "adding codec field your lcr carrier_gateway database schema.\n"); + } else { + return SWITCH_FALSE; + } + } + + /* Checking for cid field, adding if needed */ + if (db_check("SELECT cid FROM lcr LIMIT 1") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cid field defined.\n"); + } else { + if (db_check("ALTER TABLE lcr add cid varchar(32);") == SWITCH_TRUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n"); + } else { + return SWITCH_FALSE; + } + } + + if (db_check("SELECT lrn FROM lcr LIMIT 1") != SWITCH_TRUE) { + if (db_check("ALTER TABLE lcr add lrn boolean")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n"); + } else { + return SWITCH_FALSE; + } + } + sql_stream.write_function(&sql_stream, "SELECT l.digits AS lcr_digits, c.carrier_name AS lcr_carrier_name, l.${lcr_rate_field} AS lcr_rate_field, \ cg.prefix AS lcr_gw_prefix, cg.suffix AS lcr_gw_suffix, l.lead_strip AS lcr_lead_strip, \ - l.trail_strip AS lcr_trail_strip, l.prefix AS lcr_prefix, l.suffix AS lcr_suffix " - ); - if (db_check("SELECT codec from carrier_gateway limit 1") == SWITCH_TRUE) { - sql_stream.write_function(&sql_stream, ", cg.codec AS lcr_codec "); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "codec field defined.\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "codec field not defined, please update your lcr carrier_gateway database schema.\n" - ); - } - if (db_check("SELECT cid from lcr limit 1") == SWITCH_TRUE) { - sql_stream.write_function(&sql_stream, ", l.cid AS lcr_cid "); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "cid field defined.\n"); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "cid field not defined, please update your lcr database schema.\n"); - } + l.trail_strip AS lcr_trail_strip, l.prefix AS lcr_prefix, l.suffix AS lcr_suffix, \ + cg.codec AS lcr_codec, l.cid AS lcr_cid "); sql_stream.write_function(&sql_stream, "FROM lcr l JOIN carriers c ON l.carrier_id=c.id \ - JOIN carrier_gateway cg ON c.id=cg.carrier_id WHERE \ - c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND digits IN ("); - sql_stream.write_function(&sql_stream, "${lcr_query_expanded_digits}"); + JOIN carrier_gateway cg ON c.id=cg.carrier_id \ + WHERE c.enabled = '1' AND cg.enabled = '1' AND l.enabled = '1' AND (\ + (digits IN (${lcr_query_expanded_digits}) AND lrn = false) OR \ + (digits IN (${lcr_query_expanded_lrn_digits}) AND lrn = true)"); + sql_stream.write_function(&sql_stream, ") AND CURRENT_TIMESTAMP BETWEEN date_start AND date_end "); if (profile->id > 0) { sql_stream.write_function(&sql_stream, "AND lcr_profile=%d ", profile->id); @@ -1430,6 +1466,7 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt) switch_event_t *event = NULL; const char *intrastate = NULL; const char *intralata = NULL; + const char *lrn = NULL; if (session) { pool = switch_core_session_get_pool(session); @@ -1443,8 +1480,12 @@ SWITCH_STANDARD_DIALPLAN(lcr_dialplan_hunt) intrastate = switch_channel_get_variable(channel, "intrastate"); intralata = switch_channel_get_variable(channel, "intralata"); + lrn = switch_channel_get_variable(channel, "lrn"); + routes.lrn_number = (char *) lrn; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", intrastate); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intralata channel var is [%s]\n", intralata); + if (!zstr(intralata) && !strcasecmp((char *)intralata, "true")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on intralata rates\n"); routes.intralata = SWITCH_FALSE; @@ -1531,7 +1572,7 @@ void str_repeat(size_t how_many, char *what, switch_stream_handle_t *str_stream) SWITCH_STANDARD_APP(lcr_app_function) { int argc = 0; - char *argv[4] = { 0 }; + char *argv[32] = { 0 }; char *mydata = NULL; char *dest = NULL; char vbuf[1024] = ""; @@ -1544,6 +1585,7 @@ SWITCH_STANDARD_APP(lcr_app_function) switch_memory_pool_t *pool; switch_event_t *event; const char *intra = NULL; + const char *lrn = NULL; if (!(mydata = switch_core_session_strdup(session, data))) { return; @@ -1557,11 +1599,15 @@ SWITCH_STANDARD_APP(lcr_app_function) switch_event_create(&event, SWITCH_EVENT_MESSAGE); routes.event = event; } + routes.pool = pool; + + lrn = switch_channel_get_variable(channel, "lrn"); + routes.lrn_number = (char *) lrn; + intra = switch_channel_get_variable(channel, "intrastate"); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", - zstr(intra) ? "undef" : intra); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "intrastate channel var is [%s]\n", zstr(intra) ? "undef" : intra); if (zstr(intra) || strcasecmp((char *)intra, "true")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Select routes based on interstate rates\n"); routes.intrastate = SWITCH_FALSE; @@ -1578,6 +1624,7 @@ SWITCH_STANDARD_APP(lcr_app_function) if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { dest = argv[0]; + if (argc > 1) { lcr_profile = argv[1]; } @@ -1664,21 +1711,20 @@ static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, con SWITCH_STANDARD_API(dialplan_lcr_function) { - char *argv[9] = { 0 }; + char *argv[32] = { 0 }; int argc; - char *mydata = NULL; - //char *dialstring = NULL; - char *lcr_profile = NULL; - lcr_route current = NULL; - max_obj_t maximum_lengths = { 0 }; - callback_t cb_struct = { 0 }; - switch_memory_pool_t *pool = NULL; + char *mydata = NULL; + char *lcr_profile = NULL; + lcr_route current = NULL; + max_obj_t maximum_lengths = { 0 }; + callback_t cb_struct = { 0 }; + switch_memory_pool_t *pool = NULL; switch_event_t *event; switch_status_t lookup_status = SWITCH_STATUS_SUCCESS; - switch_bool_t as_xml = SWITCH_FALSE; - char *event_str = NULL; - switch_xml_t event_xml = NULL; - int rowcount=0; + switch_bool_t as_xml = SWITCH_FALSE; + char *event_str = NULL; + switch_xml_t event_xml = NULL; + int rowcount = 0; if (zstr(cmd)) { goto usage; @@ -1708,10 +1754,18 @@ SWITCH_STANDARD_API(dialplan_lcr_function) } if (argc > 2) { int i; - for (i=2; i