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

Merge flip_wifi from https://github.com/jblanked/FlipWiFi

Willy-JL 1 год назад
Родитель
Сommit
8acd712d5c

+ 8 - 0
flip_wifi/CHANGELOG.md

@@ -1,3 +1,11 @@
+## v1.3.2
+- Fixed a crash that occurred when deleting a network from the Saved APs list.
+- Updated to connect to the network after clicking "Set" on the selected SSID in the Saved APs list.
+
+## v1.3.1
+- Fixed a loading error that occurred when scanning networks.
+- Fixed a freeze that occurred when saving networks manually.
+
 ## v1.3  
 - Updated to save credentials for the FlipWorld game.  
 - Added fast commands: CUSTOM, PING, LIST, IP/ADDRESS, and WIFI/IP.  

+ 4 - 6
flip_wifi/README.md

@@ -1,11 +1,9 @@
-# FlipWiFi
-
 FlipWiFi is the companion app for the popular FlipperHTTP flash, originally introduced in the https://github.com/jblanked/WebCrawler-FlipperZero/tree/main/assets/FlipperHTTP. It allows you to scan and save WiFi networks for use across all FlipperHTTP apps.
 
 ## Requirements
 
 - WiFi Developer Board, Raspberry Pi, or ESP32 Device with FlipperHTTP Flash: https://github.com/jblanked/FlipperHTTP
-- WiFi Access Point
+- 2.4 GHz WiFi Access Point
 
 ## Features
 
@@ -14,9 +12,9 @@ FlipWiFi is the companion app for the popular FlipperHTTP flash, originally intr
 
 ## Setup
 
-FlipWiFi automatically allocates the necessary resources and initializes settings upon launch. If WiFi settings have been previously configured, they are loaded automatically for easy access. You can also edit the list of WiFi settings by downloading and modifying the "wifi_list.txt" file located in the "/SD/apps_data/flip_wifi/" directory. To use the app:
+FlipWiFi automatically allocates the necessary resources and initializes settings upon launch. If WiFi settings have been previously configured, they are loaded automatically for easy access. You can also edit the list of WiFi settings by downloading and modifying the "wifi_list.txt" file located in the "/SD/apps_data/flip_wifi/data" directory. To use the app:
 
-1. **Flash the WiFi Dev Board**: Follow the instructions to flash the WiFi Dev Board with FlipperHTTP: https://github.com/jblanked/FlipperHTTP
-2. **Install the App**: Download FlipWiFi from the App Store.
+1. **Flash the WiFi Developer Board**: Follow the instructions to flash the WiFi Dev Board with FlipperHTTP: https://github.com/jblanked/FlipperHTTP
+2. **Install the App**: Download FlipWiFi from the Flipper Lab.
 3. **Launch FlipWiFi**: Open the app on your Flipper Zero.
 4. Connect, review, and save WiFi networks.

+ 1 - 1
flip_wifi/alloc/flip_wifi_alloc.c

@@ -14,7 +14,7 @@ FlipWiFiApp *flip_wifi_app_alloc()
     }
 
     // Submenu
-    if (!easy_flipper_set_submenu(&app->submenu_main, FlipWiFiViewSubmenuMain, "FlipWiFi v1.3", callback_exit_app, &app->view_dispatcher))
+    if (!easy_flipper_set_submenu(&app->submenu_main, FlipWiFiViewSubmenuMain, "FlipWiFi v1.3.2", callback_exit_app, &app->view_dispatcher))
     {
         return NULL;
     }

+ 1 - 1
flip_wifi/application.fam

@@ -9,6 +9,6 @@ App(
     fap_icon_assets="assets",
     fap_author="JBlanked",
     fap_weburl="https://github.com/jblanked/FlipWiFi",
-    fap_version="1.3",
+    fap_version="1.3.2",
     fap_description="FlipperHTTP companion app.",
 )

BIN
flip_wifi/assets/01-home.png


+ 42 - 24
flip_wifi/callback/flip_wifi_callback.c

