jblanked 1 год назад
Родитель
Сommit
b6e11fd53c
6 измененных файлов с 100 добавлено и 61 удалено
  1. BIN
      .DS_Store
  2. 95 57
      flip_store_callback.h
  3. 0 1
      flip_store_e.h
  4. 3 0
      flip_store_free.h
  5. 1 2
      flip_store_i.h
  6. 1 1
      flipper_http.h

+ 95 - 57
flip_store_callback.h

@@ -4,24 +4,45 @@
 #include <string.h>
 #include <stdlib.h>
 #include "jsmn.h"
+#include <ctype.h>
+#include <stdbool.h>
 
 // Define maximum limits
-#define MAX_APP_NAME_LENGTH 50
+#define MAX_APP_NAME_LENGTH 32
 #define MAX_APP_COUNT 200
+#define MAX_TOKENS 1600 // there are currently 1505 tokens in the JSON response
 
 typedef struct
 {
-    char app_names[MAX_APP_COUNT][MAX_APP_NAME_LENGTH];
-    char app_ids[MAX_APP_COUNT][MAX_APP_NAME_LENGTH];
-} FlipStoreAppCatalog;
+    char *app_name;
+    char *app_id;
+} FlipStoreAppInfo;
 
-static FlipStoreAppCatalog flip_catalog;
+static FlipStoreAppInfo flip_catalog[MAX_APP_COUNT];
 
-uint32_t app_selected_index = 0;
-bool flip_store_sent_request = false;
-bool flip_store_success = false;
-bool flip_store_saved_data = false;
-bool flip_store_saved_success = false;
+static uint32_t app_selected_index = 0;
+static bool flip_store_sent_request = false;
+static bool flip_store_success = false;
+static bool flip_store_saved_data = false;
+static bool flip_store_saved_success = false;
+
+// Function to free the flip_catalog
+static void flip_catalog_free()
+{
+    for (int i = 0; i < MAX_APP_COUNT; i++)
+    {
+        if (flip_catalog[i].app_name != NULL)
+        {
+            free(flip_catalog[i].app_name);
+            flip_catalog[i].app_name = NULL;
+        }
+        if (flip_catalog[i].app_id != NULL)
+        {
+            free(flip_catalog[i].app_id);
+            flip_catalog[i].app_id = NULL;
+        }
+    }
+}
 
 // Helper function to compare JSON keys
 int jsoneq(const char *json, jsmntok_t *tok, const char *s)
@@ -34,6 +55,7 @@ int jsoneq(const char *json, jsmntok_t *tok, const char *s)
     }
     return -1;
 }
+
 // Function to clean app name string
 void clean_app_name(char *name)
 {
@@ -72,34 +94,21 @@ bool flip_store_process_app_list(char *json_data)
         return false;
     }
 
+    // Free existing catalog to prevent memory leaks
+    flip_catalog_free();
+
     jsmn_parser parser;
     jsmn_init(&parser);
 
     // Initial token allocation
-    int token_count = 128;
-    jsmntok_t *tokens = (jsmntok_t *)malloc(sizeof(jsmntok_t) * token_count);
+    jsmntok_t *tokens = (jsmntok_t *)malloc(sizeof(jsmntok_t) * MAX_TOKENS);
     if (tokens == NULL)
     {
         FURI_LOG_E(TAG, "Failed to allocate memory for JSON tokens.");
         return false;
     }
 
