libnfc/utils/mfcuk_finger.c
Xavier AVERBOUCH d5bbda3d67 added mfcuk + fix compil on Visaul studio 2022 (via Cmake)
mfcuk  added to utils
cmakelist modified
acr122_usb.C et pn53x_usb.c modified to remove errors when compiling on Visual Studio 2022 on Windows
2022-11-01 21:07:44 +01:00

188 lines
5.1 KiB
C

/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_finger.c
Description:
MFCUK fingerprinting and specific data-decoding functionality.
License:
GPL2, Copyright (C) 2009, Andrei Costin
* @file mfcuk_finger.c
* @brief MFCUK fingerprinting and specific data-decoding functionality.
* @todo add proper error codes
*/
#include "mfcuk_finger.h"
mfcuk_finger_tmpl_entry mfcuk_finger_db[] = {
{ "./data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd", "Sofia SKGT", mfcuk_finger_default_comparator, mfcuk_finger_skgt_decoder, NULL },
{ "./data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd", "Bucharest RATB", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
{ "./data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd", "London OYSTER", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
};
int mfcuk_finger_db_entries = sizeof(mfcuk_finger_db) / sizeof(mfcuk_finger_db[0]);
int mfcuk_finger_default_decoder(mifare_classic_tag *dump)
{
if (!dump) {
fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
return 0;
}
printf("UID:\t%02x%02x%02x%02x\n", dump->amb[0].mbm.abtUID[0], dump->amb[0].mbm.abtUID[1], dump->amb[0].mbm.abtUID[2], dump->amb[0].mbm.abtUID[3]);
printf("TYPE:\t%02x\n", dump->amb[0].mbm.btSAK);
return 1;
}
// Yes, I know C++ class inheritance would perfectly fit the decoders/comparators... Though C is more to my heart. Anyone to rewrite in C++?
int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump)
{
if (!dump) {
fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
return 0;
}
printf("Bulgaria/Sofia/SKGT public transport card information decoder (info credits to Andy)\n");
mfcuk_finger_default_decoder(dump);
printf("LAST TRAVEL DATA\n");
// TODO: get proper information
return 1;
}
int mfcuk_finger_default_comparator(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score)
{
int max_bytes = 0;
int i;
int num_bytes_tomatch = 0;
int num_bytes_matched = 0;
if ((!dump) || (!tmpl) || (!score)) {
return 0;
}
if (IS_MIFARE_CLASSIC_1K_TAG(dump)) {
max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_1K_MAX_BLOCKS;
} else if (IS_MIFARE_CLASSIC_4K_TAG(dump)) {
max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_4K_MAX_BLOCKS;
} else {
return 0;
}
for (i = 0; i < max_bytes; i++) {
if (((char *)(&tmpl->mask))[i] == 0x0) {
continue;
}
num_bytes_tomatch++;
if (((char *)(&tmpl->values))[i] == ((char *)dump)[i]) {
num_bytes_matched++;
}
}
if (num_bytes_tomatch == 0) {
return 0;
} else {
*score = (float)(num_bytes_matched) / num_bytes_tomatch;
}
return 1;
}
int mfcuk_finger_load(void)
{
int i;
mifare_classic_tag mask;
mifare_classic_tag values;
FILE *fp = NULL;
size_t result = 0;
mfcuk_finger_template *tmpl_new = NULL;
int template_loaded_count = 0;
for (i = 0; i < mfcuk_finger_db_entries; i++) {
fp = fopen(mfcuk_finger_db[i].tmpl_filename, "rb");
if (!fp) {
fprintf(stderr, "WARN: cannot open template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
continue;
}
// If not read exactly 1 record, something is wrong
if ((result = fread((void *)(&mask), sizeof(mask), 1, fp)) != 1) {
fprintf(stderr, "WARN: cannot read MASK from template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
fclose(fp);
continue;
}
// If not read exactly 1 record, something is wrong
if ((result = fread((void *)(&values), sizeof(values), 1, fp)) != 1) {
fprintf(stderr, "WARN: cannot read VALUES template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
fclose(fp);
continue;
}
if (mfcuk_finger_db[i].tmpl_data == NULL) {
if ((tmpl_new = (mfcuk_finger_template *) malloc(sizeof(mfcuk_finger_template))) == NULL) {
fprintf(stderr, "WARN: cannot allocate memory to template record %d\n", i);
fclose(fp);
continue;
}
memcpy(&(tmpl_new->mask), &(mask), sizeof(mask));
memcpy(&(tmpl_new->values), &(values), sizeof(values));
mfcuk_finger_db[i].tmpl_data = tmpl_new;
template_loaded_count++;
}
if (fp) {
fclose(fp);
fp = NULL;
}
}
return template_loaded_count;
}
int mfcuk_finger_unload(void)
{
int i;
for (i = 0; i < mfcuk_finger_db_entries; i++) {
if (mfcuk_finger_db[i].tmpl_data != NULL) {
free(mfcuk_finger_db[i].tmpl_data);
mfcuk_finger_db[i].tmpl_data = NULL;
}
}
return 1;
}