1 package Biblio::RFID::Reader;
6 use Data::Dump qw(dump);
14 Biblio::RFID::Reader - simple way to write RFID applications in perl
18 This module will probe all available readers and use calls from
19 L<Biblio::RFID::Reader::API> to invoke correct reader.
25 my $rfid = Biblio::RFID::Reader->new( 'optional reader filter' );
30 my ( $class, $filter ) = @_;
33 $self->{_readers} = [ $self->_available( $filter ) ];
39 my @visible = $rfid->tags(
40 enter => sub { my $tag = shift; },
41 leave => sub { my $tag = shift; },
42 reader => sub { my $reader = shift; ref($reader) =~ m/something/ },
51 $self->{_tags} ||= {};
52 $self->{_tags}->{$_}->{time} = 0 foreach keys %{$self->{_tags}};
55 foreach my $rfid ( @{ $self->{_readers} } ) {
57 if ( exists $triggers->{reader} ) {
58 if ( ! $triggers->{reader}->($rfid) ) {
59 # invalidate tags from other readers
60 if ( exists $self->{_tags} ) {
61 delete $self->{_tags}->{$_} foreach (
62 grep { $self->{_tags}->{$_}->{reader} eq ref $rfid } keys %{ $self->{_tags} }
69 warn "# inventory on $rfid";
70 my @tags = $rfid->inventory;
72 foreach my $tag ( @tags ) {
74 if ( ! exists $self->{_tags}->{$tag} ) {
76 my $blocks = $rfid->read_blocks($tag);
77 $self->{_tags}->{$tag}->{blocks} = $blocks->{$tag} || die "no $tag in ",dump($blocks);
78 my $afi = $rfid->read_afi($tag);
79 $self->{_tags}->{$tag}->{afi} = $afi;
80 $self->{_tags}->{$tag}->{type} = $rfid->tag_type( $tag );
81 $self->{_tags}->{$tag}->{reader} = ref $rfid; # save reader info
85 warn "ERROR reading $tag: $@\n";
86 $self->_invalidate_tag( $tag );
90 $triggers->{enter}->( $tag ) if $triggers->{enter};
93 $self->{_tags}->{$tag}->{time} = $t;
99 foreach my $tag ( grep { $self->{_tags}->{$_}->{time} == 0 } keys %{ $self->{_tags} } ) {
100 $triggers->{leave}->( $tag ) if $triggers->{leave};
101 $self->_invalidate_tag( $tag );
104 warn "## _tags ",dump( $self->{_tags} );
106 return grep { $self->{_tags}->{$_}->{time} } keys %{ $self->{_tags} };
111 my $blocks_arrayref = $rfid->blocks( $tag );
115 my $afi = $rfid->afi( $tag );
119 sub blocks { $_[0]->{_tags}->{$_[1]}->{ 'blocks' } || confess "no blocks for $_[1]"; };
120 sub afi { $_[0]->{_tags}->{$_[1]}->{ 'afi' } || confess "no afi for $_[1]"; };
124 $self->to_hash( $tag );
129 my ( $self, $tag ) = @_;
130 return unless exists $self->{_tags}->{$tag};
131 my $type = $self->{_tags}->{$tag}->{type} || confess "can't find type for tag $tag ",dump( $self->{_tags} );
132 my $decode = 'Biblio::RFID::' . $type;
133 my $hash = $decode->to_hash( $self->blocks( $tag ) );
134 $hash->{tag_type} = $type;
140 $self->debug(1); # or more
145 my ( $self, $level ) = @_;
146 $debug = $level if $level > $debug;
147 warn "debug level $level\n" if $level;
152 my $reader = $self->from_reader( $tag );
157 my ( $self, $tag ) = @_;
158 return unless exists $self->{_tags}->{$tag};
159 my $reader = $self->{_tags}->{$tag}->{reader};
160 $reader =~ s/^.*:://; # strip module prefix
166 =head2 _invalidate_tag
168 $rfid->_invalidate_tag( $tag );
172 sub _invalidate_tag {
173 my ( $self, $tag ) = @_;
174 my @caller = caller(0);
175 warn "## _invalidate_tag caller $caller[0] $caller[1] +$caller[2]\n";
176 my $old = delete $self->{_tags}->{$tag};
177 warn "# _invalidate_tag $tag ", dump($old);
182 Probe each RFID reader supported and returns succefull ones
184 my $rfid_readers = Biblio::RFID::Reader->_available( $regex_filter );
188 #my @readers = ( '3M810', 'CPRM02', 'librfid' );
189 my @readers = ( '3M810', 'librfid' );
192 my ( $self, $filter ) = @_;
194 $filter = '' unless defined $filter;
196 warn "# filter: $filter";
200 foreach my $reader ( @readers ) {
201 next if $filter && $reader !~ /$filter/i;
202 my $module = "Biblio::RFID::Reader::$reader";
205 if ( my $rfid = $module->new ) {
207 warn "# added $module\n";
209 warn "# ignored $module\n";
213 die "no readers found" unless @rfid;
220 On any other function calls, we just marshall to all readers
224 # we don't want DESTROY to fallback into AUTOLOAD
230 my $command = $AUTOLOAD;
235 foreach my $r ( @{ $self->{_readers} } ) {
236 push @out, $r->$command(@_);
239 $self->_invalidate_tag( $_[0] ) if $command =~ m/write/;
249 =head2 RFID reader implementations
251 L<Biblio::RFID::Reader::3M810>
253 L<Biblio::RFID::Reader::CPRM02>
255 L<Biblio::RFID::Reader::librfid>