Reply To: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.

Forum MIFARE general topics and applications Basic Tutorial for MIFARE Classic 1K using C#, C++ etc. Reply To: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.

Re: Basic Tutorial for MIFARE Classic 1K using C#, C++ etc.

28. January 2016 at 11:31
Hi mifaresdk,

I use QT Creator opensource to develop my embedded Linux terminal app. I upload my app using Wi-Fi and FileZilla.
My terminal has physical RFID module that I can use this module to write and read Mifare 1K Classic contactless card.
There is also C++ mifare demo example that shows how to read from card and update info to the card. To get better understanding I need some basic information to start. Because there isn’t and documentation for the below example. I can read the code and make some sense out of it. But I am very confuse.
Example shows below code;

This is the main cpp.
DialogMifareCardProgramming::DialogMifareCardProgramming(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogMifareCardProgramming)

{
ui->setupUi(this);

cCard_.openReader();
}

There is a button on initializeForm that connects to the card. I guess……….
void DialogMifareCardProgramming::on_pushButtonConnect_clicked()
{
try
{
cCard_.connect();

initializeControls(true);

if (cCard_._eCardType == CARD_TYPE_MIFARE_1K)
ui->labelStatus->setText("Connected to Mifare 1K");
else if (cCard_._eCardType == CARD_TYPE_MIFARE_4K)
ui->labelStatus->setText("Connected to Mifare 4K");
else
ui->labelStatus->setText("Connected to unknown card");
}
catch(AcsException cExpection)
{
ui->labelStatus->setText(cExpection.sMessage);
initializeControls(false);
}
catch(...)
{
ui->labelStatus->setText("Connection failed");
initializeControls(false);
}
}






This is load key module. I don’t understand what is happening here.

void DialogMifareCardProgramming::on_pushButtonLoadKey_clicked()
{
MIFARE_KEY_STORE eKeyStore;

char aKey[6];
char aAsciiKey[12];
int iCounter = 0;
bool bNumeric = false;

try
{
ui->lineEditKeyStoreNumberInput->text().toInt(&bNumeric);
if (!bNumeric)
{
ui->labelStatus->setText("Invalid key store number");
return;
}

if (ui->lineEditKeyStoreNumberInput->text().toInt() == 0)
eKeyStore = MIFARE_KEY_STORE_0;
else if (ui->lineEditKeyStoreNumberInput->text().toInt() == 1)
eKeyStore = MIFARE_KEY_STORE_1;
else
{
ui->labelStatus->setText("Invalid key store number");
return;
}

if (ui->lineEditKey1->text().length() != 2 ||
ui->lineEditKey2->text().length() != 2 ||
ui->lineEditKey3->text().length() != 2 ||
ui->lineEditKey4->text().length() != 2 ||
ui->lineEditKey5->text().length() != 2 ||
ui->lineEditKey6->text().length() != 2)
{
ui->labelStatus->setText("Invalid key");
return;
}

memcpy(aAsciiKey, ui->lineEditKey1->text().toAscii().data(), 2);
memcpy(aAsciiKey + 2, ui->lineEditKey2->text().toAscii().data(), 2);
memcpy(aAsciiKey + 4, ui->lineEditKey3->text().toAscii().data(), 2);
memcpy(aAsciiKey + 6, ui->lineEditKey4->text().toAscii().data(), 2);
memcpy(aAsciiKey + 8, ui->lineEditKey5->text().toAscii().data(), 2);
memcpy(aAsciiKey + 10, ui->lineEditKey6->text().toAscii().data(), 2);

for (iCounter = 0; iCounter labelStatus->setText("Invalid key");
return;
}
}

cHelper_.getBytes(ui->lineEditKey1->text().toAscii().data(), aKey);
cHelper_.getBytes(ui->lineEditKey2->text().toAscii().data(), aKey + 1);
cHelper_.getBytes(ui->lineEditKey3->text().toAscii().data(), aKey + 2);
cHelper_.getBytes(ui->lineEditKey4->text().toAscii().data(), aKey + 3);
cHelper_.getBytes(ui->lineEditKey5->text().toAscii().data(), aKey + 4);
cHelper_.getBytes(ui->lineEditKey6->text().toAscii().data(), aKey + 5);

cCard_.loadKey(aKey, eKeyStore);

ui->labelStatus->setText("Load key succeeded");
}
catch(AcsException cException)
{
char *pMessage = new char[cException.sMessage.length() + 10];
sprintf(pMessage, "%02X %02X - %s", cException.aStatusWord[0], cException.aStatusWord[1], cException.sMessage.toUtf8().constData());
ui->labelStatus->setText(pMessage);
delete pMessage;
}
catch(...)
{
ui->labelStatus->setText("Load key failed");
}
}


