![](/media/cache/profiles/a7bf3f5462cc82062e41b3a2262e1a21.50x50_q85.jpg)
rfid lock build to interface with mf7 rfid reader using white / black list
main.cpp
- Committer:
- pwheels
- Date:
- 2011-02-09
- Revision:
- 0:c9e183da8303
File content as of revision 0:c9e183da8303:
/* * 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" ); }