ソースを参照

add latest FlipperHTTP library

there are a TON of things that need update but this does compile without initial warnings/errors
jblanked 9 ヶ月 前
コミット
2a2adf56bd

+ 16 - 13
alloc/alloc.c

@@ -372,7 +372,6 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
         {
             FURI_LOG_E(TAG, "Failed to load nexy feed post");
-            fhttp.state = ISSUE;
             return false;
         }
         if (feed_view_alloc())
@@ -382,7 +381,6 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         else
         {
             FURI_LOG_E(TAG, "Failed to allocate feed dialog");
-            fhttp.state = ISSUE;
             return false;
         }
     }
@@ -399,12 +397,19 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
 
             save_char("series_index", new_series_index);
 
-            if (!flip_social_load_initial_feed(true, flip_feed_info->series_index))
+            FlipperHTTP *fhttp = flipper_http_alloc();
+            if (!fhttp)
+            {
+                FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
+                return false;
+            }
+            if (!flip_social_load_initial_feed(fhttp, flip_feed_info->series_index))
             {
                 FURI_LOG_E(TAG, "Failed to load initial feed");
-                fhttp.state = ISSUE;
+                flipper_http_free(fhttp);
                 return false;
             }
+            flipper_http_free(fhttp);
             // switch view, free dialog, re-alloc dialog, switch back to dialog
             view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewWidgetResult);
             flip_social_free_feed_view();
@@ -412,7 +417,6 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
             if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
             {
                 FURI_LOG_E(TAG, "Failed to load nexy feed post");
-                fhttp.state = ISSUE;
                 return false;
             }
             if (feed_view_alloc())
@@ -422,7 +426,6 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
             else
             {
                 FURI_LOG_E(TAG, "Failed to allocate feed dialog");
-                fhttp.state = ISSUE;
                 return false;
             }
         }
@@ -437,7 +440,6 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
         {
             FURI_LOG_E(TAG, "Failed to load nexy feed post");
-            fhttp.state = ISSUE;
             return false;
         }
         if (feed_view_alloc())
@@ -447,7 +449,6 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         else
         {
             FURI_LOG_E(TAG, "Failed to allocate feed dialog");
-            fhttp.state = ISSUE;
             return false;
         }
     }
@@ -474,7 +475,8 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
             FURI_LOG_E(TAG, "Username is NULL");
             return false;
         }
-        if (!flipper_http_init(flipper_http_rx_callback, app_instance))
+        FlipperHTTP *fhttp = flipper_http_alloc();
+        if (!fhttp)
         {
             FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
             return false;
@@ -482,7 +484,7 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         auth_headers_alloc();
         char payload[256];
         snprintf(payload, sizeof(payload), "{\"username\":\"%s\",\"post_id\":\"%u\"}", app_instance->login_username_logged_in, flip_feed_item->id);
-        if (flipper_http_post_request_with_headers("https://www.jblanked.com/flipper/api/feed/flip/", auth_headers, payload))
+        if (flipper_http_request(fhttp, POST, "https://www.jblanked.com/flipper/api/feed/flip/", auth_headers, payload))
         {
             // save feed item
             char new_save[512];
@@ -493,7 +495,7 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
             if (!flip_social_save_post(id, new_save))
             {
                 FURI_LOG_E(TAG, "Failed to save the feed post");
-                flipper_http_deinit();
+                flipper_http_free(fhttp);
                 return false;
             }
         }
@@ -504,7 +506,8 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         if (!flip_social_load_feed_post(flip_feed_info->ids[flip_feed_info->index]))
         {
             FURI_LOG_E(TAG, "Failed to load nexy feed post");
-            fhttp.state = ISSUE;
+            fhttp->state = ISSUE;
+            flipper_http_free(fhttp);
             return false;
         }
         if (feed_view_alloc())
@@ -515,7 +518,7 @@ static bool flip_social_feed_input_callback(InputEvent *event, void *context)
         {
             FURI_LOG_E(TAG, "Failed to allocate feed dialog");
         }
-        flipper_http_deinit();
+        flipper_http_free(fhttp);
     }
     return false;
 }

+ 1 - 1
alloc/free.c

@@ -25,7 +25,7 @@ void free_all(bool should_free_variable_item_list, bool should_free_submenu)
 
     if (went_to_friends)
     {
-        flipper_http_deinit();
+        // flipper_http_deinit();
         went_to_friends = false;
     }
 }

ファイルの差分が大きいため隠しています
+ 276 - 213
callback/flip_social_callback.c


+ 1 - 0
callback/flip_social_callback.h

@@ -291,6 +291,7 @@ struct DataLoaderModel
     size_t request_count;
     ViewNavigationCallback back_callback;
     FuriTimer *timer;
+    FlipperHTTP *fhttp;
 };
 void flip_social_generic_switch_to_view(FlipSocialApp *app, char *title, DataLoaderFetch fetcher, DataLoaderParser parser, size_t request_count, ViewNavigationCallback back, uint32_t view_id);
 

+ 34 - 21
explore/flip_social_explore.c

@@ -23,11 +23,16 @@ void flip_social_free_explore(void)
 
 // for now we're just listing the current users
 // as the feed is upgraded, then we can port more to the explore view
-bool flip_social_get_explore(void)
+bool flip_social_get_explore(FlipperHTTP *fhttp)
 {
-    if (!flipper_http_init(flipper_http_rx_callback, app_instance))
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "App instance is NULL");
+        return false;
+    }
+    if (!fhttp)
     {
-        FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
         return false;
     }
     char directory[128];
