Просмотр исходного кода

Add a key display to view the key

twisted_pear 2 лет назад
Родитель
Сommit
7e0b4924aa

+ 7 - 3
crypto_wrapper.c

@@ -7,9 +7,8 @@
 #include "crypto_wrapper.h"
 
 struct ESugGhzChatCryptoCtx {
-#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL
 	uint8_t key[KEY_BITS / 8];
-#else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
+#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL
 	gcm_context gcm_ctx;
 #endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
 };
@@ -52,14 +51,19 @@ void crypto_ctx_clear(ESubGhzChatCryptoCtx *ctx)
 
 bool crypto_ctx_set_key(ESubGhzChatCryptoCtx *ctx, const uint8_t *key)
 {
-#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL
 	memcpy(ctx->key, key, KEY_BITS / 8);
+#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL
 	return true;
 #else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
 	return (gcm_setkey(&(ctx->gcm_ctx), key, KEY_BITS / 8) == 0);
 #endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
 }
 
+void crypto_ctx_get_key(ESubGhzChatCryptoCtx *ctx, uint8_t *key)
+{
+	memcpy(key, ctx->key, KEY_BITS / 8);
+}
+
 bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
 		uint8_t *out)
 {

+ 1 - 0
crypto_wrapper.h

@@ -23,6 +23,7 @@ void crypto_ctx_free(ESubGhzChatCryptoCtx *ctx);
 void crypto_ctx_clear(ESubGhzChatCryptoCtx *ctx);
 
 bool crypto_ctx_set_key(ESubGhzChatCryptoCtx *ctx, const uint8_t *key);
+void crypto_ctx_get_key(ESubGhzChatCryptoCtx *ctx, uint8_t *key);
 
 bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
 		uint8_t *out);

+ 65 - 1
esubghz_chat.c

@@ -343,7 +343,7 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
 			return;
 		}
 
-		/* handle ongoing inputs when chaning to chat view */
+		/* handle ongoing inputs when changing to chat view */
 		if (event->type == InputTypePress) {
 			state->kbd_ok_input_ongoing = true;
 		} else if (event->type == InputTypeRelease) {
@@ -351,6 +351,57 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
 		}
 	}
 
+	if (event->key == InputKeyLeft) {
+		/* if we are in the chat view and no input is ongoing, allow
+		 * switching to msg input */
+		if (state->view_dispatcher->current_view ==
+				text_box_get_view(state->chat_box) &&
+				!(state->kbd_left_input_ongoing)) {
+			/* go to msg input upon short press of Left button */
+			if (event->type == InputTypeShort) {
+				view_dispatcher_send_custom_event(state->view_dispatcher,
+						ESubGhzChatEvent_GotoMsgInput);
+			}
+
+			/* do not handle any Left key events to prevent
+			 * blocking of other keys */
+			return;
+		}
+
+		/* handle ongoing inputs when changing to chat view */
+		if (event->type == InputTypePress) {
+			state->kbd_left_input_ongoing = true;
+		} else if (event->type == InputTypeRelease) {
+			state->kbd_left_input_ongoing = false;
+		}
+	}
+
+	if (event->key == InputKeyRight) {
+		/* if we are in the chat view and no input is ongoing, allow
+		 * switching to key display */
+		if (state->view_dispatcher->current_view ==
+				text_box_get_view(state->chat_box) &&
+				!(state->kbd_right_input_ongoing)) {
+			/* go to key display upon short press of Right button
+			 */
+			if (event->type == InputTypeShort) {
+				view_dispatcher_send_custom_event(state->view_dispatcher,
+						ESubGhzChatEvent_GotoKeyDisplay);
+			}
+
+			/* do not handle any Right key events to prevent
+			 * blocking of other keys */
+			return;
+		}
+
+		/* handle ongoing inputs when changing to chat view */
+		if (event->type == InputTypePress) {
+			state->kbd_right_input_ongoing = true;
+		} else if (event->type == InputTypeRelease) {
+			state->kbd_right_input_ongoing = false;
+		}
+	}
+
 	/* call original callback */
 	state->orig_input_cb(event, state->view_dispatcher);
 }
@@ -459,6 +510,11 @@ int32_t esubghz_chat(void)
 		goto err_alloc_cb;
 	}
 
