#!/usr/bin/perl
# Perl script to test network performance of a wireless device using file transfers to an NFS server on the LAN
#
# Version of 03/28/07:     Larry Finger
#
# This script has three parameters - the name of the interface, the mount point of the NFS volume, and
# the name of the local file to be transferred. The wireless utility 'iwconfig' is used
# to change the wireless rate, therefore this script must be run as root.
#
# Sample: ./file_test eth1 /nfs_mount path_to_file
#

# Set up to restore default rate if interrupted

$SIG{'INT' } = 'interrupt';
$SIG{'QUIT'} = 'interrupt';
$SIG{'HUP' } = 'interrupt';
$SIG{'TRAP'} = 'interrupt';
$SIG{'ABRT'} = 'interrupt';
$SIG{'STOP'} = 'interrupt';

# Check arguments

$numArgs = $#ARGV + 1;
if ($numArgs != 3) {
	print "\nUsage: file_test.pl <interface> <nfs mount point> <file name>\n\n";
	exit 0;
}

$interface = $ARGV[0];
$nfs_server = $ARGV[1];
$file_name = $ARGV[2];

# check that interface actually exists

`iwconfig  $interface > file.tmp 2>&1`;
$tmp = `grep IEEE file.tmp`;

if (length($tmp) < 5) {
    print "\nInterface $interface does not exist.  Run aborted.\n\n";
    exit (1);
}

# check that NFS mount point exists

opendir(IMD, $nfs_server) || die("Cannot open NFS server mount point");
closedir(IMD);

# check that file exists

if ( !( (-e $file_name) && (-r $file_name) ) ) {
    print "\nFile $file_name does not exist, or cannot be read. Run aborted.\n\n";
    exit (1);
}

# Copy file to a temporary location

$temp = "tmp_file_test";
`cp $file_name $temp`;

# Build the "from" file name

$from_file = "$nfs_server" . "/" . "$temp";

# Get size of the file

my $filesize = -s $temp;

print "\nMeasure File Transfer Speed\n";
print   "===========================\n\n";
print "This utility will do a ping/pong transfer of file \"$file_name\" to/from ";
print "the NFS server at \"$nfs_server\".\n\n";
print "The units of KBs are equal to \"size (in bytes)\" / \"time (in seconds)\" / 1024\n\n";

# Loop through the rates to be tested

foreach $i (6, 9, 11, 18, 24, 36, 48) {
    $rate = "$i" . "M";
    `iwconfig $interface rate $rate`;
    print "\nWireless rate set to $i Mbs with iwconfig\n";

# Delete any copy of the file now on the server and copy the data file to it

    `rm -f $from_file`;
    `time (cp $temp $nfs_server) > file.tmp 2>&1`;

# Get the transmit data time from file.tmp and calculate the rate

    $tmp=`grep real file.tmp | tr a-z ' '  | awk '{i=split(\$0,a) ; print 60 * a[1] + a[2] ; exit}'`;
    $trans_rate = $filesize / $tmp / 1024;
    printf "Transmit rate is %.1f KBs\n" , $trans_rate;

# Delete the local copy of the temporary copy of the data file and copy it back from the server

    `rm -f $temp`;
    `time (cp $from_file .) > file.tmp 2>&1`;

# Get the receive time from file.tmp and calculate the rate

    $tmp=`grep real file.tmp | tr a-z ' '  | awk '{i=split(\$0,a) ; print 60 * a[1] + a[2] ; exit}'`;
    $recv_rate = $filesize / $tmp / 1024;
    printf " Receive rate is %.1f KBs\n" , $recv_rate;

}

# Clean up

`rm -f file.tmp`;
`rm -f $temp`;
`rm -f $from_file`;

# Reset the interface rate

`iwconfig $interface rate 24M`;
print "\nRate reset to 24 Mbs by iwconfig\n";

exit 0;

# Interrupt subroutine

sub interrupt {
    my($signal)=@_;
    print "Caught Interrupt\: $signal \n";

# Restore a rate of 24M and clean up

    `iwconfig $interface rate 24M`;
    `rm -f perf.tmp`;

    print "\nRate reset to 24 Mbs by iwconfig\n";
    print "Now Exiting\n";
    exit(1);
}

