From 12db87b9c2b267fe696cc076e4409e450e9111a3 Mon Sep 17 00:00:00 2001
From: Philipp Claves <pclaves@web.de>
Date: Sun, 6 Nov 2011 00:39:01 +0100
Subject: [PATCH] Control: Add logging and date commands. Add invalid login
 delay support.

---
 Control/shell/readline.c |  2 +-
 Control/shell/readline.h |  3 +-
 Control/shell/shell.c    | 99 ++++++++++++++++++++++++++++++++++++----
 Control/shell/shell.h    |  4 ++
 4 files changed, 97 insertions(+), 11 deletions(-)

diff --git a/Control/shell/readline.c b/Control/shell/readline.c
index 9222554..cd67954 100644
--- a/Control/shell/readline.c
+++ b/Control/shell/readline.c
@@ -31,7 +31,7 @@ void readline_show_welcome_prompt(void){
 }
 
 void readline_write_prompt(void){
-	printf(readline_prompt);
+	if (readline_prompt) printf(readline_prompt);
 }
 
 void readline_set_mode(char* prompt, uint8_t echo, uint8_t parse){
diff --git a/Control/shell/readline.h b/Control/shell/readline.h
index 1626efd..ea75d22 100644
--- a/Control/shell/readline.h
+++ b/Control/shell/readline.h
@@ -31,4 +31,5 @@ void readline_handle_buffer(char* input_buffer);
 void readline_init(void);
 void readline_show_welcome_prompt(void);
 void readline_set_mode(char* prompt, uint8_t echo, uint8_t parse);
-void readline_process(void);
\ No newline at end of file
+void readline_process(void);
+void readline_write_prompt(void);
\ No newline at end of file
diff --git a/Control/shell/shell.c b/Control/shell/shell.c
index 604f60a..ca78d02 100644
--- a/Control/shell/shell.c
+++ b/Control/shell/shell.c
@@ -1,4 +1,7 @@
 #include "shell.h"
+#include "../ds1307.h"
+#include "../log.h"
+#include "../door.h"
 
 #define SHELL_LOGIN_PROMPT "\nMezu Login: "
 
@@ -21,10 +24,12 @@ void cmd_logout(readline_parsed_cmd_t* cmd);
 void cmd_status(readline_parsed_cmd_t* cmd);
 void cmd_keyslot_alarm_stop(readline_parsed_cmd_t* cmd);
 void cmd_reset(readline_parsed_cmd_t* cmd);
-void display_sys_state(void);
+void cmd_date(readline_parsed_cmd_t* cmd);
+void cmd_show_log(readline_parsed_cmd_t* cmd);
 
 readline_supported_cmd_t readline_commands[] = {{"help"     , 0, 0, cmd_help},
                                                 {"logout"   , 0, 0, cmd_logout},
+                                                {"exit"     , 0, 0, cmd_logout},
                                                 {"passwd"   , 0, 1, cmd_passwd},
                                                 {"unlock"   , 0, 0, cmd_unlock},
                                                 {"lock"     , 0, 1, cmd_lock},
@@ -34,19 +39,23 @@ readline_supported_cmd_t readline_commands[] = {{"help"     , 0, 0, cmd_help},
                                                 {"clearks"  , 1, 1, cmd_keyslot_clear},
                                                 {"disableks", 1, 1, cmd_keyslot_disable},
                                                 {"enableks" , 1, 1, cmd_keyslot_enable},
-                                                {"urusai"   ,  0, 0, cmd_keyslot_alarm_stop},
+                                                {"urusai"   , 0, 0, cmd_keyslot_alarm_stop},
                                                 {"ls"       , 0, 0, cmd_keyslot_list},
+                                                {"date"     , 0, 2, cmd_date},
+                                                {"log"      , 0, 0, cmd_show_log},
                                                 {0,0,0,0}};
 
 #define SHELL_STATE_READ_USER 0
 #define SHELL_STATE_READ_PASSWORD 1
 #define SHELL_STATE_LOGGED_IN 3
-#define SHELL_STATE_PASSWD1 4
-#define SHELL_STATE_PASSWD2 5
+#define SHELL_STATE_INVALID_LOGIN 4
+#define SHELL_STATE_PASSWD1 5
+#define SHELL_STATE_PASSWD2 6
 
 static uint8_t shell_state = SHELL_STATE_READ_USER;
 
-static char* users[6] = {"root", "admin", 0 };
+
+static char* users[NUM_USERS] = {"root", "admin", 0 };
 
 #define SHELL_USER_INVALID 0xFF
 static uint8_t login_user = SHELL_USER_INVALID;
@@ -56,11 +65,27 @@ static uint8_t passwd_user = SHELL_USER_INVALID;
 #define SHELL_MAX_PW_LEN 20
 static char passwd_pw[SHELL_MAX_PW_LEN];
 
+#define SHELL_LOGIN_DELAY 200
+static uint8_t shell_login_delay = SHELL_LOGIN_DELAY;
+
 void shell_init(void){
 	readline_set_mode(SHELL_LOGIN_PROMPT, 1 ,0);
 	readline_init();
 }
 
+void shell_tick(void){
+	if (shell_login_delay > 0){
+		shell_login_delay--;
+		if (shell_login_delay == 0 && shell_state == SHELL_STATE_INVALID_LOGIN){
+			printf_P(PSTR("Login incorrect\n"));
+			login_user = SHELL_USER_INVALID;
+			shell_state = SHELL_STATE_READ_USER;
+			readline_set_mode(SHELL_LOGIN_PROMPT, 1 ,0);
+			readline_write_prompt();
+		}
+	}
+}
+
 void shell_show_welcome_prompt(void){
 	readline_show_welcome_prompt();
 }
@@ -79,13 +104,20 @@ void readline_handle_buffer(char* input_buffer){
 	} else if (shell_state == SHELL_STATE_READ_PASSWORD){
 		if ((login_user != SHELL_USER_INVALID) && (shell_check_password(login_user, input_buffer))){
 			shell_state = SHELL_STATE_LOGGED_IN;
+			printf_P(PSTR("Login successful\n"));
+			ds1307_write_current_date();
+			if (door_get_status() & DOOR_STATUS_ALARM) log_append(LOG_EVENT_ALARM_LOGIN, login_user);
+			printf_P(PSTR("\n"));
 			readline_set_mode("> ", 1 ,1); //start parsing commands
 		} else {
 			login_user = SHELL_USER_INVALID;
-			shell_state = SHELL_STATE_READ_USER;
-			readline_set_mode(SHELL_LOGIN_PROMPT, 1 ,0);
-			printf(PSTR("Login incorrect\n"));
+			shell_state = SHELL_STATE_INVALID_LOGIN;
+			shell_login_delay = SHELL_LOGIN_DELAY;
+			printf_P(PSTR("\n"));
+			readline_set_mode(0, 0 ,0);
 		}
+	} else if (shell_state == SHELL_STATE_INVALID_LOGIN){
+		//ignore
 	} else if (shell_state == SHELL_STATE_PASSWD1){
 		memcpy(passwd_pw, input_buffer, MIN(strlen(input_buffer), SHELL_MAX_PW_LEN));
 		readline_set_mode("Confirm Password: ", 0 ,0);
@@ -239,7 +271,7 @@ void cmd_keyslot_list(readline_parsed_cmd_t* cmd){
 			MGMT_transmit_buffer_hex(key, 20);
 			
 			printf_P(PSTR(" H:"));
-			MGMT_transmit_buffer_hex(hashes[index], sizeof(HASH));
+			MGMT_transmit_buffer_hex(hashes[index], sizeof(HASH_HEAD));
 			
 			if (slot_status == KEYSLOT_DISABLED){
 				printf_P(PSTR(" (Disabled)"));
@@ -273,7 +305,9 @@ void cmd_unlock(readline_parsed_cmd_t* cmd){
 }
 void cmd_status(readline_parsed_cmd_t* cmd){
 	door_write_status();
+	printf_P(PSTR("\n"));
 	power_write_status();
+	printf_P(PSTR("\n"));
 }
 void cmd_reset(readline_parsed_cmd_t* cmd){
 	printf_P(PSTR("Restarting...\n"));
@@ -314,6 +348,49 @@ void cmd_keyslot_alarm_stop(readline_parsed_cmd_t* cmd){
 	}
 }
 
+void cmd_date(readline_parsed_cmd_t* cmd){
+	if (cmd->num_args == 0){
+		printf_P(PSTR("Current Date: "));
+	} else if ((cmd->num_args == 1) || (cmd->num_args == 2)) {
+		date_t new_date;
+		uint8_t date_valid = 0;
+// 		uint8_t time_valid = 0;
+		uint16_t h,m,s,d,y;
+		
+		if (cmd->num_args == 2){
+			if (sscanf_P(cmd->args[0], PSTR("%x-%x-%x"), &d, &m, &y) == 3){
+				date_valid = 1;
+				//printf_P(PSTR("%02x-%02x-%02x "), d, m, y);
+				new_date.day = d;
+				new_date.month = m;
+				new_date.year = y;
+			} else {
+				printf_P(PSTR("Date '%s' invalid, use format: dd-mm-yy\n"), cmd->args[1]);
+				return;
+			}
+		}
+		
+		if (sscanf_P(cmd->args[cmd->num_args - 1], PSTR("%x:%x:%x"), &h, &m, &s) == 3){
+			//printf_P(PSTR("%02x:%02x:%02x\n"), h, m, s);
+			new_date.hour = h;
+			new_date.minute = m;
+			new_date.second = s;
+		} else {
+			printf_P(PSTR("Time '%s' invalid, use format: hh-mm-ss\n"), cmd->args[0]);
+		}
+		
+		if (date_valid){
+			ds1307_set_date(&new_date);
+		} else {
+			ds1307_set_time((time_t*)&new_date);
+		}
+		printf_P(PSTR("New Date: "));
+	}
+	
+	ds1307_write_current_date();
+	printf_P(PSTR("\n"));
+}
+
 uint8_t shell_find_user(char* username){
 	uint8_t i = 0;
 	while (users[i]){
@@ -355,4 +432,8 @@ void shell_set_password(uint8_t user, char* password){
 	sha1(&hash, password, (pw_len+4) * 8);
 	eeprom_write_block(hash, ((char*)eeprom_addr), sizeof(HASH));
 	eeprom_write_block(&salt, ((char*)eeprom_addr) + sizeof(HASH), 4);
+}
+
+void cmd_show_log(readline_parsed_cmd_t* cmd){
+	log_dump();
 }
\ No newline at end of file
diff --git a/Control/shell/shell.h b/Control/shell/shell.h
index 207a9fa..69a0278 100644
--- a/Control/shell/shell.h
+++ b/Control/shell/shell.h
@@ -8,6 +8,10 @@
 #include "keystore.h"
 #include "random.h"
 
+#define NUM_USERS 3
+#define SHELL_EEPROM_SPACE (32*NUM_USERS)
+
 void shell_init(void);
+void shell_tick(void);
 void shell_show_welcome_prompt(void);
 void shell_process(void);
\ No newline at end of file
-- 
GitLab