+	state->key_display = dialog_ex_alloc();
+	if (state->key_display == NULL) {
+		goto err_alloc_kd;
+	}
+
 	state->subghz_worker = subghz_tx_rx_worker_alloc();
 	if (state->subghz_worker == NULL) {
 		goto err_alloc_worker;
@@ -518,6 +574,8 @@ int32_t esubghz_chat(void)
 			text_input_get_view(state->text_input));
 	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_ChatBox,
 			text_box_get_view(state->chat_box));
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay,
+			dialog_ex_get_view(state->key_display));
 
 	/* get the GUI record and attach the view dispatcher to the GUI */
 	/* no error handling here, don't know how */
@@ -550,6 +608,8 @@ int32_t esubghz_chat(void)
 			ESubGhzChatView_Input);
 	view_dispatcher_remove_view(state->view_dispatcher,
 			ESubGhzChatView_ChatBox);
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_KeyDisplay);
 
 	/* close notification record */
 	furi_record_close(RECORD_NOTIFICATION);
@@ -557,6 +617,7 @@ int32_t esubghz_chat(void)
 	/* clear the key and potential password */
 	crypto_explicit_bzero(state->text_input_store,
 			sizeof(state->text_input_store));
+	crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str));
 	crypto_ctx_clear(state->crypto_ctx);
 
 	/* deinit devices */
@@ -573,6 +634,9 @@ err_alloc_crypto:
 	subghz_tx_rx_worker_free(state->subghz_worker);
 
 err_alloc_worker:
+	dialog_ex_free(state->key_display);
+
+err_alloc_kd:
 	chat_box_free(state);
 
 err_alloc_cb:

+ 14 - 1
esubghz_chat_i.h

@@ -4,6 +4,7 @@
 #include <gui/view_dispatcher_i.h>
 #include <gui/view_port_i.h>
 #include <gui/scene_manager.h>
+#include <gui/modules/dialog_ex.h>
 #include <gui/modules/menu.h>
 #include <gui/modules/text_box.h>
 #include <gui/modules/text_input.h>
@@ -23,6 +24,8 @@
 #define CHAT_BOX_STORE_SIZE 4096
 #define TEXT_INPUT_STORE_SIZE 256
 
