4f3499d7f0343eb7f77e5fa1ddb09eb31dc65a10
[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         $settings->{device} ||= $ENV{RFID_DEVICE};
68         warn "# settings ",dump $settings;
69
70         $self->{port} = Device::SerialPort->new( $settings->{device} )
71         || die "can't open serial port: $!\n";
72
73         $self->{port}->$_( $settings->{$_} )
74         foreach ( qw/handshake baudrate databits parity stopbits/ );
75
76 }
77
78 =head2 scan
79
80   my $visible = $rfid->scan;
81
82 Returns hash with keys which match tag UID and values with blocks
83
84 =cut
85
86 sub scan {
87         my $self = shift;
88
89         warn "# scan tags in reader range\n";
90         my @tags = $self->inventory;
91
92         my $visible;
93         # FIXME this is naive implementation which just discards other tags
94         foreach my $tag ( @tags ) {
95                 my $blocks = $self->read_blocks( $tag );
96                 if ( ! $blocks ) {
97                         warn "ERROR: can't read tag $tag\n";
98                         delete $visible->{$tag};
99                 } else {
100                         $visible->{$tag} = $blocks->{$tag};
101                 }
102         }
103
104         return $visible;
105 }
106
107
108 =head1 MANDATORY IMPLEMENTATIONS
109
110 Each reader must implement following hooks as sub-classes.
111
112 =head2 init
113
114   $self->init;
115
116 =head2 inventory
117
118   my @tags = $self->invetory;
119
120 =head2 read_blocks
121
122   my $hash = $self->read_blocks( $tag );
123
124 All blocks are under key which is tag UID with array of blocks returned from reader
125
126   $hash = { 'E000000123456789' => [ 'blk1', 'blk2', ... ] };
127
128 L<RFID::Biblio::3M810> sends tag UID with data payload, so we might expect
129 to receive response from other tags from protocol specification, 
130
131 =head2 write_blocks
132
133   $self->write_blocks( $tag => $bytes );
134
135   $self->write_blocks( $tag => [ 'blk1', 'blk2', ... ] );
136
137 =head2 read_afi
138
139   my $afi = $self->read_afi( $tag );
140
141 =head2 write_afi
142
143   $self->write_afi( $tag => $afi );
144
145
146
147 =head1 EXPORT
148
149 Formatting functions are exported
150
151 =head2 hex2bytes
152
153   my $bytes = hex2bytes($hex);
154
155 =cut
156
157 sub hex2bytes {
158         my $str = shift || die "no str?";
159         my $b = $str;
160         $b =~ s/\s+//g;
161         $b =~ s/(..)/\\x$1/g;
162         $b = "\"$b\"";
163         my $bytes = eval $b;
164         die $@ if $@;
165         warn "## str2bytes( $str ) => $b => ",as_hex($bytes) if $debug;
166         return $bytes;
167 }
168
169 =head2 as_hex
170
171   print as_hex( $bytes );
172
173 =cut
174
175 sub as_hex {
176         my @out;
177         foreach my $str ( @_ ) {
178                 my $hex = uc unpack( 'H*', $str );
179                 $hex =~ s/(..)/$1 /g if length( $str ) > 2;
180                 $hex =~ s/\s+$//;
181                 push @out, $hex;
182         }
183         return join(' | ', @out);
184 }
185
186 =head2 hex_tag
187
188   print hex_tag $8bytes;
189
190 =cut
191
192 sub hex_tag { uc(unpack('H16', shift)) }
193
194
195 =head1 AUTHOR
196
197 Dobrica Pavlinusic, C<< <dpavlin at rot13.org> >>
198
199 =head1 BUGS
200
201 Please report any bugs or feature requests to C<bug-rfid-serial at rt.cpan.org>, or through
202 the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=RFID-Biblio>.  I will be notified, and then you'll
203 automatically be notified of progress on your bug as I make changes.
204
205
206
207
208 =head1 SUPPORT
209
210 You can find documentation for this module with the perldoc command.
211
212     perldoc RFID::Biblio
213
214
215 You can also look for information at:
216
217 =over 4
218
219 =item * RT: CPAN's request tracker
220
221 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=RFID-Biblio>
222
223 =item * AnnoCPAN: Annotated CPAN documentation
224
225 L<http://annocpan.org/dist/RFID-Biblio>
226
227 =item * CPAN Ratings
228
229 L<http://cpanratings.perl.org/d/RFID-Biblio>
230
231 =item * Search CPAN
232
233 L<http://search.cpan.org/dist/RFID-Biblio/>
234
235 =back
236
237
238 =head1 ACKNOWLEDGEMENTS
239
240
241 =head1 LICENSE AND COPYRIGHT
242
243 Copyright 2010 Dobrica Pavlinusic.
244
245 This program is free software; you can redistribute it and/or modify
246 it under the terms of the GNU General Public License as published by
247 the Free Software Foundation; version 2 dated June, 1991 or at your option
248 any later version.
249
250 This program is distributed in the hope that it will be useful,
251 but WITHOUT ANY WARRANTY; without even the implied warranty of
252 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
253 GNU General Public License for more details.
254
255 A copy of the GNU General Public License is available in the source tree;
256 if not, write to the Free Software Foundation, Inc.,
257 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
258
259
260 =cut
261
262 1; # End of RFID::Biblio