diff --git a/ReadMe.md b/ReadMe.md index c2e8044c1c1..a4ab0d8b6c2 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -56,6 +56,9 @@ This software is for experimental purposes only and is not meant for any illegal - OFW: [Check universal remote files before loading #3438 (By gsurkov)](https://github.com/flipperdevices/flipperzero-firmware/pull/3438) - OFW: [Fixed MyKey LockID #3412 (By zProAle)](https://github.com/flipperdevices/flipperzero-firmware/pull/3412) - Was Already In RM - Minor var type changes for the coming OFW update [3254](https://github.com/flipperdevices/flipperzero-firmware/pull/3254) (By Willy-JL) +- [CFW Settings - favorite_timeout (By WillyJL)]() +- [SubGhz protocol integrations (Weather, Pocsag, TPMS) (By htotoo)]() +- [Add GPS support for SubGHz (By Sil333033)]() - To Be Merged OFW PRs: [3352](https://github.com/flipperdevices/flipperzero-firmware/pull/3352), [3302](https://github.com/flipperdevices/flipperzero-firmware/pull/3302), [3211](https://github.com/flipperdevices/flipperzero-firmware/pull/3211), [3366](https://github.com/flipperdevices/flipperzero-firmware/pull/3366), [3250](https://github.com/flipperdevices/flipperzero-firmware/pull/3250), [3402](https://github.com/flipperdevices/flipperzero-firmware/pull/3402), [3409](https://github.com/flipperdevices/flipperzero-firmware/pull/3409), [3406](https://github.com/flipperdevices/flipperzero-firmware/pull/3406), [3431](https://github.com/flipperdevices/flipperzero-firmware/pull/3431), [3254](https://github.com/flipperdevices/flipperzero-firmware/pull/3254) & [3429](https://github.com/flipperdevices/flipperzero-firmware/pull/3429) diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index 90725dd96d9..29b9e80d932 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -34,7 +34,7 @@ static void nfc_test_alloc() { } static void nfc_test_free() { - furi_assert(nfc_test); + furi_check(nfc_test); furi_record_close(RECORD_STORAGE); free(nfc_test); diff --git a/applications/debug/unit_tests/nfc/nfc_transport.c b/applications/debug/unit_tests/nfc/nfc_transport.c index af60e84084b..e9f4e21341a 100644 --- a/applications/debug/unit_tests/nfc/nfc_transport.c +++ b/applications/debug/unit_tests/nfc/nfc_transport.c @@ -122,7 +122,7 @@ Nfc* nfc_alloc() { } void nfc_free(Nfc* instance) { - furi_assert(instance); + furi_check(instance); free(instance); } @@ -165,9 +165,9 @@ NfcError nfc_iso14443a_listener_set_col_res_data( uint8_t uid_len, uint8_t* atqa, uint8_t sak) { - furi_assert(instance); - furi_assert(uid); - furi_assert(atqa); + furi_check(instance); + furi_check(uid); + furi_check(atqa); nfc_prepare_col_res_data(instance, uid, uid_len, atqa, sak); @@ -176,7 +176,7 @@ NfcError nfc_iso14443a_listener_set_col_res_data( static int32_t nfc_worker_poller(void* context) { Nfc* instance = context; - furi_assert(instance->callback); + furi_check(instance->callback); instance->state = NfcStateReady; NfcCommand command = NfcCommandContinue; @@ -196,7 +196,7 @@ static int32_t nfc_worker_poller(void* context) { } static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, uint16_t rx_bits) { - furi_assert(instance->col_res_status != Iso14443_3aColResStatusDone); + furi_check(instance->col_res_status != Iso14443_3aColResStatusDone); BitBuffer* tx_buffer = bit_buffer_alloc(NFC_MAX_BUFFER_SIZE); bool processed = false; @@ -255,7 +255,7 @@ static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, ui static int32_t nfc_worker_listener(void* context) { Nfc* instance = context; - furi_assert(instance->callback); + furi_check(instance->callback); NfcMessage message = {}; @@ -295,17 +295,17 @@ static int32_t nfc_worker_listener(void* context) { } void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) { - furi_assert(instance); - furi_assert(instance->worker_thread == NULL); + furi_check(instance); + furi_check(instance->worker_thread == NULL); if(instance->mode == NfcModeListener) { - furi_assert(listener_queue == NULL); + furi_check(listener_queue == NULL); // Check that poller didn't start - furi_assert(poller_queue == NULL); + furi_check(poller_queue == NULL); } else { - furi_assert(poller_queue == NULL); + furi_check(poller_queue == NULL); // Check that poller is started after listener - furi_assert(listener_queue); + furi_check(listener_queue); } instance->callback = callback; @@ -334,8 +334,8 @@ void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) { } void nfc_stop(Nfc* instance) { - furi_assert(instance); - furi_assert(instance->worker_thread); + furi_check(instance); + furi_check(instance->worker_thread); if(instance->mode == NfcModeListener) { NfcMessage message = {.type = NfcMessageTypeAbort}; @@ -361,10 +361,10 @@ void nfc_stop(Nfc* instance) { // Called from worker thread NfcError nfc_listener_tx(Nfc* instance, const BitBuffer* tx_buffer) { - furi_assert(instance); - furi_assert(poller_queue); - furi_assert(listener_queue); - furi_assert(tx_buffer); + furi_check(instance); + furi_check(poller_queue); + furi_check(listener_queue); + furi_check(tx_buffer); NfcMessage message = {}; message.type = NfcMessageTypeTx; @@ -382,11 +382,11 @@ NfcError nfc_iso14443a_listener_tx_custom_parity(Nfc* instance, const BitBuffer* NfcError nfc_poller_trx(Nfc* instance, const BitBuffer* tx_buffer, BitBuffer* rx_buffer, uint32_t fwt) { - furi_assert(instance); - furi_assert(tx_buffer); - furi_assert(rx_buffer); - furi_assert(poller_queue); - furi_assert(listener_queue); + furi_check(instance); + furi_check(tx_buffer); + furi_check(rx_buffer); + furi_check(poller_queue); + furi_check(listener_queue); UNUSED(fwt); NfcError error = NfcErrorNone; @@ -396,7 +396,7 @@ NfcError message.data.data_bits = bit_buffer_get_size(tx_buffer); bit_buffer_write_bytes(tx_buffer, message.data.data, bit_buffer_get_size_bytes(tx_buffer)); // Tx - furi_assert(furi_message_queue_put(listener_queue, &message, FuriWaitForever) == FuriStatusOk); + furi_check(furi_message_queue_put(listener_queue, &message, FuriWaitForever) == FuriStatusOk); // Rx FuriStatus status = furi_message_queue_get(poller_queue, &message, 50); diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/acurite_592txr.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/acurite_592txr.sub new file mode 100644 index 00000000000..379d11f7b8c --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/acurite_592txr.sub @@ -0,0 +1,6 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok270Async +Protocol: RAW +RAW_Data: 24683 -68 97699 -66 49329 -68 77683 -66 369085 -100 59281 -68 29331 -64 357017 -68 284193 -66 128025 -64 198459 -64 522601 -66 111101 -70 132215 -64 288735 -68 747835 -102 26103 -70 25451 -68 349459 -66 166857 -66 68137 -66 595143 -128 59929 -66 17225 -66 16705 -66 105655 -66 10015 -38916 101 -2318 493 -708 395 -716 505 -734 487 -694 343 -274 339 -260 163 -440 343 -306 319 -268 159 -436 201 -432 157 -438 387 -244 179 -410 379 -234 187 -430 397 -218 183 -436 387 -236 371 -244 179 -414 409 -190 223 -410 193 -416 213 -396 393 -228 199 -406 209 -422 207 -392 387 -240 207 -384 419 -204 219 -394 203 -418 379 -244 395 -202 395 -208 251 -392 205 -380 221 -378 417 -242 215 -392 205 -396 203 -408 417 -204 217 -396 203 -394 389 -246 393 -206 393 -240 217 -396 203 -394 205 -410 191 -418 411 -190 401 -246 389 -206 393 -240 379 -222 187 -400 239 -2198 615 -592 615 -612 605 -614 597 -620 367 -224 411 -214 215 -402 387 -206 407 -226 197 -404 209 -422 205 -394 387 -238 207 -384 417 -204 219 -394 389 -238 205 -388 415 -206 379 -222 227 -400 417 -204 217 -396 203 -394 231 -370 413 -240 217 -394 203 -394 207 -408 393 -240 217 -392 367 -222 225 -400 209 -418 367 -224 413 -214 393 -204 215 -428 207 -394 201 -394 391 -246 213 -368 245 -394 203 -394 385 -240 209 -392 243 -390 395 -226 385 -212 395 -238 219 -392 205 -394 203 -418 223 -412 387 -242 369 -226 393 -210 395 -238 393 -208 217 -394 203 -59252 317 -277080 99 -1690 201 -634 469 -270 1393 -300 97817 -66 55659 -64 628165 -64 110139 -100 61425 -66 59611 -66 6621 -68 18847 -66 468225 -64 99275 diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 3faf6157211..940538887ae 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -49,7 +49,7 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS]; #define TAG "UnitTestsRpc" #define MAX_RECEIVE_OUTPUT_TIMEOUT 3000 -#define MAX_NAME_LENGTH 255 +#define MAX_NAME_LENGTH 254 #define MAX_DATA_SIZE 512u // have to be exact as in rpc_storage.c #define TEST_DIR TEST_DIR_NAME "/" #define TEST_DIR_NAME EXT_PATH("unit_tests_tmp") @@ -641,7 +641,7 @@ static void test_rpc_storage_list_create_expected_list( while(!finish) { FileInfo fileinfo; - char* name = malloc(MAX_NAME_LENGTH + 1); + char* name = malloc(MAX_NAME_LENGTH); if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { if(i == COUNT_OF(list->file)) { list->file_count = i; diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 0e6509b62cf..0a02582629f 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -819,6 +819,13 @@ MU_TEST(subghz_encoder_mastercode_test) { "Test encoder " SUBGHZ_PROTOCOL_MASTERCODE_NAME " error\r\n"); } +MU_TEST(subghz_decoder_acurite_592txr_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/acurite_592txr.sub"), WS_PROTOCOL_ACURITE_592TXR_NAME), + "Test decoder " WS_PROTOCOL_ACURITE_592TXR_NAME " error\r\n"); +} + MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -897,6 +904,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_holtek_ht12x_test); MU_RUN_TEST(subghz_encoder_dooya_test); MU_RUN_TEST(subghz_encoder_mastercode_test); + MU_RUN_TEST(subghz_decoder_acurite_592txr_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); diff --git a/applications/main/archive/application.fam b/applications/main/archive/application.fam index c7e7016535c..3787b2bf7a0 100644 --- a/applications/main/archive/application.fam +++ b/applications/main/archive/application.fam @@ -7,4 +7,7 @@ App( requires=["gui"], stack_size=6 * 1024, order=0, + sdk_headers=[ + "helpers/archive_helpers_ext.h", + ], ) diff --git a/applications/main/archive/helpers/archive_helpers_ext.h b/applications/main/archive/helpers/archive_helpers_ext.h new file mode 100644 index 00000000000..a46f7ec1eed --- /dev/null +++ b/applications/main/archive/helpers/archive_helpers_ext.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool process_favorite_launch(char** p); + +typedef struct { + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; +} FavoriteTImeoutCtx; + +void favorite_timeout_callback(void* _ctx); + +void favorite_timeout_run(ViewDispatcher* view_dispatcher, SceneManager* scene_manager); + +#ifdef __cplusplus +} +#endif diff --git a/applications/main/archive/helpers/favorite_timeout.c b/applications/main/archive/helpers/favorite_timeout.c new file mode 100644 index 00000000000..299bef03135 --- /dev/null +++ b/applications/main/archive/helpers/favorite_timeout.c @@ -0,0 +1,32 @@ +#include "archive_helpers_ext.h" +#include + +bool process_favorite_launch(char** args) { + if(*args && strlen(*args) > 4 && strncmp(*args, "fav/", 4) == 0) { + *args += 3; + return true; + } + return false; +} + +void favorite_timeout_callback(void* _ctx) { + FavoriteTImeoutCtx* ctx = _ctx; + while(scene_manager_previous_scene(ctx->scene_manager)) + ; + view_dispatcher_stop(ctx->view_dispatcher); +} + +void favorite_timeout_run(ViewDispatcher* view_dispatcher, SceneManager* scene_manager) { + uint32_t timeout = CFW_SETTINGS()->favorite_timeout; + if(timeout == 0) { + view_dispatcher_run(view_dispatcher); + return; + } + + FavoriteTImeoutCtx ctx = {.view_dispatcher = view_dispatcher, .scene_manager = scene_manager}; + FuriTimer* timer = furi_timer_alloc(favorite_timeout_callback, FuriTimerTypeOnce, &ctx); + furi_timer_start(timer, timeout * furi_kernel_get_tick_frequency()); + view_dispatcher_run(view_dispatcher); + furi_timer_stop(timer); + furi_timer_free(timer); +} \ No newline at end of file diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index afd51f7c9e1..2f55e3c1bc1 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -2,6 +2,7 @@ #include #include +#include #define TAG "IButtonApp" @@ -266,13 +267,14 @@ void ibutton_widget_callback(GuiButtonType result, InputType type, void* context } } -int32_t ibutton_app(void* arg) { +int32_t ibutton_app(char* arg) { iButton* ibutton = ibutton_alloc(); ibutton_make_app_folder(ibutton); bool key_loaded = false; + bool is_favorite = process_favorite_launch(&arg); if((arg != NULL) && (strlen(arg) != 0)) { if(sscanf(arg, "RPC %lX", (uint32_t*)&ibutton->rpc) == 1) { FURI_LOG_D(TAG, "Running in RPC mode"); @@ -303,7 +305,11 @@ int32_t ibutton_app(void* arg) { } } - view_dispatcher_run(ibutton->view_dispatcher); + if(is_favorite) { + favorite_timeout_run(ibutton->view_dispatcher, ibutton->scene_manager); + } else { + view_dispatcher_run(ibutton->view_dispatcher); + } if(ibutton->rpc) { rpc_system_app_set_callback(ibutton->rpc, NULL, NULL); diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index 1dd015655a2..f592d75b33b 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -1,6 +1,7 @@ #include "lfrfid_i.h" #include #include +#include //TODO: use .txt file in resources for passwords. const uint32_t default_passwords[] = { @@ -213,6 +214,7 @@ int32_t lfrfid_app(void* p) { lfrfid_make_app_folder(app); + bool is_favorite = process_favorite_launch(&args); if(args && strlen(args)) { uint32_t rpc_ctx_ptr = 0; if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) { @@ -228,6 +230,7 @@ int32_t lfrfid_app(void* p) { if(lfrfid_load_key_data(app, app->file_path, true)) { view_dispatcher_attach_to_gui( app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + app->fav_timeout = is_favorite; scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); dolphin_deed(DolphinDeedRfidEmulate); } else { diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index 4b8e07d066e..0701157d53e 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -136,6 +136,7 @@ struct LfRfid { uint8_t write_block; //uint8_t read_page; //uint8_t read_block; + bool fav_timeout; }; typedef enum { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c index 6190db6a912..c694a6228d5 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c @@ -1,5 +1,6 @@ #include "../lfrfid_i.h" #include +#include #define LFRFID_EMULATION_TIME_MAX_MS (5 * 60 * 1000) @@ -35,8 +36,12 @@ void lfrfid_scene_emulate_on_enter(void* context) { timer_auto_exit = furi_timer_alloc(lfrfid_scene_emulate_popup_callback, FuriTimerTypeOnce, app); - if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) - furi_timer_start(timer_auto_exit, LFRFID_EMULATION_TIME_MAX_MS); + if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) || app->fav_timeout) + furi_timer_start( + timer_auto_exit, + app->fav_timeout ? + CFW_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency() : + LFRFID_EMULATION_TIME_MAX_MS); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); } diff --git a/applications/main/nfc/nfc_app.c b/applications/main/nfc/nfc_app.c index 69f9ee22ff1..b5aeee4691c 100644 --- a/applications/main/nfc/nfc_app.c +++ b/applications/main/nfc/nfc_app.c @@ -1,6 +1,7 @@ #include "nfc_app_i.h" #include "nfc_icons.h" #include "helpers/protocol_support/nfc_protocol_support.h" +#include #include @@ -494,6 +495,7 @@ int32_t nfc_app(void* p) { NfcApp* nfc = nfc_app_alloc(); const char* args = p; + bool is_favorite = process_favorite_launch((char**)&args); if(args && strlen(args)) { if(sscanf(args, "RPC %p", &nfc->rpc_ctx) == 1) { rpc_system_app_set_callback(nfc->rpc_ctx, nfc_app_rpc_command_callback, nfc); @@ -507,6 +509,7 @@ int32_t nfc_app(void* p) { furi_string_set(nfc->file_path, args); if(nfc_load_file(nfc, nfc->file_path, false)) { + nfc->fav_timeout = is_favorite; nfc_show_initial_scene_for_device(nfc); } else { view_dispatcher_stop(nfc->view_dispatcher); diff --git a/applications/main/nfc/nfc_app_i.h b/applications/main/nfc/nfc_app_i.h index 16af5cc9650..32dbaf332f9 100644 --- a/applications/main/nfc/nfc_app_i.h +++ b/applications/main/nfc/nfc_app_i.h @@ -142,6 +142,8 @@ struct NfcApp { FuriString* file_path; FuriString* file_name; FuriTimer* timer; + + bool fav_timeout; }; typedef enum { diff --git a/applications/main/nfc/scenes/nfc_scene_emulate.c b/applications/main/nfc/scenes/nfc_scene_emulate.c index 7fd94390b79..7cc3ffb1d76 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate.c @@ -2,6 +2,8 @@ #include "nfc_app_i.h" +#include + #define NFC_EMULATION_TIME_MAX_MS (5 * 60 * 1000) FuriTimer* timer_auto_exit; @@ -21,8 +23,12 @@ void nfc_scene_emulate_on_enter(void* context) { timer_auto_exit = furi_timer_alloc(nfc_scene_emulate_timer_callback, FuriTimerTypeOnce, instance); - if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) - furi_timer_start(timer_auto_exit, NFC_EMULATION_TIME_MAX_MS); + if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) || instance->fav_timeout) + furi_timer_start( + timer_auto_exit, + instance->fav_timeout ? + CFW_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency() : + NFC_EMULATION_TIME_MAX_MS); } bool nfc_scene_emulate_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index 11a6c38fc12..52b09e1c84c 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -82,12 +83,12 @@ struct RpcSession { RpcSessionClosedCallback closed_callback; RpcSessionTerminatedCallback terminated_callback; RpcOwner owner; - bool status; void* context; }; struct Rpc { FuriMutex* busy_mutex; + size_t sessions_count; }; RpcOwner rpc_session_get_owner(RpcSession* session) { @@ -161,8 +162,11 @@ void rpc_session_set_terminated_callback( * command is gets processed - it's safe either way. But case of it is quite * odd: client sends close request and sends command after. */ -size_t - rpc_session_feed(RpcSession* session, uint8_t* encoded_bytes, size_t size, uint32_t timeout) { +size_t rpc_session_feed( + RpcSession* session, + const uint8_t* encoded_bytes, + size_t size, + uint32_t timeout) { furi_assert(session); furi_assert(encoded_bytes); @@ -187,6 +191,12 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { furi_assert(session); furi_assert(istream->bytes_left); + /* TODO FL-3768 this function may be called after + marking the worker for termination */ + if(session->terminate) { + return false; + } + uint32_t flags = 0; size_t bytes_received = 0; @@ -408,6 +418,8 @@ RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner) { furi_thread_start(session->thread); + rpc->sessions_count++; + return session; } @@ -415,6 +427,8 @@ void rpc_session_close(RpcSession* session) { furi_assert(session); furi_assert(session->rpc); + session->rpc->sessions_count--; + rpc_session_set_send_bytes_callback(session, NULL); rpc_session_set_close_callback(session, NULL); rpc_session_set_buffer_is_empty_callback(session, NULL); @@ -490,3 +504,7 @@ void rpc_send_and_release_empty(RpcSession* session, uint32_t command_id, PB_Com rpc_send_and_release(session, &message); pb_release(&PB_Main_msg, &message); } + +size_t rpc_get_sessions_count(Rpc* rpc) { + return rpc->sessions_count; +} diff --git a/applications/services/rpc/rpc.h b/applications/services/rpc/rpc.h index 82ab315a66d..a727fccfdbc 100644 --- a/applications/services/rpc/rpc.h +++ b/applications/services/rpc/rpc.h @@ -59,7 +59,7 @@ RpcOwner rpc_session_get_owner(RpcSession* session); * * * @param rpc instance - * @param owner owner of session + * @param owner owner of session * @return pointer to RpcSession descriptor, or * NULL if RPC is busy and can't open session now */ @@ -124,7 +124,7 @@ void rpc_session_set_terminated_callback( * * @return actually consumed bytes */ -size_t rpc_session_feed(RpcSession* session, uint8_t* buffer, size_t size, uint32_t timeout); +size_t rpc_session_feed(RpcSession* session, const uint8_t* buffer, size_t size, uint32_t timeout); /** Get available size of RPC buffer * @@ -134,6 +134,13 @@ size_t rpc_session_feed(RpcSession* session, uint8_t* buffer, size_t size, uint3 */ size_t rpc_session_get_available_size(RpcSession* session); +/** Get number of open RPC sessions + * + * @param rpc instance + * @return sessions count + */ +size_t rpc_get_sessions_count(Rpc* rpc); + #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/applications/services/rpc/rpc_gui.c b/applications/services/rpc/rpc_gui.c index ba0d7a6763a..528c6d12057 100644 --- a/applications/services/rpc/rpc_gui.c +++ b/applications/services/rpc/rpc_gui.c @@ -269,7 +269,7 @@ static void rpc_system_gui_virtual_display_input_callback(InputEvent* event, voi RpcGuiSystem* rpc_gui = context; RpcSession* session = rpc_gui->session; - FURI_LOG_D(TAG, "VirtulDisplay: SendInputEvent"); + FURI_LOG_D(TAG, "VirtualDisplay: SendInputEvent"); PB_Main rpc_message = { .command_id = 0, @@ -321,7 +321,7 @@ static void rpc_system_gui_start_virtual_display_process(const PB_Main* request, rpc_gui); if(request->content.gui_start_virtual_display_request.send_input) { - FURI_LOG_D(TAG, "VirtulDisplay: input forwarding requested"); + FURI_LOG_D(TAG, "VirtualDisplay: input forwarding requested"); view_port_input_callback_set( rpc_gui->virtual_display_view_port, rpc_system_gui_virtual_display_input_callback, diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index a934d1c31a1..88ae63a13dd 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -15,7 +15,7 @@ #define TAG "RpcStorage" -#define MAX_NAME_LENGTH 255 +#define MAX_NAME_LENGTH 254 static const size_t MAX_DATA_SIZE = 512; @@ -306,7 +306,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex while(!finish) { FileInfo fileinfo; - char* name = malloc(MAX_NAME_LENGTH + 1); + char* name = malloc(MAX_NAME_LENGTH); if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { if(rpc_system_storage_list_filter(list_request, &fileinfo, name)) { if(i == COUNT_OF(list->file)) { diff --git a/applications/settings/cfw_app/scenes/cfw_app_scene_interface_common.c b/applications/settings/cfw_app/scenes/cfw_app_scene_interface_common.c index c67fbca4564..0575f100af9 100644 --- a/applications/settings/cfw_app/scenes/cfw_app_scene_interface_common.c +++ b/applications/settings/cfw_app/scenes/cfw_app_scene_interface_common.c @@ -2,6 +2,7 @@ enum VarItemListIndex { VarItemListIndexSortDirsFirst, + VarItemListIndexFavoriteTimeout, }; void cfw_app_scene_interface_common_var_item_list_callback(void* context, uint32_t index) { @@ -17,6 +18,16 @@ static void cfw_app_scene_interface_common_sort_dirs_first_changed(VariableItem* app->save_settings = true; } +static void cfw_app_scene_interface_filebrowser_favorite_timeout_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + uint32_t value = variable_item_get_current_value_index(item); + char text[6]; + snprintf(text, sizeof(text), "%lu S", value); + variable_item_set_current_value_text(item, value ? text : "OFF"); + CFW_SETTINGS()->favorite_timeout = value; + app->save_settings = true; +} + void cfw_app_scene_interface_common_on_enter(void* context) { CfwApp* app = context; CfwSettings* cfw_settings = CFW_SETTINGS(); @@ -32,6 +43,17 @@ void cfw_app_scene_interface_common_on_enter(void* context) { variable_item_set_current_value_index(item, cfw_settings->sort_dirs_first); variable_item_set_current_value_text(item, cfw_settings->sort_dirs_first ? "ON" : "OFF"); + item = variable_item_list_add( + var_item_list, + "Favorite Timeout", + 61, + cfw_app_scene_interface_filebrowser_favorite_timeout_changed, + app); + variable_item_set_current_value_index(item, cfw_settings->favorite_timeout); + char text[4]; + snprintf(text, sizeof(text), "%lu S", cfw_settings->favorite_timeout); + variable_item_set_current_value_text(item, cfw_settings->favorite_timeout ? text : "OFF"); + variable_item_list_set_enter_callback( var_item_list, cfw_app_scene_interface_common_var_item_list_callback, app); diff --git a/lib/cfw/cfw.h b/lib/cfw/cfw.h index 73e3822030b..69704076988 100644 --- a/lib/cfw/cfw.h +++ b/lib/cfw/cfw.h @@ -52,6 +52,7 @@ typedef struct { bool sort_dirs_first; bool dark_mode; uint32_t charge_cap; + uint32_t favorite_timeout; SpiHandle spi_cc1101_handle; SpiHandle spi_nrf24_handle; UARTChannel uart_esp_channel; diff --git a/lib/cfw/settings.c b/lib/cfw/settings.c index 6159f273b49..8366a42b601 100644 --- a/lib/cfw/settings.c +++ b/lib/cfw/settings.c @@ -16,6 +16,7 @@ CfwSettings cfw_settings = { .sort_dirs_first = true, // ON .dark_mode = false, // OFF .charge_cap = 100, // 100% + .favorite_timeout = 0, // OFF .spi_cc1101_handle = SpiDefault, // &furi_hal_spi_bus_handle_external .spi_nrf24_handle = SpiDefault, // &furi_hal_spi_bus_handle_external .uart_esp_channel = UARTDefault, // pin 13,14 @@ -54,6 +55,8 @@ void CFW_SETTINGS_LOAD() { flipper_format_rewind(file); flipper_format_read_uint32(file, "charge_cap", &x->charge_cap, 1); flipper_format_rewind(file); + flipper_format_read_uint32(file, "favorite_timeout", &x->favorite_timeout, 1); + flipper_format_rewind(file); flipper_format_read_uint32(file, "spi_cc1101_handle", (uint32_t*)&x->spi_cc1101_handle, 1); flipper_format_rewind(file); flipper_format_read_uint32(file, "spi_nrf24_handle", (uint32_t*)&x->spi_nrf24_handle, 1); @@ -99,6 +102,7 @@ void CFW_SETTINGS_SAVE() { flipper_format_write_bool(file, "sort_dirs_first", &x->sort_dirs_first, 1); flipper_format_write_bool(file, "dark_mode", &x->dark_mode, 1); flipper_format_write_uint32(file, "charge_cap", &x->charge_cap, 1); + flipper_format_write_uint32(file, "favorite_timeout", &x->favorite_timeout, 1); flipper_format_write_uint32( file, "spi_cc1101_handle", (uint32_t*)&x->spi_cc1101_handle, 1); flipper_format_write_uint32(file, "spi_nrf24_handle", (uint32_t*)&x->spi_nrf24_handle, 1); diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 86c30c08cf2..54b6344484b 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,6 +1,7 @@ entry,status,name,type,params Version,+,50.3,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, +Header,+,applications/main/archive/helpers/archive_helpers_ext.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -951,6 +952,8 @@ Function,-,expm1l,long double,long double Function,-,fabs,double,double Function,-,fabsf,float,float Function,-,fabsl,long double,long double +Function,+,favorite_timeout_callback,void,void* +Function,+,favorite_timeout_run,void,"ViewDispatcher*, SceneManager*" Function,-,fclose,int,FILE* Function,-,fcloseall,int, Function,-,fdim,double,"double, double" @@ -2716,6 +2719,7 @@ Function,+,powf,float,"float, float" Function,-,powl,long double,"long double, long double" Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t" Function,-,printf,int,"const char*, ..." +Function,+,process_favorite_launch,_Bool,char** Function,+,property_value_out,void,"PropertyValueContext*, const char*, unsigned int, ..." Function,+,protocol_dict_alloc,ProtocolDict*,"const ProtocolBase**, size_t" Function,+,protocol_dict_decoders_feed,ProtocolId,"ProtocolDict*, _Bool, uint32_t" @@ -2798,8 +2802,9 @@ Function,-,rintl,long double,long double Function,-,round,double,double Function,+,roundf,float,float Function,-,roundl,long double,long double +Function,+,rpc_get_sessions_count,size_t,Rpc* Function,+,rpc_session_close,void,RpcSession* -Function,+,rpc_session_feed,size_t,"RpcSession*, uint8_t*, size_t, uint32_t" +Function,+,rpc_session_feed,size_t,"RpcSession*, const uint8_t*, size_t, uint32_t" Function,+,rpc_session_get_available_size,size_t,RpcSession* Function,+,rpc_session_get_owner,RpcOwner,RpcSession* Function,+,rpc_session_open,RpcSession*,"Rpc*, RpcOwner" diff --git a/targets/f7/furi_hal/furi_hal_subghz_i.h b/targets/f7/furi_hal/furi_hal_subghz_i.h new file mode 100644 index 00000000000..85532a5d368 --- /dev/null +++ b/targets/f7/furi_hal/furi_hal_subghz_i.h @@ -0,0 +1,3 @@ +#pragma once + +void furi_hal_subghz_set_extended_frequency(bool state_i); \ No newline at end of file