Skip to content

Commit

Permalink
Implement RPC mode for NFC app (flipperdevices#3096)
Browse files Browse the repository at this point in the history
Co-authored-by: gornekich <[email protected]>
  • Loading branch information
2 people authored and RebornedBrain committed Sep 21, 2023
1 parent 8e02c9f commit 664248a
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 45 deletions.
1 change: 1 addition & 0 deletions applications/main/nfc/helpers/nfc_custom_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef enum {
NfcCustomEventDictAttackDone,

NfcCustomEventRpcLoad,
NfcCustomEventRpcExit,
NfcCustomEventRpcSessionClose,

NfcCustomEventPollerSuccess,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ static bool
return consumed;
}

static void nfc_protocol_support_scene_emulate_on_exit(NfcApp* instance) {
static void nfc_protocol_support_scene_emulate_stop_listener(NfcApp* instance) {
nfc_listener_stop(instance->listener);

const NfcProtocol protocol = nfc_device_get_protocol(instance->nfc_device);
Expand All @@ -519,6 +519,10 @@ static void nfc_protocol_support_scene_emulate_on_exit(NfcApp* instance) {
}

nfc_listener_free(instance->listener);
}

static void nfc_protocol_support_scene_emulate_on_exit(NfcApp* instance) {
nfc_protocol_support_scene_emulate_stop_listener(instance);

// Clear view
widget_reset(instance->widget);
Expand All @@ -528,6 +532,65 @@ static void nfc_protocol_support_scene_emulate_on_exit(NfcApp* instance) {
nfc_blink_stop(instance);
}

static void nfc_protocol_support_scene_rpc_on_enter(NfcApp* instance) {
UNUSED(instance);
}

static void nfc_protocol_support_scene_rpc_setup_ui_and_emulate(NfcApp* instance) {
nfc_text_store_set(instance, "emulating\n%s", furi_string_get_cstr(instance->file_name));

popup_set_header(instance->popup, "NFC", 89, 42, AlignCenter, AlignBottom);
popup_set_text(instance->popup, instance->text_store, 89, 44, AlignCenter, AlignTop);
popup_set_icon(instance->popup, 0, 12, &I_RFIDDolphinSend_97x61);

view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);

notification_message(instance->notifications, &sequence_display_backlight_on);
nfc_blink_emulate_start(instance);

const NfcProtocol protocol = nfc_device_get_protocol(instance->nfc_device);
nfc_protocol_support[protocol]->scene_emulate.on_enter(instance);

instance->rpc_state = NfcRpcStateEmulating;
}

static bool nfc_protocol_support_scene_rpc_on_event(NfcApp* instance, SceneManagerEvent event) {
bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventRpcLoad && instance->rpc_state == NfcRpcStateIdle) {
furi_string_set(instance->file_path, rpc_system_app_get_data(instance->rpc_ctx));
const bool load_success = nfc_load_file(instance, instance->file_path, false);
if(load_success) {
nfc_protocol_support_scene_rpc_setup_ui_and_emulate(instance);
}
rpc_system_app_confirm(instance->rpc_ctx, RpcAppEventLoadFile, load_success);
} else if(event.event == NfcCustomEventRpcExit) {
rpc_system_app_confirm(instance->rpc_ctx, RpcAppEventAppExit, true);
scene_manager_stop(instance->scene_manager);
view_dispatcher_stop(instance->view_dispatcher);
} else if(event.event == NfcCustomEventRpcSessionClose) {
scene_manager_stop(instance->scene_manager);
view_dispatcher_stop(instance->view_dispatcher);
}
consumed = true;
}

return consumed;
}

static void nfc_protocol_support_scene_rpc_on_exit(NfcApp* instance) {
if(instance->rpc_state == NfcRpcStateEmulating) {
nfc_protocol_support_scene_emulate_stop_listener(instance);
}

popup_reset(instance->popup);
text_box_reset(instance->text_box);
furi_string_reset(instance->text_box_store);

nfc_blink_stop(instance);
}

static const NfcProtocolSupportCommonSceneBase
nfc_protocol_support_scenes[NfcProtocolSupportSceneCount] = {
[NfcProtocolSupportSceneInfo] =
Expand Down Expand Up @@ -572,4 +635,10 @@ static const NfcProtocolSupportCommonSceneBase
.on_event = nfc_protocol_support_scene_emulate_on_event,
.on_exit = nfc_protocol_support_scene_emulate_on_exit,
},
[NfcProtocolSupportSceneRpc] =
{
.on_enter = nfc_protocol_support_scene_rpc_on_enter,
.on_event = nfc_protocol_support_scene_rpc_on_event,
.on_exit = nfc_protocol_support_scene_rpc_on_exit,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ typedef enum {
NfcProtocolSupportSceneSavedMenu,
NfcProtocolSupportSceneEmulate,
NfcProtocolSupportSceneCardDump,
NfcProtocolSupportSceneRpc,

NfcProtocolSupportSceneCount,
} NfcProtocolSupportScene;
76 changes: 34 additions & 42 deletions applications/main/nfc/nfc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ bool nfc_back_event_callback(void* context) {
return scene_manager_handle_back_event(nfc->scene_manager);
}

// static void nfc_rpc_command_callback(RpcAppSystemEvent event, void* context) {
// furi_assert(context);
// NfcApp* nfc = context;

// furi_assert(nfc->rpc_ctx);

// if(event == RpcAppEventSessionClose) {
// view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcSessionClose);
// rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
// nfc->rpc_ctx = NULL;
// } else if(event == RpcAppEventAppExit) {
// view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
// } else if(event == RpcAppEventLoadFile) {
// view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad);
// } else {
// rpc_system_app_confirm(nfc->rpc_ctx, event, false);
// }
// }
static void nfc_app_rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) {
furi_assert(context);
NfcApp* nfc = (NfcApp*)context;

furi_assert(nfc->rpc_ctx);

if(rpc_event == RpcAppEventSessionClose) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcSessionClose);
rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
nfc->rpc_ctx = NULL;
} else if(rpc_event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcExit);
} else if(rpc_event == RpcAppEventLoadFile) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcLoad);
} else {
rpc_system_app_confirm(nfc->rpc_ctx, rpc_event, false);
}
}

