MX 2 лет назад
Родитель
Сommit
fad9247ecc

+ 12 - 5
non_catalog_apps/esubghz_chat/README.md

@@ -5,9 +5,7 @@ feature that is available on the CLI. In addition it allows for basic
 encryption of messages.
 encryption of messages.
 
 
 The plugin has been tested on the official firmware (version 0.87.0) and on
 The plugin has been tested on the official firmware (version 0.87.0) and on
-Unleashed (version unlshd-059).
-
-Currently the use of an external antenna is not supported.
+Unleashed (version unlshd-060).
 
 
 ## Warning
 ## Warning
 
 
@@ -85,5 +83,14 @@ The implementations of AES and GCM are taken directly from
 https://github.com/mko-x/SharedAES-GCM. They were released to the public domain
 https://github.com/mko-x/SharedAES-GCM. They were released to the public domain
 by Markus Kosmal.
 by Markus Kosmal.
 
 
-The app icon was made by [xMasterX](https://github.com/xMasterX). Other icons
-and graphics were taken from the Flipper Zero firmware.
+The app icon was made by [xMasterX](https://github.com/xMasterX). The icon for
+the hexadecimal key input was taken from [QtRoS](https://github.com/QtRoS) hex
+viewer app, which can be found here:
+https://github.com/QtRoS/flipper-zero-hex-viewer. Other icons and graphics were
+taken from the Flipper Zero firmware.
+
+The icons used in the key input method menu were picked by
+[Willy-JL](https://github.com/Willy-JL).
+
+Support for the external radio was also contributed by
+[xMasterX](https://github.com/xMasterX).

BIN
non_catalog_apps/esubghz_chat/assets/Nfc_10px.png


BIN
non_catalog_apps/esubghz_chat/assets/hex_10px.png


BIN
non_catalog_apps/esubghz_chat/assets/keyboard_10px.png


BIN
non_catalog_apps/esubghz_chat/assets/u2f_10px.png


+ 586 - 529
non_catalog_apps/esubghz_chat/esubghz_chat.c

@@ -1,8 +1,8 @@
 #include <furi_hal.h>
 #include <furi_hal.h>
 #include <gui/elements.h>
 #include <gui/elements.h>
 #include <gui/gui.h>
 #include <gui/gui.h>
-#include "helpers/radio_device_loader.h"
 
 
+#include "helpers/radio_device_loader.h"
 #include "esubghz_chat_i.h"
 #include "esubghz_chat_i.h"
 
 
 #define CHAT_LEAVE_DELAY 10
 #define CHAT_LEAVE_DELAY 10
@@ -15,685 +15,742 @@
 
 
 /* Callback for RX events from the Sub-GHz worker. Records the current ticks as
 /* Callback for RX events from the Sub-GHz worker. Records the current ticks as
  * the time of the last reception. */
  * the time of the last reception. */
-static void have_read_cb(void* context) {
-    furi_assert(context);
-    ESubGhzChatState* state = context;
+static void have_read_cb(void* context)
+{
+	furi_assert(context);
+	ESubGhzChatState* state = context;
 
 
-    state->last_time_rx_data = furi_get_tick();
+	state->last_time_rx_data = furi_get_tick();
 }
 }
 
 
 /* Sets the header for the chat input field depending on whether or not a
 /* Sets the header for the chat input field depending on whether or not a
  * message preview exists. */
  * message preview exists. */
-void set_chat_input_header(ESubGhzChatState* state) {
-    if(strlen(state->msg_preview) == 0) {
-        text_input_set_header_text(state->text_input, "Message");
-    } else {
-        text_input_set_header_text(state->text_input, state->msg_preview);
-    }
+void set_chat_input_header(ESubGhzChatState *state)
+{
+	if (strlen(state->msg_preview) == 0) {
+		text_input_set_header_text(state->text_input, "Message");
+	} else {
+		text_input_set_header_text(state->text_input,
+				state->msg_preview);
+	}
 }
 }
 
 
 /* Appends the latest message to the chat box and prepares the message preview.
 /* Appends the latest message to the chat box and prepares the message preview.
  */
  */
-void append_msg(ESubGhzChatState* state, const char* msg) {
-    /* append message to text box */
-    furi_string_cat_printf(state->chat_box_store, "\n%s", msg);
-
-    /* prepare message preview */
-    strncpy(state->msg_preview, msg, MSG_PREVIEW_SIZE);
-    state->msg_preview[MSG_PREVIEW_SIZE] = 0;
-    set_chat_input_header(state);
-
-    /* reset text box contents and focus */
-    text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store));
-    text_box_set_focus(state->chat_box, TextBoxFocusEnd);
+void append_msg(ESubGhzChatState *state, const char *msg)
+{
+	/* append message to text box */
+	furi_string_cat_printf(state->chat_box_store, "\n%s", msg);
+
+	/* prepare message preview */
+	strncpy(state->msg_preview, msg, MSG_PREVIEW_SIZE);
+	state->msg_preview[MSG_PREVIEW_SIZE] = 0;
+	set_chat_input_header(state);
+
+	/* reset text box contents and focus */
+	text_box_set_text(state->chat_box,
+			furi_string_get_cstr(state->chat_box_store));
+	text_box_set_focus(state->chat_box, TextBoxFocusEnd);
 }
 }
 
 
 /* Decrypts a message for post_rx(). */
 /* Decrypts a message for post_rx(). */
-static bool post_rx_decrypt(ESubGhzChatState* state, size_t rx_size) {
-    bool ret = crypto_ctx_decrypt(
-        state->crypto_ctx, state->rx_buffer, rx_size, (uint8_t*)state->rx_str_buffer);
-
-    if(ret) {
-        state->rx_str_buffer[rx_size - (MSG_OVERHEAD)] = 0;
-    } else {
-        state->rx_str_buffer[0] = 0;
-    }
-
-    return ret;
+static bool post_rx_decrypt(ESubGhzChatState *state, size_t rx_size)
+{
+	bool ret = crypto_ctx_decrypt(state->crypto_ctx,
+			state->rx_buffer, rx_size,
+			(uint8_t*) state->rx_str_buffer);
+
+	if (ret) {
+		state->rx_str_buffer[rx_size - (MSG_OVERHEAD)] = 0;
+	} else {
+		state->rx_str_buffer[0] = 0;
+	}
+
+	return ret;
 }
 }
 
 
 /* Post RX handler, decrypts received messages and calls append_msg(). */
 /* Post RX handler, decrypts received messages and calls append_msg(). */
-static void post_rx(ESubGhzChatState* state, size_t rx_size) {
-    furi_assert(state);
+static void post_rx(ESubGhzChatState *state, size_t rx_size)
+{
+	furi_assert(state);
 
 
-    if(rx_size == 0) {
-        return;
-    }
+	if (rx_size == 0) {
+		return;
+	}
 
 
-    furi_check(rx_size <= RX_TX_BUFFER_SIZE);
+	furi_check(rx_size <= RX_TX_BUFFER_SIZE);
 
 
-    /* decrypt if necessary */
-    if(!state->encrypted) {
-        memcpy(state->rx_str_buffer, state->rx_buffer, rx_size);
-        state->rx_str_buffer[rx_size] = 0;
+	/* decrypt if necessary */
+	if (!state->encrypted) {
+		memcpy(state->rx_str_buffer, state->rx_buffer, rx_size);
+		state->rx_str_buffer[rx_size] = 0;
 
 
-        /* remove trailing newline if it is there, for compat with CLI
+		/* remove trailing newline if it is there, for compat with CLI
 		 * Sub-GHz chat */
 		 * Sub-GHz chat */
-        if(state->rx_str_buffer[rx_size - 1] == '\n') {
-            state->rx_str_buffer[rx_size - 1] = 0;
-        }
-    } else {
-        /* if decryption fails output an error message */
-        if(!post_rx_decrypt(state, rx_size)) {
-            strcpy(state->rx_str_buffer, "ERR: Decryption failed!");
-        }
-    }
-
-    /* append message to text box and prepare message preview */
-    append_msg(state, state->rx_str_buffer);
-
-    /* send notification (make the flipper vibrate) */
-    notification_message(state->notification, &sequence_single_vibro);
+		if (state->rx_str_buffer[rx_size - 1] == '\n') {
+			state->rx_str_buffer[rx_size - 1] = 0;
+		}
+	} else {
+		/* if decryption fails output an error message */
+		if (!post_rx_decrypt(state, rx_size)) {
+			strcpy(state->rx_str_buffer, "ERR: Decryption failed!");
+		}
+	}
+
+	/* append message to text box and prepare message preview */
+	append_msg(state, state->rx_str_buffer);
+
+	/* send notification (make the flipper vibrate) */
+	notification_message(state->notification, &sequence_single_vibro);
 }
 }
 
 
 /* Reads the message from msg_input, encrypts it if necessary and then
 /* Reads the message from msg_input, encrypts it if necessary and then
  * transmits it. */
  * transmits it. */
-void tx_msg_input(ESubGhzChatState* state) {
-    /* encrypt message if necessary */
-    size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
-    size_t tx_size = msg_len;
-    if(state->encrypted) {
-        tx_size += MSG_OVERHEAD;
-        furi_check(tx_size <= sizeof(state->tx_buffer));
-
-        crypto_ctx_encrypt(
-            state->crypto_ctx,
-            (uint8_t*)furi_string_get_cstr(state->msg_input),
-            msg_len,
-            state->tx_buffer);
-    } else {
-        tx_size += 2;
-        furi_check(tx_size <= sizeof(state->tx_buffer));
-        memcpy(state->tx_buffer, furi_string_get_cstr(state->msg_input), msg_len);
-
-        /* append \r\n for compat with Sub-GHz CLI chat */
-        state->tx_buffer[msg_len] = '\r';
-        state->tx_buffer[msg_len + 1] = '\n';
-    }
-
-    /* transmit */
-    subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer, tx_size);
+void tx_msg_input(ESubGhzChatState *state)
+{
+	/* encrypt message if necessary */
+	size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
+	size_t tx_size = msg_len;
+	if (state->encrypted) {
+		tx_size += MSG_OVERHEAD;
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+
+		crypto_ctx_encrypt(state->crypto_ctx,
+				(uint8_t *)
+				furi_string_get_cstr(state->msg_input),
+				msg_len,
+				state->tx_buffer);
+	} else {
+		tx_size += 2;
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+		memcpy(state->tx_buffer,
+				furi_string_get_cstr(state->msg_input),
+				msg_len);
+
+		/* append \r\n for compat with Sub-GHz CLI chat */
+		state->tx_buffer[msg_len] = '\r';
+		state->tx_buffer[msg_len + 1] = '\n';
+	}
+
+	/* transmit */
+	subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer,
+			tx_size);
 }
 }
 
 
-/* Displays whether or not encryption has been enabled in the text box. Also
- * clears the text input buffer to remove the password and starts the Sub-GHz
- * worker. After starting the worker a join message is transmitted. */
-void enter_chat(ESubGhzChatState* state) {
-    furi_string_cat_printf(
-        state->chat_box_store, "\nEncrypted: %s", (state->encrypted ? "yes" : "no"));
+/* Displays information on frequency, encryption and radio type in the text
+ * box. Also clears the text input buffer to remove the password and starts the
+ * Sub-GHz worker. After starting the worker a join message is transmitted. */
+void enter_chat(ESubGhzChatState *state)
+{
+	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
+			state->frequency);
+
+	furi_string_cat_printf(state->chat_box_store, "\nEncrypted: %s",
+			(state->encrypted ? "yes" : "no"));
 
 
-    subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device, state->frequency);
+	subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device,
+			state->frequency);
 
 
-    if(strcmp(state->subghz_device->name, "cc1101_ext") == 0) {
-        furi_string_cat_printf(state->chat_box_store, "\nRadio: External");
-    } else {
-        furi_string_cat_printf(state->chat_box_store, "\nRadio: Internal");
-    }
+	if (strcmp(state->subghz_device->name, "cc1101_ext") == 0) {
+		furi_string_cat_printf(state->chat_box_store,
+				"\nRadio: External");
+	} else {
+		furi_string_cat_printf(state->chat_box_store,
+				"\nRadio: Internal");
+	}
 
 
-    /* concatenate the name prefix and join message */
-    furi_string_set(state->msg_input, state->name_prefix);
-    furi_string_cat_str(state->msg_input, " joined chat.");
 
 
-    /* encrypt and transmit message */
-    tx_msg_input(state);
+	/* concatenate the name prefix and join message */
+	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, " joined chat.");
 
 
-    /* clear message input buffer */
-    furi_string_set_char(state->msg_input, 0, 0);
+	/* encrypt and transmit message */
+	tx_msg_input(state);
+
+	/* clear message input buffer */
+	furi_string_set_char(state->msg_input, 0, 0);
 }
 }
 
 
 /* Sends a leave message */
 /* Sends a leave message */
