Przeglądaj źródła

WIP: add sharing key via nfc (emulation part)

twisted_pear 2 lat temu
rodzic
commit
a725e0e50e

BIN
assets/NFC_dolphin_emulation_47x61.png


+ 32 - 2
esubghz_chat.c

@@ -3,8 +3,6 @@
 #include <gui/gui.h>
 #include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
 
-#include "esubghz_chat_icons.h"
-
 #include "esubghz_chat_i.h"
 
 #define CHAT_LEAVE_DELAY 10
@@ -516,11 +514,27 @@ int32_t esubghz_chat(void)
 		goto err_alloc_kd;
 	}
 
+	state->nfc_popup = popup_alloc();
+	if (state->nfc_popup == NULL) {
+		goto err_alloc_np;
+	}
+
 	state->subghz_worker = subghz_tx_rx_worker_alloc();
 	if (state->subghz_worker == NULL) {
 		goto err_alloc_worker;
 	}
 
+	state->nfc_worker = nfc_worker_alloc();
+	if (state->nfc_worker == NULL) {
+		goto err_alloc_nworker;
+	}
+
+	state->nfc_dev_data = malloc(sizeof(NfcDeviceData));
+	if (state->nfc_dev_data == NULL) {
+		goto err_alloc_ndevdata;
+	}
+	memset(state->nfc_dev_data, 0, sizeof(NfcDeviceData));
+
 	state->crypto_ctx = crypto_ctx_alloc();
 	if (state->crypto_ctx == NULL) {
 		goto err_alloc_crypto;
@@ -579,6 +593,8 @@ int32_t esubghz_chat(void)
 			text_box_get_view(state->chat_box));
 	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay,
 			dialog_ex_get_view(state->key_display));
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_NfcPopup,
+			popup_get_view(state->nfc_popup));
 
 	/* get the GUI record and attach the view dispatcher to the GUI */
 	/* no error handling here, don't know how */
@@ -599,6 +615,9 @@ int32_t esubghz_chat(void)
 		subghz_tx_rx_worker_stop(state->subghz_worker);
 	}
 
+	/* if it is running, stop the NFC worker */
+	nfc_worker_stop(state->nfc_worker);
+
 	err = 0;
 
 	/* close GUI record */
@@ -615,6 +634,8 @@ int32_t esubghz_chat(void)
 			ESubGhzChatView_ChatBox);
 	view_dispatcher_remove_view(state->view_dispatcher,
 			ESubGhzChatView_KeyDisplay);
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_NfcPopup);
 
 	/* close notification record */
 	furi_record_close(RECORD_NOTIFICATION);
@@ -638,9 +659,18 @@ int32_t esubghz_chat(void)
 	crypto_ctx_free(state->crypto_ctx);
 
 err_alloc_crypto:
+	free(state->nfc_dev_data);
+
+err_alloc_ndevdata:
+	nfc_worker_free(state->nfc_worker);
+
+err_alloc_nworker:
 	subghz_tx_rx_worker_free(state->subghz_worker);
 
 err_alloc_worker:
+	popup_free(state->nfc_popup);
+
+err_alloc_np:
 	dialog_ex_free(state->key_display);
 
 err_alloc_kd:

+ 12 - 1
esubghz_chat_i.h

@@ -7,15 +7,19 @@
 #include <gui/modules/byte_input.h>
 #include <gui/modules/dialog_ex.h>
 #include <gui/modules/menu.h>
+#include <gui/modules/popup.h>
 #include <gui/modules/text_box.h>
 #include <gui/modules/text_input.h>
 #include <notification/notification_messages.h>
+#include <lib/nfc/nfc_worker.h>
 #include <lib/subghz/subghz_tx_rx_worker.h>
 #include <toolbox/sha256.h>
 
 #include "crypto_wrapper.h"
 #include "scenes/esubghz_chat_scene.h"
 
+#include "esubghz_chat_icons.h"
+
 #define APPLICATION_NAME "ESubGhzChat"
 
 #define DEFAULT_FREQ 433920000
@@ -42,12 +46,17 @@ typedef struct {
 	uint8_t hex_key_input_store[KEY_BITS / 8];
 	DialogEx *key_display;
 	char key_hex_str[KEY_HEX_STR_SIZE + 1];
+	Popup *nfc_popup;
 
 	// for Sub-GHz
 	uint32_t frequency;
 	SubGhzTxRxWorker *subghz_worker;
 	const SubGhzDevice *subghz_device;
 
+	// for NFC
+	NfcWorker *nfc_worker;
+	NfcDeviceData *nfc_dev_data;
+
 	// message assembly before TX
 	FuriString *name_prefix;
 	FuriString *msg_input;
@@ -86,7 +95,8 @@ typedef enum {
 	ESubGhzChatEvent_MsgEntered,
 	ESubGhzChatEvent_GotoMsgInput,
 	ESubGhzChatEvent_GotoKeyDisplay,
-	ESubGhzChatEvent_KeyDisplayBack
+	ESubGhzChatEvent_KeyDisplayBack,
+	ESubGhzChatEvent_KeyDisplayShare,
 } ESubGhzChatEvent;
 
 typedef enum {
@@ -95,6 +105,7 @@ typedef enum {
 	ESubGhzChatView_HexKeyInput,
 	ESubGhzChatView_ChatBox,
 	ESubGhzChatView_KeyDisplay,
+	ESubGhzChatView_NfcPopup,
 } ESubGhzChatView;
 
 void tx_msg_input(ESubGhzChatState *state);

+ 18 - 0
scenes/esubghz_chat_key_display.c

@@ -11,6 +11,13 @@ void key_display_result_cb(DialogExResult result, void* context)
 				ESubGhzChatEvent_KeyDisplayBack);
 		break;
 
+	case DialogExResultCenter:
+		if (state->encrypted) {
+			scene_manager_handle_custom_event(state->scene_manager,
+					ESubGhzChatEvent_KeyDisplayShare);
+		}
+		break;
+
 	default:
 		break;
 	}
