Merge remote-tracking branch 'origin/dev' into release-candidate

This commit is contained in:
Aleksandr Kutuzov 2023-04-12 15:12:01 +09:00
commit 728320b713
19 changed files with 106 additions and 164 deletions

2
.gitignore vendored
View File

@ -30,7 +30,7 @@ bindings/
Brewfile.lock.json Brewfile.lock.json
# Visual Studio Code # Visual Studio Code
.vscode/ /.vscode/
# Kate # Kate
.kateproject .kateproject

View File

@ -152,7 +152,12 @@ bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) {
} }
} }
} }
if(instance->spi) avr_isp_spi_sw_free(instance->spi);
if(instance->spi) {
avr_isp_spi_sw_free(instance->spi);
instance->spi = NULL;
}
return false; return false;
} }

View File

@ -317,7 +317,12 @@ static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) {
} }
} }
} }
if(instance->spi) avr_isp_spi_sw_free(instance->spi);
if(instance->spi) {
avr_isp_spi_sw_free(instance->spi);
instance->spi = NULL;
}
return false; return false;
} }

View File

@ -85,11 +85,6 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess); scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess);
DOLPHIN_DEED(DolphinDeedNfcReadSuccess); DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
consumed = true; consumed = true;
} else if(event.event == NfcWorkerEventReadBankCard) {
notification_message(nfc->notifications, &sequence_success);
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess);
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
consumed = true;
} else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) { } else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) {
if(mf_classic_dict_check_presence(MfClassicDictTypeSystem)) { if(mf_classic_dict_check_presence(MfClassicDictTypeSystem)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack); scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack);

View File

@ -5,7 +5,6 @@ enum SubmenuIndex {
SubmenuIndexReadMifareClassic, SubmenuIndexReadMifareClassic,
SubmenuIndexReadMifareDesfire, SubmenuIndexReadMifareDesfire,
SubmenuIndexReadMfUltralight, SubmenuIndexReadMfUltralight,
SubmenuIndexReadEMV,
SubmenuIndexReadNFCA, SubmenuIndexReadNFCA,
}; };
@ -37,12 +36,6 @@ void nfc_scene_read_card_type_on_enter(void* context) {
SubmenuIndexReadMfUltralight, SubmenuIndexReadMfUltralight,
nfc_scene_read_card_type_submenu_callback, nfc_scene_read_card_type_submenu_callback,
nfc); nfc);
submenu_add_item(
submenu,
"Read EMV card",
SubmenuIndexReadEMV,
nfc_scene_read_card_type_submenu_callback,
nfc);
submenu_add_item( submenu_add_item(
submenu, submenu,
"Read NFC-A data", "Read NFC-A data",
@ -75,11 +68,6 @@ bool nfc_scene_read_card_type_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true; consumed = true;
} }
if(event.event == SubmenuIndexReadEMV) {
nfc->dev->dev_data.read_mode = NfcReadModeEMV;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true;
}
if(event.event == SubmenuIndexReadNFCA) { if(event.event == SubmenuIndexReadNFCA) {
nfc->dev->dev_data.read_mode = NfcReadModeNFCA; nfc->dev->dev_data.read_mode = NfcReadModeNFCA;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);

View File

@ -230,7 +230,11 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
(subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) {
subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; subghz->txrx->rx_key_state = SubGhzRxKeyStateBack;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); subghz_read_raw_set_status(
subghz->subghz_read_raw,
SubGhzReadRAWStatusIDLE,
"",
subghz->txrx->raw_threshold_rssi);
} else { } else {
if(scene_manager_has_previous_scene( if(scene_manager_has_previous_scene(
subghz->scene_manager, SubGhzSceneSaved) || subghz->scene_manager, SubGhzSceneSaved) ||

View File

@ -70,9 +70,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
} }
if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
(subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { if(subghz_tx_start(subghz, subghz->txrx->fff_data)) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx);
} else {
subghz->state_notifications = SubGhzNotificationStateTx; subghz->state_notifications = SubGhzNotificationStateTx;
subghz_scene_transmitter_update_data_show(subghz); subghz_scene_transmitter_update_data_show(subghz);
DOLPHIN_DEED(DolphinDeedSubGhzSend); DOLPHIN_DEED(DolphinDeedSubGhzSend);

View File

@ -105,9 +105,11 @@ static bool subghz_tx(SubGhz* subghz, uint32_t frequency) {
furi_hal_subghz_set_frequency_and_path(frequency); furi_hal_subghz_set_frequency_and_path(frequency);
furi_hal_gpio_write(&gpio_cc1101_g0, false); furi_hal_gpio_write(&gpio_cc1101_g0, false);
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
subghz_speaker_on(subghz);
bool ret = furi_hal_subghz_tx(); bool ret = furi_hal_subghz_tx();
if(ret) {
subghz_speaker_on(subghz);
subghz->txrx->txrx_state = SubGhzTxRxStateTx; subghz->txrx->txrx_state = SubGhzTxRxStateTx;
}
return ret; return ret;
} }
@ -115,6 +117,7 @@ void subghz_idle(SubGhz* subghz) {
furi_assert(subghz); furi_assert(subghz);
furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep);
furi_hal_subghz_idle(); furi_hal_subghz_idle();
subghz_speaker_off(subghz);
subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; subghz->txrx->txrx_state = SubGhzTxRxStateIDLE;
} }