@@ -38,33 +43,34 @@ bool flip_social_get_explore(void)
     storage_common_mkdir(storage, directory);
     char *keyword = !app_instance->explore_logged_in || strlen(app_instance->explore_logged_in) == 0 ? "a" : app_instance->explore_logged_in;
     snprintf(
-        fhttp.file_path,
-        sizeof(fhttp.file_path),
+        fhttp->file_path,
+        sizeof(fhttp->file_path),
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/explore/%s.json",
         keyword);
 
-    fhttp.save_received_data = true;
+    fhttp->save_received_data = true;
     auth_headers_alloc();
     char url[256];
     snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/user/explore/%s/%d/", keyword, MAX_EXPLORE_USERS);
-    if (!flipper_http_get_request_with_headers(url, auth_headers))
+    if (!flipper_http_request(fhttp, GET, url, auth_headers, NULL))
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for explore");
-        fhttp.state = ISSUE;
+        fhttp->state = ISSUE;
         return false;
     }
-    fhttp.state = RECEIVING;
+    fhttp->state = RECEIVING;
     return true;
 }
-bool flip_social_get_explore_2(void)
+bool flip_social_get_explore_2(FlipperHTTP *fhttp)
 {
     if (!app_instance)
     {
+        FURI_LOG_E(TAG, "App instance is NULL");
         return false;
     }
-    if (!flipper_http_init(flipper_http_rx_callback, app_instance))
+    if (!fhttp)
     {
-        FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
         return false;
     }
     char directory[128];
@@ -75,31 +81,38 @@ bool flip_social_get_explore_2(void)
     storage_common_mkdir(storage, directory);
     char *keyword = !app_instance->message_users_logged_in || strlen(app_instance->message_users_logged_in) == 0 ? "a" : app_instance->message_users_logged_in;
     snprintf(
-        fhttp.file_path,
-        sizeof(fhttp.file_path),
+        fhttp->file_path,
+        sizeof(fhttp->file_path),
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/explore/%s.json",
         keyword);
 
-    fhttp.save_received_data = true;
+    fhttp->save_received_data = true;
     auth_headers_alloc();
     char url[256];
     snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/user/explore/%s/%d/", keyword, MAX_EXPLORE_USERS);
-    return flipper_http_get_request_with_headers(url, auth_headers);
+    return flipper_http_request(fhttp, GET, url, auth_headers, NULL);
 }
 
-bool flip_social_parse_json_explore()
+bool flip_social_parse_json_explore(FlipperHTTP *fhttp)
 {
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "App instance is NULL");
+        return false;
+    }
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
     // load the received data from the saved file
-    FuriString *user_data = flipper_http_load_from_file(fhttp.file_path);
+    FuriString *user_data = flipper_http_load_from_file(fhttp->file_path);
     if (user_data == NULL)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        flipper_http_deinit();
         return false;
     }
 
-    flipper_http_deinit();
-
     // Allocate memory for each username only if not already allocated
     flip_social_explore = flip_social_explore_alloc();
     if (flip_social_explore == NULL)

+ 3 - 3
explore/flip_social_explore.h

@@ -4,7 +4,7 @@
 #include <callback/flip_social_callback.h>
 FlipSocialModel *flip_social_explore_alloc();
 void flip_social_free_explore();
-bool flip_social_get_explore();
-bool flip_social_get_explore_2(void);
-bool flip_social_parse_json_explore();
+bool flip_social_get_explore(FlipperHTTP *fhttp);
+bool flip_social_get_explore_2(FlipperHTTP *fhttp);
+bool flip_social_parse_json_explore(FlipperHTTP *fhttp);
 #endif

+ 52 - 28
feed/flip_social_feed.c

@@ -1,15 +1,15 @@
 #include "flip_social_feed.h"
 
-bool flip_social_get_feed(bool alloc_http, int series_index)
+bool flip_social_get_feed(FlipperHTTP *fhttp, int series_index)
 {
     if (!app_instance)
     {
         FURI_LOG_E(TAG, "FlipSocialApp is NULL");
         return false;
     }
-    if (alloc_http && !flipper_http_init(flipper_http_rx_callback, app_instance))
+    if (!fhttp)
     {
-        FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
         return false;
     }
     // Get the feed from the server
@@ -19,11 +19,11 @@ bool flip_social_get_feed(bool alloc_http, int series_index)
         return false;
     }
     snprintf(
-        fhttp.file_path,
-        sizeof(fhttp.file_path),
+        fhttp->file_path,
+        sizeof(fhttp->file_path),
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/feed.json");
 
-    fhttp.save_received_data = true;
+    fhttp->save_received_data = true;
     auth_headers_alloc();
     char command[96];
     if (strstr(flip_social_feed_type[flip_social_feed_type_index], "Global"))
@@ -34,27 +34,35 @@ bool flip_social_get_feed(bool alloc_http, int series_index)
     {
         snprintf(command, 96, "https://www.jblanked.com/flipper/api/feed/%d/%s/%d/max/friends/series/", MAX_FEED_ITEMS, app_instance->login_username_logged_out, series_index);
     }
-    if (!flipper_http_get_request_with_headers(command, auth_headers))
+    if (!flipper_http_request(fhttp, GET, command, auth_headers, NULL))
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for feed");
-        fhttp.state = ISSUE;
+        fhttp->state = ISSUE;
         return false;
     }
-    fhttp.state = RECEIVING;
+    fhttp->state = RECEIVING;
     return true;
 }
 
-FlipSocialFeedMini *flip_social_parse_json_feed()
+FlipSocialFeedMini *flip_social_parse_json_feed(FlipperHTTP *fhttp)
 {
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
+        return NULL;
+    }
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return NULL;
+    }
     // load the received data from the saved file
-    FuriString *feed_data = flipper_http_load_from_file(fhttp.file_path);
+    FuriString *feed_data = flipper_http_load_from_file(fhttp->file_path);
     if (feed_data == NULL)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        flipper_http_deinit();
         return NULL;
     }
