RPC App: state message and GUI update (#1423)

* RPC App: state message and GUI update
* Protobuf submodule update

Co-authored-by: SG <who.just.the.doctor@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Nikolay Minaylov 2022-07-25 17:16:45 +03:00 committed by GitHub
parent f1cb95655c
commit d80edba891
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 237 additions and 62 deletions

View File

@ -118,6 +118,8 @@ static bool ibutton_rpc_command_callback(RpcAppSystemEvent event, const char* ar
string_set_str(ibutton->file_path, arg); string_set_str(ibutton->file_path, arg);
if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) { if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) {
ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key); ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key);
view_dispatcher_send_custom_event(
ibutton->view_dispatcher, iButtonCustomEventRpcLoad);
result = true; result = true;
} }
} }
@ -162,8 +164,6 @@ iButton* ibutton_alloc() {
ibutton->view_dispatcher, ibutton_tick_event_callback, 100); ibutton->view_dispatcher, ibutton_tick_event_callback, 100);
ibutton->gui = furi_record_open("gui"); ibutton->gui = furi_record_open("gui");
view_dispatcher_attach_to_gui(
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
ibutton->storage = furi_record_open("storage"); ibutton->storage = furi_record_open("storage");
ibutton->dialogs = furi_record_open("dialogs"); ibutton->dialogs = furi_record_open("dialogs");
@ -373,6 +373,7 @@ int32_t ibutton_app(void* p) {
ibutton->rpc_ctx = (void*)rpc_ctx; ibutton->rpc_ctx = (void*)rpc_ctx;
rpc_mode = true; rpc_mode = true;
rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton); rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton);
rpc_system_app_send_started(ibutton->rpc_ctx);
} else { } else {
string_set_str(ibutton->file_path, (const char*)p); string_set_str(ibutton->file_path, (const char*)p);
if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) { if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) {
@ -383,17 +384,24 @@ int32_t ibutton_app(void* p) {
} }
if(rpc_mode) { if(rpc_mode) {
view_dispatcher_attach_to_gui(
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeDesktop);
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc);
} else if(key_loaded) {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
} else { } else {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart); view_dispatcher_attach_to_gui(
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
if(key_loaded) {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
} else {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart);
}
} }
view_dispatcher_run(ibutton->view_dispatcher); view_dispatcher_run(ibutton->view_dispatcher);
if(ibutton->rpc_ctx) { if(ibutton->rpc_ctx) {
rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
rpc_system_app_send_exited(ibutton->rpc_ctx);
} }
ibutton_free(ibutton); ibutton_free(ibutton);
return 0; return 0;

View File

@ -10,5 +10,6 @@ enum iButtonCustomEvent {
iButtonCustomEventWorkerEmulated, iButtonCustomEventWorkerEmulated,
iButtonCustomEventWorkerRead, iButtonCustomEventWorkerRead,
iButtonCustomEventRpcLoad,
iButtonCustomEventRpcExit, iButtonCustomEventRpcExit,
}; };

View File

@ -3,12 +3,14 @@
void ibutton_scene_rpc_on_enter(void* context) { void ibutton_scene_rpc_on_enter(void* context) {
iButton* ibutton = context; iButton* ibutton = context;
Widget* widget = ibutton->widget; Popup* popup = ibutton->popup;
widget_add_text_box_element( popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom);
widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); popup_set_icon(popup, 2, 14, &I_iButtonKey_49x44);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup);
notification_message(ibutton->notifications, &sequence_display_backlight_on); notification_message(ibutton->notifications, &sequence_display_backlight_on);
} }
@ -17,12 +19,31 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
UNUSED(context); UNUSED(context);
UNUSED(event); UNUSED(event);
iButton* ibutton = context; iButton* ibutton = context;
Popup* popup = ibutton->popup;
bool consumed = false; bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
consumed = true; consumed = true;
if(event.event == iButtonCustomEventRpcExit) { if(event.event == iButtonCustomEventRpcLoad) {
string_t key_name;
string_init(key_name);
if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) {
path_extract_filename(ibutton->file_path, key_name, true);
}
if(!string_empty_p(key_name)) {
ibutton_text_store_set(ibutton, "emulating\n%s", string_get_cstr(key_name));
} else {
ibutton_text_store_set(ibutton, "emulating");
}
popup_set_text(popup, ibutton->text_store, 82, 32, AlignCenter, AlignTop);
ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
string_clear(key_name);
} else if(event.event == iButtonCustomEventRpcExit) {
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
view_dispatcher_stop(ibutton->view_dispatcher); view_dispatcher_stop(ibutton->view_dispatcher);
} }
} }
@ -32,5 +53,11 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
void ibutton_scene_rpc_on_exit(void* context) { void ibutton_scene_rpc_on_exit(void* context) {
iButton* ibutton = context; iButton* ibutton = context;
widget_reset(ibutton->widget); Popup* popup = ibutton->popup;
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
popup_set_icon(popup, 0, 0, NULL);
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
} }

