This commit is contained in:
Willy-JL
2023-08-27 22:14:33 +02:00
229 changed files with 1352 additions and 894 deletions

9
.vscode/.gitignore vendored
View File

@@ -1,4 +1,5 @@
./c_cpp_properties.json
./launch.json
./settings.json
./tasks.json
/c_cpp_properties.json
/extensions.json
/launch.json
/settings.json
/tasks.json

19
.vscode/example/clangd/extensions.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"ms-python.black-formatter",
"llvm-vs-code-extensions.vscode-clangd",
"amiralizadeh9480.cpp-helper",
"marus25.cortex-debug",
"zxh404.vscode-proto3",
"augustocdias.tasks-shell-input"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"twxs.cmake",
"ms-vscode.cpptools",
"ms-vscode.cmake-tools"
]
}

View File

@@ -13,6 +13,7 @@
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"llvm-vs-code-extensions.vscode-clangd",
"twxs.cmake",
"ms-vscode.cmake-tools"
]

View File

@@ -21,5 +21,10 @@
"SConscript": "python",
"SConstruct": "python",
"*.fam": "python",
}
}
},
"clangd.arguments": [
// We might be able to tighten this a bit more to only include the correct toolchain.
"--query-driver=**",
"--compile-commands-dir=${workspaceFolder}/build/latest"
]
}

View File

