#!/usr/bin/perl
use Device::USB ;

my $file = shift ( @ARGV ) ;
my $urb_start = shift ( @ARGV ) ;
my $urb_ende = shift ( @ARGV ) ;

open ( INDAT , '<' . $file ) ;

while ( !eof ( INDAT ) )
{
  ( $epD , $dataD , $infoD , $epB , $dataB , $infoB ) = get_urb_data() ;

  if ( ( $epD eq '02' ) && ( substr ( $dataD , 0 , 5 ) eq '05 70' ) )
  {
    my ( $cmd1 , $cmd2 , $lo , $hi ) = split ( m! ! , $dataD ) ;
    my $len = hex($hi)*256 + hex($lo) ;

    while ( $len )
    {
      ( $epD , $dataD , $infoD , $epB , $dataB , $infoB ) = get_urb_data() ;

      if ( $epB eq '83' )
      {
        my @data = split ( m! ! , $dataB ) ;

        if ( @data > $len )
        {
          @data = splice ( @data , 0 , $len ) ;
        }

        print join ( ' ' , @data ) , "\n" ;
        $len -= @data ;
      }
      else
      {
print 'FEHLER' , "\n" ;
exit;
      }
    }
  }
}

close ( INDAT ) ;
1 ;

sub get_urb_data
{
  my $state = 'INFO_DOWN' ;
  my ( $typD , $dirD , $epD , $dataD , $infoD ) = ( ) ;
  my ( $typB , $dirB , $epB , $dataB , $infoB ) = ( ) ;

  while ( $zeile = <INDAT> )
  {
    chomp ( $zeile ) ;

    if ( substr ( $zeile , 0 , 1 ) eq '#' )
    {
      next ( ) ;
    }

    if ( $state eq 'INFO_DOWN' )
    {
      unless ( $zeile )
      {
        next ( ) ;
      }

      ( $typD , $dirD , $epD ) = split ( m! +! , $zeile ) ;
      $infoD = $zeile ;

      unless ( $typD eq 'BULK' )
      {
        error ( 'Type does not match BULK' , $zeile ) ;
      }

      $state = 'DATA_DOWN' ;
      $dataD = '' ;
    }
    elsif ( $state eq 'DATA_DOWN' )
    {
      if ( substr ( $zeile , 12 , 1 ) eq ':' )
      {
        $dataD .= $zeile ;
      }
      elsif ( $zeile )
      {
        ( $typB , $dirB , $epB ) = split ( m! +! , $zeile ) ;
        $infoB = $zeile ;

        unless ( $typB eq 'BULK' )
        {
          error ( 'Type does not match BULK' , $infoD , $zeile ) ;
        }

        $state = 'DATA_BACK' ;
        $dataB = '' ;
      }
      else
      {
        last ( ) ;
      }
    }
    elsif ( $state eq 'DATA_BACK' )
    {
      if ( substr ( $zeile , 12 , 1 ) eq ':' )
      {
        $dataB .= $zeile ;
      }
      elsif ( $zeile )
      {
        error ( 'Empty line expected' , $infoD , $infoB , $zeile ) ;
      }
      else
      {
        last ( ) ;
      }
    }
    else
    {
      error ( 'Illegal state' , $infoD , $zeile ) ;
    }
  }

  $dataD = dez2hex ( hex2dez ( $dataD ) ) ;
  $dataB = dez2hex ( hex2dez ( $dataB ) ) ;
  return ( $epD , $dataD , $infoD , $epB , $dataB , $infoB ) ;
}

sub bin2dez
{
  my ( $data ) = @_ ;
  my @data = unpack ( 'C*' , $data ) ;
  return ( @data )
}

sub dez2bin
{
  my ( @data ) = @_ ;
  my $data = pack ( 'C*' , @data ) ;
  return ( $data )
}

sub hex2dez
{
  my ( $txt ) = @_ ;
  $txt =~ s![\da-f]+:!!ig ;
  $txt =~ s!\A\s+!! ;
  $txt =~ s!\s+\Z!! ;
  my @data = split ( m!\s+! , $txt ) ;

  foreach ( @data )
  {
    $_ = hex ( $_ ) ;
  }

  return ( @data ) ;
}

sub dez2hex
{
  my ( @line ) = @_ ;
  my $anz = @line ;
  my $line = sprintf ( '%02x ' x $anz , @line ) ;
  $line =~ s!\s+\Z!! ;
  return ( $line ) ;
}

sub bin2hex
{
  my ( $data ) = @_ ;
  my @data = bin2dez ( $data ) ;
  my $txt = dez2hex ( @data ) ;
  return ( $txt ) ;
}

sub hex2bin
{
  my ( $txt ) = @_ ;
  my @data = hex2dez ( $txt ) ;
  my $data = dez2bin ( @data ) ;
  return ( $data ) ;
}

sub control_msg
{
  my ( $dev , $txt ) = @_ ;
  my ( $typ , $req , $Lv , $Hv , $Li , $Hi , $Ls , $Hs ) = hex2dez ( $txt ) ;
  my $value = $Hv*256 + $Lv ;
  my $index = $Hi*256 + $Li ;
  my $size = $Hs*256 + $Ls ;
  my $buffer = "\0" x $size ;
  my $retval = $dev -> control_msg ( $typ , $req , $value , $index , $buffer , $size , $timeout ) ;
  my @buffer = bin2dez ( $buffer ) ;
  return ( @buffer ) ;
}

sub printhex
{
  my ( @data ) = @_ ;

  while ( @data )
  {
    my @line = splice ( @data , 0 , 16 ) ;
    my $line = dez2hex ( @line ) ;
    print $line , "\n" ;
  }
}

sub display
{
  my ( $dev , $key , $val , $txt ) = @_ ;
  my $pad = ' ' x 22 ;
  $key = substr ( $key . $pad , 0 , 22 ) ;

  if ( $txt == 1 )
  {
    $txt = $dev -> get_string_simple ( $val ) ;
  }

  if ( $txt )
  {
    $txt = ' (' . $txt . ')' ;
  }

  print ( $key , $val , $txt , "\n" ) ;
}

sub error
{
  my ( @msg ) = @_ ;
  $msg[0] .= ' !' ;
  print 'ERROR: ' , join ( "\n" , @msg ) , "\n" ;
  exit ;
}