View File

@ -65,6 +65,8 @@ static bool
infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared); infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared);
infrared_worker_tx_set_signal_sent_callback( infrared_worker_tx_set_signal_sent_callback(
infrared->worker, infrared_signal_sent_callback, infrared); infrared->worker, infrared_signal_sent_callback, infrared);
view_dispatcher_send_custom_event(
infrared->view_dispatcher, InfraredCustomEventTypeRpcLoaded);
} }
} else if(event == RpcAppEventButtonPress) { } else if(event == RpcAppEventButtonPress) {
if(arg) { if(arg) {
@ -141,7 +143,6 @@ static Infrared* infrared_alloc() {
infrared->gui = furi_record_open("gui"); infrared->gui = furi_record_open("gui");
ViewDispatcher* view_dispatcher = infrared->view_dispatcher; ViewDispatcher* view_dispatcher = infrared->view_dispatcher;
view_dispatcher_attach_to_gui(view_dispatcher, infrared->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_enable_queue(view_dispatcher); view_dispatcher_enable_queue(view_dispatcher);
view_dispatcher_set_event_callback_context(view_dispatcher, infrared); view_dispatcher_set_event_callback_context(view_dispatcher, infrared);
view_dispatcher_set_custom_event_callback(view_dispatcher, infrared_custom_event_callback); view_dispatcher_set_custom_event_callback(view_dispatcher, infrared_custom_event_callback);
@ -202,6 +203,7 @@ static void infrared_free(Infrared* infrared) {
if(infrared->rpc_ctx) { if(infrared->rpc_ctx) {
rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL);
rpc_system_app_send_exited(infrared->rpc_ctx);
infrared->rpc_ctx = NULL; infrared->rpc_ctx = NULL;
} }
@ -434,6 +436,7 @@ int32_t infrared_app(void* p) {
infrared->rpc_ctx = (void*)rpc_ctx; infrared->rpc_ctx = (void*)rpc_ctx;
rpc_system_app_set_callback( rpc_system_app_set_callback(
infrared->rpc_ctx, infrared_rpc_command_callback, infrared); infrared->rpc_ctx, infrared_rpc_command_callback, infrared);
rpc_system_app_send_started(infrared->rpc_ctx);
is_rpc_mode = true; is_rpc_mode = true;
} else { } else {
string_set_str(infrared->file_path, (const char*)p); string_set_str(infrared->file_path, (const char*)p);
@ -447,11 +450,17 @@ int32_t infrared_app(void* p) {
} }
if(is_rpc_mode) { if(is_rpc_mode) {
view_dispatcher_attach_to_gui(
infrared->view_dispatcher, infrared->gui, ViewDispatcherTypeDesktop);
scene_manager_next_scene(infrared->scene_manager, InfraredSceneRpc); scene_manager_next_scene(infrared->scene_manager, InfraredSceneRpc);
} else if(is_remote_loaded) {
scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote);
} else { } else {
scene_manager_next_scene(infrared->scene_manager, InfraredSceneStart); view_dispatcher_attach_to_gui(
infrared->view_dispatcher, infrared->gui, ViewDispatcherTypeFullscreen);
if(is_remote_loaded) {
scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote);
} else {
scene_manager_next_scene(infrared->scene_manager, InfraredSceneStart);
}
} }
view_dispatcher_run(infrared->view_dispatcher); view_dispatcher_run(infrared->view_dispatcher);

View File

@ -14,6 +14,7 @@ enum InfraredCustomEventType {
InfraredCustomEventTypePopupClosed, InfraredCustomEventTypePopupClosed,
InfraredCustomEventTypeButtonSelected, InfraredCustomEventTypeButtonSelected,
InfraredCustomEventTypeBackPressed, InfraredCustomEventTypeBackPressed,
InfraredCustomEventTypeRpcLoaded,
}; };
#pragma pack(push, 1) #pragma pack(push, 1)

View File

@ -5,12 +5,14 @@ void infrared_scene_rpc_on_enter(void* context) {
Infrared* infrared = context; Infrared* infrared = context;
Popup* popup = infrared->popup; Popup* popup = infrared->popup;
popup_set_text(popup, "Rpc mode", 64, 28, AlignCenter, AlignCenter); popup_set_header(popup, "Infrared", 82, 28, AlignCenter, AlignBottom);
popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon
popup_set_context(popup, context); popup_set_context(popup, context);
popup_set_callback(popup, infrared_popup_closed_callback); popup_set_callback(popup, infrared_popup_closed_callback);
infrared_play_notification_message(infrared, InfraredNotificationMessageYellowOn);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
notification_message(infrared->notifications, &sequence_display_backlight_on); notification_message(infrared->notifications, &sequence_display_backlight_on);
@ -26,6 +28,12 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
view_dispatcher_stop(infrared->view_dispatcher); view_dispatcher_stop(infrared->view_dispatcher);
} else if(event.event == InfraredCustomEventTypePopupClosed) { } else if(event.event == InfraredCustomEventTypePopupClosed) {
view_dispatcher_stop(infrared->view_dispatcher); view_dispatcher_stop(infrared->view_dispatcher);
} else if(event.event == InfraredCustomEventTypeRpcLoaded) {
const char* remote_name = infrared_remote_get_name(infrared->remote);
infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name);
popup_set_text(
infrared->popup, infrared->text_store[0], 82, 32, AlignCenter, AlignTop);
} }
} }
return consumed; return consumed;

