subghz_protocol_scher_khan.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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. }
  120. break;
  121. case ScherKhanDecoderStepCheckPreambula:
  122. if(level) {
  123. if((DURATION_DIFF(duration, instance->common.te_short * 2) <
  124. instance->common.te_delta) ||
  125. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  126. instance->common.te_last = duration;
  127. } else {
  128. instance->common.parser_step = ScherKhanDecoderStepReset;
  129. }
  130. } else if(
  131. (DURATION_DIFF(duration, instance->common.te_short * 2) < instance->common.te_delta) ||
  132. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  133. if(DURATION_DIFF(instance->common.te_last, instance->common.te_short * 2) <
  134. instance->common.te_delta) {
  135. // Found header
  136. instance->common.header_count++;
  137. break;
  138. } else if(
  139. DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  140. instance->common.te_delta) {
  141. // Found start bit
  142. if(instance->common.header_count >= 2) {
  143. instance->common.parser_step = ScherKhanDecoderStepSaveDuration;
  144. instance->common.code_found = 0;
  145. instance->common.code_count_bit = 1;
  146. } else {
  147. instance->common.parser_step = ScherKhanDecoderStepReset;
  148. }
  149. } else {
  150. instance->common.parser_step = ScherKhanDecoderStepReset;
  151. }
  152. } else {
  153. instance->common.parser_step = ScherKhanDecoderStepReset;
  154. }
  155. break;
  156. case ScherKhanDecoderStepSaveDuration:
  157. if(level) {
  158. if(duration >= (instance->common.te_long + instance->common.te_delta * 2)) {
  159. //Found stop bit
  160. instance->common.parser_step = ScherKhanDecoderStepReset;
  161. if(instance->common.code_count_bit >=
  162. instance->common.code_min_count_bit_for_found) {
  163. instance->common.code_last_found = instance->common.code_found;
  164. instance->common.code_last_count_bit = instance->common.code_count_bit;
  165. if(instance->common.callback)
  166. instance->common.callback(
  167. (SubGhzProtocolCommon*)instance, instance->common.context);
  168. }
  169. instance->common.code_found = 0;
  170. instance->common.code_count_bit = 0;
  171. break;
  172. } else {
  173. instance->common.te_last = duration;
  174. instance->common.parser_step = ScherKhanDecoderStepCheckDuration;
  175. }
  176. } else {
  177. instance->common.parser_step = ScherKhanDecoderStepReset;
  178. }
  179. break;
  180. case ScherKhanDecoderStepCheckDuration:
  181. if(!level) {
  182. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  183. instance->common.te_delta) &&
  184. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  185. subghz_protocol_common_add_bit(&instance->common, 0);
  186. instance->common.parser_step = ScherKhanDecoderStepSaveDuration;
  187. } else if(
  188. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  189. instance->common.te_delta) &&
  190. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  191. subghz_protocol_common_add_bit(&instance->common, 1);
  192. instance->common.parser_step = ScherKhanDecoderStepSaveDuration;
  193. } else {
  194. instance->common.parser_step = ScherKhanDecoderStepReset;
  195. }
  196. } else {
  197. instance->common.parser_step = ScherKhanDecoderStepReset;
  198. }
  199. break;
  200. }
  201. }
  202. void subghz_protocol_scher_khan_to_str(SubGhzProtocolScherKhan* instance, string_t output) {
  203. subghz_protocol_scher_khan_check_remote_controller(instance);
  204. string_cat_printf(
  205. output,
  206. "%s %dbit\r\n"
  207. "Key:0x%lX%08lX\r\n"
  208. "Sn:%07lX Btn:%lX Cnt:%04X\r\n"
  209. "Pt: %s\r\n",
  210. instance->common.name,
  211. instance->common.code_last_count_bit,
  212. (uint32_t)(instance->common.code_last_found >> 32),
  213. (uint32_t)instance->common.code_last_found,
  214. instance->common.serial,
  215. instance->common.btn,
  216. instance->common.cnt,
  217. instance->protocol_name);
  218. }
  219. void subghz_decoder_scher_khan_to_load_protocol(SubGhzProtocolScherKhan* instance, void* context) {
  220. furi_assert(context);
  221. furi_assert(instance);
  222. SubGhzProtocolCommonLoad* data = context;
  223. instance->common.code_last_found = data->code_found;
  224. instance->common.code_last_count_bit = data->code_count_bit;
  225. subghz_protocol_scher_khan_check_remote_controller(instance);
  226. }