-void exit_chat(ESubGhzChatState* state) {
-    /* concatenate the name prefix and leave message */
-    furi_string_set(state->msg_input, state->name_prefix);
-    furi_string_cat_str(state->msg_input, " left chat.");
+void exit_chat(ESubGhzChatState *state)
+{
+	/* concatenate the name prefix and leave message */
+	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, " left chat.");
 
 
-    /* encrypt and transmit message */
-    tx_msg_input(state);
+	/* encrypt and transmit message */
+	tx_msg_input(state);
 
 
-    /* clear message input buffer */
-    furi_string_set_char(state->msg_input, 0, 0);
+	/* clear message input buffer */
+	furi_string_set_char(state->msg_input, 0, 0);
 
 
-    /* wait for leave message to be delivered */
-    furi_delay_ms(CHAT_LEAVE_DELAY);
+	/* wait for leave message to be delivered */
+	furi_delay_ms(CHAT_LEAVE_DELAY);
 }
 }
 
 
 /* Whether or not to display the locked message. */
 /* Whether or not to display the locked message. */
-static bool kbd_lock_msg_display(ESubGhzChatState* state) {
-    return (state->kbd_lock_msg_ticks != 0);
+static bool kbd_lock_msg_display(ESubGhzChatState *state)
+{
+	return (state->kbd_lock_msg_ticks != 0);
 }
 }
 
 
 /* Whether or not to hide the locked message again. */
 /* Whether or not to hide the locked message again. */