View File

@ -44,6 +44,7 @@ LfRfidApp::~LfRfidApp() {
string_clear(file_path); string_clear(file_path);
if(rpc_ctx) { if(rpc_ctx) {
rpc_system_app_set_callback(rpc_ctx, NULL, NULL); rpc_system_app_set_callback(rpc_ctx, NULL, NULL);
rpc_system_app_send_exited(rpc_ctx);
} }
} }
@ -91,6 +92,7 @@ void LfRfidApp::run(void* _args) {
if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) { if(sscanf(args, "RPC %lX", &rpc_ctx_ptr) == 1) {
rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr; rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr;
rpc_system_app_set_callback(rpc_ctx, rpc_command_callback, this); rpc_system_app_set_callback(rpc_ctx, rpc_command_callback, this);
rpc_system_app_send_started(rpc_ctx);
scene_controller.add_scene(SceneType::Rpc, new LfRfidAppSceneRpc()); scene_controller.add_scene(SceneType::Rpc, new LfRfidAppSceneRpc());
scene_controller.process(100, SceneType::Rpc); scene_controller.process(100, SceneType::Rpc);
} else { } else {

View File

@ -2,10 +2,24 @@
#include <core/common_defines.h> #include <core/common_defines.h>
#include <dolphin/dolphin.h> #include <dolphin/dolphin.h>
static const NotificationSequence sequence_blink_start_magenta = {
&message_blink_start_10,
&message_blink_set_color_magenta,
&message_do_not_reset,
NULL,
};
static const NotificationSequence sequence_blink_stop = {
&message_blink_stop,
NULL,
};
void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) { void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) {
auto popup = app->view_controller.get<PopupVM>(); auto popup = app->view_controller.get<PopupVM>();
popup->set_header("RPC Mode", 64, 30, AlignCenter, AlignTop); popup->set_header("LF RFID", 89, 30, AlignCenter, AlignTop);
popup->set_text("RPC mode", 89, 43, AlignCenter, AlignTop);
popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61);
app->view_controller.switch_to<PopupVM>(); app->view_controller.switch_to<PopupVM>();
@ -23,8 +37,14 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
view_event.type = LfRfidApp::EventType::Back; view_event.type = LfRfidApp::EventType::Back;
app->view_controller.send_event(&view_event); app->view_controller.send_event(&view_event);
} else if(event->type == LfRfidApp::EventType::EmulateStart) { } else if(event->type == LfRfidApp::EventType::EmulateStart) {
auto popup = app->view_controller.get<PopupVM>();
consumed = true; consumed = true;
emulating = true; emulating = true;
app->text_store.set("emulating\n%s", app->worker.key.get_name());
popup->set_text(app->text_store.text, 89, 43, AlignCenter, AlignTop);
notification_message(app->notification, &sequence_blink_start_magenta);
} }
return consumed; return consumed;
} }
@ -32,6 +52,7 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
void LfRfidAppSceneRpc::on_exit(LfRfidApp* app) { void LfRfidAppSceneRpc::on_exit(LfRfidApp* app) {
if(emulating) { if(emulating) {
app->worker.stop_emulate(); app->worker.stop_emulate();
notification_message(app->notification, &sequence_blink_stop);
} }
app->view_controller.get<PopupVM>()->clean(); app->view_controller.get<PopupVM>()->clean();
} }