And this is authentication module. Again I don’t understand what is happening in here….

void DialogMifareCardProgramming::on_pushButtonAuthenticate_clicked()
{
MIFARE_KEY_TYPE eKeyType;
MIFARE_KEY_STORE eKeyStore;
bool bNumeric = false;

try
{
if (ui->radioButtonKeyA->isChecked())
eKeyType = MIFARE_KEY_TYPE_A;
else if (ui->radioButtonKeyB->isChecked())
eKeyType = MIFARE_KEY_TYPE_B;
else
{
ui->labelStatus->setText("Please select key type");
return;
}

ui->lineEditKeyStoreNumber->text().toInt(&bNumeric);
if (!bNumeric)
{
ui->labelStatus->setText("Invalid key store number");
return;
}

if (ui->lineEditKeyStoreNumber->text().toInt() == 0)
eKeyStore = MIFARE_KEY_STORE_0;
else if (ui->lineEditKeyStoreNumber->text().toInt() == 1)
eKeyStore = MIFARE_KEY_STORE_1;
else
{
ui->labelStatus->setText("Invalid key store number");
return;
}

ui->lineEditBlockNumber->text().toInt(&bNumeric);
if (!bNumeric || ui->lineEditBlockNumber->text().toInt() labelStatus->setText("Invalid block number");
return;
}

if (cCard_._eCardType == CARD_TYPE_MIFARE_1K)
{
if (ui->lineEditBlockNumber->text().toInt() > 63)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditBlockNumber->text());
return;
}
}
else
{
if (ui->lineEditBlockNumber->text().toInt() > 255)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditBlockNumber->text());
return;
}
}

cCard_.authenticate(eKeyType, ui->lineEditBlockNumber->text().toInt(), eKeyStore);

ui->labelStatus->setText("Authentication succeeded");
}
catch(AcsException cException)
{
char *pMessage = new char[cException.sMessage.length() + 10];
sprintf(pMessage, "%02X %02X - %s", cException.aStatusWord[0], cException.aStatusWord[1], cException.sMessage.toUtf8().constData());
ui->labelStatus->setText(pMessage);
delete pMessage;
}
catch(...)
{
ui->labelStatus->setText("Authentication failed");
}
}



And this is update module. I guess like a write into the card.

void DialogMifareCardProgramming::on_pushButtonDataUpdate_clicked()
{
bool bNumeric = false;

try
{
ui->lineEditDataBlockNumber->text().toInt(&bNumeric);
if (!bNumeric || ui->lineEditDataBlockNumber->text().toInt() labelStatus->setText("Invalid block number");
return;
}

if (cCard_._eCardType == CARD_TYPE_MIFARE_1K)
{
if (ui->lineEditDataBlockNumber->text().toInt() > 63)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditDataBlockNumber->text());
return;
}
}
else
{
if (ui->lineEditDataBlockNumber->text().toInt() > 255)
{
ui->labelStatus->setText("Card does not have block " + ui->lineEditDataBlockNumber->text());
return;
}
}

ui->lineEditDataLength->text().toInt(&bNumeric);
if (!bNumeric || ui->lineEditDataLength->text().toInt() lineEditDataLength->text().toInt() % 16) != 0)
{
ui->labelStatus->setText("Invalid data length");
return;
}

if (ui->lineEditDataLength->text().toInt() != ui->textEditData->toPlainText().length())
{
ui->labelStatus->setText("Data length does not match");
return;
}

cCard_.updateBlock(ui->lineEditDataBlockNumber->text().toInt(), ui->lineEditDataLength->text().toInt(), ui->textEditData->toPlainText().toAscii().data());

ui->textEditData->setText("");

ui->labelStatus->setText("Update block succeeded");
}
catch(AcsException cException)
{
ui->textEditData->setText("");

char *pMessage = new char[cException.sMessage.length() + 10];
sprintf(pMessage, "%02X %02X - %s", cException.aStatusWord[0], cException.aStatusWord[1], cException.sMessage.toUtf8().constData());
ui->labelStatus->setText(pMessage);
delete pMessage;
}
catch(...)
{
ui->textEditData->setText("");

ui->labelStatus->setText("Update block failed");
}
}


Is it possible to tell me what is happening in these modules? I need to order say 1000 Mifare card for the pass through authentication services. So I have to write each card one by one. I don’t want to order card that has data and I have to update the data using above update module.

I will be happy if you can help me to understand the above code.




+ 0  |  - 0