subghz_protocol_scher_khan.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "subghz_protocol_scher_khan.h"
  2. //https://phreakerclub.com/72
  3. //https://phreakerclub.com/forum/showthread.php?t=7&page=2
  4. //https://phreakerclub.com/forum/showthread.php?t=274&highlight=magicar
  5. //!!! https://phreakerclub.com/forum/showthread.php?t=489&highlight=magicar&page=5
  6. struct SubGhzProtocolScherKhan {
  7. SubGhzProtocolCommon common;
  8. const char* protocol_name;
  9. };
  10. typedef enum {
  11. ScherKhanDecoderStepReset = 0,
  12. ScherKhanDecoderStepCheckPreambula,
  13. ScherKhanDecoderStepSaveDuration,
  14. ScherKhanDecoderStepCheckDuration,
  15. } ScherKhanDecoderStep;
  16. SubGhzProtocolScherKhan* subghz_protocol_scher_khan_alloc(void) {
  17. SubGhzProtocolScherKhan* instance = furi_alloc(sizeof(SubGhzProtocolScherKhan));
  18. instance->common.name = "Scher-Khan";
  19. instance->common.code_min_count_bit_for_found = 35;
  20. instance->common.te_short = 750;
  21. instance->common.te_long = 1100;
  22. instance->common.te_delta = 150;
  23. instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
  24. instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_scher_khan_to_str;
  25. instance->common.to_load_protocol =
  26. (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_scher_khan_to_load_protocol;
  27. return instance;
  28. }
  29. void subghz_protocol_scher_khan_free(SubGhzProtocolScherKhan* instance) {
  30. furi_assert(instance);
  31. free(instance);
  32. }
  33. /** Send bit
  34. *
  35. * @param instance - SubGhzProtocolScherKhan instance
  36. * @param bit - bit
  37. */
  38. // void subghz_protocol_scher_khan_send_bit(SubGhzProtocolScherKhan* instance, uint8_t bit) {
  39. // if(bit) {
  40. // //send bit 1
  41. // SUBGHZ_TX_PIN_HIGH();
  42. // delay_us(instance->common.te_long);
  43. // SUBGHZ_TX_PIN_LOW();
  44. // delay_us(instance->common.te_short);
  45. // } else {
  46. // //send bit 0
  47. // SUBGHZ_TX_PIN_HIGH();
  48. // delay_us(instance->common.te_short);
  49. // SUBGHZ_TX_PIN_LOW();
  50. // delay_us(instance->common.te_long);
  51. // }
  52. // }
  53. // void subghz_protocol_scher_khan_send_key(
  54. // SubGhzProtocolScherKhan* instance,
  55. // uint64_t key,
  56. // uint8_t bit,
  57. // uint8_t repeat) {
  58. // while(repeat--) {
  59. // SUBGHZ_TX_PIN_HIGH();
  60. // //Send header
  61. // delay_us(instance->common.te_long * 2);
  62. // SUBGHZ_TX_PIN_LOW();
  63. // delay_us(instance->common.te_long * 2);
  64. // //Send key data
  65. // for(uint8_t i = bit; i > 0; i--) {
  66. // subghz_protocol_scher_khan_send_bit(instance, bit_read(key, i - 1));
  67. // }
  68. // }
  69. // }
  70. void subghz_protocol_scher_khan_reset(SubGhzProtocolScherKhan* instance) {
  71. instance->common.parser_step = ScherKhanDecoderStepReset;
  72. }
  73. /** Analysis of received data
  74. *
  75. * @param instance SubGhzProtocolScherKhan instance
  76. */
  77. void subghz_protocol_scher_khan_check_remote_controller(SubGhzProtocolScherKhan* instance) {
  78. /*
  79. * MAGICAR 51 bit 00000001A99121DE83C3 MAGIC CODE, Dinamic
  80. * 0E8C1619E830C -> 000011101000110000010110 0001 1001 1110 1000001100001100
  81. * 0E8C1629D830D -> 000011101000110000010110 0010 1001 1101 1000001100001101
  82. * 0E8C1649B830E -> 000011101000110000010110 0100 1001 1011 1000001100001110
  83. * 0E8C16897830F -> 000011101000110000010110 1000 1001 0111 1000001100001111
  84. * Serial Key Ser ~Key CNT
  85. */
  86. switch(instance->common.code_last_count_bit) {
  87. // case 35: //MAGIC CODE, Static
  88. // instance->protocol_name = "MAGIC CODE, Static";
  89. // break;
  90. case 51: //MAGIC CODE, Dinamic
  91. instance->protocol_name = "MAGIC CODE, Dinamic";
  92. instance->common.serial = ((instance->common.code_last_found >> 24) & 0xFFFFFF0) |
  93. ((instance->common.code_last_found >> 20) & 0x0F);
  94. instance->common.btn = (instance->common.code_last_found >> 24) & 0x0F;
  95. instance->common.cnt = instance->common.code_last_found & 0xFFFF;
  96. break;
  97. // case 57: //MAGIC CODE PRO / PRO2
  98. // instance->protocol_name = "MAGIC CODE PRO / PRO2";
  99. // break;
  100. default:
  101. instance->protocol_name = "Unknown";
  102. instance->common.serial = 0;
  103. instance->common.btn = 0;
  104. instance->common.cnt = 0;
  105. break;
  106. }
  107. }
  108. void subghz_protocol_scher_khan_parse(
  109. SubGhzProtocolScherKhan* instance,
  110. bool level,
  111. uint32_t duration) {
  112. switch(instance->common.parser_step) {
  113. case ScherKhanDecoderStepReset:
  114. if((level) &&
  115. (DURATION_DIFF(duration, instance->common.te_short * 2) < instance->common.te_delta)) {
  116. instance->common.parser_step = ScherKhanDecoderStepCheckPreambula;
  117. instance->common.te_last = duration;
  118. instance->common.header_count = 0;
  119. } else {
  120. instance->common.parser_step = ScherKhanDecoderStepReset;
  121. }
  122. break;
  123. case ScherKhanDecoderStepCheckPreambula:
  124. if(level) {
  125. if((DURATION_DIFF(duration, instance->common.te_short * 2) <
  126. instance->common.te_delta) ||
  127. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  128. instance->common.te_last = duration;
  129. } else {
  130. instance->common.parser_step = ScherKhanDecoderStepReset;
  131. }
  132. } else if(
  133. (DURATION_DIFF(duration, instance->common.te_short * 2) < instance->common.te_delta) ||
  134. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  135. if(DURATION_DIFF(instance->common.te_last, instance->common.te_short * 2) <
  136. instance->common.te_delta) {
  137. // Found header
  138. instance->common.header_count++;
  139. break;
  140. } else if(
  141. DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  142. instance->common.te_delta) {
  143. // Found start bit
  144. if(instance->common.header_count >= 2) {
  145. instance->common.parser_step = ScherKhanDecoderStepSaveDuration;
  146. instance->common.code_found = 0;
  147. instance->common.code_count_bit = 1;
  148. } else {
  149. instance->common.parser_step = ScherKhanDecoderStepReset;
  150. }
  151. } else {
  152. instance->common.parser_step = ScherKhanDecoderStepReset;
  153. }
  154. } else {
  155. instance->common.parser_step = ScherKhanDecoderStepReset;
  156. }
  157. break;
  158. case ScherKhanDecoderStepSaveDuration:
  159. if(level) {
  160. if(duration >= (instance->common.te_long + instance->common.te_delta * 2)) {
  161. //Found stop bit
  162. instance->common.parser_step = ScherKhanDecoderStepReset;
  163. if(instance->common.code_count_bit >=
  164. instance->common.code_min_count_bit_for_found) {
  165. instance->common.code_last_found = instance->common.code_found;
  166. instance->common.code_last_count_bit = instance->common.code_count_bit;
  167. if(instance->common.callback)
  168. instance->common.callback(
  169. (SubGhzProtocolCommon*)instance, instance->common.context);
  170. }
  171. instance->common.code_found = 0;
  172. instance->common.code_count_bit = 0;
  173. break;
  174. } else {
  175. instance->common.te_last = duration;
  176. instance->common.parser_step = ScherKhanDecoderStepCheckDuration;
  177. }
  178. } else {
  179. instance->common.parser_step = ScherKhanDecoderStepReset;
  180. }
  181. break;
  182. case ScherKhanDecoderStepCheckDuration:
  183. if(!level) {
  184. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  185. instance->common.te_delta) &&
  186. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  187. subghz_protocol_common_add_bit(&instance->common, 0);
  188. instance->common.parser_step = ScherKhanDecoderStepSaveDuration;
  189. } else if(
  190. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  191. instance->common.te_delta) &&
  192. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  193. subghz_protocol_common_add_bit(&instance->common, 1);
  194. instance->common.parser_step = ScherKhanDecoderStepSaveDuration;
  195. } else {
  196. instance->common.parser_step = ScherKhanDecoderStepReset;
  197. }
  198. } else {
  199. instance->common.parser_step = ScherKhanDecoderStepReset;
  200. }
  201. break;
  202. }
  203. }
  204. void subghz_protocol_scher_khan_to_str(SubGhzProtocolScherKhan* instance, string_t output) {
  205. subghz_protocol_scher_khan_check_remote_controller(instance);
  206. string_cat_printf(
  207. output,
  208. "%s %dbit\r\n"
  209. "Key:0x%lX%08lX\r\n"
  210. "Sn:%07lX Btn:%lX Cnt:%04X\r\n"
  211. "Pt: %s\r\n",
  212. instance->common.name,
  213. instance->common.code_last_count_bit,
  214. (uint32_t)(instance->common.code_last_found >> 32),
  215. (uint32_t)instance->common.code_last_found,
  216. instance->common.serial,
  217. instance->common.btn,
  218. instance->common.cnt,
  219. instance->protocol_name);
  220. }
  221. void subghz_decoder_scher_khan_to_load_protocol(SubGhzProtocolScherKhan* instance, void* context) {
  222. furi_assert(context);
  223. furi_assert(instance);
  224. SubGhzProtocolCommonLoad* data = context;
  225. instance->common.code_last_found = data->code_found;
  226. instance->common.code_last_count_bit = data->code_count_bit;
  227. subghz_protocol_scher_khan_check_remote_controller(instance);
  228. }