Merge remote-tracking branch 'origin/release-candidate' into release
This commit is contained in:
commit
357fbfe63b
@ -37,7 +37,7 @@
|
|||||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL (256)
|
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL (256)
|
||||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_HALF \
|
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_HALF \
|
||||||
(SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL / 2)
|
(SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL / 2)
|
||||||
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_GUARD_TIME 999
|
#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_GUARD_TIME 999 << 1
|
||||||
|
|
||||||
/** SubGhz state */
|
/** SubGhz state */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -483,7 +483,7 @@ static void subghz_device_cc1101_ext_capture_ISR() {
|
|||||||
|
|
||||||
subghz_device_cc1101_ext->async_rx.capture_callback(
|
subghz_device_cc1101_ext->async_rx.capture_callback(
|
||||||
true,
|
true,
|
||||||
LL_TIM_GetCounter(TIM17),
|
LL_TIM_GetCounter(TIM17) << 1,
|
||||||
(void*)subghz_device_cc1101_ext->async_rx.capture_callback_context);
|
(void*)subghz_device_cc1101_ext->async_rx.capture_callback_context);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -493,11 +493,11 @@ static void subghz_device_cc1101_ext_capture_ISR() {
|
|||||||
|
|
||||||
subghz_device_cc1101_ext->async_rx.capture_callback(
|
subghz_device_cc1101_ext->async_rx.capture_callback(
|
||||||
false,
|
false,
|
||||||
LL_TIM_GetCounter(TIM17),
|
LL_TIM_GetCounter(TIM17) << 1,
|
||||||
(void*)subghz_device_cc1101_ext->async_rx.capture_callback_context);
|
(void*)subghz_device_cc1101_ext->async_rx.capture_callback_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LL_TIM_SetCounter(TIM17, 6);
|
LL_TIM_SetCounter(TIM17, 4); //8>>1
|
||||||
}
|
}
|
||||||
|
|
||||||
void subghz_device_cc1101_ext_start_async_rx(
|
void subghz_device_cc1101_ext_start_async_rx(
|
||||||
@ -512,7 +512,8 @@ void subghz_device_cc1101_ext_start_async_rx(
|
|||||||
furi_hal_bus_enable(FuriHalBusTIM17);
|
furi_hal_bus_enable(FuriHalBusTIM17);
|
||||||
|
|
||||||
// Configure TIM
|
// Configure TIM
|
||||||
LL_TIM_SetPrescaler(TIM17, 64 - 1);
|
//Set the timer resolution to 2 us
|
||||||
|
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
|
||||||
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
||||||
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
||||||
@ -606,7 +607,7 @@ static void subghz_device_cc1101_ext_async_tx_refill(uint32_t* buffer, size_t sa
|
|||||||
|
|
||||||
uint32_t duration = level_duration_get_duration(ld);
|
uint32_t duration = level_duration_get_duration(ld);
|
||||||
furi_assert(duration > 0);
|
furi_assert(duration > 0);
|
||||||
*buffer = duration - 1;
|
*buffer = duration >> 1;
|
||||||
buffer++;
|
buffer++;
|
||||||
samples--;
|
samples--;
|
||||||
}
|
}
|
||||||
@ -692,7 +693,8 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
|
|||||||
furi_hal_bus_enable(FuriHalBusTIM17);
|
furi_hal_bus_enable(FuriHalBusTIM17);
|
||||||
|
|
||||||
// Configure TIM
|
// Configure TIM
|
||||||
LL_TIM_SetPrescaler(TIM17, 64 - 1);
|
// Set the timer resolution to 2 us
|
||||||
|
LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1);
|
||||||
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
LL_TIM_SetAutoReload(TIM17, 0xFFFF);
|
||||||
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1);
|
||||||
|
|||||||
5
applications/external/hid_app/hid.c
vendored
5
applications/external/hid_app/hid.c
vendored
@ -1,7 +1,6 @@
|
|||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
#include "views.h"
|
#include "views.h"
|
||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
#include <dolphin/dolphin.h>
|
|
||||||
|
|
||||||
#define TAG "HidApp"
|
#define TAG "HidApp"
|
||||||
|
|
||||||
@ -389,8 +388,6 @@ int32_t hid_usb_app(void* p) {
|
|||||||
|
|
||||||
bt_hid_connection_status_changed_callback(BtStatusConnected, app);
|
bt_hid_connection_status_changed_callback(BtStatusConnected, app);
|
||||||
|
|
||||||
dolphin_deed(DolphinDeedPluginStart);
|
|
||||||
|
|
||||||
view_dispatcher_run(app->view_dispatcher);
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
|
|
||||||
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
||||||
@ -429,8 +426,6 @@ int32_t hid_ble_app(void* p) {
|
|||||||
furi_hal_bt_start_advertising();
|
furi_hal_bt_start_advertising();
|
||||||
bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
|
bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
|
||||||
|
|
||||||
dolphin_deed(DolphinDeedPluginStart);
|
|
||||||
|
|
||||||
view_dispatcher_run(app->view_dispatcher);
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
|
|
||||||
bt_set_status_changed_callback(app->bt, NULL, NULL);
|
bt_set_status_changed_callback(app->bt, NULL, NULL);
|
||||||
|
|||||||
@ -60,6 +60,8 @@ typedef enum {
|
|||||||
InfraredEditModeNone,
|
InfraredEditModeNone,
|
||||||
InfraredEditModeRename,
|
InfraredEditModeRename,
|
||||||
InfraredEditModeDelete,
|
InfraredEditModeDelete,
|
||||||
|
InfraredEditModeMove,
|
||||||
|
InfraredEditModeMoveSelectDest
|
||||||
} InfraredEditMode;
|
} InfraredEditMode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -69,6 +71,7 @@ typedef struct {
|
|||||||
InfraredEditTarget edit_target : 8;
|
InfraredEditTarget edit_target : 8;
|
||||||
InfraredEditMode edit_mode : 8;
|
InfraredEditMode edit_mode : 8;
|
||||||
int32_t current_button_index;
|
int32_t current_button_index;
|
||||||
|
int32_t current_button_index_move_orig;
|
||||||
uint32_t last_transmit_time;
|
uint32_t last_transmit_time;
|
||||||
} InfraredAppState;
|
} InfraredAppState;
|
||||||
|
|
||||||
|
|||||||
@ -108,6 +108,21 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) {
|
|||||||
return infrared_remote_store(remote);
|
return infrared_remote_store(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest) {
|
||||||
|
furi_assert(index_orig < InfraredButtonArray_size(remote->buttons));
|
||||||
|
furi_assert(index_dest <= InfraredButtonArray_size(remote->buttons));
|
||||||
|
if(index_orig == index_dest) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
InfraredRemoteButton* button;
|
||||||
|
InfraredButtonArray_pop_at(&button, remote->buttons, index_orig);
|
||||||
|
if(index_orig > index_dest)
|
||||||
|
InfraredButtonArray_push_at(remote->buttons, index_dest, button);
|
||||||
|
else
|
||||||
|
InfraredButtonArray_push_at(remote->buttons, index_dest - 1, button);
|
||||||
|
return infrared_remote_store(remote);
|
||||||
|
}
|
||||||
|
|
||||||
bool infrared_remote_store(InfraredRemote* remote) {
|
bool infrared_remote_store(InfraredRemote* remote) {
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
FlipperFormat* ff = flipper_format_file_alloc(storage);
|
FlipperFormat* ff = flipper_format_file_alloc(storage);
|
||||||
|
|||||||
@ -23,6 +23,7 @@ bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* nam
|
|||||||
bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal);
|
bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal);
|
||||||
bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index);
|
bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index);
|
||||||
bool infrared_remote_delete_button(InfraredRemote* remote, size_t index);
|
bool infrared_remote_delete_button(InfraredRemote* remote, size_t index);
|
||||||
|
bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest);
|
||||||
|
|
||||||
bool infrared_remote_store(InfraredRemote* remote);
|
bool infrared_remote_store(InfraredRemote* remote);
|
||||||
bool infrared_remote_load(InfraredRemote* remote, FuriString* path);
|
bool infrared_remote_load(InfraredRemote* remote, FuriString* path);
|
||||||
|
|||||||
@ -7,6 +7,8 @@ ADD_SCENE(infrared, edit_delete_done, EditDeleteDone)
|
|||||||
ADD_SCENE(infrared, edit_button_select, EditButtonSelect)
|
ADD_SCENE(infrared, edit_button_select, EditButtonSelect)
|
||||||
ADD_SCENE(infrared, edit_rename, EditRename)
|
ADD_SCENE(infrared, edit_rename, EditRename)
|
||||||
ADD_SCENE(infrared, edit_rename_done, EditRenameDone)
|
ADD_SCENE(infrared, edit_rename_done, EditRenameDone)
|
||||||
|
ADD_SCENE(infrared, edit_move, EditMove)
|
||||||
|
ADD_SCENE(infrared, edit_move_done, EditMoveDone)
|
||||||
ADD_SCENE(infrared, learn, Learn)
|
ADD_SCENE(infrared, learn, Learn)
|
||||||
ADD_SCENE(infrared, learn_done, LearnDone)
|
ADD_SCENE(infrared, learn_done, LearnDone)
|
||||||
ADD_SCENE(infrared, learn_enter_name, LearnEnterName)
|
ADD_SCENE(infrared, learn_enter_name, LearnEnterName)
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
SubmenuIndexAddButton,
|
SubmenuIndexAddButton,
|
||||||
SubmenuIndexRenameButton,
|
SubmenuIndexRenameButton,
|
||||||
|
SubmenuIndexMoveButton,
|
||||||
SubmenuIndexDeleteButton,
|
SubmenuIndexDeleteButton,
|
||||||
SubmenuIndexRenameRemote,
|
SubmenuIndexRenameRemote,
|
||||||
SubmenuIndexDeleteRemote,
|
SubmenuIndexDeleteRemote,
|
||||||
@ -30,6 +31,12 @@ void infrared_scene_edit_on_enter(void* context) {
|
|||||||
SubmenuIndexRenameButton,
|
SubmenuIndexRenameButton,
|
||||||
infrared_scene_edit_submenu_callback,
|
infrared_scene_edit_submenu_callback,
|
||||||
context);
|
context);
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"Move Button",
|
||||||
|
SubmenuIndexMoveButton,
|
||||||
|
infrared_scene_edit_submenu_callback,
|
||||||
|
context);
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu,
|
submenu,
|
||||||
"Delete Button",
|
"Delete Button",
|
||||||
@ -74,6 +81,11 @@ bool infrared_scene_edit_on_event(void* context, SceneManagerEvent event) {
|
|||||||
infrared->app_state.edit_mode = InfraredEditModeRename;
|
infrared->app_state.edit_mode = InfraredEditModeRename;
|
||||||
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
|
} else if(submenu_index == SubmenuIndexMoveButton) {
|
||||||
|
infrared->app_state.edit_target = InfraredEditTargetButton;
|
||||||
|
infrared->app_state.edit_mode = InfraredEditModeMove;
|
||||||
|
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||||
|
consumed = true;
|
||||||
} else if(submenu_index == SubmenuIndexDeleteButton) {
|
} else if(submenu_index == SubmenuIndexDeleteButton) {
|
||||||
infrared->app_state.edit_target = InfraredEditTargetButton;
|
infrared->app_state.edit_target = InfraredEditTargetButton;
|
||||||
infrared->app_state.edit_mode = InfraredEditModeDelete;
|
infrared->app_state.edit_mode = InfraredEditModeDelete;
|
||||||
|
|||||||
@ -11,9 +11,23 @@ void infrared_scene_edit_button_select_on_enter(void* context) {
|
|||||||
InfraredRemote* remote = infrared->remote;
|
InfraredRemote* remote = infrared->remote;
|
||||||
InfraredAppState* app_state = &infrared->app_state;
|
InfraredAppState* app_state = &infrared->app_state;
|
||||||
|
|
||||||
const char* header = infrared->app_state.edit_mode == InfraredEditModeRename ?
|
const char* header = NULL;
|
||||||
"Rename Button:" :
|
switch(infrared->app_state.edit_mode) {
|
||||||
"Delete Button:";
|
case InfraredEditModeRename:
|
||||||
|
header = "Rename Button:";
|
||||||
|
break;
|
||||||
|
case InfraredEditModeDelete:
|
||||||
|
header = "Delete Button:";
|
||||||
|
break;
|
||||||
|
case InfraredEditModeMove:
|
||||||
|
header = "Select Button to Move:";
|
||||||
|
break;
|
||||||
|
case InfraredEditModeMoveSelectDest:
|
||||||
|
case InfraredEditModeNone:
|
||||||
|
default:
|
||||||
|
header = "Move Button Before:";
|
||||||
|
break;
|
||||||
|
}
|
||||||
submenu_set_header(submenu, header);
|
submenu_set_header(submenu, header);
|
||||||
|
|
||||||
const size_t button_count = infrared_remote_get_button_count(remote);
|
const size_t button_count = infrared_remote_get_button_count(remote);
|
||||||
@ -26,7 +40,14 @@ void infrared_scene_edit_button_select_on_enter(void* context) {
|
|||||||
infrared_scene_edit_button_select_submenu_callback,
|
infrared_scene_edit_button_select_submenu_callback,
|
||||||
context);
|
context);
|
||||||
}
|
}
|
||||||
|
if(infrared->app_state.edit_mode == InfraredEditModeMoveSelectDest) {
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"-- Move to the end --",
|
||||||
|
button_count,
|
||||||
|
infrared_scene_edit_button_select_submenu_callback,
|
||||||
|
context);
|
||||||
|
}
|
||||||
if(button_count && app_state->current_button_index != InfraredButtonIndexNone) {
|
if(button_count && app_state->current_button_index != InfraredButtonIndexNone) {
|
||||||
submenu_set_selected_item(submenu, app_state->current_button_index);
|
submenu_set_selected_item(submenu, app_state->current_button_index);
|
||||||
app_state->current_button_index = InfraredButtonIndexNone;
|
app_state->current_button_index = InfraredButtonIndexNone;
|
||||||
@ -48,6 +69,12 @@ bool infrared_scene_edit_button_select_on_event(void* context, SceneManagerEvent
|
|||||||
scene_manager_next_scene(scene_manager, InfraredSceneEditRename);
|
scene_manager_next_scene(scene_manager, InfraredSceneEditRename);
|
||||||
} else if(edit_mode == InfraredEditModeDelete) {
|
} else if(edit_mode == InfraredEditModeDelete) {
|
||||||
scene_manager_next_scene(scene_manager, InfraredSceneEditDelete);
|
scene_manager_next_scene(scene_manager, InfraredSceneEditDelete);
|
||||||
|
} else if(edit_mode == InfraredEditModeMove) {
|
||||||
|
app_state->current_button_index_move_orig = event.event;
|
||||||
|
app_state->edit_mode = InfraredEditModeMoveSelectDest;
|
||||||
|
scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect);
|
||||||
|
} else if(edit_mode == InfraredEditModeMoveSelectDest) {
|
||||||
|
scene_manager_next_scene(scene_manager, InfraredSceneEditMove);
|
||||||
} else {
|
} else {
|
||||||
furi_assert(0);
|
furi_assert(0);
|
||||||
}
|
}
|
||||||
|
|||||||
103
applications/main/infrared/scenes/infrared_scene_edit_move.c
Normal file
103
applications/main/infrared/scenes/infrared_scene_edit_move.c
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
static void infrared_scene_edit_move_dialog_result_callback(DialogExResult result, void* context) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
view_dispatcher_send_custom_event(infrared->view_dispatcher, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_scene_edit_move_on_enter(void* context) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
DialogEx* dialog_ex = infrared->dialog_ex;
|
||||||
|
InfraredRemote* remote = infrared->remote;
|
||||||
|
|
||||||
|
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
|
||||||
|
if(edit_target == InfraredEditTargetButton) {
|
||||||
|
int32_t current_button_index = infrared->app_state.current_button_index_move_orig;
|
||||||
|
furi_assert(current_button_index != InfraredButtonIndexNone);
|
||||||
|
|
||||||
|
dialog_ex_set_header(dialog_ex, "Move Button?", 64, 0, AlignCenter, AlignTop);
|
||||||
|
InfraredRemoteButton* current_button =
|
||||||
|
infrared_remote_get_button(remote, current_button_index);
|
||||||
|
InfraredSignal* signal = infrared_remote_button_get_signal(current_button);
|
||||||
|
|
||||||
|
if(infrared_signal_is_raw(signal)) {
|
||||||
|
const InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
|
||||||
|
infrared_text_store_set(
|
||||||
|
infrared,
|
||||||
|
0,
|
||||||
|
"%s\nRAW\n%ld samples",
|
||||||
|
infrared_remote_button_get_name(current_button),
|
||||||
|
raw->timings_size);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const InfraredMessage* message = infrared_signal_get_message(signal);
|
||||||
|
infrared_text_store_set(
|
||||||
|
infrared,
|
||||||
|
0,
|
||||||
|
"%s\n%s\nA=0x%0*lX C=0x%0*lX",
|
||||||
|
infrared_remote_button_get_name(current_button),
|
||||||
|
infrared_get_protocol_name(message->protocol),
|
||||||
|
ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4),
|
||||||
|
message->address,
|
||||||
|
ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4),
|
||||||
|
message->command);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
furi_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog_ex_set_text(dialog_ex, infrared->text_store[0], 64, 31, AlignCenter, AlignCenter);
|
||||||
|
dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
|
||||||
|
dialog_ex_set_left_button_text(dialog_ex, "Cancel");
|
||||||
|
dialog_ex_set_right_button_text(dialog_ex, "Move");
|
||||||
|
dialog_ex_set_result_callback(dialog_ex, infrared_scene_edit_move_dialog_result_callback);
|
||||||
|
dialog_ex_set_context(dialog_ex, context);
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_scene_edit_move_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
SceneManager* scene_manager = infrared->scene_manager;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == DialogExResultLeft) {
|
||||||
|
scene_manager_previous_scene(scene_manager);
|
||||||
|
consumed = true;
|
||||||
|
} else if(event.event == DialogExResultRight) {
|
||||||
|
bool success = false;
|
||||||
|
InfraredRemote* remote = infrared->remote;
|
||||||
|
InfraredAppState* app_state = &infrared->app_state;
|
||||||
|
const InfraredEditTarget edit_target = app_state->edit_target;
|
||||||
|
|
||||||
|
if(edit_target == InfraredEditTargetButton) {
|
||||||
|
furi_assert(app_state->current_button_index != InfraredButtonIndexNone);
|
||||||
|
success = infrared_remote_move_button(
|
||||||
|
remote,
|
||||||
|
app_state->current_button_index_move_orig,
|
||||||
|
app_state->current_button_index);
|
||||||
|
app_state->current_button_index_move_orig = InfraredButtonIndexNone;
|
||||||
|
app_state->current_button_index = InfraredButtonIndexNone;
|
||||||
|
} else {
|
||||||
|
furi_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(success) {
|
||||||
|
scene_manager_next_scene(scene_manager, InfraredSceneEditMoveDone);
|
||||||
|
} else {
|
||||||
|
const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
|
||||||
|
scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||||
|
scene_manager, possible_scenes, COUNT_OF(possible_scenes));
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_scene_edit_move_on_exit(void* context) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
UNUSED(infrared);
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
void infrared_scene_edit_move_done_on_enter(void* context) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
Popup* popup = infrared->popup;
|
||||||
|
|
||||||
|
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
|
||||||
|
popup_set_header(popup, "Moved", 83, 19, AlignLeft, AlignBottom);
|
||||||
|
|
||||||
|
popup_set_callback(popup, infrared_popup_closed_callback);
|
||||||
|
popup_set_context(popup, context);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infrared_scene_edit_move_done_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
SceneManager* scene_manager = infrared->scene_manager;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == InfraredCustomEventTypePopupClosed) {
|
||||||
|
const InfraredEditTarget edit_target = infrared->app_state.edit_target;
|
||||||
|
if(edit_target == InfraredEditTargetButton) {
|
||||||
|
scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
scene_manager, InfraredSceneRemote);
|
||||||
|
} else if(edit_target == InfraredEditTargetRemote) {
|
||||||
|
const uint32_t possible_scenes[] = {InfraredSceneStart, InfraredSceneRemoteList};
|
||||||
|
if(!scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||||
|
scene_manager, possible_scenes, COUNT_OF(possible_scenes))) {
|
||||||
|
view_dispatcher_stop(infrared->view_dispatcher);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
furi_assert(0);
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infrared_scene_edit_move_done_on_exit(void* context) {
|
||||||
|
Infrared* infrared = context;
|
||||||
|
UNUSED(infrared);
|
||||||
|
}
|
||||||
@ -146,7 +146,7 @@ static void nfc_cli_apdu(Cli* cli, FuriString* args) {
|
|||||||
resp_size = (tx_rx.rx_bits / 8) * 2;
|
resp_size = (tx_rx.rx_bits / 8) * 2;
|
||||||
if(!resp_size) {
|
if(!resp_size) {
|
||||||
printf("No response\r\n");
|
printf("No response\r\n");
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
resp_buffer = malloc(resp_size);
|
resp_buffer = malloc(resp_size);
|
||||||
uint8_to_hex_chars(tx_rx.rx_data, resp_buffer, resp_size);
|
uint8_to_hex_chars(tx_rx.rx_data, resp_buffer, resp_size);
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#define TAG "U2F"
|
#define TAG "U2F"
|
||||||
|
|
||||||
#define U2F_DATA_FOLDER ANY_PATH("u2f/")
|
#define U2F_DATA_FOLDER EXT_PATH("u2f/")
|
||||||
#define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der"
|
#define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der"
|
||||||
#define U2F_CERT_KEY_FILE U2F_DATA_FOLDER "assets/cert_key.u2f"
|
#define U2F_CERT_KEY_FILE U2F_DATA_FOLDER "assets/cert_key.u2f"
|
||||||
#define U2F_KEY_FILE U2F_DATA_FOLDER "key.u2f"
|
#define U2F_KEY_FILE U2F_DATA_FOLDER "key.u2f"
|
||||||
|
|||||||
@ -39,7 +39,7 @@ static const DolphinDeedWeight dolphin_deed_weights[] = {
|
|||||||
|
|
||||||
{1, DolphinAppPlugin}, // DolphinDeedGpioUartBridge
|
{1, DolphinAppPlugin}, // DolphinDeedGpioUartBridge
|
||||||
|
|
||||||
{1, DolphinAppPlugin}, // DolphinDeedPluginStart
|
{2, DolphinAppPlugin}, // DolphinDeedPluginStart
|
||||||
{1, DolphinAppPlugin}, // DolphinDeedPluginGameStart
|
{1, DolphinAppPlugin}, // DolphinDeedPluginGameStart
|
||||||
{10, DolphinAppPlugin}, // DolphinDeedPluginGameWin
|
{10, DolphinAppPlugin}, // DolphinDeedPluginGameWin
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <assets_icons.h>
|
#include <assets_icons.h>
|
||||||
|
|
||||||
|
/** ByteInput type */
|
||||||
struct ByteInput {
|
struct ByteInput {
|
||||||
View* view;
|
View* view;
|
||||||
};
|
};
|
||||||
@ -25,7 +26,7 @@ typedef struct {
|
|||||||
|
|
||||||
bool selected_high_nibble;
|
bool selected_high_nibble;
|
||||||
uint8_t selected_byte;
|
uint8_t selected_byte;
|
||||||
int8_t selected_row; // row -1 - input, row 0 & 1 - keyboard
|
int8_t selected_row; // row -2 - mini_editor, -1 - input, row 0 & 1 - keyboard
|
||||||
uint8_t selected_column;
|
uint8_t selected_column;
|
||||||
uint8_t first_visible_byte;
|
uint8_t first_visible_byte;
|
||||||
} ByteInputModel;
|
} ByteInputModel;
|
||||||
@ -61,11 +62,11 @@ static const ByteInputKey keyboard_keys_row_2[] = {
|
|||||||
{enter_symbol, 95, 17},
|
{enter_symbol, 95, 17},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** Get row size
|
||||||
* @brief Get row size
|
*
|
||||||
*
|
* @param row_index Index of row
|
||||||
* @param row_index Index of row
|
*
|
||||||
* @return uint8_t Row size
|
* @return uint8_t Row size
|
||||||
*/
|
*/
|
||||||
static uint8_t byte_input_get_row_size(uint8_t row_index) {
|
static uint8_t byte_input_get_row_size(uint8_t row_index) {
|
||||||
uint8_t row_size = 0;
|
uint8_t row_size = 0;
|
||||||
@ -84,11 +85,11 @@ static uint8_t byte_input_get_row_size(uint8_t row_index) {
|
|||||||
return row_size;
|
return row_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Get row pointer
|
||||||
* @brief Get row pointer
|
*
|
||||||
*
|
* @param row_index Index of row
|
||||||
* @param row_index Index of row
|
*
|
||||||
* @return const ByteInputKey* Row pointer
|
* @return const ByteInputKey* Row pointer
|
||||||
*/
|
*/
|
||||||
static const ByteInputKey* byte_input_get_row(uint8_t row_index) {
|
static const ByteInputKey* byte_input_get_row(uint8_t row_index) {
|
||||||
const ByteInputKey* row = NULL;
|
const ByteInputKey* row = NULL;
|
||||||
@ -107,12 +108,12 @@ static const ByteInputKey* byte_input_get_row(uint8_t row_index) {
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Get text from nibble
|
||||||
* @brief Get text from nibble
|
*
|
||||||
*
|
* @param byte byte value
|
||||||
* @param byte byte value
|
* @param high_nibble Get from high nibble, otherwise low nibble
|
||||||
* @param high_nibble Get from high nibble, otherwise low nibble
|
*
|
||||||
* @return char nibble text
|
* @return char nibble text
|
||||||
*/
|
*/
|
||||||
static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) {
|
static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) {
|
||||||
if(high_nibble) {
|
if(high_nibble) {
|
||||||
@ -149,15 +150,20 @@ static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) {
|
|||||||
return byte;
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
const char num_to_char[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||||
* @brief Draw input box (common view)
|
|
||||||
*
|
/** Draw input box (common view)
|
||||||
* @param canvas
|
*
|
||||||
* @param model
|
* @param canvas The canvas
|
||||||
|
* @param model The model
|
||||||
*/
|
*/
|
||||||
static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
|
static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
|
||||||
const uint8_t text_x = 8;
|
const uint8_t text_x = 8;
|
||||||
const uint8_t text_y = 25;
|
const uint8_t text_y = 25;
|
||||||
|
const uint8_t text_y2 = 40;
|
||||||
|
const bool draw_index_line =
|
||||||
|
(model->selected_row == -2) &&
|
||||||
|
(model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes + 1) <= 100);
|
||||||
|
|
||||||
elements_slightly_rounded_frame(canvas, 6, 14, 116, 15);
|
elements_slightly_rounded_frame(canvas, 6, 14, 116, 15);
|
||||||
|
|
||||||
@ -225,6 +231,27 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
|
|||||||
text_y,
|
text_y,
|
||||||
byte_input_get_nibble_text(model->bytes[i], false));
|
byte_input_get_nibble_text(model->bytes[i], false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(draw_index_line) {
|
||||||
|
canvas_draw_glyph(
|
||||||
|
canvas, text_x + 2 + byte_position * 14, text_y2, num_to_char[(i + 1) / 10]);
|
||||||
|
|
||||||
|
canvas_draw_glyph(
|
||||||
|
canvas, text_x + 8 + byte_position * 14, text_y2, num_to_char[(i + 1) % 10]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((model->selected_row == -2) &&
|
||||||
|
(model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes + 1) > 100)) {
|
||||||
|
char str[20];
|
||||||
|
|
||||||
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
snprintf(str, 20, "Selected index");
|
||||||
|
canvas_draw_str(canvas, text_x, text_y2, str);
|
||||||
|
|
||||||
|
canvas_set_font(canvas, FontPrimary);
|
||||||
|
snprintf(str, 20, "%u", (model->selected_byte + 1));
|
||||||
|
canvas_draw_str(canvas, text_x + 75, text_y2, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
|
if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
|
||||||
@ -236,11 +263,10 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Draw input box (selected view)
|
||||||
* @brief Draw input box (selected view)
|
*
|
||||||
*
|
* @param canvas The canvas
|
||||||
* @param canvas
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model) {
|
static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model) {
|
||||||
const uint8_t text_x = 7;
|
const uint8_t text_x = 7;
|
||||||
@ -297,13 +323,12 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model
|
|||||||
canvas_invert_color(canvas);
|
canvas_invert_color(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Set nibble at position
|
||||||
* @brief Set nibble at position
|
*
|
||||||
*
|
* @param data where to set nibble
|
||||||
* @param data where to set nibble
|
* @param position byte position
|
||||||
* @param position byte position
|
* @param value char value
|
||||||
* @param value char value
|
* @param high_nibble set high nibble
|
||||||
* @param high_nibble set high nibble
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, bool high_nibble) {
|
static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, bool high_nibble) {
|
||||||
switch(value) {
|
switch(value) {
|
||||||
@ -341,29 +366,28 @@ static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** What currently selected
|
||||||
* @brief What currently selected
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @return true - keyboard selected, false - input selected
|
*
|
||||||
|
* @return true - keyboard selected, false - input selected
|
||||||
*/
|
*/
|
||||||
static bool byte_input_keyboard_selected(ByteInputModel* model) {
|
static bool byte_input_keyboard_selected(ByteInputModel* model) {
|
||||||
return model->selected_row >= 0;
|
return model->selected_row >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Do transition from keyboard
|
||||||
* @brief Do transition from keyboard
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_transition_from_keyboard(ByteInputModel* model) {
|
static void byte_input_transition_from_keyboard(ByteInputModel* model) {
|
||||||
model->selected_row += 1;
|
model->selected_row += 1;
|
||||||
model->selected_high_nibble = true;
|
model->selected_high_nibble = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Increase selected byte position
|
||||||
* @brief Increase selected byte position
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_inc_selected_byte(ByteInputModel* model) {
|
static void byte_input_inc_selected_byte(ByteInputModel* model) {
|
||||||
if(model->selected_byte < model->bytes_count - 1) {
|
if(model->selected_byte < model->bytes_count - 1) {
|
||||||
@ -379,10 +403,20 @@ static void byte_input_inc_selected_byte(ByteInputModel* model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void byte_input_inc_selected_byte_mini(ByteInputModel* model) {
|
||||||
* @brief Decrease selected byte position
|
if((model->selected_byte < model->bytes_count - 1) || model->selected_high_nibble) {
|
||||||
*
|
if(!model->selected_high_nibble) {
|
||||||
* @param model
|
model->selected_high_nibble = !model->selected_high_nibble; //-V547
|
||||||
|
byte_input_inc_selected_byte(model);
|
||||||
|
} else {
|
||||||
|
model->selected_high_nibble = !model->selected_high_nibble; //-V547
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Decrease selected byte position
|
||||||
|
*
|
||||||
|
* @param model The model
|
||||||
*/
|
*/
|
||||||
static void byte_input_dec_selected_byte(ByteInputModel* model) {
|
static void byte_input_dec_selected_byte(ByteInputModel* model) {
|
||||||
if(model->selected_byte > 0) {
|
if(model->selected_byte > 0) {
|
||||||
@ -397,10 +431,20 @@ static void byte_input_dec_selected_byte(ByteInputModel* model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void byte_input_dec_selected_byte_mini(ByteInputModel* model) {
|
||||||
* @brief Call input callback
|
if(model->selected_byte > 0 || !model->selected_high_nibble) {
|
||||||
*
|
if(model->selected_high_nibble) {
|
||||||
* @param model
|
model->selected_high_nibble = !model->selected_high_nibble; //-V547
|
||||||
|
byte_input_dec_selected_byte(model);
|
||||||
|
} else {
|
||||||
|
model->selected_high_nibble = !model->selected_high_nibble; //-V547
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Call input callback
|
||||||
|
*
|
||||||
|
* @param model The model
|
||||||
*/
|
*/
|
||||||
static void byte_input_call_input_callback(ByteInputModel* model) {
|
static void byte_input_call_input_callback(ByteInputModel* model) {
|
||||||
if(model->input_callback != NULL) {
|
if(model->input_callback != NULL) {
|
||||||
@ -408,10 +452,9 @@ static void byte_input_call_input_callback(ByteInputModel* model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Call changed callback
|
||||||
* @brief Call changed callback
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_call_changed_callback(ByteInputModel* model) {
|
static void byte_input_call_changed_callback(ByteInputModel* model) {
|
||||||
if(model->changed_callback != NULL) {
|
if(model->changed_callback != NULL) {
|
||||||
@ -419,8 +462,9 @@ static void byte_input_call_changed_callback(ByteInputModel* model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Clear selected byte
|
||||||
* @brief Clear selected byte
|
*
|
||||||
|
* @param model The model
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void byte_input_clear_selected_byte(ByteInputModel* model) {
|
static void byte_input_clear_selected_byte(ByteInputModel* model) {
|
||||||
@ -430,36 +474,55 @@ static void byte_input_clear_selected_byte(ByteInputModel* model) {
|
|||||||
byte_input_call_changed_callback(model);
|
byte_input_call_changed_callback(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Handle up button
|
||||||
* @brief Handle up button
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_handle_up(ByteInputModel* model) {
|
static void byte_input_handle_up(ByteInputModel* model) {
|
||||||
if(model->selected_row > -1) {
|
if(model->selected_row > -2) {
|
||||||
model->selected_row -= 1;
|
model->selected_row -= 1;
|
||||||
|
} else if(model->selected_row == -2) {
|
||||||
|
if(!model->selected_high_nibble) {
|
||||||
|
model->bytes[model->selected_byte] = (model->bytes[model->selected_byte] & 0xF0) |
|
||||||
|
((model->bytes[model->selected_byte] + 1) & 0x0F);
|
||||||
|
} else {
|
||||||
|
model->bytes[model->selected_byte] =
|
||||||
|
((model->bytes[model->selected_byte] + 0x10) & 0xF0) |
|
||||||
|
(model->bytes[model->selected_byte] & 0x0F);
|
||||||
|
}
|
||||||
|
byte_input_call_changed_callback(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Handle down button
|
||||||
* @brief Handle down button
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_handle_down(ByteInputModel* model) {
|
static void byte_input_handle_down(ByteInputModel* model) {
|
||||||
if(byte_input_keyboard_selected(model)) {
|
if(model->selected_row != -2) {
|
||||||
if(model->selected_row < keyboard_row_count - 1) {
|
if(byte_input_keyboard_selected(model)) {
|
||||||
model->selected_row += 1;
|
if(model->selected_row < keyboard_row_count - 1) {
|
||||||
|
model->selected_row += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
byte_input_transition_from_keyboard(model);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte_input_transition_from_keyboard(model);
|
if(!model->selected_high_nibble) {
|
||||||
|
model->bytes[model->selected_byte] = (model->bytes[model->selected_byte] & 0xF0) |
|
||||||
|
((model->bytes[model->selected_byte] - 1) & 0x0F);
|
||||||
|
} else {
|
||||||
|
model->bytes[model->selected_byte] =
|
||||||
|
((model->bytes[model->selected_byte] - 0x10) & 0xF0) |
|
||||||
|
(model->bytes[model->selected_byte] & 0x0F);
|
||||||
|
}
|
||||||
|
byte_input_call_changed_callback(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Handle left button
|
||||||
* @brief Handle left button
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_handle_left(ByteInputModel* model) {
|
static void byte_input_handle_left(ByteInputModel* model) {
|
||||||
if(byte_input_keyboard_selected(model)) {
|
if(byte_input_keyboard_selected(model)) {
|
||||||
@ -469,14 +532,17 @@ static void byte_input_handle_left(ByteInputModel* model) {
|
|||||||
model->selected_column = byte_input_get_row_size(model->selected_row) - 1;
|
model->selected_column = byte_input_get_row_size(model->selected_row) - 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte_input_dec_selected_byte(model);
|
if(model->selected_row != -2) {
|
||||||
|
byte_input_dec_selected_byte(model);
|
||||||
|
} else {
|
||||||
|
byte_input_dec_selected_byte_mini(model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Handle right button
|
||||||
* @brief Handle right button
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_handle_right(ByteInputModel* model) {
|
static void byte_input_handle_right(ByteInputModel* model) {
|
||||||
if(byte_input_keyboard_selected(model)) {
|
if(byte_input_keyboard_selected(model)) {
|
||||||
@ -486,14 +552,17 @@ static void byte_input_handle_right(ByteInputModel* model) {
|
|||||||
model->selected_column = 0;
|
model->selected_column = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte_input_inc_selected_byte(model);
|
if(model->selected_row != -2) {
|
||||||
|
byte_input_inc_selected_byte(model);
|
||||||
|
} else {
|
||||||
|
byte_input_inc_selected_byte_mini(model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Handle OK button
|
||||||
* @brief Handle OK button
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_handle_ok(ByteInputModel* model) {
|
static void byte_input_handle_ok(ByteInputModel* model) {
|
||||||
if(byte_input_keyboard_selected(model)) {
|
if(byte_input_keyboard_selected(model)) {
|
||||||
@ -514,16 +583,17 @@ static void byte_input_handle_ok(ByteInputModel* model) {
|
|||||||
}
|
}
|
||||||
byte_input_call_changed_callback(model);
|
byte_input_call_changed_callback(model);
|
||||||
}
|
}
|
||||||
|
} else if(model->selected_row == -2) {
|
||||||
|
byte_input_call_input_callback(model);
|
||||||
} else {
|
} else {
|
||||||
byte_input_transition_from_keyboard(model);
|
byte_input_transition_from_keyboard(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Draw callback
|
||||||
* @brief Draw callback
|
*
|
||||||
*
|
* @param canvas The canvas
|
||||||
* @param canvas
|
* @param _model The model
|
||||||
* @param _model
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_view_draw_callback(Canvas* canvas, void* _model) {
|
static void byte_input_view_draw_callback(Canvas* canvas, void* _model) {
|
||||||
ByteInputModel* model = _model;
|
ByteInputModel* model = _model;
|
||||||
@ -541,80 +611,89 @@ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
byte_input_draw_input(canvas, model);
|
byte_input_draw_input(canvas, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint8_t row = 0; row < keyboard_row_count; row++) {
|
if(model->selected_row == -2) {
|
||||||
const uint8_t column_count = byte_input_get_row_size(row);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
const ByteInputKey* keys = byte_input_get_row(row);
|
canvas_draw_icon(canvas, 3, 52, &I_Pin_back_arrow_10x8);
|
||||||
|
canvas_draw_str_aligned(canvas, 16, 60, AlignLeft, AlignBottom, "back to keyboard");
|
||||||
|
} else {
|
||||||
|
// Draw keyboard
|
||||||
|
for(uint8_t row = 0; row < keyboard_row_count; row++) {
|
||||||
|
const uint8_t column_count = byte_input_get_row_size(row);
|
||||||
|
const ByteInputKey* keys = byte_input_get_row(row);
|
||||||
|
|
||||||
for(size_t column = 0; column < column_count; column++) {
|
for(size_t column = 0; column < column_count; column++) {
|
||||||
if(keys[column].value == enter_symbol) {
|
if(keys[column].value == enter_symbol) {
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
if(model->selected_row == row && model->selected_column == column) {
|
|
||||||
canvas_draw_icon(
|
|
||||||
canvas,
|
|
||||||
keyboard_origin_x + keys[column].x,
|
|
||||||
keyboard_origin_y + keys[column].y,
|
|
||||||
&I_KeySaveSelected_24x11);
|
|
||||||
} else {
|
|
||||||
canvas_draw_icon(
|
|
||||||
canvas,
|
|
||||||
keyboard_origin_x + keys[column].x,
|
|
||||||
keyboard_origin_y + keys[column].y,
|
|
||||||
&I_KeySave_24x11);
|
|
||||||
}
|
|
||||||
} else if(keys[column].value == backspace_symbol) {
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
if(model->selected_row == row && model->selected_column == column) {
|
|
||||||
canvas_draw_icon(
|
|
||||||
canvas,
|
|
||||||
keyboard_origin_x + keys[column].x,
|
|
||||||
keyboard_origin_y + keys[column].y,
|
|
||||||
&I_KeyBackspaceSelected_16x9);
|
|
||||||
} else {
|
|
||||||
canvas_draw_icon(
|
|
||||||
canvas,
|
|
||||||
keyboard_origin_x + keys[column].x,
|
|
||||||
keyboard_origin_y + keys[column].y,
|
|
||||||
&I_KeyBackspace_16x9);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(model->selected_row == row && model->selected_column == column) {
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_draw_box(
|
if(model->selected_row == row && model->selected_column == column) {
|
||||||
canvas,
|
canvas_draw_icon(
|
||||||
keyboard_origin_x + keys[column].x - 3,
|
canvas,
|
||||||
keyboard_origin_y + keys[column].y - 10,
|
keyboard_origin_x + keys[column].x,
|
||||||
11,
|
keyboard_origin_y + keys[column].y,
|
||||||
13);
|
&I_KeySaveSelected_24x11);
|
||||||
canvas_set_color(canvas, ColorWhite);
|
} else {
|
||||||
} else if(model->selected_row == -1 && row == 0 && model->selected_column == column) {
|
canvas_draw_icon(
|
||||||
|
canvas,
|
||||||
|
keyboard_origin_x + keys[column].x,
|
||||||
|
keyboard_origin_y + keys[column].y,
|
||||||
|
&I_KeySave_24x11);
|
||||||
|
}
|
||||||
|
} else if(keys[column].value == backspace_symbol) {
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_draw_frame(
|
if(model->selected_row == row && model->selected_column == column) {
|
||||||
canvas,
|
canvas_draw_icon(
|
||||||
keyboard_origin_x + keys[column].x - 3,
|
canvas,
|
||||||
keyboard_origin_y + keys[column].y - 10,
|
keyboard_origin_x + keys[column].x,
|
||||||
11,
|
keyboard_origin_y + keys[column].y,
|
||||||
13);
|
&I_KeyBackspaceSelected_16x9);
|
||||||
|
} else {
|
||||||
|
canvas_draw_icon(
|
||||||
|
canvas,
|
||||||
|
keyboard_origin_x + keys[column].x,
|
||||||
|
keyboard_origin_y + keys[column].y,
|
||||||
|
&I_KeyBackspace_16x9);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
canvas_set_color(canvas, ColorBlack);
|
if(model->selected_row == row && model->selected_column == column) {
|
||||||
}
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
canvas_draw_box(
|
||||||
|
canvas,
|
||||||
|
keyboard_origin_x + keys[column].x - 3,
|
||||||
|
keyboard_origin_y + keys[column].y - 10,
|
||||||
|
11,
|
||||||
|
13);
|
||||||
|
canvas_set_color(canvas, ColorWhite);
|
||||||
|
} else if(
|
||||||
|
model->selected_row == -1 && row == 0 &&
|
||||||
|
model->selected_column == column) {
|
||||||
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
canvas_draw_frame(
|
||||||
|
canvas,
|
||||||
|
keyboard_origin_x + keys[column].x - 3,
|
||||||
|
keyboard_origin_y + keys[column].y - 10,
|
||||||
|
11,
|
||||||
|
13);
|
||||||
|
} else {
|
||||||
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
}
|
||||||
|
|
||||||
canvas_draw_glyph(
|
canvas_draw_glyph(
|
||||||
canvas,
|
canvas,
|
||||||
keyboard_origin_x + keys[column].x,
|
keyboard_origin_x + keys[column].x,
|
||||||
keyboard_origin_y + keys[column].y,
|
keyboard_origin_y + keys[column].y,
|
||||||
keys[column].value);
|
keys[column].value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Input callback
|
||||||
* @brief Input callback
|
*
|
||||||
*
|
* @param event The event
|
||||||
* @param event
|
* @param context The context
|
||||||
* @param context
|
*
|
||||||
* @return true
|
* @return true
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
static bool byte_input_view_input_callback(InputEvent* event, void* context) {
|
static bool byte_input_view_input_callback(InputEvent* event, void* context) {
|
||||||
ByteInput* byte_input = context;
|
ByteInput* byte_input = context;
|
||||||
@ -656,6 +735,20 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(event->type == InputTypeShort && event->key == InputKeyBack) {
|
||||||
|
// Back to keyboard
|
||||||
|
with_view_model(
|
||||||
|
byte_input->view,
|
||||||
|
ByteInputModel * model,
|
||||||
|
{
|
||||||
|
if(model->selected_row == -2) {
|
||||||
|
model->selected_row += 1;
|
||||||
|
consumed = true;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
if((event->type == InputTypeLong || event->type == InputTypeRepeat) &&
|
if((event->type == InputTypeLong || event->type == InputTypeRepeat) &&
|
||||||
event->key == InputKeyBack) {
|
event->key == InputKeyBack) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
@ -669,10 +762,9 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) {
|
|||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Reset all input-related data in model
|
||||||
* @brief Reset all input-related data in model
|
*
|
||||||
*
|
* @param model The model
|
||||||
* @param model ByteInputModel
|
|
||||||
*/
|
*/
|
||||||
static void byte_input_reset_model_input_data(ByteInputModel* model) {
|
static void byte_input_reset_model_input_data(ByteInputModel* model) {
|
||||||
model->bytes = NULL;
|
model->bytes = NULL;
|
||||||
@ -684,11 +776,6 @@ static void byte_input_reset_model_input_data(ByteInputModel* model) {
|
|||||||
model->first_visible_byte = 0;
|
model->first_visible_byte = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Allocate and initialize byte input. This byte input is used to enter bytes.
|
|
||||||
*
|
|
||||||
* @return ByteInput instance pointer
|
|
||||||
*/
|
|
||||||
ByteInput* byte_input_alloc() {
|
ByteInput* byte_input_alloc() {
|
||||||
ByteInput* byte_input = malloc(sizeof(ByteInput));
|
ByteInput* byte_input = malloc(sizeof(ByteInput));
|
||||||
byte_input->view = view_alloc();
|
byte_input->view = view_alloc();
|
||||||
@ -712,38 +799,17 @@ ByteInput* byte_input_alloc() {
|
|||||||
return byte_input;
|
return byte_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize and free byte input
|
|
||||||
*
|
|
||||||
* @param byte_input Byte input instance
|
|
||||||
*/
|
|
||||||
void byte_input_free(ByteInput* byte_input) {
|
void byte_input_free(ByteInput* byte_input) {
|
||||||
furi_assert(byte_input);
|
furi_assert(byte_input);
|
||||||
view_free(byte_input->view);
|
view_free(byte_input->view);
|
||||||
free(byte_input);
|
free(byte_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get byte input view
|
|
||||||
*
|
|
||||||
* @param byte_input byte input instance
|
|
||||||
* @return View instance that can be used for embedding
|
|
||||||
*/
|
|
||||||
View* byte_input_get_view(ByteInput* byte_input) {
|
View* byte_input_get_view(ByteInput* byte_input) {
|
||||||
furi_assert(byte_input);
|
furi_assert(byte_input);
|
||||||
return byte_input->view;
|
return byte_input->view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize and free byte input
|
|
||||||
*
|
|
||||||
* @param byte_input byte input instance
|
|
||||||
* @param input_callback input callback fn
|
|
||||||
* @param changed_callback changed callback fn
|
|
||||||
* @param callback_context callback context
|
|
||||||
* @param bytes buffer to use
|
|
||||||
* @param bytes_count buffer length
|
|
||||||
*/
|
|
||||||
void byte_input_set_result_callback(
|
void byte_input_set_result_callback(
|
||||||
ByteInput* byte_input,
|
ByteInput* byte_input,
|
||||||
ByteInputCallback input_callback,
|
ByteInputCallback input_callback,
|
||||||
@ -765,12 +831,6 @@ void byte_input_set_result_callback(
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set byte input header text
|
|
||||||
*
|
|
||||||
* @param byte_input byte input instance
|
|
||||||
* @param text text to be shown
|
|
||||||
*/
|
|
||||||
void byte_input_set_header_text(ByteInput* byte_input, const char* text) {
|
void byte_input_set_header_text(ByteInput* byte_input, const char* text) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
byte_input->view, ByteInputModel * model, { model->header = text; }, true);
|
byte_input->view, ByteInputModel * model, { model->header = text; }, true);
|
||||||
|
|||||||
@ -6,7 +6,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RECORD_LOADER "loader"
|
#define RECORD_LOADER "loader"
|
||||||
#define LOADER_APPLICATIONS_NAME "Applications"
|
#define LOADER_APPLICATIONS_NAME "Apps"
|
||||||
|
|
||||||
typedef struct Loader Loader;
|
typedef struct Loader Loader;
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <gui/view_holder.h>
|
#include <gui/view_holder.h>
|
||||||
#include <gui/modules/loading.h>
|
#include <gui/modules/loading.h>
|
||||||
|
#include <dolphin/dolphin.h>
|
||||||
|
|
||||||
#define TAG "LoaderApplications"
|
#define TAG "LoaderApplications"
|
||||||
|
|
||||||
@ -119,6 +120,8 @@ static void loader_pubsub_callback(const void* message, void* context) {
|
|||||||
static void loader_applications_start_app(LoaderApplicationsApp* app) {
|
static void loader_applications_start_app(LoaderApplicationsApp* app) {
|
||||||
const char* name = furi_string_get_cstr(app->fap_path);
|
const char* name = furi_string_get_cstr(app->fap_path);
|
||||||
|
|
||||||
|
dolphin_deed(DolphinDeedPluginStart);
|
||||||
|
|
||||||
// load app
|
// load app
|
||||||
FuriThreadId thread_id = furi_thread_get_current_id();
|
FuriThreadId thread_id = furi_thread_get_current_id();
|
||||||
FuriPubSubSubscription* subscription =
|
FuriPubSubSubscription* subscription =
|
||||||
|
|||||||
@ -14,7 +14,7 @@ static void loader_cli_print_usage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void loader_cli_list() {
|
static void loader_cli_list() {
|
||||||
printf("Applications:\r\n");
|
printf("Apps:\r\n");
|
||||||
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||||
printf("\t%s\r\n", FLIPPER_APPS[i].name);
|
printf("\t%s\r\n", FLIPPER_APPS[i].name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#include <input/input.h>
|
#include <input/input.h>
|
||||||
#include <gui/gui_i.h>
|
#include <gui/gui_i.h>
|
||||||
#include <u8g2_glue.h>
|
#include <u8g2_glue.h>
|
||||||
|
#include <lib/toolbox/float_tools.h>
|
||||||
#include "notification.h"
|
#include "notification.h"
|
||||||
#include "notification_messages.h"
|
#include "notification_messages.h"
|
||||||
#include "notification_app.h"
|
#include "notification_app.h"
|
||||||
@ -104,7 +104,10 @@ static void notification_reset_notification_led_layer(NotificationLedLayer* laye
|
|||||||
furi_hal_light_set(layer->light, layer->value[LayerInternal]);
|
furi_hal_light_set(layer->light, layer->value[LayerInternal]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) {
|
static void notification_reset_notification_layer(
|
||||||
|
NotificationApp* app,
|
||||||
|
uint8_t reset_mask,
|
||||||
|
float display_brightness_set) {
|
||||||
if(reset_mask & reset_blink_mask) {
|
if(reset_mask & reset_blink_mask) {
|
||||||
furi_hal_light_blink_stop();
|
furi_hal_light_blink_stop();
|
||||||
}
|
}
|
||||||
@ -124,6 +127,9 @@ static void notification_reset_notification_layer(NotificationApp* app, uint8_t
|
|||||||
notification_sound_off();
|
notification_sound_off();
|
||||||
}
|
}
|
||||||
if(reset_mask & reset_display_mask) {
|
if(reset_mask & reset_display_mask) {
|
||||||
|
if(!float_is_equal(display_brightness_set, app->settings.display_brightness)) {
|
||||||
|
furi_hal_light_set(LightBacklight, app->settings.display_brightness * 0xFF);
|
||||||
|
}
|
||||||
furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app));
|
furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,13 +218,14 @@ static void notification_process_notification_message(
|
|||||||
notification_apply_notification_led_layer(
|
notification_apply_notification_led_layer(
|
||||||
&app->display,
|
&app->display,
|
||||||
notification_message->data.led.value * display_brightness_setting);
|
notification_message->data.led.value * display_brightness_setting);
|
||||||
|
reset_mask |= reset_display_mask;
|
||||||
} else {
|
} else {
|
||||||
|
reset_mask &= ~reset_display_mask;
|
||||||
notification_reset_notification_led_layer(&app->display);
|
notification_reset_notification_led_layer(&app->display);
|
||||||
if(furi_timer_is_running(app->display_timer)) {
|
if(furi_timer_is_running(app->display_timer)) {
|
||||||
furi_timer_stop(app->display_timer);
|
furi_timer_stop(app->display_timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset_mask |= reset_display_mask;
|
|
||||||
break;
|
break;
|
||||||
case NotificationMessageTypeLedDisplayBacklightEnforceOn:
|
case NotificationMessageTypeLedDisplayBacklightEnforceOn:
|
||||||
furi_assert(app->display_led_lock < UINT8_MAX);
|
furi_assert(app->display_led_lock < UINT8_MAX);
|
||||||
@ -370,7 +377,7 @@ static void notification_process_notification_message(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(reset_notifications) {
|
if(reset_notifications) {
|
||||||
notification_reset_notification_layer(app, reset_mask);
|
notification_reset_notification_layer(app, reset_mask, display_brightness_setting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -87,6 +87,7 @@ static DialogMessageButton icon2_screen(DialogsApp* dialogs, DialogMessage* mess
|
|||||||
message, furi_hal_version_get_mic_id(), 63, 27, AlignLeft, AlignCenter);
|
message, furi_hal_version_get_mic_id(), 63, 27, AlignLeft, AlignCenter);
|
||||||
result = dialog_message_show(dialogs, message);
|
result = dialog_message_show(dialogs, message);
|
||||||
dialog_message_set_icon(message, NULL, 0, 0);
|
dialog_message_set_icon(message, NULL, 0, 0);
|
||||||
|
dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -172,8 +173,6 @@ const AboutDialogScreen about_screens[] = {
|
|||||||
hw_version_screen,
|
hw_version_screen,
|
||||||
fw_version_screen};
|
fw_version_screen};
|
||||||
|
|
||||||
const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen);
|
|
||||||
|
|
||||||
int32_t about_settings_app(void* p) {
|
int32_t about_settings_app(void* p) {
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||||
@ -194,7 +193,7 @@ int32_t about_settings_app(void* p) {
|
|||||||
view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index);
|
view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(screen_index >= about_screens_count - 1) {
|
if(screen_index >= COUNT_OF(about_screens) - 1) {
|
||||||
dialog_message_set_buttons(message, "Back", NULL, NULL);
|
dialog_message_set_buttons(message, "Back", NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
dialog_message_set_buttons(message, "Back", NULL, "Next");
|
dialog_message_set_buttons(message, "Back", NULL, "Next");
|
||||||
@ -209,7 +208,7 @@ int32_t about_settings_app(void* p) {
|
|||||||
screen_index--;
|
screen_index--;
|
||||||
}
|
}
|
||||||
} else if(screen_result == DialogMessageButtonRight) {
|
} else if(screen_result == DialogMessageButtonRight) {
|
||||||
if(screen_index < about_screens_count) {
|
if(screen_index < COUNT_OF(about_screens) - 1) {
|
||||||
screen_index++;
|
screen_index++;
|
||||||
}
|
}
|
||||||
} else if(screen_result == DialogMessageButtonBack) {
|
} else if(screen_result == DialogMessageButtonBack) {
|
||||||
|
|||||||
@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
#define APPS_COUNT (FLIPPER_APPS_COUNT + FLIPPER_EXTERNAL_APPS_COUNT)
|
#define APPS_COUNT (FLIPPER_APPS_COUNT + FLIPPER_EXTERNAL_APPS_COUNT)
|
||||||
|
|
||||||
#define EXTERNAL_BROWSER_NAME ("Applications")
|
#define EXTERNAL_BROWSER_NAME ("Apps")
|
||||||
#define EXTERNAL_BROWSER_INDEX (APPS_COUNT + 1)
|
#define EXTERNAL_BROWSER_INDEX (APPS_COUNT + 1)
|
||||||
|
|
||||||
#define EXTERNAL_APPLICATION_NAME ("[External Application]")
|
#define EXTERNAL_APPLICATION_NAME ("[Select App]")
|
||||||
#define EXTERNAL_APPLICATION_INDEX (APPS_COUNT + 2)
|
#define EXTERNAL_APPLICATION_INDEX (APPS_COUNT + 2)
|
||||||
|
|
||||||
#define PRESELECTED_SPECIAL 0xffffffff
|
#define PRESELECTED_SPECIAL 0xffffffff
|
||||||
|
|||||||
BIN
assets/resources/badusb/assets/layouts/fr-CA.kl
Normal file
BIN
assets/resources/badusb/assets/layouts/fr-CA.kl
Normal file
Binary file not shown.
@ -581,3 +581,40 @@ type: raw
|
|||||||
frequency: 38000
|
frequency: 38000
|
||||||
duty_cycle: 0.330000
|
duty_cycle: 0.330000
|
||||||
data: 3204 9889 537 1587 491 529 512 544 489 545 489 1573 510 530 511 543 491 552 490 538 511 543 491 543 491 532 509 543 491 1587 489 537 512 543 491 1577 490 543 491 543 491 544 489 543 491 1586 489 544 490 1587 489 539 510 543 491 543 491 1586 490
|
data: 3204 9889 537 1587 491 529 512 544 489 545 489 1573 510 530 511 543 491 552 490 538 511 543 491 543 491 532 509 543 491 1587 489 537 512 543 491 1577 490 543 491 543 491 544 489 543 491 1586 489 544 490 1587 489 539 510 543 491 543 491 1586 490
|
||||||
|
#
|
||||||
|
# Model: Daikin FTXC35DV1B
|
||||||
|
name: Off
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 530 315 532 314 532 314 532 314 532 314 506 340 561 24780 3568 1647 507 1213 535 313 534 340 506 340 506 1212 507 339 507 339 506 339 506 339 506 1214 505 341 504 1215 505 1216 504 343 503 1217 503 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1219 501 345 501 344 502 345 501 1219 501 1219 501 345 501 344 502 344 502 345 501 344 502 345 501 344 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 501 1219 501 34807 3563 1652 502 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1219 501 344 502 1218 502 1219 501 344 502 1219 501 1218 502 1219 501 1219 501 1219 501 345 501 344 502 1219 501 345 501 344 502 345 501 344 502 344 502 345 501 345 501 345 501 344 502 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1219 501 345 501 345 501 1219 501 1219 501 345 501 1219 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1220 500 346 500 345 501 346 500 346 500 34806 3564 1652 502 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1219 501 1218 502 344 502 345 501 1219 501 345 501 344 502 345 501 344 502 344 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 346 500 345 501 345 501 345 501 345 501 346 500 346 500 346 500 346 500 346 500 1220 499 346 500 1220 499 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 346 500 1221 499 1221 499 1221 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 1245 475 1222 498 1245 475 371 475 348 498 348 498 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 372 474 372 474 372 474 371 475 371 475 1246 474 371 475 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 371 475 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1246 474 1246 473 372 474 372 474 1246 474 372 474
|
||||||
|
#
|
||||||
|
name: Dh
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 536 339 507 311 535 312 534 312 534 312 534 339 507 24807 3710 1507 594 1156 563 305 543 304 542 304 570 1126 592 304 515 304 542 304 542 304 542 1155 564 304 541 1158 505 1215 505 342 504 1217 503 1217 503 1218 502 1218 502 1218 502 344 502 343 503 1218 502 343 503 343 503 344 502 344 502 344 502 344 502 344 502 343 503 343 503 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 1218 502 1218 501 344 502 1218 502 344 502 1218 502 1218 502 34800 3564 1651 503 1217 503 343 503 344 502 343 503 1217 503 343 503 343 503 344 502 344 502 1218 502 344 502 1217 503 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 344 502 1218 502 1218 502 344 502 1218 502 1219 501 1219 501 345 501 344 502 344 502 344 502 344 502 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 34805 3565 1650 503 1216 503 343 503 343 503 344 502 1217 503 343 503 344 502 343 503 343 503 1217 503 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 1218 502 344 502 1218 501 344 502 344 502 344 502 345 501 344 502 345 501 344 502 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 346 500 345 501 345 501 346 500 370 476 346 500 346 500 346 500 370 476 346 500 346 500 346 500 346 500 1221 499 1244 476 1244 476 370 476 346 500 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1244 476 1244 476 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1244 476 370 476 1245 475 370 476 371 475 370 476 1245 475 1245 475 371 475 371 475 370 476 370 476 370 476 370 476 370 476 371 475 370 476 371 475 371 475 371 475 371 475 370 476 371 475 371 475 371 475 1245 475 1245 475 1245 475 371 475 371 475 1245 475 371 475
|
||||||
|
#
|
||||||
|
name: Cool_hi
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 507 340 559 306 487 341 530 315 531 313 561 305 541 24776 3569 1646 508 1212 537 340 506 340 506 340 506 1213 507 339 507 339 506 339 506 340 505 1214 505 341 504 1215 504 1216 503 343 503 1217 502 1218 502 1218 502 1218 502 1218 501 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1219 501 1218 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 501 1219 501 34800 3563 1652 502 1217 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 501 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 345 501 345 501 344 502 345 501 344 502 345 501 345 501 345 501 344 502 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 1219 501 345 501 345 501 1219 501 1219 501 345 501 1219 500 1219 500 1219 500 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1220 500 346 500 346 500 346 500 346 500 34808 3564 1652 503 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 345 501 344 502 1218 502 345 501 1218 502 1219 501 344 502 1219 501 1219 501 1219 501 1219 501 1219 501 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 500 345 501 345 501 1219 500 1219 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1219 501 346 500 346 500 345 501 345 501 346 500 346 500 346 500 345 501 346 500 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 346 500 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 347 499 346 500 1221 499 1245 475 1221 499 347 499 347 499 347 499 348 498 347 499 348 498 348 498 371 475 348 498 1222 498 1245 475 1245 475 348 498 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 372 474 372 474 372 474 371 475 1245 474 372 474 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 372 474 372 474 372 474 1247 473 1247 473
|
||||||
|
#
|
||||||
|
name: Cool_lo
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 533 311 535 312 534 312 534 313 533 310 536 312 534 24804 3705 1509 593 1129 590 305 542 305 542 305 569 1127 590 304 514 305 541 304 542 305 541 1155 564 305 540 1157 561 1159 504 341 504 1217 503 1217 503 1217 503 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 345 501 1218 502 1218 502 1218 502 344 502 1219 501 345 501 1219 501 1219 501 34806 3565 1650 503 1217 502 343 503 343 503 343 503 1217 503 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1219 501 344 502 1218 502 344 502 1219 501 1218 501 345 501 1218 501 1219 501 1218 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 34805 3565 1651 503 1217 502 343 503 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 1218 502 1219 501 1218 502 345 501 344 502 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 346 500 346 500 345 501 345 501 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 1221 499 1221 498 346 500 346 500 370 476 346 500 347 499 347 499 370 476 370 476 370 476 1244 476 1244 476 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 371 475 370 476 370 476 370 476 371 475 370 476 370 476 370 476 370 476 1244 476 371 475 1245 475 370 476 371 475 371 475 1245 475 1245 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 476 371 475 1245 475 1245 475 371 475 371 475 1246 474 1245 475
|
||||||
|
#
|
||||||
|
name: Heat_lo
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 535 313 533 311 535 311 535 312 534 312 534 313 533 24805 3711 1506 592 1129 592 305 543 305 540 305 569 1126 592 304 514 304 542 304 541 304 485 1213 507 340 506 1214 506 1215 505 342 504 1217 503 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 503 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 503 344 502 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 502 1219 502 34818 3566 1651 503 1217 503 343 503 344 502 344 502 1218 502 344 502 344 502 344 502 344 503 1218 502 344 502 1218 503 1218 502 344 502 1218 502 1218 503 1218 503 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 345 501 344 502 344 502 1219 501 345 501 345 502 1219 501 345 501 1219 502 1219 502 1219 502 344 502 1219 501 1219 502 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 345 501 1219 501 345 501 345 501 345 501 34812 3566 1651 503 1217 503 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 503 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1219 501 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 345 501 344 502 345 501 345 501 1219 502 345 501 345 501 1219 502 345 501 345 501 1219 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 502 345 501 345 501 345 501 346 500 345 501 345 501 345 501 345 501 345 501 1220 500 346 500 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 346 500 347 499 347 499 370 476 1244 476 1221 499 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1245 475 1245 476 1245 475 371 475 370 476 370 476 371 475 371 475 370 476 370 476 371 475 371 476 370 476 370 476 371 475 371 475 371 475 371 475 371 475 1245 475 371 475 1245 475 371 475 371 475 371 475 1245 475 1245 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 476 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 1245 475 1245 475 1245 475 371 475 1245 475 1246 474
|
||||||
|
#
|
||||||
|
name: Heat_hi
|
||||||
|
type: raw
|
||||||
|
frequency: 38000
|
||||||
|
duty_cycle: 0.330000
|
||||||
|
data: 535 314 532 314 533 313 533 312 534 313 533 312 508 24840 3569 1647 508 1213 536 342 505 342 504 341 505 1214 506 340 506 340 506 340 505 340 506 1214 506 341 504 1216 504 1217 503 343 503 1218 502 1219 501 1219 502 1219 502 1219 502 345 502 344 502 1219 502 345 501 345 502 345 502 345 501 345 501 345 501 345 501 345 501 345 502 345 501 1219 502 345 501 1219 501 345 502 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1220 500 1219 501 1220 500 345 501 1220 500 345 501 1220 501 1220 500 34815 3564 1653 502 1218 502 344 502 345 501 344 502 1219 501 345 501 345 501 345 501 345 501 1219 502 345 501 1219 502 1220 501 345 502 1219 501 1219 502 1219 501 1219 502 1219 502 345 501 345 501 1220 501 345 502 345 501 345 501 345 501 345 501 345 501 345 502 345 501 345 502 345 501 345 501 1220 501 345 501 345 501 345 501 345 501 1220 500 345 501 346 501 1220 500 1220 501 345 501 345 501 346 500 1220 500 1220 500 1220 500 1220 500 346 500 346 500 346 500 345 501 346 500 345 501 1220 500 346 500 1220 500 1220 500 1220 500 346 500 346 500 346 500 34816 3565 1653 502 1219 501 344 502 345 501 345 501 1219 502 345 501 345 502 345 501 345 501 1219 501 345 501 1219 502 1219 501 345 501 1219 502 1219 501 1219 501 1219 501 1219 501 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1220 501 346 501 345 501 1220 501 346 500 346 500 1220 500 346 500 345 501 346 500 1220 500 1220 500 1220 501 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 346 500 1220 500 347 499 346 500 346 500 346 500 347 499 347 499 346 500 346 500 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 1222 498 1222 499 1222 498 347 499 348 498 348 498 347 499 371 475 348 498 348 498 348 498 371 475 1222 498 1246 474 1246 474 372 475 371 475 372 474 372 474 348 498 371 475 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1247 473 372 474 1246 474 1246 474 1246 474
|
||||||
|
|||||||
@ -328,3 +328,52 @@ type: parsed
|
|||||||
protocol: NECext
|
protocol: NECext
|
||||||
address: 30 FC 00 00
|
address: 30 FC 00 00
|
||||||
command: 0C F3 00 00
|
command: 0C F3 00 00
|
||||||
|
#
|
||||||
|
# Model: Panasonic SA-PM193
|
||||||
|
name: Power
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: AC 02 20 00
|
||||||
|
command: D1 03 00 00
|
||||||
|
# CD play/pause, tape play also exists but probably less commonly used
|
||||||
|
name: Play
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: AA 02 20 00
|
||||||
|
command: A0 00 00 00
|
||||||
|
# same as above
|
||||||
|
name: Pause
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: AA 02 20 00
|
||||||
|
command: A0 00 00 00
|
||||||
|
#
|
||||||
|
name: Vol_up
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: A0 02 20 00
|
||||||
|
command: 00 02 00 00
|
||||||
|
#
|
||||||
|
name: Vol_dn
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: A0 02 20 00
|
||||||
|
command: 10 02 00 00
|
||||||
|
#
|
||||||
|
name: Next
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: AC 02 20 01
|
||||||
|
command: A1 00 00 00
|
||||||
|
#
|
||||||
|
name: Prev
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: AC 02 20 01
|
||||||
|
command: 91 00 00 00
|
||||||
|
#
|
||||||
|
name: Mute
|
||||||
|
type: parsed
|
||||||
|
protocol: Kaseikyo
|
||||||
|
address: A0 02 20 00
|
||||||
|
command: 20 03 00 00
|
||||||
|
|||||||
@ -1,56 +1,57 @@
|
|||||||
Filetype: Flipper SubGhz Keystore File
|
Filetype: Flipper SubGhz Keystore File
|
||||||
Version: 0
|
Version: 0
|
||||||
Encryption: 1
|
Encryption: 1
|
||||||
IV: 41 84 34 43 84 1D 43 04 45 44 34 38 41 24 3E 74
|
IV: 23 17 32 54 92 3A 28 13 12 DE 8B A7 24 71 25 74
|
||||||
8C5AEF725F0620DB3952B40BB8E76A815BCEE1D1B92F7E8E8E63D1894F1C7FD0
|
B8ACA082EA4B34E8B217A6FE63F3545D160AB7F4833C87E8743BAA7002ACC123
|
||||||
1DFF1D6A322D6B3D8AD7C594A02462AADE723D417B9233585526982F08187DAA
|
E779135FE66629CAC4661B1C3D5C9857C9417CAF216241933FF6CE60A74D53C0
|
||||||
0A9184F15D4A5589DDDA6422063BACD58580661CFE60EE600D87F73F0CB5013E
|
15340C049A444C79ED489619A31E2AFDCFF6E4864CC4D9B1DA8E98D7EAB9C8D5
|
||||||
6E56802DAA049C3DFDEDC90432A0E694A172C369EBECD136F4C911B979AA098D
|
8E696E85837B3BA8D6D380E1F36E445D630CF0B7B18A45930A08F832EE634A02
|
||||||
A659716B51053604059F7FC3651D6A153F5EAB1852F95B20C44C41A7889A0DE91A078B63E3C311280C4315F0A3C8BA1F
|
C85341BE669E509E902FEFCA7D025A20DC80D4F14FE1C3542B1DC3A5C7393A36F901A63C3BC074B058897B12F0F5F0D6
|
||||||
A315170EDC51627157725D9A96490DB75EBF8232957FBA313C03B2BA2884EA85
|
2834E5D7726670A03ED6C8B27B5863EEE2FD3668795251AB65B9E4FF76ADEC3E
|
||||||
DEAB3C2C2E2DC76FE45AEBAC7EBFB478CECCD970A63B8DE2024FBFDCCBD1B26E
|
8E71AF7660BCFC545E92674D74F98A35FCF1B54AB5BACCEE182B7F8EDB3FA356
|
||||||
7BBFC36CBA77468B4624C6B685610877D53985C985DAD8EFE47527EB7C7260CD
|
C20442D506332D1A410AF3187C29BE01729C282A69B85CF8D92D70FAE3407BA8
|
||||||
879EE18B314ED4F3F548B41176099176FB97F4F1A062481C935B2DDFBCE2FE4D
|
00BC449D006566A6549A86F52B98410871B0C14D60C181BFC017446B192C934A
|
||||||
493372D7D47A96A66305DFDC8A915EB651620881AE1D603B7E9605E004C04CA9
|
8A6A28DAF1F61867B1209AB9105986A7383ECE72A40F8D93F1D0066251800A3A
|
||||||
F80AAA4C447F8E8C0B039DDAECF9126119C32FF164118780BE268E326A8CBF8010DE2EBF94033CEAC39815D6A8958CF4
|
4A6AFDFA6130A50180358B111145D7914C720E04D69EE5459C049FCD64249153315F86A5A9F75AEE5CB726847BA64F2A
|
||||||
41C1393A039E665F6A53A5E5D1C105008BD14D9755751545A667860C39B2E39AA47306E76E2BA7DDDAA2A286FDB58D23
|
91F838BC515C8CDD32C5803679B81A24FD5CF0C3A4AEA2C07342ACA1020E05F3B393A410B33847A8C48141D923202CF3
|
||||||
34853A4CDE42CB80045E641AB4800C86C1CF6907EAAFA399156CCC727A008584
|
7C4DEBC03295291EC5B2EBB002670D14E7C972F32DB2B3CD4E61B2BE846345D9
|
||||||
D0783A34BD6A36D31BFF5F70FA1116CAE48EF02716D80481AE406DABB3C3400E
|
8FFEB948DA3D1A7FCF620F043B1D35354F83861F22B6D693F2A7119A2E287D01
|
||||||
0BB3582605434CF2A5D74A27773B88DA331B6033C444837E9F7A155897258B03
|
309C66AF38E6447CB33FB0967C9365CA36314DBF74695F63CF9E558A4FF5193B
|
||||||
E4E71F3EB290B9436FFF0FDADA468BE37D964E89BE8D9971A14776F821822769
|
411D32EC6ADED3360DE9E9A0962F97DF2B80A09F2A2AC8D4DB6DB09FAD6EA217
|
||||||
744AA59D129C892120B5DAB81C8A3D573B0AD80EF0708C1B9ECF13DA60CECA07DC0591A08611DB4D3A8B7C70994D5DEF
|
A5E5550BD59425003F9166237CD4BB6A323885D7916F71F3B2795B8A4C7125ACC1237BBF0840F0E999BD2EC14327654F
|
||||||
716F9F8D5D2C697BC4183EFCC97E52D08ECA07B613A0F389C801F65803DFF4A4
|
4370A828AFED684B96E8EDAB670C46D2D525FCB7E469B63CD1228C902C3ACF4E
|
||||||
560262DA8489D2C18C8D97E314DC663403AFE4DE9DCB6D453087D2BFBD36532D
|
88E3853F58129C4D834B18E4D01785591094301148D802A3A21B63521DDDA325
|
||||||
9E31F7152C50B6940EE3E3894C98F75702C7897F702B48E5C9B54B6E25083641AD2E521267505066C7E5BAB7F6CF1433
|
D5365BF55DFE7107909684F4ECCE052E617F91FAF08CE5254721A30BEF87F368F329C46439BD1EA2819DC416B2CEF247
|
||||||
6630EDA18A6E58BD395792CCC656DD10CD9C5DD2B1949FE677122FA39A53C724E79C0D0752A3A39A03407BBA2282185E
|
BDAB9FFD3A82ECE05E8CA00F11954CDB1C124B558A5D369DFE16D32C3AEF08B2013945CC69212F170F17F62A55D35928
|
||||||
00D15A06F5DD82A4B926B78809CC4D129AAFA9A92B0A81568F255D15697FE0FD
|
8E448AA1D39C894F306FE65B0D0DD733717EF81758FFA908AF7583BFD00108E5
|
||||||
29FF9A4F5346ABEE8FEDE034988F87FCD29EA747735898F1E7207EF74FAB71A8
|
019A1B0AA3492427DF3DB817B438D0302B0B8C77807D19EE45EAC7F697B2EB85
|
||||||
C0E8EB6AE6F77EE38DF2AB1B7742E34ED5236F3D8E964845E66762A4675AA21F
|
C678A3F9DA726FE1688F86BB063EA017EDB5389E0F185484D9F5DFD4EBEE0579
|
||||||
00FC4C459DC4CE92B62D0AC2546F9FBBE0893F84D2AF0A20ED462A5EAE63DE3B
|
760F77AB9BD99593AC855E4AE00FBAFBB34FA2BFF504BD5CC9557658E850C6D0
|
||||||
E92EF482A40CEEFC8339BBB713BBC452A266A09B2645EDEB12716544B2DB9B09
|
4F3E77342E9A655D4EC167E2B0428833FEE31CF603FA1CE3D1BCD619D5C9D511
|
||||||
D7D9C5C757831BCE2FF1DB25A080D77769FB36A1F3F48F4361418A0A45609280
|
2233EFBEDD4A3A95BA8160EFCED533D9F25B65AAB10F627681D2753871814366
|
||||||
C19246F52AE1EE5CE968CED52F642D9CD78B020029632FE83C49C657D23ED075
|
A1261BE878933B4905956BE7708F7C40E999714503B52B8021D44E131D87FF6C
|
||||||
FEE3C05432FB3860D5D28562323F5D1B053B8F3ADCD416BD0C4645F6F4D43DCF
|
8F31E76314A46EA9B0CCD3EDA4B2DF603829D8E3AF8CE41AEA6BFFBA2E2990AC
|
||||||
D780A4AADD0205E0BACDCC9AF46ED259E0946C5DA888C341BFE96E09A87CCCFA
|
850C08E45CDA4E42BD4F09B956299C0ED58615BE3664791C88D1E2608D46D205
|
||||||
CE3C13CFA08E532B637FDB707E29548D57EE92EAEF6516C3D67E9D36FCD59CF9
|
6283656518C6ADFC3B7D309D2763BD91111720CD51029FAA691211DEFF84CB47
|
||||||
5E88CE71258CB0D91631FEB41C9A2F47AE0FF4810A9A1EDF3F308BBDE6944D5E
|
9FCAF9F77C9D1B9B6934E53DB10DFF88D392D8E7BB4DC28D65F65DC396E2E00A
|
||||||
1531F4107FC64810BA5DB5E46C7B9AD61531AF5430E137B7688109FBC06B6221
|
41D2406BE1887FCC094861E4DF0683B1BE534C5CBF059259E946F9D04222C2AB
|
||||||
68050A39C0B302E0B713FAAC5F829C79AB30E18B1D982A94005DBAC7CCFB95379A619C0B9F7409C44D19FF2C5E8E4546
|
1D6F37E645591F0C491312C1E0CB54F1A6B70F94B54D63100C4584AA016DB589338A704B6D8B6B89C2381F660D987A2F
|
||||||
3F73E8BA22C602280496EF8E88E2CAA9EC442E3B3083B684942DBF9CB5121241
|
DCEA08D6E5C0D6229EBDE07DBB6CBC0EA8D6E24A3B631CC3775CE23A496CF178
|
||||||
FA1FCD7C9182FAE8FFF4E88433AE68F66076B3BDFF8AD0BF5CEA43870082E9BE
|
907051215A741BE55603F27C3FD86561CC6231CEED83AA76665D6A0B6B3FEC88
|
||||||
DFF7DD2678C03401656B093BF7AC7E033F15FD0F30188E48A62045740B423699
|
36CD5B5BCC63D45B89592B2938D6542B9D82AB47BEB73C0D30D2EC19BD8B35C2
|
||||||
371BCFF653E7811D99C048A1A39921AAA563E06AC86CB3D2F392C2C955A1ABD0
|
1FD9651ABAD773D6D22DE677CF7B19615D5B805594DCA117F04AC3255AE8184A
|
||||||
F4F1766DEAEDE934478208B9EB3050326D9FFCC001C73EEE93407D8B12CD49E4
|
4900723A8F7736C9BEAE938EE021F3E44AD806244010F825D04C59E6C67B5EA2
|
||||||
A241C9FC62DDF67D645936245FAFFE2A42C86151F484B7BCE5410E8F36FC87901D3AC4E40334E08FFFC2AD676E490D94
|
0D56A8CE77106DA2CB44F65B8CF5F4A024B9CC774D1C4CB8E862C95BD30B42E7B2E946CAC361F2830361C010DC938833
|
||||||
3566A94A9C0479E0C4387D9137375ADF2C921504364F3903F198D6757CDFD21B
|
11543FD104EA7D68B6B9C3BFE3F25A84F651FCB7FB5423AADDC472A48E12AFB2
|
||||||
7274E1B5A6445FDC29C355D550E981C17F349BC4A14251B3B51BC96FC334FBCA
|
98CD236E8B92D706DA0F92F43AC1D2CAF1CFBCDC7B330A7C9D65CDC4F2E2A677
|
||||||
04EEA5EDD9B3BC3E0638E53A5561DC8BF761D615A64D435BD31A94AF2650159E
|
753557A9A5075C033206111E3C832044227A32EBF3AB2B08F6FBFCC2109B2F2A
|
||||||
B84818CC1695FE8B731CD653D0679D1AAA0578C0B06AD1E3510785B2DE20841C
|
4AA124232EF6C25CB7321F5E5F7BE11114C763F8DDAFB6B05E8412ADF37B5C7B
|
||||||
4121343D6B79E38C06DD038D770D76D10336AFF47ED0D0DCDDD6B0FEA4DAE67C
|
01514EA408E26BAFD30290429DE1A0211F4FBDB09DE2E66CE92A6F09B998EF29
|
||||||
75E49C839CCD7019D9CE90AC364F488468B2AB01E387A8BEF8815915925166A6
|
4715716D5AFF99A2D8205A46AEEF0BC20D72F3F54991F7DF4142FF187485C178
|
||||||
CFAA9F4717568C1EC7B96E0D71D260B828A70484E1D9CA7C99A50D10704F8BBBAE62EE98C9FBDFF06F357F1C1E2F2677
|
281A32B90F8B85F31F54BF0D83B6D03E4E65A72ADB3D5A297C91881E36B45E8F
|
||||||
41E4D250B92BC57442B91DE2015C41226531CF9A8D77B83AFC8E4F3183DB11DE
|
9C05D3CB9F473D5693697A8567DBA7CF650C0A0D6C1BBE3ACE78ACDE0BD027B6C836B6CB6365D5B5D00F101FA83876B9
|
||||||
45EA8BD854D7F044FB249C16F08A0C24FF117D54BC20A4CC667B3DAD09EAC4F9
|
DC88B0237634CB007244A4169A5D9F5F65FC782E3C4388358A7E2019F7B4CC05
|
||||||
F455CA0BB8B496C301406DE4FB52C9B0F64645776803BC2935A2F38675318BE2
|
BC7ACAA91D23616A0070DCA328901DDDE3BB5B59260FB45083916B6ED0E6450C
|
||||||
22FF72A5D2E1A2EBFB6C55FFD0A3CEA0474CCBD13462D63229C9708276E87D3F
|
A280434D059D652D77ACB9F44409CDC7393A876239BA894DD4BE843FAB0AC561
|
||||||
8470F9A300170F226C0216C07AA829591CBD4CE34AA918EAE49363BDE86CC77EEEBEEA84A097488D35B92F773F5DBB4C
|
334F1316A35EB8A838F6B209FA4F8148062972E27A296379731B1F728A0BB32E
|
||||||
|
DDC9883E90EBE73915CFDF8EA7193F2449B66010D45F5EC6F20949D5C49719A9298B95269531A3440577B00EADE1B379
|
||||||
|
|||||||
@ -24,10 +24,10 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
|||||||
// Device Info version
|
// Device Info version
|
||||||
if(sep == '.') {
|
if(sep == '.') {
|
||||||
property_value_out(&property_context, NULL, 2, "format", "major", "3");
|
property_value_out(&property_context, NULL, 2, "format", "major", "3");
|
||||||
property_value_out(&property_context, NULL, 2, "format", "minor", "2");
|
property_value_out(&property_context, NULL, 2, "format", "minor", "3");
|
||||||
} else {
|
} else {
|
||||||
property_value_out(&property_context, NULL, 3, "device", "info", "major", "2");
|
property_value_out(&property_context, NULL, 3, "device", "info", "major", "2");
|
||||||
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "3");
|
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "4");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Model name
|
// Model name
|
||||||
@ -298,6 +298,7 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
|||||||
property_value_out(&property_context, NULL, 2, "radio", "alive", "false");
|
property_value_out(&property_context, NULL, 2, "radio", "alive", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RTC flags
|
||||||
property_value_out(
|
property_value_out(
|
||||||
&property_context,
|
&property_context,
|
||||||
"%u",
|
"%u",
|
||||||
@ -305,8 +306,52 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
|||||||
"system",
|
"system",
|
||||||
"debug",
|
"debug",
|
||||||
furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug));
|
furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug));
|
||||||
|
property_value_out(
|
||||||
|
&property_context, "%u", 2, "system", "lock", furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock));
|
||||||
|
property_value_out(
|
||||||
|
&property_context,
|
||||||
|
"%u",
|
||||||
|
2,
|
||||||
|
"system",
|
||||||
|
"orient",
|
||||||
|
furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient));
|
||||||
|
property_value_out(
|
||||||
|
&property_context,
|
||||||
|
"%u",
|
||||||
|
3,
|
||||||
|
"system",
|
||||||
|
"sleep",
|
||||||
|
"legacy",
|
||||||
|
furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep));
|
||||||
|
property_value_out(
|
||||||
|
&property_context,
|
||||||
|
"%u",
|
||||||
|
2,
|
||||||
|
"system",
|
||||||
|
"stealth",
|
||||||
|
furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode));
|
||||||
|
|
||||||
property_value_out(
|
property_value_out(
|
||||||
&property_context, "%u", 3, "system", "heap", "track", furi_hal_rtc_get_heap_track_mode());
|
&property_context, "%u", 3, "system", "heap", "track", furi_hal_rtc_get_heap_track_mode());
|
||||||
|
property_value_out(&property_context, "%u", 2, "system", "boot", furi_hal_rtc_get_boot_mode());
|
||||||
|
property_value_out(
|
||||||
|
&property_context,
|
||||||
|
"%u",
|
||||||
|
3,
|
||||||
|
"system",
|
||||||
|
"locale",
|
||||||
|
"time",
|
||||||
|
furi_hal_rtc_get_locale_timeformat());
|
||||||
|
property_value_out(
|
||||||
|
&property_context,
|
||||||
|
"%u",
|
||||||
|
3,
|
||||||
|
"system",
|
||||||
|
"locale",
|
||||||
|
"date",
|
||||||
|
furi_hal_rtc_get_locale_dateformat());
|
||||||
|
property_value_out(
|
||||||
|
&property_context, "%u", 3, "system", "locale", "unit", furi_hal_rtc_get_locale_units());
|
||||||
property_value_out(
|
property_value_out(
|
||||||
&property_context, "%u", 3, "system", "log", "level", furi_hal_rtc_get_log_level());
|
&property_context, "%u", 3, "system", "log", "level", furi_hal_rtc_get_log_level());
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@ typedef enum {
|
|||||||
FuriHalVersionColorUnknown = 0x00,
|
FuriHalVersionColorUnknown = 0x00,
|
||||||
FuriHalVersionColorBlack = 0x01,
|
FuriHalVersionColorBlack = 0x01,
|
||||||
FuriHalVersionColorWhite = 0x02,
|
FuriHalVersionColorWhite = 0x02,
|
||||||
|
FuriHalVersionColorTransparent = 0x03,
|
||||||
} FuriHalVersionColor;
|
} FuriHalVersionColor;
|
||||||
|
|
||||||
/** Device Regions */
|
/** Device Regions */
|
||||||
|
|||||||
@ -28,7 +28,7 @@ typedef enum {
|
|||||||
FuriThreadPriorityNormal = 16, /**< Normal */
|
FuriThreadPriorityNormal = 16, /**< Normal */
|
||||||
FuriThreadPriorityHigh = 17, /**< High */
|
FuriThreadPriorityHigh = 17, /**< High */
|
||||||
FuriThreadPriorityHighest = 18, /**< Highest */
|
FuriThreadPriorityHighest = 18, /**< Highest */
|
||||||
FuriThreadPriorityIsr = 32, /**< Deffered Isr (highest possible) */
|
FuriThreadPriorityIsr = (configMAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */
|
||||||
} FuriThreadPriority;
|
} FuriThreadPriority;
|
||||||
|
|
||||||
/** FuriThread anonymous structure */
|
/** FuriThread anonymous structure */
|
||||||
|
|||||||
@ -157,14 +157,6 @@ static bool flipper_application_assets_process_dirs(
|
|||||||
FuriString* full_path = flipper_application_assets_alloc_app_full_path(app_name);
|
FuriString* full_path = flipper_application_assets_alloc_app_full_path(app_name);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(!storage_simply_mkdir(storage, APPS_ASSETS_PATH)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!storage_simply_mkdir(storage, furi_string_get_cstr(full_path))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FuriString* dir_path = furi_string_alloc();
|
FuriString* dir_path = furi_string_alloc();
|
||||||
char* path = NULL;
|
char* path = NULL;
|
||||||
|
|
||||||
@ -279,6 +271,8 @@ bool flipper_application_assets_load(File* file, const char* elf_path, size_t of
|
|||||||
|
|
||||||
FURI_LOG_D(TAG, "Loading assets for %s", furi_string_get_cstr(app_name));
|
FURI_LOG_D(TAG, "Loading assets for %s", furi_string_get_cstr(app_name));
|
||||||
|
|
||||||
|
FuriString* full_path = flipper_application_assets_alloc_app_full_path(app_name);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(!storage_file_seek(file, offset, true)) {
|
if(!storage_file_seek(file, offset, true)) {
|
||||||
break;
|
break;
|
||||||
@ -319,13 +313,23 @@ bool flipper_application_assets_load(File* file, const char* elf_path, size_t of
|
|||||||
FURI_LOG_D(TAG, "Assets removed");
|
FURI_LOG_D(TAG, "Assets removed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!storage_simply_mkdir(storage, APPS_ASSETS_PATH)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!storage_simply_mkdir(storage, furi_string_get_cstr(full_path))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// process directories
|
// process directories
|
||||||
if(!flipper_application_assets_process_dirs(storage, file, app_name, header.dirs_count)) {
|
if(header.dirs_count &&
|
||||||
|
!flipper_application_assets_process_dirs(storage, file, app_name, header.dirs_count)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process files
|
// process files
|
||||||
if(!flipper_application_assets_process_files(storage, file, app_name, header.files_count)) {
|
if(header.files_count && !flipper_application_assets_process_files(
|
||||||
|
storage, file, app_name, header.files_count)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,6 +357,7 @@ bool flipper_application_assets_load(File* file, const char* elf_path, size_t of
|
|||||||
}
|
}
|
||||||
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
furi_string_free(full_path);
|
||||||
furi_string_free(app_name);
|
furi_string_free(app_name);
|
||||||
|
|
||||||
FURI_LOG_D(TAG, "Assets loading %s", result ? "success" : "failed");
|
FURI_LOG_D(TAG, "Assets loading %s", result ? "success" : "failed");
|
||||||
|
|||||||
@ -810,16 +810,10 @@ static void nfc_worker_mf_classic_key_attack(
|
|||||||
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
||||||
if(mf_classic_is_sector_read(data, i)) continue;
|
if(mf_classic_is_sector_read(data, i)) continue;
|
||||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Trying A key for sector %d, key: %012llX", i, key);
|
||||||
TAG,
|
|
||||||
"Trying A key for sector %d, key: %04lx%08lx",
|
|
||||||
i,
|
|
||||||
(uint32_t)(key >> 32),
|
|
||||||
(uint32_t)key);
|
|
||||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) {
|
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) {
|
||||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Key A found: %012llX", key);
|
||||||
TAG, "Key A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
|
||||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||||
|
|
||||||
uint64_t found_key;
|
uint64_t found_key;
|
||||||
@ -832,18 +826,13 @@ static void nfc_worker_mf_classic_key_attack(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
furi_hal_nfc_sleep();
|
||||||
}
|
}
|
||||||
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Trying B key for sector %d, key: %012llX", i, key);
|
||||||
TAG,
|
|
||||||
"Trying B key for sector %d, key: %04lx%08lx",
|
|
||||||
i,
|
|
||||||
(uint32_t)(key >> 32),
|
|
||||||
(uint32_t)key);
|
|
||||||
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) {
|
if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) {
|
||||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Key B found: %012llX", key);
|
||||||
TAG, "Key B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
|
||||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -891,8 +880,9 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
|||||||
nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context);
|
nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context);
|
||||||
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
|
||||||
if(mf_classic_is_sector_read(data, i)) continue;
|
if(mf_classic_is_sector_read(data, i)) continue;
|
||||||
bool is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA);
|
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||||
bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
mf_classic_is_key_found(data, i, MfClassicKeyB))
|
||||||
|
continue;
|
||||||
uint16_t key_index = 0;
|
uint16_t key_index = 0;
|
||||||
while(mf_classic_dict_get_next_key(dict, &key)) {
|
while(mf_classic_dict_get_next_key(dict, &key)) {
|
||||||
FURI_LOG_T(TAG, "Key %d", key_index);
|
FURI_LOG_T(TAG, "Key %d", key_index);
|
||||||
@ -910,19 +900,12 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
|||||||
nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i);
|
nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i);
|
||||||
deactivated = true;
|
deactivated = true;
|
||||||
}
|
}
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Try to auth to sector %d with key %012llX", i, key);
|
||||||
TAG,
|
if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
|
||||||
"Try to auth to sector %d with key %04lx%08lx",
|
|
||||||
i,
|
|
||||||
(uint32_t)(key >> 32),
|
|
||||||
(uint32_t)key);
|
|
||||||
if(!is_key_a_found) {
|
|
||||||
is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA);
|
|
||||||
if(mf_classic_authenticate_skip_activate(
|
if(mf_classic_authenticate_skip_activate(
|
||||||
&tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
|
&tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
|
||||||
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
mf_classic_set_key_found(data, i, MfClassicKeyA, key);
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Key A found: %012llX", key);
|
||||||
TAG, "Key A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
|
||||||
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
|
||||||
|
|
||||||
uint64_t found_key;
|
uint64_t found_key;
|
||||||
@ -952,22 +935,24 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
|||||||
|
|
||||||
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||||
memcmp(sec_trailer->key_a, current_key, 6) == 0) {
|
memcmp(sec_trailer->key_a, current_key, 6) == 0) {
|
||||||
mf_classic_set_key_not_found(data, i, MfClassicKeyA);
|
if(!mf_classic_authenticate_skip_activate(
|
||||||
is_key_a_found = false;
|
&tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
|
||||||
FURI_LOG_D(TAG, "Key %dA not found in attack", i);
|
mf_classic_set_key_not_found(data, i, MfClassicKeyA);
|
||||||
|
FURI_LOG_D(TAG, "Key %dA not found in attack", i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
furi_hal_nfc_sleep();
|
||||||
|
deactivated = true;
|
||||||
}
|
}
|
||||||
if(!is_key_b_found) {
|
if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
|
||||||
is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB);
|
|
||||||
if(mf_classic_authenticate_skip_activate(
|
if(mf_classic_authenticate_skip_activate(
|
||||||
&tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) {
|
&tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(TAG, "Key B found: %012llX", key);
|
||||||
TAG, "Key B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key);
|
|
||||||
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
mf_classic_set_key_found(data, i, MfClassicKeyB, key);
|
||||||
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
|
||||||
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
|
||||||
}
|
}
|
||||||
deactivated = true;
|
deactivated = true; //-V1048
|
||||||
} else {
|
} else {
|
||||||
// If the key B is marked as found and matches the searching key, invalidate it
|
// If the key B is marked as found and matches the searching key, invalidate it
|
||||||
MfClassicSectorTrailer* sec_trailer =
|
MfClassicSectorTrailer* sec_trailer =
|
||||||
@ -978,12 +963,18 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
|
|||||||
|
|
||||||
if(mf_classic_is_key_found(data, i, MfClassicKeyB) &&
|
if(mf_classic_is_key_found(data, i, MfClassicKeyB) &&
|
||||||
memcmp(sec_trailer->key_b, current_key, 6) == 0) {
|
memcmp(sec_trailer->key_b, current_key, 6) == 0) {
|
||||||
mf_classic_set_key_not_found(data, i, MfClassicKeyB);
|
if(!mf_classic_authenticate_skip_activate(
|
||||||
is_key_b_found = false;
|
&tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547
|
||||||
FURI_LOG_D(TAG, "Key %dB not found in attack", i);
|
mf_classic_set_key_not_found(data, i, MfClassicKeyB);
|
||||||
|
FURI_LOG_D(TAG, "Key %dB not found in attack", i);
|
||||||
|
}
|
||||||
|
furi_hal_nfc_sleep();
|
||||||
|
deactivated = true; //-V1048
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(is_key_a_found && is_key_b_found) break;
|
if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
|
||||||
|
mf_classic_is_key_found(data, i, MfClassicKeyB))
|
||||||
|
break;
|
||||||
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
|
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
|
||||||
} else {
|
} else {
|
||||||
if(!card_removed_notified) {
|
if(!card_removed_notified) {
|
||||||
|
|||||||
@ -467,6 +467,19 @@ static inline bool subghz_protocol_keeloq_check_decrypt(
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Centurion specific check
|
||||||
|
static inline bool subghz_protocol_keeloq_check_decrypt_centurion(
|
||||||
|
SubGhzBlockGeneric* instance,
|
||||||
|
uint32_t decrypt,
|
||||||
|
uint8_t btn) {
|
||||||
|
furi_assert(instance);
|
||||||
|
|
||||||
|
if((decrypt >> 28 == btn) && (((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0x1CE))) {
|
||||||
|
instance->cnt = decrypt & 0x0000FFFF;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checking the accepted code against the database manafacture key
|
* Checking the accepted code against the database manafacture key
|
||||||
@ -509,9 +522,16 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
|||||||
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
|
||||||
man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
|
||||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
if((strcmp(furi_string_get_cstr(manufacture_code->name), "Centurion") == 0)) {
|
||||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
if(subghz_protocol_keeloq_check_decrypt_centurion(instance, decrypt, btn)) {
|
||||||
return 1;
|
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||||
|
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEELOQ_LEARNING_SECURE:
|
case KEELOQ_LEARNING_SECURE:
|
||||||
|
|||||||
@ -17,6 +17,7 @@ OTP_COLORS = {
|
|||||||
"unknown": 0x00,
|
"unknown": 0x00,
|
||||||
"black": 0x01,
|
"black": 0x01,
|
||||||
"white": 0x02,
|
"white": 0x02,
|
||||||
|
"transparent": 0x03,
|
||||||
}
|
}
|
||||||
|
|
||||||
OTP_REGIONS = {
|
OTP_REGIONS = {
|
||||||
|
|||||||
@ -38,11 +38,11 @@ fbtenv_wget()
|
|||||||
fbtenv_restore_env()
|
fbtenv_restore_env()
|
||||||
{
|
{
|
||||||
TOOLCHAIN_ARCH_DIR_SED="$(echo "$TOOLCHAIN_ARCH_DIR" | sed 's/\//\\\//g')"
|
TOOLCHAIN_ARCH_DIR_SED="$(echo "$TOOLCHAIN_ARCH_DIR" | sed 's/\//\\\//g')"
|
||||||
PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/python\/bin://g")";
|
PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/python\/bin://g")";
|
||||||
PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/bin://g")";
|
PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/bin://g")";
|
||||||
PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/protobuf\/bin://g")";
|
PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/protobuf\/bin://g")";
|
||||||
PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openocd\/bin://g")";
|
PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openocd\/bin://g")";
|
||||||
PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openssl\/bin://g")";
|
PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openssl\/bin://g")";
|
||||||
if [ -n "${PS1:-""}" ]; then
|
if [ -n "${PS1:-""}" ]; then
|
||||||
PS1="$(echo "$PS1" | sed 's/\[fbt\]//g')";
|
PS1="$(echo "$PS1" | sed 's/\[fbt\]//g')";
|
||||||
elif [ -n "${PROMPT:-""}" ]; then
|
elif [ -n "${PROMPT:-""}" ]; then
|
||||||
@ -82,6 +82,9 @@ fbtenv_restore_env()
|
|||||||
|
|
||||||
fbtenv_check_sourced()
|
fbtenv_check_sourced()
|
||||||
{
|
{
|
||||||
|
if [ -n "${FBT_SKIP_CHECK_SOURCED:-""}" ]; then
|
||||||
|
return 0;
|
||||||
|
fi
|
||||||
case "${ZSH_EVAL_CONTEXT:-""}" in *:file:*)
|
case "${ZSH_EVAL_CONTEXT:-""}" in *:file:*)
|
||||||
setopt +o nomatch; # disabling 'no match found' warning in zsh
|
setopt +o nomatch; # disabling 'no match found' warning in zsh
|
||||||
return 0;;
|
return 0;;
|
||||||
@ -104,8 +107,6 @@ fbtenv_check_if_sourced_multiple_times()
|
|||||||
return 0;
|
return 0;
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo "Warning! FBT environment script was sourced more than once!";
|
|
||||||
echo "You might be doing things wrong, please open a new shell!";
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ fbtenv_get_kernel_type()
|
|||||||
fbtenv_check_rosetta()
|
fbtenv_check_rosetta()
|
||||||
{
|
{
|
||||||
if [ "$ARCH_TYPE" = "arm64" ]; then
|
if [ "$ARCH_TYPE" = "arm64" ]; then
|
||||||
if ! /usr/bin/pgrep -q oahd; then
|
if ! pgrep -q oahd; then
|
||||||
echo "Flipper Zero Toolchain needs Rosetta2 to run under Apple Silicon";
|
echo "Flipper Zero Toolchain needs Rosetta2 to run under Apple Silicon";
|
||||||
echo "Please instal it by typing 'softwareupdate --install-rosetta --agree-to-license'";
|
echo "Please instal it by typing 'softwareupdate --install-rosetta --agree-to-license'";
|
||||||
return 1;
|
return 1;
|
||||||
@ -202,7 +203,7 @@ fbtenv_download_toolchain_tar()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbtenv_remove_old_tooclhain()
|
fbtenv_remove_old_toolchain()
|
||||||
{
|
{
|
||||||
printf "Removing old toolchain..";
|
printf "Removing old toolchain..";
|
||||||
rm -rf "${TOOLCHAIN_ARCH_DIR:?}";
|
rm -rf "${TOOLCHAIN_ARCH_DIR:?}";
|
||||||
@ -233,12 +234,14 @@ fbtenv_unpack_toolchain()
|
|||||||
|
|
||||||
fbtenv_cleanup()
|
fbtenv_cleanup()
|
||||||
{
|
{
|
||||||
printf "Cleaning up..";
|
|
||||||
if [ -n "${FBT_TOOLCHAIN_PATH:-""}" ]; then
|
if [ -n "${FBT_TOOLCHAIN_PATH:-""}" ]; then
|
||||||
rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.tar.gz;
|
printf "Cleaning up..";
|
||||||
rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.part;
|
rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.part;
|
||||||
|
if [ -z "${FBT_PRESERVE_TAR:-""}" ]; then
|
||||||
|
rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.tar.gz;
|
||||||
|
fi
|
||||||
|
echo "done";
|
||||||
fi
|
fi
|
||||||
echo "done";
|
|
||||||
trap - 2;
|
trap - 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -291,16 +294,22 @@ fbtenv_download_toolchain()
|
|||||||
fbtenv_curl_wget_check || return 1;
|
fbtenv_curl_wget_check || return 1;
|
||||||
fbtenv_download_toolchain_tar || return 1;
|
fbtenv_download_toolchain_tar || return 1;
|
||||||
fi
|
fi
|
||||||
fbtenv_remove_old_tooclhain;
|
fbtenv_remove_old_toolchain;
|
||||||
fbtenv_unpack_toolchain || return 1;
|
fbtenv_unpack_toolchain || return 1;
|
||||||
fbtenv_cleanup;
|
fbtenv_cleanup;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbtenv_print_version()
|
fbtenv_print_config()
|
||||||
{
|
{
|
||||||
if [ -n "$FBT_VERBOSE" ]; then
|
if [ -n "${FBT_VERBOSE:-""}" ]; then
|
||||||
echo "FBT: using toolchain version $(cat "$TOOLCHAIN_ARCH_DIR/VERSION")";
|
echo "FBT: using toolchain version $(cat "$TOOLCHAIN_ARCH_DIR/VERSION")";
|
||||||
|
if [ -n "${FBT_SKIP_CHECK_SOURCED:-""}" ]; then
|
||||||
|
echo "FBT: fbtenv will not check if it is sourced or not";
|
||||||
|
fi
|
||||||
|
if [ -n "${FBT_PRESERVE_TAR:-""}" ]; then
|
||||||
|
echo "FBT: toolchain archives will be saved";
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,11 +321,13 @@ fbtenv_main()
|
|||||||
fbtenv_restore_env;
|
fbtenv_restore_env;
|
||||||
return 0;
|
return 0;
|
||||||
fi
|
fi
|
||||||
fbtenv_check_if_sourced_multiple_times;
|
if ! fbtenv_check_if_sourced_multiple_times; then
|
||||||
|
return 0;
|
||||||
|
fi;
|
||||||
fbtenv_check_env_vars || return 1;
|
fbtenv_check_env_vars || return 1;
|
||||||
fbtenv_check_download_toolchain || return 1;
|
fbtenv_check_download_toolchain || return 1;
|
||||||
fbtenv_set_shell_prompt;
|
fbtenv_set_shell_prompt;
|
||||||
fbtenv_print_version;
|
fbtenv_print_config;
|
||||||
PATH="$TOOLCHAIN_ARCH_DIR/python/bin:$PATH";
|
PATH="$TOOLCHAIN_ARCH_DIR/python/bin:$PATH";
|
||||||
PATH="$TOOLCHAIN_ARCH_DIR/bin:$PATH";
|
PATH="$TOOLCHAIN_ARCH_DIR/bin:$PATH";
|
||||||
PATH="$TOOLCHAIN_ARCH_DIR/protobuf/bin:$PATH";
|
PATH="$TOOLCHAIN_ARCH_DIR/protobuf/bin:$PATH";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user