-    flipper_http_deinit();
 
     FlipSocialFeedMini *feed_info = (FlipSocialFeedMini *)malloc(sizeof(FlipSocialFeedMini));
     if (!feed_info)
@@ -81,7 +89,8 @@ FlipSocialFeedMini *flip_social_parse_json_feed()
         {
             FURI_LOG_E(TAG, "Failed to parse item fields.");
             furi_string_free(item);
-            furi_string_free(id);
+            if (id)
+                furi_string_free(id);
             continue;
         }
         if (!flip_social_save_post(furi_string_get_cstr(id), furi_string_get_cstr(item)))
@@ -148,11 +157,16 @@ bool flip_social_load_feed_post(int post_id)
     if (username == NULL || message == NULL || flipped == NULL || flips == NULL || date_created == NULL)
     {
         FURI_LOG_E(TAG, "Failed to parse item fields.");
-        furi_string_free(username);
-        furi_string_free(message);
-        furi_string_free(flipped);
-        furi_string_free(flips);
-        furi_string_free(date_created);
+        if (username)
+            furi_string_free(username);
+        if (message)
+            furi_string_free(message);
+        if (flipped)
+            furi_string_free(flipped);
+        if (flips)
+            furi_string_free(flips);
+        if (date_created)
+            furi_string_free(date_created);
         furi_string_free(feed_data);
         return false;
     }
@@ -177,9 +191,19 @@ bool flip_social_load_feed_post(int post_id)
     return true;
 }
 
-bool flip_social_load_initial_feed(bool alloc_http, int series_index)
+bool flip_social_load_initial_feed(FlipperHTTP *fhttp, int series_index)
 {
-    if (fhttp.state == INACTIVE)
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "FlipSocialApp is NULL");
+        return false;
+    }
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
+    if (fhttp->state == INACTIVE)
     {
         FURI_LOG_E(TAG, "HTTP state is INACTIVE");
         return false;
@@ -194,29 +218,29 @@ bool flip_social_load_initial_feed(bool alloc_http, int series_index)
     }
     view_dispatcher_add_view(app_instance->view_dispatcher, loading_view_id, loading_get_view(loading));
     view_dispatcher_switch_to_view(app_instance->view_dispatcher, loading_view_id);
-    if (flip_social_get_feed(alloc_http, series_index)) // start the async request
+    if (flip_social_get_feed(fhttp, series_index)) // start the async request
     {
-        furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
-        fhttp.state = RECEIVING;
+        furi_timer_start(fhttp->get_timeout_timer, TIMEOUT_DURATION_TICKS);
+        fhttp->state = RECEIVING;
     }
     else
     {
         FURI_LOG_E(HTTP_TAG, "Failed to send request");
-        fhttp.state = ISSUE;
+        fhttp->state = ISSUE;
         view_dispatcher_switch_to_view(app_instance->view_dispatcher, FlipSocialViewLoggedInSubmenu);
         view_dispatcher_remove_view(app_instance->view_dispatcher, loading_view_id);
         loading_free(loading);
         return false;
     }
-    while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
+    while (fhttp->state == RECEIVING && furi_timer_is_running(fhttp->get_timeout_timer) > 0)
     {
         // Wait for the request to be received
         furi_delay_ms(100);
     }
-    furi_timer_stop(fhttp.get_timeout_timer);
+    furi_timer_stop(fhttp->get_timeout_timer);
 
     // load feed info
-    flip_feed_info = flip_social_parse_json_feed();
+    flip_feed_info = flip_social_parse_json_feed(fhttp);
     if (!flip_feed_info || flip_feed_info->count < 1)
     {
         FURI_LOG_E(TAG, "Failed to parse JSON feed");

+ 3 - 3
feed/flip_social_feed.h

@@ -4,8 +4,8 @@
 #include <callback/flip_social_callback.h>
 #include <flip_storage/flip_social_storage.h>
 
-bool flip_social_get_feed(bool alloc_http, int series_index);
+bool flip_social_get_feed(FlipperHTTP *fhttp, int series_index);
+FlipSocialFeedMini *flip_social_parse_json_feed(FlipperHTTP *fhttp);
 bool flip_social_load_feed_post(int post_id);
-bool flip_social_load_initial_feed(bool alloc_http, int series_index);
-FlipSocialFeedMini *flip_social_parse_json_feed();
+bool flip_social_load_initial_feed(FlipperHTTP *fhttp, int series_index);
 #endif

ファイルの差分が大きいため隠しています
+ 789 - 687
flipper_http/flipper_http.c


+ 129 - 287
flipper_http/flipper_http.h

@@ -1,6 +1,8 @@
-// flipper_http.h
-#ifndef FLIPPER_HTTP_H
-#define FLIPPER_HTTP_H
+// Description: Flipper HTTP API (For use with Flipper Zero and the FlipperHTTP flash: https://github.com/jblanked/FlipperHTTP)
+// License: MIT
+// Author: JBlanked
+// File: flipper_http.h
+#pragma once
 
 #include <gui/gui.h>
 #include <gui/view.h>
@@ -12,12 +14,10 @@
 #include <furi_hal_serial.h>
 #include <storage/storage.h>
 
-// STORAGE_EXT_PATH_PREFIX is defined in the Furi SDK as /ext
-
 #define HTTP_TAG "FlipSocial"             // change this to your app name
 #define http_tag "flip_social"            // change this to your app id
 #define UART_CH (FuriHalSerialIdUsart)    // UART channel
-#define TIMEOUT_DURATION_TICKS (8 * 1000) // 8 seconds (increased for Pico W)
+#define TIMEOUT_DURATION_TICKS (8 * 1000) // 8 seconds
 #define BAUDRATE (115200)                 // UART baudrate
 #define RX_BUF_SIZE 2048                  // UART RX buffer size
 #define RX_LINE_BUFFER_SIZE 7000          // UART RX line buffer size (increase for large responses)
@@ -35,7 +35,7 @@ typedef enum
     RECEIVING, // Receiving data
     SENDING,   // Sending data
     ISSUE,     // Issue with connection
-} SerialState;
+} HTTPState;
 
 // Event Flags for UART Worker Thread
 typedef enum
