Merge branch 'ofw-dev' into dev

This commit is contained in:
MX 2023-09-02 13:33:32 +03:00
commit 15c480b68a
No known key found for this signature in database
GPG key ID: 7CCC66B7DBDD1C83
50 changed files with 538 additions and 322 deletions

View file

@ -26,7 +26,6 @@ void test_furi_memmgr() {
mu_assert_int_eq(66, ((uint8_t*)ptr)[i]);
}
// TODO FL-3492: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
free(ptr);
// allocate and zero-initialize array (calloc)

View file

@ -67,7 +67,6 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS];
} while(0)
static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size);
static void clean_directory(Storage* fs_api, const char* clean_dir);
static void
test_rpc_add_empty_to_list(MsgList_t msg_list, PB_CommandStatus status, uint32_t command_id);
static void test_rpc_encode_and_feed(MsgList_t msg_list, uint8_t session);
@ -149,11 +148,41 @@ static void test_rpc_teardown_second_session(void) {
rpc_session[1].session = NULL;
}
static void test_rpc_storage_clean_directory(Storage* fs_api, const char* clean_dir) {
furi_check(fs_api);
furi_check(clean_dir);
storage_simply_remove_recursive(fs_api, clean_dir);
FS_Error error = storage_common_mkdir(fs_api, clean_dir);
furi_check(error == FSE_OK);
}
static void test_rpc_storage_create_file(Storage* fs_api, const char* path, size_t size) {
File* file = storage_file_alloc(fs_api);
bool success = false;
do {
if(!storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) break;
if(!storage_file_seek(file, size, true)) break;
success = true;
} while(false);
storage_file_close(file);
storage_file_free(file);
furi_check(success);
}
static void test_rpc_storage_setup(void) {
test_rpc_setup();
Storage* fs_api = furi_record_open(RECORD_STORAGE);
clean_directory(fs_api, TEST_DIR_NAME);
test_rpc_storage_clean_directory(fs_api, TEST_DIR_NAME);
test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file100", 100);
test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file250", 250);
test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file500", 200);
test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file1000", 1000);
test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file2500", 2500);
test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file5000", 5000);
furi_record_close(RECORD_STORAGE);
}
@ -161,7 +190,7 @@ static void test_rpc_storage_teardown(void) {
test_rpc_teardown();
Storage* fs_api = furi_record_open(RECORD_STORAGE);
clean_directory(fs_api, TEST_DIR_NAME);
test_rpc_storage_clean_directory(fs_api, TEST_DIR_NAME);
furi_record_close(RECORD_STORAGE);
}
@ -179,36 +208,6 @@ static void test_rpc_session_terminated_callback(void* context) {
xSemaphoreGive(callbacks_context->terminate_semaphore);
}
static void clean_directory(Storage* fs_api, const char* clean_dir) {
furi_check(fs_api);
furi_check(clean_dir);
File* dir = storage_file_alloc(fs_api);
if(storage_dir_open(dir, clean_dir)) {
FileInfo fileinfo;
char* name = malloc(MAX_NAME_LENGTH + 1);
while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
size_t size = strlen(clean_dir) + strlen(name) + 1 + 1;
char* fullname = malloc(size);
snprintf(fullname, size, "%s/%s", clean_dir, name);
if(file_info_is_dir(&fileinfo)) {
clean_directory(fs_api, fullname);
}
FS_Error error = storage_common_remove(fs_api, fullname);
furi_check(error == FSE_OK);
free(fullname);
}
free(name);
} else {
FS_Error error = storage_common_mkdir(fs_api, clean_dir);
(void)error;
furi_check(error == FSE_OK);
}
storage_dir_close(dir);
storage_file_free(dir);
}
static void test_rpc_print_message_list(MsgList_t msg_list) {
#if DEBUG_PRINT
MsgList_reverse(msg_list);
@ -282,24 +281,40 @@ static void test_rpc_add_ping_to_list(MsgList_t msg_list, bool request, uint32_t
response->which_content = (request == PING_REQUEST) ? PB_Main_system_ping_request_tag :
PB_Main_system_ping_response_tag;
}
static void test_rpc_fill_basic_message(PB_Main* message, uint16_t tag, uint32_t command_id) {
message->command_id = command_id;
message->command_status = PB_CommandStatus_OK;
message->cb_content.funcs.encode = NULL;
message->which_content = tag;
message->has_next = false;
}
static void test_rpc_create_storage_list_request(
PB_Main* message,
const char* path,
bool include_md5,
uint32_t command_id,
uint32_t filter_max_size) {
furi_check(message);
furi_check(path);
test_rpc_fill_basic_message(message, PB_Main_storage_list_request_tag, command_id);
message->content.storage_list_request.path = strdup(path);
message->content.storage_list_request.include_md5 = include_md5;
message->content.storage_list_request.filter_max_size = filter_max_size;
}
static void test_rpc_create_simple_message(
PB_Main* message,
uint16_t tag,
const char* str,
uint32_t command_id,
bool flag) {
uint32_t command_id) {
furi_check(message);
char* str_copy = NULL;
if(str) {
str_copy = strdup(str);
}
message->command_id = command_id;
message->command_status = PB_CommandStatus_OK;
message->cb_content.funcs.encode = NULL;
message->which_content = tag;
message->has_next = false;
test_rpc_fill_basic_message(message, tag, command_id);
switch(tag) {
case PB_Main_storage_info_request_tag:
message->content.storage_info_request.path = str_copy;
@ -307,10 +322,6 @@ static void test_rpc_create_simple_message(
case PB_Main_storage_stat_request_tag:
message->content.storage_stat_request.path = str_copy;
break;
case PB_Main_storage_list_request_tag:
message->content.storage_list_request.path = str_copy;
message->content.storage_list_request.include_md5 = flag;
break;
case PB_Main_storage_mkdir_request_tag:
message->content.storage_mkdir_request.path = str_copy;
break;
@ -573,11 +584,29 @@ static void
message->content.storage_list_response.file[2].name = str;
}
static bool test_rpc_system_storage_list_filter(
const FileInfo* fileinfo,
const char* name,
size_t filter_max_size) {
bool result = false;
do {
if(!path_contains_only_ascii(name)) break;
if(filter_max_size) {
if(fileinfo->size > filter_max_size) break;
}
result = true;
} while(false);
return result;
}
static void test_rpc_storage_list_create_expected_list(
MsgList_t msg_list,
const char* path,
uint32_t command_id,
bool append_md5) {
bool append_md5,
size_t filter_max_size) {
Storage* fs_api = furi_record_open(RECORD_STORAGE);
File* dir = storage_file_alloc(fs_api);
@ -615,7 +644,7 @@ static void test_rpc_storage_list_create_expected_list(
i = 0;
}
if(path_contains_only_ascii(name)) {
if(test_rpc_system_storage_list_filter(&fileinfo, name, filter_max_size)) {
list->file[i].type = file_info_is_dir(&fileinfo) ? PB_Storage_File_FileType_DIR :
PB_Storage_File_FileType_FILE;
list->file[i].size = fileinfo.size;
@ -698,17 +727,21 @@ static void test_rpc_free_msg_list(MsgList_t msg_list) {
MsgList_clear(msg_list);
}
static void test_rpc_storage_list_run(const char* path, uint32_t command_id, bool md5) {
static void test_rpc_storage_list_run(
const char* path,
uint32_t command_id,
bool md5,
size_t filter_max_size) {
PB_Main request;
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
test_rpc_create_simple_message(
&request, PB_Main_storage_list_request_tag, path, command_id, md5);
test_rpc_create_storage_list_request(&request, path, md5, command_id, filter_max_size);
if(!strcmp(path, "/")) {
test_rpc_storage_list_create_expected_list_root(expected_msg_list, command_id);
} else {
test_rpc_storage_list_create_expected_list(expected_msg_list, path, command_id, md5);
test_rpc_storage_list_create_expected_list(
expected_msg_list, path, command_id, md5, filter_max_size);
}
test_rpc_encode_and_feed_one(&request, 0);
test_rpc_decode_and_compare(expected_msg_list, 0);
@ -718,25 +751,32 @@ static void test_rpc_storage_list_run(const char* path, uint32_t command_id, boo
}
MU_TEST(test_storage_list) {
test_rpc_storage_list_run("/", ++command_id, false);
test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, false);
test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, false);
test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, false);
test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, false);
test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, false);
test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, false);
test_rpc_storage_list_run("error_path", ++command_id, false);
test_rpc_storage_list_run("/", ++command_id, false, 0);
test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, false, 0);
test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, false, 0);
test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, false, 0);
test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, false, 0);
test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, false, 0);
test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, false, 0);
test_rpc_storage_list_run("error_path", ++command_id, false, 0);
}
MU_TEST(test_storage_list_md5) {
test_rpc_storage_list_run("/", ++command_id, true);
test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, true);
test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, true);
test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, true);
test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, true);
test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, true);
test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, true);
test_rpc_storage_list_run("error_path", ++command_id, true);
test_rpc_storage_list_run("/", ++command_id, true, 0);
test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, true, 0);
test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, true, 0);
test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, true, 0);
test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, true, 0);
test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, true, 0);
test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, true, 0);
test_rpc_storage_list_run("error_path", ++command_id, true, 0);
}
MU_TEST(test_storage_list_size) {
test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 0);
test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 1);
test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 1000);
test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 2500);
}
static void
@ -804,8 +844,7 @@ static void test_storage_read_run(const char* path, uint32_t command_id) {
MsgList_init(expected_msg_list);
test_rpc_add_read_to_list_by_reading_real_file(expected_msg_list, path, command_id);
test_rpc_create_simple_message(
&request, PB_Main_storage_read_request_tag, path, command_id, false);
test_rpc_create_simple_message(&request, PB_Main_storage_read_request_tag, path, command_id);
test_rpc_encode_and_feed_one(&request, 0);
test_rpc_decode_and_compare(expected_msg_list, 0);
@ -859,8 +898,7 @@ static void test_rpc_storage_info_run(const char* path, uint32_t command_id) {
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
test_rpc_create_simple_message(
&request, PB_Main_storage_info_request_tag, path, command_id, false);
test_rpc_create_simple_message(&request, PB_Main_storage_info_request_tag, path, command_id);
PB_Main* response = MsgList_push_new(expected_msg_list);
response->command_id = command_id;
@ -892,8 +930,7 @@ static void test_rpc_storage_stat_run(const char* path, uint32_t command_id) {
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
test_rpc_create_simple_message(
&request, PB_Main_storage_stat_request_tag, path, command_id, false);
test_rpc_create_simple_message(&request, PB_Main_storage_stat_request_tag, path, command_id);
Storage* fs_api = furi_record_open(RECORD_STORAGE);
FileInfo fileinfo;
@ -1005,11 +1042,7 @@ static void test_storage_write_read_run(
test_rpc_add_empty_to_list(expected_msg_list, PB_CommandStatus_OK, *command_id);
test_rpc_create_simple_message(
MsgList_push_raw(input_msg_list),
PB_Main_storage_read_request_tag,
path,
++*command_id,
false);
MsgList_push_raw(input_msg_list), PB_Main_storage_read_request_tag, path, ++*command_id);
test_rpc_add_read_or_write_to_list(
expected_msg_list,
READ_RESPONSE,
@ -1082,8 +1115,7 @@ MU_TEST(test_storage_interrupt_continuous_same_system) {
MsgList_push_new(input_msg_list),
PB_Main_storage_mkdir_request_tag,
TEST_DIR "dir1",
command_id + 1,
false);
command_id + 1);
test_rpc_add_read_or_write_to_list(
input_msg_list,
WRITE_REQUEST,
@ -1163,8 +1195,7 @@ static void test_storage_delete_run(
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
test_rpc_create_simple_message(
&request, PB_Main_storage_delete_request_tag, path, command_id, false);
test_rpc_create_simple_message(&request, PB_Main_storage_delete_request_tag, path, command_id);
request.content.storage_delete_request.recursive = recursive;
test_rpc_add_empty_to_list(expected_msg_list, status, command_id);
@ -1245,8 +1276,7 @@ static void test_storage_mkdir_run(const char* path, size_t command_id, PB_Comma
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
test_rpc_create_simple_message(
&request, PB_Main_storage_mkdir_request_tag, path, command_id, false);
test_rpc_create_simple_message(&request, PB_Main_storage_mkdir_request_tag, path, command_id);
test_rpc_add_empty_to_list(expected_msg_list, status, command_id);
test_rpc_encode_and_feed_one(&request, 0);
@ -1297,12 +1327,11 @@ static void test_storage_md5sum_run(
MsgList_t expected_msg_list;
MsgList_init(expected_msg_list);
test_rpc_create_simple_message(
&request, PB_Main_storage_md5sum_request_tag, path, command_id, false);
test_rpc_create_simple_message(&request, PB_Main_storage_md5sum_request_tag, path, command_id);
if(status == PB_CommandStatus_OK) {
PB_Main* response = MsgList_push_new(expected_msg_list);
test_rpc_create_simple_message(
response, PB_Main_storage_md5sum_response_tag, md5sum, command_id, false);
response, PB_Main_storage_md5sum_response_tag, md5sum, command_id);
response->command_status = status;
} else {
test_rpc_add_empty_to_list(expected_msg_list, status, command_id);
@ -1461,6 +1490,7 @@ MU_TEST_SUITE(test_rpc_storage) {
MU_RUN_TEST(test_storage_stat);
MU_RUN_TEST(test_storage_list);
MU_RUN_TEST(test_storage_list_md5);
MU_RUN_TEST(test_storage_list_size);
MU_RUN_TEST(test_storage_read);
MU_RUN_TEST(test_storage_write_read);
MU_RUN_TEST(test_storage_write);
@ -1759,8 +1789,7 @@ MU_TEST(test_rpc_multisession_storage) {
MsgList_push_raw(input_0),
PB_Main_storage_read_request_tag,
TEST_DIR "file0.txt",
++command_id,
false);
++command_id);
test_rpc_add_read_or_write_to_list(
expected_0, READ_RESPONSE, TEST_DIR "file0.txt", pattern, sizeof(pattern), 1, command_id);
@ -1768,8 +1797,7 @@ MU_TEST(test_rpc_multisession_storage) {
MsgList_push_raw(input_1),
PB_Main_storage_read_request_tag,
TEST_DIR "file1.txt",
++command_id,
false);
++command_id);
test_rpc_add_read_or_write_to_list(
expected_1, READ_RESPONSE, TEST_DIR "file1.txt", pattern, sizeof(pattern), 1, command_id);

View file

@ -18,10 +18,12 @@ GPIOItems* gpio_items_alloc() {
}
items->pins = malloc(sizeof(GpioPinRecord) * items->count);
for(size_t i = 0; i < items->count; i++) {
size_t index = 0;
for(size_t i = 0; i < gpio_pins_count; i++) {
if(!gpio_pins[i].debug) {
items->pins[i].pin = gpio_pins[i].pin;
items->pins[i].name = gpio_pins[i].name;
items->pins[index].pin = gpio_pins[i].pin;
items->pins[index].name = gpio_pins[i].name;
index++;
}
}
return items;

View file

@ -19,7 +19,7 @@ void gpio_scene_usb_uart_on_enter(void* context) {
uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUart);
if(prev_state == 0) {
scene_usb_uart = malloc(sizeof(SceneUsbUartBridge));
scene_usb_uart->cfg.vcp_ch = 0; // TODO FL-3495: settings load
scene_usb_uart->cfg.vcp_ch = 0;
scene_usb_uart->cfg.uart_ch = 0;
scene_usb_uart->cfg.flow_pins = 0;
scene_usb_uart->cfg.baudrate_mode = 0;

View file

@ -195,7 +195,8 @@ bool ibutton_load_key(iButton* ibutton) {
bool ibutton_select_and_load_key(iButton* ibutton) {
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(&browser_options, IBUTTON_APP_EXTENSION, &I_ibutt_10px);
dialog_file_browser_set_basic_options(
&browser_options, IBUTTON_APP_FILENAME_EXTENSION, &I_ibutt_10px);
browser_options.base_path = IBUTTON_APP_FOLDER;
if(furi_string_empty(ibutton->file_path)) {

View file

@ -29,7 +29,8 @@
#include "scenes/ibutton_scene.h"
#define IBUTTON_APP_FOLDER ANY_PATH("ibutton")
#define IBUTTON_APP_EXTENSION ".ibtn"
#define IBUTTON_APP_FILENAME_PREFIX "iBtn"
#define IBUTTON_APP_FILENAME_EXTENSION ".ibtn"
#define IBUTTON_KEY_NAME_SIZE 22

View file

@ -1,6 +1,6 @@
#include "../ibutton_i.h"
#include <toolbox/random_name.h>
#include <toolbox/name_generator.h>
#include <toolbox/path.h>
#include <dolphin/dolphin.h>
@ -17,7 +17,8 @@ void ibutton_scene_save_name_on_enter(void* context) {
const bool is_new_file = furi_string_empty(ibutton->file_path);
if(is_new_file) {
set_random_name(ibutton->key_name, IBUTTON_KEY_NAME_SIZE);
name_generator_make_auto(
ibutton->key_name, IBUTTON_KEY_NAME_SIZE, IBUTTON_APP_FILENAME_PREFIX);
}
text_input_set_header_text(text_input, "Name the key");
@ -29,8 +30,8 @@ void ibutton_scene_save_name_on_enter(void* context) {
IBUTTON_KEY_NAME_SIZE,
is_new_file);
ValidatorIsFile* validator_is_file =
validator_is_file_alloc_init(IBUTTON_APP_FOLDER, IBUTTON_APP_EXTENSION, ibutton->key_name);
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
IBUTTON_APP_FOLDER, IBUTTON_APP_FILENAME_EXTENSION, ibutton->key_name);
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput);
@ -48,7 +49,7 @@ bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) {
"%s/%s%s",
IBUTTON_APP_FOLDER,
ibutton->key_name,
IBUTTON_APP_EXTENSION);
IBUTTON_APP_FILENAME_EXTENSION);
if(ibutton_save_key(ibutton)) {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess);

View file

@ -1,7 +1,6 @@
#include "../infrared_i.h"
#include "common/infrared_scene_universal_common.h"
#include <furi_hal_rtc.h>
void infrared_scene_universal_ac_on_enter(void* context) {
infrared_scene_universal_common_on_enter(context);

View file

@ -215,13 +215,16 @@ bool lfrfid_save_key(LfRfid* app) {
lfrfid_make_app_folder(app);
if(furi_string_end_with(app->file_path, LFRFID_APP_EXTENSION)) {
if(furi_string_end_with(app->file_path, LFRFID_APP_FILENAME_EXTENSION)) {
size_t filename_start = furi_string_search_rchar(app->file_path, '/');
furi_string_left(app->file_path, filename_start);
}
furi_string_cat_printf(
app->file_path, "/%s%s", furi_string_get_cstr(app->file_name), LFRFID_APP_EXTENSION);
app->file_path,
"/%s%s",
furi_string_get_cstr(app->file_name),
LFRFID_APP_FILENAME_EXTENSION);
result = lfrfid_save_key_data(app, app->file_path);
return result;
@ -231,7 +234,8 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) {
furi_assert(app);
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px);
dialog_file_browser_set_basic_options(
&browser_options, LFRFID_APP_FILENAME_EXTENSION, &I_125_10px);
browser_options.base_path = LFRFID_APP_FOLDER;
// Input events and views are managed by file_browser

View file

@ -40,8 +40,9 @@
#define LFRFID_APP_FOLDER ANY_PATH("lfrfid")
#define LFRFID_SD_FOLDER EXT_PATH("lfrfid")
#define LFRFID_APP_EXTENSION ".rfid"
#define LFRFID_APP_SHADOW_EXTENSION ".shd"
#define LFRFID_APP_FILENAME_PREFIX "RFID"
#define LFRFID_APP_FILENAME_EXTENSION ".rfid"
#define LFRFID_APP_SHADOW_FILENAME_EXTENSION ".shd"
#define LFRFID_APP_RAW_ASK_EXTENSION ".ask.raw"
#define LFRFID_APP_RAW_PSK_EXTENSION ".psk.raw"

View file

@ -1,6 +1,6 @@
#include <lib/toolbox/random_name.h>
#include "../lfrfid_i.h"
#include <dolphin/dolphin.h>
#include <toolbox/name_generator.h>
void lfrfid_scene_save_name_on_enter(void* context) {
LfRfid* app = context;
@ -11,7 +11,10 @@ void lfrfid_scene_save_name_on_enter(void* context) {
bool key_name_is_empty = furi_string_empty(app->file_name);
if(key_name_is_empty) {
furi_string_set(app->file_path, LFRFID_APP_FOLDER);
set_random_name(app->text_store, LFRFID_TEXT_STORE_SIZE);
name_generator_make_auto(
app->text_store, LFRFID_TEXT_STORE_SIZE, LFRFID_APP_FILENAME_PREFIX);
furi_string_set(folder_path, LFRFID_APP_FOLDER);
} else {
lfrfid_text_store_set(app, "%s", furi_string_get_cstr(app->file_name));
@ -31,7 +34,7 @@ void lfrfid_scene_save_name_on_enter(void* context) {
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
furi_string_get_cstr(folder_path),
LFRFID_APP_EXTENSION,
LFRFID_APP_FILENAME_EXTENSION,
furi_string_get_cstr(app->file_name));
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);

View file

@ -223,7 +223,11 @@ void nfc_blink_stop(Nfc* nfc) {
bool nfc_save_file(Nfc* nfc) {
furi_string_printf(
nfc->dev->load_path, "%s/%s%s", NFC_APP_FOLDER, nfc->dev->dev_name, NFC_APP_EXTENSION);
nfc->dev->load_path,
"%s/%s%s",
NFC_APP_FOLDER,
nfc->dev->dev_name,
NFC_APP_FILENAME_EXTENSION);
bool file_saved = nfc_device_save(nfc->dev, furi_string_get_cstr(nfc->dev->load_path));
return file_saved;
}

View file

@ -1,5 +1,5 @@
#include "../nfc_i.h"
#include <lib/toolbox/random_name.h>
#include <lib/toolbox/name_generator.h>
#include <gui/modules/validators.h>
#include <toolbox/path.h>
#include <dolphin/dolphin.h>
@ -17,7 +17,7 @@ void nfc_scene_save_name_on_enter(void* context) {
TextInput* text_input = nfc->text_input;
bool dev_name_empty = false;
if(!strcmp(nfc->dev->dev_name, "")) {
set_random_name(nfc->text_store, sizeof(nfc->text_store));
name_generator_make_auto(nfc->text_store, NFC_DEV_NAME_MAX_LEN, NFC_APP_FILENAME_PREFIX);
dev_name_empty = true;
} else {
nfc_text_store_set(nfc, nfc->dev->dev_name);
@ -34,14 +34,14 @@ void nfc_scene_save_name_on_enter(void* context) {
FuriString* folder_path;
folder_path = furi_string_alloc();
if(furi_string_end_with(nfc->dev->load_path, NFC_APP_EXTENSION)) {
if(furi_string_end_with(nfc->dev->load_path, NFC_APP_FILENAME_EXTENSION)) {
path_extract_dirname(furi_string_get_cstr(nfc->dev->load_path), folder_path);
} else {
furi_string_set(folder_path, NFC_APP_FOLDER);
}
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
furi_string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name);
furi_string_get_cstr(folder_path), NFC_APP_FILENAME_EXTENSION, nfc->dev->dev_name);
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput);

View file

@ -248,7 +248,11 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
FuriString* temp_str = furi_string_alloc();
furi_string_printf(
temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION);
temp_str,
"%s/%s%s",
SUBGHZ_RAW_FOLDER,
RAW_FILE_NAME,
SUBGHZ_APP_FILENAME_EXTENSION);
subghz_protocol_raw_gen_fff_data(
subghz_txrx_get_fff_data(subghz->txrx),
furi_string_get_cstr(temp_str),

View file

@ -167,7 +167,6 @@ void subghz_scene_receiver_on_enter(void* context) {
}
furi_string_free(item_name);
furi_string_free(item_time);
subghz_scene_receiver_update_statusbar(subghz);
subghz_view_receiver_set_callback(
subghz->subghz_receiver, subghz_scene_receiver_callback, subghz);
subghz_txrx_set_rx_calback(subghz->txrx, subghz_scene_add_to_history_callback, subghz);
@ -182,6 +181,8 @@ void subghz_scene_receiver_on_enter(void* context) {
furi_check(
subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, SUBGHZ_PROTOCOL_BIN_RAW_NAME));
subghz_scene_receiver_update_statusbar(subghz);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver);
}

View file

@ -1,10 +1,10 @@
#include "../subghz_i.h"
#include "subghz/types.h"
#include <lib/toolbox/random_name.h>
#include "../helpers/subghz_custom_event.h"
#include <lib/subghz/protocols/raw.h>
#include <gui/modules/validators.h>
#include <dolphin/dolphin.h>
#include <toolbox/name_generator.h>
#define MAX_TEXT_INPUT_LEN 23
@ -79,8 +79,8 @@ void subghz_scene_save_name_on_enter(void* context) {
subghz_scene_save_name_get_timefilename(file_name, "S", true);
}
} else {
set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME);
furi_string_set(file_name, file_name_buf);
name_generator_make_auto(file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX);
furi_string_set(file_name, file_name_buf);
}
furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER);
//highlighting the entire filename by default
@ -112,7 +112,7 @@ void subghz_scene_save_name_on_enter(void* context) {
dev_name_empty);
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
furi_string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, "");
furi_string_get_cstr(subghz->file_path), SUBGHZ_APP_FILENAME_EXTENSION, "");
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
furi_string_free(file_name);
@ -137,7 +137,10 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
if(event.event == SubGhzCustomEventSceneSaveName) {
if(strcmp(subghz->file_name_tmp, "") != 0) {
furi_string_cat_printf(
subghz->file_path, "/%s%s", subghz->file_name_tmp, SUBGHZ_APP_EXTENSION);
subghz->file_path,
"/%s%s",
subghz->file_name_tmp,
SUBGHZ_APP_FILENAME_EXTENSION);
if(subghz_path_is_file(subghz->file_path_tmp)) {
if(!subghz_rename_file(subghz)) {
return false;

View file

@ -258,7 +258,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
storage,
furi_string_get_cstr(file_path),
furi_string_get_cstr(file_name),
SUBGHZ_APP_EXTENSION,
SUBGHZ_APP_FILENAME_EXTENSION,
file_name,
max_len);
@ -267,7 +267,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
"%s/%s%s",
furi_string_get_cstr(file_path),
furi_string_get_cstr(file_name),
SUBGHZ_APP_EXTENSION);
SUBGHZ_APP_FILENAME_EXTENSION);
furi_string_set(subghz->file_path, temp_str);
res = true;
}
@ -341,7 +341,8 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) {
FuriString* file_path = furi_string_alloc();
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px);
dialog_file_browser_set_basic_options(
&browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px);
browser_options.base_path = SUBGHZ_APP_FOLDER;
// Input events and views are managed by file_select
@ -415,7 +416,7 @@ void subghz_file_name_clear(SubGhz* subghz) {
}
bool subghz_path_is_file(FuriString* path) {
return furi_string_end_with(path, SUBGHZ_APP_EXTENSION);
return furi_string_end_with(path, SUBGHZ_APP_FILENAME_EXTENSION);
}
void subghz_lock(SubGhz* subghz) {

View file

@ -101,7 +101,6 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) {
char buffer[20];
snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->time_minute);
// TODO FL-3515: never do that, may cause visual glitches
view_port_set_width(
desktop->clock_viewport,
canvas_string_width(canvas, buffer) - 1 + (desktop->time_minute % 10 == 1));
@ -126,8 +125,6 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) {
return true;
case DesktopGlobalAfterAppFinished:
animation_manager_load_and_continue_animation(desktop->animation_manager);
// TODO FL-3497: Implement a message mechanism for loading settings and (optionally)
// locking and unlocking
DESKTOP_SETTINGS_LOAD(&desktop->settings);
desktop_clock_reconfigure(desktop);

View file

@ -4,7 +4,6 @@
#include <furi.h>
#include <furi_hal.h>
#include <furi_hal_rtc.h>
#include <stdint.h>
#include <u8g2_glue.h>

View file

@ -361,10 +361,11 @@ void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) {
furi_assert(view_port);
furi_check(layer < GuiLayerMAX);
// Only fullscreen supports Vertical orientation for now
furi_assert(
ViewPortOrientation view_port_orientation = view_port_get_orientation(view_port);
furi_check(
(layer == GuiLayerFullscreen) ||
((view_port->orientation != ViewPortOrientationVertical) &&
(view_port->orientation != ViewPortOrientationVerticalFlip)));
((view_port_orientation != ViewPortOrientationVertical) &&
(view_port_orientation != ViewPortOrientationVerticalFlip)));
gui_lock(gui);
// Verify that view port is not yet added

View file

@ -272,7 +272,6 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e
} else if(view_dispatcher->navigation_event_callback) {
// Dispatch navigation event
if(!view_dispatcher->navigation_event_callback(view_dispatcher->event_context)) {
// TODO FL-3514: should we allow view_dispatcher to stop without navigation_event_callback?
view_dispatcher_stop(view_dispatcher);
return;
}

View file

@ -2,13 +2,10 @@
#include <furi.h>
#include <furi_hal.h>
#include <furi_hal_rtc.h>
#include "gui.h"
#include "gui_i.h"
// TODO FL-3498: add mutex to view_port ops
_Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count");
_Static_assert(
(ViewPortOrientationHorizontal == 0 && ViewPortOrientationHorizontalFlip == 1 &&
@ -95,52 +92,73 @@ ViewPort* view_port_alloc() {
ViewPort* view_port = malloc(sizeof(ViewPort));
view_port->orientation = ViewPortOrientationHorizontal;
view_port->is_enabled = true;
view_port->mutex = furi_mutex_alloc(FuriMutexTypeRecursive);
return view_port;
}
void view_port_free(ViewPort* view_port) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
furi_check(view_port->gui == NULL);
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
furi_mutex_free(view_port->mutex);
free(view_port);
}
void view_port_set_width(ViewPort* view_port, uint8_t width) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
view_port->width = width;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
uint8_t view_port_get_width(const ViewPort* view_port) {
furi_assert(view_port);
return view_port->width;
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
uint8_t width = view_port->width;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
return width;
}
void view_port_set_height(ViewPort* view_port, uint8_t height) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
view_port->height = height;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
uint8_t view_port_get_height(const ViewPort* view_port) {
furi_assert(view_port);
return view_port->height;
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
uint8_t height = view_port->height;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
return height;
}
void view_port_enabled_set(ViewPort* view_port, bool enabled) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
if(view_port->is_enabled != enabled) {
view_port->is_enabled = enabled;
if(view_port->gui) gui_update(view_port->gui);
}
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
bool view_port_is_enabled(const ViewPort* view_port) {
furi_assert(view_port);
return view_port->is_enabled;
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
bool is_enabled = view_port->is_enabled;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
return is_enabled;
}
void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, void* context) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
view_port->draw_callback = callback;
view_port->draw_callback_context = context;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
void view_port_input_callback_set(
@ -148,34 +166,43 @@ void view_port_input_callback_set(
ViewPortInputCallback callback,
void* context) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
view_port->input_callback = callback;
view_port->input_callback_context = context;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
void view_port_update(ViewPort* view_port) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
if(view_port->gui && view_port->is_enabled) gui_update(view_port->gui);
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
void view_port_gui_set(ViewPort* view_port, Gui* gui) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
view_port->gui = gui;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
void view_port_draw(ViewPort* view_port, Canvas* canvas) {
furi_assert(view_port);
furi_assert(canvas);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
furi_check(view_port->gui);
if(view_port->draw_callback) {
view_port_setup_canvas_orientation(view_port, canvas);
view_port->draw_callback(canvas, view_port->draw_callback_context);
}
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
void view_port_input(ViewPort* view_port, InputEvent* event) {
furi_assert(view_port);
furi_assert(event);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
furi_check(view_port->gui);
if(view_port->input_callback) {
@ -183,13 +210,19 @@ void view_port_input(ViewPort* view_port, InputEvent* event) {
view_port_map_input(event, orientation);
view_port->input_callback(event, view_port->input_callback_context);
}
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation) {
furi_assert(view_port);
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
view_port->orientation = orientation;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
}
ViewPortOrientation view_port_get_orientation(const ViewPort* view_port) {
return view_port->orientation;
furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk);
ViewPortOrientation orientation = view_port->orientation;
furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk);
return orientation;
}

View file

@ -10,6 +10,7 @@
struct ViewPort {
Gui* gui;
FuriMutex* mutex;
bool is_enabled;
ViewPortOrientation orientation;

View file

@ -15,6 +15,8 @@
#include <stdio.h>
#include <m-dict.h>
#include <bt/bt_service/bt.h>
#define TAG "RpcSrv"
typedef enum {
@ -316,6 +318,15 @@ static int32_t rpc_session_worker(void* context) {
session->closed_callback(session->context);
}
furi_mutex_release(session->callbacks_mutex);
if(session->owner == RpcOwnerBle) {
// Disconnect BLE session
FURI_LOG_E("RPC", "BLE session closed due to a decode error");
Bt* bt = furi_record_open(RECORD_BT);
bt_set_profile(bt, BtProfileSerial);
furi_record_close(RECORD_BT);
FURI_LOG_E("RPC", "Finished disconnecting the BLE session");
}
}
}

View file

@ -242,6 +242,23 @@ static void rpc_system_storage_list_root(const PB_Main* request, void* context)
rpc_send_and_release(session, &response);
}
static bool rpc_system_storage_list_filter(
const PB_Storage_ListRequest* request,
const FileInfo* fileinfo,
const char* name) {
bool result = false;
do {
if(!path_contains_only_ascii(name)) break;
if(request->filter_max_size) {
if(fileinfo->size > request->filter_max_size) break;
}
result = true;
} while(false);
return result;
}
static void rpc_system_storage_list_process(const PB_Main* request, void* context) {
furi_assert(request);
furi_assert(context);
@ -253,9 +270,11 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex
RpcSession* session = rpc_storage->session;
furi_assert(session);
const PB_Storage_ListRequest* list_request = &request->content.storage_list_request;
rpc_system_storage_reset_state(rpc_storage, session, true);
if(!strcmp(request->content.storage_list_request.path, "/")) {
if(!strcmp(list_request->path, "/")) {
rpc_system_storage_list_root(request, context);
return;
}
@ -271,7 +290,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex
};
PB_Storage_ListResponse* list = &response.content.storage_list_response;
bool include_md5 = request->content.storage_list_request.include_md5;
bool include_md5 = list_request->include_md5;
FuriString* md5 = furi_string_alloc();
FuriString* md5_path = furi_string_alloc();
File* file = storage_file_alloc(fs_api);
@ -279,7 +298,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex
bool finish = false;
int i = 0;
if(!storage_dir_open(dir, request->content.storage_list_request.path)) {
if(!storage_dir_open(dir, list_request->path)) {
response.command_status = rpc_system_storage_get_file_error(dir);
response.which_content = PB_Main_empty_tag;
finish = true;
@ -289,7 +308,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex
FileInfo fileinfo;
char* name = malloc(MAX_NAME_LENGTH + 1);
if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) {
if(path_contains_only_ascii(name)) {
if(rpc_system_storage_list_filter(list_request, &fileinfo, name)) {
if(i == COUNT_OF(list->file)) {
list->file_count = i;
response.has_next = true;
@ -303,11 +322,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex
list->file[i].name = name;
if(include_md5 && !file_info_is_dir(&fileinfo)) {
furi_string_printf( //-V576
md5_path,
"%s/%s",
request->content.storage_list_request.path,
name);
furi_string_printf(md5_path, "%s/%s", list_request->path, name); //-V576
if(md5_string_calc_file(file, furi_string_get_cstr(md5_path), md5, NULL)) {
char* md5sum = list->file[i].md5sum;

View file

@ -153,6 +153,21 @@ static void sleep_method_changed(VariableItem* item) {
}
}
const char* const filename_scheme[] = {
"Default",
"Detailed",
};
static void filename_scheme_changed(VariableItem* item) {
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, filename_scheme[index]);
if(index) {
furi_hal_rtc_set_flag(FuriHalRtcFlagDetailedFilename);
} else {
furi_hal_rtc_reset_flag(FuriHalRtcFlagDetailedFilename);
}
}
static uint32_t system_settings_exit(void* context) {
UNUSED(context);
return VIEW_NONE;
@ -236,6 +251,12 @@ SystemSettings* system_settings_alloc() {
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, sleep_method[value_index]);
item = variable_item_list_add(
app->var_item_list, "File Naming", COUNT_OF(filename_scheme), filename_scheme_changed, app);
value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDetailedFilename) ? 1 : 0;
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, filename_scheme[value_index]);
view_set_previous_callback(
variable_item_list_get_view(app->var_item_list), system_settings_exit);
view_dispatcher_add_view(

@ -1 +1 @@
Subproject commit 7e011a95863716e72e7c6b5d552bca241d688304
Subproject commit 327163d5867c7aa3051334c93ced718d15bfe4da

View file

@ -72,6 +72,7 @@ FIRMWARE_APPS = {
"unit_tests": [
"basic_services",
"updater_app",
"radio_device_cc1101_ext",
"unit_tests",
],
}

View file

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,35.1,,
Version,+,36.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@ -172,10 +172,10 @@ Header,+,lib/toolbox/hex.h,,
Header,+,lib/toolbox/manchester_decoder.h,,
Header,+,lib/toolbox/manchester_encoder.h,,
Header,+,lib/toolbox/md5.h,,
Header,+,lib/toolbox/name_generator.h,,
Header,+,lib/toolbox/path.h,,
Header,+,lib/toolbox/pretty_format.h,,
Header,+,lib/toolbox/protocols/protocol_dict.h,,
Header,+,lib/toolbox/random_name.h,,
Header,+,lib/toolbox/saved_struct.h,,
Header,+,lib/toolbox/sha256.h,,
Header,+,lib/toolbox/stream/buffered_file_stream.h,,
@ -1704,6 +1704,9 @@ Function,-,music_worker_set_callback,void,"MusicWorker*, MusicWorkerCallback, vo
Function,-,music_worker_set_volume,void,"MusicWorker*, float"
Function,-,music_worker_start,void,MusicWorker*
Function,-,music_worker_stop,void,MusicWorker*
Function,+,name_generator_make_auto,void,"char*, size_t, const char*"
Function,+,name_generator_make_detailed,void,"char*, size_t, const char*"
Function,+,name_generator_make_random,void,"char*, size_t"
Function,-,nan,double,const char*
Function,-,nanf,float,const char*
Function,-,nanl,long double,const char*
@ -1924,7 +1927,6 @@ Function,-,serial_svc_set_rpc_status,void,SerialServiceRpcStatus
Function,-,serial_svc_start,void,
Function,-,serial_svc_stop,void,
Function,-,serial_svc_update_tx,_Bool,"uint8_t*, uint16_t"
Function,+,set_random_name,void,"char*, uint8_t"
Function,-,setbuf,void,"FILE*, char*"
Function,-,setbuffer,void,"FILE*, char*, int"
Function,-,setenv,int,"const char*, const char*, int"

1 entry status name type params
2 Version + 35.1 36.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
172 Header + lib/toolbox/manchester_decoder.h
173 Header + lib/toolbox/manchester_encoder.h
174 Header + lib/toolbox/md5.h
175 Header + lib/toolbox/name_generator.h
176 Header + lib/toolbox/path.h
177 Header + lib/toolbox/pretty_format.h
178 Header + lib/toolbox/protocols/protocol_dict.h
Header + lib/toolbox/random_name.h
179 Header + lib/toolbox/saved_struct.h
180 Header + lib/toolbox/sha256.h
181 Header + lib/toolbox/stream/buffered_file_stream.h
1704 Function - music_worker_set_volume void MusicWorker*, float
1705 Function - music_worker_start void MusicWorker*
1706 Function - music_worker_stop void MusicWorker*
1707 Function + name_generator_make_auto void char*, size_t, const char*
1708 Function + name_generator_make_detailed void char*, size_t, const char*
1709 Function + name_generator_make_random void char*, size_t
1710 Function - nan double const char*
1711 Function - nanf float const char*
1712 Function - nanl long double const char*
1927 Function - serial_svc_start void
1928 Function - serial_svc_stop void
1929 Function - serial_svc_update_tx _Bool uint8_t*, uint16_t
Function + set_random_name void char*, uint8_t
1930 Function - setbuf void FILE*, char*
1931 Function - setbuffer void FILE*, char*, int
1932 Function - setenv int const char*, const char*, int

View file

@ -67,35 +67,53 @@ const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12};
const GpioPinRecord gpio_pins[] = {
{.pin = &gpio_ext_pa7, .name = "PA7", .debug = false},
{.pin = &gpio_ext_pa6, .name = "PA6", .debug = false},
{.pin = &gpio_ext_pa4, .name = "PA4", .debug = false},
{.pin = &gpio_ext_pb3, .name = "PB3", .debug = false},
{.pin = &gpio_ext_pb2, .name = "PB2", .debug = false},
{.pin = &gpio_ext_pc3, .name = "PC3", .debug = false},
{.pin = &gpio_ext_pc1, .name = "PC1", .debug = false},
{.pin = &gpio_ext_pc0, .name = "PC0", .debug = false},
// 5V: 1
{.pin = &gpio_ext_pa7, .name = "PA7", .number = 2, .debug = false},
{.pin = &gpio_ext_pa6, .name = "PA6", .number = 3, .debug = false},
{.pin = &gpio_ext_pa4, .name = "PA4", .number = 4, .debug = false},
{.pin = &gpio_ext_pb3, .name = "PB3", .number = 5, .debug = false},
{.pin = &gpio_ext_pb2, .name = "PB2", .number = 6, .debug = false},
{.pin = &gpio_ext_pc3, .name = "PC3", .number = 7, .debug = false},
// GND: 8
// Space
// 3v3: 9
{.pin = &gpio_swclk, .name = "PA14", .number = 10, .debug = true},
// GND: 11
{.pin = &gpio_swdio, .name = "PA13", .number = 12, .debug = true},
{.pin = &gpio_usart_tx, .name = "PB6", .number = 13, .debug = true},
{.pin = &gpio_usart_rx, .name = "PB7", .number = 14, .debug = true},
{.pin = &gpio_ext_pc1, .name = "PC1", .number = 15, .debug = false},
{.pin = &gpio_ext_pc0, .name = "PC0", .number = 16, .debug = false},
{.pin = &gpio_ibutton, .name = "PB14", .number = 17, .debug = true},
// GND: 18
{.pin = &gpio_ext_pc5, .name = "PC5", .debug = false},
{.pin = &gpio_ext_pc4, .name = "PC4", .debug = false},
{.pin = &gpio_ext_pa5, .name = "PA5", .debug = false},
{.pin = &gpio_ext_pb9, .name = "PB9", .debug = false},
{.pin = &gpio_ext_pa0, .name = "PA0", .debug = false},
{.pin = &gpio_ext_pa1, .name = "PA1", .debug = false},
{.pin = &gpio_ext_pa15, .name = "PA15", .debug = false},
{.pin = &gpio_ext_pe4, .name = "PE4", .debug = false},
{.pin = &gpio_ext_pa2, .name = "PA2", .debug = false},
{.pin = &gpio_ext_pb4, .name = "PB4", .debug = false},
{.pin = &gpio_ext_pb5, .name = "PB5", .debug = false},
{.pin = &gpio_ext_pd0, .name = "PD0", .debug = false},
{.pin = &gpio_ext_pb13, .name = "PB13", .debug = false},
// 2nd column
// 5V: 19
{.pin = &gpio_ext_pc5, .name = "PC5", .number = 20, .debug = false},
{.pin = &gpio_ext_pc4, .name = "PC4", .number = 21, .debug = false},
{.pin = &gpio_ext_pa5, .name = "PA5", .number = 22, .debug = false},
{.pin = &gpio_ext_pb9, .name = "PB9", .number = 23, .debug = false},
{.pin = &gpio_ext_pa0, .name = "PA0", .number = 24, .debug = false},
{.pin = &gpio_ext_pa1, .name = "PA1", .number = 25, .debug = false},
// KEY: 26
// Space
// 3v3: 27
{.pin = &gpio_ext_pa15, .name = "PA15", .number = 28, .debug = false},
// GND: 29
{.pin = &gpio_ext_pe4, .name = "PE4", .number = 30, .debug = false},
{.pin = &gpio_ext_pa2, .name = "PA2", .number = 31, .debug = false},
{.pin = &gpio_ext_pb4, .name = "PB4", .number = 32, .debug = false},
{.pin = &gpio_ext_pb5, .name = "PB5", .number = 33, .debug = false},
{.pin = &gpio_ext_pd0, .name = "PD0", .number = 34, .debug = false},
{.pin = &gpio_ext_pb13, .name = "PB13", .number = 35, .debug = false},
// GND: 36
/* Dangerous pins, may damage hardware */
{.pin = &gpio_usart_rx, .name = "PB7", .debug = true},
{.pin = &gpio_speaker, .name = "PB8", .debug = true},
{.pin = &gpio_usart_rx, .name = "PB7", .number = 0, .debug = true},
{.pin = &gpio_speaker, .name = "PB8", .number = 0, .debug = true},
};
const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord);
const size_t gpio_pins_count = COUNT_OF(gpio_pins);
const InputPin input_pins[] = {
{.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"},
@ -106,7 +124,7 @@ const InputPin input_pins[] = {
{.gpio = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"},
};
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
const size_t input_pins_count = COUNT_OF(input_pins);
static void furi_hal_resources_init_input_pins(GpioMode mode) {
for(size_t i = 0; i < input_pins_count; i++) {
@ -216,25 +234,10 @@ void furi_hal_resources_init() {
}
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) {
// TODO FL-3500: describe second ROW
if(gpio == &gpio_ext_pa7)
return 2;
else if(gpio == &gpio_ext_pa6)
return 3;
else if(gpio == &gpio_ext_pa4)
return 4;
else if(gpio == &gpio_ext_pb3)
return 5;
else if(gpio == &gpio_ext_pb2)
return 6;
else if(gpio == &gpio_ext_pc3)
return 7;
else if(gpio == &gpio_ext_pc1)
return 15;
else if(gpio == &gpio_ext_pc0)
return 16;
else if(gpio == &gpio_ibutton)
return 17;
else
return -1;
for(size_t i = 0; i < gpio_pins_count; i++) {
if(gpio_pins[i].pin == gpio) {
return gpio_pins[i].number;
}
}
return -1;
}

View file

@ -41,6 +41,7 @@ typedef struct {
typedef struct {
const GpioPin* pin;
const char* name;
const uint8_t number;
const bool debug;
} GpioPinRecord;

View file

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,35.1,,
Version,+,36.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
@ -215,10 +215,10 @@ Header,+,lib/toolbox/hex.h,,
Header,+,lib/toolbox/manchester_decoder.h,,
Header,+,lib/toolbox/manchester_encoder.h,,
Header,+,lib/toolbox/md5.h,,
Header,+,lib/toolbox/name_generator.h,,
Header,+,lib/toolbox/path.h,,
Header,+,lib/toolbox/pretty_format.h,,
Header,+,lib/toolbox/protocols/protocol_dict.h,,
Header,+,lib/toolbox/random_name.h,,
Header,+,lib/toolbox/saved_struct.h,,
Header,+,lib/toolbox/sha256.h,,
Header,+,lib/toolbox/stream/buffered_file_stream.h,,
@ -2126,6 +2126,9 @@ Function,-,music_worker_set_callback,void,"MusicWorker*, MusicWorkerCallback, vo
Function,-,music_worker_set_volume,void,"MusicWorker*, float"
Function,-,music_worker_start,void,MusicWorker*
Function,-,music_worker_stop,void,MusicWorker*
Function,+,name_generator_make_auto,void,"char*, size_t, const char*"
Function,+,name_generator_make_detailed,void,"char*, size_t, const char*"
Function,+,name_generator_make_random,void,"char*, size_t"
Function,-,nan,double,const char*
Function,-,nanf,float,const char*
Function,-,nanl,long double,const char*
@ -2573,7 +2576,6 @@ Function,-,serial_svc_set_rpc_status,void,SerialServiceRpcStatus
Function,-,serial_svc_start,void,
Function,-,serial_svc_stop,void,
Function,-,serial_svc_update_tx,_Bool,"uint8_t*, uint16_t"
Function,+,set_random_name,void,"char*, uint8_t"
Function,-,setbuf,void,"FILE*, char*"
Function,-,setbuffer,void,"FILE*, char*, int"
Function,-,setenv,int,"const char*, const char*, int"

1 entry status name type params
2 Version + 35.1 36.0
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/cli/cli.h
215 Header + lib/toolbox/manchester_decoder.h
216 Header + lib/toolbox/manchester_encoder.h
217 Header + lib/toolbox/md5.h
218 Header + lib/toolbox/name_generator.h
219 Header + lib/toolbox/path.h
220 Header + lib/toolbox/pretty_format.h
221 Header + lib/toolbox/protocols/protocol_dict.h
Header + lib/toolbox/random_name.h
222 Header + lib/toolbox/saved_struct.h
223 Header + lib/toolbox/sha256.h
224 Header + lib/toolbox/stream/buffered_file_stream.h
2126 Function - music_worker_set_volume void MusicWorker*, float
2127 Function - music_worker_start void MusicWorker*
2128 Function - music_worker_stop void MusicWorker*
2129 Function + name_generator_make_auto void char*, size_t, const char*
2130 Function + name_generator_make_detailed void char*, size_t, const char*
2131 Function + name_generator_make_random void char*, size_t
2132 Function - nan double const char*
2133 Function - nanf float const char*
2134 Function - nanl long double const char*
2576 Function - serial_svc_start void
2577 Function - serial_svc_stop void
2578 Function - serial_svc_update_tx _Bool uint8_t*, uint16_t
Function + set_random_name void char*, uint8_t
2579 Function - setbuf void FILE*, char*
2580 Function - setbuffer void FILE*, char*, int
2581 Function - setenv int const char*, const char*, int

View file

@ -222,7 +222,6 @@ bool ble_glue_wait_for_c2_start(int32_t timeout) {
bool started = false;
do {
// TODO FL-3505: use mutex?
started = ble_glue->status == BleGlueStatusC2Started;
if(!started) {
timeout--;

View file

@ -701,7 +701,9 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) {
rfalNfcWorker();
state = rfalNfcGetState();
ret = rfalNfcDataExchangeGetStatus();
if(ret == ERR_BUSY) {
if(ret == ERR_WRONG_STATE) {
return false;
} else if(ret == ERR_BUSY) {
if(DWT->CYCCNT - start > timeout_ms * clocks_in_ms) {
FURI_LOG_D(TAG, "Timeout during data exchange");
return false;

View file

@ -69,22 +69,32 @@ const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12};
const GpioPinRecord gpio_pins[] = {
{.pin = &gpio_ext_pa7, .name = "PA7", .debug = false},
{.pin = &gpio_ext_pa6, .name = "PA6", .debug = false},
{.pin = &gpio_ext_pa4, .name = "PA4", .debug = false},
{.pin = &gpio_ext_pb3, .name = "PB3", .debug = false},
{.pin = &gpio_ext_pb2, .name = "PB2", .debug = false},
{.pin = &gpio_ext_pc3, .name = "PC3", .debug = false},
{.pin = &gpio_ext_pc1, .name = "PC1", .debug = false},
{.pin = &gpio_ext_pc0, .name = "PC0", .debug = false},
// 5V: 1
{.pin = &gpio_ext_pa7, .name = "PA7", .number = 2, .debug = false},
{.pin = &gpio_ext_pa6, .name = "PA6", .number = 3, .debug = false},
{.pin = &gpio_ext_pa4, .name = "PA4", .number = 4, .debug = false},
{.pin = &gpio_ext_pb3, .name = "PB3", .number = 5, .debug = false},
{.pin = &gpio_ext_pb2, .name = "PB2", .number = 6, .debug = false},
{.pin = &gpio_ext_pc3, .name = "PC3", .number = 7, .debug = false},
// GND: 8
// Space
// 3v3: 9
{.pin = &gpio_swclk, .name = "PA14", .number = 10, .debug = true},
// GND: 11
{.pin = &gpio_swdio, .name = "PA13", .number = 12, .debug = true},
{.pin = &gpio_usart_tx, .name = "PB6", .number = 13, .debug = true},
{.pin = &gpio_usart_rx, .name = "PB7", .number = 14, .debug = true},
{.pin = &gpio_ext_pc1, .name = "PC1", .number = 15, .debug = false},
{.pin = &gpio_ext_pc0, .name = "PC0", .number = 16, .debug = false},
{.pin = &gpio_ibutton, .name = "PB14", .number = 17, .debug = true},
// GND: 18
/* Dangerous pins, may damage hardware */
{.pin = &gpio_usart_rx, .name = "PB7", .debug = true},
{.pin = &gpio_speaker, .name = "PB8", .debug = true},
{.pin = &gpio_infrared_tx, .name = "PB9", .debug = true},
};
const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord);
const size_t gpio_pins_count = COUNT_OF(gpio_pins);
const InputPin input_pins[] = {
{.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"},
@ -95,7 +105,7 @@ const InputPin input_pins[] = {
{.gpio = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"},
};
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
const size_t input_pins_count = COUNT_OF(input_pins);
static void furi_hal_resources_init_input_pins(GpioMode mode) {
for(size_t i = 0; i < input_pins_count; i++) {
@ -210,24 +220,10 @@ void furi_hal_resources_init() {
}
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) {
if(gpio == &gpio_ext_pa7)
return 2;
else if(gpio == &gpio_ext_pa6)
return 3;
else if(gpio == &gpio_ext_pa4)
return 4;
else if(gpio == &gpio_ext_pb3)
return 5;
else if(gpio == &gpio_ext_pb2)
return 6;
else if(gpio == &gpio_ext_pc3)
return 7;
else if(gpio == &gpio_ext_pc1)
return 15;
else if(gpio == &gpio_ext_pc0)
return 16;
else if(gpio == &gpio_ibutton)
return 17;
else
return -1;
for(size_t i = 0; i < gpio_pins_count; i++) {
if(gpio_pins[i].pin == gpio) {
return gpio_pins[i].number;
}
}
return -1;
}

View file

@ -41,6 +41,7 @@ typedef struct {
typedef struct {
const GpioPin* pin;
const char* name;
const uint8_t number;
const bool debug;
} GpioPinRecord;

View file

@ -32,6 +32,7 @@ typedef enum {
FuriHalRtcFlagHandOrient = (1 << 4),
FuriHalRtcFlagLegacySleep = (1 << 5),
FuriHalRtcFlagStealthMode = (1 << 6),
FuriHalRtcFlagDetailedFilename = (1 << 7),
} FuriHalRtcFlag;
typedef enum {

View file

@ -54,6 +54,10 @@ static bool bq27220_parameter_check(
}
if(update) {
// Datasheet contains incorrect procedure for memory update, more info:
// https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/719878/bq27220-technical-reference-manual-sluubd4-is-missing-extended-data-commands-chapter
// 2. Write the address AND the parameter data to 0x3E+ (auto increment)
if(!furi_hal_i2c_write_mem(
handle,
BQ27220_ADDRESS,
@ -67,9 +71,12 @@ static bool bq27220_parameter_check(
furi_delay_us(10000);
// 3. Calculate the check sum: 0xFF - (sum of address and data) OR 0xFF
uint8_t checksum = bq27220_get_checksum(buffer, size + 2);
// 4. Write the check sum to 0x60 and the total length of (address + parameter data + check sum + length) to 0x61
buffer[0] = checksum;
buffer[1] = 4 + size; // TODO FL-3519: why 4?
// 2 bytes address, `size` bytes data, 1 byte check sum, 1 byte length
buffer[1] = 2 + size + 1 + 1;
if(!furi_hal_i2c_write_mem(
handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT)) {
FURI_LOG_I(TAG, "CRC write failed");

View file

@ -1366,7 +1366,7 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) {
static void nfc_device_get_path_without_ext(FuriString* orig_path, FuriString* shadow_path) {
// TODO: this won't work if there is ".nfc" anywhere in the path other than
// at the end
size_t ext_start = furi_string_search(orig_path, NFC_APP_EXTENSION);
size_t ext_start = furi_string_search(orig_path, NFC_APP_FILENAME_EXTENSION);
furi_string_set_n(shadow_path, orig_path, 0, ext_start);
}
@ -1593,7 +1593,7 @@ bool nfc_file_select(NfcDevice* dev) {
// Input events and views are managed by file_browser
const DialogsFileBrowserOptions browser_options = {
.extension = NFC_APP_EXTENSION,
.extension = NFC_APP_FILENAME_EXTENSION,
.skip_assets = true,
.hide_dot_files = true,
.icon = &I_Nfc_10px,
@ -1665,7 +1665,7 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) {
"%s/%s%s",
furi_string_get_cstr(dev->folder),
dev->dev_name,
NFC_APP_EXTENSION);
NFC_APP_FILENAME_EXTENSION);
}
if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break;
// Delete shadow file if it exists
@ -1723,7 +1723,7 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) {
"%s/%s%s",
furi_string_get_cstr(dev->folder),
dev->dev_name,
NFC_APP_EXTENSION);
NFC_APP_FILENAME_EXTENSION);
}
if(!nfc_device_load_data(dev, path, true)) break;
restored = true;

View file

@ -21,7 +21,8 @@ extern "C" {
#define NFC_READER_DATA_MAX_SIZE 64
#define NFC_DICT_KEY_BATCH_SIZE 10
#define NFC_APP_EXTENSION ".nfc"
#define NFC_APP_FILENAME_PREFIX "NFC"
#define NFC_APP_FILENAME_EXTENSION ".nfc"
#define NFC_APP_SHADOW_EXTENSION ".shd"
typedef void (*NfcLoadingCallback)(void* context, bool state);

View file

@ -382,7 +382,9 @@ bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
} else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
//skylanders support
return true;
} else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) {
} else if(
((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) ||
((ATQA0 == 0x02 || ATQA0 == 0x04 || ATQA0 == 0x08) && (SAK == 0x38))) {
return true;
} else {
return false;
@ -394,13 +396,17 @@ MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t
if((ATQA0 == 0x44 || ATQA0 == 0x04)) {
if((SAK == 0x08 || SAK == 0x88)) {
return MfClassicType1k;
} else if((SAK == 0x38)) {
return MfClassicType4k;
} else if((SAK == 0x09 || SAK == 0x89)) {
return MfClassicTypeMini;
}
} else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
//skylanders support
return MfClassicType1k;
} else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) {
} else if(
((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) ||
((ATQA0 == 0x02 || ATQA0 == 0x08) && (SAK == 0x38))) {
return MfClassicType4k;
}
return MfClassicType1k;

View file

@ -108,7 +108,8 @@ bool subghz_protocol_raw_save_to_file_init(
furi_string_set(instance->file_name, dev_name);
// First remove subghz device file if it was saved
furi_string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION);
furi_string_printf(
temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_FILENAME_EXTENSION);
if(!storage_simply_remove(instance->storage, furi_string_get_cstr(temp_str))) {
break;

View file

@ -13,7 +13,8 @@
#define SUBGHZ_APP_FOLDER ANY_PATH("subghz")
#define SUBGHZ_RAW_FOLDER EXT_PATH("subghz")
#define SUBGHZ_APP_EXTENSION ".sub"
#define SUBGHZ_APP_FILENAME_PREFIX "SubGHz"
#define SUBGHZ_APP_FILENAME_EXTENSION ".sub"
#define SUBGHZ_KEY_FILE_VERSION 1
#define SUBGHZ_KEY_FILE_TYPE "Flipper SubGhz Key File"

View file

@ -14,7 +14,7 @@ env.Append(
File("manchester_decoder.h"),
File("manchester_encoder.h"),
File("path.h"),
File("random_name.h"),
File("name_generator.h"),
File("sha256.h"),
File("crc32_calc.h"),
File("dir_walk.h"),

View file

@ -0,0 +1,91 @@
#include "name_generator.h"
#include <stdio.h>
#include <stdint.h>
#include <furi_hal_rtc.h>
#include <stdlib.h>
#include <stdbool.h>
#include <furi.h>
const char* const name_generator_left[] = {
"super",
"big",
"little",
"liquid",
"unknown",
"thin",
"thick",
"great",
"my",
"mini",
"ultra",
"haupt",
"small",
"random",
"strange",
};
const char* const name_generator_right[] = {
"maslina",
"sus",
"anomalija",
"artefact",
"monolit",
"burer",
"sidorovich",
"habar",
"radar",
"borov",
"pda",
"konserva",
"aptechka",
"door",
"thing",
"stuff",
};
void name_generator_make_auto(char* name, size_t max_name_size, const char* prefix) {
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDetailedFilename)) {
name_generator_make_detailed(name, max_name_size, prefix);
} else {
name_generator_make_random(name, max_name_size);
}
}
void name_generator_make_random(char* name, size_t max_name_size) {
furi_assert(name);
furi_assert(max_name_size);
uint8_t name_generator_left_i = rand() % COUNT_OF(name_generator_left);
uint8_t name_generator_right_i = rand() % COUNT_OF(name_generator_right);
snprintf(
name,
max_name_size,
"%s_%s",
name_generator_left[name_generator_left_i],
name_generator_right[name_generator_right_i]);
// Set first symbol to upper case
name[0] = name[0] - 0x20;
}
void name_generator_make_detailed(char* name, size_t max_name_size, const char* prefix) {
furi_assert(name);
furi_assert(max_name_size);
furi_assert(prefix);
FuriHalRtcDateTime dateTime;
furi_hal_rtc_get_datetime(&dateTime);
snprintf(
name,
max_name_size,
"%s-%.4d_%.2d_%.2d-%.2d_%.2d",
prefix,
dateTime.year,
dateTime.month,
dateTime.day,
dateTime.hour,
dateTime.minute);
}

View file

@ -0,0 +1,35 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Generates detailed/random name based on furi_hal flags
*
* @param name buffer to write random name
* @param max_name_size length of given buffer
* @param[in] prefix The prefix of the name
*/
void name_generator_make_auto(char* name, size_t max_name_size, const char* prefix);
/** Generates random name
*
* @param name buffer to write random name
* @param max_name_size length of given buffer
*/
void name_generator_make_random(char* name, size_t max_name_size);
/** Generates detailed name
*
* @param name buffer to write random name
* @param max_name_size length of given buffer
* @param[in] prefix The prefix of the name
*/
void name_generator_make_detailed(char* name, size_t max_name_size, const char* prefix);
#ifdef __cplusplus
}
#endif

View file

@ -1,51 +0,0 @@
#include "random_name.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <furi.h>
void set_random_name(char* name, uint8_t max_name_size) {
const char* prefix[] = {
"super",
"big",
"little",
"liquid",
"unknown",
"thin",
"thick",
"great",
"my",
"mini",
"ultra",
"haupt",
"small",
"random",
"strange",
};
const char* suffix[] = {
"maslina",
"sus",
"anomalija",
"artefact",
"monolit",
"burer",
"sidorovich",
"habar",
"radar",
"borov",
"pda",
"konserva",
"aptechka",
"door",
"thing",
"stuff",
};
// sus is not (sus)pect - this is about super sus
uint8_t prefix_i = rand() % COUNT_OF(prefix);
uint8_t suffix_i = rand() % COUNT_OF(suffix);
snprintf(name, max_name_size, "%s_%s", prefix[prefix_i], suffix[suffix_i]);
// Set first symbol to upper case
name[0] = name[0] - 0x20;
}

View file

@ -1,17 +0,0 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Generates random name
* @param name buffer to write random name
* @param max_name_size length of given buffer
*/
void set_random_name(char* name, uint8_t max_name_size);
#ifdef __cplusplus
}
#endif

View file

@ -54,10 +54,10 @@ static bool
FuriString* filetype;
// TODO FL-3543: compare filetype?
filetype = furi_string_alloc();
update_manifest->valid =
flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) &&
furi_string_cmp_str(filetype, "Flipper firmware upgrade configuration") == 0 &&
flipper_format_read_string(flipper_file, MANIFEST_KEY_INFO, update_manifest->version) &&
flipper_format_read_uint32(
flipper_file, MANIFEST_KEY_TARGET, &update_manifest->target, 1) &&

View file

@ -10,6 +10,7 @@ from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from flipper.app import App
from serial.tools.list_ports_common import ListPortInfo
# When adding an interface, also add it to SWD_TRANSPORT in fbt/ufbt options
@ -88,8 +89,9 @@ class OpenOCDProgrammer(Programmer):
self._add_file(openocd_launch_params, self.interface.config_file)
if self.serial:
self._add_serial(openocd_launch_params, self.serial)
for additional_arg in self.interface.additional_args:
self._add_command(openocd_launch_params, additional_arg)
if self.interface.additional_args:
for additional_arg in self.interface.additional_args:
self._add_command(openocd_launch_params, additional_arg)
self._add_file(openocd_launch_params, "target/stm32wbx.cfg")
self._add_command(openocd_launch_params, "init")
program_params = [
@ -124,8 +126,9 @@ class OpenOCDProgrammer(Programmer):
self._add_file(openocd_launch_params, self.interface.config_file)
if self.serial:
self._add_serial(openocd_launch_params, self.serial)
for additional_arg in self.interface.additional_args:
self._add_command(openocd_launch_params, additional_arg)
if self.interface.additional_args:
for additional_arg in self.interface.additional_args:
self._add_command(openocd_launch_params, additional_arg)
self._add_file(openocd_launch_params, "target/stm32wbx.cfg")
self._add_command(openocd_launch_params, "init")
self._add_command(openocd_launch_params, "exit")
@ -167,7 +170,9 @@ def blackmagic_find_serial(serial: str):
if not serial.startswith("\\\\.\\"):
serial = f"\\\\.\\{serial}"
ports = list(list_ports.grep("blackmagic"))
# idk why, but python thinks that list_ports.grep returns tuple[str, str, str]
ports: list[ListPortInfo] = list(list_ports.grep("blackmagic")) # type: ignore
if len(ports) == 0:
return None
elif len(ports) > 2: