#!/usr/bin/perl -w
use strict;

###############################################################################
#
# Copyright (c) 2007 MetaGeek, LLC
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# Except as contained in this notice, the name(s) of the above 
# copyright holders shall not be used in advertising or otherwise 
# to promote the sale, use or other dealings in this Software 
# without prior written authorization.
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
###############################################################################

###############################################################################
#
# Note by Ryan Woodings: Oct 4, 2007
# I am NOT a perl guru as you will notice by looking at the following code.
# Although it is functional it isn't pretty code, and I'm sure there are more
# efficient ways of doing this file conversion.
# 
# Therefore I am asking two things of you:
# 1. Please do not judge my coding skills by this perl script :-)
# 2. If you are a perl guru and have a few minutes, please optimize this script.
#
###############################################################################


my($inputFileName);
my($outputFileName);

# Set the input and output file names
my($numArgs) = $#ARGV + 1;
if ($numArgs >= 1)
{
    $inputFileName = $ARGV[0];
}
else
{
    &Dienice("Please specify input file as first parameter");
}
if ($numArgs >= 2)
{
    $outputFileName = $ARGV[1];
}
else
{
    (my($fileName), my($ext)) = split(/\./, $inputFileName);		

    $outputFileName = "$fileName.csv";
}

# Open the input file
open(INPUT, "$inputFileName") or &Dienice("Couldn't open $inputFileName for reading");

# Set input file I/O mode to binary
binmode(INPUT);

# Open the output file
open(OUTPUT, ">$outputFileName") or &Dienice("Couldn't open $outputFileName for writing");

#check file version... currently only handles version 3 (compatible with Chanalyzer 2.1.6)
my($readcount) = read(INPUT, my($inputString), 4);
my($fileVersion) = unpack('N', $inputString);

if ($fileVersion != 3)
{
    &Dienice("Incorrect WSR File Version: $fileVersion");
}
#read rest of file header
$readcount = read(INPUT, $inputString, 2);
my($deviceVersion) = unpack('n', $inputString);
$readcount = read(INPUT, $inputString, 4);
my($freqOffsetKHz) = unpack('N', $inputString);
$readcount = read(INPUT, $inputString, 4);
my($freqResHz) = unpack('N', $inputString);
$readcount = read(INPUT, $inputString, 2);
my($numFreqPoints) = unpack('n', $inputString);
$readcount = read(INPUT, $inputString, 4);

#not sure how to convert to signed 32-bit network order
#so this is a hack...
my($ampOffset) = unpack('N', $inputString);
$inputString = pack('I', $ampOffset);
$ampOffset = unpack('i', $inputString);

$readcount = read(INPUT, $inputString, 4);
my($ampRes) = unpack('N', $inputString);
$readcount = read(INPUT, $inputString, 2); #RSSI max steps... we don't need it for the CSV conversion
$readcount = read(INPUT, $inputString, 8); #First bookmark in file... 


print "fileVersion: $fileVersion\n";
print "deviceVersion: $deviceVersion\n";
print "freqOffsetKHz: $freqOffsetKHz\n";
print "freqResHz: $freqResHz\n";
print "freqPoints: $numFreqPoints\n";
print "ampOffset: $ampOffset\n";
print "ampRes: $ampRes\n";

print "Converting $inputFileName\n";

print OUTPUT "Secnds since EPOCH,Microseconds,";

# Print header row
for (my($freqPoint) = 0; $freqPoint < $numFreqPoints; $freqPoint++)
{
    my($frequency) = ($freqOffsetKHz * 1000) + ($freqResHz * $freqPoint);
    print OUTPUT "$frequency";
    if ($freqPoint != $numFreqPoints - 1)
    {
        print OUTPUT ",";
    }
}
print OUTPUT "\n";

my($moreData) = 1;
while ()
{
    # Read timestamp (seconds since EPOCH)
    $readcount = read(INPUT, $inputString, 4);
    if ($readcount == 4)
    {
        my($timeStamp) = unpack('N', $inputString);
        print OUTPUT "$timeStamp,";
    
        # read microseconds 
        $readcount = read(INPUT, $inputString, 4);
        if ($readcount == 4)
        {
            my($timeStamp) = unpack('N', $inputString);
            print OUTPUT "$timeStamp,";
    
            for (my($freqPoint) = 0; $freqPoint < $numFreqPoints; $freqPoint++)
            {
                # Read RSSI of frequency
                $readcount = read(INPUT, $inputString, 1);
                if ($readcount == 1)
                {
                    # Interpret as unsigned char
                    my($rssi) = unpack('C', $inputString);
                    
                    # Convert RSSI to dBm
                    my($amplitude) = ($rssi * $ampRes + $ampOffset) / 1000;   # ampRes and ampOffset are in .001 dBm steps
                    
                    # Print amplitude to output file
                    print OUTPUT "$amplitude";
                    if ($freqPoint != $numFreqPoints - 1)
                    {
                        print OUTPUT ",";
                    }
                    else
                    {
                        print OUTPUT "\n";
                    }
                }
                else
                {
                    last;
                }
            }
        }
        else
        {
            last;
        }
    }
    else
    {
        last;
    }
}

close(INPUT);
close(OUTPUT);

print "Successfully converted $inputFileName to $outputFileName";

###########################################
sub Dienice
{
    my($errmsg) = @_;
    print "Error: $errmsg\n";
    exit;
}

