RF Card

>w## Notice > * please include the header file "bwsdk_api.h" when you need to use RF Card `#include "bwsdk_api.h"` >i## data structure ``` #define PICC_APDU_LEN_MIN 4 ///< Minimum bytes of C-APDU #define PICC_APDU_LEN_MAX 260 ///< Maximum bytes of C-APDU #define PICC_SW_SIZE 2 ///< Bytes of Status-Word /** * @brief TAG enum for PICC transparent transfer command. */ typedef enum { PICC_TAG_BDR_PCD = 0x61, ///< 0x61, Baudrate of PCD->PICC, n*106000 PICC_TAG_BDR_PICC, ///< 0x62, Baudrate of PICC->PCD, n*106000 PICC_TAG_TYPE, ///< 0x63, Type of PICC PICC_TAG_DATA_SND, ///< 0x64, Data to send PICC_TAG_DATA_RCV, ///< 0x65, Data of receive PICC_TAG_FRAME, ///< 0x66, Frame type PICC_TAG_FWT, ///< 0x67, Frame wait time PICC_TAG_FSGT, ///< 0x68, Frame guard time PICC_TAG_FSC, ///< 0x69, Frame size PICC_TAG_CRC_EN, ///< 0x6A, CRC by RF-chip } TagPicc_t; ///< tag & cmd definition #define TAG_CMD_AUTH 'A' ///< Authenticate #define TAG_CMD_RAED 'R' ///< Read block #define TAG_CMD_WRITE 'W' ///< Write block #define TAG_CMD_PAGE 'P' ///< Write page #define TAG_CMD_INC '+' ///< Value increment #define TAG_CMD_DEC '-' ///< Value decrement #define TAG_CMD_RESTORE '>' ///< Value restore #define TAG_IDX_AUTH_KEYA 'A' ///< M1 KeyA #define TAG_IDX_AUTH_KEYB 'B' ///< M1 KeyB #define TAG_IDX_TRANSPARENT_MODE 0x90 ///< For define transparent mode #define TAG_PSEUDO_APDU_CLS TAG_IDX_TRANSPARENT_MODE ///< #define TAG_M1_KEY_LEN 6 ///< Key length of M1 #define TAG_M1_BLOCK_LEN 0x10 ///< Block length of M1 #define TAG_M1_VALUE_LEN 4 ///< Value length of M1 #define MIFARE_OPT_BUF_LEN 128 ///< PICC TAG card buffer size /** * @brief PICC TAG card command and response structure */ typedef struct ST_TAG_OPT { unsigned char ucOptCmd; ///< Operation command: 'R', 'W', 'P', 'A', '+', '-', '>', ... unsigned char ucOptIdx; ///< Operation index: 'A', 'B' for M1 authenticate, 0x90 for transparent APDU mode. unsigned char ucOptSrc; ///< Operation block source: For Authen, read, write, write page, '+', '-', '>'. unsigned char ucOptDest; ///< Operation block destination: For '+', '-', '>'. unsigned char ucOptValLen; ///< Operation Length: Bytes to read or in optVal. unsigned char aucOptVal[MIFARE_OPT_BUF_LEN]; ///< Operation data. } TagOptType; /** * @brief PICC card information */ typedef struct PICC_INFO_ST { unsigned char ucPiccCardType; ///< Type of PICC unsigned char ucPiccSlot; ///< PICC logical channel number unsigned char ucPiccSnLen; ///< Length of PICC serial number unsigned char ucPiccInfoLen; ///< Length of PICC information unsigned char aucPiccSN[12]; ///< PICC serial number unsigned char aucPiccInfo[128]; ///< PICC information } PiccInfo_T; ``` >i## PiccOpen ### Prototype `int PiccOpen(void);` ### Function * Open PICC module ### Parameter |Name|Type|description| |-|-|-| |none||| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## PiccDetect ### Prototype `int PiccDetect(unsigned char ucMode, PiccInfo_T *pstPiccInfo);` ### Function * Detect PICC ### Parameter |Name|Type|description| |-|-|-| |ucMode|unsigned char|[in] ucMode: 0x01: EMV mode, 'A': TypeA CPU mode, 'B': TypeB CPU mode, 'M': Mifare mode| |pstPiccInfo|PiccInfo_T *|[out] pstPiccInfo: PICC card information| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## PiccApduExchange ### Prototype `int PiccApduExchange(unsigned char *pucCmd, unsigned int uiCmdLen, unsigned char *pucRsp, unsigned char *pucSW);` ### Function * PICC APDU exchange ### Parameter |Name|Type|description| |-|-|-| |pucCmd|unsigned char *|C-APDU| |uiCmdLen|unsigned int|Length of C-APDU| |pucRsp|unsigned char *|R-APDU| |pucSW|unsigned char *|Status-Word (2 bytes)| ### Retval |Value|Type|Description| |-|-|-| |>=0|int|success(Length of R-APDU)| |<0|int|fail| >i## PiccRemove ### Prototype `int PiccRemove(unsigned char ucMode, unsigned char ucSlot);` ### Function * Remove PICC ### Parameter |Name|Type|description| |-|-|-| |ucMode|unsigned char|[in] ucMode: 'E': EMV mode, 'S': Stop mode, 'H': Halt mode| |ucSlot|unsigned char|card slot number, see PiccInfo_T| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## PiccClose ### Prototype `int PiccClose(void);` ### Function * Close PICC module ### Parameter |Name|Type|description| |-|-|-| |none||| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## PiccSidTransceiveRev ### Prototype `int PiccSidTransceiveRev(unsigned char* pucCmd, unsigned int uiCmdLen, unsigned char *pucRsp, unsigned int *puiRspLen);` ### Function * PICC transparent transfer interface ### Parameter |Name|Type|description| |-|-|-| |pucCmd|unsigned char *|Data to send| |uiCmdLen|unsigned int|Length of Data to send| |pucRsp|unsigned char *|Data received| |puiRspLen|unsigned int *|Length of Data received| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_Tag_Iso14443_TransparentMode ### Prototype `int Picc_Tag_Iso14443_TransparentMode(unsigned char *pucCmd, unsigned int uiCmdLen, unsigned char *pucResp);` ### Function * RF TAG card transparent transfer interface ### Parameter |Name|Type|description| |-|-|-| |pucCmd|unsigned char *|TAG command| |uiCmdLen|unsigned int|Length of TAG command| |pucResp|unsigned char *|TAG response| ### Retval |Value|Type|Description| |-|-|-| |>=0|int|success(Length of response)| |<0|int|fail| >i## Picc_Tag_Iso14443_PseudoAPDU ### Prototype `int Picc_Tag_Iso14443_PseudoAPDU(unsigned char *pucCapdu, unsigned int uiCapduLen, unsigned char *pucRapdu, unsigned char *pucSW);` ### Function * RF TAG card transparent transfer interface in APDU format ### Parameter |Name|Type|description| |-|-|-| |pucCapdu|unsigned char *|[in] pucCapdu: C-APDU: CLA: 0x90, INS: TagCmd, P1: Ignored, P2: Ignored, P3: Lc| |uiCapduLen|unsigned int|Length of C-APDU| |pucRapdu|unsigned char *|R-APDU| |pucSW|unsigned char *|Status-Word(2 bytes)| ### Retval |Value|Type|Description| |-|-|-| |>=0|int|success(Length of response)| |<0|int|fail| >i## Picc_M1_KeyAuth_With_SN_Rev ### Prototype `int Picc_M1_KeyAuth_With_SN_Rev(unsigned int keyType, unsigned int blockNo, unsigned int keyLen, unsigned char *pKey, int seriNoLen, unsigned char *pSeriNo); ;` ### Function * M1 Authication with SN checked ### Parameter |Name|Type|description| |-|-|-| |keyType|unsigned int|One of TAG_IDX_AUTH_KEYA and TAG_IDX_AUTH_KEYB| |blockNo|unsigned int|Block number to authenticate| |keyLen|unsigned int|Length of KEY| |pKey|unsigned char *|KEY for authenticate| |seriNoLen|int|Length of SN| |pSeriNo|unsigned char *|SN of M1| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_KeyAuthRev ### Prototype `int Picc_M1_KeyAuthRev(unsigned int keyType, unsigned int blockNo, unsigned int keyLen, unsigned char *pKey);` ### Function * M1 Authication ### Parameter |Name|Type|description| |-|-|-| |keyType|unsigned int|One of TAG_IDX_AUTH_KEYA and TAG_IDX_AUTH_KEYB| |blockNo|unsigned int|Block number to authenticate| |keyLen|unsigned int|Length of KEY| |pKey|unsigned char *|KEY for authenticate| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_ReadBlockRev ### Prototype `int Picc_M1_ReadBlockRev(unsigned int blockNo, unsigned char *pDataRead);` ### Function * Read a block data from M1 ### Parameter |Name|Type|description| |-|-|-| |blockNo|unsigned int|Block to read| |pDataRead|unsigned char *|Block data| ### Retval |Value|Type|Description| |-|-|-| |>=0|int|success, Length of Data(will be TAG_M1_BLOCK_LEN)| |<0|int|fail| >i## Picc_M1_ReadValueRev ### Prototype `int Picc_M1_ReadValueRev(unsigned int blkNo, int *piCents);` ### Function * Read value of M1 block ### Parameter |Name|Type|description| |-|-|-| |blkNo|unsigned int|Value block| |piCents|int *|Value(unit: cent)| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_WriteBlockRev ### Prototype `int Picc_M1_WriteBlockRev(unsigned int blkNo, unsigned int iDataWriteLen, unsigned char *pDataWrite);` ### Function * Write a block data to M1 ### Parameter |Name|Type|description| |-|-|-| |blkNo|unsigned int|Block to write| |iDataWriteLen|unsigned int|Length of data to write(Should be TAG_M1_BLOCK_LEN)| |pDataWrite|unsigned char *|Data to write| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_InitValueRev ### Prototype `int Picc_M1_InitValueRev(unsigned int blkNo, int iCents, unsigned char ucAdr);` ### Function * Initial a value to block ### Parameter |Name|Type|description| |-|-|-| |blkNo|unsigned int|Block to initial a value| |iCents|int|Value(unit: cent)| |ucAdr|unsigned char|A check byte of value block(Generally, it's the block number the value in)| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_IncrementRev ### Prototype `int Picc_M1_IncrementRev(unsigned int blkNoSrc, unsigned int blkNoDst, unsigned int uiCentsInc);` ### Function * Increase value to M1 ### Parameter |Name|Type|description| |-|-|-| |blkNoSrc|unsigned int|The source value block| |blkNoDst|unsigned int|The destination value block| |uiCentsInc|unsigned int|Cents to increase| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_DecrementRev ### Prototype `int Picc_M1_DecrementRev(unsigned int blkNoSrc, unsigned int blkNoDst, unsigned int uiCentsDec);` ### Function * Decrease value to M1 ### Parameter |Name|Type|description| |-|-|-| |blkNoSrc|unsigned int|The source value block| |blkNoDst|unsigned int|The destination value block| |uiCentsDec|unsigned int|Cents to decrease| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >i## Picc_M1_RestoreRev ### Prototype `int Picc_M1_RestoreRev(unsigned int blkNoSrc, unsigned int blkNoDst);` ### Function * Restore a value block ### Parameter |Name|Type|description| |-|-|-| |blkNoSrc|unsigned int|The source value block| |blkNoDst|unsigned int|The destination value block| ### Retval |Value|Type|Description| |-|-|-| |=0|int|success| |<0|int|fail| >s## Example ``` /** * @brief test M1 card * @param result [out] test result string * @param judge_style [out] result notice type,for example:BWUI_SMT_JUDGE_STYLE_PASS_ENTER */ void bwui_smt_test_mifare_classic_fun(char *result, char *judge_style) { char type; int iRet; unsigned int uiStrLen; int iBlkNoSrc; int iBlkNoDst; int iKeyLen; int iCents; unsigned char aucKey[6]; char acSN[24]; char acInfo[100]; char acValue[20]; T_SOFTTIMER tm; PiccInfo_T stPiccInfo; iRet = PiccOpen(); if(iRet != 0){ snprintf(result, MAX_RESULT_STR_LEN, "picc open fail"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; return ; } // Detect s_TimerSet(&tm, 5000); while (s_TimerCheck(&tm)) { iRet = PiccDetect('M', &stPiccInfo); if (iRet == 0) { break; } Sleep(100); } if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read card fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } type = stPiccInfo.ucPiccCardType; uiStrLen = (2*stPiccInfo.ucPiccSnLen + 1); BytesToHexString((const char*)stPiccInfo.aucPiccSN, stPiccInfo.ucPiccSnLen, acSN, &uiStrLen); uiStrLen = (2*stPiccInfo.ucPiccInfoLen + 1); BytesToHexString((const char*)stPiccInfo.aucPiccInfo, stPiccInfo.ucPiccInfoLen, acInfo, &uiStrLen); // Authenticate iBlkNoSrc = 0x04; iKeyLen = TAG_M1_KEY_LEN; memset(aucKey, 0xFF, iKeyLen); iRet = Picc_M1_KeyAuthRev(TAG_IDX_AUTH_KEYA, iBlkNoSrc, iKeyLen, aucKey); //LOGD("Picc_M1_KeyAuth, iRet=%d", iRet); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "auth pwd fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Init Value Blk=4 iBlkNoSrc = 0x04; // Write 12345.67 iRet = Picc_M1_InitValueRev(iBlkNoSrc, 1234567, iBlkNoSrc); //LOGD("Picc_M1_InitValue, iRet=%d, blk=%d ", iRet, iBlkNoSrc); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "init amount fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Read Value Blk=4 iBlkNoSrc = 0x04; iRet = Picc_M1_ReadValueRev(iBlkNoSrc, &iCents); //LOGD("Picc_M1_ReadValue, iRet=%d, blk=%d, iCents=%d ", iRet, iBlkNoSrc, iCents); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read amount fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Increment Blk= 4->5 iBlkNoSrc = 0x04; iBlkNoDst = 0x05; iRet = Picc_M1_IncrementRev(iBlkNoSrc, iBlkNoDst, 1); //LOGD("Picc_M1_Increment, iRet=%d, src=%d, dst=%d ", iRet, iBlkNoSrc, iBlkNoDst); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read data fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Read Value Blk=5 iBlkNoSrc = 0x05; iRet = Picc_M1_ReadValueRev(iBlkNoSrc, &iCents); //LOGD("Picc_M1_ReadValue, iRet=%d, blk=%d, iCents=%d ", iRet, iBlkNoSrc, iCents); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read amount fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Decrement Blk= 4->6 iBlkNoSrc = 0x04; iBlkNoDst = 0x06; iRet = Picc_M1_DecrementRev(iBlkNoSrc, iBlkNoDst, 1); //LOGD("Picc_M1_Decrement, iRet=%d, src=%d, dst=%d ", iRet, iBlkNoSrc, iBlkNoDst); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read data fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Read Value Blk=6 iBlkNoSrc = 0x06; iRet = Picc_M1_ReadValueRev(iBlkNoSrc, &iCents); //LOGD("Picc_M1_ReadValue, iRet=%d, blk=%d, iCents=%d ", iRet, iBlkNoSrc, iCents); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read amount fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Restore Blk= 4->4 iBlkNoSrc = 0x04; iBlkNoDst = 0x04; iRet = Picc_M1_RestoreRev(iBlkNoSrc, iBlkNoDst); //LOGD("Picc_M1_Restore, iRet=%d, src=%d, dst=%d ", iRet, iBlkNoSrc, iBlkNoDst); if (iRet != 0) { *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } // Read Value Blk=4 iBlkNoSrc = 0x04; iRet = Picc_M1_ReadValueRev(iBlkNoSrc, &iCents); //LOGD("Picc_M1_ReadValue, iRet=%d, blk=%d, iCents=%d ", iRet, iBlkNoSrc, iCents); if (iRet != 0) { snprintf(result, MAX_RESULT_STR_LEN, "read amount fail\n"); *judge_style = BWUI_SMT_JUDGE_STYLE_FAIL_ENTER; PiccClose(); return; } PiccClose(); sprintf(acValue, "%.2f", ((float)iCents)/100); iRet = 0; iRet = snprintf(result, MAX_RESULT_STR_LEN-iRet, "read card success\n"); iRet = snprintf(&result[iRet], MAX_RESULT_STR_LEN-iRet, "Type:%c, SN:%s\nInfo:%s\namount=%s\n", type, acSN, acInfo, acValue); *judge_style = BWUI_SMT_JUDGE_STYLE_PASS_ENTER; } ```