@@ -44,358 +44,200 @@ typedef enum
     WorkerEvtRxDone = (1 << 1),
 } WorkerEvtFlags;
 
-// FlipperHTTP Structure
-typedef struct
+typedef enum
 {
-    FuriStreamBuffer *flipper_http_stream;  // Stream buffer for UART communication
-    FuriHalSerialHandle *serial_handle;     // Serial handle for UART communication
-    FuriThread *rx_thread;                  // Worker thread for UART
-    FuriThreadId rx_thread_id;              // Worker thread ID
-    FlipperHTTP_Callback handle_rx_line_cb; // Callback for received lines
-    void *callback_context;                 // Context for the callback
-    SerialState state;                      // State of the UART
-
-    // variable to store the last received data from the UART
-    char *last_response;
-    char file_path[256]; // Path to save the received data
-
-    // Timer-related members
-    FuriTimer *get_timeout_timer; // Timer for HTTP request timeout
-
-    bool started_receiving_get; // Indicates if a GET request has started
-    bool just_started_get;      // Indicates if GET data reception has just started
-
-    bool started_receiving_post; // Indicates if a POST request has started
-    bool just_started_post;      // Indicates if POST data reception has just started
-
-    bool started_receiving_put; // Indicates if a PUT request has started
-    bool just_started_put;      // Indicates if PUT data reception has just started
+    GET,    // GET request
+    POST,   // POST request
+    PUT,    // PUT request
+    DELETE, // DELETE request
+    //
+    BYTES,      // Stream bytes to file
+    BYTES_POST, // Stream bytes to file after a POST request
+} HTTPMethod;
 
-    bool started_receiving_delete; // Indicates if a DELETE request has started
-    bool just_started_delete;      // Indicates if DELETE data reception has just started
-
-    // Buffer to hold the raw bytes received from the UART
-    uint8_t *received_bytes;
-    size_t received_bytes_len; // Length of the received bytes
-    bool is_bytes_request;     // Flag to indicate if the request is for bytes
-    bool save_bytes;           // Flag to save the received data to a file
-    bool save_received_data;   // Flag to save the received data to a file
-
-    bool just_started_bytes; // Indicates if bytes data reception has just started
+typedef enum
+{
+    HTTP_CMD_WIFI_CONNECT,
+    HTTP_CMD_WIFI_DISCONNECT,
+    HTTP_CMD_IP_ADDRESS,
+    HTTP_CMD_IP_WIFI,
+    HTTP_CMD_SCAN,
+    HTTP_CMD_LIST_COMMANDS,
+    HTTP_CMD_LED_ON,
+    HTTP_CMD_LED_OFF,
+    HTTP_CMD_PING,
+    HTTP_CMD_REBOOT
+} HTTPCommand; // list of non-input commands
 
-    char rx_line_buffer[RX_LINE_BUFFER_SIZE];
-    uint8_t file_buffer[FILE_BUFFER_SIZE];
-    size_t file_buffer_len;
+// FlipperHTTP Structure
+typedef struct
+{
+    FuriStreamBuffer *flipper_http_stream;    // Stream buffer for UART communication
+    FuriHalSerialHandle *serial_handle;       // Serial handle for UART communication
+    FuriThread *rx_thread;                    // Worker thread for UART
+    FuriThreadId rx_thread_id;                // Worker thread ID
+    FlipperHTTP_Callback handle_rx_line_cb;   // Callback for received lines
+    void *callback_context;                   // Context for the callback
+    HTTPState state;                          // State of the UART
+    HTTPMethod method;                        // HTTP method
+    char *last_response;                      // variable to store the last received data from the UART
+    char file_path[256];                      // Path to save the received data
+    FuriTimer *get_timeout_timer;             // Timer for HTTP request timeout
+    bool started_receiving;                   // Indicates if a request has started
+    bool just_started;                        // Indicates if data reception has just started
+    bool is_bytes_request;                    // Flag to indicate if the request is for bytes
+    bool save_bytes;                          // Flag to save the received data to a file
+    bool save_received_data;                  // Flag to save the received data to a file
+    bool just_started_bytes;                  // Indicates if bytes data reception has just started
+    size_t bytes_received;                    // Number of bytes received
+    char rx_line_buffer[RX_LINE_BUFFER_SIZE]; // Buffer for received lines
+    uint8_t file_buffer[FILE_BUFFER_SIZE];    // Buffer for file data
+    size_t file_buffer_len;                   // Length of the file buffer
+    size_t content_length;                    // Length of the content received
+    int status_code;                          // HTTP status code
 } FlipperHTTP;
 
