#!/usr/bin/perl

# convert Tpod pcap to gnuplot 3D datafile
# typical commands:
# ./tpod2dat3d.pl tpod.cap 100 > tpod.3d.dat
# gnuplot> splot 'tpod.3d.dat' w d

# Andrew Daviel Feb 2016

use Net::Pcap qw( :functions );
my $err = '';

$file = shift or die "Need pcap file\n" ;
$pcap = pcap_open_offline($file, \$err) or die "Can't read '$file': $err\n";

# plot with all data plotted is too dense to read 
$skip = shift or $skip = 1 ;


$filter_str = 'udp and port 5000 and src 192.168.1.1' ;
$s = pcap_compile($pcap, \$filter, $filter_str, 1, 0) ;

#print "compile $s\n" ;
pcap_setfilter($pcap, $filter) ;

print "# time len range depth b25 temp b31 min cdepth\n" ;

#while (pcap_next_ex($pcap, \%header, \$packet)) {
$pkt = 0 ; 
pcap_loop($pcap, -1, \&process_packet, "user data");

$k = 0 ;
sub process_packet {
  my ($user_data, $header, $packet) = @_;
  $k++ ;
  if ($skip and $k<$skip) { return ; }
  $k = 0 ;
  $time = $header->{'tv_sec'} + $header->{'tv_usec'} / 1000000 ;
  my @pkt = split('',$packet) ;

  for ($i=0;$i<42;$i++) { shift(@pkt) ; } # packet header

  for ($i=0;$i<@pkt;$i++) { $B[$i] = unpack("C",$pkt[$i]) ; }

  $len = $B[5]*256+$B[4] ; # record length (340 for depth data)
  $range = $B[18] ; # display range

  unless ($len == 340) { return ; }
  for ($i=40;$i<338;$i++) {
    $depth = $B[$i] * $range / 300 ;
    print "$time $i $depth\n" ;
  }
  print "\n" ;
}
