Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorあく <alleteam@gmail.com>2022-08-02 15:54:12 +0300
committerGitHub <noreply@github.com>2022-08-02 15:54:12 +0300
commitf9745b4141570e6dbc919ac5a63ed98acb9483c7 (patch)
tree575f77ebbb4529e228024e7b954405768c7ac118
parentf9386b2649c022fde75572046ceb51198a4a5317 (diff)
[FL-2705] App RPC Bug Fixes and redesign (#1491)
* Rpc: remove callback timer * Rpc: simplify rpc event callback * Rpc: migrate to new confirmation schema * Rpc: migrate to new confirmation schema part2: finalize ibutton and rfid * Rpc: migrate to new confirmation schema part3: finallize nfc and fix id in load * Rpc: hardened sequencing check * Rpc: migrate to new confirmation schema part4: finalize subghz * iButton: properly handle exit * Nfc: correct sequence for rpc exit send * Rpc: fix review issues and nfc exit message * Rpc: more logging and condition race fix in confirmation * Rpc: migrate to new confirmation schema part5: finalize infrared * Rpc: more logging
-rw-r--r--applications/ibutton/ibutton.c29
-rw-r--r--applications/ibutton/ibutton_custom_event.h1
-rw-r--r--applications/ibutton/ibutton_i.h1
-rw-r--r--applications/ibutton/scenes/ibutton_scene_rpc.c44
-rw-r--r--applications/infrared/infrared.c47
-rw-r--r--applications/infrared/infrared_custom_event.h7
-rw-r--r--applications/infrared/scenes/infrared_scene_rpc.c35
-rw-r--r--applications/lfrfid/lfrfid_app.cpp35
-rw-r--r--applications/lfrfid/lfrfid_app.h2
-rw-r--r--applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp26
-rw-r--r--applications/nfc/helpers/nfc_custom_event.h1
-rw-r--r--applications/nfc/nfc.c84
-rwxr-xr-xapplications/nfc/nfc_i.h2
-rw-r--r--applications/nfc/scenes/nfc_scene_rpc.c49
-rw-r--r--applications/rpc/rpc_app.c147
-rw-r--r--applications/rpc/rpc_app.h6
-rw-r--r--applications/subghz/helpers/subghz_custom_event.h3
-rw-r--r--applications/subghz/scenes/subghz_scene_rpc.c64
-rw-r--r--applications/subghz/subghz.c61
-rw-r--r--applications/subghz/subghz_i.h4
20 files changed, 378 insertions, 270 deletions
diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c
index 30accd46..5ccb1f6c 100644
--- a/applications/ibutton/ibutton.c
+++ b/applications/ibutton/ibutton.c
@@ -5,7 +5,7 @@
#include "m-string.h"
#include <toolbox/path.h>
#include <flipper_format/flipper_format.h>
-#include "rpc/rpc_app.h"
+#include <rpc/rpc_app.h>
#define TAG "iButtonApp"
@@ -58,7 +58,7 @@ static void ibutton_make_app_folder(iButton* ibutton) {
}
}
-static bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) {
+bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) {
FlipperFormat* file = flipper_format_file_alloc(ibutton->storage);
bool result = false;
string_t data;
@@ -99,33 +99,20 @@ static bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show
return result;
}
-static bool ibutton_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) {
+static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context) {
furi_assert(context);
iButton* ibutton = context;
- bool result = false;
-
if(event == RpcAppEventSessionClose) {
- rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
- ibutton->rpc_ctx = NULL;
- view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit);
- result = true;
+ view_dispatcher_send_custom_event(
+ ibutton->view_dispatcher, iButtonCustomEventRpcSessionClose);
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit);
- result = true;
} else if(event == RpcAppEventLoadFile) {
- if(arg) {
- 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;
- }
- }
+ view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcLoad);
+ } else {
+ rpc_system_app_confirm(ibutton->rpc_ctx, event, false);
}
-
- return result;
}
bool ibutton_custom_event_callback(void* context, uint32_t event) {
diff --git a/applications/ibutton/ibutton_custom_event.h b/applications/ibutton/ibutton_custom_event.h
index 25dfc31d..1e2f0300 100644
--- a/applications/ibutton/ibutton_custom_event.h
+++ b/applications/ibutton/ibutton_custom_event.h
@@ -12,4 +12,5 @@ enum iButtonCustomEvent {
iButtonCustomEventRpcLoad,
iButtonCustomEventRpcExit,
+ iButtonCustomEventRpcSessionClose,
};
diff --git a/applications/ibutton/ibutton_i.h b/applications/ibutton/ibutton_i.h
index de3065c3..9d4354d0 100644
--- a/applications/ibutton/ibutton_i.h
+++ b/applications/ibutton/ibutton_i.h
@@ -78,6 +78,7 @@ typedef enum {
} iButtonNotificationMessage;
bool ibutton_file_select(iButton* ibutton);
+bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog);
bool ibutton_save_key(iButton* ibutton, const char* key_name);
bool ibutton_delete_key(iButton* ibutton);
void ibutton_text_store_set(iButton* ibutton, const char* text, ...);
diff --git a/applications/ibutton/scenes/ibutton_scene_rpc.c b/applications/ibutton/scenes/ibutton_scene_rpc.c
index 14f7df63..a3f5eeee 100644
--- a/applications/ibutton/scenes/ibutton_scene_rpc.c
+++ b/applications/ibutton/scenes/ibutton_scene_rpc.c
@@ -1,5 +1,6 @@
#include "../ibutton_i.h"
#include <toolbox/path.h>
+#include <rpc/rpc_app.h>
void ibutton_scene_rpc_on_enter(void* context) {
iButton* ibutton = context;
@@ -26,23 +27,40 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
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);
- }
+ const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx);
+ bool result = false;
+ if(arg) {
+ 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);
+ 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);
+ 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);
+ ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart);
- string_clear(key_name);
+ string_clear(key_name);
+ result = true;
+ }
+ }
+ rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result);
} else if(event.event == iButtonCustomEventRpcExit) {
+ rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventAppExit, true);
+ ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
+ view_dispatcher_stop(ibutton->view_dispatcher);
+ } else if(event.event == iButtonCustomEventRpcSessionClose) {
+ rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
+ ibutton->rpc_ctx = NULL;
ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
view_dispatcher_stop(ibutton->view_dispatcher);
}
diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c
index 4b7a4671..cbbd375d 100644
--- a/applications/infrared/infrared.c
+++ b/applications/infrared/infrared.c
@@ -36,52 +36,29 @@ static void infrared_tick_event_callback(void* context) {
scene_manager_handle_tick_event(infrared->scene_manager);
}
-static bool
- infrared_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) {
+static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context) {
furi_assert(context);
Infrared* infrared = context;
-
- if(!infrared->rpc_ctx) {
- return false;
- }
-
- bool result = false;
+ furi_assert(infrared->rpc_ctx);
if(event == RpcAppEventSessionClose) {
- rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL);
- infrared->rpc_ctx = NULL;
view_dispatcher_send_custom_event(
- infrared->view_dispatcher, InfraredCustomEventTypeBackPressed);
- result = true;
+ infrared->view_dispatcher, InfraredCustomEventTypeRpcSessionClose);
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(
- infrared->view_dispatcher, InfraredCustomEventTypeBackPressed);
- result = true;
+ infrared->view_dispatcher, InfraredCustomEventTypeRpcExit);
} else if(event == RpcAppEventLoadFile) {
- if(arg) {
- string_set_str(infrared->file_path, arg);
- result = infrared_remote_load(infrared->remote, infrared->file_path);
- infrared_worker_tx_set_get_signal_callback(
- 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);
- }
+ view_dispatcher_send_custom_event(
+ infrared->view_dispatcher, InfraredCustomEventTypeRpcLoad);
} else if(event == RpcAppEventButtonPress) {
- if(arg) {
- size_t button_index = 0;
- if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) {
- infrared_tx_start_button_index(infrared, button_index);
- result = true;
- }
- }
+ view_dispatcher_send_custom_event(
+ infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonPress);
} else if(event == RpcAppEventButtonRelease) {
- infrared_tx_stop(infrared);
- result = true;
+ view_dispatcher_send_custom_event(
+ infrared->view_dispatcher, InfraredCustomEventTypeRpcButtonRelease);
+ } else {
+ rpc_system_app_confirm(infrared->rpc_ctx, event, false);
}
-
- return result;
}
static void infrared_find_vacant_remote_name(string_t name, const char* path) {
diff --git a/applications/infrared/infrared_custom_event.h b/applications/infrared/infrared_custom_event.h
index 29bd61f1..09440dde 100644
--- a/applications/infrared/infrared_custom_event.h
+++ b/applications/infrared/infrared_custom_event.h
@@ -14,7 +14,12 @@ enum InfraredCustomEventType {
InfraredCustomEventTypePopupClosed,
InfraredCustomEventTypeButtonSelected,
InfraredCustomEventTypeBackPressed,
- InfraredCustomEventTypeRpcLoaded,
+
+ InfraredCustomEventTypeRpcLoad,
+ InfraredCustomEventTypeRpcExit,
+ InfraredCustomEventTypeRpcButtonPress,
+ InfraredCustomEventTypeRpcButtonRelease,
+ InfraredCustomEventTypeRpcSessionClose,
};
#pragma pack(push, 1)
diff --git a/applications/infrared/scenes/infrared_scene_rpc.c b/applications/infrared/scenes/infrared_scene_rpc.c
index e31e7fb6..1d970f6a 100644
--- a/applications/infrared/scenes/infrared_scene_rpc.c
+++ b/applications/infrared/scenes/infrared_scene_rpc.c
@@ -28,12 +28,45 @@ 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) {
+ } else if(event.event == InfraredCustomEventTypeRpcLoad) {
+ bool result = false;
+ const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
+ if(arg) {
+ string_set_str(infrared->file_path, arg);
+ result = infrared_remote_load(infrared->remote, infrared->file_path);
+ infrared_worker_tx_set_get_signal_callback(
+ infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared);
+ infrared_worker_tx_set_signal_sent_callback(
+ infrared->worker, infrared_signal_sent_callback, infrared);
+ }
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);
+
+ rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventLoadFile, result);
+ } else if(event.event == InfraredCustomEventTypeRpcButtonPress) {
+ bool result = false;
+ const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
+ if(arg) {
+ size_t button_index = 0;
+ if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) {
+ infrared_tx_start_button_index(infrared, button_index);
+ result = true;
+ }
+ }
+ rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result);
+ } else if(event.event == InfraredCustomEventTypeRpcButtonRelease) {
+ infrared_tx_stop(infrared);
+ rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, true);
+ } else if(event.event == InfraredCustomEventTypeRpcExit) {
+ view_dispatcher_stop(infrared->view_dispatcher);
+ rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventAppExit, true);
+ } else if(event.event == InfraredCustomEventTypeRpcSessionClose) {
+ rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL);
+ infrared->rpc_ctx = NULL;
+ view_dispatcher_stop(infrared->view_dispatcher);
}
}
return consumed;
diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp
index 329f052b..29e99b74 100644
--- a/applications/lfrfid/lfrfid_app.cpp
+++ b/applications/lfrfid/lfrfid_app.cpp
@@ -25,7 +25,7 @@
#include <toolbox/path.h>
#include <flipper_format/flipper_format.h>
-#include "rpc/rpc_app.h"
+#include <rpc/rpc_app.h>
const char* LfRfidApp::app_folder = ANY_PATH("lfrfid");
const char* LfRfidApp::app_extension = ".rfid";
@@ -48,38 +48,25 @@ LfRfidApp::~LfRfidApp() {
}
}
-static bool rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) {
+static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) {
furi_assert(context);
LfRfidApp* app = static_cast<LfRfidApp*>(context);
- bool result = false;
-
- if(event == RpcAppEventSessionClose) {
- rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL);
- app->rpc_ctx = NULL;
+ if(rpc_event == RpcAppEventSessionClose) {
LfRfidApp::Event event;
- event.type = LfRfidApp::EventType::Exit;
+ event.type = LfRfidApp::EventType::RpcSessionClose;
app->view_controller.send_event(&event);
- result = true;
- } else if(event == RpcAppEventAppExit) {
+ } else if(rpc_event == RpcAppEventAppExit) {
LfRfidApp::Event event;
event.type = LfRfidApp::EventType::Exit;
app->view_controller.send_event(&event);
- result = true;
- } else if(event == RpcAppEventLoadFile) {
- if(arg) {
- string_set_str(app->file_path, arg);
- if(app->load_key_data(app->file_path, &(app->worker.key), false)) {
- LfRfidApp::Event event;
- event.type = LfRfidApp::EventType::EmulateStart;
- app->view_controller.send_event(&event);
- app->worker.start_emulate();
- result = true;
- }
- }
+ } else if(rpc_event == RpcAppEventLoadFile) {
+ LfRfidApp::Event event;
+ event.type = LfRfidApp::EventType::RpcLoadFile;
+ app->view_controller.send_event(&event);
+ } else {
+ rpc_system_app_confirm(app->rpc_ctx, rpc_event, false);
}
-
- return result;
}
void LfRfidApp::run(void* _args) {
diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h
index 3372552f..b0d4c589 100644
--- a/applications/lfrfid/lfrfid_app.h
+++ b/applications/lfrfid/lfrfid_app.h
@@ -33,6 +33,8 @@ public:
Retry,
Exit,
EmulateStart,
+ RpcLoadFile,
+ RpcSessionClose,
};
enum class SceneType : uint8_t {
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp
index bc070ce6..a32982af 100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp
@@ -1,6 +1,7 @@
#include "lfrfid_app_scene_rpc.h"
#include <core/common_defines.h>
#include <dolphin/dolphin.h>
+#include <rpc/rpc_app.h>
static const NotificationSequence sequence_blink_start_magenta = {
&message_blink_start_10,
@@ -36,6 +37,16 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
LfRfidApp::Event view_event;
view_event.type = LfRfidApp::EventType::Back;
app->view_controller.send_event(&view_event);
+ rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true);
+ } else if(event->type == LfRfidApp::EventType::RpcSessionClose) {
+ // Detach RPC
+ rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL);
+ app->rpc_ctx = NULL;
+
+ consumed = true;
+ LfRfidApp::Event view_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;
@@ -45,7 +56,22 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
popup->set_text(app->text_store.text, 89, 43, AlignCenter, AlignTop);
notification_message(app->notification, &sequence_blink_start_magenta);
+ } else if(event->type == LfRfidApp::EventType::RpcLoadFile) {
+ const char* arg = rpc_system_app_get_data(app->rpc_ctx);
+ bool result = false;
+ if(arg) {
+ string_set_str(app->file_path, arg);
+ if(app->load_key_data(app->file_path, &(app->worker.key), false)) {
+ LfRfidApp::Event event;
+ event.type = LfRfidApp::EventType::EmulateStart;
+ app->view_controller.send_event(&event);
+ app->worker.start_emulate();
+ result = true;
+ }
+ }
+ rpc_system_app_confirm(app->rpc_ctx, RpcAppEventLoadFile, result);
}
+
return consumed;
}
diff --git a/applications/nfc/helpers/nfc_custom_event.h b/applications/nfc/helpers/nfc_custom_event.h
index fbd54b27..4227a5b1 100644
--- a/applications/nfc/helpers/nfc_custom_event.h
+++ b/applications/nfc/helpers/nfc_custom_event.h
@@ -11,4 +11,5 @@ enum NfcCustomEvent {
NfcCustomEventDictAttackDone,
NfcCustomEventDictAttackSkip,
NfcCustomEventRpcLoad,
+ NfcCustomEventRpcSessionClose,
};
diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c
index b19f92f2..32e74e8f 100644
--- a/applications/nfc/nfc.c
+++ b/applications/nfc/nfc.c
@@ -13,78 +13,21 @@ bool nfc_back_event_callback(void* context) {
return scene_manager_handle_back_event(nfc->scene_manager);
}
-void nfc_rpc_exit_callback(Nfc* nfc) {
- if(nfc->rpc_state == NfcRpcStateEmulating) {
- // Stop worker
- nfc_worker_stop(nfc->worker);
- } else if(nfc->rpc_state == NfcRpcStateEmulated) {
- // Stop worker
- nfc_worker_stop(nfc->worker);
- // Save data in shadow file
- nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name);
- }
- 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;
- }
-}
-
-static bool nfc_rpc_emulate_callback(NfcWorkerEvent event, void* context) {
- UNUSED(event);
- Nfc* nfc = context;
-
- nfc->rpc_state = NfcRpcStateEmulated;
- return true;
-}
-
-static bool nfc_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) {
+static void nfc_rpc_command_callback(RpcAppSystemEvent event, void* context) {
furi_assert(context);
Nfc* nfc = context;
- if(!nfc->rpc_ctx) {
- return false;
- }
-
- bool result = false;
+ furi_assert(nfc->rpc_ctx);
if(event == RpcAppEventSessionClose) {
- rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
- nfc->rpc_ctx = NULL;
- view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
- result = true;
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcSessionClose);
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
- result = true;
} else if(event == RpcAppEventLoadFile) {
- if((arg) && (nfc->rpc_state == NfcRpcStateIdle)) {
- if(nfc_device_load(nfc->dev, arg, false)) {
- if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
- nfc_worker_start(
- nfc->worker,
- NfcWorkerStateMfUltralightEmulate,
- &nfc->dev->dev_data,
- nfc_rpc_emulate_callback,
- nfc);
- } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
- nfc_worker_start(
- nfc->worker,
- NfcWorkerStateMfClassicEmulate,
- &nfc->dev->dev_data,
- nfc_rpc_emulate_callback,
- nfc);
- } else {
- nfc_worker_start(
- nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc);
- }
- nfc->rpc_state = NfcRpcStateEmulating;
- view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad);
- result = true;
- }
- }
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad);
+ } else {
+ rpc_system_app_confirm(nfc->rpc_ctx, event, false);
}
-
- return result;
}
Nfc* nfc_alloc() {
@@ -163,6 +106,21 @@ Nfc* nfc_alloc() {
void nfc_free(Nfc* nfc) {
furi_assert(nfc);
+ if(nfc->rpc_state == NfcRpcStateEmulating) {
+ // Stop worker
+ nfc_worker_stop(nfc->worker);
+ } else if(nfc->rpc_state == NfcRpcStateEmulated) {
+ // Stop worker
+ nfc_worker_stop(nfc->worker);
+ // Save data in shadow file
+ nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name);
+ }
+ if(nfc->rpc_ctx) {
+ rpc_system_app_send_exited(nfc->rpc_ctx);
+ rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
+ nfc->rpc_ctx = NULL;
+ }
+
// Nfc device
nfc_device_free(nfc->dev);
diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h
index 84c0e7f0..5a916e80 100755
--- a/applications/nfc/nfc_i.h
+++ b/applications/nfc/nfc_i.h
@@ -102,5 +102,3 @@ void nfc_blink_start(Nfc* nfc);
void nfc_blink_stop(Nfc* nfc);
void nfc_show_loading_popup(void* context, bool show);
-
-void nfc_rpc_exit_callback(Nfc* nfc);
diff --git a/applications/nfc/scenes/nfc_scene_rpc.c b/applications/nfc/scenes/nfc_scene_rpc.c
index 582dff8e..94beccc6 100644
--- a/applications/nfc/scenes/nfc_scene_rpc.c
+++ b/applications/nfc/scenes/nfc_scene_rpc.c
@@ -14,6 +14,14 @@ void nfc_scene_rpc_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_display_backlight_on);
}
+static bool nfc_scene_rpc_emulate_callback(NfcWorkerEvent event, void* context) {
+ UNUSED(event);
+ Nfc* nfc = context;
+
+ nfc->rpc_state = NfcRpcStateEmulated;
+ return true;
+}
+
bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
Popup* popup = nfc->popup;
@@ -22,13 +30,47 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == NfcCustomEventViewExit) {
+ rpc_system_app_confirm(nfc->rpc_ctx, RpcAppEventAppExit, true);
+ view_dispatcher_stop(nfc->view_dispatcher);
+ nfc_blink_stop(nfc);
+ } else if(event.event == NfcCustomEventRpcSessionClose) {
+ rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
+ nfc->rpc_ctx = NULL;
view_dispatcher_stop(nfc->view_dispatcher);
nfc_blink_stop(nfc);
} else if(event.event == NfcCustomEventRpcLoad) {
- nfc_blink_start(nfc);
+ bool result = false;
+ const char* arg = rpc_system_app_get_data(nfc->rpc_ctx);
+ if((arg) && (nfc->rpc_state == NfcRpcStateIdle)) {
+ if(nfc_device_load(nfc->dev, arg, false)) {
+ if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
+ nfc_worker_start(
+ nfc->worker,
+ NfcWorkerStateMfUltralightEmulate,
+ &nfc->dev->dev_data,
+ nfc_scene_rpc_emulate_callback,
+ nfc);
+ } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
+ nfc_worker_start(
+ nfc->worker,
+ NfcWorkerStateMfClassicEmulate,
+ &nfc->dev->dev_data,
+ nfc_scene_rpc_emulate_callback,
+ nfc);
+ } else {
+ nfc_worker_start(
+ nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc);
+ }
+ nfc->rpc_state = NfcRpcStateEmulating;
+ result = true;
+
+ 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);
+ }
+ }
- nfc_text_store_set(nfc, "emulating\n%s", nfc->dev->dev_name);
- popup_set_text(popup, nfc->text_store, 82, 32, AlignCenter, AlignTop);
+ rpc_system_app_confirm(nfc->rpc_ctx, RpcAppEventLoadFile, result);
}
}
return consumed;
@@ -38,7 +80,6 @@ void nfc_scene_rpc_on_exit(void* context) {
Nfc* nfc = context;
Popup* popup = nfc->popup;
- nfc_rpc_exit_callback(nfc);
nfc_blink_stop(nfc);
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
diff --git a/applications/rpc/rpc_app.c b/applications/rpc/rpc_app.c
index e349e61c..555cec8c 100644
--- a/applications/rpc/rpc_app.c
+++ b/applications/rpc/rpc_app.c
@@ -6,24 +6,18 @@
#include "rpc_app.h"
#define TAG "RpcSystemApp"
-#define APP_BUTTON_TIMEOUT 1000
struct RpcAppSystem {
RpcSession* session;
RpcAppSystemCallback app_callback;
void* app_context;
PB_Main* state_msg;
- FuriTimer* timer;
-};
-static void rpc_system_app_timer_callback(void* context) {
- furi_assert(context);
- RpcAppSystem* rpc_app = context;
+ uint32_t last_id;
+ char* last_data;
+};
- if(rpc_app->app_callback) {
- rpc_app->app_callback(RpcAppEventButtonRelease, NULL, rpc_app->app_context);
- }
-}
+#define RPC_SYSTEM_APP_TEMP_ARGS_SIZE 16
static void rpc_system_app_start_process(const PB_Main* request, void* context) {
furi_assert(request);
@@ -33,9 +27,12 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context)
RpcAppSystem* rpc_app = context;
RpcSession* session = rpc_app->session;
furi_assert(session);
- char args_temp[16];
+ char args_temp[RPC_SYSTEM_APP_TEMP_ARGS_SIZE];
+
+ furi_assert(!rpc_app->last_id);
+ furi_assert(!rpc_app->last_data);
- FURI_LOG_D(TAG, "Start");
+ FURI_LOG_D(TAG, "StartProcess: id %d", request->command_id);
PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START;
@@ -43,9 +40,9 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context)
const char* app_name = request->content.app_start_request.name;
if(app_name) {
const char* app_args = request->content.app_start_request.args;
- if(strcmp(app_args, "RPC") == 0) {
+ if(app_args && strcmp(app_args, "RPC") == 0) {
// If app is being started in RPC mode - pass RPC context via args string
- snprintf(args_temp, 16, "RPC %08lX", (uint32_t)rpc_app);
+ snprintf(args_temp, RPC_SYSTEM_APP_TEMP_ARGS_SIZE, "RPC %08lX", (uint32_t)rpc_app);
app_args = args_temp;
}
LoaderStatus status = loader_start(loader, app_name, app_args);
@@ -58,7 +55,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context)
} else if(status == LoaderStatusOk) {
result = PB_CommandStatus_OK;
} else {
- furi_assert(0);
+ furi_crash("Programming Error");
}
} else {
result = PB_CommandStatus_ERROR_INVALID_PARAMETERS;
@@ -66,6 +63,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context)
furi_record_close(RECORD_LOADER);
+ FURI_LOG_D(TAG, "StartProcess: response id %d, result %d", request->command_id, result);
rpc_send_and_release_empty(session, request->command_id, result);
}
@@ -93,6 +91,7 @@ static void rpc_system_app_lock_status_process(const PB_Main* request, void* con
furi_record_close(RECORD_LOADER);
+ FURI_LOG_D(TAG, "LockStatus: response");
rpc_send_and_release(session, &response);
pb_release(&PB_Main_msg, &response);
}
@@ -109,17 +108,17 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) {
PB_CommandStatus status;
if(rpc_app->app_callback) {
- if(rpc_app->app_callback(RpcAppEventAppExit, NULL, rpc_app->app_context)) {
- status = PB_CommandStatus_OK;
- furi_timer_stop(rpc_app->timer);
- } else {
- status = PB_CommandStatus_ERROR_APP_CMD_ERROR;
- }
+ FURI_LOG_D(TAG, "ExitRequest: id %d", request->command_id);
+ furi_assert(!rpc_app->last_id);
+ furi_assert(!rpc_app->last_data);
+ rpc_app->last_id = request->command_id;
+ rpc_app->app_callback(RpcAppEventAppExit, rpc_app->app_context);
} else {
status = PB_CommandStatus_ERROR_APP_NOT_RUNNING;
+ FURI_LOG_E(
+ TAG, "ExitRequest: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status);
+ rpc_send_and_release_empty(session, request->command_id, status);
}
-
- rpc_send_and_release_empty(session, request->command_id, status);
}
static void rpc_system_app_load_file(const PB_Main* request, void* context) {
@@ -133,17 +132,18 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) {
PB_CommandStatus status;
if(rpc_app->app_callback) {
- const char* file_path = request->content.app_load_file_request.path;
- if(rpc_app->app_callback(RpcAppEventLoadFile, file_path, rpc_app->app_context)) {
- status = PB_CommandStatus_OK;
- } else {
- status = PB_CommandStatus_ERROR_APP_CMD_ERROR;
- }
+ FURI_LOG_D(TAG, "LoadFile: id %d", request->command_id);
+ furi_assert(!rpc_app->last_id);
+ furi_assert(!rpc_app->last_data);
+ rpc_app->last_id = request->command_id;
+ rpc_app->last_data = strdup(request->content.app_load_file_request.path);
+ rpc_app->app_callback(RpcAppEventLoadFile, rpc_app->app_context);
} else {
status = PB_CommandStatus_ERROR_APP_NOT_RUNNING;
+ FURI_LOG_E(
+ TAG, "LoadFile: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status);
+ rpc_send_and_release_empty(session, request->command_id, status);
}
-
- rpc_send_and_release_empty(session, request->command_id, status);
}
static void rpc_system_app_button_press(const PB_Main* request, void* context) {
@@ -157,18 +157,18 @@ static void rpc_system_app_button_press(const PB_Main* request, void* context) {
PB_CommandStatus status;
if(rpc_app->app_callback) {
- const char* args = request->content.app_button_press_request.args;
- if(rpc_app->app_callback(RpcAppEventButtonPress, args, rpc_app->app_context)) {
- status = PB_CommandStatus_OK;
- furi_timer_start(rpc_app->timer, APP_BUTTON_TIMEOUT);
- } else {
- status = PB_CommandStatus_ERROR_APP_CMD_ERROR;
- }
+ FURI_LOG_D(TAG, "ButtonPress");
+ furi_assert(!rpc_app->last_id);
+ furi_assert(!rpc_app->last_data);
+ rpc_app->last_id = request->command_id;
+ rpc_app->last_data = strdup(request->content.app_button_press_request.args);
+ rpc_app->app_callback(RpcAppEventButtonPress, rpc_app->app_context);
} else {
status = PB_CommandStatus_ERROR_APP_NOT_RUNNING;
+ FURI_LOG_E(
+ TAG, "ButtonPress: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status);
+ rpc_send_and_release_empty(session, request->command_id, status);
}
-
- rpc_send_and_release_empty(session, request->command_id, status);
}
static void rpc_system_app_button_release(const PB_Main* request, void* context) {
@@ -182,17 +182,17 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context)
PB_CommandStatus status;
if(rpc_app->app_callback) {
- if(rpc_app->app_callback(RpcAppEventButtonRelease, NULL, rpc_app->app_context)) {
- status = PB_CommandStatus_OK;
- furi_timer_stop(rpc_app->timer);
- } else {
- status = PB_CommandStatus_ERROR_APP_CMD_ERROR;
- }
+ FURI_LOG_D(TAG, "ButtonRelease");
+ furi_assert(!rpc_app->last_id);
+ furi_assert(!rpc_app->last_data);
+ rpc_app->last_id = request->command_id;
+ rpc_app->app_callback(RpcAppEventButtonRelease, rpc_app->app_context);
} else {
status = PB_CommandStatus_ERROR_APP_NOT_RUNNING;
+ FURI_LOG_E(
+ TAG, "ButtonRelease: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status);
+ 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) {
@@ -201,6 +201,8 @@ void rpc_system_app_send_started(RpcAppSystem* rpc_app) {
furi_assert(session);
rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_STARTED;
+
+ FURI_LOG_D(TAG, "SendStarted");
rpc_send(session, rpc_app->state_msg);
}
@@ -210,9 +212,46 @@ void rpc_system_app_send_exited(RpcAppSystem* rpc_app) {
furi_assert(session);
rpc_app->state_msg->content.app_state_response.state = PB_App_AppState_APP_CLOSED;
+
+ FURI_LOG_D(TAG, "SendExit");
rpc_send(session, rpc_app->state_msg);
}
+const char* rpc_system_app_get_data(RpcAppSystem* rpc_app) {
+ furi_assert(rpc_app);
+ furi_assert(rpc_app->last_data);
+ return rpc_app->last_data;
+}
+
+void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool result) {
+ furi_assert(rpc_app);
+ RpcSession* session = rpc_app->session;
+ furi_assert(session);
+ furi_assert(rpc_app->last_id);
+
+ PB_CommandStatus status = result ? PB_CommandStatus_OK : PB_CommandStatus_ERROR_APP_CMD_ERROR;
+
+ uint32_t last_id = 0;
+ switch(event) {
+ case RpcAppEventAppExit:
+ case RpcAppEventLoadFile:
+ case RpcAppEventButtonPress:
+ case RpcAppEventButtonRelease:
+ last_id = rpc_app->last_id;
+ rpc_app->last_id = 0;
+ if(rpc_app->last_data) {
+ free(rpc_app->last_data);
+ rpc_app->last_data = NULL;
+ }
+ FURI_LOG_D(TAG, "AppConfirm: event %d last_id %d status %d", event, last_id, status);
+ rpc_send_and_release_empty(session, last_id, status);
+ break;
+ default:
+ furi_crash("RPC App state programming Error");
+ break;
+ }
+}
+
void rpc_system_app_set_callback(RpcAppSystem* rpc_app, RpcAppSystemCallback callback, void* ctx) {
furi_assert(rpc_app);
@@ -226,8 +265,6 @@ void* rpc_system_app_alloc(RpcSession* session) {
RpcAppSystem* rpc_app = malloc(sizeof(RpcAppSystem));
rpc_app->session = 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;
@@ -265,12 +302,16 @@ void rpc_system_app_free(void* context) {
RpcSession* session = rpc_app->session;
furi_assert(session);
- furi_timer_free(rpc_app->timer);
-
if(rpc_app->app_callback) {
- rpc_app->app_callback(RpcAppEventSessionClose, NULL, rpc_app->app_context);
+ rpc_app->app_callback(RpcAppEventSessionClose, rpc_app->app_context);
+ }
+
+ while(rpc_app->app_callback) {
+ furi_delay_tick(1);
}
+ if(rpc_app->last_data) free(rpc_app->last_data);
+
free(rpc_app->state_msg);
free(rpc_app);
}
diff --git a/applications/rpc/rpc_app.h b/applications/rpc/rpc_app.h
index 4e00922f..635c9f8c 100644
--- a/applications/rpc/rpc_app.h
+++ b/applications/rpc/rpc_app.h
@@ -13,7 +13,7 @@ typedef enum {
RpcAppEventButtonRelease,
} RpcAppSystemEvent;
-typedef bool (*RpcAppSystemCallback)(RpcAppSystemEvent event, const char* arg, void* context);
+typedef void (*RpcAppSystemCallback)(RpcAppSystemEvent event, void* context);
typedef struct RpcAppSystem RpcAppSystem;
@@ -23,6 +23,10 @@ void rpc_system_app_send_started(RpcAppSystem* rpc_app);
void rpc_system_app_send_exited(RpcAppSystem* rpc_app);
+const char* rpc_system_app_get_data(RpcAppSystem* rpc_app);
+
+void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool result);
+
#ifdef __cplusplus
}
#endif
diff --git a/applications/subghz/helpers/subghz_custom_event.h b/applications/subghz/helpers/subghz_custom_event.h
index 801a8ae9..765c9e25 100644
--- a/applications/subghz/helpers/subghz_custom_event.h
+++ b/applications/subghz/helpers/subghz_custom_event.h
@@ -47,6 +47,9 @@ typedef enum {
SubGhzCustomEventSceneStay,
SubGhzCustomEventSceneRpcLoad,
+ SubGhzCustomEventSceneRpcButtonPress,
+ SubGhzCustomEventSceneRpcButtonRelease,
+ SubGhzCustomEventSceneRpcSessionClose,
SubGhzCustomEventViewReceiverOK,
SubGhzCustomEventViewReceiverConfig,
diff --git a/applications/subghz/scenes/subghz_scene_rpc.c b/applications/subghz/scenes/subghz_scene_rpc.c
index 844f5c16..c6f7df26 100644
--- a/applications/subghz/scenes/subghz_scene_rpc.c
+++ b/applications/subghz/scenes/subghz_scene_rpc.c
@@ -22,20 +22,60 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == SubGhzCustomEventSceneExit) {
+ if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
+ subghz_tx_stop(subghz);
+ subghz_sleep(subghz);
+ }
view_dispatcher_stop(subghz->view_dispatcher);
+ rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventAppExit, true);
+ } else if(event.event == SubGhzCustomEventSceneRpcSessionClose) {
+ rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL);
+ subghz->rpc_ctx = NULL;
+ subghz_blink_stop(subghz);
+ if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
+ subghz_tx_stop(subghz);
+ subghz_sleep(subghz);
+ }
+ view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit);
+ } else if(event.event == SubGhzCustomEventSceneRpcButtonPress) {
+ bool result = false;
+ if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) {
+ subghz_blink_start(subghz);
+ result = subghz_tx_start(subghz, subghz->txrx->fff_data);
+ result = true;
+ }
+ rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonPress, result);
+ } else if(event.event == SubGhzCustomEventSceneRpcButtonRelease) {
+ bool result = false;
+ if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
+ subghz_blink_stop(subghz);
+ subghz_tx_stop(subghz);
+ subghz_sleep(subghz);
+ result = true;
+ }
+ rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventButtonRelease, result);
} 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);
+ bool result = false;
+ const char* arg = rpc_system_app_get_data(subghz->rpc_ctx);
+ if(arg) {
+ if(subghz_key_load(subghz, arg, false)) {
+ string_set_str(subghz->file_path, arg);
+ result = true;
+ 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);
+ }
+ }
+ rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventLoadFile, result);
}
}
return consumed;
diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c
index a970e10c..4631d7a3 100644
--- a/applications/subghz/subghz.c
+++ b/applications/subghz/subghz.c
@@ -35,57 +35,38 @@ void subghz_tick_event_callback(void* context) {
scene_manager_handle_tick_event(subghz->scene_manager);
}
-static bool subghz_rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context) {
+static void subghz_rpc_command_callback(RpcAppSystemEvent event, void* context) {
furi_assert(context);
SubGhz* subghz = context;
- if(!subghz->rpc_ctx) {
- return false;
- }
-
- bool result = false;
+ furi_assert(subghz->rpc_ctx);
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);
- subghz_sleep(subghz);
- }
- result = true;
+ view_dispatcher_send_custom_event(
+ subghz->view_dispatcher, SubGhzCustomEventSceneRpcSessionClose);
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit);
- if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
- subghz_tx_stop(subghz);
- subghz_sleep(subghz);
- }
- result = true;
} else if(event == RpcAppEventLoadFile) {
- 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;
- }
- }
+ view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneRpcLoad);
} 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);
- }
+ view_dispatcher_send_custom_event(
+ subghz->view_dispatcher, SubGhzCustomEventSceneRpcButtonPress);
} 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;
- }
+ view_dispatcher_send_custom_event(
+ subghz->view_dispatcher, SubGhzCustomEventSceneRpcButtonRelease);
+ } else {
+ rpc_system_app_confirm(subghz->rpc_ctx, event, false);
}
+}
+
+void subghz_blink_start(SubGhz* instance) {
+ furi_assert(instance);
+ notification_message(instance->notifications, &sequence_blink_start_magenta);
+}
- return result;
+void subghz_blink_stop(SubGhz* instance) {
+ furi_assert(instance);
+ notification_message(instance->notifications, &sequence_blink_stop);
}
SubGhz* subghz_alloc() {
@@ -237,7 +218,7 @@ 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_blink_stop(subghz);
subghz->rpc_ctx = NULL;
}
diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h
index 01fbe57b..99a0f8a2 100644
--- a/applications/subghz/subghz_i.h
+++ b/applications/subghz/subghz_i.h
@@ -108,6 +108,10 @@ void subghz_begin(SubGhz* subghz, uint8_t* preset_data);
uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency);
void subghz_rx_end(SubGhz* subghz);
void subghz_sleep(SubGhz* subghz);
+
+void subghz_blink_start(SubGhz* instance);
+void subghz_blink_stop(SubGhz* instance);
+
bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);
void subghz_tx_stop(SubGhz* subghz);
void subghz_dialog_message_show_only_rx(SubGhz* subghz);