/[RFID]/3m-810.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /3m-810.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 29 by dpavlin, Mon Apr 6 13:10:40 2009 UTC revision 75 by dpavlin, Thu Feb 11 22:12:34 2010 UTC
# Line 8  use Data::Dump qw/dump/; Line 8  use Data::Dump qw/dump/;
8  use Carp qw/confess/;  use Carp qw/confess/;
9  use Getopt::Long;  use Getopt::Long;
10  use File::Slurp;  use File::Slurp;
11    use JSON;
12    use POSIX qw(strftime);
13    
14  use IO::Socket::INET;  use IO::Socket::INET;
15    
16  my $meteor_server = '192.168.1.13:4671';  my $debug = 0;
17  my $meteor_fh;  
18    my $tags_data;
19    my $tags_security;
20    my $visible_tags;
21    
22    my $listen_port = 9000;                  # pick something not in use
23    my $server_url  = "http://localhost:$listen_port";
24    
25    sub http_server {
26    
27            my $server = IO::Socket::INET->new(
28                    Proto     => 'tcp',
29                    LocalPort => $listen_port,
30                    Listen    => SOMAXCONN,
31                    Reuse     => 1
32            );
33                                                                      
34            die "can't setup server" unless $server;
35    
36            print "Server $0 ready at $server_url\n";
37    
38            sub static {
39                    my ($client,$path) = @_;
40    
41                    $path = "www/$path";
42                    $path .= 'rfid.html' if $path =~ m{/$};
43    
44  sub meteor {                  return unless -e $path;
45          my @a = @_;  
46          push @a, scalar localtime() if $a[0] =~ m{^info};                  my $type = 'text/plain';
47                    $type = 'text/html' if $path =~ m{\.htm};
48          if ( ! defined $meteor_fh ) {                  $type = 'application/javascript' if $path =~ m{\.js};
49                  warn "# open connection to $meteor_server";  
50                  $meteor_fh = IO::Socket::INET->new(                  print $client "HTTP/1.0 200 OK\r\nContent-Type: $type\r\n\r\n";
51                                  PeerAddr => $meteor_server,                  open(my $html, $path);
52                                  Timeout => 1,                  while(<$html>) {
53                  ) || warn "can't connect to meteor $meteor_server: $!"; # FIXME warn => die for production                          print $client $_;
54                  $meteor_fh = 0; # don't try again                  }
55                    close($html);
56    
57                    return $path;
58          }          }
59    
60          warn ">> meteor ",dump( @a );          while (my $client = $server->accept()) {
61          print $meteor_fh "ADDMESSAGE test ",join('|',@a),"\n" if $meteor_fh;                  $client->autoflush(1);
62                    my $request = <$client>;
63    
64                    warn "WEB << $request\n" if $debug;
65    
66                    if ($request =~ m{^GET (/.*) HTTP/1.[01]}) {
67                            my $method = $1;
68                            my $param;
69                            if ( $method =~ s{\?(.+)}{} ) {
70                                    foreach my $p ( split(/[&;]/, $1) ) {
71                                            my ($n,$v) = split(/=/, $p, 2);
72                                            $param->{$n} = $v;
73                                    }
74                                    warn "WEB << param: ",dump( $param ) if $debug;
75                            }
76                            if ( my $path = static( $client,$1 ) ) {
77                                    warn "WEB >> $path" if $debug;
78                            } elsif ( $method =~ m{/scan} ) {
79                                    my $tags = scan_for_tags();
80                                    my $json = { time => time() };
81                                    map {
82                                            my $d = decode_tag($_);
83                                            $d->{sid} = $_;
84                                            $d->{security} = $tags_security->{$_};
85                                            push @{ $json->{tags} },  $d;
86                                    } keys %$tags;
87                                    print $client "HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n",
88                                            $param->{callback}, "(", to_json($json), ")\r\n";
89                            } elsif ( $method =~ m{/program} ) {
90    
91                                    my $status = 501; # Not implementd
92    
93                                    foreach my $p ( keys %$param ) {
94                                            next unless $p =~ m/^(E[0-9A-F]{15})$/;
95                                            my $tag = $1;
96                                            my $content = "\x04\x11\x00\x01" . $param->{$p};
97                                            $content = "\x00" if $param->{$p} eq 'blank';
98                                            $status = 302;
99    
100                                            warn "PROGRAM $tag $content\n";
101                                            write_tag( $tag, $content );
102                                            secure_tag_with( $tag, $param->{$p} =~ /^130/ ? 'DA' : 'D7' );
103                                    }
104    
105                                    print $client "HTTP/1.0 $status $method\r\nLocation: $server_url\r\n\r\n";
106    
107                            } elsif ( $method =~ m{/secure(.js)} ) {
108    
109                                    my $json = $1;
110    
111                                    my $status = 501; # Not implementd
112    
113                                    foreach my $p ( keys %$param ) {
114                                            next unless $p =~ m/^(E[0-9A-F]{15})$/;
115                                            my $tag = $1;
116                                            my $data = $param->{$p};
117                                            $status = 302;
118    
119                                            warn "SECURE $tag $data\n";
120                                            secure_tag_with( $tag, $data );
121                                    }
122    
123                                    if ( $json ) {
124                                            print $client "HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n",
125                                                    $param->{callback}, "({ ok: 1 })\r\n";
126                                    } else {
127                                            print $client "HTTP/1.0 $status $method\r\nLocation: $server_url\r\n\r\n";
128                                    }
129    
130                            } else {
131                                    print $client "HTTP/1.0 404 Unkown method\r\n\r\n";
132                            }
133                    } else {
134                            print $client "HTTP/1.0 500 No method\r\n\r\n";
135                    }
136                    close $client;
137            }
138    
139            die "server died";
140  }  }
141    
142  my $debug = 0;  
143    my $last_message = {};
144    sub _message {
145            my $type = shift @_;
146            my $text = join(' ',@_);
147            my $last = $last_message->{$type};
148            if ( $text ne $last ) {
149                    warn $type eq 'diag' ? '# ' : '', $text, "\n";
150                    $last_message->{$type} = $text;
151            }
152    }
153    
154    sub _log { _message('log',@_) };
155    sub diag { _message('diag',@_) };
156    
157  my $device    = "/dev/ttyUSB0";  my $device    = "/dev/ttyUSB0";
158  my $baudrate  = "19200";  my $baudrate  = "19200";
# Line 41  my $stopbits  = "1"; Line 162  my $stopbits  = "1";
162  my $handshake = "none";  my $handshake = "none";
163    
164  my $program_path = './program/';  my $program_path = './program/';
165    my $secure_path = './secure/';
166    
167    # http server
168    my $http_server = 1;
169    
170    # 3M defaults: 8,4
171    # cards 16, stickers: 8
172    my $max_rfid_block = 8;
173    my $read_blocks = 8;
174    
175  my $response = {  my $response = {
176          'd500090400110a0500027250'                              => 'version?',          'd500090400110a0500027250'                              => 'version?',
# Line 62  GetOptions( Line 192  GetOptions(
192          'parity=s'    => \$parity,          'parity=s'    => \$parity,
193          'stopbits=i'  => \$stopbits,          'stopbits=i'  => \$stopbits,
194          'handshake=s' => \$handshake,          'handshake=s' => \$handshake,
195          'meteor=s'    => \$meteor_server,          'http-server!' => \$http_server,
196  ) or die $!;  ) or die $!;
197    
198  my $verbose = $debug > 0 ? $debug-- : 0;  my $verbose = $debug > 0 ? $debug-- : 0;
# Line 98  it under the same terms ans Perl itself. Line 228  it under the same terms ans Perl itself.
228    
229  =cut  =cut
230    
231  my $tags_data;  my $item_type = {
232  my $visible_tags;          1 => 'Book',
233            6 => 'CD/CD ROM',
234            2 => 'Magazine',
235            13 => 'Book with Audio Tape',
236            9 => 'Book with CD/CD ROM',
237            0 => 'Other',
238    
239            5 => 'Video',
240            4 => 'Audio Tape',
241            3 => 'Bound Journal',
242            8 => 'Book with Diskette',
243            7 => 'Diskette',
244    };
245    
246    warn "## known item type: ",dump( $item_type ) if $debug;
247    
248  my $port=new Device::SerialPort($device) || die "can't open serial port $device: $!\n";  my $port=new Device::SerialPort($device) || die "can't open serial port $device: $!\n";
249  warn "using $device $handshake $baudrate $databits $parity $stopbits" if $debug;  warn "using $device $handshake $baudrate $databits $parity $stopbits" if $debug;
# Line 109  $databits=$port->databits($databits); Line 253  $databits=$port->databits($databits);
253  $parity=$port->parity($parity);  $parity=$port->parity($parity);
254  $stopbits=$port->stopbits($stopbits);  $stopbits=$port->stopbits($stopbits);
255    
256  print "## using $device $baudrate $databits $parity $stopbits debug: $debug verbose: $verbose\n";  warn "## using $device $baudrate $databits $parity $stopbits debug: $debug verbose: $verbose\n";
257    
258  # Just in case: reset our timing and buffers  # Just in case: reset our timing and buffers
259  $port->lookclear();  $port->lookclear();
# Line 126  cmd( 'D5 00  05   04 00 11 Line 270  cmd( 'D5 00  05   04 00 11
270       'D5 00  09   04 00 11   0A 05 00 02   7250', sub {       'D5 00  09   04 00 11   0A 05 00 02   7250', sub {
271          my $hw_ver = join('.', unpack('CCCC', skip_assert(3) ));          my $hw_ver = join('.', unpack('CCCC', skip_assert(3) ));
272          print "hardware version $hw_ver\n";          print "hardware version $hw_ver\n";
         meteor( 'info', "Found reader hardware $hw_ver" );  
273  });  });
274    
275  cmd( 'D6 00  0C   13  04  01 00  02 00  03 00  04 00   AAF2','FIXME: stats?',  cmd( 'D6 00  0C   13  04  01 00  02 00  03 00  04 00   AAF2','FIXME: stats?',
276       'D6 00  0C   13  00  02 01 01 03 02 02 03  00     E778', sub { assert() }  );       'D6 00  0C   13  00  02 01 01 03 02 02 03  00     E778', sub { assert() }  );
277    
278  # start scanning for tags  sub scan_for_tags {
279    
280  cmd( 'D6 00  05   FE     00  05         FA40', "scan for tags, retry $_",          my @tags;
281           'D6 00  0F   FE  00 00  05 ', sub { # 01 E00401003123AA26  941A         # seen, serial length: 8  
282                  my $rest = shift || die "no rest?";          cmd( 'D6 00  05   FE     00  05         FA40', "scan for tags",
283                  my $nr = ord( substr( $rest, 0, 1 ) );                   'D6 00  0F   FE  00 00  05 ', sub { # 01 E00401003123AA26  941A         # seen, serial length: 8
284                            my $rest = shift || die "no rest?";
285                  if ( ! $nr ) {                          my $nr = ord( substr( $rest, 0, 1 ) );
286                          print "no tags in range\n";  
287                          update_visible_tags();                          if ( ! $nr ) {
288                          meteor( 'info-none-in-range' );                                  _log "no tags in range\n";
289                          $tags_data = {};                                  update_visible_tags();
290                  } else {                                  $tags_data = {};
291                            } else {
292    
293                                    my $tags = substr( $rest, 1 );
294                                    my $tl = length( $tags );
295                                    die "wrong length $tl for $nr tags: ",dump( $tags ) if $tl =! $nr * 8;
296    
297                                    push @tags, uc(unpack('H16', substr($tags, $_ * 8, 8))) foreach ( 0 .. $nr - 1 );
298                                    warn "## tags ",as_hex($tags), " [$tl] = ",dump( $tags ) if $debug;
299                                    _log "$nr tags in range: ", join(',', @tags ) , "\n";
300    
301                          my $tags = substr( $rest, 1 );                                  update_visible_tags( @tags );
302                            }
303                    }
304            );
305    
306                          my $tl = length( $tags );          diag "tags: ",dump( @tags );
307                          die "wrong length $tl for $nr tags: ",dump( $tags ) if $tl =! $nr * 8;          return $tags_data;
308    
309                          my @tags;  }
                         push @tags, uc(unpack('H16', substr($tags, $_ * 8, 8))) foreach ( 0 .. $nr - 1 );  
                         warn "## tags ",as_hex($tags), " [$tl] = ",dump( $tags ) if $debug;  
                         print "$nr tags in range: ", join(',', @tags ) , "\n";  
310    
311                          meteor( 'info-in-range', join(' ',@tags));  # start scanning for tags
312    
313                          update_visible_tags( @tags );  if ( $http_server ) {
314                  }          http_server;
315    } else {
316            while (1) {
317                    scan_for_tags;
318                    sleep 1;
319          }          }
320  ) while(1);  }
 #) foreach ( 1 .. 100 );  
   
