#include "../esubghz_chat_i.h" typedef enum { ESubGhzChatKeyMenuItems_NoEncryption, ESubGhzChatKeyMenuItems_Password, ESubGhzChatKeyMenuItems_HexKey, ESubGhzChatKeyMenuItems_GenKey, ESubGhzChatKeyMenuItems_ReadKeyFromNfc, } ESubGhzChatKeyMenuItems; static void key_menu_cb(void* context, uint32_t index) { furi_assert(context); ESubGhzChatState* state = context; uint8_t key[KEY_BITS / 8]; switch(index) { case ESubGhzChatKeyMenuItems_NoEncryption: state->encrypted = false; view_dispatcher_send_custom_event( state->view_dispatcher, ESubGhzChatEvent_KeyMenuNoEncryption); break; case ESubGhzChatKeyMenuItems_Password: view_dispatcher_send_custom_event( state->view_dispatcher, ESubGhzChatEvent_KeyMenuPassword); break; case ESubGhzChatKeyMenuItems_HexKey: view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuHexKey); break; case ESubGhzChatKeyMenuItems_GenKey: /* generate a random key */ furi_hal_random_fill_buf(key, KEY_BITS / 8); /* initiate the crypto context */ bool ret = crypto_ctx_set_key(state->crypto_ctx, key, state->name_prefix, furi_get_tick()); /* cleanup */ crypto_explicit_bzero(key, sizeof(key)); if(!ret) { crypto_ctx_clear(state->crypto_ctx); return; } /* set encrypted flag and enter the chat */ state->encrypted = true; view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuGenKey); break; case ESubGhzChatKeyMenuItems_ReadKeyFromNfc: view_dispatcher_send_custom_event( state->view_dispatcher, ESubGhzChatEvent_KeyMenuReadKeyFromNfc); break; default: break; } } /* Prepares the key menu scene. */ void scene_on_enter_key_menu(void* context) { FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_menu"); furi_assert(context); ESubGhzChatState* state = context; menu_reset(state->menu); /* clear the crypto CTX in case we got back from password or hex key * input */ crypto_ctx_clear(state->crypto_ctx); menu_add_item( state->menu, "No encryption", &I_chat_14px, ESubGhzChatKeyMenuItems_NoEncryption, key_menu_cb, state); menu_add_item( state->menu, "Password", &I_keyboard_14px, ESubGhzChatKeyMenuItems_Password, key_menu_cb, state); menu_add_item( state->menu, "Hex Key", &I_hex_14px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state); menu_add_item( state->menu, "Generate Key", &I_u2f_14px, ESubGhzChatKeyMenuItems_GenKey, key_menu_cb, state); menu_add_item( state->menu, "Read Key from NFC", &I_Nfc_14px, ESubGhzChatKeyMenuItems_ReadKeyFromNfc, key_menu_cb, state); view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Menu); } /* Handles scene manager events for the key menu scene. */ bool scene_on_event_key_menu(void* context, SceneManagerEvent event) { FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_menu"); furi_assert(context); ESubGhzChatState* state = context; bool consumed = false; switch(event.type) { case SceneManagerEventTypeCustom: switch(event.event) { /* switch to frequency input scene */ case ESubGhzChatEvent_KeyMenuNoEncryption: case ESubGhzChatEvent_KeyMenuGenKey: scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput); consumed = true; break; /* switch to password input scene */ case ESubGhzChatEvent_KeyMenuPassword: scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_PassInput); consumed = true; break; /* switch to hex key input scene */ case ESubGhzChatEvent_KeyMenuHexKey: scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_HexKeyInput); consumed = true; break; /* switch to hex key read scene */ case ESubGhzChatEvent_KeyMenuReadKeyFromNfc: scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyReadPopup); consumed = true; break; } break; case SceneManagerEventTypeBack: /* stop the application if the user presses back here */ view_dispatcher_stop(state->view_dispatcher); consumed = true; break; default: consumed = false; break; } return consumed; } /* Cleans up the key menu scene. */ void scene_on_exit_key_menu(void* context) { FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_menu"); furi_assert(context); ESubGhzChatState* state = context; menu_reset(state->menu); }