-static bool kbd_lock_msg_reset_timeout(ESubGhzChatState* state) {
-    if(state->kbd_lock_msg_ticks == 0) {
-        return false;
-    }
+static bool kbd_lock_msg_reset_timeout(ESubGhzChatState *state)
+{
+	if (state->kbd_lock_msg_ticks == 0) {
+		return false;
+	}
 
 
-    if(furi_get_tick() - state->kbd_lock_msg_ticks > KBD_UNLOCK_TIMEOUT) {
-        return true;
-    }
+	if (furi_get_tick() - state->kbd_lock_msg_ticks > KBD_UNLOCK_TIMEOUT) {
+		return true;
+	}
 
 
-    return false;
+	return false;
 }
 }
 
 
 /* Resets the timeout for the locked message and turns off the backlight if
 /* Resets the timeout for the locked message and turns off the backlight if
  * specified. */
  * specified. */
-static void kbd_lock_msg_reset(ESubGhzChatState* state, bool backlight_off) {
-    state->kbd_lock_msg_ticks = 0;
-    state->kbd_lock_count = 0;
-
-    if(backlight_off) {
-        notification_message(state->notification, &sequence_display_backlight_off);
-    }
+static void kbd_lock_msg_reset(ESubGhzChatState *state, bool backlight_off)
+{
+	state->kbd_lock_msg_ticks = 0;
+	state->kbd_lock_count = 0;
+
+	if (backlight_off) {
+		notification_message(state->notification,
+				&sequence_display_backlight_off);
+	}
 }
 }
 
 
 /* Locks the keyboard. */
 /* Locks the keyboard. */
-static void kbd_lock(ESubGhzChatState* state) {
-    state->kbd_locked = true;
-    kbd_lock_msg_reset(state, true);
+static void kbd_lock(ESubGhzChatState *state)
+{
+	state->kbd_locked = true;
+	kbd_lock_msg_reset(state, true);
 }
 }
 
 
 /* Unlocks the keyboard. */
 /* Unlocks the keyboard. */
-static void kbd_unlock(ESubGhzChatState* state) {
-    state->kbd_locked = false;
-    kbd_lock_msg_reset(state, false);
+static void kbd_unlock(ESubGhzChatState *state)
+{
+	state->kbd_locked = false;
+	kbd_lock_msg_reset(state, false);
 }
 }
 
 
 /* Custom event callback for view dispatcher. Just calls scene manager. */
 /* Custom event callback for view dispatcher. Just calls scene manager. */
-static bool esubghz_chat_custom_event_callback(void* context, uint32_t event) {
-    FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_custom_event_callback");
-    furi_assert(context);
-    ESubGhzChatState* state = context;
-    return scene_manager_handle_custom_event(state->scene_manager, event);
+static bool esubghz_chat_custom_event_callback(void* context, uint32_t event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_custom_event_callback");
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+	return scene_manager_handle_custom_event(state->scene_manager, event);
 }
 }
 
 
 /* Navigation event callback for view dispatcher. Just calls scene manager. */
 /* Navigation event callback for view dispatcher. Just calls scene manager. */
-static bool esubghz_chat_navigation_event_callback(void* context) {
-    FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_navigation_event_callback");
-    furi_assert(context);
-    ESubGhzChatState* state = context;
-    return scene_manager_handle_back_event(state->scene_manager);
+static bool esubghz_chat_navigation_event_callback(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_navigation_event_callback");
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+	return scene_manager_handle_back_event(state->scene_manager);
 }
 }
 
 
 /* Tick event callback for view dispatcher. Called every TICK_INTERVAL. Resets
 /* Tick event callback for view dispatcher. Called every TICK_INTERVAL. Resets
  * the locked message if necessary. Retrieves a received message from the
  * the locked message if necessary. Retrieves a received message from the
  * Sub-GHz worker and calls post_rx(). Then calls the scene manager. */
  * Sub-GHz worker and calls post_rx(). Then calls the scene manager. */