View File

@ -9,4 +9,5 @@ enum NfcCustomEvent {
NfcCustomEventByteInputDone, NfcCustomEventByteInputDone,
NfcCustomEventTextInputDone, NfcCustomEventTextInputDone,
NfcCustomEventDictAttackDone, NfcCustomEventDictAttackDone,
NfcCustomEventRpcLoad,
}; };

View File

@ -31,6 +31,7 @@ void nfc_rpc_exit_callback(Nfc* nfc) {
} }
if(nfc->rpc_ctx) { if(nfc->rpc_ctx) {
rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
rpc_system_app_send_exited(nfc->rpc_ctx);
nfc->rpc_ctx = NULL; nfc->rpc_ctx = NULL;
} }
} }
@ -82,6 +83,7 @@ static bool nfc_rpc_command_callback(RpcAppSystemEvent event, const char* arg, v
nfc->worker, NfcWorkerStateEmulate, &nfc->dev->dev_data, NULL, nfc); nfc->worker, NfcWorkerStateEmulate, &nfc->dev->dev_data, NULL, nfc);
} }
nfc->rpc_state = NfcRpcStateEmulating; nfc->rpc_state = NfcRpcStateEmulating;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad);
result = true; result = true;
} }
} }
@ -107,7 +109,6 @@ Nfc* nfc_alloc() {
// Open GUI record // Open GUI record
nfc->gui = furi_record_open("gui"); nfc->gui = furi_record_open("gui");
view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
// Open Notification record // Open Notification record
nfc->notifications = furi_record_open("notification"); nfc->notifications = furi_record_open("notification");
@ -291,21 +292,30 @@ int32_t nfc_app(void* p) {
if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) {
nfc->rpc_ctx = (void*)rpc_ctx; nfc->rpc_ctx = (void*)rpc_ctx;
rpc_system_app_set_callback(nfc->rpc_ctx, nfc_rpc_command_callback, nfc); rpc_system_app_set_callback(nfc->rpc_ctx, nfc_rpc_command_callback, nfc);
rpc_system_app_send_started(nfc->rpc_ctx);
view_dispatcher_attach_to_gui(
nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeDesktop);
scene_manager_next_scene(nfc->scene_manager, NfcSceneRpc); scene_manager_next_scene(nfc->scene_manager, NfcSceneRpc);
} else if(nfc_device_load(nfc->dev, p, true)) {
if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic);
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
}
} else { } else {
// Exit app view_dispatcher_attach_to_gui(
view_dispatcher_stop(nfc->view_dispatcher); nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
if(nfc_device_load(nfc->dev, p, true)) {
if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic);
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
}
} else {
// Exit app
view_dispatcher_stop(nfc->view_dispatcher);
}
} }
nfc_device_set_loading_callback(nfc->dev, NULL, nfc); nfc_device_set_loading_callback(nfc->dev, NULL, nfc);
} else { } else {
view_dispatcher_attach_to_gui(
nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); scene_manager_next_scene(nfc->scene_manager, NfcSceneStart);
} }

View File

