subghz_protocol_princeton.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #include "subghz_protocol_princeton.h"
  2. /*
  3. * Help
  4. * https://phreakerclub.com/447
  5. *
  6. */
  7. #define SUBGHZ_PT_SHORT 450
  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 = 200; //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=
  81. (SubGhzProtocolCommonLoad)subghz_decoder_princeton_to_load_protocol;
  82. instance->common.get_upload_protocol =
  83. (SubGhzProtocolEncoderCommonGetUpLoad)subghz_protocol_princeton_send_key;
  84. return instance;
  85. }
  86. void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) {
  87. furi_assert(instance);
  88. free(instance);
  89. }
  90. bool subghz_protocol_princeton_send_key(SubGhzDecoderPrinceton* instance, SubGhzProtocolEncoderCommon* encoder){
  91. furi_assert(instance);
  92. furi_assert(encoder);
  93. size_t index = 0;
  94. encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2;
  95. if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
  96. //Send key data
  97. for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
  98. if(bit_read(instance->common.code_last_found, i - 1)){
  99. //send bit 1
  100. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te*3);
  101. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te);
  102. }else{
  103. //send bit 0
  104. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
  105. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te*3);
  106. }
  107. }
  108. //Send Stop bit
  109. encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
  110. //Send PT_GUARD
  111. encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te*30);
  112. return true;
  113. }
  114. void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) {
  115. instance->common.parser_step = 0;
  116. }
  117. void subghz_decoder_princeton_parse(
  118. SubGhzDecoderPrinceton* instance,
  119. bool level,
  120. uint32_t duration) {
  121. switch(instance->common.parser_step) {
  122. case 0:
  123. if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) <
  124. instance->common.te_delta * 36)) {
  125. //Found Preambula
  126. instance->common.parser_step = 1;
  127. instance->common.code_found = 0;
  128. instance->common.code_count_bit = 0;
  129. } else {
  130. instance->common.parser_step = 0;
  131. }
  132. break;
  133. case 1:
  134. //save duration
  135. if(level) {
  136. instance->common.te_last = duration;
  137. instance->common.parser_step = 2;
  138. }
  139. break;
  140. case 2:
  141. if(!level) {
  142. if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
  143. instance->common.parser_step = 1;
  144. if(instance->common.code_count_bit >=
  145. instance->common.code_min_count_bit_for_found) {
  146. if(instance->common.code_last_found == instance->common.code_found) {
  147. //instance->te = (instance->te+instance->common.te_last)/2; //Option 1 TE averaging
  148. if(instance->te > instance->common.te_last)
  149. instance->te = instance->common.te_last; //Option 2 TE averaging
  150. } else {
  151. instance->te = instance->common.te_last;
  152. }
  153. instance->common.code_last_found = instance->common.code_found;
  154. instance->common.code_last_count_bit = instance->common.code_count_bit;
  155. instance->common.serial = instance->common.code_found >> 4;
  156. instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
  157. if(instance->common.callback)
  158. instance->common.callback(
  159. (SubGhzProtocolCommon*)instance, instance->common.context);
  160. }
  161. instance->common.code_found = 0;
  162. instance->common.code_count_bit = 0;
  163. break;
  164. }
  165. if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
  166. instance->common.te_delta) &&
  167. (DURATION_DIFF(duration, instance->common.te_long) <
  168. instance->common.te_delta * 3)) {
  169. subghz_protocol_common_add_bit(&instance->common, 0);
  170. instance->common.parser_step = 1;
  171. } else if(
  172. (DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
  173. instance->common.te_delta * 3) &&
  174. (DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
  175. subghz_protocol_common_add_bit(&instance->common, 1);
  176. instance->common.parser_step = 1;
  177. } else {
  178. instance->common.parser_step = 0;
  179. }
  180. } else {
  181. instance->common.parser_step = 0;
  182. }
  183. break;
  184. }
  185. }
  186. void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) {
  187. uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
  188. uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
  189. instance->common.code_last_found, instance->common.code_last_count_bit);
  190. uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
  191. string_cat_printf(
  192. output,
  193. "%s %d Bit te %dus\r\n"
  194. " KEY:0x%08lX\r\n"
  195. " YEK:0x%08lX\r\n"
  196. " SN:0x%05lX BTN:%02X\r\n",
  197. instance->common.name,
  198. instance->common.code_last_count_bit,
  199. instance->te,
  200. code_found_lo,
  201. code_found_reverse_lo,
  202. instance->common.serial,
  203. instance->common.btn);
  204. }
  205. void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) {
  206. string_printf(
  207. output,
  208. "Protocol: %s\n"
  209. "Bit: %d\n"
  210. "Te: %d\n"
  211. "Key: %08lX\n",
  212. instance->common.name,
  213. instance->common.code_last_count_bit,
  214. instance->te,
  215. (uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
  216. }
  217. bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance){
  218. bool loaded = false;
  219. string_t temp_str;
  220. string_init(temp_str);
  221. int res = 0;
  222. int data = 0;
  223. do {
  224. // Read and parse bit data from 2nd line
  225. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  226. break;
  227. }
  228. res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
  229. if(res != 1) {
  230. break;
  231. }
  232. instance->common.code_last_count_bit = (uint8_t)data;
  233. // Read and parse te data from 3nd line
  234. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  235. break;
  236. }
  237. res = sscanf(string_get_cstr(temp_str), "Te: %d\n", &data);
  238. if(res != 1) {
  239. break;
  240. }
  241. instance->te = (uint16_t)data;
  242. // Read and parse key data from 4nd line
  243. if(!file_worker_read_until(file_worker, temp_str, '\n')) {
  244. break;
  245. }
  246. uint32_t temp_key = 0;
  247. res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
  248. if(res != 1) {
  249. break;
  250. }
  251. instance->common.code_last_found = (uint64_t)temp_key;
  252. instance->common.serial = instance->common.code_last_found >> 4;
  253. instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
  254. loaded = true;
  255. } while(0);
  256. string_clear(temp_str);
  257. return loaded;
  258. }