Merge remote-tracking branch 'ofw/dev' into mntm-dev

This commit is contained in:
Willy-JL
2024-09-09 23:12:13 +02:00
10 changed files with 391 additions and 349 deletions
+7 -1
View File
@@ -21,18 +21,24 @@
- Quac!: Setting for external IR board support (by @daniilty), code improvements (by @rdefeo)
- UL: Sub-GHz Bruteforcer: Add new protocols for existing dump option (by @xMasterX)
- CLI: Print plugin name on load fail (by @Willy-JL)
- OFW: NFC: Rename 'Detect Reader' to 'Extract MF Keys' (by @bettse)
- Infrared:
- OFW: IR button operation fails now shows more informative messages (by @RebornedBrain)
- OFW: Add Airwell AW-HKD012-N91 to univeral AC remote (by @valeraOlexienko)
- OFW: Add TCL 75S451 to TV universal remote (by @christhetech131)
- OFW: GUI: Change dialog_ex text ownership model (by @skotopes)
- OFW: CCID: App changes and improvements (by @kidbomb)
- OFW: API: Exposed `view_dispatcher_get_event_loop` (by @CookiePLMonster)
- OFW: Furi: Replace all calls to strncpy with strlcpy, use strdup more, expose strlcat (by @CookiePLMonster)
- Furi:
- OFW: Replace all calls to strncpy with strlcpy, use strdup more, expose strlcat (by @CookiePLMonster)
- OFW: Threading, Timers improvements (by @CookiePLMonster)
- OFW: FuriTimer uses an event instead of a volatile bool to wait for deletion (by @CookiePLMonster)
### Fixed:
- RFID:
- OFW: Fix detection of GProx II cards and false detection of other cards (by @Astrrra)
- OFW: Fix Guard GProxII False Positive and 36-bit Parsing (by @zinongli)
- OFW: GProxII Fix Writing and Rendering Conflict (by @zinongli)
- Desktop: Fallback Poweroff prompt when power settings is unavailable (by @Willy-JL)
- Storage: Fallback SD format prompt when storage settings is unavailable (by @Willy-JL)
- About: Fix BLE stack version string (by @Willy-JL)
File diff suppressed because it is too large Load Diff
@@ -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);
@@ -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);
+1 -1
View File
@@ -787,7 +787,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;
}
+22 -12
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) {
+4 -1
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);
}
/*
+11 -10
View File
@@ -57,7 +57,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);
@@ -66,14 +66,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);
@@ -235,7 +235,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);
}
@@ -350,7 +350,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) {
@@ -378,7 +378,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) {
@@ -584,15 +584,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;
+11 -8
View File
@@ -4,6 +4,7 @@
#include "kernel.h"
#include <FreeRTOS.h>
#include <event_groups.h>
#include <timers.h>
const char* current_timer_name = NULL;
@@ -12,12 +13,13 @@ 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)
const char* furi_timer_get_current_name(void) {
return current_timer_name;
}
@@ -54,9 +56,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) {
@@ -65,11 +66,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);
}
+16 -15
View File
@@ -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) {
@@ -77,6 +77,7 @@ bool wiegand_check(uint64_t fc_and_card, bool even_parity, bool odd_parity, int
if(odd_parity_sum % 2 != odd_parity) return false;
break;
default:
furi_crash();
}
return true;
}
@@ -151,23 +152,22 @@ 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) {
// 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;
}
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) {
@@ -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);