-static void esubghz_chat_tick_event_callback(void* context) {
-    FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_tick_event_callback");
+static void esubghz_chat_tick_event_callback(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_tick_event_callback");
 
 
-    furi_assert(context);
-    ESubGhzChatState* state = context;
+	furi_assert(context);
+	ESubGhzChatState* state = context;
 
 
-    /* reset locked message if necessary */
-    if(kbd_lock_msg_reset_timeout(state)) {
-        kbd_lock_msg_reset(state, true);
-    }
+	/* reset locked message if necessary */
+	if (kbd_lock_msg_reset_timeout(state)) {
+		kbd_lock_msg_reset(state, true);
+	}
 
 
-    /* if the maximum message size was reached or the
+	/* if the maximum message size was reached or the
 	 * MESSAGE_COMPLETION_TIMEOUT has expired, retrieve a message and call
 	 * MESSAGE_COMPLETION_TIMEOUT has expired, retrieve a message and call
 	 * post_rx() */
 	 * post_rx() */
-    size_t avail = 0;
-    while((avail = subghz_tx_rx_worker_available(state->subghz_worker)) > 0) {
-        volatile uint32_t since_last_rx = furi_get_tick() - state->last_time_rx_data;
-        if(avail < RX_TX_BUFFER_SIZE && since_last_rx < MESSAGE_COMPLETION_TIMEOUT) {
-            break;
-        }
-
-        size_t rx_size =
-            subghz_tx_rx_worker_read(state->subghz_worker, state->rx_buffer, RX_TX_BUFFER_SIZE);
-        post_rx(state, rx_size);
-    }
-
-    /* call scene manager */
-    scene_manager_handle_tick_event(state->scene_manager);
+	size_t avail = 0;
+	while ((avail = subghz_tx_rx_worker_available(state->subghz_worker)) >
+			0) {
+		volatile uint32_t since_last_rx = furi_get_tick() -
+			state->last_time_rx_data;
+		if (avail < RX_TX_BUFFER_SIZE && since_last_rx <
+				MESSAGE_COMPLETION_TIMEOUT) {
+			break;
+		}
+
+		size_t rx_size = subghz_tx_rx_worker_read(state->subghz_worker,
+				state->rx_buffer, RX_TX_BUFFER_SIZE);
+		post_rx(state, rx_size);
+	}
+
+	/* call scene manager */
+	scene_manager_handle_tick_event(state->scene_manager);
 }
 }
 
 
 /* Hooks into the view port's draw callback to overlay the keyboard locked
 /* Hooks into the view port's draw callback to overlay the keyboard locked
  * message. */
  * message. */
-static void esubghz_hooked_draw_callback(Canvas* canvas, void* context) {
-    FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_draw_callback");
-
-    furi_assert(canvas);
-
-    furi_assert(context);
-    ESubGhzChatState* state = context;
-
-    /* call original callback */
-    state->orig_draw_cb(canvas, state->view_dispatcher);
-
-    /* display if the keyboard is locked */
-    if(state->kbd_locked) {
-        canvas_set_font(canvas, FontPrimary);
-        elements_multiline_text_framed(canvas, 42, 30, "Locked");
-    }
-
-    /* display the unlock message if necessary */
-    if(kbd_lock_msg_display(state)) {
-        canvas_set_font(canvas, FontSecondary);
-        elements_bold_rounded_frame(canvas, 14, 8, 99, 48);
-        elements_multiline_text(canvas, 65, 26, "To unlock\npress:");
-        canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8);
-        canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8);
-        canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8);
-        canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42);
-    }
+static void esubghz_hooked_draw_callback(Canvas* canvas, void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_draw_callback");
+
+	furi_assert(canvas);
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	/* call original callback */
+	state->orig_draw_cb(canvas, state->view_dispatcher);
+
+	/* display if the keyboard is locked */
+	if (state->kbd_locked) {
+		canvas_set_font(canvas, FontPrimary);
+		elements_multiline_text_framed(canvas, 42, 30, "Locked");
+	}
+
+	/* display the unlock message if necessary */
+	if (kbd_lock_msg_display(state)) {
+		canvas_set_font(canvas, FontSecondary);
+		elements_bold_rounded_frame(canvas, 14, 8, 99, 48);
+		elements_multiline_text(canvas, 65, 26, "To unlock\npress:");
+		canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8);
+		canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8);
+		canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8);
+		canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42);
+	}
 }
 }
 
 
 /* Hooks into the view port's input callback to handle the user locking the
 /* Hooks into the view port's input callback to handle the user locking the
  * keyboard. */
  * keyboard. */