-extern FlipperHTTP fhttp;
-
-// fhttp.last_response holds the last received data from the UART
-
-// Function to append received data to file
-// make sure to initialize the file path before calling this function
-bool flipper_http_append_to_file(
-    const void *data,
-    size_t data_size,
-    bool start_new_file,
-    char *file_path);
-
-FuriString *flipper_http_load_from_file(char *file_path);
-
-// UART worker thread
-/**
- * @brief      Worker thread to handle UART data asynchronously.
- * @return     0
- * @param      context   The context to pass to the callback.
- * @note       This function will handle received data asynchronously via the callback.
- */
-// UART worker thread
-int32_t flipper_http_worker(void *context);
-
-// Timer callback function
-/**
- * @brief      Callback function for the GET timeout timer.
- * @return     0
- * @param      context   The context to pass to the callback.
- * @note       This function will be called when the GET request times out.
- */
-void get_timeout_timer_callback(void *context);
-
-// UART RX Handler Callback (Interrupt Context)
-/**
- * @brief      A private callback function to handle received data asynchronously.
- * @return     void
- * @param      handle    The UART handle.
- * @param      event     The event type.
- * @param      context   The context to pass to the callback.
- * @note       This function will handle received data asynchronously via the callback.
- */
-void _flipper_http_rx_callback(
-    FuriHalSerialHandle *handle,
-    FuriHalSerialRxEvent event,
-    void *context);
-
-// UART initialization function
 /**
  * @brief      Initialize UART.
- * @return     true if the UART was initialized successfully, false otherwise.
- * @param      callback  The callback function to handle received data (ex. flipper_http_rx_callback).
- * @param      context   The context to pass to the callback.
+ * @return     FlipperHTTP context if the UART was initialized successfully, NULL otherwise.
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_init(FlipperHTTP_Callback callback, void *context);
+FlipperHTTP *flipper_http_alloc();
 
-// Deinitialize UART
 /**
  * @brief      Deinitialize UART.
  * @return     void
+ * @param fhttp The FlipperHTTP context
  * @note       This function will stop the asynchronous RX, release the serial handle, and free the resources.
  */
-void flipper_http_deinit();
+void flipper_http_free(FlipperHTTP *fhttp);
 
-// Function to send data over UART with newline termination
 /**
- * @brief      Send data over UART with newline termination.
- * @return     true if the data was sent successfully, false otherwise.
- * @param      data  The data to send over UART.
- * @note       The data will be sent over UART with a newline character appended.
+ * @brief      Append received data to a file.
+ * @return     true if the data was appended successfully, false otherwise.
+ * @param      data        The data to append to the file.
+ * @param      data_size   The size of the data to append.
+ * @param      start_new_file  Flag to indicate if a new file should be created.
+ * @param      file_path   The path to the file.
+ * @note       Make sure to initialize the file path before calling this function.
  */
-bool flipper_http_send_data(const char *data);
+bool flipper_http_append_to_file(const void *data, size_t data_size, bool start_new_file, char *file_path);
 
-// Function to send a PING request
 /**
- * @brief      Send a PING request to check if the Wifi Dev Board is connected.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- * @note       This is best used to check if the Wifi Dev Board is connected.
- * @note       The state will remain INACTIVE until a PONG is received.
+ * @brief      Load data from a file.
+ * @return     The loaded data as a FuriString.
+ * @param      file_path The path to the file to load.
  */
-bool flipper_http_ping();
+FuriString *flipper_http_load_from_file(char *file_path);
 
-// Function to list available commands
 /**
- * @brief      Send a command to list available commands.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
+ * @brief      Load data from a file with a size limit.
+ * @return     The loaded data as a FuriString.
+ * @param      file_path The path to the file to load.
+ * @param      limit     The size limit for loading data.
  */
-bool flipper_http_list_commands();
+FuriString *flipper_http_load_from_file_with_limit(char *file_path, size_t limit);
 
-// Function to turn on the LED
 /**
- * @brief      Allow the LED to display while processing.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_led_on();
-
-// Function to turn off the LED
-/**
- * @brief      Disable the LED from displaying while processing.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
+ * @brief Perform a task while displaying a loading screen
+ * @param fhttp The FlipperHTTP context
+ * @param http_request The function to send the request
+ * @param parse_response The function to parse the response
+ * @param success_view_id The view ID to switch to on success
+ * @param failure_view_id The view ID to switch to on failure
+ * @param view_dispatcher The view dispatcher to use
+ * @return
  */
-bool flipper_http_led_off();
+void flipper_http_loading_task(FlipperHTTP *fhttp,
+                               bool (*http_request)(void),
+                               bool (*parse_response)(void),
+                               uint32_t success_view_id,
+                               uint32_t failure_view_id,
+                               ViewDispatcher **view_dispatcher);
 
-// Function to parse JSON data
 /**
  * @brief      Parse JSON data.
  * @return     true if the JSON data was parsed successfully, false otherwise.
+ * @param fhttp The FlipperHTTP context
  * @param      key       The key to parse from the JSON data.
  * @param      json_data The JSON data to parse.
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_parse_json(const char *key, const char *json_data);
+bool flipper_http_parse_json(FlipperHTTP *fhttp, const char *key, const char *json_data);
 
-// Function to parse JSON array data
 /**
  * @brief      Parse JSON array data.
  * @return     true if the JSON array data was parsed successfully, false otherwise.
+ * @param fhttp The FlipperHTTP context
  * @param      key       The key to parse from the JSON array data.
  * @param      index     The index to parse from the JSON array data.
  * @param      json_data The JSON array data to parse.
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_parse_json_array(const char *key, int index, const char *json_data);
-
-// Function to scan for WiFi networks
-/**
- * @brief      Send a command to scan for WiFi networks.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_scan_wifi();
-
-// Function to save WiFi settings (returns true if successful)
-/**
- * @brief      Send a command to save WiFi settings.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_save_wifi(const char *ssid, const char *password);
+bool flipper_http_parse_json_array(FlipperHTTP *fhttp, const char *key, int index, const char *json_data);
 
-// Function to get IP address of WiFi Devboard
 /**
- * @brief      Send a command to get the IP address of the WiFi Devboard
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_ip_address();
-
-// Function to get IP address of the connected WiFi network
-/**
- * @brief      Send a command to get the IP address of the connected WiFi network.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_ip_wifi();
-
-// Function to disconnect from WiFi (returns true if successful)
-/**
- * @brief      Send a command to disconnect from WiFi.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_disconnect_wifi();
-
-// Function to connect to WiFi (returns true if successful)
-/**
- * @brief      Send a command to connect to WiFi.
- * @return     true if the request was successful, false otherwise.
- * @note       The received data will be handled asynchronously via the callback.
- */
-bool flipper_http_connect_wifi();
-
-// Function to send a GET request
-/**
- * @brief      Send a GET request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the GET request to.
- * @note       The received data will be handled asynchronously via the callback.
+ * @brief Process requests and parse JSON data asynchronously
+ * @param fhttp The FlipperHTTP context
+ * @param http_request The function to send the request
+ * @param parse_json The function to parse the JSON
+ * @return true if successful, false otherwise
  */
