diff --git a/applications/debug/rpc_debug_app/rpc_debug_app.c b/applications/debug/rpc_debug_app/rpc_debug_app.c index 1536b8918..1affeae29 100644 --- a/applications/debug/rpc_debug_app/rpc_debug_app.c +++ b/applications/debug/rpc_debug_app/rpc_debug_app.c @@ -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, "", buf_size); + strlcpy(buf, "", buf_size); return; } diff --git a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c index be7774881..09d58c2c9 100644 --- a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c +++ b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_code.c @@ -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); diff --git a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c index b07f8f4af..cca293b66 100644 --- a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c +++ b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_input_error_text.c @@ -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, diff --git a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c index 10d5e36f6..686a6f95d 100644 --- a/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c +++ b/applications/debug/rpc_debug_app/scenes/rpc_debug_app_scene_receive_data_exchange.c @@ -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); diff --git a/applications/examples/example_thermo/example_thermo.c b/applications/examples/example_thermo/example_thermo.c index 895f05ce7..e5af819e9 100644 --- a/applications/examples/example_thermo/example_thermo.c +++ b/applications/examples/example_thermo/example_thermo.c @@ -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); diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index 765d53612..eff44c6de 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -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); } diff --git a/applications/main/ibutton/ibutton_i.h b/applications/main/ibutton/ibutton_i.h index fc2324c63..73f108080 100644 --- a/applications/main/ibutton/ibutton_i.h +++ b/applications/main/ibutton/ibutton_i.h @@ -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; diff --git a/applications/main/infrared/infrared_app_i.h b/applications/main/infrared/infrared_app_i.h index 721771ef0..692cc9671 100644 --- a/applications/main/infrared/infrared_app_i.h +++ b/applications/main/infrared/infrared_app_i.h @@ -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" diff --git a/applications/main/infrared/resources/infrared/assets/tv.ir b/applications/main/infrared/resources/infrared/assets/tv.ir index 4d5868cce..9df664a7b 100644 --- a/applications/main/infrared/resources/infrared/assets/tv.ir +++ b/applications/main/infrared/resources/infrared/assets/tv.ir @@ -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 diff --git a/applications/main/infrared/scenes/infrared_scene_edit_rename.c b/applications/main/infrared/scenes/infrared_scene_edit_rename.c index 301e936d9..ea49080a1 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit_rename.c +++ b/applications/main/infrared/scenes/infrared_scene_edit_rename.c @@ -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(); diff --git a/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c b/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c index 7a51e3d86..4fece16be 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c +++ b/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c @@ -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); diff --git a/applications/main/nfc/scenes/nfc_scene_start.c b/applications/main/nfc/scenes/nfc_scene_start.c index 53857b849..b981b719a 100644 --- a/applications/main/nfc/scenes/nfc_scene_start.c +++ b/applications/main/nfc/scenes/nfc_scene_start.c @@ -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); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 08ba0ba82..cdf218aca 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -6,7 +6,7 @@ #include #include -#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, diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index 9ee85727b..a05525776 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -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; diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index 0f4cc4a0c..b76b38c25 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -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; } diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index aedcf8c94..163535f9a 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -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); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c index 74d09b2ac..17ef88358 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -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)); diff --git a/furi/core/event_loop.c b/furi/core/event_loop.c index 2a6cd51d3..f4f008a71 100644 --- a/furi/core/event_loop.c +++ b/furi/core/event_loop.c @@ -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) { diff --git a/furi/core/event_loop_timer.c b/furi/core/event_loop_timer.c index 03b6c5132..f4a79bb4f 100644 --- a/furi/core/event_loop_timer.c +++ b/furi/core/event_loop_timer.c @@ -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); } /* diff --git a/furi/core/thread.c b/furi/core/thread.c index 69c6b0f04..60cc628ac 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -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; diff --git a/furi/core/timer.c b/furi/core/timer.c index 1ca56f0fa..21952cf12 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -3,18 +3,20 @@ #include "kernel.h" #include +#include #include 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); } diff --git a/lib/lfrfid/protocols/protocol_gproxii.c b/lib/lfrfid/protocols/protocol_gproxii.c index 999e965ec..ab1d0b94d 100644 --- a/lib/lfrfid/protocols/protocol_gproxii.c +++ b/lib/lfrfid/protocols/protocol_gproxii.c @@ -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"); } diff --git a/lib/mjs/common/frozen/frozen.c b/lib/mjs/common/frozen/frozen.c index 923e6a556..7646864c0 100644 --- a/lib/mjs/common/frozen/frozen.c +++ b/lib/mjs/common/frozen/frozen.c @@ -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) { diff --git a/lib/mjs/mjs_json.c b/lib/mjs/mjs_json.c index 829b3b4c0..654eeb3d6 100644 --- a/lib/mjs/mjs_json.c +++ b/lib/mjs/mjs_json.c @@ -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; } } diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 6216906e5..553cf1472 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -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* diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index abc57fc4a..b0f1d339b 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -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* diff --git a/targets/f7/furi_hal/furi_hal_version.c b/targets/f7/furi_hal/furi_hal_version.c index bd449e599..2859ae362 100644 --- a/targets/f7/furi_hal/furi_hal_version.c +++ b/targets/f7/furi_hal/furi_hal_version.c @@ -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;