@@ -905,6 +905,13 @@ static const MenuCommand status_idle_commands[] = {
905905 .details_text = "Set idle status display to\n"
906906 "HUD-style overlay." ,
907907 },
908+ {
909+ .label = "Matrix" ,
910+ .command = "statusidle set matrix\n" ,
911+ .details_header = "Matrix Animation" ,
912+ .details_text = "Set idle status display to\n"
913+ "Matrix-style rain effect." ,
914+ },
908915};
909916
910917// BLE menu command definitions
@@ -1203,15 +1210,15 @@ static bool ir_query_and_parse_list(AppState* state) {
12031210 uart_reset_text_buffers (state -> uart_context );
12041211 send_uart_command ("ir list\n" , state );
12051212
1206- char * buffer = malloc (IR_UART_PARSE_BUF_SIZE );
1207- if (!buffer ) return false;
1213+ char buffer [IR_UART_PARSE_BUF_SIZE ];
12081214
12091215 size_t len = 0 ;
12101216 uint32_t start = furi_get_tick ();
12111217 const uint32_t timeout_ms = 2000 ;
12121218 while (furi_get_tick () - start < timeout_ms ) {
12131219 furi_delay_ms (100 );
1214- if (uart_copy_text_buffer (state -> uart_context , buffer , IR_UART_PARSE_BUF_SIZE , & len ) &&
1220+ if (uart_copy_text_buffer_tail (
1221+ state -> uart_context , buffer , IR_UART_PARSE_BUF_SIZE , & len ) &&
12151222 len > 0 ) {
12161223 if (strstr (buffer , "IR files in " ) || strstr (buffer , "(none)" ) ||
12171224 strstr (buffer , "(none)." ) || strchr (buffer , '[' )) {
@@ -1221,7 +1228,6 @@ static bool ir_query_and_parse_list(AppState* state) {
12211228 }
12221229
12231230 if (len == 0 ) {
1224- free (buffer );
12251231 return false;
12261232 }
12271233
@@ -1252,7 +1258,6 @@ static bool ir_query_and_parse_list(AppState* state) {
12521258 }
12531259 }
12541260
1255- free (buffer );
12561261 return state -> ir_remote_count > 0 ;
12571262}
12581263
@@ -1265,15 +1270,15 @@ static bool ir_query_and_parse_show(AppState* state, uint32_t remote_index) {
12651270 snprintf (cmd , sizeof (cmd ), "ir show %lu\n" , (unsigned long )remote_index );
12661271 send_uart_command (cmd , state );
12671272
1268- char * buffer = malloc (IR_UART_PARSE_BUF_SIZE );
1269- if (!buffer ) return false;
1273+ char buffer [IR_UART_PARSE_BUF_SIZE ];
12701274
12711275 size_t len = 0 ;
12721276 uint32_t start = furi_get_tick ();
12731277 const uint32_t timeout_ms = 3000 ;
12741278 while (furi_get_tick () - start < timeout_ms ) {
12751279 furi_delay_ms (100 );
1276- if (uart_copy_text_buffer (state -> uart_context , buffer , IR_UART_PARSE_BUF_SIZE , & len ) &&
1280+ if (uart_copy_text_buffer_tail (
1281+ state -> uart_context , buffer , IR_UART_PARSE_BUF_SIZE , & len ) &&
12771282 len > 0 ) {
12781283 if (strstr (buffer , "Signals in " ) || strstr (buffer , "Unique buttons in " ) ||
12791284 strchr (buffer , '[' )) {
@@ -1283,7 +1288,6 @@ static bool ir_query_and_parse_show(AppState* state, uint32_t remote_index) {
12831288 }
12841289
12851290 if (len == 0 ) {
1286- free (buffer );
12871291 return false;
12881292 }
12891293
@@ -1322,7 +1326,6 @@ static bool ir_query_and_parse_show(AppState* state, uint32_t remote_index) {
13221326 }
13231327 }
13241328
1325- free (buffer );
13261329 return state -> ir_signal_count > 0 ;
13271330}
13281331
@@ -1333,14 +1336,12 @@ static bool ir_query_and_parse_universals(AppState* state) {
13331336 send_uart_command ("ir universals list\n" , state );
13341337 furi_delay_ms (200 );
13351338
1336- char * buffer = malloc (IR_UART_PARSE_BUF_SIZE );
1337- if (!buffer ) return false;
1339+ char buffer [IR_UART_PARSE_BUF_SIZE ];
13381340
13391341 size_t len = 0 ;
1340- if (!uart_copy_text_buffer (
1342+ if (!uart_copy_text_buffer_tail (
13411343 state -> uart_context , buffer , IR_UART_PARSE_BUF_SIZE , & len ) ||
13421344 len == 0 ) {
1343- free (buffer );
13441345 return false;
13451346 }
13461347
@@ -1390,7 +1391,6 @@ static bool ir_query_and_parse_universals(AppState* state) {
13901391 }
13911392 }
13921393
1393- free (buffer );
13941394 return state -> ir_universal_count > 0 ;
13951395}
13961396
@@ -1406,8 +1406,7 @@ static bool ir_query_and_parse_universal_buttons(AppState* state, const char* fi
14061406 snprintf (cmd , sizeof (cmd ), "ir show %s\n" , path );
14071407 send_uart_command (cmd , state );
14081408
1409- char * buffer = malloc (IR_UART_PARSE_BUF_SIZE );
1410- if (!buffer ) return false;
1409+ char buffer [IR_UART_PARSE_BUF_SIZE ];
14111410
14121411 size_t len = 0 ;
14131412
@@ -1424,7 +1423,6 @@ static bool ir_query_and_parse_universal_buttons(AppState* state, const char* fi
14241423 }
14251424
14261425 if (len == 0 ) {
1427- free (buffer );
14281426 return false;
14291427 }
14301428
@@ -1477,7 +1475,6 @@ static bool ir_query_and_parse_universal_buttons(AppState* state, const char* fi
14771475 }
14781476
14791477 bool result = state -> ir_signal_count > 0 ;
1480- free (buffer );
14811478 return result ;
14821479}
14831480
@@ -1819,8 +1816,8 @@ static bool handle_ir_command_feedback_ex(
18191816
18201817 if (is_uni_sendall ) {
18211818 state -> previous_view = state -> current_view ;
1822- confirmation_view_set_header (state -> confirmation_view , "IR Sweep " );
1823- confirmation_view_set_text (state -> confirmation_view , "Transmitting sweep ...\nOK = Stop" );
1819+ confirmation_view_set_header (state -> confirmation_view , "Universal send " );
1820+ confirmation_view_set_text (state -> confirmation_view , "Universal sending ...\nOK = Stop" );
18241821 confirmation_view_set_ok_callback (state -> confirmation_view , ir_sweep_stop_callback , state );
18251822 confirmation_view_set_cancel_callback (
18261823 state -> confirmation_view , app_info_ok_callback , state );
@@ -1842,7 +1839,7 @@ static bool handle_ir_command_feedback_ex(
18421839 bool saw_ok = false;
18431840
18441841 uint32_t start = furi_get_tick ();
1845- const uint32_t timeout_ms = 5000 ;
1842+ const uint32_t timeout_ms = is_uni_sendall ? 60000 : 5000 ;
18461843
18471844 while (furi_get_tick () - start < timeout_ms ) {
18481845 furi_delay_ms (100 );
@@ -1873,7 +1870,8 @@ static bool handle_ir_command_feedback_ex(
18731870 char freq_str [24 ] = {0 };
18741871 char duty_str [16 ] = {0 };
18751872
1876- if (strstr (p , " raw " ) || strstr (p , " raw len=" )) {
1873+ if (strncmp (p , "raw " , 4 ) == 0 || strncmp (p , "raw len=" , 8 ) == 0 ||
1874+ strstr (p , " raw " ) || strstr (p , " raw len=" )) {
18771875 if (sscanf (
18781876 line ,
18791877 "IR: signal raw len=%15s freq=%31s duty=%15s" ,
@@ -1995,20 +1993,13 @@ static bool handle_ir_command_feedback_ex(
19951993 if (strstr (line , "universal sendall already running" )) {
19961994 strncpy (
19971995 message ,
1998- "Universal sweep already running; use 'stop' to cancel." ,
1996+ "Universal send already running; use 'stop' to cancel." ,
19991997 sizeof (message ) - 1 );
20001998 message [sizeof (message ) - 1 ] = '\0' ;
20011999 start = timeout_ms + start ;
20022000 break ;
20032001 }
20042002 if (strstr (line , "universal sendall started" )) {
2005- strncpy (
2006- message ,
2007- "Universal sending\nPress OK to stop and exit" ,
2008- sizeof (message ) - 1 );
2009- message [sizeof (message ) - 1 ] = '\0' ;
2010- start = timeout_ms + start ;
2011- break ;
20122003 }
20132004 if (strstr (line , "no builtin signals named" )) {
20142005 strncpy (message , "No builtin signals with that name." , sizeof (message ) - 1 );
@@ -2023,14 +2014,26 @@ static bool handle_ir_command_feedback_ex(
20232014 break ;
20242015 }
20252016 if (strstr (line , "universal sendall finished" )) {
2026- strncpy (message , "Universal sweep finished." , sizeof (message ) - 1 );
2017+ strncpy (message , "Universal send finished." , sizeof (message ) - 1 );
20272018 message [sizeof (message ) - 1 ] = '\0' ;
2019+ confirmation_view_set_header (state -> confirmation_view , "Universal send" );
2020+ confirmation_view_set_text (state -> confirmation_view , message );
2021+ confirmation_view_set_ok_callback (
2022+ state -> confirmation_view , app_info_ok_callback , state );
2023+ confirmation_view_set_cancel_callback (
2024+ state -> confirmation_view , app_info_ok_callback , state );
20282025 start = timeout_ms + start ;
20292026 break ;
20302027 }
20312028 if (strstr (line , "universal sendall stopped" )) {
2032- strncpy (message , "Universal sweep stopped." , sizeof (message ) - 1 );
2029+ strncpy (message , "Universal send stopped." , sizeof (message ) - 1 );
20332030 message [sizeof (message ) - 1 ] = '\0' ;
2031+ confirmation_view_set_header (state -> confirmation_view , "Universal send" );
2032+ confirmation_view_set_text (state -> confirmation_view , message );
2033+ confirmation_view_set_ok_callback (
2034+ state -> confirmation_view , app_info_ok_callback , state );
2035+ confirmation_view_set_cancel_callback (
2036+ state -> confirmation_view , app_info_ok_callback , state );
20342037 start = timeout_ms + start ;
20352038 break ;
20362039 }
@@ -2103,11 +2106,22 @@ static void text_input_result_callback(void* context) {
21032106 input_state -> connect_input_stage = 0 ;
21042107 input_state -> connect_ssid [0 ] = '\0' ;
21052108 } else {
2106- send_uart_command_with_text (
2107- input_state -> uart_command , input_state -> input_buffer , input_state );
2109+ if (input_state -> uart_command && strcmp (input_state -> uart_command , "ir send" ) == 0 ) {
2110+ char cmd [256 ];
2111+ snprintf (cmd , sizeof (cmd ), "ir send %s\n" , input_state -> input_buffer );
2112+ handle_ir_command_feedback_ex (input_state , cmd , true, true);
2113+ } else {
2114+ send_uart_command_with_text (
2115+ input_state -> uart_command , input_state -> input_buffer , input_state );
2116+ uart_receive_data (
2117+ input_state -> uart_context ,
2118+ input_state -> view_dispatcher ,
2119+ input_state ,
2120+ "" ,
2121+ "" ,
2122+ "" );
2123+ }
21082124 }
2109- uart_receive_data (
2110- input_state -> uart_context , input_state -> view_dispatcher , input_state , "" , "" , "" );
21112125 if (input_state -> input_buffer ) memset (input_state -> input_buffer , 0 , INPUT_BUFFER_SIZE );
21122126}
21132127
@@ -2134,6 +2148,9 @@ static void send_ir_file(AppState* state) {
21342148 state -> ir_file_buttons_mode = true;
21352149
21362150 if (!ir_parse_buttons_from_ir_buffer (state , state -> ir_file_buffer , state -> ir_file_buffer_size )) {
2151+ free (state -> ir_file_buffer );
2152+ state -> ir_file_buffer = NULL ;
2153+ state -> ir_file_buffer_size = 0 ;
21372154 state -> ir_file_buttons_mode = false;
21382155 ir_show_error (state , "No IR buttons found." );
21392156 return ;
@@ -2974,11 +2991,7 @@ bool back_event_callback(void* context) {
29742991
29752992 // Cleanup text buffer
29762993 if (state -> textBoxBuffer ) {
2977- free (state -> textBoxBuffer );
2978- state -> textBoxBuffer = malloc (1 );
2979- if (state -> textBoxBuffer ) {
2980- state -> textBoxBuffer [0 ] = '\0' ;
2981- }
2994+ state -> textBoxBuffer [0 ] = '\0' ;
29822995 state -> buffer_length = 0 ;
29832996 }
29842997
@@ -3076,6 +3089,14 @@ bool back_event_callback(void* context) {
30763089 }
30773090 // Handle IR submenus (31-33)
30783091 else if (current_view >= 31 && current_view <= 33 ) {
3092+ if (state -> ir_file_buffer ) {
3093+ free (state -> ir_file_buffer );
3094+ state -> ir_file_buffer = NULL ;
3095+ state -> ir_file_buffer_size = 0 ;
3096+ }
3097+ state -> ir_file_buttons_mode = false;
3098+ state -> ir_universal_buttons_mode = false;
3099+
30793100 show_ir_menu (state );
30803101 submenu_set_selected_item (state -> ir_menu , state -> last_ir_index );
30813102 state -> current_view = 30 ;
0 commit comments