Buzz Access

Dependencies:   4DGL-uLCD-SE KeyPad PinDetect HID_Wiegand mbed-rtos mbed

main.cpp

Committer:
otis22894
Date:
2015-04-30
Revision:
1:c41a71a200d6
Parent:
0:0d31da041b5c
Child:
2:ec211fc4bdc2

File content as of revision 1:c41a71a200d6:

#include "mbed.h"
#include "KeyPad.h"
#include "rtos.h"
#include "uLCD_4DGL.h"
#include <iostream>
#include "PinDetect.h"
#include "Wiegand.h"
#include <string>
#include <sstream>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#define CARDSALLOWED 10

bool checkCode(std::vector<int>,std::vector<int>);
void keypad_thread(void const *args);
void knock_thread(void const *args);
void rfid_thread(void const *args);
void changeCode();
void changeSecretKnock();
void captureKnock();
void checkKnocks();
void onCardRead();
int readCardsFromFile(FILE *fp);
int readCardsFromFile();
bool isAllowed(const char *card);
void storeCard(const char *card);
void menuShiftUp();
void menuShiftDown();
void display();
void menuSelect();

Serial pc(USBTX, USBRX);
KeyPad2 keypad(p25, p27, p23, p26, p21, p22, p24);
static const int arr[] = {1,2,3,4};
std::vector<int> master(arr, arr + sizeof(arr) / sizeof(arr[0]) );
std::vector<int> keys;
std::vector<int> key;
std::vector<int> knock;
std::vector<int> userKnock;
static const std::string arr2[] = {"Lock Door","Unlock Door","Change Key Code","Change Knock","Add Card","Delete Card","This is wayyyyyyyyyyyyyyy too long"};
std::vector<string> menuOptions(arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]));
DigitalOut led2(LED2);
DigitalOut led1(LED1);
uLCD_4DGL lcd(p9, p10, p8); 
PinDetect menuUp(p13);
PinDetect select(p6);
PinDetect menuDown(p7);
Timer timer;
AnalogIn ain(p15);
Wiegand rfid(p30, p29, p28, &onCardRead);
char **allowedCards;
int allowedCount = 0;
bool changeCodeBool = false;
LocalFileSystem fileSystem("local");
int selected = 0;
int oldSelected = -1;

int main() {
    timer.start();
    Thread keypadThread(keypad_thread); 
    //Thread knockThread(knock_thread); 
    //Thread rfidThread(rfid_thread);
    lcd.baudrate(500000);
    menuUp.mode(PullUp);
    menuDown.mode(PullUp);
    select.mode(PullUp);
    Thread::wait(500);
    menuUp.attach_deasserted(&menuShiftUp);
    menuDown.attach_deasserted(&menuShiftDown);
    select.attach_deasserted(&menuSelect);
    menuUp.setSampleFrequency();
    menuDown.setSampleFrequency();
    select.setSampleFrequency();
    int count = 0;
    led1 = 0;
    while(1){
        if(count > 100){
            count = 0;
            led1 = !led1;
        }
        display();
        Thread::wait(1);
        count++;
    }
    
}

void display(){
    if(changeCodeBool){
        lcd.cls();
        lcd.locate(0,0);
        lcd.printf("%s","Enter New Code");
        lcd.locate(0,1);
        bool first = true;
        while(changeCodeBool){
            if(key.size()>0 && (!first && key.front()==0)){
                lcd.printf("%d ",key.front());
                Thread::wait(150);
                first = false; 
            }
        }
    }else if(oldSelected != selected){
        for(int i = 0;i<menuOptions.size();i++){
            lcd.locate(0,i);
            if(selected==i){
                lcd.textbackground_color(WHITE);
            }else{
                lcd.textbackground_color(BLACK);
            }
            if(menuOptions[i].size()>17){
                lcd.printf("%s",menuOptions[i].substr(0,18).c_str());
            }else{
                lcd.printf("%s",menuOptions[i].c_str() + std::string(18-menuOptions[i].size(),' '));
            }
        }
        oldSelected = selected;
    }
}

void menuSelect(){
    changeCodeBool = true;
}

void menuShiftUp(){
    selected = (selected + 1) % menuOptions.size();
}

void menuShiftDown(){
    selected--;
    if(selected == -1){
        selected = menuOptions.size() - 1;    
    }
}

void rfid_thread(void const *args){
    allowedCards = new char*[CARDSALLOWED]; 
    for (int i = 0; i < CARDSALLOWED; ++i){
        allowedCards[i] = new char[11];
    }
    readCardsFromFile();
    while(1){
        rfid.doEvents();
        Thread::wait(100);    
    } 
}

