![](/media/cache/profiles/a7bf3f5462cc82062e41b3a2262e1a21.50x50_q85.jpg)
rfid lock build to interface with mf7 rfid reader using white / black list
Diff: main.cpp
- Revision:
- 0:c9e183da8303
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Feb 09 07:44:59 2011 +0000 @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2011 Paul van der Wielen, Pro-Serv + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to use + * and implement the software for none commercial reason and usage only and + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Usage and assumptions: + * a RFID reader Model MF7(1.05) is configured in ascii mode and attached to p10 via + * a level converter (rs232 at ttl level to 3.3V), which also inverses the signal + * The imbedded local drive holds a white list and black list file in csv format. + * Operation signalling is available via default LED 1-4 being: + * LED1 - access granted, LED2 - access denied, LED3 - door unlocked, LED4 - file reading + * + * the white list master card should be at white[0], being first entry in white list csv file + * while the black list master card should be at white[1], being second entry in white list csv + * file, mind these two card DON'T provide access and/or door unlocking operations + * + * Used device = LPC1768, basic logging is availabe as needed on the serial to usb port via + * terminal emulator like Tera, extend logging or debugging data is available by uncomment + * the #define DEBUG statement + */ + +#include "mbed.h" +#include <string.h> + +//#define DEBUG + +Serial pc(USBTX, USBRX); // tx, rx +Serial device(p9, p10); // tx, rx +LocalFileSystem local("local"); + +const char *wl = "/local/list_wht.csv"; +const char *bl = "/local/list_blk.csv"; + +const char *ver = "V1.1"; + +/* + * In order to assure proper white & black list operation we assume to + * have the master card for white & black list to be at index 0 and 1 resp. + */ +unsigned long white[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0 + }; + +unsigned long black[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + +unsigned int hex2int(char a); +bool rfid_match_wl( unsigned long b); +bool rfid_match_bl( unsigned long b); +int add_card(const char *ft, char *xx); +int get_list(const char *ft, unsigned long *xx); + +void memdump( char *p, int n ); + +char rfid[10]; +char buffer[32]; + +unsigned char tmp; +int cnt = 0; +int pnt = 0; +int mst = 0; // usage format abxxxxxn where a = white, b = black operation, n indicates second step + +DigitalOut myled1(LED1); +DigitalOut myled2(LED2); +DigitalOut myled3(LED3); +DigitalOut myled4(LED4); + +int main() { + +#ifdef DEBUG + char mem[ 1024 ]; // memory, it should be aligned to word boundary +#endif + + float release = 7.0; + unsigned long val = 0; + + printf( "\r\nRFID Lock System, version: %s\r\n", ver); + printf( " CPU running %dkHz\r\n", SystemCoreClock / 1000 ); + + cnt = get_list(wl, white); +#ifdef DEBUG + memcpy(&mem, &white, 1024); + + printf( "Showing `White List` content ...\r\n" ); + memdump( mem, 256 * 4 ); +#endif + printf( "Started with %d known RFID 'White list' cards\r\n\n", cnt); + + cnt = get_list(bl, black); +#ifdef DEBUG + memcpy(&mem, &black, 256); + + printf( "Showing `Black List` content ...\r\n" ); + memdump( mem, 256 * 1 ); +#endif + printf( "Started with %d known RFID 'Black list' cards\r\n\n", cnt); + + while (1) { + if (device.readable()) { + tmp = device.getc(); + switch (tmp) { + case 0x02: + cnt = 0; + val = 0; + break; + case 0x03: + rfid[cnt++] = 0x00; + val = strtoul(rfid, 0, 16); +#ifdef DEBUG + pc.printf("%s %u", rfid, val ); // define for debug mode +#endif + pc.printf("%s", rfid ); + if ((rfid_match_wl(val)) && !(rfid_match_bl(val)) && (mst == 0x00)) { + // green led - access provided + myled1 = 1; + // activate lock for 'release' time duration + myled3 = 1; + // we will need to add a defenition for DigitalOut here + wait(0.25); + myled1 = 0; + wait(release-0.25); + myled3 = 0; + // we will need to add a defenition for DigitalOut here + pc.printf(" -> Granted\r\n" ); + } else { + if (mst == 0x81) { + // master mode, add new card to white list + white[cnt++] = val; + mst = 0; + pc.printf(" -> Card added\r\n" ); + if (add_card(wl, rfid) != 0) { + pc.printf("%s -> WL Add Failed\r\n", rfid ); + } + } else if (mst == 0x41) { + // master mode, add new card to white list + black[cnt++] = val; + mst = 0; + pc.printf(" -> Card Removed\r\n" ); + if (add_card(bl, rfid) != 0) { + pc.printf("%s -> BL Remove Failed\r\n", rfid ); + } + } else { + // red led - no access + myled2 = 1; + wait(0.25); + myled2 = 0; + if (mst == 0x80) { + pc.printf(" -> White List Mode!\r\n"); + } else if (mst == 0x40) { + pc.printf(" -> Black List Mode!\r\n"); + } else { + pc.printf(" -> Denied !\r\n" ); + } + } + } + break; + case 0x0a: + case 0x0d: + break; + default: + // data from MF7 (ascii mode) is in `litle endian` format, so need + // to swap groups but, we will store rfid card as a value + // char array addressing = [group + count - count offset] + switch (cnt) { + case 0x00: + case 0x01: + rfid[6 + cnt] = tmp; + break; + case 0x02: + case 0x03: + rfid[4 + cnt - 2] = tmp; + break; + case 0x04: + case 0x05: + rfid[2 + cnt - 4] = tmp; + break; + case 0x06: + case 0x07: + rfid[0 + cnt - 6] = tmp; + break; + } + cnt++; + } + } + } +} +/* + * All used functions are listed below + * + * function to add a card to selected list (black or white) + */ +int add_card(const char *ft, char *xx) { + + FILE *fp; + + if ((fp = fopen(ft, "a")) == NULL) { + fprintf(stderr, "File %s could not be opened!\r\n", ft); + return -1; + } + fprintf(fp,"%s\r\n", xx); + fclose(fp); + return 0; +} + +/* + * function to read initial content for selected list (black or white) + */ +int get_list(const char *ft, unsigned long *xx) { + + FILE *fp; + + if ((fp = fopen(ft, "r")) == NULL) { + fprintf(stderr, "File %s could not be opened!\r\n", ft); + return 0; + } else { + cnt = pnt = 0; + printf("Reading Data File...\r\n"); + // reading file content + while ((tmp = getc(fp)) != 0xff) { + switch (tmp) { + case 0x0d: + myled4 = 1; + rfid[pnt++] = 0x00; + xx[cnt++] = strtoul(rfid, 0, 16); +#ifdef DEBUG + printf( " %s !\r\n", rfid); // define for debug mode +#endif + pnt = 0; + myled4 = 0; + break; + case 0x0a: + break; + default: + rfid[pnt++] = tmp; + break; + } + } + printf("Closing Data File...\r\n"); + fclose(fp); + } + return cnt; +} + +/* + * function to match current card against selected white list + */ +bool rfid_match_wl( unsigned long myval) { + int i; + + if (( mst == 0x80 ) || ( mst == 0x40 )) { + mst++; + } + for (i = 0; i < sizeof(white)/sizeof(white[0]); i++) { + if (white[i] == myval) { + // if master card (being first in list) is presented twice ! -> add new card + if (( i == 0 ) && (mst == 0)) { + mst = 0x80; + } else if (( i == 1 ) && (mst == 0)) { + mst = 0x40; + } else { + ; + } +#ifdef DEBUG + pc.printf("%u %u\r\n", white[i], i); // define for debug mode +#endif + return true; + } + } + return false; +} + +/* + * function to match current card against selected black list + */ +bool rfid_match_bl( unsigned long myval) { + int i; + + for (i = 0; i < sizeof(black)/sizeof(black[0]); i++) { + if (black[i] == myval) { + return true; + } + } + return false; +} + +/* + * function to convert single character value it's decimal value + */ +unsigned int hex2int(char a) { + unsigned int val = 0; + + if ((int)a <= 57) + val = ((int)a-48); + else + val = ((int)a-55); + return val; +} + +/* + * function to dump specific memory block + */ +void memdump( char *base, int n ) { + unsigned int *p; + + printf( " memdump from 0x%08X for %d bytes", (unsigned long)base, n ); + + p = (unsigned int *)((unsigned int)base & ~(unsigned int)0x3); + + for ( int i = 0; i < (n >> 2); i++, p++ ) { + if ( !(i % 4) ) + printf( "\r\n 0x%08X :", (unsigned int)p ); + + printf( " 0x%08X", *p ); + } + + printf( "\r\n" ); +}