#!/usr/bin/perl -w

# Extraction of data from Wintec EasyShowily GPS logger ring buffer file
# NVPIPE.DAT

use strict;

use Time::Local;
use Fcntl ":seek";

# -> raw time value from Wintec GPS
# <- (year, month, day, hour, minute, second, seconds since epoch) all in UTC
sub decodetime
{
    my $raw= shift;
    my @result;
    unshift @result, ($raw & 0x3F);
    $raw >>= 6;
    unshift @result, ($raw & 0x3F);
    $raw >>= 6;
    unshift @result, ($raw & 0x1F);
    $raw >>= 5;
    unshift @result, ($raw & 0x1F);
    $raw >>= 5;
    unshift @result, ($raw & 0xF);
    $raw >>= 4;
    unshift @result, ($raw & 0x3F) + 2000;
    my $epochsecs= eval { timegm(reverse(@result[2..5]), $result[1]-1, $result[0]); };
    if( $@ ) {
        print STDERR "Error determining epoch-based date: $@\n";
        $epochsecs= 0;
    }
    push @result, $epochsecs;
    return @result;
}

my $handle;

if( @ARGV ) {
    if( $ARGV[0] =~ /^(?:-h|--help)$/i ) {
        print <<EOF;
usage: wintec2000-extract.pl [<input file>]
Converts the data from the binary ring buffer of a Wintec EasyShowily GPS
logger to an ASCII table.  The input file may be given on the command line;
otherwise the appropriate file name NVPIPE.DAT is looked for in the current
directory and the automount point of the logger; otherwise data are read from
STDIN.
The columns of the output are: latitude, longitude, altitude, year, month, day,
hour, minute, second, seconds since Epoch (00:00 1 Jan 1970).  All time data is
in time zone 0 (UTC).
EOF
        exit;
    }
    open $handle, "<", $ARGV[0] or die "\nCannot open $ARGV[0]";
}
elsif( -f "./NVPIPE.DAT" ) {
    open $handle, "<./NVPIPE.DAT"
        or die "\n./NVPIPE.DAT exists, but cannot be opened.";
}
elsif( -f "/media/sfio_easyshowily_0/NVPIPE.DAT" ) {
    open $handle, "</media/sfio_easyshowily_0/NVPIPE.DAT" or
     die "\n/media/sfio_easyshowily_0/NVPIPE.DAT exists, but cannot be opened.";
}
else {
    print "Reading binary data from STDIN...\n";
    $handle= *STDIN{IO};
}

seek $handle, 0x1000, SEEK_SET;

my $data;

print "# latitude [deg]   longitude [deg]   altitude [m]   time  track\n";

while( 16 == read $handle, $data, 16 ) {
    my ($track, $time, $lat, $long, $alt)= unpack "Sllls", $data;
    last if $lat == -1;
    $lat /= 10000000.0;
    $long /= 10000000.0;
    if( $lat > 100 || $lat < -100 ) {
        print "\n\n";
        next;
    }
    $track ||= "";
    print "\n\n" if $track =~ /^[13]/;      # switched on or new track
    print "$lat   $long   $alt   ", join(" ", decodetime $time), "   $track\n";
}

