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