c7adf9e0799daf5c60259cfa7c3d15b0af55de7d
[Biblio-RFID.git] / lib / RFID / Biblio.pm
1 package RFID::Biblio;
2
3 use warnings;
4 use strict;
5
6 use base 'Exporter';
7 our @EXPORT = qw( hex2bytes as_hex hex_tag );
8
9 use Device::SerialPort qw(:STAT);
10 use Data::Dump qw(dump);
11
12 =head1 NAME
13
14 RFID::Biblio - support serial RFID devices
15
16 =cut
17
18 our $VERSION = '0.01';
19
20 my $debug = 0;
21
22
23 =head1 SYNOPSIS
24
25 This module tries to support USB serial RFID readers wsing simple API
26 which is sutable for direct mapping to REST JSONP service.
27
28 Perhaps a little code snippet.
29
30     use RFID::Biblio;
31
32     my $rfid = RFID::Biblio->new(
33                 device => '/dev/ttyUSB0', # with fallback to RFID_DEVICE
34         );
35         my $visible = $rfid->scan;
36
37 =head1 SUBROUTINES/METHODS
38
39 =head2 new
40
41 =cut
42
43 sub new {
44         my $class = shift;
45         my $self = {@_};
46         bless $self, $class;
47
48         $self->port;
49
50         $self->init;
51
52         return $self;
53 }
54
55 =head2 port
56
57   my $serial_obj = $self->port;
58
59 =cut
60
61 sub port {
62         my $self = shift;
63
64         return $self->{port} if defined $self->{port};
65
66         my $settings = $self->serial_settings;
67         my $device   = $settings->{device} ||= $ENV{RFID_DEVICE};
68         warn "# settings ",dump $settings;
69
70         if ( ! $device ) {
71                 warn "# no device, serial port not opened\n";
72                 return;
73         }
74
75         $self->{port} = Device::SerialPort->new( $settings->{device} )
76         || die "can't open serial port: $!\n";
77
78         $self->{port}->$_( $settings->{$_} )
79         foreach ( qw/handshake baudrate databits parity stopbits/ );
80
81 }
82
83 =head2 scan
84
85   my $visible = $rfid->scan;
86
87 Returns hash with keys which match tag UID and values with blocks
88
89 =cut
90
91 sub scan {
92         my $self = shift;
93
94         warn "# scan tags in reader range\n";
95         my @tags = $self->inventory;
96
97         my $visible;
98         # FIXME this is naive implementation which just discards other tags
99         foreach my $tag ( @tags ) {
100                 my $blocks = $self->read_blocks( $tag );
101                 if ( ! $blocks ) {
102                         warn "ERROR: can't read tag $tag\n";
103                         delete $visible->{$tag};
104                 } else {
105                         $visible->{$tag} = $blocks->{$tag};
106                 }
107         }
108
109         return $visible;
110 }
111
112
113 =head1 MANDATORY IMPLEMENTATIONS
114
115 Each reader must implement following hooks as sub-classes.
116
117 =head2 init
118
119   $self->init;
120
121 =head2 inventory
122
123   my @tags = $self->invetory;
124
125 =head2 read_blocks
126
127   my $hash = $self->read_blocks( $tag );
128
129 All blocks are under key which is tag UID with array of blocks returned from reader
130
131   $hash = { 'E000000123456789' => [ 'blk1', 'blk2', ... ] };
132
133 L<RFID::Biblio::3M810> sends tag UID with data payload, so we might expect
134 to receive response from other tags from protocol specification, 
135
136 =head2 write_blocks
137
138   $self->write_blocks( $tag => $bytes );
139
140   $self->write_blocks( $tag => [ 'blk1', 'blk2', ... ] );
141
142 =head2 read_afi
143
144   my $afi = $self->read_afi( $tag );
145
146 =head2 write_afi
147
148   $self->write_afi( $tag => $afi );
149
150
151
152 =head1 EXPORT
153
154 Formatting functions are exported
155
156 =head2 hex2bytes
157
158   my $bytes = hex2bytes($hex);
159
160 =cut
161
162 sub hex2bytes {
163         my $str = shift || die "no str?";
164         my $b = $str;
165         $b =~ s/\s+//g;
166         $b =~ s/(..)/\\x$1/g;
167         $b = "\"$b\"";
168         my $bytes = eval $b;
169         die $@ if $@;
170         warn "## str2bytes( $str ) => $b => ",as_hex($bytes) if $debug;
171         return $bytes;
172 }
173
174 =head2 as_hex
175
176   print as_hex( $bytes );
177
178 =cut
179
180 sub as_hex {
181         my @out;
182         foreach my $str ( @_ ) {
183                 my $hex = uc unpack( 'H*', $str );
184                 $hex =~ s/(..)/$1 /g if length( $str ) > 2;
185                 $hex =~ s/\s+$//;
186                 push @out, $hex;
187         }
188         return join(' | ', @out);
189 }
190
191 =head2 hex_tag
192
193   print hex_tag $8bytes;
194
195 =cut
196
197 sub hex_tag { uc(unpack('H16', shift)) }
198
199
200 =head1 SUPPORTED READERS
201
202 Support for different RFID readers is implemented in subclasses:
203
204 =head2 3M 810
205
206 L<RFID::Biblio::3M810>
207
208 =head2 CPR-M02
209
210 L<RFID::Biblio::CPRM02>
211
212 =head2 librfid
213
214 L<RFID::Biblio::librfid>
215
216 =head1 AUTHOR
217
218 Dobrica Pavlinusic, C<< <dpavlin at rot13.org> >>
219
220 =head1 BUGS
221
222 Please report any bugs or feature requests to C<bug-rfid-serial at rt.cpan.org>, or through
223 the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=RFID-Biblio>.  I will be notified, and then you'll
224 automatically be notified of progress on your bug as I make changes.
225
226
227
228
229 =head1 SUPPORT
230
231 You can find documentation for this module with the perldoc command.
232
233     perldoc RFID::Biblio
234
235
236 You can also look for information at:
237
238 =over 4
239
240 =item * RT: CPAN's request tracker
241
242 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=RFID-Biblio>
243
244 =item * AnnoCPAN: Annotated CPAN documentation
245
246 L<http://annocpan.org/dist/RFID-Biblio>
247
248 =item * CPAN Ratings
249
250 L<http://cpanratings.perl.org/d/RFID-Biblio>
251
252 =item * Search CPAN
253
254 L<http://search.cpan.org/dist/RFID-Biblio/>
255
256 =back
257
258
259 =head1 ACKNOWLEDGEMENTS
260
261
262 =head1 LICENSE AND COPYRIGHT
263
264 Copyright 2010 Dobrica Pavlinusic.
265
266 This program is free software; you can redistribute it and/or modify
267 it under the terms of the GNU General Public License as published by
268 the Free Software Foundation; version 2 dated June, 1991 or at your option
269 any later version.
270
271 This program is distributed in the hope that it will be useful,
272 but WITHOUT ANY WARRANTY; without even the implied warranty of
273 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
274 GNU General Public License for more details.
275
276 A copy of the GNU General Public License is available in the source tree;
277 if not, write to the Free Software Foundation, Inc.,
278 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
279
280
281 =cut
282
283 1; # End of RFID::Biblio