rfid lock build to interface with mf7 rfid reader using white / black list

Dependencies:   mbed

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" );
+}