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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
pwheels
Date:
Wed Feb 09 07:44:59 2011 +0000
Commit message:
initial release

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r c9e183da8303 main.cpp
--- /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" );
+}
diff -r 000000000000 -r c9e183da8303 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Feb 09 07:44:59 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e