Merge branch 'fz-dev' into dev

This commit is contained in:
MX 2022-10-12 04:37:59 +03:00
commit aa9f958f07
No known key found for this signature in database
GPG Key ID: 6C4C311DFD4B4AB5
16 changed files with 124 additions and 104 deletions

View File

@ -1,6 +1,7 @@
#include "../gpio_app_i.h"
#include "furi_hal_power.h"
#include "furi_hal_usb.h"
#include <dolphin/dolphin.h>
enum GpioItem {
GpioItemUsbUart,
@ -88,6 +89,7 @@ bool gpio_scene_start_on_event(void* context, SceneManagerEvent event) {
} else if(event.event == GpioStartEventUsbUart) {
scene_manager_set_scene_state(app->scene_manager, GpioSceneStart, GpioItemUsbUart);
if(!furi_hal_usb_is_locked()) {
DOLPHIN_DEED(DolphinDeedGpioUartBridge);
scene_manager_next_scene(app->scene_manager, GpioSceneUsbUart);
} else {
scene_manager_next_scene(app->scene_manager, GpioSceneUsbUartCloseRpc);

View File

@ -70,7 +70,7 @@ bool infrared_scene_universal_common_on_event(void* context, SceneManagerEvent e
uint32_t record_count;
if(infrared_brute_force_start(
brute_force, infrared_custom_event_get_value(event.event), &record_count)) {
DOLPHIN_DEED(DolphinDeedIrBruteForce);
DOLPHIN_DEED(DolphinDeedIrSend);
infrared_scene_universal_common_show_popup(infrared, record_count);
} else {
scene_manager_next_scene(scene_manager, InfraredSceneErrorDatabases);

View File

@ -26,7 +26,7 @@ void nfc_scene_detect_reader_callback(void* context) {
void nfc_scene_detect_reader_on_enter(void* context) {
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcEmulate);
DOLPHIN_DEED(DolphinDeedNfcDetectReader);
detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc);
detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX);

View File

@ -1,7 +1,6 @@
#include "../nfc_i.h"
enum SubmenuIndex {
SubmenuIndexSave,
SubmenuIndexInfo,
};
@ -15,7 +14,6 @@ void nfc_scene_emv_menu_on_enter(void* context) {
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(submenu, "Save", SubmenuIndexSave, nfc_scene_emv_menu_submenu_callback, nfc);
submenu_add_item(submenu, "Info", SubmenuIndexInfo, nfc_scene_emv_menu_submenu_callback, nfc);
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmvMenu));
@ -28,13 +26,7 @@ bool nfc_scene_emv_menu_on_event(void* context, SceneManagerEvent event) {
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexSave) {
nfc->dev->format = NfcDeviceSaveFormatBankCard;
// Clear device name
nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
consumed = true;
} else if(event.event == SubmenuIndexInfo) {
if(event.event == SubmenuIndexInfo) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
consumed = true;
}

View File

@ -24,12 +24,33 @@ void nfc_scene_emv_read_success_on_enter(void* context) {
nfc->widget, GuiButtonTypeRight, "More", nfc_scene_emv_read_success_widget_callback, nfc);
FuriString* temp_str;
temp_str = furi_string_alloc_printf("\e#%s\n", emv_data->name);
for(uint8_t i = 0; i < emv_data->number_len; i += 2) {
furi_string_cat_printf(
temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]);
if(emv_data->name[0] != '\0') {
temp_str = furi_string_alloc_printf("\e#%s\n", emv_data->name);
} else {
temp_str = furi_string_alloc_printf("\e#Unknown Bank Card\n");
}
if(emv_data->number_len) {
for(uint8_t i = 0; i < emv_data->number_len; i += 2) {
furi_string_cat_printf(
temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]);
}
furi_string_trim(temp_str);
} else if(emv_data->aid_len) {
furi_string_cat_printf(temp_str, "Can't parse data from app\n");
// Parse AID name
FuriString* aid_name;
aid_name = furi_string_alloc();
if(nfc_emv_parser_get_aid_name(
nfc->dev->storage, emv_data->aid, emv_data->aid_len, aid_name)) {
furi_string_cat_printf(temp_str, "AID: %s", furi_string_get_cstr(aid_name));
} else {
furi_string_cat_printf(temp_str, "AID: ");
for(uint8_t i = 0; i < emv_data->aid_len; i++) {
furi_string_cat_printf(temp_str, "%02X", emv_data->aid[i]);
}
}
furi_string_free(aid_name);
}
furi_string_trim(temp_str);
// Add expiration date
if(emv_data->exp_mon) {

View File

@ -1,4 +1,5 @@
#include "../nfc_i.h"
#include <dolphin/dolphin.h>
enum SubmenuIndex {
SubmenuIndexSave,
@ -35,6 +36,8 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event)
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexSave) {
DOLPHIN_DEED(DolphinDeedNfcMfcAdd);
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexSave);
nfc->dev->format = NfcDeviceSaveFormatMifareClassic;

View File

@ -14,7 +14,6 @@ void nfc_scene_mf_ultralight_read_auth_result_widget_callback(
void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
// Setup dialog view
FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
@ -38,6 +37,7 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
widget_add_string_element(
widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
if(mf_ul_data->auth_success) {
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
furi_string_printf(
temp_str,
"Password: %02X %02X %02X %02X",
@ -54,6 +54,8 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) {
config_pages->auth_data.pack.raw[1]);
widget_add_string_element(
widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str));
} else {
DOLPHIN_DEED(DolphinDeedNfcMfulError);
}
furi_string_printf(
temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4);

View File

@ -30,7 +30,7 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventByteInputDone) {
DOLPHIN_DEED(DolphinDeedNfcAdd);
DOLPHIN_DEED(DolphinDeedNfcAddSave);
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) {
nfc->dev->dev_data.nfc_data = nfc->dev_edit_data;
if(nfc_device_save(nfc->dev, nfc->dev->dev_name)) {

View File

@ -1,6 +1,7 @@
#include "bt_hid.h"
#include <furi_hal_bt.h>
#include <notification/notification_messages.h>
#include <dolphin/dolphin.h>
#define TAG "BtHidApp"
@ -185,6 +186,8 @@ int32_t bt_hid_app(void* p) {
}
furi_hal_bt_start_advertising();
DOLPHIN_DEED(DolphinDeedPluginStart);
view_dispatcher_run(app->view_dispatcher);
bt_set_status_changed_callback(app->bt, NULL, NULL);

View File

@ -2,6 +2,7 @@
#include <gui/gui.h>
#include <input/input.h>
#include <stdlib.h>
#include <dolphin/dolphin.h>
#include <notification/notification.h>
#include <notification/notification_messages.h>
@ -347,6 +348,8 @@ int32_t snake_game_app(void* p) {
notification_message_block(notification, &sequence_display_backlight_enforce_on);
DOLPHIN_DEED(DolphinDeedPluginGameStart);
SnakeEvent event;
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);

View File

@ -18,13 +18,15 @@ static const DolphinDeedWeight dolphin_deed_weights[] = {
{1, DolphinAppNfc}, // DolphinDeedNfcRead
{3, DolphinAppNfc}, // DolphinDeedNfcReadSuccess
{3, DolphinAppNfc}, // DolphinDeedNfcSave
{1, DolphinAppNfc}, // DolphinDeedNfcDetectReader
{2, DolphinAppNfc}, // DolphinDeedNfcEmulate
{2, DolphinAppNfc}, // DolphinDeedNfcAdd
{2, DolphinAppNfc}, // DolphinDeedNfcMfcAdd
{1, DolphinAppNfc}, // DolphinDeedNfcMfulError
{1, DolphinAppNfc}, // DolphinDeedNfcAddSave
{1, DolphinAppIr}, // DolphinDeedIrSend
{3, DolphinAppIr}, // DolphinDeedIrLearnSuccess
{3, DolphinAppIr}, // DolphinDeedIrSave
{2, DolphinAppIr}, // DolphinDeedIrBruteForce
{1, DolphinAppIbutton}, // DolphinDeedIbuttonRead
{3, DolphinAppIbutton}, // DolphinDeedIbuttonReadSuccess
@ -34,16 +36,24 @@ static const DolphinDeedWeight dolphin_deed_weights[] = {
{3, DolphinAppBadusb}, // DolphinDeedBadUsbPlayScript
{3, DolphinAppU2f}, // DolphinDeedU2fAuthorized
{1, DolphinAppGpio}, // DolphinDeedGpioUartBridge
{1, DolphinAppPlugin}, // DolphinDeedPluginStart
{1, DolphinAppPlugin}, // DolphinDeedPluginGameStart
{10, DolphinAppPlugin}, // DolphinDeedPluginGameWin
};
static uint8_t dolphin_deed_limits[] = {
15, // DolphinAppSubGhz
15, // DolphinAppRfid
15, // DolphinAppNfc
15, // DolphinAppIr
15, // DolphinAppIbutton
15, // DolphinAppBadusb
15, // DolphinAppU2f
20, // DolphinAppSubGhz
20, // DolphinAppRfid
20, // DolphinAppNfc
20, // DolphinAppIr
20, // DolphinAppIbutton
20, // DolphinAppBadusb
20, // DolphinAppU2f
20, // DolphinAppGpio
20, // DolphinAppPlugin
};
_Static_assert(COUNT_OF(dolphin_deed_weights) == DolphinDeedMAX, "dolphin_deed_weights size error");

View File

@ -14,6 +14,8 @@ typedef enum {
DolphinAppIbutton,
DolphinAppBadusb,
DolphinAppU2f,
DolphinAppGpio,
DolphinAppPlugin,
DolphinAppMAX,
} DolphinApp;
@ -34,13 +36,15 @@ typedef enum {
DolphinDeedNfcRead,
DolphinDeedNfcReadSuccess,
DolphinDeedNfcSave,
DolphinDeedNfcDetectReader,
DolphinDeedNfcEmulate,
DolphinDeedNfcAdd,
DolphinDeedNfcMfcAdd,
DolphinDeedNfcMfulError,
DolphinDeedNfcAddSave,
DolphinDeedIrSend,
DolphinDeedIrLearnSuccess,
DolphinDeedIrSave,
DolphinDeedIrBruteForce,
DolphinDeedIbuttonRead,
DolphinDeedIbuttonReadSuccess,
@ -52,6 +56,12 @@ typedef enum {
DolphinDeedU2fAuthorized,
DolphinDeedGpioUartBridge,
DolphinDeedPluginStart,
DolphinDeedPluginGameStart,
DolphinDeedPluginGameWin,
DolphinDeedMAX,
DolphinDeedTestLeft,

View File

@ -636,35 +636,7 @@ bool nfc_device_load_mifare_df_data(FlipperFormat* file, NfcDevice* dev) {
return parsed;
}
static bool nfc_device_save_bank_card_data(FlipperFormat* file, NfcDevice* dev) {
bool saved = false;
EmvData* data = &dev->dev_data.emv_data;
uint32_t data_temp = 0;
do {
// Write Bank card specific data
if(!flipper_format_write_comment_cstr(file, "Bank card specific data")) break;
if(!flipper_format_write_hex(file, "AID", data->aid, data->aid_len)) break;
if(!flipper_format_write_string_cstr(file, "Name", data->name)) break;
if(!flipper_format_write_hex(file, "Number", data->number, data->number_len)) break;
if(data->exp_mon) {
uint8_t exp_data[2] = {data->exp_mon, data->exp_year};
if(!flipper_format_write_hex(file, "Exp data", exp_data, sizeof(exp_data))) break;
}
if(data->country_code) {
data_temp = data->country_code;
if(!flipper_format_write_uint32(file, "Country code", &data_temp, 1)) break;
}
if(data->currency_code) {
data_temp = data->currency_code;
if(!flipper_format_write_uint32(file, "Currency code", &data_temp, 1)) break;
}
saved = true;
} while(false);
return saved;
}
// Leave for backward compatibility
bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) {
bool parsed = false;
EmvData* data = &dev->dev_data.emv_data;
@ -1068,7 +1040,7 @@ static bool nfc_device_save_file(
if(!flipper_format_write_header_cstr(file, nfc_file_header, nfc_file_version)) break;
// Write nfc device type
if(!flipper_format_write_comment_cstr(
file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic, Bank card"))
file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic"))
break;
nfc_device_prepare_format_string(dev, temp_str);
if(!flipper_format_write_string(file, "Device type", temp_str)) break;
@ -1083,8 +1055,6 @@ static bool nfc_device_save_file(
if(!nfc_device_save_mifare_ul_data(file, dev)) break;
} else if(dev->format == NfcDeviceSaveFormatMifareDesfire) {
if(!nfc_device_save_mifare_df_data(file, dev)) break;
} else if(dev->format == NfcDeviceSaveFormatBankCard) {
if(!nfc_device_save_bank_card_data(file, dev)) break;
} else if(dev->format == NfcDeviceSaveFormatMifareClassic) {
// Save data
if(!nfc_device_save_mifare_classic_data(file, dev)) break;

View File

@ -233,31 +233,51 @@ static bool nfc_worker_read_bank_card(NfcWorker* nfc_worker, FuriHalNfcTxRxConte
reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
}
do {
// Read card
// Bank cards require strong field to start application. If we find AID, try at least several
// times to start EMV application
uint8_t start_application_attempts = 0;
while(start_application_attempts < 3) {
if(nfc_worker->state != NfcWorkerStateRead) break;
start_application_attempts++;
if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break;
if(!emv_read_bank_card(tx_rx, &emv_app)) break;
// Copy data
// TODO Set EmvData to reader or like in mifare ultralight!
result->number_len = emv_app.card_number_len;
memcpy(result->number, emv_app.card_number, result->number_len);
if(emv_read_bank_card(tx_rx, &emv_app)) {
FURI_LOG_D(TAG, "Bank card number read from %d attempt", start_application_attempts);
break;
} else if(emv_app.aid_len && !emv_app.app_started) {
FURI_LOG_D(
TAG,
"AID found but failed to start EMV app from %d attempt",
start_application_attempts);
furi_hal_nfc_sleep();
continue;
} else {
FURI_LOG_D(TAG, "Failed to find AID");
break;
}
}
// Copy data
if(emv_app.aid_len) {
result->aid_len = emv_app.aid_len;
memcpy(result->aid, emv_app.aid, result->aid_len);
if(emv_app.name_found) {
memcpy(result->name, emv_app.name, sizeof(emv_app.name));
}
if(emv_app.exp_month) {
result->exp_mon = emv_app.exp_month;
result->exp_year = emv_app.exp_year;
}
if(emv_app.country_code) {
result->country_code = emv_app.country_code;
}
if(emv_app.currency_code) {
result->currency_code = emv_app.currency_code;
}
read_success = true;
} while(false);
}
if(emv_app.card_number_len) {
result->number_len = emv_app.card_number_len;
memcpy(result->number, emv_app.card_number, result->number_len);
}
if(emv_app.name_found) {
memcpy(result->name, emv_app.name, sizeof(emv_app.name));
}
if(emv_app.exp_month) {
result->exp_mon = emv_app.exp_month;
result->exp_year = emv_app.exp_year;
}
if(emv_app.country_code) {
result->country_code = emv_app.country_code;
}
if(emv_app.currency_code) {
result->currency_code = emv_app.currency_code;
}
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_stop(nfc_worker->reader_analyzer);

View File

@ -182,7 +182,7 @@ static bool emv_decode_response(uint8_t* buff, uint16_t len, EmvApplication* app
return success;
}
bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
static bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
bool app_aid_found = false;
const uint8_t emv_select_ppse_cmd[] = {
0x00, 0xA4, // SELECT ppse
@ -212,8 +212,8 @@ bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
return app_aid_found;
}
bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
bool select_app_success = false;
static bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
app->app_started = false;
const uint8_t emv_select_header[] = {
0x00,
0xA4, // SELECT application
@ -236,7 +236,7 @@ bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
if(furi_hal_nfc_tx_rx(tx_rx, 300)) {
emv_trace(tx_rx, "Start application answer:");
if(emv_decode_response(tx_rx->rx_data, tx_rx->rx_bits / 8, app)) {
select_app_success = true;
app->app_started = true;
} else {
FURI_LOG_E(TAG, "Failed to read PAN or PDOL");
}
@ -244,7 +244,7 @@ bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
FURI_LOG_E(TAG, "Failed to start application");
}
return select_app_success;
return app->app_started;
}
static uint16_t emv_prepare_pdol(APDU* dest, APDU* src) {
@ -367,14 +367,6 @@ static bool emv_read_files(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) {
return card_num_read;
}
bool emv_search_application(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app) {
furi_assert(tx_rx);
furi_assert(emv_app);
memset(emv_app, 0, sizeof(EmvApplication));
return emv_select_ppse(tx_rx, emv_app);
}
bool emv_read_bank_card(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app) {
furi_assert(tx_rx);
furi_assert(emv_app);

View File

@ -45,6 +45,7 @@ typedef struct {
uint8_t priority;
uint8_t aid[16];
uint8_t aid_len;
bool app_started;
char name[32];
bool name_found;
uint8_t card_number[10];
@ -68,15 +69,6 @@ typedef struct {
*/
bool emv_read_bank_card(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app);
/** Search for EMV Application
*
* @param tx_rx FuriHalNfcTxRxContext instance
* @param emv_app EmvApplication instance
*
* @return true on success
*/
bool emv_search_application(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app);
/** Emulate bank card
* @note Answer to application selection and PDOL
*