write_blocks
[Biblio-RFID.git] / lib / RFID / Serial / 3M810.pm
index 2c27e4d..8fffb78 100644 (file)
@@ -62,16 +62,27 @@ sub cmd {
 
        my $r_len = $port->read(3);
 
-       while ( ! $r_len ) {
+       while ( length($r_len) < 3 ) {
                wait_device;
-               $r_len = $port->read(3);
+               $r_len = $port->read( 3 - length($r_len) );
        }
 
        wait_device;
 
        my $len = ord( substr($r_len,2,1) );
        $data = $port->read( $len );
-       warn "<< ", as_hex($r_len,$data)," $len\n";
+
+       while ( length($data) < $len ) {
+               warn "# short read ", length($data), " < $len\n";
+               wait_device;
+               $data .= $port->read( $len - length($data) );
+       }
+
+       warn "<< ", as_hex($r_len,$data),
+               ' | ',
+               substr($data,-2,2) eq checksum(substr($r_len,1).substr($data,0,-2)) ? 'OK' : 'ERROR',
+               " $len bytes\n";
+
 
        $coderef->( $data ) if $coderef;
 
@@ -189,4 +200,93 @@ sub read_blocks {
        return $tag_blocks;
 }
 
+sub write_blocks {
+       my $tag = shift;
+       $tag = shift if ref $tag;
+       my $data = join('', @_);
+
+       warn "## write_blocks ",dump($tag,$data);
+
+       if ( length($data) % 4 ) {
+               $data .= '\x00' x ( 4 - length($data) % 4 );
+               warn "# padded data to ",dump($data);
+       }
+
+       my $hex_data = as_hex $data;
+       my $blocks   = sprintf('%02x', length($data) / 4 );
+
+       cmd(
+               "04 $tag 00 $blocks 00 $hex_data", "write_blocks $tag [$blocks] $hex_data", sub {
+                       my $data = shift;
+                       if ( my $rest = _matched $data => '04 00' ) {
+                               my $tag = substr($rest,0,8);
+                               my $blocks = substr($rest,8,1);
+                               warn "# WRITE ",as_hex($tag), " [$blocks]\n";
+                       } elsif ( my $rest = _matched $data => '04 06' ) {
+                               warn "ERROR ",as_hex($rest);
+                       } else {
+                               die "UNSUPPORTED";
+                       }
+               }
+       );
+
+}
+
+sub read_afi {
+       my $tag = shift;
+       $tag = shift if ref $tag;
+
+       my $afi;
+
+       cmd(
+               "0A $tag", "read_afi $tag", sub {
+               my $data = shift;
+
+               if ( my $rest = _matched $data => '0A 00' ) {
+
+                       my $tag = substr($rest,0,8);
+                          $afi = substr($rest,8,1);
+
+                       warn "# SECURITY ", hex_tag($tag), " AFI: ", as_hex($afi);
+
+               } elsif ( my $rest = _matched $data => '0A 06' ) {
+                       warn "ERROR reading security from $tag ", as_hex($data);
+               } else {
+                       warn "IGNORED ",as_hex($data);
+               }
+       });
+       warn "## read_afi ",dump($tag, $afi);
+       return $afi;
+}
+
+sub write_afi {
+       my $tag = shift;
+       $tag = shift if ref $tag;
+       my $afi = shift || die "no afi?";
+
+       $afi = as_hex $afi;
+
+       cmd(
+               "09 $tag $afi", "write_afi $tag $afi", sub {
+               my $data = shift;
+
+               if ( my $rest = _matched $data => '09 00' ) {
+
+                       my $tag = substr($rest,0,8);
+                          $afi = substr($rest,8,1);
+
+                       warn "# SECURITY ", hex_tag($tag), " AFI: ", as_hex($afi);
+
+               } elsif ( my $rest = _matched $data => '0A 06' ) {
+                       warn "ERROR writing AFI to $tag ", as_hex($data);
+                       undef $afi;
+               } else {
+                       warn "IGNORED ",as_hex($data);
+                       undef $afi;
+               }
+       });
+       warn "## write_afi ", dump( $tag, $afi );
+       return $afi;
+}
+
 1