miguel747 icon

Secret-KnockLock.h

miguel747 | PRO | 12/16/13 06:42:04 PM UTC | 0 ⭐ | 195 👁️ | Never ⏰ | []
C |

4.03 KB

|

None

|

0 👍

/

0 👎

/*
 * secret_knock_lib.c
 *
 *  Created on: 03/12/2013
 *      Author: Filipe Ribeiro
 */
 
#include "secret_knock_lib.h"
 
unsigned char recordMode;
unsigned char stupidUser;
unsigned long int elapseTime;
unsigned long int knockBuffer[KNOCK_MAX_SEQ];
unsigned long int passwordBuffer[KNOCK_MAX_SEQ];
unsigned char passwordLength;
unsigned char knockIndex;
 
/*
 *  portInit
 *
 *  Initialize ports
 *
 */
 
void portInit(void)
{
    //  Port 1
    P1DIR = PORT1_DIR;
    P1REN = PUSH_BUTTON;
    P1OUT = PUSH_BUTTON;
    P1IE = PUSH_BUTTON + PIEZO_PIN;
    P1IES = PUSH_BUTTON;
    P1IFG = 0x00;
 
    //  Port 2
    P2DIR = PORT2_DIR;
}
 
/*
 *  timerAInit
 *
 *  Initialize timer to work in up mode with SMCLK clock source
 *
 */
 
void timerAInit(unsigned char timerAMask)
{
 
    if(timerAMask & TIMER_A_0)
    {
        TA0CCR0 = 1000;
        TA0CTL = TASSEL_2+MC_1;
    }
 
    if(timerAMask & TIMER_A_1)
    {
        TA1CCTL0 = CCIE;
        TA1CCR0 = 1000;
        TA1CTL = TASSEL_2+MC_1;
    }
}
 
/*
 *  knockReset
 *
 *  Reset knockIndex and clear knockBuffer.
 *
 */
 
void knockReset(void){
 
    unsigned char i;
 
    knockIndex = 0;
 
    for(i=0;i<KNOCK_MAX_SEQ;i++)
        knockBuffer[i]=0;
}
 
/*
 *  knockNormalize
 *
 *  In order to compare sequences with different frequencies all sequences
 *  are normalized before storing new passwords and comparing to the existing
 *  one.
 *
 *  Normalization is done by dividing all intervals by the highest-valued one.
 *  Then, all values are multiplied by a standard constant so calculations
 *  can be performed only using integers.
 *
 */
 
void knockNormalize(void)
{
    unsigned char i;
    unsigned long int maxInterval = 0;
 
    //  Find maximum interval
    for(i=1;i<knockIndex;i++)
        if(knockBuffer[i]>maxInterval)
            maxInterval=knockBuffer[i];
    if(maxInterval == 0)
        return ;
    //  Normalize intervals and record secret knock
    for(i=1;i<knockIndex;i++){
        knockBuffer[i-1] = knockBuffer[i]*KNOCK_NORM_INTERVAL;
        knockBuffer[i-1] /= maxInterval;
    }
    knockIndex--;
}
 
/*
 *  passwordRecord
 *
 *  Store the normalized sequence in the password vector
 *
 */
 
void passwordRecord(void)
{
    unsigned char i;
    knockNormalize();
    for(i=0;i<knockIndex;i++)
        passwordBuffer[i] = knockBuffer[i];
    passwordLength = knockIndex;
}
 
/*
 *  passwordCheck
 *
 *  Verify if the sequence tried is the password
 *  Both sequence and password are already normalized, so two types of
 *  inaccuracy are verified:
 *      1 knockError: The difference between each knock of the sequence and the
 *      corresponding knock in the password. Errors cannot exceed the threshold
 *      (KNOCK_TOLERANCE).
 *      2 totalError: The sum of all knock errors. totalError cannot exceed the
 *      threshold (TOTAL_TOLERANCE).
 *
 */
 
unsigned char passwordCheck(void)
{
    unsigned char i;
    unsigned long int knockError;
    unsigned int totalError;
    int t;
 
    knockNormalize();
 
    if(knockIndex != passwordLength)
        return KNOCK_NOT_OK;
 
    totalError = 0;
 
    //  Validate knock
    for(i=0;i<passwordLength;i++)
    {
        if(knockBuffer[i] > passwordBuffer[i])
            knockError = knockBuffer[i]-passwordBuffer[i];
        else
            knockError = passwordBuffer[i] - knockBuffer[i];
 
        if(knockError> KNOCK_TOLERANCE)
            return KNOCK_NOT_OK;
 
        totalError += knockError;
    }
 
    //  In case this if statement is ignored alter the optimization configurations: project -> properties -> build -> msp430 compiler -> optimization -> optimization level = 1
    if(totalError > TOTAL_TOLERANCE)
        return KNOCK_NOT_OK;
 
    return KNOCK_OK;
}
 
/*
 *  knockInit
 *
 *  Reset all program flags and password buffer
 *  Initialize ports and timer
 *
 */
 
void knockInit(void)
{
    unsigned char i;
    //  Reset record mode
    recordMode = RECORD_MODE_OFF;
    //  Reset elapse time counter
    elapseTime = 0;
    //  Set index to beginning of the buffer
    knockIndex = 0;
    //  Reset blocking flag
    stupidUser = 0;
    //  Reset knock code
    for(i=0;i<KNOCK_MAX_SEQ;i++)
        passwordBuffer[i] = 1;
    //  Reset knock code length
    passwordLength = KNOCK_MAX_SEQ;
 
    portInit();
    timerAInit(TIMER_A_1);
}

Comments