@ -2,24 +2,33 @@
void nfc_scene_rpc_on_enter(void* context) { void nfc_scene_rpc_on_enter(void* context) {
Nfc* nfc = context; Nfc* nfc = context;
Widget* widget = nfc->widget; Popup* popup = nfc->popup;
widget_add_text_box_element( popup_set_header(popup, "NFC", 82, 28, AlignCenter, AlignBottom);
widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
notification_message(nfc->notifications, &sequence_display_backlight_on); notification_message(nfc->notifications, &sequence_display_backlight_on);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
} }
bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context; Nfc* nfc = context;
Popup* popup = nfc->popup;
bool consumed = false; bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
consumed = true; consumed = true;
if(event.event == NfcCustomEventViewExit) { if(event.event == NfcCustomEventViewExit) {
view_dispatcher_stop(nfc->view_dispatcher); view_dispatcher_stop(nfc->view_dispatcher);
nfc_blink_stop(nfc);
} else if(event.event == NfcCustomEventRpcLoad) {
nfc_blink_start(nfc);
nfc_text_store_set(nfc, "emulating\n%s", nfc->dev->dev_name);
popup_set_text(popup, nfc->text_store, 82, 32, AlignCenter, AlignTop);
} }
} }
return consumed; return consumed;
@ -27,8 +36,12 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
void nfc_scene_rpc_on_exit(void* context) { void nfc_scene_rpc_on_exit(void* context) {
Nfc* nfc = context; Nfc* nfc = context;
Popup* popup = nfc->popup;
nfc_rpc_exit_callback(nfc); nfc_rpc_exit_callback(nfc);
nfc_blink_stop(nfc);
widget_reset(nfc->widget); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
popup_set_icon(popup, 0, 0, NULL);
} }

View File

