diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | kbc.c | 98 |
2 files changed, 97 insertions, 5 deletions
@@ -10,2 +10,6 @@ DPIN=-DPIN=\"$(PIN)\" endif + +ifdef MASTER_PIN +DPIN+=-DMASTER_PIN=\"$(MASTER_PIN)\" +endif ACFLAGS=-g -mmcu=$(MCU) $(CFLAGS) $(DPIN) -Os -mcall-prologues @@ -14,2 +14,6 @@ +#ifndef MASTER_PIN +#error need to define a MASTER_PIN +#endif + /* port B RJ45 @@ -56,2 +60,4 @@ enum state { STATE_IDLEBLINK, + STATE_PASSWORD, + STATE_PASSWORD2, STATE_INPUT, @@ -343,2 +349,3 @@ static uint8_t wait_byte(void) #define CNTR_BEEP 10 +#define CNTR_BEEP_ACK 30 #define CNTR_BEEP_REJ 92 @@ -359,4 +366,6 @@ static uint8_t error; -static const EEMEM uint8_t passwd[sizeof(PIN) - 1] = PIN; +static EEMEM uint8_t passwd[sizeof(PIN) - 1] = PIN; +static EEMEM uint8_t mpasswd[sizeof(MASTER_PIN) - 1] = MASTER_PIN; static uint8_t code[sizeof(PIN)]; +static uint8_t new_code[sizeof(PIN)]; @@ -440,2 +449,11 @@ static void state_enter(void) break; + case STATE_PASSWORD: + case STATE_PASSWORD2: + toutstate = STATE_IDLE; + statecntr = WAIT_INPUT; + if (send_byte(0xed) != 0xfa) + break; + if (send_byte(KBLED_STATE | KBLED_OK) != 0xfa) + break; + break; case STATE_ACCEPT: @@ -534,2 +552,3 @@ const PROGMEM uint8_t kbc[] = { #define NUMPAD_ENTER 0xda /* e0 5a */ +#define F12 0x07 @@ -539,3 +558,3 @@ static void handle_keypress(uint8_t data) { - uint8_t unlock, lock; + uint8_t unlock, lock, change_pass; uint8_t ascii = '_'; @@ -575,4 +594,62 @@ static void handle_keypress(uint8_t data) - lock = ascii == ESC; - unlock = ascii == ENT || data == NUMPAD_ENTER; + if (state != STATE_PASSWORD && state != STATE_PASSWORD2) { + lock = ascii == ESC; + unlock = ascii == ENT || data == NUMPAD_ENTER; + change_pass = data == F12; + } else { + lock = unlock = 0; + change_pass = ascii == ENT || data == NUMPAD_ENTER; + } + + if (change_pass) { + uint8_t pos, ok = 1; + switch(state) { + default: + /* Check master password, change state to password input */ + if (code[0]) + ok = 0; + + for (pos = 1; pos < sizeof(code); pos++) + if(code[pos] != eeprom_read_byte(mpasswd + pos - 1)) + ok = 0; + + if (ok) { + cntr = CNTR_BEEP_ACK; + nextstate = STATE_PASSWORD; + } + break; + case STATE_PASSWORD: + /* Check password and store it to buffer */ + if (code[0]) + ok = 0; + + if (ok) { + memcpy(new_code, code, sizeof(code)); + PORTB &= ~B_BEEP; + cntr = CNTR_BEEP_ACK; + nextstate = STATE_PASSWORD2; + } + break; + case STATE_PASSWORD2: + /* Compare password with buffer, write to eeprom */ + if (memcmp(new_code, code, sizeof(code))) + ok = 0; + if (ok) { + eeprom_update_block(new_code + 1, passwd, + sizeof(new_code) - 1); + PORTB &= ~B_BEEP; + cntr = CNTR_BEEP_REJ; + nextstate = STATE_ACCEPT; + } + break; + } + if (!ok) { + PORTB &= ~B_BEEP; + + cntr = CNTR_BEEP_REJ; + nextstate = STATE_REJECT; + } + memset(code, 0, sizeof(code)); + return; + } @@ -624,3 +701,12 @@ static void handle_keypress(uint8_t data) cntr = CNTR_BEEP; - nextstate = STATE_INPUT; + switch (state) { + case STATE_PASSWORD: + nextstate = STATE_PASSWORD; + break; + case STATE_PASSWORD2: + nextstate = STATE_PASSWORD2; + break; + default: + nextstate = STATE_INPUT; + } } @@ -642,2 +728,4 @@ ISR(USART_RX_vect) case STATE_IDLEBLINK: + case STATE_PASSWORD: + case STATE_PASSWORD2: case STATE_INPUT: |