-    int ret = jsmn_parse(&parser, json_data, strlen(json_data), tokens, token_count);
-
-    // Reallocate tokens if needed
-    while (ret == JSMN_ERROR_NOMEM)
-    {
-        token_count *= 2;
-        jsmntok_t *new_tokens = (jsmntok_t *)realloc(tokens, sizeof(jsmntok_t) * token_count);
-        if (new_tokens == NULL)
-        {
-            FURI_LOG_E(TAG, "Failed to reallocate memory for JSON tokens.");
-            free(tokens);
-            return false;
-        }
-        tokens = new_tokens;
-        ret = jsmn_parse(&parser, json_data, strlen(json_data), tokens, token_count);
-    }
+    int ret = jsmn_parse(&parser, json_data, strlen(json_data), tokens, MAX_TOKENS);
 
     if (ret < 0)
     {
@@ -167,14 +176,6 @@ bool flip_store_process_app_list(char *json_data)
                     jsmntok_t *key_token = &tokens[app_token_index];
                     jsmntok_t *val_token = &tokens[app_token_index + 1];
 
-                    int key_length = key_token->end - key_token->start;
-                    if (key_length >= MAX_APP_NAME_LENGTH)
-                        key_length = MAX_APP_NAME_LENGTH - 1;
-
-                    char key_string[MAX_APP_NAME_LENGTH];
-                    strncpy(key_string, json_data + key_token->start, key_length);
-                    key_string[key_length] = '\0';
-
                     if (jsoneq(json_data, key_token, "name") == 0)
                     {
                         int val_length = val_token->end - val_token->start;
@@ -182,6 +183,7 @@ bool flip_store_process_app_list(char *json_data)
                             val_length = MAX_APP_NAME_LENGTH - 1;
                         strncpy(name_value, json_data + val_token->start, val_length);
                         name_value[val_length] = '\0';
+                        clean_app_name(name_value);
                     }
                     else if (jsoneq(json_data, key_token, "id") == 0)
                     {
@@ -190,6 +192,7 @@ bool flip_store_process_app_list(char *json_data)
                             val_length = MAX_APP_NAME_LENGTH - 1;
                         strncpy(id_value, json_data + val_token->start, val_length);
                         id_value[val_length] = '\0';
+                        clean_app_name(id_value);
                     }
 
                     app_token_index += 2;
@@ -201,14 +204,42 @@ bool flip_store_process_app_list(char *json_data)
                     break;
                 }
 
-                strncpy(flip_catalog.app_names[app_count], name_value, MAX_APP_NAME_LENGTH - 1);
-                flip_catalog.app_names[app_count][MAX_APP_NAME_LENGTH - 1] = '\0';
+                // Allocate memory for app_name and app_id
+                flip_catalog[app_count].app_name = (char *)malloc(MAX_APP_NAME_LENGTH);
+                flip_catalog[app_count].app_id = (char *)malloc(MAX_APP_NAME_LENGTH);
+
+                if (flip_catalog[app_count].app_name == NULL || flip_catalog[app_count].app_id == NULL)
+                {
+                    FURI_LOG_E(TAG, "Memory allocation failed for app_name or app_id.");
+
+                    // Cleanup already allocated entries
+                    for (int cleanup = 0; cleanup < app_count; cleanup++)
+                    {
+                        if (flip_catalog[cleanup].app_name != NULL)
+                        {
+                            free(flip_catalog[cleanup].app_name);
+                            flip_catalog[cleanup].app_name = NULL;
+                        }
+                        if (flip_catalog[cleanup].app_id != NULL)
+                        {
+                            free(flip_catalog[cleanup].app_id);
+                            flip_catalog[cleanup].app_id = NULL;
+                        }
+                    }
+
+                    free(tokens);
+                    return false;
+                }
+
+                strncpy(flip_catalog[app_count].app_name, name_value, MAX_APP_NAME_LENGTH - 1);
+                flip_catalog[app_count].app_name[MAX_APP_NAME_LENGTH - 1] = '\0';
 
-                strncpy(flip_catalog.app_ids[app_count], id_value, MAX_APP_NAME_LENGTH - 1);
-                flip_catalog.app_ids[app_count][MAX_APP_NAME_LENGTH - 1] = '\0';
+                strncpy(flip_catalog[app_count].app_id, id_value, MAX_APP_NAME_LENGTH - 1);
+                flip_catalog[app_count].app_id[MAX_APP_NAME_LENGTH - 1] = '\0';
 
                 app_count++;
 
+                // Update current to skip the current app object tokens
                 int tokens_to_skip = 1 + 2 * app_size;
                 current += tokens_to_skip;
             }