@ -12,6 +12,7 @@ struct RpcAppSystem {
RpcSession* session; RpcSession* session;
RpcAppSystemCallback app_callback; RpcAppSystemCallback app_callback;
void* app_context; void* app_context;
PB_Main* state_msg;
FuriTimer* timer; FuriTimer* timer;
}; };
@ -96,7 +97,7 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con
pb_release(&PB_Main_msg, &response); pb_release(&PB_Main_msg, &response);
} }
static void rpc_system_app_exit(const PB_Main* request, void* context) { static void rpc_system_app_exit_request(const PB_Main* request, void* context) {
furi_assert(request); furi_assert(request);
furi_assert(context); furi_assert(context);
@ -194,6 +195,24 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context)
rpc_send_and_release_empty(session, request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status);
} }
void rpc_system_app_send_started(RpcAppSystem* rpc_app) {
furi_assert(rpc_app);
RpcSession* session = rpc_app->session;
furi_assert(session);
rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_STARTED;
rpc_send(session, rpc_app->state_msg);
}
void rpc_system_app_send_exited(RpcAppSystem* rpc_app) {
furi_assert(rpc_app);
RpcSession* session = rpc_app->session;
furi_assert(session);
rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_CLOSED;
rpc_send(session, rpc_app->state_msg);
}
void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx) { void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx) {
furi_assert(rpc_app); furi_assert(rpc_app);
@ -209,6 +228,11 @@ void* rpc_system_app_alloc(RpcSession* session) {
rpc_app->timer = furi_timer_alloc(rpc_system_app_timer_callback, FuriTimerTypeOnce, rpc_app); rpc_app->timer = furi_timer_alloc(rpc_system_app_timer_callback, FuriTimerTypeOnce, rpc_app);
// App exit message
rpc_app->state_msg = malloc(sizeof(PB_Main));
rpc_app->state_msg->which_content = PB_Main_app_state_response_tag;
rpc_app->state_msg->command_status = PB_CommandStatus_OK;
RpcHandler rpc_handler = { RpcHandler rpc_handler = {
.message_handler = NULL, .message_handler = NULL,
.decode_submessage = NULL, .decode_submessage = NULL,
@ -221,7 +245,7 @@ void* rpc_system_app_alloc(RpcSession* session) {
rpc_handler.message_handler = rpc_system_app_lock_status_process; rpc_handler.message_handler = rpc_system_app_lock_status_process;
rpc_add_handler(session, PB_Main_app_lock_status_request_tag, &rpc_handler); rpc_add_handler(session, PB_Main_app_lock_status_request_tag, &rpc_handler);
rpc_handler.message_handler = rpc_system_app_exit; rpc_handler.message_handler = rpc_system_app_exit_request;
rpc_add_handler(session, PB_Main_app_exit_request_tag, &rpc_handler); rpc_add_handler(session, PB_Main_app_exit_request_tag, &rpc_handler);
rpc_handler.message_handler = rpc_system_app_load_file; rpc_handler.message_handler = rpc_system_app_load_file;
@ -247,5 +271,6 @@ void rpc_system_app_free(void* context) {
rpc_app->app_callback(RpcAppEventSessionClose, NULL, rpc_app->app_context); rpc_app->app_callback(RpcAppEventSessionClose, NULL, rpc_app->app_context);
} }
free(rpc_app->state_msg);
free(rpc_app); free(rpc_app);
} }

View File

@ -19,6 +19,10 @@ typedef struct RpcAppSystem RpcAppSystem;
void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx); void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx);
void rpc_system_app_send_started(RpcAppSystem* rpc_app);
void rpc_system_app_send_exited(RpcAppSystem* rpc_app);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -46,6 +46,8 @@ typedef enum {
SubGhzCustomEventSceneExit, SubGhzCustomEventSceneExit,
SubGhzCustomEventSceneStay, SubGhzCustomEventSceneStay,
SubGhzCustomEventSceneRpcLoad,
SubGhzCustomEventViewReceiverOK, SubGhzCustomEventViewReceiverOK,
SubGhzCustomEventViewReceiverConfig, SubGhzCustomEventViewReceiverConfig,
SubGhzCustomEventViewReceiverBack, SubGhzCustomEventViewReceiverBack,

View File

@ -2,24 +2,40 @@
void subghz_scene_rpc_on_enter(void* context) { void subghz_scene_rpc_on_enter(void* context) {
SubGhz* subghz = context; SubGhz* subghz = context;
Widget* widget = subghz->widget; Popup* popup = subghz->popup;
widget_add_text_box_element( popup_set_header(popup, "Sub-GHz", 82, 28, AlignCenter, AlignBottom);
widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);
notification_message(subghz->notifications, &sequence_display_backlight_on); notification_message(subghz->notifications, &sequence_display_backlight_on);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdWidget);
} }
bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context; SubGhz* subghz = context;
Popup* popup = subghz->popup;
bool consumed = false; bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
consumed = true; consumed = true;
if(event.event == SubGhzCustomEventSceneExit) { if(event.event == SubGhzCustomEventSceneExit) {
view_dispatcher_stop(subghz->view_dispatcher); view_dispatcher_stop(subghz->view_dispatcher);
} else if(event.event == SubGhzCustomEventSceneRpcLoad) {
string_t file_name;
string_init(file_name);
path_extract_filename(subghz->file_path, file_name, true);
snprintf(
subghz->file_name_tmp,
SUBGHZ_MAX_LEN_NAME,
"loaded\n%s",
string_get_cstr(file_name));
popup_set_text(popup, subghz->file_name_tmp, 82, 32, AlignCenter, AlignTop);
string_clear(file_name);
} }
} }
return consumed; return consumed;
@ -27,8 +43,9 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
void subghz_scene_rpc_on_exit(void* context) { void subghz_scene_rpc_on_exit(void* context) {
SubGhz* subghz = context; SubGhz* subghz = context;
Popup* popup = subghz->popup;
//subghz_rpc_exit_callback(subghz); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
widget_reset(subghz->widget); popup_set_icon(popup, 0, 0, NULL);
} }

View File

