mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-22 20:43:07 +00:00
kinda parser refactor. datetime format added
This commit is contained in:
parent
ae160efa16
commit
b6a6528526
7 changed files with 134 additions and 136 deletions
|
@ -24,8 +24,8 @@
|
|||
#include <lib/nfc/protocols/mf_desfire/mf_desfire.h>
|
||||
|
||||
#include <bit_lib.h>
|
||||
#include <applications/services/locale/locale.h>
|
||||
#include <datetime.h>
|
||||
#include <locale/locale.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
//
|
||||
|
@ -173,7 +173,6 @@ static void furi_string_cat_timestamp(
|
|||
const char* date_hdr,
|
||||
const char* time_hdr,
|
||||
uint32_t tmst_1900);
|
||||
static void epoch_1900_datetime_to_furi(uint32_t seconds, DateTime* out);
|
||||
static bool get_file_contents(
|
||||
const MfDesfireApplication* app,
|
||||
const MfDesfireFileId* id,
|
||||
|
@ -530,7 +529,7 @@ static void furi_string_cat_timestamp(
|
|||
uint32_t tmst_1900) {
|
||||
DateTime tm;
|
||||
|
||||
epoch_1900_datetime_to_furi(tmst_1900, &tm);
|
||||
datetime_timestamp_to_datetime(tmst_1900, &tm);
|
||||
|
||||
FuriString* date_str = furi_string_alloc();
|
||||
locale_format_date(date_str, &tm, locale_get_date_format(), "-");
|
||||
|
@ -550,57 +549,6 @@ static void furi_string_cat_timestamp(
|
|||
furi_string_free(time_str);
|
||||
}
|
||||
|
||||
// Convert a "1900"-based timestamp to Furi time, assuming a UTC/GMT timezone.
|
||||
static void epoch_1900_datetime_to_furi(uint32_t seconds, DateTime* out) {
|
||||
uint16_t year, month, day, hour, minute, second;
|
||||
|
||||
// Calculate absolute number of days elapsed since the 1900 epoch
|
||||
// and save the residual for the time within the day.
|
||||
uint32_t absolute_days = seconds / 86400;
|
||||
uint32_t seconds_within_day = seconds % 86400;
|
||||
|
||||
// Calculate day of the week.
|
||||
// January 1, 1900 was a Monday ("day of week" = 1)
|
||||
uint8_t dow = (absolute_days + 1) % 7;
|
||||
|
||||
//
|
||||
// Compute the date by simply marching through time in as large chunks
|
||||
// as possible.
|
||||
//
|
||||
|
||||
for(year = 1900;; year++) {
|
||||
uint16_t year_days = datetime_get_days_per_year(year);
|
||||
if(absolute_days >= year_days)
|
||||
absolute_days -= year_days;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_leap = datetime_is_leap_year(year);
|
||||
|
||||
for(month = 1;; month++) {
|
||||
uint8_t days_in_month = datetime_get_days_per_month(is_leap, month);
|
||||
if(absolute_days >= days_in_month)
|
||||
absolute_days -= days_in_month;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
day = absolute_days + 1;
|
||||
hour = seconds_within_day / 3600;
|
||||
uint16_t sub_hour = seconds_within_day % 3600;
|
||||
minute = sub_hour / 60;
|
||||
second = sub_hour % 60;
|
||||
|
||||
out->year = year;
|
||||
out->month = month;
|
||||
out->day = day;
|
||||
out->hour = hour;
|
||||
out->minute = minute;
|
||||
out->second = second;
|
||||
out->weekday = dow;
|
||||
}
|
||||
|
||||
/* Actual implementation of app<>plugin interface */
|
||||
static const NfcSupportedCardsPlugin clipper_plugin = {
|
||||
.protocol = NfcProtocolMfDesfire,
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "protocols/emv/emv.h"
|
||||
#include "helpers/nfc_emv_parser.h"
|
||||
|
||||
#include <bit_lib.h>
|
||||
#include <datetime.h>
|
||||
#include <locale/locale.h>
|
||||
|
||||
#define TAG "EMV"
|
||||
|
||||
bool emv_get_currency_name(uint16_t cur_code, FuriString* currency_name) {
|
||||
|
@ -96,34 +100,49 @@ static bool emv_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
parsed = true;
|
||||
}
|
||||
|
||||
if(app.effective_month) {
|
||||
char day[] = "--";
|
||||
if(app.effective_day) itoa(app.effective_day, day, 16);
|
||||
if(day[1] == '\0') {
|
||||
day[1] = day[0];
|
||||
day[0] = '0';
|
||||
}
|
||||
bool nevermind = false;
|
||||
DateTime effective_datetime = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
bit_lib_bytes_to_num_bcd(&app.effective_day, 1, &nevermind),
|
||||
bit_lib_bytes_to_num_bcd(&app.effective_month, 1, &nevermind),
|
||||
2000 + bit_lib_bytes_to_num_bcd(&app.effective_year, 1, &nevermind),
|
||||
0};
|
||||
DateTime expiration_datetime = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
bit_lib_bytes_to_num_bcd(&app.exp_day, 1, &nevermind),
|
||||
bit_lib_bytes_to_num_bcd(&app.exp_month, 1, &nevermind),
|
||||
2000 + bit_lib_bytes_to_num_bcd(&app.exp_year, 1, &nevermind),
|
||||
0};
|
||||
|
||||
LocaleDateFormat date_format = locale_get_date_format();
|
||||
const char* separator = (date_format == LocaleDateFormatDMY) ? "." : "/";
|
||||
|
||||
FuriString* effective_date_str = furi_string_alloc();
|
||||
locale_format_date(effective_date_str, &effective_datetime, date_format, separator);
|
||||
|
||||
FuriString* expiration_date_str = furi_string_alloc();
|
||||
locale_format_date(expiration_date_str, &expiration_datetime, date_format, separator);
|
||||
|
||||
if(app.effective_month) {
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"Effective: %s.%02X.20%02X\n",
|
||||
day,
|
||||
app.effective_month,
|
||||
app.effective_year);
|
||||
"Effective: %s\n",
|
||||
app.effective_day ? furi_string_get_cstr(effective_date_str) :
|
||||
furi_string_get_cstr(effective_date_str) + 3);
|
||||
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
if(app.exp_month) {
|
||||
char day[] = "--";
|
||||
if(app.exp_day) itoa(app.exp_day, day, 16);
|
||||
if(day[1] == '\0') {
|
||||
day[1] = day[0];
|
||||
day[0] = '0';
|
||||
}
|
||||
|
||||
furi_string_cat_printf(
|
||||
parsed_data, "Expires: %s.%02X.20%02X\n", day, app.exp_month, app.exp_year);
|
||||
parsed_data,
|
||||
"Expires: %s\n",
|
||||
app.exp_day ? furi_string_get_cstr(expiration_date_str) :
|
||||
furi_string_get_cstr(expiration_date_str) + 3);
|
||||
|
||||
parsed = true;
|
||||
}
|
||||
|
@ -154,6 +173,10 @@ static bool emv_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
|
||||
if(!parsed) furi_string_cat_printf(parsed_data, "No data was parsed\n");
|
||||
|
||||
furi_string_free(str);
|
||||
furi_string_free(effective_date_str);
|
||||
furi_string_free(expiration_date_str);
|
||||
|
||||
parsed = true;
|
||||
} while(false);
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ static bool itso_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
|
||||
DateTime timestamp = {0};
|
||||
datetime_timestamp_to_datetime(unixTimestamp, ×tamp);
|
||||
|
||||
FuriString* timestamp_str = furi_string_alloc();
|
||||
locale_format_date(timestamp_str, ×tamp, locale_get_date_format(), "-");
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <bit_lib.h>
|
||||
#include <datetime.h>
|
||||
#include <locale/locale.h>
|
||||
|
||||
#define TAG "Kazan"
|
||||
|
||||
|
@ -317,74 +318,75 @@ static bool kazan_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
furi_string_cat_printf(
|
||||
parsed_data, "\e#Kazan transport card\nCard number: %lu\n", card_number);
|
||||
|
||||
LocaleDateFormat date_format = locale_get_date_format();
|
||||
const char* separator = (date_format == LocaleDateFormatDMY) ? "." : "/";
|
||||
|
||||
FuriString* valid_from_str = furi_string_alloc();
|
||||
locale_format_date(valid_from_str, &valid_from, date_format, separator);
|
||||
|
||||
FuriString* valid_to_str = furi_string_alloc();
|
||||
locale_format_date(valid_to_str, &valid_to, date_format, separator);
|
||||
|
||||
FuriString* last_trip_date_str = furi_string_alloc();
|
||||
locale_format_date(last_trip_date_str, &last_trip, date_format, separator);
|
||||
|
||||
FuriString* last_trip_time_str = furi_string_alloc();
|
||||
locale_format_time(last_trip_time_str, &last_trip, locale_get_time_format(), false);
|
||||
|
||||
if(subscription_type == SUBSCRIPTION_TYPE_PURSE) {
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"Type: purse\nBalance: %lu RUR\nBalance valid:\nfrom: %02u.%02u.%u\nto: %02u.%02u.%u",
|
||||
"Type: purse\nBalance: %lu RUR\nBalance valid:\nfrom: %s\nto: %s",
|
||||
trip_counter,
|
||||
valid_from.day,
|
||||
valid_from.month,
|
||||
valid_from.year,
|
||||
valid_to.day,
|
||||
valid_to.month,
|
||||
valid_to.year);
|
||||
furi_string_get_cstr(valid_from_str),
|
||||
furi_string_get_cstr(valid_to_str));
|
||||
}
|
||||
|
||||
if(subscription_type == SUBSCRIPTION_TYPE_ABONNEMENT_BY_TRIPS) {
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"Type: abonnement\nTariff: %s\nTrips left: %lu\nCard valid:\nfrom: %02u.%02u.%u\nto: %02u.%02u.%u",
|
||||
"Type: abonnement\nTariff: %s\nTrips left: %lu\nCard valid:\nfrom: %s\nto: %s",
|
||||
furi_string_get_cstr(tariff_name),
|
||||
trip_counter,
|
||||
valid_from.day,
|
||||
valid_from.month,
|
||||
valid_from.year,
|
||||
valid_to.day,
|
||||
valid_to.month,
|
||||
valid_to.year);
|
||||
furi_string_get_cstr(valid_from_str),
|
||||
furi_string_get_cstr(valid_to_str));
|
||||
}
|
||||
|
||||
if(subscription_type == SUBSCRIPTION_TYPE_ABONNEMENT_BY_TIME) {
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"Type: abonnement\nTariff: %s\nTotal valid time: %lu days\nCard valid:\nfrom: %02u.%02u.%u\nto: %02u.%02u.%u",
|
||||
"Type: abonnement\nTariff: %s\nTotal valid time: %lu days\nCard valid:\nfrom: %s\nto: %s",
|
||||
furi_string_get_cstr(tariff_name),
|
||||
trip_counter,
|
||||
valid_from.day,
|
||||
valid_from.month,
|
||||
valid_from.year,
|
||||
valid_to.day,
|
||||
valid_to.month,
|
||||
valid_to.year);
|
||||
furi_string_get_cstr(valid_from_str),
|
||||
furi_string_get_cstr(valid_to_str));
|
||||
}
|
||||
|
||||
if(subscription_type == SUBSCRIPTION_TYPE_UNKNOWN) {
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"Type: unknown\nTariff: %s\nCounter: %lu\nValid from: %02u.%02u.%u\nValid to: %02u.%02u.%u",
|
||||
"Type: unknown\nTariff: %s\nCounter: %lu\nValid from: %s\nValid to: %s",
|
||||
furi_string_get_cstr(tariff_name),
|
||||
trip_counter,
|
||||
valid_from.day,
|
||||
valid_from.month,
|
||||
valid_from.year,
|
||||
valid_to.day,
|
||||
valid_to.month,
|
||||
valid_to.year);
|
||||
furi_string_get_cstr(valid_from_str),
|
||||
furi_string_get_cstr(valid_to_str));
|
||||
}
|
||||
|
||||
if(is_last_trip_valid) {
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\nLast trip: %02u.%02u.%u at %02u:%02u",
|
||||
last_trip.day,
|
||||
last_trip.month,
|
||||
last_trip.year,
|
||||
last_trip.hour,
|
||||
last_trip.minute);
|
||||
"\nLast trip: %s at %s",
|
||||
furi_string_get_cstr(last_trip_date_str),
|
||||
furi_string_get_cstr(last_trip_time_str));
|
||||
}
|
||||
|
||||
furi_string_free(tariff_name);
|
||||
|
||||
furi_string_free(valid_from_str);
|
||||
furi_string_free(valid_to_str);
|
||||
furi_string_free(last_trip_date_str);
|
||||
furi_string_free(last_trip_time_str);
|
||||
|
||||
parsed = true;
|
||||
} while(false);
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ static_assert(sizeof(OpalFile) == 16, "OpalFile");
|
|||
//
|
||||
// Opal measures days since 1980-01-01 and minutes since midnight, and presumes
|
||||
// all days are 1440 minutes.
|
||||
static void opal_date_time_to_furi(uint16_t days, uint16_t minutes, DateTime* out) {
|
||||
static void opal_days_minutes_to_datetime(uint16_t days, uint16_t minutes, DateTime* out) {
|
||||
out->year = 1980;
|
||||
out->month = 1;
|
||||
// 1980-01-01 is a Tuesday
|
||||
|
@ -155,7 +155,7 @@ static bool opal_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
const int32_t balance_dollars = balance / 100;
|
||||
|
||||
DateTime timestamp;
|
||||
opal_date_time_to_furi(opal_file->days, opal_file->minutes, ×tamp);
|
||||
opal_days_minutes_to_datetime(opal_file->days, opal_file->minutes, ×tamp);
|
||||
|
||||
// Usages 4..6 associated with the Manly Ferry, which correspond to
|
||||
// usages 1..3 for other modes.
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <bit_lib.h>
|
||||
#include <datetime.h>
|
||||
#include <locale/locale.h>
|
||||
|
||||
#define TAG "Umarsh"
|
||||
|
||||
|
@ -91,6 +92,19 @@ static bool umarsh_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
bool is_last_refill_datetime_valid =
|
||||
parse_datetime(last_refill_date, &last_refill_datetime);
|
||||
|
||||
LocaleDateFormat date_format = locale_get_date_format();
|
||||
const char* separator = (date_format == LocaleDateFormatDMY) ? "." : "/";
|
||||
|
||||
FuriString* expiry_datetime_str = furi_string_alloc();
|
||||
locale_format_date(expiry_datetime_str, &expiry_datetime, date_format, separator);
|
||||
|
||||
FuriString* valid_to_datetime_str = furi_string_alloc();
|
||||
locale_format_date(valid_to_datetime_str, &valid_to_datetime, date_format, separator);
|
||||
|
||||
FuriString* last_refill_datetime_str = furi_string_alloc();
|
||||
locale_format_date(
|
||||
last_refill_datetime_str, &last_refill_datetime, date_format, separator);
|
||||
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\e#Umarsh\nCard number: %lu\nRegion: %02u\nTerminal number: %lu\nRefill counter: %u\nBalance: %u.%02u RUR",
|
||||
|
@ -103,25 +117,17 @@ static bool umarsh_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||
|
||||
if(is_expiry_datetime_valid)
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\nExpires: %02u.%02u.%u",
|
||||
expiry_datetime.day,
|
||||
expiry_datetime.month,
|
||||
expiry_datetime.year);
|
||||
parsed_data, "\nExpires: %s", furi_string_get_cstr(expiry_datetime_str));
|
||||
if(is_valid_to_datetime_valid)
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\nValid to: %02u.%02u.%u",
|
||||
valid_to_datetime.day,
|
||||
valid_to_datetime.month,
|
||||
valid_to_datetime.year);
|
||||
parsed_data, "\nValid to: %s", furi_string_get_cstr(valid_to_datetime_str));
|
||||
if(is_last_refill_datetime_valid)
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\nLast refill: %02u.%02u.%u",
|
||||
last_refill_datetime.day,
|
||||
last_refill_datetime.month,
|
||||
last_refill_datetime.year);
|
||||
parsed_data, "\nLast refill: %s", furi_string_get_cstr(last_refill_datetime_str));
|
||||
|
||||
furi_string_free(expiry_datetime_str);
|
||||
furi_string_free(valid_to_datetime_str);
|
||||
furi_string_free(last_refill_datetime_str);
|
||||
|
||||
parsed = true;
|
||||
} while(false);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "protocols/mf_classic/mf_classic.h"
|
||||
|
||||
#include <bit_lib.h>
|
||||
#include <locale/locale.h>
|
||||
#include <furi_hal_rtc.h>
|
||||
|
||||
#define TAG "Zolotaya Korona"
|
||||
|
@ -124,6 +125,23 @@ static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_da
|
|||
uint32_t balance_rub = balance / 100;
|
||||
uint8_t balance_kop = balance % 100;
|
||||
|
||||
LocaleDateFormat date_format = locale_get_date_format();
|
||||
const char* separator = (date_format == LocaleDateFormatDMY) ? "." : "/";
|
||||
|
||||
FuriString* last_refill_date_str = furi_string_alloc();
|
||||
locale_format_date(last_refill_date_str, &last_refill_datetime, date_format, separator);
|
||||
|
||||
FuriString* last_refill_time_str = furi_string_alloc();
|
||||
locale_format_time(
|
||||
last_refill_time_str, &last_refill_datetime, locale_get_time_format(), false);
|
||||
|
||||
FuriString* last_trip_date_str = furi_string_alloc();
|
||||
locale_format_date(last_trip_date_str, &last_trip_datetime, date_format, separator);
|
||||
|
||||
FuriString* last_trip_time_str = furi_string_alloc();
|
||||
locale_format_time(
|
||||
last_trip_time_str, &last_trip_datetime, locale_get_time_format(), false);
|
||||
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\e#Zolotaya korona\nCard number: %u%015llu\nRegion: %u\nBalance: %lu.%02u RUR\nPrev. balance: %lu.%02u RUR",
|
||||
|
@ -137,25 +155,19 @@ static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_da
|
|||
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\nLast refill amount: %lu.%02u RUR\nRefill counter: %u\nLast refill: %u.%02u.%02u %02u:%02u\nRefill machine id: %u",
|
||||
"\nLast refill amount: %lu.%02u RUR\nRefill counter: %u\nLast refill: %s at %s\nRefill machine id: %u",
|
||||
last_refill_amount_rub,
|
||||
last_refill_amount_kop,
|
||||
refill_counter,
|
||||
last_refill_datetime.day,
|
||||
last_refill_datetime.month,
|
||||
last_refill_datetime.year,
|
||||
last_refill_datetime.hour,
|
||||
last_refill_datetime.minute,
|
||||
furi_string_get_cstr(last_refill_date_str),
|
||||
furi_string_get_cstr(last_refill_time_str),
|
||||
refill_machine_id);
|
||||
|
||||
furi_string_cat_printf(
|
||||
parsed_data,
|
||||
"\nLast trip: %u.%02u.%02u %02u:%02u\nTrack number: %u\nValidator: %c%06lu",
|
||||
last_trip_datetime.day,
|
||||
last_trip_datetime.month,
|
||||
last_trip_datetime.year,
|
||||
last_trip_datetime.hour,
|
||||
last_trip_datetime.minute,
|
||||
"\nLast trip: %s at %s\nTrack number: %u\nValidator: %c%06lu",
|
||||
furi_string_get_cstr(last_trip_date_str),
|
||||
furi_string_get_cstr(last_trip_time_str),
|
||||
track_number,
|
||||
validator_first_letter,
|
||||
validator_id);
|
||||
|
@ -169,6 +181,12 @@ static bool zolotaya_korona_parse(const NfcDevice* device, FuriString* parsed_da
|
|||
discount_code);
|
||||
}
|
||||
|
||||
furi_string_free(last_refill_date_str);
|
||||
furi_string_free(last_refill_time_str);
|
||||
|
||||
furi_string_free(last_trip_date_str);
|
||||
furi_string_free(last_trip_time_str);
|
||||
|
||||
parsed = true;
|
||||
} while(false);
|
||||
|
||||
|
|
Loading…
Reference in a new issue