subghz_protocol_princeton.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #include "subghz_protocol_princeton.h"
  2. /*
  3. * Help
  4. * https://phreakerclub.com/447
  5. *
  6. */
  7. #define SUBGHZ_PT_SHORT 400
  8. #define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3)
  9. #define SUBGHZ_PT_GUARD (SUBGHZ_PT_SHORT * 30)
  10. struct SubGhzEncoderPrinceton {
  11. uint32_t key;
  12. uint16_t te;
  13. size_t repeat;
  14. size_t front;
  15. };
  16. SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() {
  17. SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton));
  18. return instance;
  19. }
  20. void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) {
  21. furi_assert(instance);
  22. free(instance);
  23. }
  24. void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder) {
  25. SubGhzDecoderPrinceton* pricenton = decoder;
  26. if((pricenton->te) != 0) {
  27. instance->te = pricenton->te;
  28. } else {
  29. instance->te = SUBGHZ_PT_SHORT;
  30. }
  31. }
  32. void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) {
  33. furi_assert(instance);
  34. instance->te = SUBGHZ_PT_SHORT;
  35. instance->key = key;
  36. instance->repeat = repeat;
  37. instance->front = 48;
  38. }
  39. size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance) {
  40. furi_assert(instance);
  41. return instance->repeat;
  42. }
  43. LevelDuration subghz_encoder_princeton_yield(void* context) {
  44. SubGhzEncoderPrinceton* instance = context;
  45. if(instance->repeat == 0) return level_duration_reset();
  46. size_t bit = instance->front / 2;
  47. bool level = !(instance->front % 2);
  48. LevelDuration ret;
  49. if(bit < 24) {
  50. uint8_t byte = bit / 8;
  51. uint8_t bit_in_byte = bit % 8;
  52. bool value = (((uint8_t*)&instance->key)[2 - byte] >> (7 - bit_in_byte)) & 1;
  53. if(value) {
  54. ret = level_duration_make(level, level ? instance->te * 3 : instance->te);
  55. } else {
  56. ret = level_duration_make(level, level ? instance->te : instance->te * 3);
  57. }
  58. } else {
  59. ret = level_duration_make(level, level ? instance->te : instance->te * 30);
  60. }
  61. instance->front++;
  62. if(instance->front == 50) {
  63. instance->repeat--;
  64. instance->front = 0;
  65. }
  66. return ret;
  67. }
  68. SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) {
  69. SubGhzDecoderPrinceton* instance = furi_alloc(sizeof(SubGhzDecoderPrinceton));
  70. instance->te = SUBGHZ_PT_SHORT;
  71. instance->common.name = "Princeton";
  72. instance->common.code_min_count_bit_for_found = 24;
  73. instance->common.te_short = SUBGHZ_PT_SHORT; //150;
  74. instance->common.te_long = SUBGHZ_PT_LONG; //450;
  75. instance->common.te_delta = 250; //50;
  76. instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
  77. instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str;
  78. instance->common.to_save_string =
  79. (SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str;
  80. instance->common.to_load_protocol_from_file =
  81. (SubGhzProtocolCommonLoadFromFile)subghz_decoder_princeton_to_load_protocol_from_file;
  82. instance->common.to_load_protocol =
  83. (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_princeton_to_load_protocol;
  84. instance->common.get_upload_protocol =
  85. (SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_princeton_send_key;
  86. return instance;
  87. }
  88. void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) {
  89. furi_assert(instance);
  90. free(instance);
  91. }
  92. uint16_t subghz_protocol_princeton_get_te(void* context) {
  93. SubGhzDecoderPrinceton* instance = context;
  94. return instance->te;
  95. }
  96. bool subghz_protocol_princeton_send_key(
  97. SubGhzDecoderPrinceton* instance,
  98. SubGhzProtocolCommonEncoder* encoder) {
  99. furi_assert(instance);
  100. furi_assert(encoder);
  101. size_t index = 0;
  102. encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2;
  103. if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
  104. //Send key data
  105. for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
  106. if(bit_read(instance->common.code_last_found, i - 1)) {
  107. //send bit 1
  108. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te * 3);
  109. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te);
  110. } else {
  111. //send bit 0
  112. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
  113. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 3);
  114. }
  115. }
  116. //Send Stop bit
  117. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
  118. //Send PT_GUARD
  119. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 30);
  120. return true;
  121. }
  122. void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) {
  123. instance->common.parser_step = 0;
  124. }
  125. void subghz_decoder_princeton_parse(
  126. SubGhzDecoderPrinceton* instance,
  127. bool level,
  128. uint32_t duration) {
  129. switch(instance->common.parser_step) {
  130. case 0:
  131. if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) <
  132. instance->common.te_delta * 36)) {
  133. //Found Preambula
  134. instance->common.parser_step = 1;
  135. instance->common.code_found = 0;
  136. instance->common.code_count_bit = 0;
  137. } else {
  138. instance->common.parser_step = 0;
  139. }
  140. break;
  141. case 1:
  142. //save duration
  143. if(level) {
  144. instance->common.te_last = duration;
  145. instance->common.parser_step = 2;
  146. }
  147. break;
  148. case 2:
  149. if(!level) {
  150. if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
  151. instance->common.parser_step = 1;
  152. if(instance->common.code_count_bit ==
  153. instance->common.code_min_count_bit_for_found) {
  154. if(instance->common.code_last_found == instance->common.code_found) {
  155. //instance->te = (instance->te+instance->common.te_last)/2; //Option 1 TE averaging
  156. if(instance->te > instance->common.te_last)
  157. instance->te = instance->common.te_last; //Option 2 TE averaging
  158. } else {
  159. instance->te = instance->common.te_last;
  160. }
  161. instance->common.code_last_found = instance->common.code_found;
  162. instance->common.code_last_count_bit = instance->common.code_count_bit;
  163. instance->common.serial = instance->common.code_found >> 4;
  164. instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
  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. }
  173. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  174. instance->common.te_delta) &&
  175. (DURATION_DIFF(duration, instance->common.te_long) <
  176. instance->common.te_delta * 3)) {
  177. subghz_protocol_common_add_bit(&instance->common, 0);
  178. instance->common.parser_step = 1;
  179. } else if(
  180. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  181. instance->common.te_delta * 3) &&
  182. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  183. subghz_protocol_common_add_bit(&instance->common, 1);
  184. instance->common.parser_step = 1;
  185. } else {
  186. instance->common.parser_step = 0;
  187. }
  188. } else {
  189. instance->common.parser_step = 0;
  190. }
  191. break;
  192. }
  193. }
  194. void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) {
  195. uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
  196. uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
  197. instance->common.code_last_found, instance->common.code_last_count_bit);
  198. uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
  199. string_cat_printf(
  200. output,
  201. "%s %dbit\r\n"
  202. "Key:0x%08lX\r\n"
  203. "Yek:0x%08lX\r\n"
  204. "Sn:0x%05lX BTN:%02X\r\n"
  205. "Te:%dus\r\n",
  206. instance->common.name,
  207. instance->common.code_last_count_bit,
  208. code_found_lo,
  209. code_found_reverse_lo,
  210. instance->common.serial,
  211. instance->common.btn,
  212. instance->te);
  213. }
  214. void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) {
  215. string_printf(
  216. output,
  217. "Protocol: %s\n"
  218. "Bit: %d\n"
  219. "Te: %d\n"
  220. "Key: %08lX\n",
  221. instance->common.name,
  222. instance->common.code_last_count_bit,
  223. instance->te,
  224. (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
  225. }
  226. bool subghz_decoder_princeton_to_load_protocol_from_file(
  227. FileWorker* file_worker,
  228. SubGhzDecoderPrinceton* instance) {
  229. bool loaded = false;
  230. string_t temp_str;
  231. string_init(temp_str);
  232. int res = 0;
  233. int data = 0;
  234. do {
  235. // Read and parse bit data from 2nd line
  236. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  237. break;
  238. }
  239. res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
  240. if(res != 1) {
  241. break;
  242. }
  243. instance->common.code_last_count_bit = (uint8_t)data;
  244. // Read and parse te data from 3nd line
  245. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  246. break;
  247. }
  248. res = sscanf(string_get_cstr(temp_str), "Te: %d\n", &data);
  249. if(res != 1) {
  250. break;
  251. }
  252. instance->te = (uint16_t)data;
  253. // Read and parse key data from 4nd line
  254. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  255. break;
  256. }
  257. uint32_t temp_key = 0;
  258. res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
  259. if(res != 1) {
  260. break;
  261. }
  262. instance->common.code_last_found = (uint64_t)temp_key;
  263. instance->common.serial = instance->common.code_last_found >> 4;
  264. instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
  265. loaded = true;
  266. } while(0);
  267. string_clear(temp_str);
  268. return loaded;
  269. }
  270. void subghz_decoder_princeton_to_load_protocol(
  271. SubGhzDecoderPrinceton* instance,
  272. void* context) {
  273. furi_assert(context);
  274. furi_assert(instance);
  275. SubGhzProtocolCommonLoad* data = context;
  276. instance->common.code_last_found = data->code_found;
  277. instance->common.code_last_count_bit = data->code_count_bit;
  278. instance->te = data->param1;
  279. instance->common.serial = instance->common.code_last_found >> 4;
  280. instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
  281. }