HiPi

 view release on metacpan or  search on metacpan

lib/HiPi/Interface/MFRC522.pm  view on Meta::CPAN

    
    my @buffer = ();
    
	while (!$uidComplete) {
		#// Set the Cascade Level in the SEL byte, find out if we need to use the Cascade Tag in byte 2.
        
        $selectDone = 0;
        
        if( $cascadeLevel == 1 ) {
            
            $buffer[0] = MIFARE_SELECT_CL1;
            $uidIndex = 0,
            $useCascadeTag = ( $validbits && $uid->{'size'} > 4 ) ? 1 : 0;
        } elsif( $cascadeLevel == 2 ) {
			            
            $buffer[0] = MIFARE_SELECT_CL2;
            $uidIndex = 3,
            $useCascadeTag = ( $validbits && $uid->{'size'} > 7 ) ? 1 : 0;
		
        } elsif( $cascadeLevel == 3 ) {
			            
            $buffer[0] = MIFARE_SELECT_CL3;
            $uidIndex = 6,
            $useCascadeTag = 0
			
		} else {
            # should not get here
            # warn qq( cascade level $cascadeLevel);
            return ( MFRC522_STATUS_INTERNAL_ERROR );
        }
		
		# // How many UID bits are known in this Cascade Level?
		$currentLevelKnownBits = $validbits - (8 * $uidIndex);
        
		if ($currentLevelKnownBits < 0) {
			$currentLevelKnownBits = 0;
		}
                
		# // Copy the known bits from uid->uidByte[] to buffer[]
		$index = 2; #// destination index in buffer[]
		if ($useCascadeTag) {
			$buffer[$index++] = MIFARE_CASCADE;
		}
        
		my $bytesToCopy = int($currentLevelKnownBits / 8) + ($currentLevelKnownBits % 8 ? 1 : 0); # // The number of bytes needed to represent the known bits for this level.
		
        if ($bytesToCopy) {
			my $maxBytes = $useCascadeTag ? 3 : 4; #// Max 4 bytes in each Cascade Level. Only 3 left if we use the Cascade Tag
			if ($bytesToCopy > $maxBytes) {
				$bytesToCopy = $maxBytes;
			}
			for (my $count = 0; $count < $bytesToCopy; $count++) {
				$buffer[$index++] = $uid->{'data'}->[$uidIndex + $count] || 0;
			}
		}
		# // Now that the data has been copied we need to include the 8 bits in CT in currentLevelKnownBits
		if ($useCascadeTag) {
			$currentLevelKnownBits += 8;
		}
		
		# // Repeat anti collision loop until we can transmit all UID bits + BCC and receive a SAK - max 32 iterations.
		
		while (!$selectDone) {
			# // Find out how many bits and bytes to send and receive.
			if ($currentLevelKnownBits >= 32) { # // All UID bits in this Cascade Level are known. This is a SELECT.
				
				$buffer[1] = 0x70; #// NVB - Number of Valid Bits: Seven whole bytes
				#// Calculate BCC - Block Check Character
                
                for( 2,3,4,5) {
                    $buffer[$_] //= 0;
                }
                
				$buffer[6] = $buffer[2] ^ $buffer[3] ^ $buffer[4] ^ $buffer[5];
				# // Calculate CRC_A
                
                my @crcdata = @buffer[0..6];
                
                ( $crcstatus, $cbuffer1, $cbuffer2 ) = $self->pcd_calculate_crc( \@crcdata );
                
				if ($crcstatus != MFRC522_STATUS_OK) {
					return ( $crcstatus, undef, undef );
				}
                
                # set the crc result
                $buffer[7] = $cbuffer1;
                $buffer[8] = $cbuffer2;
                
				$txLastBits		= 0; #// 0 => All 8 bits are valid.
				$bufferUsed		= 9; 
				$responseLength	= 3;
                $responseIndex  = 6;
                
			} else { #// This is an ANTICOLLISION.
				
				$txLastBits		= $currentLevelKnownBits % 8;
				my $count		= int($currentLevelKnownBits / 8);	#// Number of whole bytes in the UID part.
				$index			= 2 + $count;					#// Number of whole bytes: SEL + NVB + UIDs
				$buffer[1]		= ($index << 4) + $txLastBits;	#// NVB - Number of Valid Bits
				$bufferUsed		= $index + ($txLastBits ? 1 : 0);
				$responseLength = 9 - $index;
                $responseIndex = $index;
			}
			
			#// Set bit adjustments
			$rxAlign = $txLastBits || 0;											#// Having a separate variable is overkill. But it makes the next line easier to read.
			$self->write_register(MFRC522_REG_BitFramingReg, ($rxAlign << 4) + $txLastBits);	#// RxAlign = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0]
			
			#// Transmit the buffer and receive the response.
            
            my $getlen = $responseLength;
            
            my $sendlen = $bufferUsed -1;
           
            my @sendbuffer = @buffer[0..$sendlen];
                        
            ($respstatus, $respdata, $respvalidbits) = $self->pcd_transceive_data(\@sendbuffer, $txLastBits, $getlen, $rxAlign );
            
			$txLastBits = $respvalidbits;
            
            if($respdata && ref($respdata)) {



( run in 1.006 second using v1.01-cache-2.11-cpan-71847e10f99 )