X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=lib%2FBiblio%2FRFID%2FReader%2Flibrfid.pm;h=8f6a96da6e9ab56b8e393049f0b282198b6f2a73;hb=f0440178e57e4a3fc985fc6670bda920600f78c6;hp=126d0d5d805eb2d14678c8ba1ad220b8bf4a46a4;hpb=0ae60c365104f24ae4053d0fdfcfa7c985024598;p=Biblio-RFID.git diff --git a/lib/Biblio/RFID/Reader/librfid.pm b/lib/Biblio/RFID/Reader/librfid.pm index 126d0d5..8f6a96d 100644 --- a/lib/Biblio/RFID/Reader/librfid.pm +++ b/lib/Biblio/RFID/Reader/librfid.pm @@ -22,6 +22,10 @@ Due to limitation of L only L and L is supported. +This version uses modidified C which supports +new C<-s> flag which reads sectors 0-3 with C<-k> key and +sectors 4-7 with key from C<-s> option. + However, this code might provide template for integration with any command-line utilities for different RFID readers. @@ -35,62 +39,126 @@ C sub serial_settings {} # don't open serial -our $bin = '/usr/local/bin/librfid-tool'; - -sub init { - my $self = shift; - if ( -e $bin ) { - warn "# using $bin"; - return 1; - } else { - warn "# no $bin found\n"; - return 0; - } -} +sub init { 1 } sub _grep_tool { - my ( $param, $coderef ) = @_; + my ( $bin, $param, $coderef, $path ) = @_; + + my $timeout = 3; # s + + eval { warn "# _grep_tool $bin $param\n"; - open(my $s, '-|', "$bin $param") || die $!; +# $param .= ' 2>/dev/null'; + my $pipe_pid = open(my $s, '-|', "$bin $param") || die $!; + + local $SIG{ALRM} = sub { + warn "TIMEOUT!"; + kill TERM => $pipe_pid; + die "timeout\n" + }; + alarm $timeout; + + my $sid; + my $iso; + while(<$s>) { chomp; warn "## $_\n"; - my $sid; - if ( m/success.+:\s+(.+)/ ) { - $sid = $1; + if ( m/Layer 2 success.+\(([^\)]+)\).*:\s+(.+)/ ) { + ( $sid, $iso ) = ( $2, $1 ); $sid =~ s/\s*'\s*//g; - $sid = uc join('', reverse split(/\s+/, $sid)); + my @sid = split(/\s+/, $sid); + @sid = reverse @sid if $iso =~ m/15693/; + $sid = uc join('', @sid); + warn "## sid=[$sid] iso=[$iso]\n"; } - - $coderef->( $sid ); + $coderef->( $sid, $iso ); } + alarm(0); + close($s); + + }; # eval + + if ( $? >> 8 || $@ ) { + my $lsusb = `lsusb -d 076b:`; + if ( $lsusb =~ m/\S+\s+(\d+)\s+\S+\s+(\d+)/ ) { + my $cmd = "usbreset /dev/bus/usb/$1/$2"; + warn "# $cmd\n"; + system $cmd; + } else { + warn "can't reset device $lsusb"; + } + } } +my $sid_iso; + sub inventory { my @tags; - _grep_tool '--scan' => sub { - my $sid = shift; - push @tags, $sid if $sid; + $sid_iso = {}; + _grep_tool 'librfid-tool', '--scan' => sub { + my ( $sid, $iso ) = @_; + if ( $sid && ! exists $sid_iso->{$sid} ) { + push @tags, $sid; + $sid_iso->{$sid} = $iso; + } }; warn "# invetory ",dump(@tags); return @tags; } +sub tag_type { + my ( $self, $tag ) = @_; + return $sid_iso->{$tag} =~ m/15693/ ? 'RFID501' : 'SmartX'; +} + +our $mifare_keys; +sub read_mifare_keys { + my $key_path = $0; + $key_path =~ s{/[^/]+$}{/}; + $key_path .= "mifare_keys.pl"; + warn "# $key_path"; + if ( -e $key_path ) { + require $key_path; + warn "# mifare keys for sectors ", join(' ', keys %$mifare_keys), " loaded\n"; + } +} + sub read_blocks { + my ( $self, $sid ) = @_; - my $sid; + my $iso = $sid_iso->{$sid}; my $blocks; - _grep_tool '--read -1' => sub { - $sid ||= shift; - $blocks->{$sid}->[$1] = hex2bytes($2) - if m/block\[\s*(\d+):.+data.+:\s*(.+)/; - }; + if ( $iso =~ m/15693/ ) { + _grep_tool 'librfid-tool', '--read -1' => sub { + $sid ||= shift; + $blocks->{$sid}->[$1] = hex2bytes($2) + if m/block\[\s*(\d+):.+data.+:\s*(.+)/; + + }; + } else { + read_mifare_keys unless $mifare_keys; + +=for unmodified mifate-tool + foreach my $sector ( keys %$mifare_keys ) { + my $key = lc $mifare_keys->{$sector}; + _grep_tool 'mifare-tool', "-k $key -r $sector" => sub { + $blocks->{$sid}->[$sector] = hex2bytes($1) + if m/data=\s*(.+)/; + }; + } +=cut + _grep_tool 'mifare-tool', "-k " . $mifare_keys->{0} . " -s " . $mifare_keys->{4} => sub { + $blocks->{$sid}->[$1] = hex2bytes($2) + if m/page=(\d+).*data=\s*(.+)/; + }; + } warn "# read_blocks ",dump($blocks); return $blocks; }