-static void esubghz_hooked_input_callback(InputEvent* event, void* context) {
-    FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_input_callback");
+static void esubghz_hooked_input_callback(InputEvent* event, void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_input_callback");
 
 
-    furi_assert(event);
+	furi_assert(event);
 
 
-    furi_assert(context);
-    ESubGhzChatState* state = context;
+	furi_assert(context);
+	ESubGhzChatState* state = context;
 
 
-    /* if the keyboard is locked no key presses are forwarded */
-    if(state->kbd_locked) {
-        /* key has been pressed, display the unlock message and
+	/* if the keyboard is locked no key presses are forwarded */
+	if (state->kbd_locked) {
+		/* key has been pressed, display the unlock message and
 		 * initiate the timer */
 		 * initiate the timer */
-        if(state->kbd_lock_count == 0) {
-            state->kbd_lock_msg_ticks = furi_get_tick();
-        }
-
-        /* back button has been pressed, increase the lock counter */
-        if(event->key == InputKeyBack && event->type == InputTypeShort) {
-            state->kbd_lock_count++;
-        }
-
-        /* unlock the keyboard */
-        if(state->kbd_lock_count >= KBD_UNLOCK_CNT) {
-            kbd_unlock(state);
-        }
-
-        /* do not handle the event */
-        return;
-    }
-
-    if(event->key == InputKeyOk) {
-        /* if we are in the chat view and no input is ongoing, allow
+		if (state->kbd_lock_count == 0) {
+			state->kbd_lock_msg_ticks = furi_get_tick();
+		}
+
+		/* back button has been pressed, increase the lock counter */
+		if (event->key == InputKeyBack && event->type ==
+				InputTypeShort) {
+			state->kbd_lock_count++;
+		}
+
+		/* unlock the keyboard */
+		if (state->kbd_lock_count >= KBD_UNLOCK_CNT) {
+			kbd_unlock(state);
+		}
+
+		/* do not handle the event */
+		return;
+	}
+
+	if (event->key == InputKeyOk) {
+		/* if we are in the chat view and no input is ongoing, allow
 		 * locking */
 		 * locking */
-        if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) &&
-           !(state->kbd_ok_input_ongoing)) {
-            /* lock keyboard upon long press of Ok button */
-            if(event->type == InputTypeLong) {
-                kbd_lock(state);
-            }
-
-            /* do not handle any Ok key events to prevent blocking
+		if (state->view_dispatcher->current_view ==
+				text_box_get_view(state->chat_box) &&
+				!(state->kbd_ok_input_ongoing)) {
+			/* lock keyboard upon long press of Ok button */
+			if (event->type == InputTypeLong) {
+				kbd_lock(state);
+			}
+
+			/* do not handle any Ok key events to prevent blocking
 			 * of other keys */
 			 * of other keys */
-            return;
-        }
-
-        /* handle ongoing inputs when changing to chat view */
-        if(event->type == InputTypePress) {
-            state->kbd_ok_input_ongoing = true;
-        } else if(event->type == InputTypeRelease) {
-            state->kbd_ok_input_ongoing = false;
-        }
-    }
-
-    if(event->key == InputKeyLeft) {
-        /* if we are in the chat view and no input is ongoing, allow
+			return;
+		}
+
+		/* handle ongoing inputs when changing to chat view */
+		if (event->type == InputTypePress) {
+			state->kbd_ok_input_ongoing = true;
+		} else if (event->type == InputTypeRelease) {
+			state->kbd_ok_input_ongoing = false;
+		}
+	}
+
+	if (event->key == InputKeyLeft) {
+		/* if we are in the chat view and no input is ongoing, allow
 		 * switching to msg input */
 		 * 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
+		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 */
 			 * 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
+			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 */
 		 * 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 (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);
-            }
+			if (event->type == InputTypeShort) {
+				view_dispatcher_send_custom_event(state->view_dispatcher,
+						ESubGhzChatEvent_GotoKeyDisplay);
+			}
 
 
-            /* do not handle any Right key events to prevent
+			/* do not handle any Right key events to prevent
 			 * blocking of other keys */
 			 * 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);
+			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);
 }
 }
 
 
-static bool helper_strings_alloc(ESubGhzChatState* state) {
-    furi_assert(state);
+static bool helper_strings_alloc(ESubGhzChatState *state)
+{
+	furi_assert(state);
 
 
-    state->name_prefix = furi_string_alloc();
-    if(state->name_prefix == NULL) {
-        return false;
-    }
+	state->name_prefix = furi_string_alloc();
+	if (state->name_prefix == NULL) {
+		return false;
+	}
 
 
-    state->msg_input = furi_string_alloc();
-    if(state->msg_input == NULL) {
-        furi_string_free(state->name_prefix);
-        return false;
-    }
+	state->msg_input = furi_string_alloc();
+	if (state->msg_input == NULL) {
+		furi_string_free(state->name_prefix);
+		return false;
+	}
 
 
-    return true;
+	return true;
 }
 }
 
 
-static void helper_strings_free(ESubGhzChatState* state) {
-    furi_assert(state);
+static void helper_strings_free(ESubGhzChatState *state)
+{
+	furi_assert(state);
 
 
-    furi_string_free(state->name_prefix);
-    furi_string_free(state->msg_input);
+	furi_string_free(state->name_prefix);
+	furi_string_free(state->msg_input);
 }
 }
 
 
-static bool chat_box_alloc(ESubGhzChatState* state) {
-    furi_assert(state);
+static bool chat_box_alloc(ESubGhzChatState *state)
+{
+	furi_assert(state);
 
 
-    state->chat_box = text_box_alloc();
-    if(state->chat_box == NULL) {
-        return false;
-    }
+	state->chat_box = text_box_alloc();
+	if (state->chat_box == NULL) {
+		return false;
+	}
 
 
-    state->chat_box_store = furi_string_alloc();
-    if(state->chat_box_store == NULL) {
-        text_box_free(state->chat_box);
-        return false;
-    }
+	state->chat_box_store = furi_string_alloc();
+	if (state->chat_box_store == NULL) {
+		text_box_free(state->chat_box);
+		return false;
+	}
 
 
-    furi_string_reserve(state->chat_box_store, CHAT_BOX_STORE_SIZE);
-    furi_string_set_char(state->chat_box_store, 0, 0);
-    text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store));
-    text_box_set_focus(state->chat_box, TextBoxFocusEnd);
+	furi_string_reserve(state->chat_box_store, CHAT_BOX_STORE_SIZE);
+	furi_string_set_char(state->chat_box_store, 0, 0);
+	text_box_set_text(state->chat_box,
+			furi_string_get_cstr(state->chat_box_store));
+	text_box_set_focus(state->chat_box, TextBoxFocusEnd);
 
 
-    return true;
+	return true;
 }
 }
 
 
-static void chat_box_free(ESubGhzChatState* state) {
-    furi_assert(state);
+static void chat_box_free(ESubGhzChatState *state)
+{
+	furi_assert(state);
 
 
-    text_box_free(state->chat_box);
-    furi_string_free(state->chat_box_store);
+	text_box_free(state->chat_box);
+	furi_string_free(state->chat_box_store);
 }
 }
 
 