@@ -133,7 +133,7 @@ static bool flip_wifi_alloc_widgets(void *context, uint32_t widget)
     case FlipWiFiViewAbout:
         if (!app->widget_info)
         {
-            if (!easy_flipper_set_widget(&app->widget_info, FlipWiFiViewAbout, "FlipWiFi v1.3\n-----\nFlipperHTTP companion app.\nScan and save WiFi networks.\n-----\nwww.github.com/jblanked", callback_to_submenu_main, &app->view_dispatcher))
+            if (!easy_flipper_set_widget(&app->widget_info, FlipWiFiViewAbout, "FlipWiFi v1.3.2\n-----\nFlipperHTTP companion app.\nScan and save WiFi networks.\n-----\nwww.github.com/jblanked", callback_to_submenu_main, &app->view_dispatcher))
             {
                 return false;
             }
@@ -563,19 +563,35 @@ static bool flip_wifi_view_input_callback_saved(InputEvent *event, void *context
         // save the settings
         save_settings(wifi_playlist->ssids[ssid_index], wifi_playlist->passwords[ssid_index]);
 
-        flipper_http_save_wifi(wifi_playlist->ssids[ssid_index], wifi_playlist->passwords[ssid_index]);
+        // initialize uart
+        if (!flipper_http_init(flipper_http_rx_callback, app))
+        {
+            easy_flipper_dialog("[ERROR]", "Failed to initialize flipper http");
+            return false;
+        }
+
+        // clear response
+        if (fhttp.last_response)
+            snprintf(fhttp.last_response, RX_BUF_SIZE, "%s", "");
+
+        if (!flipper_http_save_wifi(wifi_playlist->ssids[ssid_index], wifi_playlist->passwords[ssid_index]))
+        {
+            easy_flipper_dialog("[ERROR]", "Failed to save WiFi settings");
+            return false;
+        }
+
+        while (!fhttp.last_response || strlen(fhttp.last_response) == 0)
+        {
+            furi_delay_ms(100);
+        }
 
-        flipper_http_connect_wifi();
+        flipper_http_deinit();
 
         easy_flipper_dialog("[SUCCESS]", "All FlipperHTTP apps will now\nuse the selected network.");
         return true;
     }
     else if (event->type == InputTypePress && event->key == InputKeyLeft)
     {
-        // delete the selected ssid and password
-        free(wifi_playlist->ssids[ssid_index]);
-        free(wifi_playlist->passwords[ssid_index]);
-        free(ssid_list[ssid_index]);
         // shift the remaining ssids and passwords
         for (uint32_t i = ssid_index; i < wifi_playlist->count - 1; i++)
         {
@@ -591,6 +607,10 @@ static bool flip_wifi_view_input_callback_saved(InputEvent *event, void *context
         }
         wifi_playlist->count--;
 
+        // delete the last ssid and password
+        wifi_playlist->ssids[wifi_playlist->count][0] = '\0';
+        wifi_playlist->passwords[wifi_playlist->count][0] = '\0';
+
         // save the playlist to storage
         save_playlist(wifi_playlist);
 
@@ -637,23 +657,13 @@ static bool flip_wifi_handle_scan(void *context)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
         fhttp.state = ISSUE;
-        easy_flipper_dialog("[ERROR]", "Failed to load received data from file.");
-        return false;
-    }
-    char *data_cstr = (char *)furi_string_get_cstr(scan_data);
-    if (data_cstr == NULL)
-    {
-        FURI_LOG_E(TAG, "Failed to get C-string from FuriString.");
-        furi_string_free(scan_data);
-        fhttp.state = ISSUE;
-        free(data_cstr);
-        easy_flipper_dialog("[ERROR]", "Failed to get C-string from FuriString.");
+        easy_flipper_dialog("[ERROR]", "Failed to load data from /apps_data/flip_wifi/data/scan.txt");
         return false;
     }
 
     uint32_t ssid_count = 0;
 
-    char *current_position = data_cstr;
+    char *current_position = (char *)furi_string_get_cstr(scan_data);
     char *next_comma = NULL;
 
     // Manually split the string on commas
@@ -679,7 +689,6 @@ static bool flip_wifi_handle_scan(void *context)
         {
             FURI_LOG_E(TAG, "Memory allocation failed");
             easy_flipper_dialog("[ERROR]", "Memory allocation failed");
-            free(data_cstr);
             furi_string_free(scan_data);
             return false;
         }
@@ -736,7 +745,6 @@ static bool flip_wifi_handle_scan(void *context)
         snprintf(ssid, sizeof(ssid), "%s", ssid_item);
         submenu_add_item(app->submenu_wifi, ssid, FlipWiFiSubmenuIndexWiFiScanStart + i, callback_submenu_choices, app);
     }
-    free(data_cstr);
     furi_string_free(scan_data);
     return true;
 }
@@ -767,6 +775,15 @@ void callback_submenu_choices(void *context, uint32_t index)
         {
             return flip_wifi_handle_scan(app);
         }
+        Storage *storage = furi_record_open(RECORD_STORAGE);
+        // ensure flip_wifi directory is there
+        char directory_path[128];
+        snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi");
+        storage_common_mkdir(storage, directory_path);
+        // ensure directory is there for saving data
+        snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data");
+        storage_common_mkdir(storage, directory_path);
+        furi_record_close(RECORD_STORAGE);
         // scan for wifi ad parse the results
         flipper_http_loading_task(flipper_http_scan_wifi, _flip_wifi_handle_scan, FlipWiFiViewSubmenu, FlipWiFiViewSubmenuMain, &app->view_dispatcher);
         flipper_http_deinit();