@@ -227,7 +258,7 @@ bool flip_store_process_app_list(char *json_data)
 
 bool flip_store_get_fap_file(char *app_id)
 {
-    char payload[256];
+    char payload[164];
     snprintf(payload, sizeof(payload), "{\"app_id\":\"%s\"}", app_id);
     return flipper_http_post_request_bytes("https://www.flipsocial.net/api/app/compile/", "{\"Content-Type\":\"application/json\"}", payload);
 }
@@ -278,22 +309,23 @@ void flip_store_request_error(Canvas *canvas)
 bool flip_store_install_app(Canvas *canvas)
 {
     // create /apps/FlipStore directory if it doesn't exist
-    char directory_path[256];
+    char directory_path[128];
     snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps/FlipStore");
 
     // Create the directory
     Storage *storage = furi_record_open(RECORD_STORAGE);
     storage_common_mkdir(storage, directory_path);
 
-    char *app_name = flip_catalog.app_names[app_selected_index];
-    char installaing_text[128];
-    snprintf(installaing_text, sizeof(installaing_text), "Installing %s", app_name);
+    // Adjusted to access flip_catalog as an array of structures
+    char *app_name = flip_catalog[app_selected_index].app_name;
+    char installing_text[128];
+    snprintf(installing_text, sizeof(installing_text), "Installing %s", app_name);
     char bin_path[256];
-    snprintf(bin_path, sizeof(bin_path), STORAGE_EXT_PATH_PREFIX "/apps/FlipStore/%s.fap", flip_catalog.app_ids[app_selected_index]);
+    snprintf(bin_path, sizeof(bin_path), STORAGE_EXT_PATH_PREFIX "/apps/FlipStore/%s.fap", flip_catalog[app_selected_index].app_id);
     strncpy(fhttp.file_path, bin_path, sizeof(fhttp.file_path) - 1);
-    canvas_draw_str(canvas, 0, 10, installaing_text);
-    canvas_draw_str(canvas, 0, 20, "Sending reqeuest..");
-    if (fhttp.state != INACTIVE && flip_store_get_fap_file(flip_catalog.app_ids[app_selected_index]))
+    canvas_draw_str(canvas, 0, 10, installing_text);
+    canvas_draw_str(canvas, 0, 20, "Sending request..");
+    if (fhttp.state != INACTIVE && flip_store_get_fap_file(flip_catalog[app_selected_index].app_id))
     {
         canvas_draw_str(canvas, 0, 30, "Request sent.");
         fhttp.state = RECEIVING;
@@ -379,7 +411,8 @@ static void flip_store_view_draw_callback_app_list(Canvas *canvas, void *model)
     UNUSED(model);
     canvas_clear(canvas);
     canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(canvas, 0, 10, flip_catalog.app_names[app_selected_index]);
+    // Adjusted to access flip_catalog as an array of structures
+    canvas_draw_str(canvas, 0, 10, flip_catalog[app_selected_index].app_name);
     // canvas_draw_icon(canvas, 0, 53, &I_ButtonLeft_4x7); (future implementation)
     //  canvas_draw_str_aligned(canvas, 7, 54, AlignLeft, AlignTop, "Delete");  (future implementation)
     canvas_draw_icon(canvas, 0, 53, &I_ButtonBACK_10x8);
@@ -508,6 +541,8 @@ static uint32_t callback_to_submenu(void *context)
         return VIEW_NONE;
     }
     UNUSED(context);
+    // free the app list
+    flip_catalog_free();
     return FlipStoreViewSubmenu;
 }
 
@@ -616,11 +651,14 @@ static void callback_submenu_choices(void *context, uint32_t index)
     case FlipStoreSubmenuIndexSettings:
         view_dispatcher_switch_to_view(app->view_dispatcher, FlipStoreViewSettings);
         break;
-    case FlipStoreSubmenuIndexDownloadApp:
-        view_dispatcher_switch_to_view(app->view_dispatcher, FlipStoreViewAppList);
-        break;
     // Ideally users should be sent to a draw callback view to show to request process (like in FlipSocial and WebCrawler)
     case FlipStoreSubmenuIndexAppList:
