subbrute_worker.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include "subbrute_worker.h"
  2. #include <subghz/environment.h>
  3. #include <subghz/transmitter.h>
  4. #include <flipper_format_i.h>
  5. #include <lib/subghz/subghz_tx_rx_worker.h>
  6. #define TAG "SubBruteWorker"
  7. struct SubBruteWorker {
  8. SubGhzTxRxWorker* subghz_txrx;
  9. volatile bool worker_running;
  10. volatile bool worker_manual_mode;
  11. bool is_manual_init;
  12. bool is_continuous_worker;
  13. SubGhzEnvironment* environment;
  14. SubGhzTransmitter* transmitter;
  15. FlipperFormat* flipper_format;
  16. uint32_t last_time_tx_data;
  17. // Preset and frequency needed
  18. FuriHalSubGhzPreset preset;
  19. uint32_t frequency;
  20. string_t protocol_name;
  21. //SubBruteWorkerCallback callback;
  22. //void* context;
  23. };
  24. /** Taken from subghz_tx_rx_worker.c */
  25. #define SUBBRUTE_TXRX_WORKER_BUF_SIZE 2048
  26. #define SUBBRUTE_TXRX_WORKER_MAX_TXRX_SIZE 60
  27. #define SUBBRUTE_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40
  28. #define SUBBRUTE_TX_TIMEOUT 5
  29. #define SUBBRUTE_SEND_DELAY 20
  30. SubBruteWorker* subbrute_worker_alloc() {
  31. SubBruteWorker* instance = malloc(sizeof(SubBruteWorker));
  32. //instance->status = SubBruteWorkerStatusIDLE;
  33. instance->worker_running = false;
  34. instance->worker_manual_mode = false;
  35. //instance->environment = subghz_environment_alloc();
  36. instance->transmitter = NULL;
  37. instance->flipper_format = flipper_format_string_alloc();
  38. string_init(instance->protocol_name);
  39. // SubGhzTxRxWorker
  40. instance->subghz_txrx = subghz_tx_rx_worker_alloc();
  41. return instance;
  42. }
  43. void subbrute_worker_free(SubBruteWorker* instance) {
  44. furi_assert(instance);
  45. furi_assert(!instance->worker_running);
  46. if(instance->transmitter != NULL) {
  47. subghz_transmitter_free(instance->transmitter);
  48. instance->transmitter = NULL;
  49. }
  50. /*if(instance->environment != NULL) {
  51. subghz_environment_free(instance->environment);
  52. instance->environment = NULL;
  53. }*/
  54. flipper_format_free(instance->flipper_format);
  55. string_clear(instance->protocol_name);
  56. // SubGhzTxRxWorker
  57. subghz_tx_rx_worker_free(instance->subghz_txrx);
  58. free(instance);
  59. }
  60. bool subbrute_worker_start(
  61. SubBruteWorker* instance,
  62. uint32_t frequency,
  63. FuriHalSubGhzPreset preset,
  64. const char* protocol_name) {
  65. furi_assert(instance);
  66. if(instance->worker_manual_mode) {
  67. FURI_LOG_W(TAG, "Invalid mode for starting worker!");
  68. return false;
  69. }
  70. instance->frequency = frequency;
  71. instance->preset = preset;
  72. string_clear(instance->protocol_name);
  73. string_init_printf(instance->protocol_name, "%s", protocol_name);
  74. bool res = false;
  75. furi_hal_subghz_reset();
  76. furi_hal_subghz_idle();
  77. furi_hal_subghz_load_preset(instance->preset);
  78. furi_hal_subghz_set_frequency_and_path(instance->frequency);
  79. furi_hal_subghz_flush_rx();
  80. if(furi_hal_subghz_is_tx_allowed(frequency)) {
  81. instance->frequency = frequency;
  82. res = true;
  83. }
  84. instance->worker_running = res;
  85. #ifdef FURI_DEBUG
  86. FURI_LOG_I(TAG, "Frequency: %d", frequency);
  87. #endif
  88. instance->preset = preset;
  89. if(res) {
  90. instance->worker_running = res =
  91. subghz_tx_rx_worker_start(instance->subghz_txrx, frequency);
  92. }
  93. return res;
  94. }
  95. void subbrute_worker_stop(SubBruteWorker* instance) {
  96. furi_assert(instance);
  97. instance->worker_running = false;
  98. if(subghz_tx_rx_worker_is_running(instance->subghz_txrx)) {
  99. subghz_tx_rx_worker_stop(instance->subghz_txrx);
  100. }
  101. }
  102. void subbrute_worker_set_continuous_worker(SubBruteWorker* instance, bool is_continuous_worker) {
  103. furi_assert(instance);
  104. instance->is_continuous_worker = is_continuous_worker;
  105. }
  106. bool subbrute_worker_get_continuous_worker(SubBruteWorker* instance) {
  107. furi_assert(instance);
  108. return instance->is_continuous_worker;
  109. }
  110. bool subbrute_worker_is_running(SubBruteWorker* instance) {
  111. furi_assert(instance);
  112. return instance->worker_running;
  113. }
  114. bool subbrute_worker_can_transmit(SubBruteWorker* instance) {
  115. furi_assert(instance);
  116. return (furi_get_tick() - instance->last_time_tx_data) > SUBBRUTE_SEND_DELAY;
  117. }
  118. bool subbrute_worker_can_manual_transmit(SubBruteWorker* instance, bool is_button_pressed) {
  119. furi_assert(instance);
  120. if(is_button_pressed) {
  121. // It's human pressed, trying to reset twice pressing
  122. return !instance->worker_manual_mode &&
  123. (furi_get_tick() - instance->last_time_tx_data) > 500;
  124. } else {
  125. return !instance->worker_manual_mode;
  126. }
  127. }
  128. bool subbrute_worker_transmit(SubBruteWorker* instance, const char* payload) {
  129. furi_assert(instance);
  130. furi_assert(instance->worker_running);
  131. if(!subbrute_worker_can_transmit(instance)) {
  132. FURI_LOG_E(TAG, "Too early to transmit");
  133. return false;
  134. }
  135. instance->last_time_tx_data = furi_get_tick();
  136. #ifdef FURI_DEBUG
  137. //FURI_LOG_D(TAG, "payload: %s", payload);
  138. #endif
  139. while(!subghz_tx_rx_worker_write(instance->subghz_txrx, (uint8_t*)payload, strlen(payload))) {
  140. furi_delay_ms(10);
  141. }
  142. furi_hal_subghz_flush_tx();
  143. // Stream* stream = flipper_format_get_raw_stream(instance->flipper_format);
  144. // stream_clean(stream);
  145. // stream_write_cstring(stream, payload);
  146. // subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format);
  147. return true;
  148. }
  149. // Init MANUAL
  150. bool subbrute_worker_init_manual_transmit(
  151. SubBruteWorker* instance,
  152. uint32_t frequency,
  153. FuriHalSubGhzPreset preset,
  154. const char* protocol_name) {
  155. #ifdef FURI_DEBUG
  156. FURI_LOG_D(
  157. TAG,
  158. "subbrute_worker_init_manual_transmit. frequency: %d, protocol: %s",
  159. frequency,
  160. protocol_name);
  161. #endif
  162. if(instance->worker_manual_mode || !subbrute_worker_can_manual_transmit(instance, false) ||
  163. instance->worker_running) {
  164. #ifdef FURI_DEBUG
  165. FURI_LOG_D(TAG, "cannot transmit");
  166. #endif
  167. return false;
  168. }
  169. if(instance->worker_running) {
  170. #ifdef FURI_DEBUG
  171. FURI_LOG_D(TAG, "subbrute_worker_stop");
  172. #endif
  173. subbrute_worker_stop(instance);
  174. }
  175. // Not transmit at this period
  176. instance->worker_manual_mode = true;
  177. if(instance->is_manual_init) {
  178. FURI_LOG_E(TAG, "Trying to setup without normally shutdown prev transmit session!");
  179. subbrute_worker_manual_transmit_stop(instance);
  180. }
  181. instance->preset = preset;
  182. instance->frequency = frequency;
  183. string_clear(instance->protocol_name);
  184. string_init_printf(instance->protocol_name, "%s", protocol_name);
  185. furi_hal_subghz_reset();
  186. furi_hal_subghz_idle();
  187. furi_hal_subghz_load_preset(instance->preset);
  188. furi_hal_subghz_set_frequency_and_path(instance->frequency);
  189. furi_hal_subghz_flush_rx();
  190. if(!furi_hal_subghz_is_tx_allowed(frequency)) {
  191. FURI_LOG_E(TAG, "Frequency: %d invalid!", frequency);
  192. instance->frequency = frequency;
  193. instance->worker_manual_mode = false;
  194. return false;
  195. }
  196. #ifdef FURI_DEBUG
  197. FURI_LOG_I(TAG, "Frequency: %d", frequency);
  198. #endif
  199. instance->transmitter = subghz_transmitter_alloc_init(
  200. instance->environment, string_get_cstr(instance->protocol_name));
  201. furi_hal_subghz_reset();
  202. furi_hal_subghz_load_preset(instance->preset);
  203. instance->frequency = furi_hal_subghz_set_frequency_and_path(frequency);
  204. furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
  205. furi_hal_subghz_sleep();
  206. subghz_transmitter_free(instance->transmitter);
  207. instance->transmitter = NULL;
  208. instance->worker_manual_mode = false;
  209. instance->is_manual_init = true;
  210. return true;
  211. }
  212. void subbrute_worker_manual_transmit_stop(SubBruteWorker* instance) {
  213. #ifdef FURI_DEBUG
  214. FURI_LOG_D(TAG, "subbrute_worker_manual_transmit_stop");
  215. #endif
  216. if(!instance->is_manual_init) {
  217. return;
  218. }
  219. furi_hal_subghz_idle();
  220. furi_hal_subghz_sleep();
  221. if(instance->transmitter != NULL) {
  222. subghz_transmitter_free(instance->transmitter);
  223. instance->transmitter = NULL;
  224. }
  225. instance->is_manual_init = false;
  226. }
  227. bool subbrute_worker_manual_transmit(SubBruteWorker* instance, const char* payload) {
  228. furi_assert(instance);
  229. if(instance->worker_manual_mode || !subbrute_worker_can_transmit(instance)) {
  230. #ifdef FURI_DEBUG
  231. FURI_LOG_D(TAG, "cannot transmit");
  232. #endif
  233. return false;
  234. }
  235. if(instance->worker_running) {
  236. FURI_LOG_W(TAG, "Worker was working for manual mode. Shutdown thread");
  237. subbrute_worker_stop(instance);
  238. }
  239. if(!instance->is_manual_init) {
  240. FURI_LOG_E(TAG, "Manually transmit doesn't set!");
  241. return false;
  242. }
  243. instance->last_time_tx_data = furi_get_tick();
  244. instance->worker_manual_mode = true;
  245. Stream* stream = flipper_format_get_raw_stream(instance->flipper_format);
  246. stream_clean(stream);
  247. stream_write_cstring(stream, payload);
  248. instance->transmitter = subghz_transmitter_alloc_init(
  249. instance->environment, string_get_cstr(instance->protocol_name));
  250. subghz_transmitter_deserialize(instance->transmitter, instance->flipper_format);
  251. furi_hal_subghz_reset();
  252. furi_hal_subghz_load_preset(instance->preset);
  253. instance->frequency = furi_hal_subghz_set_frequency_and_path(instance->frequency);
  254. furi_hal_subghz_start_async_tx(subghz_transmitter_yield, instance->transmitter);
  255. while(!furi_hal_subghz_is_async_tx_complete()) {
  256. furi_delay_ms(SUBBRUTE_TX_TIMEOUT);
  257. }
  258. furi_hal_subghz_stop_async_tx();
  259. furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
  260. furi_hal_subghz_sleep();
  261. subghz_transmitter_free(instance->transmitter);
  262. instance->transmitter = NULL;
  263. stream_clean(stream);
  264. instance->worker_manual_mode = false;
  265. return true;
  266. }