rolling_flaws_subghz_receive.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "rolling_flaws_subghz_receive.h"
  2. static SubGhzEnvironment* load_environment() {
  3. SubGhzEnvironment* environment = subghz_environment_alloc();
  4. subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_NAME);
  5. subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_USER_NAME);
  6. subghz_environment_set_came_atomo_rainbow_table_file_name(
  7. environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
  8. subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
  9. environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
  10. subghz_environment_set_nice_flor_s_rainbow_table_file_name(
  11. environment, SUBGHZ_NICE_FLOR_S_DIR_NAME);
  12. subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry);
  13. return environment;
  14. }
  15. RollingFlawsSubGhz* rolling_flaws_subghz_alloc() {
  16. RollingFlawsSubGhz* subghz = malloc(sizeof(RollingFlawsSubGhz));
  17. subghz->status = SUBGHZ_RECEIVER_UNINITIALIZED;
  18. subghz->environment = load_environment();
  19. subghz->stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration));
  20. furi_check(subghz->stream);
  21. subghz->overrun = false;
  22. return subghz;
  23. }
  24. void rolling_flaws_subghz_free(RollingFlawsSubGhz* subghz) {
  25. subghz_environment_free(subghz->environment);
  26. furi_stream_buffer_free(subghz->stream);
  27. free(subghz);
  28. }
  29. static void
  30. rx_callback(SubGhzReceiver* receiver, SubGhzProtocolDecoderBase* decoder_base, void* cxt) {
  31. RollingFlawsSubGhz* context = (RollingFlawsSubGhz*)cxt;
  32. FuriString* buffer = furi_string_alloc();
  33. subghz_protocol_decoder_base_get_string(decoder_base, buffer);
  34. subghz_receiver_reset(receiver);
  35. FURI_LOG_I(TAG, "PACKET:\r\n%s", furi_string_get_cstr(buffer));
  36. if(context->callback) {
  37. if(!context->callback(buffer, context->callback_context)) {
  38. context->status = SUBGHZ_RECEIVER_SYNCHRONIZED;
  39. }
  40. }
  41. furi_string_free(buffer);
  42. }
  43. static void rx_capture_callback(bool level, uint32_t duration, void* context) {
  44. RollingFlawsSubGhz* instance = context;
  45. LevelDuration level_duration = level_duration_make(level, duration);
  46. if(instance->overrun) {
  47. instance->overrun = false;
  48. level_duration = level_duration_reset();
  49. }
  50. size_t ret =
  51. furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0);
  52. if(sizeof(LevelDuration) != ret) {
  53. instance->overrun = true;
  54. }
  55. }
  56. static int32_t listen_rx(void* ctx) {
  57. RollingFlawsSubGhz* context = (RollingFlawsSubGhz*)ctx;
  58. context->status = SUBGHZ_RECEIVER_LISTENING;
  59. LevelDuration level_duration;
  60. FURI_LOG_I(TAG, "listen_rx started...");
  61. while(context->status == SUBGHZ_RECEIVER_LISTENING) {
  62. int ret = furi_stream_buffer_receive(
  63. context->stream, &level_duration, sizeof(LevelDuration), 10);
  64. if(ret == sizeof(LevelDuration)) {
  65. if(level_duration_is_reset(level_duration)) {
  66. subghz_receiver_reset(context->receiver);
  67. } else {
  68. bool level = level_duration_get_level(level_duration);
  69. uint32_t duration = level_duration_get_duration(level_duration);
  70. subghz_receiver_decode(context->receiver, level, duration);
  71. }
  72. }
  73. }
  74. FURI_LOG_I(TAG, "listen_rx exiting...");
  75. context->status = SUBGHZ_RECEIVER_NOTLISTENING;
  76. return 0;
  77. }
  78. void start_listening(
  79. RollingFlawsSubGhz* context,
  80. uint32_t frequency,
  81. SubghzPacketCallback callback,
  82. void* callback_context) {
  83. context->status = SUBGHZ_RECEIVER_INITIALIZING;
  84. context->callback = callback;
  85. context->callback_context = callback_context;
  86. subghz_devices_init();
  87. const SubGhzDevice* device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
  88. if(!subghz_devices_is_frequency_valid(device, frequency)) {
  89. FURI_LOG_E(TAG, "Frequency not in range. %lu\r\n", frequency);
  90. subghz_devices_deinit();
  91. return;
  92. }
  93. context->receiver = subghz_receiver_alloc_init(context->environment);
  94. subghz_receiver_set_filter(context->receiver, SubGhzProtocolFlag_Decodable);
  95. subghz_receiver_set_rx_callback(context->receiver, rx_callback, context);
  96. subghz_devices_begin(device);
  97. subghz_devices_reset(device);
  98. subghz_devices_load_preset(device, FuriHalSubGhzPresetOok650Async, NULL);
  99. frequency = subghz_devices_set_frequency(device, frequency);
  100. furi_hal_power_suppress_charge_enter();
  101. subghz_devices_start_async_rx(device, rx_capture_callback, context);
  102. FURI_LOG_I(TAG, "Listening at frequency: %lu\r\n", frequency);
  103. context->thread = furi_thread_alloc_ex("RX", 1024, listen_rx, context);
  104. furi_thread_start(context->thread);
  105. }
  106. void stop_listening(RollingFlawsSubGhz* context) {
  107. if(context->status == SUBGHZ_RECEIVER_UNINITIALIZED) {
  108. return;
  109. }
  110. context->status = SUBGHZ_RECEIVER_UNINITIALING;
  111. FURI_LOG_D(TAG, "Stopping listening...");
  112. furi_thread_join(context->thread);
  113. furi_thread_free(context->thread);
  114. furi_hal_power_suppress_charge_exit();
  115. const SubGhzDevice* device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
  116. subghz_devices_stop_async_rx(device);
  117. subghz_receiver_free(context->receiver);
  118. subghz_devices_deinit();
  119. context->status = SUBGHZ_RECEIVER_UNINITIALIZED;
  120. }