-int32_t esubghz_chat(void) {
-    /* init the crypto system */
-    crypto_init();
-
-    int32_t err = -1;
-
-    FURI_LOG_I(APPLICATION_NAME, "Starting...");
-
-    /* allocate necessary structs and buffers */
-
-    ESubGhzChatState* state = malloc(sizeof(ESubGhzChatState));
-    if(state == NULL) {
-        goto err_alloc;
-    }
-    memset(state, 0, sizeof(*state));
-
-    state->scene_manager = scene_manager_alloc(&esubghz_chat_scene_event_handlers, state);
-    if(state->scene_manager == NULL) {
-        goto err_alloc_sm;
-    }
-
-    state->view_dispatcher = view_dispatcher_alloc();
-    if(state->view_dispatcher == NULL) {
-        goto err_alloc_vd;
-    }
-
-    if(!helper_strings_alloc(state)) {
-        goto err_alloc_hs;
-    }
-
-    state->menu = menu_alloc();
-    if(state->menu == NULL) {
-        goto err_alloc_menu;
-    }
-
-    state->text_input = text_input_alloc();
-    if(state->text_input == NULL) {
-        goto err_alloc_ti;
-    }
-
-    state->hex_key_input = byte_input_alloc();
-    if(state->hex_key_input == NULL) {
-        goto err_alloc_hki;
-    }
-
-    if(!chat_box_alloc(state)) {
-        goto err_alloc_cb;
-    }
-
-    state->key_display = dialog_ex_alloc();
-    if(state->key_display == NULL) {
-        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;
-    }
-
-    /* set the have_read callback of the Sub-GHz worker */
-    subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker, have_read_cb, state);
-
-    /* enter suppress charge mode */
-    furi_hal_power_suppress_charge_enter();
-
-    /* init internal device */
-    subghz_devices_init();
-
-    state->subghz_device =
-        radio_device_loader_set(state->subghz_device, SubGhzRadioDeviceTypeExternalCC1101);
-
-    subghz_devices_reset(state->subghz_device);
-    subghz_devices_idle(state->subghz_device);
-
-    /* set chat name prefix */
-    furi_string_printf(state->name_prefix, "%s", furi_hal_version_get_name_ptr());
-
-    /* get notification record, we use this to make the flipper vibrate */
-    /* no error handling here, don't know how */
-    state->notification = furi_record_open(RECORD_NOTIFICATION);
-
-    /* hook into the view port's draw and input callbacks */
-    state->orig_draw_cb = state->view_dispatcher->view_port->draw_callback;
-    state->orig_input_cb = state->view_dispatcher->view_port->input_callback;
-    view_port_draw_callback_set(
-        state->view_dispatcher->view_port, esubghz_hooked_draw_callback, state);
-    view_port_input_callback_set(
-        state->view_dispatcher->view_port, esubghz_hooked_input_callback, state);
-
-    view_dispatcher_enable_queue(state->view_dispatcher);
-
-    /* set callbacks for view dispatcher */
-    view_dispatcher_set_event_callback_context(state->view_dispatcher, state);
-    view_dispatcher_set_custom_event_callback(
-        state->view_dispatcher, esubghz_chat_custom_event_callback);
-    view_dispatcher_set_navigation_event_callback(
-        state->view_dispatcher, esubghz_chat_navigation_event_callback);
-    view_dispatcher_set_tick_event_callback(
-        state->view_dispatcher, esubghz_chat_tick_event_callback, TICK_INTERVAL);
-
-    /* add our two views to the view dispatcher */
-    view_dispatcher_add_view(
-        state->view_dispatcher, ESubGhzChatView_Menu, menu_get_view(state->menu));
-    view_dispatcher_add_view(
-        state->view_dispatcher, ESubGhzChatView_Input, text_input_get_view(state->text_input));
-    view_dispatcher_add_view(
-        state->view_dispatcher,
-        ESubGhzChatView_HexKeyInput,
-        byte_input_get_view(state->hex_key_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));
-    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 */
-    Gui* gui = furi_record_open(RECORD_GUI);
-    view_dispatcher_attach_to_gui(state->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
-
-    /* switch to the frequency input scene */
-    scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
-
-    /* run the view dispatcher, this call only returns when we close the
+int32_t esubghz_chat(void)
+{
+	/* init the crypto system */
+	crypto_init();
+
+	int32_t err = -1;
+
+	FURI_LOG_I(APPLICATION_NAME, "Starting...");
+
+	/* allocate necessary structs and buffers */
+
+	ESubGhzChatState *state = malloc(sizeof(ESubGhzChatState));
+	if (state == NULL) {
+		goto err_alloc;
+	}
+	memset(state, 0, sizeof(*state));
+
+	state->scene_manager = scene_manager_alloc(
+			&esubghz_chat_scene_event_handlers, state);
+	if (state->scene_manager == NULL) {
+		goto err_alloc_sm;
+	}
+
+	state->view_dispatcher = view_dispatcher_alloc();
+	if (state->view_dispatcher == NULL) {
+		goto err_alloc_vd;
+	}
+
+	if (!helper_strings_alloc(state)) {
+		goto err_alloc_hs;
+	}
+
+	state->menu = menu_alloc();
+	if (state->menu == NULL) {
+		goto err_alloc_menu;
+	}
+
+	state->text_input = text_input_alloc();
+	if (state->text_input == NULL) {
+		goto err_alloc_ti;
+	}
+
+	state->hex_key_input = byte_input_alloc();
+	if (state->hex_key_input == NULL) {
+		goto err_alloc_hki;
+	}
+
+	if (!chat_box_alloc(state)) {
+		goto err_alloc_cb;
+	}
+
+	state->key_display = dialog_ex_alloc();
+	if (state->key_display == NULL) {
+		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;
+	}
+
+	/* set the have_read callback of the Sub-GHz worker */
+	subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker,
+			have_read_cb, state);
+
+	/* enter suppress charge mode */
+	furi_hal_power_suppress_charge_enter();
+
+	/* init internal device */
+	subghz_devices_init();
+
+	state->subghz_device = radio_device_loader_set(state->subghz_device,
+			SubGhzRadioDeviceTypeExternalCC1101);
+
+	subghz_devices_reset(state->subghz_device);
+	subghz_devices_idle(state->subghz_device);
+
+	/* set chat name prefix */
+	furi_string_printf(state->name_prefix, "%s",
+			furi_hal_version_get_name_ptr());
+
+	/* get notification record, we use this to make the flipper vibrate */
+	/* no error handling here, don't know how */
+	state->notification = furi_record_open(RECORD_NOTIFICATION);
+
+	/* hook into the view port's draw and input callbacks */
+	state->orig_draw_cb = state->view_dispatcher->view_port->draw_callback;
+	state->orig_input_cb = state->view_dispatcher->view_port->input_callback;
+	view_port_draw_callback_set(state->view_dispatcher->view_port,
+			esubghz_hooked_draw_callback, state);
+	view_port_input_callback_set(state->view_dispatcher->view_port,
+			esubghz_hooked_input_callback, state);
+
+	view_dispatcher_enable_queue(state->view_dispatcher);
+
+	/* set callbacks for view dispatcher */
+	view_dispatcher_set_event_callback_context(state->view_dispatcher, state);
+	view_dispatcher_set_custom_event_callback(
+			state->view_dispatcher,
+			esubghz_chat_custom_event_callback);
+	view_dispatcher_set_navigation_event_callback(
+			state->view_dispatcher,
+			esubghz_chat_navigation_event_callback);
+	view_dispatcher_set_tick_event_callback(
+			state->view_dispatcher,
+			esubghz_chat_tick_event_callback,
+			TICK_INTERVAL);
+
+	/* add our two views to the view dispatcher */
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_Menu,
+			menu_get_view(state->menu));
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_Input,
+			text_input_get_view(state->text_input));
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput,
+			byte_input_get_view(state->hex_key_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));
+	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 */
+	Gui *gui = furi_record_open(RECORD_GUI);
+	view_dispatcher_attach_to_gui(state->view_dispatcher, gui,
+			ViewDispatcherTypeFullscreen);
+
+	/* switch to the frequency input scene */
+	scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
+
+	/* run the view dispatcher, this call only returns when we close the
 	 * application */
 	 * application */
