This commit is contained in:
Willy-JL
2024-04-19 22:33:39 +01:00
5 changed files with 119 additions and 62 deletions

View File

@@ -505,7 +505,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
card_use_before_date_s.year); card_use_before_date_s.year);
if(data_block.valid_from_date == 0 || data_block.valid_to_date == 0) { if(data_block.valid_from_date == 0 || data_block.valid_to_date == 0) {
furi_string_cat(result, "\e#No ticket\n"); furi_string_cat(result, "\e#No ticket");
return true; return true;
} }
//remaining_trips //remaining_trips
@@ -625,7 +625,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992); data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid to: %02d.%02d.%04d\n", "Valid to: %02d.%02d.%04d",
card_valid_to_date_s.day, card_valid_to_date_s.day,
card_valid_to_date_s.month, card_valid_to_date_s.month,
card_valid_to_date_s.year); card_valid_to_date_s.year);
@@ -663,7 +663,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2016); 2016);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid to: %02d.%02d.%04d\n", "Valid to: %02d.%02d.%04d",
card_valid_to_date_s.day, card_valid_to_date_s.day,
card_valid_to_date_s.month, card_valid_to_date_s.month,
card_valid_to_date_s.year); card_valid_to_date_s.year);
@@ -676,7 +676,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2016); 2016);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip from: %02d.%02d.%04d %02d:%02d\n", "\nTrip from: %02d.%02d.%04d %02d:%02d",
card_start_trip_minutes_s.day, card_start_trip_minutes_s.day,
card_start_trip_minutes_s.month, card_start_trip_minutes_s.month,
card_start_trip_minutes_s.year, card_start_trip_minutes_s.year,
@@ -693,7 +693,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2016); 2016);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip switch: %02d.%02d.%04d %02d:%02d\n", "\nTrip switch: %02d.%02d.%04d %02d:%02d",
card_start_switch_trip_minutes_s.day, card_start_switch_trip_minutes_s.day,
card_start_switch_trip_minutes_s.month, card_start_switch_trip_minutes_s.month,
card_start_switch_trip_minutes_s.year, card_start_switch_trip_minutes_s.year,
@@ -703,10 +703,10 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
//transport //transport
FuriString* transport = furi_string_alloc(); FuriString* transport = furi_string_alloc();
parse_transport_type(&data_block, transport); parse_transport_type(&data_block, transport);
furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); furi_string_cat_printf(result, "\nTransport: %s", furi_string_get_cstr(transport));
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d\n", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
furi_string_free(transport); furi_string_free(transport);
break; break;
@@ -740,9 +740,9 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
card_valid_to_date_s.month, card_valid_to_date_s.month,
card_valid_to_date_s.year); card_valid_to_date_s.year);
//remaining_trips //remaining_trips
furi_string_cat_printf(result, "Trips left: %d\n", data_block.remaining_trips); furi_string_cat_printf(result, "Trips left: %d", data_block.remaining_trips);
//trip_from //trip_from
if(data_block.start_trip_date) { if(data_block.start_trip_date) { // TODO: (-nofl) unused
DateTime card_start_trip_minutes_s = {0}; DateTime card_start_trip_minutes_s = {0};
from_minutes_to_datetime( from_minutes_to_datetime(
data_block.start_trip_date * 24 * 60 + data_block.start_trip_time, data_block.start_trip_date * 24 * 60 + data_block.start_trip_time,
@@ -751,7 +751,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
} }
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
break; break;
} }
@@ -785,12 +785,12 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992); data_block.valid_from_date + data_block.valid_for_days, &card_valid_to_date_s, 1992);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid to: %02d.%02d.%04d\n", "Valid to: %02d.%02d.%04d",
card_valid_to_date_s.day, card_valid_to_date_s.day,
card_valid_to_date_s.month, card_valid_to_date_s.month,
card_valid_to_date_s.year); card_valid_to_date_s.year);
//trip_from //trip_from
if(data_block.start_trip_date) { if(data_block.start_trip_date) { // TODO: (-nofl) unused
DateTime card_start_trip_minutes_s = {0}; DateTime card_start_trip_minutes_s = {0};
from_minutes_to_datetime( from_minutes_to_datetime(
data_block.start_trip_date * 24 * 60 + data_block.start_trip_time, data_block.start_trip_date * 24 * 60 + data_block.start_trip_time,
@@ -798,7 +798,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
1992); 1992);
} }
//trip_switch //trip_switch
if(data_block.passage_5_minutes) { if(data_block.passage_5_minutes) { // TODO: (-nofl) unused
DateTime card_start_switch_trip_minutes_s = {0}; DateTime card_start_switch_trip_minutes_s = {0};
from_minutes_to_datetime( from_minutes_to_datetime(
data_block.start_trip_date * 24 * 60 + data_block.start_trip_time + data_block.start_trip_date * 24 * 60 + data_block.start_trip_time +
@@ -808,7 +808,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
} }
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
break; break;
} }
@@ -870,10 +870,10 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
furi_string_cat(transport, ""); furi_string_cat(transport, "");
break; break;
} }
furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); furi_string_cat_printf(result, "Transport: %s", furi_string_get_cstr(transport));
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
furi_string_free(transport); furi_string_free(transport);
break; break;
@@ -899,7 +899,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992); from_days_to_datetime(data_block.valid_from_date, &card_valid_from_date_s, 1992);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid from: %02d.%02d.%04d\n", "Valid from: %02d.%02d.%04d",
card_valid_from_date_s.day, card_valid_from_date_s.day,
card_valid_from_date_s.month, card_valid_from_date_s.month,
card_valid_from_date_s.year); card_valid_from_date_s.year);
@@ -912,7 +912,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
1992); 1992);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid to: %02d.%02d.%04d\n", "\nValid to: %02d.%02d.%04d",
card_valid_to_date_s.day, card_valid_to_date_s.day,
card_valid_to_date_s.month, card_valid_to_date_s.month,
card_valid_to_date_s.year); card_valid_to_date_s.year);
@@ -924,7 +924,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
1992); 1992);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid to: %02d.%02d.%04d\n", "\nValid to: %02d.%02d.%04d",
card_valid_to_date_s.day, card_valid_to_date_s.day,
card_valid_to_date_s.month, card_valid_to_date_s.month,
card_valid_to_date_s.year); card_valid_to_date_s.year);
@@ -939,7 +939,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
1992); //-time 1992); //-time
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip from: %02d.%02d.%04d %02d:%02d\n", "\nTrip from: %02d.%02d.%04d %02d:%02d",
card_start_trip_minutes_s.day, card_start_trip_minutes_s.day,
card_start_trip_minutes_s.month, card_start_trip_minutes_s.month,
card_start_trip_minutes_s.year, card_start_trip_minutes_s.year,
@@ -956,7 +956,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
1992); 1992);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip switch: %02d.%02d.%04d %02d:%02d\n", "\nTrip switch: %02d.%02d.%04d %02d:%02d",
card_start_switch_trip_minutes_s.day, card_start_switch_trip_minutes_s.day,
card_start_switch_trip_minutes_s.month, card_start_switch_trip_minutes_s.month,
card_start_switch_trip_minutes_s.year, card_start_switch_trip_minutes_s.year,
@@ -965,7 +965,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
} }
//transport //transport
FuriString* transport = furi_string_alloc(); FuriString* transport = furi_string_alloc();
switch(data_block.transport_type) { switch(data_block.transport_type) { // TODO: (-nofl) unused
case 1: case 1:
furi_string_cat(transport, "Metro"); furi_string_cat(transport, "Metro");
break; break;
@@ -981,7 +981,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
} }
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
furi_string_free(transport); furi_string_free(transport);
break; break;
@@ -1094,14 +1094,14 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes - data_block.valid_from_date * 24 * 60 + data_block.valid_for_minutes -
data_block.start_trip_neg_minutes, data_block.start_trip_neg_minutes,
&card_start_trip_minutes_s, &card_start_trip_minutes_s,
2016); 2016); // TODO: (-nofl) unused
//transport //transport
FuriString* transport = furi_string_alloc(); FuriString* transport = furi_string_alloc();
parse_transport_type(&data_block, transport); parse_transport_type(&data_block, transport);
furi_string_cat_printf(result, "Transport: %s\n", furi_string_get_cstr(transport)); furi_string_cat_printf(result, "Transport: %s", furi_string_get_cstr(transport));
// validator // validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
furi_string_free(transport); furi_string_free(transport);
break; break;
@@ -1121,7 +1121,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
card_use_before_date_s.month, card_use_before_date_s.month,
card_use_before_date_s.year); card_use_before_date_s.year);
//remaining_funds //remaining_funds
furi_string_cat_printf(result, "Balance: %ld rub\n", data_block.remaining_funds / 100); furi_string_cat_printf(result, "Balance: %ld rub", data_block.remaining_funds / 100);
//start_trip_minutes //start_trip_minutes
if(data_block.start_trip_minutes) { if(data_block.start_trip_minutes) {
DateTime card_start_trip_minutes_s = {0}; DateTime card_start_trip_minutes_s = {0};
@@ -1129,7 +1129,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
data_block.start_trip_minutes, &card_start_trip_minutes_s, 2019); data_block.start_trip_minutes, &card_start_trip_minutes_s, 2019);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip from: %02d.%02d.%04d %02d:%02d\n", "\nTrip from: %02d.%02d.%04d %02d:%02d",
card_start_trip_minutes_s.day, card_start_trip_minutes_s.day,
card_start_trip_minutes_s.month, card_start_trip_minutes_s.month,
card_start_trip_minutes_s.year, card_start_trip_minutes_s.year,
@@ -1145,7 +1145,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2019); 2019);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"(M) from: %02d.%02d.%04d %02d:%02d\n", "\n(M) from: %02d.%02d.%04d %02d:%02d",
card_start_m_trip_minutes_s.day, card_start_m_trip_minutes_s.day,
card_start_m_trip_minutes_s.month, card_start_m_trip_minutes_s.month,
card_start_m_trip_minutes_s.year, card_start_m_trip_minutes_s.year,
@@ -1160,7 +1160,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2019); 2019);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip edit: %02d.%02d.%04d %02d:%02d\n", "\nTrip edit: %02d.%02d.%04d %02d:%02d",
card_start_change_trip_minutes_s.day, card_start_change_trip_minutes_s.day,
card_start_change_trip_minutes_s.month, card_start_change_trip_minutes_s.month,
card_start_change_trip_minutes_s.year, card_start_change_trip_minutes_s.year,
@@ -1170,7 +1170,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
//transport //transport
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
break; break;
} }
@@ -1207,7 +1207,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2019); 2019);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Valid to: %02d.%02d.%04d\n", "Valid to: %02d.%02d.%04d",
card_use_to_date_s.day, card_use_to_date_s.day,
card_use_to_date_s.month, card_use_to_date_s.month,
card_use_to_date_s.year); card_use_to_date_s.year);
@@ -1221,7 +1221,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2019); //-time 2019); //-time
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"Trip from: %02d.%02d.%04d %02d:%02d\n", "\nTrip from: %02d.%02d.%04d %02d:%02d",
card_start_trip_minutes_s.day, card_start_trip_minutes_s.day,
card_start_trip_minutes_s.month, card_start_trip_minutes_s.month,
card_start_trip_minutes_s.year, card_start_trip_minutes_s.year,
@@ -1238,7 +1238,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
2019); 2019);
furi_string_cat_printf( furi_string_cat_printf(
result, result,
"(M) from: %02d.%02d.%04d %02d:%02d\n", "\n(M) from: %02d.%02d.%04d %02d:%02d",
card_start_trip_m_minutes_s.day, card_start_trip_m_minutes_s.day,
card_start_trip_m_minutes_s.month, card_start_trip_m_minutes_s.month,
card_start_trip_m_minutes_s.year, card_start_trip_m_minutes_s.year,
@@ -1248,7 +1248,7 @@ bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString*
//transport //transport
//validator //validator
if(data_block.validator) { if(data_block.validator) {
furi_string_cat_printf(result, "Validator: %05d", data_block.validator); furi_string_cat_printf(result, "\nValidator: %05d", data_block.validator);
} }
break; break;
} }

