mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-11-25 23:05:30 +03:00
NFC: Plaintain parser fix
by mxcdoam https://github.com/flipperdevices/flipperzero-firmware/pull/3975/files
This commit is contained in:
parent
e87356af72
commit
ed57ddb14b
@ -201,8 +201,9 @@ static bool plantain_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
|
|
||||||
static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
|
static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
|
||||||
furi_assert(device);
|
furi_assert(device);
|
||||||
|
size_t uid_len = 0;
|
||||||
const MfClassicData* data = nfc_device_get_data(device, NfcProtocolMfClassic);
|
const MfClassicData* data = nfc_device_get_data(device, NfcProtocolMfClassic);
|
||||||
|
const uint8_t* uid = mf_classic_get_uid(data, &uid_len);
|
||||||
|
|
||||||
bool parsed = false;
|
bool parsed = false;
|
||||||
|
|
||||||
@ -220,12 +221,30 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||||||
if(key != cfg.keys[cfg.data_sector].a) break;
|
if(key != cfg.keys[cfg.data_sector].a) break;
|
||||||
|
|
||||||
furi_string_printf(parsed_data, "\e#Plantain card\n");
|
furi_string_printf(parsed_data, "\e#Plantain card\n");
|
||||||
|
|
||||||
|
const uint8_t* temp_ptr = &uid[0];
|
||||||
|
|
||||||
|
// UID is read from last to first byte
|
||||||
|
uint8_t card_number_tmp[uid_len];
|
||||||
|
|
||||||
|
if(uid_len == 4) {
|
||||||
|
for(size_t i = 0; i < 4; i++) {
|
||||||
|
card_number_tmp[i] = temp_ptr[3 - i];
|
||||||
|
}
|
||||||
|
} else if(uid_len == 7) {
|
||||||
|
for(size_t i = 0; i < 7; i++) {
|
||||||
|
card_number_tmp[i] = temp_ptr[6 - i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//UID is converted to a card number
|
||||||
uint64_t card_number = 0;
|
uint64_t card_number = 0;
|
||||||
for(size_t i = 0; i < 7; i++) {
|
for(size_t i = 0; i < uid_len; i++) {
|
||||||
card_number = (card_number << 8) | data->block[0].data[6 - i];
|
card_number = (card_number << 8) | card_number_tmp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print card number with 4-digit groups
|
// Print card number with 4-digit groups. "3" in "3078" denotes a ticket type "3 - full ticket", will differ on discounted cards.
|
||||||
furi_string_cat_printf(parsed_data, "Number: ");
|
furi_string_cat_printf(parsed_data, "Number: ");
|
||||||
FuriString* card_number_s = furi_string_alloc();
|
FuriString* card_number_s = furi_string_alloc();
|
||||||
furi_string_cat_printf(card_number_s, "%llu", card_number);
|
furi_string_cat_printf(card_number_s, "%llu", card_number);
|
||||||
@ -237,6 +256,7 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||||||
furi_string_push_back(tmp_s, ' ');
|
furi_string_push_back(tmp_s, ' ');
|
||||||
}
|
}
|
||||||
furi_string_cat_printf(parsed_data, "%s\n", furi_string_get_cstr(tmp_s));
|
furi_string_cat_printf(parsed_data, "%s\n", furi_string_get_cstr(tmp_s));
|
||||||
|
// this works for 2K Plantain
|
||||||
if(data->type == MfClassicType1k) {
|
if(data->type == MfClassicType1k) {
|
||||||
//balance
|
//balance
|
||||||
uint32_t balance = 0;
|
uint32_t balance = 0;
|
||||||
@ -290,20 +310,70 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||||||
last_payment_date.year,
|
last_payment_date.year,
|
||||||
last_payment_date.hour,
|
last_payment_date.hour,
|
||||||
last_payment_date.minute);
|
last_payment_date.minute);
|
||||||
//payment summ
|
//payment amount. This needs to be investigated more, currently it shows incorrect amount on some cards.
|
||||||
uint16_t last_payment = (data->block[18].data[9] << 8) | data->block[18].data[8];
|
uint16_t last_payment = (data->block[18].data[9] << 8) | data->block[18].data[8];
|
||||||
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment / 100);
|
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment / 100);
|
||||||
furi_string_free(card_number_s);
|
furi_string_free(card_number_s);
|
||||||
furi_string_free(tmp_s);
|
furi_string_free(tmp_s);
|
||||||
|
//This is for 4K Plantains.
|
||||||
} else if(data->type == MfClassicType4k) {
|
} else if(data->type == MfClassicType4k) {
|
||||||
|
//balance
|
||||||
|
uint32_t balance = 0;
|
||||||
|
for(uint8_t i = 0; i < 4; i++) {
|
||||||
|
balance = (balance << 8) | data->block[16].data[3 - i];
|
||||||
|
}
|
||||||
|
furi_string_cat_printf(parsed_data, "Balance: %ld rub\n", balance / 100);
|
||||||
|
|
||||||
//trips
|
//trips
|
||||||
uint8_t trips_metro = data->block[36].data[0];
|
uint8_t trips_metro = data->block[21].data[0];
|
||||||
uint8_t trips_ground = data->block[36].data[1];
|
uint8_t trips_ground = data->block[21].data[1];
|
||||||
furi_string_cat_printf(parsed_data, "Trips: %d\n", trips_metro + trips_ground);
|
furi_string_cat_printf(parsed_data, "Trips: %d\n", trips_metro + trips_ground);
|
||||||
|
//trip time
|
||||||
|
uint32_t last_trip_timestamp = 0;
|
||||||
|
for(uint8_t i = 0; i < 3; i++) {
|
||||||
|
last_trip_timestamp = (last_trip_timestamp << 8) | data->block[21].data[4 - i];
|
||||||
|
}
|
||||||
|
DateTime last_trip = {0};
|
||||||
|
from_minutes_to_datetime(last_trip_timestamp + 24 * 60, &last_trip, 2010);
|
||||||
|
furi_string_cat_printf(
|
||||||
|
parsed_data,
|
||||||
|
"Trip start: %02d.%02d.%04d %02d:%02d\n",
|
||||||
|
last_trip.day,
|
||||||
|
last_trip.month,
|
||||||
|
last_trip.year,
|
||||||
|
last_trip.hour,
|
||||||
|
last_trip.minute);
|
||||||
|
//validator
|
||||||
|
uint16_t validator = (data->block[20].data[5] << 8) | data->block[20].data[4];
|
||||||
|
furi_string_cat_printf(parsed_data, "Validator: %d\n", validator);
|
||||||
|
//tariff
|
||||||
|
uint16_t fare = (data->block[20].data[7] << 8) | data->block[20].data[6];
|
||||||
|
furi_string_cat_printf(parsed_data, "Tariff: %d rub\n", fare / 100);
|
||||||
//trips in metro
|
//trips in metro
|
||||||
furi_string_cat_printf(parsed_data, "Trips (Metro): %d\n", trips_metro);
|
furi_string_cat_printf(parsed_data, "Trips (Metro): %d\n", trips_metro);
|
||||||
//trips on ground
|
//trips on ground
|
||||||
furi_string_cat_printf(parsed_data, "Trips (Ground): %d\n", trips_ground);
|
furi_string_cat_printf(parsed_data, "Trips (Ground): %d\n", trips_ground);
|
||||||
|
//last payment
|
||||||
|
uint32_t last_payment_timestamp = 0;
|
||||||
|
for(uint8_t i = 0; i < 3; i++) {
|
||||||
|
last_payment_timestamp = (last_payment_timestamp << 8) |
|
||||||
|
data->block[18].data[4 - i];
|
||||||
|
}
|
||||||
|
DateTime last_payment_date = {0};
|
||||||
|
from_minutes_to_datetime(last_payment_timestamp + 24 * 60, &last_payment_date, 2010);
|
||||||
|
furi_string_cat_printf(
|
||||||
|
parsed_data,
|
||||||
|
"Last pay: %02d.%02d.%04d %02d:%02d\n",
|
||||||
|
last_payment_date.day,
|
||||||
|
last_payment_date.month,
|
||||||
|
last_payment_date.year,
|
||||||
|
last_payment_date.hour,
|
||||||
|
last_payment_date.minute);
|
||||||
|
//payment amount
|
||||||
|
uint16_t last_payment = (data->block[18].data[9] << 8) | data->block[18].data[8];
|
||||||
|
furi_string_cat_printf(parsed_data, "Amount: %d rub", last_payment / 100);
|
||||||
|
furi_string_free(card_number_s);
|
||||||
|
furi_string_free(tmp_s);
|
||||||
}
|
}
|
||||||
parsed = true;
|
parsed = true;
|
||||||
} while(false);
|
} while(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user