Para desarrollar una aplicación de lector NFC en Linux utilizando el framework QT5, se requiere configurar un proyecto y enlazar la biblioteca correspondiente. A continuación, se describe el proceso y un ejemplo de código funcional.
Configuración del proyecto e inclusión de bibliotecas
Crea un proyecto de consola en QT, eliminando la interfaz gráfica si es necesario. En el archivo de proyecto (.pro), se debe enlazar la biblioteca libyw60x, que gestiona la comunicación con el lector NFC. Asegúrate de colocar el archivo libyw60x.so en el directorio lib dentro de la carpeta del proyecto.
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
CONFIG += static
CONFIG -= shared
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp
LIBS += -L$$PWD/lib -lyw60x
HEADERS += \
libyw60x.h
Desarrollo del código principal
El siguiente código de ejemplo muestra cómo interactuar con el lector NFC para leer el número de serie, datos de bloques y escribir datos. Se han modificado nombres de variables y estructuras para reducir la similitud con el código original.
#include <iostream>
#include <string>
#include "libyw60x.h"
// Función auxiliar para convertir bytes a cadena hexadecimal
std::string bytesToHexStr(const unsigned char* data, int length) {
std::string hexStr;
for (int i = 0; i < length; ++i) {
char buf[3];
sprintf(buf, "%02X", data[i]);
hexStr += buf;
}
return hexStr;
}
int main(int argc, char *argv[]) {
NfcDevice readerDevice;
std::string userInput;
unsigned short atqaValue = 0;
unsigned char sakValue = 0;
unsigned char uidLength;
unsigned char cardUID[10];
unsigned char defaultKey[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char readBuffer[16];
unsigned char writeBuffer[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
std::cout << "Demostración de lector NFC USB en consola\n" << std::endl;
std::cout << "Opciones disponibles:\n1: Leer número de serie de la tarjeta\n2: Leer datos de bloque\n3: Escribir datos en bloque\n4: Salir\n" << std::endl;
std::cout << "Seleccione una opción (1, 2, 3 o 4):" << std::endl;
std::getline(std::cin, userInput);
if (userInput == "1") {
int status = readerDevice.initializeReader();
if (status <= 0) {
std::cout << "Error al abrir el lector. Saliendo.\n" << std::endl;
return 0;
}
status = readerDevice.requestAndSelectCard(1, 0x52, 0, &atqaValue, &sakValue, &uidLength, cardUID);
if (status < 0) {
std::cout << "Error al solicitar tarjeta. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
readerDevice.beepBuzzer(1, 5, 5, 1);
std::cout << "Número de serie de la tarjeta: " << bytesToHexStr(cardUID, uidLength) << "\n" << std::endl;
readerDevice.releaseReader();
} else if (userInput == "2") {
std::cout << "Leyendo bloque 4 con clave modo A y clave FFFFFFFFFFFF\n" << std::endl;
int status = readerDevice.initializeReader();
if (status <= 0) {
std::cout << "Error al abrir el lector. Saliendo.\n" << std::endl;
return 0;
}
status = readerDevice.requestAndSelectCard(1, 0x52, 0, &atqaValue, &sakValue, &uidLength, cardUID);
std::cout << "Número de serie de la tarjeta: " << bytesToHexStr(cardUID, uidLength) << "\n" << std::endl;
if (status < 0) {
std::cout << "Error al solicitar tarjeta. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
if (readerDevice.authorizeKey(1, KEY_MODE_A, 4, defaultKey) < 0) {
std::cout << "Error de clave. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
if (readerDevice.readBlock(1, 4, 16, readBuffer) < 0) {
std::cout << "Error al leer bloque. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
readerDevice.beepBuzzer(1, 5, 5, 1);
std::cout << "Datos del bloque 4: " << bytesToHexStr(readBuffer, 16) << "\n" << std::endl;
readerDevice.releaseReader();
} else if (userInput == "3") {
std::cout << "Escribiendo en bloque 4 con clave modo A y clave FFFFFFFFFFFF, datos: 00112233445566778899AABBCCDDEEFF\n" << std::endl;
int status = readerDevice.initializeReader();
if (status <= 0) {
std::cout << "Error al abrir el lector. Saliendo.\n" << std::endl;
return 0;
}
status = readerDevice.requestAndSelectCard(1, 0x52, 0, &atqaValue, &sakValue, &uidLength, cardUID);
std::cout << "Número de serie de la tarjeta: " << bytesToHexStr(cardUID, uidLength) << "\n" << std::endl;
if (status < 0) {
std::cout << "Error al solicitar tarjeta. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
if (readerDevice.authorizeKey(1, KEY_MODE_A, 4, defaultKey) < 0) {
std::cout << "Error de clave. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
if (readerDevice.writeBlock(1, 4, 16, writeBuffer) < 0) {
std::cout << "Error al escribir en bloque. Saliendo.\n" << std::endl;
readerDevice.releaseReader();
return 0;
}
readerDevice.beepBuzzer(1, 5, 5, 1);
std::cout << "Escritura exitosa en bloque 4\n" << std::endl;
readerDevice.releaseReader();
} else if (userInput == "4") {
std::cout << "Saliendo del programa.\n" << std::endl;
} else {
std::cout << "Opción no válida.\n" << std::endl;
}
return 0;
}
Tras compilar y ejecutar el programa, se puede interactuar con el lector NFC para operaciones de lectura y escritura en tarjetas compatibles.