[FL-1619] NFC long APDU emulation (#623)
* nfc: add apdu sequence exchange debug scene * api-hal-gpio: fix GPIO initialization * nfc: pull down nfc chip IRQ pin Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
15592682ad
commit
841804026e
@ -364,7 +364,7 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
while(nfc_worker->state == NfcWorkerStateEmulateEMV) {
|
while(nfc_worker->state == NfcWorkerStateEmulateEMV) {
|
||||||
if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) {
|
if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 300)) {
|
||||||
FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected");
|
FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected");
|
||||||
// Read data from POS terminal
|
// Read data from POS terminal
|
||||||
err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
|
err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
|
||||||
|
@ -25,3 +25,4 @@ ADD_SCENE(nfc, delete_success, DeleteSuccess)
|
|||||||
ADD_SCENE(nfc, run_emv_app_confirm, RunEmvAppConfirm)
|
ADD_SCENE(nfc, run_emv_app_confirm, RunEmvAppConfirm)
|
||||||
ADD_SCENE(nfc, read_emv_data, ReadEmvData)
|
ADD_SCENE(nfc, read_emv_data, ReadEmvData)
|
||||||
ADD_SCENE(nfc, read_emv_data_success, ReadEmvDataSuccess)
|
ADD_SCENE(nfc, read_emv_data_success, ReadEmvDataSuccess)
|
||||||
|
ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence)
|
||||||
|
38
applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c
Normal file
38
applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "../nfc_i.h"
|
||||||
|
|
||||||
|
const void nfc_scene_emulate_apdu_sequence_on_enter(void* context) {
|
||||||
|
Nfc* nfc = (Nfc*)context;
|
||||||
|
|
||||||
|
// Setup view
|
||||||
|
Popup* popup = nfc->popup;
|
||||||
|
|
||||||
|
popup_set_header(popup, "Run APDU reader", 64, 31, AlignCenter, AlignTop);
|
||||||
|
|
||||||
|
// Setup and start worker
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
|
||||||
|
nfc_worker_start(nfc->worker, NfcWorkerStateEmulateEMV, &nfc->dev.dev_data, NULL, nfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
Nfc* nfc = (Nfc*)context;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeTick) {
|
||||||
|
notification_message(nfc->notifications, &sequence_blink_blue_10);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void nfc_scene_emulate_apdu_sequence_on_exit(void* context) {
|
||||||
|
Nfc* nfc = (Nfc*)context;
|
||||||
|
|
||||||
|
// Stop worker
|
||||||
|
nfc_worker_stop(nfc->worker);
|
||||||
|
|
||||||
|
// Clear view
|
||||||
|
Popup* popup = nfc->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);
|
||||||
|
}
|
@ -5,6 +5,7 @@ enum SubmenuIndex {
|
|||||||
SubmenuIndexRunScript,
|
SubmenuIndexRunScript,
|
||||||
SubmenuIndexSaved,
|
SubmenuIndexSaved,
|
||||||
SubmenuIndexAddManualy,
|
SubmenuIndexAddManualy,
|
||||||
|
SubmenuIndexDebug,
|
||||||
};
|
};
|
||||||
|
|
||||||
void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
|
void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||||
@ -29,6 +30,7 @@ const void nfc_scene_start_on_enter(void* context) {
|
|||||||
submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
|
submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc);
|
submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc);
|
||||||
|
submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc);
|
||||||
submenu_set_selected_item(
|
submenu_set_selected_item(
|
||||||
submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart));
|
submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart));
|
||||||
|
|
||||||
@ -38,29 +40,34 @@ const void nfc_scene_start_on_enter(void* context) {
|
|||||||
|
|
||||||
const bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
|
const bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||||
Nfc* nfc = (Nfc*)context;
|
Nfc* nfc = (Nfc*)context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubmenuIndexRead) {
|
if(event.event == SubmenuIndexRead) {
|
||||||
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexRead);
|
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexRead);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCard);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCard);
|
||||||
return true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexRunScript) {
|
} else if(event.event == SubmenuIndexRunScript) {
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
nfc->scene_manager, NfcSceneStart, SubmenuIndexRunScript);
|
nfc->scene_manager, NfcSceneStart, SubmenuIndexRunScript);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneScriptsMenu);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneScriptsMenu);
|
||||||
return true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexSaved) {
|
} else if(event.event == SubmenuIndexSaved) {
|
||||||
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexSaved);
|
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexSaved);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneFileSelect);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneFileSelect);
|
||||||
return true;
|
consumed = true;
|
||||||
} else if(event.event == SubmenuIndexAddManualy) {
|
} else if(event.event == SubmenuIndexAddManualy) {
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
nfc->scene_manager, NfcSceneStart, SubmenuIndexAddManualy);
|
nfc->scene_manager, NfcSceneStart, SubmenuIndexAddManualy);
|
||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType);
|
||||||
return true;
|
consumed = true;
|
||||||
|
} else if(event.event == SubmenuIndexDebug) {
|
||||||
|
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexDebug);
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateApduSequence);
|
||||||
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void nfc_scene_start_on_exit(void* context) {
|
const void nfc_scene_start_on_exit(void* context) {
|
||||||
|
@ -54,7 +54,7 @@ void hal_gpio_init(
|
|||||||
furi_assert(mode != GpioModeAltFunctionPushPull);
|
furi_assert(mode != GpioModeAltFunctionPushPull);
|
||||||
furi_assert(mode != GpioModeAltFunctionOpenDrain);
|
furi_assert(mode != GpioModeAltFunctionOpenDrain);
|
||||||
|
|
||||||
hal_gpio_init_ex(gpio, mode, GpioPullNo, GpioSpeedLow, GpioAltFnUnused);
|
hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_gpio_init_ex(
|
void hal_gpio_init_ex(
|
||||||
|
@ -88,12 +88,13 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t tim
|
|||||||
|
|
||||||
bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) {
|
bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) {
|
||||||
rfalNfcState state = rfalNfcGetState();
|
rfalNfcState state = rfalNfcGetState();
|
||||||
|
|
||||||
if(state == RFAL_NFC_STATE_NOTINIT) {
|
if(state == RFAL_NFC_STATE_NOTINIT) {
|
||||||
rfalNfcInitialize();
|
rfalNfcInitialize();
|
||||||
} else if(state >= RFAL_NFC_STATE_ACTIVATED) {
|
} else if(state >= RFAL_NFC_STATE_ACTIVATED) {
|
||||||
rfalNfcDeactivate(false);
|
rfalNfcDeactivate(false);
|
||||||
}
|
}
|
||||||
|
rfalLowPowerModeStop();
|
||||||
rfalNfcDiscoverParam params = {
|
rfalNfcDiscoverParam params = {
|
||||||
.compMode = RFAL_COMPLIANCE_MODE_NFC,
|
.compMode = RFAL_COMPLIANCE_MODE_NFC,
|
||||||
.techs2Find = RFAL_NFC_LISTEN_TECH_A,
|
.techs2Find = RFAL_NFC_LISTEN_TECH_A,
|
||||||
|
@ -27,7 +27,7 @@ void platformIrqWorker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void platformEnableIrqCallback() {
|
void platformEnableIrqCallback() {
|
||||||
hal_gpio_init(&pin, GpioModeInterruptRise, GpioPullNo, GpioSpeedLow);
|
hal_gpio_init(&pin, GpioModeInterruptRise, GpioPullDown, GpioSpeedLow);
|
||||||
hal_gpio_enable_int_callback(&pin);
|
hal_gpio_enable_int_callback(&pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user