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:
		
							parent
							
								
									f1cb95655c
								
							
						
					
					
						commit
						d80edba891
					
				| @ -118,6 +118,8 @@ static bool ibutton_rpc_command_callback(RpcAppSystemEvent event, const char* ar | ||||
|             string_set_str(ibutton->file_path, arg); | ||||
|             if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) { | ||||
|                 ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key); | ||||
|                 view_dispatcher_send_custom_event( | ||||
|                     ibutton->view_dispatcher, iButtonCustomEventRpcLoad); | ||||
|                 result = true; | ||||
|             } | ||||
|         } | ||||
| @ -162,8 +164,6 @@ iButton* ibutton_alloc() { | ||||
|         ibutton->view_dispatcher, ibutton_tick_event_callback, 100); | ||||
| 
 | ||||
|     ibutton->gui = furi_record_open("gui"); | ||||
|     view_dispatcher_attach_to_gui( | ||||
|         ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen); | ||||
| 
 | ||||
|     ibutton->storage = furi_record_open("storage"); | ||||
|     ibutton->dialogs = furi_record_open("dialogs"); | ||||
| @ -373,6 +373,7 @@ int32_t ibutton_app(void* p) { | ||||
|             ibutton->rpc_ctx = (void*)rpc_ctx; | ||||
|             rpc_mode = true; | ||||
|             rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton); | ||||
|             rpc_system_app_send_started(ibutton->rpc_ctx); | ||||
|         } else { | ||||
|             string_set_str(ibutton->file_path, (const char*)p); | ||||
|             if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) { | ||||
| @ -383,17 +384,24 @@ int32_t ibutton_app(void* p) { | ||||
|     } | ||||
| 
 | ||||
|     if(rpc_mode) { | ||||
|         view_dispatcher_attach_to_gui( | ||||
|             ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeDesktop); | ||||
|         scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRpc); | ||||
|     } else if(key_loaded) { | ||||
|         scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate); | ||||
|     } 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); | ||||
| 
 | ||||
|     if(ibutton->rpc_ctx) { | ||||
|         rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL); | ||||
|         rpc_system_app_send_exited(ibutton->rpc_ctx); | ||||
|     } | ||||
|     ibutton_free(ibutton); | ||||
|     return 0; | ||||
|  | ||||
| @ -10,5 +10,6 @@ enum iButtonCustomEvent { | ||||
|     iButtonCustomEventWorkerEmulated, | ||||
|     iButtonCustomEventWorkerRead, | ||||
| 
 | ||||
|     iButtonCustomEventRpcLoad, | ||||
|     iButtonCustomEventRpcExit, | ||||
| }; | ||||
|  | ||||
| @ -3,12 +3,14 @@ | ||||
| 
 | ||||
| void ibutton_scene_rpc_on_enter(void* context) { | ||||
|     iButton* ibutton = context; | ||||
|     Widget* widget = ibutton->widget; | ||||
|     Popup* popup = ibutton->popup; | ||||
| 
 | ||||
|     widget_add_text_box_element( | ||||
|         widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); | ||||
|     popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom); | ||||
|     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); | ||||
| } | ||||
| @ -17,12 +19,31 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { | ||||
|     UNUSED(context); | ||||
|     UNUSED(event); | ||||
|     iButton* ibutton = context; | ||||
|     Popup* popup = ibutton->popup; | ||||
| 
 | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         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); | ||||