321    
322    die "over and out";
323    
324  sub update_visible_tags {  sub update_visible_tags {
325          my @tags = @_;          my @tags = @_;
# Line 173  sub update_visible_tags { Line 328  sub update_visible_tags {
328          $visible_tags = {};          $visible_tags = {};
329    
330          foreach my $tag ( @tags ) {          foreach my $tag ( @tags ) {
331                    $visible_tags->{$tag}++;
332                  if ( ! defined $last_visible_tags->{$tag} ) {                  if ( ! defined $last_visible_tags->{$tag} ) {
333                          if ( defined $tags_data->{$tag} ) {                          if ( defined $tags_data->{$tag} ) {
334  #                               meteor( 'in-range', $tag );                                  warn "$tag in range\n";
335                          } else {                          } else {
                                 meteor( 'read', $tag );  
336                                  read_tag( $tag );                                  read_tag( $tag );
337                          }                          }
                         $visible_tags->{$tag}++;  
338                  } else {                  } else {
339                          warn "## using cached data for $tag" if $debug;                          warn "## using cached data for $tag" if $debug;
340                  }                  }
341                  delete $last_visible_tags->{$tag}; # leave just missing tags                  delete $last_visible_tags->{$tag}; # leave just missing tags
342    
343                  if ( -e "$program_path/$tag" ) {                  if ( -e "$program_path/$tag" ) {
                                 meteor( 'write', $tag );  
344                                  write_tag( $tag );                                  write_tag( $tag );
345                  }                  }
346                    if ( -e "$secure_path/$tag" ) {
347                                    secure_tag( $tag );
348                    }
349          }          }
350    
351          foreach my $tag ( keys %$last_visible_tags ) {          foreach my $tag ( keys %$last_visible_tags ) {
352                  my $data = delete $tags_data->{$tag};                  my $data = delete $tags_data->{$tag};
353                  print "removed tag $tag with data ",dump( $data ),"\n";                  warn "$tag removed ", dump($data), $/;
                 meteor( 'removed', $tag );  
354          }          }
355    
356          warn "## update_visible_tags(",dump( @tags ),") = ",dump( $visible_tags )," removed: ",dump( $last_visible_tags ), " data: ",dump( $tags_data ) if $debug;          warn "## update_visible_tags(",dump( @tags ),") = ",dump( $visible_tags )," removed: ",dump( $last_visible_tags ), " data: ",dump( $tags_data ) if $debug;
# Line 206  my $tag_data_block; Line 361  my $tag_data_block;
361  sub read_tag_data {  sub read_tag_data {
362          my ($start_block,$rest) = @_;          my ($start_block,$rest) = @_;
363          die "no rest?" unless $rest;          die "no rest?" unless $rest;
364    
365            my $last_block = 0;
366    
367          warn "## DATA [$start_block] ", dump( $rest ) if $debug;          warn "## DATA [$start_block] ", dump( $rest ) if $debug;
368          my $tag = uc(unpack('H16',substr( $rest, 0, 8 )));          my $tag = uc(unpack('H16',substr( $rest, 0, 8 )));
369          my $blocks = ord(substr($rest,8,1));          my $blocks = ord(substr($rest,8,1));
# Line 215  sub read_tag_data { Line 373  sub read_tag_data {
373                  warn "## block ",as_hex( $block ) if $debug;                  warn "## block ",as_hex( $block ) if $debug;
374                  my $ord   = unpack('v',substr( $block, 0, 2 ));                  my $ord   = unpack('v',substr( $block, 0, 2 ));
375                  my $expected_ord = $nr + $start_block;                  my $expected_ord = $nr + $start_block;
376                  die "got block $ord, expected block $expected_ord from ",dump( $block ) if $ord != $expected_ord;                  warn "got block $ord, expected block $expected_ord from ",dump( $block ) if $ord != $expected_ord;
377                  my $data  = substr( $block, 2 );                  my $data  = substr( $block, 2 );
378                  die "data payload should be 4 bytes" if length($data) != 4;                  die "data payload should be 4 bytes" if length($data) != 4;
379                  warn sprintf "## tag %9s %02d %s |%-4s|\n", $tag, $ord, as_hex( $data ), $data;                  warn sprintf "## tag %9s %02d: %s |%-4s|\n", $tag, $ord, as_hex( $data ), $data;
380                  $tag_data_block->{$tag}->[ $ord ] = $data;                  $tag_data_block->{$tag}->[ $ord ] = $data;
381                    $last_block = $ord;
382          }          }
383          $tags_data->{ $tag } = join('', @{ $tag_data_block->{$tag} });          $tags_data->{ $tag } = join('', @{ $tag_data_block->{$tag} });
384          print "DATA $tag ",dump( $tags_data ), "\n";  
385            my $item_type_nr = ord(substr( $tags_data->{$tag}, 3, 1 ));
386            print "DATA $tag ",dump( $tags_data ), " item type: ", ( $item_type->{ $item_type_nr } || "UNKWOWN '$item_type_nr'" ), "\n";
387    
388            return $last_block + 1;
389    }
390    
391    my $saved_in_log;
392    
393    sub decode_tag {
394            my $tag = shift;
395    
396            my $data = $tags_data->{$tag} || die "no data for $tag";
397    
398            my ( $u1, $set_item, $u2, $type, $content, $br_lib, $custom ) = unpack('C4Z16Nl>',$data);
399            my $hash = {
400                    u1 => $u1,
401                    u2 => $u2,
402                    set => ( $set_item & 0xf0 ) >> 4,
403                    total => ( $set_item & 0x0f ),
404    
405                    type => $type,
406                    content => $content,
407    
408                    branch => $br_lib >> 20,
409                    library => $br_lib & 0x000fffff,
410    
411                    custom => $custom,
412            };
413    
414            if ( ! $saved_in_log->{$tag}++ ) {
415                    open(my $log, '>>', 'rfid-log.txt');
416                    print $log strftime( "%Y-%m-%d %H:%M:%S", localtime ), ",$tag,$content\n";
417                    close($log);
418            }
419    
420            return $hash;
421    }
422    
423    sub forget_tag {
424            my $tag = shift;
425            delete $tags_data->{$tag};
426            delete $visible_tags->{$tag};
427  }  }
428    
429  sub read_tag {  sub read_tag {
# Line 232  sub read_tag { Line 433  sub read_tag {
433    
434          print "read_tag $tag\n";          print "read_tag $tag\n";
435    
436          cmd(          my $start_block = 0;
437                  "D6 00  0D  02      $tag   00   03     1CC4", "read $tag offset: 0 blocks: 3",  
438                  "D6 00  0F  FE  00 00  05 01   $tag    941A", sub {          while ( $start_block < $max_rfid_block ) {
439                          print "FIXME: tag $tag ready?\n";  
440                  },                  cmd(
441                  "D6 00  1F  02 00", sub { # $tag  03   00 00   04 11 00 01   01 00   31 32 33 34   02 00   35 36 37 38    531F\n";                           sprintf( "D6 00  0D  02      $tag   %02x   %02x     BEEF", $start_block, $read_blocks ),
442                          read_tag_data( 0, @_ );                                  "read $tag offset: $start_block blocks: $read_blocks",
443                  },                          "D6 00  1F  02 00", sub { # $tag  03   00 00   04 11 00 01   01 00   31 32 33 34   02 00   35 36 37 38    531F\n";
444          );                                  $start_block = read_tag_data( $start_block, @_ );
445                                    warn "# read tag upto $start_block\n";
446                            },
447                            "D6 00  0F  FE  00 00  05 01   $tag    BEEF", sub {
448                                    print "FIXME: tag $tag ready? (expected block read instead)\n";
449                            },
450                    );
451    
452            }
453    
454            my $security;
455    
456          cmd(          cmd(
457                  "D6 00  0D  02      $tag   03   04     3970", "read $tag offset: 3 blocks: 4",                  "D6 00 0B 0A $tag BEEF", "check security $tag",
458                  "D6 00  25  02 00", sub { # $tag   04                         03 00   30 30 00 00   04 00   00 00 00 00                    "D6 00 0D 0A 00", sub {
459                          read_tag_data( 3, @_ );                          my $rest = shift;
460                            my $from_tag;
461                            ( $from_tag, $security ) = ( substr($rest,0,8), substr($rest,8,1) );
462                            die "security from other tag: ",as_hex( $from_tag ) if $from_tag ne str2bytes( $tag );
463                            $security = as_hex( $security );
464                            $tags_security->{$tag} = $security;
465                            warn "# SECURITY $tag = $security\n";
466                  }                  }
467          );          );
468    
469            print "TAG $tag ", dump(decode_tag( $tag ));
470  }  }
471    
472  sub write_tag {  sub write_tag {
473          my ($tag) = @_;          my ($tag,$data) = @_;
474    
475          my $path = "$program_path/$tag";          my $path = "$program_path/$tag";
476            $data = read_file( $path ) if -e $path;
477    
478          my $data = read_file( $path );          die "no data" unless $data;
479    
480          print "write_tag $tag = $data\n";          my $hex_data;
481    
482            if ( $data =~ s{^hex\s+}{} ) {
483                    $hex_data = $data;
484                    $hex_data =~ s{\s+}{}g;
485            } else {
486    
487                    $data .= "\0" x ( 4 - ( length($data) % 4 ) );
488    
489                    my $max_len = $max_rfid_block * 4;
490    
491                    if ( length($data) > $max_len ) {
492                            $data = substr($data,0,$max_len);
493                            warn "strip content to $max_len bytes\n";
494                    }
495    
496                    $hex_data = unpack('H*', $data);
497            }
498    
499            my $len = length($hex_data) / 2;
500            # pad to block size
501            $hex_data .= '00' x ( 4 - $len % 4 );
502            my $blocks = sprintf('%02x', length($hex_data) / 4);
503    
504            print "write_tag $tag = ",dump( $data ), " [$len/$blocks] == $hex_data\n";
505    
506          cmd(          cmd(
507                  "D6 00  26  04  $tag  00 06 00  04 11 00 01  61 61 61 61  62 62 62 62  63 63 63 63  64 64 64 64  00 00 00 00  FD3B", "write $tag",                  "d6 00  ff  04  $tag  00 $blocks 00  $hex_data  BEEF", "write $tag",
508                  "D6 00  0D  04 00  $tag  06  AFB1", sub { assert() },                  "d6 00  0d  04 00  $tag  $blocks  BEEF", sub { assert() },
509          ) foreach ( 1 .. 3 ); # XXX 3M software does this three times!          ); # foreach ( 1 .. 3 ); # XXX 3m software does this three times!
510    
511          my $to = $path;          my $to = $path;
512          $to .= '.' . time();          $to .= '.' . time();
# Line 271  sub write_tag { Line 514  sub write_tag {
514          rename $path, $to;          rename $path, $to;
515          print ">> $to\n";          print ">> $to\n";
516    
517            forget_tag $tag;
518    }
519    
520    sub secure_tag_with {
521            my ( $tag, $data ) = @_;
522    
523            cmd(
524                    "d6 00  0c  09  $tag $data BEEF", "secure $tag -> $data",
525                    "d6 00  0c  09 00  $tag    BEEF", sub { assert() },
526            );
527    
528            forget_tag $tag;
529    }
530    
531    sub secure_tag {
532            my ($tag) = @_;
533    
534            my $path = "$secure_path/$tag";
535            my $data = substr(read_file( $path ),0,2);
536    
537            secure_tag_with( $tag, $data );
538    
539            my $to = $path;
540            $to .= '.' . time();
541    
542            rename $path, $to;
543            print ">> $to\n";
544  }  }
545    
546  exit;  exit;
# Line 305  sub writechunk Line 575  sub writechunk
575  {  {
576          my $str=shift;          my $str=shift;
577          my $count = $port->write($str);          my $count = $port->write($str);
578            my $len = length($str);
579            die "wrong write length $count != $len in ",as_hex( $str ) if $count != $len;
580          print "#> ", as_hex( $str ), "\t[$count]\n" if $debug;          print "#> ", as_hex( $str ), "\t[$count]\n" if $debug;
581  }  }
582    
# Line 371  sub crcccitt { Line 643  sub crcccitt {
643  sub checksum {  sub checksum {
644          my ( $bytes, $checksum ) = @_;          my ( $bytes, $checksum ) = @_;
645    
         my $xor = crcccitt( substr($bytes,1) ); # skip D6  
         warn "## checksum ",dump( $bytes, $xor, $checksum ) if $debug;  
   
646          my $len = ord(substr($bytes,2,1));          my $len = ord(substr($bytes,2,1));
647          my $len_real = length($bytes) - 1;          my $len_real = length($bytes) - 1;
648    
649          if ( $len_real != $len ) {          if ( $len_real != $len ) {
650                  print "length wrong: $len_real != $len\n";                  print "length wrong: $len_real != $len\n";
651                  $bytes = substr($bytes,0,2) . chr($len_real) . substr($bytes,4);                  $bytes = substr($bytes,0,2) . chr($len_real) . substr($bytes,3);
652          }          }
653    
654            my $xor = crcccitt( substr($bytes,1) ); # skip D6
655            warn "## checksum ",dump( $bytes, $xor, $checksum ) if $debug;
656    
657          if ( defined $checksum && $xor ne $checksum ) {          if ( defined $checksum && $xor ne $checksum ) {
658                  print "checksum doesn't match: ", as_hex($xor), " != ", as_hex($checksum), " data: ", as_hex($bytes), "\n";                  warn "checksum error: ", as_hex($xor), " != ", as_hex($checksum), " data: ", as_hex($bytes), "\n" if $checksum ne "\xBE\xEF";
659                  return $bytes . $xor;                  return $bytes . $xor;
660          }          }
661          return $bytes . $checksum;          return $bytes . $checksum;
# Line 392  sub checksum { Line 664  sub checksum {
664  our $dispatch;  our $dispatch;
665    
666  sub readchunk {  sub readchunk {
667          sleep 1;        # FIXME remove  #       sleep 1;        # FIXME remove
668    
669          # read header of packet          # read header of packet
670          my $header = read_bytes( 2, 'header' );          my $header = read_bytes( 2, 'header' );
# Line 421  sub readchunk { Line 693  sub readchunk {
693          warn "?? payload dispatch to ",dump( $payload, $dispatch, $to ) if $debug;          warn "?? payload dispatch to ",dump( $payload, $dispatch, $to ) if $debug;
694    
695          if ( defined $to ) {          if ( defined $to ) {
696                  my $rest = substr( $payload, length($to) );                  my $rest = substr( $payload, length($to) ) if length($to) < length($payload);
697                  warn "## DISPATCH payload to with rest", dump( $payload, $to, $rest ) if $debug;                  warn "## DISPATCH payload to with rest", dump( $payload, $to, $rest ) if $debug;
698                  $dispatch->{ $to }->( $rest );                  $dispatch->{ $to }->( $rest );
699          } else {          } else {
700                  print "NO DISPATCH for ",dump( $full ),"\n";                  die "NO DISPATCH for ",as_hex( $full ),"\n";
701          }          }
702    
703          return $data;          return $data;

Legend:
Removed from v.29  
changed lines
  Added in v.75

  ViewVC Help
Powered by ViewVC 1.1.26