@@ -1012,12 +1029,13 @@ void flip_wifi_text_updated_add_password(void *context)
 
     // store the entered text
     strncpy(app->uart_text_input_buffer, app->uart_text_input_temp_buffer, app->uart_text_input_buffer_size);
-
-    save_char("wifi-password", app->uart_text_input_buffer);
-
     // Ensure null-termination
     app->uart_text_input_buffer[app->uart_text_input_buffer_size - 1] = '\0';
 
+    view_dispatcher_switch_to_view(app->view_dispatcher, FlipWiFiViewSubmenuMain);
+
+    save_char("wifi-password", app->uart_text_input_buffer);
+
     char wifi_ssid[64];
     if (!load_char("wifi-ssid", wifi_ssid, sizeof(wifi_ssid)))
     {

+ 7 - 3
flip_wifi/flip_storage/flip_wifi_storage.c

@@ -21,7 +21,7 @@ void save_playlist(WiFiPlaylist *playlist)
 
     // Create the directory for saving settings
     char directory_path[128];
-    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data");
+    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi");
 
     // Open storage
     Storage *storage = furi_record_open(RECORD_STORAGE);
@@ -33,6 +33,8 @@ void save_playlist(WiFiPlaylist *playlist)
 
     // Create the directory
     storage_common_mkdir(storage, directory_path);
+    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data");
+    storage_common_mkdir(storage, directory_path);
 
     // Open the settings file
     File *file = storage_file_alloc(storage);
@@ -334,7 +336,7 @@ bool save_char(
     }
     // Create the directory for saving settings
     char directory_path[256];
-    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data");
+    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi");
 
     // Create the directory
     Storage *storage = furi_record_open(RECORD_STORAGE);
@@ -344,6 +346,8 @@ bool save_char(
         return false;
     }
     storage_common_mkdir(storage, directory_path);
+    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data");
+    storage_common_mkdir(storage, directory_path);
 
     // Open the settings file
     File *file = storage_file_alloc(storage);
@@ -397,7 +401,7 @@ bool load_char(
     {
         storage_file_free(file);
         furi_record_close(RECORD_STORAGE);
-        return NULL; // Return false if the file does not exist
+        return false; // Return false if the file does not exist
     }
 
     // Read data into the buffer

+ 13 - 12
flip_wifi/flipper_http/flipper_http.c

@@ -642,21 +642,10 @@ bool flipper_http_parse_json_array(const char *key, int index, const char *json_
  */
 bool flipper_http_scan_wifi()
 {
-    if (!flipper_http_send_data("[WIFI/SCAN]"))
-    {
-        FURI_LOG_E("FlipperHTTP", "Failed to send WiFi scan command.");
-        return false;
-    }
     // custom for FlipWiFi app
     fhttp.just_started_get = true;
 
-    // Create the directory for saving settings
-    char directory_path[256];
-    snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data");
-
-    // Create the directory
-    Storage *storage = furi_record_open(RECORD_STORAGE);
-    storage_common_mkdir(storage, directory_path);
+    // ensure the data folder exists
 
     snprintf(
         fhttp.file_path,
@@ -664,11 +653,17 @@ bool flipper_http_scan_wifi()
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_wifi/data/scan.txt");
 
     // ensure the file is empty
+    Storage *storage = furi_record_open(RECORD_STORAGE);
     storage_simply_remove_recursive(storage, fhttp.file_path);
     furi_record_close(RECORD_STORAGE);
 
     fhttp.save_received_data = true;
 
+    if (!flipper_http_send_data("[WIFI/SCAN]"))
+    {
+        FURI_LOG_E("FlipperHTTP", "Failed to send WiFi scan command.");
+        return false;
+    }
     // The response will be handled asynchronously via the callback
     return true;
 }
@@ -686,6 +681,10 @@ bool flipper_http_save_wifi(const char *ssid, const char *password)
         FURI_LOG_E("FlipperHTTP", "Invalid arguments provided to flipper_http_save_wifi.");
         return false;
     }
+
+    // custom for FlipWiFi app
+    fhttp.just_started_get = true;
+
     char buffer[256];
     int ret = snprintf(
         buffer, sizeof(buffer), "[WIFI/SAVE]{\"ssid\":\"%s\",\"password\":\"%s\"}", ssid, password);
@@ -701,6 +700,8 @@ bool flipper_http_save_wifi(const char *ssid, const char *password)
         return false;
     }
 
+    fhttp.state = RECEIVING;
+
     // The response will be handled asynchronously via the callback
     return true;
 }

+ 18 - 0
flip_wifi/jsmn/jsmn.c

@@ -454,6 +454,11 @@ char *get_json_value(char *key, const char *json_data)
         jsmn_parser parser;
         jsmn_init(&parser);
         uint32_t max_tokens = json_token_count(json_data);
+        if (!jsmn_memory_check(max_tokens))
+        {
+            FURI_LOG_E("JSMM.H", "Insufficient memory for JSON tokens.");
+            return NULL;
+        }
         // Allocate tokens array on the heap
         jsmntok_t *tokens = malloc(sizeof(jsmntok_t) * max_tokens);
         if (tokens == NULL)
@@ -572,6 +577,12 @@ char *get_json_array_value(char *key, uint32_t index, const char *json_data)
         return NULL;
     }
     uint32_t max_tokens = json_token_count(array_str);
