| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605 |
- #include <furi.h>
- #include <furi_hal.h>
- #include <infrared_worker.h>
- #include <gui/gui.h>
- #include <input/input.h>
- #include <dialogs/dialogs.h>
- #include <ir_remote_icons.h>
- #include <infrared/infrared_settings.h>
- #include <toolbox/saved_struct.h>
- #include <notification/notification.h>
- #include <notification/notification_messages.h>
- #include "infrared_signal.h"
- #include "infrared_remote.h"
- #include "infrared_remote_button.h"
- #define TAG "ir_remote"
- #include <flipper_format/flipper_format.h>
- typedef struct {
- int status;
- ViewPort* view_port;
- FuriString* up_button;
- FuriString* down_button;
- FuriString* left_button;
- FuriString* right_button;
- FuriString* ok_button;
- FuriString* back_button;
- FuriString* up_hold_button;
- FuriString* down_hold_button;
- FuriString* left_hold_button;
- FuriString* right_hold_button;
- FuriString* ok_hold_button;
- InfraredWorker* infrared_worker;
- } IRApp;
- // Screen is 128x64 px
- static void app_draw_callback(Canvas* canvas, void* ctx) {
- // Show config is incorrect when cannot read the remote file
- // Showing button string in the screen, upper part is short press, lower part is long press
- IRApp* app = ctx;
- if(app->status) {
- canvas_clear(canvas);
- view_port_set_orientation(app->view_port, ViewPortOrientationHorizontal);
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str_aligned(canvas, 62, 5, AlignCenter, AlignTop, "Config is incorrect.");
- canvas_set_font(canvas, FontSecondary);
- canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignTop, "Please configure map.");
- canvas_draw_str_aligned(canvas, 62, 60, AlignCenter, AlignBottom, "Press Back to Exit.");
- } else {
- canvas_clear(canvas);
- view_port_set_orientation(app->view_port, ViewPortOrientationVertical);
- canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4);
- canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4);
- canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7);
- canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7);
- canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9);
- canvas_draw_icon(canvas, 0, 53, &I_back_10px);
- //Labels
- canvas_set_font(canvas, FontSecondary);
- canvas_draw_str_aligned(
- canvas, 32, 8, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_button));
- canvas_draw_str_aligned(
- canvas, 32, 18, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_button));
- canvas_draw_str_aligned(
- canvas, 32, 28, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_button));
- canvas_draw_str_aligned(
- canvas, 32, 38, AlignCenter, AlignCenter, furi_string_get_cstr(app->right_button));
- canvas_draw_str_aligned(
- canvas, 32, 48, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_button));
- canvas_draw_str_aligned(
- canvas, 32, 58, AlignCenter, AlignCenter, furi_string_get_cstr(app->back_button));
- canvas_draw_line(canvas, 0, 65, 64, 65);
- canvas_draw_icon(canvas, 1, 70, &I_ButtonUp_7x4);
- canvas_draw_icon(canvas, 1, 80, &I_ButtonDown_7x4);
- canvas_draw_icon(canvas, 2, 88, &I_ButtonLeft_4x7);
- canvas_draw_icon(canvas, 2, 98, &I_ButtonRight_4x7);
- canvas_draw_icon(canvas, 0, 107, &I_Ok_btn_9x9);
- canvas_draw_icon(canvas, 0, 118, &I_back_10px);
- canvas_draw_str_aligned(
- canvas, 32, 73, AlignCenter, AlignCenter, furi_string_get_cstr(app->up_hold_button));
- canvas_draw_str_aligned(
- canvas, 32, 83, AlignCenter, AlignCenter, furi_string_get_cstr(app->down_hold_button));
- canvas_draw_str_aligned(
- canvas, 32, 93, AlignCenter, AlignCenter, furi_string_get_cstr(app->left_hold_button));
- canvas_draw_str_aligned(
- canvas,
- 32,
- 103,
- AlignCenter,
- AlignCenter,
- furi_string_get_cstr(app->right_hold_button));
- canvas_draw_str_aligned(
- canvas, 32, 113, AlignCenter, AlignCenter, furi_string_get_cstr(app->ok_hold_button));
- canvas_draw_str_aligned(canvas, 32, 123, AlignCenter, AlignCenter, "Exit App");
- }
- }
- static void app_input_callback(InputEvent* input_event, void* ctx) {
- furi_assert(ctx);
- FuriMessageQueue* event_queue = ctx;
- furi_message_queue_put(event_queue, input_event, FuriWaitForever);
- }
- int32_t infrared_remote_app(char* p) {
- FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
- // App button string
- IRApp* app = malloc(sizeof(IRApp));
- app->up_button = furi_string_alloc();
- app->down_button = furi_string_alloc();
- app->left_button = furi_string_alloc();
- app->right_button = furi_string_alloc();
- app->ok_button = furi_string_alloc();
- app->back_button = furi_string_alloc();
- app->up_hold_button = furi_string_alloc();
- app->down_hold_button = furi_string_alloc();
- app->left_hold_button = furi_string_alloc();
- app->right_hold_button = furi_string_alloc();
- app->ok_hold_button = furi_string_alloc();
- app->view_port = view_port_alloc();
- app->infrared_worker = infrared_worker_alloc();
- // Configure view port
- view_port_draw_callback_set(app->view_port, app_draw_callback, app);
- view_port_input_callback_set(app->view_port, app_input_callback, event_queue);
- // Register view port in GUI
- Gui* gui = furi_record_open(RECORD_GUI);
- gui_add_view_port(gui, app->view_port, GuiLayerFullscreen);
- InputEvent event;
- FuriString* map_file = furi_string_alloc();
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FlipperFormat* ff = flipper_format_file_alloc(storage);
- if(!storage_file_exists(storage, IR_REMOTE_PATH)) {
- storage_common_mkdir(storage, IR_REMOTE_PATH); //Make Folder If dir not exist
- }
- bool res;
- if(p && strlen(p)) {
- furi_string_set(map_file, p);
- res = true;
- } else {
- DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
- DialogsFileBrowserOptions browser_options;
- dialog_file_browser_set_basic_options(&browser_options, ".txt", &I_sub1_10px);
- browser_options.base_path = IR_REMOTE_PATH;
- furi_string_set(map_file, IR_REMOTE_PATH);
- res = dialog_file_browser_show(dialogs, map_file, map_file, &browser_options);
- furi_record_close(RECORD_DIALOGS);
- }
- // if user didn't choose anything, free everything and exit
- if(!res) {
- FURI_LOG_I(TAG, "exit");
- flipper_format_free(ff);
- furi_record_close(RECORD_STORAGE);
- furi_string_free(app->up_button);
- furi_string_free(app->down_button);
- furi_string_free(app->left_button);
- furi_string_free(app->right_button);
- furi_string_free(app->ok_button);
- furi_string_free(app->back_button);
- furi_string_free(app->up_hold_button);
- furi_string_free(app->down_hold_button);
- furi_string_free(app->left_hold_button);
- furi_string_free(app->right_hold_button);
- furi_string_free(app->ok_hold_button);
- view_port_enabled_set(app->view_port, false);
- gui_remove_view_port(gui, app->view_port);
- view_port_free(app->view_port);
- free(app);
- furi_message_queue_free(event_queue);
- furi_record_close(RECORD_GUI);
- return 255;
- }
- InfraredRemote* remote = infrared_remote_alloc();
- FuriString* remote_path = furi_string_alloc();
- InfraredSignal* up_signal = infrared_signal_alloc();
- InfraredSignal* down_signal = infrared_signal_alloc();
- InfraredSignal* left_signal = infrared_signal_alloc();
- InfraredSignal* right_signal = infrared_signal_alloc();
- InfraredSignal* ok_signal = infrared_signal_alloc();
- InfraredSignal* back_signal = infrared_signal_alloc();
- InfraredSignal* up_hold_signal = infrared_signal_alloc();
- InfraredSignal* down_hold_signal = infrared_signal_alloc();
- InfraredSignal* left_hold_signal = infrared_signal_alloc();
- InfraredSignal* right_hold_signal = infrared_signal_alloc();
- InfraredSignal* ok_hold_signal = infrared_signal_alloc();
- InfraredSignal* active_signal = NULL;
- bool is_transmitting = false;
- bool up_enabled = false;
- bool down_enabled = false;
- bool left_enabled = false;
- bool right_enabled = false;
- bool ok_enabled = false;
- bool back_enabled = false;
- bool up_hold_enabled = false;
- bool down_hold_enabled = false;
- bool left_hold_enabled = false;
- bool right_hold_enabled = false;
- bool ok_hold_enabled = false;
- if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(map_file))) {
- FURI_LOG_E(TAG, "Could not open MAP file %s", furi_string_get_cstr(map_file));
- app->status = 1;
- } else {
- //Filename Assignment/Check Start
- if(!flipper_format_read_string(ff, "REMOTE", remote_path)) {
- FURI_LOG_E(TAG, "Could not read REMOTE string");
- app->status = 1;
- } else {
- if(!infrared_remote_load(remote, remote_path)) {
- FURI_LOG_E(TAG, "Could not load ir file: %s", furi_string_get_cstr(remote_path));
- app->status = 1;
- } else {
- FURI_LOG_I(TAG, "Loaded REMOTE file: %s", furi_string_get_cstr(remote_path));
- }
- }
- //assign variables to values within map file
- //set missing filenames to N/A
- //assign button signals
- size_t index = 0;
- if(!flipper_format_read_string(ff, "UP", app->up_button)) {
- FURI_LOG_W(TAG, "Could not read UP string");
- furi_string_set(app->up_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->up_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- up_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- up_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "DOWN", app->down_button)) {
- FURI_LOG_W(TAG, "Could not read DOWN string");
- furi_string_set(app->down_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->down_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- down_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- down_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "LEFT", app->left_button)) {
- FURI_LOG_W(TAG, "Could not read LEFT string");
- furi_string_set(app->left_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->left_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- left_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- left_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "RIGHT", app->right_button)) {
- FURI_LOG_W(TAG, "Could not read RIGHT string");
- furi_string_set(app->right_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->right_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- right_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- right_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "OK", app->ok_button)) {
- FURI_LOG_W(TAG, "Could not read OK string");
- furi_string_set(app->ok_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->ok_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- ok_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- ok_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "BACK", app->back_button)) {
- FURI_LOG_W(TAG, "Could not read BACK string");
- furi_string_set(app->back_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->back_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- back_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- back_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "UPHOLD", app->up_hold_button)) {
- FURI_LOG_W(TAG, "Could not read UPHOLD string");
- furi_string_set(app->up_hold_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->up_hold_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- up_hold_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- up_hold_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "DOWNHOLD", app->down_hold_button)) {
- FURI_LOG_W(TAG, "Could not read DOWNHOLD string");
- furi_string_set(app->down_hold_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->down_hold_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- down_hold_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- down_hold_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "LEFTHOLD", app->left_hold_button)) {
- FURI_LOG_W(TAG, "Could not read LEFTHOLD string");
- furi_string_set(app->left_hold_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->left_hold_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- left_hold_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- left_hold_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "RIGHTHOLD", app->right_hold_button)) {
- FURI_LOG_W(TAG, "Could not read RIGHTHOLD string");
- furi_string_set(app->right_hold_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->right_hold_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- right_hold_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- right_hold_enabled = true;
- }
- }
- if(!flipper_format_read_string(ff, "OKHOLD", app->ok_hold_button)) {
- FURI_LOG_W(TAG, "Could not read OKHOLD string");
- furi_string_set(app->ok_hold_button, "N/A");
- } else {
- if(!infrared_remote_find_button_by_name(
- remote, furi_string_get_cstr(app->ok_hold_button), &index)) {
- FURI_LOG_W(TAG, "Error");
- } else {
- ok_hold_signal =
- infrared_remote_button_get_signal(infrared_remote_get_button(remote, index));
- ok_hold_enabled = true;
- }
- }
- }
- furi_string_free(remote_path);
- flipper_format_free(ff);
- furi_record_close(RECORD_STORAGE);
- bool otg_was_enabled = furi_hal_power_is_otg_enabled();
- InfraredSettings settings = {0};
- infrared_settings_load(&settings);
- if(settings.tx_pin < FuriHalInfraredTxPinMax) {
- furi_hal_infrared_set_tx_output(settings.tx_pin);
- if(settings.otg_enabled != otg_was_enabled) {
- if(settings.otg_enabled) {
- furi_hal_power_enable_otg();
- } else {
- furi_hal_power_disable_otg();
- }
- }
- } else {
- FuriHalInfraredTxPin tx_pin_detected = furi_hal_infrared_detect_tx_output();
- furi_hal_infrared_set_tx_output(tx_pin_detected);
- if(tx_pin_detected != FuriHalInfraredTxPinInternal) {
- furi_hal_power_enable_otg();
- }
- }
- bool running = true;
- NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
- if(app->status) {
- view_port_update(app->view_port);
- while(running) {
- if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
- if(event.type == InputTypeShort) {
- switch(event.key) {
- case InputKeyBack:
- running = false;
- break;
- default:
- break;
- }
- }
- }
- }
- } else {
- view_port_update(app->view_port);
- while(running) {
- if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
- // short press signal
- if(event.type == InputTypeShort) {
- switch(event.key) {
- case InputKeyUp:
- if(up_enabled) {
- active_signal = up_signal;
- FURI_LOG_I(TAG, "up");
- }
- break;
- case InputKeyDown:
- if(down_enabled) {
- active_signal = down_signal;
- FURI_LOG_I(TAG, "down");
- }
- break;
- case InputKeyRight:
- if(right_enabled) {
- active_signal = right_signal;
- FURI_LOG_I(TAG, "right");
- }
- break;
- case InputKeyLeft:
- if(left_enabled) {
- active_signal = left_signal;
- FURI_LOG_I(TAG, "left");
- }
- break;
- case InputKeyOk:
- if(ok_enabled) {
- active_signal = ok_signal;
- FURI_LOG_I(TAG, "ok");
- }
- break;
- case InputKeyBack:
- if(back_enabled) {
- active_signal = back_signal;
- FURI_LOG_I(TAG, "back");
- }
- break;
- default:
- running = false;
- break;
- }
- // long press signal
- } else if(event.type == InputTypeLong) {
- switch(event.key) {
- case InputKeyUp:
- if(up_hold_enabled) {
- active_signal = up_hold_signal;
- FURI_LOG_I(TAG, "up!");
- }
- break;
- case InputKeyDown:
- if(down_hold_enabled) {
- active_signal = down_hold_signal;
- FURI_LOG_I(TAG, "down!");
- }
- break;
- case InputKeyRight:
- if(right_hold_enabled) {
- active_signal = right_hold_signal;
- FURI_LOG_I(TAG, "right!");
- }
- break;
- case InputKeyLeft:
- if(left_hold_enabled) {
- active_signal = left_hold_signal;
- FURI_LOG_I(TAG, "left!");
- }
- break;
- case InputKeyOk:
- if(ok_hold_enabled) {
- active_signal = ok_hold_signal;
- FURI_LOG_I(TAG, "ok!");
- }
- break;
- default:
- running = false;
- break;
- }
- } else if(event.type == InputTypeRelease && is_transmitting) {
- notification_message(notification, &sequence_blink_stop);
- infrared_worker_tx_stop(app->infrared_worker);
- is_transmitting = false;
- active_signal = NULL;
- }
- if(active_signal != NULL &&
- (event.type == InputTypeShort || event.type == InputTypeLong)) {
- if(is_transmitting) {
- infrared_worker_tx_stop(app->infrared_worker);
- }
- if(infrared_signal_is_raw(active_signal)) {
- InfraredRawSignal* raw_signal =
- infrared_signal_get_raw_signal(active_signal);
- infrared_worker_set_raw_signal(
- app->infrared_worker,
- raw_signal->timings,
- raw_signal->timings_size,
- raw_signal->frequency,
- raw_signal->duty_cycle);
- } else {
- InfraredMessage* message = infrared_signal_get_message(active_signal);
- infrared_worker_set_decoded_signal(app->infrared_worker, message);
- }
- infrared_worker_tx_set_get_signal_callback(
- app->infrared_worker, infrared_worker_tx_get_signal_steady_callback, app);
- infrared_worker_tx_start(app->infrared_worker);
- notification_message(notification, &sequence_blink_start_magenta);
- is_transmitting = true;
- }
- }
- view_port_update(app->view_port);
- }
- }
- furi_hal_infrared_set_tx_output(FuriHalInfraredTxPinInternal);
- if(furi_hal_power_is_otg_enabled() != otg_was_enabled) {
- if(otg_was_enabled) {
- furi_hal_power_enable_otg();
- } else {
- furi_hal_power_disable_otg();
- }
- }
- // Free all things
- furi_string_free(app->up_button);
- furi_string_free(app->down_button);
- furi_string_free(app->left_button);
- furi_string_free(app->right_button);
- furi_string_free(app->ok_button);
- furi_string_free(app->back_button);
- furi_string_free(app->up_hold_button);
- furi_string_free(app->down_hold_button);
- furi_string_free(app->left_hold_button);
- furi_string_free(app->right_hold_button);
- furi_string_free(app->ok_hold_button);
- if(is_transmitting) {
- infrared_worker_tx_stop(app->infrared_worker);
- notification_message(notification, &sequence_blink_stop);
- }
- infrared_worker_free(app->infrared_worker);
- infrared_remote_free(remote);
- view_port_enabled_set(app->view_port, false);
- gui_remove_view_port(gui, app->view_port);
- view_port_free(app->view_port);
- free(app);
- furi_message_queue_free(event_queue);
- furi_record_close(RECORD_NOTIFICATION);
- furi_record_close(RECORD_GUI);
- return 0;
- }
|