CDataLink.cpp
上传用户:hbchunshui
上传日期:2021-02-03
资源大小:3k
文件大小:11k
源码类别:

中间件编程

开发平台:

C/C++

  1. // cDataLink.cpp: implementation of the cDataLink class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. //#include "cos.h"
  6. #include "CDataLink.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CDataLink::CDataLink()
  16. {
  17.   // Declaration of PICC or Application specific settings
  18.   power_level_indication = 0x00;  // 00: PICC does not support power level indication
  19.   nad  = 0x0F;  // e.g. 
  20.   wtxm = 0x15;  // e.g.
  21.   // Internal Variables Declaration
  22.   i = 0;  // Loop parameter only for I-Block -> Chaining PCD
  23.   j = 0;  // Loop parameter only for I-Block -> Chaining PICC
  24.   n = 0;  // Loop parameter
  25.   r = 0;  // Loop parameter
  26.   offset = 0;       // Counter to calculate the maximum space for INF Bytes
  27.   byte_cnt = 0; // Byte Counter only used for Chaining PICC
  28.   byte_nr = 1; 
  29.   temp = 0;
  30.   processing = READY;               
  31.   fsdi = 128;         // will be later corrected
  32.   //prot_state = RECEIVE_WAIT;
  33.   block_number = 0x00;     // Initializised to 0 (Rule B)
  34. }
  35. CDataLink::~CDataLink()
  36. {
  37. }
  38. int CDataLink::ImplementLinker(BYTE cid,BYTE prot_state,CInfBuf *CInfBuffer)
  39. {
  40. // Loop to processing the ISO/IEC 14443-4 Transmission Protocol
  41.  while ( 1 )
  42.  {
  43. switch ( prot_state )
  44. {
  45. // WAIT STATE
  46.         case RECEIVE_WAIT: 
  47. // Reset variable
  48. byte_nr = 1;
  49. // Protocol error catching
  50. if ( processing == PROTOCOL_ERROR )
  51. {
  52. // If a protocol error occurs all flag have to be reset
  53. i = 0;
  54.     j = 0;
  55. byte_cnt = 0;
  56. CComBuf.ClearBuffer();
  57.                 processing = READY;
  58. }
  59. if (CComBuf.ReceiveBuffer()!= 0) 
  60. {
  61.     //test code require
  62. return 0;
  63. // Error occur(Rule 4)
  64. if (processing == S_DESELECT_REQ)
  65. {
  66.    //Rule 8
  67. prot_state = SEND_S_DES_REQ;
  68.      break;
  69. }
  70. if (processing == PICC_CHAINING)
  71. {
  72.    //Rule 5
  73.    prot_state = SEND_R_ACK;
  74.    break;
  75. }
  76. prot_state = SEND_R_NAK;
  77.   break;
  78. }
  79.                         
  80.        
  81. // Error detecting and Decoding of the PCB Byte
  82.             // Check the validation of the CID 
  83.   if ( (CComBuf.GetBufferValue(0) & M_CID) != 0 )
  84. {  
  85.    if ( (CComBuf.GetBufferValue(byte_nr) & M_CID_BYTE) != cid )
  86.    {
  87.    // CID not matched
  88.                    prot_state = RECEIVE_WAIT; // If not -> Wait State
  89.        break;
  90. }
  91. else
  92. {
  93. // CID matched
  94. //add_cid = true;
  95. byte_nr++; 
  96. }
  97. }
  98.         else
  99. {
  100. prot_state = RECEIVE_WAIT;
  101. break;
  102. }
  103.               
  104.             // Check PCB Byte for I-Block 
  105. if ( (CComBuf.GetBufferValue(0) & M_I_BLOCK) == I_BLOCK ) 
  106.             {
  107. //add_nad = false;
  108. prot_state = RECEIVE_I;
  109. break;
  110. }
  111.             // Check PCB Byte for R(ACK)-Block
  112. if ( (CComBuf.GetBufferValue(0) & M_R_BLOCK) == R_BLOCK_ACK )
  113. {                                       
  114. if ( CComBuf.GetBufferCount()!= byte_nr )
  115. {
  116. // Transmission error occured
  117. prot_state = SEND_R_NAK;
  118. break;                        
  119. }  
  120. else
  121. {
  122. // R-Block ACK received
  123. prot_state = RECEIVE_R_ACK;
  124. break;
  125. }
  126. }
  127.                             
  128.             // Check PCB Byte for S(DES)-Block
  129. if ( (CComBuf.GetBufferValue(0) & M_S_BLOCK) == S_BLOCK_DES )
  130. {
  131. if ( CComBuf.GetBufferCount() != byte_nr )
  132. {
  133. // Transmission error occured
  134. prot_state =  SEND_S_DES_REQ ;
  135. break;                        
  136. }     
  137. else
  138. {
  139. // S-Block DES received
  140. //prot_state = RECEIVE_S_DES_REQ;
  141. return 0;
  142. }
  143. }
  144.         
  145.             // Check PCB Byte for S(WTX)request-Block
  146. if ( (CComBuf.GetBufferValue(0) & M_S_BLOCK) == S_BLOCK_WTX ) 
  147. {                                       
  148. if ( CComBuf.GetBufferCount() != (byte_nr + 1) )
  149. {
  150. // Transmission error occured
  151. prot_state = SEND_R_NAK;
  152. break;                        
  153. }  
  154. else
  155. {
  156. // S-Block WTX received
  157. prot_state = SEND_S_WTX_RES;
  158. break;
  159. }
  160. }        
  161. // Block received with no valid coding
  162. prot_state = SEND_R_NAK;
  163. break;
  164.         
  165. //SEND DESELECT REQUEST
  166.         case SEND_S_DES_REQ:
  167. CComBuf.ClearBuffer();
  168. temp = S_BLOCK_DES | M_CID; // Set CID bit
  169. CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
  170.                                         
  171. // Generate CID Byte with Power Level Indication
  172. temp = 0x00 | cid; // Add Power Level Indication and cid to CID Byte
  173. CComBuf.AddBufferValue(temp); // Append CID Byte to transmit buffer
  174. // Save then send S (Des)
  175. CBufferCopy.CopyBuffer(CComBuf);
  176. CComBuf.TransmitBuffer();
  177. processing = S_DESELECT_REQ;
  178.   prot_state = RECEIVE_WAIT;
  179. break;
  180.         // SEND S (WTX) RESPONSE
  181. case SEND_S_WTX_RES:  
  182. CComBuf.ClearBuffer();
  183. temp = S_BLOCK_WTX | M_CID; // Set CID bit
  184. CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
  185.                                         
  186. // Generate CID Byte 
  187. temp = 0x00|cid; 
  188. CComBuf.AddBufferValue(temp); // Append CID Byte to transmit buffer
  189. temp = 0x00 | wtxm; 
  190. CComBuf.AddBufferValue(temp); // Append WTXM Byte to transmit buffer
  191. // Save then send WTX(Res)
  192. CBufferCopy.CopyBuffer(CComBuf);
  193. CComBuf.TransmitBuffer();
  194.   prot_state = RECEIVE_WAIT;
  195. break;                                                          
  196.          // Retransmit the last block
  197. case SEND_RETRANSMIT:
  198. CBufferCopy.RestoreBuffer(&CComBuf);
  199. CComBuf.TransmitBuffer();
  200. // Goto next state
  201. prot_state = RECEIVE_WAIT;
  202. break;
  203.         // Send R (ACK) after received part of chain
  204.         case SEND_R_ACK:  
  205.          CComBuf.ClearBuffer();
  206.     temp = R_BLOCK_ACK | M_CID; // Set CID bit
  207. temp = temp | block_number; // Add Block Number
  208. CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
  209. // Generate CID Byte
  210. temp = power_level_indication | cid; // Add Power Level Indication and cid to CID Byte
  211. CComBuf.AddBufferValue(temp);        // Append CID Byte to transmit buffer
  212. // Save the transmission data
  213. CBufferCopy.CopyBuffer(CComBuf);
  214. // Send R (ACK)
  215. CComBuf.TransmitBuffer();
  216. // Goto next State
  217. prot_state = RECEIVE_WAIT;
  218. break;
  219.         case SEND_R_NAK:  
  220.          CComBuf.ClearBuffer();
  221.     temp = R_BLOCK_NAK | M_CID; // Set CID bit
  222. temp = temp | block_number; // Add Block Number
  223. CComBuf.AddBufferValue(temp); // Append PCB Byte to transmit buffer
  224. // Generate CID Byte
  225. temp = 0x00 | cid;                  //  cid to CID Byte
  226. CComBuf.AddBufferValue(temp);       // Append CID Byte to transmit buffer
  227. // Save the transmission data
  228. CBufferCopy.CopyBuffer(CComBuf);
  229. // Send R (ACK)
  230. CComBuf.TransmitBuffer();
  231. // Goto next State
  232. prot_state = RECEIVE_WAIT;
  233. break;
  234.         //R (ACK) Received 
  235.         case RECEIVE_R_ACK: 
  236. // Block numbering rules (Rule B)
  237. if ( (CComBuf.GetBufferValue(0) & M_BLOCK_NUMBER) == block_number ) 
  238. {
  239. // Received Block Number is equal to the current PCD Block number
  240. block_number ^= 0x01; // Toggle the block number
  241.                 prot_state = SEND_I;
  242. break;
  243. }
  244.             else
  245. {
  246. // Transmission error occured,Retransmit last block 
  247.             prot_state = SEND_RETRANSMIT;
  248. break;
  249. }
  250.         //I-BLOCK Received 
  251.         case RECEIVE_I:         
  252. n = 0; // Reset of the loop parameter        
  253. // Block number handling 
  254. if ( (CComBuf.GetBufferValue(0) & M_BLOCK_NUMBER) == block_number ) 
  255. {
  256. // Received Block Number is equal to the current PCD Block number
  257. block_number ^= 0x01; // Toggle the block number
  258. }
  259.                                              
  260. // Chaining?
  261. if ( (CComBuf.GetBufferValue(0) & M_CHAINING) == 0 )
  262. {
  263. // No Chaining or last part of Chain
  264. // Get INF Bytes from the received block
  265.     CInfBuffer->ClearBuffer();
  266. for ( n = byte_nr; n < CComBuf.GetBufferCount(); n++)
  267. {
  268. CInfBuffer->AddBufferValue(CComBuf.GetBufferValue(n));
  269. }
  270.  
  271. processing = READY; // Reset this Flag for protocol error detecting
  272. // Goto next State
  273. prot_state = APPLICATION_STATE;
  274. break;
  275. }
  276. else
  277. {
  278. //Set Chaining  Flag
  279. processing = PICC_CHAINING; 
  280. // Get part of INF Bytes from the received block and add it to 
  281. // the former received Bytes
  282. for ( n = byte_nr; n < CComBuf.GetBufferCount(); n++)
  283. {
  284. CInfBuffer->AddBufferValue(CComBuf.GetBufferValue(n));
  285. }
  286. //Rule 5
  287. prot_state = SEND_R_ACK;
  288. break;
  289. }
  290.         //Send I Block
  291.         case SEND_I:
  292. CComBuf.ClearBuffer();
  293. offset = 4; // 1xPCB + 1xCID + 2xCRC
  294. // Append I-Block Code to PCB Byte
  295.             temp = I_BLOCK | block_number;
  296. temp|=M_CID;
  297. CComBuf.AddBufferValue(temp);
  298.         
  299. //Append CID
  300. temp = 0x00 | cid; // Add  cid to CID Byte temp = cid;
  301. CComBuf.AddBufferValue(temp);
  302. //  NO CHAINING         
  303. if ( (offset + (CInfBuffer->GetBufferCount()- byte_cnt)) <= fsdi )
  304. {
  305. // No Chaining required
  306. n = CInfBuffer->GetBufferCount() - byte_cnt;
  307.                                 
  308. // Append INF Bytes        
  309. for ( j = 0; j < n ; j++ )
  310. {
  311. // Append Byte 
  312. CComBuf.AddBufferValue(CInfBuffer->GetBufferValue(byte_cnt++));                                                                                  
  313.                 }
  314.                 // Reset of the Loop parameter
  315. j = 0;
  316. offset = 0;
  317. n = 0;
  318. byte_cnt = 0;
  319. processing = READY;
  320.     CInfBuffer->ClearBuffer();
  321. }
  322. else
  323. {
  324. // Chaining required
  325.             processing = PCD_CHAINING; // Set PCD Chaining flag
  326. // Set chaining bit in PCB
  327. CComBuf.SetBufferValue(CComBuf.GetBufferValue(0)| M_CHAINING,0); 
  328.       
  329. // Append INF Bytes        
  330. for ( j = 0; j < (fsdi - offset); j++ )
  331. {
  332. // Append Byte 
  333. CComBuf.AddBufferValue(CInfBuffer->GetBufferValue(byte_cnt++));                                                                                  
  334. }
  335. }
  336. // Save the transmission data
  337. CBufferCopy.CopyBuffer(CComBuf);
  338. // Send I-Block
  339. CComBuf.TransmitBuffer();
  340. prot_state = RECEIVE_WAIT;
  341. break; 
  342.         // Application State 
  343.         case APPLICATION_STATE:
  344. return 1;
  345. // Error has been occured -> WAIT State
  346. default:
  347. processing = PROTOCOL_ERROR;
  348.             prot_state = RECEIVE_WAIT;
  349. }//switch
  350.   }//while
  351. }