File Coverage

blib/lib/RFID/EPC/Tag.pm
Criterion Covered Total %
statement 102 110 92.7
branch 42 56 75.0
condition 3 3 100.0
subroutine 12 13 92.3
pod 3 3 100.0
total 162 185 87.5


line stmt bran cond sub pod time code
1             package RFID::EPC::Tag;
2             $VERSION=0.002;
3             @ISA = qw(RFID::Tag);
4              
5             # Written by Scott Gifford
6             # Copyright (C) 2004 The Regents of the University of Michigan.
7             # See the file LICENSE included with the distribution for license
8             # information.
9             =head1 NAME
10              
11             RFID::EPC::Tag - An EPC tag.
12              
13             =head1 SYNOPSIS
14              
15             This class implements an EPC tag based on L. It
16             allows tags to be created based on the fields of the various EPC tag
17             types, and allows tag IDs to be parsed into their EPC components.
18              
19             Generally, you'll get these objects returend from an EPC RFID reader:
20              
21             use RFID::Gumbo::Reader::TCP;
22             my $reader =
23             RFID::Gumbo::Reader::TCP->new(PeerAddr => 10.20.30.40,
24             PeerPort => 4001)
25             or die "Couldn't create Blammo reader";
26             my @tags = $reader->readtags();
27             foreach my $tag (@tags)
28             {
29             if ($tag->type eq 'epc')
30             {
31             my $epc_type = $tag->get('epc_type');
32             print "I see EPC tag ",$tag->id," of type $epc_type\n";
33             }
34             }
35              
36             But you can also create a tag yourself, either with an ID string:
37              
38             my $tag = RFID::EPC::Tag->new(id => '357777777666666999999999');
39              
40             or with the various componenets:
41              
42             my $tag =
43             RFID::EPC::Tag->new(epc_serial => '999999999',
44             epc_manager => '7777777',
45             epc_class => '666666',
46             epc_type => 'GID-96');
47             print "Tag ID is ",$tag->id,"\n";
48              
49              
50             =head1 DESCRIPTION
51              
52             The parsing and tag creation in this module are based on the
53             specifications in EPCGlobal's I
54             Rev.1.24>, from April 1st 2004 (although it doesn't appear to be a
55             joke...). See L for more information.
56              
57             =cut
58              
59 2     2   117846 use strict;
  2         6  
  2         102  
60 2     2   14 use warnings;
  2         4  
  2         73  
61              
62 2     2   13 use Carp;
  2         9  
  2         270  
63 2     2   13 use Exporter;
  2         3  
  2         108  
64 2     2   8366 use RFID::Tag;
  2         6508  
  2         151  
65              
66             our @EXPORT_OK = (@RFID::Tag::Export_OK);
67              
68 2     2   18 use constant TAGTYPE => 'epc';
  2         3  
  2         23055  
