subghz_scene_read_raw.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. #include "../subghz_i.h"
  2. #include "../views/subghz_read_raw.h"
  3. #include <dolphin/dolphin.h>
  4. #include <lib/subghz/protocols/subghz_protocol_raw.h>
  5. #include <lib/subghz/subghz_parser.h>
  6. #include <lib/toolbox/path.h>
  7. #define RAW_FILE_NAME "Raw_signal_"
  8. bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
  9. bool ret = false;
  10. //set the path to read the file
  11. if(strcmp(
  12. subghz_protocol_raw_get_last_file_name(
  13. (SubGhzProtocolRAW*)subghz->txrx->protocol_result),
  14. "")) {
  15. string_t temp_str;
  16. string_init_printf(
  17. temp_str,
  18. "%s",
  19. subghz_protocol_raw_get_last_file_name(
  20. (SubGhzProtocolRAW*)subghz->txrx->protocol_result));
  21. path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str);
  22. strcpy(subghz->file_name, string_get_cstr(temp_str));
  23. string_printf(
  24. temp_str, "%s/%s%s", SUBGHZ_APP_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION);
  25. subghz_protocol_raw_set_last_file_name(
  26. (SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str));
  27. string_clear(temp_str);
  28. ret = true;
  29. }
  30. return ret;
  31. }
  32. static void subghz_scene_read_raw_update_statusbar(void* context) {
  33. furi_assert(context);
  34. SubGhz* subghz = context;
  35. string_t frequency_str;
  36. string_t modulation_str;
  37. string_init(frequency_str);
  38. string_init(modulation_str);
  39. subghz_get_frequency_modulation(subghz, frequency_str, modulation_str);
  40. subghz_read_raw_add_data_statusbar(
  41. subghz->subghz_read_raw, string_get_cstr(frequency_str), string_get_cstr(modulation_str));
  42. string_clear(frequency_str);
  43. string_clear(modulation_str);
  44. }
  45. void subghz_scene_read_raw_callback(SubghzCustomEvent event, void* context) {
  46. furi_assert(context);
  47. SubGhz* subghz = context;
  48. view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
  49. }
  50. void subghz_scene_read_raw_callback_end_tx(void* context) {
  51. furi_assert(context);
  52. SubGhz* subghz = context;
  53. view_dispatcher_send_custom_event(
  54. subghz->view_dispatcher, SubghzCustomEventViewReadRAWSendStop);
  55. }
  56. void subghz_scene_read_raw_on_enter(void* context) {
  57. SubGhz* subghz = context;
  58. switch(subghz->txrx->rx_key_state) {
  59. case SubGhzRxKeyStateBack:
  60. subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE, "");
  61. break;
  62. case SubGhzRxKeyStateRAWLoad:
  63. subghz_read_raw_set_status(
  64. subghz->subghz_read_raw, SubghzReadRAWStatusLoadKeyTX, subghz->file_name);
  65. subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
  66. break;
  67. case SubGhzRxKeyStateRAWSave:
  68. subghz_read_raw_set_status(
  69. subghz->subghz_read_raw, SubghzReadRAWStatusSaveKey, subghz->file_name);
  70. subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
  71. break;
  72. default:
  73. subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart, "");
  74. subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
  75. break;
  76. }
  77. subghz_scene_read_raw_update_statusbar(subghz);
  78. subghz_read_raw_set_callback(subghz->subghz_read_raw, subghz_scene_read_raw_callback, subghz);
  79. subghz->txrx->protocol_result = subghz_parser_get_by_name(subghz->txrx->parser, "RAW");
  80. furi_assert(subghz->txrx->protocol_result);
  81. subghz_worker_set_pair_callback(
  82. subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_raw_parse);
  83. subghz_protocol_raw_file_encoder_worker_set_callback_end(
  84. (SubGhzProtocolRAW*)subghz->txrx->protocol_result,
  85. subghz_scene_read_raw_callback_end_tx,
  86. subghz);
  87. view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReadRAW);
  88. }
  89. bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
  90. SubGhz* subghz = context;
  91. if(event.type == SceneManagerEventTypeCustom) {
  92. switch(event.event) {
  93. case SubghzCustomEventViewReadRAWBack:
  94. //Stop TX
  95. if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
  96. subghz_tx_stop(subghz);
  97. subghz_sleep(subghz);
  98. }
  99. //Stop RX
  100. if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
  101. subghz_rx_end(subghz);
  102. subghz_sleep(subghz);
  103. };
  104. //Stop save file
  105. subghz_protocol_raw_save_to_file_stop(
  106. (SubGhzProtocolRAW*)subghz->txrx->protocol_result);
  107. subghz->state_notifications = SubGhzNotificationStateIDLE;
  108. //needed save?
  109. if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) ||
  110. (subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) {
  111. subghz->txrx->rx_key_state = SubGhzRxKeyStateExit;
  112. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
  113. } else {
  114. //Restore default setting
  115. subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92];
  116. subghz->txrx->preset = FuriHalSubGhzPresetOok650Async;
  117. if(!scene_manager_search_and_switch_to_previous_scene(
  118. subghz->scene_manager, SubGhzSceneSaved)) {
  119. if(!scene_manager_search_and_switch_to_previous_scene(
  120. subghz->scene_manager, SubGhzSceneStart)) {
  121. scene_manager_stop(subghz->scene_manager);
  122. view_dispatcher_stop(subghz->view_dispatcher);
  123. }
  124. }
  125. }
  126. return true;
  127. break;
  128. case SubghzCustomEventViewReadRAWTXRXStop:
  129. //Stop TX
  130. if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
  131. subghz_tx_stop(subghz);
  132. subghz_sleep(subghz);
  133. }
  134. //Stop RX
  135. if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
  136. subghz_rx_end(subghz);
  137. subghz_sleep(subghz);
  138. };
  139. subghz->state_notifications = SubGhzNotificationStateIDLE;
  140. return true;
  141. break;
  142. case SubghzCustomEventViewReadRAWConfig:
  143. scene_manager_set_scene_state(
  144. subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet);
  145. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig);
  146. return true;
  147. break;
  148. case SubghzCustomEventViewReadRAWErase:
  149. subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
  150. return true;
  151. break;
  152. case SubghzCustomEventViewReadRAWVibro:
  153. notification_message(subghz->notifications, &sequence_single_vibro);
  154. return true;
  155. break;
  156. case SubghzCustomEventViewReadRAWMore:
  157. if(subghz_scene_read_raw_update_filename(subghz)) {
  158. scene_manager_set_scene_state(
  159. subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet);
  160. subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad;
  161. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW);
  162. return true;
  163. } else {
  164. furi_crash(NULL);
  165. }
  166. break;
  167. case SubghzCustomEventViewReadRAWSendStart:
  168. if(subghz_scene_read_raw_update_filename(subghz)) {
  169. //start send
  170. subghz->state_notifications = SubGhzNotificationStateIDLE;
  171. if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
  172. subghz_rx_end(subghz);
  173. }
  174. if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
  175. (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
  176. if(!subghz_tx_start(subghz)) {
  177. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
  178. } else {
  179. DOLPHIN_DEED(DolphinDeedSubGhzSend);
  180. subghz->state_notifications = SubGhzNotificationStateTX;
  181. }
  182. }
  183. }
  184. return true;
  185. break;
  186. case SubghzCustomEventViewReadRAWSendStop:
  187. subghz->state_notifications = SubGhzNotificationStateIDLE;
  188. if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
  189. subghz_tx_stop(subghz);
  190. subghz_sleep(subghz);
  191. }
  192. subghz_read_raw_stop_send(subghz->subghz_read_raw);
  193. return true;
  194. break;
  195. case SubghzCustomEventViewReadRAWIDLE:
  196. if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
  197. subghz_rx_end(subghz);
  198. subghz_sleep(subghz);
  199. };
  200. subghz_protocol_raw_save_to_file_stop(
  201. (SubGhzProtocolRAW*)subghz->txrx->protocol_result);
  202. subghz->state_notifications = SubGhzNotificationStateIDLE;
  203. subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
  204. return true;
  205. break;
  206. case SubghzCustomEventViewReadRAWREC:
  207. if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) {
  208. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
  209. } else {
  210. subghz_get_preset_name(subghz, subghz->error_str);
  211. if(subghz_protocol_raw_save_to_file_init(
  212. (SubGhzProtocolRAW*)subghz->txrx->protocol_result,
  213. RAW_FILE_NAME,
  214. subghz->txrx->frequency,
  215. string_get_cstr(subghz->error_str))) {
  216. DOLPHIN_DEED(DolphinDeedSubGhzRawRec);
  217. if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
  218. (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
  219. subghz_begin(subghz, subghz->txrx->preset);
  220. subghz_rx(subghz, subghz->txrx->frequency);
  221. }
  222. subghz->state_notifications = SubGhzNotificationStateRX;
  223. subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
  224. } else {
  225. string_set(subghz->error_str, "Function requires\nan SD card.");
  226. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
  227. }
  228. }
  229. return true;
  230. break;
  231. case SubghzCustomEventViewReadRAWSave:
  232. if(subghz_scene_read_raw_update_filename(subghz)) {
  233. scene_manager_set_scene_state(
  234. subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSetRAW);
  235. subghz->txrx->rx_key_state = SubGhzRxKeyStateBack;
  236. scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
  237. }
  238. return true;
  239. break;
  240. default:
  241. break;
  242. }
  243. } else if(event.type == SceneManagerEventTypeTick) {
  244. switch(subghz->state_notifications) {
  245. case SubGhzNotificationStateRX:
  246. notification_message(subghz->notifications, &sequence_blink_blue_10);
  247. subghz_read_raw_update_sample_write(
  248. subghz->subghz_read_raw,
  249. subghz_protocol_raw_get_sample_write(
  250. (SubGhzProtocolRAW*)subghz->txrx->protocol_result));
  251. subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi());
  252. break;
  253. case SubGhzNotificationStateTX:
  254. notification_message(subghz->notifications, &sequence_blink_green_10);
  255. subghz_read_raw_update_sin(subghz->subghz_read_raw);
  256. break;
  257. default:
  258. break;
  259. }
  260. }
  261. return false;
  262. }
  263. void subghz_scene_read_raw_on_exit(void* context) {
  264. SubGhz* subghz = context;
  265. //Stop CC1101
  266. if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
  267. subghz_rx_end(subghz);
  268. subghz_sleep(subghz);
  269. };
  270. subghz->state_notifications = SubGhzNotificationStateIDLE;
  271. //Сallback restoration
  272. subghz_worker_set_pair_callback(
  273. subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_parse);
  274. }