kinggates_stylo_4k.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #include "kinggates_stylo_4k.h"
  2. #include "keeloq_common.h"
  3. #include "../subghz_keystore.h"
  4. #include "../blocks/const.h"
  5. #include "../blocks/decoder.h"
  6. #include "../blocks/encoder.h"
  7. #include "../blocks/generic.h"
  8. #include "../blocks/math.h"
  9. #define TAG "SubGhzProtocoKingGates_stylo_4k"
  10. static const SubGhzBlockConst subghz_protocol_kinggates_stylo_4k_const = {
  11. .te_short = 400,
  12. .te_long = 1100,
  13. .te_delta = 140,
  14. .min_count_bit_for_found = 89,
  15. };
  16. struct SubGhzProtocolDecoderKingGates_stylo_4k {
  17. SubGhzProtocolDecoderBase base;
  18. SubGhzBlockDecoder decoder;
  19. SubGhzBlockGeneric generic;
  20. uint64_t data;
  21. uint16_t header_count;
  22. SubGhzKeystore* keystore;
  23. };
  24. struct SubGhzProtocolEncoderKingGates_stylo_4k {
  25. SubGhzProtocolEncoderBase base;
  26. SubGhzProtocolBlockEncoder encoder;
  27. SubGhzBlockGeneric generic;
  28. };
  29. typedef enum {
  30. KingGates_stylo_4kDecoderStepReset = 0,
  31. KingGates_stylo_4kDecoderStepCheckPreambula,
  32. KingGates_stylo_4kDecoderStepCheckStartBit,
  33. KingGates_stylo_4kDecoderStepSaveDuration,
  34. KingGates_stylo_4kDecoderStepCheckDuration,
  35. } KingGates_stylo_4kDecoderStep;
  36. const SubGhzProtocolDecoder subghz_protocol_kinggates_stylo_4k_decoder = {
  37. .alloc = subghz_protocol_decoder_kinggates_stylo_4k_alloc,
  38. .free = subghz_protocol_decoder_kinggates_stylo_4k_free,
  39. .feed = subghz_protocol_decoder_kinggates_stylo_4k_feed,
  40. .reset = subghz_protocol_decoder_kinggates_stylo_4k_reset,
  41. .get_hash_data = subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data,
  42. .serialize = subghz_protocol_decoder_kinggates_stylo_4k_serialize,
  43. .deserialize = subghz_protocol_decoder_kinggates_stylo_4k_deserialize,
  44. .get_string = subghz_protocol_decoder_kinggates_stylo_4k_get_string,
  45. };
  46. const SubGhzProtocolEncoder subghz_protocol_kinggates_stylo_4k_encoder = {
  47. .alloc = NULL,
  48. .free = NULL,
  49. .deserialize = NULL,
  50. .stop = NULL,
  51. .yield = NULL,
  52. };
  53. const SubGhzProtocol subghz_protocol_kinggates_stylo_4k = {
  54. .name = SUBGHZ_PROTOCOL_KINGGATES_STYLO_4K_NAME,
  55. .type = SubGhzProtocolTypeDynamic,
  56. .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable,
  57. .decoder = &subghz_protocol_kinggates_stylo_4k_decoder,
  58. .encoder = &subghz_protocol_kinggates_stylo_4k_encoder,
  59. };
  60. void* subghz_protocol_decoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment) {
  61. SubGhzProtocolDecoderKingGates_stylo_4k* instance =
  62. malloc(sizeof(SubGhzProtocolDecoderKingGates_stylo_4k));
  63. instance->base.protocol = &subghz_protocol_kinggates_stylo_4k;
  64. instance->generic.protocol_name = instance->base.protocol->name;
  65. instance->keystore = subghz_environment_get_keystore(environment);
  66. return instance;
  67. }
  68. void subghz_protocol_decoder_kinggates_stylo_4k_free(void* context) {
  69. furi_assert(context);
  70. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  71. free(instance);
  72. }
  73. void subghz_protocol_decoder_kinggates_stylo_4k_reset(void* context) {
  74. furi_assert(context);
  75. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  76. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  77. }
  78. void subghz_protocol_decoder_kinggates_stylo_4k_feed(void* context, bool level, uint32_t duration) {
  79. furi_assert(context);
  80. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  81. switch(instance->decoder.parser_step) {
  82. case KingGates_stylo_4kDecoderStepReset:
  83. if((level) && DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short) <
  84. subghz_protocol_kinggates_stylo_4k_const.te_delta) {
  85. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepCheckPreambula;
  86. instance->header_count++;
  87. }
  88. break;
  89. case KingGates_stylo_4kDecoderStepCheckPreambula:
  90. if((!level) &&
  91. (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short) <
  92. subghz_protocol_kinggates_stylo_4k_const.te_delta)) {
  93. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  94. break;
  95. }
  96. if((instance->header_count > 2) &&
  97. (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_long * 2) <
  98. subghz_protocol_kinggates_stylo_4k_const.te_delta * 2)) {
  99. // Found header
  100. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepCheckStartBit;
  101. } else {
  102. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  103. instance->header_count = 0;
  104. }
  105. break;
  106. case KingGates_stylo_4kDecoderStepCheckStartBit:
  107. if((level) &&
  108. DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short * 2) <
  109. subghz_protocol_kinggates_stylo_4k_const.te_delta * 2) {
  110. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
  111. instance->decoder.decode_data = 0;
  112. instance->data = 0;
  113. instance->decoder.decode_count_bit = 0;
  114. instance->header_count = 0;
  115. }
  116. break;
  117. case KingGates_stylo_4kDecoderStepSaveDuration:
  118. if(!level) {
  119. if(duration >= ((uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long * 3)) {
  120. if(instance->decoder.decode_count_bit ==
  121. subghz_protocol_kinggates_stylo_4k_const.min_count_bit_for_found) {
  122. instance->generic.data = instance->data;
  123. instance->data = instance->decoder.decode_data;
  124. instance->generic.data_count_bit = instance->decoder.decode_count_bit;
  125. if(instance->base.callback)
  126. instance->base.callback(&instance->base, instance->base.context);
  127. }
  128. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  129. instance->decoder.decode_data = 0;
  130. instance->data = 0;
  131. instance->decoder.decode_count_bit = 0;
  132. instance->header_count = 0;
  133. break;
  134. } else {
  135. instance->decoder.te_last = duration;
  136. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepCheckDuration;
  137. }
  138. } else {
  139. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  140. instance->header_count = 0;
  141. }
  142. break;
  143. case KingGates_stylo_4kDecoderStepCheckDuration:
  144. if(level) {
  145. if((DURATION_DIFF(
  146. instance->decoder.te_last, subghz_protocol_kinggates_stylo_4k_const.te_short) <
  147. subghz_protocol_kinggates_stylo_4k_const.te_delta) &&
  148. (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_long) <
  149. subghz_protocol_kinggates_stylo_4k_const.te_delta * 2)) {
  150. subghz_protocol_blocks_add_bit(&instance->decoder, 1);
  151. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
  152. } else if(
  153. (DURATION_DIFF(
  154. instance->decoder.te_last, subghz_protocol_kinggates_stylo_4k_const.te_long) <
  155. subghz_protocol_kinggates_stylo_4k_const.te_delta * 2) &&
  156. (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short) <
  157. subghz_protocol_kinggates_stylo_4k_const.te_delta)) {
  158. subghz_protocol_blocks_add_bit(&instance->decoder, 0);
  159. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepSaveDuration;
  160. } else {
  161. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  162. instance->header_count = 0;
  163. }
  164. if(instance->decoder.decode_count_bit == 53) {
  165. instance->data = instance->decoder.decode_data;
  166. instance->decoder.decode_data = 0;
  167. }
  168. } else {
  169. instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset;
  170. instance->header_count = 0;
  171. }
  172. break;
  173. }
  174. }
  175. /**
  176. * Analysis of received data
  177. * @param instance Pointer to a SubGhzBlockGeneric* instance
  178. * @param file_name Full path to rainbow table the file
  179. */
  180. static void subghz_protocol_kinggates_stylo_4k_remote_controller(
  181. SubGhzBlockGeneric* instance,
  182. uint64_t data,
  183. SubGhzKeystore* keystore) {
  184. /**
  185. * 9500us 12*(400/400) 2200/800|1-bit|0-bit|
  186. * _ _ _ __ ___ _
  187. * ________| |_| |_..._| |_____| |_| |___| |.....
  188. *
  189. * 1-bit 400/1100 us
  190. * 0-bit 1100/400 us
  191. *
  192. * The package consists of 89 bits of data, LSB first
  193. * Data - 1C9037F0C80000 CE280BA00
  194. * S[3] S[2] 1 key S[1] S[0] 2 byte always 0 Hop[3] Hop[2] Hop[1] Hop[0] 0
  195. * 11100100 10000001 1 0111 11110000 11001000 00000000 00000000 11001110 00101000 00001011 10100000 0000
  196. *
  197. * Encryption - keeloq Simple Learning
  198. * key C S[3] CNT
  199. * Decrypt - 0xEC270B9C => 0x E C 27 0B9C
  200. *
  201. *
  202. *
  203. */
  204. uint32_t hop = subghz_protocol_blocks_reverse_key(data >> 4, 32);
  205. uint64_t fix = subghz_protocol_blocks_reverse_key(instance->data, 53);
  206. bool ret = false;
  207. uint32_t decrypt = 0;
  208. instance->btn = (fix >> 17) & 0x0F;
  209. instance->serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF);
  210. for
  211. M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
  212. if(manufacture_code->type == KEELOQ_LEARNING_SIMPLE) {
  213. decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
  214. if(((decrypt >> 28) == instance->btn) && (((decrypt >> 24) & 0x0F) == 0x0C) &&
  215. (((decrypt >> 16) & 0xFF) == (instance->serial & 0xFF))) {
  216. ret = true;
  217. break;
  218. }
  219. }
  220. }
  221. if(ret) {
  222. instance->cnt = decrypt & 0xFFFF;
  223. } else {
  224. instance->btn = 0;
  225. instance->serial = 0;
  226. instance->cnt = 0;
  227. }
  228. }
  229. uint8_t subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data(void* context) {
  230. furi_assert(context);
  231. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  232. return subghz_protocol_blocks_get_hash_data(
  233. &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
  234. }
  235. bool subghz_protocol_decoder_kinggates_stylo_4k_serialize(
  236. void* context,
  237. FlipperFormat* flipper_format,
  238. SubGhzRadioPreset* preset) {
  239. furi_assert(context);
  240. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  241. bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
  242. uint8_t key_data[sizeof(uint64_t)] = {0};
  243. for(size_t i = 0; i < sizeof(uint64_t); i++) {
  244. key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF;
  245. }
  246. if(res && !flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
  247. FURI_LOG_E(TAG, "Unable to add Data");
  248. res = false;
  249. }
  250. return res;
  251. return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
  252. }
  253. bool subghz_protocol_decoder_kinggates_stylo_4k_deserialize(
  254. void* context,
  255. FlipperFormat* flipper_format) {
  256. furi_assert(context);
  257. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  258. bool ret = false;
  259. do {
  260. if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
  261. break;
  262. }
  263. if(instance->generic.data_count_bit !=
  264. subghz_protocol_kinggates_stylo_4k_const.min_count_bit_for_found) {
  265. FURI_LOG_E(TAG, "Wrong number of bits in key");
  266. break;
  267. }
  268. if(!flipper_format_rewind(flipper_format)) {
  269. FURI_LOG_E(TAG, "Rewind error");
  270. break;
  271. }
  272. uint8_t key_data[sizeof(uint64_t)] = {0};
  273. if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
  274. FURI_LOG_E(TAG, "Missing Data");
  275. break;
  276. }
  277. for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
  278. instance->data = instance->data << 8 | key_data[i];
  279. }
  280. ret = true;
  281. } while(false);
  282. return ret;
  283. }
  284. void subghz_protocol_decoder_kinggates_stylo_4k_get_string(void* context, FuriString* output) {
  285. furi_assert(context);
  286. SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
  287. subghz_protocol_kinggates_stylo_4k_remote_controller(
  288. &instance->generic, instance->data, instance->keystore);
  289. furi_string_cat_printf(
  290. output,
  291. "%s\r\n"
  292. "Key:0x%llX%07llX %dbit\r\n"
  293. "Sn:0x%08lX Btn:0x%01X\r\n"
  294. "Cnt:0x%04lX\r\n",
  295. instance->generic.protocol_name,
  296. instance->generic.data,
  297. instance->data,
  298. instance->generic.data_count_bit,
  299. instance->generic.serial,
  300. instance->generic.btn,
  301. instance->generic.cnt);
  302. }