CDataLink.cpp
资源名称:CDataLink.rar [点击查看]
上传用户:hbchunshui
上传日期:2021-02-03
资源大小:3k
文件大小:11k
源码类别:
中间件编程
开发平台:
C/C++
- // cDataLink.cpp: implementation of the cDataLink class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- //#include "cos.h"
- #include "CDataLink.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CDataLink::CDataLink()
- {
- // Declaration of PICC or Application specific settings
- power_level_indication = 0x00; // 00: PICC does not support power level indication
- nad = 0x0F; // e.g.
- wtxm = 0x15; // e.g.
- // Internal Variables Declaration
- i = 0; // Loop parameter only for I-Block -> Chaining PCD
- j = 0; // Loop parameter only for I-Block -> Chaining PICC
- n = 0; // Loop parameter
- r = 0; // Loop parameter
- offset = 0; // Counter to calculate the maximum space for INF Bytes
- byte_cnt = 0; // Byte Counter only used for Chaining PICC
- byte_nr = 1;
- temp = 0;
- processing = READY;
- fsdi = 128; // will be later corrected
- //prot_state = RECEIVE_WAIT;
- block_number = 0x00; // Initializised to 0 (Rule B)
- }
- CDataLink::~CDataLink()
- {
- }
- int CDataLink::ImplementLinker(BYTE cid,BYTE prot_state,CInfBuf *CInfBuffer)
- {
- // Loop to processing the ISO/IEC 14443-4 Transmission Protocol
- while ( 1 )
- {
- switch ( prot_state )
- {
- // WAIT STATE
- case RECEIVE_WAIT:
- // Reset variable
- byte_nr = 1;
- // Protocol error catching
- if ( processing == PROTOCOL_ERROR )
- {
- // If a protocol error occurs all flag have to be reset
- i = 0;
- j = 0;
- byte_cnt = 0;
- CComBuf.ClearBuffer();
- processing = READY;
- }
- if (CComBuf.ReceiveBuffer()!= 0)
- {
- //test code require
- return 0;
- // Error occur(Rule 4)
- if (processing == S_DESELECT_REQ)
- {
- //Rule 8
- prot_state = SEND_S_DES_REQ;
- break;
- }
- if (processing == PICC_CHAINING)
- {
- //Rule 5
- prot_state = SEND_R_ACK;
- break;
- }
- prot_state = SEND_R_NAK;
- break;
- }
- // Error detecting and Decoding of the PCB Byte
- // Check the validation of the CID
- if ( (CComBuf.GetBufferValue(0) & M_CID) != 0 )
- {
- if ( (CComBuf.GetBufferValue(byte_nr) & M_CID_BYTE) != cid )
- {
- // CID not matched
- prot_state = RECEIVE_WAIT; // If not -> Wait State
- break;
- }
- else
- {
- // CID matched
- //add_cid = true;
- byte_nr++;
- }
- }
- else
- {
- prot_state = RECEIVE_WAIT;
- break;
- }
- // Check PCB Byte for I-Block
- if ( (CComBuf.GetBufferValue(0) & M_I_BLOCK) == I_BLOCK )
- {
- //add_nad = false;
- prot_state = RECEIVE_I;
- break;
- }
- // Check PCB Byte for R(ACK)-Block
- if ( (CComBuf.GetBufferValue(0) & M_R_BLOCK) == R_BLOCK_ACK )
- {
- if ( CComBuf.GetBufferCount()!= byte_nr )
- {
- // Transmission error occured
- prot_state = SEND_R_NAK;
- break;
- }
- else
- {
- // R-Block ACK received
- prot_state = RECEIVE_R_ACK;
- break;
- }
- }
- // Check PCB Byte for S(DES)-Block
- if ( (CComBuf.GetBufferValue(0) & M_S_BLOCK) == S_BLOCK_DES )
- {
- if ( CComBuf.GetBufferCount() != byte_nr )
- {
- // Transmission error occured
- prot_state = SEND_S_DES_REQ ;
- break;
- }
- else
- {
- // S-Block DES received
- //prot_state = RECEIVE_S_DES_REQ;
- return 0;
- }
- }
- // Check PCB Byte for S(WTX)request-Block
- if ( (CComBuf.GetBufferValue(0) & M_S_BLOCK) == S_BLOCK_WTX )
- {
- if ( CComBuf.GetBufferCount() != (byte_nr + 1) )
- {
- // Transmission error occured
- prot_state = SEND_R_NAK;
- break;
- }
- else
- {
- // S-Block WTX received
- prot_state = SEND_S_WTX_RES;
- break;
- }
- }
- // Block received with no valid coding
- prot_state = SEND_R_NAK;
- break;
- //SEND DESELECT REQUEST
- case SEND_S_DES_REQ:
- CComBuf.ClearBuffer();
- temp = S_BLOCK_DES | M_CID; // Set CID bit
- CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
- // Generate CID Byte with Power Level Indication
- temp = 0x00 | cid; // Add Power Level Indication and cid to CID Byte
- CComBuf.AddBufferValue(temp); // Append CID Byte to transmit buffer
- // Save then send S (Des)
- CBufferCopy.CopyBuffer(CComBuf);
- CComBuf.TransmitBuffer();
- processing = S_DESELECT_REQ;
- prot_state = RECEIVE_WAIT;
- break;
- // SEND S (WTX) RESPONSE
- case SEND_S_WTX_RES:
- CComBuf.ClearBuffer();
- temp = S_BLOCK_WTX | M_CID; // Set CID bit
- CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
- // Generate CID Byte
- temp = 0x00|cid;
- CComBuf.AddBufferValue(temp); // Append CID Byte to transmit buffer
- temp = 0x00 | wtxm;
- CComBuf.AddBufferValue(temp); // Append WTXM Byte to transmit buffer
- // Save then send WTX(Res)
- CBufferCopy.CopyBuffer(CComBuf);
- CComBuf.TransmitBuffer();
- prot_state = RECEIVE_WAIT;
- break;
- // Retransmit the last block
- case SEND_RETRANSMIT:
- CBufferCopy.RestoreBuffer(&CComBuf);
- CComBuf.TransmitBuffer();
- // Goto next state
- prot_state = RECEIVE_WAIT;
- break;
- // Send R (ACK) after received part of chain
- case SEND_R_ACK:
- CComBuf.ClearBuffer();
- temp = R_BLOCK_ACK | M_CID; // Set CID bit
- temp = temp | block_number; // Add Block Number
- CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
- // Generate CID Byte
- temp = power_level_indication | cid; // Add Power Level Indication and cid to CID Byte
- CComBuf.AddBufferValue(temp); // Append CID Byte to transmit buffer
- // Save the transmission data
- CBufferCopy.CopyBuffer(CComBuf);
- // Send R (ACK)
- CComBuf.TransmitBuffer();
- // Goto next State
- prot_state = RECEIVE_WAIT;
- break;
- case SEND_R_NAK:
- CComBuf.ClearBuffer();
- temp = R_BLOCK_NAK | M_CID; // Set CID bit
- temp = temp | block_number; // Add Block Number
- CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
- // Generate CID Byte
- temp = 0x00 | cid; // cid to CID Byte
- CComBuf.AddBufferValue(temp); // Append CID Byte to transmit buffer
- // Save the transmission data
- CBufferCopy.CopyBuffer(CComBuf);
- // Send R (ACK)
- CComBuf.TransmitBuffer();
- // Goto next State
- prot_state = RECEIVE_WAIT;
- break;
- //R (ACK) Received
- case RECEIVE_R_ACK:
- // Block numbering rules (Rule B)
- if ( (CComBuf.GetBufferValue(0) & M_BLOCK_NUMBER) == block_number )
- {
- // Received Block Number is equal to the current PCD Block number
- block_number ^= 0x01; // Toggle the block number
- prot_state = SEND_I;
- break;
- }
- else
- {
- // Transmission error occured,Retransmit last block
- prot_state = SEND_RETRANSMIT;
- break;
- }
- //I-BLOCK Received
- case RECEIVE_I:
- n = 0; // Reset of the loop parameter
- // Block number handling
- if ( (CComBuf.GetBufferValue(0) & M_BLOCK_NUMBER) == block_number )
- {
- // Received Block Number is equal to the current PCD Block number
- block_number ^= 0x01; // Toggle the block number
- }
- // Chaining?
- if ( (CComBuf.GetBufferValue(0) & M_CHAINING) == 0 )
- {
- // No Chaining or last part of Chain
- // Get INF Bytes from the received block
- CInfBuffer->ClearBuffer();
- for ( n = byte_nr; n < CComBuf.GetBufferCount(); n++)
- {
- CInfBuffer->AddBufferValue(CComBuf.GetBufferValue(n));
- }
- processing = READY; // Reset this Flag for protocol error detecting
- // Goto next State
- prot_state = APPLICATION_STATE;
- break;
- }
- else
- {
- //Set Chaining Flag
- processing = PICC_CHAINING;
- // Get part of INF Bytes from the received block and add it to
- // the former received Bytes
- for ( n = byte_nr; n < CComBuf.GetBufferCount(); n++)
- {
- CInfBuffer->AddBufferValue(CComBuf.GetBufferValue(n));
- }
- //Rule 5
- prot_state = SEND_R_ACK;
- break;
- }
- //Send I Block
- case SEND_I:
- CComBuf.ClearBuffer();
- offset = 4; // 1xPCB + 1xCID + 2xCRC
- // Append I-Block Code to PCB Byte
- temp = I_BLOCK | block_number;
- temp|=M_CID;
- CComBuf.AddBufferValue(temp);
- //Append CID
- temp = 0x00 | cid; // Add cid to CID Byte temp = cid;
- CComBuf.AddBufferValue(temp);
- // NO CHAINING
- if ( (offset + (CInfBuffer->GetBufferCount()- byte_cnt)) <= fsdi )
- {
- // No Chaining required
- n = CInfBuffer->GetBufferCount() - byte_cnt;
- // Append INF Bytes
- for ( j = 0; j < n ; j++ )
- {
- // Append Byte
- CComBuf.AddBufferValue(CInfBuffer->GetBufferValue(byte_cnt++));
- }
- // Reset of the Loop parameter
- j = 0;
- offset = 0;
- n = 0;
- byte_cnt = 0;
- processing = READY;
- CInfBuffer->ClearBuffer();
- }
- else
- {
- // Chaining required
- processing = PCD_CHAINING; // Set PCD Chaining flag
- // Set chaining bit in PCB
- CComBuf.SetBufferValue(CComBuf.GetBufferValue(0)| M_CHAINING,0);
- // Append INF Bytes
- for ( j = 0; j < (fsdi - offset); j++ )
- {
- // Append Byte
- CComBuf.AddBufferValue(CInfBuffer->GetBufferValue(byte_cnt++));
- }
- }
- // Save the transmission data
- CBufferCopy.CopyBuffer(CComBuf);
- // Send I-Block
- CComBuf.TransmitBuffer();
- prot_state = RECEIVE_WAIT;
- break;
- // Application State
- case APPLICATION_STATE:
- return 1;
- // Error has been occured -> WAIT State
- default:
- processing = PROTOCOL_ERROR;
- prot_state = RECEIVE_WAIT;
- }//switch
- }//while
- }