@@ -58,6 +65,10 @@ void scene_on_enter_key_display(void* context)
 
 	dialog_ex_set_left_button_text(state->key_display, "Back");
 
+	if (state->encrypted) {
+		dialog_ex_set_center_button_text(state->key_display, "Share");
+	}
+
 	dialog_ex_set_result_callback(state->key_display,
 			key_display_result_cb);
 	dialog_ex_set_context(state->key_display, state);
@@ -86,6 +97,13 @@ bool scene_on_event_key_display(void* context, SceneManagerEvent event)
 			}
 			consumed = true;
 			break;
+
+		/* open key sharing popup */
+		case ESubGhzChatEvent_KeyDisplayShare:
+			scene_manager_next_scene(state->scene_manager,
+					ESubGhzChatScene_KeySharePopup);
+			consumed = true;
+			break;
 		}
 		break;
 

+ 88 - 0
scenes/esubghz_chat_key_share_popup.c

@@ -0,0 +1,88 @@
+#include "../esubghz_chat_i.h"
+
+static void prepare_nfc_dev_data(ESubGhzChatState *state)
+{
+	NfcDeviceData *dev_data = state->nfc_dev_data;
+
+	dev_data->protocol = NfcDeviceProtocolMifareUl;
+	furi_hal_random_fill_buf(dev_data->nfc_data.uid, 7);
+	dev_data->nfc_data.uid_len = 7;
+	dev_data->nfc_data.atqa[0] = 0x44;
+	dev_data->nfc_data.atqa[1] = 0x00;
+	dev_data->nfc_data.sak = 0x00;
+
+	dev_data->mf_ul_data.type = MfUltralightTypeNTAG215;
+	dev_data->mf_ul_data.version.header = 0x00;
+	dev_data->mf_ul_data.version.vendor_id = 0x04;
+	dev_data->mf_ul_data.version.prod_type = 0x04;
+	dev_data->mf_ul_data.version.prod_subtype = 0x02;
+	dev_data->mf_ul_data.version.prod_ver_major = 0x01;
+	dev_data->mf_ul_data.version.prod_ver_minor = 0x00;
+	dev_data->mf_ul_data.version.storage_size = 0x11;
+	dev_data->mf_ul_data.version.protocol_type = 0x03;
+
+	/* Add 16 to the size for config pages */
+	dev_data->mf_ul_data.data_size = (KEY_BITS / 8) + 16;
+	crypto_ctx_get_key(state->crypto_ctx, dev_data->mf_ul_data.data);
+}
+
+/* Prepares the key share popup scene. */
+void scene_on_enter_key_share_popup(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_share_popup");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	popup_reset(state->nfc_popup);
+
+	popup_disable_timeout(state->nfc_popup);
+
+	popup_set_header(state->nfc_popup, "Sharing...", 67, 13, AlignLeft,
+			AlignTop);
+	popup_set_icon(state->nfc_popup, 0, 3, &I_NFC_dolphin_emulation_47x61);
+	popup_set_text(state->nfc_popup, "Sharing\nKey via\nNFC", 90, 28,
+			AlignCenter, AlignTop);
+
+	prepare_nfc_dev_data(state);
+	nfc_worker_start(state->nfc_worker, NfcWorkerStateMfUltralightEmulate,
+			state->nfc_dev_data, NULL, NULL);
+
+	notification_message(state->notification,
+			&sequence_blink_start_magenta);
+
+	view_dispatcher_switch_to_view(state->view_dispatcher,
+			ESubGhzChatView_NfcPopup);
+}
+
+/* Handles scene manager events for the key share popup scene. */
+bool scene_on_event_key_share_popup(void* context, SceneManagerEvent event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_share_popup");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	UNUSED(state);
+	UNUSED(event);
+
+	return false;
+}
+
+/* Cleans up the key share popup scene. */
+void scene_on_exit_key_share_popup(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_share_popup");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	popup_reset(state->nfc_popup);
+
+	notification_message(state->notification, &sequence_blink_stop);
+
+	nfc_worker_stop(state->nfc_worker);
+
+	crypto_explicit_bzero(state->nfc_dev_data->mf_ul_data.data, KEY_BITS / 8);
+	memset(state->nfc_dev_data, 0, sizeof(NfcDeviceData));
+}

+ 1 - 0
scenes/esubghz_chat_scene_config.h

@@ -5,3 +5,4 @@ ADD_SCENE(esubghz_chat, hex_key_input, HexKeyInput)
 ADD_SCENE(esubghz_chat, chat_input, ChatInput)
 ADD_SCENE(esubghz_chat, chat_box, ChatBox)
 ADD_SCENE(esubghz_chat, key_display, KeyDisplay)
+ADD_SCENE(esubghz_chat, key_share_popup, KeySharePopup)