|
@@ -1,7 +1,8 @@
|
|
|
-#include <flipper_http/flipper_http.h>
|
|
|
|
|
|
|
+#include <flipper_http/flipper_http.h> // change this to where flipper_http.h is located
|
|
|
FlipperHTTP fhttp;
|
|
FlipperHTTP fhttp;
|
|
|
char rx_line_buffer[RX_LINE_BUFFER_SIZE];
|
|
char rx_line_buffer[RX_LINE_BUFFER_SIZE];
|
|
|
uint8_t file_buffer[FILE_BUFFER_SIZE];
|
|
uint8_t file_buffer[FILE_BUFFER_SIZE];
|
|
|
|
|
+size_t file_buffer_len = 0;
|
|
|
// Function to append received data to file
|
|
// Function to append received data to file
|
|
|
// make sure to initialize the file path before calling this function
|
|
// make sure to initialize the file path before calling this function
|
|
|
bool flipper_http_append_to_file(
|
|
bool flipper_http_append_to_file(
|
|
@@ -13,6 +14,15 @@ bool flipper_http_append_to_file(
|
|
|
File* file = storage_file_alloc(storage);
|
|
File* file = storage_file_alloc(storage);
|
|
|
|
|
|
|
|
if(start_new_file) {
|
|
if(start_new_file) {
|
|
|
|
|
+ // Delete the file if it already exists
|
|
|
|
|
+ if(storage_file_exists(storage, file_path)) {
|
|
|
|
|
+ if(!storage_simply_remove_recursive(storage, file_path)) {
|
|
|
|
|
+ FURI_LOG_E(HTTP_TAG, "Failed to delete file: %s", file_path);
|
|
|
|
|
+ storage_file_free(file);
|
|
|
|
|
+ furi_record_close(RECORD_STORAGE);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
// Open the file in write mode
|
|
// Open the file in write mode
|
|
|
if(!storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
|
if(!storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
|
|
FURI_LOG_E(HTTP_TAG, "Failed to open file for writing: %s", file_path);
|
|
FURI_LOG_E(HTTP_TAG, "Failed to open file for writing: %s", file_path);
|
|
@@ -131,12 +141,13 @@ FuriString* flipper_http_load_from_file(char* file_path) {
|
|
|
int32_t flipper_http_worker(void* context) {
|
|
int32_t flipper_http_worker(void* context) {
|
|
|
UNUSED(context);
|
|
UNUSED(context);
|
|
|
size_t rx_line_pos = 0;
|
|
size_t rx_line_pos = 0;
|
|
|
- static size_t file_buffer_len = 0;
|
|
|
|
|
|
|
|
|
|
while(1) {
|
|
while(1) {
|
|
|
uint32_t events = furi_thread_flags_wait(
|
|
uint32_t events = furi_thread_flags_wait(
|
|
|
WorkerEvtStop | WorkerEvtRxDone, FuriFlagWaitAny, FuriWaitForever);
|
|
WorkerEvtStop | WorkerEvtRxDone, FuriFlagWaitAny, FuriWaitForever);
|
|
|
- if(events & WorkerEvtStop) break;
|
|
|
|
|
|
|
+ if(events & WorkerEvtStop) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
if(events & WorkerEvtRxDone) {
|
|
if(events & WorkerEvtRxDone) {
|
|
|
// Continuously read from the stream buffer until it's empty
|
|
// Continuously read from the stream buffer until it's empty
|
|
|
while(!furi_stream_buffer_is_empty(fhttp.flipper_http_stream)) {
|
|
while(!furi_stream_buffer_is_empty(fhttp.flipper_http_stream)) {
|
|
@@ -156,10 +167,14 @@ int32_t flipper_http_worker(void* context) {
|
|
|
// Write to file if buffer is full
|
|
// Write to file if buffer is full
|
|
|
if(file_buffer_len >= FILE_BUFFER_SIZE) {
|
|
if(file_buffer_len >= FILE_BUFFER_SIZE) {
|
|
|
if(!flipper_http_append_to_file(
|
|
if(!flipper_http_append_to_file(
|
|
|
- file_buffer, file_buffer_len, false, fhttp.file_path)) {
|
|
|
|
|
|
|
+ file_buffer,
|
|
|
|
|
+ file_buffer_len,
|
|
|
|
|
+ fhttp.just_started_bytes,
|
|
|
|
|
+ fhttp.file_path)) {
|
|
|
FURI_LOG_E(HTTP_TAG, "Failed to append data to file");
|
|
FURI_LOG_E(HTTP_TAG, "Failed to append data to file");
|
|
|
}
|
|
}
|
|
|
file_buffer_len = 0;
|
|
file_buffer_len = 0;
|
|
|
|
|
+ fhttp.just_started_bytes = false;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -182,36 +197,6 @@ int32_t flipper_http_worker(void* context) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if(fhttp.save_bytes) {
|
|
|
|
|
- // Write the remaining data to the file
|
|
|
|
|
- if(file_buffer_len > 0) {
|
|
|
|
|
- if(!flipper_http_append_to_file(file_buffer, file_buffer_len, false, fhttp.file_path)) {
|
|
|
|
|
- FURI_LOG_E(HTTP_TAG, "Failed to append remaining data to file");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // remove [POST/END] and/or [GET/END] from the file
|
|
|
|
|
- if(fhttp.save_bytes) {
|
|
|
|
|
- char* end = NULL;
|
|
|
|
|
- if((end = strstr(fhttp.file_path, "[POST/END]")) != NULL) {
|
|
|
|
|
- *end = '\0';
|
|
|
|
|
- } else if((end = strstr(fhttp.file_path, "[GET/END]")) != NULL) {
|
|
|
|
|
- *end = '\0';
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // remove newline from the from the end of the file
|
|
|
|
|
- if(fhttp.save_bytes) {
|
|
|
|
|
- char* end = NULL;
|
|
|
|
|
- if((end = strstr(fhttp.file_path, "\n")) != NULL) {
|
|
|
|
|
- *end = '\0';
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Reset the file buffer length
|
|
|
|
|
- file_buffer_len = 0;
|
|
|
|
|
-
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
// Timer callback function
|
|
// Timer callback function
|
|
@@ -418,13 +403,13 @@ bool flipper_http_send_data(const char* data) {
|
|
|
|
|
|
|
|
// Create a buffer with data + '\n'
|
|
// Create a buffer with data + '\n'
|
|
|
size_t send_length = data_length + 1; // +1 for '\n'
|
|
size_t send_length = data_length + 1; // +1 for '\n'
|
|
|
- if(send_length > 256) { // Ensure buffer size is sufficient
|
|
|
|
|
|
|
+ if(send_length > 512) { // Ensure buffer size is sufficient
|
|
|
FURI_LOG_E("FlipperHTTP", "Data too long to send over FHTTP.");
|
|
FURI_LOG_E("FlipperHTTP", "Data too long to send over FHTTP.");
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- char send_buffer[257]; // 256 + 1 for safety
|
|
|
|
|
- strncpy(send_buffer, data, 256);
|
|
|
|
|
|
|
+ char send_buffer[513]; // 512 + 1 for safety
|
|
|
|
|
+ strncpy(send_buffer, data, 512);
|
|
|
send_buffer[data_length] = '\n'; // Append newline
|
|
send_buffer[data_length] = '\n'; // Append newline
|
|
|
send_buffer[data_length + 1] = '\0'; // Null-terminate
|
|
send_buffer[data_length + 1] = '\0'; // Null-terminate
|
|
|
|
|
|
|
@@ -710,7 +695,7 @@ bool flipper_http_get_request(const char* url) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare GET request command
|
|
// Prepare GET request command
|
|
|
- char command[256];
|
|
|
|
|
|
|
+ char command[512];
|
|
|
int ret = snprintf(command, sizeof(command), "[GET]%s", url);
|
|
int ret = snprintf(command, sizeof(command), "[GET]%s", url);
|
|
|
if(ret < 0 || ret >= (int)sizeof(command)) {
|
|
if(ret < 0 || ret >= (int)sizeof(command)) {
|
|
|
FURI_LOG_E("FlipperHTTP", "Failed to format GET request command.");
|
|
FURI_LOG_E("FlipperHTTP", "Failed to format GET request command.");
|
|
@@ -742,7 +727,7 @@ bool flipper_http_get_request_with_headers(const char* url, const char* headers)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare GET request command with headers
|
|
// Prepare GET request command with headers
|
|
|
- char command[256];
|
|
|
|
|
|
|
+ char command[512];
|
|
|
int ret = snprintf(
|
|
int ret = snprintf(
|
|
|
command, sizeof(command), "[GET/HTTP]{\"url\":\"%s\",\"headers\":%s}", url, headers);
|
|
command, sizeof(command), "[GET/HTTP]{\"url\":\"%s\",\"headers\":%s}", url, headers);
|
|
|
if(ret < 0 || ret >= (int)sizeof(command)) {
|
|
if(ret < 0 || ret >= (int)sizeof(command)) {
|
|
@@ -774,7 +759,7 @@ bool flipper_http_get_request_bytes(const char* url, const char* headers) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare GET request command with headers
|
|
// Prepare GET request command with headers
|
|
|
- char command[256];
|
|
|
|
|
|
|
+ char command[512];
|
|
|
int ret = snprintf(
|
|
int ret = snprintf(
|
|
|
command, sizeof(command), "[GET/BYTES]{\"url\":\"%s\",\"headers\":%s}", url, headers);
|
|
command, sizeof(command), "[GET/BYTES]{\"url\":\"%s\",\"headers\":%s}", url, headers);
|
|
|
if(ret < 0 || ret >= (int)sizeof(command)) {
|
|
if(ret < 0 || ret >= (int)sizeof(command)) {
|
|
@@ -812,7 +797,7 @@ bool flipper_http_post_request_with_headers(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare POST request command with headers and data
|
|
// Prepare POST request command with headers and data
|
|
|
- char command[256];
|
|
|
|
|
|
|
+ char command[512];
|
|
|
int ret = snprintf(
|
|
int ret = snprintf(
|
|
|
command,
|
|
command,
|
|
|
sizeof(command),
|
|
sizeof(command),
|
|
@@ -851,7 +836,7 @@ bool flipper_http_post_request_bytes(const char* url, const char* headers, const
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare POST request command with headers and data
|
|
// Prepare POST request command with headers and data
|
|
|
- char command[256];
|
|
|
|
|
|
|
+ char command[512];
|
|
|
int ret = snprintf(
|
|
int ret = snprintf(
|
|
|
command,
|
|
command,
|
|
|
sizeof(command),
|
|
sizeof(command),
|
|
@@ -1006,8 +991,35 @@ void flipper_http_rx_callback(const char* line, void* context) {
|
|
|
fhttp.just_started_get = false;
|
|
fhttp.just_started_get = false;
|
|
|
fhttp.state = IDLE;
|
|
fhttp.state = IDLE;
|
|
|
fhttp.save_bytes = false;
|
|
fhttp.save_bytes = false;
|
|
|
- fhttp.is_bytes_request = false;
|
|
|
|
|
fhttp.save_received_data = false;
|
|
fhttp.save_received_data = false;
|
|
|
|
|
+
|
|
|
|
|
+ if(fhttp.is_bytes_request) {
|
|
|
|
|
+ // Search for the binary marker `[GET/END]` in the file buffer
|
|
|
|
|
+ const char marker[] = "[GET/END]";
|
|
|
|
|
+ const size_t marker_len = sizeof(marker) - 1; // Exclude null terminator
|
|
|
|
|
+
|
|
|
|
|
+ for(size_t i = 0; i <= file_buffer_len - marker_len; i++) {
|
|
|
|
|
+ // Check if the marker is found
|
|
|
|
|
+ if(memcmp(&file_buffer[i], marker, marker_len) == 0) {
|
|
|
|
|
+ // Remove the marker by shifting the remaining data left
|
|
|
|
|
+ size_t remaining_len = file_buffer_len - (i + marker_len);
|
|
|
|
|
+ memmove(&file_buffer[i], &file_buffer[i + marker_len], remaining_len);
|
|
|
|
|
+ file_buffer_len -= marker_len;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // If there is data left in the buffer, append it to the file
|
|
|
|
|
+ if(file_buffer_len > 0) {
|
|
|
|
|
+ if(!flipper_http_append_to_file(
|
|
|
|
|
+ file_buffer, file_buffer_len, false, fhttp.file_path)) {
|
|
|
|
|
+ FURI_LOG_E(HTTP_TAG, "Failed to append data to file.");
|
|
|
|
|
+ }
|
|
|
|
|
+ file_buffer_len = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fhttp.is_bytes_request = false;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1041,8 +1053,35 @@ void flipper_http_rx_callback(const char* line, void* context) {
|
|
|
fhttp.just_started_post = false;
|
|
fhttp.just_started_post = false;
|
|
|
fhttp.state = IDLE;
|
|
fhttp.state = IDLE;
|
|
|
fhttp.save_bytes = false;
|
|
fhttp.save_bytes = false;
|
|
|
- fhttp.is_bytes_request = false;
|
|
|
|
|
fhttp.save_received_data = false;
|
|
fhttp.save_received_data = false;
|
|
|
|
|
+
|
|
|
|
|
+ if(fhttp.is_bytes_request) {
|
|
|
|
|
+ // Search for the binary marker `[POST/END]` in the file buffer
|
|
|
|
|
+ const char marker[] = "[POST/END]";
|
|
|
|
|
+ const size_t marker_len = sizeof(marker) - 1; // Exclude null terminator
|
|
|
|
|
+
|
|
|
|
|
+ for(size_t i = 0; i <= file_buffer_len - marker_len; i++) {
|
|
|
|
|
+ // Check if the marker is found
|
|
|
|
|
+ if(memcmp(&file_buffer[i], marker, marker_len) == 0) {
|
|
|
|
|
+ // Remove the marker by shifting the remaining data left
|
|
|
|
|
+ size_t remaining_len = file_buffer_len - (i + marker_len);
|
|
|
|
|
+ memmove(&file_buffer[i], &file_buffer[i + marker_len], remaining_len);
|
|
|
|
|
+ file_buffer_len -= marker_len;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // If there is data left in the buffer, append it to the file
|
|
|
|
|
+ if(file_buffer_len > 0) {
|
|
|
|
|
+ if(!flipper_http_append_to_file(
|
|
|
|
|
+ file_buffer, file_buffer_len, false, fhttp.file_path)) {
|
|
|
|
|
+ FURI_LOG_E(HTTP_TAG, "Failed to append data to file.");
|
|
|
|
|
+ }
|
|
|
|
|
+ file_buffer_len = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fhttp.is_bytes_request = false;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1149,6 +1188,8 @@ void flipper_http_rx_callback(const char* line, void* context) {
|
|
|
fhttp.state = RECEIVING;
|
|
fhttp.state = RECEIVING;
|
|
|
// for GET request, save data only if it's a bytes request
|
|
// for GET request, save data only if it's a bytes request
|
|
|
fhttp.save_bytes = fhttp.is_bytes_request;
|
|
fhttp.save_bytes = fhttp.is_bytes_request;
|
|
|
|
|
+ fhttp.just_started_bytes = true;
|
|
|
|
|
+ file_buffer_len = 0;
|
|
|
return;
|
|
return;
|
|
|
} else if(strstr(line, "[POST/SUCCESS]") != NULL) {
|
|
} else if(strstr(line, "[POST/SUCCESS]") != NULL) {
|
|
|
FURI_LOG_I(HTTP_TAG, "POST request succeeded.");
|
|
FURI_LOG_I(HTTP_TAG, "POST request succeeded.");
|
|
@@ -1157,6 +1198,8 @@ void flipper_http_rx_callback(const char* line, void* context) {
|
|
|
fhttp.state = RECEIVING;
|
|
fhttp.state = RECEIVING;
|
|
|
// for POST request, save data only if it's a bytes request
|
|
// for POST request, save data only if it's a bytes request
|
|
|
fhttp.save_bytes = fhttp.is_bytes_request;
|
|
fhttp.save_bytes = fhttp.is_bytes_request;
|
|
|
|
|
+ fhttp.just_started_bytes = true;
|
|
|
|
|
+ file_buffer_len = 0;
|
|
|
return;
|
|
return;
|
|
|
} else if(strstr(line, "[PUT/SUCCESS]") != NULL) {
|
|
} else if(strstr(line, "[PUT/SUCCESS]") != NULL) {
|
|
|
FURI_LOG_I(HTTP_TAG, "PUT request succeeded.");
|
|
FURI_LOG_I(HTTP_TAG, "PUT request succeeded.");
|