flipperzero-firmware/applications/subghz/scenes/subghz_scene_read_raw.c
Albert Kharisov 84410c83b5
[FL-2183] [FL-2209] Dolphin Deeds, Level up, assets generation, refactoring (#965)
* Desktop: cleanup headers
* Get loader pubsub via record
* [FL-2183] Dolphin refactoring 2022.01
* Restruct animations assets structure
* Rename assets
* Cleanup headers
* Update Recording animation
* Add BadBattery animation
* Provide loader's pubsub via record
* Fix load/unload animations
* Scripts: add flipper format support, initial dolphin packager rework. Assets: internal and external dolphin.
* Sync internal meta.txt and manifest.txt
* Reorder, rename dolphin assets
* Split essential generated assets
* Add ReadMe for dolphin assets
* Separate essential blocking animations
* Scripts: full dolphin validation before packaging
* Assets, Scripts: dolphin external resources packer
* Github: update codeowners
* Scripts: proper slots handling in dolphin animation meta
* Scripts: correct frames enumeration and fix compiled assets.
* [FL-2209] Add Dolphin Deeds points and many more
* Remove excess frame_rate
* Change dolphin assets directory
* Scripts: add internal resource support to dolphin compiler
* Scripts: add internal assets generation, renaming
* Scripts: correct assert, renaming
* Code cleanup, documentation, fixes
* Update Levelup animations
* Rename essential -> blocking
* Fix Unlocked hint
* Scripts: rewrite Templite compiller, replace regexps with token parser, split block types into code and variable blocks. Update dolphin templates.
* Documentation: add key combos description and use information
* Scripts: cleanup templit, more debug info and add dev comment

Co-authored-by: あく <alleteam@gmail.com>
2022-01-29 12:20:41 +03:00

309 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "../subghz_i.h"
#include "../views/subghz_read_raw.h"
#include <dolphin/dolphin.h>
#include <lib/subghz/protocols/subghz_protocol_raw.h>
#include <lib/subghz/subghz_parser.h>
#include <lib/toolbox/path.h>
#define RAW_FILE_NAME "Raw_signal_"
bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
bool ret = false;
//set the path to read the file
if(strcmp(
subghz_protocol_raw_get_last_file_name(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result),
"")) {
string_t temp_str;
string_init_printf(
temp_str,
"%s",
subghz_protocol_raw_get_last_file_name(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result));
path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str);
strcpy(subghz->file_name, string_get_cstr(temp_str));
string_printf(
temp_str, "%s/%s%s", SUBGHZ_APP_PATH_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION);
subghz_protocol_raw_set_last_file_name(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result, string_get_cstr(temp_str));
string_clear(temp_str);
ret = true;
}
return ret;
}
static void subghz_scene_read_raw_update_statusbar(void* context) {
furi_assert(context);
SubGhz* subghz = context;
string_t frequency_str;
string_t modulation_str;
string_init(frequency_str);
string_init(modulation_str);
subghz_get_frequency_modulation(subghz, frequency_str, modulation_str);
subghz_read_raw_add_data_statusbar(
subghz->subghz_read_raw, string_get_cstr(frequency_str), string_get_cstr(modulation_str));
string_clear(frequency_str);
string_clear(modulation_str);
}
void subghz_scene_read_raw_callback(SubghzCustomEvent event, void* context) {
furi_assert(context);
SubGhz* subghz = context;
view_dispatcher_send_custom_event(subghz->view_dispatcher, event);
}
void subghz_scene_read_raw_callback_end_tx(void* context) {
furi_assert(context);
SubGhz* subghz = context;
view_dispatcher_send_custom_event(
subghz->view_dispatcher, SubghzCustomEventViewReadRAWSendStop);
}
void subghz_scene_read_raw_on_enter(void* context) {
SubGhz* subghz = context;
switch(subghz->txrx->rx_key_state) {
case SubGhzRxKeyStateBack:
subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE, "");
break;
case SubGhzRxKeyStateRAWLoad:
subghz_read_raw_set_status(
subghz->subghz_read_raw, SubghzReadRAWStatusLoadKeyTX, subghz->file_name);
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
break;
case SubGhzRxKeyStateRAWSave:
subghz_read_raw_set_status(
subghz->subghz_read_raw, SubghzReadRAWStatusSaveKey, subghz->file_name);
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
break;
default:
subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart, "");
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
break;
}
subghz_scene_read_raw_update_statusbar(subghz);
subghz_read_raw_set_callback(subghz->subghz_read_raw, subghz_scene_read_raw_callback, subghz);
subghz->txrx->protocol_result = subghz_parser_get_by_name(subghz->txrx->parser, "RAW");
furi_assert(subghz->txrx->protocol_result);
subghz_worker_set_pair_callback(
subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_raw_parse);
subghz_protocol_raw_file_encoder_worker_set_callback_end(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result,
subghz_scene_read_raw_callback_end_tx,
subghz);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewReadRAW);
}
bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case SubghzCustomEventViewReadRAWBack:
//Stop TX
if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
subghz_tx_stop(subghz);
subghz_sleep(subghz);
}
//Stop RX
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
subghz_sleep(subghz);
};
//Stop save file
subghz_protocol_raw_save_to_file_stop(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result);
subghz->state_notifications = SubGhzNotificationStateIDLE;
//needed save?
if((subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) ||
(subghz->txrx->rx_key_state == SubGhzRxKeyStateBack)) {
subghz->txrx->rx_key_state = SubGhzRxKeyStateExit;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
} else {
//Restore default setting
subghz->txrx->frequency = subghz_frequencies[subghz_frequencies_433_92];
subghz->txrx->preset = FuriHalSubGhzPresetOok650Async;
if(!scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneSaved)) {
if(!scene_manager_search_and_switch_to_previous_scene(
subghz->scene_manager, SubGhzSceneStart)) {
scene_manager_stop(subghz->scene_manager);
view_dispatcher_stop(subghz->view_dispatcher);
}
}
}
return true;
break;
case SubghzCustomEventViewReadRAWTXRXStop:
//Stop TX
if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
subghz_tx_stop(subghz);
subghz_sleep(subghz);
}
//Stop RX
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
subghz_sleep(subghz);
};
subghz->state_notifications = SubGhzNotificationStateIDLE;
return true;
break;
case SubghzCustomEventViewReadRAWConfig:
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig);
return true;
break;
case SubghzCustomEventViewReadRAWErase:
subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE;
return true;
break;
case SubghzCustomEventViewReadRAWVibro:
notification_message(subghz->notifications, &sequence_single_vibro);
return true;
break;
case SubghzCustomEventViewReadRAWMore:
if(subghz_scene_read_raw_update_filename(subghz)) {
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet);
subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneMoreRAW);
return true;
} else {
furi_crash(NULL);
}
break;
case SubghzCustomEventViewReadRAWSendStart:
if(subghz_scene_read_raw_update_filename(subghz)) {
//start send
subghz->state_notifications = SubGhzNotificationStateIDLE;
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
}
if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
(subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
if(!subghz_tx_start(subghz)) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
} else {
DOLPHIN_DEED(DolphinDeedSubGhzSend);
subghz->state_notifications = SubGhzNotificationStateTX;
}
}
}
return true;
break;
case SubghzCustomEventViewReadRAWSendStop:
subghz->state_notifications = SubGhzNotificationStateIDLE;
if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
subghz_tx_stop(subghz);
subghz_sleep(subghz);
}
subghz_read_raw_stop_send(subghz->subghz_read_raw);
return true;
break;
case SubghzCustomEventViewReadRAWIDLE:
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
subghz_sleep(subghz);
};
subghz_protocol_raw_save_to_file_stop(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result);
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
return true;
break;
case SubghzCustomEventViewReadRAWREC:
if(subghz->txrx->rx_key_state != SubGhzRxKeyStateIDLE) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
} else {
subghz_get_preset_name(subghz, subghz->error_str);
if(subghz_protocol_raw_save_to_file_init(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result,
RAW_FILE_NAME,
subghz->txrx->frequency,
string_get_cstr(subghz->error_str))) {
DOLPHIN_DEED(DolphinDeedSubGhzRawRec);
if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
(subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
subghz_begin(subghz, subghz->txrx->preset);
subghz_rx(subghz, subghz->txrx->frequency);
}
subghz->state_notifications = SubGhzNotificationStateRX;
subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey;
} else {
string_set(subghz->error_str, "Function requires\nan SD card.");
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
}
}
return true;
break;
case SubghzCustomEventViewReadRAWSave:
if(subghz_scene_read_raw_update_filename(subghz)) {
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneReadRAW, SubghzCustomEventManagerSet);
subghz->txrx->rx_key_state = SubGhzRxKeyStateBack;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName);
}
return true;
break;
default:
break;
}
} else if(event.type == SceneManagerEventTypeTick) {
switch(subghz->state_notifications) {
case SubGhzNotificationStateRX:
notification_message(subghz->notifications, &sequence_blink_blue_10);
subghz_read_raw_update_sample_write(
subghz->subghz_read_raw,
subghz_protocol_raw_get_sample_write(
(SubGhzProtocolRAW*)subghz->txrx->protocol_result));
subghz_read_raw_add_data_rssi(subghz->subghz_read_raw, furi_hal_subghz_get_rssi());
break;
case SubGhzNotificationStateTX:
notification_message(subghz->notifications, &sequence_blink_green_10);
subghz_read_raw_update_sin(subghz->subghz_read_raw);
break;
default:
break;
}
}
return false;
}
void subghz_scene_read_raw_on_exit(void* context) {
SubGhz* subghz = context;
//Stop CC1101
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
subghz_sleep(subghz);
};
subghz->state_notifications = SubGhzNotificationStateIDLE;
//Сallback restoration
subghz_worker_set_pair_callback(
subghz->txrx->worker, (SubGhzWorkerPairCallback)subghz_parser_parse);
}