|         } | ||||
|     } | ||||
| @ -32,5 +53,11 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void ibutton_scene_rpc_on_exit(void* 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); | ||||
| } | ||||
|  | ||||
| @ -65,6 +65,8 @@ static bool | ||||
|                 infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared); | ||||
|             infrared_worker_tx_set_signal_sent_callback( | ||||
|                 infrared->worker, infrared_signal_sent_callback, infrared); | ||||
|             view_dispatcher_send_custom_event( | ||||
|                 infrared->view_dispatcher, InfraredCustomEventTypeRpcLoaded); | ||||
|         } | ||||
|     } else if(event == RpcAppEventButtonPress) { | ||||
|         if(arg) { | ||||
| @ -141,7 +143,6 @@ static Infrared* infrared_alloc() { | ||||
|     infrared->gui = furi_record_open("gui"); | ||||
| 
 | ||||
|     ViewDispatcher* view_dispatcher = infrared->view_dispatcher; | ||||
|     view_dispatcher_attach_to_gui(view_dispatcher, infrared->gui, ViewDispatcherTypeFullscreen); | ||||
|     view_dispatcher_enable_queue(view_dispatcher); | ||||
|     view_dispatcher_set_event_callback_context(view_dispatcher, infrared); | ||||
|     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) { | ||||
|         rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL); | ||||
|         rpc_system_app_send_exited(infrared->rpc_ctx); | ||||
|         infrared->rpc_ctx = NULL; | ||||
|     } | ||||
| 
 | ||||
| @ -434,6 +436,7 @@ int32_t infrared_app(void* p) { | ||||
|             infrared->rpc_ctx = (void*)rpc_ctx; | ||||
|             rpc_system_app_set_callback( | ||||
|                 infrared->rpc_ctx, infrared_rpc_command_callback, infrared); | ||||
|             rpc_system_app_send_started(infrared->rpc_ctx); | ||||
|             is_rpc_mode = true; | ||||
|         } else { | ||||
|             string_set_str(infrared->file_path, (const char*)p); | ||||
| @ -447,11 +450,17 @@ int32_t infrared_app(void* p) { | ||||
|     } | ||||
| 
 | ||||
|     if(is_rpc_mode) { | ||||
|         view_dispatcher_attach_to_gui( | ||||
|             infrared->view_dispatcher, infrared->gui, ViewDispatcherTypeDesktop); | ||||
|         scene_manager_next_scene(infrared->scene_manager, InfraredSceneRpc); | ||||
|     } else if(is_remote_loaded) { | ||||
|         scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote); | ||||
|     } 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); | ||||
|  | ||||
| @ -14,6 +14,7 @@ enum InfraredCustomEventType { | ||||
|     InfraredCustomEventTypePopupClosed, | ||||
|     InfraredCustomEventTypeButtonSelected, | ||||
|     InfraredCustomEventTypeBackPressed, | ||||
|     InfraredCustomEventTypeRpcLoaded, | ||||
| }; | ||||
| 
 | ||||
| #pragma pack(push, 1) | ||||
|  | ||||
| @ -5,12 +5,14 @@ void infrared_scene_rpc_on_enter(void* context) { | ||||
|     Infrared* infrared = context; | ||||
|     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_callback(popup, infrared_popup_closed_callback); | ||||
| 
 | ||||
|     infrared_play_notification_message(infrared, InfraredNotificationMessageYellowOn); | ||||
|     view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); | ||||
| 
 | ||||
|     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); | ||||
|         } else if(event.event == InfraredCustomEventTypePopupClosed) { | ||||
|             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; | ||||
|  | ||||
| @ -44,6 +44,7 @@ LfRfidApp::~LfRfidApp() { | ||||
|     string_clear(file_path); | ||||
|     if(rpc_ctx) { | ||||
|         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) { | ||||
|             rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr; | ||||
|             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.process(100, SceneType::Rpc); | ||||
|         } else { | ||||
|  | ||||
| @ -2,10 +2,24 @@ | ||||
| #include <core/common_defines.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 */) { | ||||
|     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>(); | ||||
| 
 | ||||
| @ -23,8 +37,14 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | ||||
|         view_event.type = LfRfidApp::EventType::Back; | ||||
|         app->view_controller.send_event(&view_event); | ||||
|     } else if(event->type == LfRfidApp::EventType::EmulateStart) { | ||||
|         auto popup = app->view_controller.get<PopupVM>(); | ||||
|         consumed = 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; | ||||
| } | ||||
| @ -32,6 +52,7 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | ||||
| void LfRfidAppSceneRpc::on_exit(LfRfidApp* app) { | ||||
|     if(emulating) { | ||||
|         app->worker.stop_emulate(); | ||||
|         notification_message(app->notification, &sequence_blink_stop); | ||||
|     } | ||||
|     app->view_controller.get<PopupVM>()->clean(); | ||||
| } | ||||
|  | ||||
| @ -9,4 +9,5 @@ enum NfcCustomEvent { | ||||
|     NfcCustomEventByteInputDone, | ||||
|     NfcCustomEventTextInputDone, | ||||
|     NfcCustomEventDictAttackDone, | ||||
|     NfcCustomEventRpcLoad, | ||||
| }; | ||||
|  | ||||
| @ -31,6 +31,7 @@ void nfc_rpc_exit_callback(Nfc* nfc) { | ||||
|     } | ||||
|     if(nfc->rpc_ctx) { | ||||
|         rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL); | ||||
|         rpc_system_app_send_exited(nfc->rpc_ctx); | ||||
|         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->rpc_state = NfcRpcStateEmulating; | ||||
|                 view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad); | ||||
|                 result = true; | ||||
|             } | ||||
|         } | ||||
| @ -107,7 +109,6 @@ Nfc* nfc_alloc() { | ||||
| 
 | ||||
|     // Open GUI record
 | ||||
|     nfc->gui = furi_record_open("gui"); | ||||
|     view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); | ||||
| 
 | ||||
