mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-10 19:23:31 -07:00
Merge remote-tracking branch 'ofw/dev' into mntm-dev
This commit is contained in:
+7
-1
@@ -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);
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user