-bool flipper_http_get_request(const char *url);
+bool flipper_http_process_response_async(FlipperHTTP *fhttp, bool (*http_request)(void), bool (*parse_json)(void));
 
-// Function to send a GET request with headers
 /**
- * @brief      Send a GET request to the specified URL.
+ * @brief      Send a request to the specified URL.
  * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the GET request to.
- * @param      headers  The headers to send with the GET request.
+ * @param      fhttp The FlipperHTTP context
+ * @param      method The HTTP method to use.
+ * @param      url  The URL to send the request to.
+ * @param      headers  The headers to send with the request.
+ * @param      payload  The data to send with the request.
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_get_request_with_headers(const char *url, const char *headers);
+bool flipper_http_request(FlipperHTTP *fhttp, HTTPMethod method, const char *url, const char *headers, const char *payload);
 
-// Function to send a GET request with headers and return bytes
 /**
- * @brief      Send a GET request to the specified URL.
+ * @brief      Send a command to save WiFi settings.
  * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the GET request to.
- * @param      headers  The headers to send with the GET request.
+ * @param fhttp The FlipperHTTP context
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_get_request_bytes(const char *url, const char *headers);
+bool flipper_http_save_wifi(FlipperHTTP *fhttp, const char *ssid, const char *password);
 
-// Function to send a POST request with headers
 /**
- * @brief      Send a POST request to the specified URL.
+ * @brief      Send a command.
  * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the POST request to.
- * @param      headers  The headers to send with the POST request.
- * @param      data  The data to send with the POST request.
+ * @param      fhttp The FlipperHTTP context
+ * @param      command The command to send.
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_post_request_with_headers(
-    const char *url,
-    const char *headers,
-    const char *payload);
+bool flipper_http_send_command(FlipperHTTP *fhttp, HTTPCommand command);
 
-// Function to send a POST request with headers and return bytes
 /**
- * @brief      Send a POST request to the specified URL.
- * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the POST request to.
- * @param      headers  The headers to send with the POST request.
- * @param      payload  The data to send with the POST request.
- * @note       The received data will be handled asynchronously via the callback.
+ * @brief      Send data over UART with newline termination.
+ * @return     true if the data was sent successfully, false otherwise.
+ * @param fhttp The FlipperHTTP context
+ * @param      data  The data to send over UART.
+ * @note       The data will be sent over UART with a newline character appended.
  */
-bool flipper_http_post_request_bytes(const char *url, const char *headers, const char *payload);
+bool flipper_http_send_data(FlipperHTTP *fhttp, const char *data);
 
-// Function to send a PUT request with headers
 /**
- * @brief      Send a PUT request to the specified URL.
+ * @brief      Send a request to the specified URL to start a WebSocket connection.
  * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the PUT request to.
- * @param      headers  The headers to send with the PUT request.
- * @param      data  The data to send with the PUT request.
+ * @param fhttp The FlipperHTTP context
+ * @param      url  The URL to send the WebSocket request to.
+ * @param port The port to connect to
+ * @param headers The headers to send with the WebSocket request
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_put_request_with_headers(
-    const char *url,
-    const char *headers,
-    const char *payload);
+bool flipper_http_websocket_start(FlipperHTTP *fhttp, const char *url, uint16_t port, const char *headers);
 
-// Function to send a DELETE request with headers
 /**
- * @brief      Send a DELETE request to the specified URL.
+ * @brief      Send a request to stop the WebSocket connection.
  * @return     true if the request was successful, false otherwise.
- * @param      url  The URL to send the DELETE request to.
- * @param      headers  The headers to send with the DELETE request.
- * @param      data  The data to send with the DELETE request.
+ * @param fhttp The FlipperHTTP context
  * @note       The received data will be handled asynchronously via the callback.
  */
