mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
Merge branch 'fz-dev' into dev
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#define ICLASS_ELITE_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_elite_dict.txt")
|
#define ICLASS_ELITE_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_elite_dict.txt")
|
||||||
#define ICLASS_ELITE_DICT_USER_NAME APP_DATA_PATH("assets/iclass_elite_dict_user.txt")
|
#define ICLASS_ELITE_DICT_USER_NAME APP_DATA_PATH("assets/iclass_elite_dict_user.txt")
|
||||||
|
#define ICLASS_STANDARD_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_standard_dict.txt")
|
||||||
|
|
||||||
#define TAG "IclassEliteDict"
|
#define TAG "IclassEliteDict"
|
||||||
|
|
||||||
@@ -25,6 +26,9 @@ bool iclass_elite_dict_check_presence(IclassEliteDictType dict_type) {
|
|||||||
(storage_common_stat(storage, ICLASS_ELITE_DICT_FLIPPER_NAME, NULL) == FSE_OK);
|
(storage_common_stat(storage, ICLASS_ELITE_DICT_FLIPPER_NAME, NULL) == FSE_OK);
|
||||||
} else if(dict_type == IclassEliteDictTypeUser) {
|
} else if(dict_type == IclassEliteDictTypeUser) {
|
||||||
dict_present = (storage_common_stat(storage, ICLASS_ELITE_DICT_USER_NAME, NULL) == FSE_OK);
|
dict_present = (storage_common_stat(storage, ICLASS_ELITE_DICT_USER_NAME, NULL) == FSE_OK);
|
||||||
|
} else if(dict_type == IclassStandardDictTypeFlipper) {
|
||||||
|
dict_present =
|
||||||
|
(storage_common_stat(storage, ICLASS_STANDARD_DICT_FLIPPER_NAME, NULL) == FSE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
@@ -52,6 +56,15 @@ IclassEliteDict* iclass_elite_dict_alloc(IclassEliteDictType dict_type) {
|
|||||||
buffered_file_stream_close(dict->stream);
|
buffered_file_stream_close(dict->stream);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if(dict_type == IclassStandardDictTypeFlipper) {
|
||||||
|
if(!buffered_file_stream_open(
|
||||||
|
dict->stream,
|
||||||
|
ICLASS_STANDARD_DICT_FLIPPER_NAME,
|
||||||
|
FSAM_READ,
|
||||||
|
FSOM_OPEN_EXISTING)) {
|
||||||
|
buffered_file_stream_close(dict->stream);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read total amount of keys
|
// Read total amount of keys
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
IclassEliteDictTypeUser,
|
IclassEliteDictTypeUser,
|
||||||
IclassEliteDictTypeFlipper,
|
IclassEliteDictTypeFlipper,
|
||||||
|
IclassStandardDictTypeFlipper,
|
||||||
} IclassEliteDictType;
|
} IclassEliteDictType;
|
||||||
|
|
||||||
typedef struct IclassEliteDict IclassEliteDict;
|
typedef struct IclassEliteDict IclassEliteDict;
|
||||||
|
|||||||
46
applications/external/picopass/picopass_worker.c
vendored
46
applications/external/picopass/picopass_worker.c
vendored
@@ -172,14 +172,18 @@ ReturnCode picopass_read_preauth(PicopassBlock* AA1) {
|
|||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ReturnCode picopass_auth_dict(
|
static ReturnCode
|
||||||
uint8_t* csn,
|
picopass_auth_dict(PicopassWorker* picopass_worker, IclassEliteDictType dict_type) {
|
||||||
PicopassPacs* pacs,
|
|
||||||
uint8_t* div_key,
|
|
||||||
IclassEliteDictType dict_type,
|
|
||||||
bool elite) {
|
|
||||||
rfalPicoPassReadCheckRes rcRes;
|
rfalPicoPassReadCheckRes rcRes;
|
||||||
rfalPicoPassCheckRes chkRes;
|
rfalPicoPassCheckRes chkRes;
|
||||||
|
bool elite = (dict_type != IclassStandardDictTypeFlipper);
|
||||||
|
|
||||||
|
PicopassDeviceData* dev_data = picopass_worker->dev_data;
|
||||||
|
PicopassBlock* AA1 = dev_data->AA1;
|
||||||
|
PicopassPacs* pacs = &dev_data->pacs;
|
||||||
|
|
||||||
|
uint8_t* csn = AA1[PICOPASS_CSN_BLOCK_INDEX].data;
|
||||||
|
uint8_t* div_key = AA1[PICOPASS_KD_BLOCK_INDEX].data;
|
||||||
|
|
||||||
ReturnCode err = ERR_PARAM;
|
ReturnCode err = ERR_PARAM;
|
||||||
|
|
||||||
@@ -204,7 +208,8 @@ static ReturnCode picopass_auth_dict(
|
|||||||
while(iclass_elite_dict_get_next_key(dict, key)) {
|
while(iclass_elite_dict_get_next_key(dict, key)) {
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
TAG,
|
TAG,
|
||||||
"Try to auth with key %zu %02x%02x%02x%02x%02x%02x%02x%02x",
|
"Try to %s auth with key %zu %02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
|
elite ? "elite" : "standard",
|
||||||
index++,
|
index++,
|
||||||
key[0],
|
key[0],
|
||||||
key[1],
|
key[1],
|
||||||
@@ -230,6 +235,8 @@ static ReturnCode picopass_auth_dict(
|
|||||||
memcpy(pacs->key, key, PICOPASS_BLOCK_LEN);
|
memcpy(pacs->key, key, PICOPASS_BLOCK_LEN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(picopass_worker->state != PicopassWorkerStateDetect) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iclass_elite_dict_free(dict);
|
iclass_elite_dict_free(dict);
|
||||||
@@ -237,38 +244,23 @@ static ReturnCode picopass_auth_dict(
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode picopass_auth(PicopassBlock* AA1, PicopassPacs* pacs) {
|
ReturnCode picopass_auth(PicopassWorker* picopass_worker) {
|
||||||
ReturnCode err;
|
ReturnCode err;
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]");
|
FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]");
|
||||||
err = picopass_auth_dict(
|
err = picopass_auth_dict(picopass_worker, IclassStandardDictTypeFlipper);
|
||||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
|
|
||||||
pacs,
|
|
||||||
AA1[PICOPASS_KD_BLOCK_INDEX].data,
|
|
||||||
IclassEliteDictTypeFlipper,
|
|
||||||
false);
|
|
||||||
if(err == ERR_NONE) {
|
if(err == ERR_NONE) {
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "Starting user dictionary attack [Elite KDF]");
|
FURI_LOG_I(TAG, "Starting user dictionary attack [Elite KDF]");
|
||||||
err = picopass_auth_dict(
|
err = picopass_auth_dict(picopass_worker, IclassEliteDictTypeUser);
|
||||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
|
|
||||||
pacs,
|
|
||||||
AA1[PICOPASS_KD_BLOCK_INDEX].data,
|
|
||||||
IclassEliteDictTypeUser,
|
|
||||||
true);
|
|
||||||
if(err == ERR_NONE) {
|
if(err == ERR_NONE) {
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "Starting system dictionary attack [Elite KDF]");
|
FURI_LOG_I(TAG, "Starting system dictionary attack [Elite KDF]");
|
||||||
err = picopass_auth_dict(
|
err = picopass_auth_dict(picopass_worker, IclassEliteDictTypeFlipper);
|
||||||
AA1[PICOPASS_CSN_BLOCK_INDEX].data,
|
|
||||||
pacs,
|
|
||||||
AA1[PICOPASS_KD_BLOCK_INDEX].data,
|
|
||||||
IclassEliteDictTypeFlipper,
|
|
||||||
true);
|
|
||||||
if(err == ERR_NONE) {
|
if(err == ERR_NONE) {
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
@@ -520,7 +512,7 @@ void picopass_worker_detect(PicopassWorker* picopass_worker) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(nextState == PicopassWorkerEventSuccess) {
|
if(nextState == PicopassWorkerEventSuccess) {
|
||||||
err = picopass_auth(AA1, pacs);
|
err = picopass_auth(picopass_worker);
|
||||||
if(err != ERR_NONE) {
|
if(err != ERR_NONE) {
|
||||||
FURI_LOG_E(TAG, "picopass_try_auth error %d", err);
|
FURI_LOG_E(TAG, "picopass_try_auth error %d", err);
|
||||||
nextState = PicopassWorkerEventFail;
|
nextState = PicopassWorkerEventFail;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
#include <lib/toolbox/args.h>
|
#include <lib/toolbox/args.h>
|
||||||
|
#include <lib/toolbox/hex.h>
|
||||||
|
|
||||||
#include <lib/nfc/nfc_types.h>
|
#include <lib/nfc/nfc_types.h>
|
||||||
#include <lib/nfc/nfc_device.h>
|
#include <lib/nfc/nfc_device.h>
|
||||||
@@ -12,6 +13,7 @@ static void nfc_cli_print_usage() {
|
|||||||
printf("Cmd list:\r\n");
|
printf("Cmd list:\r\n");
|
||||||
printf("\tdetect\t - detect nfc device\r\n");
|
printf("\tdetect\t - detect nfc device\r\n");
|
||||||
printf("\temulate\t - emulate predefined nfca card\r\n");
|
printf("\temulate\t - emulate predefined nfca card\r\n");
|
||||||
|
printf("\tapdu\t - Send APDU and print response \r\n");
|
||||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||||
printf("\tfield\t - turn field on\r\n");
|
printf("\tfield\t - turn field on\r\n");
|
||||||
}
|
}
|
||||||
@@ -98,6 +100,67 @@ static void nfc_cli_field(Cli* cli, FuriString* args) {
|
|||||||
furi_hal_nfc_sleep();
|
furi_hal_nfc_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nfc_cli_apdu(Cli* cli, FuriString* args) {
|
||||||
|
UNUSED(cli);
|
||||||
|
if(furi_hal_nfc_is_busy()) {
|
||||||
|
printf("Nfc is busy\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_hal_nfc_exit_sleep();
|
||||||
|
FuriString* data = NULL;
|
||||||
|
data = furi_string_alloc();
|
||||||
|
FuriHalNfcTxRxContext tx_rx = {};
|
||||||
|
FuriHalNfcDevData dev_data = {};
|
||||||
|
uint8_t* req_buffer = NULL;
|
||||||
|
uint8_t* resp_buffer = NULL;
|
||||||
|
size_t apdu_size = 0;
|
||||||
|
size_t resp_size = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!args_read_string_and_trim(args, data)) {
|
||||||
|
printf(
|
||||||
|
"Use like `nfc apdu 00a404000e325041592e5359532e444446303100 00a4040008a0000003010102` \r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("detecting tag\r\n");
|
||||||
|
if(!furi_hal_nfc_detect(&dev_data, 300)) {
|
||||||
|
printf("Failed to detect tag\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
apdu_size = furi_string_size(data) / 2;
|
||||||
|
req_buffer = malloc(apdu_size);
|
||||||
|
hex_chars_to_uint8(furi_string_get_cstr(data), req_buffer);
|
||||||
|
|
||||||
|
memcpy(tx_rx.tx_data, req_buffer, apdu_size);
|
||||||
|
tx_rx.tx_bits = apdu_size * 8;
|
||||||
|
tx_rx.tx_rx_type = FuriHalNfcTxRxTypeDefault;
|
||||||
|
|
||||||
|
printf("Sending APDU:%s to Tag\r\n", furi_string_get_cstr(data));
|
||||||
|
if(!furi_hal_nfc_tx_rx(&tx_rx, 300)) {
|
||||||
|
printf("Failed to tx_rx\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
resp_size = (tx_rx.rx_bits / 8) * 2;
|
||||||
|
resp_buffer = malloc(resp_size);
|
||||||
|
uint8_to_hex_chars(tx_rx.rx_data, resp_buffer, resp_size);
|
||||||
|
resp_buffer[resp_size] = 0;
|
||||||
|
printf("Response: %s\r\n", resp_buffer);
|
||||||
|
free(req_buffer);
|
||||||
|
free(resp_buffer);
|
||||||
|
req_buffer = NULL;
|
||||||
|
resp_buffer = NULL;
|
||||||
|
} while(args_read_string_and_trim(args, data));
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
free(req_buffer);
|
||||||
|
free(resp_buffer);
|
||||||
|
furi_string_free(data);
|
||||||
|
furi_hal_nfc_sleep();
|
||||||
|
}
|
||||||
|
|
||||||
static void nfc_cli(Cli* cli, FuriString* args, void* context) {
|
static void nfc_cli(Cli* cli, FuriString* args, void* context) {
|
||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
FuriString* cmd;
|
FuriString* cmd;
|
||||||
@@ -117,6 +180,11 @@ static void nfc_cli(Cli* cli, FuriString* args, void* context) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(furi_string_cmp_str(cmd, "apdu") == 0) {
|
||||||
|
nfc_cli_apdu(cli, args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||||
if(furi_string_cmp_str(cmd, "field") == 0) {
|
if(furi_string_cmp_str(cmd, "field") == 0) {
|
||||||
nfc_cli_field(cli, args);
|
nfc_cli_field(cli, args);
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
|
|
||||||
## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
|
## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
|
||||||
|
|
||||||
# AA1
|
|
||||||
AEA684A6DAB23278
|
|
||||||
# key1/Kc from PicoPass 2k documentation
|
# key1/Kc from PicoPass 2k documentation
|
||||||
7665544332211000
|
7665544332211000
|
||||||
# SAGEM
|
# SAGEM
|
||||||
0123456789ABCDEF
|
0123456789ABCDEF
|
||||||
# from loclass demo file.
|
|
||||||
5b7c62c491c11b39
|
|
||||||
# Kd from PicoPass 2k documentation
|
|
||||||
F0E1D2C3B4A59687
|
|
||||||
# PicoPass Default Exchange Key
|
# PicoPass Default Exchange Key
|
||||||
5CBCF1DA45D5FB4F
|
5CBCF1DA45D5FB4F
|
||||||
# From HID multiclassSE reader
|
# From HID multiclassSE reader
|
||||||
@@ -19,12 +13,6 @@ F0E1D2C3B4A59687
|
|||||||
6EFD46EFCBB3C875
|
6EFD46EFCBB3C875
|
||||||
E033CA419AEE43F9
|
E033CA419AEE43F9
|
||||||
|
|
||||||
# iCopy-x DRM keys
|
|
||||||
# iCL tags
|
|
||||||
2020666666668888
|
|
||||||
# iCS tags reversed from the SOs
|
|
||||||
6666202066668888
|
|
||||||
|
|
||||||
# default picopass KD / Page 0 / Book 1
|
# default picopass KD / Page 0 / Book 1
|
||||||
FDCB5A52EA8F3090
|
FDCB5A52EA8F3090
|
||||||
237FF9079863DF44
|
237FF9079863DF44
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
|
||||||
|
|
||||||
|
# AA1
|
||||||
|
AEA684A6DAB23278
|
||||||
|
# key1/Kc from PicoPass 2k documentation
|
||||||
|
7665544332211000
|
||||||
|
# SAGEM
|
||||||
|
0123456789ABCDEF
|
||||||
|
# from loclass demo file.
|
||||||
|
5b7c62c491c11b39
|
||||||
|
# Kd from PicoPass 2k documentation
|
||||||
|
F0E1D2C3B4A59687
|
||||||
|
# PicoPass Default Exchange Key
|
||||||
|
5CBCF1DA45D5FB4F
|
||||||
|
# From HID multiclassSE reader
|
||||||
|
31ad7ebd2f282168
|
||||||
|
# From pastebin: https://pastebin.com/uHqpjiuU
|
||||||
|
6EFD46EFCBB3C875
|
||||||
|
E033CA419AEE43F9
|
||||||
|
|
||||||
|
# iCopy-x DRM keys
|
||||||
|
# iCL tags
|
||||||
|
2020666666668888
|
||||||
|
# iCS tags reversed from the SOs
|
||||||
|
6666202066668888
|
||||||
|
|
||||||
|
# default picopass KD / Page 0 / Book 1
|
||||||
|
FDCB5A52EA8F3090
|
||||||
|
237FF9079863DF44
|
||||||
|
5ADC25FB27181D32
|
||||||
|
83B881F2936B2E49
|
||||||
|
43644E61EE866BA5
|
||||||
|
897034143D016080
|
||||||
|
82D17B44C0122963
|
||||||
|
4895CA7DE65E2025
|
||||||
|
DADAD4C57BE271B7
|
||||||
|
E41E9EDEF5719ABF
|
||||||
|
293D275EC3AF9C7F
|
||||||
|
C3C169251B8A70FB
|
||||||
|
F41DAF58B20C8B91
|
||||||
|
28877A609EC0DD2B
|
||||||
|
66584C91EE80D5E5
|
||||||
|
C1B74D7478053AE2
|
||||||
|
|
||||||
|
# default iCLASS RFIDeas
|
||||||
|
6B65797374726B72
|
||||||
4
fbt
4
fbt
@@ -25,10 +25,10 @@ fi
|
|||||||
|
|
||||||
if [ -z "$FBT_NO_SYNC" ]; then
|
if [ -z "$FBT_NO_SYNC" ]; then
|
||||||
if [ ! -d "$SCRIPT_PATH/.git" ]; then
|
if [ ! -d "$SCRIPT_PATH/.git" ]; then
|
||||||
echo "\".git\" directory not found, please clone repo via \"git clone --recursive\"";
|
echo "\".git\" directory not found, please clone repo via \"git clone\"";
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
git submodule update --init;
|
git submodule update --init --depth 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$SCONS_EP $SCONS_DEFAULT_FLAGS "$@"
|
$SCONS_EP $SCONS_DEFAULT_FLAGS "$@"
|
||||||
|
|||||||
4
fbt.cmd
4
fbt.cmd
@@ -5,9 +5,9 @@ set SCONS_EP=python -m SCons
|
|||||||
|
|
||||||
if [%FBT_NO_SYNC%] == [] (
|
if [%FBT_NO_SYNC%] == [] (
|
||||||
if exist ".git" (
|
if exist ".git" (
|
||||||
git submodule update --init
|
git submodule update --init --depth 1
|
||||||
) else (
|
) else (
|
||||||
echo Not in a git repo, please clone with git clone --recursive
|
echo Not in a git repo, please clone with "git clone"
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
dev_data->parsed_data, "\e#Plantain\nN:%llu-\nBalance:%ld\n", card_number, balance);
|
dev_data->parsed_data, "\e#Plantain\nN:%llu-\nBalance:%lu\n", card_number, balance);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
dev_data->parsed_data, "\e#Plantain\nN:%llu-\nBalance:%ld\n", card_number, balance);
|
dev_data->parsed_data, "\e#Plantain\nN:%llu-\nBalance:%lu\n", card_number, balance);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ bool troika_4k_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
number >>= 4;
|
number >>= 4;
|
||||||
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance);
|
dev_data->parsed_data, "\e#Troika\nNum: %lu\nBalance: %u rur.", number, balance);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ bool troika_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
number >>= 4;
|
number >>= 4;
|
||||||
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance);
|
dev_data->parsed_data, "\e#Troika\nNum: %lu\nBalance: %u rur.", number, balance);
|
||||||
troika_parsed = true;
|
troika_parsed = true;
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
dev_data->parsed_data,
|
dev_data->parsed_data,
|
||||||
"\e#Troika+Plantain\nPN: %llu-\nPB: %ld rur.\nTN: %ld\nTB: %d rur.\n",
|
"\e#Troika+Plantain\nPN: %llu-\nPB: %lu rur.\nTN: %lu\nTB: %u rur.\n",
|
||||||
card_number,
|
card_number,
|
||||||
balance,
|
balance,
|
||||||
troika_number,
|
troika_number,
|
||||||
|
|||||||
@@ -611,7 +611,7 @@ bool subghz_protocol_secplus_v2_create_data(
|
|||||||
if((res == SubGhzProtocolStatusOk) &&
|
if((res == SubGhzProtocolStatusOk) &&
|
||||||
!flipper_format_write_hex(flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) {
|
!flipper_format_write_hex(flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) {
|
||||||
FURI_LOG_E(TAG, "Unable to add Secplus_packet_1");
|
FURI_LOG_E(TAG, "Unable to add Secplus_packet_1");
|
||||||
res = SubGhzProtocolStatusError;
|
res = SubGhzProtocolStatusErrorParserOthers;
|
||||||
}
|
}
|
||||||
return res == SubGhzProtocolStatusOk;
|
return res == SubGhzProtocolStatusOk;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user