#!/usr/bin/perl use strict; use Getopt::Long qw(:config no_ignore_case); use filetest qw(access); # Make sure ACLs are honored use POSIX qw(strftime); use Time::HiRes qw(tv_interval gettimeofday); #use Data::Dumper; #open FR, '>>', "ding"; #---------------------------------------------------------------------- # Globals #---------------------------------------------------------------------- my $PROGNAME = $0; $PROGNAME =~ s|^.*/||; # PROGNAME is basename of script #dbgprint("progname = '$PROGNAME'\n"); my $PROG_START_TIME = time(); my ($PROG_LOAD_START_TIME, $PROG_LOAD_END_TIME); my ($PROG_LOAD_START_TIME_hr, $PROG_LOAD_END_TIME_hr); my ($PROG_END_TIME); # Current datetime in YYYYMMDDHHMMSS format my $YYYYmmddHHMMSS = strftime('%Y'.'%m'.'%d'.'%H'.'%M'.'%S',gmtime($PROG_START_TIME)); # Quoted so SCME won't mess it up my $FN_ABORTFILE = "/tmp/err.$PROGNAME"; # Base part of abort filename. More stuff is added later when used my $FN_LOGFILE; # Format: "ohdr_cucp_sip_fix_perl_.log" my $FN_OUTPUT; # Format: PMOSS_SIPNBVQM_5MIN_OHDR__.processing (.completed) my $FN_TRINITY_OUTPUT; # Format: PMOSS_T3_SIPNBVQM_5MIN_OHDR__.processing (.completed) my $FN_P3_OUTPUT; # Format: PMOSS_P3_SIPNBVQM_5MIN_OHDR__.processing (.completed) my $FN_CONFIG; # rename to ".processing" on startup and then ".completed" when done #---------------------------------------------------------------------- # Globals used when processing FILE1: SIP-FIXED #---------------------------------------------------------------------- my $STAT_ignored_ohdrs=0; my $STAT_ignored_ohdrs_nomatch=0; my $STAT_processed_ohdrs=0; #---------------------------------------------------------------------- # Fields from First Leg are prefixed with 'FL_' #---------------------------------------------------------------------- my ($FL_dr_id, $FL_start_time, $FL_start_time_msec, $FL_matched_start_time, $FL_matched_start_time_msec, $FL_ring_progress_time, $FL_ring_progress_time_msec, $FL_call_answered_time, $FL_call_answered_time_msec, $FL_src_ipv4, $FL_dst_ipv4, $FL_resp_id, $FL_src_port, $FL_dst_port, $FL_src_url, $FL_dst_url, $FL_call_id, $FL_src_ipv6, $FL_dst_ipv6, $FL_F0A_F1, $FL_F0A_F2,$FL_F0A_F3, $FL_matched, ); #---------------------------------------------------------------------- # Fields from Last Leg are prefixed with 'LL_' #---------------------------------------------------------------------- my ($LL_dr_id, $LL_ctc_dr_id,$LL_resp_dr_id, $LL_start_time, $LL_start_time_msec, $LL_end_time, $LL_end_time_msec, $LL_ctc_resp_time, $LL_ctc_resp_time_msec, $LL_ctc_time, $LL_ctc_time_msec, $LL_resp_id, ); #---------------------------------------------------------------------- # Fields from First Leg are prefixed with 'FL_' for Trinity #---------------------------------------------------------------------- my ($FL_matched_dr_id, $FL_matched_start_time, $FL_matched_start_time_msec, $FL_matched_end_time, $FL_matched_end_time_msec , $FL_matched_ring_progress_time, $FL_matched_ring_progress_time_msec, $FL_matched_call_answered_time, $FL_matched_call_answered_time_msec, $FL_matched_src_ipv4, $FL_matched_dst_ipv4, $FL_matched_src_ipv6, $FL_matched_dst_ipv6, $FL_trinity_matched, $FL_SIP_Signaling_IP_Address , $FL_a_SBGv_Hostname ); my ($FL_matched_mix_dr_id, $FL_matched_mix_start_time, $FL_matched_mix_start_time_msec, $FL_matched_mix_end_time, $FL_matched_mix_end_time_msec , $FL_matched_mix_ring_progress_time, $FL_matched_mix_ring_progress_time_msec, $FL_matched_mix_call_answered_time, $FL_matched_mix_call_answered_time_msec, $FL_matched_mix_src_ipv4, $FL_matched_mix_dst_ipv4, $FL_matched_mix_src_ipv6, $FL_matched_mix_dst_ipv6, $FL_trinity_matched_mix, $FL_resp_mix_id, $FL_src_mix_port, $FL_dst_mix_port, $FL_src_mix_url, $FL_dst_mix_url, $FL_call_mix_id ); #---------------------------------------------------------------------- # Trinity Identity String #---------------------------------------------------------------------- my $trinity_str ='@hcomm.att.net'; my ($SrcTN ,$DesTN ,$SrcMixTN,$DesMixTN,$SrcMixTN_Matched,$DesMixTN_Matched); my ($found_T3_T3,$found_T3_XX,$found_XX_T3); #---------------------------------------------------------------------- # P3 Call Parameter #---------------------------------------------------------------------- my %VLAN_ID_HASH; #---------------------------------------------------------------------- # Default values for variables that can be set via command line options #---------------------------------------------------------------------- my $DRYRUN = 0; # TRUE -> Do NOT update actual files my $DEBUG = 0; # TRUE -> Print debug msgs my $DEBUG_HDRS = 0; # TRUE -> Add additional debug info in output data my $MAX_LINES = 0; # Max number of lines to read from a large file. 0 == Unlimited #my $VTIERBASE = "/opt/app/active-vtier/Prod"; # FIXME: Should really use FindBin module to determine parent dir my $VTIERBASE = "/opt/app/vcc"; #---------------------------------------------------------------------- # Variables set via positional parameters # The ones with assignments were originally optional params until specs changed #---------------------------------------------------------------------- #my $SRC_DIR = "EDS/CUCP/SIP"; # must prepend $VTIERBASE/Data/Ready if not fully specified my @dir = ("$VTIERBASE/pvc/ohdr/topology","$VTIERBASE/pvc/ohdr/instance-0/preprocess"); foreach my $SRC_DIR(@dir) {{ print "Source dir: '$SRC_DIR'\n"; } #my $SRC_DIR = "/pvc/ohdr/topology"; my $DONE_DIR = "$VTIERBASE/pvc/ohdr/instance-0/cucp"; # must prepend $VTIERBASE/Data/Done if not fully specified #my $DST_DIR = "EDS/CUCP/SIP"; # must prepend $VTIERBASE/Data/Ready if not fully specified my $DST_DIR = "$VTIERBASE/pvc/ohdr/instance-0/processed"; my $LOG_DIR; # must prepend $VTIERBASE if not fully specified my $LOG_DIR = "$VTIERBASE/logs/DCAE/ohdr"; my $EMAIL_DL; #my $CONFIG_FILE; my $CONFIG_FILE = "$VTIERBASE/config/ohdr"; my @feed_files; my $FN_FILE0A = "BVOIP_SITE_INFO.txt"; my $FN_FILE0B = "TVSP_NODE_SERVICE.txt"; my $FN_FILE10 = "TVSP_NODE_NAMES.txt"; my $FN_RESP = "response_avt.txt"; my $FN_TRINITY_TN = "TRINITYTNCFG_TN_FILE.txt"; my $INSTANCE; #---------------------------------------------------------------------- # Debug/Logging functions #---------------------------------------------------------------------- sub dbgprint { # NOTE: Sometimes you might want to check $DEBUG *before* calling this to avoid some processing # ie. dbgprint "msg: ", join("|", @output), "\n" if $DEBUG; print STDERR "$PROGNAME: ", @_ if ($DEBUG); } sub dbgprintlvl { my $lvl = shift; dbgprint @_ if $DEBUG >= $lvl; } sub write_log { my $msg = join("", @_); # Allow for multiple params my $time_now = gmtime(time); my $log_msg = "${time_now}:${msg}"; # Assumes msg already contains '\n' print LOGFILE $log_msg; print STDOUT $log_msg; # Also put log messages on STDOUT so it shows up in TWS output capture #dbgprint $log_msg if $DEBUG; } sub logNdie { my $msg = join("", @_); # Allow for multiple params write_log "################################################################################\n"; write_log "ABORTING: logNdie : $msg\n"; # Determine VTIER name from /opt/app/active-vtier chomp(my $vtiername = qx(readlink /opt/app/active-vtier)); chomp(my $hostname = uc(qx(hostname))); $vtiername =~ s|.*/(.*)$|\1|; # Remove the leading dirs my $ABORT_FILE = "$FN_ABORTFILE.$YYYYmmddHHMMSS.$$"; # Include PID as part of filename to make sure it is unique my ($fh_abort, $fh_email); umask(002); open($fh_abort, "> $ABORT_FILE" ) or write_log "ERROR: Could not create ABORT_FILE: $ABORT_FILE\n"; if ( $EMAIL_DL ) { # Try to get first list from error msg to include in subject my ($line1) = ( $msg =~ m/(.*?)\n/ ); my $subj = "[Fatal ERROR]: $hostname($vtiername) : $line1"; write_log "Email will also be sent to $EMAIL_DL\n"; write_log "Email subject: '$subj'\n"; #open($fh_email, "| mail -s '[Fatal ERROR]: $hostname($vtiername) : $PROGNAME : $line1' '$EMAIL_DL'") or write_log "ERROR: Cannot open MAIL filehandle\n"; open($fh_email, "| mail -s '$subj' '$EMAIL_DL'") or write_log "ERROR: Cannot open MAIL filehandle\n"; print $fh_email "Check the following logfile for details:\n\t$FN_LOGFILE\n\n"; print $fh_email "Following is contents of abort file: $ABORT_FILE\n\n"; } # Write abort file and send the same contents to the EMAIL_DL (if known) foreach my $fh ($fh_abort, $fh_email) { if ( $fh ) { print $fh "PROGNAME='$0'\n"; print $fh "ERRMSG='$msg'\n"; print $fh "ABORT_TIME='", scalar(gmtime(time)), "'\n"; print $fh "ABORT_FILE='$ABORT_FILE'\n"; print $fh "LOGFILE='$FN_LOGFILE'\n" if $FN_LOGFILE; print $fh "PARAMS='@ARGV'\n"; } } write_log "Created ABORT file: $ABORT_FILE\n"; close($fh_abort) if $fh_abort; close($fh_email) if $fh_email; die "$msg"; } #---------------------------------------------------------------------- # Process the command line options and parameters #---------------------------------------------------------------------- GetOptions( 'DRYRUN!' => \$DRYRUN, 'debug' => sub { $DEBUG++; }, 'setdebug=i' => \$DEBUG, 'hdr_debug!' => \$DEBUG_HDRS, 'maxlines=s' => \$MAX_LINES, 'vtierbase=s' => \$VTIERBASE, # 'srcdir=s' => \$SRC_DIR, # 'dstdir|resultsdir=s' => \$DST_DIR, # 'file0a|bvoip=s'=> \$FN_FILE0A, # BVOIP_SITE_INFO.txt # 'file0b|tvsp=s' => \$FN_FILE0B, # TVSP_NODE_SERVICE.txt # 'file9|resp=s' => \$FN_RESP, # response_avt.txt ) or logNdie "$PROGNAME: ERROR: Invalid options specified\n" . "Usage: $0 [--DRYRUN] [--setdebug dbglevel] [--maxlines #] [--vtierbase DIR] " . "SRC_DIR DONE_DIR DST_DIR LOG_DIR EMAIL_DL CONFIG_FILE F1 F2 F3 F4 F5 F6 F7 F8 F0A F0B F9(RESP) FTN(TRINITY) F10(TVSP NODE) INSTANCE\n"; my $npos = scalar(@ARGV); dbgprint("Found $npos Positional Args:\n\t", join("\n\t",@ARGV),"\n"); $YYYYmmddHHMMSS = "dbgYYYYmmddHHMMSS" if $DEBUG; # FIXME - static for debug purposes #---------------------------------------------------------------------- # Originally, FN_FILE0A, FN_FILE0B, FN_RESP were optional parameters # But specs now say to pass them in as positional parameters :( # # The positional params are in this order: # SRC_DIR DONE_DIR DST_DIR LOG_DIR EMAIL_DL CONFIG_FILE F1 F2 F3 F4 F5 F6 F7 F8 F0A F0B F9(RESP) FTN(TRINITY) F10(TVSP NODE) INSTANCE #---------------------------------------------------------------------- #logNdie "$PROGNAME: ERROR: Invalid number of parameters specified ($npos). 18 are required!\n" unless $npos == 18; logNdie "$PROGNAME: ERROR: Invalid number of parameters specified ($npos). 20 are required!\n" unless $npos == 20; ( $SRC_DIR, $DONE_DIR, $DST_DIR, $LOG_DIR, $EMAIL_DL, $CONFIG_FILE, @feed_files[0..7], $FN_FILE0A, $FN_FILE0B, $FN_RESP, $FN_TRINITY_TN, $FN_FILE10, $INSTANCE, ) = @ARGV; #---------------------------------------------------------------------- # Open LOGFILE quickly #---------------------------------------------------------------------- $LOG_DIR = "$VTIERBASE/$LOG_DIR" unless $LOG_DIR =~ m|^/|; $FN_LOGFILE = "$LOG_DIR/ohdr_cucp_sip_fix_perl_${CONFIG_FILE}_${YYYYmmddHHMMSS}.log"; open(LOGFILE, "> $FN_LOGFILE") or logNdie "$PROGNAME: ERROR: Cannot open logfile for writing - $FN_LOGFILE: $!\n"; write_log "################################################################################\n"; write_log "$0 ($PROGNAME) Started. Processing config_file=$CONFIG_FILE : YYYYmmddHHMMSS=$YYYYmmddHHMMSS\n"; write_log "################################################################################\n"; write_log "FN_LOGFILE = $FN_LOGFILE\n"; write_log "DEBUG mode enabled\n" if $DEBUG; write_log "WARNING!! Max of $MAX_LINES per data file will be read.\n" if $MAX_LINES; #---------------------------------------------------------------------- # Validate the parameters #---------------------------------------------------------------------- my $file_cnt= scalar(@feed_files); logNdie "$PROGNAME: ERROR: Invalid number of feed files specified ($file_cnt). 8 are required!\n" unless $file_cnt == 8; # Build the complete path if not fully specified #$DONE_DIR = "$VTIERBASE/Data/Done/$DONE_DIR" unless $DONE_DIR =~ m|^/|; $DONE_DIR = "$VTIERBASE/pvc/ohdr/cucp/$DONE_DIR" unless $DONE_DIR =~ m|^/|; #$SRC_DIR = "$VTIERBASE/Data/Ready/$SRC_DIR" unless $SRC_DIR =~ m|^/|; $SRC_DIR = "$VTIERBASE/pvc/ohdr/topology/$SRC_DIR" unless $SRC_DIR =~ m|^/|; #$DST_DIR = "$VTIERBASE/Data/Ready/$DST_DIR" unless $DST_DIR =~ m|^/|; # DST_DIR is where we output results $DST_DIR = "$VTIERBASE/pvc/ohdr/pvc/ohdr/instance-0/processed/$DST_DIR" unless $DST_DIR =~ m|^/|; # DST_DIR is where we output results $FN_OUTPUT = "$DST_DIR/PMOSS_SIPNBVQM_5MIN_OHDR_${YYYYmmddHHMMSS}_${INSTANCE}_$$"; # Suffixes added later: .processing .completed $FN_TRINITY_OUTPUT = "$DST_DIR/PMOSS_T3_SIPNBVQM_5MIN_OHDR_${YYYYmmddHHMMSS}_${INSTANCE}_$$"; # Suffixes added later: .processing .completed $FN_P3_OUTPUT = "$DST_DIR/PMOSS_P3_SIPNBVQM_5MIN_OHDR_${YYYYmmddHHMMSS}_${INSTANCE}_$$"; # Suffixes added later: .processing .completed write_log sprintf "DRYRUN=%s\n", ($DRYRUN) ? "Enabled (NO FILES WILL BE MOVED to $DONE_DIR)" : "Disabled (Files WILL be moved to $DONE_DIR)"; write_log "################################################################################\n"; write_log "CONFIG_FILE= $CONFIG_FILE\n"; write_log "INSTANCE = $INSTANCE\n"; write_log "DONE_DIR = $DONE_DIR\n"; write_log "SRC_DIR = $SRC_DIR\n"; write_log "DST_DIR = $DST_DIR\n"; write_log "LOG_DIR = $LOG_DIR\n"; write_log "FN_OUTPUT = $FN_OUTPUT\n"; write_log "FN_TRINITY_OUTPUT = $FN_TRINITY_OUTPUT\n"; write_log "FN_P3_OUTPUT = $FN_P3_OUTPUT\n"; ( -d $DONE_DIR && -w $DONE_DIR ) or logNdie "$PROGNAME: ERROR: DONEDIR=$DONE_DIR not writeable\n"; ( -d $SRC_DIR && -w $SRC_DIR ) or logNdie "$PROGNAME: ERROR: SRCDIR=$SRC_DIR not writeable\n"; ( -d $DST_DIR && -w $DST_DIR ) or logNdie "$PROGNAME: ERROR: DSTDIR=$DST_DIR not writeable\n"; ( -d $LOG_DIR && -w $LOG_DIR ) or logNdie "$PROGNAME: ERROR: LOGDIR=$LOG_DIR not writeable\n"; # We chdir to SRC_DIR since it contains feedfiles which are NOT fully qualified chdir $SRC_DIR or logNdie "$PROGNAME: ERROR: Cannot chdir to SRCDIR=$SRC_DIR\n"; $FN_FILE0A = "$SRC_DIR/$FN_FILE0A" unless $FN_FILE0A =~ m|^/|; $FN_FILE0B = "$SRC_DIR/$FN_FILE0B" unless $FN_FILE0B =~ m|^/|; $FN_FILE10 = "$SRC_DIR/$FN_FILE10" unless $FN_FILE10 =~ m|^/|; $FN_RESP = "$SRC_DIR/$FN_RESP" unless $FN_RESP =~ m|^/|; $FN_TRINITY_TN = "$SRC_DIR/$FN_TRINITY_TN" unless $FN_TRINITY_TN =~ m|^/|; write_log "################################################################################\n"; ( -f $CONFIG_FILE ) or logNdie "$PROGNAME: ERROR: CONFIG_FILE=$CONFIG_FILE not found\n"; write_log "Renaming $CONFIG_FILE to $CONFIG_FILE.processing", ($DRYRUN)? " (DRYRUN:Not really moved)\n" : "\n"; if ( ! $DRYRUN ) { rename "$CONFIG_FILE", "$CONFIG_FILE.processing" or logNdie "$PROGNAME: ERROR: Cannot rename $CONFIG_FILE to $CONFIG_FILE.completed\n"; } open(OUTPUT, "> $FN_OUTPUT.processing") or logNdie "$PROGNAME: ERROR: Cannot open output file for writing - $FN_OUTPUT.processing: $!\n"; open(OUTPUT_TN, "> $FN_TRINITY_OUTPUT.processing") or logNdie "$PROGNAME: ERROR: Cannot open output file for writing - $FN_TRINITY_OUTPUT.processing: $!\n"; open(OUTPUT_P3, "> $FN_P3_OUTPUT.processing") or logNdie "$PROGNAME: ERROR: Cannot open output file for writing - $FN_P3_OUTPUT.processing: $!\n"; write_log "Opening FN_FILE0A = $FN_FILE0A\n"; open(fh_F0A, "< $FN_FILE0A") or logNdie "$PROGNAME: ERROR: Cannot open file for Reading - $FN_FILE0A\n"; write_log "Opening FN_FILE0B = $FN_FILE0B\n"; open(fh_F0B, "< $FN_FILE0B") or logNdie "$PROGNAME: ERROR: Cannot open file for Reading - $FN_FILE0B\n"; write_log "Opening FN_RESP/F9 = $FN_RESP\n"; open(fh_RESP,"< $FN_RESP") or logNdie "$PROGNAME: ERROR: Cannot open file for Reading - $FN_RESP\n"; write_log "Opening FN_TRINITY_TN/FTN = $FN_TRINITY_TN\n"; open(fh_TRINITY_TN,"< $FN_TRINITY_TN") or logNdie "$PROGNAME: ERROR: Cannot open file for Reading - $FN_TRINITY_TN\n"; write_log "Opening FN_FILE10/F10 = $FN_FILE10\n"; open(fh_TVSP_NODE,"< $FN_FILE10") or logNdie "$PROGNAME: ERROR: Cannot open file for Reading - $FN_FILE10\n"; #---------------------------------------------------------------------- # Now validate we can access the feed files @feed_files # by opening file handles for each #---------------------------------------------------------------------- my @fh_feed; my $cnt = 1; foreach (@feed_files) { $_ = "$SRC_DIR/$_" unless $_ =~ m|^/|; write_log "Opening FILE$cnt - $_\n"; open($fh_feed[$cnt], "< $_") or logNdie "$PROGNAME: ERROR: Cannot open feed file for Reading - $_\n"; $cnt++; } #---------------------------------------------------------------------- # At this point, we should have all the required files opened for reading/writing # # Read in reference tables: FILE0A, FILE0B, RESP #---------------------------------------------------------------------- write_log "################################################################################\n"; write_log "Reading in Reference Files:\n"; $PROG_LOAD_START_TIME = time(); $PROG_LOAD_START_TIME_hr = [gettimeofday]; #---------------------------------------------------------------------- # F0A: BVOIP_SITE_INFO.txt #---------------------------------------------------------------------- # F0A Layout # NOTE: Array starts at 0 not 1.... # 0 = siteID # 1 = public IP # 2 = media IP # 3 = Prob Name # 4 = IPBE6300 Node Name # 5 = VLANID # 6 = mfaCapabilityIndr my %lookup_F0A; my %lookup_F0M;#kl6224 Media IP Address my (%lookup_F10,%BVOIP_P3_IP_ARRAY,%BVOIP_IPBE6300_ARRAY,%BVOIP_IPBE6300_ARRAY_VLANID,%p3publicIp2siteid,%siteid2p3mediaIp); my (%publicIp2siteid,%siteid2mediaIp,%siteid2publicIp,%mediaIp2siteid); my $t=time; my $t0 = [gettimeofday]; while () { chomp; my $c = my @field = split(/\|/, $_, -1); #next if ($c != 4); # Invalid number of fields next if ($c != 7); # Invalid number of fields ##it is increased from 4 to 7 to have new columns IPBE6300 next unless ($field[0]); # Ignore if IP address is null $field[1] = lc($field[1]); # ln056j #2015-10-14 to handle IPv6 data as teradata is converting it into upper case $field[2] = lc($field[2]); # ln056j #2015-10-14 to handle IPv6 data $field[6] = lc($field[6]); # ln056j #2015-10-14 to handle IPv6 data #$lookup_F0A{$field[0]} = $field[1];#kl6224 Commenting for adding new change if (($field[6] eq "y" || $field[6] eq "Y") && defined($field[4]) && defined($field[5])) { $field[4] = lc($field[4]); if (! $BVOIP_IPBE6300_ARRAY{$field[4]}) { $BVOIP_IPBE6300_ARRAY{$field[4]} = [$field[5]]; $BVOIP_IPBE6300_ARRAY_VLANID{$field[4]}{$field[5]} = 1; } else { push @{$BVOIP_IPBE6300_ARRAY{$field[4]}} , $field[5]; $BVOIP_IPBE6300_ARRAY_VLANID{$field[4]}{$field[5]} = 1 } #$BVOIP_IPBE6300_ARRAY{$field[4]}=1; $BVOIP_P3_IP_ARRAY{$field[1]}=$field[4]; $p3publicIp2siteid{$field[1]} = $field[0]; #kl6224 publicIP to siteid mapping $siteid2p3mediaIp{$field[0]} = $field[2]; #kl6224 siteid to media ip mapping $lookup_F10{$field[1]} = "$field[3]";#kl6224 Public IP Address } else { $lookup_F0A{$field[1]} = "$field[3]";#kl6224 Public IP Address #dbgprint "SITE ID $field[0] $field[1] $lookup_F0A{$field[1]}\n"; $lookup_F0M{$field[2]} = "$field[3]";#kl6224 Media IP Address $publicIp2siteid{$field[1]} = $field[0]; #kl6224 publicIP to siteid mapping $siteid2mediaIp{$field[0]} = $field[2]; #kl6224 siteid to media ip mapping $mediaIp2siteid{$field[2]} = $field[0]; #ln056j mediaIp to siteid mapping $siteid2publicIp{$field[0]} = $field[1]; #ln056j siteid to publicIP ip mapping } } my $e = (time - $t); # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer #dbgprint "lookup_F0A contains ", scalar(keys %lookup_F0A), " entries\n"; write_log "Loaded F0A : contains ", scalar(keys %lookup_F0A), " entries ($hre secs) - $FN_FILE0A\n"; write_log "Loaded F0M : contains ", scalar(keys %lookup_F0M), " entries ($hre secs) - $FN_FILE0A\n"; write_log "Loaded F10 : contains ", scalar(keys %lookup_F10), " entries ($hre secs) - $FN_FILE0A\n"; write_log "Loaded P3_IP : contains ", scalar(keys %BVOIP_P3_IP_ARRAY), " entries ($hre secs) - $FN_FILE0A\n"; write_log "Loaded P3_IPBE6300 : contains ", scalar(keys %BVOIP_IPBE6300_ARRAY), " entries ($hre secs) - $FN_FILE0A\n"; #---------------------------------------------------------------------- # F0B: TVSP_NODE_SERVICE.txt #---------------------------------------------------------------------- # F0B Layout # NOTE: Array starts at 0 not 1.... # 0 = NODE_NM # 1 = NODE_TYPE # 2 = IP_ADDR # 3 = SERVICE # 4 = SERVICE_TYPE my %lookup_F0B; my $linecnt=0; my $t=time; my $t0 = [gettimeofday]; while () { chomp; s/^\s+//; # ignore leading spaces s/#.*//; # skip comment lines s/\s+$//; # ignore trailing spaces next unless length; # anything less my $c = my @field = split(/\|/, $_, -1); next if ($c != 5); # Invalid number of fields next unless ($field[2]); # Ignore if IP address is null $field[2] = lc($field[2]); # ln056h #2015-10-14 to handle IPv6 data #dbgprint "F0B: $_\n"; #$lookup_F0B{$field[2]} = 1; $lookup_F0B{$field[2]} = $field[0];#kl6224 change Node name last if $MAX_LINES && ++$linecnt >= $MAX_LINES; } my $e = (time - $t); # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer #dbgprint "lookup_F0B contains ", scalar(keys %lookup_F0B), " entries\n"; write_log "Loaded F0B : contains ", scalar(keys %lookup_F0B), " entries ($hre secs) - $FN_FILE0B\n"; #foreach my $k (sort keys %lookup_F0B) { # dbgprint "F0B: $k\n"; #} #---------------------------------------------------------------------- # RESP (FILE9): response_avt.txt #---------------------------------------------------------------------- my %lookup_RESP; my $t=time; my $t0 = [gettimeofday]; while () { chomp; s/^\s+//; # ignore leading spaces s/#.*//; # skip comment lines s/\s+$//; # ignore trailing spaces next unless length; # anything less my $nfields = my @field = split(/\|/, $_, -1); next if ($nfields != 2); # Invalid number of fields $lookup_RESP{$field[0]} = $field[1]; } my $e = (time - $t); # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer #dbgprint "lookup_RESP contains ", scalar(keys %lookup_RESP), " entries\n"; write_log "Loaded RESP : contains ", scalar(keys %lookup_RESP), " entries ($hre secs) - $FN_RESP\n"; #foreach my $k (sort keys %lookup_RESP) { # dbgprint "RESP: $k = '$lookup_RESP{$k}'\n"; #} #---------------------------------------------------------------------- # F10: TRINITY_TN.txt #---------------------------------------------------------------------- my (%lookup_FTN,%lookup_FTN_Range); my $linecnt=0; my ($i,$calculated_TN,$preTN_Hash_numberm,$range_diff)=0; my $t=time; my $t0 = [gettimeofday]; while () { chomp; s/^\s+//; # ignore leading spaces s/#.*//; # skip comment lines s/\s+$//; # ignore trailing spaces next unless length; # anything less my $c = my @field = split(/\|/, $_, -1); next if ($c != 3); # Invalid number of fields next if (/^TRINITY_TN_CONFIG/); # Ignore if it is header TRINITY_TN_CONFIG #dbgprint "FTN: $_\n"; #$lookup_FTN{$field[2]} = 1; $range_diff = $field[2]-$field[1]; ##if Range is containg only one number then it would be pre-store to lookup_FTN 7027266106-7027266106 #if ($field[1]==$field[2]) #{ # $lookup_FTN{$field[1]} =1; #} ##elsif Range is containg Range such as 7166307092-7166307093 then it would be pre-store to lookup_FTN if ($range_diff <= 300) #elsif ($range_diff <= 300) { $i=0 ; #dbgprint "$range_diff is so these numbers would be added into hash\n"; while($range_diff >= $i) { $calculated_TN =$field[1]+$i; $lookup_FTN{$calculated_TN} =1; #dbgprint "$field[2],$field[1] ,$calculated_TN\n"; $i=$i+1; $preTN_Hash_numberm=$preTN_Hash_numberm+1; } } else { $lookup_FTN_Range{$field[1]} = $field[2]; ## Creating Hash key- Value pair for each Range. dbgprint "$field[2] $field[1] --Range\n"; } last if $MAX_LINES && ++$linecnt >= $MAX_LINES; } my @tn_indices = sort(keys(%lookup_FTN_Range)); my $e = (time - $t); # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer #dbgprint "lookup_FTN_Range contains ", scalar(keys %lookup_FTN_Range), " entries\n"; write_log "Loaded FTN_Range : contains ", scalar(keys %lookup_FTN_Range), " entries ($hre secs) - $FN_TRINITY_TN\n"; #write_log "Loaded FTN_Pre-FilterTN : contains ", scalar(keys %lookup_FTN), " entries ($hre secs) - $FN_TRINITY_TN\n"; write_log "Loaded FTN_Pre-FilterTN : contains ", $preTN_Hash_numberm, " entries ($hre secs) - $FN_TRINITY_TN\n"; #foreach my $k (sort keys %lookup_FTN_Range) { # dbgprint "FTN: $k\n"; #} #---------------------------------------------------------------------- # F11: TVSP_NODE_FILE - TVSP GSX IPBE6300 IPBE4500 #---------------------------------------------------------------------- # FN_FILE10 Layout # NOTE: Array starts at 0 not 1.... # 0 = NODE_NM # 1 = IP_ADDR my (%TVSP_4500_ARRAY,%TVSP_GSX_ARRAY,%TVSP_IP6300_ARRAY); my $linecnt=0; my $t=time; my $t0 = [gettimeofday]; while () { chomp; s/^\s+//; # ignore leading spaces s/#.*//; # skip comment lines s/\s+$//; # ignore trailing spaces next unless length; # anything less my $c = my @field = split(/\|/, $_, -1); next if ($c != 2); # Invalid number of fields next unless ($field[1]); # Ignore if IP address is null $field[0] = lc($field[0]); if ( $field[0] =~ /.*(pbc|mbc)$/) { $TVSP_IP6300_ARRAY{$field[1]} = $field[0]; } elsif ( $field[0] =~ /.*sd[s1a]$/) { $TVSP_4500_ARRAY{$field[1]} = $field[0]; } elsif ( $field[0] =~ /.*(gh|gc)$/) { $TVSP_GSX_ARRAY{$field[1]} = $field[0]; } last if $MAX_LINES && ++$linecnt >= $MAX_LINES; } my $e = (time - $t); # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer dbgprint "Loaded TVSP_IP6300_ARRAY : contains ", scalar(keys %TVSP_IP6300_ARRAY), " entries ($hre secs) - $FN_FILE10\n"; write_log "Loaded TVSP_IP6300_ARRAY : contains ", scalar(keys %TVSP_IP6300_ARRAY), " entries ($hre secs) - $FN_FILE10\n"; write_log "Loaded TVSP_4500_ARRAY : contains ", scalar(keys %TVSP_4500_ARRAY), " entries ($hre secs) - $FN_FILE10\n"; write_log "Loaded TVSP_GSX_ARRAY : contains ", scalar(keys %TVSP_GSX_ARRAY), " entries ($hre secs) - $FN_FILE10\n"; #foreach my $k (sort keys %lookup_F0B) { # dbgprint "F0B: $k\n"; #} #---------------------------------------------------------------------- # Read in table: FILE2 - RTP-FIXED #---------------------------------------------------------------------- # FILE2 Layout # NOTE: Array starts at 0 not 1.... # 0 = collect_timestamp # 1 = app_id # 2 = ohdr_id # 3 = dr_id # 4 = start_time_sec # 5 = start_time_ms # 6 = end_time_sec # 7 = end_time_ms # 8 = server_ipv4 # 9 = client_ipv4 # 10 = status_bits # 11 = forward_ssrc # 12 = reverse_ssrc # 13 = app_protocol # 14 = call_type # 15 = src_port_num # 16 = dest_port_num # 17 = protocol_info # 18 = dscp_tos # 19 = src_ipv6 # 20 = dest_ipv6 my %lookup_F2; my %lookup_F2_TN; my $t=time; my $t0 = [gettimeofday]; my $linecnt_f2; my $F2_pairs=0; my $F2_bad_recs=0; for($linecnt_f2=0;my $line = readline($fh_feed[2]); $linecnt_f2++ ) { chomp($line); next if ( $line =~ /^#/); # Added as part of Rel 16.02 277170p to remove header my $nfields = my @field = split(/\|/, $line, -1); # Note, there might be trailing null fields next if ($nfields != 21); # Invalid number of fields last if $MAX_LINES && $linecnt_f2 >= $MAX_LINES; # Only count valid lines with MAX_LINES # Save fields to use later in $lookup_F2{ohdrid}[] with ez lookup by ohdrid # [0] 8 = server_ipv4 # [1] 9 = client_ipv4 # [2] 19 = src_ipv6 # [3] 20 = dest_ipv6 # [4] 11 = forward_ssrc # [5] 12 = reverse_ssrc # [6] 18 = dscp_tos # [7] 3 = dr_id # [8] 4 = start_time / 6 = end_time # [9] 5 = start_time_msec / 7 = end_time_msec # [10] r1 (source ipaddr - ipv4 or ipv6) - computed in process_ohdr() # [11] r2 (dest ipaddr - ipv4 or ipv6) - computed in process_ohdr() #push @{$lookup_F2{$field[2]}}, [ @field[8,9, 19,20, 11,12,18, 3,4,5] ]; $field[19]=lc($field[19]); ## store IPv6 into lower format $field[20]=lc($field[20]); ## store IPv6 into lower format #next if ($field[12] == 0); ## When the row has reverse_ssrc=0, the row should be excluded for VQM extraction. push @{$lookup_F2{$field[2]}}, [ @field[8,9, 19,20, 11,12,18, 3,6,7] ]; push @{$lookup_F2_TN{$field[2]}}, [ @field[8,9, 19,20, 11,12,18, 3,4,5,6,7] ]; $F2_pairs++; } my $e = (time - $t); # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer #dbgprint "lookup_F2 contains ", scalar(keys %lookup_F2), " uniq OHDR entries ($linecnt_f2 recs) ($F2_pairs ipaddr pairs)\n"; write_log "Loaded FILE2: contains ", scalar(keys %lookup_F2), " uniq OHDR entries ($linecnt_f2 recs) ($F2_pairs ipaddr pairs) ($hre secs)\n"; #---------------------------------------------------------------------- # Read in table: FILE3 - MEDIA-STREAM #---------------------------------------------------------------------- # FILE3 Layout # NOTE: Array starts at 0 not 1.... # 0 = collect_timestamp # 1 = app_id # 2 = ohdr_id # 3 = dr_id # 4 = vari_index # 5 = sub_vari_index # 6 = CALLING_CALLD_ID # 7 = media_type # 8 = base_port # 9 = number_of_ports # 10 = connection_info # 11 = format_list my %lookup_F3; my $t=time; my $t0 = [gettimeofday]; my $linecnt_f3; my $F3_bad_combo=0; for($linecnt_f3=0;my $line = readline($fh_feed[3]); $linecnt_f3++ ) { chomp($line); next if ( $line =~ /^#/); # Added as part of Rel 16.02 277170p to remove header my $nfields = my @field = split(/\|/, $line, -1); # Note, there might be trailing null fields next if ($nfields != 14); # Invalid number of fields #Added as part of Rel 16.02 277170p as two new cols added # next if ($nfields != 12); # Invalid number of fields last if $MAX_LINES && $linecnt_f3 >= $MAX_LINES; # Only count valid lines with MAX_LINES $field[10] =~ s/.*\s+(\S+)$/\1/; # Only keep IPADDR from "IN IP4 12.95.111.139" $field[10] = lc($field[10]); ## store IPv6 into lower format # This file has data grouped by ohdr|dr_id|ipaddr # Store as a hash{ohdr_id}{ipaddr}{dr_id} = CALLING_CALLD_ID # Where CALLING_CALLD_ID: 0 == SRC_IPADDR, 1 == DST_IPADDR if ( ! defined($lookup_F3{$field[2]}{$field[10]}{$field[3]}) ) { # Only first combo seen is saved since most of them are all the same $lookup_F3{$field[2]}{$field[10]}{$field[3]} = $field[6]; # $lookup{ohdr_id}${ipaddr}${dr_id} = calld_id } elsif ( $lookup_F3{$field[2]}{$field[10]}{$field[3]} ne $field[6] ) { # But there are bad entries out there where calld_id is listed as both SRC(0) and DST(1) # for an IPaddr using the same DR_ID. $F3_bad_combo++; #dbgprint "WARNING: file3: Combination already defined '$field[2]', '$field[10]', '$field[3]' = $lookup_F3{$field[2]}{$field[10]}{$field[3]} ($field[6])'\n"; } } my $e = time - $t; # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer #dbgprint "lookup_F3 contains ", scalar(keys %lookup_F3), " OHDR uniq entries ($linecnt_f3 recs) ($F3_bad_combo bad combos)\n"; write_log "Loaded FILE3: contains ", scalar(keys %lookup_F3), " OHDR uniq entries ($linecnt_f3 recs) ($F3_bad_combo bad combos) ($hre secs)\n"; #---------------------------------------------------------------------- # Read in remaining tables: FILE4 - FILE8 (anping) #---------------------------------------------------------------------- my ( @fileHashR, $file4IdxGrpR ); write_log "Loading FILE4 thru FILE8\n"; my $tapc = time; my $t0 = [gettimeofday]; my $rc = &initLoadFiles(); # Load in file4 thru file8 my $e = time - $tapc; # Time to load file my $hre = tv_interval($t0, [gettimeofday]); # HiRes version of timer if ($rc != 0) { logNdie "$PROGNAME: ERROR: initLoadFiles() failed while loading FILE4 thru FILE8 ($hre secs)\n"; } write_log "Loaded FILE4 - FILE8: Elapsed Time $e secs\n"; #---------------------------------------------------------------------- # We are done loading files into memory #---------------------------------------------------------------------- $PROG_LOAD_END_TIME = time(); $PROG_LOAD_END_TIME_hr = [gettimeofday]; my $hre = tv_interval($PROG_LOAD_START_TIME_hr, $PROG_LOAD_END_TIME_hr); # HiRes version of timer write_log "Time to Load Ref Files = ", ($PROG_LOAD_END_TIME-$PROG_LOAD_START_TIME), " seconds ($hre)\n"; #---------------------------------------------------------------------- # Run some basic tests on F2 and F3 #---------------------------------------------------------------------- =begin dbgprint "\nRunning Basic Tests:\n"; foreach my $oid ( qw(8921081858089250024 8925081858163082697) ) { foreach my $x (@{$lookup_F2{$oid}}) { dbgprint "Test F2 OID $oid|$x->[7] - ($x->[0], $x->[1]) '", join("|", @{$x}), "'\n"; } } my @testdata = ( "8921081858089250024 12.194.198.5 12.213.147.226", # error: IPaddrs Defined with BOTH directions #"8921081858089250024 12.213.147.226 12.194.198.5", #"8921081858089250024 12.194.198.5 12.213.147.226", #"8925081858031149080 12.194.124.213 32.252.37.210", #"8922081858024882761 12.194.100.69 68.68.122.85", #"8922081858024882761 68.68.116.53 12.194.99.197", "8925081858163082697 32.252.41.202 12.194.99.165", #"8930081858236860999 12.211.11.26 12.194.152.48", ); # Test out the logic for checking if R1/R2 needs to be swapped for my $testrec (@testdata) { #dbgprint "\nTesting F2/F3 lookup using $testrec\n"; my ($f2_ohdr_id, $r1, $r2) = split(/ /, $testrec); dbgprint "\nTesting F2/F3 lookup using ohdrid=$f2_ohdr_id r1=$r1 r2=$r2\n"; # Test out the needRTPaddrSwap() routine my $need_swap= needRTPaddrSwap($f2_ohdr_id,$r1,$r2); if (! defined $need_swap) { dbgprint "WARNING: No matching values in F3 for ohdrid=$f2_ohdr_id r1=$r1 r2=$r2\n" } dbgprint "Need to swap r1=$r1 and r2=$r2\n" if $need_swap; } #exit 11; # FIXME - DEBUG STMT =end =cut #---------------------------------------------------------------------- # Main loop, read from FILE1 and process groups of OHDR_IDs #---------------------------------------------------------------------- write_log "################################################################################\n"; write_log "Processing data from FILE1\n"; # FILE1 Layout. '*' indicates fields we use # NOTE: Array starts at 0 not 1.... # 0 collect_timestamp # * 1 app_id # * 2 ohdr_id # * 3 dr_id # * 4 start_time_secs # * 5 start_time_msecs # * 6 end_time_secs # * 7 end_time_msecs # * 8 ringing_progess_time_secs # * 9 ringing_progess_time_msecs # * 10 call_answered_time_secs # * 11 call_answered_time_msecs # 12 call_answered_conf_time_secs # 13 call_answered_conf_time_msecs # * 14 call_terminal_time_secs # * 15 call_terminal_time_msecs # 16 status_bits # * 17 src_ip_addr # * 18 dest_ip_addr # 19 app_protocol # 20 call_type # * 21 response_code # * 22 src_port_number # * 23 dest_port_number # 24 protocol_info # 25 call_tear_down # * 26 from_url # * 27 to_url # * 28 call_id # * 29 src_IPv6 # * 30 dest_IPv6 my $linecnt_f1; my $ohdr_id; my (%SIP_FIX_MATCH_IP,%SIP_FIX_MATCH_P3_IP); my (%OHDR_TRINITY_IP,%OHDR_VNI_ID,%OHDR_P3_ID); my %P3_lookup_F1; for($linecnt_f1=0; my $line = readline($fh_feed[1]) ; $linecnt_f1++) { chomp($line); next if ( $line =~ /^#/); # Added as part of Rel 16.02 277170p to remove header my $nfields = my @field = split(/\|/, $line, -1); # Note, there might be trailing null fields next if ($nfields != 31); # Invalid number of fields last if $MAX_LINES && $linecnt_f1 >= $MAX_LINES; # Only count valid lines with MAX_LINES #dbgprint "File1/$linecnt_f1: ", join(", ", @field[2, 3, 4, 5, 17, 18, 21, 29, 30 ]), "\n"; my ( $n_app_id, $n_OHDR_ID, $n_start_ts, $n_start_msec, $n_end_ts, $n_end_msec, $n_ctc_time, $n_ctc_time_msec, $n_resp_id ) = @field[1, 2, 4, 5, 6, 7, 14, 15, 21]; ##Added by LN056J ON 03052015 #dbgprint "Line $linecnt_f1: null ipv4_srcaddr" if ( ! $field[17] ); # FIXME - DEBUG # Filter out the useless stuff quickly next unless $n_start_ts; if ( $n_OHDR_ID ne $ohdr_id ) { # OHDR_ID switched. Finish processing the prev OHDR_ID process_trinity_ohdr($ohdr_id) if $ohdr_id; # reset values to NULL since we will be starting a new OHDR_ID dbgprint "############################### Processing OHDR ID $ohdr_id #########################\n"; $ohdr_id = $n_OHDR_ID; ( $FL_dr_id, $FL_matched_dr_id, $FL_start_time, $FL_start_time_msec, $FL_matched_start_time, $FL_matched_start_time_msec, $FL_ring_progress_time, $FL_ring_progress_time_msec, $FL_call_answered_time, $FL_call_answered_time_msec, $FL_matched_ring_progress_time, $FL_matched_ring_progress_time_msec, $FL_matched_call_answered_time, $FL_matched_call_answered_time_msec, $FL_src_ipv4, $FL_dst_ipv4, $FL_matched_src_ipv4, $FL_matched_dst_ipv4, $FL_resp_id, $FL_src_port, $FL_dst_port, $FL_src_url, $FL_dst_url, $FL_call_id, $FL_src_ipv6, $FL_dst_ipv6, $FL_matched_src_ipv6, $FL_matched_dst_ipv6, $FL_F0A_F1, $FL_F0A_F2, $FL_trinity_matched ) = ("") x 29; ( $FL_matched_mix_dr_id, $FL_matched_mix_start_time, $FL_matched_mix_start_time_msec, $FL_matched_mix_ring_progress_time, $FL_matched_mix_ring_progress_time_msec, $FL_matched_mix_call_answered_time, $FL_matched_mix_call_answered_time_msec, $FL_matched_mix_src_ipv4, $FL_matched_mix_dst_ipv4, $FL_matched_mix_src_ipv6, $FL_matched_mix_dst_ipv6, $FL_resp_mix_id, $FL_src_mix_port, $FL_dst_mix_port, $FL_src_mix_url, $FL_dst_mix_url, $FL_call_mix_id, $FL_trinity_matched_mix, $SrcMixTN,$DesMixTN,$SrcMixTN_Matched,$DesMixTN_Matched ) = ("") x 22; # reset values to zero since we will be starting a new OHDR_ID ( $LL_start_time, $LL_start_time_msec, $LL_end_time, $LL_end_time_msec, $FL_matched_end_time, $FL_matched_end_time_msec , $LL_ctc_time, $LL_ctc_time_msec, $LL_ctc_resp_time, $LL_ctc_resp_time_msec, $LL_resp_id, $LL_dr_id, $LL_ctc_dr_id, $LL_resp_dr_id, $LL_ctc_dr_id, $LL_resp_dr_id ) = (0) x 10; ( $found_T3_T3, $found_T3_XX, $found_XX_T3 ) = (0) x 3; #%SIP_FIX_MATCH_TRINITY_IP = (); } #---------------------------------------------------------------------- # Check if we have newer LL record, time order based on Call_Terminal_Confirm_Time not Start_Time #---------------------------------------------------------------------- if ( $n_ctc_time > $LL_ctc_resp_time || ($n_ctc_time == $LL_ctc_resp_time && $n_ctc_time_msec > $LL_ctc_resp_time_msec) || ($n_ctc_time == 0 && $LL_ctc_resp_time == 0 && $n_ctc_time_msec == 0 && $LL_ctc_resp_time_msec == 0) ) { # This record is newer than previous LL record. Make sure it is valid before using it as new LL ## Fields to save for LL: @field[3,14,15]; ## F1: 3 #dr_id ## 14 #call_terminal_time_secs ## 15 #call_terminal_time_msecs # LL_resp_id is the last valid resp_id and is used as Call Termination Response Code. # NOTE: The final LL record might not meet the conditions for selecting resp_id so we have to track them all if ( $n_app_id == 205 && $n_resp_id < 300 ) { $LL_resp_id = $n_resp_id; $LL_ctc_resp_time = $n_ctc_time; $LL_ctc_resp_time_msec = $n_ctc_time_msec; ($LL_resp_dr_id,$LL_ctc_resp_time,$LL_ctc_resp_time_msec) = @field[3,14,15]; } elsif ( $n_app_id == 905 && $n_resp_id > 399 ) { $LL_resp_id = $n_resp_id; $LL_ctc_resp_time = $n_ctc_time; $LL_ctc_resp_time_msec = $n_ctc_time_msec; ($LL_resp_dr_id,$LL_ctc_resp_time,$LL_ctc_resp_time_msec) = @field[3,14,15]; } #dbgprint ($LL_resp_id); } if ( $n_ctc_time > $LL_ctc_time || ($n_ctc_time == $LL_ctc_time && $n_ctc_time_msec > $LL_ctc_time_msec) || ($n_ctc_time == 0 && $LL_ctc_time == 0 && $n_ctc_time_msec == 0 && $LL_ctc_time_msec == 0) ) { ## Fields to save for LL: @field[6,7, 14,15, 21] ## F1: 6 (modified date), 7, # End_Time ## 14 (modified date), 15, # Call_Terminal_Confirm_Time ## 21 (lookup in F9) # Call Termination Resp Code # dbgprint "$ohdr_id|$field[3] - new LL found\n"; $LL_ctc_time = $n_ctc_time; $LL_ctc_time_msec = $n_ctc_time_msec; #( $LL_dr_id, $LL_end_time, $LL_end_time_msec, $LL_ctc_time, $LL_ctc_time_msec) = @field[3, 6,7, 14,15]; ($LL_ctc_dr_id,$LL_ctc_time,$LL_ctc_time_msec) = @field[3,14,15]; #dbgprint ( $LL_dr_id, $LL_end_time, $LL_end_time_msec, $LL_ctc_time, $LL_ctc_time_msec , $LL_resp_id); } if ( $n_end_ts > $LL_start_time || ($n_end_ts == $LL_start_time && $n_end_msec > $LL_start_time_msec) ) { ##Added by LN056J ON 03052015 $LL_start_time = $n_end_ts; ##Added by LN056J ON 03052015 $LL_start_time_msec = $n_end_msec; ##Added by LN056J ON 03052015 ($LL_dr_id,$LL_end_time,$LL_end_time_msec) = @field[3,6,7]; #dbgprint ( $LL_dr_id, $LL_end_time, $LL_end_time_msec, $LL_ctc_time, $LL_ctc_time_msec , $LL_resp_id); } #---------------------------------------------------------------------- # Check if we have older FL record (M1/M2 check) #---------------------------------------------------------------------- #dbgprint "FL:$ohdr_id|$field[3] - $n_start_ts|$FL_start_time - $n_start_msec|$FL_start_time_msec\n"; # FIXME if ( $n_start_ts < $FL_start_time || ($n_start_ts == $FL_start_time && $n_start_msec < $FL_start_time_msec) || ! $FL_start_time) { # This record is older than previous FL record. # Make sure it is valid before using it as new FL # Retain new FL info $FL_start_time = $n_start_ts; # FL start time is from the earliest record $FL_start_time_msec = $n_start_msec; # Does not depend on validating src/dst ipaddrs ( $FL_dr_id, $FL_ring_progress_time, $FL_ring_progress_time_msec, $FL_call_answered_time, $FL_call_answered_time_msec, $FL_src_ipv4, $FL_dst_ipv4, $FL_src_ipv6, $FL_dst_ipv6 ) = @field[3,8,9,10,11,17,18,29,30]; $FL_SIP_Signaling_IP_Address = $FL_src_ipv4 ? $FL_src_ipv4 : $FL_src_ipv6; $FL_a_SBGv_Hostname = $lookup_F0A{$FL_SIP_Signaling_IP_Address}; } #---------------------------------------------------------------------- # Check for Mixed Trinity #---------------------------------------------------------------------- if ( $n_start_ts < $FL_matched_mix_start_time || ($n_start_ts == $FL_matched_mix_start_time && $n_start_msec < $FL_matched_mix_start_time_msec) || ! $FL_matched_mix_start_time) { if ($FL_trinity_matched) { dbgprint "Pure Trinity Call is Already found $SrcTN:$DesTN:$FL_matched_dr_id:$ohdr_id skip processing for $field[3]\n"; #next; } else { ($found_T3_XX,$found_XX_T3) = (0) x 2; if ( $field[26] || $field[27] ) { my ($f_26_1,$f_26_2,$f_26_3,$f_26_4)= $field[26] =~ /([^0-9]*)(\d*)(.*)(hcomm.att.net)/; my ($f_27_1,$f_27_2,$f_27_3,$f_27_4)= $field[27] =~ /([^0-9]*)(\d*)(.*)(hcomm.att.net)/; dbgprint "Mixed 1---> $f_26_2 2---> $f_27_2 3---> $field[26] $f_26_2:::$field[27] $f_27_2:::$field[3]:$ohdr_id\n"; if ($f_26_2 || $f_27_2) { my $f_26= substr ($f_26_2, -10) if $f_26_2; my $f_27= substr ($f_27_2, -10) if $f_27_2; if ( $f_26 > 0 || $f_27 > 0) { $SrcMixTN = $f_26 ; $DesMixTN = $f_27 ; my $foundMix1 = &checkTrinityCallTN($SrcMixTN,$field[3]); my $foundMix2 = &checkTrinityCallTN($DesMixTN,$field[3]); dbgprint "Mixed Trinity CAll Source TN $SrcMixTN flag $foundMix1\n"; dbgprint "Mixed Trinity CAll Destination TN $DesMixTN flag $foundMix2\n"; if ($foundMix1) { $found_T3_XX = 1; dbgprint "Mixed Trinity Call is found on From URL $SrcMixTN:$DesMixTN:$field[3]:$ohdr_id\n"; } else { $SrcMixTN = ""; } if ($foundMix2) { $found_XX_T3 = 1; dbgprint "Mixed Trinity Call is found on TO URL $SrcMixTN:$DesMixTN:$field[3]:$ohdr_id\n" } else { $DesMixTN = ""; } } } } if ($found_T3_XX || $found_XX_T3) # Indicate we found complete matches in F0A/F0B. Otherwise we will ignore the OHDR_ID { dbgprint "Mixed Trinity OHDR ID is being processed -- $ohdr_id\n"; $SrcMixTN_Matched = $SrcMixTN; $DesMixTN_Matched = $DesMixTN; $FL_trinity_matched_mix = 1; $FL_matched_mix_start_time = $n_start_ts; # FL start time is from the earliest record $FL_matched_mix_start_time_msec = $n_start_msec; # Does not depend on validating src/dst ipaddrs ( $FL_matched_mix_dr_id, $FL_matched_mix_end_time, $FL_matched_mix_end_time_msec, $FL_matched_mix_ring_progress_time, $FL_matched_mix_ring_progress_time_msec, $FL_matched_mix_call_answered_time, $FL_matched_mix_call_answered_time_msec, $FL_matched_mix_src_ipv4, $FL_matched_mix_dst_ipv4, $FL_resp_mix_id, $FL_src_mix_port, $FL_dst_mix_port, $FL_src_mix_url, $FL_dst_mix_url, $FL_call_mix_id, $FL_matched_src_ipv6, $FL_matched_dst_ipv6 ) = @field[3, 6,7,8,9, 10,11, 17,18, 21,22,23, 26,27,28, 29,30]; } } } #---------------------------------------------------------------------- # Check for pure Trinity #---------------------------------------------------------------------- if ( $n_start_ts < $FL_matched_start_time || ($n_start_ts == $FL_matched_start_time && $n_start_msec < $FL_matched_start_time_msec) || ! $FL_matched_start_time) { # This record is older than previous matched FL record. # Make sure it is valid before using it as new FL # Now we find the 'matched sorted record' by matching src/dst TN against Trinity TN Range list if ( $field[26] && $field[27] ) { #my ($f_26) = $field[26] =~ /\:(\d*)hcomm.att.net/; #my ($f_26) = $field[26] =~ /(\d*)\@hcomm.att.net/; #my ($f_26_1,$f_26_2,$f_26_3,$f_26_4)= $field[26] =~ /([^0-9]*)(\d*)(.*)(\@hcomm.att.net)/; my ($f_26_1,$f_26_2,$f_26_3,$f_26_4)= $field[26] =~ /([^0-9]*)(\d*)(.*)(hcomm.att.net)/; #$f_26 =~ s/^0+(?=\d)//; #my ($f_27) = $field[27] =~ /(\d*)\@hcomm.att.net/; #my ($f_27_1,$f_27_2,$f_27_3,$f_27_4)= $field[27] =~ /([^0-9]*)(\d*)(.*)(\@hcomm.att.net)/; my ($f_27_1,$f_27_2,$f_27_3,$f_27_4)= $field[27] =~ /([^0-9]*)(\d*)(.*)(hcomm.att.net)/; #my ($f_27) = $field[27] =~ /\:(\d*)hcomm.att.net/; #$f_27 =~ s/^0+(?=\d)//; #my $f_26 = index($field[26],$trinity_str); #my $f_27 = index($field[27],$trinity_str); dbgprint "1-FROMTN--> $f_26_2 \n"; dbgprint "2-TOTN--> $f_27_2 \n"; dbgprint "3---> $field[26] $f_26_2:::$field[27] $f_27_2:::$field[3]:$ohdr_id\n"; next if !$f_26_2; next if !$f_27_2; if ($f_26_2 && $f_27_2) { my $f_26= substr ($f_26_2, -10); my $f_27= substr ($f_27_2, -10); dbgprint "4---> f_26=$f_26:f_27=$f_27:$field[3]:$ohdr_id\n"; if ( $f_26 > 0 && $f_27 > 0) { $SrcTN = $f_26 ; #$SrcTN= substr($field[26],0,$f_26) ; #($SrcTN) = $SrcTN =~ /([0-9]+)/; $DesTN = $f_27 ; #$DesTN= substr($field[27],0,$f_27) ; #($DesTN) = $DesTN =~ /([0-9]+)/; dbgprint "$SrcTN:$DesTN:$field[3]:$ohdr_id\n" ; #$SIP_FIX_MATCH_TRINITY_IP{$field[2]}{$field[3]} = "$SrcTN:$DesTN:$field[17]:$field[18]:$field[29]:$field[30]:0";#LN056J if ($SrcTN && $DesTN) { my $found1 = &checkTrinityCallTN($SrcTN,$field[3]); my $found2 = &checkTrinityCallTN($DesTN,$field[3]); dbgprint "Trinity CAll Source TN $SrcTN flag $found1\n"; dbgprint "Trinity CAll Destination TN $DesTN flag $found2\n"; my $found = 1 if ($found1 && $found2); next if !$found; dbgprint "Trinity CAll $SrcTN:$DesTN:$field[3]:$ohdr_id\n" #$SIP_FIX_MATCH_TRINITY_IP{$field[2]}{$field[3]} = "$SrcTN:$DesTN:$field[17]:$field[18]:$field[29]:$field[30]:1";#LN056J } else{ next; } } else { next; } } else { next; } } else { next; # Ignore record since neither IPv4 or IPv6 was completely specified } ## Fields to save for FL: ## F0A: 0, 1 # Values saved during ipaddr check above ## F1: 2, # OHDRID ## 4 (modified date), 5, # Start_Time ## 8 (modified date), 9, # Ring_Progress_Time ## 10 (modified date), 11, # Call_Answered_Time ## 17 # Source_IP_V4 ## 18 # Destination_IP_V4 ## 21 (lookup in F9) # Response_Code ## 22 # Source_Port ## 23 # Destination_Port ## 26 # Source_URL ## 27 # Destination_URL ## 28 # Call_ID ## 29 # Source_IP_V6 ## 30 # Destination_IP_V6 dbgprint "Trinity OHDR ID is being processed -- $ohdr_id\n"; $FL_trinity_matched = 1; # Indicate we found complete matches in F0A/F0B. Otherwise we will ignore the OHDR_ID #$OHDR_TRINITY_IP{$ohdr_id} = 1; ##Added as part of 16.03 release to build Hash Array of Trinity OHDR_ID # Retain new FL info $FL_matched_start_time = $n_start_ts; # FL start time is from the earliest record $FL_matched_start_time_msec = $n_start_msec; # Does not depend on validating src/dst ipaddrs #$LL_matched_end_time = $n_end_ts; # FL start time is from the earliest record #$LL_matched_end_time_msec = $n_end_msec; # Does not depend on validating src/dst ipaddrs ( $FL_matched_dr_id, $FL_matched_end_time, $FL_matched_end_time_msec, $FL_matched_ring_progress_time, $FL_matched_ring_progress_time_msec, $FL_matched_call_answered_time, $FL_matched_call_answered_time_msec, $FL_matched_src_ipv4, $FL_matched_dst_ipv4, $FL_resp_id, $FL_src_port, $FL_dst_port, $FL_src_url, $FL_dst_url, $FL_call_id, $FL_matched_src_ipv6, $FL_matched_dst_ipv6 ) = @field[3, 6,7,8,9, 10,11, 17,18, 21,22,23, 26,27,28, 29,30]; } } process_trinity_ohdr($ohdr_id); # Process last remaining OHDR dbgprint "##############################################\n"; dbgprint "Non Trinity DR Processing would start from here\n"; dbgprint "##############################################\n"; #### Reset File 1 reader##### seek ($fh_feed[1],0,0); ############################# for($linecnt_f1=0; my $line = readline($fh_feed[1]) ; $linecnt_f1++) { chomp($line); next if ( $line =~ /^#/); # Added as part of Rel 16.02 277170p to remove header my $nfields = my @field = split(/\|/, $line, -1); # Note, there might be trailing null fields next if ($nfields != 31); # Invalid number of fields last if $MAX_LINES && $linecnt_f1 >= $MAX_LINES; # Only count valid lines with MAX_LINES #dbgprint "File1/$linecnt_f1: ", join(", ", @field[2, 3, 4, 5, 17, 18, 21, 29, 30 ]), "\n"; ##my ( $n_app_id, $n_OHDR_ID, $n_start_ts, $n_start_msec, $n_ctc_time, $n_ctc_time_msec, $n_resp_id ) = @field[1, 2, 4, 5, 14, 15, 21];#Replaced by LN056J 03022015 my ( $n_app_id, $n_OHDR_ID, $n_start_ts, $n_start_msec, $n_end_ts, $n_end_msec, $n_ctc_time, $n_ctc_time_msec, $n_resp_id ) = @field[1, 2, 4, 5, 6, 7, 14, 15, 21]; ##Added by LN056J ON 03052015 #dbgprint "Line $linecnt_f1: null ipv4_srcaddr" if ( ! $field[17] ); # FIXME - DEBUG # Filter out the useless stuff quickly next if ($OHDR_TRINITY_IP{$n_OHDR_ID}); ## If OHDRID is already processed as Trinity OHDR then no need to process it again. #dbgprint "Non Trinity $n_OHDR_ID and $line\n"; next unless $n_start_ts; if ( $n_OHDR_ID ne $ohdr_id ) { # OHDR_ID switched. Finish processing the prev OHDR_ID