--- cpr-m02.pl 2010/07/09 23:10:05 82 +++ cpr-m02.pl 2010/07/16 13:33:10 88 @@ -10,10 +10,11 @@ use File::Slurp; use JSON; use POSIX qw(strftime); +use Time::HiRes; use IO::Socket::INET; -my $debug = 2; +my $debug = 0; my $tags_data; my $tags_security; @@ -280,29 +281,97 @@ $crc = $crc >> 1; } } - warn sprintf('%d %04x', $i, $crc & 0xffff); +# warn sprintf('%d %04x', $i, $crc & 0xffff); } return pack('v', $crc); } +sub cpr_psst_wait { + # Protocol Start Synchronization Time (PSST): 5ms < data timeout 12 ms + Time::HiRes::sleep 0.005; +} + sub cpr { - my $hex = shift; + my ( $hex, $description, $coderef ) = @_; my $bytes = str2bytes($hex); my $len = pack( 'c', length( $bytes ) + 3 ); my $send = $len . $bytes; my $checksum = cpr_m02_checksum($send); $send .= $checksum; - warn ">> ", as_hex( $send ); - writechunk( $send ); - my $r_len = read_bytes( 1, 'response length' ); - $r_len = ord($r_len) - 1; - my $data = read_bytes( $r_len, 'data' ); - warn "<< ", as_hex( $data ); + warn ">> ", as_hex( $send ), "\t\t[$description]\n"; + $port->write( $send ); + + cpr_psst_wait; + + my $r_len = $port->read(1); + + while ( ! $r_len ) { + warn "# wait for response length 5ms\n"; + cpr_psst_wait; + $r_len = $port->read(1); + } + + my $data_len = ord($r_len) - 1; + my $data = $port->read( $data_len ); + warn "<< ", as_hex( $r_len . $data ),"\n"; + + cpr_psst_wait; + + $coderef->( $data ) if $coderef; + +} + +# FF = COM-ADDR any + +cpr( 'FF 52 00', 'Boud Rate Detection' ); + +cpr( 'FF 65', 'Get Software Version' ); + +cpr( 'FF 66 00', 'Get Reader Info - General hard and firware' ); + +cpr( 'FF 69', 'RF Reset' ); + + +sub cpr_read { + my $uid = shift; + my $hex_uid = as_hex($uid); + + cpr( "FF B0 23 01 $hex_uid 00 04", "Read Multiple Blocks $hex_uid" ); +# cpr( "FF B0 2B 01 $hex_uid", "Get System Information $hex_uid" ); +} + + +my $inventory; + +while(1) { + +cpr( 'FF B0 01 00', 'ISO - Inventory', sub { + my $data = shift; + if (length($data) < 5 + 2 ) { + warn "# no tags in range\n"; + return; + } + my $data_sets = ord(substr($data,3,1)); + $data = substr($data,4); + foreach ( 1 .. $data_sets ) { + my $tr_type = substr($data,0,1); + die "FIXME only TR-TYPE=3 ISO 15693 supported" unless $tr_type eq "\x03"; + my $dsfid = substr($data,1,1); + my $uid = substr($data,2,8); + $inventory->{$uid}++; + $data = substr($data,10); + warn "# TAG $_ ",as_hex( $tr_type, $dsfid, $uid ),$/; + + cpr_read( $uid ); + } + warn "inventory: ",dump($inventory); +}); + } -cpr( '00 52 00' ); +#cpr( '', '?' ); exit; # initial hand-shake with device @@ -654,6 +723,7 @@ my ( $c, $b ) = $port->read(1); die "no bytes on port: $!" unless defined $b; warn "## got $c bytes: ", as_hex($b), "\n"; + last if $c == 0; $data .= $b; } $desc ||= '?';