-bool flipper_http_delete_request_with_headers(
-    const char *url,
-    const char *headers,
-    const char *payload);
-
-// Function to handle received data asynchronously
-/**
- * @brief      Callback function to handle received data asynchronously.
- * @return     void
- * @param      line     The received line.
- * @param      context  The context passed to the callback.
- * @note       The received data will be handled asynchronously via the callback and handles the state of the UART.
- */
-void flipper_http_rx_callback(const char *line, void *context);
-
-// Function to trim leading and trailing spaces and newlines from a constant string
-char *trim(const char *str);
-/**
- * @brief Process requests and parse JSON data asynchronously
- * @param http_request The function to send the request
- * @param parse_json The function to parse the JSON
- * @return true if successful, false otherwise
- */
-bool flipper_http_process_response_async(bool (*http_request)(void), bool (*parse_json)(void));
-bool flipper_http_process_response_async_2(bool (*http_request)(void), int (*parse_json)(void));
-
-/**
- * @brief Perform a task while displaying a loading screen
- * @param http_request The function to send the request
- * @param parse_response The function to parse the response
- * @param success_view_id The view ID to switch to on success
- * @param failure_view_id The view ID to switch to on failure
- * @param view_dispatcher The view dispatcher to use
- * @return
- */
-void flipper_http_loading_task(bool (*http_request)(void),
-                               bool (*parse_response)(void),
-                               uint32_t success_view_id,
-                               uint32_t failure_view_id,
-                               ViewDispatcher **view_dispatcher);
-
-/**
- * @brief Perform a task while displaying a loading screen
- * @param http_request The function to send the request
- * @param parse_response The function to parse the response
- * @param success_view_id The view ID to switch to on success
- * @param failure_view_id The view ID to switch to on failure
- * @param view_dispatcher The view dispatcher to use
- * @return
- */
-void flipper_http_loading_task_2(bool (*http_request)(void),
-                                 int (*parse_response)(void),
-                                 uint32_t success_view_id,
-                                 uint32_t failure_view_id,
-                                 ViewDispatcher **view_dispatcher);
-
-#endif // FLIPPER_HTTP_H
+bool flipper_http_websocket_stop(FlipperHTTP *fhttp);

+ 28 - 11
friends/flip_social_friends.c

@@ -14,35 +14,48 @@ FlipSocialModel *flip_social_friends_alloc()
 
 // for now we're just listing the current users
 // as the feed is upgraded, then we can port more to the friends view
-bool flip_social_get_friends()
+bool flip_social_get_friends(FlipperHTTP *fhttp)
 {
     if (!app_instance)
     {
         FURI_LOG_E(TAG, "App instance is NULL");
         return false;
     }
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
+    // Create the directory
+    Storage *storage = furi_record_open(RECORD_STORAGE);
+    storage_common_mkdir(storage, STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/friends");
     // will return true unless the devboard is not connected
     char url[100];
     snprintf(
-        fhttp.file_path,
-        sizeof(fhttp.file_path),
+        fhttp->file_path,
+        sizeof(fhttp->file_path),
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/friends.json");
 
-    fhttp.save_received_data = true;
+    fhttp->save_received_data = true;
     auth_headers_alloc();
     snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/user/friends/%s/", app_instance->login_username_logged_in);
-    if (!flipper_http_get_request_with_headers(url, auth_headers))
+    if (!flipper_http_request(fhttp, GET, url, auth_headers, NULL))
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for friends");
-        fhttp.state = ISSUE;
+        fhttp->state = ISSUE;
         return false;
     }
-    fhttp.state = RECEIVING;
+    fhttp->state = RECEIVING;
     return true;
 }
 
 bool flip_social_update_friends()
 {
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "App instance is NULL");
+        return false;
+    }
     if (!app_instance->submenu)
     {
         FURI_LOG_E(TAG, "Friends submenu is NULL");
@@ -63,14 +76,18 @@ bool flip_social_update_friends()
     return true;
 }
 
-bool flip_social_parse_json_friends()
+bool flip_social_parse_json_friends(FlipperHTTP *fhttp)
 {
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
     // load the received data from the saved file
-    FuriString *friend_data = flipper_http_load_from_file(fhttp.file_path);
+    FuriString *friend_data = flipper_http_load_from_file(fhttp->file_path);
     if (friend_data == NULL)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        flipper_http_deinit();
         return false;
     }
 
@@ -106,6 +123,6 @@ bool flip_social_parse_json_friends()
         furi_string_free(friend);
     }
     furi_string_free(friend_data);
-    // flipper_http_deinit();
+
     return true;
 }

+ 2 - 2
friends/flip_social_friends.h

@@ -4,7 +4,7 @@
 #include <callback/flip_social_callback.h>
 
 FlipSocialModel *flip_social_friends_alloc();
-bool flip_social_get_friends();
+bool flip_social_get_friends(FlipperHTTP *fhttp);
 bool flip_social_update_friends();
-bool flip_social_parse_json_friends();
+bool flip_social_parse_json_friends(FlipperHTTP *fhttp);
 #endif

+ 57 - 34
messages/flip_social_messages.c

@@ -98,16 +98,21 @@ bool flip_social_update_submenu_user_choices()
 }
 
 // Get all the users that have sent messages to the logged in user