NfcApp* nfc_app_alloc() {
NfcApp* instance = malloc(sizeof(NfcApp));
Expand Down Expand Up @@ -130,21 +130,9 @@ NfcApp* nfc_app_alloc() {
void nfc_app_free(NfcApp* instance) {
furi_assert(instance);

// if(instance->rpc_state == NfcRpcStateEmulating) {
// // Stop worker
// nfc_worker_stop(instance->worker);
// } else if(instance->rpc_state == NfcRpcStateEmulated) {
// // Stop worker
// nfc_worker_stop(instance->worker);
// // Save data in shadow file
// if(furi_string_size(instance->dev->load_path)) {
// nfc_device_save_shadow(instance->dev, furi_string_get_cstr(instance->dev->load_path));
// }
// }
if(instance->rpc_ctx) {
rpc_system_app_send_exited(instance->rpc_ctx);
rpc_system_app_set_callback(instance->rpc_ctx, NULL, NULL);
instance->rpc_ctx = NULL;
}

nfc_free(instance->nfc);
Expand Down Expand Up @@ -476,24 +464,28 @@ static bool nfc_is_hal_ready() {
}

int32_t nfc_app(void* p) {
UNUSED(p);
if(!nfc_is_hal_ready()) return 0;

NfcApp* nfc = nfc_app_alloc();
char* args = p;
// const char* args = "/ext/nfc/4.nfc";
const char* args = p;

// Check argument and run corresponding scene
if(args && strlen(args)) {
nfc_device_set_loading_callback(nfc->nfc_device, nfc_show_loading_popup, nfc);
view_dispatcher_attach_to_gui(
nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
if(nfc_device_load(nfc->nfc_device, args)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulate);

if(sscanf(args, "RPC %p", &nfc->rpc_ctx) == 1) {
rpc_system_app_set_callback(nfc->rpc_ctx, nfc_app_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 {
// Exit app
view_dispatcher_stop(nfc->view_dispatcher);
view_dispatcher_attach_to_gui(
nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);

furi_string_set(nfc->file_path, args);
if(nfc_load_file(nfc, nfc->file_path, false)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulate);
} else {
view_dispatcher_stop(nfc->view_dispatcher);
}
}
} else {
view_dispatcher_attach_to_gui(
Expand Down
3 changes: 1 addition & 2 deletions applications/main/nfc/nfc_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
typedef enum {
NfcRpcStateIdle,
NfcRpcStateEmulating,
NfcRpcStateEmulated,
} NfcRpcState;

typedef struct {
Expand Down Expand Up @@ -105,7 +104,7 @@ struct NfcApp {
NfcProtocol protocols_detected[NfcProtocolNum];
uint32_t protocols_detected_selected_idx;

void* rpc_ctx;
RpcAppSystem* rpc_ctx;
NfcRpcState rpc_state;

// Common Views
Expand Down
1 change: 1 addition & 0 deletions applications/main/nfc/scenes/nfc_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ADD_SCENE(nfc, extra_actions, ExtraActions)
ADD_SCENE(nfc, read_success, ReadSuccess)
ADD_SCENE(nfc, read_menu, ReadMenu)
ADD_SCENE(nfc, emulate, Emulate)
ADD_SCENE(nfc, rpc, Rpc)
ADD_SCENE(nfc, debug, Debug)
ADD_SCENE(nfc, field, Field)
ADD_SCENE(nfc, retry_confirm, RetryConfirm)
Expand Down
13 changes: 13 additions & 0 deletions applications/main/nfc/scenes/nfc_scene_rpc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "../helpers/protocol_support/nfc_protocol_support.h"

void nfc_scene_rpc_on_enter(void* context) {
nfc_protocol_support_on_enter(NfcProtocolSupportSceneRpc, context);
}

bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
return nfc_protocol_support_on_event(NfcProtocolSupportSceneRpc, context, event);
}

void nfc_scene_rpc_on_exit(void* context) {
nfc_protocol_support_on_exit(NfcProtocolSupportSceneRpc, context);
}

0 comments on commit 664248a

Please sign in to comment.