#!/usr/bin/perl
#/* ========================================
# * ███╗   ███╗██████╗ ██╗ █████╗ ██╗
# * ████╗ ████║██╔══██╗██║██╔══██╗██║
# * ██╔████╔██║██║  ██║██║███████║██║
# * ██║╚██╔╝██║██║  ██║██║██╔══██║██║
# * ██║ ╚═╝ ██║██████╔╝██║██║  ██║███████╗
# * ╚═╝     ╚═╝╚═════╝ ╚═╝╚═╝  ╚═╝╚══════╝
# * ========================================
# * mDial - Omni-Channel Contact Centre Suite.
# * Initially Written by Martin McCarthy.
# * Contributions welcome.
# * Active: 2020 - 2023.
# *
# * This software is licensed under AGPLv2.
# * You can find more information here;
# * https://www.gnu.org/licenses/agpl-3.0.en.html
# * A copy of the license is also shipped with this build.
# *
# * Important note: this software is provided to you free of charge.
# * If you paid for this software, you were ripped off.
# *
# * This project is a fork of the awesome FOSS project, ViCiDial.
# * ViCiDial is copyrighted by Matt Florell and the ViCiDial Group
# * under the AGPLv2 license.
# *
# * You can find out more about ViCiDial;
# * Web: https://www.vicidial.com/
# * Email: Matt Florell <vicidial@gmail.com>
# * IRC: Libera.Chat - ##vicidial
# *
# * Bug reports, feature requests and patches welcome!
# * ======================================== */
$script             = 'agi-DID_route.agi';
$dtmf_silent_prefix = '7';
$at                 = '@';
$S                  = '*';
$US                 = '_';
$route_type         = 'DID';
$DBX                = 0;                   # set to 1 for extra debugging output
( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
  localtime(time);
$year = ( $year + 1900 );
$mon++;
if ( $mon < 10 )  { $mon  = "0$mon"; }
if ( $mday < 10 ) { $mday = "0$mday"; }
if ( $hour < 10 ) { $hour = "0$hour"; }
if ( $min < 10 )  { $min  = "0$min"; }
if ( $sec < 10 )  { $sec  = "0$sec"; }
$hm             = "$hour$min";
$hm             = ( $hm + 0 );
$now_date_epoch = time();
$now_date       = "$year-$mon-$mday $hour:$min:$sec";
$CLInow_date    = "$year-$mon-$mday\\ $hour:$min:$sec";
$start_time     = $now_date;
$CIDdate        = "$mon$mday$hour$min$sec";
$tsSQLdate      = "$year$mon$mday$hour$min$sec";
$SQLdate        = "$year-$mon-$mday $hour:$min:$sec";
$SQLdateBEGIN   = $SQLdate;
$PATHconf       = '/etc/astguiclient.conf';
open( conf, "$PATHconf" ) || die "can't open $PATHconf: $!\n";
@conf = <conf>;
close(conf);
$i = 0;

foreach (@conf) {
    $line = $conf[$i];
    $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi;
    if ( ( $line =~ /^PATHhome/ ) && ( $CLIhome < 1 ) ) {
        $PATHhome = $line;
        $PATHhome =~ s/.*=//gi;
    }
    if ( ( $line =~ /^PATHlogs/ ) && ( $CLIlogs < 1 ) ) {
        $PATHlogs = $line;
        $PATHlogs =~ s/.*=//gi;
    }
    if ( ( $line =~ /^PATHagi/ ) && ( $CLIagi < 1 ) ) {
        $PATHagi = $line;
        $PATHagi =~ s/.*=//gi;
    }
    if ( ( $line =~ /^PATHweb/ ) && ( $CLIweb < 1 ) ) {
        $PATHweb = $line;
        $PATHweb =~ s/.*=//gi;
    }
    if ( ( $line =~ /^PATHsounds/ ) && ( $CLIsounds < 1 ) ) {
        $PATHsounds = $line;
        $PATHsounds =~ s/.*=//gi;
    }
    if ( ( $line =~ /^PATHmonitor/ ) && ( $CLImonitor < 1 ) ) {
        $PATHmonitor = $line;
        $PATHmonitor =~ s/.*=//gi;
    }
    if ( ( $line =~ /^VARserver_ip/ ) && ( $CLIserver_ip < 1 ) ) {
        $VARserver_ip = $line;
        $VARserver_ip =~ s/.*=//gi;
    }
    if ( ( $line =~ /^VARDB_server/ ) && ( $CLIDB_server < 1 ) ) {
        $VARDB_server = $line;
        $VARDB_server =~ s/.*=//gi;
    }
    if ( ( $line =~ /^VARDB_database/ ) && ( $CLIDB_database < 1 ) ) {
        $VARDB_database = $line;
        $VARDB_database =~ s/.*=//gi;
    }
    if ( ( $line =~ /^VARDB_user/ ) && ( $CLIDB_user < 1 ) ) {
        $VARDB_user = $line;
        $VARDB_user =~ s/.*=//gi;
    }
    if ( ( $line =~ /^VARDB_pass/ ) && ( $CLIDB_pass < 1 ) ) {
        $VARDB_pass = $line;
        $VARDB_pass =~ s/.*=//gi;
    }
    if ( ( $line =~ /^VARDB_port/ ) && ( $CLIDB_port < 1 ) ) {
        $VARDB_port = $line;
        $VARDB_port =~ s/.*=//gi;
    }
    $i++;
}
if ( !$VARDB_port ) { $VARDB_port = '3306'; }
if ( !$AGILOGfile ) { $AGILOGfile = "$PATHlogs/agiout.$year-$mon-$mday"; }
if ( !$DIDLOGfile ) { $DIDLOGfile = "$PATHlogs/didin.$year-$mon-$mday"; }
use DBI;
use Time::HiRes ( 'gettimeofday', 'usleep', 'sleep' )
  ;    # necessary to have perl sleep command of less than one second
use Asterisk::AGI;
$AGI  = new Asterisk::AGI;
$dbhA = DBI->connect( "DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port",
    "$VARDB_user", "$VARDB_pass" )
  or die "Couldn't connect to database: " . DBI->errstr;
$stmtA =
"SELECT agi_output,local_gmt,asterisk_version FROM servers where server_ip = '$VARserver_ip';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
$sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
$sthArows = $sthA->rows;

if ( $sthArows > 0 ) {
    $AGILOG           = '0';
    @aryA             = $sthA->fetchrow_array;
    $DBagi_output     = $aryA[0];
    $local_gmt        = $aryA[1];
    $asterisk_version = $aryA[2];
    if ( $DBagi_output =~ /STDERR/ ) { $AGILOG = '1'; }
    if ( $DBagi_output =~ /FILE/ )   { $AGILOG = '2'; }
    if ( $DBagi_output =~ /BOTH/ )   { $AGILOG = '3'; }
}
$sthA->finish();
$stmtA =
"SELECT enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_log_id,queuemetrics_eq_prepend,did_agent_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_system_filter,inbound_answer_config FROM system_settings;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
$sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
$sthArows = $sthA->rows;
if ( $sthArows > 0 ) {
    @aryA                        = $sthA->fetchrow_array;
    $enable_queuemetrics_logging = $aryA[0];
    $queuemetrics_server_ip      = $aryA[1];
    $queuemetrics_dbname         = $aryA[2];
    $queuemetrics_login          = $aryA[3];
    $queuemetrics_pass           = $aryA[4];
    $queuemetrics_log_id         = $aryA[5];
    $queuemetrics_eq_prepend     = $aryA[6];
    $did_agent_log               = $aryA[7];
    $alt_log_server_ip           = $aryA[8];
    $alt_log_dbname              = $aryA[9];
    $alt_log_login               = $aryA[10];
    $alt_log_pass                = $aryA[11];
    $tables_use_alt_log_db       = $aryA[12];
    $SSdid_system_filter         = $aryA[13];
    $SSinbound_answer_config     = $aryA[14];
}
$sthA->finish();
$| = 1;
while (<STDIN>) {
    chomp;
    last unless length($_);
    if ($AGILOG) {
        if (/^agi_(\w+)\:\s+(.*)$/) {
            $AGI{$1} = $2;
        }
    }
    if (/^agi_uniqueid\:\s+(.*)$/)  { $unique_id = $1; $uniqueid = $unique_id; }
    if (/^agi_channel\:\s+(.*)$/)   { $channel   = $1; }
    if (/^agi_extension\:\s+(.*)$/) { $extension = $1; }
    if (/^agi_type\:\s+(.*)$/)      { $type      = $1; }
    if (/^agi_callerid\:\s+(.*)$/)  { $callerid  = $1; }
    if (/^agi_calleridname\:\s+(.*)$/) { $calleridname = $1; }
}
if (   ( $callerid =~ /\".*\"/ )
    && ( ( !$calleridname ) or ( $calleridname =~ /unknown/ ) ) )
{
    $calleridname = $callerid;
    $calleridname =~ s/\<\d\d\d\d\d\d\d\d\d\d\>//gi;
    $calleridname =~ s/\"|\" //gi;
}
$callerid     =~ s/\D|\'//gi;
$calleridname =~ s/unknown|\'//gi;
if ( ( !$callerid ) or ( $callerid =~ /unknown/ ) ) {
    $callerid = $calleridname;
}
$callerid     =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$calleridname =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$extension    =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$VICIrecGatewayID = $AGI->get_variable('VICIrecGatewayID');
$VICIrecGatewayID =~ s/[^0-9a-zA-Z]//gi;
if ( length($VICIrecGatewayID) > 19 ) {
    if ($AGILOG) {
        $agi_string =
          "--    VICIrecGatewayID set on this call: |$VICIrecGatewayID|";
        &agi_output;
    }
    $stmtA =
"INSERT INTO vicidial_did_gateway_log SET uniqueid='$uniqueid',channel='$channel',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',call_date='$SQLdate',VICIrecGatewayID='$VICIrecGatewayID';";
    if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
    $affected_rowsG = $dbhA->do($stmtA);
    if ($AGILOG) {
        $agi_string =
          "--    VICIrecGatewayID LOG INSERT: |$affected_rowsG|$stmtA|";
        &agi_output;
    }
}
if ( $SSdid_system_filter > 0 ) {
    if ($AGILOG) {
        $agi_string = "--    DID SYSTEM FILTER ENABLED: |$SSdid_system_filter|";
        &agi_output;
    }
    $stmtA =
"SELECT did_id,did_pattern,did_description,did_active,did_route,extension,exten_context,voicemail_ext,phone,server_ip,user,user_unavailable_action,user_route_settings_ingroup,menu_id,record_call,filter_inbound_number,filter_phone_group_id,filter_url,filter_action,filter_extension,filter_exten_context,filter_voicemail_ext,filter_phone,filter_server_ip,filter_user,filter_user_unavailable_action,filter_user_route_settings_ingroup,filter_group_id,filter_call_handle_method,filter_agent_search_method,filter_list_id,filter_campaign_id,filter_phone_code,filter_menu_id,filter_clean_cid_number,group_id,filter_dnc_campaign,filter_url_did_redirect,no_agent_ingroup_redirect,no_agent_ingroup_id,no_agent_ingroup_extension,pre_filter_phone_group_id,pre_filter_extension,max_queue_ingroup_calls,max_queue_ingroup_id,max_queue_ingroup_extension,inbound_route_answer,pre_filter_recent_call,pre_filter_recent_extension FROM vicidial_inbound_dids where did_pattern = 'did_system_filter' and did_active='Y';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;
    if ( $sthArows > 0 ) {
        @aryA                               = $sthA->fetchrow_array;
        $did_id                             = $aryA[0];
        $did_pattern                        = $aryA[1];
        $did_description                    = $aryA[2];
        $did_active                         = $aryA[3];
        $did_route                          = $aryA[4];
        $did_extension                      = $aryA[5];
        $exten_context                      = $aryA[6];
        $voicemail_ext                      = $aryA[7];
        $phone                              = $aryA[8];
        $did_server_ip                      = $aryA[9];
        $user                               = $aryA[10];
        $user_unavailable_action            = $aryA[11];
        $user_route_settings_ingroup        = $aryA[12];
        $menu_id                            = $aryA[13];
        $record_call                        = $aryA[14];
        $filter_inbound_number              = $aryA[15];
        $filter_phone_group_id              = $aryA[16];
        $filter_url                         = $aryA[17];
        $filter_action                      = $aryA[18];
        $filter_extension                   = $aryA[19];
        $filter_exten_context               = $aryA[20];
        $filter_voicemail_ext               = $aryA[21];
        $filter_phone                       = $aryA[22];
        $filter_server_ip                   = $aryA[23];
        $filter_user                        = $aryA[24];
        $filter_user_unavailable_action     = $aryA[25];
        $filter_user_route_settings_ingroup = $aryA[26];
        $filter_group_id                    = $aryA[27];
        $filter_call_handle_method          = $aryA[28];
        $filter_agent_search_method         = $aryA[29];
        $filter_list_id                     = $aryA[30];
        $filter_campaign_id                 = $aryA[31];
        $filter_phone_code                  = $aryA[32];
        $filter_menu_id                     = $aryA[33];
        $filter_clean_cid_number            = $aryA[34];
        $group_id                           = $aryA[35];
        $filter_dnc_campaign                = $aryA[36];
        $filter_url_did_redirect            = $aryA[37];
        $no_agent_ingroup_redirect          = $aryA[38];
        $no_agent_ingroup_id                = $aryA[39];
        $no_agent_ingroup_extension         = $aryA[40];
        $pre_filter_phone_group_id          = $aryA[41];
        $pre_filter_extension               = $aryA[42];
        $max_queue_ingroup_calls            = $aryA[43];
        $max_queue_ingroup_id               = $aryA[44];
        $max_queue_ingroup_extension        = $aryA[45];
        $inbound_route_answer               = $aryA[46];
        $pre_filter_recent_call             = $aryA[47];
        $pre_filter_recent_extension        = $aryA[48];
    }
    else {
        if ($AGILOG) {
            $agi_string = "--    DID SYSTEM FILTER DOES NOT EXIST: |$sthArows|";
            &agi_output;
        }
    }
    $sthA->finish();
    if ( $sthArows > 0 ) {
        if ( $filter_inbound_number =~ /GROUP|URL|DNC_INTERNAL|DNC_CAMPAIGN/ ) {
            $original_callerid = $callerid;
            if ( length($filter_clean_cid_number) > 1 ) {
                $original_callerid     = $callerid;
                $filter_number_altered = 0;
                if ( $filter_clean_cid_number =~ /R\d/ ) {
                    @filter_rule = split( /R/, $filter_clean_cid_number );
                    $filter_rule[1] =~ s/ .*//gi;
                    while ( length($callerid) > $filter_rule[1] ) {
                        $callerid =~ s/^.//gi;
                    }
                    if ( length($callerid) != length($original_callerid) ) {
                        $filter_number_altered++;
                    }
                }
                if ( $filter_clean_cid_number =~ /L\d/ ) {
                    @filter_rule = split( /L/, $filter_clean_cid_number );
                    $filter_rule[1] =~ s/ .*//gi;
                    $filter_rule_reg = $filter_rule[1];
                    $callerid =~ s/^$filter_rule_reg//gi;
                    if ( length($callerid) != length($original_callerid) ) {
                        $filter_number_altered++;
                    }
                }
                if ( $filter_clean_cid_number =~ /T\d/ ) {
                    @filter_rule = split( /T/, $filter_clean_cid_number );
                    $filter_rule[1] =~ s/ .*//gi;
                    $callerid = substr( $callerid, 0, $filter_rule[1] );
                    if ( length($callerid) != length($original_callerid) ) {
                        $filter_number_altered++;
                    }
                }
            }
            if ($AGILOG) {
                $agi_string =
"SYSTEM filtering active: |$extension|$filter_inbound_number|$filter_phone_group_id|$filter_url|$filter_action|$filter_clean_cid_number|";
                &agi_output;
            }
            if ( $filter_inbound_number =~ /GROUP/ ) {
                $temp_cid_test = $callerid;
                if ( length($callerid) < 1 ) { $temp_cid_test = 'BLANK'; }
                $stmtA =
"SELECT count(*) FROM vicidial_filter_phone_numbers where filter_phone_group_id='$filter_phone_group_id' and phone_number='$temp_cid_test';";
                $sthA = $dbhA->prepare($stmtA)
                  or die "preparing: ", $dbhA->errstr;
                $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
                $sthArows = $sthA->rows;
                if ( $sthArows > 0 ) {
                    @aryA               = $sthA->fetchrow_array;
                    $filter_match_found = $aryA[0];
                }
                $sthA->finish();
                if (   ( $filter_match_found < 1 )
                    && ( $filter_inbound_number =~ /AREACODE/ ) )
                {
                    $alt_areacode = substr( $callerid, 0, 3 );
                    $alt_areacode .= "XXXXXXX";
                    $stmtB =
"SELECT count(*) FROM vicidial_filter_phone_numbers where filter_phone_group_id='$filter_phone_group_id' and phone_number='$alt_areacode';";
                    $sthA = $dbhA->prepare($stmtB)
                      or die "preparing: ", $dbhA->errstr;
                    $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
                    $sthArows = $sthA->rows;
                    if ( $sthArows > 0 ) {
                        @aryA               = $sthA->fetchrow_array;
                        $filter_match_found = $aryA[0];
                    }
                    $sthA->finish();
                }
                if ($AGILOG) {
                    $agi_string =
"SYSTEM FILTER GROUP: |$filter_match_found|$stmtA|$stmtB|";
                    &agi_output;
                }
            }
            elsif ( $filter_inbound_number =~ /DNC_INTERNAL/ ) {
                $alt_areacode = substr( $callerid, 0, 3 );
                $alt_areacode .= "XXXXXXX";
                $stmtA =
"SELECT count(*) FROM vicidial_dnc where phone_number IN('$callerid','$alt_areacode');";
                $sthA = $dbhA->prepare($stmtA)
                  or die "preparing: ", $dbhA->errstr;
                $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
                $sthArows = $sthA->rows;
                if ( $sthArows > 0 ) {
                    @aryA               = $sthA->fetchrow_array;
                    $filter_match_found = $aryA[0];
                }
                $sthA->finish();
                if ($AGILOG) {
                    $agi_string =
"SYSTEM FILTER DNC_INTERNAL: |$filter_match_found|$stmtA|";
                    &agi_output;
                }
            }
            elsif ( $filter_inbound_number =~ /DNC_CAMPAIGN/ ) {
                $alt_areacode = substr( $callerid, 0, 3 );
                $alt_areacode .= "XXXXXXX";
                $stmtA =
"SELECT count(*) FROM vicidial_campaign_dnc where campaign_id='$filter_dnc_campaign' and phone_number IN('$callerid','$alt_areacode');";
                $sthA = $dbhA->prepare($stmtA)
                  or die "preparing: ", $dbhA->errstr;
                $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
                $sthArows = $sthA->rows;
                if ( $sthArows > 0 ) {
                    @aryA               = $sthA->fetchrow_array;
                    $filter_match_found = $aryA[0];
                }
                $sthA->finish();
                if ($AGILOG) {
                    $agi_string =
"SYSTEM FILTER DNC_CAMPAIGN: |$filter_match_found|$stmtA|";
                    &agi_output;
                }
            }
            else {
                $curlbin = '';
                if ( -e ('/bin/curl') ) { $curlbin = '/bin/curl'; }
                else {
                    if ( -e ('/usr/bin/curl') ) { $curlbin = '/usr/bin/curl'; }
                    else {
                        if ( -e ('/usr/local/bin/curl') ) {
                            $curlbin = '/usr/local/bin/curl';
                        }
                        else {
                            if ($AGILOG) {
                                $agi_string =
"ERROR: cannot filter by URL, curl binary not found";
                                &agi_output;
                            }
                        }
                    }
                }
                if (   ( length($curlbin) > 4 )
                    && ( $filter_url =~ /http/i )
                    && ( length($filter_url) > 8 ) )
                {
                    $filter_url =~ s/^VAR|^ //gi;
                    $filter_url =~ s/--A--phone_number--B--/$callerid/gi;
                    $filter_url =~ s/--A--did_pattern--B--/$did_pattern/gi;
                    $filter_url =~ s/--A--uniqueid--B--/$uniqueid/gi;
                    $filter_url =~ s/--A--channel--B--/$channel/gi;
                    $filter_url =~ s/--A--server_ip--B--/$VARserver_ip/gi;
                    $filter_url =~ s/&/\\&/gi;
                    $filter_url =~ s/ /+/gi;
                    $SQL_log = "$filter_url";
                    $SQL_log =~ s/;|\||\\//gi;
                    $stmtA =
"INSERT INTO vicidial_url_log SET uniqueid='$uniqueid',url_date=NOW(),url_type='DID_FILTER',url='$SQL_log',url_response='';";
                    $affected_rows = $dbhA->do($stmtA);
                    $stmtB         = "SELECT LAST_INSERT_ID() LIMIT 1;";
                    $sthA          = $dbhA->prepare($stmtB)
                      or die "preparing: ", $dbhA->errstr;
                    $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
                    $sthArows = $sthA->rows;

                    if ( $sthArows > 0 ) {
                        @aryA   = $sthA->fetchrow_array;
                        $url_id = $aryA[0];
                    }
                    $sthA->finish();
                    my $secW = time();
                    @curl_output = `$curlbin $filter_url`;
                    my $secY         = time();
                    my $response_sec = ( $secY - $secW );
                    $k           = 0;
                    $full_output = '';

                    foreach (@curl_output) {
                        $full_output_raw .= $curl_output[$k];
                        $k++;
                    }
                    $full_output = $full_output_raw;
                    $full_output =~ s/\D//gi;
                    if ( $full_output > 0 ) {
                        $filter_match_found = $full_output;
                        if ( $filter_url_did_redirect =~ /Y/ ) {
                            $did_route = 'DID';
                            if ($AGILOG) {
                                $agi_string =
"SYSTEM Filter URL DID Redirect found: |$filter_match_found|$filter_url_did_redirect|$did_route|";
                                &agi_output;
                            }
                        }
                    }
                    $full_output_raw =~ s/;|\||\\//gi;
                    $stmtA =
"UPDATE vicidial_url_log SET url_response='$full_output_raw|$full_output',response_sec='$response_sec' where url_log_id='$url_id';";
                    $affected_rows = $dbhA->do($stmtA);
                    if ($AGILOG) {
                        $agi_string =
"SYSTEM URL filter search response: |$filter_match_found|$full_output|$filter_url|$affected_rows|";
                        &agi_output;
                    }
                }
            }
            if ( $filter_match_found > 0 ) {
                if ( $did_route !~ /DID/ ) { $did_route = $filter_action; }
                $did_extension           = $filter_extension;
                $exten_context           = $filter_exten_context;
                $voicemail_ext           = $filter_voicemail_ext;
                $phone                   = $filter_phone;
                $did_server_ip           = $filter_server_ip;
                $user                    = $filter_user;
                $user_unavailable_action = $filter_user_unavailable_action;
                $user_route_settings_ingroup =
                  $filter_user_route_settings_ingroup;
                $menu_id    = $filter_menu_id;
                $route_type = 'FILTER';

                if ($AGILOG) {
                    $agi_string =
"SYSTEM Filter match found: |$filter_match_found|$filter_inbound_number|$filter_action|$did_route|";
                    &agi_output;
                }
                if ( $filter_number_altered > 0 ) {
                    $newcallerid = "\"$calleridname <$callerid>\"";
                    $AGI->set_callerid($newcallerid);
                    if ($AGILOG) {
                        $agi_string =
"filter clean callerid, setting new CID: |$callerid|$calleridname|$newcallerid|$filter_clean_cid_number|   Old: |$original_callerid|";
                        &agi_output;
                    }
                }
                $stmtA =
"INSERT INTO vicidial_did_log SET uniqueid='$uniqueid',channel='$channel',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',call_date='$SQLdate',did_id='$did_id',did_route='F_$did_route';";
                if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
                $affected_rowsL = $dbhA->do($stmtA);
                if ($AGILOG) {
                    $agi_string =
                      "--    SYSTEM FILTER DID LOG : |$affected_rowsL|$stmtA|";
                    &agi_output;
                }
                $stmtA =
"INSERT INTO call_log SET uniqueid='$unique_id', channel='$channel', channel_group='DID_INBOUND', server_ip='$VARserver_ip', type='$type', extension='$extension', number_dialed='$extension', caller_code='$callerid', start_time='$SQLdate', start_epoch='$now_date_epoch';";
                $affected_rowsC = $dbhA->do($stmtA);
                if ($AGILOG) {
                    $agi_string =
                      "--    SYSTEM FILTER CALL LOG : |$affected_rowsC|$stmtA|";
                    &agi_output;
                }
                if ($AGILOG) {
                    $did_string =
"$SQLdate|$uniqueid|$channel|$extension|$callerid|$calleridname|$did_id|$did_route|";
                    &did_output;
                }
                if ( $did_agent_log =~ /Y/ ) {
                    if ( $did_route !~ /IN_GROUP/ ) { $group_id = ''; }
                    $stmtA =
"INSERT INTO vicidial_did_agent_log SET uniqueid='$uniqueid',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',call_date='$SQLdate',did_id='$did_id',did_route='$did_route',user='VDCL',group_id='$group_id',did_description='$did_description';";
                    if (   ( $tables_use_alt_log_db =~ /did_agent_log/i )
                        && ( length($alt_log_server_ip) > 4 )
                        && ( length($alt_log_dbname) > 0 ) )
                    {
                        $dbhD = DBI->connect(
                            "DBI:mysql:$alt_log_dbname:$alt_log_server_ip:3306",
                            "$alt_log_login",
                            "$alt_log_pass"
                          )
                          or die "Couldn't connect to database: " . DBI->errstr;
                        if ($AGILOG) {
                            $agi_string =
"CONNECTED TO ALT-LOG DATABASE:  $alt_log_server_ip|$alt_log_dbname|$uniqueid";
                            &agi_output;
                        }
                        $affected_rowsAL = $dbhD->do($stmtA);
                        $dbhD->disconnect();
                    }
                    else {
                        $affected_rowsAL = $dbhA->do($stmtA);
                    }
                    if ($AGILOG) {
                        $agi_string =
"SYSTEM FILTER --    DID AGENT LOG : |$affected_rowsAL|$stmtA|";
                        &agi_output;
                    }
                }
                if ( $did_route =~ /PHONE/ ) {
                    $stmtA =
"SELECT dialplan_number,voicemail_id,protocol,ext_context FROM phones where server_ip='$did_server_ip' and extension='$phone';";
                    $sthA = $dbhA->prepare($stmtA)
                      or die "preparing: ", $dbhA->errstr;
                    $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
                    $sthArows = $sthA->rows;
                    if ( $sthArows > 0 ) {
                        @aryA            = $sthA->fetchrow_array;
                        $dialplan_number = $aryA[0];
                        $voicemail_id    = $aryA[1];
                        $protocol        = $aryA[2];
                        $ext_context     = $aryA[3];
                    }
                    $sthA->finish();
                    if ( $did_server_ip =~ m/(\S+)\.(\S+)\.(\S+)\.(\S+)/ ) {
                        $a            = leading_zero($1);
                        $b            = leading_zero($2);
                        $c            = leading_zero($3);
                        $d            = leading_zero($4);
                        $ServerString = "$a$S$b$S$c$S$d$S";
                    }
                    $did_extension = "$ServerString$dialplan_number";
                    $did_route     = 'EXTEN';
                }
                if ( $did_route =~ /VOICEMAIL|VMAIL_NO_INST/ ) {
                    if ( $did_server_ip =~ m/(\S+)\.(\S+)\.(\S+)\.(\S+)/ ) {
                        $a            = leading_zero($1);
                        $b            = leading_zero($2);
                        $c            = leading_zero($3);
                        $d            = leading_zero($4);
                        $ServerString = "$a$S$b$S$c$S$d$S";
                    }
                    if ( $did_route =~ /VMAIL_NO_INST/ ) {
                        $voicemail_dump_exten = $voicemail_dump_exten_no_inst;
                    }
                    $did_extension =
                      "$ServerString$voicemail_dump_exten$voicemail_ext";
                    $did_route = 'EXTEN';
                }
                $did_ig_prefix = '99909';
                if (   ( $SSinbound_answer_config > 0 )
                    && ( $inbound_route_answer =~ /N/i ) )
                {
                    $did_ig_prefix = '99809';
                }
                if ( $did_route =~ /IN_GROUP/ ) {
                    $did_extension = "$did_ig_prefix$S$did_id$S$S$S$route_type";
                    $exten_context = $ext_context;
                    $did_route     = 'EXTEN';
                }
                if ( $did_route =~ /AGENT/ ) {
                    $did_extension = "$did_ig_prefix$S$did_id$S$S$S$route_type";
                    $exten_context = $ext_context;
                    $did_route     = 'EXTEN';
                }
                if (   ( $did_route =~ /EXTEN|CALLMENU/ )
                    && ( $enable_queuemetrics_logging > 0 ) )
                {
                    $dbhB = DBI->connect(
"DBI:mysql:$queuemetrics_dbname:$queuemetrics_server_ip:3306",
                        "$queuemetrics_login",
                        "$queuemetrics_pass"
                    ) or die "Couldn't connect to database: " . DBI->errstr;
                    if ($DBX) {
                        print
"CONNECTED TO QueueMetrics DATABASE:  $queuemetrics_server_ip|$queuemetrics_dbname\n";
                    }
                    $stmtB =
"INSERT INTO queue_log SET `partition`='P01',time_id='$now_date_epoch',call_id='$uniqueid',queue='NONE',agent='NONE',verb='INFO',data1='DID',data2='$extension',serverid='$queuemetrics_log_id';";
                    $Baffected_rows = $dbhB->do($stmtB);
                    $dbhB->disconnect();
                }
                if ( $did_route =~ /EXTEN/ ) {
                    $XFERexten = "$did_extension";
                    if ($AGILOG) {
                        $agi_string =
"SYSTEM FILTER exiting the DID app, transferring call to $XFERexten @ $exten_context";
                        &agi_output;
                    }
                    print "SET CONTEXT $exten_context\n";
                    $result = <STDIN>;
                    checkresult($result);
                    print "SET EXTENSION $XFERexten\n";
                    $result = <STDIN>;
                    checkresult($result);
                    print "SET PRIORITY 1\n";
                    $result = <STDIN>;
                    checkresult($result);
                    exit;
                }
                if ( $did_route =~ /DID/ ) {
                    if ($AGILOG) {
                        $agi_string =
"SYSTEM FILTER exiting the DID app, transferring call to $filter_match_found @ trunkinbound";
                        &agi_output;
                    }
                    print "SET CONTEXT trunkinbound\n";
                    $result = <STDIN>;
                    checkresult($result);
                    print "SET EXTENSION $filter_match_found\n";
                    $result = <STDIN>;
                    checkresult($result);
                    print "SET PRIORITY 1\n";
                    $result = <STDIN>;
                    checkresult($result);
                    exit;
                }
                if ( $did_route =~ /CALLMENU/ ) {
                    if ( $enable_queuemetrics_logging > 0 ) {
                        $dbhB = DBI->connect(
"DBI:mysql:$queuemetrics_dbname:$queuemetrics_server_ip:3306",
                            "$queuemetrics_login",
                            "$queuemetrics_pass"
                          )
                          or die "Couldn't connect to database: " . DBI->errstr;
                        if ($DBX) {
                            print
"CONNECTED TO QM DATABASE:  $queuemetrics_server_ip|$queuemetrics_dbname\n";
                        }
                        $stmtB =
"INSERT INTO queue_log SET `partition`='P01',time_id='$now_date_epoch',call_id='$uniqueid',queue='NONE',agent='NONE',verb='INFO',data1='IVRSTART',data2='$callerid',data3='$extension',serverid='$queuemetrics_log_id';";
                        $Baffected_rows = $dbhB->do($stmtB);
                        $dbhB->disconnect();
                    }
                    $XFERcontext = "$menu_id";
                    if ($AGILOG) {
                        $agi_string =
"SYSTEM FILTER exiting the DID app, transferring call to CALLMENU $XFERcontext";
                        &agi_output;
                    }
                    print "SET CONTEXT $XFERcontext\n";
                    $result = <STDIN>;
                    checkresult($result);
                    print "SET EXTENSION s\n";
                    $result = <STDIN>;
                    checkresult($result);
                    print "SET PRIORITY 1\n";
                    $result = <STDIN>;
                    checkresult($result);
                    exit;
                }
            }
            $callerid = $original_callerid;
        }
    }
}
$DIDs_in_system = 0;
$stmtA =
"SELECT did_id,did_pattern,did_description,did_active,did_route,extension,exten_context,voicemail_ext,phone,server_ip,user,user_unavailable_action,user_route_settings_ingroup,menu_id,record_call,filter_inbound_number,filter_phone_group_id,filter_url,filter_action,filter_extension,filter_exten_context,filter_voicemail_ext,filter_phone,filter_server_ip,filter_user,filter_user_unavailable_action,filter_user_route_settings_ingroup,filter_group_id,filter_call_handle_method,filter_agent_search_method,filter_list_id,filter_campaign_id,filter_phone_code,filter_menu_id,filter_clean_cid_number,group_id,filter_dnc_campaign,filter_url_did_redirect,no_agent_ingroup_redirect,no_agent_ingroup_id,no_agent_ingroup_extension,pre_filter_phone_group_id,pre_filter_extension,max_queue_ingroup_calls,max_queue_ingroup_id,max_queue_ingroup_extension,inbound_route_answer,pre_filter_recent_call,pre_filter_recent_extension FROM vicidial_inbound_dids where did_pattern = '$extension' and did_active='Y';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
$sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
$sthArows = $sthA->rows;
if ( $sthArows > 0 ) {
    @aryA                               = $sthA->fetchrow_array;
    $did_id                             = $aryA[0];
    $did_pattern                        = $aryA[1];
    $did_description                    = $aryA[2];
    $did_active                         = $aryA[3];
    $did_route                          = $aryA[4];
    $did_extension                      = $aryA[5];
    $exten_context                      = $aryA[6];
    $voicemail_ext                      = $aryA[7];
    $phone                              = $aryA[8];
    $did_server_ip                      = $aryA[9];
    $user                               = $aryA[10];
    $user_unavailable_action            = $aryA[11];
    $user_route_settings_ingroup        = $aryA[12];
    $menu_id                            = $aryA[13];
    $record_call                        = $aryA[14];
    $filter_inbound_number              = $aryA[15];
    $filter_phone_group_id              = $aryA[16];
    $filter_url                         = $aryA[17];
    $filter_action                      = $aryA[18];
    $filter_extension                   = $aryA[19];
    $filter_exten_context               = $aryA[20];
    $filter_voicemail_ext               = $aryA[21];
    $filter_phone                       = $aryA[22];
    $filter_server_ip                   = $aryA[23];
    $filter_user                        = $aryA[24];
    $filter_user_unavailable_action     = $aryA[25];
    $filter_user_route_settings_ingroup = $aryA[26];
    $filter_group_id                    = $aryA[27];
    $filter_call_handle_method          = $aryA[28];
    $filter_agent_search_method         = $aryA[29];
    $filter_list_id                     = $aryA[30];
    $filter_campaign_id                 = $aryA[31];
    $filter_phone_code                  = $aryA[32];
    $filter_menu_id                     = $aryA[33];
    $filter_clean_cid_number            = $aryA[34];
    $group_id                           = $aryA[35];
    $filter_dnc_campaign                = $aryA[36];
    $filter_url_did_redirect            = $aryA[37];
    $no_agent_ingroup_redirect          = $aryA[38];
    $no_agent_ingroup_id                = $aryA[39];
    $no_agent_ingroup_extension         = $aryA[40];
    $pre_filter_phone_group_id          = $aryA[41];
    $pre_filter_extension               = $aryA[42];
    $max_queue_ingroup_calls            = $aryA[43];
    $max_queue_ingroup_id               = $aryA[44];
    $max_queue_ingroup_extension        = $aryA[45];
    $inbound_route_answer               = $aryA[46];
    $pre_filter_recent_call             = $aryA[47];
    $pre_filter_recent_extension        = $aryA[48];
    $DIDs_in_system++;
}
$sthA->finish();
if ( $sthArows < 1 ) {
    $stmtA =
"SELECT did_id,did_pattern,did_description,did_active,did_route,extension,exten_context,voicemail_ext,phone,server_ip,user,user_unavailable_action,user_route_settings_ingroup,menu_id,record_call,filter_inbound_number,filter_phone_group_id,filter_url,filter_action,filter_extension,filter_exten_context,filter_voicemail_ext,filter_phone,filter_server_ip,filter_user,filter_user_unavailable_action,filter_user_route_settings_ingroup,filter_group_id,filter_call_handle_method,filter_agent_search_method,filter_list_id,filter_campaign_id,filter_phone_code,filter_menu_id,filter_clean_cid_number,group_id,filter_dnc_campaign,filter_url_did_redirect,no_agent_ingroup_redirect,no_agent_ingroup_id,no_agent_ingroup_extension,pre_filter_phone_group_id,pre_filter_extension,max_queue_ingroup_calls,max_queue_ingroup_id,max_queue_ingroup_extension,inbound_route_answer,pre_filter_recent_call,pre_filter_recent_extension FROM vicidial_inbound_dids where did_pattern = 'default' and did_active='Y';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $DIDs_in_system = $sthA->rows;
    if ( $DIDs_in_system > 0 ) {
        @aryA                               = $sthA->fetchrow_array;
        $did_id                             = $aryA[0];
        $did_pattern                        = $aryA[1];
        $did_description                    = $aryA[2];
        $did_active                         = $aryA[3];
        $did_route                          = $aryA[4];
        $did_extension                      = $aryA[5];
        $exten_context                      = $aryA[6];
        $voicemail_ext                      = $aryA[7];
        $phone                              = $aryA[8];
        $did_server_ip                      = $aryA[9];
        $user                               = $aryA[10];
        $user_unavailable_action            = $aryA[11];
        $user_route_settings_ingroup        = $aryA[12];
        $menu_id                            = $aryA[13];
        $record_call                        = $aryA[14];
        $filter_inbound_number              = $aryA[15];
        $filter_phone_group_id              = $aryA[16];
        $filter_url                         = $aryA[17];
        $filter_action                      = $aryA[18];
        $filter_extension                   = $aryA[19];
        $filter_exten_context               = $aryA[20];
        $filter_voicemail_ext               = $aryA[21];
        $filter_phone                       = $aryA[22];
        $filter_server_ip                   = $aryA[23];
        $filter_user                        = $aryA[24];
        $filter_user_unavailable_action     = $aryA[25];
        $filter_user_route_settings_ingroup = $aryA[26];
        $filter_group_id                    = $aryA[27];
        $filter_call_handle_method          = $aryA[28];
        $filter_agent_search_method         = $aryA[29];
        $filter_list_id                     = $aryA[30];
        $filter_campaign_id                 = $aryA[31];
        $filter_phone_code                  = $aryA[32];
        $filter_menu_id                     = $aryA[33];
        $filter_clean_cid_number            = $aryA[34];
        $group_id                           = $aryA[35];
        $filter_dnc_campaign                = $aryA[36];
        $filter_url_did_redirect            = $aryA[37];
        $no_agent_ingroup_redirect          = $aryA[38];
        $no_agent_ingroup_id                = $aryA[39];
        $no_agent_ingroup_extension         = $aryA[40];
        $pre_filter_phone_group_id          = $aryA[41];
        $pre_filter_extension               = $aryA[42];
        $max_queue_ingroup_calls            = $aryA[43];
        $max_queue_ingroup_id               = $aryA[44];
        $max_queue_ingroup_extension        = $aryA[45];
        $inbound_route_answer               = $aryA[46];
        $pre_filter_recent_call             = $aryA[47];
        $pre_filter_recent_extension        = $aryA[48];
    }
    $sthA->finish();
}
$stmtA =
"INSERT INTO vicidial_did_log SET uniqueid='$uniqueid',channel='$channel',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',call_date='$SQLdate',did_id='$did_id',did_route='$did_route';";
if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
$affected_rowsL = $dbhA->do($stmtA);
if ($AGILOG) {
    $agi_string = "--    DID LOG : |$affected_rowsL|$stmtA|";
    &agi_output;
}
$stmtA =
"INSERT INTO call_log SET uniqueid='$unique_id', channel='$channel', channel_group='DID_INBOUND', server_ip='$VARserver_ip', type='$type', extension='$extension', number_dialed='$extension', caller_code='$callerid', start_time='$SQLdate', start_epoch='$now_date_epoch';";
$affected_rowsC = $dbhA->do($stmtA);
if ($AGILOG) {
    $agi_string = "--    CALL LOG : |$affected_rowsC|$stmtA|";
    &agi_output;
}
if ($AGILOG) {
    $did_string =
"$SQLdate|$uniqueid|$channel|$extension|$callerid|$calleridname|$did_id|$did_route|";
    &did_output;
}
if ( $did_agent_log =~ /Y/ ) {
    if ( $did_route !~ /IN_GROUP/ ) { $group_id = ''; }
    $stmtA =
"INSERT INTO vicidial_did_agent_log SET uniqueid='$uniqueid',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',call_date='$SQLdate',did_id='$did_id',did_route='$did_route',user='VDCL',group_id='$group_id',did_description='$did_description';";
    if (   ( $tables_use_alt_log_db =~ /did_agent_log/i )
        && ( length($alt_log_server_ip) > 4 )
        && ( length($alt_log_dbname) > 0 ) )
    {
        $dbhD =
          DBI->connect( "DBI:mysql:$alt_log_dbname:$alt_log_server_ip:3306",
            "$alt_log_login", "$alt_log_pass" )
          or die "Couldn't connect to database: " . DBI->errstr;
        if ($AGILOG) {
            $agi_string =
"CONNECTED TO ALT-LOG DATABASE:  $alt_log_server_ip|$alt_log_dbname|$uniqueid";
            &agi_output;
        }
        $affected_rowsAL = $dbhD->do($stmtA);
        $dbhD->disconnect();
    }
    else {
        $affected_rowsAL = $dbhA->do($stmtA);
    }
    if ($AGILOG) {
        $agi_string = "--    DID AGENT LOG : |$affected_rowsAL|$stmtA|";
        &agi_output;
    }
}
if ( $DIDs_in_system < 1 ) {
    if ($AGILOG) {
        $did_string =
"NO default DID DEFINED! EXITING...   $SQLdate|$uniqueid|$channel|$extension|$callerid|$calleridname|";
        &did_output;
    }
    exit;
}
if ( $record_call =~ /Y/ ) {
    $insert_recording_id = '';
    $filename            = "$tsSQLdate$US$extension$US$callerid";
    %ast_ver_str         = parse_asterisk_version($asterisk_version);
    if ( ( $ast_ver_str{major} = 1 ) && ( $ast_ver_str{minor} < 6 ) ) {
        $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$filename");
    }
    else {
        $AGI->exec( "Monitor",
            "wav,/var/spool/asterisk/monitor/MIX/$filename" );
    }
    $stmtA =
"INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$callerid','$SQLdate','$now_date_epoch','0','$filename','0','$extension','$filename','$unique_id');";
    $affected_rowsR = $dbhA->do($stmtA);
    if ( $affected_rowsR > 0 ) {
        $stmtB = "select LAST_INSERT_ID() LIMIT 1;";
        $sthA  = $dbhA->prepare($stmtB) or die "preparing: ", $dbhA->errstr;
        $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
        $sthArows = $sthA->rows;
        if ( $sthArows > 0 ) {
            @aryA                = $sthA->fetchrow_array;
            $insert_recording_id = $aryA[0];
        }
        $sthA->finish();
    }
    if ($AGILOG) {
        $did_string =
          "--    RECORDING LOG : |$affected_rowsR|$insert_recording_id|$stmtA|";
        &did_output;
    }
}
$cbc = 0;
$stmtA =
"SELECT voicemail_dump_exten,ext_context,answer_transfer_agent,local_gmt,asterisk_version,max_vicidial_trunks,voicemail_dump_exten_no_inst FROM servers where server_ip = '$VARserver_ip';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
$sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
$sthArows = $sthA->rows;
while ( $sthArows > $cbc ) {
    @aryA                         = $sthA->fetchrow_array;
    $DBvoicemail_dump_exten       = $aryA[0];
    $DBext_context                = $aryA[1];
    $DBanswer_transfer_agent      = $aryA[2];
    $DBSERVER_GMT                 = $aryA[3];
    $DBasterisk_version           = $aryA[4];
    $DBmax_vicidial_trunks        = $aryA[5];
    $voicemail_dump_exten_no_inst = $aryA[6];

    if ($DBvoicemail_dump_exten) {
        $voicemail_dump_exten = $DBvoicemail_dump_exten;
    }
    if ($DBext_context) { $ext_context = $DBext_context; }
    if ($DBanswer_transfer_agent) {
        $answer_transfer_agent = $DBanswer_transfer_agent;
    }
    if ($DBSERVER_GMT)       { $SERVER_GMT = $DBSERVER_GMT; }
    if ($DBasterisk_version) { $AST_ver    = $DBasterisk_version; }
    if ($DBmax_vicidial_trunks) {
        $max_vicidial_trunks = $DBmax_vicidial_trunks;
    }
    $cbc++;
}
$sthA->finish();
if ( length($filter_clean_cid_number) > 1 ) {
    $original_callerid     = $callerid;
    $filter_number_altered = 0;
    if ( $filter_clean_cid_number =~ /R\d/ ) {
        @filter_rule = split( /R/, $filter_clean_cid_number );
        $filter_rule[1] =~ s/ .*//gi;
        while ( length($callerid) > $filter_rule[1] ) { $callerid =~ s/^.//gi; }
        if ( length($callerid) != length($original_callerid) ) {
            $filter_number_altered++;
        }
    }
    if ( $filter_clean_cid_number =~ /L\d/ ) {
        @filter_rule = split( /L/, $filter_clean_cid_number );
        $filter_rule[1] =~ s/ .*//gi;
        $filter_rule_reg = $filter_rule[1];
        $callerid =~ s/^$filter_rule_reg//gi;
        if ( length($callerid) != length($original_callerid) ) {
            $filter_number_altered++;
        }
    }
    if ( $filter_clean_cid_number =~ /T\d/ ) {
        @filter_rule = split( /T/, $filter_clean_cid_number );
        $filter_rule[1] =~ s/ .*//gi;
        $callerid = substr( $callerid, 0, $filter_rule[1] );
        if ( length($callerid) != length($original_callerid) ) {
            $filter_number_altered++;
        }
    }
    if ( $filter_number_altered > 0 ) {
        $newcallerid = "\"$calleridname <$callerid>\"";
        $AGI->set_callerid($newcallerid);
        if ($AGILOG) {
            $agi_string =
"filter clean callerid, setting new CID: |$callerid|$calleridname|$newcallerid|$filter_clean_cid_number|   Old: |$original_callerid|";
            &agi_output;
        }
    }
}
$pre_filter_match_found = 0;
$filter_match_found     = 0;
if (   ( length($pre_filter_phone_group_id) > 0 )
    && ( length($pre_filter_extension) > 0 ) )
{
    if ($AGILOG) {
        $agi_string =
"pre-filtering active: |$extension|$pre_filter_phone_group_id|$pre_filter_extension|$filter_clean_cid_number|$callerid";
        &agi_output;
    }
    $temp_cid_test = $callerid;
    if ( length($callerid) < 1 ) { $temp_cid_test = 'BLANK'; }
    $stmtA =
"SELECT count(*) FROM vicidial_filter_phone_numbers where filter_phone_group_id='$pre_filter_phone_group_id' and phone_number='$temp_cid_test';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;
    if ( $sthArows > 0 ) {
        @aryA                   = $sthA->fetchrow_array;
        $pre_filter_match_found = $aryA[0];
    }
    $sthA->finish();
    if ( $pre_filter_match_found > 0 ) {
        $did_route          = 'DID';
        $did_extension      = $pre_filter_extension;
        $filter_match_found = $pre_filter_extension;
        $exten_context      = 'trunkinbound';
        $route_type         = 'PREFILTER';
        if ($AGILOG) {
            $agi_string =
"PRE-Filter match found: |$pre_filter_match_found|$pre_filter_phone_group_id|$pre_filter_extension|$did_route|";
            &agi_output;
        }
        $stmtA =
"UPDATE vicidial_did_log SET did_route='PF_$did_route' where uniqueid='$uniqueid' and channel='$channel' and server_ip='$VARserver_ip' and caller_id_number='$callerid' and call_date='$SQLdate';";
        if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
        $affected_rowsL = $dbhA->do($stmtA);
        if ($AGILOG) {
            $agi_string = "--    DID UPDATE LOG : |$affected_rowsL|$stmtA|";
            &agi_output;
        }
    }
}
$pre_filter_recent_outbound_found = 0;
$pre_filter_recent_inbound_found  = 0;
$outbound_searchSQL               = '';
$inbound_searchSQL                = '';
if (   ( length($pre_filter_recent_call) > 0 )
    && ( length($pre_filter_recent_extension) > 0 ) )
{
    if ($AGILOG) {
        $agi_string =
"pre-filter recent call active: |$extension|$pre_filter_recent_call|$pre_filter_recent_extension|$filter_clean_cid_number|$callerid";
        &agi_output;
    }
    $temp_cid_test = $callerid;
    if ( length($callerid) < 1 ) { $temp_cid_test = 'BLANK'; }
    $CQcontainer_entry = '';
    $stmtA =
"SELECT container_entry FROM vicidial_settings_containers where container_id='$pre_filter_recent_call';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;

    if ( $sthArows > 0 ) {
        $outbound_recent_call_check_type = '';
        $outbound_recent_call_days       = 0;
        $outbound_recent_call_campaigns  = '';
        $outbound_recent_call_statuses   = '';
        $inbound_recent_call_check_type  = '';
        $inbound_recent_call_days        = 0;
        $inbound_recent_call_groups      = '';
        $inbound_recent_call_statuses    = '';
        @aryA                            = $sthA->fetchrow_array;
        $RCcontainer_entry               = $aryA[0];
        $RCcontainer_entry =~ s/\r|\t|\'|\"//gi;
        @RCfilter_settings = split( /\n/, $RCcontainer_entry );
        $sea               = 0;

        foreach (@RCfilter_settings) {
            if ( $DBX > 0 ) {
                print STDERR "RC DEBUG 0: $sea|$RCfilter_settings[$sea]|\n";
            }
            if ( $RCfilter_settings[$sea] =~
                /^outbound_recent_call_check_type => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^outbound_recent_call_check_type => //gi;
                $outbound_recent_call_check_type = $RCfilter_settings[$sea];
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 2:    outbound_recent_call_check_type FOUND: |$outbound_recent_call_check_type|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~ /^outbound_recent_call_days => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^outbound_recent_call_days => //gi;
                $outbound_recent_call_days = $RCfilter_settings[$sea];
                $outbound_recent_call_days =~ s/[^-0-9]//gi;
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 2:    outbound_recent_call_days FOUND: |$outbound_recent_call_days|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~
                /^outbound_recent_call_campaigns => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^outbound_recent_call_campaigns => //gi;
                $outbound_recent_call_campaigns = $RCfilter_settings[$sea];
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 3:    outbound_recent_call_campaigns FOUND: |$outbound_recent_call_campaigns|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~
                /^outbound_recent_call_statuses => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^outbound_recent_call_statuses => //gi;
                $outbound_recent_call_statuses = $RCfilter_settings[$sea];
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 4:    outbound_recent_call_statuses FOUND: |$outbound_recent_call_statuses|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~
                /^inbound_recent_call_check_type => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^inbound_recent_call_check_type => //gi;
                $inbound_recent_call_check_type = $RCfilter_settings[$sea];
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 5:    inbound_recent_call_check_type FOUND: |$inbound_recent_call_check_type|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~ /^inbound_recent_call_days => / ) {
                $RCfilter_settings[$sea] =~ s/^inbound_recent_call_days => //gi;
                $inbound_recent_call_days = $RCfilter_settings[$sea];
                $inbound_recent_call_days =~ s/[^-0-9]//gi;
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 6:    inbound_recent_call_days FOUND: |$inbound_recent_call_days|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~ /^inbound_recent_call_groups => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^inbound_recent_call_groups => //gi;
                $inbound_recent_call_groups = $RCfilter_settings[$sea];
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 7:    inbound_recent_call_groups FOUND: |$inbound_recent_call_groups|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            if ( $RCfilter_settings[$sea] =~
                /^inbound_recent_call_statuses => / )
            {
                $RCfilter_settings[$sea] =~
                  s/^inbound_recent_call_statuses => //gi;
                $inbound_recent_call_statuses = $RCfilter_settings[$sea];
                if ( $DBX > 0 ) {
                    print STDERR
"RC DEBUG 8:    inbound_recent_call_statuses FOUND: |$inbound_recent_call_statuses|   $sea|$RCfilter_settings[$sea]|\n";
                }
            }
            $sea++;
        }
        $outbound_search_table = 'vicidial_log';
        $outbound_search_date  = 'call_date';
        if (   ( $outbound_recent_call_check_type =~ /x-y-days-range/i )
            && ( $outbound_recent_call_check_type =~ /lead|log/i )
            && ( length($outbound_recent_call_campaigns) > 1 )
            && ( length($outbound_recent_call_statuses) > 0 ) )
        {
            if (   ( length($outbound_recent_call_days) > 2 )
                && ( $outbound_recent_call_days =~ /\d-\d/ ) )
            {
                if ( $outbound_recent_call_check_type =~ /lead/i ) {
                    $outbound_search_table = 'vicidial_list';
                    $outbound_search_date  = 'last_local_call_time';
                }
                @outbound_recent_call_days_ARY =
                  split( /-/, $outbound_recent_call_days );
                $temp_days_start = $outbound_recent_call_days_ARY[0];
                $temp_days_end   = $outbound_recent_call_days_ARY[1];
                $temp_days_start =~ s/\D//gi;
                $temp_days_end   =~ s/\D//gi;
                if (   ( length($temp_days_start) > 0 )
                    && ( length($temp_days_start) > 0 ) )
                {
                    $outbound_searchSQL =
"and ($outbound_search_date <= CONCAT(DATE_ADD(CURDATE(), INTERVAL -$temp_days_start DAY),' 23:59:59')) and ($outbound_search_date >= CONCAT(DATE_ADD(CURDATE(), INTERVAL -$temp_days_end DAY),' 00:00:00'))";
                }
                if ( $outbound_recent_call_campaigns !~ /--ALL--/ ) {
                    $outbound_recent_call_campaigns =~ s/\|/','/gi;
                    if ( $outbound_recent_call_check_type =~ /lead/i ) {
                        $temp_lists = '';
                        $cl         = 0;
                        $stmtA =
"SELECT list_id FROM vicidial_lists where campaign_id IN('$outbound_recent_call_campaigns');";
                        $sthA = $dbhA->prepare($stmtA)
                          or die "preparing: ", $dbhA->errstr;
                        $sthA->execute
                          or die "executing: $stmtA ", $dbhA->errstr;
                        $sthArows = $sthA->rows;
                        while ( $sthArows > $cl ) {
                            @aryA = $sthA->fetchrow_array;
                            if ( $cl > 0 ) { $temp_lists .= ","; }
                            $temp_lists .= "'$aryA[0]'";
                            $cl++;
                        }
                        $sthA->finish();
                        if ( length($temp_lists) < 3 ) {
                            $temp_lists = "'99999999999999999999'";
                        }
                        $outbound_searchSQL .= " and list_id IN($temp_lists)";
                    }
                    else {
                        $outbound_searchSQL .=
" and campaign_id IN('$outbound_recent_call_campaigns')";
                    }
                }
                if ( $outbound_recent_call_statuses !~ /--ALL--/ ) {
                    $outbound_recent_call_statuses =~ s/\|/','/gi;
                    $outbound_searchSQL .=
                      " and status IN('$outbound_recent_call_statuses')";
                }
            }
        }
        $inbound_search_table = 'vicidial_closer_log';
        $inbound_search_date  = 'call_date';
        if (   ( $inbound_recent_call_check_type =~ /x-y-days-range/i )
            && ( $inbound_recent_call_check_type =~ /lead|log/i )
            && ( length($inbound_recent_call_groups) > 1 )
            && ( length($inbound_recent_call_statuses) > 0 ) )
        {
            if (   ( length($inbound_recent_call_days) > 2 )
                && ( $inbound_recent_call_days =~ /\d-\d/ ) )
            {
                if ( $inbound_recent_call_check_type =~ /lead/i ) {
                    $inbound_search_table = 'vicidial_list';
                    $inbound_search_date  = 'last_local_call_time';
                }
                @inbound_recent_call_days_ARY =
                  split( /-/, $inbound_recent_call_days );
                $temp_days_start = $inbound_recent_call_days_ARY[0];
                $temp_days_end   = $inbound_recent_call_days_ARY[1];
                $temp_days_start =~ s/\D//gi;
                $temp_days_end   =~ s/\D//gi;
                if (   ( length($temp_days_start) > 0 )
                    && ( length($temp_days_start) > 0 ) )
                {
                    $inbound_searchSQL =
"and ($inbound_search_date <= CONCAT(DATE_ADD(CURDATE(), INTERVAL -$temp_days_start DAY),' 23:59:59')) and ($inbound_search_date >= CONCAT(DATE_ADD(CURDATE(), INTERVAL -$temp_days_end DAY),' 00:00:00'))";
                }
                if ( $inbound_recent_call_groups !~ /--ALL--/ ) {
                    $inbound_recent_call_groups =~ s/\|/','/gi;
                    if ( $inbound_recent_call_check_type =~ /lead/i ) {
                        $temp_lists = '';
                        $cl         = 0;
                        $stmtA =
"SELECT list_id FROM vicidial_lists where campaign_id IN('$inbound_recent_call_groups');";
                        $sthA = $dbhA->prepare($stmtA)
                          or die "preparing: ", $dbhA->errstr;
                        $sthA->execute
                          or die "executing: $stmtA ", $dbhA->errstr;
                        $sthArows = $sthA->rows;
                        while ( $sthArows > $cl ) {
                            @aryA = $sthA->fetchrow_array;
                            if ( $cl > 0 ) { $temp_lists .= ","; }
                            $temp_lists .= "'$aryA[0]'";
                            $cl++;
                        }
                        $sthA->finish();
                        if ( length($temp_lists) < 3 ) {
                            $temp_lists = "'99999999999999999999'";
                        }
                        $inbound_searchSQL .= " and list_id IN($temp_lists)";
                    }
                    else {
                        $inbound_searchSQL .=
                          " and campaign_id IN('$inbound_recent_call_groups')";
                    }
                }
                if ( $inbound_recent_call_statuses !~ /--ALL--/ ) {
                    $inbound_recent_call_statuses =~ s/\|/','/gi;
                    $inbound_searchSQL .=
                      " and status IN('$inbound_recent_call_statuses')";
                }
            }
        }
    }
    $sthA->finish();
    if ( length($outbound_searchSQL) > 10 ) {
        $stmtA =
"SELECT count(*) FROM $outbound_search_table where phone_number='$temp_cid_test' $outbound_searchSQL;";
        $sthA = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
        $sthA->execute or die "executing: $stmtA ",          $dbhA->errstr;
        $sthArows = $sthA->rows;
        if ( $sthArows > 0 ) {
            @aryA                             = $sthA->fetchrow_array;
            $pre_filter_recent_outbound_found = $aryA[0];
        }
        if ($AGILOG) {
            $agi_string =
"--    DID RECENT OUTBOUND CALL SEARCH : |$pre_filter_recent_outbound_found|$stmtA|";
            &agi_output;
        }
    }
    if ( length($inbound_searchSQL) > 10 ) {
        $stmtA =
"SELECT count(*) FROM $inbound_search_table where phone_number='$temp_cid_test' $inbound_searchSQL;";
        $sthA = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
        $sthA->execute or die "executing: $stmtA ",          $dbhA->errstr;
        $sthArows = $sthA->rows;
        if ( $sthArows > 0 ) {
            @aryA                            = $sthA->fetchrow_array;
            $pre_filter_recent_inbound_found = $aryA[0];
        }
        if ($AGILOG) {
            $agi_string =
"--    DID RECENT INBOUND CALL SEARCH : |$pre_filter_recent_inbound_found|$stmtA|";
            &agi_output;
        }
    }
    $sthA->finish();
    if (   ( $pre_filter_recent_inbound_found > 0 )
        || ($pre_filter_recent_outbound_found) )
    {
        $did_route          = 'DID';
        $did_extension      = $pre_filter_recent_extension;
        $filter_match_found = $pre_filter_recent_extension;
        $exten_context      = 'trunkinbound';
        $route_type         = 'PRERECENT';
        if ($AGILOG) {
            $agi_string =
"PRE-Filter Recent Call match found: |$pre_filter_recent_outbound_found|$pre_filter_recent_inbound_found|$pre_filter_recent_call|$pre_filter_recent_extension|$did_route|";
            &agi_output;
        }
        $stmtA =
"UPDATE vicidial_did_log SET did_route='PFR_$did_route' where uniqueid='$uniqueid' and channel='$channel' and server_ip='$VARserver_ip' and caller_id_number='$callerid' and call_date='$SQLdate';";
        if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
        $affected_rowsL = $dbhA->do($stmtA);
        if ($AGILOG) {
            $agi_string = "--    DID UPDATE LOG : |$affected_rowsL|$stmtA|";
            &agi_output;
        }
    }
    else {
        if ($AGILOG) {
            $agi_string =
"--    DID NO RECENT CALL FOUND : |$outbound_searchSQL|$inbound_searchSQL|";
            &agi_output;
        }
    }
}
if (   ( $filter_inbound_number =~ /GROUP|URL|DNC_INTERNAL|DNC_CAMPAIGN/ )
    && ( $pre_filter_match_found < 1 ) )
{
    if ($AGILOG) {
        $agi_string =
"filtering active: |$extension|$filter_inbound_number|$filter_phone_group_id|$filter_url|$filter_action|$filter_clean_cid_number|";
        &agi_output;
    }
    if ( $filter_inbound_number =~ /GROUP/ ) {
        $temp_cid_test = $callerid;
        if ( length($callerid) < 1 ) { $temp_cid_test = 'BLANK'; }
        $stmtA =
"SELECT count(*) FROM vicidial_filter_phone_numbers where filter_phone_group_id='$filter_phone_group_id' and phone_number='$temp_cid_test';";
        $sthA = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
        $sthA->execute or die "executing: $stmtA ",          $dbhA->errstr;
        $sthArows = $sthA->rows;
        if ( $sthArows > 0 ) {
            @aryA               = $sthA->fetchrow_array;
            $filter_match_found = $aryA[0];
        }
        $sthA->finish();
        if (   ( $filter_match_found < 1 )
            && ( $filter_inbound_number =~ /AREACODE/ ) )
        {
            $alt_areacode = substr( $callerid, 0, 3 );
            $alt_areacode .= "XXXXXXX";
            $stmtB =
"SELECT count(*) FROM vicidial_filter_phone_numbers where filter_phone_group_id='$filter_phone_group_id' and phone_number='$alt_areacode';";
            $sthA = $dbhA->prepare($stmtB) or die "preparing: ", $dbhA->errstr;
            $sthA->execute or die "executing: $stmtA ",          $dbhA->errstr;
            $sthArows = $sthA->rows;
            if ( $sthArows > 0 ) {
                @aryA               = $sthA->fetchrow_array;
                $filter_match_found = $aryA[0];
            }
            $sthA->finish();
        }
        if ($AGILOG) {
            $agi_string = "GROUP: |$filter_match_found|$stmtA|$stmtB|";
            &agi_output;
        }
    }
    elsif ( $filter_inbound_number =~ /DNC_INTERNAL/ ) {
        $alt_areacode = substr( $callerid, 0, 3 );
        $alt_areacode .= "XXXXXXX";
        $stmtA =
"SELECT count(*) FROM vicidial_dnc where phone_number IN('$callerid','$alt_areacode');";
        $sthA = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
        $sthA->execute or die "executing: $stmtA ",          $dbhA->errstr;
        $sthArows = $sthA->rows;
        if ( $sthArows > 0 ) {
            @aryA               = $sthA->fetchrow_array;
            $filter_match_found = $aryA[0];
        }
        $sthA->finish();
        if ($AGILOG) {
            $agi_string = "DNC_INTERNAL: |$filter_match_found|$stmtA|";
            &agi_output;
        }
    }
    elsif ( $filter_inbound_number =~ /DNC_CAMPAIGN/ ) {
        $alt_areacode = substr( $callerid, 0, 3 );
        $alt_areacode .= "XXXXXXX";
        $stmtA =
"SELECT count(*) FROM vicidial_campaign_dnc where campaign_id='$filter_dnc_campaign' and phone_number IN('$callerid','$alt_areacode');";
        $sthA = $dbhA->prepare($stmtA) or die "preparing: ", $dbhA->errstr;
        $sthA->execute or die "executing: $stmtA ",          $dbhA->errstr;
        $sthArows = $sthA->rows;
        if ( $sthArows > 0 ) {
            @aryA               = $sthA->fetchrow_array;
            $filter_match_found = $aryA[0];
        }
        $sthA->finish();
        if ($AGILOG) {
            $agi_string = "DNC_CAMPAIGN: |$filter_match_found|$stmtA|";
            &agi_output;
        }
    }
    else {
        $curlbin = '';
        if ( -e ('/bin/curl') ) { $curlbin = '/bin/curl'; }
        else {
            if ( -e ('/usr/bin/curl') ) { $curlbin = '/usr/bin/curl'; }
            else {
                if ( -e ('/usr/local/bin/curl') ) {
                    $curlbin = '/usr/local/bin/curl';
                }
                else {
                    if ($AGILOG) {
                        $agi_string =
                          "ERROR: cannot filter by URL, curl binary not found";
                        &agi_output;
                    }
                }
            }
        }
        if (   ( length($curlbin) > 4 )
            && ( $filter_url =~ /http/i )
            && ( length($filter_url) > 8 ) )
        {
            $filter_url =~ s/^VAR|^ //gi;
            $filter_url =~ s/--A--phone_number--B--/$callerid/gi;
            $filter_url =~ s/--A--did_pattern--B--/$did_pattern/gi;
            $filter_url =~ s/--A--uniqueid--B--/$uniqueid/gi;
            $filter_url =~ s/--A--channel--B--/$channel/gi;
            $filter_url =~ s/--A--server_ip--B--/$VARserver_ip/gi;
            $filter_url =~ s/&/\\&/gi;
            $filter_url =~ s/ /+/gi;
            $SQL_log = "$filter_url";
            $SQL_log =~ s/;|\||\\//gi;
            $stmtA =
"INSERT INTO vicidial_url_log SET uniqueid='$uniqueid',url_date=NOW(),url_type='DID_FILTER',url='$SQL_log',url_response='';";
            $affected_rows = $dbhA->do($stmtA);
            $stmtB         = "SELECT LAST_INSERT_ID() LIMIT 1;";
            $sthA = $dbhA->prepare($stmtB) or die "preparing: ", $dbhA->errstr;
            $sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
            $sthArows = $sthA->rows;

            if ( $sthArows > 0 ) {
                @aryA   = $sthA->fetchrow_array;
                $url_id = $aryA[0];
            }
            $sthA->finish();
            my $secW = time();
            @curl_output = `$curlbin $filter_url`;
            my $secY         = time();
            my $response_sec = ( $secY - $secW );
            $k           = 0;
            $full_output = '';

            foreach (@curl_output) {
                $full_output_raw .= $curl_output[$k];
                $k++;
            }
            $full_output = $full_output_raw;
            $full_output =~ s/\D//gi;
            if ( $full_output > 0 ) {
                $filter_match_found = $full_output;
                if ( $filter_url_did_redirect =~ /Y/ ) {
                    $did_route = 'DID';
                    if ($AGILOG) {
                        $agi_string =
"Filter URL DID Redirect found: |$filter_match_found|$filter_url_did_redirect|$did_route|";
                        &agi_output;
                    }
                }
            }
            $full_output_raw =~ s/;|\||\\//gi;
            $stmtA =
"UPDATE vicidial_url_log SET url_response='$full_output_raw|$full_output',response_sec='$response_sec' where url_log_id='$url_id';";
            $affected_rows = $dbhA->do($stmtA);
            if ($AGILOG) {
                $agi_string =
"URL filter search response: |$filter_match_found|$full_output|$filter_url|$affected_rows|";
                &agi_output;
            }
        }
    }
    if ( $filter_match_found > 0 ) {
        if ( $did_route !~ /DID/ ) { $did_route = $filter_action; }
        $did_extension               = $filter_extension;
        $exten_context               = $filter_exten_context;
        $voicemail_ext               = $filter_voicemail_ext;
        $phone                       = $filter_phone;
        $did_server_ip               = $filter_server_ip;
        $user                        = $filter_user;
        $user_unavailable_action     = $filter_user_unavailable_action;
        $user_route_settings_ingroup = $filter_user_route_settings_ingroup;
        $menu_id                     = $filter_menu_id;
        $route_type                  = 'FILTER';

        if ($AGILOG) {
            $agi_string =
"Filter match found: |$filter_match_found|$filter_inbound_number|$filter_action|$did_route|";
            &agi_output;
        }
        $stmtA =
"UPDATE vicidial_did_log SET did_route='F_$did_route' where uniqueid='$uniqueid' and channel='$channel' and server_ip='$VARserver_ip' and caller_id_number='$callerid' and call_date='$SQLdate';";
        if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
        $affected_rowsL = $dbhA->do($stmtA);
        if ($AGILOG) {
            $agi_string = "--    DID UPDATE LOG : |$affected_rowsL|$stmtA|";
            &agi_output;
        }
    }
}
$no_agent_redirect_bypass = 1;
if (   ( $no_agent_ingroup_redirect =~ /Y|NO_PAUSED|READY_ONLY/ )
    && ( $pre_filter_match_found < 1 )
    && ( $filter_match_found < 1 ) )
{
    if ($AGILOG) {
        $agi_string =
"no-agent active: |$extension|$no_agent_ingroup_redirect|$no_agent_ingroup_id|$no_agent_ingroup_extension|$filter_clean_cid_number|";
        &agi_output;
    }
    $queue_date_epoch = time();
    $BDtarget         = ( $queue_date_epoch - 5 );
    ( $Bsec, $Bmin, $Bhour, $Bmday, $Bmon, $Byear, $Bwday, $Byday, $Bisdst ) =
      localtime($BDtarget);
    $Byear = ( $Byear + 1900 );
    $Bmon++;
    if ( $Bmon < 10 )  { $Bmon  = "0$Bmon"; }
    if ( $Bmday < 10 ) { $Bmday = "0$Bmday"; }
    if ( $Bhour < 10 ) { $Bhour = "0$Bhour"; }
    if ( $Bmin < 10 )  { $Bmin  = "0$Bmin"; }
    if ( $Bsec < 10 )  { $Bsec  = "0$Bsec"; }
    $BDtsSQLdate = "$Byear$Bmon$Bmday$Bhour$Bmin$Bsec";
    $NPsql       = '';

    if ( $no_agent_ingroup_redirect =~ /NO_PAUSED/ ) {
        $NPsql = "and status NOT IN('PAUSED')";
    }
    if ( $no_agent_ingroup_redirect =~ /READY_ONLY/ ) {
        $NPsql = "and status IN('READY','CLOSER')";
    }
    $SQL_group_id = $no_agent_ingroup_id;
    $SQL_group_id =~ s/_/\\_/gi;
    $stmtA =
"SELECT count(*) FROM vicidial_live_agents where closer_campaigns LIKE \"% $SQL_group_id %\" and last_update_time > '$BDtsSQLdate' $NPsql;";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;
    if ( $sthArows > 0 ) {
        @aryA                     = $sthA->fetchrow_array;
        $no_agent_redirect_bypass = $aryA[0];
    }
    $sthA->finish();
    if ( $no_agent_redirect_bypass < 1 ) {
        $did_route     = 'EXTEN';
        $did_extension = $no_agent_ingroup_extension;
        $exten_context = 'default';
        $route_type    = 'NOAGENT';
        if ($AGILOG) {
            $agi_string =
"No-Agent Redirect: |$no_agent_redirect_bypass|$no_agent_ingroup_redirect|$did_extension|$no_agent_ingroup_id|$stmtA|";
            &agi_output;
        }
        $stmtA =
"UPDATE vicidial_did_log SET did_route='NA_$did_route' where uniqueid='$uniqueid' and channel='$channel' and server_ip='$VARserver_ip' and caller_id_number='$callerid' and call_date='$SQLdate';";
        if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
        $affected_rowsL = $dbhA->do($stmtA);
        if ($AGILOG) {
            $agi_string = "--    DID UPDATE LOG : |$affected_rowsL|$stmtA|";
            &agi_output;
        }
    }
    else {
        if ($AGILOG) {
            $agi_string =
"No-Agent Debug: |$no_agent_redirect_bypass|$no_agent_ingroup_redirect|$did_extension|$no_agent_ingroup_id|$stmtA|";
            &agi_output;
        }
    }
}
$max_queue_redirect_bypass = 1;
if (   ( ( $max_queue_ingroup_calls > 0 ) || ( $max_queue_ingroup_calls < 0 ) )
    && ( $no_agent_redirect_bypass > 0 )
    && ( $pre_filter_match_found < 1 )
    && ( $filter_match_found < 1 ) )
{
    if ($AGILOG) {
        $agi_string =
"max queue active: |$extension|$max_queue_ingroup_calls|$max_queue_ingroup_id|$max_queue_ingroup_extension|";
        &agi_output;
    }
    $queue_date_epoch = time();
    $BDtarget         = ( $queue_date_epoch - 60 );
    ( $Bsec, $Bmin, $Bhour, $Bmday, $Bmon, $Byear, $Bwday, $Byday, $Bisdst ) =
      localtime($BDtarget);
    $Byear = ( $Byear + 1900 );
    $Bmon++;
    if ( $Bmon < 10 )  { $Bmon  = "0$Bmon"; }
    if ( $Bmday < 10 ) { $Bmday = "0$Bmday"; }
    if ( $Bhour < 10 ) { $Bhour = "0$Bhour"; }
    if ( $Bmin < 10 )  { $Bmin  = "0$Bmin"; }
    if ( $Bsec < 10 )  { $Bsec  = "0$Bsec"; }
    $BDtsSQLdate = "$Byear$Bmon$Bmday$Bhour$Bmin$Bsec";
    $stmtA =
"SELECT count(*) FROM vicidial_auto_calls where campaign_id='$max_queue_ingroup_id' and status IN('LIVE','IVR') and last_update_time > '$BDtsSQLdate';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;

    if ( $sthArows > 0 ) {
        @aryA                      = $sthA->fetchrow_array;
        $max_queue_redirect_bypass = $aryA[0];
    }
    $sthA->finish();
    if ( $max_queue_redirect_bypass >= $max_queue_ingroup_calls ) {
        $did_route     = 'EXTEN';
        $did_extension = $max_queue_ingroup_extension;
        $exten_context = 'default';
        $route_type    = 'MAXQUE';
        if ($AGILOG) {
            $agi_string =
"Max Queue Redirect: |$max_queue_redirect_bypass|$max_queue_ingroup_calls|$did_extension|$max_queue_ingroup_id|$stmtA|";
            &agi_output;
        }
        $stmtA =
"UPDATE vicidial_did_log SET did_route='MQ_$did_route' where uniqueid='$uniqueid' and channel='$channel' and server_ip='$VARserver_ip' and caller_id_number='$callerid' and call_date='$SQLdate';";
        if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
        $affected_rowsL = $dbhA->do($stmtA);
        if ($AGILOG) {
            $agi_string = "--    DID UPDATE LOG : |$affected_rowsL|$stmtA|";
            &agi_output;
        }
    }
    else {
        if ($AGILOG) {
            $agi_string =
"Max Queue Debug: |$max_queue_redirect_bypass|$max_queue_ingroup_calls|$did_extension|$max_queue_ingroup_id|$stmtA|";
            &agi_output;
        }
    }
}
if ( $did_route =~ /AGENT/ ) {
    if ($AGILOG) {
        $agi_string =
          "  did_route AGENT: |$user|$extension|$user_unavailable_action|";
        &agi_output;
    }
    $agent_live       = 0;
    $queue_date_epoch = time();
    $BDtarget         = ( $queue_date_epoch - 5 );
    ( $Bsec, $Bmin, $Bhour, $Bmday, $Bmon, $Byear, $Bwday, $Byday, $Bisdst ) =
      localtime($BDtarget);
    $Byear = ( $Byear + 1900 );
    $Bmon++;
    if ( $Bmon < 10 )  { $Bmon  = "0$Bmon"; }
    if ( $Bmday < 10 ) { $Bmday = "0$Bmday"; }
    if ( $Bhour < 10 ) { $Bhour = "0$Bhour"; }
    if ( $Bmin < 10 )  { $Bmin  = "0$Bmin"; }
    if ( $Bsec < 10 )  { $Bsec  = "0$Bsec"; }
    $BDtsSQLdate = "$Byear$Bmon$Bmday$Bhour$Bmin$Bsec";
    $stmtA =
"SELECT count(*) FROM vicidial_live_agents where user='$user' and last_update_time > '$BDtsSQLdate';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;

    if ( $sthArows > 0 ) {
        @aryA       = $sthA->fetchrow_array;
        $agent_live = $aryA[0];
    }
    $sthA->finish();
    if ( $agent_live > 0 ) {
        $did_ig_prefix = '99909';
        if (   ( $SSinbound_answer_config > 0 )
            && ( $inbound_route_answer =~ /N/i ) )
        {
            $did_ig_prefix = '99809';
        }
        $did_extension = "$did_ig_prefix$S$did_id$S$S$S$route_type";
        $exten_context = $ext_context;
        $did_route     = 'EXTEN';
        if ($AGILOG) {
            $agi_string = "AGENT available, Routing call: $agent_live|$user";
            &agi_output;
        }
    }
    else {
        $did_route     = $user_unavailable_action;
        $exten_context = 'default';
        $route_type    = 'NOAGENT';
        if ($AGILOG) {
            $agi_string =
"AGENT unavailable Redirect: |$user|$user_unavailable_action|$user_route_settings_ingroup|$did_extension|$stmtA|";
            &agi_output;
        }
        $stmtA =
"UPDATE vicidial_did_log SET did_route='NA_$did_route' where uniqueid='$uniqueid' and channel='$channel' and server_ip='$VARserver_ip' and caller_id_number='$callerid' and call_date='$SQLdate';";
        if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
        $affected_rowsL = $dbhA->do($stmtA);
        if ($AGILOG) {
            $agi_string = "--    DID UPDATE LOG : |$affected_rowsL|$stmtA|";
            &agi_output;
        }
    }
}
if ( $did_route =~ /PHONE/ ) {
    $stmtA =
"SELECT dialplan_number,voicemail_id,protocol,ext_context FROM phones where server_ip='$did_server_ip' and extension='$phone';";
    $sthA = $dbhA->prepare($stmtA) or die "preparing: ",        $dbhA->errstr;
    $sthA->execute                 or die "executing: $stmtA ", $dbhA->errstr;
    $sthArows = $sthA->rows;
    if ( $sthArows > 0 ) {
        @aryA            = $sthA->fetchrow_array;
        $dialplan_number = $aryA[0];
        $voicemail_id    = $aryA[1];
        $protocol        = $aryA[2];
        $ext_context     = $aryA[3];
    }
    $sthA->finish();
    if ( $did_server_ip =~ m/(\S+)\.(\S+)\.(\S+)\.(\S+)/ ) {
        $a            = leading_zero($1);
        $b            = leading_zero($2);
        $c            = leading_zero($3);
        $d            = leading_zero($4);
        $ServerString = "$a$S$b$S$c$S$d$S";
    }
    $did_extension = "$ServerString$dialplan_number";
    $did_route     = 'EXTEN';
}
if ( $did_route =~ /VOICEMAIL|VMAIL_NO_INST/ ) {
    if ( $did_server_ip =~ m/(\S+)\.(\S+)\.(\S+)\.(\S+)/ ) {
        $a            = leading_zero($1);
        $b            = leading_zero($2);
        $c            = leading_zero($3);
        $d            = leading_zero($4);
        $ServerString = "$a$S$b$S$c$S$d$S";
    }
    if ( $did_route =~ /VMAIL_NO_INST/ ) {
        $voicemail_dump_exten = $voicemail_dump_exten_no_inst;
    }
    $did_extension = "$ServerString$voicemail_dump_exten$voicemail_ext";
    $did_route     = 'EXTEN';
}
$did_ig_prefix = '99909';
if ( ( $SSinbound_answer_config > 0 ) && ( $inbound_route_answer =~ /N/i ) ) {
    $did_ig_prefix = '99809';
}
if ( $did_route =~ /IN_GROUP/ ) {
    $did_extension = "$did_ig_prefix$S$did_id$S$S$S$route_type";
    $exten_context = $ext_context;
    $did_route     = 'EXTEN';
}
if (   ( $did_route =~ /EXTEN|CALLMENU/ )
    && ( $enable_queuemetrics_logging > 0 ) )
{
    $dbhB = DBI->connect(
        "DBI:mysql:$queuemetrics_dbname:$queuemetrics_server_ip:3306",
        "$queuemetrics_login", "$queuemetrics_pass" )
      or die "Couldn't connect to database: " . DBI->errstr;
    if ($DBX) {
        print
"CONNECTED TO QueueMetrics DATABASE:  $queuemetrics_server_ip|$queuemetrics_dbname\n";
    }
    $stmtB =
"INSERT INTO queue_log SET `partition`='P01',time_id='$now_date_epoch',call_id='$uniqueid',queue='NONE',agent='NONE',verb='INFO',data1='DID',data2='$extension',serverid='$queuemetrics_log_id';";
    $Baffected_rows = $dbhB->do($stmtB);
    $dbhB->disconnect();
}
if ( $did_route =~ /EXTEN/ ) {
    $XFERexten = "$did_extension";
    if ($AGILOG) {
        $agi_string =
"exiting the DID app, transferring call to $XFERexten @ $exten_context";
        &agi_output;
    }
    print "SET CONTEXT $exten_context\n";
    $result = <STDIN>;
    checkresult($result);
    print "SET EXTENSION $XFERexten\n";
    $result = <STDIN>;
    checkresult($result);
    print "SET PRIORITY 1\n";
    $result = <STDIN>;
    checkresult($result);
    exit;
}
if ( $did_route =~ /DID/ ) {
    if ($AGILOG) {
        $agi_string =
"exiting the DID app, transferring call to $filter_match_found @ trunkinbound";
        &agi_output;
    }
    print "SET CONTEXT trunkinbound\n";
    $result = <STDIN>;
    checkresult($result);
    print "SET EXTENSION $filter_match_found\n";
    $result = <STDIN>;
    checkresult($result);
    print "SET PRIORITY 1\n";
    $result = <STDIN>;
    checkresult($result);
    exit;
}
if ( $did_route =~ /CALLMENU/ ) {
    if ( $enable_queuemetrics_logging > 0 ) {
        $dbhB = DBI->connect(
            "DBI:mysql:$queuemetrics_dbname:$queuemetrics_server_ip:3306",
            "$queuemetrics_login", "$queuemetrics_pass" )
          or die "Couldn't connect to database: " . DBI->errstr;
        if ($DBX) {
            print
"CONNECTED TO QM DATABASE:  $queuemetrics_server_ip|$queuemetrics_dbname\n";
        }
        $stmtB =
"INSERT INTO queue_log SET `partition`='P01',time_id='$now_date_epoch',call_id='$uniqueid',queue='NONE',agent='NONE',verb='INFO',data1='IVRSTART',data2='$callerid',data3='$extension',serverid='$queuemetrics_log_id';";
        $Baffected_rows = $dbhB->do($stmtB);
        $dbhB->disconnect();
    }
    $XFERcontext = "$menu_id";
    if ($AGILOG) {
        $agi_string =
          "exiting the DID app, transferring call to CALLMENU $XFERcontext";
        &agi_output;
    }
    print "SET CONTEXT $XFERcontext\n";
    $result = <STDIN>;
    checkresult($result);
    print "SET EXTENSION s\n";
    $result = <STDIN>;
    checkresult($result);
    print "SET PRIORITY 1\n";
    $result = <STDIN>;
    checkresult($result);
    exit;
}

sub checkresult {
    $pass = 0;
    $fail = 0;
    my ($res) = @_;
    my $retval;
    $tests++;
    chomp $res;
    if ( $res =~ /^200/ ) {
        $res =~ /result=(-?\d+)/;
        if ( !length($1) ) {
            $fail++;
        }
        else {
            $pass++;
        }
    }
    else {
        $fail++;
    }
}

sub leading_zero($) {
    $_ = $_[0];
    s/^(\d)$/0$1/;
    s/^(\d\d)$/0$1/;
    return $_;
}    # End of the leading_zero() routine.

sub agi_output {
    if ( $AGILOG >= 2 ) {
        open( Lout, ">>$AGILOGfile" )
          || die "Can't open $AGILOGfile: $!\n";
        print Lout "$now_date|$script|$agi_string\n";
        close(Lout);
    }
    if ( ( $AGILOG == '1' ) || ( $AGILOG == '3' ) ) {
        print STDERR "$now_date|$script|$agi_string\n";
    }
    $agi_string = '';
}

sub did_output {
    if ( $AGILOG >= 2 ) {
        open( Dout, ">>$DIDLOGfile" )
          || die "Can't open $DIDLOGfile: $!\n";
        print Dout "$did_string\n";
        close(Dout);
    }
    $did_string = '';
}

sub parse_asterisk_version {
    my $ast_ver_str     = $_[0];
    my @hyphen_parts    = split( /-/, $ast_ver_str );
    my $ast_ver_postfix = $hyphen_parts[1];
    my @dot_parts       = split( /\./, $hyphen_parts[0] );
    my %ast_ver_hash;
    if ( $dot_parts[0] <= 1 ) {
        %ast_ver_hash = (
            "major"    => $dot_parts[0],
            "minor"    => $dot_parts[1],
            "build"    => $dot_parts[2],
            "revision" => $dot_parts[3],
            "postfix"  => $ast_ver_postfix
        );
    }
    if ( $dot_parts[0] > 1 ) {
        %ast_ver_hash = (
            "major"    => 1,
            "minor"    => $dot_parts[0],
            "build"    => $dot_parts[1],
            "revision" => $dot_parts[2],
            "postfix"  => $ast_ver_postfix
        );
    }
    return (%ast_ver_hash);
}
