From 8c2223df5dfc9c5b1119adee634e53610ca504d1 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 7 Sep 2024 20:18:51 +0200 Subject: [PATCH 1/6] Threading, Timers improvements (#3865) * FuriTimer: Use a local variable to wait for deletion This combines the current synchronous behaviour (as we could have deferred the free call too) with a smaller FuriTimer - it's safe to pass a pointer to a local variable to this pending timer call, because we know it'll be finished before the caller returns * Tighten the use of FuriThread* vs FuriThreadId Event loop and Loader mixed those two, but the fact those are aliases should be an implementation detail. For this reason, thread.c is still allowed to mix them freely. --- applications/services/loader/loader.c | 2 +- furi/core/event_loop.c | 34 +++++++++++++++++---------- furi/core/event_loop_timer.c | 5 +++- furi/core/thread.c | 21 +++++++++-------- furi/core/timer.c | 14 ++++++----- 5 files changed, 46 insertions(+), 30 deletions(-) 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/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..4ed913958 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -9,7 +9,6 @@ struct FuriTimer { StaticTimer_t container; FuriTimerCallback cb_func; void* cb_context; - volatile bool can_be_removed; }; // IMPORTANT: container MUST be the FIRST struct member @@ -42,9 +41,8 @@ static void furi_timer_epilogue(void* context, uint32_t arg) { furi_assert(context); UNUSED(arg); - FuriTimer* instance = context; - - instance->can_be_removed = true; + volatile bool* can_be_removed = context; + *can_be_removed = true; } void furi_timer_free(FuriTimer* instance) { @@ -53,9 +51,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) { + volatile bool can_be_removed = false; + furi_check( + xTimerPendFunctionCall(furi_timer_epilogue, (void*)&can_be_removed, 0, portMAX_DELAY) == + pdPASS); + + while(!can_be_removed) { furi_delay_tick(2); } From a122ee75f6711b449a1f172fc5c12d287e1997cc Mon Sep 17 00:00:00 2001 From: Zinong Li <131403964+zinongli@users.noreply.github.com> Date: Sun, 8 Sep 2024 06:25:31 -0400 Subject: [PATCH 2/6] LFRFID: Guard GProxII Wiegand Check Against False Positive and Correct 36-bit Parsing (#3868) * Update protocol_gproxii.c * 36 bit format parsing fix * Update protocol_gproxii.c * wiegand checks as single function * LfRfid: simplify gprox wiegand payload validation flow * LfRfid: extra furi_check in gprox wiegand validation code Co-authored-by: Aleksandr Kutuzov --- lib/lfrfid/protocols/protocol_gproxii.c | 82 ++++++++++++++++++++----- 1 file changed, 67 insertions(+), 15 deletions(-) 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"); } From 75f4782fab640bb61278fba463544eddd8f6174e Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Sun, 8 Sep 2024 15:43:14 -0700 Subject: [PATCH 3/6] Rename 'Detect Reader' to 'Extract MF Keys' (#3874) * Rename 'Detect Reader' to 'Collect Nonces' * Updated name * Updated name * Format Sources Co-authored-by: Aleksandr Kutuzov --- .../nfc/helpers/protocol_support/mf_classic/mf_classic.c | 4 ++-- applications/main/nfc/scenes/nfc_scene_start.c | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) 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); From 543f6058e5c3cf5593c3dbcfc3beea8ccaeb8f3c Mon Sep 17 00:00:00 2001 From: christhetech131 <85564092+christhetech131@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:54:38 -0500 Subject: [PATCH 4/6] Infrared: add TCL 75S451 to TV universal remote (#3880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update tv.ir * Infrared: mark TCL 75S451 block in universal remote, cleanup extra spaces Co-authored-by: あく --- .../infrared/resources/infrared/assets/tv.ir | 94 +++++++++++++------ 1 file changed, 66 insertions(+), 28 deletions(-) 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 From 70d8951fb703d09750972be125a4bc11d2ae3b40 Mon Sep 17 00:00:00 2001 From: Silent Date: Mon, 9 Sep 2024 01:04:56 +0200 Subject: [PATCH 5/6] FuriTimer: Use an event instead of a volatile bool to wait for deletion (#3887) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- furi/core/timer.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/furi/core/timer.c b/furi/core/timer.c index 4ed913958..21952cf12 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -3,6 +3,7 @@ #include "kernel.h" #include +#include #include struct FuriTimer { @@ -14,6 +15,8 @@ struct FuriTimer { // 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); @@ -41,8 +44,8 @@ static void furi_timer_epilogue(void* context, uint32_t arg) { furi_assert(context); UNUSED(arg); - volatile bool* can_be_removed = context; - *can_be_removed = true; + EventGroupHandle_t hEvent = context; + xEventGroupSetBits(hEvent, TIMER_DELETED_EVENT); } void furi_timer_free(FuriTimer* instance) { @@ -52,14 +55,12 @@ void furi_timer_free(FuriTimer* instance) { TimerHandle_t hTimer = (TimerHandle_t)instance; furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); - volatile bool can_be_removed = false; - furi_check( - xTimerPendFunctionCall(furi_timer_epilogue, (void*)&can_be_removed, 0, portMAX_DELAY) == - pdPASS); + StaticEventGroup_t event_container; + EventGroupHandle_t hEvent = xEventGroupCreateStatic(&event_container); + furi_check(xTimerPendFunctionCall(furi_timer_epilogue, hEvent, 0, portMAX_DELAY) == pdPASS); - while(!can_be_removed) { - furi_delay_tick(2); - } + xEventGroupWaitBits(hEvent, TIMER_DELETED_EVENT, 0, pdTRUE, portMAX_DELAY); + vEventGroupDelete(hEvent); free(instance); } From 78c5dd95d867941206e1be2fd3585c9c76132bd7 Mon Sep 17 00:00:00 2001 From: Zinong Li <131403964+zinongli@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:23:18 -0400 Subject: [PATCH 6/6] LFRFID GProxII Fix Writing and Rendering Conflict (#3888) --- lib/lfrfid/protocols/protocol_gproxii.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/lfrfid/protocols/protocol_gproxii.c b/lib/lfrfid/protocols/protocol_gproxii.c index ab1d0b94d..341d092e9 100644 --- a/lib/lfrfid/protocols/protocol_gproxii.c +++ b/lib/lfrfid/protocols/protocol_gproxii.c @@ -39,7 +39,7 @@ void protocol_gproxii_free(ProtocolGProxII* protocol) { } uint8_t* protocol_gproxii_get_data(ProtocolGProxII* protocol) { - return protocol->decoded_data; + return protocol->data; } bool wiegand_check(uint64_t fc_and_card, bool even_parity, bool odd_parity, int card_len) { @@ -235,6 +235,7 @@ LevelDuration protocol_gproxii_encoder_yield(ProtocolGProxII* protocol) { } void protocol_gproxii_render_data(ProtocolGProxII* protocol, FuriString* result) { + protocol_gproxii_can_be_decoded(protocol); int xor_code = bit_lib_get_bits(protocol->decoded_data, 0, 8); int card_len = bit_lib_get_bits(protocol->decoded_data, 8, 6); int crc_code = bit_lib_get_bits(protocol->decoded_data, 14, 2);