-    view_dispatcher_run(state->view_dispatcher);
+	view_dispatcher_run(state->view_dispatcher);
 
 
-    /* if it is running, stop the Sub-GHz worker */
-    if(subghz_tx_rx_worker_is_running(state->subghz_worker)) {
-        exit_chat(state);
-        subghz_tx_rx_worker_stop(state->subghz_worker);
-    }
+	/* if it is running, stop the Sub-GHz worker */
+	if (subghz_tx_rx_worker_is_running(state->subghz_worker)) {
+		exit_chat(state);
+		subghz_tx_rx_worker_stop(state->subghz_worker);
+	}
 
 
-    /* if it is running, stop the NFC worker */
-    nfc_worker_stop(state->nfc_worker);
+	/* if it is running, stop the NFC worker */
+	nfc_worker_stop(state->nfc_worker);
 
 
-    err = 0;
+	err = 0;
 
 
-    /* close GUI record */
-    furi_record_close(RECORD_GUI);
+	/* close GUI record */
+	furi_record_close(RECORD_GUI);
 
 
-    /* remove our two views from the view dispatcher */
-    view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_Menu);
-    view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_Input);
-    view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput);
-    view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_ChatBox);
-    view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay);
-    view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_NfcPopup);
+	/* remove our two views from the view dispatcher */
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_Menu);
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_Input);
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_HexKeyInput);
+	view_dispatcher_remove_view(state->view_dispatcher,
+			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);
+	/* close notification record */
+	furi_record_close(RECORD_NOTIFICATION);
 
 
-    /* clear the key and potential password */
-    crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store));
-    crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store));
-    crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str));
-    crypto_ctx_clear(state->crypto_ctx);
+	/* clear the key and potential password */
+	crypto_explicit_bzero(state->text_input_store,
+			sizeof(state->text_input_store));
+	crypto_explicit_bzero(state->hex_key_input_store,
+			sizeof(state->hex_key_input_store));
+	crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str));
+	crypto_ctx_clear(state->crypto_ctx);
 
 
-    /* clear nfc data */
-    if(state->nfc_dev_data->parsed_data != NULL) {
-        furi_string_free(state->nfc_dev_data->parsed_data);
-    }
-    crypto_explicit_bzero(state->nfc_dev_data, sizeof(NfcDeviceData));
+	/* clear nfc data */
+	if (state->nfc_dev_data->parsed_data != NULL) {
+		furi_string_free(state->nfc_dev_data->parsed_data);
+	}
+	crypto_explicit_bzero(state->nfc_dev_data, sizeof(NfcDeviceData));
 
 
-    /* deinit devices */
-    radio_device_loader_end(state->subghz_device);
+	/* deinit devices */
+	radio_device_loader_end(state->subghz_device);
 
 
-    subghz_devices_deinit();
+	subghz_devices_deinit();
 
 
-    /* exit suppress charge mode */
-    furi_hal_power_suppress_charge_exit();
+	/* exit suppress charge mode */
+	furi_hal_power_suppress_charge_exit();
 
 
-    /* free everything we allocated */
+	/* free everything we allocated */
 
 
-    crypto_ctx_free(state->crypto_ctx);
+	crypto_ctx_free(state->crypto_ctx);
 
 
 err_alloc_crypto:
 err_alloc_crypto:
-    free(state->nfc_dev_data);
+	free(state->nfc_dev_data);
 
 
 err_alloc_ndevdata:
 err_alloc_ndevdata:
-    nfc_worker_free(state->nfc_worker);
+	nfc_worker_free(state->nfc_worker);
 
 
 err_alloc_nworker:
 err_alloc_nworker:
-    subghz_tx_rx_worker_free(state->subghz_worker);
+	subghz_tx_rx_worker_free(state->subghz_worker);
 
 
 err_alloc_worker:
 err_alloc_worker:
-    popup_free(state->nfc_popup);
+	popup_free(state->nfc_popup);
 
 
 err_alloc_np:
 err_alloc_np:
-    dialog_ex_free(state->key_display);
+	dialog_ex_free(state->key_display);
 
 
 err_alloc_kd:
 err_alloc_kd:
