irda_decoder_encoder_test.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include <furi.h>
  2. #include "../minunit.h"
  3. #include "irda.h"
  4. #include "irda_common_i.h"
  5. #include "test_data/irda_nec_test_data.srcdata"
  6. #include "test_data/irda_necext_test_data.srcdata"
  7. #include "test_data/irda_samsung_test_data.srcdata"
  8. #include "test_data/irda_rc6_test_data.srcdata"
  9. #define RUN_ENCODER(data, expected) \
  10. run_encoder((data), COUNT_OF(data), (expected), COUNT_OF(expected))
  11. #define RUN_DECODER(data, expected) \
  12. run_decoder((data), COUNT_OF(data), (expected), COUNT_OF(expected))
  13. static IrdaDecoderHandler* decoder_handler;
  14. static IrdaEncoderHandler* encoder_handler;
  15. static void test_setup(void) {
  16. decoder_handler = irda_alloc_decoder();
  17. encoder_handler = irda_alloc_encoder();
  18. }
  19. static void test_teardown(void) {
  20. irda_free_decoder(decoder_handler);
  21. irda_free_encoder(encoder_handler);
  22. }
  23. static void compare_message_results(
  24. const IrdaMessage* message_decoded,
  25. const IrdaMessage* message_expected) {
  26. mu_check(message_decoded->protocol == message_expected->protocol);
  27. mu_check(message_decoded->command == message_expected->command);
  28. mu_check(message_decoded->address == message_expected->address);
  29. mu_check(message_decoded->repeat == message_expected->repeat);
  30. }
  31. static void
  32. run_encoder_fill_array(IrdaEncoderHandler* handler, uint32_t* timings, uint32_t* timings_len) {
  33. uint32_t duration = 0;
  34. bool level = false; // start from space
  35. bool level_read;
  36. IrdaStatus status = IrdaStatusError;
  37. int i = 0;
  38. while(1) {
  39. status = irda_encode(handler, &duration, &level_read);
  40. if(level_read != level) {
  41. level = level_read;
  42. ++i;
  43. }
  44. timings[i] += duration;
  45. furi_assert((status == IrdaStatusOk) || (status == IrdaStatusDone));
  46. if(status == IrdaStatusDone) break;
  47. furi_assert(i < *timings_len);
  48. }
  49. *timings_len = i + 1;
  50. }
  51. // messages in input array for encoder should have one protocol
  52. static void run_encoder(
  53. const IrdaMessage input_messages[],
  54. uint32_t input_messages_len,
  55. const uint32_t expected_timings[],
  56. uint32_t expected_timings_len) {
  57. uint32_t* timings = 0;
  58. uint32_t timings_len = 0;
  59. uint32_t j = 0;
  60. for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) {
  61. const IrdaMessage* message = &input_messages[message_counter];
  62. if(!message->repeat) {
  63. irda_reset_encoder(encoder_handler, message);
  64. }
  65. timings_len = 200;
  66. timings = furi_alloc(sizeof(uint32_t) * timings_len);
  67. run_encoder_fill_array(encoder_handler, timings, &timings_len);
  68. furi_assert(timings_len <= 200);
  69. for(int i = 0; i < timings_len; ++i, ++j) {
  70. mu_check(MATCH_BIT_TIMING(timings[i], expected_timings[j], 120));
  71. mu_assert(j < expected_timings_len, "encoded more timings than expected");
  72. }
  73. free(timings);
  74. }
  75. mu_assert(j == expected_timings_len, "encoded less timings than expected");
  76. }
  77. static void run_encoder_decoder(const IrdaMessage input_messages[], uint32_t input_messages_len) {
  78. uint32_t* timings = 0;
  79. uint32_t timings_len = 0;
  80. bool level = false;
  81. for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) {
  82. const IrdaMessage* message_encoded = &input_messages[message_counter];
  83. if(!message_encoded->repeat) {
  84. irda_reset_encoder(encoder_handler, message_encoded);
  85. level = false;
  86. }
  87. timings_len = 200;
  88. timings = furi_alloc(sizeof(uint32_t) * timings_len);
  89. run_encoder_fill_array(encoder_handler, timings, &timings_len);
  90. furi_assert(timings_len <= 200);
  91. const IrdaMessage* message_decoded = 0;
  92. for(int i = 0; i < timings_len; ++i) {
  93. message_decoded = irda_decode(decoder_handler, level, timings[i]);
  94. if(i < timings_len - 1)
  95. mu_check(!message_decoded);
  96. else
  97. mu_check(message_decoded);
  98. level = !level;
  99. }
  100. if(message_decoded) {
  101. compare_message_results(message_decoded, message_encoded);
  102. } else {
  103. mu_check(0);
  104. }
  105. free(timings);
  106. }
  107. }
  108. static void run_decoder(
  109. const uint32_t* input_delays,
  110. uint32_t input_delays_len,
  111. const IrdaMessage* message_expected,
  112. uint32_t message_expected_len) {
  113. const IrdaMessage* message_decoded = 0;
  114. bool level = 0;
  115. uint32_t message_counter = 0;
  116. for(uint32_t i = 0; i < input_delays_len; ++i) {
  117. message_decoded = irda_decode(decoder_handler, level, input_delays[i]);
  118. if(message_decoded) {
  119. mu_assert(message_counter < message_expected_len, "decoded more than expected");
  120. if(message_counter >= message_expected_len) break;
  121. compare_message_results(message_decoded, &message_expected[message_counter]);
  122. ++message_counter;
  123. }
  124. level = !level;
  125. }
  126. mu_assert(message_counter == message_expected_len, "decoded less than expected");
  127. }
  128. MU_TEST(test_decoder_samsung32) {
  129. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  130. }
  131. MU_TEST(test_mix) {
  132. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  133. // can use encoder data for decoding, but can't do opposite
  134. RUN_DECODER(test_encoder_rc6_expected1, test_encoder_rc6_input1);
  135. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  136. RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
  137. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  138. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  139. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  140. RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
  141. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  142. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  143. }
  144. MU_TEST(test_decoder_nec1) {
  145. RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1);
  146. }
  147. MU_TEST(test_decoder_nec2) {
  148. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  149. }
  150. MU_TEST(test_decoder_unexpected_end_in_sequence) {
  151. // test_decoder_nec_input1 and test_decoder_nec_input2 shuts unexpected
  152. RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1);
  153. RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1);
  154. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  155. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  156. }
  157. MU_TEST(test_decoder_necext1) {
  158. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  159. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  160. }
  161. MU_TEST(test_decoder_rc6) {
  162. RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
  163. }
  164. MU_TEST(test_encoder_rc6) {
  165. RUN_ENCODER(test_encoder_rc6_input1, test_encoder_rc6_expected1);
  166. }
  167. MU_TEST(test_encoder_decoder_all) {
  168. run_encoder_decoder(test_nec_all, COUNT_OF(test_nec_all));
  169. run_encoder_decoder(test_necext_all, COUNT_OF(test_necext_all));
  170. run_encoder_decoder(test_samsung32_all, COUNT_OF(test_samsung32_all));
  171. run_encoder_decoder(test_rc6_all, COUNT_OF(test_rc6_all));
  172. }
  173. MU_TEST_SUITE(test_irda_decoder_encoder) {
  174. MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
  175. MU_RUN_TEST(test_encoder_decoder_all);
  176. MU_RUN_TEST(test_decoder_unexpected_end_in_sequence);
  177. MU_RUN_TEST(test_decoder_nec1);
  178. MU_RUN_TEST(test_decoder_nec2);
  179. MU_RUN_TEST(test_decoder_samsung32);
  180. MU_RUN_TEST(test_decoder_necext1);
  181. MU_RUN_TEST(test_mix);
  182. MU_RUN_TEST(test_decoder_rc6);
  183. MU_RUN_TEST(test_encoder_rc6);
  184. }
  185. int run_minunit_test_irda_decoder_encoder() {
  186. MU_RUN_SUITE(test_irda_decoder_encoder);
  187. MU_REPORT();
  188. return MU_EXIT_CODE;
  189. }