1 package Biblio::RFID::RFID501;
6 use Data::Dump qw(dump);
10 Biblio::RFID::RFID501 - RFID Standard for Libraries
14 This module tries to decode tag format as described in document
16 RFID 501: RFID Standards for Libraries
18 L<http://solutions.3m.com/wps/portal/3M/en_US/3MLibrarySystems/Home/Resources/CaseStudiesAndWhitePapers/RFID501/>
20 Goal is to be compatibile with existing 3M Alphanumeric tag format
21 which, as far as I know, isn't specificed anywhere. My documentation about
22 this format is available at
24 L<http://saturn.ffzg.hr/rot13/index.cgi?hitchhikers_guide_to_rfid>
28 =head2 3M Alphanumeric tag
30 0 04 is 00 tt i [4 bit] = number of item in set [1 .. i .. s]
31 s [4 bit] = total items in set
32 tt [8 bit] = item type
34 1 dd dd dd dd dd [16 bytes] = barcode data
39 5 bb bl ll ll b [12 bit] = branch [unsigned]
40 l [20 bit] = library [unsigned]
42 6 cc cc cc cc c [32 bit] = custom signed integer
44 =head2 3M Manufacturing Blank
62 AFI byte on RFID tag is used for security.
64 In my case, we have RFID door which can only read AFI bytes from tag and issue
65 alarm sound or ignore it depending on value of byte.
71 secured item (door will beep)
75 unsecured (door will ignore it)
84 my $hash = Biblio::RFID::Decode::RFID501->to_hash( $bytes );
86 my $hash = Biblio::RFID::Decode::RFID501->to_hash( [ 'blk1', 'blk2', ... , 'blk7' ] );
90 my $blocks = Biblio::RFID::Decode::RFID->from_hash({ content => "1301234567" });
96 my $blocks = Biblio::RFID::Decode::RFID->blank;
104 13 => 'Book with Audio Tape',
105 9 => 'Book with CD/CD ROM',
110 3 => 'Bound Journal',
111 8 => 'Book with Diskette',
116 my ( $self, $data ) = @_;
120 $data = join('', @$data) if ref $data eq 'ARRAY';
122 if ( length($data) < 24 ) {
123 die "short data from tag ", length($data), " < 24 bytes";
126 warn "## to_hash ",dump($data);
128 my ( $u1, $set_item, $u2, $type, $content, $br_lib, $custom, $zero ) = unpack('C4Z16Nl>l',$data);
130 u1 => $u1, # FIXME 0x04
131 set => ( $set_item & 0xf0 ) >> 4,
132 total => ( $set_item & 0x0f ),
134 u2 => $u2, # FIXME 0x00
137 type_label => $item_type->{$type},
141 branch => $br_lib >> 20,
142 library => $br_lib & 0x000fffff,
147 warn "expected first byte to be 0x04, not $u1\n" if $u1 != 4;
148 warn "expected third byte to be 0x00, not $u2\n" if $u2 != 0;
149 warn "expected last block to be zero, not $zero\n" if $zero != 0;
155 my ( $self, $hash ) = @_;
157 warn "## from_hash ",dump($hash);
159 $hash->{$_} ||= 0 foreach ( qw( set total type branch library ) );
161 return pack('C4Z16Nl>l',
163 ( $hash->{set} << 4 ) | ( $hash->{total} & 0x0f ),
169 ( $hash->{branch} << 20 ) | ( $hash->{library} & 0x000fffff ),
177 return ( "\x55" x ( 6 * 4 ) ) . ( "\x00" x 4 );
181 return "\x00" x ( 4 * 3 );