View File

@ -56,7 +56,6 @@ typedef enum {
NfcReadModeMfClassic, NfcReadModeMfClassic,
NfcReadModeMfUltralight, NfcReadModeMfUltralight,
NfcReadModeMfDesfire, NfcReadModeMfDesfire,
NfcReadModeEMV,
NfcReadModeNFCA, NfcReadModeNFCA,
} NfcReadMode; } NfcReadMode;

View File

@ -229,69 +229,6 @@ static bool nfc_worker_read_mf_desfire(NfcWorker* nfc_worker, FuriHalNfcTxRxCont
return read_success; return read_success;
} }
static bool nfc_worker_read_bank_card(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
bool read_success = false;
EmvApplication emv_app = {};
EmvData* result = &nfc_worker->dev_data->emv_data;
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false);
reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
}
// 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)) {
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);
read_success = true;
}
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);
}
return read_success;
}
static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
@ -315,14 +252,6 @@ static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t
nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown;
} }
card_read = true; card_read = true;
} else if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) {
FURI_LOG_I(TAG, "ISO14443-4 card detected");
nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV;
if(!nfc_worker_read_bank_card(nfc_worker, tx_rx)) {
FURI_LOG_I(TAG, "Unknown card. Save UID");
nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown;
}
card_read = true;
} else { } else {
nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown;
card_read = true; card_read = true;
@ -358,9 +287,6 @@ void nfc_worker_read(NfcWorker* nfc_worker) {
} else if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) { } else if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) {
event = NfcWorkerEventReadMfDesfire; event = NfcWorkerEventReadMfDesfire;
break; break;
} else if(dev_data->protocol == NfcDeviceProtocolEMV) {
event = NfcWorkerEventReadBankCard;
break;
} else if(dev_data->protocol == NfcDeviceProtocolUnknown) { } else if(dev_data->protocol == NfcDeviceProtocolUnknown) {
event = NfcWorkerEventReadUidNfcA; event = NfcWorkerEventReadUidNfcA;
break; break;
@ -444,12 +370,6 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) {
event = NfcWorkerEventReadMfDesfire; event = NfcWorkerEventReadMfDesfire;
break; break;
} }
} else if(read_mode == NfcReadModeEMV) {
nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV;
if(nfc_worker_read_bank_card(nfc_worker, &tx_rx)) {
event = NfcWorkerEventReadBankCard;
break;
}
} else if(read_mode == NfcReadModeNFCA) { } else if(read_mode == NfcReadModeNFCA) {
nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown;
event = NfcWorkerEventReadUidNfcA; event = NfcWorkerEventReadUidNfcA;

View File

@ -39,7 +39,6 @@ typedef enum {
NfcWorkerEventReadMfClassicDone, NfcWorkerEventReadMfClassicDone,
NfcWorkerEventReadMfClassicLoadKeyCache, NfcWorkerEventReadMfClassicLoadKeyCache,
NfcWorkerEventReadMfClassicDictAttackRequired, NfcWorkerEventReadMfClassicDictAttackRequired,
NfcWorkerEventReadBankCard,
// Nfc worker common events // Nfc worker common events
NfcWorkerEventSuccess, NfcWorkerEventSuccess,

View File

@ -6,7 +6,6 @@
#include <lib/toolbox/stream/file_stream.h> #include <lib/toolbox/stream/file_stream.h>
#include <lib/nfc/protocols/nfc_util.h> #include <lib/nfc/protocols/nfc_util.h>
#include <lib/nfc/protocols/emv.h>
#include <lib/nfc/protocols/mifare_common.h> #include <lib/nfc/protocols/mifare_common.h>
#include <lib/nfc/protocols/mifare_ultralight.h> #include <lib/nfc/protocols/mifare_ultralight.h>
#include <lib/nfc/protocols/mifare_classic.h> #include <lib/nfc/protocols/mifare_classic.h>

View File

@ -181,9 +181,9 @@ class Main(App):
) as zf: ) as zf:
for component_key in sdk_components_keys: for component_key in sdk_components_keys:
component_path = self._dist_components.get(component_key) component_path = self._dist_components.get(component_key)
components_paths[component_key] = basename(component_path)
if component_key.endswith(".dir"): if component_key.endswith(".dir"):
components_paths[component_key] = basename(component_path)
for root, dirnames, files in walk(component_path): for root, dirnames, files in walk(component_path):
if "__pycache__" in dirnames: if "__pycache__" in dirnames:
dirnames.remove("__pycache__") dirnames.remove("__pycache__")
@ -199,7 +199,9 @@ class Main(App):
), ),
) )
else: else:
zf.write(component_path, basename(component_path)) # We use fixed names for files to avoid having to regenerate VSCode project
components_paths[component_key] = component_key
zf.write(component_path, component_key)
zf.writestr( zf.writestr(
"components.json", "components.json",

View File

@ -163,6 +163,18 @@ dist_env.Alias("flash", openocd_target)
if env["FORCE"]: if env["FORCE"]:
env.AlwaysBuild(openocd_target) env.AlwaysBuild(openocd_target)
firmware_jflash = dist_env.JFlash(
dist_env["UFBT_STATE_DIR"].File("jflash"),
dist_env["FW_BIN"],
JFLASHADDR="0x20000000",
)
dist_env.Alias("firmware_jflash", firmware_jflash)
dist_env.Alias("jflash", firmware_jflash)
if env["FORCE"]:
env.AlwaysBuild(firmware_jflash)
firmware_debug = dist_env.PhonyTarget( firmware_debug = dist_env.PhonyTarget(
"debug", "debug",
"${GDBPYCOM}", "${GDBPYCOM}",
@ -391,3 +403,13 @@ AddPostAction(
dist_env.Precious(app_template_dist) dist_env.Precious(app_template_dist)
dist_env.NoClean(app_template_dist) dist_env.NoClean(app_template_dist)
dist_env.Alias("create", app_template_dist) dist_env.Alias("create", app_template_dist)
dist_env.PhonyTarget(
"get_blackmagic",
"@echo $( ${BLACKMAGIC_ADDR} $)",
)
dist_env.PhonyTarget(
"get_apiversion",
"@echo $( ${UFBT_API_VERSION} $)",
)

View File

@ -2,19 +2,16 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"inputs": [ "inputs": [
// { {
// "id": "BLACKMAGIC", "id": "BLACKMAGIC",
// "type": "command", "type": "command",
// "command": "shellCommand.execute", "command": "shellCommand.execute",
// "args": { "args": {
// "useSingleResult": true, "description": "Get Blackmagic device",
// "env": { "useSingleResult": true,
// "PATH": "${workspaceFolder};${env:PATH}" "command": "ufbt -s get_blackmagic",
// }, }
// "command": "./fbt get_blackmagic", },
// "description": "Get Blackmagic device",
// }
// },
], ],
"configurations": [ "configurations": [
{ {
@ -57,26 +54,26 @@
], ],
// "showDevDebugOutput": "raw", // "showDevDebugOutput": "raw",
}, },
// { {
// "name": "Attach FW (blackmagic)", "name": "Attach FW (blackmagic)",
// "cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
// "executable": "@UFBT_FIRMWARE_ELF@", "executable": "@UFBT_FIRMWARE_ELF@",
// "request": "attach", "request": "attach",
// "type": "cortex-debug", "type": "cortex-debug",
// "servertype": "external", "servertype": "external",
// "gdbTarget": "${input:BLACKMAGIC}", "gdbTarget": "${input:BLACKMAGIC}",
// "svdFile": "@UFBT_DEBUG_DIR@/STM32WB55_CM4.svd", "svdFile": "@UFBT_DEBUG_DIR@/STM32WB55_CM4.svd",
// "rtos": "FreeRTOS", "rtos": "FreeRTOS",
// "postAttachCommands": [ "postAttachCommands": [
// "monitor swdp_scan", "monitor swdp_scan",
// "attach 1", "attach 1",
// "set confirm off", "set confirm off",
// "set mem inaccessible-by-default off", "set mem inaccessible-by-default off",
// "source @UFBT_DEBUG_DIR@/flipperapps.py", "source @UFBT_DEBUG_DIR@/flipperapps.py",
// "fap-set-debug-elf-root @UFBT_DEBUG_ELF_DIR@" "fap-set-debug-elf-root @UFBT_DEBUG_ELF_DIR@"
// ] ]
// // "showDevDebugOutput": "raw", // "showDevDebugOutput": "raw",
// }, },
{ {
"name": "Attach FW (JLink)", "name": "Attach FW (JLink)",
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",

View File

@ -20,24 +20,30 @@
"type": "shell", "type": "shell",
"command": "ufbt" "command": "ufbt"
}, },
{
"label": "Clean",
"group": "build",
"type": "shell",
"command": "ufbt -c"
},
{ {
"label": "Flash FW (ST-Link)", "label": "Flash FW (ST-Link)",
"group": "build", "group": "build",
"type": "shell", "type": "shell",
"command": "ufbt FORCE=1 flash" "command": "ufbt FORCE=1 flash"
}, },
// { {
// "label": "[NOTIMPL] Flash FW (blackmagic)", "label": "Flash FW (blackmagic)",
// "group": "build", "group": "build",
// "type": "shell", "type": "shell",
// "command": "ufbt flash_blackmagic" "command": "ufbt flash_blackmagic"
// }, },
// { {
// "label": "[NOTIMPL] Flash FW (JLink)", "label": "Flash FW (JLink)",
// "group": "build", "group": "build",
// "type": "shell", "type": "shell",
// "command": "ufbt FORCE=1 jflash" "command": "ufbt FORCE=1 jflash"
// }, },
{ {
"label": "Flash FW (USB, with resources)", "label": "Flash FW (USB, with resources)",
"group": "build", "group": "build",
@ -49,6 +55,12 @@
"group": "build", "group": "build",
"type": "shell", "type": "shell",
"command": "ufbt update" "command": "ufbt update"
},
{
"label": "Update VSCode config for current SDK",
"group": "build",
"type": "shell",
"command": "ufbt vscode_dist"
} }
] ]
} }

View File

@ -6,7 +6,7 @@ App(
apptype=FlipperAppType.EXTERNAL, apptype=FlipperAppType.EXTERNAL,
entry_point="@FBT_APPID@_app", entry_point="@FBT_APPID@_app",
stack_size=2 * 1024, stack_size=2 * 1024,
fap_category="Misc", fap_category="Examples",
# Optional values # Optional values
# fap_version=(0, 1), # (major, minor) # fap_version=(0, 1), # (major, minor)
fap_icon="@FBT_APPID@.png", # 10x10 1-bit PNG fap_icon="@FBT_APPID@.png", # 10x10 1-bit PNG

View File

@ -75,12 +75,6 @@ def generate(env, **kw):
if not sdk_state["meta"]["hw_target"].endswith(sdk_data["hardware"]): if not sdk_state["meta"]["hw_target"].endswith(sdk_data["hardware"]):
raise StopError("SDK state file doesn't match hardware target") raise StopError("SDK state file doesn't match hardware target")
if sdk_state["meta"]["version"] != ufbt_state["version"]:
warn(
WarningOnByDefault,
f"Version mismatch: SDK state vs uFBT: {sdk_state['meta']['version']} vs {ufbt_state['version']}",
)
scripts_dir = sdk_current_sdk_dir_node.Dir(sdk_components["scripts.dir"]) scripts_dir = sdk_current_sdk_dir_node.Dir(sdk_components["scripts.dir"])
env.SetDefault( env.SetDefault(
# Paths # Paths

View File

@ -1,5 +1,4 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from os.path import dirname
from SCons.Node import NodeList from SCons.Node import NodeList
from SCons.Warnings import warn, WarningOnByDefault from SCons.Warnings import warn, WarningOnByDefault
@ -131,6 +130,7 @@ Depends(sdk_source, appenv.ProcessSdkDepends(f"{amalgamated_api}.d"))
appenv["SDK_DIR"] = appenv.Dir("${BUILD_DIR}/sdk_headers") appenv["SDK_DIR"] = appenv.Dir("${BUILD_DIR}/sdk_headers")
sdk_header_tree = appenv.SDKHeaderTreeExtractor(appenv["SDK_DIR"], amalgamated_api) sdk_header_tree = appenv.SDKHeaderTreeExtractor(appenv["SDK_DIR"], amalgamated_api)
Depends(sdk_header_tree, appenv["SDK_DEFINITION"])
# AlwaysBuild(sdk_tree) # AlwaysBuild(sdk_tree)
Alias("sdk_tree", sdk_header_tree) Alias("sdk_tree", sdk_header_tree)
extapps.sdk_tree = sdk_header_tree extapps.sdk_tree = sdk_header_tree