From a5b3d71e5963876cc88bd4692b15cb2e56437cb1 Mon Sep 17 00:00:00 2001 From: Anna Antonenko Date: Mon, 16 Sep 2024 15:37:40 +0300 Subject: [PATCH 1/8] feat: cli icon on the desktop --- applications/services/cli/cli_vcp.c | 35 ++++++++++++++++++ assets/icons/StatusBar/Console_active_8x8.png | Bin 0 -> 4347 bytes 2 files changed, 35 insertions(+) create mode 100644 assets/icons/StatusBar/Console_active_8x8.png diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index cdabaaa05..9eabd4d7d 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include #define TAG "CliVcp" @@ -43,6 +46,10 @@ typedef struct { FuriHalUsbInterface* usb_if_prev; uint8_t data_buffer[USB_CDC_PKT_LEN]; + + // CLI icon + Gui* gui; + ViewPort* view_port; } CliVcp; static int32_t vcp_worker(void* context); @@ -64,6 +71,13 @@ static CliVcp* vcp = NULL; static const uint8_t ascii_soh = 0x01; static const uint8_t ascii_eot = 0x04; +static void cli_vcp_icon_draw_callback(Canvas* canvas, void* context) { + furi_assert(canvas); + furi_assert(context); + const Icon* icon = context; + canvas_draw_icon(canvas, 0, 0, icon); +} + static void cli_vcp_init(void) { if(vcp == NULL) { vcp = malloc(sizeof(CliVcp)); @@ -115,6 +129,18 @@ static int32_t vcp_worker(void* context) { if(vcp->connected == false) { vcp->connected = true; furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); + + // GUI icon + furi_assert(!vcp->gui); + furi_assert(!vcp->view_port); + const Icon* icon = &I_Console_active_8x8; + vcp->gui = furi_record_open(RECORD_GUI); + vcp->view_port = view_port_alloc(); + view_port_set_width(vcp->view_port, icon_get_width(icon)); + // casting const away. we know that we cast it right back in the callback + view_port_draw_callback_set( + vcp->view_port, cli_vcp_icon_draw_callback, (void*)icon); + gui_add_view_port(vcp->gui, vcp->view_port, GuiLayerStatusBarLeft); } } @@ -126,6 +152,15 @@ static int32_t vcp_worker(void* context) { vcp->connected = false; furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + + // remove GUI icon + furi_assert(vcp->gui); + furi_assert(vcp->view_port); + gui_remove_view_port(vcp->gui, vcp->view_port); + view_port_free(vcp->view_port); + furi_record_close(RECORD_GUI); + vcp->gui = NULL; + vcp->view_port = NULL; } } diff --git a/assets/icons/StatusBar/Console_active_8x8.png b/assets/icons/StatusBar/Console_active_8x8.png new file mode 100644 index 0000000000000000000000000000000000000000..0423c12563b7602ed5ca6b513b2ceb9eab3751f8 GIT binary patch literal 4347 zcmeHKeQZ-z6o2jb7-Qg^AYVgYIzU8T-$!4&_HBhhJ6Hpq1FEYZfUob}*FISLO8d5U z2pS0B_)x;YL39D4l1xQ|Mo>U;D09Tfha!-OAOS-Zi9{rTM49KkcHIahW{Lc_*WBLo z&OP^c?)lwwPkUEZR!kj`Gdu^wumPTO_e|)swU*rnz7O2DZ#9M)1|h#k@_5GSBmF_q z3p1qc3|(ZSAq&d_eFL+PPkM%{+H{O7^+F7VMYFE?1?;<-(&eMUtx# zh9#R8uXC1vSz6FK_nB?u1`jT-=fviU+8Ot^J-yuI%icNp-GO5^zA$P1iczhtGopn3 z#s~hI=zYhr2B$fiNF-#XAfdijI&Lj~8*pZ=`vbaBgE(sKM#z2O~c*xT-B z4~kXG&px*2+qHR9D4d?P<$=~wC2c32ixz#h`pWpr@fTm2Gdjq$Jd)S8DdImc;(+D# z#=~`6?BA?vn7pW>gg@GQ<-@zpd;k7w_t_m=f-7ED=WVu6A3x{^e?)ka^_`Q?)xR-s z!{sBNY>%Efx4rS*?RAge`l7PpnWrvrhh~i0Q9rsq4}Wu2{?|M5wmnhU>Rxs2{6n|+ zHnL&bn5uqj3i>yfF8}$){`RwpkEIvpedo<-U2=HHsar#{mhLTmQ#$oi+pg1ggYihq zt0%5hU2M7Z$gevaA9NUR?pm_?x5hD-4I7JFj;=QkYbfj;y7_0_*?-pTd$fP<8KZN4 zL^-s$X#yr+99NfBP+&aY`|CN^lZmS5mG;f@wd+}-DX}+BE^J;3d7PAee%0@t&IwA` z%!^6@nUmqDzKf^x)Zy1e&u6E2HRQy%-Evp5P z^n&g>BkrqX3zmDQq%TG$mrJ7*aLEu^3vj_N@HdAB(eg^XRaCRVN6hysbK zQ5Znuus-@WdsUV?$+~TA+K3)b*M)$)4E}A_9kJ`iVCD64ZbhikoO;|&leS(?R0LV% zbdeG)HY>%81aD&l1RD@V!r_qY1mj==HX*>U5+inj@j~GaCjl$um!A$ zpe;6 zizqu`W06IqDQh6WA{|QG2X0cO$7y2BRHvr0npY(y7IvDZ%aNL7=YUTRqgg7ikwzCW zHrDPavN#w^k&Q0uG$22f+Zbyq2ec ztm`2bPA{WM%%>>TPE)2fXNJ9SoJ3yb-B8uRTc%q3I;!GacOW~MUW1WLFPe-D03y#y#2fztNS`d7VNL z_!pFb%hJeCuX1qJ>JykY)t$OJ|K-~IB1rwBIguzx2z? zEhx5bpY|!JhN)$K)un{Bf92R6ckZes1BZYS>2Xi;4L$bWS~>@#a+iH{wSDfsirGeQ xBe!~MX~>_uD8J$A(wiHu5zXJfw(8gg!yjV@=5G4E?>d-@dCDr>?@xYi>A&8Jxyb+k literal 0 HcmV?d00001 From 15b271bd922ed0e315206492e67cc1469652aa4c Mon Sep 17 00:00:00 2001 From: Anna Antonenko Date: Mon, 16 Sep 2024 16:27:24 +0300 Subject: [PATCH 2/8] fix: cli autolock inhibit --- applications/services/cli/cli_vcp.c | 43 +++++++++++-------- applications/services/desktop/desktop.c | 43 ++++++++++++++++++- applications/services/desktop/desktop.h | 14 ++++++ applications/services/desktop/desktop_i.h | 1 + .../services/desktop/views/desktop_events.h | 2 + scripts/serial_cli.py | 2 +- 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index 9eabd4d7d..a74710284 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -5,6 +5,7 @@ #include #include #include +#include #define TAG "CliVcp" @@ -50,6 +51,9 @@ typedef struct { // CLI icon Gui* gui; ViewPort* view_port; + + // Autolocking inhibition + Desktop* desktop; } CliVcp; static int32_t vcp_worker(void* context); @@ -117,6 +121,15 @@ static int32_t vcp_worker(void* context) { FURI_LOG_D(TAG, "Start"); vcp->running = true; + // GUI icon + vcp->desktop = furi_record_open(RECORD_DESKTOP); + const Icon* icon = &I_Console_active_8x8; + vcp->gui = furi_record_open(RECORD_GUI); + vcp->view_port = view_port_alloc(); + view_port_set_width(vcp->view_port, icon_get_width(icon)); + // casting const away. we know that we cast it right back in the callback + view_port_draw_callback_set(vcp->view_port, cli_vcp_icon_draw_callback, (void*)icon); + while(1) { uint32_t flags = furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); @@ -129,18 +142,8 @@ static int32_t vcp_worker(void* context) { if(vcp->connected == false) { vcp->connected = true; furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); - - // GUI icon - furi_assert(!vcp->gui); - furi_assert(!vcp->view_port); - const Icon* icon = &I_Console_active_8x8; - vcp->gui = furi_record_open(RECORD_GUI); - vcp->view_port = view_port_alloc(); - view_port_set_width(vcp->view_port, icon_get_width(icon)); - // casting const away. we know that we cast it right back in the callback - view_port_draw_callback_set( - vcp->view_port, cli_vcp_icon_draw_callback, (void*)icon); gui_add_view_port(vcp->gui, vcp->view_port, GuiLayerStatusBarLeft); + desktop_api_add_external_inhibitor(vcp->desktop); } } @@ -152,15 +155,8 @@ static int32_t vcp_worker(void* context) { vcp->connected = false; furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); - - // remove GUI icon - furi_assert(vcp->gui); - furi_assert(vcp->view_port); gui_remove_view_port(vcp->gui, vcp->view_port); - view_port_free(vcp->view_port); - furi_record_close(RECORD_GUI); - vcp->gui = NULL; - vcp->view_port = NULL; + desktop_api_remove_external_inhibitor(vcp->desktop); } } @@ -225,6 +221,10 @@ static int32_t vcp_worker(void* context) { } if(flags & VcpEvtStop) { + if(vcp->connected) { + gui_remove_view_port(vcp->gui, vcp->view_port); + desktop_api_remove_external_inhibitor(vcp->desktop); + } vcp->connected = false; vcp->running = false; furi_hal_cdc_set_callbacks(VCP_IF_NUM, NULL, NULL); @@ -238,6 +238,11 @@ static int32_t vcp_worker(void* context) { break; } } + + view_port_free(vcp->view_port); + furi_record_close(RECORD_DESKTOP); + furi_record_close(RECORD_GUI); + FURI_LOG_D(TAG, "End"); return 0; } diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index e57e1eb00..93d00c78d 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -19,6 +19,8 @@ static void desktop_auto_lock_arm(Desktop*); static void desktop_auto_lock_inhibit(Desktop*); static void desktop_start_auto_lock_timer(Desktop*); static void desktop_apply_settings(Desktop*); +static void desktop_auto_lock_add_inhibitor(Desktop* desktop); +static void desktop_auto_lock_remove_inhibitor(Desktop* desktop); static void desktop_loader_callback(const void* message, void* context) { furi_assert(context); @@ -130,16 +132,22 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { animation_manager_unload_and_stall_animation(desktop->animation_manager); } - desktop_auto_lock_inhibit(desktop); + desktop_auto_lock_add_inhibitor(desktop); desktop->app_running = true; furi_semaphore_release(desktop->animation_semaphore); } else if(event == DesktopGlobalAfterAppFinished) { animation_manager_load_and_continue_animation(desktop->animation_manager); - desktop_auto_lock_arm(desktop); + desktop_auto_lock_remove_inhibitor(desktop); desktop->app_running = false; + } else if(event == DesktopGlobalAddExternalInhibitor) { + desktop_auto_lock_add_inhibitor(desktop); + + } else if(event == DesktopGlobalRemoveExternalInhibitor) { + desktop_auto_lock_remove_inhibitor(desktop); + } else if(event == DesktopGlobalAutoLock) { if(!desktop->app_running && !desktop->locked) { desktop_lock(desktop); @@ -205,6 +213,24 @@ static void desktop_auto_lock_arm(Desktop* desktop) { } } +static void desktop_auto_lock_add_inhibitor(Desktop* desktop) { + furi_check(furi_semaphore_release(desktop->auto_lock_inhibitors) == FuriStatusOk); + FURI_LOG_D( + TAG, + "%lu autolock inhibitors (+1)", + furi_semaphore_get_count(desktop->auto_lock_inhibitors)); + desktop_auto_lock_inhibit(desktop); +} + +static void desktop_auto_lock_remove_inhibitor(Desktop* desktop) { + furi_check(furi_semaphore_acquire(desktop->auto_lock_inhibitors, 0) == FuriStatusOk); + uint32_t inhibitors = furi_semaphore_get_count(desktop->auto_lock_inhibitors); + FURI_LOG_D(TAG, "%lu autolock inhibitors (-1)", inhibitors); + if(inhibitors == 0) { + desktop_auto_lock_arm(desktop); + } +} + static void desktop_auto_lock_inhibit(Desktop* desktop) { desktop_stop_auto_lock_timer(desktop); if(desktop->input_events_subscription) { @@ -371,6 +397,7 @@ static Desktop* desktop_alloc(void) { desktop->notification = furi_record_open(RECORD_NOTIFICATION); desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); + desktop->auto_lock_inhibitors = furi_semaphore_alloc(UINT32_MAX, 0); desktop->auto_lock_timer = furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); @@ -503,6 +530,18 @@ void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings view_dispatcher_send_custom_event(instance->view_dispatcher, DesktopGlobalSaveSettings); } +void desktop_api_add_external_inhibitor(Desktop* instance) { + furi_assert(instance); + view_dispatcher_send_custom_event( + instance->view_dispatcher, DesktopGlobalAddExternalInhibitor); +} + +void desktop_api_remove_external_inhibitor(Desktop* instance) { + furi_assert(instance); + view_dispatcher_send_custom_event( + instance->view_dispatcher, DesktopGlobalRemoveExternalInhibitor); +} + /* * Application thread */ diff --git a/applications/services/desktop/desktop.h b/applications/services/desktop/desktop.h index e83bc3ee4..4f1556f7c 100644 --- a/applications/services/desktop/desktop.h +++ b/applications/services/desktop/desktop.h @@ -21,3 +21,17 @@ FuriPubSub* desktop_api_get_status_pubsub(Desktop* instance); void desktop_api_get_settings(Desktop* instance, DesktopSettings* settings); void desktop_api_set_settings(Desktop* instance, const DesktopSettings* settings); + +/** + * @brief Adds 1 to the count of active external autolock inhibitors + * + * Autolocking will not get triggered while there's at least 1 inhibitor + */ +void desktop_api_add_external_inhibitor(Desktop* instance); + +/** + * @brief Removes 1 from the count of active external autolock inhibitors + * + * Autolocking will not get triggered while there's at least 1 inhibitor + */ +void desktop_api_remove_external_inhibitor(Desktop* instance); diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index 1dc7c7d21..b62dac63c 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -73,6 +73,7 @@ struct Desktop { FuriPubSub* input_events_pubsub; FuriPubSubSubscription* input_events_subscription; + FuriSemaphore* auto_lock_inhibitors; FuriTimer* auto_lock_timer; FuriTimer* update_clock_timer; diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 07631dfac..94348184d 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -57,4 +57,6 @@ typedef enum { DesktopGlobalApiUnlock, DesktopGlobalSaveSettings, DesktopGlobalReloadSettings, + DesktopGlobalAddExternalInhibitor, + DesktopGlobalRemoveExternalInhibitor, } DesktopEvent; diff --git a/scripts/serial_cli.py b/scripts/serial_cli.py index 8e35d57fa..095b5dd35 100644 --- a/scripts/serial_cli.py +++ b/scripts/serial_cli.py @@ -13,7 +13,7 @@ def main(): parser.add_argument("-p", "--port", help="CDC Port", default="auto") args = parser.parse_args() if not (port := resolve_port(logger, args.port)): - logger.error("Is Flipper connected via USB and not in DFU mode?") + logger.error("Is Flipper connected via USB, currently unlocked and not in DFU mode?") return 1 subprocess.call( [ From 1a9aca2d8c6e1c8625ea5200423844973621a696 Mon Sep 17 00:00:00 2001 From: Anna Antonenko Date: Mon, 16 Sep 2024 17:11:31 +0300 Subject: [PATCH 3/8] fix: always autolock if pin set --- applications/services/desktop/desktop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 93d00c78d..ceea867ba 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -562,7 +562,7 @@ int32_t desktop_srv(void* p) { scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { + if(desktop_pin_code_is_set()) { desktop_lock(desktop); } From 4a8202514d7b6b6695667c083cd32b611d40f7c5 Mon Sep 17 00:00:00 2001 From: Anna Antonenko Date: Mon, 16 Sep 2024 19:29:55 +0300 Subject: [PATCH 4/8] style: fix linter errors --- assets/icons/StatusBar/Console_active_8x8.png | Bin 4347 -> 4559 bytes scripts/serial_cli.py | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/icons/StatusBar/Console_active_8x8.png b/assets/icons/StatusBar/Console_active_8x8.png index 0423c12563b7602ed5ca6b513b2ceb9eab3751f8..794f4e59726186ddc3c0998ba81fe8814c86ad72 100644 GIT binary patch delta 703 zcmeyZcwTve1Scai0|UdqgE}WBD&{dVPn_V)`$v<3AsQ$MrYAm-Ww*34va~X`oXo;# zSsz^zBE`VK*qZ6=9N_8ftWZ#tpO%@E%D_-Dr*@*P$6*JFw)@+>LbbTW1WQi@%zd*+ zsc$Qn>k5Ia)-YKgy}!+Byq;a%iyuT4d`RE;>cOKmtD9FVaQthqu(r_L<}s6DjY_wM22 z-?3BDE3f~xteQIKB*T0MndDuGg82gHbE2%C*FG}P_Tu_z`LV@OT&3>Gt~Z~gpEn(@ znl6k_iIMw`yX6FQ%Jq|Zt%e{Y>_5SvL z)3g8nGSuxZTD>ky{4N6nU-agyOkGSWCTSKaNtVV2x|U|C2D&C@h8DU>$p#j>rYUL3 ziOI=^=H_XMlbc!lxlIjB3@r@I%q$GeCd;z*!J~N-n>viW`2m|C<77Ve7?tFdG?UcC zRAXHO!xUp(6AKF?-9$@+L|vn#R3l3>OCv)QW24D^?0yiPCI*`yv*&Rr^L>-v2TVz9 z0X`wFK>Gjx|4VPq2fCGkG0EHAg`tC0)?;$IfFiqqtj1o`MDxl00vhTXJIEZ3k6x-JDr((fm9oOGEKu-x zRI5@5$5yA+d}`C{94EJ_96cIXplk7CV?=2|;kBy=Lj_pu9p=c+5s6)LYEP6RcVqdU1Cn8gttDZ*WPupU%<^k!7zBf@KF_;DRW#?$^`Q-ZM_OK5${O zp5!ED){I}DDaIzd*A3T;fv#G<_n;)_XGH$-gk-#A)yXT7)Fio%} zdAqv+X(0INyt{sKgrFijkBqhH8t*-m8w536^gUf1LnJP*?Kk9NFyLv~^5uX0KEGHd x-)UCe3mh^ccxr?ueQEkN<(uw`E3>*TKV$r;!N)V>9s5L(fu62@F6*2UngGI64HW Date: Tue, 17 Sep 2024 13:26:28 +0300 Subject: [PATCH 5/8] style: fix linter error(?) --- assets/icons/StatusBar/Console_active_8x8.png | Bin 4559 -> 75 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/icons/StatusBar/Console_active_8x8.png b/assets/icons/StatusBar/Console_active_8x8.png index 794f4e59726186ddc3c0998ba81fe8814c86ad72..f2230a374fc93be0309b026550135d2c21c155fb 100644 GIT binary patch delta 56 zcmX@F>^(u!hye)Rlr*aWDIrf6$B>FS$q5Zi>};%Rwrp$+%uEaub)uI30;%$J^>bP0 Hl+XkKg!m2J literal 4559 zcmeHLYitx%6rL^8LP@b84*_e&K}?Ix&SPh%Gh>%hb_-o(aV?9KhlbgiJKKTXon>~~ zZZQ%BK`Wq$ijp804WeKmAcBH|icyR)K7ObK6a=EE2)=?31Uxgl-L}ERG|Iou=Jwt> z=iKj}^WAgL_HJ8v%EXf5;l&t+l?3Yo_0adRo2wW6z4+#sgBa!-gc^ccFgV)L^aH_F zm@8-J>NGBZIrgm8(E7Uyuz}D&32h+AZF{>7clCDq%`hI38}EQ|dCtb3&%oRg==VTl zVLS+Wa0Aot&#rp}#`e?4`S?vFTS&!QbgL1c7z~B6zbY_n7UNCpy^=vsngF854~Jm`+Vu#rFWD~c3)U>Q%Uf_<Fkj9;a^UWx=gr^Bj%|Bl?cC65 zei)xAeRI!o`sPW+KZ!rxS2Og+g(vr%{&~bViw`VZKaBt6h1TQr_Hd)}>dF}(hub!_ zjeKzP?fa@v?0Bnn`Aajm?)cjGM?b%qKx@C>IpL8vh&A~5MJq;6DnBs(vF4S7uBnh7 zzWew4%l6l~*UlbAn`53X7`*yK(WNCvU-$kp_0eQ~d4Fr)=jYzNw)9Bv;oid+$L{*! zoxY`+!mT^k?5{7Otg6nWWMv+*@F&*^??aF2zc`mjh2;?D5|BU#ogj@8)l4RL{X$@mSR~FEXZ_g z(vmY|GCk6U$YKOgS~2yMr5j1y#+0K*ljS1_(Btj?B~qbK9zL1Qu>gEf897BUZkkFY zsLnIeR&6tY+YZ|PbGSzUayHBLC49f9TY_+6~qV|R?fDio3ehSFp&8VvXd z+h0jF6kU~^A+30LFDfLqikd*OA{*tED9dTA+6gL{Oj~kNK{gbCyLG_f zG(nAu9-0(+M3WrP2xL^D1=6c(imWJ1Wu+!}g1F7pAuHv0XRmB16`)v6)-*4}le9pK zB*$(B5d2Lk^U^4^mAy=p$G+-609bWlJ;6gpZi4Cz~=Iiin;-Q!Uvh zjj3cIVvZ4Lo);Ltvcu>OWTqkEY)q$;IvQ1xCIF%giK8dv7@|_in4_?_MS@^}SlP}~ zKz8I1i{#W%!;Bb4+(+b#b6y>SDUEV6hM;=n z(zRW#|3fMujb?b3lSzSB?QHUTNkQWT5^*f6@nWSwv)QQf=xIZmtxG|z6{G- zM(l&zWMO!6q!#*1mo9BQv;i)jm@9hg!~pg{@3K00>6@yXk;X9hNV~Z*8>^c^SY!o5 zwMD1;mX?;4zwVVQK{U*&ZLs`C!oG!Im;J~v{oejV!DwJGP!s9%nKEZlK~Z7v!s^08 Ytk+CzTk_ Date: Fri, 20 Sep 2024 06:35:46 +0300 Subject: [PATCH 6/8] Frequency analyzer fixes and improvements disable ext module due to lack of required hardware on them and incorrect usage of freq analyzer, like trying to receive "signals" with it (from the space??), while it should be used only to get frequency of the remote placed around 1-10cm around flipper's left corner Also fix possible GSM mobile towers signal interference by limiting upper freq to 920mhz max Fix dupliacted freq lists and use user config for nearest freq selector too (finally) --- .../subghz_frequency_analyzer_worker.c | 48 ++++++-- .../subghz_frequency_analyzer_worker.h | 5 + .../subghz/views/subghz_frequency_analyzer.c | 104 ++---------------- documentation/SubGHzSettings.md | 2 + lib/subghz/subghz_setting.c | 2 + 5 files changed, 55 insertions(+), 106 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index 00ce0fb04..3894f022f 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -132,11 +132,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { uint32_t current_frequency = subghz_setting_get_frequency(instance->setting, i); // if(furi_hal_subghz_is_frequency_valid(current_frequency) && if(subghz_devices_is_frequency_valid(radio_device, current_frequency) && - (current_frequency != 467750000) && (current_frequency != 464000000) && - !((instance->ext_radio) && - ((current_frequency == 390000000) || (current_frequency == 312000000) || - (current_frequency == 312100000) || (current_frequency == 312200000) || - (current_frequency == 440175000)))) { + (((current_frequency != 467750000) && (current_frequency != 464000000)) && + (current_frequency <= 920000000))) { furi_hal_spi_acquire(spi_bus); cc1101_switch_to_idle(spi_bus); frequency = cc1101_set_frequency(spi_bus, current_frequency); @@ -323,18 +320,21 @@ void subghz_frequency_analyzer_worker_start( furi_assert(instance); furi_assert(!instance->worker_running); + /* SubGhzRadioDeviceType radio_type = subghz_txrx_radio_device_get(txrx); if(radio_type == SubGhzRadioDeviceTypeExternalCC1101) { instance->spi_bus = &furi_hal_spi_bus_handle_external; instance->ext_radio = true; } else if(radio_type == SubGhzRadioDeviceTypeInternal) { - instance->spi_bus = &furi_hal_spi_bus_handle_subghz; - instance->ext_radio = false; + */ + instance->spi_bus = &furi_hal_spi_bus_handle_subghz; + /* + instance->ext_radio = false; } else { - furi_crash("Unsuported external module"); + furi_crash("Wrong subghz radio type"); } - + */ instance->radio_device = subghz_devices_get_by_name(subghz_txrx_radio_device_get_name(txrx)); instance->worker_running = true; @@ -365,3 +365,33 @@ void subghz_frequency_analyzer_worker_set_trigger_level( float subghz_frequency_analyzer_worker_get_trigger_level(SubGhzFrequencyAnalyzerWorker* instance) { return instance->trigger_level; } + +uint32_t subghz_frequency_analyzer_get_nearest_frequency( + SubGhzFrequencyAnalyzerWorker* instance, + uint32_t input) { + uint32_t prev_freq = 0; + uint32_t result = 0; + uint32_t current; + + for(size_t i = 0; i < subghz_setting_get_frequency_count(instance->setting); i++) { + current = subghz_setting_get_frequency(instance->setting, i); + if(current == 0) { + continue; + } + if(current == input) { + result = current; + break; + } + if(current > input && prev_freq < input) { + if(current - input < input - prev_freq) { + result = current; + } else { + result = prev_freq; + } + break; + } + prev_freq = current; + } + + return result; +} diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h index 1b21c39e9..6533571d5 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h @@ -78,3 +78,8 @@ void subghz_frequency_analyzer_worker_set_trigger_level( * @return RSSI trigger level */ float subghz_frequency_analyzer_worker_get_trigger_level(SubGhzFrequencyAnalyzerWorker* instance); + +// Round up the frequency +uint32_t subghz_frequency_analyzer_get_nearest_frequency( + SubGhzFrequencyAnalyzerWorker* instance, + uint32_t input); diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index fde3a1f61..2ce2dfbbf 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -20,71 +20,6 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif -static const uint32_t subghz_frequency_list[] = { - /* 300 - 348 */ - 300000000, - 302757000, - 303875000, - 303900000, - 304250000, - 307000000, - 307500000, - 307800000, - 309000000, - 310000000, - 312000000, - 312100000, - 312200000, - 313000000, - 313850000, - 314000000, - 314350000, - 314980000, - 315000000, - 318000000, - 330000000, - 345000000, - 348000000, - 350000000, - - /* 387 - 464 */ - 387000000, - 390000000, - 418000000, - 430000000, - 430500000, - 431000000, - 431500000, - 433075000, /* LPD433 first */ - 433220000, - 433420000, - 433657070, - 433889000, - 433920000, /* LPD433 mid */ - 434075000, - 434176948, - 434190000, - 434390000, - 434420000, - 434620000, - 434775000, /* LPD433 last channels */ - 438900000, - 440175000, - 464000000, - 467750000, - - /* 779 - 928 */ - 779000000, - 868350000, - 868400000, - 868800000, - 868950000, - 906400000, - 915000000, - 925000000, - 928000000, -}; - typedef enum { SubGhzFrequencyAnalyzerStatusIDLE, } SubGhzFrequencyAnalyzerStatus; @@ -225,7 +160,7 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 7, model->is_ext_radio ? "Ext" : "Int"); + //canvas_draw_str(canvas, 0, 7, model->is_ext_radio ? "Ext" : "Int"); canvas_draw_str(canvas, 20, 7, "Frequency Analyzer"); // RSSI @@ -278,34 +213,6 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel elements_button_right(canvas, "+T"); } -uint32_t subghz_frequency_find_correct(uint32_t input) { - uint32_t prev_freq = 0; - uint32_t result = 0; - uint32_t current; - - for(size_t i = 0; i < ARRAY_SIZE(subghz_frequency_list) - 1; i++) { - current = subghz_frequency_list[i]; - if(current == 0) { - continue; - } - if(current == input) { - result = current; - break; - } - if(current > input && prev_freq < input) { - if(current - input < input - prev_freq) { - result = current; - } else { - result = prev_freq; - } - break; - } - prev_freq = current; - } - - return result; -} - bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { furi_assert(context); SubGhzFrequencyAnalyzer* instance = (SubGhzFrequencyAnalyzer*)context; @@ -364,7 +271,8 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { } else if( (model->show_frame && model->signal) || (!model->show_frame && model->signal)) { - frequency_candidate = subghz_frequency_find_correct(model->frequency); + frequency_candidate = subghz_frequency_analyzer_get_nearest_frequency( + instance->worker, model->frequency); } frequency_candidate = frequency_candidate == 0 || @@ -372,7 +280,8 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { instance->txrx, frequency_candidate) || prev_freq_to_save == frequency_candidate ? 0 : - subghz_frequency_find_correct(frequency_candidate); + subghz_frequency_analyzer_get_nearest_frequency( + instance->worker, frequency_candidate); if(frequency_candidate > 0 && frequency_candidate != model->frequency_to_save) { model->frequency_to_save = frequency_candidate; updated = true; @@ -445,7 +354,8 @@ void subghz_frequency_analyzer_pair_callback( SubGhzFrequencyAnalyzerModel * model, { bool in_array = false; - uint32_t normal_frequency = subghz_frequency_find_correct(model->frequency); + uint32_t normal_frequency = subghz_frequency_analyzer_get_nearest_frequency( + instance->worker, model->frequency); for(size_t i = 0; i < MAX_HISTORY; i++) { if(model->history_frequency[i] == normal_frequency) { in_array = true; diff --git a/documentation/SubGHzSettings.md b/documentation/SubGHzSettings.md index 3c952a1a3..a93618778 100644 --- a/documentation/SubGHzSettings.md +++ b/documentation/SubGHzSettings.md @@ -30,6 +30,8 @@ if you need your custom one, make sure it doesn't listed here 314980000, 315000000, 318000000, + 320000000, + 320150000, 330000000, 345000000, 348000000, diff --git a/lib/subghz/subghz_setting.c b/lib/subghz/subghz_setting.c index a7c3ee1df..2ee02c7f9 100644 --- a/lib/subghz/subghz_setting.c +++ b/lib/subghz/subghz_setting.c @@ -36,6 +36,8 @@ static const uint32_t subghz_frequency_list[] = { 314980000, 315000000, 318000000, + 320000000, + 320150000, 330000000, 345000000, 348000000, From 16e4b9219aa9136ce55afeabf2cf4e5e992fea3d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 21 Sep 2024 03:49:55 +0300 Subject: [PATCH 7/8] merge ofw pr 3885 - Add API to enforce ISO15693 mode [ci skip] by aaronjamt https://github.com/flipperdevices/flipperzero-firmware/pull/3885/files --- lib/nfc/nfc.c | 27 ++++++++++++++++++ lib/nfc/nfc.h | 24 ++++++++++++++++ .../parsers/iso15693/iso15693_parser.c | 28 +++++++++++++++++-- .../parsers/iso15693/iso15693_parser.h | 4 +++ targets/f7/api_symbols.csv | 6 ++++ targets/f7/furi_hal/furi_hal_nfc_iso15693.c | 18 ++++++++++++ targets/furi_hal_include/furi_hal_nfc.h | 18 ++++++++++++ 7 files changed, 122 insertions(+), 3 deletions(-) diff --git a/lib/nfc/nfc.c b/lib/nfc/nfc.c index 90e65b282..4f4358711 100644 --- a/lib/nfc/nfc.c +++ b/lib/nfc/nfc.c @@ -646,6 +646,33 @@ NfcError nfc_iso15693_listener_tx_sof(Nfc* instance) { return ret; } +NfcError nfc_iso15693_detect_mode(Nfc* instance) { + furi_check(instance); + + FuriHalNfcError error = furi_hal_nfc_iso15693_detect_mode(); + NfcError ret = nfc_process_hal_error(error); + + return ret; +} + +NfcError nfc_iso15693_force_1outof4(Nfc* instance) { + furi_check(instance); + + FuriHalNfcError error = furi_hal_nfc_iso15693_force_1outof4(); + NfcError ret = nfc_process_hal_error(error); + + return ret; +} + +NfcError nfc_iso15693_force_1outof256(Nfc* instance) { + furi_check(instance); + + FuriHalNfcError error = furi_hal_nfc_iso15693_force_1outof256(); + NfcError ret = nfc_process_hal_error(error); + + return ret; +} + NfcError nfc_felica_listener_set_sensf_res_data( Nfc* instance, const uint8_t* idm, diff --git a/lib/nfc/nfc.h b/lib/nfc/nfc.h index 8fbf90d1f..ebd29dc4b 100644 --- a/lib/nfc/nfc.h +++ b/lib/nfc/nfc.h @@ -380,6 +380,30 @@ NfcError nfc_felica_listener_set_sensf_res_data( */ NfcError nfc_iso15693_listener_tx_sof(Nfc* instance); +/** + * @brief Set ISO15693 parser mode to autodetect + * +* @param[in,out] instance pointer to the instance to be configured. + * @returns NfcErrorNone on success, any other error code on failure. +*/ +NfcError nfc_iso15693_detect_mode(Nfc* instance); + +/** + * @brief Set ISO15693 parser mode to 1OutOf4, disables autodetection + * + * @param[in,out] instance pointer to the instance to be configured. + * @return NfcErrorNone on success, any other error code on failure. +*/ +NfcError nfc_iso15693_force_1outof4(Nfc* instance); + +/** + * @brief Set ISO15693 parser mode to 1OutOf256, disables autodetection + * + * @param[in,out] instance pointer to the instance to be configured. + * @return NfcErrorNone on success, any other error code on failure. +*/ +NfcError nfc_iso15693_force_1outof256(Nfc* instance); + #ifdef __cplusplus } #endif diff --git a/lib/signal_reader/parsers/iso15693/iso15693_parser.c b/lib/signal_reader/parsers/iso15693/iso15693_parser.c index a2c6912e6..d2f538c5e 100644 --- a/lib/signal_reader/parsers/iso15693/iso15693_parser.c +++ b/lib/signal_reader/parsers/iso15693/iso15693_parser.c @@ -26,6 +26,7 @@ typedef enum { struct Iso15693Parser { Iso15693ParserState state; Iso15693ParserMode mode; + bool detect_mode; SignalReader* signal_reader; @@ -62,6 +63,7 @@ typedef Iso15693ParserCommand (*Iso15693ParserStateHandler)(Iso15693Parser* inst Iso15693Parser* iso15693_parser_alloc(const GpioPin* pin, size_t max_frame_size) { Iso15693Parser* instance = malloc(sizeof(Iso15693Parser)); + instance->detect_mode = true; instance->parsed_frame = bit_buffer_alloc(max_frame_size); instance->signal_reader = signal_reader_alloc(pin, ISO15693_PARSER_SIGNAL_READER_BUFF_SIZE); @@ -86,7 +88,7 @@ void iso15693_parser_reset(Iso15693Parser* instance) { furi_assert(instance); instance->state = Iso15693ParserStateParseSoF; - instance->mode = Iso15693ParserMode1OutOf4; + if(instance->detect_mode) instance->mode = Iso15693ParserMode1OutOf4; memset(instance->bitstream_buff, 0x00, sizeof(instance->bitstream_buff)); instance->bitstream_idx = 0; @@ -122,10 +124,10 @@ static void signal_reader_callback(SignalReaderEvent event, void* context) { if(instance->state == Iso15693ParserStateParseSoF) { if(event.data->data[0] == sof_1_out_of_4) { - instance->mode = Iso15693ParserMode1OutOf4; + if(instance->detect_mode) instance->mode = Iso15693ParserMode1OutOf4; instance->state = Iso15693ParserStateParseFrame; } else if(event.data->data[0] == sof_1_out_of_256) { - instance->mode = Iso15693ParserMode1OutOf256; + if(instance->detect_mode) instance->mode = Iso15693ParserMode1OutOf256; instance->state = Iso15693ParserStateParseFrame; } else if(event.data->data[0] == eof_single) { instance->eof_received = true; @@ -298,3 +300,23 @@ void iso15693_parser_get_data( bit_buffer_write_bytes(instance->parsed_frame, buff, buff_size); *data_bits = bit_buffer_get_size(instance->parsed_frame); } + +void iso15693_parser_detect_mode(Iso15693Parser* instance) { + furi_assert(instance); + + instance->detect_mode = true; +} + +void iso15693_parser_force_1outof4(Iso15693Parser* instance) { + furi_assert(instance); + + instance->detect_mode = false; + instance->mode = Iso15693ParserMode1OutOf4; +} + +void iso15693_parser_force_1outof256(Iso15693Parser* instance) { + furi_assert(instance); + + instance->detect_mode = false; + instance->mode = Iso15693ParserMode1OutOf256; +} \ No newline at end of file diff --git a/lib/signal_reader/parsers/iso15693/iso15693_parser.h b/lib/signal_reader/parsers/iso15693/iso15693_parser.h index 3017a96d7..66486e0e7 100644 --- a/lib/signal_reader/parsers/iso15693/iso15693_parser.h +++ b/lib/signal_reader/parsers/iso15693/iso15693_parser.h @@ -37,6 +37,10 @@ void iso15693_parser_get_data( size_t buff_size, size_t* data_bits); +void iso15693_parser_detect_mode(Iso15693Parser* instance); +void iso15693_parser_force_1outof4(Iso15693Parser* instance); +void iso15693_parser_force_1outof256(Iso15693Parser* instance); + #ifdef __cplusplus } #endif diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 410e3e17e..a78a44c2e 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1489,6 +1489,9 @@ Function,+,furi_hal_nfc_iso14443a_poller_trx_short_frame,FuriHalNfcError,FuriHal Function,+,furi_hal_nfc_iso14443a_poller_tx_custom_parity,FuriHalNfcError,"const uint8_t*, size_t" Function,+,furi_hal_nfc_iso14443a_rx_sdd_frame,FuriHalNfcError,"uint8_t*, size_t, size_t*" Function,+,furi_hal_nfc_iso14443a_tx_sdd_frame,FuriHalNfcError,"const uint8_t*, size_t" +Function,+,furi_hal_nfc_iso15693_detect_mode,FuriHalNfcError, +Function,+,furi_hal_nfc_iso15693_force_1outof256,FuriHalNfcError, +Function,+,furi_hal_nfc_iso15693_force_1outof4,FuriHalNfcError, Function,+,furi_hal_nfc_iso15693_listener_tx_sof,FuriHalNfcError, Function,+,furi_hal_nfc_listener_enable_rx,FuriHalNfcError, Function,+,furi_hal_nfc_listener_idle,FuriHalNfcError, @@ -2831,6 +2834,9 @@ Function,+,nfc_iso14443a_listener_tx_custom_parity,NfcError,"Nfc*, const BitBuff Function,+,nfc_iso14443a_poller_trx_custom_parity,NfcError,"Nfc*, const BitBuffer*, BitBuffer*, uint32_t" Function,+,nfc_iso14443a_poller_trx_sdd_frame,NfcError,"Nfc*, const BitBuffer*, BitBuffer*, uint32_t" Function,+,nfc_iso14443a_poller_trx_short_frame,NfcError,"Nfc*, NfcIso14443aShortFrame, BitBuffer*, uint32_t" +Function,+,nfc_iso15693_detect_mode,NfcError,Nfc* +Function,+,nfc_iso15693_force_1outof256,NfcError,Nfc* +Function,+,nfc_iso15693_force_1outof4,NfcError,Nfc* Function,+,nfc_iso15693_listener_tx_sof,NfcError,Nfc* Function,+,nfc_listener_alloc,NfcListener*,"Nfc*, NfcProtocol, const NfcDeviceData*" Function,+,nfc_listener_free,void,NfcListener* diff --git a/targets/f7/furi_hal/furi_hal_nfc_iso15693.c b/targets/f7/furi_hal/furi_hal_nfc_iso15693.c index 3245b67cc..0fd5dbca5 100644 --- a/targets/f7/furi_hal/furi_hal_nfc_iso15693.c +++ b/targets/f7/furi_hal/furi_hal_nfc_iso15693.c @@ -406,6 +406,24 @@ FuriHalNfcError furi_hal_nfc_iso15693_listener_tx_sof(void) { return FuriHalNfcErrorNone; } +FuriHalNfcError furi_hal_nfc_iso15693_detect_mode(void) { + iso15693_parser_detect_mode(furi_hal_nfc_iso15693_listener->parser); + + return FuriHalNfcErrorNone; +} + +FuriHalNfcError furi_hal_nfc_iso15693_force_1outof4(void) { + iso15693_parser_force_1outof4(furi_hal_nfc_iso15693_listener->parser); + + return FuriHalNfcErrorNone; +} + +FuriHalNfcError furi_hal_nfc_iso15693_force_1outof256(void) { + iso15693_parser_force_1outof256(furi_hal_nfc_iso15693_listener->parser); + + return FuriHalNfcErrorNone; +} + static FuriHalNfcError furi_hal_nfc_iso15693_listener_rx( FuriHalSpiBusHandle* handle, uint8_t* rx_data, diff --git a/targets/furi_hal_include/furi_hal_nfc.h b/targets/furi_hal_include/furi_hal_nfc.h index 3a81de6f5..a651c9777 100644 --- a/targets/furi_hal_include/furi_hal_nfc.h +++ b/targets/furi_hal_include/furi_hal_nfc.h @@ -452,6 +452,24 @@ FuriHalNfcError furi_hal_nfc_iso14443a_listener_tx_custom_parity( */ FuriHalNfcError furi_hal_nfc_iso15693_listener_tx_sof(void); +/** Set ISO15693 parser mode to autodetect + * + * @return FuriHalNfcError +*/ +FuriHalNfcError furi_hal_nfc_iso15693_detect_mode(void); + +/** Set ISO15693 parser mode to 1OutOf4, disables autodetection + * + * @return FuriHalNfcError +*/ +FuriHalNfcError furi_hal_nfc_iso15693_force_1outof4(void); + +/** Set ISO15693 parser mode to 1OutOf256, disables autodetection + * + * @return FuriHalNfcError +*/ +FuriHalNfcError furi_hal_nfc_iso15693_force_1outof256(void); + /** * @brief Set FeliCa collision resolution parameters in listener mode. * From 42ab90b19b281d45e19b95b812093802617ca7a4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 21 Sep 2024 04:10:17 +0300 Subject: [PATCH 8/8] upd changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c6a456d..2864856cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,16 @@ ## Main changes - SubGHz: + - Frequency analyzer fixes and improvements: + - Enforce int module (like in OFW) usage due to lack of required hardware on external boards (PathIsolate (+rf switch for multiple paths)) and incorrect usage and/or understanding the purpose of frequency analyzer app by users, it should be used only to get frequency of the remote placed around 1-10cm around flipper's left corner + - Fix possible GSM mobile towers signal interference by limiting upper frequency to 920mhz max + - Fix duplicated frequency lists and use user config for nearest frequency selector too - Protocol improvements: - GangQi fix serial check - Hollarm add more button codes (thanks to @mishamyte for captures) * Apps: **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) ## Other changes +* OFW PR 3332: Autolock fixes (by @portasynthinca3) +* OFW PR 3885: Add API to enforce ISO15693 mode (by @aaronjamt) * OFW: kerel typo * OFW: Folder rename fails * OFW: Put errno into TCB