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