|     // Open Notification record
 | ||||
|     nfc->notifications = furi_record_open("notification"); | ||||
| @ -291,21 +292,30 @@ int32_t nfc_app(void* p) { | ||||
|         if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { | ||||
|             nfc->rpc_ctx = (void*)rpc_ctx; | ||||
|             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); | ||||
|         } 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 { | ||||
|             // Exit app
 | ||||
|             view_dispatcher_stop(nfc->view_dispatcher); | ||||
|             view_dispatcher_attach_to_gui( | ||||
|                 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); | ||||
|     } else { | ||||
|         view_dispatcher_attach_to_gui( | ||||
|             nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); | ||||
|         scene_manager_next_scene(nfc->scene_manager, NfcSceneStart); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -2,24 +2,33 @@ | ||||
| 
 | ||||
| void nfc_scene_rpc_on_enter(void* context) { | ||||
|     Nfc* nfc = context; | ||||
|     Widget* widget = nfc->widget; | ||||
|     Popup* popup = nfc->popup; | ||||
| 
 | ||||
|     widget_add_text_box_element( | ||||
|         widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); | ||||
|     popup_set_header(popup, "NFC", 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
 | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); | ||||
| 
 | ||||
|     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) { | ||||
|     Nfc* nfc = context; | ||||
|     Popup* popup = nfc->popup; | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         consumed = true; | ||||
|         if(event.event == NfcCustomEventViewExit) { | ||||
|             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; | ||||
| @ -27,8 +36,12 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void nfc_scene_rpc_on_exit(void* context) { | ||||
|     Nfc* nfc = context; | ||||
|     Popup* popup = nfc->popup; | ||||
| 
 | ||||
|     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); | ||||
| } | ||||
|  | ||||
| @ -12,6 +12,7 @@ struct RpcAppSystem { | ||||
|     RpcSession* session; | ||||
|     RpcAppSystemCallback app_callback; | ||||
|     void* app_context; | ||||
|     PB_Main* state_msg; | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| 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(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); | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|     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); | ||||
| 
 | ||||
|     // 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 = { | ||||
|         .message_handler = 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_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_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); | ||||
|     } | ||||
| 
 | ||||
|     free(rpc_app->state_msg); | ||||
|     free(rpc_app); | ||||
| } | ||||
|  | ||||
| @ -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_send_started(RpcAppSystem* rpc_app); | ||||
| 
 | ||||
