came.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #include "came.h"
  2. #include "../blocks/const.h"
  3. #include "../blocks/decoder.h"
  4. #include "../blocks/encoder.h"
  5. #include "../blocks/generic.h"
  6. #include "../blocks/math.h"
  7. /*
  8. * Help
  9. * https://phreakerclub.com/447
  10. *
  11. */
  12. #define TAG "SubGhzProtocolCAME"
  13. #define CAME_12_COUNT_BIT 12
  14. #define CAME_24_COUNT_BIT 24
  15. #define PRASTEL_COUNT_BIT 25
  16. #define PRASTEL_NAME "Prastel"
  17. #define AIRFORCE_COUNT_BIT 18
  18. #define AIRFORCE_NAME "Airforce"
  19. static const SubGhzBlockConst subghz_protocol_came_const = {
  20. .te_short = 320,
  21. .te_long = 640,
  22. .te_delta = 150,
  23. .min_count_bit_for_found = 12,
  24. };
  25. struct SubGhzProtocolDecoderCame {
  26. SubGhzProtocolDecoderBase base;
  27. SubGhzBlockDecoder decoder;
  28. SubGhzBlockGeneric generic;
  29. };
  30. struct SubGhzProtocolEncoderCame {
  31. SubGhzProtocolEncoderBase base;
  32. SubGhzProtocolBlockEncoder encoder;
  33. SubGhzBlockGeneric generic;
  34. };
  35. typedef enum {
  36. CameDecoderStepReset = 0,
  37. CameDecoderStepFoundStartBit,
  38. CameDecoderStepSaveDuration,
  39. CameDecoderStepCheckDuration,
  40. } CameDecoderStep;
  41. const SubGhzProtocolDecoder subghz_protocol_came_decoder = {
  42. .alloc = subghz_protocol_decoder_came_alloc,
  43. .free = subghz_protocol_decoder_came_free,
  44. .feed = subghz_protocol_decoder_came_feed,
  45. .reset = subghz_protocol_decoder_came_reset,
  46. .get_hash_data = subghz_protocol_decoder_came_get_hash_data,
  47. .serialize = subghz_protocol_decoder_came_serialize,
  48. .deserialize = subghz_protocol_decoder_came_deserialize,
  49. .get_string = subghz_protocol_decoder_came_get_string,
  50. };
  51. const SubGhzProtocolEncoder subghz_protocol_came_encoder = {
  52. .alloc = subghz_protocol_encoder_came_alloc,
  53. .free = subghz_protocol_encoder_came_free,
  54. .deserialize = subghz_protocol_encoder_came_deserialize,
  55. .stop = subghz_protocol_encoder_came_stop,
  56. .yield = subghz_protocol_encoder_came_yield,
  57. };
  58. const SubGhzProtocol subghz_protocol_came = {
  59. .name = SUBGHZ_PROTOCOL_CAME_NAME,
  60. .type = SubGhzProtocolTypeStatic,
  61. .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM |
  62. SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save |
  63. SubGhzProtocolFlag_Send,
  64. .decoder = &subghz_protocol_came_decoder,
  65. .encoder = &subghz_protocol_came_encoder,
  66. };
  67. void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment) {
  68. UNUSED(environment);
  69. SubGhzProtocolEncoderCame* instance = malloc(sizeof(SubGhzProtocolEncoderCame));
  70. instance->base.protocol = &subghz_protocol_came;
  71. instance->generic.protocol_name = instance->base.protocol->name;
  72. instance->encoder.repeat = 10;
  73. instance->encoder.size_upload = 128;
  74. instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
  75. instance->encoder.is_running = false;
  76. return instance;
  77. }
  78. void subghz_protocol_encoder_came_free(void* context) {
  79. furi_assert(context);
  80. SubGhzProtocolEncoderCame* instance = context;
  81. free(instance->encoder.upload);
  82. free(instance);
  83. }
  84. /**
  85. * Generating an upload from data.
  86. * @param instance Pointer to a SubGhzProtocolEncoderCame instance
  87. * @return true On success
  88. */
  89. static bool subghz_protocol_encoder_came_get_upload(SubGhzProtocolEncoderCame* instance) {
  90. furi_assert(instance);
  91. uint32_t header_te = 0;
  92. size_t index = 0;
  93. size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
  94. if(size_upload > instance->encoder.size_upload) {
  95. FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer.");
  96. return false;
  97. } else {
  98. instance->encoder.size_upload = size_upload;
  99. }
  100. //Send header
  101. switch(instance->generic.data_count_bit) {
  102. case CAME_24_COUNT_BIT:
  103. // CAME 24 Bit = 24320 us
  104. header_te = 76;
  105. break;
  106. case CAME_12_COUNT_BIT:
  107. case AIRFORCE_COUNT_BIT:
  108. // CAME 12 Bit Original only! and Airforce protocol = 15040 us
  109. header_te = 47;
  110. break;
  111. case PRASTEL_COUNT_BIT:
  112. // PRASTEL = 11520 us
  113. header_te = 36;
  114. break;
  115. default:
  116. // Some wrong detected protocols, 5120 us
  117. header_te = 16;
  118. break;
  119. }
  120. instance->encoder.upload[index++] =
  121. level_duration_make(false, (uint32_t)subghz_protocol_came_const.te_short * header_te);
  122. //Send start bit
  123. instance->encoder.upload[index++] =
  124. level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_short);
  125. //Send key data
  126. for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) {
  127. if(bit_read(instance->generic.data, i - 1)) {
  128. //send bit 1
  129. instance->encoder.upload[index++] =
  130. level_duration_make(false, (uint32_t)subghz_protocol_came_const.te_long);
  131. instance->encoder.upload[index++] =
  132. level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_short);
  133. } else {
  134. //send bit 0
  135. instance->encoder.upload[index++] =
  136. level_duration_make(false, (uint32_t)subghz_protocol_came_const.te_short);
  137. instance->encoder.upload[index++] =
  138. level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_long);
  139. }
  140. }
  141. return true;
  142. }
  143. SubGhzProtocolStatus
  144. subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format) {
  145. furi_assert(context);
  146. SubGhzProtocolEncoderCame* instance = context;
  147. SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
  148. do {
  149. ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
  150. if(ret != SubGhzProtocolStatusOk) {
  151. break;
  152. }
  153. if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) {
  154. FURI_LOG_E(TAG, "Wrong number of bits in key");
  155. ret = SubGhzProtocolStatusErrorValueBitCount;
  156. break;
  157. }
  158. //optional parameter parameter
  159. flipper_format_read_uint32(
  160. flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
  161. if(!subghz_protocol_encoder_came_get_upload(instance)) {
  162. ret = SubGhzProtocolStatusErrorEncoderGetUpload;
  163. break;
  164. }
  165. instance->encoder.is_running = true;
  166. } while(false);
  167. return ret;
  168. }
  169. void subghz_protocol_encoder_came_stop(void* context) {
  170. SubGhzProtocolEncoderCame* instance = context;
  171. instance->encoder.is_running = false;
  172. }
  173. LevelDuration subghz_protocol_encoder_came_yield(void* context) {
  174. SubGhzProtocolEncoderCame* instance = context;
  175. if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
  176. instance->encoder.is_running = false;
  177. return level_duration_reset();
  178. }
  179. LevelDuration ret = instance->encoder.upload[instance->encoder.front];
  180. if(++instance->encoder.front == instance->encoder.size_upload) {
  181. instance->encoder.repeat--;
  182. instance->encoder.front = 0;
  183. }
  184. return ret;
  185. }
  186. void* subghz_protocol_decoder_came_alloc(SubGhzEnvironment* environment) {
  187. UNUSED(environment);
  188. SubGhzProtocolDecoderCame* instance = malloc(sizeof(SubGhzProtocolDecoderCame));
  189. instance->base.protocol = &subghz_protocol_came;
  190. instance->generic.protocol_name = instance->base.protocol->name;
  191. return instance;
  192. }
  193. void subghz_protocol_decoder_came_free(void* context) {
  194. furi_assert(context);
  195. SubGhzProtocolDecoderCame* instance = context;
  196. free(instance);
  197. }
  198. void subghz_protocol_decoder_came_reset(void* context) {
  199. furi_assert(context);
  200. SubGhzProtocolDecoderCame* instance = context;
  201. instance->decoder.parser_step = CameDecoderStepReset;
  202. }
  203. void subghz_protocol_decoder_came_feed(void* context, bool level, uint32_t duration) {
  204. furi_assert(context);
  205. SubGhzProtocolDecoderCame* instance = context;
  206. switch(instance->decoder.parser_step) {
  207. case CameDecoderStepReset:
  208. if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_const.te_short * 56) <
  209. subghz_protocol_came_const.te_delta * 47)) {
  210. //Found header CAME
  211. instance->decoder.parser_step = CameDecoderStepFoundStartBit;
  212. }
  213. break;
  214. case CameDecoderStepFoundStartBit:
  215. if(!level) {
  216. break;
  217. } else if(
  218. DURATION_DIFF(duration, subghz_protocol_came_const.te_short) <
  219. subghz_protocol_came_const.te_delta) {
  220. //Found start bit CAME
  221. instance->decoder.parser_step = CameDecoderStepSaveDuration;
  222. instance->decoder.decode_data = 0;
  223. instance->decoder.decode_count_bit = 0;
  224. } else {
  225. instance->decoder.parser_step = CameDecoderStepReset;
  226. }
  227. break;
  228. case CameDecoderStepSaveDuration:
  229. if(!level) { //save interval
  230. if(duration >= (subghz_protocol_came_const.te_short * 4)) {
  231. instance->decoder.parser_step = CameDecoderStepFoundStartBit;
  232. if((instance->decoder.decode_count_bit ==
  233. subghz_protocol_came_const.min_count_bit_for_found) ||
  234. (instance->decoder.decode_count_bit == AIRFORCE_COUNT_BIT) ||
  235. (instance->decoder.decode_count_bit == PRASTEL_COUNT_BIT) ||
  236. (instance->decoder.decode_count_bit == CAME_24_COUNT_BIT)) {
  237. instance->generic.serial = 0x0;
  238. instance->generic.btn = 0x0;
  239. instance->generic.data = instance->decoder.decode_data;
  240. instance->generic.data_count_bit = instance->decoder.decode_count_bit;
  241. if(instance->base.callback)
  242. instance->base.callback(&instance->base, instance->base.context);
  243. }
  244. break;
  245. }
  246. instance->decoder.te_last = duration;
  247. instance->decoder.parser_step = CameDecoderStepCheckDuration;
  248. } else {
  249. instance->decoder.parser_step = CameDecoderStepReset;
  250. }
  251. break;
  252. case CameDecoderStepCheckDuration:
  253. if(level) {
  254. if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_came_const.te_short) <
  255. subghz_protocol_came_const.te_delta) &&
  256. (DURATION_DIFF(duration, subghz_protocol_came_const.te_long) <
  257. subghz_protocol_came_const.te_delta)) {
  258. subghz_protocol_blocks_add_bit(&instance->decoder, 0);
  259. instance->decoder.parser_step = CameDecoderStepSaveDuration;
  260. } else if(
  261. (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_came_const.te_long) <
  262. subghz_protocol_came_const.te_delta) &&
  263. (DURATION_DIFF(duration, subghz_protocol_came_const.te_short) <
  264. subghz_protocol_came_const.te_delta)) {
  265. subghz_protocol_blocks_add_bit(&instance->decoder, 1);
  266. instance->decoder.parser_step = CameDecoderStepSaveDuration;
  267. } else
  268. instance->decoder.parser_step = CameDecoderStepReset;
  269. } else {
  270. instance->decoder.parser_step = CameDecoderStepReset;
  271. }
  272. break;
  273. }
  274. }
  275. uint8_t subghz_protocol_decoder_came_get_hash_data(void* context) {
  276. furi_assert(context);
  277. SubGhzProtocolDecoderCame* instance = context;
  278. return subghz_protocol_blocks_get_hash_data(
  279. &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
  280. }
  281. SubGhzProtocolStatus subghz_protocol_decoder_came_serialize(
  282. void* context,
  283. FlipperFormat* flipper_format,
  284. SubGhzRadioPreset* preset) {
  285. furi_assert(context);
  286. SubGhzProtocolDecoderCame* instance = context;
  287. return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
  288. }
  289. SubGhzProtocolStatus
  290. subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format) {
  291. furi_assert(context);
  292. SubGhzProtocolDecoderCame* instance = context;
  293. SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
  294. do {
  295. ret = subghz_block_generic_deserialize(&instance->generic, flipper_format);
  296. if(ret != SubGhzProtocolStatusOk) {
  297. break;
  298. }
  299. if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) {
  300. FURI_LOG_E(TAG, "Wrong number of bits in key");
  301. ret = SubGhzProtocolStatusErrorValueBitCount;
  302. break;
  303. }
  304. } while(false);
  305. return ret;
  306. }
  307. void subghz_protocol_decoder_came_get_string(void* context, FuriString* output) {
  308. furi_assert(context);
  309. SubGhzProtocolDecoderCame* instance = context;
  310. uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
  311. uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key(
  312. instance->generic.data, instance->generic.data_count_bit);
  313. uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
  314. furi_string_cat_printf(
  315. output,
  316. "%s %dbit\r\n"
  317. "Key:0x%08lX\r\n"
  318. "Yek:0x%08lX\r\n",
  319. (instance->generic.data_count_bit == PRASTEL_COUNT_BIT ?
  320. PRASTEL_NAME :
  321. (instance->generic.data_count_bit == AIRFORCE_COUNT_BIT ?
  322. AIRFORCE_NAME :
  323. instance->generic.protocol_name)),
  324. instance->generic.data_count_bit,
  325. code_found_lo,
  326. code_found_reverse_lo);
  327. }