-    chat_box_free(state);
+	chat_box_free(state);
 
 
 err_alloc_cb:
 err_alloc_cb:
-    byte_input_free(state->hex_key_input);
+	byte_input_free(state->hex_key_input);
 
 
 err_alloc_hki:
 err_alloc_hki:
-    text_input_free(state->text_input);
+	text_input_free(state->text_input);
 
 
 err_alloc_ti:
 err_alloc_ti:
-    menu_free(state->menu);
+	menu_free(state->menu);
 
 
 err_alloc_menu:
 err_alloc_menu:
-    helper_strings_free(state);
+	helper_strings_free(state);
 
 
 err_alloc_hs:
 err_alloc_hs:
-    view_dispatcher_free(state->view_dispatcher);
+	view_dispatcher_free(state->view_dispatcher);
 
 
 err_alloc_vd:
 err_alloc_vd:
-    scene_manager_free(state->scene_manager);
+	scene_manager_free(state->scene_manager);
 
 
 err_alloc_sm:
 err_alloc_sm:
-    free(state);
+	free(state);
 
 
 err_alloc:
 err_alloc:
-    if(err != 0) {
-        FURI_LOG_E(APPLICATION_NAME, "Failed to launch (alloc error)!");
-    } else {
-        FURI_LOG_I(APPLICATION_NAME, "Clean exit.");
-    }
+	if (err != 0) {
+		FURI_LOG_E(APPLICATION_NAME, "Failed to launch (alloc error)!");
+	} else {
+		FURI_LOG_I(APPLICATION_NAME, "Clean exit.");
+	}
 
 
-    return err;
+	return err;
 }
 }

+ 0 - 0
non_catalog_apps/esubghz_chat/nfc_helpers.h → non_catalog_apps/esubghz_chat/helpers/nfc_helpers.h


+ 1 - 5
non_catalog_apps/esubghz_chat/scenes/esubghz_chat_freq_input.c

@@ -1,15 +1,11 @@
 #include "../esubghz_chat_i.h"
 #include "../esubghz_chat_i.h"
 
 
-/* Sends FreqEntered event to scene manager and displays the frequency in the
- * text box. */
+/* Sends FreqEntered event to scene manager. */
 static void freq_input_cb(void *context)
 static void freq_input_cb(void *context)
 {
 {
 	furi_assert(context);
 	furi_assert(context);
 	ESubGhzChatState* state = context;
 	ESubGhzChatState* state = context;
 
 
-	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
-			state->frequency);
-
 	view_dispatcher_send_custom_event(state->view_dispatcher,
 	view_dispatcher_send_custom_event(state->view_dispatcher,
 			ESubGhzChatEvent_FreqEntered);
 			ESubGhzChatEvent_FreqEntered);
 }
 }

+ 5 - 5
non_catalog_apps/esubghz_chat/scenes/esubghz_chat_key_menu.c

@@ -81,7 +81,7 @@ void scene_on_enter_key_menu(void* context)
 	menu_add_item(
 	menu_add_item(
 		state->menu,
 		state->menu,
 		"No encryption",
 		"No encryption",
-		NULL,
+		&I_chat_10px,
 		ESubGhzChatKeyMenuItems_NoEncryption,
 		ESubGhzChatKeyMenuItems_NoEncryption,
 		key_menu_cb,
 		key_menu_cb,
 		state
 		state
@@ -89,7 +89,7 @@ void scene_on_enter_key_menu(void* context)
 	menu_add_item(
 	menu_add_item(
 		state->menu,
 		state->menu,
 		"Password",
 		"Password",
-		NULL,
+		&I_keyboard_10px,
 		ESubGhzChatKeyMenuItems_Password,
 		ESubGhzChatKeyMenuItems_Password,
 		key_menu_cb,
 		key_menu_cb,
 		state
 		state
@@ -97,7 +97,7 @@ void scene_on_enter_key_menu(void* context)
 	menu_add_item(
 	menu_add_item(
 		state->menu,
 		state->menu,
 		"Hex Key",
 		"Hex Key",
-		NULL,
+		&I_hex_10px,
 		ESubGhzChatKeyMenuItems_HexKey,
 		ESubGhzChatKeyMenuItems_HexKey,
 		key_menu_cb,
 		key_menu_cb,
 		state
 		state
@@ -105,7 +105,7 @@ void scene_on_enter_key_menu(void* context)
 	menu_add_item(
 	menu_add_item(
 		state->menu,
 		state->menu,
 		"Generate Key",
 		"Generate Key",
-		NULL,
+		&I_u2f_10px,
 		ESubGhzChatKeyMenuItems_GenKey,
 		ESubGhzChatKeyMenuItems_GenKey,
 		key_menu_cb,
 		key_menu_cb,
 		state
 		state
@@ -113,7 +113,7 @@ void scene_on_enter_key_menu(void* context)
 	menu_add_item(
 	menu_add_item(
 		state->menu,
 		state->menu,
 		"Read Key from NFC",
 		"Read Key from NFC",
-		NULL,
+		&I_Nfc_10px,
 		ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
 		ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
 		key_menu_cb,
 		key_menu_cb,
 		state
 		state

+ 1 - 1
non_catalog_apps/esubghz_chat/scenes/esubghz_chat_key_read_popup.c

@@ -1,5 +1,5 @@
 #include "../esubghz_chat_i.h"
 #include "../esubghz_chat_i.h"
-#include "../nfc_helpers.h"
+#include "../helpers/nfc_helpers.h"
 
 
 typedef enum {
 typedef enum {
 	KeyReadPopupState_Idle,
 	KeyReadPopupState_Idle,

+ 1 - 1
non_catalog_apps/esubghz_chat/scenes/esubghz_chat_key_share_popup.c

@@ -1,5 +1,5 @@
 #include "../esubghz_chat_i.h"
 #include "../esubghz_chat_i.h"
-#include "../nfc_helpers.h"
+#include "../helpers/nfc_helpers.h"
 
 
 struct ReplayDictNfcWriterContext {
 struct ReplayDictNfcWriterContext {
 	uint8_t *cur;
 	uint8_t *cur;