Merge branch 'dev' into nestednonces

This commit is contained in:
gornekich 2024-09-09 13:34:47 +01:00 committed by GitHub
commit 9558a5fa08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 236 additions and 125 deletions

View file

@ -24,7 +24,7 @@ static void rpc_debug_app_tick_event_callback(void* context) {
static void
rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) {
if(data == NULL || data_size == 0) {
strncpy(buf, "<Data empty>", buf_size);
strlcpy(buf, "<Data empty>", buf_size);
return;
}

View file

@ -26,7 +26,7 @@ static void rpc_debug_app_scene_input_error_code_result_callback(void* context)
void rpc_debug_app_scene_input_error_code_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "666", TEXT_STORE_SIZE);
strlcpy(app->text_store, "666", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error code");
text_input_set_validator(
app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL);

View file

@ -7,7 +7,7 @@ static void rpc_debug_app_scene_input_error_text_result_callback(void* context)
void rpc_debug_app_scene_input_error_text_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
strlcpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error text");
text_input_set_result_callback(
app->text_input,

View file

@ -2,7 +2,7 @@
void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
RpcDebugApp* app = context;
strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
strlcpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
text_box_set_text(app->text_box, app->text_store);
text_box_set_font(app->text_box, TextBoxFontHex);

View file

@ -257,7 +257,7 @@ static void example_thermo_draw_callback(Canvas* canvas, void* ctx) {
snprintf(text_store, TEXT_STORE_SIZE, "Temperature: %+.1f%c", (double)temp, temp_units);
} else {
/* Or show a message that no data is available */
strncpy(text_store, "-- No data --", TEXT_STORE_SIZE);
strlcpy(text_store, "-- No data --", TEXT_STORE_SIZE);
}
canvas_draw_str_aligned(canvas, middle_x, 58, AlignCenter, AlignBottom, text_store);

View file

@ -183,7 +183,7 @@ bool ibutton_load_key(iButton* ibutton, bool show_error) {
FuriString* tmp = furi_string_alloc();
path_extract_filename(ibutton->file_path, tmp, true);
strncpy(ibutton->key_name, furi_string_get_cstr(tmp), IBUTTON_KEY_NAME_SIZE);
strlcpy(ibutton->key_name, furi_string_get_cstr(tmp), IBUTTON_KEY_NAME_SIZE);
furi_string_free(tmp);
} else if(show_error) {
@ -243,7 +243,7 @@ bool ibutton_delete_key(iButton* ibutton) {
}
void ibutton_reset_key(iButton* ibutton) {
memset(ibutton->key_name, 0, IBUTTON_KEY_NAME_SIZE + 1);
ibutton->key_name[0] = '\0';
furi_string_reset(ibutton->file_path);
ibutton_key_reset(ibutton->key);
}

View file

@ -32,7 +32,7 @@
#define IBUTTON_APP_FILENAME_PREFIX "iBtn"
#define IBUTTON_APP_FILENAME_EXTENSION ".ibtn"
#define IBUTTON_KEY_NAME_SIZE 22
#define IBUTTON_KEY_NAME_SIZE 23
typedef enum {
iButtonWriteModeInvalid,
@ -56,7 +56,7 @@ struct iButton {
iButtonWriteMode write_mode;
FuriString* file_path;
char key_name[IBUTTON_KEY_NAME_SIZE + 1];
char key_name[IBUTTON_KEY_NAME_SIZE];
Submenu* submenu;
ByteInput* byte_input;

View file

@ -43,8 +43,8 @@
#define INFRARED_TEXT_STORE_NUM 2
#define INFRARED_TEXT_STORE_SIZE 128
#define INFRARED_MAX_BUTTON_NAME_LENGTH 22
#define INFRARED_MAX_REMOTE_NAME_LENGTH 22
#define INFRARED_MAX_BUTTON_NAME_LENGTH 23
#define INFRARED_MAX_REMOTE_NAME_LENGTH 23
#define INFRARED_APP_FOLDER EXT_PATH("infrared")
#define INFRARED_APP_EXTENSION ".ir"

View file

@ -1694,69 +1694,69 @@ type: parsed
protocol: RC6
address: 00 00 00 00
command: 0C 00 00 00
#
#
name: Mute
type: parsed
protocol: RC6
address: 00 00 00 00
command: 0D 00 00 00
#
#
name: Vol_up
type: parsed
protocol: RC6
address: 00 00 00 00
command: 10 00 00 00
#
#
name: Vol_dn
type: parsed
protocol: RC6
address: 00 00 00 00
command: 11 00 00 00
#
#
name: Ch_next
type: parsed
protocol: RC6
address: 00 00 00 00
command: 20 00 00 00
#
#
name: Ch_prev
type: parsed
protocol: RC6
address: 00 00 00 00
command: 21 00 00 00
#
#
# Model TCL 50P715X1
#
#
name: Power
type: parsed
protocol: RCA
address: 0F 00 00 00
command: 54 00 00 00
#
#
name: Mute
type: parsed
protocol: RCA
address: 0F 00 00 00
command: FC 00 00 00
#
#
name: Vol_up
type: parsed
protocol: RCA
address: 0F 00 00 00
command: F4 00 00 00
#
#
name: Vol_dn
type: parsed
protocol: RCA
address: 0F 00 00 00
command: 74 00 00 00
#
#
name: Ch_next
type: parsed
protocol: RCA
address: 0F 00 00 00
command: B4 00 00 00
#
#
name: Ch_prev
type: parsed
protocol: RCA
@ -1770,31 +1770,31 @@ type: parsed
protocol: NECext
address: 01 72 00 00
command: 5C A3 00 00
#
#
name: Power
type: parsed
protocol: NECext
address: 01 72 00 00
command: 1E E1 00 00
#
#
name: Vol_up
type: parsed
protocol: NECext
address: 01 72 00 00
command: 0A F5 00 00
#
#
name: Vol_dn
type: parsed
protocol: NECext
address: 01 72 00 00
command: 06 F9 00 00
#
#
name: Ch_next
type: parsed
protocol: NECext
address: 01 72 00 00
command: 48 B7 00 00
#
#
name: Ch_prev
type: parsed
protocol: NECext
@ -1836,39 +1836,39 @@ type: parsed
protocol: NEC
address: 04 00 00 00
command: 08 00 00 00
#
#
name: Vol_up
type: parsed
protocol: NEC
address: 04 00 00 00
command: 02 00 00 00
#
#
name: Vol_dn
type: parsed
protocol: NEC
address: 04 00 00 00
command: 03 00 00 00
#
#
name: Ch_next
type: parsed
protocol: NEC
address: 04 00 00 00
command: 00 00 00 00
#
#
name: Ch_prev
type: parsed
protocol: NEC
address: 04 00 00 00
command: 01 00 00 00
#
#
name: Mute
type: parsed
protocol: NEC
address: 04 00 00 00
command: 09 00 00 00
#
#
# Emerson TV
#
#
name: Power
type: parsed
protocol: NECext
@ -1880,28 +1880,66 @@ type: parsed
protocol: NECext
address: 84 E0 00 00
command: 50 AF 00 00
#
#
name: Ch_prev
type: parsed
protocol: NECext
address: 84 E0 00 00
command: 51 AE 00 00
#
#
name: Vol_up
type: parsed
protocol: NECext
address: 84 E0 00 00
command: 60 9F 00 00
#
#
name: Vol_dn
type: parsed
protocol: NECext
address: 84 E0 00 00
command: 61 9E 00 00
#
#
name: Mute
type: parsed
protocol: NECext
address: 84 E0 00 00
command: 64 9B 00 00
#
# TCL 75S451
#
name: Power
type: parsed
protocol: NECext
address: EA C7 00 00
command: 17 E8 00 00
#
name: Mute
type: parsed
protocol: NECext
address: EA C7 00 00
command: 20 DF 00 00
#
name: Vol_up
type: parsed
protocol: NECext
address: EA C7 00 00
command: 0F F0 00 00
#
name: Vol_dn
type: parsed
protocol: NECext
address: EA C7 00 00
command: 10 EF 00 00
#
name: Ch_next
type: parsed
protocol: NECext
address: EA C7 00 00
command: 19 E6 00 00
#
name: Ch_prev
type: parsed
protocol: NECext
address: EA C7 00 00
command: 33 CC 00 00

View file

@ -39,7 +39,7 @@ void infrared_scene_edit_rename_on_enter(void* context) {
furi_check(current_button_index != InfraredButtonIndexNone);
enter_name_length = INFRARED_MAX_BUTTON_NAME_LENGTH;
strncpy(
strlcpy(
infrared->text_store[0],
infrared_remote_get_signal_name(remote, current_button_index),
enter_name_length);
@ -47,7 +47,7 @@ void infrared_scene_edit_rename_on_enter(void* context) {
} else if(edit_target == InfraredEditTargetRemote) {
text_input_set_header_text(text_input, "Name the remote");
enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH;
strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length);
strlcpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length);
FuriString* folder_path;
folder_path = furi_string_alloc();

View file

@ -117,7 +117,7 @@ static void nfc_scene_read_menu_on_enter_mf_classic(NfcApp* instance) {
if(!mf_classic_is_card_read(data)) {
submenu_add_item(
submenu,
"Detect Reader",
"Extract MF Keys",
SubmenuIndexDetectReader,
nfc_protocol_support_common_submenu_callback,
instance);
@ -155,7 +155,7 @@ static void nfc_scene_saved_menu_on_enter_mf_classic(NfcApp* instance) {
if(!mf_classic_is_card_read(data)) {
submenu_add_item(
submenu,
"Detect Reader",
"Extract MF Keys",
SubmenuIndexDetectReader,
nfc_protocol_support_common_submenu_callback,
instance);

View file

@ -29,7 +29,11 @@ void nfc_scene_start_on_enter(void* context) {
submenu_add_item(submenu, "Read", SubmenuIndexRead, nfc_scene_start_submenu_callback, nfc);
submenu_add_item(
submenu, "Detect Reader", SubmenuIndexDetectReader, nfc_scene_start_submenu_callback, nfc);
submenu,
"Extract MF Keys",
SubmenuIndexDetectReader,
nfc_scene_start_submenu_callback,
nfc);
submenu_add_item(submenu, "Saved", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
submenu_add_item(
submenu, "Extra Actions", SubmenuIndexExtraAction, nfc_scene_start_submenu_callback, nfc);

View file

@ -6,7 +6,7 @@
#include <dolphin/dolphin.h>
#include <toolbox/name_generator.h>
#define MAX_TEXT_INPUT_LEN 22
#define MAX_TEXT_INPUT_LEN 23
void subghz_scene_save_name_text_input_callback(void* context) {
furi_assert(context);
@ -39,7 +39,7 @@ void subghz_scene_save_name_on_enter(void* context) {
FuriString* dir_name = furi_string_alloc();
if(!subghz_path_is_file(subghz->file_path)) {
char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0};
char file_name_buf[SUBGHZ_MAX_LEN_NAME];
name_generator_make_auto(file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX);
@ -62,7 +62,7 @@ void subghz_scene_save_name_on_enter(void* context) {
furi_string_set(subghz->file_path, dir_name);
}
strncpy(subghz->file_name_tmp, furi_string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME);
strlcpy(subghz->file_name_tmp, furi_string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME);
text_input_set_header_text(text_input, "Name signal");
text_input_set_result_callback(
text_input,

View file

@ -52,8 +52,7 @@ static bool animation_storage_load_single_manifest_info(
if(furi_string_cmp_str(read_string, name)) break;
flipper_format_set_strict_mode(file, true);
manifest_info->name = malloc(furi_string_size(read_string) + 1);
strcpy((char*)manifest_info->name, furi_string_get_cstr(read_string));
manifest_info->name = strdup(furi_string_get_cstr(read_string));
if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break;
manifest_info->min_butthurt = u32value;
@ -105,9 +104,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis
storage_animation->manifest_info.name = NULL;
if(!flipper_format_read_string(file, "Name", read_string)) break;
storage_animation->manifest_info.name = malloc(furi_string_size(read_string) + 1);
strcpy(
(char*)storage_animation->manifest_info.name, furi_string_get_cstr(read_string));
storage_animation->manifest_info.name = strdup(furi_string_get_cstr(read_string));
if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break;
storage_animation->manifest_info.min_butthurt = u32value;
@ -401,8 +398,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo
furi_string_replace_all(str, "\\n", "\n");
FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(furi_string_size(str) + 1));
strcpy((char*)bubble->bubble.text, furi_string_get_cstr(str));
FURI_CONST_ASSIGN_PTR(bubble->bubble.text, strdup(furi_string_get_cstr(str)));
if(!flipper_format_read_string(ff, "AlignH", str)) break;
if(!animation_storage_cast_align(str, (Align*)&bubble->bubble.align_h)) break;

View file

@ -717,7 +717,7 @@ static bool loader_do_signal(Loader* loader, uint32_t signal, void* arg) {
static bool loader_do_get_application_name(Loader* loader, FuriString* name) {
if(loader_is_application_running(loader)) {
furi_string_set(name, furi_thread_get_name(loader->app.thread));
furi_string_set(name, furi_thread_get_name(furi_thread_get_id(loader->app.thread)));
return true;
}

View file

@ -226,9 +226,7 @@ static void rpc_system_storage_list_root(const PB_Main* request, void* context)
response.content.storage_list_response.file[i].data = NULL;
response.content.storage_list_response.file[i].size = 0;
response.content.storage_list_response.file[i].type = PB_Storage_File_FileType_DIR;
char* str = malloc(strlen(hard_coded_dirs[i]) + 1);
strcpy(str, hard_coded_dirs[i]);
response.content.storage_list_response.file[i].name = str;
response.content.storage_list_response.file[i].name = strdup(hard_coded_dirs[i]);
}
rpc_send_and_release(session, &response);

View file

@ -209,7 +209,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e
if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) {
submenu_reset(app->submenu); // Prevent menu from being shown when we exiting scene
strncpy(
strlcpy(
curr_favorite_app->name_or_path,
furi_string_get_cstr(temp_path),
sizeof(curr_favorite_app->name_or_path));
@ -219,7 +219,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e
size_t app_index = event.event - 2;
const char* name = favorite_fap_get_app_name(app_index);
if(name)
strncpy(
strlcpy(
curr_favorite_app->name_or_path,
name,
sizeof(curr_favorite_app->name_or_path));

View file

@ -71,9 +71,9 @@ FuriEventLoop* furi_event_loop_alloc(void) {
PendingQueue_init(instance->pending_queue);
// Clear notification state and value
xTaskNotifyStateClearIndexed(instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX);
ulTaskNotifyValueClearIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, 0xFFFFFFFF);
TaskHandle_t task = (TaskHandle_t)instance->thread_id;
xTaskNotifyStateClearIndexed(task, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX);
ulTaskNotifyValueClearIndexed(task, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, 0xFFFFFFFF);
return instance;
}
@ -178,7 +178,7 @@ static void furi_event_loop_process_waiting_list(FuriEventLoop* instance) {
static void furi_event_loop_restore_flags(FuriEventLoop* instance, uint32_t flags) {
if(flags) {
xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, flags, eSetBits);
(TaskHandle_t)instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, flags, eSetBits);
}
}
@ -186,10 +186,11 @@ void furi_event_loop_run(FuriEventLoop* instance) {
furi_check(instance);
furi_check(instance->thread_id == furi_thread_get_current_id());
FuriThread* thread = furi_thread_get_current();
// Set the default signal callback if none was previously set
if(furi_thread_get_signal_callback(instance->thread_id) == NULL) {
furi_thread_set_signal_callback(
instance->thread_id, furi_event_loop_signal_callback, instance);
if(furi_thread_get_signal_callback(thread) == NULL) {
furi_thread_set_signal_callback(thread, furi_event_loop_signal_callback, instance);
}
furi_event_loop_init_tick(instance);
@ -233,8 +234,8 @@ void furi_event_loop_run(FuriEventLoop* instance) {
}
// Disable the default signal callback
if(furi_thread_get_signal_callback(instance->thread_id) == furi_event_loop_signal_callback) {
furi_thread_set_signal_callback(instance->thread_id, NULL, NULL);
if(furi_thread_get_signal_callback(thread) == furi_event_loop_signal_callback) {
furi_thread_set_signal_callback(thread, NULL, NULL);
}
}
@ -242,7 +243,10 @@ void furi_event_loop_stop(FuriEventLoop* instance) {
furi_check(instance);
xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagStop, eSetBits);
(TaskHandle_t)instance->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagStop,
eSetBits);
}
/*
@ -265,7 +269,10 @@ void furi_event_loop_pend_callback(
PendingQueue_push_front(instance->pending_queue, item);
xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagPending, eSetBits);
(TaskHandle_t)instance->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagPending,
eSetBits);
}
/*
@ -473,7 +480,10 @@ static void furi_event_loop_item_notify(FuriEventLoopItem* instance) {
FURI_CRITICAL_EXIT();
xTaskNotifyIndexed(
owner->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagEvent, eSetBits);
(TaskHandle_t)owner->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagEvent,
eSetBits);
}
static bool furi_event_loop_item_is_waiting(FuriEventLoopItem* instance) {

View file

@ -65,7 +65,10 @@ static void furi_event_loop_timer_enqueue_request(
TimerQueue_push_back(instance->timer_queue, timer);
xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagTimer, eSetBits);
(TaskHandle_t)instance->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagTimer,
eSetBits);
}
/*

View file

@ -97,7 +97,7 @@ static void furi_thread_body(void* context) {
furi_thread_set_state(thread, FuriThreadStateRunning);
if(thread->heap_trace_enabled == true) {
memmgr_heap_enable_thread_trace(thread);
memmgr_heap_enable_thread_trace((FuriThreadId)thread);
}
thread->ret = thread->callback(thread->context);
@ -106,14 +106,14 @@ static void furi_thread_body(void* context) {
if(thread->heap_trace_enabled == true) {
furi_delay_ms(33);
thread->heap_size = memmgr_heap_get_thread_memory(thread);
thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)thread);
furi_log_print_format(
thread->heap_size ? FuriLogLevelError : FuriLogLevelInfo,
TAG,
"%s allocation balance: %zu",
thread->name ? thread->name : "Thread",
thread->heap_size);
memmgr_heap_disable_thread_trace(thread);
memmgr_heap_disable_thread_trace((FuriThreadId)thread);
}
furi_check(thread->state == FuriThreadStateRunning);
@ -275,7 +275,7 @@ void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority) {
FuriThreadPriority furi_thread_get_priority(FuriThread* thread) {
furi_check(thread);
TaskHandle_t hTask = furi_thread_get_id(thread);
TaskHandle_t hTask = (TaskHandle_t)thread;
return (FuriThreadPriority)uxTaskPriorityGet(hTask);
}
@ -390,7 +390,7 @@ bool furi_thread_join(FuriThread* thread) {
FuriThreadId furi_thread_get_id(FuriThread* thread) {
furi_check(thread);
return thread;
return (FuriThreadId)thread;
}
void furi_thread_enable_heap_trace(FuriThread* thread) {
@ -418,7 +418,7 @@ int32_t furi_thread_get_return_code(FuriThread* thread) {
}
FuriThreadId furi_thread_get_current_id(void) {
return xTaskGetCurrentTaskHandle();
return (FuriThreadId)xTaskGetCurrentTaskHandle();
}
FuriThread* furi_thread_get_current(void) {
@ -624,15 +624,16 @@ bool furi_thread_enumerate(FuriThreadList* thread_list) {
FuriThreadListItem* item =
furi_thread_list_get_or_insert(thread_list, (FuriThread*)task[i].xHandle);
item->thread = (FuriThreadId)task[i].xHandle;
item->app_id = furi_thread_get_appid(item->thread);
FuriThreadId thread_id = (FuriThreadId)task[i].xHandle;
item->thread = (FuriThread*)thread_id;
item->app_id = furi_thread_get_appid(thread_id);
item->name = task[i].pcTaskName;
item->priority = task[i].uxCurrentPriority;
item->stack_address = (uint32_t)tcb->pxStack;
size_t thread_heap = memmgr_heap_get_thread_memory(item->thread);
size_t thread_heap = memmgr_heap_get_thread_memory(thread_id);
item->heap = thread_heap == MEMMGR_HEAP_UNKNOWN ? 0u : thread_heap;
item->stack_size = (tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t);
item->stack_min_free = furi_thread_get_stack_space(item->thread);
item->stack_min_free = furi_thread_get_stack_space(thread_id);
item->state = furi_thread_state_name(task[i].eCurrentState);
item->counter_previous = item->counter_current;
item->counter_current = task[i].ulRunTimeCounter;

View file

@ -3,18 +3,20 @@
#include "kernel.h"
#include <FreeRTOS.h>
#include <event_groups.h>
#include <timers.h>
struct FuriTimer {
StaticTimer_t container;
FuriTimerCallback cb_func;
void* cb_context;
volatile bool can_be_removed;
};
// IMPORTANT: container MUST be the FIRST struct member
static_assert(offsetof(FuriTimer, container) == 0);
#define TIMER_DELETED_EVENT (1U << 0)
static void TimerCallback(TimerHandle_t hTimer) {
FuriTimer* instance = pvTimerGetTimerID(hTimer);
furi_check(instance);
@ -42,9 +44,8 @@ static void furi_timer_epilogue(void* context, uint32_t arg) {
furi_assert(context);
UNUSED(arg);
FuriTimer* instance = context;
instance->can_be_removed = true;
EventGroupHandle_t hEvent = context;
xEventGroupSetBits(hEvent, TIMER_DELETED_EVENT);
}
void furi_timer_free(FuriTimer* instance) {
@ -53,11 +54,13 @@ void furi_timer_free(FuriTimer* instance) {
TimerHandle_t hTimer = (TimerHandle_t)instance;
furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS);
furi_check(xTimerPendFunctionCall(furi_timer_epilogue, instance, 0, portMAX_DELAY) == pdPASS);
while(!instance->can_be_removed) {
furi_delay_tick(2);
}
StaticEventGroup_t event_container;
EventGroupHandle_t hEvent = xEventGroupCreateStatic(&event_container);
furi_check(xTimerPendFunctionCall(furi_timer_epilogue, hEvent, 0, portMAX_DELAY) == pdPASS);
xEventGroupWaitBits(hEvent, TIMER_DELETED_EVENT, 0, pdTRUE, portMAX_DELAY);
vEventGroupDelete(hEvent);
free(instance);
}

View file

@ -38,8 +38,48 @@ void protocol_gproxii_free(ProtocolGProxII* protocol) {
free(protocol);
}
uint8_t* protocol_gproxii_get_data(ProtocolGProxII* proto) {
return proto->decoded_data;
uint8_t* protocol_gproxii_get_data(ProtocolGProxII* protocol) {
return protocol->decoded_data;
}
bool wiegand_check(uint64_t fc_and_card, bool even_parity, bool odd_parity, int card_len) {
uint8_t even_parity_sum = 0;
uint8_t odd_parity_sum = 1;
switch(card_len) {
case 26:
for(int8_t i = 12; i < 24; i++) {
if(((fc_and_card >> i) & 1) == 1) {
even_parity_sum++;
}
}
if(even_parity_sum % 2 != even_parity) return false;
for(int8_t i = 0; i < 12; i++) {
if(((fc_and_card >> i) & 1) == 1) {
odd_parity_sum++;
}
}
if(odd_parity_sum % 2 != odd_parity) return false;
break;
case 36:
for(int8_t i = 17; i < 34; i++) {
if(((fc_and_card >> i) & 1) == 1) {
even_parity_sum++;
}
}
if(even_parity_sum % 2 != even_parity) return false;
for(int8_t i = 0; i < 17; i++) {
if(((fc_and_card >> i) & 1) == 1) {
odd_parity_sum++;
}
}
if(odd_parity_sum % 2 != odd_parity) return false;
break;
default:
furi_crash();
}
return true;
}
void protocol_gproxii_decoder_start(ProtocolGProxII* protocol) {
@ -74,13 +114,13 @@ static bool protocol_gproxii_can_be_decoded(ProtocolGProxII* protocol) {
// XORVALUE LLLLLL DD PPPPPPPPPPPPPPPP E FFFFFFFF CCCCCCCCCCCCCCCC O UUUUUUUUUUUUUU
// 10010000 011010 11 0000000100000000 0 00000000 0000000000000001 0 00000000000000 - Profile: 256 FC: 0 Card: 1
// 72 Bit Guardall/Verex/Chubb GProx II 36 bit key with 26 bit profile
// 0 10 20 30 40 50 60 70
// | | | | | | | |
// 01234567 890123 45 67890123456789012345678901 2 34567890 1234567890123456 7 8901
// 72 Bit Guardall/Verex/Chubb GProx II 36 bit key with 16 bit profile
// 0 10 20 30 40 50 60 70
// | | | | | | | |
// 01234567 890123 45 67890123 45678901 2 34567890123456 78901234567890123456 7 8901
// --------------------------------------------------------------------------------
// XORVALUE LLLLLL DD PPPPPPPPPPPPPPPPPPPPPPPPPP E FFFFFFFF CCCCCCCCCCCCCCCC O UUUU
// 10111000 100100 10 00000001000000000000000000 1 01000000 1000100010111000 1 0000 - Profile: 262144 FC: 64 Card: 35000
// XORVALUE LLLLLL DD PPPPPPPP PPPPPPPP E UUUUUUFFFFFFFF UUUUCCCCCCCCCCCCCCCC O UUUU
// 10111000 100100 10 00000001 00000000 0 00000000010100 00001000100010111000 1 0000 - Profile: 256 FC: 20 Card: 35000
// X = XOR Key, L = Message length, D = 2 bit check digits, P = Profile, E = Wiegand leading even parity
// F = Faclity code, C = Card number, O = Wiegand trailing odd parity, U = Unused bits
@ -111,11 +151,23 @@ static bool protocol_gproxii_can_be_decoded(ProtocolGProxII* protocol) {
// Check card length is either 26 or 36
int card_len = bit_lib_get_bits(protocol->decoded_data, 8, 6);
if(card_len == 26 || card_len == 36) {
return true;
// wiegand parity
if(card_len == 26) {
uint64_t fc_and_card = bit_lib_get_bits_64(protocol->decoded_data, 33, 24);
bool even_parity = bit_lib_get_bits(protocol->decoded_data, 32, 1);
bool odd_parity = bit_lib_get_bits(protocol->decoded_data, 57, 1);
if(!wiegand_check(fc_and_card, even_parity, odd_parity, card_len)) return false;
} else if(card_len == 36) {
uint64_t fc_and_card = bit_lib_get_bits_64(protocol->decoded_data, 33, 34);
uint8_t even_parity = bit_lib_get_bits(protocol->decoded_data, 32, 1);
uint8_t odd_parity = bit_lib_get_bits(protocol->decoded_data, 67, 1);
if(!wiegand_check(fc_and_card, even_parity, odd_parity, card_len)) return false;
} else {
return false; // If we don't get a 26 or 36 it's not a known card type
}
return true;
}
bool protocol_gproxii_decoder_feed(ProtocolGProxII* protocol, bool level, uint32_t duration) {
@ -191,7 +243,7 @@ void protocol_gproxii_render_data(ProtocolGProxII* protocol, FuriString* result)
// Print FC, Card and Length
furi_string_cat_printf(
result,
"FC: %hhu Card: %hu LEN: %hhu\n",
"FC: %u Card: %u LEN: %hhu\n",
bit_lib_get_bits(protocol->decoded_data, 33, 8),
bit_lib_get_bits_16(protocol->decoded_data, 41, 16),
card_len);
@ -206,17 +258,17 @@ void protocol_gproxii_render_data(ProtocolGProxII* protocol, FuriString* result)
// Print FC, Card and Length
furi_string_cat_printf(
result,
"FC: %hhu Card: %hu LEN: %hhu\n",
bit_lib_get_bits(protocol->decoded_data, 43, 8),
"FC: %u Card: %u LEN: %hhu\n",
bit_lib_get_bits_16(protocol->decoded_data, 33, 14),
bit_lib_get_bits_16(protocol->decoded_data, 51, 16),
card_len);
// XOR Key, CRC and Profile
furi_string_cat_printf(
result,
"XOR: %hhu CRC: %hhu P: %06lX",
"XOR: %hhu CRC: %hhu P: %04hX",
xor_code,
crc_code,
bit_lib_get_bits_32(protocol->decoded_data, 16, 26));
bit_lib_get_bits_16(protocol->decoded_data, 16, 16));
} else {
furi_string_cat_printf(result, "Read Error\n");
}

View file

@ -37,7 +37,7 @@
#ifdef _WIN32
#undef snprintf
#undef vsnprintf
#define snprintf cs_win_snprintf
#define snprintf cs_win_snprintf
#define vsnprintf cs_win_vsnprintf
int cs_win_snprintf(char* str, size_t size, const char* format, ...);
int cs_win_vsnprintf(char* str, size_t size, const char* format, va_list ap);
@ -150,7 +150,8 @@ static int json_isspace(int ch) {
}
static void json_skip_whitespaces(struct frozen* f) {
while(f->cur < f->end && json_isspace(*f->cur)) f->cur++;
while(f->cur < f->end && json_isspace(*f->cur))
f->cur++;
}
static int json_cur(struct frozen* f) {
@ -263,15 +264,18 @@ static int json_parse_number(struct frozen* f) {
f->cur += 2;
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++;
while(f->cur < f->end && json_isxdigit(f->cur[0]))
f->cur++;
} else {
EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++;
while(f->cur < f->end && json_isdigit(f->cur[0]))
f->cur++;
if(f->cur < f->end && f->cur[0] == '.') {
f->cur++;
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++;
while(f->cur < f->end && json_isdigit(f->cur[0]))
f->cur++;
}
if(f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
f->cur++;
@ -279,7 +283,8 @@ static int json_parse_number(struct frozen* f) {
if((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++;
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++;
while(f->cur < f->end && json_isdigit(f->cur[0]))
f->cur++;
}
}
json_truncate_path(f, fstate.path_len);
@ -639,8 +644,7 @@ int json_vprintf(struct json_out* out, const char* fmt, va_list xap) {
int need_len, size = sizeof(buf);
char fmt2[20];
va_list ap_copy;
strncpy(fmt2, fmt, n + 1 > (int)sizeof(fmt2) ? sizeof(fmt2) : (size_t)n + 1);
fmt2[n + 1] = '\0';
strlcpy(fmt2, fmt, sizeof(fmt2));
va_copy(ap_copy, ap);
need_len = vsnprintf(pbuf, size, fmt2, ap_copy);
@ -1047,7 +1051,7 @@ int json_vscanf(const char* s, int len, const char* fmt, va_list ap) {
while(fmt[i] != '\0') {
if(fmt[i] == '{') {
strcat(path, ".");
strlcat(path, ".", sizeof(path));
i++;
} else if(fmt[i] == '}') {
if((p = strrchr(path, '.')) != NULL) *p = '\0';
@ -1160,7 +1164,8 @@ struct json_setf_data {
static int get_matched_prefix_len(const char* s1, const char* s2) {
int i = 0;
while(s1[i] && s2[i] && s1[i] == s2[i]) i++;
while(s1[i] && s2[i] && s1[i] == s2[i])
i++;
return i;
}
@ -1235,7 +1240,8 @@ int json_vsetf(
/* Trim comma after the value that begins at object/array start */
if(s[data.prev - 1] == '{' || s[data.prev - 1] == '[') {
int i = data.end;
while(i < len && json_isspace(s[i])) i++;
while(i < len && json_isspace(s[i]))
i++;
if(s[i] == ',') data.end = i + 1; /* Point after comma */
}
json_printf(out, "%.*s", len - data.end, s + data.end);
@ -1305,7 +1311,8 @@ struct prettify_data {
};
static void indent(struct json_out* out, int level) {
while(level-- > 0) out->printer(out, " ", 2);
while(level-- > 0)
out->printer(out, " ", 2);
}
static void print_key(struct prettify_data* pd, const char* path, const char* name, int name_len) {

View file

@ -138,8 +138,7 @@ MJS_PRIVATE mjs_err_t to_json_or_debug(
vp < mjs->json_visited_stack.buf + mjs->json_visited_stack.len;
vp += sizeof(mjs_val_t)) {
if(*(mjs_val_t*)vp == v) {
strncpy(buf, "[Circular]", size);
len = 10;
len = strlcpy(buf, "[Circular]", size);
goto clean;
}
}

View file

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,73.1,,
Version,+,73.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,,
@ -2598,7 +2598,7 @@ Function,+,strint_to_int64,StrintParseError,"const char*, char**, int64_t*, uint
Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t"
Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t"
Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t"
Function,-,strlcat,size_t,"char*, const char*, size_t"
Function,+,strlcat,size_t,"char*, const char*, size_t"
Function,+,strlcpy,size_t,"char*, const char*, size_t"
Function,+,strlen,size_t,const char*
Function,-,strlwr,char*,char*

1 entry status name type params
2 Version + 73.1 73.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/bt/bt_service/bt_keys_storage.h
5 Header + applications/services/cli/cli.h
2598 Function + strint_to_uint16 StrintParseError const char*, char**, uint16_t*, uint8_t
2599 Function + strint_to_uint32 StrintParseError const char*, char**, uint32_t*, uint8_t
2600 Function + strint_to_uint64 StrintParseError const char*, char**, uint64_t*, uint8_t
2601 Function - + strlcat size_t char*, const char*, size_t
2602 Function + strlcpy size_t char*, const char*, size_t
2603 Function + strlen size_t const char*
2604 Function - strlwr char* char*

View file

@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,73.1,,
Version,+,73.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@ -3280,7 +3280,7 @@ Function,+,strint_to_int64,StrintParseError,"const char*, char**, int64_t*, uint
Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t"
Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t"
Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t"
Function,-,strlcat,size_t,"char*, const char*, size_t"
Function,+,strlcat,size_t,"char*, const char*, size_t"
Function,+,strlcpy,size_t,"char*, const char*, size_t"
Function,+,strlen,size_t,const char*
Function,-,strlwr,char*,char*

1 entry status name type params
2 Version + 73.1 73.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/bt/bt_service/bt_keys_storage.h
3280 Function + strint_to_uint16 StrintParseError const char*, char**, uint16_t*, uint8_t
3281 Function + strint_to_uint32 StrintParseError const char*, char**, uint32_t*, uint8_t
3282 Function + strint_to_uint64 StrintParseError const char*, char**, uint64_t*, uint8_t
3283 Function - + strlcat size_t char*, const char*, size_t
3284 Function + strlcpy size_t char*, const char*, size_t
3285 Function + strlen size_t const char*
3286 Function - strlwr char* char*

View file

@ -99,7 +99,7 @@ static void furi_hal_version_set_name(const char* name) {
"xFlipper %s",
furi_hal_version.name);
} else {
snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper");
strlcpy(furi_hal_version.device_name, "xFlipper", FURI_HAL_VERSION_DEVICE_NAME_LENGTH);
}
furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;