Henry Lovett
/
MifareRFIDReaderWriter
Basic Read and Writer implementation for an OEM Mifare RWD Device.
Embed:
(wiki syntax)
Show/hide line numbers
RWDMifare.cpp
00001 /* 00002 Copyright (c) 2010 ARM Limited 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 #include "RWDMifare.h" 00024 00025 RWDMifare::RWDMifare(PinName tx, PinName rx, PinName cts) : RWDModule(tx, rx, cts) 00026 { 00027 00028 } 00029 00030 00031 RWDMifare::~RWDMifare() 00032 { 00033 00034 } 00035 RWDMifare::RWDMifareErr RWDMifare::init() 00036 { 00037 const uint8_t config[] = {0x03, 0x00}; //Configure ready for Mifare Op (0x00 to addr 0x03 in EEPROM) 00038 uint8_t resp[64] = {0}; 00039 //Cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf 00040 //Command 'P': cf p11 00041 //EEPROM parameters: cf p12 00042 //Ack check: cf p13 00043 command(CMD_Prog_EEPROM, config, 2, resp, 0, 0x80, 0x89); //Program EEPROM command is 0x50 ('P') 00044 while(!ready()) { //Wait for a response 00045 00046 } 00047 00048 if(!result()) { //If this fails, there is something wrong with the hardware 00049 return MIFARE_HW; 00050 } 00051 00052 return MIFARE_OK; 00053 } 00054 RWDMifare::RWDMifareErr RWDMifare::Prog_EEPROM(uint8_t Address, uint8_t Value) 00055 { 00056 const uint8_t config[] = {Address, Value}; //Configure ready for Mifare Op (0x00 to addr 0x03 in EEPROM) 00057 uint8_t resp[64] = {0}; 00058 //Cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf 00059 //Command 'P': cf p11 00060 //EEPROM parameters: cf p12 00061 //Ack check: cf p13 00062 command(CMD_Prog_EEPROM, config, 2, resp, 0, 0x80, 0x81); //Program EEPROM command is 0x50 ('P') 00063 while(!ready()) { //Wait for a response 00064 00065 } 00066 00067 if(!result()) { //If this fails, there is something wrong with the hardware 00068 return MIFARE_HW; 00069 } 00070 00071 return MIFARE_OK; 00072 00073 } 00074 RWDMifare::RWDMifareErr RWDMifare::printStatus(uint8_t Status) 00075 { 00076 printf("\n\rEEPROM Error\t= %d", (Status & Ack_Code_EEPROM_ERR)); 00077 printf("\n\rCard Okay \t= %d", (Status & Ack_Code_Card_OK)>>1); 00078 printf("\n\rRX Okay \t= %d", (Status & Ack_Code_RX_OK)>>2); 00079 printf("\n\rRS232 Error \t= %d", (Status & Ack_Code_RS232_ERR)>>3); 00080 printf("\n\rMF Type \t= %d", (Status & Ack_Code_MF_Type)>>4); 00081 printf("\n\rUL Type \t= %d", (Status & Ack_Code_UL_Type)>>5); 00082 printf("\n\rMFRC Error \t= %d", (Status & Ack_Code_MRRFC_Err)>>6); 00083 return MIFARE_OK; 00084 } 00085 RWDMifare::RWDMifareErr RWDMifare::getStatus(uint8_t* Status) 00086 { 00087 //Gets the status code of the Mifare 00088 command(CMD_Get_Status, NULL, 0, Status, 1, 0x86,0x86); 00089 printf("\n\rStatus 0x%02x", *Status); 00090 00091 return MIFARE_OK; 00092 } 00093 RWDMifare::RWDMifareErr RWDMifare::getUID(uint8_t* pUID, size_t* pLen) //pUID must be at least 10-bytes long 00094 //(A Mifare UID can either be 4, 7, or 10 bytes long) 00095 //This reader does not support 10 bytes uids 00096 { 00097 //Cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf 00098 //Command 'U': cf p19 00099 //Ack check: cf p13 00100 command(CMD_Get_UID, NULL, 0, pUID, 7, 0x86, 0x86); //UID command is 0x55 ('U') 00101 while(!ready()) { //Wait for a response 00102 00103 } 00104 00105 if(!result()) { //Error detected, there is no card in field 00106 return MIFARE_NOCARD; 00107 } 00108 00109 //printf("Got card.\n\r"); 00110 00111 //Checks UID length returned by reader 00112 int i; 00113 for(i = 0; i < 7; i++) { 00114 if(pUID[i] == 0) //End of UID, cf http://www.ibtechnology.co.uk/pdf/MF_ICprot.pdf p19 00115 break; 00116 } 00117 *pLen = i; 00118 00119 return MIFARE_OK; 00120 } 00121 00122 RWDMifare::RWDMifareErr RWDMifare::StoreKey(uint8_t KeyNumber, uint8_t* Key) 00123 { 00124 uint8_t cmd[7] = {0}; 00125 //command[0] = CMD_Store_Key; 00126 cmd[0] = KeyNumber & 31; //mask it. 00127 for(int i = 0; i < 6; i++) 00128 { 00129 cmd[i+1] = Key[i]; 00130 } 00131 /* printf("Command:\n"); 00132 for(int i = 0; i < 8; i ++){ 00133 printf("0x%02x ", command[i]); 00134 }*/ 00135 command(CMD_Store_Key, cmd, 7, NULL, 0, 0x80, 0x89); 00136 while(!ready()) { //Wait for a response 00137 00138 } 00139 00140 if(!result()) { //Error detected, there is no card in field 00141 return MIFARE_NOCARD; 00142 } 00143 00144 return MIFARE_OK; 00145 } 00146 RWDMifare::RWDMifareErr RWDMifare::AuthAllCards() 00147 { 00148 if (Prog_EEPROM(0x0C, 0xFF)) 00149 return MIFARE_HW; 00150 if (Prog_EEPROM(0x0C, 0xFF)) 00151 return MIFARE_HW; 00152 if (Prog_EEPROM(0x0C, 0xFF)) 00153 return MIFARE_HW; 00154 if (Prog_EEPROM(0x0C, 0xFF)) 00155 return MIFARE_HW; 00156 return MIFARE_OK; 00157 } 00158 00159 RWDMifare::RWDMifareErr RWDMifare::ReadBlock(uint8_t Addr, uint8_t KeyNumber_Type, uint8_t* Data) 00160 { 00161 uint8_t cmd[2] = {Addr, KeyNumber_Type}; 00162 command(CMD_Read_Block, cmd, 2, Data, 16, 0x96, 0xFE); 00163 while(!ready()) { //Wait for a response 00164 00165 } 00166 00167 if(!result()) { //Error detected, there is no card in field 00168 return MIFARE_NOCARD; 00169 } 00170 00171 return MIFARE_OK; 00172 00173 } 00174 RWDMifare::RWDMifareErr RWDMifare::ReadBlock(uint8_t Addr, uint8_t KeyNumber, uint8_t Type, uint8_t* Data) 00175 { 00176 KeyNumber &= 0x1F; 00177 if(Type) 00178 KeyNumber |= 0x80; 00179 return ReadBlock(Addr, KeyNumber, Data); 00180 00181 } 00182 RWDMifare::RWDMifareErr RWDMifare::WriteBlock(uint8_t Addr, uint8_t KeyNumber, uint8_t Type, uint8_t* Data) 00183 { 00184 //CARE MUST BE TAKEN WHEN WRITING TO A SECTION TRAILER. 00185 //THIS METHOD WILL NOT WRITE TO A SECTION TRAILER, ONLY USER DATA 00186 if(Addr < 32) 00187 { 00188 if ((Addr & 0x3) == 0x3) // section trailer occurs on blocks 3, 7, 11, 15 . . . 00189 return MIFARE_TRAIL; 00190 } 00191 else //only applicable for 4k cards 00192 { 00193 if ((Addr & 0xF) == 0xF) //for sectors 32 - 39, trailer occurs in block 15. 00194 return MIFARE_TRAIL; 00195 } 00196 00197 //get here, writing to a user field. 00198 KeyNumber &= 0x1F; 00199 if(Type) 00200 KeyNumber |= 0x80; 00201 00202 uint8_t cmd[18]; 00203 cmd[0] = Addr; 00204 cmd[1] = KeyNumber; 00205 for(int i = 0; i < 16; i ++) 00206 { 00207 cmd[i+2] = Data[i]; 00208 } 00209 printf("Command to write:\n"); 00210 for(int i = 0; i < 18;i++){ 00211 printf("0x%02x ", cmd[i]); 00212 } 00213 printf("\r\n"); 00214 command(CMD_Write_Block, cmd, 18, NULL, 0, 0x96, 0xFE); 00215 while(!ready()) { //Wait for a response 00216 00217 } 00218 00219 if(!result()) { //Error detected, there is no card in field 00220 return MIFARE_NOCARD; 00221 } 00222 return MIFARE_OK; 00223 }
Generated on Wed Jul 13 2022 03:38:17 by 1.7.2