/*
* 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