Skip to content

Commit

Permalink
Generic listener part 1 (#2820)
Browse files Browse the repository at this point in the history
* nfc device data: add get base data api

* nfc listener: rework generic listener

* nfc: rework iso14443_3a emulation

* nfc: complete iso14443a emulation

* nfc: rework mf ultralight emulation

* nfc: clean up code

* nfc: rename poller -> instance in generic event

* nfc listener: add assert for supported protocols

* nfc: fix typos, code clean up
  • Loading branch information
gornekich committed Jun 30, 2023
1 parent 399c77b commit 673465c
Show file tree
Hide file tree
Showing 56 changed files with 498 additions and 512 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static const NfcPollerReadHandler nfc_poller_handlers_read[] = {
};
NfcCustomEvent nfc_poller_handler_read(NfcGenericEvent event, void* context) {
furi_assert(context);
furi_assert(event.poller);
furi_assert(event.instance);
furi_assert(event.data);
furi_assert(event.protocol < COUNT_OF(nfc_poller_handlers_read));

Expand Down
7 changes: 1 addition & 6 deletions applications/main/nfc/nfc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,10 @@ NfcApp* nfc_app_alloc() {
instance->view_dispatcher, nfc_back_event_callback);

instance->nfc = nfc_alloc();
instance->iso14443_3a_listener = iso14443_3a_listener_alloc(instance->nfc);
instance->mf_ul_listener = mf_ultralight_listener_alloc(instance->iso14443_3a_listener);
instance->scanner = nfc_scanner_alloc(instance->nfc);

instance->parsed_data = furi_string_alloc();

instance->scanner = nfc_scanner_alloc(instance->nfc);

instance->mf_ul_auth = mf_ultralight_auth_alloc();

// Nfc device
Expand Down Expand Up @@ -153,8 +150,6 @@ void nfc_app_free(NfcApp* instance) {

furi_string_free(instance->parsed_data);

mf_ultralight_listener_free(instance->mf_ul_listener);
iso14443_3a_listener_free(instance->iso14443_3a_listener);
nfc_free(instance->nfc);
nfc_scanner_free(instance->scanner);

Expand Down
5 changes: 2 additions & 3 deletions applications/main/nfc/nfc_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#include <nfc/nfc_poller.h>
#include <nfc/nfc_scanner.h>
#include <nfc/nfc_listener.h>

#include <lib/nfc/nfc_device.h>
#include <lib/nfc/helpers/nfc_data_generator.h>
Expand Down Expand Up @@ -108,11 +109,9 @@ struct NfcApp {
DetectReader* detect_reader;

Nfc* nfc;
Iso14443_3aListener* iso14443_3a_listener;
MfUltralightListener* mf_ul_listener;

NfcPoller* poller;
NfcScanner* scanner;
NfcListener* listener;

MfUltralightAuth* mf_ul_auth;
NfcMfClassicDictAttackContext mf_dict_context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ typedef enum {
NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context) {
furi_assert(context);
furi_assert(event.data);
furi_assert(event.poller);
furi_assert(event.instance);
furi_assert(event.protocol == NfcProtocolMfClassic);

NfcCommand command = NfcCommandContinue;
Expand Down
28 changes: 10 additions & 18 deletions applications/main/nfc/scenes/nfc_scene_mf_ultralight_capture_pass.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#include "../nfc_app_i.h"

MfUltralightListenerCommand nfc_scene_mf_ultralight_capture_pass_worker_callback(
MfUltralightListenerEvent event,
void* context) {
NfcApp* nfc = context;
// MfUltralightListenerCommand nfc_scene_mf_ultralight_capture_pass_worker_callback(
// MfUltralightListenerEvent event,
// void* context) {
// NfcApp* nfc = context;

if(event.type == MfUltralightListenerEventTypeAuth) {
nfc->mf_ul_auth->password = event.data->password;
view_dispatcher_send_custom_event(nfc->view_dispatcher, MfUltralightListenerEventTypeAuth);
}
// if(event.type == MfUltralightListenerEventTypeAuth) {
// nfc->mf_ul_auth->password = event.data->password;
// view_dispatcher_send_custom_event(nfc->view_dispatcher, MfUltralightListenerEventTypeAuth);
// }

return MfUltralightListenerCommandContinue;
}
// return MfUltralightListenerCommandContinue;
// }

void nfc_scene_mf_ultralight_capture_pass_on_enter(void* context) {
NfcApp* nfc = context;
Expand All @@ -30,12 +30,6 @@ void nfc_scene_mf_ultralight_capture_pass_on_enter(void* context) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);

// Start worker
// FIXME: Make it compile
// mf_ultralight_listener_start(
// nfc->mf_ul_listener,
// nfc->nfc_dev_data.mf_ul_data,
// nfc_scene_mf_ultralight_capture_pass_worker_callback,
// nfc);

nfc_blink_read_start(nfc);
}
Expand All @@ -57,8 +51,6 @@ bool nfc_scene_mf_ultralight_capture_pass_on_event(void* context, SceneManagerEv
void nfc_scene_mf_ultralight_capture_pass_on_exit(void* context) {
NfcApp* nfc = context;

// Stop worker
mf_ultralight_listener_stop(nfc->mf_ul_listener);
// Clear view
widget_reset(nfc->widget);

Expand Down
13 changes: 8 additions & 5 deletions applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) {

// Setup and start worker
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
mf_ultralight_listener_start(nfc->mf_ul_listener, data, NULL, NULL);
nfc->listener = nfc_listener_alloc(nfc->nfc, NfcProtocolMfUltralight, data);
nfc_listener_start(nfc->listener, NULL, NULL);

nfc_blink_emulate_start(nfc);
}

bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent event) {
NfcApp* nfc = context;
UNUSED(nfc);
bool consumed = false;

if(event.type == SceneManagerEventTypeBack) {
MfUltralightData* mfu_data_after_emulation = mf_ultralight_alloc();
mf_ultralight_listener_get_data(nfc->mf_ul_listener, mfu_data_after_emulation);
mf_ultralight_listener_stop(nfc->mf_ul_listener);
// MfUltralightData* mfu_data_after_emulation = nfc_listener_get_data(nfc->listener, NfcProtocolMfUltralight);
// Check if data changed and save in shadow file
// FIXME: A comparison method?
// if(memcmp(
Expand All @@ -47,7 +47,7 @@ bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent e
// nfc_save_shadow_file(nfc);
// }
// }
mf_ultralight_free(mfu_data_after_emulation);
// mf_ultralight_free(mfu_data_after_emulation);
consumed = false;
}
return consumed;
Expand All @@ -56,6 +56,9 @@ bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent e
void nfc_scene_mf_ultralight_emulate_on_exit(void* context) {
NfcApp* nfc = context;

nfc_listener_stop(nfc->listener);
nfc_listener_free(nfc->listener);

// Clear view
popup_reset(nfc->popup);

Expand Down
28 changes: 16 additions & 12 deletions applications/main/nfc/scenes/nfc_scene_nfca_emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,27 @@ enum {
NfcSceneNfcaEmulateStateTextBox,
};

Iso14443_3aListenerCommand
nfc_scene_nfca_emulate_worker_callback(Iso14443_3aListenerEvent event, void* context) {
NfcCommand nfc_scene_nfca_emulate_worker_callback(NfcGenericEvent event, void* context) {
furi_assert(context);
furi_assert(event.protocol == NfcProtocolIso14443_3a);
furi_assert(event.data);

NfcApp* nfc = context;
if(event.type == Iso14443_3aListenerEventTypeReceivedStandartFrame) {
Iso14443_3aListenerEvent* iso14443_3a_event = event.data;

if(iso14443_3a_event->type == Iso14443_3aListenerEventTypeReceivedStandardFrame) {
furi_string_cat_printf(nfc->text_box_store, "R:");
for(size_t i = 0; i < bit_buffer_get_size_bytes(event.data.buffer); i++) {
for(size_t i = 0; i < bit_buffer_get_size_bytes(iso14443_3a_event->data->buffer); i++) {
furi_string_cat_printf(
nfc->text_box_store, " %02X", bit_buffer_get_byte(event.data.buffer, i));
nfc->text_box_store,
" %02X",
bit_buffer_get_byte(iso14443_3a_event->data->buffer, i));
}
furi_string_cat_printf(nfc->text_box_store, "\n");
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerUpdate);
}

return Iso14443_3aListenerCommandContinue;
return NfcCommandContinue;
}

void nfc_scene_nfca_emulate_widget_callback(GuiButtonType result, InputType type, void* context) {
Expand Down Expand Up @@ -73,11 +78,9 @@ void nfc_scene_nfca_emulate_on_enter(void* context) {
text_box_set_focus(text_box, TextBoxFocusEnd);
furi_string_reset(nfc->text_box_store);

iso14443_3a_listener_start(
nfc->iso14443_3a_listener,
nfc_device_get_data(nfc->nfc_device, NfcProtocolIso14443_3a),
nfc_scene_nfca_emulate_worker_callback,
nfc);
const NfcDeviceData* data = nfc_device_get_data(nfc->nfc_device, NfcProtocolIso14443_3a);
nfc->listener = nfc_listener_alloc(nfc->nfc, NfcProtocolIso14443_3a, data);
nfc_listener_start(nfc->listener, nfc_scene_nfca_emulate_worker_callback, nfc);

// Set Widget state and view
scene_manager_set_scene_state(
Expand Down Expand Up @@ -127,7 +130,8 @@ bool nfc_scene_nfca_emulate_on_event(void* context, SceneManagerEvent event) {
void nfc_scene_nfca_emulate_on_exit(void* context) {
NfcApp* nfc = context;

iso14443_3a_listener_stop(nfc->iso14443_3a_listener);
nfc_listener_stop(nfc->listener);
nfc_listener_free(nfc->listener);

// Clear view
widget_reset(nfc->widget);
Expand Down
4 changes: 0 additions & 4 deletions applications/main/nfc_rpc/nfc_rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ static NfcRpc* nfc_rpc_app_alloc() {
NfcRpc* instance = malloc(sizeof(NfcRpc));

instance->nfc = nfc_alloc();
instance->iso14443_3a_listener = iso14443_3a_listener_alloc(instance->nfc);
instance->mf_ul_listener = mf_ultralight_listener_alloc(instance->iso14443_3a_listener);

NfcRpcHandlerDict_init(instance->handlers);
for(size_t i = 0; i < COUNT_OF(nfc_rpc_callbacks); i++) {
Expand Down Expand Up @@ -171,8 +169,6 @@ static NfcRpc* nfc_rpc_app_alloc() {
void nfc_rpc_app_free(NfcRpc* instance) {
furi_assert(instance);

mf_ultralight_listener_free(instance->mf_ul_listener);
iso14443_3a_listener_free(instance->iso14443_3a_listener);
nfc_free(instance->nfc);

for(size_t i = 0; i < COUNT_OF(nfc_rpc_callbacks); i++) {
Expand Down
5 changes: 3 additions & 2 deletions applications/main/nfc_rpc/nfc_rpc_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <lib/nfc/protocols/iso14443_3a/iso14443_3a_listener.h>
#include <lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.h>

#include <nfc/nfc_listener.h>

typedef void (*NfcRpcHandler)(Nfc_Main* cmd, void* context);

DICT_DEF2(NfcRpcHandlerDict, pb_size_t, M_DEFAULT_OPLIST, NfcRpcHandler, M_POD_OPLIST)
Expand Down Expand Up @@ -54,8 +56,7 @@ struct NfcRpc {
NfcRpcHandlerDict_t handlers;

Nfc* nfc;
Iso14443_3aListener* iso14443_3a_listener;
MfUltralightListener* mf_ul_listener;
NfcListener* listener;
};

typedef struct {
Expand Down
18 changes: 11 additions & 7 deletions applications/main/nfc_rpc/nfc_rpc_mf_ultralight.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ static void init_mf_ul_data(MfUltralightData* data) {
iso14443_3a_data->sak = 0x00;

data->type = MfUltralightTypeUnknown;
data->pages_total = 16;
MfUltralightVersion version = {
.header = 1,
.protocol_type = 228,
Expand All @@ -208,11 +209,13 @@ void nfc_rpc_mf_ultralight_emulate_start(Nfc_Main* cmd, void* context) {
PB_MfUltralight_EmulateStartResponse_init_default;
cmd->command_status = Nfc_CommandStatus_OK;
cmd->which_content = Nfc_Main_mf_ultralight_emulate_start_resp_tag;
if(instance->mf_ul_listener == NULL) {
MfUltralightData mf_ul_data = {};
if(instance->listener == NULL) {
MfUltralightData* mf_ul_data = mf_ultralight_alloc();
// TODO initialize data from rpc message
init_mf_ul_data(&mf_ul_data);
mf_ultralight_listener_start(instance->mf_ul_listener, &mf_ul_data, NULL, NULL);
init_mf_ul_data(mf_ul_data);
instance->listener =
nfc_listener_alloc(instance->nfc, NfcProtocolMfUltralight, mf_ul_data);
nfc_listener_start(instance->listener, NULL, NULL);
pb_mf_ultralight_emulate_start_resp.error = PB_MfUltralight_Error_None;
} else {
// TODO add Busy error
Expand All @@ -230,10 +233,11 @@ void nfc_rpc_mf_ultralight_emulate_stop(Nfc_Main* cmd, void* context) {
PB_MfUltralight_EmulateStopResponse_init_default;
cmd->command_status = Nfc_CommandStatus_OK;
cmd->which_content = Nfc_Main_mf_ultralight_emulate_stop_resp_tag;
if(instance->mf_ul_listener) {
if(instance->listener) {
// Stop before free
mf_ultralight_listener_stop(instance->mf_ul_listener);
instance->mf_ul_listener = NULL;
nfc_listener_stop(instance->listener);
nfc_listener_free(instance->listener);
instance->listener = NULL;
pb_mf_ultralight_emulate_stop_resp.error = PB_MfUltralight_Error_None;
} else {
// TODO emulation not started error
Expand Down
13 changes: 8 additions & 5 deletions applications/main/nfc_rpc/nfc_rpc_nfca.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static void nfc_rpc_nfca_emulate_start(Nfc_Main* cmd, void* context) {
PB_Nfca_EmulateStartResponse_init_default;
cmd->command_status = Nfc_CommandStatus_OK;
cmd->which_content = Nfc_Main_nfca_emulate_start_resp_tag;
if(instance->iso14443_3a_listener == NULL) {
if(instance->listener == NULL) {
Iso14443_3aData iso14443_3a_data = {};
iso14443_3a_data.uid_len = cmd->content.nfca_emulate_start_req.uid_len;
memcpy(
Expand All @@ -85,7 +85,9 @@ static void nfc_rpc_nfca_emulate_start(Nfc_Main* cmd, void* context) {
memcpy(iso14443_3a_data.atqa, cmd->content.nfca_emulate_start_req.atqa.bytes, 2);
memcpy(&iso14443_3a_data.sak, cmd->content.nfca_emulate_start_req.sak.bytes, 1);

iso14443_3a_listener_start(instance->iso14443_3a_listener, &iso14443_3a_data, NULL, NULL);
instance->listener =
nfc_listener_alloc(instance->nfc, NfcProtocolIso14443_3a, &iso14443_3a_data);
nfc_listener_start(instance->listener, NULL, NULL);
pb_nfca_emulate_start_resp.error = PB_Nfca_Error_None;
} else {
// TODO add Busy error
Expand All @@ -103,9 +105,10 @@ static void nfc_rpc_nfca_emulate_stop(Nfc_Main* cmd, void* context) {
PB_Nfca_EmulateStopResponse_init_default;
cmd->command_status = Nfc_CommandStatus_OK;
cmd->which_content = Nfc_Main_nfca_emulate_stop_resp_tag;
if(instance->iso14443_3a_listener) {
iso14443_3a_listener_stop(instance->iso14443_3a_listener);
instance->iso14443_3a_listener = NULL;
if(instance->listener) {
nfc_listener_stop(instance->listener);
nfc_listener_free(instance->listener);
instance->listener = NULL;
pb_nfca_emulate_stop_resp.error = PB_Nfca_Error_None;
} else {
// TODO add Busy error
Expand Down
4 changes: 3 additions & 1 deletion firmware/targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,36.2,,
Version,+,36.6,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -1815,6 +1815,7 @@ Function,-,iso14443_3a_append_crc,void,BitBuffer*
Function,-,iso14443_3a_check_crc,_Bool,const BitBuffer*
Function,-,iso14443_3a_copy,void,"Iso14443_3aData*, const Iso14443_3aData*"
Function,-,iso14443_3a_free,void,Iso14443_3aData*
Function,-,iso14443_3a_get_base_data,const Iso14443_3aData*,const Iso14443_3aData*
Function,-,iso14443_3a_get_cuid,uint32_t,Iso14443_3aData*
Function,-,iso14443_3a_get_device_name,const char*,"const Iso14443_3aData*, NfcDeviceNameType"
Function,-,iso14443_3a_get_uid,const uint8_t*,"const Iso14443_3aData*, size_t*"
Expand Down Expand Up @@ -2006,6 +2007,7 @@ Function,+,mf_classic_alloc,MfClassicData*,
Function,+,mf_classic_copy,void,"MfClassicData*, const MfClassicData*"
Function,-,mf_classic_detect_protocol,_Bool,"Iso14443_3aData*, MfClassicType*"
Function,+,mf_classic_free,void,MfClassicData*
Function,-,mf_classic_get_base_data,const Iso14443_3aData*,const MfClassicData*
Function,-,mf_classic_get_blocks_num_in_sector,uint8_t,uint8_t
Function,-,mf_classic_get_device_name,const char*,"const MfClassicData*, NfcDeviceNameType"
Function,-,mf_classic_get_first_block_num_of_sector,uint8_t,uint8_t
Expand Down
4 changes: 3 additions & 1 deletion lib/nfc/helpers/bit_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ const uint8_t* bit_buffer_get_data(const BitBuffer* buf) {

void bit_buffer_set_byte(BitBuffer* buf, size_t index, uint8_t byte) {
furi_assert(buf);
furi_assert(buf->size_bits / BITS_IN_BYTE > index);

size_t size_byted = bit_buffer_get_size_bytes(buf);
furi_assert(size_byted > index);

buf->data[index] = byte;
}
Expand Down
10 changes: 3 additions & 7 deletions lib/nfc/nfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,7 @@ static int32_t nfc_worker_listener(void* context) {

Nfc* instance = context;
furi_assert(instance->callback);

f_hal_nfc_low_power_mode_stop();

NfcEvent nfc_event = {.type = NfcEventTypeConfigureRequest};
instance->callback(nfc_event, instance->context);
furi_assert(instance->config_state == NfcConfigurationStateDone);

f_hal_nfc_listen_start();
instance->state = NfcStateListenStarted;
Expand All @@ -93,6 +89,7 @@ static int32_t nfc_worker_listener(void* context) {

NfcEventData event_data = {};
event_data.buffer = bit_buffer_alloc(NFC_MAX_BUFFER_SIZE);
NfcEvent nfc_event = {.data = event_data};

while(true) {
FHalNfcEvent event = f_hal_nfc_wait_event(F_HAL_NFC_EVENT_WAIT_FOREVER);
Expand Down Expand Up @@ -126,8 +123,6 @@ static int32_t nfc_worker_listener(void* context) {
}
}

nfc_event.type = NfcEventTypeReset;
instance->callback(nfc_event, instance->context);
nfc_config(instance, NfcModeIdle);
bit_buffer_free(event_data.buffer);
f_hal_nfc_low_power_mode_start();
Expand Down Expand Up @@ -252,6 +247,7 @@ void nfc_config(Nfc* instance, NfcMode mode) {
f_hal_nfc_set_mode(FHalNfcModeIso14443_3aPoller, FHalNfcBitrate106);
instance->config_state = NfcConfigurationStateDone;
} else if(mode == NfcModeIso14443_3aListener) {
f_hal_nfc_low_power_mode_stop();
f_hal_nfc_set_mode(FHalNfcModeIso14443_3aListener, FHalNfcBitrate106);
instance->config_state = NfcConfigurationStateDone;
}
Expand Down
Loading

0 comments on commit 673465c

Please sign in to comment.