infrared_decoder_encoder_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #include <furi.h>
  2. #include "../minunit.h"
  3. #include "infrared.h"
  4. #include "common/infrared_common_i.h"
  5. #include "test_data/infrared_nec_test_data.srcdata"
  6. #include "test_data/infrared_necext_test_data.srcdata"
  7. #include "test_data/infrared_samsung_test_data.srcdata"
  8. #include "test_data/infrared_rc6_test_data.srcdata"
  9. #include "test_data/infrared_rc5_test_data.srcdata"
  10. #include "test_data/infrared_sirc_test_data.srcdata"
  11. #define RUN_ENCODER(data, expected) \
  12. run_encoder((data), COUNT_OF(data), (expected), COUNT_OF(expected))
  13. #define RUN_DECODER(data, expected) \
  14. run_decoder((data), COUNT_OF(data), (expected), COUNT_OF(expected))
  15. #define RUN_ENCODER_DECODER(data) run_encoder_decoder((data), COUNT_OF(data))
  16. static InfraredDecoderHandler* decoder_handler;
  17. static InfraredEncoderHandler* encoder_handler;
  18. static void test_setup(void) {
  19. decoder_handler = infrared_alloc_decoder();
  20. encoder_handler = infrared_alloc_encoder();
  21. }
  22. static void test_teardown(void) {
  23. infrared_free_decoder(decoder_handler);
  24. infrared_free_encoder(encoder_handler);
  25. }
  26. static void compare_message_results(
  27. const InfraredMessage* message_decoded,
  28. const InfraredMessage* message_expected) {
  29. mu_check(message_decoded->protocol == message_expected->protocol);
  30. mu_check(message_decoded->command == message_expected->command);
  31. mu_check(message_decoded->address == message_expected->address);
  32. if((message_expected->protocol == InfraredProtocolSIRC) ||
  33. (message_expected->protocol == InfraredProtocolSIRC15) ||
  34. (message_expected->protocol == InfraredProtocolSIRC20)) {
  35. mu_check(message_decoded->repeat == false);
  36. } else {
  37. mu_check(message_decoded->repeat == message_expected->repeat);
  38. }
  39. }
  40. /* Encodes signal and merges same levels (high+high, low+low) */
  41. static void run_encoder_fill_array(
  42. InfraredEncoderHandler* handler,
  43. uint32_t* timings,
  44. uint32_t* timings_len,
  45. bool* start_level) {
  46. uint32_t duration = 0;
  47. bool level = false;
  48. bool level_read;
  49. InfraredStatus status = InfraredStatusError;
  50. int i = 0;
  51. bool first = true;
  52. while(1) {
  53. status = infrared_encode(handler, &duration, &level_read);
  54. if(first) {
  55. if(start_level) *start_level = level_read;
  56. first = false;
  57. timings[0] = 0;
  58. } else if(level_read != level) {
  59. ++i;
  60. furi_check(i < *timings_len);
  61. timings[i] = 0;
  62. }
  63. level = level_read;
  64. timings[i] += duration;
  65. furi_check((status == InfraredStatusOk) || (status == InfraredStatusDone));
  66. if(status == InfraredStatusDone) break;
  67. }
  68. *timings_len = i + 1;
  69. }
  70. // messages in input array for encoder should have one protocol
  71. static void run_encoder(
  72. const InfraredMessage input_messages[],
  73. uint32_t input_messages_len,
  74. const uint32_t expected_timings[],
  75. uint32_t expected_timings_len) {
  76. uint32_t* timings = 0;
  77. uint32_t timings_len = 200;
  78. uint32_t j = 0;
  79. timings = malloc(sizeof(uint32_t) * timings_len);
  80. for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) {
  81. const InfraredMessage* message = &input_messages[message_counter];
  82. if(!message->repeat) {
  83. infrared_reset_encoder(encoder_handler, message);
  84. }
  85. timings_len = 200;
  86. run_encoder_fill_array(encoder_handler, timings, &timings_len, NULL);
  87. furi_check(timings_len <= 200);
  88. for(int i = 0; i < timings_len; ++i, ++j) {
  89. mu_check(MATCH_TIMING(timings[i], expected_timings[j], 120));
  90. mu_assert(j < expected_timings_len, "encoded more timings than expected");
  91. }
  92. }
  93. free(timings);
  94. mu_assert(j == expected_timings_len, "encoded less timings than expected");
  95. }
  96. static void
  97. run_encoder_decoder(const InfraredMessage input_messages[], uint32_t input_messages_len) {
  98. uint32_t* timings = 0;
  99. uint32_t timings_len = 200;
  100. bool level = false;
  101. timings = malloc(sizeof(uint32_t) * timings_len);
  102. for(uint32_t message_counter = 0; message_counter < input_messages_len; ++message_counter) {
  103. const InfraredMessage* message_encoded = &input_messages[message_counter];
  104. if(!message_encoded->repeat) {
  105. infrared_reset_encoder(encoder_handler, message_encoded);
  106. }
  107. timings_len = 200;
  108. run_encoder_fill_array(encoder_handler, timings, &timings_len, &level);
  109. furi_check(timings_len <= 200);
  110. const InfraredMessage* message_decoded = 0;
  111. for(int i = 0; i < timings_len; ++i) {
  112. message_decoded = infrared_decode(decoder_handler, level, timings[i]);
  113. if((i == timings_len - 2) && level && message_decoded) {
  114. /* In case we end with space timing - message can be decoded at last mark */
  115. break;
  116. } else if(i < timings_len - 1) {
  117. mu_check(!message_decoded);
  118. } else {
  119. if(!message_decoded) {
  120. message_decoded = infrared_check_decoder_ready(decoder_handler);
  121. }
  122. mu_check(message_decoded);
  123. }
  124. level = !level;
  125. }
  126. if(message_decoded) {
  127. compare_message_results(message_decoded, message_encoded);
  128. } else {
  129. mu_check(0);
  130. }
  131. }
  132. free(timings);
  133. }
  134. static void run_decoder(
  135. const uint32_t* input_delays,
  136. uint32_t input_delays_len,
  137. const InfraredMessage* message_expected,
  138. uint32_t message_expected_len) {
  139. InfraredMessage message_decoded_check_local;
  140. bool level = 0;
  141. uint32_t message_counter = 0;
  142. const InfraredMessage* message_decoded = 0;
  143. for(uint32_t i = 0; i < input_delays_len; ++i) {
  144. const InfraredMessage* message_decoded_check = 0;
  145. if(input_delays[i] > INFRARED_RAW_RX_TIMING_DELAY_US) {
  146. message_decoded_check = infrared_check_decoder_ready(decoder_handler);
  147. if(message_decoded_check) {
  148. /* infrared_decode() can reset message, but we have to call infrared_decode() to perform real
  149. * simulation: infrared_check() by timeout, then infrared_decode() when meet edge */
  150. message_decoded_check_local = *message_decoded_check;
  151. message_decoded_check = &message_decoded_check_local;
  152. }
  153. }
  154. message_decoded = infrared_decode(decoder_handler, level, input_delays[i]);
  155. if(message_decoded_check || message_decoded) {
  156. mu_assert(
  157. !(message_decoded_check && message_decoded),
  158. "both messages decoded: check_ready() and infrared_decode()");
  159. if(message_decoded_check) {
  160. message_decoded = message_decoded_check;
  161. }
  162. mu_assert(message_counter < message_expected_len, "decoded more than expected");
  163. compare_message_results(message_decoded, &message_expected[message_counter]);
  164. ++message_counter;
  165. }
  166. level = !level;
  167. }
  168. message_decoded = infrared_check_decoder_ready(decoder_handler);
  169. if(message_decoded) {
  170. compare_message_results(message_decoded, &message_expected[message_counter]);
  171. ++message_counter;
  172. }
  173. mu_assert(message_counter == message_expected_len, "decoded less than expected");
  174. }
  175. MU_TEST(test_decoder_samsung32) {
  176. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  177. }
  178. MU_TEST(test_mix) {
  179. RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2);
  180. RUN_DECODER(test_decoder_sirc_input1, test_decoder_sirc_expected1);
  181. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  182. // can use encoder data for decoding, but can't do opposite
  183. RUN_DECODER(test_encoder_rc6_expected1, test_encoder_rc6_input1);
  184. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  185. RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
  186. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  187. RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1);
  188. RUN_DECODER(test_decoder_sirc_input2, test_decoder_sirc_expected2);
  189. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  190. RUN_DECODER(test_decoder_sirc_input4, test_decoder_sirc_expected4);
  191. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  192. RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
  193. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  194. RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5);
  195. RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3);
  196. RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5);
  197. RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
  198. RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3);
  199. }
  200. MU_TEST(test_decoder_nec) {
  201. RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1);
  202. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  203. RUN_DECODER(test_decoder_nec_input3, test_decoder_nec_expected3);
  204. }
  205. MU_TEST(test_decoder_unexpected_end_in_sequence) {
  206. // test_decoder_nec_input1 and test_decoder_nec_input2 shuts unexpected
  207. RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1);
  208. RUN_DECODER(test_decoder_nec_input1, test_decoder_nec_expected1);
  209. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  210. RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
  211. }
  212. MU_TEST(test_decoder_necext1) {
  213. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  214. RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
  215. }
  216. MU_TEST(test_decoder_long_packets_with_nec_start) {
  217. RUN_DECODER(test_decoder_nec42ext_input1, test_decoder_nec42ext_expected1);
  218. RUN_DECODER(test_decoder_nec42ext_input2, test_decoder_nec42ext_expected2);
  219. }
  220. MU_TEST(test_encoder_sirc) {
  221. RUN_ENCODER(test_encoder_sirc_input1, test_encoder_sirc_expected1);
  222. RUN_ENCODER(test_encoder_sirc_input2, test_encoder_sirc_expected2);
  223. }
  224. MU_TEST(test_decoder_sirc) {
  225. RUN_DECODER(test_decoder_sirc_input3, test_decoder_sirc_expected3);
  226. RUN_DECODER(test_decoder_sirc_input1, test_decoder_sirc_expected1);
  227. RUN_DECODER(test_decoder_sirc_input2, test_decoder_sirc_expected2);
  228. RUN_DECODER(test_decoder_sirc_input4, test_decoder_sirc_expected4);
  229. RUN_DECODER(test_decoder_sirc_input5, test_decoder_sirc_expected5);
  230. RUN_ENCODER_DECODER(test_sirc);
  231. }
  232. MU_TEST(test_decoder_rc5) {
  233. RUN_DECODER(test_decoder_rc5x_input1, test_decoder_rc5x_expected1);
  234. RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1);
  235. RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2);
  236. RUN_DECODER(test_decoder_rc5_input3, test_decoder_rc5_expected3);
  237. RUN_DECODER(test_decoder_rc5_input4, test_decoder_rc5_expected4);
  238. RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5);
  239. RUN_DECODER(test_decoder_rc5_input6, test_decoder_rc5_expected6);
  240. RUN_DECODER(test_decoder_rc5_input_all_repeats, test_decoder_rc5_expected_all_repeats);
  241. }
  242. MU_TEST(test_encoder_rc5x) {
  243. RUN_ENCODER(test_decoder_rc5x_expected1, test_decoder_rc5x_input1);
  244. }
  245. MU_TEST(test_encoder_rc5) {
  246. RUN_ENCODER(test_decoder_rc5_expected_all_repeats, test_decoder_rc5_input_all_repeats);
  247. }
  248. MU_TEST(test_decoder_rc6) {
  249. RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
  250. }
  251. MU_TEST(test_encoder_rc6) {
  252. RUN_ENCODER(test_encoder_rc6_input1, test_encoder_rc6_expected1);
  253. }
  254. MU_TEST(test_encoder_decoder_all) {
  255. RUN_ENCODER_DECODER(test_nec);
  256. RUN_ENCODER_DECODER(test_necext);
  257. RUN_ENCODER_DECODER(test_nec42);
  258. RUN_ENCODER_DECODER(test_nec42ext);
  259. RUN_ENCODER_DECODER(test_samsung32);
  260. RUN_ENCODER_DECODER(test_rc6);
  261. RUN_ENCODER_DECODER(test_rc5);
  262. RUN_ENCODER_DECODER(test_sirc);
  263. }
  264. MU_TEST_SUITE(test_infrared_decoder_encoder) {
  265. MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
  266. MU_RUN_TEST(test_encoder_sirc);
  267. MU_RUN_TEST(test_decoder_sirc);
  268. MU_RUN_TEST(test_encoder_rc5x);
  269. MU_RUN_TEST(test_encoder_rc5);
  270. MU_RUN_TEST(test_decoder_rc5);
  271. MU_RUN_TEST(test_decoder_rc6);
  272. MU_RUN_TEST(test_encoder_rc6);
  273. MU_RUN_TEST(test_decoder_unexpected_end_in_sequence);
  274. MU_RUN_TEST(test_decoder_long_packets_with_nec_start);
  275. MU_RUN_TEST(test_decoder_nec);
  276. MU_RUN_TEST(test_decoder_samsung32);
  277. MU_RUN_TEST(test_decoder_necext1);
  278. MU_RUN_TEST(test_mix);
  279. MU_RUN_TEST(test_encoder_decoder_all);
  280. }
  281. int run_minunit_test_infrared_decoder_encoder() {
  282. MU_RUN_SUITE(test_infrared_decoder_encoder);
  283. return MU_EXIT_CODE;
  284. }