@ -5,6 +5,18 @@
#include "subghz_i.h" #include "subghz_i.h"
#include <lib/toolbox/path.h> #include <lib/toolbox/path.h>
static const NotificationSequence sequence_blink_start_magenta = {
&message_blink_start_10,
&message_blink_set_color_magenta,
&message_do_not_reset,
NULL,
};
static const NotificationSequence sequence_blink_stop = {
&message_blink_stop,
NULL,
};
bool subghz_custom_event_callback(void* context, uint32_t event) { bool subghz_custom_event_callback(void* context, uint32_t event) {
furi_assert(context); furi_assert(context);
SubGhz* subghz = context; SubGhz* subghz = context;
@ -36,6 +48,7 @@ static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg
if(event == RpcAppEventSessionClose) { if(event == RpcAppEventSessionClose) {
rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL);
subghz->rpc_ctx = NULL; subghz->rpc_ctx = NULL;
notification_message(subghz->notifications, &sequence_blink_stop);
view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit);
if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
subghz_tx_stop(subghz); subghz_tx_stop(subghz);
@ -53,15 +66,19 @@ static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg
if(arg) { if(arg) {
if(subghz_key_load(subghz, arg, false)) { if(subghz_key_load(subghz, arg, false)) {
string_set_str(subghz->file_path, arg); string_set_str(subghz->file_path, arg);
view_dispatcher_send_custom_event(
subghz->view_dispatcher, SubGhzCustomEventSceneRpcLoad);
result = true; result = true;
} }
} }
} else if(event == RpcAppEventButtonPress) { } else if(event == RpcAppEventButtonPress) {
if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) {
notification_message(subghz->notifications, &sequence_blink_start_magenta);
result = subghz_tx_start(subghz, subghz->txrx->fff_data); result = subghz_tx_start(subghz, subghz->txrx->fff_data);
} }
} else if(event == RpcAppEventButtonRelease) { } else if(event == RpcAppEventButtonRelease) {
if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
notification_message(subghz->notifications, &sequence_blink_stop);
subghz_tx_stop(subghz); subghz_tx_stop(subghz);
subghz_sleep(subghz); subghz_sleep(subghz);
result = true; result = true;
@ -83,8 +100,6 @@ SubGhz* subghz_alloc() {
// View Dispatcher // View Dispatcher
subghz->view_dispatcher = view_dispatcher_alloc(); subghz->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(subghz->view_dispatcher); view_dispatcher_enable_queue(subghz->view_dispatcher);
view_dispatcher_attach_to_gui(
subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen);
subghz->scene_manager = scene_manager_alloc(&subghz_scene_handlers, subghz); subghz->scene_manager = scene_manager_alloc(&subghz_scene_handlers, subghz);
view_dispatcher_set_event_callback_context(subghz->view_dispatcher, subghz); view_dispatcher_set_event_callback_context(subghz->view_dispatcher, subghz);
@ -218,6 +233,8 @@ void subghz_free(SubGhz* subghz) {
if(subghz->rpc_ctx) { if(subghz->rpc_ctx) {
rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL);
rpc_system_app_send_exited(subghz->rpc_ctx);
notification_message(subghz->notifications, &sequence_blink_stop);
subghz->rpc_ctx = NULL; subghz->rpc_ctx = NULL;
} }
@ -322,24 +339,33 @@ int32_t subghz_app(void* p) {
if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) {
subghz->rpc_ctx = (void*)rpc_ctx; subghz->rpc_ctx = (void*)rpc_ctx;
rpc_system_app_set_callback(subghz->rpc_ctx, subghz_rpc_command_callback, subghz); rpc_system_app_set_callback(subghz->rpc_ctx, subghz_rpc_command_callback, subghz);
rpc_system_app_send_started(subghz->rpc_ctx);
view_dispatcher_attach_to_gui(
subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeDesktop);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRpc); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneRpc);
} else if(subghz_key_load(subghz, p, true)) {
string_set_str(subghz->file_path, p);
if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) {
//Load Raw TX
subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
} else {
//Load transmitter TX
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter);
}
} else { } else {
//exit app view_dispatcher_attach_to_gui(
scene_manager_stop(subghz->scene_manager); subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_stop(subghz->view_dispatcher); if(subghz_key_load(subghz, p, true)) {
string_set_str(subghz->file_path, p);
if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) {
//Load Raw TX
subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
} else {
//Load transmitter TX
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter);
}
} else {
//exit app
scene_manager_stop(subghz->scene_manager);
view_dispatcher_stop(subghz->view_dispatcher);
}
} }
} else { } else {
view_dispatcher_attach_to_gui(
subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen);
string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER);
if(load_database) { if(load_database) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart);

@ -1 +1 @@
Subproject commit d9e343661dd36cfab792b78be1dea4e5950cb4dd Subproject commit cc5918dc488ac3617012ce5377114e086b447324