From 98830a8a4194a50ccb8ae9eefaa5271750ff21a1 Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Sat, 16 Oct 2021 16:00:21 +0400 Subject: [PATCH] [FL-1956] Fix long packets bug, fix Manchester overrun (#766) Also fix RC6 test to detect this manchester bug --- applications/tests/furi_record_test.c | 3 + .../irda_decoder_encoder_test.c | 6 + .../test_data/irda_nec_test_data.srcdata | 33 ++++++ .../test_data/irda_rc6_test_data.srcdata | 108 +++++++++++++----- applications/tests/rpc/rpc_test.c | 4 +- .../common/irda_common_decoder.c | 32 ++++-- .../common/irda_common_protocol_defs.c | 3 + lib/irda/encoder_decoder/irda.c | 3 + .../encoder_decoder/irda_protocol_defs_i.h | 6 + .../encoder_decoder/rc5/irda_decoder_rc5.c | 5 + .../encoder_decoder/rc6/irda_decoder_rc6.c | 5 + .../samsung/irda_decoder_samsung.c | 4 + 12 files changed, 174 insertions(+), 38 deletions(-) diff --git a/applications/tests/furi_record_test.c b/applications/tests/furi_record_test.c index 0b4d7a46..7f8a0507 100644 --- a/applications/tests/furi_record_test.c +++ b/applications/tests/furi_record_test.c @@ -11,4 +11,7 @@ void test_furi_create_open() { // 2. Open it void* record = furi_record_open("test/holding"); mu_assert_pointers_eq(record, &test_data); + furi_record_close("test/holding"); + + furi_record_destroy("test/holding"); } diff --git a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c index 01bca32d..908e196d 100644 --- a/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c +++ b/applications/tests/irda_decoder_encoder/irda_decoder_encoder_test.c @@ -247,6 +247,11 @@ MU_TEST(test_decoder_necext1) { RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1); } +MU_TEST(test_decoder_long_packets_with_nec_start) { + RUN_DECODER(test_decoder_nec42ext_input1, test_decoder_nec42ext_expected1); + RUN_DECODER(test_decoder_nec42ext_input2, test_decoder_nec42ext_expected2); +} + MU_TEST(test_encoder_sirc) { RUN_ENCODER(test_encoder_sirc_input1, test_encoder_sirc_expected1); RUN_ENCODER(test_encoder_sirc_input2, test_encoder_sirc_expected2); @@ -310,6 +315,7 @@ MU_TEST_SUITE(test_irda_decoder_encoder) { MU_RUN_TEST(test_decoder_rc6); MU_RUN_TEST(test_encoder_rc6); MU_RUN_TEST(test_decoder_unexpected_end_in_sequence); + MU_RUN_TEST(test_decoder_long_packets_with_nec_start); MU_RUN_TEST(test_decoder_nec); MU_RUN_TEST(test_decoder_samsung32); MU_RUN_TEST(test_decoder_necext1); diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata index f97f31ca..1214ae9b 100644 --- a/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata +++ b/applications/tests/irda_decoder_encoder/test_data/irda_nec_test_data.srcdata @@ -306,3 +306,36 @@ const IrdaMessage test_nec42ext[] = { {IrdaProtocolNEC42ext, 0x1555555, 0x5555, true}, }; +const uint32_t test_decoder_nec42ext_input1[] = { +2000000, 9000, 4500, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 8 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 16 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 24 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 32 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 40 + 560, 560, 560, 560, 560, // 42 +}; + +const uint32_t test_decoder_nec42ext_input2[] = { +2000000, 9000, 4500, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 8 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 16 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 24 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 32 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 40 + 560, 560, 560, 560, 560, 560, 560, // 43 - failed + +2000000, 9000, 4500, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 8 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 16 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 24 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 32 + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, // 40 + 560, 560, 560, 560, 560, 10000, 560, // 42 OK + 1 failed +}; + +const IrdaMessage test_decoder_nec42ext_expected1[] = { + {IrdaProtocolNEC42ext, 0x00, 0, false}, +}; + +const IrdaMessage test_decoder_nec42ext_expected2[] = { + {IrdaProtocolNEC42ext, 0x00, 0, false}, +}; + diff --git a/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata b/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata index 4c3fadca..25010b0c 100644 --- a/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata +++ b/applications/tests/irda_decoder_encoder/test_data/irda_rc6_test_data.srcdata @@ -1,45 +1,95 @@ /* _____---------______--____--__--__--____------____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -_____---------______--____--__--__------____--____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -_____---------______--____--__--__--____------____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -_____---------______--____--__--__--____------____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -_____---------______--____--__--__--____------____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | -_____---------______--____--__--__------____--____--__----____--__----__--__--____----____--__--__--__--__--___________ - | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | + | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 93 A0 0 s m2 m1 m0 T | address | command | +// 93 A0 0 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, +// --__----__--__-- +// 0 | 0 | 1 | 1 | 1 +//444, 444, 888, 444, 444, 444, 444, +//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + +_____---------______--____--__--__------____--____--__----____--__----__--__--____----____--__--__--__--__--___________ + | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 93 A0 1 +// 93 A0 1 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, +//444, 444, 888, 444, 444, 444, 444, +//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + +_____---------______--____--__--__--____------____--__----____----____--__----____----____--__--__--__--__--___________ + | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 94 A0 0 +// 94 A0 0 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, +//----____--__---- +//0 | 1 | 0 | 0 | 1 +//888, 888, 444, 444, 888, +//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + +_____---------______--____--__--__------____--____--__----____----____--__----____----____--__--__--__--__--___________ + | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 94 A0 1 +// 94 A0 1 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, +//888, 888, 444, 444, 888, +//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + +_____---------______--____--__--__--____------____--__----____----____----__--____----____--__--__--__--__--___________ + | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 95 A0 0 +// 95 A0 0 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, +//----____----__-- +//0 | 1 | 0 | 1 | 1 +//888, 888, 888, 444, 444, +//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + +_____---------______--____--__--__------____--____--__----____----____----__--____----____--__--__--__--__--___________ + | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 95 A0 1 +// 95 A0 1 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +//27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, +//888, 888, 888, 444, 444, +//888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + */ const uint32_t test_decoder_rc6_input1[] = { -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +// 94 A0 0 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +// 93 A0 1 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed + // failed 95 + 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, +// 93 A0 0 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888, -27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed +// 94 A0 1 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 444, 444, 888, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, +// 95 A0 0 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, + // failed 93 + 1 sample + 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, + // failed 93 + 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, 444, 444, + // failed 93 + 27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, +// 95 A0 1 +27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 888, 888, 888, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444, }; const IrdaMessage test_decoder_rc6_expected1[] = { - {IrdaProtocolRC6, 0x93, 0xA0, false}, // toggle 0 + {IrdaProtocolRC6, 0x94, 0xA0, false}, // toggle 0 {IrdaProtocolRC6, 0x93, 0xA0, false}, // toggle 1 -// {IrdaProtocolRC6, 0x93, 0xA0, false}, +// {IrdaProtocolRC6, 0x95, 0xA0, false}, failed {IrdaProtocolRC6, 0x93, 0xA0, false}, // toggle 0 - {IrdaProtocolRC6, 0x93, 0xA0, true}, // toggle 0 - {IrdaProtocolRC6, 0x93, 0xA0, true}, // toggle 0 - {IrdaProtocolRC6, 0x93, 0xA0, false}, // toggle 1 -// {IrdaProtocolRC6, 0x93, 0xA0, false}, - {IrdaProtocolRC6, 0x93, 0xA0, false}, // toggle 0 - {IrdaProtocolRC6, 0x93, 0xA1, false}, // toggle 1 -// {IrdaProtocolRC6, 0x93, 0xA0, false}, + {IrdaProtocolRC6, 0x94, 0xA0, false}, // toggle 1 + {IrdaProtocolRC6, 0x95, 0xA0, false}, // toggle 0 +// {IrdaProtocolRC6, 0x93, 0xA0, false}, failed +// {IrdaProtocolRC6, 0x93, 0xA0, false}, failed +// {IrdaProtocolRC6, 0x93, 0xA0, false}, failed + {IrdaProtocolRC6, 0x95, 0xA0, false}, // toggle 1 }; const IrdaMessage test_encoder_rc6_input1[] = { diff --git a/applications/tests/rpc/rpc_test.c b/applications/tests/rpc/rpc_test.c index 1ac2b490..18f1c7a8 100644 --- a/applications/tests/rpc/rpc_test.c +++ b/applications/tests/rpc/rpc_test.c @@ -5,6 +5,7 @@ #include "pb_decode.h" #include "rpc/rpc_i.h" #include "storage.pb.h" +#include "storage/filesystem-api-defines.h" #include "storage/storage.h" #include #include "../minunit.h" @@ -104,7 +105,8 @@ static void clean_directory(Storage* fs_api, const char* clean_dir) { if(fileinfo.flags & FSF_DIRECTORY) { clean_directory(fs_api, fullname); } - storage_common_remove(fs_api, fullname); + FS_Error error = storage_common_remove(fs_api, fullname); + furi_assert(error == FSE_OK); free(fullname); } free(name); diff --git a/lib/irda/encoder_decoder/common/irda_common_decoder.c b/lib/irda/encoder_decoder/common/irda_common_decoder.c index 87458f37..2fb10e15 100644 --- a/lib/irda/encoder_decoder/common/irda_common_decoder.c +++ b/lib/irda/encoder_decoder/common/irda_common_decoder.c @@ -84,16 +84,22 @@ static IrdaStatus irda_common_decode_bits(IrdaCommonDecoder* decoder) { bool level = (decoder->level + decoder->timings_cnt + 1) % 2; uint32_t timing = decoder->timings[0]; - /* check if short protocol version can be decoded */ - if (timings->min_split_time && !level && (timing > timings->min_split_time)) { - for (int i = 1; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { - if (decoder->protocol->databit_len[i] == decoder->databit_cnt) { - return IrdaStatusReady; + if (timings->min_split_time && !level) { + if (timing > timings->min_split_time) { + /* long low timing - check if we're ready for any of protocol modification */ + for (int i = 0; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { + if (decoder->protocol->databit_len[i] == decoder->databit_cnt) { + return IrdaStatusReady; + } } + } else if (decoder->protocol->databit_len[0] == decoder->databit_cnt) { + /* short low timing for longest protocol - this is signal is longer than we expected */ + return IrdaStatusError; } } status = decoder->protocol->decode(decoder, level, timing); + furi_check(decoder->databit_cnt <= decoder->protocol->databit_len[0]); furi_assert(status == IrdaStatusError || status == IrdaStatusOk); if (status == IrdaStatusError) { break; @@ -101,7 +107,7 @@ static IrdaStatus irda_common_decode_bits(IrdaCommonDecoder* decoder) { decoder->timings_cnt = consume_samples(decoder->timings, decoder->timings_cnt, 1); /* check if largest protocol version can be decoded */ - if (level && (decoder->protocol->databit_len[0] == decoder->databit_cnt)) { + if (level && (decoder->protocol->databit_len[0] == decoder->databit_cnt) && !timings->min_split_time) { status = IrdaStatusReady; break; } @@ -177,6 +183,9 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level, } if (*switch_detect) { + if (decoder->protocol->databit_len[0] == decoder->databit_cnt) { + return IrdaStatusError; + } accumulate_lsb(decoder, level); } @@ -185,8 +194,16 @@ IrdaStatus irda_common_decode_manchester(IrdaCommonDecoder* decoder, bool level, IrdaMessage* irda_common_decoder_check_ready(IrdaCommonDecoder* decoder) { IrdaMessage* message = NULL; + bool found_length = false; - if (decoder->protocol->interpret(decoder)) { + for (int i = 0; decoder->protocol->databit_len[i] && (i < COUNT_OF(decoder->protocol->databit_len)); ++i) { + if (decoder->protocol->databit_len[i] == decoder->databit_cnt) { + found_length = true; + break; + } + } + + if (found_length && decoder->protocol->interpret(decoder)) { decoder->databit_cnt = 0; message = &decoder->message; if (decoder->protocol->decode_repeat) { @@ -268,7 +285,6 @@ void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec* protocol) { + protocol->databit_len[0] / 8 + !!(protocol->databit_len[0] % 8); IrdaCommonDecoder* decoder = furi_alloc(alloc_size); - memset(decoder, 0, alloc_size); decoder->protocol = protocol; decoder->level = true; return decoder; diff --git a/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c b/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c index 61744887..a8ef16d6 100644 --- a/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c +++ b/lib/irda/encoder_decoder/common/irda_common_protocol_defs.c @@ -35,6 +35,7 @@ const IrdaCommonProtocolSpec protocol_samsung32 = { .preamble_tolerance = IRDA_SAMSUNG_PREAMBLE_TOLERANCE, .bit_tolerance = IRDA_SAMSUNG_BIT_TOLERANCE, .silence_time = IRDA_SAMSUNG_SILENCE, + .min_split_time = IRDA_SAMSUNG_MIN_SPLIT_TIME, }, .databit_len[0] = 32, .no_stop_bit = false, @@ -53,6 +54,7 @@ const IrdaCommonProtocolSpec protocol_rc6 = { .preamble_tolerance = IRDA_RC6_PREAMBLE_TOLERANCE, .bit_tolerance = IRDA_RC6_BIT_TOLERANCE, .silence_time = IRDA_RC6_SILENCE, + .min_split_time = IRDA_RC6_MIN_SPLIT_TIME, }, .databit_len[0] = 1 + 3 + 1 + 8 + 8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command .manchester_start_from_space = false, @@ -71,6 +73,7 @@ const IrdaCommonProtocolSpec protocol_rc5 = { .preamble_tolerance = 0, .bit_tolerance = IRDA_RC5_BIT_TOLERANCE, .silence_time = IRDA_RC5_SILENCE, + .min_split_time = IRDA_RC5_MIN_SPLIT_TIME, }, .databit_len[0] = 1 + 1 + 1 + 5 + 6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command .manchester_start_from_space = true, diff --git a/lib/irda/encoder_decoder/irda.c b/lib/irda/encoder_decoder/irda.c index 19a4df46..8d25f489 100644 --- a/lib/irda/encoder_decoder/irda.c +++ b/lib/irda/encoder_decoder/irda.c @@ -59,6 +59,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = { .alloc = irda_decoder_samsung32_alloc, .decode = irda_decoder_samsung32_decode, .reset = irda_decoder_samsung32_reset, + .check_ready = irda_decoder_samsung32_check_ready, .free = irda_decoder_samsung32_free}, .encoder = { .alloc = irda_encoder_samsung32_alloc, @@ -72,6 +73,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = { .alloc = irda_decoder_rc5_alloc, .decode = irda_decoder_rc5_decode, .reset = irda_decoder_rc5_reset, + .check_ready = irda_decoder_rc5_check_ready, .free = irda_decoder_rc5_free}, .encoder = { .alloc = irda_encoder_rc5_alloc, @@ -85,6 +87,7 @@ static const IrdaEncoderDecoder irda_encoder_decoder[] = { .alloc = irda_decoder_rc6_alloc, .decode = irda_decoder_rc6_decode, .reset = irda_decoder_rc6_reset, + .check_ready = irda_decoder_rc6_check_ready, .free = irda_decoder_rc6_free}, .encoder = { .alloc = irda_encoder_rc6_alloc, diff --git a/lib/irda/encoder_decoder/irda_protocol_defs_i.h b/lib/irda/encoder_decoder/irda_protocol_defs_i.h index 4c380160..d6abd2a0 100644 --- a/lib/irda/encoder_decoder/irda_protocol_defs_i.h +++ b/lib/irda/encoder_decoder/irda_protocol_defs_i.h @@ -81,6 +81,7 @@ extern const IrdaCommonProtocolSpec protocol_nec; * of some data. Real tolerances we don't know, but in real life * silence time should be greater than max repeat time. This is * because of similar preambule timings for repeat and first messages. */ +#define IRDA_SAMSUNG_MIN_SPLIT_TIME 5000 #define IRDA_SAMSUNG_SILENCE 145000 #define IRDA_SAMSUNG_REPEAT_PAUSE_MAX 140000 #define IRDA_SAMSUNG_REPEAT_MARK 4500 @@ -91,6 +92,7 @@ extern const IrdaCommonProtocolSpec protocol_nec; void* irda_decoder_samsung32_alloc(void); void irda_decoder_samsung32_reset(void* decoder); void irda_decoder_samsung32_free(void* decoder); +IrdaMessage* irda_decoder_samsung32_check_ready(void* ctx); IrdaMessage* irda_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration); IrdaStatus irda_encoder_samsung32_encode(void* encoder_ptr, uint32_t* duration, bool* level); void irda_encoder_samsung32_reset(void* encoder_ptr, const IrdaMessage* message); @@ -135,10 +137,12 @@ extern const IrdaCommonProtocolSpec protocol_samsung32; #define IRDA_RC6_BIT_TOLERANCE 120 // us /* protocol allows 2700 silence, but it is hard to send 1 message without repeat */ #define IRDA_RC6_SILENCE (2700 * 10) +#define IRDA_RC6_MIN_SPLIT_TIME 2700 void* irda_decoder_rc6_alloc(void); void irda_decoder_rc6_reset(void* decoder); void irda_decoder_rc6_free(void* decoder); +IrdaMessage* irda_decoder_rc6_check_ready(void* ctx); IrdaMessage* irda_decoder_rc6_decode(void* decoder, bool level, uint32_t duration); void* irda_encoder_rc6_alloc(void); void irda_encoder_rc6_reset(void* encoder_ptr, const IrdaMessage* message); @@ -184,10 +188,12 @@ extern const IrdaCommonProtocolSpec protocol_rc6; #define IRDA_RC5_BIT_TOLERANCE 120 // us /* protocol allows 2700 silence, but it is hard to send 1 message without repeat */ #define IRDA_RC5_SILENCE (2700 * 10) +#define IRDA_RC5_MIN_SPLIT_TIME 2700 void* irda_decoder_rc5_alloc(void); void irda_decoder_rc5_reset(void* decoder); void irda_decoder_rc5_free(void* decoder); +IrdaMessage* irda_decoder_rc5_check_ready(void* ctx); IrdaMessage* irda_decoder_rc5_decode(void* decoder, bool level, uint32_t duration); void* irda_encoder_rc5_alloc(void); void irda_encoder_rc5_reset(void* encoder_ptr, const IrdaMessage* message); diff --git a/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c b/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c index 6843b283..d37e6792 100644 --- a/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c +++ b/lib/irda/encoder_decoder/rc5/irda_decoder_rc5.c @@ -11,6 +11,11 @@ typedef struct { bool toggle; } IrdaRc5Decoder; +IrdaMessage* irda_decoder_rc5_check_ready(void* ctx) { + IrdaRc5Decoder* decoder = ctx; + return irda_common_decoder_check_ready(decoder->common_decoder); +} + bool irda_decoder_rc5_interpret(IrdaCommonDecoder* decoder) { furi_assert(decoder); diff --git a/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c b/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c index cedc617f..698dfb0d 100644 --- a/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c +++ b/lib/irda/encoder_decoder/rc6/irda_decoder_rc6.c @@ -11,6 +11,11 @@ typedef struct { bool toggle; } IrdaRc6Decoder; +IrdaMessage* irda_decoder_rc6_check_ready(void* ctx) { + IrdaRc6Decoder* decoder_rc6 = ctx; + return irda_common_decoder_check_ready(decoder_rc6->common_decoder); +} + bool irda_decoder_rc6_interpret(IrdaCommonDecoder* decoder) { furi_assert(decoder); diff --git a/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c b/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c index d7640f3d..feb80f86 100644 --- a/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c +++ b/lib/irda/encoder_decoder/samsung/irda_decoder_samsung.c @@ -6,6 +6,10 @@ #include "../irda_i.h" +IrdaMessage* irda_decoder_samsung32_check_ready(void* ctx) { + return irda_common_decoder_check_ready(ctx); +} + bool irda_decoder_samsung32_interpret(IrdaCommonDecoder* decoder) { furi_assert(decoder);