+#define KEY_HEX_STR_SIZE ((KEY_BITS / 8) * 3)
+
 typedef struct {
 	SceneManager *scene_manager;
 	ViewDispatcher *view_dispatcher;
@@ -34,6 +37,8 @@ typedef struct {
 	FuriString *chat_box_store;
 	TextInput *text_input;
 	char text_input_store[TEXT_INPUT_STORE_SIZE + 1];
+	DialogEx *key_display;
+	char key_hex_str[KEY_HEX_STR_SIZE + 1];
 
 	// for Sub-GHz
 	uint32_t frequency;
@@ -60,7 +65,11 @@ typedef struct {
 	bool kbd_locked;
 	uint32_t kbd_lock_msg_ticks;
 	uint8_t kbd_lock_count;
+
+	// for ongoing inputs
 	bool kbd_ok_input_ongoing;
+	bool kbd_left_input_ongoing;
+	bool kbd_right_input_ongoing;
 } ESubGhzChatState;
 
 typedef enum {
@@ -68,13 +77,17 @@ typedef enum {
 	ESubGhzChatEvent_KeyMenuNoEncryption,
 	ESubGhzChatEvent_KeyMenuPassword,
 	ESubGhzChatEvent_PassEntered,
-	ESubGhzChatEvent_MsgEntered
+	ESubGhzChatEvent_MsgEntered,
+	ESubGhzChatEvent_GotoMsgInput,
+	ESubGhzChatEvent_GotoKeyDisplay,
+	ESubGhzChatEvent_KeyDisplayBack
 } ESubGhzChatEvent;
 
 typedef enum {
 	ESubGhzChatView_Menu,
 	ESubGhzChatView_Input,
 	ESubGhzChatView_ChatBox,
+	ESubGhzChatView_KeyDisplay,
 } ESubGhzChatView;
 
 void tx_msg_input(ESubGhzChatState *state);

+ 29 - 5
scenes/esubghz_chat_chat_box.c

@@ -16,17 +16,41 @@ void scene_on_enter_chat_box(void* context)
 	view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_ChatBox);
 }
 
-/* Handles scene manager events for the text box scene. No events are handled
- * here. */
+/* Handles scene manager events for the text box scene. */
 bool scene_on_event_chat_box(void* context, SceneManagerEvent event)
 {
-	UNUSED(event);
-
 	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_box");
 
 	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	bool consumed = false;
+
+	switch(event.type) {
+	case SceneManagerEventTypeCustom:
+		switch(event.event) {
+		/* switch to message input scene */
+		case ESubGhzChatEvent_GotoMsgInput:
+			if (!scene_manager_previous_scene(
+						state->scene_manager)) {
+				view_dispatcher_stop(state->view_dispatcher);
+			}
+			consumed = true;
+			break;
+		case ESubGhzChatEvent_GotoKeyDisplay:
+			scene_manager_next_scene(state->scene_manager,
+					ESubGhzChatScene_KeyDisplay);
+			consumed = true;
+			break;
+		}
+		break;
+
+	default:
+		consumed = false;
+		break;
+	}
 
-	return false;
+	return consumed;
 }
 
 /* Cleans up the text box scene. */

+ 108 - 0
scenes/esubghz_chat_key_display.c

@@ -0,0 +1,108 @@
+#include "../esubghz_chat_i.h"
+
+void key_display_result_cb(DialogExResult result, void* context)
+{
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	switch(result) {
+	case DialogExResultLeft:
+		scene_manager_handle_custom_event(state->scene_manager,
+				ESubGhzChatEvent_KeyDisplayBack);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/* Prepares the key display scene. */
+void scene_on_enter_key_display(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_display");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	if (state->encrypted) {
+		uint8_t key[KEY_BITS / 8];
+		crypto_ctx_get_key(state->crypto_ctx, key);
+		snprintf(state->key_hex_str, KEY_HEX_STR_SIZE,
+				"%02hX%02hX%02hX%02hX%02hX%02hX"
+				"%02hX%02hX%02hX%02hX%02hX\n"
+				"%02hX%02hX%02hX%02hX%02hX%02hX"
+				"%02hX%02hX%02hX%02hX%02hX\n"
+				"%02hX%02hX%02hX%02hX%02hX%02hX"
+				"%02hX%02hX%02hX%02hX",
+				key[0], key[1], key[2], key[3], key[4], key[5],
+				key[6], key[7], key[8], key[9], key[10],
+				key[11], key[12], key[13], key[14], key[15], key[16],
+				key[17], key[18], key[19], key[20], key[21],
+				key[22], key[23], key[24], key[25], key[26], key[27],
+				key[28], key[29], key[30], key[31]);
+		crypto_explicit_bzero(key, sizeof(key));
+	} else {
+		strcpy(state->key_hex_str, "No Key");
+	}
+
+	dialog_ex_reset(state->key_display);
+
+	dialog_ex_set_header(state->key_display, "KEY (HEX)", 64, 2,
+			AlignCenter, AlignTop);
+	dialog_ex_set_text(state->key_display, state->key_hex_str, 64, 16,
+			AlignCenter, AlignTop);
+
+	dialog_ex_set_icon(state->key_display, 0, 0, NULL);
+
+	dialog_ex_set_left_button_text(state->key_display, "Back");
+
+	dialog_ex_set_result_callback(state->key_display,
+			key_display_result_cb);
+	dialog_ex_set_context(state->key_display, state);
+
+	view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay);
+}
+
+/* Handles scene manager events for the key display scene. */
+bool scene_on_event_key_display(void* context, SceneManagerEvent event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_display");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	bool consumed = false;
+
+	switch(event.type) {
+	case SceneManagerEventTypeCustom:
+		switch(event.event) {
+		/* switch to message input scene */
+		case ESubGhzChatEvent_KeyDisplayBack:
+			if (!scene_manager_previous_scene(
+						state->scene_manager)) {
+				view_dispatcher_stop(state->view_dispatcher);
+			}
+			consumed = true;
+			break;
+		}
+		break;
+
+	default:
+		consumed = false;
+		break;
+	}
+
+	return consumed;
+}
+
+/* Cleans up the key display scene. */
+void scene_on_exit_key_display(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_display");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	dialog_ex_reset(state->key_display);
+	crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str));
+}

+ 1 - 0
scenes/esubghz_chat_scene_config.h

@@ -3,3 +3,4 @@ ADD_SCENE(esubghz_chat, key_menu, KeyMenu)
 ADD_SCENE(esubghz_chat, pass_input, PassInput)
 ADD_SCENE(esubghz_chat, chat_input, ChatInput)
 ADD_SCENE(esubghz_chat, chat_box, ChatBox)
+ADD_SCENE(esubghz_chat, key_display, KeyDisplay)