+        // initialize the flip_catalog[MAX_APP_COUNT];
+        // if (!flip_catalog_init())
+        // {
+        //     FURI_LOG_E(TAG, "Failed to initialize flip catalog");
+        //     return;
+        // }
         // async call to the app list with timer
         if (fhttp.state != INACTIVE && flipper_http_get_request_with_headers("https://www.flipsocial.net/api/flipper/apps/", "{\"Content-Type\":\"application/json\"}"))
         {
@@ -684,9 +722,9 @@ static void callback_submenu_choices(void *context, uint32_t index)
                 // add each app name to submenu
                 for (int i = 0; i < MAX_APP_COUNT; i++)
                 {
-                    if (strlen(flip_catalog.app_names[i]) > 0)
+                    if (flip_catalog[i].app_name != NULL && strlen(flip_catalog[i].app_name) > 0)
                     {
-                        submenu_add_item(app->submenu_app_list, flip_catalog.app_names[i], FlipStoreSubmenuIndexStartAppList + i, callback_submenu_choices, app);
+                        submenu_add_item(app->submenu_app_list, flip_catalog[i].app_name, FlipStoreSubmenuIndexStartAppList + i, callback_submenu_choices, app);
                     }
                 }
 
@@ -712,7 +750,7 @@ static void callback_submenu_choices(void *context, uint32_t index)
             if ((int)app_index >= 0 && app_index < MAX_APP_COUNT)
             {
                 // Get the app name
-                char *app_name = flip_catalog.app_names[app_index];
+                char *app_name = flip_catalog[app_index].app_name;
 
                 // Check if the app name is valid
                 if (app_name != NULL && strlen(app_name) > 0)
@@ -738,4 +776,4 @@ static void callback_submenu_choices(void *context, uint32_t index)
     }
 }
 
-#endif // FLIP_STORE_CALLBACK_H
+#endif // FLIP_STORE_CALLBACK_H

+ 0 - 1
flip_store_e.h

@@ -20,7 +20,6 @@ typedef enum
     FlipStoreSubmenuIndexAbout,
     FlipStoreSubmenuIndexSettings,
     FlipStoreSubmenuIndexAppList,
-    FlipStoreSubmenuIndexDownloadApp,
     //
     FlipStoreSubmenuIndexStartAppList
 } FlipStoreSubmenuIndex;

+ 3 - 0
flip_store_free.h

@@ -79,6 +79,9 @@ static void flip_store_app_free(FlipStoreApp *app)
         dialog_ex_free(app->dialog_delete);
     }
 
+    // Free the view dispatcher
+    flip_catalog_free();
+
     // deinitalize flipper http
     flipper_http_deinit();
 

+ 1 - 2
flip_store_i.h

@@ -126,8 +126,7 @@ static FlipStoreApp *flip_store_app_alloc()
         // Update variable items
         if (app->variable_item_ssid)
             variable_item_set_current_value_text(app->variable_item_ssid, app->uart_text_input_buffer_ssid);
-        if (app->variable_item_pass)
-            variable_item_set_current_value_text(app->variable_item_pass, app->uart_text_input_buffer_pass);
+        // do not display the password
 
         // Copy items into their temp buffers with safety checks
         if (app->uart_text_input_buffer_ssid && app->uart_text_input_temp_buffer_ssid)

+ 1 - 1
flipper_http.h

@@ -18,7 +18,7 @@
 #define TIMEOUT_DURATION_TICKS (2 * 1000) // 2 seconds
 #define BAUDRATE (115200)                 // UART baudrate
 #define RX_BUF_SIZE 1024                  // UART RX buffer size
-#define RX_LINE_BUFFER_SIZE 9000          // UART RX line buffer size (increase for large responses)
+#define RX_LINE_BUFFER_SIZE 10000         // UART RX line buffer size (increase for large responses)
 
 // Forward declaration for callback
 typedef void (*FlipperHTTP_Callback)(const char *line, void *context);