@@ -28,29 +28,17 @@
"command": "./fbt -c"
},
{
"label": "[Release] Flash (ST-Link)",
"label": "[Release] Flash (SWD)",
"group": "build",
"type": "shell",
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash"
},
{
"label": "[Debug] Flash (ST-Link)",
"label": "[Debug] Flash (SWD)",
"group": "build",
"type": "shell",
"command": "./fbt FORCE=1 flash"
},
{
"label": "[Release] Flash (blackmagic)",
"group": "build",
"type": "shell",
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_blackmagic"
},
{
"label": "[Debug] Flash (blackmagic)",
"group": "build",
"type": "shell",
"command": "./fbt FORCE=1 flash_blackmagic"
},
{
"label": "[Release] Flash (JLink)",
"group": "build",

View File

@@ -45,6 +45,7 @@ distenv = coreenv.Clone(
],
ENV=os.environ,
UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
VSCODE_LANG_SERVER=ARGUMENTS.get("LANG_SERVER", "cpptools"),
)
firmware_env = distenv.AddFwProject(
@@ -184,27 +185,15 @@ copro_dist = distenv.CoproBuilder(
distenv.AlwaysBuild(copro_dist)
distenv.Alias("copro_dist", copro_dist)
firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
firmware_flash = distenv.AddFwFlashTarget(firmware_env)
distenv.Alias("flash", firmware_flash)
# To be implemented in fwflash.py
firmware_jflash = distenv.AddJFlashTarget(firmware_env)
distenv.Alias("jflash", firmware_jflash)
firmware_bm_flash = distenv.PhonyTarget(
"flash_blackmagic",
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="${BLACKMAGIC_ADDR}",
GDBFLASH=[
"-ex",
"load",
"-ex",
"quit",
],
)
gdb_backtrace_all_threads = distenv.PhonyTarget(
distenv.PhonyTarget(
"gdb_trace_all",
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
source=firmware_env["FW_ELF"],
@@ -348,7 +337,14 @@ distenv.PhonyTarget(
)
# Prepare vscode environment
vscode_dist = distenv.Install("#.vscode", distenv.Glob("#.vscode/example/*"))
VSCODE_LANG_SERVER = cmd_environment["LANG_SERVER"]
vscode_dist = distenv.Install(
"#.vscode",
[
distenv.Glob("#.vscode/example/*.json"),
distenv.Glob(f"#.vscode/example/{VSCODE_LANG_SERVER}/*.json"),
],
)
distenv.Precious(vscode_dist)
distenv.NoClean(vscode_dist)
distenv.Alias("vscode_dist", vscode_dist)

View File

@@ -174,7 +174,7 @@ bool WIEGAND::DoWiegandConversion() {
return false;
}
// TODO: Handle validation failure case!
// TODO FL-3490: Handle validation failure case!
} else if(4 == _bitCount) {
// 4-bit Wiegand codes have no data integrity check so we just
// read the LOW nibble.

View File

@@ -56,7 +56,6 @@ static void subghz_test_packet_rx_callback(bool level, uint32_t duration, void*
subghz_decoder_princeton_for_testing_parse(instance->decoder, level, duration);
}
//todo
static void subghz_test_packet_rx_pt_callback(SubGhzDecoderPrinceton* parser, void* context) {
UNUSED(parser);
furi_assert(context);

View File

@@ -3,6 +3,7 @@ App(
apptype=FlipperAppType.STARTUP,
entry_point="unit_tests_on_system_start",
cdefines=["APP_UNIT_TESTS"],
requires=["system_settings"],
provides=["delay_test"],
order=100,
)

View File

@@ -26,7 +26,7 @@ void test_furi_memmgr() {
mu_assert_int_eq(66, ((uint8_t*)ptr)[i]);
}
// TODO: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
// TODO FL-3492: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
free(ptr);
// allocate and zero-initialize array (calloc)

View File

@@ -69,7 +69,7 @@ MU_TEST(mu_test_furi_string_mem) {
mu_check(string != NULL);
mu_check(!furi_string_empty(string));
// TODO: how to test furi_string_reserve?
// TODO FL-3493: how to test furi_string_reserve?
// test furi_string_reset
furi_string_reset(string);

View File

@@ -311,7 +311,7 @@ MU_TEST(test_bit_lib_test_parity) {
}
MU_TEST(test_bit_lib_remove_bit_every_nth) {
// TODO: more tests
// TODO FL-3494: more tests
uint8_t data_i[1] = {0b00001111};
uint8_t data_o[1] = {0b00011111};
size_t length;

View File

@@ -330,7 +330,12 @@ bool subghz_hal_async_tx_test_run(SubGhzHalAsyncTxTestType type) {
return false;
}
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(30000000);
while(!furi_hal_subghz_is_async_tx_complete()) {
if(furi_hal_cortex_timer_is_expired(timer)) {
return false;
}
furi_delay_ms(10);
}
furi_hal_subghz_stop_async_tx();

View File

@@ -90,7 +90,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
Loader* loader = furi_record_open(RECORD_LOADER);
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
// TODO: lock device while test running
// TODO FL-3491: lock device while test running
if(loader_is_locked(loader)) {
printf("RPC: stop all applications to run tests\r\n");
notification_message(notification, &sequence_blink_magenta_100);

View File

@@ -378,7 +378,7 @@ bool subghz_device_cc1101_ext_rx_pipe_not_empty() {
(CC1101_STATUS_RXBYTES) | CC1101_BURST,
(uint8_t*)status);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
// TODO: you can add a buffer overflow flag if needed
// TODO: Find reason why RXFIFO_OVERFLOW doesnt work correctly
if(status->NUM_RXBYTES > 0) {
return true;
} else {

View File

@@ -84,7 +84,7 @@ SubRemLoadSubState subrem_sub_preset_load(
if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) {
FURI_LOG_W(TAG, "Cannot read frequency. Set default frequency");
sub_preset->freq_preset.frequency = subghz_setting_get_default_frequency(setting);
} else if(!subghz_txrx_radio_device_is_frequecy_valid(txrx, temp_data32)) {
} else if(!subghz_txrx_radio_device_is_frequency_valid(txrx, temp_data32)) {
FURI_LOG_E(TAG, "Frequency not supported on chosen radio module");
break;
}

View File

@@ -629,12 +629,12 @@ const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance) {
return subghz_devices_get_name(instance->radio_device);
}
bool subghz_txrx_radio_device_is_frequecy_valid(SubGhzTxRx* instance, uint32_t frequency) {
bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency) {
furi_assert(instance);
return subghz_devices_is_frequency_valid(instance->radio_device, frequency);
}
bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t frequency) {
bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency) {
furi_assert(instance);
furi_assert(instance->txrx_state != SubGhzTxRxStateSleep);

View File

@@ -363,9 +363,9 @@ const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance);
* @param instance Pointer to a SubGhzTxRx
* @return bool True if the frequency is valid
*/
bool subghz_txrx_radio_device_is_frequecy_valid(SubGhzTxRx* instance, uint32_t frequency);
bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency);
bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t frequency);
bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency);
void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state);
bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance);

View File

@@ -19,7 +19,7 @@ void gpio_scene_usb_uart_on_enter(void* context) {
uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUart);
if(prev_state == 0) {
scene_usb_uart = malloc(sizeof(SceneUsbUartBridge));
scene_usb_uart->cfg.vcp_ch = 0; // TODO: settings load
scene_usb_uart->cfg.vcp_ch = 0; // TODO FL-3495: settings load
scene_usb_uart->cfg.uart_ch = 0;
scene_usb_uart->cfg.flow_pins = 0;
scene_usb_uart->cfg.baudrate_mode = 0;

View File

@@ -85,7 +85,7 @@ static void infrared_cli_print_usage(void) {
printf("\tir decode <input_file> [<output_file>]\r\n");
printf("\tir universal <remote_name> <signal_name>\r\n");
printf("\tir universal list <remote_name>\r\n");
// TODO: Do not hardcode universal remote names
// TODO FL-3496: Do not hardcode universal remote names
printf("\tAvailable universal remotes: tv audio ac projector\r\n");
}
@@ -211,7 +211,7 @@ static bool infrared_cli_decode_raw_signal(
size_t i;
for(i = 0; i < raw_signal->timings_size; ++i) {
// TODO: Any infrared_check_decoder_ready() magic?
// TODO FL-3523: Any infrared_check_decoder_ready() magic?
const InfraredMessage* message = infrared_decode(decoder, level, raw_signal->timings[i]);
if(message) {

View File

@@ -208,6 +208,21 @@ void infrared_signal_set_raw_signal(
float duty_cycle) {
infrared_signal_clear_timings(signal);
// If the frequency is out of bounds, set it to the closest bound same for duty cycle
// TODO: Should we return error instead? Also infrared_signal_is_valid is used only in CLI for some reason?!
if(frequency > INFRARED_MAX_FREQUENCY) {
frequency = INFRARED_MAX_FREQUENCY;
} else if(frequency < INFRARED_MIN_FREQUENCY) {
frequency = INFRARED_MIN_FREQUENCY;
}
if((duty_cycle <= (float)0) || (duty_cycle > (float)1)) {
duty_cycle = (float)0.33;
}
// In case of timings out of bounds we just call return
if((timings_size <= 0) || (timings_size > MAX_TIMINGS_AMOUNT)) {
return;
}
signal->is_raw = true;
signal->payload.raw.timings_size = timings_size;

View File

@@ -1,6 +1,7 @@
#include "../infrared_i.h"
#include "common/infrared_scene_universal_common.h"
#include <furi_hal_rtc.h>
void infrared_scene_universal_ac_on_enter(void* context) {
infrared_scene_universal_common_on_enter(context);
@@ -18,24 +19,26 @@ void infrared_scene_universal_ac_on_enter(void* context) {
i,
0,
0,
3,
22,
&I_Off_25x27,
&I_Off_hvr_25x27,
6,
15,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 4, 37, &I_power_text_24x5);
infrared_brute_force_add_record(brute_force, i++, "Off");
button_panel_add_item(
button_panel,
i,
1,
0,
36,
22,
&I_Dehumidify_25x27,
&I_Dehumidify_hvr_25x27,
39,
15,
&I_dry_19x20,
&I_dry_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 41, 37, &I_dry_text_15x5);
infrared_brute_force_add_record(brute_force, i++, "Dh");
button_panel_add_item(
button_panel,
@@ -43,9 +46,9 @@ void infrared_scene_universal_ac_on_enter(void* context) {
0,
1,
3,
59,
&I_CoolHi_25x27,
&I_CoolHi_hvr_25x27,
49,
&I_max_24x23,
&I_max_hover_24x23,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Cool_hi");
@@ -54,39 +57,71 @@ void infrared_scene_universal_ac_on_enter(void* context) {
i,
1,
1,
36,
59,
&I_HeatHi_25x27,
&I_HeatHi_hvr_25x27,
37,
49,
&I_max_24x23,
&I_max_hover_24x23,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Heat_hi");
button_panel_add_item(
button_panel,
i,
0,
2,
3,
91,
&I_CoolLo_25x27,
&I_CoolLo_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) {
button_panel_add_item(
button_panel,
i,
0,
2,
3,
100,
&I_celsius_24x23,
&I_celsius_hover_24x23,
infrared_scene_universal_common_item_callback,
context);
} else {
button_panel_add_item(
button_panel,
i,
0,
2,
3,
100,
&I_fahren_24x23,
&I_fahren_hover_24x23,
infrared_scene_universal_common_item_callback,
context);
}
infrared_brute_force_add_record(brute_force, i++, "Cool_lo");
button_panel_add_item(
button_panel,
i,
1,
2,
36,
91,
&I_HeatLo_25x27,
&I_HeatLo_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) {
button_panel_add_item(
button_panel,
i,
1,
2,
37,
100,
&I_celsius_24x23,
&I_celsius_hover_24x23,
infrared_scene_universal_common_item_callback,
context);
} else {
button_panel_add_item(
button_panel,
i,
1,
2,
37,
100,
&I_fahren_24x23,
&I_fahren_hover_24x23,
infrared_scene_universal_common_item_callback,
context);
}
infrared_brute_force_add_record(brute_force, i++, "Heat_lo");
button_panel_add_label(button_panel, 6, 10, FontPrimary, "AC remote");
button_panel_add_icon(button_panel, 0, 60, &I_cool_30x51);
button_panel_add_icon(button_panel, 34, 60, &I_heat_30x51);
button_panel_add_label(button_panel, 4, 10, FontPrimary, "AC remote");
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -18,82 +18,88 @@ void infrared_scene_universal_audio_on_enter(void* context) {
i,
0,
0,
3,
11,
&I_Power_25x27,
&I_Power_hvr_25x27,
6,
13,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 4, 35, &I_power_text_24x5);
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_item(
button_panel,
i,
1,
0,
36,
11,
&I_Mute_25x27,
&I_Mute_hvr_25x27,
39,
13,
&I_mute_19x20,
&I_mute_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 39, 35, &I_mute_text_19x5);
infrared_brute_force_add_record(brute_force, i++, "Mute");
button_panel_add_item(
button_panel,
i,
0,
1,
3,
41,
&I_Play_25x27,
&I_Play_hvr_25x27,
6,
42,
&I_play_19x20,
&I_play_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 6, 64, &I_play_text_19x5);
infrared_brute_force_add_record(brute_force, i++, "Play");
button_panel_add_item(
button_panel,
i,
1,
1,
36,
41,
&I_Pause_25x27,
&I_Pause_hvr_25x27,
0,
2,
6,
71,
&I_pause_19x20,
&I_pause_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 4, 93, &I_pause_text_23x5);
infrared_brute_force_add_record(brute_force, i++, "Pause");
button_panel_add_item(
button_panel,
i,
0,
2,
3,
71,
&I_TrackPrev_25x27,
&I_TrackPrev_hvr_25x27,
6,
101,
&I_prev_19x20,
&I_prev_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 6, 123, &I_prev_text_19x5);
infrared_brute_force_add_record(brute_force, i++, "Prev");
button_panel_add_item(
button_panel,
i,
1,
2,
36,
71,
&I_TrackNext_25x27,
&I_TrackNext_hvr_25x27,
3,
39,
101,
&I_next_19x20,
&I_next_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 39, 123, &I_next_text_19x6);
infrared_brute_force_add_record(brute_force, i++, "Next");
button_panel_add_item(
button_panel,
i,
0,
3,
3,
101,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
1,
2,
37,
77,
&I_voldown_24x21,
&I_voldown_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
@@ -101,16 +107,17 @@ void infrared_scene_universal_audio_on_enter(void* context) {
button_panel,
i,
1,
3,
36,
101,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
1,
37,
43,
&I_volup_24x21,
&I_volup_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
button_panel_add_label(button_panel, 1, 8, FontPrimary, "Mus. remote");
button_panel_add_label(button_panel, 1, 10, FontPrimary, "Mus. remote");
button_panel_add_icon(button_panel, 34, 56, &I_vol_ac_text_30x30);
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -20,8 +20,8 @@ void infrared_scene_universal_digital_sign_on_enter(void* context) {
0,
3,
19,
&I_Power_25x27,
&I_Power_hvr_25x27,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");

View File

@@ -19,34 +19,38 @@ void infrared_scene_universal_fan_on_enter(void* context) {
i,
0,
0,
3,
6,
24,
&I_Power_25x27,
&I_Power_hvr_25x27,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_icon(button_panel, 4, 46, &I_power_text_24x5);
button_panel_add_item(
button_panel,
i,
1,
0,
36,
39,
24,
&I_Mode_25x27,
&I_Mode_hvr_25x27,
&I_mode_19x20,
&I_mode_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Mode");
button_panel_add_icon(button_panel, 39, 46, &I_mode_text_20x5);
button_panel_add_item(
button_panel,
i,
0,
1,
3,
66,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
1,
37,
55,
&I_volup_24x21,
&I_volup_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Speed_up");
@@ -54,11 +58,11 @@ void infrared_scene_universal_fan_on_enter(void* context) {
button_panel,
i,
1,
1,
36,
66,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
2,
37,
89,
&I_voldown_24x21,
&I_voldown_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Speed_dn");
@@ -66,31 +70,32 @@ void infrared_scene_universal_fan_on_enter(void* context) {
button_panel,
i,
0,
2,
3,
98,
&I_Rotate_25x27,
&I_Rotate_hvr_25x27,
1,
6,
58,
&I_rotate_19x20,
&I_rotate_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Rotate");
button_panel_add_icon(button_panel, 4, 80, &I_rotate_text_24x5);
button_panel_add_item(
button_panel,
i,
1,
0,
2,
36,
98,
&I_Timer_25x27,
&I_Timer_hvr_25x27,
6,
87,
&I_timer_19x20,
&I_timer_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Timer");
button_panel_add_icon(button_panel, 4, 109, &I_timer_text_23x5);
button_panel_add_label(button_panel, 5, 11, FontPrimary, "Fan remote");
button_panel_add_label(button_panel, 20, 63, FontSecondary, "Speed");
button_panel_add_label(button_panel, 8, 23, FontSecondary, "Pwr");
button_panel_add_label(button_panel, 40, 23, FontSecondary, "Mod");
button_panel_add_icon(button_panel, 34, 68, &I_speed_text_30x30);
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -20,8 +20,8 @@ void infrared_scene_universal_led_on_enter(void* context) {
0,
3,
19,
&I_Power_25x27,
&I_Power_hvr_25x27,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");
@@ -44,8 +44,8 @@ void infrared_scene_universal_led_on_enter(void* context) {
1,
3,
64,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
&I_volup_24x21,
&I_volup_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "BRIGHTNESS+");
@@ -56,8 +56,8 @@ void infrared_scene_universal_led_on_enter(void* context) {
1,
36,
64,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
&I_voldown_24x21,
&I_voldown_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "BRIGHTNESS-");

View File

@@ -21,8 +21,8 @@ void infrared_scene_universal_monitor_on_enter(void* context) {
0,
3,
24,
&I_Power_25x27,
&I_Power_hvr_25x27,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "POWER");
@@ -45,8 +45,8 @@ void infrared_scene_universal_monitor_on_enter(void* context) {
1,
3,
66,
&I_Mode_25x27,
&I_Mode_hvr_25x27,
&I_mode_19x20,
&I_mode_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "MENU");

View File

@@ -18,46 +18,49 @@ void infrared_scene_universal_projector_on_enter(void* context) {
i,
0,
0,
3,
19,
&I_Power_25x27,
&I_Power_hvr_25x27,
6,
24,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 4, 46, &I_power_text_24x5);
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_item(
button_panel,
i,
1,
0,
36,
19,
&I_Mute_25x27,
&I_Mute_hvr_25x27,
39,
24,
&I_mute_19x20,
&I_mute_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 39, 46, &I_mute_text_19x5);
infrared_brute_force_add_record(brute_force, i++, "Mute");
button_panel_add_item(
button_panel,
i,
0,
1,
3,
64,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
1,
37,
55,
&I_volup_24x21,
&I_volup_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
button_panel_add_item(
button_panel,
i,
1,
1,
36,
64,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
2,
37,
89,
&I_voldown_24x21,
&I_voldown_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
@@ -65,29 +68,31 @@ void infrared_scene_universal_projector_on_enter(void* context) {
button_panel,
i,
0,
2,
3,
101,
&I_Play_25x27,
&I_Play_hvr_25x27,
1,
6,
58,
&I_play_19x20,
&I_play_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Play");
button_panel_add_icon(button_panel, 6, 80, &I_play_text_19x5);
button_panel_add_item(
button_panel,
i,
1,
0,
2,
36,
101,
&I_Pause_25x27,
&I_Pause_hvr_25x27,
6,
87,
&I_pause_19x20,
&I_pause_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Pause");
button_panel_add_icon(button_panel, 4, 109, &I_pause_text_23x5);
button_panel_add_label(button_panel, 10, 11, FontPrimary, "Projector");
button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");
button_panel_add_label(button_panel, 3, 11, FontPrimary, "Proj. remote");
button_panel_add_icon(button_panel, 34, 68, &I_vol_ac_text_30x30);
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -18,77 +18,82 @@ void infrared_scene_universal_tv_on_enter(void* context) {
i,
0,
0,
3,
19,
&I_Power_25x27,
&I_Power_hvr_25x27,
6,
16,
&I_power_19x20,
&I_power_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 4, 38, &I_power_text_24x5);
infrared_brute_force_add_record(brute_force, i++, "Power");
button_panel_add_item(
button_panel,
i,
1,
0,
36,
19,
&I_Mute_25x27,
&I_Mute_hvr_25x27,
39,
16,
&I_mute_19x20,
&I_mute_hover_19x20,
infrared_scene_universal_common_item_callback,
context);
button_panel_add_icon(button_panel, 39, 38, &I_mute_text_19x5);
button_panel_add_icon(button_panel, 0, 66, &I_ch_text_31x34);
button_panel_add_icon(button_panel, 35, 66, &I_vol_tv_text_29x34);
infrared_brute_force_add_record(brute_force, i++, "Mute");
button_panel_add_item(
button_panel,
i,
1,
1,
38,
53,
&I_volup_24x21,
&I_volup_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
button_panel_add_item(
button_panel,
i,
0,
1,
3,
66,
&I_Vol_up_25x27,
&I_Vol_up_hvr_25x27,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
button_panel_add_item(
button_panel,
i,
1,
1,
36,
66,
&I_Up_25x27,
&I_Up_hvr_25x27,
53,
&I_ch_up_24x21,
&I_ch_up_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Ch_next");
button_panel_add_item(
button_panel,
i,
0,
1,
2,
3,
98,
&I_Vol_down_25x27,
&I_Vol_down_hvr_25x27,
38,
91,
&I_voldown_24x21,
&I_voldown_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
button_panel_add_item(
button_panel,
i,
1,
0,
2,
36,
98,
&I_Down_25x27,
&I_Down_hvr_25x27,
3,
91,
&I_ch_down_24x21,
&I_ch_down_hover_24x21,
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "Ch_prev");
button_panel_add_label(button_panel, 6, 11, FontPrimary, "TV remote");
button_panel_add_label(button_panel, 9, 64, FontSecondary, "Vol");
button_panel_add_label(button_panel, 43, 64, FontSecondary, "Ch");
button_panel_add_label(button_panel, 5, 10, FontPrimary, "TV remote");
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);

View File

@@ -14,4 +14,4 @@ enum NfcCustomEvent {
NfcCustomEventRpcSessionClose,
NfcCustomEventUpdateLog,
NfcCustomEventSaveShadow,
};
};

View File

@@ -3,6 +3,7 @@ ADD_SCENE(nfc, read, Read)
ADD_SCENE(nfc, saved_menu, SavedMenu)
ADD_SCENE(nfc, extra_actions, ExtraActions)
ADD_SCENE(nfc, set_type, SetType)
ADD_SCENE(nfc, set_type_mf_uid, SetTypeMfUid)
ADD_SCENE(nfc, set_sak, SetSak)
ADD_SCENE(nfc, set_atqa, SetAtqa)
ADD_SCENE(nfc, set_uid, SetUid)

View File

@@ -3,6 +3,8 @@
void nfc_scene_file_select_on_enter(void* context) {
Nfc* nfc = context;
nfc_device_data_clear(&nfc->dev->dev_data);
// Process file_select return
nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc);
if(!furi_string_size(nfc->dev->load_path)) {

View File

@@ -58,7 +58,8 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) {
if(strcmp(nfc->dev->dev_name, "") != 0) {
nfc_device_delete(nfc->dev, true);
}
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetUid)) {
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetUid) &&
(!scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetTypeMfUid))) {
nfc->dev->dev_data.nfc_data = nfc->dev_edit_data;
}
strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1);

View File

@@ -4,6 +4,7 @@
enum SubmenuIndex {
SubmenuIndexNFCA4,
SubmenuIndexNFCA7,
SubmenuIndexMFClassicCustomUID,
SubmenuIndexGeneratorsStart,
};
@@ -23,6 +24,12 @@ void nfc_scene_set_type_on_enter(void* context) {
submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc);
submenu_add_item(
submenu, "NFC-A 4-bytes UID", SubmenuIndexNFCA4, nfc_scene_set_type_submenu_callback, nfc);
submenu_add_item(
submenu,
"Mifare Classic Custom UID",
SubmenuIndexMFClassicCustomUID,
nfc_scene_set_type_submenu_callback,
nfc);
// Generators
int i = SubmenuIndexGeneratorsStart;
@@ -49,6 +56,10 @@ bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) {
nfc->dev->format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
consumed = true;
} else if(event.event == SubmenuIndexMFClassicCustomUID) {
nfc_device_clear(nfc->dev);
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetTypeMfUid);
consumed = true;
} else {
nfc_device_clear(nfc->dev);
nfc->generator = nfc_generators[event.event - SubmenuIndexGeneratorsStart];

View File

@@ -0,0 +1,103 @@
#include "../nfc_i.h"
#include "lib/nfc/helpers/nfc_generators.h"
enum SubmenuIndex {
SubmenuIndexMFC1k4b,
SubmenuIndexMFC4k4b,
SubmenuIndexMFC1k7b,
SubmenuIndexMFC4k7b,
SubmenuIndexMFCMini,
};
static const NfcGenerator ganeator_gag = {
.name = "Mifare Classic Custom UID",
.generator_func = NULL,
};
void nfc_scene_set_type_mf_uid_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_set_type_mf_uid_on_enter(void* context) {
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
submenu,
"Mifare Classic 1k 4byte UID",
SubmenuIndexMFC1k4b,
nfc_scene_set_type_mf_uid_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Mifare Classic 4k 4byte UID",
SubmenuIndexMFC4k4b,
nfc_scene_set_type_mf_uid_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Mifare Classic 1k 7byte UID",
SubmenuIndexMFC1k7b,
nfc_scene_set_type_mf_uid_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Mifare Classic 4k 7byte UID",
SubmenuIndexMFC4k7b,
nfc_scene_set_type_mf_uid_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Mifare Classic Mini",
SubmenuIndexMFCMini,
nfc_scene_set_type_mf_uid_submenu_callback,
nfc);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
bool nfc_scene_set_type_mf_uid_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
bool correct_index = false;
MfClassicType mf_type = MfClassicType1k;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexMFC1k4b) {
nfc->dev->dev_data.nfc_data.uid_len = 4;
mf_type = MfClassicType1k;
correct_index = true;
} else if(event.event == SubmenuIndexMFC1k7b) {
nfc->dev->dev_data.nfc_data.uid_len = 7;
mf_type = MfClassicType1k;
correct_index = true;
} else if(event.event == SubmenuIndexMFC4k4b) {
nfc->dev->dev_data.nfc_data.uid_len = 4;
mf_type = MfClassicType4k;
correct_index = true;
} else if(event.event == SubmenuIndexMFC4k7b) {
nfc->dev->dev_data.nfc_data.uid_len = 7;
mf_type = MfClassicType4k;
correct_index = true;
} else if(event.event == SubmenuIndexMFCMini) {
nfc->dev->dev_data.nfc_data.uid_len = 4;
mf_type = MfClassicTypeMini;
correct_index = true;
}
if(correct_index) {
nfc->generator = &ganeator_gag;
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSetTypeMfUid, mf_type);
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid);
consumed = true;
}
}
return consumed;
}
void nfc_scene_set_type_mf_uid_on_exit(void* context) {
Nfc* nfc = context;
submenu_reset(nfc->submenu);
}

View File

@@ -35,6 +35,21 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
consumed = true;
}
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetTypeMfUid)) {
MfClassicType mf_type =
scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSetTypeMfUid);
if(mf_type > MfClassicTypeMini) {
furi_crash("Nfc unknown type");
}
nfc_generate_mf_classic_ext(
&nfc->dev->dev_data,
nfc->dev_edit_data.uid_len,
mf_type,
false,
nfc->dev_edit_data.uid);
scene_manager_next_scene(nfc->scene_manager, NfcSceneGenerateInfo);
consumed = true;
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
consumed = true;

View File

@@ -336,7 +336,6 @@ static void subghz_txrx_tx_stop(SubGhzTxRx* instance) {
}
subghz_txrx_idle(instance);
subghz_txrx_speaker_off(instance);
//Todo: Show message
}
FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) {
@@ -629,13 +628,16 @@ const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance) {
return subghz_devices_get_name(instance->radio_device);
}
bool subghz_txrx_radio_device_is_frequecy_valid(SubGhzTxRx* instance, uint32_t frequency) {
bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency) {
furi_assert(instance);
return subghz_devices_is_frequency_valid(instance->radio_device, frequency);
}
bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t frequency) {
bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency) {
// TODO: Remake this function to check if the frequency is allowed on specific module - for modules not based on CC1101
furi_assert(instance);
UNUSED(frequency);
/*
furi_assert(instance->txrx_state != SubGhzTxRxStateSleep);
subghz_devices_idle(instance->radio_device);
@@ -645,6 +647,8 @@ bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t freque
subghz_devices_idle(instance->radio_device);
return ret;
*/
return true;
}
void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state) {

View File

@@ -334,9 +334,9 @@ const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance);
* @param instance Pointer to a SubGhzTxRx
* @return bool True if the frequency is valid
*/
bool subghz_txrx_radio_device_is_frequecy_valid(SubGhzTxRx* instance, uint32_t frequency);
bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency);
bool subghz_txrx_radio_device_is_tx_alowed(SubGhzTxRx* instance, uint32_t frequency);
bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency);
void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state);
bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance);

View File

@@ -30,7 +30,7 @@ bool subghz_txrx_gen_data_protocol(
subghz_receiver_search_decoder_base_by_name(instance->receiver, protocol_name);
if(instance->decoder_result == NULL) {
//TODO: Error
//TODO FL-3502: Error
// furi_string_set(error_str, "Protocol not\nfound!");
// scene_manager_next_scene(scene_manager, SubGhzSceneShowErrorSub);
FURI_LOG_E(TAG, "Protocol not found!");
@@ -199,7 +199,7 @@ bool subghz_txrx_gen_faac_slh_protocol(
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
uint32_t cnt,
uint32_t seed,
const char* manufacture_name) {
SubGhzTxRx* txrx = context;

View File

@@ -88,7 +88,7 @@ bool subghz_txrx_gen_faac_slh_protocol(
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
uint32_t cnt,
uint32_t seed,
const char* manufacture_name);

View File

@@ -25,7 +25,7 @@ static bool subghz_scene_receiver_info_update_parser(void* context) {
if(subghz_txrx_load_decoder_by_name_protocol(
subghz->txrx,
subghz_history_get_protocol_name(subghz->history, subghz->idx_menu_chosen))) {
//todo we are trying to deserialize without checking for errors, since it is assumed that we just received this signal
// we are trying to deserialize without checking for errors, since it is assumed that we just received this chignal
subghz_protocol_decoder_base_deserialize(
subghz_txrx_get_decoder(subghz->txrx),
subghz_history_get_raw_data(subghz->history, subghz->idx_menu_chosen));

View File

@@ -45,6 +45,13 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 |
subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3];
if(seed == 0) {
furi_string_set(subghz->error_str, "Seed value\ncan not be 0.");
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
consumed = true;
break;
}
generated_protocol = subghz_txrx_gen_keeloq_bft_protocol(
subghz->txrx,
"AM650",
@@ -73,6 +80,12 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 |
subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3];
if(seed == 0) {
furi_string_set(subghz->error_str, "Seed value\ncan not be 0.");
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
consumed = true;
break;
}
if(state == SubmenuIndexFaacSLH_433) {
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
subghz->txrx,
@@ -108,8 +121,14 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
}
}
// Reset Seed, Fix, Cnt in secure data after successful or unsuccessful generation
memset(subghz->secure_data->seed, 0, sizeof(subghz->secure_data->seed));
memset(subghz->secure_data->cnt, 0, sizeof(subghz->secure_data->cnt));
memset(subghz->secure_data->fix, 0, sizeof(subghz->secure_data->fix));
if(generated_protocol) {
subghz_file_name_clear(subghz);
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneSetType, SubGhzCustomEventManagerSet);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);

View File

@@ -611,7 +611,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
break;
case SubmenuIndexSomfyTelis:
generated_protocol = subghz_txrx_gen_somfy_telis_protocol(
subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003);
subghz->txrx, "AM650", 433420000, key & 0x00FFFFFF, 0x2, 0x0003);
break;
case SubmenuIndexDoorHan_433_92:
generated_protocol = subghz_txrx_gen_keeloq_protocol(

View File

@@ -115,14 +115,15 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
break;
}
if(!subghz_txrx_radio_device_is_frequecy_valid(subghz->txrx, temp_data32)) {
if(!subghz_txrx_radio_device_is_frequency_valid(subghz->txrx, temp_data32)) {
FURI_LOG_E(TAG, "Frequency not supported on chosen radio module");
load_key_state = SubGhzLoadKeyStateUnsuportedFreq;
break;
}
if(!subghz_txrx_radio_device_is_tx_alowed(subghz->txrx, temp_data32)) {
FURI_LOG_E(TAG, "This frequency can only be used for RX on chosen radio module");
// TODO: use different frequency allowed lists for differnet modules (non cc1101)
if(!furi_hal_subghz_is_tx_allowed(temp_data32)) {
FURI_LOG_E(TAG, "This frequency can only be used for RX");
load_key_state = SubGhzLoadKeyStateOnlyRx;
break;
}
@@ -141,7 +142,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
if(!strcmp(furi_string_get_cstr(temp_str), "CUSTOM")) {
//Todo add Custom_preset_module
//TODO FL-3551: add Custom_preset_module
//delete preset if it already exists
subghz_setting_delete_custom_preset(setting, furi_string_get_cstr(temp_str));
//load custom preset from file
@@ -308,10 +309,14 @@ bool subghz_save_protocol_to_file(
if(!storage_simply_remove(storage, dev_file_name)) {
break;
}
//ToDo check Write
stream_seek(flipper_format_stream, 0, StreamOffsetFromStart);
stream_save_to_file(flipper_format_stream, storage, dev_file_name, FSOM_CREATE_ALWAYS);
if(storage_common_stat(storage, dev_file_name, NULL) != FSE_OK) {
break;
}
saved = true;
} while(0);
furi_string_free(file_dir);

View File

@@ -315,7 +315,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
uint32_t frequency_candidate = model->history_frequency[model->selected_index];
if(frequency_candidate == 0 ||
// !furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
!subghz_txrx_radio_device_is_frequecy_valid(
!subghz_txrx_radio_device_is_frequency_valid(
instance->txrx, frequency_candidate) ||
prev_freq_to_save == frequency_candidate) {
frequency_candidate = 0;
@@ -339,7 +339,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
uint32_t frequency_candidate = subghz_frequency_find_correct(model->frequency);
if(frequency_candidate == 0 ||
// !furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
!subghz_txrx_radio_device_is_frequecy_valid(
!subghz_txrx_radio_device_is_frequency_valid(
instance->txrx, frequency_candidate) ||
prev_freq_to_save == frequency_candidate) {
frequency_candidate = 0;
@@ -356,7 +356,7 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) {
uint32_t frequency_candidate = subghz_frequency_find_correct(model->frequency);
if(frequency_candidate == 0 ||
// !furi_hal_subghz_is_frequency_valid(frequency_candidate) ||
!subghz_txrx_radio_device_is_frequecy_valid(
!subghz_txrx_radio_device_is_frequency_valid(
instance->txrx, frequency_candidate) ||
prev_freq_to_save == frequency_candidate) {
frequency_candidate = 0;

View File

@@ -51,6 +51,12 @@ extern const size_t FLIPPER_ON_SYSTEM_START_COUNT;
extern const FlipperInternalApplication FLIPPER_SYSTEM_APPS[];
extern const size_t FLIPPER_SYSTEM_APPS_COUNT;
/* Debug apps
* Can only be spawned by loader by name
*/
extern const FlipperInternalApplication FLIPPER_DEBUG_APPS[];
extern const size_t FLIPPER_DEBUG_APPS_COUNT;
extern const FlipperInternalApplication FLIPPER_ARCHIVE;
/* Settings list

View File

@@ -96,7 +96,7 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) {
char buffer[20];
snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->time_minute);
// ToDo: never do that, may cause visual glitches
// TODO FL-3515: never do that, may cause visual glitches
view_port_set_width(
desktop->clock_viewport,
canvas_string_width(canvas, buffer) - 1 + (desktop->time_minute % 10 == 1));
@@ -365,12 +365,7 @@ Desktop* desktop_alloc() {
}
gui_add_view_port(desktop->gui, desktop->stealth_mode_icon_viewport, GuiLayerStatusBarLeft);
// Special case: autostart application is already running
desktop->loader = furi_record_open(RECORD_LOADER);
if(loader_is_locked(desktop->loader) &&
animation_manager_is_animation_loaded(desktop->animation_manager)) {
animation_manager_unload_and_stall_animation(desktop->animation_manager);
}
desktop->notification = furi_record_open(RECORD_NOTIFICATION);
desktop->app_start_stop_subscription = furi_pubsub_subscribe(
@@ -510,6 +505,12 @@ int32_t desktop_srv(void* p) {
scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault);
}
// Special case: autostart application is already running
if(loader_is_locked(desktop->loader) &&
animation_manager_is_animation_loaded(desktop->animation_manager)) {
animation_manager_unload_and_stall_animation(desktop->animation_manager);
}
view_dispatcher_run(desktop->view_dispatcher);
furi_crash("That was unexpected");

View File

@@ -93,6 +93,10 @@ bool desktop_scene_locked_on_event(void* context, SceneManagerEvent event) {
desktop_unlock(desktop);
consumed = true;
break;
case DesktopLockedEventCoversClosed:
notification_message(desktop->notification, &sequence_display_backlight_off);
consumed = true;
break;
case DesktopLockedEventUpdate:
if(desktop_view_locked_is_locked_hint_visible(desktop->locked_view)) {
notification_message(

View File

@@ -13,6 +13,7 @@ typedef enum {
DesktopLockedEventUnlocked,
DesktopLockedEventUpdate,
DesktopLockedEventShowPinInput,
DesktopLockedEventCoversClosed,
DesktopPinInputEventResetWrongPinLabel,
DesktopPinInputEventUnlocked,

View File

@@ -165,6 +165,7 @@ void desktop_view_locked_update(DesktopViewLocked* locked_view) {
if(view_state == DesktopViewLockedStateCoverClosing &&
!desktop_view_locked_cover_move(model, true)) {
locked_view->callback(DesktopLockedEventCoversClosed, locked_view->context);
model->view_state = DesktopViewLockedStateLocked;
} else if(
view_state == DesktopViewLockedStateCoverOpening &&

View File

@@ -259,11 +259,11 @@ static size_t
}
if(len_px > px_left) {
uint8_t excess_symbols_approximately =
roundf((float)(len_px - px_left) / ((float)len_px / (float)text_size));
size_t excess_symbols_approximately =
ceilf((float)(len_px - px_left) / ((float)len_px / (float)text_size));
// reduce to 5 to be sure dash fit, and next line will be at least 5 symbols long
if(excess_symbols_approximately > 0) {
excess_symbols_approximately = MAX(excess_symbols_approximately, 5);
excess_symbols_approximately = MAX(excess_symbols_approximately, 5u);
result = text_size - excess_symbols_approximately - 1;
} else {
result = text_size;

View File

@@ -29,6 +29,9 @@ typedef struct {
const Icon* name_selected;
} IconElement;
LIST_DEF(IconList, IconElement, M_POD_OPLIST)
#define M_OPL_IconList_t() LIST_OPLIST(IconList)
typedef struct ButtonItem {
uint32_t index;
ButtonItemCallback callback;
@@ -47,6 +50,7 @@ struct ButtonPanel {
typedef struct {
ButtonMatrix_t button_matrix;
IconList_t icons;
LabelList_t labels;
uint16_t reserve_x;
uint16_t reserve_y;
@@ -114,7 +118,6 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re
ButtonArray_t* array = ButtonMatrix_get(model->button_matrix, i);
ButtonArray_init(*array);
ButtonArray_reserve(*array, reserve_x);
// TODO: do we need to clear allocated memory of ptr-s to ButtonItem ??
}
LabelList_init(model->labels);
},
@@ -158,6 +161,7 @@ void button_panel_reset(ButtonPanel* button_panel) {
model->selected_item_x = 0;
model->selected_item_y = 0;
LabelList_reset(model->labels);
IconList_reset(model->icons);
ButtonMatrix_reset(model->button_matrix);
},
true);
@@ -220,9 +224,17 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) {
canvas_clear(canvas);
canvas_set_color(canvas, ColorBlack);
for
M_EACH(icon, model->icons, IconList_t) {
canvas_draw_icon(canvas, icon->x, icon->y, icon->name);
}
for(size_t x = 0; x < model->reserve_x; ++x) {
for(size_t y = 0; y < model->reserve_y; ++y) {
ButtonItem* button_item = *button_panel_get_item(model, x, y);
if(!button_item) {
continue;
}
const Icon* icon_name = button_item->icon.name;
if((model->selected_item_x == x) && (model->selected_item_y == y)) {
icon_name = button_item->icon.name_selected;
@@ -418,3 +430,24 @@ void button_panel_add_label(
},
true);
}
// Draw an icon but don't make it a button.
void button_panel_add_icon(
ButtonPanel* button_panel,
uint16_t x,
uint16_t y,
const Icon* icon_name) {
furi_assert(button_panel);
with_view_model( //-V773
button_panel->view,
ButtonPanelModel * model,
{
IconElement* icon = IconList_push_raw(model->icons);
icon->x = x;
icon->y = y;
icon->name = icon_name;
icon->name_selected = icon_name;
},
true);
}

View File

@@ -106,6 +106,19 @@ void button_panel_add_label(
Font font,
const char* label_str);
/** Add a non-button icon to button_panel module.
*
* @param button_panel ButtonPanel instance
* @param x x-coordinate to place icon
* @param y y-coordinate to place icon
* @param icon_name name of the icon to draw
*/
void button_panel_add_icon(
ButtonPanel* button_panel,
uint16_t x,
uint16_t y,
const Icon* icon_name);
#ifdef __cplusplus
}
#endif

View File

@@ -272,7 +272,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e
} else if(view_dispatcher->navigation_event_callback) {
// Dispatch navigation event
if(!view_dispatcher->navigation_event_callback(view_dispatcher->event_context)) {
// TODO: should we allow view_dispatcher to stop without navigation_event_callback?
// TODO FL-3514: should we allow view_dispatcher to stop without navigation_event_callback?
view_dispatcher_stop(view_dispatcher);
return;
}

View File

@@ -7,7 +7,7 @@
#include "gui.h"
#include "gui_i.h"
// TODO add mutex to view_port ops
// TODO FL-3498: add mutex to view_port ops
_Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count");
_Static_assert(

View File

@@ -10,6 +10,19 @@
static_assert(!has_hash_collisions(elf_api_table), "Detected API method hash collision!");
#ifdef APP_UNIT_TESTS
constexpr HashtableApiInterface mock_elf_api_interface{
{
.api_version_major = 0,
.api_version_minor = 0,
.resolver_callback = &elf_resolve_from_hashtable,
},
.table_cbegin = nullptr,
.table_cend = nullptr,
};
const ElfApiInterface* const firmware_api_interface = &mock_elf_api_interface;
#else
constexpr HashtableApiInterface elf_api_interface{
{
.api_version_major = (elf_api_version >> 16),
@@ -19,10 +32,10 @@ constexpr HashtableApiInterface elf_api_interface{
.table_cbegin = elf_api_table.cbegin(),
.table_cend = elf_api_table.cend(),
};
const ElfApiInterface* const firmware_api_interface = &elf_api_interface;
#endif
extern "C" void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) {
*major = elf_api_interface.api_version_major;
*minor = elf_api_interface.api_version_minor;
*major = firmware_api_interface->api_version_major;
*minor = firmware_api_interface->api_version_minor;
}

View File

@@ -1,4 +1,5 @@
#include "loader.h"
#include "core/core_defines.h"
#include "loader_i.h"
#include <applications.h>
#include <storage/storage.h>
@@ -47,7 +48,7 @@ LoaderStatus
}
static void loader_show_gui_error(LoaderStatus status, FuriString* error_message) {
// TODO: we have many places where we can emit a double start, ex: desktop, menu
// TODO FL-3522: we have many places where we can emit a double start, ex: desktop, menu
// so i prefer to not show LoaderStatusErrorAppStarted error message for now
if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) {
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
@@ -315,18 +316,25 @@ static FlipperInternalApplication const* loader_find_application_by_name_in_list
}
static const FlipperInternalApplication* loader_find_application_by_name(const char* name) {
const FlipperInternalApplication* application = NULL;
application = loader_find_application_by_name_in_list(name, FLIPPER_APPS, FLIPPER_APPS_COUNT);
if(!application) {
application = loader_find_application_by_name_in_list(
name, FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT);
}
if(!application) {
application = loader_find_application_by_name_in_list(
name, FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_APPS_COUNT);
const struct {
const FlipperInternalApplication* list;
const uint32_t count;
} lists[] = {
{FLIPPER_APPS, FLIPPER_APPS_COUNT},
{FLIPPER_SETTINGS_APPS, FLIPPER_SETTINGS_APPS_COUNT},
{FLIPPER_SYSTEM_APPS, FLIPPER_SYSTEM_APPS_COUNT},
{FLIPPER_DEBUG_APPS, FLIPPER_DEBUG_APPS_COUNT},
};
for(size_t i = 0; i < COUNT_OF(lists); i++) {
const FlipperInternalApplication* application =
loader_find_application_by_name_in_list(name, lists[i].list, lists[i].count);
if(application) {
return application;
}
}
return application;
return NULL;
}
static void loader_start_app_thread(Loader* loader, FlipperInternalApplicationFlag flags) {
@@ -382,9 +390,7 @@ static void loader_log_status_error(
furi_string_vprintf(error_message, format, args);
FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(error_message));
} else {
FuriString* tmp = furi_string_alloc();
FURI_LOG_E(TAG, "Status [%d]: %s", status, furi_string_get_cstr(tmp));
furi_string_free(tmp);
FURI_LOG_E(TAG, "Status [%d]", status);
}
}
@@ -665,7 +671,9 @@ int32_t loader_srv(void* p) {
FLIPPER_ON_SYSTEM_START[i]();
}
if(FLIPPER_AUTORUN_APP_NAME && strlen(FLIPPER_AUTORUN_APP_NAME)) {
if((furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) && FLIPPER_AUTORUN_APP_NAME &&
strlen(FLIPPER_AUTORUN_APP_NAME)) {
FURI_LOG_I(TAG, "Starting autorun app: %s", FLIPPER_AUTORUN_APP_NAME);
loader_do_start_by_name(loader, FLIPPER_AUTORUN_APP_NAME, NULL, NULL);
}

View File

@@ -31,7 +31,7 @@ static void loader_cli_info(Loader* loader) {
if(!loader_is_locked(loader)) {
printf("No application is running\r\n");
} else {
// TODO: print application name ???
// TODO FL-3513: print application name ???
printf("Application is running\r\n");
}
}

View File

@@ -279,7 +279,7 @@ static void rpc_system_gui_start_virtual_display_process(const PB_Main* request,
return;
}
// TODO: consider refactoring
// TODO FL-3511: consider refactoring
// Using display framebuffer size as an XBM buffer size is like comparing apples and oranges
// Glad they both are 1024 for now
size_t buffer_size = canvas_get_buffer_size(rpc_gui->gui->canvas);

View File

@@ -430,7 +430,7 @@ static FS_Error storage_process_common_fs_info(
}
/****************** Raw SD API ******************/
// TODO think about implementing a custom storage API to split that kind of api linkage
// TODO FL-3521: think about implementing a custom storage API to split that kind of api linkage
#include "storages/storage_ext.h"
static FS_Error storage_process_sd_format(Storage* app) {

View File

@@ -100,7 +100,7 @@ FS_Error sd_unmount_card(StorageData* storage) {
storage->status = StorageStatusNotReady;
error = FR_DISK_ERR;
// TODO do i need to close the files?
// TODO FL-3522: do i need to close the files?
f_mount(0, sd_data->path, 0);
return storage_ext_parse_error(error);

View File

@@ -80,7 +80,7 @@ bool updater_scene_main_on_event(void* context, SceneManagerEvent event) {
break;
case UpdaterCustomEventSdUnmounted:
// TODO: error out, stop worker (it's probably dead actually)
// TODO FL-3499: error out, stop worker (it's probably dead actually)
break;
default:
break;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Some files were not shown because too many files have changed in this diff Show More