| void rpc_system_app_send_exited(RpcAppSystem* rpc_app); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -46,6 +46,8 @@ typedef enum { | ||||
|     SubGhzCustomEventSceneExit, | ||||
|     SubGhzCustomEventSceneStay, | ||||
| 
 | ||||
|     SubGhzCustomEventSceneRpcLoad, | ||||
| 
 | ||||
|     SubGhzCustomEventViewReceiverOK, | ||||
|     SubGhzCustomEventViewReceiverConfig, | ||||
|     SubGhzCustomEventViewReceiverBack, | ||||
|  | ||||
| @ -2,24 +2,40 @@ | ||||
| 
 | ||||
| void subghz_scene_rpc_on_enter(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     Widget* widget = subghz->widget; | ||||
|     Popup* popup = subghz->popup; | ||||
| 
 | ||||
|     widget_add_text_box_element( | ||||
|         widget, 0, 0, 128, 28, AlignCenter, AlignCenter, "RPC mode", false); | ||||
|     popup_set_header(popup, "Sub-GHz", 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
 | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); | ||||
| 
 | ||||
|     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) { | ||||
|     SubGhz* subghz = context; | ||||
|     Popup* popup = subghz->popup; | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         consumed = true; | ||||
|         if(event.event == SubGhzCustomEventSceneExit) { | ||||
|             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; | ||||
| @ -27,8 +43,9 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
| void subghz_scene_rpc_on_exit(void* context) { | ||||
|     SubGhz* subghz = context; | ||||
|     Popup* popup = subghz->popup; | ||||
| 
 | ||||
|     //subghz_rpc_exit_callback(subghz);
 | ||||
| 
 | ||||
|     widget_reset(subghz->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); | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,18 @@ | ||||
| #include "subghz_i.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) { | ||||
|     furi_assert(context); | ||||
|     SubGhz* subghz = context; | ||||
| @ -36,6 +48,7 @@ static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg | ||||
|     if(event == RpcAppEventSessionClose) { | ||||
|         rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL); | ||||
|         subghz->rpc_ctx = NULL; | ||||
|         notification_message(subghz->notifications, &sequence_blink_stop); | ||||
|         view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit); | ||||
|         if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { | ||||
|             subghz_tx_stop(subghz); | ||||
| @ -53,15 +66,19 @@ static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg | ||||
|         if(arg) { | ||||
|             if(subghz_key_load(subghz, arg, false)) { | ||||
|                 string_set_str(subghz->file_path, arg); | ||||
|                 view_dispatcher_send_custom_event( | ||||
|                     subghz->view_dispatcher, SubGhzCustomEventSceneRpcLoad); | ||||
|                 result = true; | ||||
|             } | ||||
|         } | ||||
|     } else if(event == RpcAppEventButtonPress) { | ||||
|         if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) { | ||||
|             notification_message(subghz->notifications, &sequence_blink_start_magenta); | ||||
|             result = subghz_tx_start(subghz, subghz->txrx->fff_data); | ||||
|         } | ||||
|     } else if(event == RpcAppEventButtonRelease) { | ||||
|         if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) { | ||||
|             notification_message(subghz->notifications, &sequence_blink_stop); | ||||
|             subghz_tx_stop(subghz); | ||||
|             subghz_sleep(subghz); | ||||
|             result = true; | ||||
| @ -83,8 +100,6 @@ SubGhz* subghz_alloc() { | ||||
|     // View Dispatcher
 | ||||
|     subghz->view_dispatcher = view_dispatcher_alloc(); | ||||
|     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); | ||||
|     view_dispatcher_set_event_callback_context(subghz->view_dispatcher, subghz); | ||||
| @ -218,6 +233,8 @@ void subghz_free(SubGhz* subghz) { | ||||
| 
 | ||||
|     if(subghz->rpc_ctx) { | ||||
|         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; | ||||
|     } | ||||
| 
 | ||||
| @ -322,24 +339,33 @@ int32_t subghz_app(void* p) { | ||||
|         if(sscanf(p, "RPC %lX", &rpc_ctx) == 1) { | ||||
|             subghz->rpc_ctx = (void*)rpc_ctx; | ||||
|             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); | ||||
|         } 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 { | ||||
|             //exit app
 | ||||
|             scene_manager_stop(subghz->scene_manager); | ||||
|             view_dispatcher_stop(subghz->view_dispatcher); | ||||
|             view_dispatcher_attach_to_gui( | ||||
|                 subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); | ||||
|             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 { | ||||
|         view_dispatcher_attach_to_gui( | ||||
|             subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); | ||||
|         string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); | ||||
|         if(load_database) { | ||||
|             scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| Subproject commit d9e343661dd36cfab792b78be1dea4e5950cb4dd | ||||
| Subproject commit cc5918dc488ac3617012ce5377114e086b447324 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikolay Minaylov
						Nikolay Minaylov