void onCardRead() {
   /*pc.printf("%d\n",rfid.bitsRead());
   uint64_t rawCardData = rfid.getBits(14,33);
   pc.printf("%" PRIx64 "\n",rawCardData);
   pc.printf("%" PRIx64 "\n",rfid.getBits(0,34));*/
   uint64_t cardData = rfid.getBits(0,34);
   ostringstream o;
   string str;
   o << cardData;
   str += o.str();
   storeCard(str.c_str());
}

bool isAllowed(const char *card){
    for(int i = 0;i<allowedCount;i++){
        for(int j = 0;j<11;j++){
            if(card[j]!=allowedCards[i][j]){
                break;
            }else if(j==10){
                return true;
            }
        }
    }    
    return false;
}

void storeCard(const char *card){
    if(allowedCount < 10 && !isAllowed(card)){
        FILE *fp = fopen("/local/cards.txt", "a");
        if(fp==NULL){
            //ERROR
        }
        fprintf(fp, "%c%c%c%c%c%c%c%c%c%c%c\r\n",card[0],card[1],card[2],card[3],card[4],card[5],card[6],card[7],card[8],card[9],card[10]);
        fclose(fp);
        for(int transfer = 0;transfer<11;transfer++){
            allowedCards[allowedCount][transfer] = card[transfer];
        }
        allowedCount++;
    }
}

int readCardsFromFile(){
    FILE *fp = fopen("/local/cards.txt", "r");
    int ret = readCardsFromFile(fp);
    return ret;
}

int readCardsFromFile(FILE *fp){
    int c,transfer = 0;
    if(fp!=NULL){
        c = fgetc(fp);
        while(c!=EOF){
            allowedCards[allowedCount][transfer] = c;
            transfer++;
            if(transfer==11){
                allowedCount++;
                if(allowedCount==CARDSALLOWED){
                    break;
                }
                transfer = 0;
                fgetc(fp);
                fgetc(fp);
            }
            c = fgetc(fp);
        }
        fclose(fp);
        return 1;
    }else{
        return 0;
    }
}

void knock_thread(void const *args){
    Thread::wait(1000);
    changeSecretKnock();
    float newval;
    while(1){
        newval = ain.read();
        if(newval > 0.508 && newval < 0.538){
            Thread::wait(50);
            captureKnock();
            checkKnocks();
        }
        Thread::wait(1);
    }  
}

void checkKnocks(){
    if(knock.size() != userKnock.size()){
        //DENIED
    }else{
        bool access = true;
        for(int i = 0; i<knock.size(); i++){
            if(!(abs(1-((float)knock[i])/((float)userKnock[i]))<0.15)){
                access = false;    
            }
        }
        if(access){
            //GRANTED
        }else{
            //GRANTED   
        }
    }
}

void captureKnock(){
    float val;
    userKnock.clear();
    timer.reset();
    int time;
    while(timer.read() < 2){
        val = ain.read();
        if(val > 0.508 && val < 0.538){
            time = timer.read_ms();
            userKnock.push_back(time);
            Thread::wait(50);
            timer.reset();
        }
        Thread::wait(1);
    }
}

void changeSecretKnock(){
    float val;
    Timer t;
    while(true){
        val = ain.read(); 
        if(val > 0.508 && val < 0.538){
            break;
        }
        Thread::wait(1);   
    }
    t.start();
    int time;
    while(t.read() < 2){
        val = ain.read();
        if(val > 0.508 && val < 0.538){
            time = t.read_ms();
            knock.push_back(time);
            Thread::wait(50);
            t.reset();
        }
        Thread::wait(1);
    }
}

bool checkCode(std::vector<int> master,std::vector<int> v1){
    if(v1.size() != master.size()){
        return false;
    }else{
        for(int i = 0;i<master.size();i++){
            if(master[i] != v1[i]){
                return false;
            }
        } 
        return true;   
    }
}

void changeCode(){
    std::vector<int> tempMaster;
    key.push_back(0);
    while(key.front() != 12){
        key = keypad.getkey();
        if(key.size()>0){
            tempMaster.push_back(key.front());
        }
        Thread::wait(100); 
    }
    tempMaster.pop_back();
    if(tempMaster.size() >= 4){
        master.clear();
        for(int i = 0;i<tempMaster.size();i++){
            master.push_back(tempMaster[i]);
        }
    }else{   
    }
    changeCodeBool = false;
    oldSelected = -1;
}

void keypad_thread(void const *args){
    std::vector<int> key;
    key.push_back(0);
    while(1) {
        while(key.front() != 12){
            if(changeCodeBool){
                changeCode();
            }
            key = keypad.getkey();
            if(key.size()>0){
                keys.push_back(key.front());
            }
            Thread::wait(100);
        }  
        keys.pop_back();
        bool result = checkCode(master,keys);
        int size = keys.size();
        for(int i = 0;i<size;i++){
            keys.erase(keys.begin());   
        }
        keys.clear();
        key.clear();
        key.push_back(0);
        Thread::wait(100);
    }
}