View File

@@ -59,6 +59,29 @@ static const MfClassicKeyPair plantain_4k_keys[] = {
{.a = 0xb27addfb64b0, .b = 0x152fd0c420a7}, {.a = 0x7259fa0197c6, .b = 0x5583698df085}, {.a = 0xb27addfb64b0, .b = 0x152fd0c420a7}, {.a = 0x7259fa0197c6, .b = 0x5583698df085},
}; };
static const MfClassicKeyPair plantain_4k_keys_legacy[] = {
{.a = 0xffffffffffff, .b = 0xffffffffffff}, {.a = 0xffffffffffff, .b = 0xffffffffffff},
{.a = 0xffffffffffff, .b = 0xffffffffffff}, {.a = 0xffffffffffff, .b = 0xffffffffffff},
{.a = 0xe56ac127dd45, .b = 0x19fc84a3784b}, {.a = 0x77dabc9825e1, .b = 0x9764fec3154a},
{.a = 0xffffffffffff, .b = 0xffffffffffff}, {.a = 0xffffffffffff, .b = 0xffffffffffff},
{.a = 0x26973ea74321, .b = 0xd27058c6e2c7}, {.a = 0xeb0a8ff88ade, .b = 0x578a9ada41e3},
{.a = 0xea0fd73cb149, .b = 0x29c35fa068fb}, {.a = 0xc76bf71a2509, .b = 0x9ba241db3f56},
{.a = 0xacffffffffff, .b = 0x71f3a315ad26}, {.a = 0xffffffffffff, .b = 0xffffffffffff},
{.a = 0xffffffffffff, .b = 0xffffffffffff}, {.a = 0xffffffffffff, .b = 0xffffffffffff},
{.a = 0x72f96bdd3714, .b = 0x462225cd34cf}, {.a = 0x044ce1872bc3, .b = 0x8c90c70cff4a},
{.a = 0xbc2d1791dec1, .b = 0xca96a487de0b}, {.a = 0x8791b2ccb5c4, .b = 0xc956c3b80da3},
{.a = 0x8e26e45e7d65, .b = 0x8e65b3af7d22}, {.a = 0x0f318130ed18, .b = 0x0c420a20e056},
{.a = 0x045ceca15535, .b = 0x31bec3d9e510}, {.a = 0x9d993c5d4ef4, .b = 0x86120e488abf},
{.a = 0xc65d4eaa645b, .b = 0xb69d40d1a439}, {.a = 0x46d78e850a7e, .b = 0xa470f8130991},
{.a = 0x42e9b54e51ab, .b = 0x0231b86df52e}, {.a = 0x0f01ceff2742, .b = 0x6fec74559ca7},
{.a = 0xb81f2b0c2f66, .b = 0xa7e2d95f0003}, {.a = 0x9ea3387a63c1, .b = 0x437e59f57561},
{.a = 0x0eb23cc8110b, .b = 0x04dc35277635}, {.a = 0xbc4580b7f20b, .b = 0xd0a4131fb290},
{.a = 0x7a396f0d633d, .b = 0xad2bdc097023}, {.a = 0xa3faa6daff67, .b = 0x7600e889adf9},
{.a = 0xfd8705e721b0, .b = 0x296fc317a513}, {.a = 0x22052b480d11, .b = 0xe19504c39461},
{.a = 0xa7141147d430, .b = 0xff16014fefc7}, {.a = 0x8a8d88151a00, .b = 0x038b5f9b5a2a},
{.a = 0xb27addfb64b0, .b = 0x152fd0c420a7}, {.a = 0x7259fa0197c6, .b = 0x5583698df085},
};
static bool plantain_get_card_config(PlantainCardConfig* config, MfClassicType type) { static bool plantain_get_card_config(PlantainCardConfig* config, MfClassicType type) {
bool success = true; bool success = true;
@@ -125,6 +148,21 @@ static bool plantain_read(Nfc* nfc, NfcDevice* device) {
PlantainCardConfig cfg = {}; PlantainCardConfig cfg = {};
if(!plantain_get_card_config(&cfg, data->type)) break; if(!plantain_get_card_config(&cfg, data->type)) break;
const uint8_t legacy_check_sec_num = 26;
const uint8_t legacy_check_block_num =
mf_classic_get_first_block_num_of_sector(legacy_check_sec_num);
MfClassicKey key = {0};
bit_lib_num_to_bytes_be(
plantain_4k_keys_legacy[legacy_check_sec_num].a, COUNT_OF(key.data), key.data);
error = mf_classic_poller_sync_auth(
nfc, legacy_check_block_num, &key, MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) {
FURI_LOG_D(TAG, "Legacy keys detected");
cfg.keys = plantain_4k_keys_legacy;
}
MfClassicDeviceKeys keys = {}; MfClassicDeviceKeys keys = {};
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) { for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data); bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);

View File

@@ -211,11 +211,11 @@ static bool troika_parse(const NfcDevice* device, FuriString* parsed_data) {
if(result2) { if(result2) {
furi_string_cat_printf( furi_string_cat_printf(
parsed_data, "\e#Ediniy\n%s\n", furi_string_get_cstr(ground_result)); parsed_data, "\n\e#Ediniy\n%s\n", furi_string_get_cstr(ground_result));
} }
if(result3) { if(result3) {
furi_string_cat_printf(parsed_data, "\e#TAT\n%s\n", furi_string_get_cstr(tat_result)); furi_string_cat_printf(parsed_data, "\n\e#TAT\n%s", furi_string_get_cstr(tat_result));
} }
furi_string_free(tat_result); furi_string_free(tat_result);

View File

@@ -73,13 +73,11 @@ static void menu_centered_icon(
size_t y, size_t y,
size_t width, size_t width,
size_t height) { size_t height) {
if(item->icon) { canvas_draw_icon_animation(
canvas_draw_icon_animation( canvas,
canvas, x + (width - item->icon->icon->width) / 2,
x + (width - item->icon->icon->width) / 2, y + (height - item->icon->icon->height) / 2,
y + (height - item->icon->icon->height) / 2, item->icon);
item->icon);
}
} }
static size_t menu_scroll_counter(MenuModel* model, bool selected) { static size_t menu_scroll_counter(MenuModel* model, bool selected) {
@@ -482,8 +480,8 @@ static void menu_enter(void* context) {
menu->view, menu->view,
MenuModel * model, MenuModel * model,
{ {
MenuItem* item = MenuItemArray_get(model->items, model->position); if(MenuItemArray_size(model->items)) {
if(item && item->icon) { MenuItem* item = MenuItemArray_get(model->items, model->position);
icon_animation_start(item->icon); icon_animation_start(item->icon);
} }
model->scroll_counter = 0; model->scroll_counter = 0;
@@ -498,14 +496,9 @@ static void menu_exit(void* context) {
menu->view, menu->view,
MenuModel * model, MenuModel * model,
{ {
// If menu_reset() is called before view exit, model->items is reset if(MenuItemArray_size(model->items)) {
// But for some reason, even with size 0, array get() returns a non-null pointer?
// MLIB docs have no mention of out of bounds condition, seems weird
if(model->position < MenuItemArray_size(model->items)) {
MenuItem* item = MenuItemArray_get(model->items, model->position); MenuItem* item = MenuItemArray_get(model->items, model->position);
if(item && item->icon) { icon_animation_stop(item->icon);
icon_animation_stop(item->icon);
}
} }
}, },
false); false);
@@ -608,14 +601,10 @@ void menu_set_selected_item(Menu* menu, uint32_t index) {
model->scroll_counter = 0; model->scroll_counter = 0;
MenuItem* item = MenuItemArray_get(model->items, model->position); MenuItem* item = MenuItemArray_get(model->items, model->position);
if(item && item->icon) { icon_animation_stop(item->icon);
icon_animation_stop(item->icon);
}
item = MenuItemArray_get(model->items, index); item = MenuItemArray_get(model->items, index);
if(item && item->icon) { icon_animation_start(item->icon);
icon_animation_start(item->icon);
}
model->position = index; model->position = index;
} }
@@ -836,7 +825,7 @@ static void menu_process_ok(Menu* menu) {
menu->view, menu->view,
MenuModel * model, MenuModel * model,
{ {
if(model->position < MenuItemArray_size(model->items)) { if(MenuItemArray_size(model->items)) {
item = MenuItemArray_get(model->items, model->position); item = MenuItemArray_get(model->items, model->position);
} }
}, },

View File

@@ -7,6 +7,10 @@
#define TAG "Iso14443_4aPoller" #define TAG "Iso14443_4aPoller"
#define ISO14443_4A_FSDI_256 (0x8U) #define ISO14443_4A_FSDI_256 (0x8U)
#define ISO14443_4A_FWT_MAX (4096UL << 14)
#define ISO14443_4A_WTXM_MASK (0x3FU)
#define ISO14443_4A_WTXM_MAX (0x3BU)
#define ISO14443_4A_SWTX (0xF2U)
#define ISO14443_4A_SEND_BLOCK_MAX_ATTEMPTS (20) #define ISO14443_4A_SEND_BLOCK_MAX_ATTEMPTS (20)
Iso14443_4aError iso14443_4a_poller_halt(Iso14443_4aPoller* instance) { Iso14443_4aError iso14443_4a_poller_halt(Iso14443_4aPoller* instance) {
@@ -75,9 +79,35 @@ Iso14443_4aError iso14443_4a_poller_send_block(
if(iso14443_3a_error != Iso14443_3aErrorNone) { if(iso14443_3a_error != Iso14443_3aErrorNone) {
error = iso14443_4a_process_error(iso14443_3a_error); error = iso14443_4a_process_error(iso14443_3a_error);
break; break;
}
} else if(!iso14443_4_layer_decode_block( if(bit_buffer_starts_with_byte(instance->rx_buffer, ISO14443_4A_SWTX)) {
instance->iso14443_4_layer, rx_buffer, instance->rx_buffer)) { do {
uint8_t wtxm = bit_buffer_get_byte(instance->rx_buffer, 1) & ISO14443_4A_WTXM_MASK;
if(wtxm > ISO14443_4A_WTXM_MAX) {
return Iso14443_4aErrorProtocol;
}
bit_buffer_reset(instance->tx_buffer);
bit_buffer_copy_left(instance->tx_buffer, instance->rx_buffer, 1);
bit_buffer_append_byte(instance->tx_buffer, wtxm);
iso14443_3a_error = iso14443_3a_poller_send_standard_frame(
instance->iso14443_3a_poller,
instance->tx_buffer,
instance->rx_buffer,
MAX(iso14443_4a_get_fwt_fc_max(instance->data) * wtxm, ISO14443_4A_FWT_MAX));
if(iso14443_3a_error != Iso14443_3aErrorNone) {
error = iso14443_4a_process_error(iso14443_3a_error);
return error;
}
} while(bit_buffer_starts_with_byte(instance->rx_buffer, ISO14443_4A_SWTX));
}
if(!iso14443_4_layer_decode_block(
instance->iso14443_4_layer, rx_buffer, instance->rx_buffer)) {
error = Iso14443_4aErrorProtocol; error = Iso14443_4aErrorProtocol;
break; break;
} }