mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-22 20:43:07 +00:00
[FL-2059] Storage fixes for handling empty files (#1563)
* storage: fixed handling of zero-length files * docs: added ReadMe.md for vscode workspace * rpc: storage: improved empty file & error handling in write handler * docs: markdown fix * docs: typo fixes Co-authored-by: SG <who.just.the.doctor@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
01eb92db06
commit
1d50a5981e
4 changed files with 82 additions and 47 deletions
17
.vscode/ReadMe.md
vendored
Normal file
17
.vscode/ReadMe.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Visual Studio Code workspace for Flipper Zero
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
* To start developing with VSCode, run `./fbt vscode_dist` in project root. _That should only be done once_
|
||||||
|
* After that, open firmware folder in VSCode: "File" > "Open folder"
|
||||||
|
|
||||||
|
For more details on fbt, see [fbt docs](../documentation/fbt.md).
|
||||||
|
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
Commands for building firmware are invoked through Build menu: Ctrl+Shift+B.
|
||||||
|
|
||||||
|
To attach a debugging session, first build and flash firmware, then choose your debug probe in Debug menu (Ctrl+Shift+D).
|
||||||
|
|
||||||
|
Note that you have to detach debugging session before rebuilding and re-flashing firmware.
|
|
@ -305,21 +305,27 @@ static void rpc_system_storage_read_process(const PB_Main* request, void* contex
|
||||||
response->command_id = request->command_id;
|
response->command_id = request->command_id;
|
||||||
response->which_content = PB_Main_storage_read_response_tag;
|
response->which_content = PB_Main_storage_read_response_tag;
|
||||||
response->command_status = PB_CommandStatus_OK;
|
response->command_status = PB_CommandStatus_OK;
|
||||||
response->content.storage_read_response.has_file = true;
|
|
||||||
response->content.storage_read_response.file.data =
|
|
||||||
malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(MIN(size_left, MAX_DATA_SIZE)));
|
|
||||||
uint8_t* buffer = response->content.storage_read_response.file.data->bytes;
|
|
||||||
uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
|
|
||||||
|
|
||||||
size_t read_size = MIN(size_left, MAX_DATA_SIZE);
|
size_t read_size = MIN(size_left, MAX_DATA_SIZE);
|
||||||
*read_size_msg = storage_file_read(file, buffer, read_size);
|
if(read_size) {
|
||||||
size_left -= read_size;
|
response->content.storage_read_response.has_file = true;
|
||||||
result = (*read_size_msg == read_size);
|
response->content.storage_read_response.file.data =
|
||||||
|
malloc(PB_BYTES_ARRAY_T_ALLOCSIZE());
|
||||||
|
uint8_t* buffer = response->content.storage_read_response.file.data->bytes;
|
||||||
|
uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
|
||||||
|
|
||||||
if(result) {
|
*read_size_msg = storage_file_read(file, buffer, read_size);
|
||||||
response->has_next = (size_left > 0);
|
size_left -= read_size;
|
||||||
rpc_send_and_release(session, response);
|
result = (*read_size_msg == read_size);
|
||||||
|
|
||||||
|
response->has_next = result && (size_left > 0);
|
||||||
|
} else {
|
||||||
|
response->content.storage_read_response.has_file = false;
|
||||||
|
response->has_next = false;
|
||||||
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc_send_and_release(session, response);
|
||||||
} while((size_left != 0) && result);
|
} while((size_left != 0) && result);
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
|
@ -349,7 +355,7 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
|
||||||
RpcSession* session = rpc_storage->session;
|
RpcSession* session = rpc_storage->session;
|
||||||
furi_assert(session);
|
furi_assert(session);
|
||||||
|
|
||||||
bool result = true;
|
bool fs_operation_success = true;
|
||||||
|
|
||||||
if(!path_contains_only_ascii(request->content.storage_write_request.path)) {
|
if(!path_contains_only_ascii(request->content.storage_write_request.path)) {
|
||||||
rpc_storage->current_command_id = request->command_id;
|
rpc_storage->current_command_id = request->command_id;
|
||||||
|
@ -370,28 +376,32 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
|
||||||
rpc_storage->current_command_id = request->command_id;
|
rpc_storage->current_command_id = request->command_id;
|
||||||
rpc_storage->state = RpcStorageStateWriting;
|
rpc_storage->state = RpcStorageStateWriting;
|
||||||
const char* path = request->content.storage_write_request.path;
|
const char* path = request->content.storage_write_request.path;
|
||||||
result = storage_file_open(rpc_storage->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
|
fs_operation_success =
|
||||||
|
storage_file_open(rpc_storage->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
File* file = rpc_storage->file;
|
File* file = rpc_storage->file;
|
||||||
|
bool send_response = false;
|
||||||
|
|
||||||
if(result) {
|
if(fs_operation_success) {
|
||||||
uint8_t* buffer = request->content.storage_write_request.file.data->bytes;
|
if(request->content.storage_write_request.has_file) {
|
||||||
size_t buffer_size = request->content.storage_write_request.file.data->size;
|
uint8_t* buffer = request->content.storage_write_request.file.data->bytes;
|
||||||
|
size_t buffer_size = request->content.storage_write_request.file.data->size;
|
||||||
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
||||||
result = (written_size == buffer_size);
|
fs_operation_success = (written_size == buffer_size);
|
||||||
|
|
||||||
if(result && !request->has_next) {
|
|
||||||
rpc_send_and_release_empty(
|
|
||||||
session, rpc_storage->current_command_id, PB_CommandStatus_OK);
|
|
||||||
rpc_system_storage_reset_state(rpc_storage, session, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
send_response = !request->has_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result) {
|
PB_CommandStatus command_status = PB_CommandStatus_OK;
|
||||||
rpc_send_and_release_empty(
|
if(!fs_operation_success) {
|
||||||
session, rpc_storage->current_command_id, rpc_system_storage_get_file_error(file));
|
send_response = true;
|
||||||
|
command_status = rpc_system_storage_get_file_error(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(send_response) {
|
||||||
|
rpc_send_and_release_empty(session, rpc_storage->current_command_id, command_status);
|
||||||
rpc_system_storage_reset_state(rpc_storage, session, false);
|
rpc_system_storage_reset_state(rpc_storage, session, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,24 +274,26 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) {
|
||||||
if(parsed_count == EOF || parsed_count != 1) {
|
if(parsed_count == EOF || parsed_count != 1) {
|
||||||
storage_cli_print_usage();
|
storage_cli_print_usage();
|
||||||
} else if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
} else if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||||
uint8_t* data = malloc(buffer_size);
|
|
||||||
uint64_t file_size = storage_file_size(file);
|
uint64_t file_size = storage_file_size(file);
|
||||||
|
|
||||||
printf("Size: %lu\r\n", (uint32_t)file_size);
|
printf("Size: %lu\r\n", (uint32_t)file_size);
|
||||||
|
|
||||||
while(file_size > 0) {
|
if(buffer_size) {
|
||||||
printf("\r\nReady?\r\n");
|
uint8_t* data = malloc(buffer_size);
|
||||||
cli_getc(cli);
|
while(file_size > 0) {
|
||||||
|
printf("\r\nReady?\r\n");
|
||||||
|
cli_getc(cli);
|
||||||
|
|
||||||
uint16_t read_size = storage_file_read(file, data, buffer_size);
|
uint16_t read_size = storage_file_read(file, data, buffer_size);
|
||||||
for(uint16_t i = 0; i < read_size; i++) {
|
for(uint16_t i = 0; i < read_size; i++) {
|
||||||
putchar(data[i]);
|
putchar(data[i]);
|
||||||
|
}
|
||||||
|
file_size -= read_size;
|
||||||
}
|
}
|
||||||
file_size -= read_size;
|
free(data);
|
||||||
}
|
}
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
|
|
||||||
free(data);
|
|
||||||
} else {
|
} else {
|
||||||
storage_cli_print_error(storage_file_get_error(file));
|
storage_cli_print_error(storage_file_get_error(file));
|
||||||
}
|
}
|
||||||
|
@ -315,19 +317,21 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) {
|
||||||
if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) {
|
if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) {
|
||||||
printf("Ready\r\n");
|
printf("Ready\r\n");
|
||||||
|
|
||||||
uint8_t* buffer = malloc(buffer_size);
|
if(buffer_size) {
|
||||||
|
uint8_t* buffer = malloc(buffer_size);
|
||||||
|
|
||||||
for(uint32_t i = 0; i < buffer_size; i++) {
|
for(uint32_t i = 0; i < buffer_size; i++) {
|
||||||
buffer[i] = cli_getc(cli);
|
buffer[i] = cli_getc(cli);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
||||||
|
|
||||||
|
if(written_size != buffer_size) {
|
||||||
|
storage_cli_print_error(storage_file_get_error(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t written_size = storage_file_write(file, buffer, buffer_size);
|
|
||||||
|
|
||||||
if(written_size != buffer_size) {
|
|
||||||
storage_cli_print_error(storage_file_get_error(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
} else {
|
} else {
|
||||||
storage_cli_print_error(storage_file_get_error(file));
|
storage_cli_print_error(storage_file_get_error(file));
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,10 @@ void path_concat(const char* path, const char* suffix, string_t out_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool path_contains_only_ascii(const char* path) {
|
bool path_contains_only_ascii(const char* path) {
|
||||||
|
if(!path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const char* name_pos = strrchr(path, '/');
|
const char* name_pos = strrchr(path, '/');
|
||||||
if(name_pos == NULL) {
|
if(name_pos == NULL) {
|
||||||
name_pos = path;
|
name_pos = path;
|
||||||
|
|
Loading…
Reference in a new issue