Indent whole code using make indent. (Fixes issue 84).
This commit is contained in:
parent
f93b4939f4
commit
18cc86a613
42 changed files with 2613 additions and 2479 deletions
|
@ -6,7 +6,8 @@
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
#include <nfc/nfc-messages.h>
|
#include <nfc/nfc-messages.h>
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd;
|
nfc_device_t *pnd;
|
||||||
nfc_target_info_t nti;
|
nfc_target_info_t nti;
|
||||||
|
@ -22,7 +23,6 @@ int main(int argc, const char* argv[])
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to connect to NFC device.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set connected NFC device to initiator mode
|
// Set connected NFC device to initiator mode
|
||||||
nfc_initiator_init (pnd);
|
nfc_initiator_init (pnd);
|
||||||
|
|
||||||
|
@ -44,15 +44,17 @@ int main(int argc, const char* argv[])
|
||||||
// Poll for a ISO14443A (MIFARE) tag
|
// Poll for a ISO14443A (MIFARE) tag
|
||||||
if (nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
|
if (nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
|
||||||
printf ("The following (NFC) ISO14443A tag was found:\n");
|
printf ("The following (NFC) ISO14443A tag was found:\n");
|
||||||
printf(" ATQA (SENS_RES): "); print_hex(nti.nai.abtAtqa,2);
|
printf (" ATQA (SENS_RES): ");
|
||||||
printf(" UID (NFCID%c): ",(nti.nai.abtUid[0]==0x08?'3':'1')); print_hex(nti.nai.abtUid,nti.nai.szUidLen);
|
print_hex (nti.nai.abtAtqa, 2);
|
||||||
printf(" SAK (SEL_RES): "); print_hex(&nti.nai.btSak,1);
|
printf (" UID (NFCID%c): ", (nti.nai.abtUid[0] == 0x08 ? '3' : '1'));
|
||||||
|
print_hex (nti.nai.abtUid, nti.nai.szUidLen);
|
||||||
|
printf (" SAK (SEL_RES): ");
|
||||||
|
print_hex (&nti.nai.btSak, 1);
|
||||||
if (nti.nai.szAtsLen) {
|
if (nti.nai.szAtsLen) {
|
||||||
printf (" ATS (ATR): ");
|
printf (" ATS (ATR): ");
|
||||||
print_hex (nti.nai.abtAts, nti.nai.szAtsLen);
|
print_hex (nti.nai.abtAts, nti.nai.szAtsLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from NFC device
|
// Disconnect from NFC device
|
||||||
nfc_disconnect (pnd);
|
nfc_disconnect (pnd);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
* After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
|
* After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
|
||||||
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
|
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
|
||||||
*/
|
*/
|
||||||
bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param* pmp)
|
bool
|
||||||
|
nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp)
|
||||||
{
|
{
|
||||||
byte_t abtRx[265];
|
byte_t abtRx[265];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
|
@ -25,13 +26,13 @@ bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint
|
||||||
byte_t abtCmd[265];
|
byte_t abtCmd[265];
|
||||||
|
|
||||||
// Make sure we are dealing with a active device
|
// Make sure we are dealing with a active device
|
||||||
if (!pnd->bActive) return false;
|
if (!pnd->bActive)
|
||||||
|
return false;
|
||||||
|
|
||||||
abtCmd[0] = mc; // The MIFARE Classic command
|
abtCmd[0] = mc; // The MIFARE Classic command
|
||||||
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
|
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
|
||||||
|
|
||||||
switch (mc)
|
switch (mc) {
|
||||||
{
|
|
||||||
// Read and store command have no parameter
|
// Read and store command have no parameter
|
||||||
case MC_READ:
|
case MC_READ:
|
||||||
case MC_STORE:
|
case MC_STORE:
|
||||||
|
@ -63,7 +64,8 @@ bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// When available, copy the parameter bytes
|
// When available, copy the parameter bytes
|
||||||
if (szParamLen) memcpy(abtCmd+2,(byte_t*)pmp,szParamLen);
|
if (szParamLen)
|
||||||
|
memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen);
|
||||||
|
|
||||||
// Fire the mifare command
|
// Fire the mifare command
|
||||||
if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRxLen)) {
|
if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRxLen)) {
|
||||||
|
@ -71,7 +73,6 @@ bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint
|
||||||
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
|
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we have executed a read command, copy the received bytes into the param
|
// When we have executed a read command, copy the received bytes into the param
|
||||||
if (mc == MC_READ) {
|
if (mc == MC_READ) {
|
||||||
if (szRxLen == 16) {
|
if (szRxLen == 16) {
|
||||||
|
@ -80,7 +81,6 @@ bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command succesfully executed
|
// Command succesfully executed
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,54 +58,51 @@ byte_t abtSelectTag [9] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||||
byte_t abtRats[4] = { 0xe0, 0x50, 0xbc, 0xa5 };
|
byte_t abtRats[4] = { 0xe0, 0x50, 0xbc, 0xa5 };
|
||||||
byte_t abtHalt[4] = { 0x50, 0x00, 0x57, 0xcd };
|
byte_t abtHalt[4] = { 0x50, 0x00, 0x57, 0xcd };
|
||||||
|
|
||||||
static bool transmit_bits(const byte_t* pbtTx, const size_t szTxBits)
|
static bool
|
||||||
|
transmit_bits (const byte_t * pbtTx, const size_t szTxBits)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("R: ");
|
printf ("R: ");
|
||||||
print_hex_bits (pbtTx, szTxBits);
|
print_hex_bits (pbtTx, szTxBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
// Transmit the bit frame command, we don't use the arbitrary parity feature
|
||||||
if (!nfc_initiator_transceive_bits(pnd,pbtTx,szTxBits,NULL,abtRx,&szRxBits,NULL)) return false;
|
if (!nfc_initiator_transceive_bits (pnd, pbtTx, szTxBits, NULL, abtRx, &szRxBits, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("T: ");
|
printf ("T: ");
|
||||||
print_hex_bits (abtRx, szRxBits);
|
print_hex_bits (abtRx, szRxBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Succesful transfer
|
// Succesful transfer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool transmit_bytes(const byte_t* pbtTx, const size_t szTxLen)
|
static bool
|
||||||
|
transmit_bytes (const byte_t * pbtTx, const size_t szTxLen)
|
||||||
{
|
{
|
||||||
// Show transmitted command
|
// Show transmitted command
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("R: ");
|
printf ("R: ");
|
||||||
print_hex (pbtTx, szTxLen);
|
print_hex (pbtTx, szTxLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transmit the command bytes
|
// Transmit the command bytes
|
||||||
if (!nfc_initiator_transceive_bytes(pnd,pbtTx,szTxLen,abtRx,&szRxLen)) return false;
|
if (!nfc_initiator_transceive_bytes (pnd, pbtTx, szTxLen, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Show received answer
|
// Show received answer
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("T: ");
|
printf ("T: ");
|
||||||
print_hex (abtRx, szRxLen);
|
print_hex (abtRx, szRxLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Succesful transfer
|
// Succesful transfer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_usage(char* argv[])
|
static void
|
||||||
|
print_usage (char *argv[])
|
||||||
{
|
{
|
||||||
printf ("Usage: %s [OPTIONS]\n", argv[0]);
|
printf ("Usage: %s [OPTIONS]\n", argv[0]);
|
||||||
printf ("Options:\n");
|
printf ("Options:\n");
|
||||||
|
@ -113,7 +110,8 @@ static void print_usage(char* argv[])
|
||||||
printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc,char* argv[])
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int arg;
|
int arg;
|
||||||
|
|
||||||
|
@ -135,8 +133,7 @@ int main(int argc,char* argv[])
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_connect (NULL);
|
||||||
|
|
||||||
if (!pnd)
|
if (!pnd) {
|
||||||
{
|
|
||||||
printf ("Error connecting NFC reader\n");
|
printf ("Error connecting NFC reader\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -147,19 +144,16 @@ int main(int argc,char* argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the CRC
|
// Configure the CRC
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
|
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure parity settings
|
// Configure parity settings
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable field so more power consuming cards can power themselves up
|
// Enable field so more power consuming cards can power themselves up
|
||||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -174,13 +168,11 @@ int main(int argc,char* argv[])
|
||||||
printf ("\nConnected to NFC reader: %s\n\n", pnd->acName);
|
printf ("\nConnected to NFC reader: %s\n\n", pnd->acName);
|
||||||
|
|
||||||
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
// Send the 7 bits request command specified in ISO 14443A (0x26)
|
||||||
if (!transmit_bits(abtReqa,7))
|
if (!transmit_bits (abtReqa, 7)) {
|
||||||
{
|
|
||||||
printf ("Error: No tag available\n");
|
printf ("Error: No tag available\n");
|
||||||
nfc_disconnect (pnd);
|
nfc_disconnect (pnd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Anti-collision
|
// Anti-collision
|
||||||
transmit_bytes (abtSelectAll, 2);
|
transmit_bytes (abtSelectAll, 2);
|
||||||
|
|
||||||
|
@ -191,8 +183,7 @@ int main(int argc,char* argv[])
|
||||||
transmit_bytes (abtSelectTag, 9);
|
transmit_bytes (abtSelectTag, 9);
|
||||||
|
|
||||||
// Test if we are dealing with a 4 bytes uid
|
// Test if we are dealing with a 4 bytes uid
|
||||||
if (abtUid[0]!= 0x88)
|
if (abtUid[0] != 0x88) {
|
||||||
{
|
|
||||||
szUidLen = 4;
|
szUidLen = 4;
|
||||||
} else {
|
} else {
|
||||||
// We have to do the anti-collision for cascade level 2
|
// We have to do the anti-collision for cascade level 2
|
||||||
|
@ -211,7 +202,8 @@ int main(int argc,char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request ATS, this only applies to tags that support ISO 14443A-4
|
// Request ATS, this only applies to tags that support ISO 14443A-4
|
||||||
if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) transmit_bytes(abtRats,4);
|
if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED)
|
||||||
|
transmit_bytes (abtRats, 4);
|
||||||
|
|
||||||
// Done, halt the tag now
|
// Done, halt the tag now
|
||||||
transmit_bytes (abtHalt, 4);
|
transmit_bytes (abtHalt, 4);
|
||||||
|
|
|
@ -48,7 +48,8 @@ byte_t abtAtqa [2] = { 0x04,0x00 };
|
||||||
byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xAF, 0x62 };
|
byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xAF, 0x62 };
|
||||||
byte_t abtSak[9] = { 0x08, 0xb6, 0xdd };
|
byte_t abtSak[9] = { 0x08, 0xb6, 0xdd };
|
||||||
|
|
||||||
void print_usage(char* argv[])
|
void
|
||||||
|
print_usage (char *argv[])
|
||||||
{
|
{
|
||||||
printf ("Usage: %s [OPTIONS] [UID]\n", argv[0]);
|
printf ("Usage: %s [OPTIONS] [UID]\n", argv[0]);
|
||||||
printf ("Options:\n");
|
printf ("Options:\n");
|
||||||
|
@ -58,13 +59,15 @@ void print_usage(char* argv[])
|
||||||
printf ("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEAF).\n");
|
printf ("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEAF).\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
byte_t *pbtTx = NULL;
|
byte_t *pbtTx = NULL;
|
||||||
size_t szTxBits;
|
size_t szTxBits;
|
||||||
bool quiet_output = false;
|
bool quiet_output = false;
|
||||||
|
|
||||||
int arg, i;
|
int arg,
|
||||||
|
i;
|
||||||
|
|
||||||
// Get commandline options
|
// Get commandline options
|
||||||
for (arg = 1; arg < argc; arg++) {
|
for (arg = 1; arg < argc; arg++) {
|
||||||
|
@ -78,8 +81,7 @@ int main(int argc, char *argv[])
|
||||||
byte_t abtTmp[3] = { 0x00, 0x00, 0x00 };
|
byte_t abtTmp[3] = { 0x00, 0x00, 0x00 };
|
||||||
printf ("[+] Using UID: %s\n", argv[arg]);
|
printf ("[+] Using UID: %s\n", argv[arg]);
|
||||||
abtUidBcc[4] = 0x00;
|
abtUidBcc[4] = 0x00;
|
||||||
for(i= 0; i < 4; ++i)
|
for (i = 0; i < 4; ++i) {
|
||||||
{
|
|
||||||
memcpy (abtTmp, argv[arg] + i * 2, 2);
|
memcpy (abtTmp, argv[arg] + i * 2, 2);
|
||||||
abtUidBcc[i] = (byte_t) strtol ((char *) abtTmp, NULL, 16);
|
abtUidBcc[i] = (byte_t) strtol ((char *) abtTmp, NULL, 16);
|
||||||
abtUidBcc[4] ^= abtUidBcc[i];
|
abtUidBcc[4] ^= abtUidBcc[i];
|
||||||
|
@ -94,8 +96,7 @@ int main(int argc, char *argv[])
|
||||||
// Try to open the NFC reader
|
// Try to open the NFC reader
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_connect (NULL);
|
||||||
|
|
||||||
if (pnd == NULL)
|
if (pnd == NULL) {
|
||||||
{
|
|
||||||
printf ("Error connecting NFC reader\n");
|
printf ("Error connecting NFC reader\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -105,8 +106,7 @@ int main(int argc, char *argv[])
|
||||||
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
||||||
printf ("[+] To do this, please send any command after the anti-collision\n");
|
printf ("[+] To do this, please send any command after the anti-collision\n");
|
||||||
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||||
if (!nfc_target_init(pnd,abtRecv,&szRecvBits))
|
if (!nfc_target_init (pnd, abtRecv, &szRecvBits)) {
|
||||||
{
|
|
||||||
printf ("Error: Could not come out of auto-emulation, no command was received\n");
|
printf ("Error: Could not come out of auto-emulation, no command was received\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -117,21 +117,20 @@ int main(int argc, char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
printf("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n",abtUidBcc[0],abtUidBcc[1],abtUidBcc[2],abtUidBcc[3]);
|
printf ("[+] Done, the emulated tag is initialized with UID: %02X%02X%02X%02X\n\n", abtUidBcc[0], abtUidBcc[1],
|
||||||
|
abtUidBcc[2], abtUidBcc[3]);
|
||||||
|
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
|
||||||
// Test if we received a frame
|
// Test if we received a frame
|
||||||
if (nfc_target_receive_bits(pnd,abtRecv,&szRecvBits,NULL))
|
if (nfc_target_receive_bits (pnd, abtRecv, &szRecvBits, NULL)) {
|
||||||
{
|
|
||||||
// Prepare the command to send back for the anti-collision request
|
// Prepare the command to send back for the anti-collision request
|
||||||
switch(szRecvBits)
|
switch (szRecvBits) {
|
||||||
{
|
|
||||||
case 7: // Request or Wakeup
|
case 7: // Request or Wakeup
|
||||||
pbtTx = abtAtqa;
|
pbtTx = abtAtqa;
|
||||||
szTxBits = 16;
|
szTxBits = 16;
|
||||||
// New anti-collsion session started
|
// New anti-collsion session started
|
||||||
if (!quiet_output) printf("\n");
|
if (!quiet_output)
|
||||||
|
printf ("\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16: // Select All
|
case 16: // Select All
|
||||||
|
@ -149,22 +148,18 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("R: ");
|
printf ("R: ");
|
||||||
print_hex_bits (abtRecv, szRecvBits);
|
print_hex_bits (abtRecv, szRecvBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if we know how to respond
|
// Test if we know how to respond
|
||||||
if(szTxBits)
|
if (szTxBits) {
|
||||||
{
|
|
||||||
// Send and print the command to the screen
|
// Send and print the command to the screen
|
||||||
if (!nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL)) {
|
if (!nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL)) {
|
||||||
nfc_perror (pnd, "nfc_target_send_bits");
|
nfc_perror (pnd, "nfc_target_send_bits");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("T: ");
|
printf ("T: ");
|
||||||
print_hex_bits (pbtTx, szTxBits);
|
print_hex_bits (pbtTx, szTxBits);
|
||||||
}
|
}
|
||||||
|
@ -175,4 +170,3 @@ int main(int argc, char *argv[])
|
||||||
nfc_disconnect (pnd);
|
nfc_disconnect (pnd);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@
|
||||||
|
|
||||||
static nfc_device_t *pnd;
|
static nfc_device_t *pnd;
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
const char *acLibnfcVersion;
|
const char *acLibnfcVersion;
|
||||||
size_t szDeviceFound;
|
size_t szDeviceFound;
|
||||||
|
@ -65,7 +66,6 @@ int main(int argc, const char* argv[])
|
||||||
if (argc > 1 && szDeviceFound == 0) {
|
if (argc > 1 && szDeviceFound == 0) {
|
||||||
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
|
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
usb_set_debug (4);
|
usb_set_debug (4);
|
||||||
|
@ -87,10 +87,8 @@ int main(int argc, const char* argv[])
|
||||||
pnd = nfc_connect (&ndd);
|
pnd = nfc_connect (&ndd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (szDeviceFound == 0)
|
if (szDeviceFound == 0) {
|
||||||
{
|
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
||||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices))))
|
|
||||||
{
|
|
||||||
fprintf (stderr, "malloc() failed\n");
|
fprintf (stderr, "malloc() failed\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -98,19 +96,16 @@ int main(int argc, const char* argv[])
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
|
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szDeviceFound == 0)
|
if (szDeviceFound == 0) {
|
||||||
{
|
|
||||||
INFO ("%s", "No device found.");
|
INFO ("%s", "No device found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < szDeviceFound; i++)
|
for (i = 0; i < szDeviceFound; i++) {
|
||||||
{
|
|
||||||
nfc_target_info_t anti[MAX_TARGET_COUNT];
|
nfc_target_info_t anti[MAX_TARGET_COUNT];
|
||||||
pnd = nfc_connect (&(pnddDevices[i]));
|
pnd = nfc_connect (&(pnddDevices[i]));
|
||||||
|
|
||||||
|
|
||||||
if (pnd == NULL)
|
if (pnd == NULL) {
|
||||||
{
|
|
||||||
ERR ("%s", "Unable to connect to NFC device.");
|
ERR ("%s", "Unable to connect to NFC device.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -121,13 +116,11 @@ int main(int argc, const char* argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the CRC and Parity settings
|
// Configure the CRC and Parity settings
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -137,7 +130,6 @@ int main(int argc, const char* argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable field so more power consuming cards can power themselves up
|
// Enable field so more power consuming cards can power themselves up
|
||||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -160,11 +152,11 @@ int main(int argc, const char* argv[])
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List Felica tags
|
// List Felica tags
|
||||||
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_212, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_212, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||||
size_t n;
|
size_t n;
|
||||||
printf("%d Felica (212 kbps) passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound,
|
||||||
|
(szTargetFound == 0) ? ".\n" : ":");
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < szTargetFound; n++) {
|
||||||
print_nfc_felica_info (anti[n].nfi);
|
print_nfc_felica_info (anti[n].nfi);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
@ -172,13 +164,13 @@ int main(int argc, const char* argv[])
|
||||||
}
|
}
|
||||||
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_424, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_424, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||||
size_t n;
|
size_t n;
|
||||||
printf("%d Felica (424 kbps) passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound,
|
||||||
|
(szTargetFound == 0) ? ".\n" : ":");
|
||||||
for (n = 0; n < szTargetFound; n++) {
|
for (n = 0; n < szTargetFound; n++) {
|
||||||
print_nfc_felica_info (anti[n].nfi);
|
print_nfc_felica_info (anti[n].nfi);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List ISO14443B targets
|
// List ISO14443B targets
|
||||||
if (nfc_initiator_list_passive_targets (pnd, NM_ISO14443B_106, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
if (nfc_initiator_list_passive_targets (pnd, NM_ISO14443B_106, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
|
@ -308,8 +308,7 @@ mifare_classic_extract_payload (const char *abDump, char *pbPayload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
ACTION_READ,
|
ACTION_READ,
|
||||||
ACTION_WRITE,
|
ACTION_WRITE,
|
||||||
ACTION_EXTRACT,
|
ACTION_EXTRACT,
|
||||||
|
@ -418,7 +417,6 @@ main (int argc, const char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -432,13 +430,11 @@ main (int argc, const char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable field so more power consuming cards can power themselves up
|
// Enable field so more power consuming cards can power themselves up
|
||||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
|
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
|
||||||
nfc_configure (pnd, NDO_AUTO_ISO14443_4, false);
|
nfc_configure (pnd, NDO_AUTO_ISO14443_4, false);
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,6 @@ write_card (void)
|
||||||
}
|
}
|
||||||
bFailure = false;
|
bFailure = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the Mifare Ultralight, this write command can be used
|
// For the Mifare Ultralight, this write command can be used
|
||||||
// in compatibility mode, which only actually writes the first
|
// in compatibility mode, which only actually writes the first
|
||||||
// page (4 bytes). The Ultralight-specific Write command only
|
// page (4 bytes). The Ultralight-specific Write command only
|
||||||
|
@ -135,7 +134,8 @@ write_card (void)
|
||||||
print_success_or_failure (bFailure, &uiWritenPages);
|
print_success_or_failure (bFailure, &uiWritenPages);
|
||||||
}
|
}
|
||||||
printf ("|\n");
|
printf ("|\n");
|
||||||
printf ("Done, %d of %d pages written (%d first pages are skipped).\n", uiWritenPages, uiBlocks + 1, write_otp?3:4);
|
printf ("Done, %d of %d pages written (%d first pages are skipped).\n", uiWritenPages, uiBlocks + 1,
|
||||||
|
write_otp ? 3 : 4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,6 @@ main (int argc, const char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -208,7 +207,6 @@ main (int argc, const char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable field so more power consuming cards can power themselves up
|
// Enable field so more power consuming cards can power themselves up
|
||||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -230,7 +228,6 @@ main (int argc, const char *argv[])
|
||||||
nfc_disconnect (pnd);
|
nfc_disconnect (pnd);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the info from the current tag (UID is stored little-endian)
|
// Get the info from the current tag (UID is stored little-endian)
|
||||||
pbtUID = nti.nai.abtUid;
|
pbtUID = nti.nai.abtUid;
|
||||||
printf ("Found MIFARE Ultralight card with UID: %02x%02x%02x%02x\n", pbtUID[3], pbtUID[2], pbtUID[1], pbtUID[0]);
|
printf ("Found MIFARE Ultralight card with UID: %02x%02x%02x%02x\n", pbtUID[3], pbtUID[2], pbtUID[1], pbtUID[0]);
|
||||||
|
|
|
@ -92,13 +92,11 @@ main (int argc, const char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the CRC and Parity settings
|
// Configure the CRC and Parity settings
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -108,7 +106,6 @@ main (int argc, const char *argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable field so more power consuming cards can power themselves up
|
// Enable field so more power consuming cards can power themselves up
|
||||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
|
|
@ -50,14 +50,16 @@ static nfc_device_t* pndReader;
|
||||||
static nfc_device_t *pndTag;
|
static nfc_device_t *pndTag;
|
||||||
static bool quitting = false;
|
static bool quitting = false;
|
||||||
|
|
||||||
void intr_hdlr(void)
|
void
|
||||||
|
intr_hdlr (void)
|
||||||
{
|
{
|
||||||
printf ("\nQuitting...\n");
|
printf ("\nQuitting...\n");
|
||||||
quitting = true;
|
quitting = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_usage(char* argv[])
|
void
|
||||||
|
print_usage (char *argv[])
|
||||||
{
|
{
|
||||||
printf ("Usage: %s [OPTIONS]\n", argv[0]);
|
printf ("Usage: %s [OPTIONS]\n", argv[0]);
|
||||||
printf ("Options:\n");
|
printf ("Options:\n");
|
||||||
|
@ -65,7 +67,8 @@ void print_usage(char* argv[])
|
||||||
printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc,char* argv[])
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int arg;
|
int arg;
|
||||||
bool quiet_output = false;
|
bool quiet_output = false;
|
||||||
|
@ -102,7 +105,6 @@ int main(int argc,char* argv[])
|
||||||
fprintf (stderr, "malloc() failed\n");
|
fprintf (stderr, "malloc() failed\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List available devices
|
// List available devices
|
||||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
||||||
|
|
||||||
|
@ -110,11 +112,9 @@ int main(int argc,char* argv[])
|
||||||
ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound);
|
ERR ("%zd device found but two connected devices are needed to relay NFC.", szFound);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to open the NFC emulator device
|
// Try to open the NFC emulator device
|
||||||
pndTag = nfc_connect (&(pnddDevices[0]));
|
pndTag = nfc_connect (&(pnddDevices[0]));
|
||||||
if (pndTag == NULL)
|
if (pndTag == NULL) {
|
||||||
{
|
|
||||||
printf ("Error connecting NFC emulator device\n");
|
printf ("Error connecting NFC emulator device\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -125,16 +125,14 @@ int main(int argc,char* argv[])
|
||||||
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
printf ("[+] Try to break out the auto-emulation, this requires a second reader!\n");
|
||||||
printf ("[+] To do this, please send any command after the anti-collision\n");
|
printf ("[+] To do this, please send any command after the anti-collision\n");
|
||||||
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
printf ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||||
if (!nfc_target_init(pndTag,abtReaderRx,&szReaderRxBits))
|
if (!nfc_target_init (pndTag, abtReaderRx, &szReaderRxBits)) {
|
||||||
{
|
|
||||||
ERR ("%s", "Initialization of NFC emulator failed");
|
ERR ("%s", "Initialization of NFC emulator failed");
|
||||||
nfc_disconnect (pndTag);
|
nfc_disconnect (pndTag);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf ("%s", "Configuring emulator settings...");
|
printf ("%s", "Configuring emulator settings...");
|
||||||
if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) ||
|
if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) ||
|
||||||
!nfc_configure(pndTag,NDO_HANDLE_PARITY,false) ||
|
!nfc_configure (pndTag, NDO_HANDLE_PARITY, false) || !nfc_configure (pndTag, NDO_ACCEPT_INVALID_FRAMES, true)) {
|
||||||
!nfc_configure(pndTag,NDO_ACCEPT_INVALID_FRAMES,true)) {
|
|
||||||
nfc_perror (pndTag, "nfc_configure");
|
nfc_perror (pndTag, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -154,14 +152,11 @@ int main(int argc,char* argv[])
|
||||||
}
|
}
|
||||||
printf ("%s", "Done, relaying frames now!");
|
printf ("%s", "Done, relaying frames now!");
|
||||||
|
|
||||||
while(!quitting)
|
while (!quitting) {
|
||||||
{
|
|
||||||
// Test if we received a frame from the reader
|
// Test if we received a frame from the reader
|
||||||
if (nfc_target_receive_bits(pndTag,abtReaderRx,&szReaderRxBits,abtReaderRxPar))
|
if (nfc_target_receive_bits (pndTag, abtReaderRx, &szReaderRxBits, abtReaderRxPar)) {
|
||||||
{
|
|
||||||
// Drop down the field before sending a REQA command and start a new session
|
// Drop down the field before sending a REQA command and start a new session
|
||||||
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26)
|
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) {
|
||||||
{
|
|
||||||
// Drop down field for a very short time (original tag will reboot)
|
// Drop down field for a very short time (original tag will reboot)
|
||||||
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) {
|
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) {
|
||||||
nfc_perror (pndReader, "nfc_configure");
|
nfc_perror (pndReader, "nfc_configure");
|
||||||
|
@ -174,25 +169,21 @@ int main(int argc,char* argv[])
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the reader frame to the screen
|
// Print the reader frame to the screen
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("R: ");
|
printf ("R: ");
|
||||||
print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar);
|
print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar);
|
||||||
}
|
}
|
||||||
// Forward the frame to the original tag
|
// Forward the frame to the original tag
|
||||||
if (nfc_initiator_transceive_bits(pndReader,abtReaderRx,szReaderRxBits,abtReaderRxPar,abtTagRx,&szTagRxBits,abtTagRxPar))
|
if (nfc_initiator_transceive_bits
|
||||||
{
|
(pndReader, abtReaderRx, szReaderRxBits, abtReaderRxPar, abtTagRx, &szTagRxBits, abtTagRxPar)) {
|
||||||
// Redirect the answer back to the reader
|
// Redirect the answer back to the reader
|
||||||
if (!nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar)) {
|
if (!nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar)) {
|
||||||
nfc_perror (pndTag, "nfc_target_send_bits");
|
nfc_perror (pndTag, "nfc_target_send_bits");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the tag frame to the screen
|
// Print the tag frame to the screen
|
||||||
if(!quiet_output)
|
if (!quiet_output) {
|
||||||
{
|
|
||||||
printf ("T: ");
|
printf ("T: ");
|
||||||
print_hex_par (abtTagRx, szTagRxBits, abtTagRxPar);
|
print_hex_par (abtTagRx, szTagRxBits, abtTagRxPar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,8 @@
|
||||||
#define WIRED_CARD_MODE 3
|
#define WIRED_CARD_MODE 3
|
||||||
#define DUAL_CARD_MODE 4
|
#define DUAL_CARD_MODE 4
|
||||||
|
|
||||||
bool sam_connection(nfc_device_t* pnd, int mode)
|
bool
|
||||||
|
sam_connection (nfc_device_t * pnd, int mode)
|
||||||
{
|
{
|
||||||
byte_t pncmd_sam_config[] = { 0xD4, 0x14, 0x00, 0x00 };
|
byte_t pncmd_sam_config[] = { 0xD4, 0x14, 0x00, 0x00 };
|
||||||
size_t szCmd = 0;
|
size_t szCmd = 0;
|
||||||
|
@ -66,8 +67,7 @@ bool sam_connection(nfc_device_t* pnd, int mode)
|
||||||
|
|
||||||
pncmd_sam_config[2] = mode;
|
pncmd_sam_config[2] = mode;
|
||||||
|
|
||||||
switch (mode)
|
switch (mode) {
|
||||||
{
|
|
||||||
case VIRTUAL_CARD_MODE:
|
case VIRTUAL_CARD_MODE:
|
||||||
{
|
{
|
||||||
// Only the VIRTUAL_CARD_MODE requires 4 bytes.
|
// Only the VIRTUAL_CARD_MODE requires 4 bytes.
|
||||||
|
@ -91,15 +91,15 @@ bool sam_connection(nfc_device_t* pnd, int mode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_one_minute()
|
void
|
||||||
|
wait_one_minute ()
|
||||||
{
|
{
|
||||||
int secs = 0;
|
int secs = 0;
|
||||||
|
|
||||||
printf ("|");
|
printf ("|");
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
|
|
||||||
while (secs < TIMEOUT)
|
while (secs < TIMEOUT) {
|
||||||
{
|
|
||||||
sleep (SUSP_TIME);
|
sleep (SUSP_TIME);
|
||||||
secs++;
|
secs++;
|
||||||
printf (".");
|
printf (".");
|
||||||
|
@ -109,7 +109,8 @@ void wait_one_minute()
|
||||||
printf ("|\n");
|
printf ("|\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd;
|
nfc_device_t *pnd;
|
||||||
|
|
||||||
|
@ -145,12 +146,10 @@ int main(int argc, const char* argv[])
|
||||||
ERR ("%s", "Invalid selection.");
|
ERR ("%s", "Invalid selection.");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect with the SAM
|
// Connect with the SAM
|
||||||
sam_connection (pnd, mode);
|
sam_connection (pnd, mode);
|
||||||
|
|
||||||
switch (mode)
|
switch (mode) {
|
||||||
{
|
|
||||||
case VIRTUAL_CARD_MODE:
|
case VIRTUAL_CARD_MODE:
|
||||||
{
|
{
|
||||||
// FIXME: after the loop the reader doesn't respond to host commands...
|
// FIXME: after the loop the reader doesn't respond to host commands...
|
||||||
|
@ -171,13 +170,11 @@ int main(int argc, const char* argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the reader only try once to find a tag
|
// Let the reader only try once to find a tag
|
||||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the CRC and Parity settings
|
// Configure the CRC and Parity settings
|
||||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
|
@ -187,13 +184,11 @@ int main(int argc, const char* argv[])
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable field so more power consuming cards can power themselves up
|
// Enable field so more power consuming cards can power themselves up
|
||||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||||
nfc_perror (pnd, "nfc_configure");
|
nfc_perror (pnd, "nfc_configure");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the SAM's info
|
// Read the SAM's info
|
||||||
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
|
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
|
||||||
ERR ("%s", "Reading of SAM info failed.");
|
ERR ("%s", "Reading of SAM info failed.");
|
||||||
|
|
|
@ -21,47 +21,47 @@ static const byte_t OddParity[256] = {
|
||||||
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
byte_t oddparity(const byte_t bt)
|
byte_t
|
||||||
|
oddparity (const byte_t bt)
|
||||||
{
|
{
|
||||||
return OddParity[bt];
|
return OddParity[bt];
|
||||||
}
|
}
|
||||||
|
|
||||||
void oddparity_bytes_ts(const byte_t* pbtData, const size_t szLen, byte_t* pbtPar)
|
void
|
||||||
|
oddparity_bytes_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar)
|
||||||
{
|
{
|
||||||
size_t szByteNr;
|
size_t szByteNr;
|
||||||
// Calculate the parity bits for the command
|
// Calculate the parity bits for the command
|
||||||
for (szByteNr=0; szByteNr<szLen; szByteNr++)
|
for (szByteNr = 0; szByteNr < szLen; szByteNr++) {
|
||||||
{
|
|
||||||
pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
|
pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_hex(const byte_t* pbtData, const size_t szBytes)
|
void
|
||||||
|
print_hex (const byte_t * pbtData, const size_t szBytes)
|
||||||
{
|
{
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
|
|
||||||
for (szPos=0; szPos < szBytes; szPos++)
|
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||||
{
|
|
||||||
printf ("%02x ", pbtData[szPos]);
|
printf ("%02x ", pbtData[szPos]);
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_hex_bits(const byte_t* pbtData, const size_t szBits)
|
void
|
||||||
|
print_hex_bits (const byte_t * pbtData, const size_t szBits)
|
||||||
{
|
{
|
||||||
uint8_t uRemainder;
|
uint8_t uRemainder;
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
size_t szBytes = szBits / 8;
|
size_t szBytes = szBits / 8;
|
||||||
|
|
||||||
for (szPos=0; szPos < szBytes; szPos++)
|
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||||
{
|
|
||||||
printf ("%02x ", pbtData[szPos]);
|
printf ("%02x ", pbtData[szPos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uRemainder = szBits % 8;
|
uRemainder = szBits % 8;
|
||||||
// Print the rest bits
|
// Print the rest bits
|
||||||
if (uRemainder != 0)
|
if (uRemainder != 0) {
|
||||||
{
|
|
||||||
if (uRemainder < 5)
|
if (uRemainder < 5)
|
||||||
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
|
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
|
||||||
else
|
else
|
||||||
|
@ -70,17 +70,16 @@ void print_hex_bits(const byte_t* pbtData, const size_t szBits)
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbtDataPar)
|
void
|
||||||
|
print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar)
|
||||||
{
|
{
|
||||||
uint8_t uRemainder;
|
uint8_t uRemainder;
|
||||||
size_t szPos;
|
size_t szPos;
|
||||||
size_t szBytes = szBits / 8;
|
size_t szBytes = szBits / 8;
|
||||||
|
|
||||||
for (szPos=0; szPos < szBytes; szPos++)
|
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||||
{
|
|
||||||
printf ("%02x", pbtData[szPos]);
|
printf ("%02x", pbtData[szPos]);
|
||||||
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos])
|
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos]) {
|
||||||
{
|
|
||||||
printf ("! ");
|
printf ("! ");
|
||||||
} else {
|
} else {
|
||||||
printf (" ");
|
printf (" ");
|
||||||
|
@ -89,8 +88,7 @@ void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbt
|
||||||
|
|
||||||
uRemainder = szBits % 8;
|
uRemainder = szBits % 8;
|
||||||
// Print the rest bits, these cannot have parity bit
|
// Print the rest bits, these cannot have parity bit
|
||||||
if (uRemainder != 0)
|
if (uRemainder != 0) {
|
||||||
{
|
|
||||||
if (uRemainder < 5)
|
if (uRemainder < 5)
|
||||||
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
|
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
|
||||||
else
|
else
|
||||||
|
@ -102,35 +100,49 @@ void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbt
|
||||||
#define SAK_ISO14443_4_COMPLIANT 0x20
|
#define SAK_ISO14443_4_COMPLIANT 0x20
|
||||||
#define SAK_ISO18092_COMPLIANT 0x40
|
#define SAK_ISO18092_COMPLIANT 0x40
|
||||||
|
|
||||||
void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai)
|
void
|
||||||
|
print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai)
|
||||||
{
|
{
|
||||||
printf(" ATQA (SENS_RES): "); print_hex(nai.abtAtqa,2);
|
printf (" ATQA (SENS_RES): ");
|
||||||
printf(" UID (NFCID%c): ",(nai.abtUid[0]==0x08?'3':'1')); print_hex(nai.abtUid, nai.szUidLen);
|
print_hex (nai.abtAtqa, 2);
|
||||||
printf(" SAK (SEL_RES): "); print_hex(&nai.btSak,1);
|
printf (" UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1'));
|
||||||
|
print_hex (nai.abtUid, nai.szUidLen);
|
||||||
|
printf (" SAK (SEL_RES): ");
|
||||||
|
print_hex (&nai.btSak, 1);
|
||||||
if (nai.szAtsLen) {
|
if (nai.szAtsLen) {
|
||||||
printf (" ATS (ATR): ");
|
printf (" ATS (ATR): ");
|
||||||
print_hex (nai.abtAts, nai.szAtsLen);
|
print_hex (nai.abtAts, nai.szAtsLen);
|
||||||
}
|
}
|
||||||
if ((nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT)) {
|
if ((nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT)) {
|
||||||
printf (" Compliant with: ");
|
printf (" Compliant with: ");
|
||||||
if (nai.btSak & SAK_ISO14443_4_COMPLIANT) printf("ISO/IEC 14443-4 ");
|
if (nai.btSak & SAK_ISO14443_4_COMPLIANT)
|
||||||
if (nai.btSak & SAK_ISO18092_COMPLIANT) printf("ISO/IEC 18092");
|
printf ("ISO/IEC 14443-4 ");
|
||||||
|
if (nai.btSak & SAK_ISO18092_COMPLIANT)
|
||||||
|
printf ("ISO/IEC 18092");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void print_nfc_felica_info(const nfc_felica_info_t nfi)
|
|
||||||
|
void
|
||||||
|
print_nfc_felica_info (const nfc_felica_info_t nfi)
|
||||||
{
|
{
|
||||||
printf(" ID (NFCID2): "); print_hex(nfi.abtId,8);
|
printf (" ID (NFCID2): ");
|
||||||
printf(" Parameter (PAD): "); print_hex(nfi.abtPad,8);
|
print_hex (nfi.abtId, 8);
|
||||||
|
printf (" Parameter (PAD): ");
|
||||||
|
print_hex (nfi.abtPad, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_nfc_iso14443b_info(const nfc_iso14443b_info_t nbi)
|
void
|
||||||
|
print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi)
|
||||||
{
|
{
|
||||||
printf(" ATQB: "); print_hex(nbi.abtAtqb,12);
|
printf (" ATQB: ");
|
||||||
printf(" ID: "); print_hex(nbi.abtId,4);
|
print_hex (nbi.abtAtqb, 12);
|
||||||
|
printf (" ID: ");
|
||||||
|
print_hex (nbi.abtId, 4);
|
||||||
printf (" CID: %02x\n", nbi.btCid);
|
printf (" CID: %02x\n", nbi.btCid);
|
||||||
if (nbi.szInfLen > 0) {
|
if (nbi.szInfLen > 0) {
|
||||||
printf(" INF: "); print_hex(nbi.abtInf,nbi.szInfLen);
|
printf (" INF: ");
|
||||||
|
print_hex (nbi.abtInf, nbi.szInfLen);
|
||||||
}
|
}
|
||||||
printf (" PARAMS: %02x %02x %02x %02x\n", nbi.btParam1, nbi.btParam2, nbi.btParam3, nbi.btParam4);
|
printf (" PARAMS: %02x %02x %02x %02x\n", nbi.btParam1, nbi.btParam2, nbi.btParam3, nbi.btParam4);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +151,8 @@ void print_nfc_iso14443b_info(const nfc_iso14443b_info_t nbi)
|
||||||
* @brief Tries to parse arguments to find device descriptions.
|
* @brief Tries to parse arguments to find device descriptions.
|
||||||
* @return Returns the list of found device descriptions.
|
* @return Returns the list of found device descriptions.
|
||||||
*/
|
*/
|
||||||
nfc_device_desc_t* parse_device_desc(int argc, const char *argv[], size_t* szFound)
|
nfc_device_desc_t *
|
||||||
|
parse_device_desc (int argc, const char *argv[], size_t * szFound)
|
||||||
{
|
{
|
||||||
nfc_device_desc_t *pndd = 0;
|
nfc_device_desc_t *pndd = 0;
|
||||||
int arg;
|
int arg;
|
||||||
|
@ -176,4 +189,3 @@ nfc_device_desc_t* parse_device_desc(int argc, const char *argv[], size_t* szFou
|
||||||
|
|
||||||
return pndd;
|
return pndd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
int main(int argc, const char *argv[])
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd;
|
nfc_device_t *pnd;
|
||||||
nfc_target_info_t ti;
|
nfc_target_info_t ti;
|
||||||
|
@ -47,18 +48,13 @@ int main(int argc, const char *argv[])
|
||||||
|
|
||||||
pnd = nfc_connect (NULL);
|
pnd = nfc_connect (NULL);
|
||||||
if (!pnd || !nfc_initiator_init (pnd)
|
if (!pnd || !nfc_initiator_init (pnd)
|
||||||
|| !nfc_initiator_select_dep_target(pnd, NM_PASSIVE_DEP, NULL, 0,
|
|| !nfc_initiator_select_dep_target (pnd, NM_PASSIVE_DEP, NULL, 0, NULL, 0, NULL, 0, &ti)) {
|
||||||
NULL, 0, NULL, 0, &ti)) {
|
printf ("unable to connect, initialize, or select the target\n");
|
||||||
printf
|
|
||||||
("unable to connect, initialize, or select the target\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("Sending : %s\n", send);
|
printf ("Sending : %s\n", send);
|
||||||
if (!nfc_initiator_transceive_bytes(pnd,
|
if (!nfc_initiator_transceive_bytes (pnd, send, strlen ((char *) send), abtRecv, &szRecvBits)) {
|
||||||
send,
|
|
||||||
strlen((char*)send), abtRecv,
|
|
||||||
&szRecvBits)) {
|
|
||||||
printf ("unable to send data\n");
|
printf ("unable to send data\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
|
|
||||||
#define MAX_FRAME_LEN 264
|
#define MAX_FRAME_LEN 264
|
||||||
|
|
||||||
int main(int argc, const char *argv[])
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
byte_t abtRecv[MAX_FRAME_LEN];
|
byte_t abtRecv[MAX_FRAME_LEN];
|
||||||
size_t szRecvBits;
|
size_t szRecvBits;
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
#define MAX_DEVICE_COUNT 16
|
#define MAX_DEVICE_COUNT 16
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int
|
||||||
|
main (int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
size_t szFound;
|
size_t szFound;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -53,7 +54,6 @@ int main(int argc, const char* argv[])
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
errx (1, "usage: %s", argv[0]);
|
errx (1, "usage: %s", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
acLibnfcVersion = nfc_version ();
|
acLibnfcVersion = nfc_version ();
|
||||||
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||||
|
@ -80,9 +80,13 @@ int main(int argc, const char* argv[])
|
||||||
printf ("NFC device [%s] connected.\n", pnd->acName);
|
printf ("NFC device [%s] connected.\n", pnd->acName);
|
||||||
|
|
||||||
// FIXME: Direct call
|
// FIXME: Direct call
|
||||||
result = pn53x_transceive(pnd,pncmd_diagnose_communication_line_test,sizeof(pncmd_diagnose_communication_line_test),abtRx,&szRxLen);
|
result =
|
||||||
|
pn53x_transceive (pnd, pncmd_diagnose_communication_line_test, sizeof (pncmd_diagnose_communication_line_test),
|
||||||
|
abtRx, &szRxLen);
|
||||||
if (result) {
|
if (result) {
|
||||||
result = (memcmp(pncmd_diagnose_communication_line_test+2, abtRx, sizeof(pncmd_diagnose_communication_line_test)-2 ) == 0);
|
result =
|
||||||
|
(memcmp (pncmd_diagnose_communication_line_test + 2, abtRx, sizeof (pncmd_diagnose_communication_line_test) - 2)
|
||||||
|
== 0);
|
||||||
}
|
}
|
||||||
printf (" Communication line test: %s\n", result ? "OK" : "Failed");
|
printf (" Communication line test: %s\n", result ? "OK" : "Failed");
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,11 @@ struct driver_callbacks {
|
||||||
/** Connect callback */
|
/** Connect callback */
|
||||||
nfc_device_t *(*connect) (const nfc_device_desc_t * pndd);
|
nfc_device_t *(*connect) (const nfc_device_desc_t * pndd);
|
||||||
/** Transceive callback */
|
/** Transceive callback */
|
||||||
bool (*transceive)(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
|
||||||
|
|
||||||
|
|
||||||
|
bool (*transceive) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen);
|
||||||
/** Disconnect callback */
|
/** Disconnect callback */
|
||||||
void (*disconnect) (nfc_device_t * pnd);
|
void (*disconnect) (nfc_device_t * pnd);
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,16 +36,22 @@
|
||||||
/* CMake compilation */
|
/* CMake compilation */
|
||||||
# ifdef nfc_EXPORTS
|
# ifdef nfc_EXPORTS
|
||||||
# define NFC_EXPORT __declspec(dllexport)
|
# define NFC_EXPORT __declspec(dllexport)
|
||||||
#else /* nfc_EXPORTS */
|
# else
|
||||||
|
/* nfc_EXPORTS */
|
||||||
# define NFC_EXPORT __declspec(dllimport)
|
# define NFC_EXPORT __declspec(dllimport)
|
||||||
#endif /* nfc_EXPORTS */
|
# endif
|
||||||
#else /* _WINDLL */
|
/* nfc_EXPORTS */
|
||||||
|
# else
|
||||||
|
/* _WINDLL */
|
||||||
/* Manual makefile */
|
/* Manual makefile */
|
||||||
# define NFC_EXPORT
|
# define NFC_EXPORT
|
||||||
#endif /* _WINDLL */
|
# endif
|
||||||
#else /* _WIN32 */
|
/* _WINDLL */
|
||||||
|
# else
|
||||||
|
/* _WIN32 */
|
||||||
# define NFC_EXPORT
|
# define NFC_EXPORT
|
||||||
#endif /* _WIN32 */
|
# endif
|
||||||
|
/* _WIN32 */
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
|
@ -61,19 +67,33 @@ NFC_EXPORT bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo,
|
||||||
|
|
||||||
/* NFC initiator: act as "reader" */
|
/* NFC initiator: act as "reader" */
|
||||||
NFC_EXPORT bool nfc_initiator_init (nfc_device_t * pnd);
|
NFC_EXPORT bool nfc_initiator_init (nfc_device_t * pnd);
|
||||||
NFC_EXPORT bool nfc_initiator_select_passive_target(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtInitData, const size_t szInitDataLen, nfc_target_info_t* pti);
|
NFC_EXPORT bool nfc_initiator_select_passive_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
NFC_EXPORT bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, nfc_target_info_t anti[], const size_t szTargets, size_t *pszTargetFound );
|
const byte_t * pbtInitData, const size_t szInitDataLen,
|
||||||
NFC_EXPORT bool nfc_initiator_poll_targets(nfc_device_t* pnd, const nfc_target_type_t* pnttTargetTypes, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t* pntTargets, size_t* pszTargetFound);
|
nfc_target_info_t * pti);
|
||||||
NFC_EXPORT bool nfc_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pti);
|
NFC_EXPORT bool nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
|
nfc_target_info_t anti[], const size_t szTargets,
|
||||||
|
size_t * pszTargetFound);
|
||||||
|
NFC_EXPORT bool nfc_initiator_poll_targets (nfc_device_t * pnd, const nfc_target_type_t * pnttTargetTypes,
|
||||||
|
const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod,
|
||||||
|
nfc_target_t * pntTargets, size_t * pszTargetFound);
|
||||||
|
NFC_EXPORT bool nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
|
const byte_t * pbtPidData, const size_t szPidDataLen,
|
||||||
|
const byte_t * pbtNFCID3i, const size_t szNFCID3iDataLen,
|
||||||
|
const byte_t * pbtGbData, const size_t szGbDataLen,
|
||||||
|
nfc_target_info_t * pti);
|
||||||
NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd);
|
NFC_EXPORT bool nfc_initiator_deselect_target (nfc_device_t * pnd);
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
NFC_EXPORT bool nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
||||||
NFC_EXPORT bool nfc_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits,
|
||||||
|
byte_t * pbtRxPar);
|
||||||
|
NFC_EXPORT bool nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen,
|
||||||
|
byte_t * pbtRx, size_t * pszRxLen);
|
||||||
|
|
||||||
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */
|
||||||
NFC_EXPORT bool nfc_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits);
|
NFC_EXPORT bool nfc_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits);
|
||||||
NFC_EXPORT bool nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
NFC_EXPORT bool nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
||||||
NFC_EXPORT bool nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen);
|
NFC_EXPORT bool nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen);
|
||||||
NFC_EXPORT bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
|
NFC_EXPORT bool nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
||||||
|
const byte_t * pbtTxPar);
|
||||||
NFC_EXPORT bool nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen);
|
NFC_EXPORT bool nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen);
|
||||||
|
|
||||||
/* Error reporting */
|
/* Error reporting */
|
||||||
|
@ -97,7 +117,4 @@ NFC_EXPORT const char* nfc_version(void);
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
}
|
}
|
||||||
# endif // __cplusplus
|
# endif // __cplusplus
|
||||||
|
|
||||||
|
|
||||||
#endif // _LIBNFC_H_
|
#endif // _LIBNFC_H_
|
||||||
|
|
||||||
|
|
|
@ -22,4 +22,3 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nfc/nfc-types.h>
|
#include <nfc/nfc-types.h>
|
||||||
|
|
||||||
|
|
|
@ -60,32 +60,29 @@ const struct timeval timeout = {
|
||||||
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
|
||||||
# define CCLAIMED 0x80000000
|
# define CCLAIMED 0x80000000
|
||||||
|
|
||||||
serial_port uart_open(const char* pcPortName)
|
serial_port
|
||||||
|
uart_open (const char *pcPortName)
|
||||||
{
|
{
|
||||||
serial_port_unix *sp = malloc (sizeof (serial_port_unix));
|
serial_port_unix *sp = malloc (sizeof (serial_port_unix));
|
||||||
|
|
||||||
if (sp == 0) return INVALID_SERIAL_PORT;
|
if (sp == 0)
|
||||||
|
return INVALID_SERIAL_PORT;
|
||||||
|
|
||||||
sp->fd = open (pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
sp->fd = open (pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||||
if(sp->fd == -1)
|
if (sp->fd == -1) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tcgetattr(sp->fd,&sp->tiOld) == -1)
|
if (tcgetattr (sp->fd, &sp->tiOld) == -1) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the port is not claimed already
|
// Make sure the port is not claimed already
|
||||||
if (sp->tiOld.c_iflag & CCLAIMED)
|
if (sp->tiOld.c_iflag & CCLAIMED) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return CLAIMED_SERIAL_PORT;
|
return CLAIMED_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the old terminal info struct
|
// Copy the old terminal info struct
|
||||||
sp->tiNew = sp->tiOld;
|
sp->tiNew = sp->tiOld;
|
||||||
|
|
||||||
|
@ -97,8 +94,7 @@ serial_port uart_open(const char* pcPortName)
|
||||||
sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received
|
sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received
|
||||||
sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
|
sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
|
||||||
|
|
||||||
if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1)
|
if (tcsetattr (sp->fd, TCSANOW, &sp->tiNew) == -1) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +103,8 @@ serial_port uart_open(const char* pcPortName)
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
void
|
||||||
|
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
{
|
{
|
||||||
DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||||
const serial_port_unix *spu = (serial_port_unix *) sp;
|
const serial_port_unix *spu = (serial_port_unix *) sp;
|
||||||
|
@ -116,67 +113,81 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||||
// uint32_t <=> speed_t associations by hand.
|
// uint32_t <=> speed_t associations by hand.
|
||||||
speed_t stPortSpeed = B9600;
|
speed_t stPortSpeed = B9600;
|
||||||
switch (uiPortSpeed) {
|
switch (uiPortSpeed) {
|
||||||
case 9600: stPortSpeed = B9600;
|
case 9600:
|
||||||
|
stPortSpeed = B9600;
|
||||||
break;
|
break;
|
||||||
case 19200: stPortSpeed = B19200;
|
case 19200:
|
||||||
|
stPortSpeed = B19200;
|
||||||
break;
|
break;
|
||||||
case 38400: stPortSpeed = B38400;
|
case 38400:
|
||||||
|
stPortSpeed = B38400;
|
||||||
break;
|
break;
|
||||||
# ifdef B57600
|
# ifdef B57600
|
||||||
case 57600: stPortSpeed = B57600;
|
case 57600:
|
||||||
|
stPortSpeed = B57600;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef B115200
|
# ifdef B115200
|
||||||
case 115200: stPortSpeed = B115200;
|
case 115200:
|
||||||
|
stPortSpeed = B115200;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef B230400
|
# ifdef B230400
|
||||||
case 230400: stPortSpeed = B230400;
|
case 230400:
|
||||||
|
stPortSpeed = B230400;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef B460800
|
# ifdef B460800
|
||||||
case 460800: stPortSpeed = B460800;
|
case 460800:
|
||||||
|
stPortSpeed = B460800;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
default:
|
default:
|
||||||
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).", uiPortSpeed);
|
ERR ("Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).",
|
||||||
|
uiPortSpeed);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set port speed (Input and Output)
|
// Set port speed (Input and Output)
|
||||||
cfsetispeed ((struct termios *) &(spu->tiNew), stPortSpeed);
|
cfsetispeed ((struct termios *) &(spu->tiNew), stPortSpeed);
|
||||||
cfsetospeed ((struct termios *) &(spu->tiNew), stPortSpeed);
|
cfsetospeed ((struct termios *) &(spu->tiNew), stPortSpeed);
|
||||||
if( tcsetattr(spu->fd, TCSADRAIN, &(spu->tiNew)) == -1)
|
if (tcsetattr (spu->fd, TCSADRAIN, &(spu->tiNew)) == -1) {
|
||||||
{
|
|
||||||
ERR ("%s", "Unable to apply new speed settings.");
|
ERR ("%s", "Unable to apply new speed settings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uart_get_speed(serial_port sp)
|
uint32_t
|
||||||
|
uart_get_speed (serial_port sp)
|
||||||
{
|
{
|
||||||
uint32_t uiPortSpeed = 0;
|
uint32_t uiPortSpeed = 0;
|
||||||
const serial_port_unix *spu = (serial_port_unix *) sp;
|
const serial_port_unix *spu = (serial_port_unix *) sp;
|
||||||
switch (cfgetispeed(&spu->tiNew))
|
switch (cfgetispeed (&spu->tiNew)) {
|
||||||
{
|
case B9600:
|
||||||
case B9600: uiPortSpeed = 9600;
|
uiPortSpeed = 9600;
|
||||||
break;
|
break;
|
||||||
case B19200: uiPortSpeed = 19200;
|
case B19200:
|
||||||
|
uiPortSpeed = 19200;
|
||||||
break;
|
break;
|
||||||
case B38400: uiPortSpeed = 38400;
|
case B38400:
|
||||||
|
uiPortSpeed = 38400;
|
||||||
break;
|
break;
|
||||||
# ifdef B57600
|
# ifdef B57600
|
||||||
case B57600: uiPortSpeed = 57600;
|
case B57600:
|
||||||
|
uiPortSpeed = 57600;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef B115200
|
# ifdef B115200
|
||||||
case B115200: uiPortSpeed = 115200;
|
case B115200:
|
||||||
|
uiPortSpeed = 115200;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef B230400
|
# ifdef B230400
|
||||||
case B230400: uiPortSpeed = 230400;
|
case B230400:
|
||||||
|
uiPortSpeed = 230400;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef B460800
|
# ifdef B460800
|
||||||
case B460800: uiPortSpeed = 460800;
|
case B460800:
|
||||||
|
uiPortSpeed = 460800;
|
||||||
break;
|
break;
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
@ -184,7 +195,8 @@ uint32_t uart_get_speed(serial_port sp)
|
||||||
return uiPortSpeed;
|
return uiPortSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_close(const serial_port sp)
|
void
|
||||||
|
uart_close (const serial_port sp)
|
||||||
{
|
{
|
||||||
if (((serial_port_unix *) sp)->fd >= 0) {
|
if (((serial_port_unix *) sp)->fd >= 0) {
|
||||||
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->tiOld);
|
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->tiOld);
|
||||||
|
@ -221,7 +233,6 @@ uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
DBG ("%s", "RX error.");
|
DBG ("%s", "RX error.");
|
||||||
return DEIO;
|
return DEIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read time-out
|
// Read time-out
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
if (*pszRxLen == 0) {
|
if (*pszRxLen == 0) {
|
||||||
|
@ -233,13 +244,11 @@ uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the count of the incoming bytes
|
// Retrieve the count of the incoming bytes
|
||||||
res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &byteCount);
|
res = ioctl (((serial_port_unix *) sp)->fd, FIONREAD, &byteCount);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return DEIO;
|
return DEIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is something available, read the data
|
// There is something available, read the data
|
||||||
res = read (((serial_port_unix *) sp)->fd, pbtRx + (*pszRxLen), byteCount);
|
res = read (((serial_port_unix *) sp)->fd, pbtRx + (*pszRxLen), byteCount);
|
||||||
|
|
||||||
|
@ -268,8 +277,7 @@ uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
while (szPos < szTxLen)
|
while (szPos < szTxLen) {
|
||||||
{
|
|
||||||
// Reset file descriptor
|
// Reset file descriptor
|
||||||
FD_ZERO (&rfds);
|
FD_ZERO (&rfds);
|
||||||
FD_SET (((serial_port_unix *) sp)->fd, &rfds);
|
FD_SET (((serial_port_unix *) sp)->fd, &rfds);
|
||||||
|
@ -281,13 +289,11 @@ uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||||
DBG ("%s", "TX error.");
|
DBG ("%s", "TX error.");
|
||||||
return DEIO;
|
return DEIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write time-out
|
// Write time-out
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
DBG ("%s", "TX time-out.");
|
DBG ("%s", "TX time-out.");
|
||||||
return DETIMEOUT;
|
return DETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send away the bytes
|
// Send away the bytes
|
||||||
res = write (((serial_port_unix *) sp)->fd, pbtTx + szPos, szTxLen - szPos);
|
res = write (((serial_port_unix *) sp)->fd, pbtTx + szPos, szTxLen - szPos);
|
||||||
|
|
||||||
|
@ -310,7 +316,8 @@ typedef struct {
|
||||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||||
} serial_port_windows;
|
} serial_port_windows;
|
||||||
|
|
||||||
serial_port uart_open(const char* pcPortName)
|
serial_port
|
||||||
|
uart_open (const char *pcPortName)
|
||||||
{
|
{
|
||||||
char acPortName[255];
|
char acPortName[255];
|
||||||
serial_port_windows *sp = malloc (sizeof (serial_port_windows));
|
serial_port_windows *sp = malloc (sizeof (serial_port_windows));
|
||||||
|
@ -321,24 +328,19 @@ serial_port uart_open(const char* pcPortName)
|
||||||
|
|
||||||
// Try to open the serial port
|
// Try to open the serial port
|
||||||
sp->hPort = CreateFileA (acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
sp->hPort = CreateFileA (acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
if (sp->hPort == INVALID_HANDLE_VALUE)
|
if (sp->hPort == INVALID_HANDLE_VALUE) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the device control
|
// Prepare the device control
|
||||||
memset (&sp->dcb, 0, sizeof (DCB));
|
memset (&sp->dcb, 0, sizeof (DCB));
|
||||||
sp->dcb.DCBlength = sizeof (DCB);
|
sp->dcb.DCBlength = sizeof (DCB);
|
||||||
if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb))
|
if (!BuildCommDCBA ("baud=9600 data=8 parity=N stop=1", &sp->dcb)) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the active serial port
|
// Update the active serial port
|
||||||
if(!SetCommState(sp->hPort,&sp->dcb))
|
if (!SetCommState (sp->hPort, &sp->dcb)) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
@ -349,8 +351,7 @@ serial_port uart_open(const char* pcPortName)
|
||||||
sp->ct.WriteTotalTimeoutMultiplier = 0;
|
sp->ct.WriteTotalTimeoutMultiplier = 0;
|
||||||
sp->ct.WriteTotalTimeoutConstant = 30;
|
sp->ct.WriteTotalTimeoutConstant = 30;
|
||||||
|
|
||||||
if(!SetCommTimeouts(sp->hPort,&sp->ct))
|
if (!SetCommTimeouts (sp->hPort, &sp->ct)) {
|
||||||
{
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +361,8 @@ serial_port uart_open(const char* pcPortName)
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_close(const serial_port sp)
|
void
|
||||||
|
uart_close (const serial_port sp)
|
||||||
{
|
{
|
||||||
if (((serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
|
if (((serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle (((serial_port_windows *) sp)->hPort);
|
CloseHandle (((serial_port_windows *) sp)->hPort);
|
||||||
|
@ -368,7 +370,8 @@ void uart_close(const serial_port sp)
|
||||||
free (sp);
|
free (sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
void
|
||||||
|
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
|
||||||
{
|
{
|
||||||
serial_port_windows *spw;
|
serial_port_windows *spw;
|
||||||
|
|
||||||
|
@ -384,18 +387,20 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||||
case 460800:
|
case 460800:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
|
ERR
|
||||||
|
("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.",
|
||||||
|
uiPortSpeed);
|
||||||
};
|
};
|
||||||
|
|
||||||
spw = (serial_port_windows *) sp;
|
spw = (serial_port_windows *) sp;
|
||||||
spw->dcb.BaudRate = uiPortSpeed;
|
spw->dcb.BaudRate = uiPortSpeed;
|
||||||
if (!SetCommState(spw->hPort, &spw->dcb))
|
if (!SetCommState (spw->hPort, &spw->dcb)) {
|
||||||
{
|
|
||||||
ERR ("Unable to apply new speed settings.");
|
ERR ("Unable to apply new speed settings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uart_get_speed(const serial_port sp)
|
uint32_t
|
||||||
|
uart_get_speed (const serial_port sp)
|
||||||
{
|
{
|
||||||
const serial_port_windows *spw = (serial_port_windows *) sp;
|
const serial_port_windows *spw = (serial_port_windows *) sp;
|
||||||
if (!GetCommState (spw->hPort, (serial_port) & spw->dcb))
|
if (!GetCommState (spw->hPort, (serial_port) & spw->dcb))
|
||||||
|
@ -404,7 +409,8 @@ uint32_t uart_get_speed(const serial_port sp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
int
|
||||||
|
uart_receive (serial_port sp, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
if (!ReadFile (((serial_port_windows *) sp)->hPort, pbtRx, *pszRxLen, (LPDWORD) pszRxLen, NULL)) {
|
if (!ReadFile (((serial_port_windows *) sp)->hPort, pbtRx, *pszRxLen, (LPDWORD) pszRxLen, NULL)) {
|
||||||
return DEIO;
|
return DEIO;
|
||||||
|
@ -414,7 +420,8 @@ int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
int
|
||||||
|
uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTxLen)
|
||||||
{
|
{
|
||||||
DWORD dwTxLen = 0;
|
DWORD dwTxLen = 0;
|
||||||
if (!WriteFile (((serial_port_windows *) sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL)) {
|
if (!WriteFile (((serial_port_windows *) sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL)) {
|
||||||
|
|
|
@ -88,4 +88,3 @@ int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
|
||||||
int uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTxLen);
|
int uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTxLen);
|
||||||
|
|
||||||
#endif // __NFC_BUS_UART_H__
|
#endif // __NFC_BUS_UART_H__
|
||||||
|
|
||||||
|
|
|
@ -30,4 +30,3 @@
|
||||||
# include "chips/pn53x.h"
|
# include "chips/pn53x.h"
|
||||||
|
|
||||||
#endif // __NFC_CHIPS_H__
|
#endif // __NFC_CHIPS_H__
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,8 @@ static const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
||||||
static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
|
static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
|
||||||
|
|
||||||
// XXX: Is this function correctly named ?
|
// XXX: Is this function correctly named ?
|
||||||
bool pn53x_transceive_check_ack_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
bool
|
||||||
|
pn53x_transceive_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen)
|
||||||
{
|
{
|
||||||
if (szRxFrameLen >= sizeof (pn53x_ack_frame)) {
|
if (szRxFrameLen >= sizeof (pn53x_ack_frame)) {
|
||||||
if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
|
if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
|
||||||
|
@ -103,7 +104,8 @@ bool pn53x_transceive_check_ack_frame_callback(nfc_device_t* pnd, const byte_t *
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_transceive_check_error_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
bool
|
||||||
|
pn53x_transceive_check_error_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame, const size_t szRxFrameLen)
|
||||||
{
|
{
|
||||||
if (szRxFrameLen >= sizeof (pn53x_error_frame)) {
|
if (szRxFrameLen >= sizeof (pn53x_error_frame)) {
|
||||||
if (0 == memcmp (pbtRxFrame, pn53x_error_frame, sizeof (pn53x_error_frame))) {
|
if (0 == memcmp (pbtRxFrame, pn53x_error_frame, sizeof (pn53x_error_frame))) {
|
||||||
|
@ -116,21 +118,22 @@ bool pn53x_transceive_check_error_frame_callback(nfc_device_t* pnd, const byte_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
|
|
||||||
// Check if receiving buffers are available, if not, replace them
|
// Check if receiving buffers are available, if not, replace them
|
||||||
if (!pszRxLen || !pbtRx)
|
if (!pszRxLen || !pbtRx) {
|
||||||
{
|
|
||||||
pbtRx = abtRx;
|
pbtRx = abtRx;
|
||||||
pszRxLen = &szRxLen;
|
pszRxLen = &szRxLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pszRxLen = MAX_FRAME_LEN;
|
*pszRxLen = MAX_FRAME_LEN;
|
||||||
// Call the tranceive callback function of the current device
|
// Call the tranceive callback function of the current device
|
||||||
if (!pnd->pdc->transceive(pnd,pbtTx,szTxLen,pbtRx,pszRxLen)) return false;
|
if (!pnd->pdc->transceive (pnd, pbtTx, szTxLen, pbtRx, pszRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (pbtTx[1]) {
|
switch (pbtTx[1]) {
|
||||||
case 0x16: // PowerDown
|
case 0x16: // PowerDown
|
||||||
|
@ -158,7 +161,8 @@ bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxL
|
||||||
return (0 == pnd->iLastError);
|
return (0 == pnd->iLastError);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_get_reg(nfc_device_t* pnd, uint16_t ui16Reg, uint8_t* ui8Value)
|
bool
|
||||||
|
pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value)
|
||||||
{
|
{
|
||||||
size_t szValueLen = 1;
|
size_t szValueLen = 1;
|
||||||
byte_t abtCmd[sizeof (pncmd_get_register)];
|
byte_t abtCmd[sizeof (pncmd_get_register)];
|
||||||
|
@ -169,7 +173,8 @@ bool pn53x_get_reg(nfc_device_t* pnd, uint16_t ui16Reg, uint8_t* ui8Value)
|
||||||
return pn53x_transceive (pnd, abtCmd, 4, ui8Value, &szValueLen);
|
return pn53x_transceive (pnd, abtCmd, 4, ui8Value, &szValueLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_set_reg(nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value)
|
bool
|
||||||
|
pn53x_set_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value)
|
||||||
{
|
{
|
||||||
uint8_t ui8Current;
|
uint8_t ui8Current;
|
||||||
byte_t abtCmd[sizeof (pncmd_set_register)];
|
byte_t abtCmd[sizeof (pncmd_set_register)];
|
||||||
|
@ -184,7 +189,8 @@ bool pn53x_set_reg(nfc_device_t* pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, u
|
||||||
return pn53x_transceive (pnd, abtCmd, 5, NULL, NULL);
|
return pn53x_transceive (pnd, abtCmd, 5, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_set_parameters(nfc_device_t* pnd, uint8_t ui8Value)
|
bool
|
||||||
|
pn53x_set_parameters (nfc_device_t * pnd, uint8_t ui8Value)
|
||||||
{
|
{
|
||||||
byte_t abtCmd[sizeof (pncmd_set_parameters)];
|
byte_t abtCmd[sizeof (pncmd_set_parameters)];
|
||||||
memcpy (abtCmd, pncmd_set_parameters, sizeof (pncmd_set_parameters));
|
memcpy (abtCmd, pncmd_set_parameters, sizeof (pncmd_set_parameters));
|
||||||
|
@ -193,13 +199,14 @@ bool pn53x_set_parameters(nfc_device_t* pnd, uint8_t ui8Value)
|
||||||
return pn53x_transceive (pnd, abtCmd, 3, NULL, NULL);
|
return pn53x_transceive (pnd, abtCmd, 3, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_set_tx_bits(nfc_device_t* pnd, uint8_t ui8Bits)
|
bool
|
||||||
|
pn53x_set_tx_bits (nfc_device_t * pnd, uint8_t ui8Bits)
|
||||||
{
|
{
|
||||||
// Test if we need to update the transmission bits register setting
|
// Test if we need to update the transmission bits register setting
|
||||||
if (pnd->ui8TxBits != ui8Bits)
|
if (pnd->ui8TxBits != ui8Bits) {
|
||||||
{
|
|
||||||
// Set the amount of transmission bits in the PN53X chip register
|
// Set the amount of transmission bits in the PN53X chip register
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_BIT_FRAMING,SYMBOL_TX_LAST_BITS,ui8Bits)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, ui8Bits))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Store the new setting
|
// Store the new setting
|
||||||
((nfc_device_t *) pnd)->ui8TxBits = ui8Bits;
|
((nfc_device_t *) pnd)->ui8TxBits = ui8Bits;
|
||||||
|
@ -207,7 +214,9 @@ bool pn53x_set_tx_bits(nfc_device_t* pnd, uint8_t ui8Bits)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, size_t* pszFrameBits)
|
bool
|
||||||
|
pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtFrame,
|
||||||
|
size_t * pszFrameBits)
|
||||||
{
|
{
|
||||||
byte_t btFrame;
|
byte_t btFrame;
|
||||||
byte_t btData;
|
byte_t btData;
|
||||||
|
@ -216,16 +225,15 @@ bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t*
|
||||||
size_t szBitsLeft = szTxBits;
|
size_t szBitsLeft = szTxBits;
|
||||||
|
|
||||||
// Make sure we should frame at least something
|
// Make sure we should frame at least something
|
||||||
if (szBitsLeft == 0) return false;
|
if (szBitsLeft == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Handle a short response (1byte) as a special case
|
// Handle a short response (1byte) as a special case
|
||||||
if (szBitsLeft < 9)
|
if (szBitsLeft < 9) {
|
||||||
{
|
|
||||||
*pbtFrame = *pbtTx;
|
*pbtFrame = *pbtTx;
|
||||||
*pszFrameBits = szTxBits;
|
*pszFrameBits = szTxBits;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We start by calculating the frame length in bits
|
// We start by calculating the frame length in bits
|
||||||
*pszFrameBits = szTxBits + (szTxBits / 8);
|
*pszFrameBits = szTxBits + (szTxBits / 8);
|
||||||
|
|
||||||
|
@ -234,13 +242,11 @@ bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t*
|
||||||
// buffer = mirror(frame-byte) + parity + mirror(frame-byte) + parity + ...
|
// buffer = mirror(frame-byte) + parity + mirror(frame-byte) + parity + ...
|
||||||
// split "buffer" up in segments of 8 bits again and mirror them
|
// split "buffer" up in segments of 8 bits again and mirror them
|
||||||
// air-bytes = mirror(buffer-byte) + mirror(buffer-byte) + mirror(buffer-byte) + ..
|
// air-bytes = mirror(buffer-byte) + mirror(buffer-byte) + mirror(buffer-byte) + ..
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
|
||||||
// Reset the temporary frame byte;
|
// Reset the temporary frame byte;
|
||||||
btFrame = 0;
|
btFrame = 0;
|
||||||
|
|
||||||
for (uiBitPos=0; uiBitPos<8; uiBitPos++)
|
for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
|
||||||
{
|
|
||||||
// Copy as much data that fits in the frame byte
|
// Copy as much data that fits in the frame byte
|
||||||
btData = mirror (pbtTx[uiDataPos]);
|
btData = mirror (pbtTx[uiDataPos]);
|
||||||
btFrame |= (btData >> uiBitPos);
|
btFrame |= (btData >> uiBitPos);
|
||||||
|
@ -255,7 +261,8 @@ bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t*
|
||||||
// Increase the data (without parity bit) position
|
// Increase the data (without parity bit) position
|
||||||
uiDataPos++;
|
uiDataPos++;
|
||||||
// Test if we are done
|
// Test if we are done
|
||||||
if (szBitsLeft < 9) return true;
|
if (szBitsLeft < 9)
|
||||||
|
return true;
|
||||||
szBitsLeft -= 8;
|
szBitsLeft -= 8;
|
||||||
}
|
}
|
||||||
// Every 8 data bytes we lose one frame byte to the parities
|
// Every 8 data bytes we lose one frame byte to the parities
|
||||||
|
@ -263,7 +270,9 @@ bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
bool
|
||||||
|
pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
|
||||||
|
byte_t * pbtRxPar)
|
||||||
{
|
{
|
||||||
byte_t btFrame;
|
byte_t btFrame;
|
||||||
byte_t btData;
|
byte_t btData;
|
||||||
|
@ -273,35 +282,34 @@ bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t
|
||||||
size_t szBitsLeft = szFrameBits;
|
size_t szBitsLeft = szFrameBits;
|
||||||
|
|
||||||
// Make sure we should frame at least something
|
// Make sure we should frame at least something
|
||||||
if (szBitsLeft == 0) return false;
|
if (szBitsLeft == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Handle a short response (1byte) as a special case
|
// Handle a short response (1byte) as a special case
|
||||||
if (szBitsLeft < 9)
|
if (szBitsLeft < 9) {
|
||||||
{
|
|
||||||
*pbtRx = *pbtFrame;
|
*pbtRx = *pbtFrame;
|
||||||
*pszRxBits = szFrameBits;
|
*pszRxBits = szFrameBits;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the data length in bits
|
// Calculate the data length in bits
|
||||||
*pszRxBits = szFrameBits - (szFrameBits / 9);
|
*pszRxBits = szFrameBits - (szFrameBits / 9);
|
||||||
|
|
||||||
// Parse the frame bytes, remove the parity bits and store them in the parity array
|
// Parse the frame bytes, remove the parity bits and store them in the parity array
|
||||||
// This process is the reverse of WrapFrame(), look there for more info
|
// This process is the reverse of WrapFrame(), look there for more info
|
||||||
while(true)
|
while (true) {
|
||||||
{
|
for (uiBitPos = 0; uiBitPos < 8; uiBitPos++) {
|
||||||
for (uiBitPos=0; uiBitPos<8; uiBitPos++)
|
|
||||||
{
|
|
||||||
btFrame = mirror (pbtFramePos[uiDataPos]);
|
btFrame = mirror (pbtFramePos[uiDataPos]);
|
||||||
btData = (btFrame << uiBitPos);
|
btData = (btFrame << uiBitPos);
|
||||||
btFrame = mirror (pbtFramePos[uiDataPos + 1]);
|
btFrame = mirror (pbtFramePos[uiDataPos + 1]);
|
||||||
btData |= (btFrame >> (8 - uiBitPos));
|
btData |= (btFrame >> (8 - uiBitPos));
|
||||||
pbtRx[uiDataPos] = mirror (btData);
|
pbtRx[uiDataPos] = mirror (btData);
|
||||||
if(pbtRxPar != NULL) pbtRxPar[uiDataPos] = ((btFrame >> (7-uiBitPos)) & 0x01);
|
if (pbtRxPar != NULL)
|
||||||
|
pbtRxPar[uiDataPos] = ((btFrame >> (7 - uiBitPos)) & 0x01);
|
||||||
// Increase the data (without parity bit) position
|
// Increase the data (without parity bit) position
|
||||||
uiDataPos++;
|
uiDataPos++;
|
||||||
// Test if we are done
|
// Test if we are done
|
||||||
if (szBitsLeft < 9) return true;
|
if (szBitsLeft < 9)
|
||||||
|
return true;
|
||||||
szBitsLeft -= 9;
|
szBitsLeft -= 9;
|
||||||
}
|
}
|
||||||
// Every 8 data bytes we lose one frame byte to the parities
|
// Every 8 data bytes we lose one frame byte to the parities
|
||||||
|
@ -310,7 +318,8 @@ bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt, nfc_target_info_t* pnti)
|
pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt,
|
||||||
|
nfc_target_info_t * pnti)
|
||||||
{
|
{
|
||||||
uint8_t ui8AttribResLen;
|
uint8_t ui8AttribResLen;
|
||||||
switch (ntt) {
|
switch (ntt) {
|
||||||
|
@ -397,8 +406,7 @@ pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t
|
||||||
memcpy (pnti->nfi.abtPad, pbtRawData, 8);
|
memcpy (pnti->nfi.abtPad, pbtRawData, 8);
|
||||||
pbtRawData += 8;
|
pbtRawData += 8;
|
||||||
// Test if the System code (SYST_CODE) is available
|
// Test if the System code (SYST_CODE) is available
|
||||||
if (pnti->nfi.szLen > 18)
|
if (pnti->nfi.szLen > 18) {
|
||||||
{
|
|
||||||
memcpy (pnti->nfi.abtSysCode, pbtRawData, 2);
|
memcpy (pnti->nfi.abtSysCode, pbtRawData, 2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -447,7 +455,8 @@ pn53x_InListPassiveTarget(nfc_device_t* pnd,
|
||||||
abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
|
abtCmd[3] = nmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
|
||||||
|
|
||||||
// Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
|
// Set the optional initiator data (used for Felica, ISO14443B, Topaz Polling or for ISO14443A selecting a specific UID).
|
||||||
if (pbtInitiatorData) memcpy(abtCmd+4,pbtInitiatorData,szInitiatorDataLen);
|
if (pbtInitiatorData)
|
||||||
|
memcpy (abtCmd + 4, pbtInitiatorData, szInitiatorDataLen);
|
||||||
|
|
||||||
// Try to find a tag, call the tranceive callback function of the current device
|
// Try to find a tag, call the tranceive callback function of the current device
|
||||||
szRxLen = MAX_FRAME_LEN;
|
szRxLen = MAX_FRAME_LEN;
|
||||||
|
@ -482,10 +491,11 @@ pn53x_InRelease(nfc_device_t* pnd, const uint8_t ui8Target)
|
||||||
bool
|
bool
|
||||||
pn53x_InAutoPoll (nfc_device_t * pnd,
|
pn53x_InAutoPoll (nfc_device_t * pnd,
|
||||||
const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes,
|
const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes,
|
||||||
const byte_t btPollNr, const byte_t btPeriod,
|
const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets, size_t * pszTargetFound)
|
||||||
nfc_target_t* pntTargets, size_t* pszTargetFound)
|
|
||||||
{
|
{
|
||||||
size_t szTxInAutoPoll, n, szRxLen;
|
size_t szTxInAutoPoll,
|
||||||
|
n,
|
||||||
|
szRxLen;
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
bool res;
|
bool res;
|
||||||
byte_t *pbtTxInAutoPoll;
|
byte_t *pbtTxInAutoPoll;
|
||||||
|
@ -495,7 +505,6 @@ pn53x_InAutoPoll(nfc_device_t* pnd,
|
||||||
pnd->iLastError = DENOTSUP;
|
pnd->iLastError = DENOTSUP;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... }
|
// InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... }
|
||||||
szTxInAutoPoll = 4 + szTargetTypes;
|
szTxInAutoPoll = 4 + szTargetTypes;
|
||||||
pbtTxInAutoPoll = malloc (szTxInAutoPoll);
|
pbtTxInAutoPoll = malloc (szTxInAutoPoll);
|
||||||
|
@ -543,46 +552,51 @@ static struct sErrorMessage {
|
||||||
const char *pcErrorMsg;
|
const char *pcErrorMsg;
|
||||||
} sErrorMessages[] = {
|
} sErrorMessages[] = {
|
||||||
/* Chip-level errors */
|
/* Chip-level errors */
|
||||||
{ 0x00, "Success" },
|
{
|
||||||
{ 0x01, "Timeout" },
|
0x00, "Success"}, {
|
||||||
{ 0x02, "CRC Error" },
|
0x01, "Timeout"}, {
|
||||||
{ 0x03, "Parity Error" },
|
0x02, "CRC Error"}, {
|
||||||
{ 0x04, "Erroneous Bit Count" },
|
0x03, "Parity Error"}, {
|
||||||
{ 0x05, "Framing Error" },
|
0x04, "Erroneous Bit Count"}, {
|
||||||
{ 0x06, "Bit-collision" },
|
0x05, "Framing Error"}, {
|
||||||
{ 0x07, "Buffer Too Small" },
|
0x06, "Bit-collision"}, {
|
||||||
{ 0x09, "Buffer Overflow" },
|
0x07, "Buffer Too Small"}, {
|
||||||
{ 0x0a, "Timeout" },
|
0x09, "Buffer Overflow"}, {
|
||||||
{ 0x0b, "Protocol Error" },
|
0x0a, "Timeout"}, {
|
||||||
{ 0x0d, "Overheating" },
|
0x0b, "Protocol Error"}, {
|
||||||
{ 0x0e, "Internal Buffer overflow." },
|
0x0d, "Overheating"}, {
|
||||||
{ 0x10, "Invalid Parameter" },
|
0x0e, "Internal Buffer overflow."}, {
|
||||||
|
0x10, "Invalid Parameter"},
|
||||||
/* DEP Errors */
|
/* DEP Errors */
|
||||||
{ 0x12, "Unknown DEP Command" },
|
{
|
||||||
{ 0x13, "Invalid Parameter" },
|
0x12, "Unknown DEP Command"}, {
|
||||||
|
0x13, "Invalid Parameter"},
|
||||||
/* MIFARE */
|
/* MIFARE */
|
||||||
{ 0x14, "Authentication Error" },
|
{
|
||||||
|
0x14, "Authentication Error"},
|
||||||
/* */
|
/* */
|
||||||
{ 0x23, "Wrong ISO/IEC14443-3 Check Byte" },
|
{
|
||||||
{ 0x25, "Invalid State" },
|
0x23, "Wrong ISO/IEC14443-3 Check Byte"}, {
|
||||||
{ 0x26, "Operation Not Allowed" },
|
0x25, "Invalid State"}, {
|
||||||
{ 0x27, "Command Not Acceptable" },
|
0x26, "Operation Not Allowed"}, {
|
||||||
{ 0x29, "Target Released" },
|
0x27, "Command Not Acceptable"}, {
|
||||||
{ 0x2a, "Card ID Mismatch" },
|
0x29, "Target Released"}, {
|
||||||
{ 0x2B, "Card Discarded" },
|
0x2a, "Card ID Mismatch"}, {
|
||||||
{ 0x2C, "NFCID3 Mismatch" },
|
0x2B, "Card Discarded"}, {
|
||||||
{ 0x2D, "Over Current" },
|
0x2C, "NFCID3 Mismatch"}, {
|
||||||
{ 0x2E, "NAD Missing in DEP Frame" },
|
0x2D, "Over Current"}, {
|
||||||
|
0x2E, "NAD Missing in DEP Frame"},
|
||||||
/* Driver-level error */
|
/* Driver-level error */
|
||||||
{ DENACK, "Received NACK" },
|
{
|
||||||
{ DEACKMISMATCH, "Expected ACK/NACK" },
|
DENACK, "Received NACK"}, {
|
||||||
{ DEISERRFRAME, "Received an error frame" },
|
DEACKMISMATCH, "Expected ACK/NACK"}, {
|
||||||
|
DEISERRFRAME, "Received an error frame"},
|
||||||
/* TODO: Move me in more generic code for libnfc 1.6 */
|
/* TODO: Move me in more generic code for libnfc 1.6 */
|
||||||
{ DEINVAL, "Invalid argument" },
|
{
|
||||||
{ DEIO, "Input/output error" },
|
DEINVAL, "Invalid argument"}, {
|
||||||
{ DETIMEOUT, "Operation timed-out" },
|
DEIO, "Input/output error"}, {
|
||||||
{ DENOTSUP, "Operation not supported" }
|
DETIMEOUT, "Operation timed-out"}, {
|
||||||
|
DENOTSUP, "Operation not supported"}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -608,20 +622,24 @@ pn53x_get_firmware_version (nfc_device_t *pnd)
|
||||||
size_t szFwLen = sizeof (abtFw);
|
size_t szFwLen = sizeof (abtFw);
|
||||||
char *pcName;
|
char *pcName;
|
||||||
|
|
||||||
if (!pn53x_transceive(pnd,pncmd_get_firmware_version,2,abtFw,&szFwLen))
|
if (!pn53x_transceive (pnd, pncmd_get_firmware_version, 2, abtFw, &szFwLen)) {
|
||||||
{
|
|
||||||
// Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
|
// Failed to get firmware revision??, whatever...let's disconnect and clean up and return err
|
||||||
DBG ("Failed to get firmware revision for: %s", pnd->acName);
|
DBG ("Failed to get firmware revision for: %s", pnd->acName);
|
||||||
pnd->pdc->disconnect (pnd);
|
pnd->pdc->disconnect (pnd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the firmware revision to the device name, PN531 gives 2 bytes info, but PN532 and PN533 gives 4
|
// Add the firmware revision to the device name, PN531 gives 2 bytes info, but PN532 and PN533 gives 4
|
||||||
pcName = strdup (pnd->acName);
|
pcName = strdup (pnd->acName);
|
||||||
switch (pnd->nc) {
|
switch (pnd->nc) {
|
||||||
case NC_PN531: snprintf(pnd->acName,DEVICE_NAME_LENGTH - 1,"%s - PN531 v%d.%d",pcName,abtFw[0],abtFw[1]); break;
|
case NC_PN531:
|
||||||
case NC_PN532: snprintf(pnd->acName,DEVICE_NAME_LENGTH - 1,"%s - PN532 v%d.%d (0x%02x)",pcName,abtFw[1],abtFw[2],abtFw[3]); break;
|
snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - PN531 v%d.%d", pcName, abtFw[0], abtFw[1]);
|
||||||
case NC_PN533: snprintf(pnd->acName,DEVICE_NAME_LENGTH - 1,"%s - PN533 v%d.%d (0x%02x)",pcName,abtFw[1],abtFw[2],abtFw[3]); break;
|
break;
|
||||||
|
case NC_PN532:
|
||||||
|
snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - PN532 v%d.%d (0x%02x)", pcName, abtFw[1], abtFw[2], abtFw[3]);
|
||||||
|
break;
|
||||||
|
case NC_PN533:
|
||||||
|
snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s - PN533 v%d.%d (0x%02x)", pcName, abtFw[1], abtFw[2], abtFw[3]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free (pcName);
|
free (pcName);
|
||||||
return true;
|
return true;
|
||||||
|
@ -636,23 +654,26 @@ pn53x_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEn
|
||||||
memcpy (abtCmd, pncmd_rf_configure, sizeof (pncmd_rf_configure));
|
memcpy (abtCmd, pncmd_rf_configure, sizeof (pncmd_rf_configure));
|
||||||
|
|
||||||
// Make sure we are dealing with a active device
|
// Make sure we are dealing with a active device
|
||||||
if (!pnd->bActive) return false;
|
if (!pnd->bActive)
|
||||||
|
return false;
|
||||||
|
|
||||||
switch(ndo)
|
switch (ndo) {
|
||||||
{
|
|
||||||
case NDO_HANDLE_CRC:
|
case NDO_HANDLE_CRC:
|
||||||
// Enable or disable automatic receiving/sending of CRC bytes
|
// Enable or disable automatic receiving/sending of CRC bytes
|
||||||
// TX and RX are both represented by the symbol 0x80
|
// TX and RX are both represented by the symbol 0x80
|
||||||
btValue = (bEnable) ? 0x80 : 0x00;
|
btValue = (bEnable) ? 0x80 : 0x00;
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_TX_MODE,SYMBOL_TX_CRC_ENABLE,btValue)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_TX_MODE, SYMBOL_TX_CRC_ENABLE, btValue))
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_RX_MODE,SYMBOL_RX_CRC_ENABLE,btValue)) return false;
|
return false;
|
||||||
|
if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_CRC_ENABLE, btValue))
|
||||||
|
return false;
|
||||||
pnd->bCrc = bEnable;
|
pnd->bCrc = bEnable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDO_HANDLE_PARITY:
|
case NDO_HANDLE_PARITY:
|
||||||
// Handle parity bit by PN53X chip or parse it as data bit
|
// Handle parity bit by PN53X chip or parse it as data bit
|
||||||
btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE;
|
btValue = (bEnable) ? 0x00 : SYMBOL_PARITY_DISABLE;
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_MANUAL_RCV,SYMBOL_PARITY_DISABLE,btValue)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_MANUAL_RCV, SYMBOL_PARITY_DISABLE, btValue))
|
||||||
|
return false;
|
||||||
pnd->bPar = bEnable;
|
pnd->bPar = bEnable;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -663,12 +684,14 @@ pn53x_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEn
|
||||||
case NDO_ACTIVATE_FIELD:
|
case NDO_ACTIVATE_FIELD:
|
||||||
abtCmd[2] = RFCI_FIELD;
|
abtCmd[2] = RFCI_FIELD;
|
||||||
abtCmd[3] = (bEnable) ? 1 : 0;
|
abtCmd[3] = (bEnable) ? 1 : 0;
|
||||||
if (!pn53x_transceive(pnd,abtCmd,4,NULL,NULL)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, 4, NULL, NULL))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDO_ACTIVATE_CRYPTO1:
|
case NDO_ACTIVATE_CRYPTO1:
|
||||||
btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00;
|
btValue = (bEnable) ? SYMBOL_MF_CRYPTO1_ON : 0x00;
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_STATUS2,SYMBOL_MF_CRYPTO1_ON,btValue)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_STATUS2, SYMBOL_MF_CRYPTO1_ON, btValue))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDO_INFINITE_SELECT:
|
case NDO_INFINITE_SELECT:
|
||||||
|
@ -677,25 +700,30 @@ pn53x_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEn
|
||||||
abtCmd[3] = (bEnable) ? 0xff : 0x00; // MxRtyATR, default: active = 0xff, passive = 0x02
|
abtCmd[3] = (bEnable) ? 0xff : 0x00; // MxRtyATR, default: active = 0xff, passive = 0x02
|
||||||
abtCmd[4] = (bEnable) ? 0xff : 0x00; // MxRtyPSL, default: 0x01
|
abtCmd[4] = (bEnable) ? 0xff : 0x00; // MxRtyPSL, default: 0x01
|
||||||
abtCmd[5] = (bEnable) ? 0xff : 0x00; // MxRtyPassiveActivation, default: 0xff
|
abtCmd[5] = (bEnable) ? 0xff : 0x00; // MxRtyPassiveActivation, default: 0xff
|
||||||
if (!pn53x_transceive(pnd,abtCmd,6,NULL,NULL)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, 6, NULL, NULL))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDO_ACCEPT_INVALID_FRAMES:
|
case NDO_ACCEPT_INVALID_FRAMES:
|
||||||
btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00;
|
btValue = (bEnable) ? SYMBOL_RX_NO_ERROR : 0x00;
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_RX_MODE,SYMBOL_RX_NO_ERROR,btValue)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_NO_ERROR, btValue))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDO_ACCEPT_MULTIPLE_FRAMES:
|
case NDO_ACCEPT_MULTIPLE_FRAMES:
|
||||||
btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00;
|
btValue = (bEnable) ? SYMBOL_RX_MULTIPLE : 0x00;
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_RX_MODE,SYMBOL_RX_MULTIPLE,btValue)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_RX_MODE, SYMBOL_RX_MULTIPLE, btValue))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NDO_AUTO_ISO14443_4:
|
case NDO_AUTO_ISO14443_4:
|
||||||
// TODO: PN53x parameters could not be read, so we have to buffered current value in order to prevent from configuration overwrite
|
// TODO: PN53x parameters could not be read, so we have to buffered current value in order to prevent from configuration overwrite
|
||||||
// ATM, buffered current value is not needed due to a single usage of these parameters
|
// ATM, buffered current value is not needed due to a single usage of these parameters
|
||||||
btValue = (bEnable) ? (SYMBOL_PARAM_fAutomaticRATS | SYMBOL_PARAM_fAutomaticATR_RES): SYMBOL_PARAM_fAutomaticATR_RES;
|
btValue =
|
||||||
if(!pn53x_set_parameters(pnd,btValue)) return false;
|
(bEnable) ? (SYMBOL_PARAM_fAutomaticRATS | SYMBOL_PARAM_fAutomaticATR_RES) : SYMBOL_PARAM_fAutomaticATR_RES;
|
||||||
|
if (!pn53x_set_parameters (pnd, btValue))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -704,7 +732,11 @@ pn53x_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEn
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pnti)
|
bool
|
||||||
|
pn53x_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
|
const byte_t * pbtPidData, const size_t szPidDataLen, const byte_t * pbtNFCID3i,
|
||||||
|
const size_t szNFCID3iDataLen, const byte_t * pbtGbData, const size_t szGbDataLen,
|
||||||
|
nfc_target_info_t * pnti)
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
|
@ -736,16 +768,16 @@ bool pn53x_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t
|
||||||
memcpy (abtCmd + offset, pbtGbData, szGbDataLen);
|
memcpy (abtCmd + offset, pbtGbData, szGbDataLen);
|
||||||
offset += szGbDataLen;
|
offset += szGbDataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a target, call the transceive callback function of the current device
|
// Try to find a target, call the transceive callback function of the current device
|
||||||
if (!pn53x_transceive(pnd,abtCmd,5+szPidDataLen+szNFCID3iDataLen+szGbDataLen,abtRx,&szRxLen)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, 5 + szPidDataLen + szNFCID3iDataLen + szGbDataLen, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Make sure one target has been found, the PN53X returns 0x00 if none was available
|
// Make sure one target has been found, the PN53X returns 0x00 if none was available
|
||||||
if (abtRx[1] != 1) return false;
|
if (abtRx[1] != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Is a target info struct available
|
// Is a target info struct available
|
||||||
if (pnti)
|
if (pnti) {
|
||||||
{
|
|
||||||
memcpy (pnti->ndi.NFCID3i, abtRx + 2, 10);
|
memcpy (pnti->ndi.NFCID3i, abtRx + 2, 10);
|
||||||
pnti->ndi.btDID = abtRx[12];
|
pnti->ndi.btDID = abtRx[12];
|
||||||
pnti->ndi.btBSt = abtRx[13];
|
pnti->ndi.btBSt = abtRx[13];
|
||||||
|
@ -754,7 +786,9 @@ bool pn53x_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
bool
|
||||||
|
pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
||||||
|
const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
|
@ -767,8 +801,7 @@ bool pn53x_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, con
|
||||||
memcpy (abtCmd, pncmd_initiator_exchange_raw_data, sizeof (pncmd_initiator_exchange_raw_data));
|
memcpy (abtCmd, pncmd_initiator_exchange_raw_data, sizeof (pncmd_initiator_exchange_raw_data));
|
||||||
|
|
||||||
// Check if we should prepare the parity bits ourself
|
// Check if we should prepare the parity bits ourself
|
||||||
if (!pnd->bPar)
|
if (!pnd->bPar) {
|
||||||
{
|
|
||||||
// Convert data with parity to a frame
|
// Convert data with parity to a frame
|
||||||
pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
|
pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
|
||||||
} else {
|
} else {
|
||||||
|
@ -782,14 +815,17 @@ bool pn53x_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, con
|
||||||
szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
|
szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
|
||||||
|
|
||||||
// When the parity is handled before us, we just copy the data
|
// When the parity is handled before us, we just copy the data
|
||||||
if (pnd->bPar) memcpy(abtCmd+2,pbtTx,szFrameBytes);
|
if (pnd->bPar)
|
||||||
|
memcpy (abtCmd + 2, pbtTx, szFrameBytes);
|
||||||
|
|
||||||
// Set the amount of transmission bits in the PN53X chip register
|
// Set the amount of transmission bits in the PN53X chip register
|
||||||
if (!pn53x_set_tx_bits(pnd,ui8Bits)) return false;
|
if (!pn53x_set_tx_bits (pnd, ui8Bits))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Send the frame to the PN53X chip and get the answer
|
// Send the frame to the PN53X chip and get the answer
|
||||||
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
|
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
|
||||||
if (!pn53x_transceive(pnd,abtCmd,szFrameBytes+2,abtRx,&szRxLen)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 2, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Get the last bit-count that is stored in the received byte
|
// Get the last bit-count that is stored in the received byte
|
||||||
if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
|
if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
|
||||||
|
@ -801,8 +837,7 @@ bool pn53x_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, con
|
||||||
|
|
||||||
// Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
|
// Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
|
||||||
// Check if we should recover the parity bits ourself
|
// Check if we should recover the parity bits ourself
|
||||||
if (!pnd->bPar)
|
if (!pnd->bPar) {
|
||||||
{
|
|
||||||
// Unwrap the response frame
|
// Unwrap the response frame
|
||||||
pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
|
pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
|
||||||
} else {
|
} else {
|
||||||
|
@ -816,14 +851,18 @@ bool pn53x_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, con
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szExtraTxLen, szRxLen;
|
size_t szExtraTxLen,
|
||||||
|
szRxLen;
|
||||||
byte_t abtCmd[sizeof (pncmd_initiator_exchange_raw_data)];
|
byte_t abtCmd[sizeof (pncmd_initiator_exchange_raw_data)];
|
||||||
|
|
||||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||||
if (!pnd->bPar) return false;
|
if (!pnd->bPar)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Copy the data into the command frame
|
// Copy the data into the command frame
|
||||||
if (pnd->bEasyFraming) {
|
if (pnd->bEasyFraming) {
|
||||||
|
@ -838,11 +877,13 @@ bool pn53x_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// To transfer command frames bytes we can not have any leading bits, reset this to zero
|
// To transfer command frames bytes we can not have any leading bits, reset this to zero
|
||||||
if (!pn53x_set_tx_bits(pnd,0)) return false;
|
if (!pn53x_set_tx_bits (pnd, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Send the frame to the PN53X chip and get the answer
|
// Send the frame to the PN53X chip and get the answer
|
||||||
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
|
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
|
||||||
if (!pn53x_transceive(pnd,abtCmd,szTxLen + szExtraTxLen,abtRx,&szRxLen)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, szTxLen + szExtraTxLen, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Save the received byte count
|
// Save the received byte count
|
||||||
*pszRxLen = szRxLen - 1;
|
*pszRxLen = szRxLen - 1;
|
||||||
|
@ -854,7 +895,8 @@ bool pn53x_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, co
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
bool
|
||||||
|
pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
|
@ -883,18 +925,23 @@ bool pn53x_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
||||||
abtCmd[7] = 0x0b;
|
abtCmd[7] = 0x0b;
|
||||||
|
|
||||||
// Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
|
// Make sure the CRC & parity are handled by the device, this is needed for target_init to work properly
|
||||||
if (!bCrc) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_CRC,true);
|
if (!bCrc)
|
||||||
if (!bPar) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_PARITY,true);
|
nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, true);
|
||||||
|
if (!bPar)
|
||||||
|
nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_PARITY, true);
|
||||||
|
|
||||||
// Let the PN53X be activated by the RF level detector from power down mode
|
// Let the PN53X be activated by the RF level detector from power down mode
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_TX_AUTO, SYMBOL_INITIAL_RF_ON,0x04)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_INITIAL_RF_ON, 0x04))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Request the initialization as a target
|
// Request the initialization as a target
|
||||||
szRxLen = MAX_FRAME_LEN;
|
szRxLen = MAX_FRAME_LEN;
|
||||||
if (!pn53x_transceive(pnd,abtCmd,39,abtRx,&szRxLen)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, 39, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Get the last bit-count that is stored in the received byte
|
// Get the last bit-count that is stored in the received byte
|
||||||
if (!pn53x_get_reg(pnd,REG_CIU_CONTROL, &ui8rcc)) return false;
|
if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
|
||||||
|
return false;
|
||||||
ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
|
ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
|
||||||
|
|
||||||
// We are sure the parity is handled by the PN53X chip, so we handle it this way
|
// We are sure the parity is handled by the PN53X chip, so we handle it this way
|
||||||
|
@ -903,13 +950,16 @@ bool pn53x_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
||||||
memcpy (pbtRx, abtRx + 1, szRxLen - 1);
|
memcpy (pbtRx, abtRx + 1, szRxLen - 1);
|
||||||
|
|
||||||
// Restore the CRC & parity setting to the original value (if needed)
|
// Restore the CRC & parity setting to the original value (if needed)
|
||||||
if (!bCrc) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_CRC,false);
|
if (!bCrc)
|
||||||
if (!bPar) nfc_configure((nfc_device_t*)pnd,NDO_HANDLE_PARITY,false);
|
nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_CRC, false);
|
||||||
|
if (!bPar)
|
||||||
|
nfc_configure ((nfc_device_t *) pnd, NDO_HANDLE_PARITY, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
bool
|
||||||
|
pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
|
||||||
{
|
{
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
|
@ -918,10 +968,12 @@ bool pn53x_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBi
|
||||||
uint8_t ui8Bits;
|
uint8_t ui8Bits;
|
||||||
|
|
||||||
// Try to gather a received frame from the reader
|
// Try to gather a received frame from the reader
|
||||||
if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
|
if (!pn53x_transceive (pnd, pncmd_target_receive, 2, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Get the last bit-count that is stored in the received byte
|
// Get the last bit-count that is stored in the received byte
|
||||||
if (!pn53x_get_reg(pnd,REG_CIU_CONTROL, &ui8rcc)) return false;
|
if (!pn53x_get_reg (pnd, REG_CIU_CONTROL, &ui8rcc))
|
||||||
|
return false;
|
||||||
ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
|
ui8Bits = ui8rcc & SYMBOL_RX_LAST_BITS;
|
||||||
|
|
||||||
// Recover the real frame length in bits
|
// Recover the real frame length in bits
|
||||||
|
@ -929,8 +981,7 @@ bool pn53x_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBi
|
||||||
|
|
||||||
// Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
|
// Ignore the status byte from the PN53X here, it was checked earlier in pn53x_transceive()
|
||||||
// Check if we should recover the parity bits ourself
|
// Check if we should recover the parity bits ourself
|
||||||
if (!pnd->bPar)
|
if (!pnd->bPar) {
|
||||||
{
|
|
||||||
// Unwrap the response frame
|
// Unwrap the response frame
|
||||||
pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
|
pn53x_unwrap_frame (abtRx + 1, szFrameBits, pbtRx, pszRxBits, pbtRxPar);
|
||||||
} else {
|
} else {
|
||||||
|
@ -943,7 +994,8 @@ bool pn53x_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBi
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
byte_t const *pbtTx;
|
byte_t const *pbtTx;
|
||||||
byte_t abtRx[MAX_FRAME_LEN];
|
byte_t abtRx[MAX_FRAME_LEN];
|
||||||
|
@ -956,7 +1008,8 @@ bool pn53x_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxL
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to gather a received frame from the reader
|
// Try to gather a received frame from the reader
|
||||||
if (!pn53x_transceive(pnd,pbtTx,2,abtRx,&szRxLen)) return false;
|
if (!pn53x_transceive (pnd, pbtTx, 2, abtRx, &szRxLen))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Save the received byte count
|
// Save the received byte count
|
||||||
*pszRxLen = szRxLen - 1;
|
*pszRxLen = szRxLen - 1;
|
||||||
|
@ -968,7 +1021,8 @@ bool pn53x_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxL
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
|
bool
|
||||||
|
pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar)
|
||||||
{
|
{
|
||||||
size_t szFrameBits = 0;
|
size_t szFrameBits = 0;
|
||||||
size_t szFrameBytes = 0;
|
size_t szFrameBytes = 0;
|
||||||
|
@ -978,8 +1032,7 @@ bool pn53x_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
memcpy (abtCmd, pncmd_target_send, sizeof (pncmd_target_send));
|
memcpy (abtCmd, pncmd_target_send, sizeof (pncmd_target_send));
|
||||||
|
|
||||||
// Check if we should prepare the parity bits ourself
|
// Check if we should prepare the parity bits ourself
|
||||||
if (!pnd->bPar)
|
if (!pnd->bPar) {
|
||||||
{
|
|
||||||
// Convert data with parity to a frame
|
// Convert data with parity to a frame
|
||||||
pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
|
pn53x_wrap_frame (pbtTx, szTxBits, pbtTxPar, abtCmd + 2, &szFrameBits);
|
||||||
} else {
|
} else {
|
||||||
|
@ -993,25 +1046,30 @@ bool pn53x_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
|
szFrameBytes = (szFrameBits / 8) + ((ui8Bits == 0) ? 0 : 1);
|
||||||
|
|
||||||
// When the parity is handled before us, we just copy the data
|
// When the parity is handled before us, we just copy the data
|
||||||
if (pnd->bPar) memcpy(abtCmd+2,pbtTx,szFrameBytes);
|
if (pnd->bPar)
|
||||||
|
memcpy (abtCmd + 2, pbtTx, szFrameBytes);
|
||||||
|
|
||||||
// Set the amount of transmission bits in the PN53X chip register
|
// Set the amount of transmission bits in the PN53X chip register
|
||||||
if (!pn53x_set_tx_bits(pnd,ui8Bits)) return false;
|
if (!pn53x_set_tx_bits (pnd, ui8Bits))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Try to send the bits to the reader
|
// Try to send the bits to the reader
|
||||||
if (!pn53x_transceive(pnd,abtCmd,szFrameBytes+2,NULL,NULL)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, szFrameBytes + 2, NULL, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Everyting seems ok, return true
|
// Everyting seems ok, return true
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
bool
|
||||||
|
pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen)
|
||||||
{
|
{
|
||||||
byte_t abtCmd[MAX (sizeof (pncmd_target_send), sizeof (pncmd_target_set_data))];
|
byte_t abtCmd[MAX (sizeof (pncmd_target_send), sizeof (pncmd_target_set_data))];
|
||||||
|
|
||||||
|
|
||||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||||
if (!pnd->bPar) return false;
|
if (!pnd->bPar)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (pnd->bEasyFraming) {
|
if (pnd->bEasyFraming) {
|
||||||
memcpy (abtCmd, pncmd_target_set_data, sizeof (pncmd_target_set_data));
|
memcpy (abtCmd, pncmd_target_set_data, sizeof (pncmd_target_set_data));
|
||||||
|
@ -1023,7 +1081,8 @@ bool pn53x_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_
|
||||||
memcpy (abtCmd + 2, pbtTx, szTxLen);
|
memcpy (abtCmd + 2, pbtTx, szTxLen);
|
||||||
|
|
||||||
// Try to send the bits to the reader
|
// Try to send the bits to the reader
|
||||||
if (!pn53x_transceive(pnd,abtCmd,szTxLen+2,NULL,NULL)) return false;
|
if (!pn53x_transceive (pnd, abtCmd, szTxLen + 2, NULL, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Everyting seems ok, return true
|
// Everyting seems ok, return true
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -78,32 +78,50 @@
|
||||||
# define DEISERRFRAME 0x0300/* Error frame */
|
# define DEISERRFRAME 0x0300/* Error frame */
|
||||||
# define DENOTSUP 0x0400/* Not supported */
|
# define DENOTSUP 0x0400/* Not supported */
|
||||||
|
|
||||||
bool pn53x_transceive_check_ack_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen);
|
bool pn53x_transceive_check_ack_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame,
|
||||||
bool pn53x_transceive_check_error_frame_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen);
|
const size_t szRxFrameLen);
|
||||||
bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
bool pn53x_transceive_check_error_frame_callback (nfc_device_t * pnd, const byte_t * pbtRxFrame,
|
||||||
|
const size_t szRxFrameLen);
|
||||||
|
bool pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen);
|
||||||
bool pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value);
|
bool pn53x_get_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t * ui8Value);
|
||||||
bool pn53x_set_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value);
|
bool pn53x_set_reg (nfc_device_t * pnd, uint16_t ui16Reg, uint8_t ui8SybmolMask, uint8_t ui8Value);
|
||||||
bool pn53x_set_parameters (nfc_device_t * pnd, uint8_t ui8Value);
|
bool pn53x_set_parameters (nfc_device_t * pnd, uint8_t ui8Value);
|
||||||
bool pn53x_set_tx_bits (nfc_device_t * pnd, uint8_t ui8Bits);
|
bool pn53x_set_tx_bits (nfc_device_t * pnd, uint8_t ui8Bits);
|
||||||
bool pn53x_wrap_frame(const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtFrame, size_t* pszFrameBits);
|
bool pn53x_wrap_frame (const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtFrame,
|
||||||
bool pn53x_unwrap_frame(const byte_t* pbtFrame, const size_t szFrameBits, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
size_t * pszFrameBits);
|
||||||
bool pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt, nfc_target_info_t* pnti);
|
bool pn53x_unwrap_frame (const byte_t * pbtFrame, const size_t szFrameBits, byte_t * pbtRx, size_t * pszRxBits,
|
||||||
|
byte_t * pbtRxPar);
|
||||||
|
bool pn53x_decode_target_data (const byte_t * pbtRawData, size_t szDataLen, nfc_chip_t nc, nfc_target_type_t ntt,
|
||||||
|
nfc_target_info_t * pnti);
|
||||||
|
|
||||||
bool pn53x_InListPassiveTarget(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets, const byte_t* pbtInitiatorData, const size_t szInitiatorDataLen, byte_t* pbtTargetsData, size_t* pszTargetsData);
|
bool pn53x_InListPassiveTarget (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
|
const byte_t szMaxTargets, const byte_t * pbtInitiatorData,
|
||||||
|
const size_t szInitiatorDataLen, byte_t * pbtTargetsData, size_t * pszTargetsData);
|
||||||
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
|
bool pn53x_InDeselect (nfc_device_t * pnd, const uint8_t ui8Target);
|
||||||
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
|
bool pn53x_InRelease (nfc_device_t * pnd, const uint8_t ui8Target);
|
||||||
bool pn53x_InAutoPoll(nfc_device_t* pnd, const nfc_target_type_t* pnttTargetTypes, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t* pntTargets, size_t* pszTargetFound);
|
bool pn53x_InAutoPoll (nfc_device_t * pnd, const nfc_target_type_t * pnttTargetTypes, const size_t szTargetTypes,
|
||||||
|
const byte_t btPollNr, const byte_t btPeriod, nfc_target_t * pntTargets,
|
||||||
|
size_t * pszTargetFound);
|
||||||
|
|
||||||
bool pn53x_get_firmware_version (nfc_device_t * pnd);
|
bool pn53x_get_firmware_version (nfc_device_t * pnd);
|
||||||
bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
bool pn53x_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
||||||
bool pn53x_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pnti);
|
bool pn53x_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
bool pn53x_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar);
|
const byte_t * pbtPidData, const size_t szPidDataLen,
|
||||||
bool pn53x_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
const byte_t * pbtNFCID3i, const size_t szNFCID3iDataLen,
|
||||||
|
const byte_t * pbtGbData, const size_t szGbDataLen,
|
||||||
|
nfc_target_info_t * pnti);
|
||||||
|
bool pn53x_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
||||||
|
const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits,
|
||||||
|
byte_t * pbtRxPar);
|
||||||
|
bool pn53x_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen,
|
||||||
|
byte_t * pbtRx, size_t * pszRxLen);
|
||||||
|
|
||||||
bool pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits);
|
bool pn53x_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits);
|
||||||
bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
bool pn53x_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
|
||||||
bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen);
|
bool pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen);
|
||||||
bool pn53x_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar);
|
bool pn53x_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits,
|
||||||
|
const byte_t * pbtTxPar);
|
||||||
bool pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen);
|
bool pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen);
|
||||||
|
|
||||||
const char *pn53x_strerror (const nfc_device_t * pnd);
|
const char *pn53x_strerror (const nfc_device_t * pnd);
|
||||||
|
@ -113,4 +131,3 @@ static const struct chip_callbacks pn53x_callbacks_list = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __NFC_CHIPS_PN53X_H__
|
#endif // __NFC_CHIPS_PN53X_H__
|
||||||
|
|
||||||
|
|
|
@ -31,27 +31,33 @@
|
||||||
|
|
||||||
# if defined (DRIVER_ACR122_ENABLED)
|
# if defined (DRIVER_ACR122_ENABLED)
|
||||||
# include "drivers/acr122.h"
|
# include "drivers/acr122.h"
|
||||||
#endif /* DRIVER_ACR122_ENABLED */
|
# endif
|
||||||
|
/* DRIVER_ACR122_ENABLED */
|
||||||
|
|
||||||
# if defined (DRIVER_PN531_USB_ENABLED) || defined (DRIVER_PN533_USB_ENABLED)
|
# if defined (DRIVER_PN531_USB_ENABLED) || defined (DRIVER_PN533_USB_ENABLED)
|
||||||
# include "drivers/pn53x_usb.h"
|
# include "drivers/pn53x_usb.h"
|
||||||
#endif /* DRIVER_PN531_USB_ENABLED || DRIVER_PN533_USB_ENABLED */
|
# endif
|
||||||
|
/* DRIVER_PN531_USB_ENABLED || DRIVER_PN533_USB_ENABLED */
|
||||||
|
|
||||||
# if defined (DRIVER_PN531_USB_ENABLED)
|
# if defined (DRIVER_PN531_USB_ENABLED)
|
||||||
# include "drivers/pn531_usb.h"
|
# include "drivers/pn531_usb.h"
|
||||||
#endif /* DRIVER_PN531_USB_ENABLED */
|
# endif
|
||||||
|
/* DRIVER_PN531_USB_ENABLED */
|
||||||
|
|
||||||
# if defined (DRIVER_PN533_USB_ENABLED)
|
# if defined (DRIVER_PN533_USB_ENABLED)
|
||||||
# include "drivers/pn533_usb.h"
|
# include "drivers/pn533_usb.h"
|
||||||
#endif /* DRIVER_PN533_USB_ENABLED */
|
# endif
|
||||||
|
/* DRIVER_PN533_USB_ENABLED */
|
||||||
|
|
||||||
# if defined (DRIVER_ARYGON_ENABLED)
|
# if defined (DRIVER_ARYGON_ENABLED)
|
||||||
# include "drivers/arygon.h"
|
# include "drivers/arygon.h"
|
||||||
#endif /* DRIVER_ARYGON_ENABLED */
|
# endif
|
||||||
|
/* DRIVER_ARYGON_ENABLED */
|
||||||
|
|
||||||
# if defined (DRIVER_PN532_UART_ENABLED)
|
# if defined (DRIVER_PN532_UART_ENABLED)
|
||||||
# include "drivers/pn532_uart.h"
|
# include "drivers/pn532_uart.h"
|
||||||
#endif /* DRIVER_PN532_UART_ENABLED */
|
# endif
|
||||||
|
/* DRIVER_PN532_UART_ENABLED */
|
||||||
|
|
||||||
# define DRIVERS_MAX_DEVICES 16
|
# define DRIVERS_MAX_DEVICES 16
|
||||||
# define MAX_FRAME_LEN 264
|
# define MAX_FRAME_LEN 264
|
||||||
|
@ -59,20 +65,30 @@
|
||||||
static const struct driver_callbacks drivers_callbacks_list[] = {
|
static const struct driver_callbacks drivers_callbacks_list[] = {
|
||||||
// Driver Name Chip callbacks Pick Device List Devices Connect Transceive Disconnect
|
// Driver Name Chip callbacks Pick Device List Devices Connect Transceive Disconnect
|
||||||
# if defined (DRIVER_ACR122_ENABLED)
|
# if defined (DRIVER_ACR122_ENABLED)
|
||||||
{ ACR122_DRIVER_NAME, &pn53x_callbacks_list, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
{ACR122_DRIVER_NAME, &pn53x_callbacks_list, acr122_pick_device, acr122_list_devices, acr122_connect,
|
||||||
#endif /* DRIVER_ACR122_ENABLED */
|
acr122_transceive, acr122_disconnect},
|
||||||
|
# endif
|
||||||
|
/* DRIVER_ACR122_ENABLED */
|
||||||
# if defined (DRIVER_PN531_USB_ENABLED)
|
# if defined (DRIVER_PN531_USB_ENABLED)
|
||||||
{ PN531_USB_DRIVER_NAME, &pn53x_callbacks_list, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
{PN531_USB_DRIVER_NAME, &pn53x_callbacks_list, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect,
|
||||||
#endif /* DRIVER_PN531_USB_ENABLED */
|
pn53x_usb_transceive, pn53x_usb_disconnect},
|
||||||
|
# endif
|
||||||
|
/* DRIVER_PN531_USB_ENABLED */
|
||||||
# if defined (DRIVER_PN533_USB_ENABLED)
|
# if defined (DRIVER_PN533_USB_ENABLED)
|
||||||
{ PN533_USB_DRIVER_NAME, &pn53x_callbacks_list, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect },
|
{PN533_USB_DRIVER_NAME, &pn53x_callbacks_list, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect,
|
||||||
#endif /* DRIVER_PN533_USB_ENABLED */
|
pn53x_usb_transceive, pn53x_usb_disconnect},
|
||||||
|
# endif
|
||||||
|
/* DRIVER_PN533_USB_ENABLED */
|
||||||
# if defined (DRIVER_ARYGON_ENABLED)
|
# if defined (DRIVER_ARYGON_ENABLED)
|
||||||
{ ARYGON_DRIVER_NAME, &pn53x_callbacks_list, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect },
|
{ARYGON_DRIVER_NAME, &pn53x_callbacks_list, arygon_pick_device, arygon_list_devices, arygon_connect,
|
||||||
#endif /* DRIVER_ARYGON_ENABLED */
|
arygon_transceive, arygon_disconnect},
|
||||||
|
# endif
|
||||||
|
/* DRIVER_ARYGON_ENABLED */
|
||||||
# if defined (DRIVER_PN532_UART_ENABLED)
|
# if defined (DRIVER_PN532_UART_ENABLED)
|
||||||
{ PN532_UART_DRIVER_NAME, &pn53x_callbacks_list, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect },
|
{PN532_UART_DRIVER_NAME, &pn53x_callbacks_list, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect,
|
||||||
#endif /* DRIVER_PN532_UART_ENABLED */
|
pn532_uart_transceive, pn532_uart_disconnect},
|
||||||
|
# endif
|
||||||
|
/* DRIVER_PN532_UART_ENABLED */
|
||||||
};
|
};
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
|
@ -92,4 +108,3 @@ static const struct driver_callbacks drivers_callbacks_list[] = {
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#endif // __NFC_DRIVERS_H__
|
#endif // __NFC_DRIVERS_H__
|
||||||
|
|
||||||
|
|
|
@ -77,9 +77,9 @@ static int _iSCardContextRefCount = 0;
|
||||||
SCARDCONTEXT *
|
SCARDCONTEXT *
|
||||||
acr122_get_scardcontext (void)
|
acr122_get_scardcontext (void)
|
||||||
{
|
{
|
||||||
if ( _iSCardContextRefCount == 0 )
|
if (_iSCardContextRefCount == 0) {
|
||||||
{
|
if (SCardEstablishContext (SCARD_SCOPE_USER, NULL, NULL, &_SCardContext) != SCARD_S_SUCCESS)
|
||||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&_SCardContext) != SCARD_S_SUCCESS) return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
_iSCardContextRefCount++;
|
_iSCardContextRefCount++;
|
||||||
|
|
||||||
|
@ -89,11 +89,9 @@ acr122_get_scardcontext(void)
|
||||||
void
|
void
|
||||||
acr122_free_scardcontext (void)
|
acr122_free_scardcontext (void)
|
||||||
{
|
{
|
||||||
if (_iSCardContextRefCount)
|
if (_iSCardContextRefCount) {
|
||||||
{
|
|
||||||
_iSCardContextRefCount--;
|
_iSCardContextRefCount--;
|
||||||
if (!_iSCardContextRefCount)
|
if (!_iSCardContextRefCount) {
|
||||||
{
|
|
||||||
SCardReleaseContext (_SCardContext);
|
SCardReleaseContext (_SCardContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,14 +147,13 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
|
|
||||||
// Test if context succeeded
|
// Test if context succeeded
|
||||||
if (!(pscc = acr122_get_scardcontext ()))
|
if (!(pscc = acr122_get_scardcontext ())) {
|
||||||
{
|
|
||||||
DBG ("%s", "PCSC context not found");
|
DBG ("%s", "PCSC context not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the string array of all available pcsc readers
|
// Retrieve the string array of all available pcsc readers
|
||||||
if (SCardListReaders(*pscc,NULL,acDeviceNames,(void*)&szDeviceNamesLen) != SCARD_S_SUCCESS) return false;
|
if (SCardListReaders (*pscc, NULL, acDeviceNames, (void *) &szDeviceNamesLen) != SCARD_S_SUCCESS)
|
||||||
|
return false;
|
||||||
|
|
||||||
// DBG("%s", "PCSC reports following device(s):");
|
// DBG("%s", "PCSC reports following device(s):");
|
||||||
|
|
||||||
|
@ -171,17 +168,14 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
||||||
bSupported = 0 == strncmp (supported_devices[i], acDeviceNames + szPos, l);
|
bSupported = 0 == strncmp (supported_devices[i], acDeviceNames + szPos, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bSupported)
|
if (bSupported) {
|
||||||
{
|
|
||||||
// Supported ACR122 device found
|
// Supported ACR122 device found
|
||||||
strncpy (pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, DEVICE_NAME_LENGTH - 1);
|
strncpy (pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, DEVICE_NAME_LENGTH - 1);
|
||||||
pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
|
pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
|
||||||
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
|
pnddDevices[*pszDeviceFound].pcDriver = ACR122_DRIVER_NAME;
|
||||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG ("PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
|
DBG ("PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +189,8 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
nfc_device_t *
|
||||||
|
acr122_connect (const nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd = NULL;
|
nfc_device_t *pnd = NULL;
|
||||||
acr122_spec_t as;
|
acr122_spec_t as;
|
||||||
|
@ -206,13 +201,15 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
||||||
|
|
||||||
DBG ("Attempt to connect to %s", pndd->acDevice);
|
DBG ("Attempt to connect to %s", pndd->acDevice);
|
||||||
// Test if context succeeded
|
// Test if context succeeded
|
||||||
if (!(pscc = acr122_get_scardcontext ())) return NULL;
|
if (!(pscc = acr122_get_scardcontext ()))
|
||||||
|
return NULL;
|
||||||
// Test if we were able to connect to the "emulator" card
|
// Test if we were able to connect to the "emulator" card
|
||||||
if (SCardConnect(*pscc,pndd->acDevice,SCARD_SHARE_EXCLUSIVE,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
if (SCardConnect
|
||||||
{
|
(*pscc, pndd->acDevice, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(as.hCard),
|
||||||
|
(void *) &(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
|
||||||
// Connect to ACR122 firmware version >2.0
|
// Connect to ACR122 firmware version >2.0
|
||||||
if (SCardConnect(*pscc,pndd->acDevice,SCARD_SHARE_DIRECT,0,&(as.hCard),(void*)&(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS)
|
if (SCardConnect (*pscc, pndd->acDevice, SCARD_SHARE_DIRECT, 0, &(as.hCard), (void *) &(as.ioCard.dwProtocol)) !=
|
||||||
{
|
SCARD_S_SUCCESS) {
|
||||||
// We can not connect to this device.
|
// We can not connect to this device.
|
||||||
DBG ("%s", "PCSC connect failed");
|
DBG ("%s", "PCSC connect failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -223,8 +220,7 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
||||||
|
|
||||||
// Retrieve the current firmware version
|
// Retrieve the current firmware version
|
||||||
pcFirmware = acr122_firmware ((nfc_device_t *) & as);
|
pcFirmware = acr122_firmware ((nfc_device_t *) & as);
|
||||||
if (strstr(pcFirmware,FIRMWARE_TEXT) != NULL)
|
if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
|
||||||
{
|
|
||||||
// Allocate memory and store the device specification
|
// Allocate memory and store the device specification
|
||||||
pas = malloc (sizeof (acr122_spec_t));
|
pas = malloc (sizeof (acr122_spec_t));
|
||||||
*pas = as;
|
*pas = as;
|
||||||
|
@ -246,7 +242,8 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void acr122_disconnect(nfc_device_t* pnd)
|
void
|
||||||
|
acr122_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
acr122_spec_t *pas = (acr122_spec_t *) pnd->nds;
|
acr122_spec_t *pas = (acr122_spec_t *) pnd->nds;
|
||||||
SCardDisconnect (pas->hCard, SCARD_LEAVE_CARD);
|
SCardDisconnect (pas->hCard, SCARD_LEAVE_CARD);
|
||||||
|
@ -255,7 +252,8 @@ void acr122_disconnect(nfc_device_t* pnd)
|
||||||
free (pnd);
|
free (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
acr122_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
byte_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
byte_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
||||||
size_t szRxCmdLen = sizeof (abtRxCmd);
|
size_t szRxCmdLen = sizeof (abtRxCmd);
|
||||||
|
@ -270,7 +268,6 @@ bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the length of the command we are going to send
|
// Store the length of the command we are going to send
|
||||||
abtTxBuf[4] = szTxLen;
|
abtTxBuf[4] = szTxLen;
|
||||||
|
|
||||||
|
@ -281,48 +278,48 @@ bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
||||||
PRINT_HEX ("TX", abtTxBuf, szTxLen + 5);
|
PRINT_HEX ("TX", abtTxBuf, szTxLen + 5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||||
{
|
if (SCardControl
|
||||||
if (SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtTxBuf,szTxLen+5,abtRxBuf,szRxBufLen,(void*)&szRxBufLen) != SCARD_S_SUCCESS) {
|
(pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTxLen + 5, abtRxBuf, szRxBufLen,
|
||||||
|
(void *) &szRxBufLen) != SCARD_S_SUCCESS) {
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (SCardTransmit(pas->hCard,&(pas->ioCard),abtTxBuf,szTxLen+5,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) {
|
if (SCardTransmit (pas->hCard, &(pas->ioCard), abtTxBuf, szTxLen + 5, NULL, abtRxBuf, (void *) &szRxBufLen) !=
|
||||||
|
SCARD_S_SUCCESS) {
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_T0)
|
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
|
||||||
{
|
|
||||||
// Make sure we received the byte-count we expected
|
// Make sure we received the byte-count we expected
|
||||||
if (szRxBufLen != 2) {
|
if (szRxBufLen != 2) {
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the operation was successful, so an answer is available
|
// Check if the operation was successful, so an answer is available
|
||||||
if (*abtRxBuf == SCARD_OPERATION_ERROR) {
|
if (*abtRxBuf == SCARD_OPERATION_ERROR) {
|
||||||
pnd->iLastError = DEISERRFRAME;
|
pnd->iLastError = DEISERRFRAME;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the response bytes
|
// Retrieve the response bytes
|
||||||
abtRxCmd[4] = abtRxBuf[1];
|
abtRxCmd[4] = abtRxBuf[1];
|
||||||
szRxBufLen = sizeof (abtRxBuf);
|
szRxBufLen = sizeof (abtRxBuf);
|
||||||
if (SCardTransmit(pas->hCard,&(pas->ioCard),abtRxCmd,szRxCmdLen,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) {
|
if (SCardTransmit (pas->hCard, &(pas->ioCard), abtRxCmd, szRxCmdLen, NULL, abtRxBuf, (void *) &szRxBufLen) !=
|
||||||
|
SCARD_S_SUCCESS) {
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// When the answer should be ignored, just return a succesful result
|
// When the answer should be ignored, just return a succesful result
|
||||||
if (pbtRx == NULL || pszRxLen == NULL) return true;
|
if (pbtRx == NULL || pszRxLen == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
// Make sure we have an emulated answer that fits the return buffer
|
// Make sure we have an emulated answer that fits the return buffer
|
||||||
if (szRxBufLen < 4 || (szRxBufLen - 4) > *pszRxLen) {
|
if (szRxBufLen < 4 || (szRxBufLen - 4) > *pszRxLen) {
|
||||||
|
@ -337,7 +334,8 @@ bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* acr122_firmware(const nfc_device_spec_t nds)
|
char *
|
||||||
|
acr122_firmware (const nfc_device_spec_t nds)
|
||||||
{
|
{
|
||||||
byte_t abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
|
byte_t abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
|
||||||
uint32_t uiResult;
|
uint32_t uiResult;
|
||||||
|
@ -346,16 +344,18 @@ char* acr122_firmware(const nfc_device_spec_t nds)
|
||||||
static char abtFw[11];
|
static char abtFw[11];
|
||||||
size_t szFwLen = sizeof (abtFw);
|
size_t szFwLen = sizeof (abtFw);
|
||||||
memset (abtFw, 0x00, szFwLen);
|
memset (abtFw, 0x00, szFwLen);
|
||||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||||
{
|
uiResult =
|
||||||
uiResult = SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtGetFw,sizeof(abtGetFw),abtFw,szFwLen,(void*)&szFwLen);
|
SCardControl (pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof (abtGetFw), abtFw, szFwLen,
|
||||||
|
(void *) &szFwLen);
|
||||||
} else {
|
} else {
|
||||||
uiResult = SCardTransmit(pas->hCard,&(pas->ioCard),abtGetFw,sizeof(abtGetFw),NULL,(byte_t*)abtFw,(void*)&szFwLen);
|
uiResult =
|
||||||
|
SCardTransmit (pas->hCard, &(pas->ioCard), abtGetFw, sizeof (abtGetFw), NULL, (byte_t *) abtFw,
|
||||||
|
(void *) &szFwLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (uiResult != SCARD_S_SUCCESS)
|
if (uiResult != SCARD_S_SUCCESS) {
|
||||||
{
|
|
||||||
printf ("No ACR122 firmware received, Error: %08x\n", uiResult);
|
printf ("No ACR122 firmware received, Error: %08x\n", uiResult);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -363,18 +363,21 @@ char* acr122_firmware(const nfc_device_spec_t nds)
|
||||||
return abtFw;
|
return abtFw;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acr122_led_red(const nfc_device_spec_t nds, bool bOn)
|
bool
|
||||||
|
acr122_led_red (const nfc_device_spec_t nds, bool bOn)
|
||||||
{
|
{
|
||||||
byte_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
byte_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
||||||
acr122_spec_t *pas = (acr122_spec_t *) nds;
|
acr122_spec_t *pas = (acr122_spec_t *) nds;
|
||||||
byte_t abtBuf[2];
|
byte_t abtBuf[2];
|
||||||
size_t szBufLen = sizeof (abtBuf);
|
size_t szBufLen = sizeof (abtBuf);
|
||||||
(void) bOn;
|
(void) bOn;
|
||||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||||
{
|
return (SCardControl
|
||||||
return (SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtLed,sizeof(abtLed),abtBuf,szBufLen,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
(pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtLed, sizeof (abtLed), abtBuf, szBufLen,
|
||||||
|
(void *) &szBufLen) == SCARD_S_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
return (SCardTransmit(pas->hCard,&(pas->ioCard),abtLed,sizeof(abtLed),NULL,(byte_t*)abtBuf,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
return (SCardTransmit
|
||||||
|
(pas->hCard, &(pas->ioCard), abtLed, sizeof (abtLed), NULL, (byte_t *) abtBuf,
|
||||||
|
(void *) &szBufLen) == SCARD_S_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,11 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd);
|
||||||
void acr122_disconnect (nfc_device_t * pnd);
|
void acr122_disconnect (nfc_device_t * pnd);
|
||||||
|
|
||||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||||
bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
bool acr122_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen);
|
||||||
|
|
||||||
// Various additional features this device supports
|
// Various additional features this device supports
|
||||||
char *acr122_firmware (const nfc_device_spec_t nds);
|
char *acr122_firmware (const nfc_device_spec_t nds);
|
||||||
bool acr122_led_red (const nfc_device_spec_t nds, bool bOn);
|
bool acr122_led_red (const nfc_device_spec_t nds, bool bOn);
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_ACR122_H__
|
#endif // ! __NFC_DRIVER_ACR122_H__
|
||||||
|
|
||||||
|
|
|
@ -124,10 +124,10 @@ arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
||||||
sp = uart_open (pcPort);
|
sp = uart_open (pcPort);
|
||||||
DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
|
DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
|
||||||
|
|
||||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT))
|
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||||
{
|
|
||||||
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
||||||
if(!arygon_check_communication((nfc_device_spec_t)sp)) continue;
|
if (!arygon_check_communication ((nfc_device_spec_t) sp))
|
||||||
|
continue;
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
|
|
||||||
// ARYGON reader is found
|
// ARYGON reader is found
|
||||||
|
@ -140,18 +140,23 @@ arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
|
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if((*pszDeviceFound) >= szDevices) break;
|
if ((*pszDeviceFound) >= szDevices)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s", pcPort);
|
if (sp == INVALID_SERIAL_PORT)
|
||||||
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s", pcPort);
|
DBG ("Invalid serial port: %s", pcPort);
|
||||||
#endif /* DEBUG */
|
if (sp == CLAIMED_SERIAL_PORT)
|
||||||
|
DBG ("Serial port already claimed: %s", pcPort);
|
||||||
|
# endif
|
||||||
|
/* DEBUG */
|
||||||
}
|
}
|
||||||
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
|
nfc_device_t *
|
||||||
|
arygon_connect (const nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
serial_port sp;
|
serial_port sp;
|
||||||
nfc_device_t *pnd = NULL;
|
nfc_device_t *pnd = NULL;
|
||||||
|
@ -159,9 +164,12 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
|
||||||
DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
|
DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
|
||||||
sp = uart_open (pndd->pcPort);
|
sp = uart_open (pndd->pcPort);
|
||||||
|
|
||||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
|
if (sp == INVALID_SERIAL_PORT)
|
||||||
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort);
|
ERR ("Invalid serial port: %s", pndd->pcPort);
|
||||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
|
if (sp == CLAIMED_SERIAL_PORT)
|
||||||
|
ERR ("Serial port already claimed: %s", pndd->pcPort);
|
||||||
|
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
uart_set_speed (sp, pndd->uiSpeed);
|
uart_set_speed (sp, pndd->uiSpeed);
|
||||||
|
|
||||||
|
@ -181,13 +189,15 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
|
||||||
return pnd;
|
return pnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arygon_disconnect(nfc_device_t* pnd)
|
void
|
||||||
|
arygon_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
uart_close ((serial_port) pnd->nds);
|
uart_close ((serial_port) pnd->nds);
|
||||||
free (pnd);
|
free (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||||
|
@ -222,7 +232,6 @@ bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bzero (abtRxBuf, sizeof (abtRxBuf));
|
bzero (abtRxBuf, sizeof (abtRxBuf));
|
||||||
#endif
|
#endif
|
||||||
|
@ -232,7 +241,6 @@ bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||||
#endif
|
#endif
|
||||||
|
@ -270,10 +278,12 @@ bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// When the answer should be ignored, just return a successful result
|
// When the answer should be ignored, just return a successful result
|
||||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
if (pbtRx == NULL || pszRxLen == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
||||||
if(szRxBufLen < 9) return false;
|
if (szRxBufLen < 9)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||||
*pszRxLen = szRxBufLen - 9;
|
*pszRxLen = szRxBufLen - 9;
|
||||||
|
@ -288,11 +298,15 @@ arygon_check_communication(const nfc_device_spec_t nds)
|
||||||
{
|
{
|
||||||
byte_t abtRx[BUFFER_LENGTH];
|
byte_t abtRx[BUFFER_LENGTH];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
const byte_t attempted_result[] = { 0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0xff,0x09,0xf7,0xD5,0x01,0x00,'l','i','b','n','f','c',0xbc,0x00};
|
const byte_t attempted_result[] =
|
||||||
|
{ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xD5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c',
|
||||||
|
0xbc, 0x00 };
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
||||||
const byte_t pncmd_communication_test[] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00,0x00,0xff,0x09,0xf7,0xd4,0x00,0x00,'l','i','b','n','f','c',0xbe,0x00 };
|
const byte_t pncmd_communication_test[] =
|
||||||
|
{ DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe,
|
||||||
|
0x00 };
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
|
PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
|
||||||
|
@ -318,4 +332,3 @@ arygon_check_communication(const nfc_device_spec_t nds)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd);
|
||||||
void arygon_disconnect (nfc_device_t * pnd);
|
void arygon_disconnect (nfc_device_t * pnd);
|
||||||
|
|
||||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||||
bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
bool arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen);
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_ARYGON_H__
|
#endif // ! __NFC_DRIVER_ARYGON_H__
|
||||||
|
|
||||||
|
|
|
@ -35,22 +35,20 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include <nfc/nfc-messages.h>
|
#include <nfc/nfc-messages.h>
|
||||||
|
|
||||||
nfc_device_desc_t * pn531_usb_pick_device (void)
|
nfc_device_desc_t *
|
||||||
|
pn531_usb_pick_device (void)
|
||||||
{
|
{
|
||||||
nfc_device_desc_t *pndd;
|
nfc_device_desc_t *pndd;
|
||||||
|
|
||||||
if ((pndd = malloc (sizeof (*pndd))))
|
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||||
{
|
|
||||||
size_t szN;
|
size_t szN;
|
||||||
|
|
||||||
if (!pn531_usb_list_devices (pndd, 1, &szN))
|
if (!pn531_usb_list_devices (pndd, 1, &szN)) {
|
||||||
{
|
|
||||||
DBG ("%s", "pn531_usb_list_devices failed");
|
DBG ("%s", "pn531_usb_list_devices failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szN == 0)
|
if (szN == 0) {
|
||||||
{
|
|
||||||
DBG ("%s", "No device found");
|
DBG ("%s", "No device found");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -58,16 +56,20 @@ nfc_device_desc_t * pn531_usb_pick_device (void)
|
||||||
return pndd;
|
return pndd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn531_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
bool
|
||||||
|
pn531_usb_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
||||||
{
|
{
|
||||||
// array of {vendor,product} pairs for USB devices
|
// array of {vendor,product} pairs for USB devices
|
||||||
usb_candidate_t candidates[]= {{0x04CC,0x0531},{0x054c,0x0193}};
|
usb_candidate_t candidates[] = { {0x04CC, 0x0531}
|
||||||
|
, {0x054c, 0x0193}
|
||||||
|
};
|
||||||
|
|
||||||
return pn53x_usb_list_devices(&pnddDevices[0], szDevices, pszDeviceFound, &candidates[0], sizeof(candidates) / sizeof(usb_candidate_t),PN531_USB_DRIVER_NAME);
|
return pn53x_usb_list_devices (&pnddDevices[0], szDevices, pszDeviceFound, &candidates[0],
|
||||||
|
sizeof (candidates) / sizeof (usb_candidate_t), PN531_USB_DRIVER_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd)
|
nfc_device_t *
|
||||||
|
pn531_usb_connect (const nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
return pn53x_usb_connect (pndd, pndd->acDevice, NC_PN531);
|
return pn53x_usb_connect (pndd, pndd->acDevice, NC_PN531);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,3 @@ bool pn531_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
||||||
nfc_device_desc_t *pn531_usb_pick_device (void);
|
nfc_device_desc_t *pn531_usb_pick_device (void);
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_PN531_USB_H__
|
#endif // ! __NFC_DRIVER_PN531_USB_H__
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,7 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_
|
||||||
sp = uart_open (pcPort);
|
sp = uart_open (pcPort);
|
||||||
DBG ("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
|
DBG ("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
|
||||||
|
|
||||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT))
|
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||||
{
|
|
||||||
bool bComOk;
|
bool bComOk;
|
||||||
// Serial port claimed but we need to check if a PN532_UART is connected.
|
// Serial port claimed but we need to check if a PN532_UART is connected.
|
||||||
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
||||||
|
@ -115,18 +114,23 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
|
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if((*pszDeviceFound) >= szDevices) break;
|
if ((*pszDeviceFound) >= szDevices)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s", pcPort);
|
if (sp == INVALID_SERIAL_PORT)
|
||||||
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s", pcPort);
|
DBG ("Invalid serial port: %s", pcPort);
|
||||||
#endif /* DEBUG */
|
if (sp == CLAIMED_SERIAL_PORT)
|
||||||
|
DBG ("Serial port already claimed: %s", pcPort);
|
||||||
|
# endif
|
||||||
|
/* DEBUG */
|
||||||
}
|
}
|
||||||
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
nfc_device_t *
|
||||||
|
pn532_uart_connect (const nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
serial_port sp;
|
serial_port sp;
|
||||||
nfc_device_t *pnd = NULL;
|
nfc_device_t *pnd = NULL;
|
||||||
|
@ -135,9 +139,12 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
||||||
DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
|
DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
|
||||||
sp = uart_open (pndd->pcPort);
|
sp = uart_open (pndd->pcPort);
|
||||||
|
|
||||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
|
if (sp == INVALID_SERIAL_PORT)
|
||||||
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort);
|
ERR ("Invalid serial port: %s", pndd->pcPort);
|
||||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
|
if (sp == CLAIMED_SERIAL_PORT)
|
||||||
|
ERR ("Serial port already claimed: %s", pndd->pcPort);
|
||||||
|
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
uart_set_speed (sp, pndd->uiSpeed);
|
uart_set_speed (sp, pndd->uiSpeed);
|
||||||
|
|
||||||
|
@ -165,13 +172,16 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
||||||
return pnd;
|
return pnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pn532_uart_disconnect(nfc_device_t* pnd)
|
void
|
||||||
|
pn532_uart_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
uart_close ((serial_port) pnd->nds);
|
uart_close ((serial_port) pnd->nds);
|
||||||
free (pnd);
|
free (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
pn532_uart_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||||
|
@ -190,8 +200,7 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
|
|
||||||
// Calculate data payload checksum
|
// Calculate data payload checksum
|
||||||
abtTxBuf[szTxLen + 5] = 0;
|
abtTxBuf[szTxLen + 5] = 0;
|
||||||
for(szPos=0; szPos < szTxLen; szPos++)
|
for (szPos = 0; szPos < szTxLen; szPos++) {
|
||||||
{
|
|
||||||
abtTxBuf[szTxLen + 5] -= abtTxBuf[szPos + 5];
|
abtTxBuf[szTxLen + 5] -= abtTxBuf[szPos + 5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +223,6 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||||
#endif
|
#endif
|
||||||
|
@ -236,7 +244,6 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("TX", ack_frame, 6);
|
PRINT_HEX ("TX", ack_frame, 6);
|
||||||
#endif
|
#endif
|
||||||
|
@ -251,14 +258,14 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// When the answer should be ignored, just return a successful result
|
// When the answer should be ignored, just return a successful result
|
||||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
if (pbtRx == NULL || pszRxLen == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
||||||
if (szRxBufLen < 9) {
|
if (szRxBufLen < 9) {
|
||||||
pnd->iLastError = DEINVAL;
|
pnd->iLastError = DEINVAL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||||
*pszRxLen = szRxBufLen - 9;
|
*pszRxLen = szRxBufLen - 9;
|
||||||
memcpy (pbtRx, abtRxBuf + 7, *pszRxLen);
|
memcpy (pbtRx, abtRxBuf + 7, *pszRxLen);
|
||||||
|
@ -274,7 +281,9 @@ pn532_uart_wakeup(const nfc_device_spec_t nds)
|
||||||
/** PN532C106 wakeup. */
|
/** PN532C106 wakeup. */
|
||||||
/** High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for PN532 being wakeup. */
|
/** High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for PN532 being wakeup. */
|
||||||
/** After the preamble we request the PN532C106 chip to switch to "normal" mode (SAM is not used) */
|
/** After the preamble we request the PN532C106 chip to switch to "normal" mode (SAM is not used) */
|
||||||
const byte_t pncmd_pn532c106_wakeup_preamble[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
|
const byte_t pncmd_pn532c106_wakeup_preamble[] =
|
||||||
|
{ 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00, 0x00, 0xff, 0x03, 0xfd,
|
||||||
|
0xd4, 0x14, 0x01, 0x17, 0x00 };
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("TX", pncmd_pn532c106_wakeup_preamble, sizeof (pncmd_pn532c106_wakeup_preamble));
|
PRINT_HEX ("TX", pncmd_pn532c106_wakeup_preamble, sizeof (pncmd_pn532c106_wakeup_preamble));
|
||||||
#endif
|
#endif
|
||||||
|
@ -291,11 +300,14 @@ pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||||
{
|
{
|
||||||
byte_t abtRx[BUFFER_LENGTH];
|
byte_t abtRx[BUFFER_LENGTH];
|
||||||
size_t szRxLen;
|
size_t szRxLen;
|
||||||
const byte_t attempted_result[] = { 0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0xff,0x09,0xf7,0xD5,0x01,0x00,'l','i','b','n','f','c',0xbc,0x00};
|
const byte_t attempted_result[] =
|
||||||
|
{ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xD5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c',
|
||||||
|
0xbc, 0x00 };
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
/** To be sure that PN532 is alive, we have put a "Diagnose" command to execute a "Communication Line Test" */
|
||||||
const byte_t pncmd_communication_test[] = { 0x00,0x00,0xff,0x09,0xf7,0xd4,0x00,0x00,'l','i','b','n','f','c',0xbe,0x00 };
|
const byte_t pncmd_communication_test[] =
|
||||||
|
{ 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe, 0x00 };
|
||||||
|
|
||||||
*success = false;
|
*success = false;
|
||||||
|
|
||||||
|
@ -313,7 +325,6 @@ pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||||
ERR ("%s", "Unable to receive data. (RX)");
|
ERR ("%s", "Unable to receive data. (RX)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("RX", abtRx, szRxLen);
|
PRINT_HEX ("RX", abtRx, szRxLen);
|
||||||
#endif
|
#endif
|
||||||
|
@ -323,4 +334,3 @@ pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd);
|
||||||
void pn532_uart_disconnect (nfc_device_t * pnd);
|
void pn532_uart_disconnect (nfc_device_t * pnd);
|
||||||
|
|
||||||
// Callback function used by libnfc to transmit commands to the PN53X chip
|
// Callback function used by libnfc to transmit commands to the PN53X chip
|
||||||
bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
bool pn532_uart_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen);
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_PN532_UART_H__
|
#endif // ! __NFC_DRIVER_PN532_UART_H__
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include <nfc/nfc-messages.h>
|
#include <nfc/nfc-messages.h>
|
||||||
|
|
||||||
nfc_device_desc_t * pn533_usb_pick_device (void)
|
nfc_device_desc_t *
|
||||||
|
pn533_usb_pick_device (void)
|
||||||
{
|
{
|
||||||
nfc_device_desc_t *pndd;
|
nfc_device_desc_t *pndd;
|
||||||
|
|
||||||
|
@ -56,16 +57,20 @@ nfc_device_desc_t * pn533_usb_pick_device (void)
|
||||||
return pndd;
|
return pndd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn533_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
bool
|
||||||
|
pn533_usb_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
||||||
{
|
{
|
||||||
// array of {vendor,product} pairs for USB devices
|
// array of {vendor,product} pairs for USB devices
|
||||||
usb_candidate_t candidates[]= {{0x04CC,0x2533},{0x04E6,0x5591}};
|
usb_candidate_t candidates[] = { {0x04CC, 0x2533}
|
||||||
|
, {0x04E6, 0x5591}
|
||||||
|
};
|
||||||
|
|
||||||
return pn53x_usb_list_devices(&pnddDevices[0], szDevices, pszDeviceFound, &candidates[0], sizeof(candidates) / sizeof(usb_candidate_t),PN533_USB_DRIVER_NAME);
|
return pn53x_usb_list_devices (&pnddDevices[0], szDevices, pszDeviceFound, &candidates[0],
|
||||||
|
sizeof (candidates) / sizeof (usb_candidate_t), PN533_USB_DRIVER_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd)
|
nfc_device_t *
|
||||||
|
pn533_usb_connect (const nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
return pn53x_usb_connect (pndd, pndd->acDevice, NC_PN533);
|
return pn53x_usb_connect (pndd, pndd->acDevice, NC_PN533);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,3 @@ bool pn533_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
||||||
nfc_device_desc_t *pn533_usb_pick_device (void);
|
nfc_device_desc_t *pn533_usb_pick_device (void);
|
||||||
|
|
||||||
#endif // ! __NFC_DRIVER_PN533_USB_H__
|
#endif // ! __NFC_DRIVER_PN533_USB_H__
|
||||||
|
|
||||||
|
|
|
@ -46,38 +46,39 @@ Thanks to d18c7db and Okko for example code
|
||||||
#define USB_TIMEOUT 30000
|
#define USB_TIMEOUT 30000
|
||||||
|
|
||||||
// Find transfer endpoints for bulk transfers
|
// Find transfer endpoints for bulk transfers
|
||||||
void get_end_points(struct usb_device *dev, usb_spec_t* pus)
|
void
|
||||||
|
get_end_points (struct usb_device *dev, usb_spec_t * pus)
|
||||||
{
|
{
|
||||||
uint32_t uiIndex;
|
uint32_t uiIndex;
|
||||||
uint32_t uiEndPoint;
|
uint32_t uiEndPoint;
|
||||||
struct usb_interface_descriptor *puid = dev->config->interface->altsetting;
|
struct usb_interface_descriptor *puid = dev->config->interface->altsetting;
|
||||||
|
|
||||||
// 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
|
// 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
|
||||||
for(uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++)
|
for (uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++) {
|
||||||
{
|
|
||||||
// Only accept bulk transfer endpoints (ignore interrupt endpoints)
|
// Only accept bulk transfer endpoints (ignore interrupt endpoints)
|
||||||
if(puid->endpoint[uiIndex].bmAttributes != USB_ENDPOINT_TYPE_BULK) continue;
|
if (puid->endpoint[uiIndex].bmAttributes != USB_ENDPOINT_TYPE_BULK)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Copy the endpoint to a local var, makes it more readable code
|
// Copy the endpoint to a local var, makes it more readable code
|
||||||
uiEndPoint = puid->endpoint[uiIndex].bEndpointAddress;
|
uiEndPoint = puid->endpoint[uiIndex].bEndpointAddress;
|
||||||
|
|
||||||
// Test if we dealing with a bulk IN endpoint
|
// Test if we dealing with a bulk IN endpoint
|
||||||
if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
|
if ((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN) {
|
||||||
{
|
|
||||||
pus->uiEndPointIn = uiEndPoint;
|
pus->uiEndPointIn = uiEndPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if we dealing with a bulk OUT endpoint
|
// Test if we dealing with a bulk OUT endpoint
|
||||||
if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
|
if ((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT) {
|
||||||
{
|
|
||||||
pus->uiEndPointOut = uiEndPoint;
|
pus->uiEndPointOut = uiEndPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,usb_candidate_t candidates[], int num_candidates, char * target_name)
|
bool
|
||||||
|
pn53x_usb_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound,
|
||||||
|
usb_candidate_t candidates[], int num_candidates, char *target_name)
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret,
|
||||||
|
i;
|
||||||
|
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
|
@ -89,42 +90,37 @@ bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
||||||
usb_init ();
|
usb_init ();
|
||||||
|
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the number of changes since previous call to this function (total of new busses and busses removed).
|
// usb_find_busses will find all of the busses on the system. Returns the number of changes since previous call to this function (total of new busses and busses removed).
|
||||||
if ((ret= usb_find_busses() < 0)) return false;
|
if ((ret = usb_find_busses () < 0))
|
||||||
|
return false;
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be called after usb_find_busses. Returns the number of changes since the previous call to this function (total of new device and devices removed).
|
// usb_find_devices will find all of the devices on each bus. This should be called after usb_find_busses. Returns the number of changes since the previous call to this function (total of new device and devices removed).
|
||||||
if ((ret= usb_find_devices() < 0)) return false;
|
if ((ret = usb_find_devices () < 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
|
|
||||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
||||||
{
|
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++) {
|
||||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++)
|
for (i = 0; i < num_candidates; ++i) {
|
||||||
{
|
|
||||||
for(i = 0; i < num_candidates; ++i)
|
|
||||||
{
|
|
||||||
// DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct,candidates[i].idVendor,candidates[i].idProduct);
|
// DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct,candidates[i].idVendor,candidates[i].idProduct);
|
||||||
if (candidates[i].idVendor==dev->descriptor.idVendor && candidates[i].idProduct==dev->descriptor.idProduct)
|
if (candidates[i].idVendor == dev->descriptor.idVendor && candidates[i].idProduct == dev->descriptor.idProduct) {
|
||||||
{
|
|
||||||
// Make sure there are 2 endpoints available
|
// Make sure there are 2 endpoints available
|
||||||
// with libusb-win32 we got some null pointers so be robust before looking at endpoints:
|
// with libusb-win32 we got some null pointers so be robust before looking at endpoints:
|
||||||
if (dev->config == NULL || dev->config->interface == NULL || dev->config->interface->altsetting == NULL)
|
if (dev->config == NULL || dev->config->interface == NULL || dev->config->interface->altsetting == NULL) {
|
||||||
{
|
|
||||||
// Nope, we maybe want the next one, let's try to find another
|
// Nope, we maybe want the next one, let's try to find another
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dev->config->interface->altsetting->bNumEndpoints < 2)
|
if (dev->config->interface->altsetting->bNumEndpoints < 2) {
|
||||||
{
|
|
||||||
// Nope, we maybe want the next one, let's try to find another
|
// Nope, we maybe want the next one, let's try to find another
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dev->descriptor.iManufacturer || dev->descriptor.iProduct)
|
if (dev->descriptor.iManufacturer || dev->descriptor.iProduct) {
|
||||||
{
|
|
||||||
udev = usb_open (dev);
|
udev = usb_open (dev);
|
||||||
if(udev)
|
if (udev) {
|
||||||
{
|
|
||||||
usb_get_string_simple (udev, dev->descriptor.iManufacturer, string, sizeof (string));
|
usb_get_string_simple (udev, dev->descriptor.iManufacturer, string, sizeof (string));
|
||||||
if (strlen (string) > 0)
|
if (strlen (string) > 0)
|
||||||
strcpy (string + strlen (string), " / ");
|
strcpy (string + strlen (string), " / ");
|
||||||
usb_get_string_simple(udev, dev->descriptor.iProduct, string + strlen(string), sizeof(string) - strlen(string));
|
usb_get_string_simple (udev, dev->descriptor.iProduct, string + strlen (string),
|
||||||
|
sizeof (string) - strlen (string));
|
||||||
}
|
}
|
||||||
usb_close (udev);
|
usb_close (udev);
|
||||||
}
|
}
|
||||||
|
@ -136,8 +132,7 @@ bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
||||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||||
(*pszDeviceFound)++;
|
(*pszDeviceFound)++;
|
||||||
// Test if we reach the maximum "wanted" devices
|
// Test if we reach the maximum "wanted" devices
|
||||||
if((*pszDeviceFound) == szDevices)
|
if ((*pszDeviceFound) == szDevices) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +144,8 @@ bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, s
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * target_name, int target_chip)
|
nfc_device_t *
|
||||||
|
pn53x_usb_connect (const nfc_device_desc_t * pndd, const char *target_name, int target_chip)
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd = NULL;
|
nfc_device_t *pnd = NULL;
|
||||||
usb_spec_t *pus;
|
usb_spec_t *pus;
|
||||||
|
@ -167,27 +163,22 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * targe
|
||||||
|
|
||||||
uiBusIndex = pndd->uiBusIndex;
|
uiBusIndex = pndd->uiBusIndex;
|
||||||
|
|
||||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
||||||
{
|
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--) {
|
||||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--)
|
|
||||||
{
|
|
||||||
// DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
// DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||||
if(uiBusIndex == 0)
|
if (uiBusIndex == 0) {
|
||||||
{
|
|
||||||
// Open the USB device
|
// Open the USB device
|
||||||
us.pudh = usb_open (dev);
|
us.pudh = usb_open (dev);
|
||||||
|
|
||||||
get_end_points (dev, &us);
|
get_end_points (dev, &us);
|
||||||
if(usb_set_configuration(us.pudh,1) < 0)
|
if (usb_set_configuration (us.pudh, 1) < 0) {
|
||||||
{
|
|
||||||
DBG ("%s", "Setting config failed");
|
DBG ("%s", "Setting config failed");
|
||||||
usb_close (us.pudh);
|
usb_close (us.pudh);
|
||||||
// we failed to use the specified device
|
// we failed to use the specified device
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(usb_claim_interface(us.pudh,0) < 0)
|
if (usb_claim_interface (us.pudh, 0) < 0) {
|
||||||
{
|
|
||||||
DBG ("%s", "Can't claim interface");
|
DBG ("%s", "Can't claim interface");
|
||||||
usb_close (us.pudh);
|
usb_close (us.pudh);
|
||||||
// we failed to use the specified device
|
// we failed to use the specified device
|
||||||
|
@ -213,7 +204,8 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * targe
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pn53x_usb_disconnect(nfc_device_t* pnd)
|
void
|
||||||
|
pn53x_usb_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
usb_spec_t *pus = (usb_spec_t *) pnd->nds;
|
usb_spec_t *pus = (usb_spec_t *) pnd->nds;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -234,7 +226,8 @@ void pn53x_usb_disconnect(nfc_device_t* pnd)
|
||||||
free (pnd);
|
free (pnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
pn53x_usb_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
size_t uiPos = 0;
|
size_t uiPos = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -253,8 +246,7 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
||||||
|
|
||||||
// Calculate data payload checksum
|
// Calculate data payload checksum
|
||||||
abtTx[szTxLen + 5] = 0;
|
abtTx[szTxLen + 5] = 0;
|
||||||
for(uiPos=0; uiPos < szTxLen; uiPos++)
|
for (uiPos = 0; uiPos < szTxLen; uiPos++) {
|
||||||
{
|
|
||||||
abtTx[szTxLen + 5] -= abtTx[uiPos + 5];
|
abtTx[szTxLen + 5] -= abtTx[uiPos + 5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,21 +258,18 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = usb_bulk_write (pus->pudh, pus->uiEndPointOut, (char *) abtTx, szTxLen + 7, USB_TIMEOUT);
|
ret = usb_bulk_write (pus->pudh, pus->uiEndPointOut, (char *) abtTx, szTxLen + 7, USB_TIMEOUT);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
{
|
|
||||||
DBG ("usb_bulk_write failed with error %d", ret);
|
DBG ("usb_bulk_write failed with error %d", ret);
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = usb_bulk_read (pus->pudh, pus->uiEndPointIn, (char *) abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
ret = usb_bulk_read (pus->pudh, pus->uiEndPointIn, (char *) abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
{
|
|
||||||
DBG ("usb_bulk_read failed with error %d", ret);
|
DBG ("usb_bulk_read failed with error %d", ret);
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("RX", abtRx, ret);
|
PRINT_HEX ("RX", abtRx, ret);
|
||||||
#endif
|
#endif
|
||||||
|
@ -289,13 +278,11 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ret = usb_bulk_read (pus->pudh, pus->uiEndPointIn, (char *) abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
ret = usb_bulk_read (pus->pudh, pus->uiEndPointIn, (char *) abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
{
|
|
||||||
DBG ("usb_bulk_read failed with error %d", ret);
|
DBG ("usb_bulk_read failed with error %d", ret);
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX ("RX", abtRx, ret);
|
PRINT_HEX ("RX", abtRx, ret);
|
||||||
#endif
|
#endif
|
||||||
|
@ -309,16 +296,15 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// When the answer should be ignored, just return a succesful result
|
// When the answer should be ignored, just return a succesful result
|
||||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
if (pbtRx == NULL || pszRxLen == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
// Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
|
||||||
if(ret < 9)
|
if (ret < 9) {
|
||||||
{
|
|
||||||
DBG ("%s", "No data");
|
DBG ("%s", "No data");
|
||||||
pnd->iLastError = DEINVAL;
|
pnd->iLastError = DEINVAL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||||
*pszRxLen = ret - 7 - 2;
|
*pszRxLen = ret - 7 - 2;
|
||||||
|
|
||||||
|
|
|
@ -37,5 +37,7 @@ typedef struct {
|
||||||
nfc_device_t *pn53x_usb_connect (const nfc_device_desc_t * pndd, const char *target_name, int target_chip);
|
nfc_device_t *pn53x_usb_connect (const nfc_device_desc_t * pndd, const char *target_name, int target_chip);
|
||||||
void get_end_points (struct usb_device *dev, usb_spec_t * pus);
|
void get_end_points (struct usb_device *dev, usb_spec_t * pus);
|
||||||
void pn53x_usb_disconnect (nfc_device_t * pnd);
|
void pn53x_usb_disconnect (nfc_device_t * pnd);
|
||||||
bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
bool pn53x_usb_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,usb_candidate_t candidates[], int num_candidates, char * target_name);
|
size_t * pszRxLen);
|
||||||
|
bool pn53x_usb_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound,
|
||||||
|
usb_candidate_t candidates[], int num_candidates, char *target_name);
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
|
||||||
void iso14443a_crc(byte_t* pbtData, size_t szLen, byte_t* pbtCrc)
|
void
|
||||||
|
iso14443a_crc (byte_t * pbtData, size_t szLen, byte_t * pbtCrc)
|
||||||
{
|
{
|
||||||
byte_t bt;
|
byte_t bt;
|
||||||
uint32_t wCrc = 0x6363;
|
uint32_t wCrc = 0x6363;
|
||||||
|
@ -46,7 +47,8 @@ void iso14443a_crc(byte_t* pbtData, size_t szLen, byte_t* pbtCrc)
|
||||||
*pbtCrc = (byte_t) ((wCrc >> 8) & 0xFF);
|
*pbtCrc = (byte_t) ((wCrc >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_iso14443a_crc(byte_t* pbtData, size_t szLen)
|
void
|
||||||
|
append_iso14443a_crc (byte_t * pbtData, size_t szLen)
|
||||||
{
|
{
|
||||||
iso14443a_crc (pbtData, szLen, pbtData + szLen);
|
iso14443a_crc (pbtData, szLen, pbtData + szLen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,29 +53,32 @@ static const byte_t ByteMirror[256] = {
|
||||||
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
byte_t mirror(byte_t bt)
|
byte_t
|
||||||
|
mirror (byte_t bt)
|
||||||
{
|
{
|
||||||
return ByteMirror[bt];
|
return ByteMirror[bt];
|
||||||
}
|
}
|
||||||
|
|
||||||
void mirror_bytes(byte_t *pbts, size_t szLen)
|
void
|
||||||
|
mirror_bytes (byte_t * pbts, size_t szLen)
|
||||||
{
|
{
|
||||||
size_t szByteNr;
|
size_t szByteNr;
|
||||||
|
|
||||||
for (szByteNr=0; szByteNr<szLen; szByteNr++)
|
for (szByteNr = 0; szByteNr < szLen; szByteNr++) {
|
||||||
{
|
|
||||||
*pbts = ByteMirror[*pbts];
|
*pbts = ByteMirror[*pbts];
|
||||||
pbts++;
|
pbts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mirror32(uint32_t ui32Bits)
|
uint32_t
|
||||||
|
mirror32 (uint32_t ui32Bits)
|
||||||
{
|
{
|
||||||
mirror_bytes ((byte_t *) & ui32Bits, 4);
|
mirror_bytes ((byte_t *) & ui32Bits, 4);
|
||||||
return ui32Bits;
|
return ui32Bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t mirror64(uint64_t ui64Bits)
|
uint64_t
|
||||||
|
mirror64 (uint64_t ui64Bits)
|
||||||
{
|
{
|
||||||
mirror_bytes ((byte_t *) & ui64Bits, 8);
|
mirror_bytes ((byte_t *) & ui64Bits, 8);
|
||||||
return ui64Bits;
|
return ui64Bits;
|
||||||
|
|
153
libnfc/nfc.c
153
libnfc/nfc.c
|
@ -56,12 +56,11 @@ nfc_pick_device (void)
|
||||||
uint32_t uiDriver;
|
uint32_t uiDriver;
|
||||||
nfc_device_desc_t *nddRes;
|
nfc_device_desc_t *nddRes;
|
||||||
|
|
||||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
|
||||||
{
|
if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
|
||||||
if (drivers_callbacks_list[uiDriver].pick_device != NULL)
|
|
||||||
{
|
|
||||||
nddRes = drivers_callbacks_list[uiDriver].pick_device ();
|
nddRes = drivers_callbacks_list[uiDriver].pick_device ();
|
||||||
if (nddRes != NULL) return nddRes;
|
if (nddRes != NULL)
|
||||||
|
return nddRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,19 +81,15 @@ nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszD
|
||||||
|
|
||||||
*pszDeviceFound = 0;
|
*pszDeviceFound = 0;
|
||||||
|
|
||||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
|
||||||
{
|
if (drivers_callbacks_list[uiDriver].list_devices != NULL) {
|
||||||
if (drivers_callbacks_list[uiDriver].list_devices != NULL)
|
|
||||||
{
|
|
||||||
szN = 0;
|
szN = 0;
|
||||||
if (drivers_callbacks_list[uiDriver].list_devices (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN))
|
if (drivers_callbacks_list[uiDriver].
|
||||||
{
|
list_devices (pnddDevices + (*pszDeviceFound), szDevices - (*pszDeviceFound), &szN)) {
|
||||||
*pszDeviceFound += szN;
|
*pszDeviceFound += szN;
|
||||||
DBG ("%ld device(s) found using %s driver", (unsigned long) szN, drivers_callbacks_list[uiDriver].acDriver);
|
DBG ("%ld device(s) found using %s driver", (unsigned long) szN, drivers_callbacks_list[uiDriver].acDriver);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG ("No listing function avaible for %s driver", drivers_callbacks_list[uiDriver].acDriver);
|
DBG ("No listing function avaible for %s driver", drivers_callbacks_list[uiDriver].acDriver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,14 +108,14 @@ nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszD
|
||||||
* When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a nfc_device_t struct.
|
* When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a nfc_device_t struct.
|
||||||
* This pointer should be supplied by every next function of libnfc that should perform an action with this device.
|
* This pointer should be supplied by every next function of libnfc that should perform an action with this device.
|
||||||
*/
|
*/
|
||||||
nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
nfc_device_t *
|
||||||
|
nfc_connect (nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
nfc_device_t *pnd = NULL;
|
nfc_device_t *pnd = NULL;
|
||||||
uint32_t uiDriver;
|
uint32_t uiDriver;
|
||||||
|
|
||||||
// Search through the device list for an available device
|
// Search through the device list for an available device
|
||||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
|
||||||
{
|
|
||||||
if (pndd == NULL) {
|
if (pndd == NULL) {
|
||||||
// No device description specified: try to automatically claim a device
|
// No device description specified: try to automatically claim a device
|
||||||
if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
|
if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
|
||||||
|
@ -140,8 +135,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Specific device is requested: using device description pndd
|
// Specific device is requested: using device description pndd
|
||||||
if( 0 != strcmp(drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver ) )
|
if (0 != strcmp (drivers_callbacks_list[uiDriver].acDriver, pndd->pcDriver)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
pnd = drivers_callbacks_list[uiDriver].connect (pndd);
|
pnd = drivers_callbacks_list[uiDriver].connect (pndd);
|
||||||
|
@ -149,8 +143,7 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if the connection was successful
|
// Test if the connection was successful
|
||||||
if (pnd != NULL)
|
if (pnd != NULL) {
|
||||||
{
|
|
||||||
DBG ("[%s] has been claimed.", pnd->acName);
|
DBG ("[%s] has been claimed.", pnd->acName);
|
||||||
// Great we have claimed a device
|
// Great we have claimed a device
|
||||||
pnd->pdc = &(drivers_callbacks_list[uiDriver]);
|
pnd->pdc = &(drivers_callbacks_list[uiDriver]);
|
||||||
|
@ -159,27 +152,35 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Reset the ending transmission bits register, it is unknown what the last tranmission used there
|
// Reset the ending transmission bits register, it is unknown what the last tranmission used there
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_BIT_FRAMING,SYMBOL_TX_LAST_BITS,0x00)) return NULL;
|
if (!pn53x_set_reg (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, 0x00))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Set default configuration options
|
// Set default configuration options
|
||||||
// Make sure we reset the CRC and parity to chip handling.
|
// Make sure we reset the CRC and parity to chip handling.
|
||||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,true)) return NULL;
|
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true))
|
||||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) return NULL;
|
return NULL;
|
||||||
|
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Deactivate the CRYPTO1 chiper, it may could cause problems when still active
|
// Deactivate the CRYPTO1 chiper, it may could cause problems when still active
|
||||||
if (!nfc_configure(pnd,NDO_ACTIVATE_CRYPTO1,false)) return NULL;
|
if (!nfc_configure (pnd, NDO_ACTIVATE_CRYPTO1, false))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Activate "easy framing" feature by default
|
// Activate "easy framing" feature by default
|
||||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) return NULL;
|
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Activate auto ISO14443-4 switching by default
|
// Activate auto ISO14443-4 switching by default
|
||||||
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) return NULL;
|
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Disallow invalid frame
|
// Disallow invalid frame
|
||||||
if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false)) return NULL;
|
if (!nfc_configure (pnd, NDO_ACCEPT_INVALID_FRAMES, false))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Disallow multiple frames
|
// Disallow multiple frames
|
||||||
if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false)) return NULL;
|
if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return pnd;
|
return pnd;
|
||||||
} else {
|
} else {
|
||||||
|
@ -196,7 +197,8 @@ nfc_device_t* nfc_connect(nfc_device_desc_t* pndd)
|
||||||
*
|
*
|
||||||
* Initiator is disconnected and the device, including allocated \a nfc_device_t struct, is released.
|
* Initiator is disconnected and the device, including allocated \a nfc_device_t struct, is released.
|
||||||
*/
|
*/
|
||||||
void nfc_disconnect(nfc_device_t* pnd)
|
void
|
||||||
|
nfc_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
if (pnd) {
|
if (pnd) {
|
||||||
// Release and deselect all active communications
|
// Release and deselect all active communications
|
||||||
|
@ -219,7 +221,8 @@ void nfc_disconnect(nfc_device_t* pnd)
|
||||||
* There are different categories for configuring the PN53X chip features (handle, activate, infinite and accept).
|
* There are different categories for configuring the PN53X chip features (handle, activate, infinite and accept).
|
||||||
* These are defined to organize future settings that will become available when they are needed.
|
* These are defined to organize future settings that will become available when they are needed.
|
||||||
*/
|
*/
|
||||||
bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEnable)
|
bool
|
||||||
|
nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -236,18 +239,22 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
||||||
* After initialization it can be used to communicate to passive RFID tags and active NFC devices.
|
* After initialization it can be used to communicate to passive RFID tags and active NFC devices.
|
||||||
* The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.
|
* The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.
|
||||||
*/
|
*/
|
||||||
bool nfc_initiator_init(nfc_device_t* pnd)
|
bool
|
||||||
|
nfc_initiator_init (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
// Make sure we are dealing with a active device
|
// Make sure we are dealing with a active device
|
||||||
if (!pnd->bActive) return false;
|
if (!pnd->bActive)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards)
|
// Set the PN53X to force 100% ASK Modified miller decoding (default for 14443A cards)
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_TX_AUTO,SYMBOL_FORCE_100_ASK,0x40)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_TX_AUTO, SYMBOL_FORCE_100_ASK, 0x40))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Configure the PN53X to be an Initiator or Reader/Writer
|
// Configure the PN53X to be an Initiator or Reader/Writer
|
||||||
if (!pn53x_set_reg(pnd,REG_CIU_CONTROL,SYMBOL_INITIATOR,0x10)) return false;
|
if (!pn53x_set_reg (pnd, REG_CIU_CONTROL, SYMBOL_INITIATOR, 0x10))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -268,11 +275,15 @@ bool nfc_initiator_init(nfc_device_t* pnd)
|
||||||
* The NFC device will try to find the available target. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications.
|
* The NFC device will try to find the available target. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications.
|
||||||
* @note nfc_dep_info_t will be returned when the target was acquired successfully.
|
* @note nfc_dep_info_t will be returned when the target was acquired successfully.
|
||||||
*/
|
*/
|
||||||
bool nfc_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t* pbtPidData, const size_t szPidDataLen, const byte_t* pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t* pnti)
|
bool
|
||||||
|
nfc_initiator_select_dep_target (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation, const byte_t * pbtPidData,
|
||||||
|
const size_t szPidDataLen, const byte_t * pbtNFCID3i, const size_t szNFCID3iDataLen,
|
||||||
|
const byte_t * pbtGbData, const size_t szGbDataLen, nfc_target_info_t * pnti)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
return pn53x_initiator_select_dep_target(pnd, nmInitModulation, pbtPidData, szPidDataLen, pbtNFCID3i, szNFCID3iDataLen, pbtGbData, szGbDataLen, pnti);
|
return pn53x_initiator_select_dep_target (pnd, nmInitModulation, pbtPidData, szPidDataLen, pbtNFCID3i,
|
||||||
|
szNFCID3iDataLen, pbtGbData, szGbDataLen, pnti);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -292,8 +303,7 @@ bool nfc_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t n
|
||||||
bool
|
bool
|
||||||
nfc_initiator_select_passive_target (nfc_device_t * pnd,
|
nfc_initiator_select_passive_target (nfc_device_t * pnd,
|
||||||
const nfc_modulation_t nmInitModulation,
|
const nfc_modulation_t nmInitModulation,
|
||||||
const byte_t* pbtInitData, const size_t szInitDataLen,
|
const byte_t * pbtInitData, const size_t szInitDataLen, nfc_target_info_t * pnti)
|
||||||
nfc_target_info_t* pnti)
|
|
||||||
{
|
{
|
||||||
byte_t abtInit[MAX_FRAME_LEN];
|
byte_t abtInit[MAX_FRAME_LEN];
|
||||||
size_t szInitLen;
|
size_t szInitLen;
|
||||||
|
@ -304,13 +314,12 @@ nfc_initiator_select_passive_target(nfc_device_t* pnd,
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
// Make sure we are dealing with a active device
|
// Make sure we are dealing with a active device
|
||||||
if (!pnd->bActive) return false;
|
if (!pnd->bActive)
|
||||||
|
return false;
|
||||||
// TODO Put this in a function
|
// TODO Put this in a function
|
||||||
switch(nmInitModulation)
|
switch (nmInitModulation) {
|
||||||
{
|
|
||||||
case NM_ISO14443A_106:
|
case NM_ISO14443A_106:
|
||||||
switch (szInitDataLen)
|
switch (szInitDataLen) {
|
||||||
{
|
|
||||||
case 7:
|
case 7:
|
||||||
abtInit[0] = 0x88;
|
abtInit[0] = 0x88;
|
||||||
memcpy (abtInit + 1, pbtInitData, 7);
|
memcpy (abtInit + 1, pbtInitData, 7);
|
||||||
|
@ -339,17 +348,17 @@ nfc_initiator_select_passive_target(nfc_device_t* pnd,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!pn53x_InListPassiveTarget(pnd, nmInitModulation, 1, abtInit, szInitLen, abtTargetsData, &szTargetsData)) return false;
|
if (!pn53x_InListPassiveTarget (pnd, nmInitModulation, 1, abtInit, szInitLen, abtTargetsData, &szTargetsData))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
|
// Make sure one tag has been found, the PN53X returns 0x00 if none was available
|
||||||
if (abtTargetsData[0] == 0) return false;
|
if (abtTargetsData[0] == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Is a tag info struct available
|
// Is a tag info struct available
|
||||||
if (pnti)
|
if (pnti) {
|
||||||
{
|
|
||||||
// Fill the tag info struct with the values corresponding to this init modulation
|
// Fill the tag info struct with the values corresponding to this init modulation
|
||||||
switch(nmInitModulation)
|
switch (nmInitModulation) {
|
||||||
{
|
|
||||||
case NM_ISO14443A_106:
|
case NM_ISO14443A_106:
|
||||||
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) {
|
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -388,7 +397,8 @@ nfc_initiator_select_passive_target(nfc_device_t* pnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, nfc_target_info_t anti[], const size_t szTargets, size_t *pszTargetFound)
|
nfc_initiator_list_passive_targets (nfc_device_t * pnd, const nfc_modulation_t nmInitModulation,
|
||||||
|
nfc_target_info_t anti[], const size_t szTargets, size_t * pszTargetFound)
|
||||||
{
|
{
|
||||||
nfc_target_info_t nti;
|
nfc_target_info_t nti;
|
||||||
size_t szTargetFound = 0;
|
size_t szTargetFound = 0;
|
||||||
|
@ -425,7 +435,8 @@ nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_t nmI
|
||||||
*
|
*
|
||||||
* After selecting and communicating with a passive tag, this function could be used to deactivate and release the tag. This is very useful when there are multiple tags available in the field. It is possible to use the nfc_initiator_select_passive_target() function to select the first available tag, test it for the available features and support, deselect it and skip to the next tag until the correct tag is found.
|
* After selecting and communicating with a passive tag, this function could be used to deactivate and release the tag. This is very useful when there are multiple tags available in the field. It is possible to use the nfc_initiator_select_passive_target() function to select the first available tag, test it for the available features and support, deselect it and skip to the next tag until the correct tag is found.
|
||||||
*/
|
*/
|
||||||
bool nfc_initiator_deselect_target(nfc_device_t* pnd)
|
bool
|
||||||
|
nfc_initiator_deselect_target (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -466,7 +477,9 @@ nfc_initiator_poll_targets(nfc_device_t* pnd,
|
||||||
*
|
*
|
||||||
* The NFC reader will transmit low-level messages where only the modulation is handled by the PN53X chip. Construction of the frame (data, CRC and parity) is completely done by libnfc. This can be very useful for testing purposes. Some protocols (e.g. MIFARE Classic) require to violate the ISO14443-A standard by sending incorrect parity and CRC bytes. Using this feature you are able to simulate these frames.
|
* The NFC reader will transmit low-level messages where only the modulation is handled by the PN53X chip. Construction of the frame (data, CRC and parity) is completely done by libnfc. This can be very useful for testing purposes. Some protocols (e.g. MIFARE Classic) require to violate the ISO14443-A standard by sending incorrect parity and CRC bytes. Using this feature you are able to simulate these frames.
|
||||||
*/
|
*/
|
||||||
bool nfc_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
bool
|
||||||
|
nfc_initiator_transceive_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar,
|
||||||
|
byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -486,7 +499,9 @@ bool nfc_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, const
|
||||||
*
|
*
|
||||||
* @warning The configuration option NDO_HANDLE_PARITY must be set to true (the default value).
|
* @warning The configuration option NDO_HANDLE_PARITY must be set to true (the default value).
|
||||||
*/
|
*/
|
||||||
bool nfc_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
nfc_initiator_transceive_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
|
||||||
|
size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -501,7 +516,8 @@ bool nfc_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, cons
|
||||||
*
|
*
|
||||||
* @warning Be aware that this function will wait (hang) until a command is received that is not part of the anti-collision. The RATS command for example would wake up the emulator. After this is received, the send and receive functions can be used.
|
* @warning Be aware that this function will wait (hang) until a command is received that is not part of the anti-collision. The RATS command for example would wake up the emulator. After this is received, the send and receive functions can be used.
|
||||||
*/
|
*/
|
||||||
bool nfc_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
bool
|
||||||
|
nfc_target_init (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -514,7 +530,8 @@ bool nfc_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
||||||
*
|
*
|
||||||
* This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the NDO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.
|
* This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the NDO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.
|
||||||
*/
|
*/
|
||||||
bool nfc_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits, byte_t* pbtRxPar)
|
bool
|
||||||
|
nfc_target_receive_bits (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -527,7 +544,8 @@ bool nfc_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits
|
||||||
*
|
*
|
||||||
* The main receive function that returns the received frames from a nearby reader.
|
* The main receive function that returns the received frames from a nearby reader.
|
||||||
*/
|
*/
|
||||||
bool nfc_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
bool
|
||||||
|
nfc_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxLen)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -540,7 +558,8 @@ bool nfc_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen
|
||||||
*
|
*
|
||||||
* This function can be used to transmit (raw) bit-frames to the reader.
|
* This function can be used to transmit (raw) bit-frames to the reader.
|
||||||
*/
|
*/
|
||||||
bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxBits, const byte_t* pbtTxPar)
|
bool
|
||||||
|
nfc_target_send_bits (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -554,7 +573,8 @@ bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
||||||
*
|
*
|
||||||
* To communicate byte frames and APDU responses to the reader, this function could be used.
|
* To communicate byte frames and APDU responses to the reader, this function could be used.
|
||||||
*/
|
*/
|
||||||
bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
bool
|
||||||
|
nfc_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen)
|
||||||
{
|
{
|
||||||
pnd->iLastError = 0;
|
pnd->iLastError = 0;
|
||||||
|
|
||||||
|
@ -565,7 +585,8 @@ bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
* @brief Return the PCD error string
|
* @brief Return the PCD error string
|
||||||
* @return Returns a string
|
* @return Returns a string
|
||||||
*/
|
*/
|
||||||
const char *nfc_strerror (const nfc_device_t *pnd)
|
const char *
|
||||||
|
nfc_strerror (const nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
return pnd->pdc->pcc->strerror (pnd);
|
return pnd->pdc->pcc->strerror (pnd);
|
||||||
}
|
}
|
||||||
|
@ -574,7 +595,8 @@ const char *nfc_strerror (const nfc_device_t *pnd)
|
||||||
* @brief Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen chars
|
* @brief Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen chars
|
||||||
* @return Returns 0 upon success
|
* @return Returns 0 upon success
|
||||||
*/
|
*/
|
||||||
int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen)
|
int
|
||||||
|
nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen)
|
||||||
{
|
{
|
||||||
return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0;
|
return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
@ -582,7 +604,8 @@ int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen)
|
||||||
/**
|
/**
|
||||||
* @brief Display the PCD error a-la perror
|
* @brief Display the PCD error a-la perror
|
||||||
*/
|
*/
|
||||||
void nfc_perror (const nfc_device_t *pnd, const char *pcString)
|
void
|
||||||
|
nfc_perror (const nfc_device_t * pnd, const char *pcString)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd));
|
fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd));
|
||||||
}
|
}
|
||||||
|
@ -593,7 +616,8 @@ void nfc_perror (const nfc_device_t *pnd, const char *pcString)
|
||||||
* @brief Returns the device name
|
* @brief Returns the device name
|
||||||
* @return Returns a string with the device name
|
* @return Returns a string with the device name
|
||||||
*/
|
*/
|
||||||
const char* nfc_device_name(nfc_device_t* pnd)
|
const char *
|
||||||
|
nfc_device_name (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
return pnd->acName;
|
return pnd->acName;
|
||||||
}
|
}
|
||||||
|
@ -604,7 +628,8 @@ const char* nfc_device_name(nfc_device_t* pnd)
|
||||||
* @brief Returns the library version
|
* @brief Returns the library version
|
||||||
* @return Returns a string with the library version
|
* @return Returns a string with the library version
|
||||||
*/
|
*/
|
||||||
const char* nfc_version(void)
|
const char *
|
||||||
|
nfc_version (void)
|
||||||
{
|
{
|
||||||
#ifdef SVN_REVISION
|
#ifdef SVN_REVISION
|
||||||
return PACKAGE_VERSION " (r" SVN_REVISION ")";
|
return PACKAGE_VERSION " (r" SVN_REVISION ")";
|
||||||
|
|
Loading…
Reference in a new issue