subghz_protocol_hormann.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include "subghz_protocol_hormann.h"
  2. #include "subghz_protocol_common.h"
  3. struct SubGhzProtocolHormann {
  4. SubGhzProtocolCommon common;
  5. };
  6. typedef enum {
  7. HormannDecoderStepReset = 0,
  8. HormannDecoderStepFoundStartHeader,
  9. HormannDecoderStepFoundHeader,
  10. HormannDecoderStepFoundStartBit,
  11. HormannDecoderStepSaveDuration,
  12. HormannDecoderStepCheckDuration,
  13. } HormannDecoderStep;
  14. SubGhzProtocolHormann* subghz_protocol_hormann_alloc() {
  15. SubGhzProtocolHormann* instance = furi_alloc(sizeof(SubGhzProtocolHormann));
  16. instance->common.name = "Hormann HSM";
  17. instance->common.code_min_count_bit_for_found = 44;
  18. instance->common.te_short = 511;
  19. instance->common.te_long = 1022;
  20. instance->common.te_delta = 200;
  21. instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
  22. instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_hormann_to_str;
  23. instance->common.to_save_string =
  24. (SubGhzProtocolCommonGetStrSave)subghz_protocol_hormann_to_save_str;
  25. instance->common.to_load_protocol_from_file =
  26. (SubGhzProtocolCommonLoadFromFile)subghz_protocol_hormann_to_load_protocol_from_file;
  27. instance->common.to_load_protocol =
  28. (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_hormann_to_load_protocol;
  29. instance->common.get_upload_protocol =
  30. (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_hormann_send_key;
  31. return instance;
  32. }
  33. void subghz_protocol_hormann_free(SubGhzProtocolHormann* instance) {
  34. furi_assert(instance);
  35. free(instance);
  36. }
  37. bool subghz_protocol_hormann_send_key(
  38. SubGhzProtocolHormann* instance,
  39. SubGhzProtocolCommonEncoder* encoder) {
  40. furi_assert(instance);
  41. furi_assert(encoder);
  42. size_t index = 0;
  43. encoder->size_upload = 3 + (instance->common.code_last_count_bit * 2 + 2) * 20 + 1;
  44. if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
  45. //Send header
  46. encoder->upload[index++] =
  47. level_duration_make(false, (uint32_t)instance->common.te_short * 64);
  48. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 64);
  49. encoder->upload[index++] =
  50. level_duration_make(false, (uint32_t)instance->common.te_short * 64);
  51. encoder->repeat = 10;
  52. for(size_t repeat = 0; repeat < 20; repeat++) {
  53. //Send start bit
  54. encoder->upload[index++] =
  55. level_duration_make(true, (uint32_t)instance->common.te_short * 24);
  56. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
  57. //Send key data
  58. for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
  59. if(bit_read(instance->common.code_last_found, i - 1)) {
  60. //send bit 1
  61. encoder->upload[index++] =
  62. level_duration_make(true, (uint32_t)instance->common.te_long);
  63. encoder->upload[index++] =
  64. level_duration_make(false, (uint32_t)instance->common.te_short);
  65. } else {
  66. //send bit 0
  67. encoder->upload[index++] =
  68. level_duration_make(true, (uint32_t)instance->common.te_short);
  69. encoder->upload[index++] =
  70. level_duration_make(false, (uint32_t)instance->common.te_long);
  71. }
  72. }
  73. }
  74. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 24);
  75. return true;
  76. }
  77. void subghz_protocol_hormann_reset(SubGhzProtocolHormann* instance) {
  78. instance->common.parser_step = HormannDecoderStepReset;
  79. }
  80. void subghz_protocol_hormann_parse(SubGhzProtocolHormann* instance, bool level, uint32_t duration) {
  81. switch(instance->common.parser_step) {
  82. case HormannDecoderStepReset:
  83. if((level) && (DURATION_DIFF(duration, instance->common.te_short * 64) <
  84. instance->common.te_delta * 64)) {
  85. instance->common.parser_step = HormannDecoderStepFoundStartHeader;
  86. } else {
  87. instance->common.parser_step = HormannDecoderStepReset;
  88. }
  89. break;
  90. case HormannDecoderStepFoundStartHeader:
  91. if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 64) <
  92. instance->common.te_delta * 64)) {
  93. instance->common.parser_step = HormannDecoderStepFoundHeader;
  94. } else {
  95. instance->common.parser_step = HormannDecoderStepReset;
  96. }
  97. break;
  98. case HormannDecoderStepFoundHeader:
  99. if((level) && (DURATION_DIFF(duration, instance->common.te_short * 24) <
  100. instance->common.te_delta * 24)) {
  101. instance->common.parser_step = HormannDecoderStepFoundStartBit;
  102. } else {
  103. instance->common.parser_step = HormannDecoderStepReset;
  104. }
  105. break;
  106. case HormannDecoderStepFoundStartBit:
  107. if((!level) &&
  108. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  109. instance->common.parser_step = HormannDecoderStepSaveDuration;
  110. instance->common.code_found = 0;
  111. instance->common.code_count_bit = 0;
  112. } else {
  113. instance->common.parser_step = HormannDecoderStepReset;
  114. }
  115. break;
  116. case HormannDecoderStepSaveDuration:
  117. if(level) { //save interval
  118. if(duration >= (instance->common.te_short * 5)) {
  119. instance->common.parser_step = HormannDecoderStepFoundStartBit;
  120. if(instance->common.code_count_bit >=
  121. instance->common.code_min_count_bit_for_found) {
  122. instance->common.serial = 0x0;
  123. instance->common.btn = 0x0;
  124. instance->common.code_last_found = instance->common.code_found;
  125. instance->common.code_last_count_bit = instance->common.code_count_bit;
  126. if(instance->common.callback)
  127. instance->common.callback(
  128. (SubGhzProtocolCommon*)instance, instance->common.context);
  129. }
  130. break;
  131. }
  132. instance->common.te_last = duration;
  133. instance->common.parser_step = HormannDecoderStepCheckDuration;
  134. } else {
  135. instance->common.parser_step = HormannDecoderStepReset;
  136. }
  137. break;
  138. case HormannDecoderStepCheckDuration:
  139. if(!level) {
  140. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  141. instance->common.te_delta) &&
  142. (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
  143. subghz_protocol_common_add_bit(&instance->common, 0);
  144. instance->common.parser_step = HormannDecoderStepSaveDuration;
  145. } else if(
  146. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  147. instance->common.te_delta) &&
  148. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  149. subghz_protocol_common_add_bit(&instance->common, 1);
  150. instance->common.parser_step = HormannDecoderStepSaveDuration;
  151. } else
  152. instance->common.parser_step = HormannDecoderStepReset;
  153. } else {
  154. instance->common.parser_step = HormannDecoderStepReset;
  155. }
  156. break;
  157. }
  158. }
  159. void subghz_protocol_hormann_to_str(SubGhzProtocolHormann* instance, string_t output) {
  160. uint32_t code_found_hi = instance->common.code_last_found >> 32;
  161. uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
  162. instance->common.btn = (instance->common.code_last_found >> 4) & 0xF;
  163. string_cat_printf(
  164. output,
  165. "%s\r\n"
  166. "%dbit\r\n"
  167. "Key:0x%03lX%08lX\r\n"
  168. "Btn:0x%01X",
  169. instance->common.name,
  170. instance->common.code_last_count_bit,
  171. code_found_hi,
  172. code_found_lo,
  173. instance->common.btn);
  174. }
  175. void subghz_protocol_hormann_to_save_str(SubGhzProtocolHormann* instance, string_t output) {
  176. string_printf(
  177. output,
  178. "Protocol: %s\n"
  179. "Bit: %d\n"
  180. "Key: %08lX%08lX\n",
  181. instance->common.name,
  182. instance->common.code_last_count_bit,
  183. (uint32_t)(instance->common.code_last_found >> 32),
  184. (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
  185. }
  186. bool subghz_protocol_hormann_to_load_protocol_from_file(
  187. FileWorker* file_worker,
  188. SubGhzProtocolHormann* instance,
  189. const char* file_path) {
  190. bool loaded = false;
  191. string_t temp_str;
  192. string_init(temp_str);
  193. int res = 0;
  194. int data = 0;
  195. do {
  196. // Read and parse bit data from 2nd line
  197. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  198. break;
  199. }
  200. res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
  201. if(res != 1) {
  202. break;
  203. }
  204. instance->common.code_last_count_bit = (uint8_t)data;
  205. // Read and parse key data from 3nd line
  206. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  207. break;
  208. }
  209. // strlen("Key: ") = 5
  210. string_right(temp_str, 5);
  211. uint8_t buf_key[8] = {0};
  212. if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)) {
  213. break;
  214. }
  215. for(uint8_t i = 0; i < 8; i++) {
  216. instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i];
  217. }
  218. loaded = true;
  219. } while(0);
  220. string_clear(temp_str);
  221. return loaded;
  222. }
  223. void subghz_decoder_hormann_to_load_protocol(SubGhzProtocolHormann* instance, void* context) {
  224. furi_assert(context);
  225. furi_assert(instance);
  226. SubGhzProtocolCommonLoad* data = context;
  227. instance->common.code_last_found = data->code_found;
  228. instance->common.code_last_count_bit = data->code_count_bit;
  229. }