From fe216b4ddd77256874572d66133f83248f2c9f0c Mon Sep 17 00:00:00 2001 From: g3gg0 Date: Wed, 9 Nov 2022 22:59:09 +0100 Subject: [PATCH] implemented unlock, read, save sequence --- .../main/nfc/scenes/nfc_scene_nfcv_unlock.c | 63 +++++++++++++++++-- firmware/targets/f7/api_symbols.csv | 4 +- lib/nfc/nfc_worker.c | 28 ++++++--- lib/nfc/nfc_worker.h | 1 + lib/nfc/protocols/nfcv.c | 8 ++- lib/nfc/protocols/nfcv.h | 2 +- lib/nfc/protocols/slix_l.c | 11 ++-- lib/nfc/protocols/slix_l.h | 2 +- 8 files changed, 98 insertions(+), 21 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c index 9e31e9743..4b15c777c 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c @@ -9,7 +9,7 @@ typedef enum { NfcSceneNfcVUnlockStateNotSupportedCard, } NfcSceneNfcVUnlockState; -bool nfc_scene_nfcv_unlock_worker_callback(NfcWorkerEvent event, void* context) { +static bool nfc_scene_nfcv_unlock_worker_callback(NfcWorkerEvent event, void* context) { Nfc* nfc = context; if(event == NfcWorkerEventNfcVPassKey) { @@ -19,6 +19,45 @@ bool nfc_scene_nfcv_unlock_worker_callback(NfcWorkerEvent event, void* context) } return true; } +/* +static void nfc_scene_nfcv_unlock_button_callback(GuiButtonType event, InputType type, void* context) { + furi_assert(context); + furi_assert(type); + Nfc* nfc = context; + + if(event == GuiButtonTypeCenter) { + if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) { + nfc_worker_stop(nfc->worker); + nfc_worker_start( + nfc->worker, + NfcWorkerStateNfcVUnlock, + &nfc->dev->dev_data, + nfc_scene_nfcv_unlock_worker_callback, + nfc); + widget_add_button_element( + nfc->widget, + GuiButtonTypeCenter, + "Autosave", + nfc_scene_nfcv_unlock_button_callback, + nfc); + } else { + nfc_worker_stop(nfc->worker); + nfc_worker_start( + nfc->worker, + NfcWorkerStateNfcVUnlockAndSave, + &nfc->dev->dev_data, + nfc_scene_nfcv_unlock_worker_callback, + nfc); + widget_add_button_element( + nfc->widget, + GuiButtonTypeCenter, + "Unlock", + nfc_scene_nfcv_unlock_button_callback, + nfc); + } + notification_message(nfc->notifications, &sequence_single_vibro); + } +}*/ void nfc_scene_nfcv_unlock_popup_callback(void* context) { Nfc* nfc = context; @@ -26,6 +65,7 @@ void nfc_scene_nfcv_unlock_popup_callback(void* context) { } void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { + FuriHalNfcDevData* nfc_data = &(nfc->dev->dev_data.nfc_data); NfcVData* nfcv_data = &(nfc->dev->dev_data.nfcv_data); uint32_t curr_state = @@ -40,14 +80,28 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { } else if(state == NfcSceneNfcVUnlockStateUnlocked) { popup_reset(popup); + if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) { + nfc_text_store_set(nfc, "SLIX-L_%02X%02X%02X%02X%02X%02X%02X%02X", + nfc_data->uid[7], nfc_data->uid[6], nfc_data->uid[5], nfc_data->uid[4], + nfc_data->uid[3], nfc_data->uid[2], nfc_data->uid[1], nfc_data->uid[0]); + + nfc->dev->format = NfcDeviceSaveFormatSlixL; + + if(nfc_device_save(nfc->dev, nfc->text_store)) { + popup_set_header(popup, "Successfully\nsaved", 94, 3, AlignCenter, AlignTop); + } else { + popup_set_header(popup, "Unlocked but\nsave failed!", 94, 3, AlignCenter, AlignTop); + } + } else { + popup_set_header(popup, "Successfully\nunlocked", 94, 3, AlignCenter, AlignTop); + } + notification_message(nfc->notifications, &sequence_success); - popup_set_header(popup, "Successfully\nUnlocked!", 94, 3, AlignCenter, AlignTop); popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_nfcv_unlock_popup_callback); popup_set_timeout(popup, 1500); - //popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); @@ -85,10 +139,11 @@ void nfc_scene_nfcv_unlock_on_enter(void* context) { // Setup view nfc_scene_nfcv_unlock_set_state(nfc, NfcSceneNfcVUnlockStateDetecting); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + // Start worker nfc_worker_start( nfc->worker, - NfcWorkerStateNfcVUnlock, + NfcWorkerStateNfcVUnlockAndSave, &nfc->dev->dev_data, nfc_scene_nfcv_unlock_worker_callback, nfc); diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index c4d451ec5..306e2e559 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,7.4,, +Version,+,7.5,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1960,7 +1960,7 @@ Function,-,nfca_signal_encode,void,"NfcaSignal*, uint8_t*, uint16_t, uint8_t*" Function,-,nfca_signal_free,void,NfcaSignal* Function,-,nfcv_inventory,ReturnCode,uint8_t* Function,-,nfcv_read_blocks,ReturnCode,"NfcVReader*, NfcVData*" -Function,-,nfcv_read_sysinfo,ReturnCode,NfcVData* +Function,-,nfcv_read_sysinfo,ReturnCode,"FuriHalNfcDevData*, NfcVData*" Function,+,notification_internal_message,void,"NotificationApp*, const NotificationSequence*" Function,+,notification_internal_message_block,void,"NotificationApp*, const NotificationSequence*" Function,+,notification_message,void,"NotificationApp*, const NotificationSequence*" diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 76b21762d..a36ee4da3 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -111,6 +111,8 @@ int32_t nfc_worker_task(void* context) { nfc_worker_analyze_reader(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateNfcVUnlock) { nfc_worker_nfcv_unlock(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateNfcVUnlockAndSave) { + nfc_worker_nfcv_unlock(nfc_worker); } furi_hal_nfc_sleep(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); @@ -133,7 +135,8 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { furi_hal_nfc_sleep(); - while(nfc_worker->state == NfcWorkerStateNfcVUnlock) { + while((nfc_worker->state == NfcWorkerStateNfcVUnlock) || + (nfc_worker->state == NfcWorkerStateNfcVUnlockAndSave)) { furi_hal_nfc_exit_sleep(); furi_hal_nfc_ll_txrx_on(); @@ -195,12 +198,26 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { } if(ret == ERR_NONE) { /* unlock succesful */ - furi_hal_console_printf(" => success, wait for chip to disappear.\r\n"); - nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + if(nfc_worker->state == NfcWorkerStateNfcVUnlockAndSave) { + NfcVReader reader; + + if(!slix_l_read_card(&reader, &nfc_worker->dev_data->nfc_data, nfcv_data)) { + furi_hal_console_printf(" => failed, wait for chip to disappear.\r\n"); + snprintf(nfcv_data->error, sizeof(nfcv_data->error), "Read card\nfailed"); + nfc_worker->callback(NfcWorkerEventWrongCardDetected, nfc_worker->context); + } else { + furi_hal_console_printf(" => success, wait for chip to disappear.\r\n"); + nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + } + } else { + furi_hal_console_printf(" => success, wait for chip to disappear.\r\n"); + nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); + } while(slix_l_get_random(NULL) == ERR_NONE) { furi_delay_ms(100); } + } else { /* unlock failed */ furi_hal_console_printf(" => failed, wait for chip to disappear.\r\n"); @@ -235,7 +252,6 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { static bool nfc_worker_read_slix_l(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { bool read_success = false; NfcVReader reader = {}; - NfcVData data = {}; if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); @@ -244,9 +260,7 @@ static bool nfc_worker_read_slix_l(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* do { if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 200)) break; - if(!slix_l_read_card(&reader, &data)) break; - // Copy data - nfc_worker->dev_data->nfcv_data = data; + if(!slix_l_read_card(&reader, &nfc_worker->dev_data->nfc_data, &nfc_worker->dev_data->nfcv_data)) break; read_success = true; } while(false); diff --git a/lib/nfc/nfc_worker.h b/lib/nfc/nfc_worker.h index 8801ca025..2910cb240 100644 --- a/lib/nfc/nfc_worker.h +++ b/lib/nfc/nfc_worker.h @@ -20,6 +20,7 @@ typedef enum { NfcWorkerStateMfClassicDictAttack, NfcWorkerStateAnalyzeReader, NfcWorkerStateNfcVUnlock, + NfcWorkerStateNfcVUnlockAndSave, // Debug NfcWorkerStateEmulateApdu, NfcWorkerStateField, diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index 814d2e08a..b8933d438 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -54,7 +54,7 @@ ReturnCode nfcv_read_blocks( return ERR_NONE; } -ReturnCode nfcv_read_sysinfo(NfcVData* data) { +ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) { uint8_t rxBuf[32]; uint16_t received = 0; @@ -65,6 +65,12 @@ ReturnCode nfcv_read_sysinfo(NfcVData* data) { rxBuf, sizeof(rxBuf), &received); if(ret == ERR_NONE) { + nfc_data->type = FuriHalNfcTypeV; + nfc_data->uid_len = 8; + /* UID is stored reversed in this structure */ + for(int pos = 0; pos < nfc_data->uid_len; pos++) { + nfc_data->uid[pos] = rxBuf[2 + (7 - pos)]; + } data->dsfid = rxBuf[10]; data->afi = rxBuf[11]; data->block_num = rxBuf[12] + 1; diff --git a/lib/nfc/protocols/nfcv.h b/lib/nfc/protocols/nfcv.h index 5fd349963..024dea42e 100644 --- a/lib/nfc/protocols/nfcv.h +++ b/lib/nfc/protocols/nfcv.h @@ -49,6 +49,6 @@ typedef struct { } NfcVReader; ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* data); -ReturnCode nfcv_read_sysinfo(NfcVData* data); +ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data); ReturnCode nfcv_inventory(uint8_t* uid); diff --git a/lib/nfc/protocols/slix_l.c b/lib/nfc/protocols/slix_l.c index 0ce92d338..b7d1bd174 100644 --- a/lib/nfc/protocols/slix_l.c +++ b/lib/nfc/protocols/slix_l.c @@ -16,16 +16,17 @@ bool slix_l_check_card_type(uint8_t UID0, uint8_t UID1, uint8_t UID2) { bool slix_l_read_card( NfcVReader* reader, - NfcVData* data) { + FuriHalNfcDevData* nfc_data, + NfcVData* nfcv_data) { furi_assert(reader); - furi_assert(data); + furi_assert(nfcv_data); - if(nfcv_read_sysinfo(data) != ERR_NONE) { + if(nfcv_read_sysinfo(nfc_data, nfcv_data) != ERR_NONE) { return false; } - reader->blocks_to_read = data->block_num; - return (nfcv_read_blocks(reader, data) == ERR_NONE); + reader->blocks_to_read = nfcv_data->block_num; + return (nfcv_read_blocks(reader, nfcv_data) == ERR_NONE); } ReturnCode slix_l_get_random(uint8_t* rand) { diff --git a/lib/nfc/protocols/slix_l.h b/lib/nfc/protocols/slix_l.h index 94d51c74a..c40ced942 100644 --- a/lib/nfc/protocols/slix_l.h +++ b/lib/nfc/protocols/slix_l.h @@ -11,7 +11,7 @@ bool slix_l_check_card_type(uint8_t UID0, uint8_t UID1, uint8_t UID2); -bool slix_l_read_card(NfcVReader* reader, NfcVData* data); +bool slix_l_read_card(NfcVReader* reader, FuriHalNfcDevData* nfc_data, NfcVData* data); ReturnCode slix_l_get_random(uint8_t* rand); ReturnCode slix_l_unlock(uint32_t id, uint8_t* rand, uint32_t password);