In my previous post I detailed the basics for communicating with the MFRC522 and PN532 RFID modules to read/write data from Mifare Classic 1k tags. In this post I take it one step further and show how to use those modules to create an electronic wallet out of the tags. As with the previous post, this is presented as a basic implementation but should provide a foundation for a variety of applications that require increment/decrement or tallying functions.
Step 1: Data Integrity
For an electronic wallet there is always a concern that someone may add credits without paying for them. There is also a concern that the credits on the tag may get inadvertently corrupted during a data write. Data accesses require use of the tag key so it is necessary to change the default key when the tag is first initialized. There are articles online that talk about how to hack a tag even if you don’t know the key but the technique is not trivial. I wouldn’t recommend using these tags for your bank account but they are good enough for lots of less risky applications.
The probability of data corruption is relatively small but the software should be able to at least handle the basic case. This process involves two steps with the first step to simply detect the corruption. In this project that is handled by storing both the credit value as well as a 1’s complement of the credit value. That allows for a simple comparison of the values. The second step is to store a backup version of both the credit value and its complement. That allows for a recovery operation if the first set of credits gets corrupted. If both sets are corrupted then the software attempts to reinitialize the tag which results in a loss of all credits.
Step 2: Hardware
The hardware connections are shown in the diagram above. This is the same setup as the previous post with the addition of two switches and a pull-up resistor. One switch doesn’t require a pull-up resistor because it’s on a PIC input that has a weak pull-up capability built in. In practice both switches would be hidden because they are used for adding credits and for initializing a tag. The initialize switch is optional (to do manual credit zeroing) because the software can detect and initialize a new tag on its own. Jumper pins could be used instead of switches.
Step 3: Software
Additions to the main loop in the software were made to allow for reading of the two switches and for detection of a condition requiring tag initialization. As mentioned in the hardware section, tag initialization can be manually commanded with a switch. The software can also command a tag initialization in two other cases. First, if it detects a new tag or data sector and second, if both sets of credit data are corrupted.
Authentication of tags requires use of “key A” for the target data sector. The default key for the Mifare Classic 1k tags is “FF FF FF FF FF FF” but should be changed for your application. The software provides defines for both the default key and a new key (“My_Key”). Just plug in whatever values you want into “My_Key”. The software always attempts to first authenticate the tag using “My_Key”. If that fails, then the routine to initialize the tag is called and the default key is used for authentication. The initialization routine changes the key to “My_Key” and sets the credits to zero. If you have a tag with a non-default key and you don’t know what it is, then the tag can’t be authenticated. If this happens you might want to check other data sectors using the default key to see if one is available. The Trailer block, Data block, and Backup blocks are all defined at the beginning of the software listing so you can easily change them.
The format for data stored in the tag for this application uses only positive numbers (no deficits allowed) and values are stored as four bytes of packed BCD (Binary Coded Decimal). That allows for a credit range from 0 to 99,999,999 (two digits per byte). The credit value and its 1’s complement only use 8 of the 16 bytes in a single data block and the rest are padded with zeros. There is room in the same data block for the backup copy but I decided that it would be safer to put the backup in a separate data block. The backup block is in the same sector as the data block so a separate authentication is not required. To be even safer you might consider putting the backup in a different data sector but then a separate authentication step would be needed to access that data.
When a read is done of the credits the complemented value is also read and then the two are compared against each other. If there is a mismatch, then the backup set of value/complement is read and compared. If they match then the backup is assumed to be correct and is used to repair the corrupted data. If the backup copies don’t match then the tag is deemed to be bad and an attempt is made to re-initialize it.
The increment and decrement values are defined near the front of the listing and are expected to be in packed BCD. The routines that do the incrementing and decrementing effectively do so on a 32-bit number. The math is very simple but requires the use of routines to adjust the results for carries within each packed BCD byte and from one byte to the next. That is accomplished by the use of macros DAA (Decimal Adjust Addition) and DAS (Decimal Adjust Subtraction). These macros make sure that each 4-bit BCD digit always stays within the range of 0-9.
In addition to the display messages in the previous post, this application has messages for many of the additional steps - particularly if there are data errors and/or the tag needs to be fixed or initialized. The credits are also displayed before and after an increment/decrement step so that you can see the values change.
That’s it for this post. Check out my other electronics projects at: www.boomerrules.wordpress.com