action_subghz.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Methods for Sub-GHz transmission
  2. // subghz
  3. #include <lib/subghz/transmitter.h>
  4. #include <lib/subghz/devices/devices.h>
  5. #include <lib/subghz/devices/cc1101_configs.h>
  6. #include <lib/subghz/protocols/raw.h>
  7. #include <lib/subghz/subghz_protocol_registry.h>
  8. #include "action_i.h"
  9. static FuriHalSubGhzPreset action_subghz_get_preset_name(const char* preset_name) {
  10. FuriHalSubGhzPreset preset = FuriHalSubGhzPresetIDLE;
  11. if(!strcmp(preset_name, "FuriHalSubGhzPresetOok270Async")) {
  12. preset = FuriHalSubGhzPresetOok270Async;
  13. } else if(!strcmp(preset_name, "FuriHalSubGhzPresetOok650Async")) {
  14. preset = FuriHalSubGhzPresetOok650Async;
  15. } else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev238Async")) {
  16. preset = FuriHalSubGhzPreset2FSKDev238Async;
  17. } else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev476Async")) {
  18. preset = FuriHalSubGhzPreset2FSKDev476Async;
  19. } else if(!strcmp(preset_name, "FuriHalSubGhzPresetCustom")) {
  20. preset = FuriHalSubGhzPresetCustom;
  21. } else {
  22. FURI_LOG_E(TAG, "Unknown preset!");
  23. }
  24. return preset;
  25. }
  26. // Lifted from flipperzero-firmware/applications/main/subghz/subghz_cli.c
  27. void action_subghz_tx(void* context, Item* item) {
  28. App* app = context;
  29. FuriString* file_name = item->path;
  30. uint32_t repeat = 1; // 10?
  31. // uint32_t device_ind = 0; // 0 - CC1101_INT, 1 - CC1101_EXT
  32. FlipperFormat* fff_data_file = flipper_format_file_alloc(app->storage);
  33. FlipperFormat* fff_data_raw = flipper_format_string_alloc();
  34. FuriString* temp_str;
  35. temp_str = furi_string_alloc();
  36. uint32_t temp_data32;
  37. bool check_file = false;
  38. const SubGhzDevice* device = NULL;
  39. uint32_t frequency = 0;
  40. SubGhzTransmitter* transmitter = NULL;
  41. FURI_LOG_I(TAG, "action_run_tx starting...");
  42. subghz_devices_init();
  43. SubGhzEnvironment* environment = subghz_environment_alloc();
  44. if(!subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_NAME)) {
  45. FURI_LOG_E(TAG, "Load_keystore keeloq_mfcodes ERROR");
  46. }
  47. if(!subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_USER_NAME)) {
  48. FURI_LOG_E(TAG, "Load_keystore keeloq_mfcodes_user ERROR");
  49. }
  50. subghz_environment_set_came_atomo_rainbow_table_file_name(
  51. environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
  52. subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
  53. environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
  54. subghz_environment_set_nice_flor_s_rainbow_table_file_name(
  55. environment, SUBGHZ_NICE_FLOR_S_DIR_NAME);
  56. subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry);
  57. do {
  58. // SUBGHZ_DEVICE_CC1101_INT_NAME = "cc1101_int"
  59. device = subghz_devices_get_by_name("cc1101_int");
  60. if(!subghz_devices_is_connect(device)) {
  61. // power off
  62. if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
  63. device = subghz_devices_get_by_name("cc1101_int");
  64. // device_ind = 0;
  65. }
  66. if(!flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(file_name))) {
  67. FURI_LOG_E(TAG, "Error opening %s", furi_string_get_cstr(file_name));
  68. break;
  69. }
  70. if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
  71. FURI_LOG_E(TAG, "Missing or incorrect header");
  72. break;
  73. }
  74. if(((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) ||
  75. (!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) &&
  76. temp_data32 == SUBGHZ_KEY_FILE_VERSION) {
  77. } else {
  78. FURI_LOG_E(TAG, "Type or version mismatch");
  79. break;
  80. }
  81. if(!flipper_format_read_uint32(fff_data_file, "Frequency", &frequency, 1)) {
  82. FURI_LOG_E(TAG, "Missing Frequency");
  83. break;
  84. }
  85. if(!subghz_devices_is_frequency_valid(device, frequency)) {
  86. FURI_LOG_E(TAG, "Frequency not supported");
  87. break;
  88. }
  89. if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {
  90. FURI_LOG_E(TAG, "Missing Preset");
  91. break;
  92. }
  93. subghz_devices_begin(device);
  94. subghz_devices_reset(device);
  95. if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
  96. uint8_t* custom_preset_data;
  97. uint32_t custom_preset_data_size;
  98. if(!flipper_format_get_value_count(fff_data_file, "Custom_preset_data", &temp_data32))
  99. break;
  100. if(!temp_data32 || (temp_data32 % 2)) {
  101. FURI_LOG_E(TAG, "Custom_preset_data size error");
  102. break;
  103. }
  104. custom_preset_data_size = sizeof(uint8_t) * temp_data32;
  105. custom_preset_data = malloc(custom_preset_data_size);
  106. if(!flipper_format_read_hex(
  107. fff_data_file,
  108. "Custom_preset_data",
  109. custom_preset_data,
  110. custom_preset_data_size)) {
  111. FURI_LOG_E(TAG, "Custom_preset_data read error");
  112. break;
  113. }
  114. subghz_devices_load_preset(
  115. device,
  116. action_subghz_get_preset_name(furi_string_get_cstr(temp_str)),
  117. custom_preset_data);
  118. free(custom_preset_data);
  119. } else {
  120. subghz_devices_load_preset(
  121. device, action_subghz_get_preset_name(furi_string_get_cstr(temp_str)), NULL);
  122. }
  123. subghz_devices_set_frequency(device, frequency);
  124. // Load Protocol
  125. if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) {
  126. FURI_LOG_E(TAG, "Missing protocol");
  127. break;
  128. }
  129. SubGhzProtocolStatus status;
  130. bool is_init_protocol = true;
  131. if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) {
  132. FURI_LOG_I(TAG, "Protocol = RAW");
  133. subghz_protocol_raw_gen_fff_data(
  134. fff_data_raw, furi_string_get_cstr(file_name), subghz_devices_get_name(device));
  135. transmitter =
  136. subghz_transmitter_alloc_init(environment, furi_string_get_cstr(temp_str));
  137. if(transmitter == NULL) {
  138. FURI_LOG_E(TAG, "Error transmitter");
  139. is_init_protocol = false;
  140. }
  141. if(is_init_protocol) {
  142. status = subghz_transmitter_deserialize(transmitter, fff_data_raw);
  143. if(status != SubGhzProtocolStatusOk) {
  144. FURI_LOG_E(TAG, "Error deserialize protocol");
  145. is_init_protocol = false;
  146. }
  147. }
  148. } else { // if not RAW protocol
  149. FURI_LOG_I(TAG, "Protocol != RAW");
  150. flipper_format_insert_or_update_uint32(fff_data_file, "Repeat", &repeat, 1);
  151. transmitter =
  152. subghz_transmitter_alloc_init(environment, furi_string_get_cstr(temp_str));
  153. if(transmitter == NULL) {
  154. FURI_LOG_E(TAG, "Error transmitter");
  155. is_init_protocol = false;
  156. }
  157. if(is_init_protocol) {
  158. status = subghz_transmitter_deserialize(transmitter, fff_data_file);
  159. if(status != SubGhzProtocolStatusOk) {
  160. FURI_LOG_E(TAG, "Error deserialize protocol");
  161. is_init_protocol = false;
  162. }
  163. }
  164. flipper_format_delete_key(fff_data_file, "Repeat");
  165. }
  166. if(is_init_protocol) {
  167. check_file = true;
  168. } else {
  169. subghz_devices_sleep(device);
  170. subghz_devices_end(device);
  171. subghz_transmitter_free(transmitter);
  172. }
  173. } while(false);
  174. flipper_format_free(fff_data_file);
  175. if(check_file) {
  176. furi_hal_power_suppress_charge_enter();
  177. FURI_LOG_I(
  178. TAG,
  179. "Listening at %s. Frequency=%lu, Protocol=%s",
  180. furi_string_get_cstr(file_name),
  181. frequency,
  182. furi_string_get_cstr(temp_str));
  183. do {
  184. // delay in downloading files and other preparatory processes
  185. furi_delay_ms(200);
  186. if(subghz_devices_start_async_tx(device, subghz_transmitter_yield, transmitter)) {
  187. while(!(subghz_devices_is_async_complete_tx(
  188. device))) { // || cli_cmd_interrupt_received
  189. furi_delay_ms(333);
  190. }
  191. subghz_devices_stop_async_tx(device);
  192. } else {
  193. FURI_LOG_W(TAG, "Transmission on this frequency is restricted in your region");
  194. }
  195. if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) {
  196. subghz_transmitter_stop(transmitter);
  197. repeat--;
  198. if(repeat) subghz_transmitter_deserialize(transmitter, fff_data_raw);
  199. }
  200. } while(repeat && !strcmp(furi_string_get_cstr(temp_str), "RAW"));
  201. subghz_devices_sleep(device);
  202. subghz_devices_end(device);
  203. // power off
  204. if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
  205. furi_hal_power_suppress_charge_exit();
  206. subghz_transmitter_free(transmitter);
  207. }
  208. flipper_format_free(fff_data_raw);
  209. furi_string_free(temp_str);
  210. subghz_devices_deinit();
  211. subghz_environment_free(environment);
  212. }