Update apps

This commit is contained in:
Willy-JL
2023-08-30 18:59:32 +02:00
parent 160ab755a2
commit ee37769ee2
308 changed files with 2314 additions and 801 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 bigbrodude6119
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -6,7 +6,9 @@ App(
cdefines=["APP_EVIL_PORTAL"],
requires=["gui"],
stack_size=1 * 1024,
order=90,
fap_author="bigbrodude6119",
fap_description="Create an evil captive portal Wi-Fi access point",
fap_icon_assets="icons",
fap_icon="icons/evil_portal_10px.png",
fap_category="WiFi",
)

View File

@@ -32,10 +32,15 @@ Evil_PortalApp* evil_portal_app_alloc() {
app->command_index = 0;
app->portal_logs = furi_string_alloc();
app->gui = furi_record_open(RECORD_GUI);
app->dialogs = furi_record_open(RECORD_DIALOGS);
app->file_path = furi_string_alloc();
app->gui = furi_record_open(RECORD_GUI);
app->view_dispatcher = view_dispatcher_alloc();
app->loading = loading_alloc();
app->scene_manager = scene_manager_alloc(&evil_portal_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
@@ -49,12 +54,18 @@ Evil_PortalApp* evil_portal_app_alloc() {
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
app->view_stack = view_stack_alloc();
app->var_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
Evil_PortalAppViewVarItemList,
variable_item_list_get_view(app->var_item_list));
app->text_input = text_input_alloc();
view_dispatcher_add_view(
app->view_dispatcher, Evil_PortalAppViewTextInput, text_input_get_view(app->text_input));
for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
app->selected_option_index[i] = 0;
}
@@ -89,6 +100,10 @@ void evil_portal_app_free(Evil_PortalApp* app) {
text_box_free(app->text_box);
furi_string_free(app->text_box_store);
text_input_free(app->text_input);
view_stack_free(app->view_stack);
loading_free(app->loading);
// View dispatcher
view_dispatcher_free(app->view_dispatcher);
@@ -98,36 +113,32 @@ void evil_portal_app_free(Evil_PortalApp* app) {
// Close records
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_DIALOGS);
furi_string_free(app->file_path);
free(app);
}
int32_t evil_portal_app(void* p) {
UNUSED(p);
Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
// turn off 5v, so it gets reset on startup
if(furi_hal_power_is_otg_enabled()) {
furi_hal_power_disable_otg();
}
// Enable 5v on startup
uint8_t attempts = 0;
bool otg_was_enabled = furi_hal_power_is_otg_enabled();
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
furi_hal_power_enable_otg();
furi_delay_ms(10);
}
furi_delay_ms(200);
Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
evil_portal_app->uart = evil_portal_uart_init(evil_portal_app);
view_dispatcher_run(evil_portal_app->view_dispatcher);
evil_portal_app_free(evil_portal_app);
if(furi_hal_power_is_otg_enabled()) {
if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) {
furi_hal_power_disable_otg();
}

View File

@@ -8,4 +8,4 @@ typedef struct Evil_PortalApp Evil_PortalApp;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -4,19 +4,22 @@
#include "evil_portal_custom_event.h"
#include "evil_portal_uart.h"
#include "scenes/evil_portal_scene.h"
#include "evil_portal_icons.h"
#include <assets_icons.h>
#include <gui/gui.h>
#include <gui/modules/loading.h>
#include <gui/modules/text_box.h>
#include <gui/modules/text_input.h>
#include <gui/modules/variable_item_list.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include <assets_icons.h>
#include <gui/view_stack.h>
#include <dialogs/dialogs.h>
#include <xtreme.h>
#define NUM_MENU_ITEMS (4)
#define NUM_MENU_ITEMS (6)
#define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096)
#define UART_CH \
@@ -27,14 +30,13 @@
#define SET_AP_CMD "setap"
#define RESET_CMD "reset"
#define EVIL_PORTAL_INDEX_EXTENSION ".html"
#define EVIL_PORTAL_BASE_FOLDER STORAGE_APP_DATA_PATH_PREFIX
#define HTML_EXTENSION ".html"
#define HTML_FOLDER APP_DATA_PATH("html")
struct Evil_PortalApp {
Gui* gui;
ViewDispatcher* view_dispatcher;
SceneManager* scene_manager;
DialogsApp* dialogs;
FuriString* portal_logs;
const char* command_queue[1];
@@ -47,6 +49,11 @@ struct Evil_PortalApp {
VariableItemList* var_item_list;
Evil_PortalUart* uart;
TextInput* text_input;
DialogsApp* dialogs;
FuriString* file_path;
Loading* loading;
ViewStack* view_stack;
int selected_menu_index;
int selected_option_index[NUM_MENU_ITEMS];
@@ -59,6 +66,7 @@ struct Evil_PortalApp {
bool sent_html;
bool sent_reset;
int BAUDRATE;
char text_store[2][128 + 1];
uint8_t* index_html;
uint8_t* ap_name;
@@ -68,4 +76,5 @@ typedef enum {
Evil_PortalAppViewVarItemList,
Evil_PortalAppViewConsoleOutput,
Evil_PortalAppViewStartPortal,
Evil_PortalAppViewTextInput,
} Evil_PortalAppView;

View File

@@ -5,4 +5,5 @@ typedef enum {
Evil_PortalEventStartConsole,
Evil_PortalEventStartKeyboard,
Evil_PortalEventStartPortal,
Evil_PortalEventTextInput,
} Evil_PortalCustomEvent;

View File

@@ -8,31 +8,21 @@ static void evil_portal_close_storage() {
furi_record_close(RECORD_STORAGE);
}
bool evil_portal_read_index_html(void* context) {
FuriString* file_path = furi_string_alloc_set(EVIL_PORTAL_BASE_FOLDER);
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
&browser_options,
EVIL_PORTAL_INDEX_EXTENSION,
NULL); // TODO configure icon
browser_options.base_path = EVIL_PORTAL_BASE_FOLDER;
void evil_portal_read_index_html(void* context) {
Evil_PortalApp* app = context;
bool res = dialog_file_browser_show(app->dialogs, file_path, file_path, &browser_options);
if(!res) {
furi_string_free(file_path);
return false;
}
Storage* storage = evil_portal_open_storage();
FileInfo fi;
if(storage_common_stat(storage, furi_string_get_cstr(file_path), &fi) == FSE_OK) {
if(!storage_common_exists(storage, EVIL_PORTAL_INDEX_SAVE_PATH)) {
FuriString* tmp = furi_string_alloc_set(EVIL_PORTAL_INDEX_DEFAULT_PATH);
evil_portal_replace_index_html(tmp);
furi_string_free(tmp);
}
if(storage_common_stat(storage, EVIL_PORTAL_INDEX_SAVE_PATH, &fi) == FSE_OK) {
File* index_html = storage_file_alloc(storage);
if(storage_file_open(
index_html, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
index_html, EVIL_PORTAL_INDEX_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
app->index_html = malloc((size_t)fi.size);
uint8_t* buf_ptr = app->index_html;
size_t read = 0;
@@ -45,7 +35,6 @@ bool evil_portal_read_index_html(void* context) {
}
free(buf_ptr);
}
furi_string_free(file_path);
storage_file_close(index_html);
storage_file_free(index_html);
} else {
@@ -57,7 +46,33 @@ bool evil_portal_read_index_html(void* context) {
}
evil_portal_close_storage();
return true;
}
void evil_portal_replace_index_html(FuriString* path) {
Storage* storage = evil_portal_open_storage();
FS_Error error;
error = storage_common_remove(storage, EVIL_PORTAL_INDEX_SAVE_PATH);
if(error != FSE_OK) {
FURI_LOG_D("EVIL PORTAL", "Error removing file");
} else {
FURI_LOG_D("EVIL PORTAL", "Error removed file");
}
error = storage_common_copy(storage, furi_string_get_cstr(path), EVIL_PORTAL_INDEX_SAVE_PATH);
if(error != FSE_OK) {
FURI_LOG_D("EVIL PORTAL", "Error copying file");
}
evil_portal_close_storage();
}
void evil_portal_create_html_folder_if_not_exists() {
Storage* storage = evil_portal_open_storage();
if(storage_common_stat(storage, HTML_FOLDER, NULL) == FSE_NOT_EXIST) {
FURI_LOG_D("Evil Portal", "Directory %s doesn't exist. Will create new.", HTML_FOLDER);
if(!storage_simply_mkdir(storage, HTML_FOLDER)) {
FURI_LOG_E("Evil Portal", "Error creating directory %s", HTML_FOLDER);
}
}
evil_portal_close_storage();
}
void evil_portal_read_ap_name(void* context) {
@@ -89,6 +104,19 @@ void evil_portal_read_ap_name(void* context) {
evil_portal_close_storage();
}
void evil_portal_write_ap_name(void* context) {
Evil_PortalApp* app = context;
Storage* storage = evil_portal_open_storage();
File* ap_name = storage_file_alloc(storage);
if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
storage_file_write(ap_name, app->text_store[0], strlen(app->text_store[0]));
}
storage_file_close(ap_name);
storage_file_free(ap_name);
evil_portal_close_storage();
}
char* sequential_file_resolve_path(
Storage* storage,
const char* dir,

View File

@@ -1,5 +1,4 @@
#include "../evil_portal_app_i.h"
#include <dialogs/dialogs.h>
#include <flipper_format/flipper_format_i.h>
#include <lib/toolbox/stream/file_stream.h>
#include <stdlib.h>
@@ -8,11 +7,15 @@
#define PORTAL_FILE_DIRECTORY_PATH EXT_PATH("apps_data/evil_portal")
#define EVIL_PORTAL_INDEX_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/index.html"
#define EVIL_PORTAL_INDEX_DEFAULT_PATH PORTAL_FILE_DIRECTORY_PATH "/html/xtreme.html"
#define EVIL_PORTAL_AP_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/ap.config.txt"
#define EVIL_PORTAL_LOG_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/logs"
bool evil_portal_read_index_html(void* context);
void evil_portal_read_index_html(void* context);
void evil_portal_read_ap_name(void* context);
void evil_portal_write_ap_name(void* context);
void evil_portal_replace_index_html(FuriString* path);
void evil_portal_create_html_folder_if_not_exists();
void write_logs(FuriString* portal_logs);
char* sequential_file_resolve_path(
Storage* storage,

View File

@@ -1,2 +1,4 @@
ADD_SCENE(evil_portal, start, Start)
ADD_SCENE(evil_portal, console_output, ConsoleOutput)
ADD_SCENE(evil_portal, rename, Rename)
ADD_SCENE(evil_portal, select_html, SelectHtml)

View File

@@ -22,8 +22,6 @@ void evil_portal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void
void evil_portal_scene_console_output_on_enter(void* context) {
Evil_PortalApp* app = context;
bool portal_file_set = false;
TextBox* text_box = app->text_box;
text_box_reset(app->text_box);
text_box_set_font(text_box, TextBoxFontText);
@@ -64,25 +62,24 @@ void evil_portal_scene_console_output_on_enter(void* context) {
}
}
if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
portal_file_set = evil_portal_read_index_html(context);
if(0 == strncmp("setapname", app->selected_tx_string, strlen("setapname"))) {
scene_manager_next_scene(app->scene_manager, Evil_PortalSceneRename);
return;
}
if(portal_file_set) {
app->command_queue[0] = SET_AP_CMD;
app->has_command_queue = true;
app->command_index = 0;
if(app->show_stopscan_tip) {
const char* msg = "Starting portal\nIf no response press\nBACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
} else {
if(app->show_stopscan_tip) {
const char* msg = "No portal selected\nShowing current logs\nPress "
"BACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
if(0 == strncmp("selecthtml", app->selected_tx_string, strlen("selecthtml"))) {
scene_manager_next_scene(app->scene_manager, Evil_PortalSceneSelectHtml);
return;
}
if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
app->command_queue[0] = SET_AP_CMD;
app->has_command_queue = true;
app->command_index = 0;
if(app->show_stopscan_tip) {
const char* msg = "Starting portal\nIf no response press\nBACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
}
@@ -107,13 +104,7 @@ void evil_portal_scene_console_output_on_enter(void* context) {
if(app->is_command && app->selected_tx_string) {
if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
if(!portal_file_set) {
scene_manager_set_scene_state(
app->scene_manager, Evil_PortalSceneConsoleOutput, 0);
view_dispatcher_switch_to_view(
app->view_dispatcher, Evil_PortalAppViewConsoleOutput);
return;
}
evil_portal_read_index_html(context);
FuriString* data = furi_string_alloc();
furi_string_cat(data, "sethtml=");

View File

@@ -0,0 +1,42 @@
#include "../evil_portal_app_i.h"
#include "../helpers/evil_portal_storage.h"
void evil_portal_text_input_callback(void* context) {
furi_assert(context);
Evil_PortalApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventTextInput);
}
void evil_portal_scene_rename_on_enter(void* context) {
Evil_PortalApp* app = context;
TextInput* text_input = app->text_input;
size_t enter_name_length = 25;
evil_portal_read_ap_name(app);
text_input_set_header_text(text_input, "AP Name/SSID");
strncpy(app->text_store[0], (char*)app->ap_name, enter_name_length);
text_input_set_result_callback(
text_input,
evil_portal_text_input_callback,
context,
app->text_store[0],
enter_name_length,
false);
view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewTextInput);
}
bool evil_portal_scene_rename_on_event(void* context, SceneManagerEvent event) {
Evil_PortalApp* app = context;
SceneManager* scene_manager = app->scene_manager;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
evil_portal_write_ap_name(app);
scene_manager_search_and_switch_to_previous_scene(scene_manager, Evil_PortalSceneStart);
consumed = true;
}
return consumed;
}
void evil_portal_scene_rename_on_exit(void* context) {
Evil_PortalApp* app = context;
variable_item_list_reset(app->var_item_list);
}

View File

@@ -0,0 +1,54 @@
#include "../evil_portal_app_i.h"
#include "../helpers/evil_portal_storage.h"
void evil_portal_show_loading_popup(Evil_PortalApp* app, bool show) {
TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME);
ViewStack* view_stack = app->view_stack;
Loading* loading = app->loading;
if(show) {
// Raise timer priority so that animations can play
vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1);
view_stack_add_view(view_stack, loading_get_view(loading));
} else {
view_stack_remove_view(view_stack, loading_get_view(loading));
// Restore default timer priority
vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY);
}
}
void evil_portal_scene_select_html_on_enter(void* context) {
Evil_PortalApp* app = context;
DialogsFileBrowserOptions browser_options;
evil_portal_create_html_folder_if_not_exists();
dialog_file_browser_set_basic_options(&browser_options, HTML_EXTENSION, &I_evil_portal_10px);
browser_options.base_path = HTML_FOLDER;
FuriString* path;
path = furi_string_alloc();
furi_string_set(path, HTML_FOLDER);
bool success = dialog_file_browser_show(app->dialogs, app->file_path, path, &browser_options);
furi_string_free(path);
if(success) {
//Replace HTML File
evil_portal_show_loading_popup(app, true);
evil_portal_replace_index_html(app->file_path);
evil_portal_show_loading_popup(app, false);
}
scene_manager_search_and_switch_to_previous_scene(app->scene_manager, Evil_PortalSceneStart);
}
bool evil_portal_scene_select_html_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
bool consumed = true;
return consumed;
}
void evil_portal_scene_select_html_on_exit(void* context) {
UNUSED(context);
}

View File

@@ -33,6 +33,12 @@ const Evil_PortalItem items[NUM_MENU_ITEMS] = {
// console
{"Save logs", {""}, 1, {"savelogs"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
// set AP name
{"Set AP name", {""}, 1, {"setapname"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
// select HTML Portal File
{"Select HTML", {""}, 1, {"selecthtml"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
// help
{"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
};