#!/usr/bin/perl -w

use bytes;	# no unicode

$| = 1;
my $header;
my $message;
my %memory;
while(sysread(STDIN, $header, 8) == 8) {

  (my $magic, my $length) = unpack('N2', $header);
  if ($magic != 0xbeefdead || $length < 8) { 
    die("Bad header: " . unpack('H*', $header) . "!\n"); 
  }
  $length -= 8;
  
  if (sysread(STDIN, $message, $length) != $length) { 
    die("read($length): $!\n"); 
  }

  # Walk through the message

  undef $op;
  undef $key;
  undef $pairs;
  for(my $ofs = 0; $ofs < $length; $ofs += $skiplen) {

    # Decode the pair 

    (my $sva, my $len) = unpack('@' . $ofs . 'A[12] N', $message);
    $ofs += 16;
    $skiplen = ($len + 3) & ~3;
    my $val = unpack('@' . $ofs . 'a[' . $skiplen . ']', $message);

    print STDERR  unpack('H*', $sva) . "\t" .
		  unpack('H*', $val) . "\n";

    # Save last instances of 'op' and 'key'; save rest in our pairs structure,
    # which is a hash keyed by the attribute tuple, containing an array
    # reference 
    # to by a hash element with the space, vendor attribute tuple as the key.

    if ($sva eq "\x00\x00\x00\x64\x80\x00\x00\x00\x00\x00\x00\x84") {
      $op = unpack('N', $val);
    } elsif ($sva eq "\x00\x00\x00\x64\x80\x00\x00\x00\x00\x00\x00\x85") {
      $key = $val;
    } else {
      push @{$pairs->{$sva}}, [ $len, $val ];
    }
  }

  # If we didn't get a key, respond with int=-1 and we're done.

  unless (defined $key) {
    print STDERR "Didn't get a key, ignorning message.\n";
    print "\xde\xad\xbe\xef\x00\x00\x00\x1c" .
	  "\x00\x00\x00\x64\x80\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04" .
	    "\xff\xff\xff\xff";
    next;
  }

  print STDERR "Got request " . $op . " for key [" . $key . "]\n";

  # Act on the requested operation
  
  $ret = defined $memory{$key};
  $reppkt = '';

  if ($op == 1) {				  # Store
    $memory{$key} = $pairs;
  } elsif ($op == 4 || $op == 5) {		  # Load, Load-Purge
    $pairs = $memory{$key};
    $ret = 0;
    foreach my $sva (keys %$pairs) {
      foreach my $pair (@{$pairs->{$sva}}) {
	print STDERR unpack('H*', $sva) . ":\t" . $pair->[0] . "\t" . unpack('H8', $pair->[1]) . "\t" . $pair->[1] . "\n";
	$reppkt .= $sva . pack('Na*x![N]', $pair->[0], $pair->[1]);
	$ret++;
      }
    }
  }
  if ($op == 5 || $op == 6) { undef $memory{$key}; }  # Load-Purge, Purge

  # Respond with an instance of 'int'

  print "\xde\xad\xbe\xef" . pack('N', length($reppkt) + 0x1c) . 
	$reppkt . 
        "\x00\x00\x00\x64\x80\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04" .
	  pack('N', $ret);
}

die("EOF on input - exiting"); 

# vim:softtabstop=2:sw=2

