#Sample perl file to grab the data from the log...

@items;  #stores one line
@total;
@lines;

#POSITIONS, starting from 0
#Start time, End time, BSSID, Ch, Sl, Nl, Snr, AP Name
$STARTTIME = 0;
$ENDTIME = 1;
$ID = 2;
$CH = 3; 
$SL = 4;
$NL = 5;
$SNR = 6;
$NAME = 7;

$location_name;
$dir = '.';   #current directory
$suffix = '.pos.txt';
$fmt = "5.4f"; #number format

# Hashes to hold fields, keys are BSSID ($ID)
%starttime;
%endtime;
%ch;
%sl;
%nl;
%snr;
%name;

%num; #used for

#get log
$LOG = "c:/program files/orinoco/client manager/log/monitor.log";
open LOG or die "Error opening $LOG: $!\n";

#extract important data from log
while ($line = <LOG>) {            #get line of input
  if ( $line =~ /,,.*[\d]/ ){      # contains ",," and a number
     @items = split( /,/ , $line); # get the fields
     #print "$line";
     #print "@items \n";
     $full = join ' ', @items;
     #print "$full \n";
     #push (@total, [ @items ]);  #maybe an array of arrays is too annoying
     push (@lines, $full); 
  }
}

close LOG;

# put signal data into tables
foreach $line (@lines){
	@item = split( ' ', $line ); #delimited by spaces now
	
	#print @item;
	#print "$item[$ID] $item[$SNR] \n";
	
	#hash on the ID
	$snr{ $item[$ID] } += $item[$SNR]; 	# used with averages 
	$nl{ $item[$ID] } += $item[$NL];   	# used with averages 
	$sl{ $item[$ID] } += $item[$SL]; 	# used with averages 
	$name{ $item[$ID] } = $item[$NAME]; 
	$ch{ $item[$ID] } = $item[$CH];
	
	$num{ $item[$ID] }++; #increment count for this ID
}

#compute averages for snr, sl, nl

&set_avgs();
#&print_hashes();
&distance(\%snr, \%nl); # need to get access list...

##########################################################
#
# Get other variables for the snr, etc. of the acess list
#  Read these in to get the match.. then print the matches in order
# along with the name of the access list.
###########################################################


#either match OR record ... don't want to do both.
#&record($location_name);
&match();

# get all the entries
# compare to them one-by-one (in future, create hash table an iterate
#    through them?). create some sort of profile?


###########################################################
# FUNCTIONS
#
###########################################################


#
# match()
sub match{
	my $ID = 0; #all in new format (see record)
	my $SL = 1;
	my $NL = 2;
	my $SNR = 3;
	my $NAME = 4;
	my %results;

	opendir DIR, $dir or die "Can't open directory $dir: $!\n";
	
	@files = grep /$suffix/, readdir(DIR);
	#print "Location files found: \n", "@files";
	
	close DIR;
	
	foreach $file (@files){
		%loc_snr = base_extract($file, $ID, $SNR);
		#print_hash(%loc_snr, "loc_snr");
		
		$num = sprintf( "%$fmt", distance(\%loc_snr, \%snr) );
		$_ = $suffix;
		
		#$results{ $num } = substr($file, 0, length($file) - length($suffix));
		#store name as hash key, distance as value
		$results{ substr($file, 0, length($file) - length($suffix)) } = $num;
	}
	
	$max = 10;	
	print "\n----$max Closest Matches----\n";
	
	@sorted = sort { $results{$a} <=> $results{$b} } keys %results;
	
	for ($i = 0; $i < $max; $i++) {
		print "name: $sorted[$i]  distance: $results{$sorted[$i]} \n";
	}
	
	#foreach $i (sort { $results{$a} <=> $results{$b} } keys %results ){
	#	print "name: $i  distance: $results{$i} \n";
	#}

	unlink $LOG; #delete original log file
	print "deleting $LOG\n";	
}

#
# base_extract( $file, $ID, $element )  ... returns hash
sub base_extract(){
	my %hash;
	my $file = shift;
	my $ID = shift;
	my $elm = shift;
	open FILE, $file or die "Can't open file $file: $!\n";
	
	while (<FILE>){
		my @item = split;
		$hash{ $item[$ID] } = $item[ $elm ]; #take certain element
	}
	
	close FILE;
	
	return %hash;
}

# record( $location_name ) -> file.txt
# record info as ID, sl, nl, snr, AP name 
sub record{
	my $name = shift;
	
	$name = $name.$suffix; #add suffix
	
	open OUT, ">$name" or die "Couldn't open file $name: $!\n";
	print "Recording $name \n";
	
	foreach $i (keys %snr){
		printf OUT "$i %$fmt %$fmt %$fmt %s\n", $sl{$i}, $nl{$i}, $snr{$i}, $name{$i};
	}
	
	close OUT;
}

#
# Assume that a (first argument) is the table data
# Iterates through keys in a
# distance( \%a, \%b);
sub distance{
	my $dist = 0;
	my $a = shift;
	my $b = shift;
	
	foreach $i (keys %{$a} ){
		$a_val = $a->{$i};
		$b_val = $b->{$i};
		$dist += ($a_val - $b_val) * ($a_val - $b_val); #square difference
	}
	
	foreach $i (keys %{$b} ){
		if (! exists $a->{$i} ){
			$dist += ($b->{$i} * $b->{$i}) ; #punish for nodes in b not found in a
		}
	}
	
	printf ("distance: %$fmt \n", $dist);
	return $dist;
}

# Prints key, value and name of hash
# print_hash(%hash, $name)
sub print_hash{
	$name = pop(@_); 	#ugly hack... the hash and name get combined
					 	#so pop the name off
	%hash = @_;
	print "----hash $name ---- \n";
	foreach $i (keys %hash) {
        print "key: $i value: $hash{$i}\n";
	}
	print "\n";
}

# Sets hash to avg value, depending on num
# set_avg(\%hash)   [pointer to hash]
sub set_avg{
	#print "set_avg:\n";
	$hash = shift; #grab first reference
	
	foreach $i (keys %{$hash}) {
		#print "key: $i value: $hash->{$i}\n";
		#print $hash->{$i} / $num{$i};
		$avg = $hash->{$i} / $num{$i};
		#print "$avg \n";
		${$hash}{$i} = $avg;
	}
}

#compute averages for snr, sl, nl
sub set_avgs{
	&set_avg(\%snr);
	&set_avg(\%sl);
	&set_avg(\%nl);
}

#prints all the hash tables
sub print_hashes{
	&print_hash(%snr, 'snr');
	&print_hash(%nl, 'nl');
	&print_hash(%num, 'num');
	&print_hash(%ch, 'ch');
	&print_hash(%sl, 'sl');
}