+    if (!jsmn_memory_check(max_tokens))
+    {
+        FURI_LOG_E("JSMM.H", "Insufficient memory for JSON tokens.");
+        free(array_str);
+        return NULL;
+    }
 
     jsmn_parser parser;
     jsmn_init(&parser);
@@ -602,6 +613,7 @@ char *get_json_array_value(char *key, uint32_t index, const char *json_data)
 
     if (index >= (uint32_t)tokens[0].size)
     {
+        // FURI_LOG_E("JSMM.H", "Index %lu out of bounds for array with size %u.", index, tokens[0].size);
         free(tokens);
         free(array_str);
         return NULL;
@@ -653,6 +665,12 @@ char **get_json_array_values(char *key, char *json_data, int *num_values)
         return NULL;
     }
     uint32_t max_tokens = json_token_count(array_str);
+    if (!jsmn_memory_check(max_tokens))
+    {
+        FURI_LOG_E("JSMM.H", "Insufficient memory for JSON tokens.");
+        free(array_str);
+        return NULL;
+    }
     // Initialize the JSON parser
     jsmn_parser parser;
     jsmn_init(&parser);

+ 18 - 0
flip_wifi/jsmn/jsmn_furi.c

@@ -481,6 +481,11 @@ FuriString *get_json_value_furi(const char *key, const FuriString *json_data)
         return NULL;
     }
     uint32_t max_tokens = json_token_count_furi(json_data);
+    if (!jsmn_memory_check(max_tokens))
+    {
+        FURI_LOG_E("JSMM.H", "Insufficient memory for JSON tokens.");
+        return NULL;
+    }
     // Create a temporary FuriString from key
     FuriString *key_str = furi_string_alloc();
     furi_string_cat_str(key_str, key);
@@ -546,6 +551,12 @@ FuriString *get_json_array_value_furi(const char *key, uint32_t index, const Fur
         return NULL;
     }
     uint32_t max_tokens = json_token_count_furi(array_str);
+    if (!jsmn_memory_check(max_tokens))
+    {
+        FURI_LOG_E("JSMM.H", "Insufficient memory for JSON tokens.");
+        furi_string_free(array_str);
+        return NULL;
+    }
     jsmn_parser parser;
     jsmn_init_furi(&parser);
 
@@ -576,6 +587,7 @@ FuriString *get_json_array_value_furi(const char *key, uint32_t index, const Fur
 
     if (index >= (uint32_t)tokens[0].size)
     {
+        // FURI_LOG_E("JSMM.H", "Index %lu out of bounds for array with size %u.", index, tokens[0].size);
         free(tokens);
         furi_string_free(array_str);
         return NULL;
@@ -621,6 +633,12 @@ FuriString **get_json_array_values_furi(const char *key, const FuriString *json_
     }
 
     uint32_t max_tokens = json_token_count_furi(array_str);
+    if (!jsmn_memory_check(max_tokens))
+    {
+        FURI_LOG_E("JSMM.H", "Insufficient memory for JSON tokens.");
+        furi_string_free(array_str);
+        return NULL;
+    }
     jsmn_parser parser;
     jsmn_init_furi(&parser);
 

+ 1 - 0
flip_wifi/jsmn/jsmn_h.c

@@ -12,3 +12,4 @@ FuriString *char_to_furi_string(const char *str)
     }
     return furi_str;
 }
+bool jsmn_memory_check(size_t heap_size) { return memmgr_get_free_heap() > (heap_size + 1024); }

+ 4 - 1
flip_wifi/jsmn/jsmn_h.h

@@ -50,4 +50,7 @@ typedef struct
     FuriString *value;
 } FuriJSON;
 
-FuriString *char_to_furi_string(const char *str);
+FuriString *char_to_furi_string(const char *str);
+
+// check memory
+bool jsmn_memory_check(size_t heap_size);