69              
70             # Cheatsheet for fast hex conversion
71             our %HEXCHEAT = ( 0 => '0000', 1 => '0001', 2 => '0010', 3 => '0011',
72             4 => '0100', 5 => '0101', 6 => '0110', 7 => '0111',
73             8 => '1000', 9 => '1001', A => '1010', B => '1011',
74             C => '1100', D => '1101', E => '1110', F => '1111');
75              
76             # The names and specifications for all of the EPC tags we know about.
77             our %TAGTYPES =
78             (
79             'SGTIN-96' => {
80             bits => 96,
81             type_bits => 8,
82             type_val => 0b00110000,
83             fields => [
84             epc_header => 8,
85             epc_filter => 3,
86             epc_partition => 3,
87             epc_company => '?',
88             epc_item => '?',
89             epc_serial => 38
90             ],
91             partition_fields => [qw(epc_company epc_item)],
92             partitions => [
93             [40,4],
94             [37,7],
95             [34,10],
96             [30,14],
97             [27,17],
98             [24,20],
99             [20,24],
100             ],
101             },
102             'GID-96' => {
103             bits => 96,
104             type_bits => 8,
105             type_val => 0b00110101,
106             fields => [
107             epc_header => 8,
108             epc_manager => 28,
109             epc_class => 24,
110             epc_serial => 36
111             ]
112             },
113             'SGTIN-64' => {
114             bits => 64,
115             type_bits => 2,
116             type_val => 0b10000000,
117             fields => [
118             epc_header => 2,
119             epc_filter => 3,
120             epc_company => 14,
121             epc_item => 20,
122             epc_serial => 25
123             ]
124             },
125             'SSCC-64' => {
126             bits => 64,
127             type_bits => 8,
128             type_val => 0b00001000,
129             fields => [
130             epc_header => 8,
131             epc_filter => 3,
132             epc_company => 14,
133             epc_serial => 39
134             ]
135             },
136             'SSCC-96' => {
137             bits => 96,
138             type_bits => 8,
139             type_val => 0b00110001,
140             fields => [
141             epc_header => 8,
142             epc_filter => 3,
143             epc_partition => 3,
144             epc_company => '?',
145             epc_serial => '?',
146             epc_unallocated => 25
147             ],
148             partition_fields => [qw(epc_company epc_serial)],
149             partitions => [
150             [40,17],
151             [37,20],
152             [34,23],
153             [30,27],
154             [27,30],
155             [24,33],
156             [20,37],
157             ],
158             },
159             'GRAI-64' => {
160             bits => 64,
161             type_bits => 8,
162             type_val => 0b00001010,
163             fields => [
164             epc_header => 8,
165             epc_filter => 3,
166             epc_company => 14,
167             epc_asset_type => 20,
168             epc_serial => 19
169             ]
170             },
171             'GRAI-96' => {
172             bits => 96,
173             type_bits => 8,
174             type_val => 0b00110011,
175             fields => [
176             epc_header => 8,
177             epc_filter => 3,
178             epc_partition => 3,
179             epc_company => '?',
180             epc_asset_type => '?',
181             epc_serial => 38
182             ],
183             partition_fields => [qw(epc_company epc_asset_type)],
184             partitions => [
185             [40,4],
186             [37,7],
187             [34,10],
188             [30,14],
189             [27,17],
190             [24,20],
191             [20,24],
192             ],
193             },
194             'SGLN-64' => {
195             bits => 64,
196             type_bits => 8,
197             type_val => 0b00001001,
198             fields => [
199             epc_header => 8,
200             epc_filter => 3,
201             epc_company => 14,
202             epc_location => 20,
203             epc_serial => 19
204             ]
205             },
206             'SGLN-96' => {
207             bits => 96,
208             type_bits => 8,
209             type_val => 0b00110010,
210             fields => [
211             epc_header => 8,
212             epc_filter => 3,
213             epc_partition => 3,
214             epc_company => '?',
215             epc_location => '?',
216             epc_serial => 41
217             ],
218             partition_fields => [qw(epc_company epc_location)],
219             partitions => [
220             [40,1],
221             [37,4],
222             [34,7],
223             [30,11],
224             [27,14],
225             [24,17],
226             [20,21],
227             ],
228             },
229             'GIAI-64' => {
230             bits => 64,
231             type_bits => 8,
232             type_val => 0b00001011,
233             fields => [
234             epc_header => 8,
235             epc_filter => 3,
236             epc_company => 14,
237             epc_asset => 39,
238             ]
239             },
240             'GIAI-96' => {
241             bits => 96,
242             type_bits => 8,
243             type_val => 0b00110100,
244             fields => [
245             epc_header => 8,
246             epc_filter => 3,
247             epc_partition => 3,
248             epc_company => '?',
249             epc_asset => '?',
250             ],
251             partition_fields => [qw(epc_company epc_asset)],
252             partitions => [
253             [40,42],
254             [37,45],
255             [34,48],
256             [30,52],
257             [27,55],
258             [24,58],
259             [20,62],
260             ],
261             },
262             'UNKNOWN1-64' => {
263             bits => 64,
264             type_bits => 2,
265             type_val => 0b01000000,
266             fields => [
267             epc_header => 2,
268             epc_unknown => 62,
269             ]
270             },
271             'UNKNOWN2-64' => {
272             bits => 64,
273             type_bits => 2,
274             type_val => 0b11000000,
275             fields => [
276             epc_header => 2,
277             epc_unknown => 62,
278             ]
279             },
280             'UNKNOWN3-64' => {
281             bits => 64,
282             type_bits => 5,
283             type_val => 0b00001111,
284             fields => [
285             epc_header => 8,
286             epc_unknown => 56,
287             ]
288             },
289             'UNKNOWN-96' => {
290             bits => 96,
291             type_bits => 4,
292             type_val => 0b00111111,
293             fields => [
294             epc_header => 8,
295             epc_unknown => 88,
296             ]
297             },
298             'UNKNOWN' => {
299             type_bits => 0,
300             type_val => 0b00000111,
301             fields => [
302             epc_header => 8,
303             epc_unknown => '*',
304             ],
305             },
306            
307             );
308              
309            
310             # Sort from longest type_bits to shortest.
311             our @TAGSEARCH = sort
312             { -1 * ($TAGTYPES{$a}{type_bits} <=> $TAGTYPES{$b}{type_bits}) }
313             keys %TAGTYPES;
314              
315             =head2 Constructor
316              
317             =head3 new
318              
319             Creates a new EPC tag object with the requested properties.
320              
321             There are two general ways to create an EPC tag. First, you can pass
322             in the tag ID number as a hex string with the parameter name I.
323             Second, you can pass in various components specific to your L
324             Type|/Tag Types>, including at least I.
325              
326             my $tag1 = RFID::EPC::Tag->new(id => '357777777666666999999999');
327              
328             my $tag2 =
329             RFID::EPC::Tag->new(epc_serial => '999999999',
330             epc_manager => '7777777',
331             epc_class => '666666',
332             epc_type => 'GID-96');
333              
334             print "The two tags are ",
335             ($tag1->tagcmp($tag2)==0?"the same":"different"),
336             "\n";
337              
338             =cut
339              
340             sub new
341             {
342 58     58 1 72739 my $self = bless {}, shift;
343 58         227 my(%p)=@_;
344              
345 58         389 $self->_init(%p);
346              
347 58 100       3398 if (defined($p{id}))
    50          
348             {
349             # Construct a tag from its ID
350 29         72 $self->{id} = uc $p{id};
351 29         134 $self->{id} =~ tr/0-9A-Z//cd;
352 29 50       169 $self->{id} =~ /^[0-9A-F]+$/
353             or croak "RFID::EPC::Tag id format is invalid (must be a hex number)";
354             }
355             elsif (defined($p{epc_type}))
356             {
357             # Construct a tag from its components.
358 29         93 _maketag($self,\%p);
359             }
360             else
361             {
362 0         0 croak "Cannot create RFID::EPC::Tag with no id or parts";
363             }
364              
365 58         400 $self;
366             }
367              
368             =head2 Methods
369              
370             The following methods are supported. In addition,
371             L are inherited.
372              
373             =head3 get
374              
375             Get a property of this tag. In addition to the L
376             from RFID::Tag|RFID::Tag/Properties>, the following fields are
377             supported. Note that whether a particular field is supported depends
378             on the tag type. All fields are represented as hex strings.
379              
380             =over 4
381              
382             =item epc_type
383              
384             The EPC type of this tag.
385              
386             =item epc_serial
387              
388             The EPC serial number of this tag.
389              
390             =item epc_manager
391              
392             The EPC manager number of this tag.
393              
394             =item epc_class
395              
396             The EPC class of this tag.
397              
398             =item epc_header
399              
400             The EPC header bits for this tag.
401              
402             =item epc_filter
403              
404             The EPC filter for this tag.
405              
406             =item epc_partition
407              
408             The EPC partition number for this tag. This field determines the size
409             of later fields; see the EPC specification for more information.
410              
411             =item epc_item
412              
413             The EPC item number for this tag.
414              
415             =item epc_company
416              
417             The EPC company number for this tag.
418              
419             =item epc_asset_type
420              
421             The EPC asset type number for this tag.
422              
423             =item epc_location
424              
425             The EPC location number for this tag.
426              
427             =item epc_asset
428              
429             The EPC asset number for this tag.
430              
431             =item epc_unknown
432              
433             For tags of unrecognized type, all of the bytes that could not be
434             parsed.
435              
436             =back
437              
438             =cut
439              
440             sub get
441             {
442 29     29 1 46257 my $self = shift;
443 29         182 my(@p)=@_;
444 29         34 my(%ret);
445              
446 29         69 foreach my $p (@p)
447             {
448 132 50       1411 if (lc $p eq 'type')
    50          
449             {
450 0         0 $ret{$p} = TAGTYPE;
451             }
452             elsif ($p =~ /^epc_/)
453             {
454 132 100       635 $self->{_epc_parsed} = $self->_epc_parse
455             unless ($self->{_epc_parsed});
456 132 50       272 if ($p eq 'epc_all')
457             {
458 0         0 $ret{$p} = { %{$self->{_epc_parsed}} }
  0         0  
459             }
460             else
461             {
462 132         1279 $ret{$p}=$self->{_epc_parsed}{$p};
463             }
464             }
465             else
466             {
467 0         0 $ret{$p} = $self->SUPER::get($p);
468             }
469             }
470            
471 29 50       65 if (wantarray)
472             {
473 29         351 return %ret;
474             }
475             else
476             {
477             # Return last value
478 0         0 return $ret{$_[$#_]};
479             }
480              
481             }
482              
483             # Create a tag from its various components
484             sub _maketag
485             {
486 29     29   43 my($tag,$p)=@_;
487            
488 29         91 _packbits($tag,$p,$p->{epc_type});
489 29         51 $tag;
490             }
491              
492             # Helper function for _maketag
493             sub _packbits
494             {
495 29     29   48 my($tag,$p,$type)=@_;
496 29 50       137 my $spec = $TAGTYPES{$type}
497             or die "Unknown tag type '$type'";
498 29         44 my $bits = "";
499 29         36 my %calc_fieldsize;
500              
501             # Create the header byte, with the bits right-justified in the
502             # epc_header field, so they'll parse properly.
503 29 50       503 $p->{epc_header} = sprintf "%x", $spec->{type_val} >> (8 - $spec->{fields}[1])
504             unless (defined($p->{epc_header}));
505              
506             # Now build the tag ID based on the specs.
507 29         346 my @fields = @{$spec->{fields}};
  29         413  
508 29         86 while (@fields)
509             {
510 134         186 my $field = shift @fields;
511 134         164 my $numbits = shift @fields;
512              
513             # Get the value for this field in hex, then clean it up.
514 134 100       456 my $fieldval = defined($p->{$field})
515             ? uc $p->{$field}
516             : '';
517 134         550 $fieldval =~ tr/0-9A-Z//cd;
518 134 50       886 $fieldval =~ /^[0-9A-F]*$/
519             or croak "field '$field' must be in hex for tag type $tag->{epc_type}";
520 134 100       659 if (length($fieldval) % 2)
521             {
522 74         481 $fieldval = "0".$fieldval;
523             }
524              
525             # Deal with special cases
526 134 100       835 if ($field eq 'epc_partition')
    100          
    100          
527             {
528             # The epc_partition field is an index into an array of
529             # sizes for fields that aren't yet defined (are set to ?)
530 16 50       73 my $partlist = $spec->{partitions}[hex $fieldval]
531             or die "Invalid EPC partition size\n";
532 16         92 foreach my $i (0..$#{$partlist})
  16         309  
533             {
534 32         116 $calc_fieldsize{$spec->{partition_fields}[$i]} = $partlist->[$i];
535             }
536             }
537             elsif ($numbits eq '?')
538             {
539             # We should have already precalculated this from epc_partition
540 32 50       90 $numbits = $calc_fieldsize{$field}
541             or die "Couldn't figure out fieldsize for '$field'\n";
542             }
543             elsif ($numbits eq '*')
544             {
545             # Just use all of the bits available.
546             # This is only used for the UNKNOWN type, where we don't
547             # know the size and have to guess.
548 3         6 $numbits = length($fieldval)*4;
549             }
550            
551             # Convert into binary and append to current bits
552 134         1058 my $fieldbits=substr(unpack("B*",pack("H*",$fieldval)),-$numbits);
553 134         601 $bits .= "0" x ($numbits-length($fieldbits)) . $fieldbits;
554             }
555             # Convert bitstring into hex.
556 29         196 $tag->{id} = unpack("H*",pack("B*",$bits));
557             }
558              
559             # Return a hash with the components of a tag's ID
560             sub _epc_parse
561             {
562 29     29   43 my $self = shift;
563 29         161 my $id = $self->id;
564 29         272 my $byte1 = hex substr($id,0,2);
565 29         42 my $taglen;
566            
567             # Find the match for the header with the longest mask
568 29         128 foreach my $name (@TAGSEARCH)
569             {
570 232         379 my $spec = $TAGTYPES{$name};
571 232         272 my $mask;
572 232 100       1043 if (!defined($mask=$spec->{type_mask}))
573             {
574 16         46 $mask=$spec->{type_mask} = 2**($spec->{type_bits})-1 << (8 - $spec->{type_bits});
575             }
576 232 100       1249 if (($byte1 & $mask) == ($spec->{type_val} & $mask))
577             {
578 29         77 return _splitbits($id,$name);
579             }
580             }
581              
582             # This should never happen, since the UNKNOWN tag type should
583             # always match.
584 0         0 die "Couldn't figure out tag type '$byte1'!\n";
585             }
586              
587             # Helper function for _epc_parse
588             sub _splitbits
589             {
590 29     29   110 my($hex,$name)=@_;
591 29 50       146 my $spec = $TAGTYPES{$name}
592             or die "Unknown tag type '$name'";
593 29         390 my %r = (epc_type => $name);
594 29         31 my %calc_fieldsize;
595            
596             # Convert hex to a string of bits
597 29         186 my $bits = unpack("B*",pack("H*",$hex));
598              
599             # Now deconstruct the ID field-by-field.
600 29         42 my @fields = @{$spec->{fields}};
  29         131  
601 29         88 while (@fields)
602             {
603 134         189 my $field = shift @fields;
604 134         164 my $numbits = shift @fields;
605              
606 134 100       732 if ($numbits eq '?')
    100          
607             {
608 32 50       76 $numbits = $calc_fieldsize{$field}
609             or die "Couldn't figure out fieldsize for '$field'\n";
610             }
611             elsif ($numbits eq '*')
612             {
613 3         5 $numbits = length($bits);
614             }
615              
616 134         558 my $thesebits = substr($bits,0,$numbits,'');
617            
618             # Pad with 0's so that unpack can parse it properly.
619 134 100       265 if ($numbits % 4)
620             {
621 80         474 $thesebits = "0"x(4-$numbits%4) . $thesebits;
622             }
623              
624             # Now convert the bits into hex
625 134         1057 $r{$field} = unpack("H*",(pack("B*",$thesebits)));
626 134 100 100     1376 if (($numbits % 8) and ($numbits % 8) <= 4)
627             {
628             # Remove trailing zero.
629 68         423 chop($r{$field});
630             }
631              
632             # Handle the special partition case, which determines the sizes
633             # of later fields.
634 134 100       802 if ($field eq 'epc_partition')
635             {
636 16         37 my $partition = hex($r{$field});
637 16 50       52 my $partlist = $spec->{partitions}[$partition]
638             or die "Invalid EPC partition size\n";
639 16         20 foreach my $i (0..$#{$partlist})
  16         135  
640             {
641 32         198 $calc_fieldsize{$spec->{partition_fields}[$i]} = $partlist->[$i];
642             }
643             }
644            
645             }
646              
647 29         323 return \%r;
648             }
649              
650             =head3 type
651              
652             This method returns the general type of this tag (always C).
653              
654             =cut
655              
656             sub type
657             {
658 0     0 1   return TAGTYPE;
659             }
660              
661             =head2 Tag Types
662              
663             The EPC Tag Data Standards document defines many specific types of EPC
664             tags. We do our best to parse these out, and return the appropriate
665             fields. This isn't very well tested, since we don't have access to a
666             large number of different types of EPC tags, but it tries to follow
667             the spec, and should be easy to correct if any errors are found.
668              
669             The purpose of the fields is beyond the scope of this document; we
670             assume you know what the fields are for, and just want to know what
671             names they are given in this code. Mostly that's because it took EPC
672             78 pages to describe exactly what the tag types are, and I don't want
673             to repeat that here. Look up the I document
674             referenced at the top of this documentation for more information.
675              
676             =over 4
677              
678             =item GIAI-64
679              
680             64-bit Global Individual Asset Identifier. Fields are epc_header,
681             epc_filter, epc_company, epc_asset.
682              
683             =item GIAI-96
684              
685             96-bit Global Individual Asset Identifier. Fields are epc_header,
686             epc_filter, epc_partition, epc_company, epc_asset.
687              
688             =item GID-96
689              
690             96-bit General Identifier. Fields are epc_header, epc_manager,
691             epc_class, epc_serial.
692              
693             =item GRAI-64
694              
695             64-bit Global Returnable Asset Identifier. Fields are epc_header,
696             epc_filter, epc_company, epc_asset_type, epc_serial.
697              
698             =item GRAI-96
699              
700             96-bit Global Returnable Asset Identifier. Fields are epc_header,
701             epc_filter, epc_partition, epc_company, epc_asset_type, epc_serial.
702              
703             =item SGLN-64
704              
705             64-bit Serialized Global Location Number. Fields are epc_header,
706             epc_filter, epc_company, epc_location, epc_serial.
707              
708             =item SGLN-96
709              
710             96-bit Serialized Global Location Number. Fields are epc_header,
711             epc_filter, epc_partition, epc_company, epc_location, epc_serial.
712              
713             =item SGTIN-64
714              
715             64-bit Serialized Global Trade Identification Number. Fields are
716             epc_header, epc_filter, epc_company, epc_item, epc_serial.
717              
718             =item SGTIN-96
719              
720             96-bit Serialized Global Trade Identification Number. Fields are
721             epc_header, epc_filter, epc_partition, epc_company, epc_item,
722             epc_serial.
723              
724             =item SSCC-64
725              
726             64-bit Serial Shipping Container Code. Fields are epc_header,
727             epc_filter, epc_company, epc_serial.
728              
729             =item SSCC-96
730              
731             96-bit Serial Shipping Container Code. Fields are epc_header,
732             epc_filter, epc_partition, epc_company, epc_serial, epc_unallocated.
733              
734             =item UNKNOWNI-64
735              
736             64-bit tag without any type recognized by this software, but with a
737             header indicating it is 64 bits. Fields are epc_header and
738             epc_unknown.
739              
740             =item UNKNOWN-96
741              
742             96-bit tag without any type recognized by this software, but with a
743             header indicating it is 96 bits. Fields are epc_header and
744             epc_unknown.
745              
746             =item UNKNOWN
747              
748             Tag without any type recognized by this software, and with no
749             indication of its size in the header. Fields are epc_header and
750             epc_unknown.
751              
752             =back
753              
754             =head1 SEE ALSO
755              
756             L, L,
757             L,
758             L, The manual for your particular RFID
759             reader.
760              
761             =head1 AUTHOR
762              
763             Scott Gifford Egifford@umich.eduE, Esgifford@suspectclass.comE
764              
765             Copyright (C) 2004 The Regents of the University of Michigan.
766              
767             See the file LICENSE included with the distribution for license
768             information.
769              
770             =cut
771              
772              
773             1;