1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 04:34:43 +04:00

Infrared Universal remote DBs unit test & move infrared_signal / infrared_brute_force into lib (#4284)

* make infrared db unit tests

* fix the tests, no assets are in asset folder oh no

* fix formate

* ship ir app along with unit_test pkg

* libify ir signal and bruteforce parts

* small cleanup

* api: removed infrared methods (you can link with the lib if needed), unit_tests, infrared: adjusted to link with ir lib; api: added `__aeabi_f2d`

---------

Co-authored-by: hedger <hedger@users.noreply.github.com>
Co-authored-by: hedger <hedger@nanode.su>
This commit is contained in:
MMX
2025-11-06 19:23:59 +03:00
committed by GitHub
parent 67b906e6ba
commit 6a5ae6cc0d
17 changed files with 150 additions and 18 deletions

View File

@@ -131,6 +131,7 @@ App(
apptype=FlipperAppType.PLUGIN,
entry_point="get_api",
requires=["unit_tests"],
fap_libs=["infrared"],
)
App(

View File

@@ -2,6 +2,7 @@
#include <flipper_format.h>
#include <infrared.h>
#include <common/infrared_common_i.h>
#include <lib/infrared/signal/infrared_brute_force.h>
#include "../test.h" // IWYU pragma: keep
#define IR_TEST_FILES_DIR EXT_PATH("unit_tests/infrared/")
@@ -13,6 +14,7 @@ typedef struct {
InfraredEncoderHandler* encoder_handler;
FuriString* file_path;
FlipperFormat* ff;
InfraredBruteForce* brutedb;
} InfraredTest;
static InfraredTest* test;
@@ -24,12 +26,14 @@ static void infrared_test_alloc(void) {
test->encoder_handler = infrared_alloc_encoder();
test->ff = flipper_format_buffered_file_alloc(storage);
test->file_path = furi_string_alloc();
test->brutedb = infrared_brute_force_alloc();
}
static void infrared_test_free(void) {
furi_check(test);
infrared_free_decoder(test->decoder_handler);
infrared_free_encoder(test->encoder_handler);
infrared_brute_force_free(test->brutedb);
flipper_format_free(test->ff);
furi_string_free(test->file_path);
furi_record_close(RECORD_STORAGE);
@@ -523,6 +527,74 @@ MU_TEST(infrared_test_encoder_decoder_all) {
infrared_test_run_encoder_decoder(InfraredProtocolPioneer, 1);
}
MU_TEST(infrared_test_ac_database) {
infrared_brute_force_set_db_filename(test->brutedb, EXT_PATH("infrared/assets/ac.ir"));
uint32_t i = 0;
infrared_brute_force_add_record(test->brutedb, i++, "Off");
infrared_brute_force_add_record(test->brutedb, i++, "Dh");
infrared_brute_force_add_record(test->brutedb, i++, "Cool_hi");
infrared_brute_force_add_record(test->brutedb, i++, "Heat_hi");
infrared_brute_force_add_record(test->brutedb, i++, "Cool_lo");
infrared_brute_force_add_record(test->brutedb, i++, "Heat_lo");
mu_assert(
infrared_brute_force_calculate_messages(test->brutedb) == InfraredErrorCodeNone,
"universal ac database is invalid");
infrared_brute_force_reset(test->brutedb);
}
MU_TEST(infrared_test_audio_database) {
infrared_brute_force_set_db_filename(test->brutedb, EXT_PATH("infrared/assets/audio.ir"));
uint32_t i = 0;
infrared_brute_force_add_record(test->brutedb, i++, "Power");
infrared_brute_force_add_record(test->brutedb, i++, "Mute");
infrared_brute_force_add_record(test->brutedb, i++, "Play");
infrared_brute_force_add_record(test->brutedb, i++, "Pause");
infrared_brute_force_add_record(test->brutedb, i++, "Prev");
infrared_brute_force_add_record(test->brutedb, i++, "Next");
infrared_brute_force_add_record(test->brutedb, i++, "Vol_dn");
infrared_brute_force_add_record(test->brutedb, i++, "Vol_up");
mu_assert(
infrared_brute_force_calculate_messages(test->brutedb) == InfraredErrorCodeNone,
"universal audio database is invalid");
infrared_brute_force_reset(test->brutedb);
}
MU_TEST(infrared_test_projector_database) {
infrared_brute_force_set_db_filename(test->brutedb, EXT_PATH("infrared/assets/projector.ir"));
uint32_t i = 0;
infrared_brute_force_add_record(test->brutedb, i++, "Power");
infrared_brute_force_add_record(test->brutedb, i++, "Mute");
infrared_brute_force_add_record(test->brutedb, i++, "Vol_up");
infrared_brute_force_add_record(test->brutedb, i++, "Vol_dn");
mu_assert(
infrared_brute_force_calculate_messages(test->brutedb) == InfraredErrorCodeNone,
"universal projector database is invalid");
infrared_brute_force_reset(test->brutedb);
}
MU_TEST(infrared_test_tv_database) {
infrared_brute_force_set_db_filename(test->brutedb, EXT_PATH("infrared/assets/tv.ir"));
uint32_t i = 0;
infrared_brute_force_add_record(test->brutedb, i++, "Power");
infrared_brute_force_add_record(test->brutedb, i++, "Mute");
infrared_brute_force_add_record(test->brutedb, i++, "Vol_up");
infrared_brute_force_add_record(test->brutedb, i++, "Ch_next");
infrared_brute_force_add_record(test->brutedb, i++, "Vol_dn");
infrared_brute_force_add_record(test->brutedb, i++, "Ch_prev");
mu_assert(
infrared_brute_force_calculate_messages(test->brutedb) == InfraredErrorCodeNone,
"universal tv database is invalid");
infrared_brute_force_reset(test->brutedb);
}
MU_TEST_SUITE(infrared_test) {
MU_SUITE_CONFIGURE(&infrared_test_alloc, &infrared_test_free);
@@ -543,6 +615,10 @@ MU_TEST_SUITE(infrared_test) {
MU_RUN_TEST(infrared_test_decoder_pioneer);
MU_RUN_TEST(infrared_test_decoder_mixed);
MU_RUN_TEST(infrared_test_encoder_decoder_all);
MU_RUN_TEST(infrared_test_ac_database);
MU_RUN_TEST(infrared_test_audio_database);
MU_RUN_TEST(infrared_test_projector_database);
MU_RUN_TEST(infrared_test_tv_database);
}
int run_minunit_test_infrared(void) {

View File

@@ -9,7 +9,7 @@ App(
order=40,
sources=["*.c", "!infrared_cli.c"],
resources="resources",
fap_libs=["assets"],
fap_libs=["assets", "infrared"],
fap_icon="icon.png",
fap_category="Infrared",
)
@@ -20,9 +20,5 @@ App(
apptype=FlipperAppType.PLUGIN,
entry_point="cli_ir_ep",
requires=["cli"],
sources=[
"infrared_cli.c",
"infrared_brute_force.c",
"infrared_signal.c",
],
sources=["infrared_cli.c"],
)

View File

@@ -3,9 +3,7 @@
* @brief Infrared application - start here.
*
* @see infrared_app_i.h for the main application data structure and functions.
* @see infrared_signal.h for the infrared signal library - loading, storing and transmitting signals.
* @see infrared_remote.hl for the infrared remote library - loading, storing and manipulating remotes.
* @see infrared_brute_force.h for the infrared brute force - loading and transmitting multiple signals.
* @see infrared_remote.h for the infrared remote library - loading, storing and manipulating remotes
*/
#pragma once

View File

@@ -31,7 +31,7 @@
#include "infrared_app.h"
#include "infrared_remote.h"
#include "infrared_brute_force.h"
#include <lib/infrared/signal/infrared_brute_force.h>
#include "infrared_custom_event.h"
#include "scenes/infrared_scene.h"

View File

@@ -8,8 +8,8 @@
#include <toolbox/pipe.h>
#include <m-dict.h>
#include "infrared_signal.h"
#include "infrared_brute_force.h"
#include <lib/infrared/signal/infrared_signal.h>
#include <lib/infrared/signal/infrared_brute_force.h>
#define INFRARED_CLI_BUF_SIZE (10U)
#define INFRARED_CLI_FILE_NAME_SIZE (256U)

View File

@@ -11,7 +11,7 @@
*/
#pragma once
#include "infrared_signal.h"
#include <lib/infrared/signal/infrared_signal.h>
/**
* @brief InfraredRemote opaque type declaration.

View File

@@ -76,6 +76,7 @@ FIRMWARE_APPS = {
"radio_device_cc1101_ext",
"unit_tests",
"js_app",
"infrared",
"archive",
],
}

View File

@@ -4,11 +4,15 @@ env.Append(
CPPPATH=[
"#/lib/infrared/encoder_decoder",
"#/lib/infrared/worker",
"#/lib/infrared/signal",
],
SDK_HEADERS=[
File("encoder_decoder/infrared.h"),
File("worker/infrared_worker.h"),
File("worker/infrared_transmit.h"),
File("signal/infrared_error_code.h"),
File("signal/infrared_signal.h"),
File("signal/infrared_brute_force.h"),
],
LINT_SOURCES=[
Dir("."),

View File

@@ -12,6 +12,10 @@
#include <stdbool.h>
#include "infrared_error_code.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief InfraredBruteForce opaque type declaration.
*/
@@ -107,3 +111,7 @@ void infrared_brute_force_add_record(
* @param[in,out] brute_force pointer to the instance to be reset.
*/
void infrared_brute_force_reset(InfraredBruteForce* brute_force);
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,9 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
InfraredErrorCodeNone = 0,
InfraredErrorCodeFileOperationFailed = 0x800000,
@@ -43,3 +47,7 @@ typedef enum {
#define INFRARED_ERROR_PRESENT(error) (INFRARED_ERROR_GET_CODE(error) != InfraredErrorCodeNone)
#define INFRARED_ERROR_CHECK(error, test_code) (INFRARED_ERROR_GET_CODE(error) == (test_code))
#ifdef __cplusplus
}
#endif

View File

@@ -85,7 +85,7 @@ static bool infrared_signal_is_raw_valid(const InfraredRawSignal* raw) {
raw->frequency);
return false;
} else if((raw->duty_cycle <= 0) || (raw->duty_cycle > 1)) {
} else if((raw->duty_cycle <= 0) || (raw->duty_cycle > 1.f)) {
FURI_LOG_E(TAG, "Duty cycle is out of range (0 - 1): %f", (double)raw->duty_cycle);
return false;

View File

@@ -10,7 +10,11 @@
#include "infrared_error_code.h"
#include <flipper_format/flipper_format.h>
#include <infrared/encoder_decoder/infrared.h>
#include <infrared.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief InfraredSignal opaque type declaration.
@@ -218,3 +222,7 @@ InfraredErrorCode
* @param[in] signal pointer to the instance holding the signal to be transmitted.
*/
void infrared_signal_transmit(const InfraredSignal* signal);
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,87.0,,
Version,+,87.1,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,,
@@ -339,6 +339,7 @@ Function,-,Osal_MemSet,void*,"void*, int, unsigned int"
Function,-,SystemCoreClockUpdate,void,
Function,-,SystemInit,void,
Function,-,_Exit,void,int
Function,+,__aeabi_f2d,double,float
Function,+,__aeabi_uldivmod,void*,"uint64_t, uint64_t"
Function,-,__assert,void,"const char*, int, const char*"
Function,+,__assert_func,void,"const char*, int, const char*, const char*"
1 entry status name type params
2 Version + 87.0 87.1
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/bt/bt_service/bt_keys_storage.h
5 Header + applications/services/cli/cli.h
339 Function - SystemCoreClockUpdate void
340 Function - SystemInit void
341 Function - _Exit void int
342 Function + __aeabi_f2d double float
343 Function + __aeabi_uldivmod void* uint64_t, uint64_t
344 Function - __assert void const char*, int, const char*
345 Function + __assert_func void const char*, int, const char*, const char*

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,87.0,,
Version,+,87.1,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@@ -63,6 +63,9 @@ Header,+,lib/ibutton/ibutton_protocols.h,,
Header,+,lib/ibutton/ibutton_worker.h,,
Header,+,lib/ieee754_parse_wrap/wrappers.h,,
Header,+,lib/infrared/encoder_decoder/infrared.h,,
Header,+,lib/infrared/signal/infrared_brute_force.h,,
Header,+,lib/infrared/signal/infrared_error_code.h,,
Header,+,lib/infrared/signal/infrared_signal.h,,
Header,+,lib/infrared/worker/infrared_transmit.h,,
Header,+,lib/infrared/worker/infrared_worker.h,,
Header,+,lib/lfrfid/lfrfid_dict_file.h,,
@@ -418,6 +421,7 @@ Function,-,Osal_MemSet,void*,"void*, int, unsigned int"
Function,-,SystemCoreClockUpdate,void,
Function,-,SystemInit,void,
Function,-,_Exit,void,int
Function,+,__aeabi_f2d,double,float
Function,+,__aeabi_uldivmod,void*,"uint64_t, uint64_t"
Function,-,__assert,void,"const char*, int, const char*"
Function,+,__assert_func,void,"const char*, int, const char*, const char*"
@@ -625,8 +629,8 @@ Function,-,arc4random_uniform,__uint32_t,__uint32_t
Function,+,args_char_to_hex,_Bool,"char, char, uint8_t*"
Function,+,args_get_first_word_length,size_t,FuriString*
Function,+,args_length,size_t,FuriString*
Function,+,args_read_float_and_trim,_Bool,"FuriString*, float*"
Function,+,args_read_duration,_Bool,"FuriString*, uint32_t*, const char*"
Function,+,args_read_float_and_trim,_Bool,"FuriString*, float*"
Function,+,args_read_hex_bytes,_Bool,"FuriString*, uint8_t*, size_t"
Function,+,args_read_int_and_trim,_Bool,"FuriString*, int*"
Function,+,args_read_probably_quoted_string_and_trim,_Bool,"FuriString*, FuriString*"
@@ -2065,6 +2069,16 @@ Function,-,infinity,double,
Function,-,infinityf,float,
Function,+,infrared_alloc_decoder,InfraredDecoderHandler*,
Function,+,infrared_alloc_encoder,InfraredEncoderHandler*,
Function,-,infrared_brute_force_add_record,void,"InfraredBruteForce*, uint32_t, const char*"
Function,-,infrared_brute_force_alloc,InfraredBruteForce*,
Function,-,infrared_brute_force_calculate_messages,InfraredErrorCode,InfraredBruteForce*
Function,-,infrared_brute_force_free,void,InfraredBruteForce*
Function,-,infrared_brute_force_is_started,_Bool,const InfraredBruteForce*
Function,-,infrared_brute_force_reset,void,InfraredBruteForce*
Function,-,infrared_brute_force_send,_Bool,"InfraredBruteForce*, uint32_t"
Function,-,infrared_brute_force_set_db_filename,void,"InfraredBruteForce*, const char*"
Function,-,infrared_brute_force_start,_Bool,"InfraredBruteForce*, uint32_t, uint32_t*"
Function,-,infrared_brute_force_stop,void,InfraredBruteForce*
Function,+,infrared_check_decoder_ready,const InfraredMessage*,InfraredDecoderHandler*
Function,+,infrared_decode,const InfraredMessage*,"InfraredDecoderHandler*, _Bool, uint32_t"
Function,+,infrared_encode,InfraredStatus,"InfraredEncoderHandler*, uint32_t*, _Bool*"
@@ -2083,6 +2097,22 @@ Function,+,infrared_reset_encoder,void,"InfraredEncoderHandler*, const InfraredM
Function,+,infrared_send,void,"const InfraredMessage*, int"
Function,+,infrared_send_raw,void,"const uint32_t[], uint32_t, _Bool"
Function,+,infrared_send_raw_ext,void,"const uint32_t[], uint32_t, _Bool, uint32_t, float"
Function,-,infrared_signal_alloc,InfraredSignal*,
Function,-,infrared_signal_free,void,InfraredSignal*
Function,-,infrared_signal_get_message,const InfraredMessage*,const InfraredSignal*
Function,-,infrared_signal_get_raw_signal,const InfraredRawSignal*,const InfraredSignal*
Function,-,infrared_signal_is_raw,_Bool,const InfraredSignal*
Function,-,infrared_signal_is_valid,_Bool,const InfraredSignal*
Function,-,infrared_signal_read,InfraredErrorCode,"InfraredSignal*, FlipperFormat*, FuriString*"
Function,-,infrared_signal_read_body,InfraredErrorCode,"InfraredSignal*, FlipperFormat*"
Function,-,infrared_signal_read_name,InfraredErrorCode,"FlipperFormat*, FuriString*"
Function,-,infrared_signal_save,InfraredErrorCode,"const InfraredSignal*, FlipperFormat*, const char*"
Function,-,infrared_signal_search_by_index_and_read,InfraredErrorCode,"InfraredSignal*, FlipperFormat*, size_t"
Function,-,infrared_signal_search_by_name_and_read,InfraredErrorCode,"InfraredSignal*, FlipperFormat*, const char*"
Function,-,infrared_signal_set_message,void,"InfraredSignal*, const InfraredMessage*"
Function,-,infrared_signal_set_raw_signal,void,"InfraredSignal*, const uint32_t*, size_t, uint32_t, float"
Function,-,infrared_signal_set_signal,void,"InfraredSignal*, const InfraredSignal*"
Function,-,infrared_signal_transmit,void,const InfraredSignal*
Function,+,infrared_worker_alloc,InfraredWorker*,
Function,+,infrared_worker_free,void,InfraredWorker*
Function,+,infrared_worker_get_decoded_signal,const InfraredMessage*,const InfraredWorkerSignal*
1 entry status name type params
2 Version + 87.0 87.1
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h
63 Header + lib/ibutton/ibutton_worker.h
64 Header + lib/ieee754_parse_wrap/wrappers.h
65 Header + lib/infrared/encoder_decoder/infrared.h
66 Header + lib/infrared/signal/infrared_brute_force.h
67 Header + lib/infrared/signal/infrared_error_code.h
68 Header + lib/infrared/signal/infrared_signal.h
69 Header + lib/infrared/worker/infrared_transmit.h
70 Header + lib/infrared/worker/infrared_worker.h
71 Header + lib/lfrfid/lfrfid_dict_file.h
421 Function - SystemCoreClockUpdate void
422 Function - SystemInit void
423 Function - _Exit void int
424 Function + __aeabi_f2d double float
425 Function + __aeabi_uldivmod void* uint64_t, uint64_t
426 Function - __assert void const char*, int, const char*
427 Function + __assert_func void const char*, int, const char*, const char*
629 Function + args_char_to_hex _Bool char, char, uint8_t*
630 Function + args_get_first_word_length size_t FuriString*
631 Function + args_length size_t FuriString*
Function + args_read_float_and_trim _Bool FuriString*, float*
632 Function + args_read_duration _Bool FuriString*, uint32_t*, const char*
633 Function + args_read_float_and_trim _Bool FuriString*, float*
634 Function + args_read_hex_bytes _Bool FuriString*, uint8_t*, size_t
635 Function + args_read_int_and_trim _Bool FuriString*, int*
636 Function + args_read_probably_quoted_string_and_trim _Bool FuriString*, FuriString*
2069 Function - infinityf float
2070 Function + infrared_alloc_decoder InfraredDecoderHandler*
2071 Function + infrared_alloc_encoder InfraredEncoderHandler*
2072 Function - infrared_brute_force_add_record void InfraredBruteForce*, uint32_t, const char*
2073 Function - infrared_brute_force_alloc InfraredBruteForce*
2074 Function - infrared_brute_force_calculate_messages InfraredErrorCode InfraredBruteForce*
2075 Function - infrared_brute_force_free void InfraredBruteForce*
2076 Function - infrared_brute_force_is_started _Bool const InfraredBruteForce*
2077 Function - infrared_brute_force_reset void InfraredBruteForce*
2078 Function - infrared_brute_force_send _Bool InfraredBruteForce*, uint32_t
2079 Function - infrared_brute_force_set_db_filename void InfraredBruteForce*, const char*
2080 Function - infrared_brute_force_start _Bool InfraredBruteForce*, uint32_t, uint32_t*
2081 Function - infrared_brute_force_stop void InfraredBruteForce*
2082 Function + infrared_check_decoder_ready const InfraredMessage* InfraredDecoderHandler*
2083 Function + infrared_decode const InfraredMessage* InfraredDecoderHandler*, _Bool, uint32_t
2084 Function + infrared_encode InfraredStatus InfraredEncoderHandler*, uint32_t*, _Bool*
2097 Function + infrared_send void const InfraredMessage*, int
2098 Function + infrared_send_raw void const uint32_t[], uint32_t, _Bool
2099 Function + infrared_send_raw_ext void const uint32_t[], uint32_t, _Bool, uint32_t, float
2100 Function - infrared_signal_alloc InfraredSignal*
2101 Function - infrared_signal_free void InfraredSignal*
2102 Function - infrared_signal_get_message const InfraredMessage* const InfraredSignal*
2103 Function - infrared_signal_get_raw_signal const InfraredRawSignal* const InfraredSignal*
2104 Function - infrared_signal_is_raw _Bool const InfraredSignal*
2105 Function - infrared_signal_is_valid _Bool const InfraredSignal*
2106 Function - infrared_signal_read InfraredErrorCode InfraredSignal*, FlipperFormat*, FuriString*
2107 Function - infrared_signal_read_body InfraredErrorCode InfraredSignal*, FlipperFormat*
2108 Function - infrared_signal_read_name InfraredErrorCode FlipperFormat*, FuriString*
2109 Function - infrared_signal_save InfraredErrorCode const InfraredSignal*, FlipperFormat*, const char*
2110 Function - infrared_signal_search_by_index_and_read InfraredErrorCode InfraredSignal*, FlipperFormat*, size_t
2111 Function - infrared_signal_search_by_name_and_read InfraredErrorCode InfraredSignal*, FlipperFormat*, const char*
2112 Function - infrared_signal_set_message void InfraredSignal*, const InfraredMessage*
2113 Function - infrared_signal_set_raw_signal void InfraredSignal*, const uint32_t*, size_t, uint32_t, float
2114 Function - infrared_signal_set_signal void InfraredSignal*, const InfraredSignal*
2115 Function - infrared_signal_transmit void const InfraredSignal*
2116 Function + infrared_worker_alloc InfraredWorker*
2117 Function + infrared_worker_free void InfraredWorker*
2118 Function + infrared_worker_get_decoded_signal const InfraredMessage* const InfraredWorkerSignal*

View File

@@ -8,6 +8,7 @@ extern "C" {
void __clear_cache(void*, void*);
void* __aeabi_uldivmod(uint64_t, uint64_t);
double __aeabi_f2d(float);
#ifdef __cplusplus
}