-bool flip_social_get_message_users()
+bool flip_social_get_message_users(FlipperHTTP *fhttp)
 {
-    if (app_instance->login_username_logged_out == NULL)
+    if (!app_instance)
     {
-        FURI_LOG_E(TAG, "Username is NULL");
+        FURI_LOG_E(TAG, "App instance is NULL");
         return false;
     }
-    if (!flipper_http_init(flipper_http_rx_callback, app_instance))
+    if (!fhttp)
     {
-        FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
+    if (app_instance->login_username_logged_out == NULL)
+    {
+        FURI_LOG_E(TAG, "Username is NULL");
         return false;
     }
     char directory[128];
@@ -118,30 +123,34 @@ bool flip_social_get_message_users()
     storage_common_mkdir(storage, directory);
     char command[128];
     snprintf(
-        fhttp.file_path,
-        sizeof(fhttp.file_path),
+        fhttp->file_path,
+        sizeof(fhttp->file_path),
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/messages/message_users.json");
 
-    fhttp.save_received_data = true;
+    fhttp->save_received_data = true;
     auth_headers_alloc();
     snprintf(command, 128, "https://www.jblanked.com/flipper/api/messages/%s/get/list/%d/", app_instance->login_username_logged_out, MAX_MESSAGE_USERS);
-    if (!flipper_http_get_request_with_headers(command, auth_headers))
+    if (!flipper_http_request(fhttp, GET, command, auth_headers, NULL))
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for messages");
-        fhttp.state = ISSUE;
-        flipper_http_deinit();
+        fhttp->state = ISSUE;
         return false;
     }
-    fhttp.state = RECEIVING;
+    fhttp->state = RECEIVING;
     return true;
 }
 
 // Get all the messages between the logged in user and the selected user
-bool flip_social_get_messages_with_user()
+bool flip_social_get_messages_with_user(FlipperHTTP *fhttp)
 {
-    if (!flipper_http_init(flipper_http_rx_callback, app_instance))
+    if (!app_instance)
+    {
+        FURI_LOG_E(TAG, "App instance is NULL");
+        return false;
+    }
+    if (!fhttp)
     {
-        FURI_LOG_E(TAG, "Failed to initialize FlipperHTTP");
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
         return false;
     }
     if (app_instance->login_username_logged_out == NULL)
@@ -163,36 +172,39 @@ bool flip_social_get_messages_with_user()
 
     char command[256];
     snprintf(
-        fhttp.file_path,
-        sizeof(fhttp.file_path),
+        fhttp->file_path,
+        sizeof(fhttp->file_path),
         STORAGE_EXT_PATH_PREFIX "/apps_data/flip_social/messages/%s_messages.json",
         flip_social_message_users->usernames[flip_social_message_users->index]);
 
-    fhttp.save_received_data = true;
+    fhttp->save_received_data = true;
     auth_headers_alloc();
     snprintf(command, sizeof(command), "https://www.jblanked.com/flipper/api/messages/%s/get/%s/%d/", app_instance->login_username_logged_out, flip_social_message_users->usernames[flip_social_message_users->index], MAX_MESSAGES);
-    if (!flipper_http_get_request_with_headers(command, auth_headers))
+    if (!flipper_http_request(fhttp, GET, command, auth_headers, NULL))
     {
         FURI_LOG_E(TAG, "Failed to send HTTP request for messages");
-        fhttp.state = ISSUE;
+        fhttp->state = ISSUE;
         return false;
     }
-    fhttp.state = RECEIVING;
+    fhttp->state = RECEIVING;
     return true;
 }
 
 // Parse the users that have sent messages to the logged-in user
-bool flip_social_parse_json_message_users()
+bool flip_social_parse_json_message_users(FlipperHTTP *fhttp)
 {
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
     // load the received data from the saved file
-    FuriString *message_data = flipper_http_load_from_file(fhttp.file_path);
+    FuriString *message_data = flipper_http_load_from_file(fhttp->file_path);
     if (message_data == NULL)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        flipper_http_deinit();
         return false;
     }
-    flipper_http_deinit();
 
     // Allocate memory for each username only if not already allocated
     flip_social_message_users = flip_social_messages_alloc();
@@ -227,19 +239,22 @@ bool flip_social_parse_json_message_users()
 }
 
 // Parse the users that the logged in user can message
-bool flip_social_parse_json_message_user_choices()
+bool flip_social_parse_json_message_user_choices(FlipperHTTP *fhttp)
 {
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
+
     // load the received data from the saved file
-    FuriString *user_data = flipper_http_load_from_file(fhttp.file_path);
+    FuriString *user_data = flipper_http_load_from_file(fhttp->file_path);
     if (user_data == NULL)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        flipper_http_deinit();
         return false;
     }
 
-    flipper_http_deinit();
-
     // Allocate memory for each username only if not already allocated
     flip_social_explore = flip_social_explore_alloc();
     if (flip_social_explore == NULL)
@@ -273,17 +288,21 @@ bool flip_social_parse_json_message_user_choices()
 }
 
 // parse messages between the logged in user and the selected user
-bool flip_social_parse_json_messages()
+bool flip_social_parse_json_messages(FlipperHTTP *fhttp)
 {
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "FlipperHTTP is NULL");
+        return false;
+    }
+
     // load the received data from the saved file
-    FuriString *message_data = flipper_http_load_from_file(fhttp.file_path);
+    FuriString *message_data = flipper_http_load_from_file(fhttp->file_path);
     if (message_data == NULL)
     {
         FURI_LOG_E(TAG, "Failed to load received data from file.");
-        flipper_http_deinit();
         return false;
     }
-    flipper_http_deinit();
 
     // Allocate memory for each message only if not already allocated
     flip_social_messages = flip_social_user_messages_alloc();
@@ -314,6 +333,10 @@ bool flip_social_parse_json_messages()
         if (sender == NULL || content == NULL)
         {
             FURI_LOG_E(TAG, "Failed to parse item fields.");
+            if (sender)
+                furi_string_free(sender);
+            if (content)
+                furi_string_free(content);
             furi_string_free(item);
             continue;
         }

+ 5 - 5
messages/flip_social_messages.h

@@ -12,16 +12,16 @@ void flip_social_free_messages();
 bool flip_social_update_messages_submenu();
 bool flip_social_update_submenu_user_choices();
 // Get all the users that have sent messages to the logged in user
-bool flip_social_get_message_users();
+bool flip_social_get_message_users(FlipperHTTP *fhttp);
 // Get all the messages between the logged in user and the selected user
-bool flip_social_get_messages_with_user();
+bool flip_social_get_messages_with_user(FlipperHTTP *fhttp);
 // Parse the users that have sent messages to the logged-in user
-bool flip_social_parse_json_message_users();
+bool flip_social_parse_json_message_users(FlipperHTTP *fhttp);
 
 // Parse the users that the logged in user can message
-bool flip_social_parse_json_message_user_choices();
+bool flip_social_parse_json_message_user_choices(FlipperHTTP *fhttp);
 
 // parse messages between the logged in user and the selected user
-bool flip_social_parse_json_messages();
+bool flip_social_parse_json_messages(FlipperHTTP *fhttp);
 
 #endif

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません