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
|
@ -1,59 +1,61 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <nfc/nfc.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;
|
||||
|
||||
// Display libnfc version
|
||||
const char* acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
const char *acLibnfcVersion = nfc_version ();
|
||||
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
// Connect using the first available NFC device
|
||||
pnd = nfc_connect(NULL);
|
||||
pnd = nfc_connect (NULL);
|
||||
|
||||
if (pnd == NULL) {
|
||||
ERR("%s", "Unable to connect to NFC device.");
|
||||
return EXIT_FAILURE;
|
||||
ERR ("%s", "Unable to connect to NFC device.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Set connected NFC device to initiator mode
|
||||
nfc_initiator_init(pnd);
|
||||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
nfc_configure(pnd,NDO_INFINITE_SELECT,false);
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
nfc_configure(pnd,NDO_HANDLE_CRC,true);
|
||||
nfc_configure(pnd,NDO_HANDLE_PARITY,true);
|
||||
nfc_configure (pnd, NDO_HANDLE_CRC, true);
|
||||
nfc_configure (pnd, NDO_HANDLE_PARITY, true);
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, true);
|
||||
|
||||
printf("Connected to NFC reader: %s\n",pnd->acName);
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
||||
// Poll for a ISO14443A (MIFARE) tag
|
||||
if (nfc_initiator_select_passive_target(pnd,NM_ISO14443A_106,NULL,0,&nti)) {
|
||||
printf("The following (NFC) ISO14443A tag was found:\n");
|
||||
printf(" ATQA (SENS_RES): "); print_hex(nti.nai.abtAtqa,2);
|
||||
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) {
|
||||
printf(" ATS (ATR): ");
|
||||
print_hex(nti.nai.abtAts,nti.nai.szAtsLen);
|
||||
}
|
||||
if (nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
|
||||
printf ("The following (NFC) ISO14443A tag was found:\n");
|
||||
printf (" ATQA (SENS_RES): ");
|
||||
print_hex (nti.nai.abtAtqa, 2);
|
||||
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) {
|
||||
printf (" ATS (ATR): ");
|
||||
print_hex (nti.nai.abtAts, nti.nai.szAtsLen);
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect from NFC device
|
||||
nfc_disconnect(pnd);
|
||||
nfc_disconnect (pnd);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -17,70 +17,70 @@
|
|||
* 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.
|
||||
*/
|
||||
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];
|
||||
size_t szRxLen;
|
||||
size_t szParamLen;
|
||||
byte_t abtCmd[265];
|
||||
byte_t abtRx[265];
|
||||
size_t szRxLen;
|
||||
size_t szParamLen;
|
||||
byte_t abtCmd[265];
|
||||
|
||||
// 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[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
|
||||
abtCmd[0] = mc; // The MIFARE Classic command
|
||||
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
|
||||
|
||||
switch (mc)
|
||||
{
|
||||
switch (mc) {
|
||||
// Read and store command have no parameter
|
||||
case MC_READ:
|
||||
case MC_STORE:
|
||||
szParamLen = 0;
|
||||
case MC_READ:
|
||||
case MC_STORE:
|
||||
szParamLen = 0;
|
||||
break;
|
||||
|
||||
// Authenticate command
|
||||
case MC_AUTH_A:
|
||||
case MC_AUTH_B:
|
||||
szParamLen = sizeof(mifare_param_auth);
|
||||
case MC_AUTH_A:
|
||||
case MC_AUTH_B:
|
||||
szParamLen = sizeof (mifare_param_auth);
|
||||
break;
|
||||
|
||||
// Data command
|
||||
case MC_WRITE:
|
||||
szParamLen = sizeof(mifare_param_data);
|
||||
case MC_WRITE:
|
||||
szParamLen = sizeof (mifare_param_data);
|
||||
break;
|
||||
|
||||
// Value command
|
||||
case MC_DECREMENT:
|
||||
case MC_INCREMENT:
|
||||
case MC_TRANSFER:
|
||||
szParamLen = sizeof(mifare_param_value);
|
||||
case MC_DECREMENT:
|
||||
case MC_INCREMENT:
|
||||
case MC_TRANSFER:
|
||||
szParamLen = sizeof (mifare_param_value);
|
||||
break;
|
||||
|
||||
// Please fix your code, you never should reach this statement
|
||||
default:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// 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
|
||||
if (!nfc_initiator_transceive_bytes(pnd,abtCmd,2+szParamLen,abtRx,&szRxLen)) {
|
||||
if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRxLen)) {
|
||||
if (pnd->iLastError != 0x14)
|
||||
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
|
||||
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
// When we have executed a read command, copy the received bytes into the param
|
||||
if (mc == MC_READ) {
|
||||
if(szRxLen == 16) {
|
||||
memcpy(pmp->mpd.abtData,abtRx,16);
|
||||
if (szRxLen == 16) {
|
||||
memcpy (pmp->mpd.abtData, abtRx, 16);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Command succesfully executed
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -22,36 +22,36 @@
|
|||
*/
|
||||
|
||||
#ifndef _LIBNFC_MIFARE_H_
|
||||
#define _LIBNFC_MIFARE_H_
|
||||
# define _LIBNFC_MIFARE_H_
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
||||
#pragma pack(1)
|
||||
# pragma pack(1)
|
||||
|
||||
typedef enum {
|
||||
MC_AUTH_A = 0x60,
|
||||
MC_AUTH_B = 0x61,
|
||||
MC_READ = 0x30,
|
||||
MC_WRITE = 0xA0,
|
||||
MC_TRANSFER = 0xB0,
|
||||
MC_DECREMENT = 0xC0,
|
||||
MC_INCREMENT = 0xC1,
|
||||
MC_STORE = 0xC2
|
||||
MC_AUTH_A = 0x60,
|
||||
MC_AUTH_B = 0x61,
|
||||
MC_READ = 0x30,
|
||||
MC_WRITE = 0xA0,
|
||||
MC_TRANSFER = 0xB0,
|
||||
MC_DECREMENT = 0xC0,
|
||||
MC_INCREMENT = 0xC1,
|
||||
MC_STORE = 0xC2
|
||||
} mifare_cmd;
|
||||
|
||||
// MIFARE command params
|
||||
typedef struct {
|
||||
byte_t abtKey[6];
|
||||
byte_t abtUid[4];
|
||||
byte_t abtKey[6];
|
||||
byte_t abtUid[4];
|
||||
} mifare_param_auth;
|
||||
|
||||
typedef struct {
|
||||
byte_t abtData[16];
|
||||
byte_t abtData[16];
|
||||
} mifare_param_data;
|
||||
|
||||
typedef struct {
|
||||
byte_t abtValue[4];
|
||||
byte_t abtValue[4];
|
||||
} mifare_param_value;
|
||||
|
||||
typedef union {
|
||||
|
@ -61,30 +61,30 @@ typedef union {
|
|||
} mifare_param;
|
||||
|
||||
// Reset struct alignment to default
|
||||
#pragma pack()
|
||||
# pragma pack()
|
||||
|
||||
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);
|
||||
|
||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
||||
#pragma pack(1)
|
||||
# pragma pack(1)
|
||||
|
||||
// MIFARE Classic
|
||||
typedef struct {
|
||||
byte_t abtUID[4];
|
||||
byte_t btBCC;
|
||||
byte_t btUnknown;
|
||||
byte_t abtATQA[2];
|
||||
byte_t abtUnknown[8];
|
||||
byte_t abtUID[4];
|
||||
byte_t btBCC;
|
||||
byte_t btUnknown;
|
||||
byte_t abtATQA[2];
|
||||
byte_t abtUnknown[8];
|
||||
} mifare_classic_block_manufacturer;
|
||||
|
||||
typedef struct {
|
||||
byte_t abtData[16];
|
||||
byte_t abtData[16];
|
||||
} mifare_classic_block_data;
|
||||
|
||||
typedef struct {
|
||||
byte_t abtKeyA[6];
|
||||
byte_t abtAccessBits[4];
|
||||
byte_t abtKeyB[6];
|
||||
byte_t abtKeyA[6];
|
||||
byte_t abtAccessBits[4];
|
||||
byte_t abtKeyB[6];
|
||||
} mifare_classic_block_trailer;
|
||||
|
||||
typedef union {
|
||||
|
@ -99,17 +99,17 @@ typedef struct {
|
|||
|
||||
// MIFARE Ultralight
|
||||
typedef struct {
|
||||
byte_t sn0[3];
|
||||
byte_t btBCC0;
|
||||
byte_t sn1[4];
|
||||
byte_t btBCC1;
|
||||
byte_t internal;
|
||||
byte_t lock[2];
|
||||
byte_t otp[4];
|
||||
byte_t sn0[3];
|
||||
byte_t btBCC0;
|
||||
byte_t sn1[4];
|
||||
byte_t btBCC1;
|
||||
byte_t internal;
|
||||
byte_t lock[2];
|
||||
byte_t otp[4];
|
||||
} mifareul_block_manufacturer;
|
||||
|
||||
typedef struct {
|
||||
byte_t abtData[16];
|
||||
byte_t abtData[16];
|
||||
} mifareul_block_data;
|
||||
|
||||
typedef union {
|
||||
|
@ -122,6 +122,6 @@ typedef struct {
|
|||
} mifareul_tag;
|
||||
|
||||
// Reset struct alignment to default
|
||||
#pragma pack()
|
||||
# pragma pack()
|
||||
|
||||
#endif // _LIBNFC_MIFARE_H_
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -47,152 +47,143 @@ static size_t szRxBits;
|
|||
static size_t szRxLen;
|
||||
static byte_t abtUid[10];
|
||||
static size_t szUidLen = 4;
|
||||
static nfc_device_t* pnd;
|
||||
static nfc_device_t *pnd;
|
||||
|
||||
bool quiet_output = false;
|
||||
bool quiet_output = false;
|
||||
|
||||
// ISO14443A Anti-Collision Commands
|
||||
byte_t abtReqa [1] = { 0x26 };
|
||||
byte_t abtSelectAll [2] = { 0x93,0x20 };
|
||||
byte_t abtSelectTag [9] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
byte_t abtRats [4] = { 0xe0,0x50,0xbc,0xa5 };
|
||||
byte_t abtHalt [4] = { 0x50,0x00,0x57,0xcd };
|
||||
byte_t abtReqa[1] = { 0x26 };
|
||||
byte_t abtSelectAll[2] = { 0x93, 0x20 };
|
||||
byte_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
byte_t abtRats[4] = { 0xe0, 0x50, 0xbc, 0xa5 };
|
||||
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
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("R: ");
|
||||
print_hex_bits(pbtTx,szTxBits);
|
||||
if (!quiet_output) {
|
||||
printf ("R: ");
|
||||
print_hex_bits (pbtTx, szTxBits);
|
||||
}
|
||||
|
||||
// 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
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("T: ");
|
||||
print_hex_bits(abtRx,szRxBits);
|
||||
if (!quiet_output) {
|
||||
printf ("T: ");
|
||||
print_hex_bits (abtRx, szRxBits);
|
||||
}
|
||||
|
||||
// Succesful transfer
|
||||
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
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("R: ");
|
||||
print_hex(pbtTx,szTxLen);
|
||||
if (!quiet_output) {
|
||||
printf ("R: ");
|
||||
print_hex (pbtTx, szTxLen);
|
||||
}
|
||||
|
||||
// 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
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("T: ");
|
||||
print_hex(abtRx,szRxLen);
|
||||
if (!quiet_output) {
|
||||
printf ("T: ");
|
||||
print_hex (abtRx, szRxLen);
|
||||
}
|
||||
|
||||
// Succesful transfer
|
||||
return true;
|
||||
}
|
||||
|
||||
static void print_usage(char* argv[])
|
||||
static void
|
||||
print_usage (char *argv[])
|
||||
{
|
||||
printf("Usage: %s [OPTIONS]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf("\t-h\tHelp. Print this message.\n");
|
||||
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
||||
printf ("Usage: %s [OPTIONS]\n", argv[0]);
|
||||
printf ("Options:\n");
|
||||
printf ("\t-h\tHelp. Print this message.\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;
|
||||
|
||||
// Get commandline options
|
||||
for (arg=1;arg<argc;arg++) {
|
||||
if (0 == strcmp(argv[arg], "-h")) {
|
||||
print_usage(argv);
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
if (0 == strcmp (argv[arg], "-h")) {
|
||||
print_usage (argv);
|
||||
return 0;
|
||||
} else if (0 == strcmp(argv[arg], "-q")) {
|
||||
INFO("%s", "Quiet mode.");
|
||||
} else if (0 == strcmp (argv[arg], "-q")) {
|
||||
INFO ("%s", "Quiet mode.");
|
||||
quiet_output = true;
|
||||
} else {
|
||||
ERR("%s is not supported option.", argv[arg]);
|
||||
print_usage(argv);
|
||||
ERR ("%s is not supported option.", argv[arg]);
|
||||
print_usage (argv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to open the NFC reader
|
||||
pnd = nfc_connect(NULL);
|
||||
pnd = nfc_connect (NULL);
|
||||
|
||||
if (!pnd)
|
||||
{
|
||||
printf("Error connecting NFC reader\n");
|
||||
if (!pnd) {
|
||||
printf ("Error connecting NFC reader\n");
|
||||
return 1;
|
||||
}
|
||||
nfc_initiator_init(pnd);
|
||||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,false)) {
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,false)) {
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure parity settings
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 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");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!nfc_configure(pnd, NDO_EASY_FRAMING, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_EASY_FRAMING, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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)
|
||||
if (!transmit_bits(abtReqa,7))
|
||||
{
|
||||
printf("Error: No tag available\n");
|
||||
nfc_disconnect(pnd);
|
||||
if (!transmit_bits (abtReqa, 7)) {
|
||||
printf ("Error: No tag available\n");
|
||||
nfc_disconnect (pnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Anti-collision
|
||||
transmit_bytes(abtSelectAll,2);
|
||||
transmit_bytes (abtSelectAll, 2);
|
||||
|
||||
// Save the UID
|
||||
memcpy(abtUid,abtRx,4);
|
||||
memcpy(abtSelectTag+2,abtRx,5);
|
||||
append_iso14443a_crc(abtSelectTag,7);
|
||||
transmit_bytes(abtSelectTag,9);
|
||||
memcpy (abtUid, abtRx, 4);
|
||||
memcpy (abtSelectTag + 2, abtRx, 5);
|
||||
append_iso14443a_crc (abtSelectTag, 7);
|
||||
transmit_bytes (abtSelectTag, 9);
|
||||
|
||||
// Test if we are dealing with a 4 bytes uid
|
||||
if (abtUid[0]!= 0x88)
|
||||
{
|
||||
if (abtUid[0] != 0x88) {
|
||||
szUidLen = 4;
|
||||
} else {
|
||||
// We have to do the anti-collision for cascade level 2
|
||||
|
@ -200,28 +191,29 @@ int main(int argc,char* argv[])
|
|||
abtSelectTag[0] = 0x95;
|
||||
|
||||
// Anti-collision
|
||||
transmit_bytes(abtSelectAll,2);
|
||||
transmit_bytes (abtSelectAll, 2);
|
||||
|
||||
// Save the UID
|
||||
memcpy(abtUid+4,abtRx,4);
|
||||
memcpy(abtSelectTag+2,abtRx,5);
|
||||
append_iso14443a_crc(abtSelectTag,7);
|
||||
transmit_bytes(abtSelectTag,9);
|
||||
memcpy (abtUid + 4, abtRx, 4);
|
||||
memcpy (abtSelectTag + 2, abtRx, 5);
|
||||
append_iso14443a_crc (abtSelectTag, 7);
|
||||
transmit_bytes (abtSelectTag, 9);
|
||||
szUidLen = 7;
|
||||
}
|
||||
|
||||
// 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
|
||||
transmit_bytes(abtHalt,4);
|
||||
transmit_bytes (abtHalt, 4);
|
||||
|
||||
printf("\nFound tag with UID: ");
|
||||
printf ("\nFound tag with UID: ");
|
||||
if (szUidLen == 7) {
|
||||
printf("%02x%02x%02x", abtUid[6], abtUid[5], abtUid[4]);
|
||||
printf ("%02x%02x%02x", abtUid[6], abtUid[5], abtUid[4]);
|
||||
}
|
||||
printf("%02x%02x%02x%02x\n", abtUid[3], abtUid[2], abtUid[1], abtUid[0]);
|
||||
printf ("%02x%02x%02x%02x\n", abtUid[3], abtUid[2], abtUid[1], abtUid[0]);
|
||||
|
||||
nfc_disconnect(pnd);
|
||||
nfc_disconnect (pnd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -41,138 +41,132 @@
|
|||
|
||||
static byte_t abtRecv[MAX_FRAME_LEN];
|
||||
static size_t szRecvBits;
|
||||
static nfc_device_t* pnd;
|
||||
static nfc_device_t *pnd;
|
||||
|
||||
// ISO14443A Anti-Collision response
|
||||
byte_t abtAtqa [2] = { 0x04,0x00 };
|
||||
byte_t abtUidBcc [5] = { 0xDE,0xAD,0xBE,0xAF,0x62 };
|
||||
byte_t abtSak [9] = { 0x08,0xb6,0xdd };
|
||||
byte_t abtAtqa[2] = { 0x04, 0x00 };
|
||||
byte_t abtUidBcc[5] = { 0xDE, 0xAD, 0xBE, 0xAF, 0x62 };
|
||||
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("Options:\n");
|
||||
printf("\t-h\tHelp. Print this message.\n");
|
||||
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
||||
printf("\n");
|
||||
printf("\t[UID]\tUID to emulate, specified as 8 HEX digits (default is DEADBEAF).\n");
|
||||
printf ("Usage: %s [OPTIONS] [UID]\n", argv[0]);
|
||||
printf ("Options:\n");
|
||||
printf ("\t-h\tHelp. Print this message.\n");
|
||||
printf ("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
||||
printf ("\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;
|
||||
size_t szTxBits;
|
||||
bool quiet_output = false;
|
||||
byte_t *pbtTx = NULL;
|
||||
size_t szTxBits;
|
||||
bool quiet_output = false;
|
||||
|
||||
int arg, i;
|
||||
int arg,
|
||||
i;
|
||||
|
||||
// Get commandline options
|
||||
for (arg=1;arg<argc;arg++) {
|
||||
if (0 == strcmp(argv[arg], "-h")) {
|
||||
print_usage(argv);
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
if (0 == strcmp (argv[arg], "-h")) {
|
||||
print_usage (argv);
|
||||
return 0;
|
||||
} else if (0 == strcmp(argv[arg], "-q")) {
|
||||
INFO("%s", "Quiet mode.");
|
||||
} else if (0 == strcmp (argv[arg], "-q")) {
|
||||
INFO ("%s", "Quiet mode.");
|
||||
quiet_output = true;
|
||||
} else if((arg == argc-1) && (strlen(argv[arg]) == 8)) { // See if UID was specified as HEX string
|
||||
byte_t abtTmp[3] = { 0x00,0x00,0x00 };
|
||||
printf("[+] Using UID: %s\n",argv[arg]);
|
||||
abtUidBcc[4]= 0x00;
|
||||
for(i= 0; i < 4; ++i)
|
||||
{
|
||||
memcpy(abtTmp,argv[arg]+i*2,2);
|
||||
abtUidBcc[i]= (byte_t) strtol((char*)abtTmp,NULL,16);
|
||||
} else if ((arg == argc - 1) && (strlen (argv[arg]) == 8)) { // See if UID was specified as HEX string
|
||||
byte_t abtTmp[3] = { 0x00, 0x00, 0x00 };
|
||||
printf ("[+] Using UID: %s\n", argv[arg]);
|
||||
abtUidBcc[4] = 0x00;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
memcpy (abtTmp, argv[arg] + i * 2, 2);
|
||||
abtUidBcc[i] = (byte_t) strtol ((char *) abtTmp, NULL, 16);
|
||||
abtUidBcc[4] ^= abtUidBcc[i];
|
||||
}
|
||||
} else {
|
||||
ERR("%s is not supported option.", argv[arg]);
|
||||
print_usage(argv);
|
||||
ERR ("%s is not supported option.", argv[arg]);
|
||||
print_usage (argv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to open the NFC reader
|
||||
pnd = nfc_connect(NULL);
|
||||
pnd = nfc_connect (NULL);
|
||||
|
||||
if (pnd == NULL)
|
||||
{
|
||||
printf("Error connecting NFC reader\n");
|
||||
if (pnd == NULL) {
|
||||
printf ("Error connecting NFC reader\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("[+] Connected to NFC reader: %s\n",pnd->acName);
|
||||
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("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
if (!nfc_target_init(pnd,abtRecv,&szRecvBits))
|
||||
{
|
||||
printf("Error: Could not come out of auto-emulation, no command was received\n");
|
||||
printf ("\n");
|
||||
printf ("[+] Connected to NFC reader: %s\n", pnd->acName);
|
||||
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 ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
if (!nfc_target_init (pnd, abtRecv, &szRecvBits)) {
|
||||
printf ("Error: Could not come out of auto-emulation, no command was received\n");
|
||||
return 1;
|
||||
}
|
||||
printf("[+] Received initiator command: ");
|
||||
print_hex_bits(abtRecv,szRecvBits);
|
||||
printf("[+] Configuring communication\n");
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,false) || !nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
printf ("[+] Received initiator command: ");
|
||||
print_hex_bits (abtRecv, szRecvBits);
|
||||
printf ("[+] Configuring communication\n");
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, false) || !nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
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
|
||||
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
|
||||
switch(szRecvBits)
|
||||
{
|
||||
case 7: // Request or Wakeup
|
||||
pbtTx = abtAtqa;
|
||||
szTxBits = 16;
|
||||
// New anti-collsion session started
|
||||
if (!quiet_output) printf("\n");
|
||||
switch (szRecvBits) {
|
||||
case 7: // Request or Wakeup
|
||||
pbtTx = abtAtqa;
|
||||
szTxBits = 16;
|
||||
// New anti-collsion session started
|
||||
if (!quiet_output)
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case 16: // Select All
|
||||
pbtTx = abtUidBcc;
|
||||
szTxBits = 40;
|
||||
case 16: // Select All
|
||||
pbtTx = abtUidBcc;
|
||||
szTxBits = 40;
|
||||
break;
|
||||
|
||||
case 72: // Select Tag
|
||||
pbtTx = abtSak;
|
||||
szTxBits = 24;
|
||||
case 72: // Select Tag
|
||||
pbtTx = abtSak;
|
||||
szTxBits = 24;
|
||||
break;
|
||||
|
||||
default: // unknown length?
|
||||
szTxBits = 0;
|
||||
default: // unknown length?
|
||||
szTxBits = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("R: ");
|
||||
print_hex_bits(abtRecv,szRecvBits);
|
||||
if (!quiet_output) {
|
||||
printf ("R: ");
|
||||
print_hex_bits (abtRecv, szRecvBits);
|
||||
}
|
||||
|
||||
// Test if we know how to respond
|
||||
if(szTxBits)
|
||||
{
|
||||
if (szTxBits) {
|
||||
// Send and print the command to the screen
|
||||
if (!nfc_target_send_bits(pnd,pbtTx,szTxBits,NULL)) {
|
||||
nfc_perror(pnd, "nfc_target_send_bits");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_target_send_bits (pnd, pbtTx, szTxBits, NULL)) {
|
||||
nfc_perror (pnd, "nfc_target_send_bits");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("T: ");
|
||||
print_hex_bits(pbtTx,szTxBits);
|
||||
if (!quiet_output) {
|
||||
printf ("T: ");
|
||||
print_hex_bits (pbtTx, szTxBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nfc_disconnect(pnd);
|
||||
exit(EXIT_SUCCESS);
|
||||
nfc_disconnect (pnd);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#ifdef DEBUG
|
||||
#include <sys/param.h>
|
||||
#include <usb.h>
|
||||
#endif
|
||||
# ifdef DEBUG
|
||||
# include <sys/param.h>
|
||||
# include <usb.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <err.h>
|
||||
|
@ -46,35 +46,35 @@
|
|||
#define MAX_DEVICE_COUNT 16
|
||||
#define MAX_TARGET_COUNT 16
|
||||
|
||||
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;
|
||||
size_t szDeviceFound;
|
||||
size_t szTargetFound;
|
||||
size_t i;
|
||||
const char *acLibnfcVersion;
|
||||
size_t szDeviceFound;
|
||||
size_t szTargetFound;
|
||||
size_t i;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
|
||||
// Display libnfc version
|
||||
acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
pnddDevices = parse_device_desc(argc, argv, &szDeviceFound);
|
||||
// Display libnfc version
|
||||
acLibnfcVersion = nfc_version ();
|
||||
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
pnddDevices = parse_device_desc (argc, argv, &szDeviceFound);
|
||||
|
||||
if (argc > 1 && szDeviceFound == 0) {
|
||||
errx (1, "usage: %s [--device driver:port:speed]", argv[0]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#ifdef DEBUG
|
||||
usb_set_debug(4);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
# ifdef DEBUG
|
||||
usb_set_debug (4);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Lazy way to open an NFC device */
|
||||
#if 0
|
||||
pnd = nfc_connect(NULL);
|
||||
pnd = nfc_connect (NULL);
|
||||
#endif
|
||||
|
||||
/* If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 */
|
||||
|
@ -84,13 +84,11 @@ int main(int argc, const char* argv[])
|
|||
ndd.pcPort = "/dev/ttyUSB0";
|
||||
ndd.uiSpeed = 115200;
|
||||
|
||||
pnd = nfc_connect(&ndd);
|
||||
pnd = nfc_connect (&ndd);
|
||||
#endif
|
||||
|
||||
if (szDeviceFound == 0)
|
||||
{
|
||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices))))
|
||||
{
|
||||
if (szDeviceFound == 0) {
|
||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
||||
fprintf (stderr, "malloc() failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -98,94 +96,88 @@ int main(int argc, const char* argv[])
|
|||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szDeviceFound);
|
||||
}
|
||||
|
||||
if (szDeviceFound == 0)
|
||||
{
|
||||
INFO("%s", "No device found.");
|
||||
if (szDeviceFound == 0) {
|
||||
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];
|
||||
pnd = nfc_connect(&(pnddDevices[i]));
|
||||
pnd = nfc_connect (&(pnddDevices[i]));
|
||||
|
||||
|
||||
if (pnd == NULL)
|
||||
{
|
||||
ERR("%s", "Unable to connect to NFC device.");
|
||||
if (pnd == NULL) {
|
||||
ERR ("%s", "Unable to connect to NFC device.");
|
||||
return 1;
|
||||
}
|
||||
nfc_initiator_init(pnd);
|
||||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
if (!nfc_configure(pnd,NDO_INFINITE_SELECT,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!nfc_configure(pnd, NDO_AUTO_ISO14443_4, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_AUTO_ISO14443_4, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Connected to NFC reader: %s\n",pnd->acName);
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
||||
// List ISO14443A targets
|
||||
if (nfc_initiator_list_passive_targets(pnd, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &szTargetFound )) {
|
||||
size_t n;
|
||||
printf("%d ISO14443A passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
||||
for(n=0; n<szTargetFound; n++) {
|
||||
if (nfc_initiator_list_passive_targets (pnd, NM_ISO14443A_106, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||
size_t n;
|
||||
printf ("%d ISO14443A passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
||||
for (n = 0; n < szTargetFound; n++) {
|
||||
print_nfc_iso14443a_info (anti[n].nai);
|
||||
printf("\n");
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// List Felica tags
|
||||
if (nfc_initiator_list_passive_targets(pnd, NM_FELICA_212, anti, MAX_TARGET_COUNT, &szTargetFound )) {
|
||||
size_t n;
|
||||
printf("%d Felica (212 kbps) passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
||||
for(n=0; n<szTargetFound; n++) {
|
||||
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_212, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||
size_t n;
|
||||
printf ("%d Felica (212 kbps) passive target(s) was found%s\n", (int) szTargetFound,
|
||||
(szTargetFound == 0) ? ".\n" : ":");
|
||||
for (n = 0; n < szTargetFound; n++) {
|
||||
print_nfc_felica_info (anti[n].nfi);
|
||||
printf("\n");
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
if (nfc_initiator_list_passive_targets(pnd, NM_FELICA_424, anti, MAX_TARGET_COUNT, &szTargetFound )) {
|
||||
size_t n;
|
||||
printf("%d Felica (424 kbps) passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
||||
for(n=0; n<szTargetFound; n++) {
|
||||
if (nfc_initiator_list_passive_targets (pnd, NM_FELICA_424, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||
size_t n;
|
||||
printf ("%d Felica (424 kbps) passive target(s) was found%s\n", (int) szTargetFound,
|
||||
(szTargetFound == 0) ? ".\n" : ":");
|
||||
for (n = 0; n < szTargetFound; n++) {
|
||||
print_nfc_felica_info (anti[n].nfi);
|
||||
printf("\n");
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// List ISO14443B targets
|
||||
if (nfc_initiator_list_passive_targets(pnd, NM_ISO14443B_106, anti, MAX_TARGET_COUNT, &szTargetFound )) {
|
||||
size_t n;
|
||||
printf("%d ISO14443B passive target(s) was found%s\n", (int)szTargetFound, (szTargetFound==0)?".\n":":");
|
||||
for(n=0; n<szTargetFound; n++) {
|
||||
if (nfc_initiator_list_passive_targets (pnd, NM_ISO14443B_106, anti, MAX_TARGET_COUNT, &szTargetFound)) {
|
||||
size_t n;
|
||||
printf ("%d ISO14443B passive target(s) was found%s\n", (int) szTargetFound, (szTargetFound == 0) ? ".\n" : ":");
|
||||
for (n = 0; n < szTargetFound; n++) {
|
||||
print_nfc_iso14443b_info (anti[n].nbi);
|
||||
printf("\n");
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,8 +191,8 @@ int main(int argc, const char* argv[])
|
|||
}
|
||||
}
|
||||
*/
|
||||
nfc_disconnect(pnd);
|
||||
}
|
||||
nfc_disconnect (pnd);
|
||||
}
|
||||
|
||||
free (pnddDevices);
|
||||
return 0;
|
||||
|
|
|
@ -69,7 +69,7 @@ print_success_or_failure (bool bFailure, uint32_t * uiBlockCounter)
|
|||
*uiBlockCounter += (*uiBlockCounter < 128) ? 4 : 16;
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
is_first_block (uint32_t uiBlock)
|
||||
{
|
||||
// Test if we are in the small or big sectors
|
||||
|
@ -79,7 +79,7 @@ is_first_block (uint32_t uiBlock)
|
|||
return ((uiBlock) % 16 == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
is_trailer_block (uint32_t uiBlock)
|
||||
{
|
||||
// Test if we are in the small or big sectors
|
||||
|
@ -89,7 +89,7 @@ is_trailer_block (uint32_t uiBlock)
|
|||
return ((uiBlock + 1) % 16 == 0);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
static uint32_t
|
||||
get_trailer_block (uint32_t uiFirstBlock)
|
||||
{
|
||||
// Test if we are in the small or big sectors
|
||||
|
@ -102,12 +102,12 @@ get_trailer_block (uint32_t uiFirstBlock)
|
|||
return trailer_block;
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
authenticate (uint32_t uiBlock)
|
||||
{
|
||||
mifare_cmd mc;
|
||||
uint32_t uiTrailerBlock;
|
||||
size_t key_index;
|
||||
size_t key_index;
|
||||
|
||||
// Key file authentication.
|
||||
if (bUseKeyFile) {
|
||||
|
@ -156,11 +156,11 @@ authenticate (uint32_t uiBlock)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
read_card (void)
|
||||
{
|
||||
int32_t iBlock;
|
||||
bool bFailure = false;
|
||||
bool bFailure = false;
|
||||
uint32_t uiReadBlocks = 0;
|
||||
|
||||
printf ("Reading out %d blocks |", uiBlocks + 1);
|
||||
|
@ -197,7 +197,7 @@ read_card (void)
|
|||
memcpy (mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpd.abtData + 6, 4);
|
||||
memcpy (mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, 6);
|
||||
} else {
|
||||
printf("!\nError: unable to read trailer block 0x%02x\n", iBlock);
|
||||
printf ("!\nError: unable to read trailer block 0x%02x\n", iBlock);
|
||||
}
|
||||
} else {
|
||||
// Make sure a earlier readout did not fail
|
||||
|
@ -207,7 +207,7 @@ read_card (void)
|
|||
memcpy (mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16);
|
||||
} else {
|
||||
bFailure = true;
|
||||
printf("!\nError: unable to read block 0x%02x\n", iBlock);
|
||||
printf ("!\nError: unable to read block 0x%02x\n", iBlock);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -221,11 +221,11 @@ read_card (void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
write_card (void)
|
||||
{
|
||||
uint32_t uiBlock;
|
||||
bool bFailure = false;
|
||||
bool bFailure = false;
|
||||
uint32_t uiWriteBlocks = 0;
|
||||
|
||||
printf ("Writing %d blocks |", uiBlocks + 1);
|
||||
|
@ -295,8 +295,8 @@ mifare_classic_extract_payload (const char *abDump, char *pbPayload)
|
|||
{
|
||||
uint8_t uiSectorIndex;
|
||||
uint8_t uiBlockIndex;
|
||||
size_t szDumpOffset;
|
||||
size_t szPayloadIndex = 0;
|
||||
size_t szDumpOffset;
|
||||
size_t szPayloadIndex = 0;
|
||||
|
||||
for (uiSectorIndex = 1; uiSectorIndex < 16; uiSectorIndex++) {
|
||||
for (uiBlockIndex = 0; uiBlockIndex < 3; uiBlockIndex++) {
|
||||
|
@ -308,8 +308,7 @@ mifare_classic_extract_payload (const char *abDump, char *pbPayload)
|
|||
}
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
ACTION_READ,
|
||||
ACTION_WRITE,
|
||||
ACTION_EXTRACT,
|
||||
|
@ -335,11 +334,11 @@ print_usage (const char *pcProgramName)
|
|||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
bool b4K;
|
||||
bool b4K;
|
||||
action_t atAction = ACTION_USAGE;
|
||||
byte_t *pbtUID;
|
||||
FILE *pfKeys = NULL;
|
||||
FILE *pfDump = NULL;
|
||||
FILE *pfKeys = NULL;
|
||||
FILE *pfDump = NULL;
|
||||
const char *command = argv[1];
|
||||
|
||||
if (argc < 2) {
|
||||
|
@ -415,32 +414,29 @@ main (int argc, const char *argv[])
|
|||
|
||||
// Drop the field for a while
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
||||
|
@ -499,11 +495,11 @@ main (int argc, const char *argv[])
|
|||
const char *pcDump = argv[2];
|
||||
const char *pcPayload = argv[3];
|
||||
|
||||
FILE *pfDump = NULL;
|
||||
FILE *pfPayload = NULL;
|
||||
FILE *pfDump = NULL;
|
||||
FILE *pfPayload = NULL;
|
||||
|
||||
char abDump[4096];
|
||||
char abPayload[4096];
|
||||
char abDump[4096];
|
||||
char abPayload[4096];
|
||||
|
||||
pfDump = fopen (pcDump, "rb");
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@ print_success_or_failure (bool bFailure, uint32_t * uiCounter)
|
|||
*uiCounter += (bFailure) ? 0 : 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
read_card (void)
|
||||
{
|
||||
uint32_t page;
|
||||
bool bFailure = false;
|
||||
bool bFailure = false;
|
||||
uint32_t uiReadedPages = 0;
|
||||
|
||||
printf ("Reading %d pages |", uiBlocks + 1);
|
||||
|
@ -85,16 +85,16 @@ read_card (void)
|
|||
return (!bFailure);
|
||||
}
|
||||
|
||||
static bool
|
||||
static bool
|
||||
write_card (void)
|
||||
{
|
||||
uint32_t uiBlock = 0;
|
||||
int page = 0x4;
|
||||
bool bFailure = false;
|
||||
int page = 0x4;
|
||||
bool bFailure = false;
|
||||
uint32_t uiWritenPages = 0;
|
||||
|
||||
char buffer[BUFSIZ];
|
||||
bool write_otp;
|
||||
char buffer[BUFSIZ];
|
||||
bool write_otp;
|
||||
|
||||
printf ("Write OTP bytes ? [yN] ");
|
||||
fgets (buffer, BUFSIZ, stdin);
|
||||
|
@ -104,11 +104,11 @@ write_card (void)
|
|||
printf ("Writing %d pages |", uiBlocks + 1);
|
||||
printf ("sss");
|
||||
|
||||
if(write_otp) {
|
||||
if (write_otp) {
|
||||
page = 0x3;
|
||||
} else {
|
||||
/* If user don't want to write OTP, we skip 1 page more. */
|
||||
printf("s");
|
||||
printf ("s");
|
||||
page = 0x4;
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,6 @@ write_card (void)
|
|||
}
|
||||
bFailure = false;
|
||||
}
|
||||
|
||||
// For the Mifare Ultralight, this write command can be used
|
||||
// in compatibility mode, which only actually writes the first
|
||||
// page (4 bytes). The Ultralight-specific Write command only
|
||||
|
@ -130,12 +129,13 @@ write_card (void)
|
|||
uiBlock = page / 4;
|
||||
memcpy (mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
|
||||
if (!nfc_initiator_mifare_cmd (pnd, MC_WRITE, page, &mp))
|
||||
bFailure = true;
|
||||
bFailure = true;
|
||||
|
||||
print_success_or_failure (bFailure, &uiWritenPages);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -143,9 +143,9 @@ write_card (void)
|
|||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
bool bReadAction;
|
||||
bool bReadAction;
|
||||
byte_t *pbtUID;
|
||||
FILE *pfDump;
|
||||
FILE *pfDump;
|
||||
|
||||
if (argc < 3) {
|
||||
printf ("\n");
|
||||
|
@ -191,28 +191,26 @@ main (int argc, const char *argv[])
|
|||
|
||||
// Drop the field for a while
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
@ -230,7 +228,6 @@ main (int argc, const char *argv[])
|
|||
nfc_disconnect (pnd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Get the info from the current tag (UID is stored little-endian)
|
||||
pbtUID = nti.nai.abtUid;
|
||||
printf ("Found MIFARE Ultralight card with UID: %02x%02x%02x%02x\n", pbtUID[3], pbtUID[2], pbtUID[1], pbtUID[0]);
|
||||
|
|
|
@ -44,8 +44,8 @@ static nfc_device_t *pnd;
|
|||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
size_t szFound;
|
||||
size_t i;
|
||||
size_t szFound;
|
||||
size_t i;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
|
||||
// Display libnfc version
|
||||
|
@ -76,8 +76,8 @@ main (int argc, const char *argv[])
|
|||
const size_t szTargetTypes = 1;
|
||||
|
||||
nfc_target_t antTargets[2];
|
||||
size_t szTargetFound;
|
||||
bool res;
|
||||
size_t szTargetFound;
|
||||
bool res;
|
||||
|
||||
pnd = nfc_connect (&(pnddDevices[i]));
|
||||
|
||||
|
@ -89,30 +89,27 @@ main (int argc, const char *argv[])
|
|||
|
||||
// Drop the field for a while
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -46,55 +46,58 @@ static size_t szReaderRxBits;
|
|||
static byte_t abtTagRx[MAX_FRAME_LEN];
|
||||
static byte_t abtTagRxPar[MAX_FRAME_LEN];
|
||||
static size_t szTagRxBits;
|
||||
static nfc_device_t* pndReader;
|
||||
static nfc_device_t* pndTag;
|
||||
static bool quitting=false;
|
||||
static nfc_device_t *pndReader;
|
||||
static nfc_device_t *pndTag;
|
||||
static bool quitting = false;
|
||||
|
||||
void intr_hdlr(void)
|
||||
void
|
||||
intr_hdlr (void)
|
||||
{
|
||||
printf("\nQuitting...\n");
|
||||
quitting=true;
|
||||
printf ("\nQuitting...\n");
|
||||
quitting = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void print_usage(char* argv[])
|
||||
void
|
||||
print_usage (char *argv[])
|
||||
{
|
||||
printf("Usage: %s [OPTIONS]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf("\t-h\tHelp. Print this message.\n");
|
||||
printf("\t-q\tQuiet mode. Suppress output of READER and EMULATOR data (improves timing).\n");
|
||||
printf ("Usage: %s [OPTIONS]\n", argv[0]);
|
||||
printf ("Options:\n");
|
||||
printf ("\t-h\tHelp. Print this message.\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;
|
||||
bool quiet_output = false;
|
||||
size_t szFound;
|
||||
int arg;
|
||||
bool quiet_output = false;
|
||||
size_t szFound;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
const char* acLibnfcVersion = nfc_version();
|
||||
const char *acLibnfcVersion = nfc_version ();
|
||||
|
||||
// Get commandline options
|
||||
for (arg=1;arg<argc;arg++) {
|
||||
if (0 == strcmp(argv[arg], "-h")) {
|
||||
print_usage(argv);
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
if (0 == strcmp (argv[arg], "-h")) {
|
||||
print_usage (argv);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (0 == strcmp(argv[arg], "-q")) {
|
||||
INFO("%s", "Quiet mode.");
|
||||
} else if (0 == strcmp (argv[arg], "-q")) {
|
||||
INFO ("%s", "Quiet mode.");
|
||||
quiet_output = true;
|
||||
} else {
|
||||
ERR("%s is not supported option.", argv[arg]);
|
||||
print_usage(argv);
|
||||
ERR ("%s is not supported option.", argv[arg]);
|
||||
print_usage (argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Display libnfc version
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
#ifdef WIN32
|
||||
signal(SIGINT, (void (__cdecl*)(int)) intr_hdlr);
|
||||
signal (SIGINT, (void (__cdecl *) (int)) intr_hdlr);
|
||||
#else
|
||||
signal(SIGINT, (void (*)()) intr_hdlr);
|
||||
signal (SIGINT, (void (*)()) intr_hdlr);
|
||||
#endif
|
||||
|
||||
// Allocate memory to put the result of available devices listing
|
||||
|
@ -102,105 +105,93 @@ int main(int argc,char* argv[])
|
|||
fprintf (stderr, "malloc() failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// List available devices
|
||||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
||||
|
||||
if (szFound < 2) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
// Try to open the NFC emulator device
|
||||
pndTag = nfc_connect(&(pnddDevices[0]));
|
||||
if (pndTag == NULL)
|
||||
{
|
||||
printf("Error connecting NFC emulator device\n");
|
||||
pndTag = nfc_connect (&(pnddDevices[0]));
|
||||
if (pndTag == NULL) {
|
||||
printf ("Error connecting NFC emulator device\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Hint: tag <---> emulator (relay) <---> reader (relay) <---> original reader\n\n");
|
||||
|
||||
printf("Connected to the NFC emulator device: %s\n", pndTag->acName);
|
||||
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("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
if (!nfc_target_init(pndTag,abtReaderRx,&szReaderRxBits))
|
||||
{
|
||||
ERR("%s", "Initialization of NFC emulator failed");
|
||||
nfc_disconnect(pndTag);
|
||||
|
||||
printf ("Hint: tag <---> emulator (relay) <---> reader (relay) <---> original reader\n\n");
|
||||
|
||||
printf ("Connected to the NFC emulator device: %s\n", pndTag->acName);
|
||||
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 ("[+] For example, send a RATS command or use the \"nfc-anticol\" tool\n");
|
||||
if (!nfc_target_init (pndTag, abtReaderRx, &szReaderRxBits)) {
|
||||
ERR ("%s", "Initialization of NFC emulator failed");
|
||||
nfc_disconnect (pndTag);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("%s", "Configuring emulator settings...");
|
||||
if (!nfc_configure(pndTag,NDO_HANDLE_CRC,false) ||
|
||||
!nfc_configure(pndTag,NDO_HANDLE_PARITY,false) ||
|
||||
!nfc_configure(pndTag,NDO_ACCEPT_INVALID_FRAMES,true)) {
|
||||
nfc_perror(pndTag, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
printf ("%s", "Configuring emulator settings...");
|
||||
if (!nfc_configure (pndTag, NDO_HANDLE_CRC, false) ||
|
||||
!nfc_configure (pndTag, NDO_HANDLE_PARITY, false) || !nfc_configure (pndTag, NDO_ACCEPT_INVALID_FRAMES, true)) {
|
||||
nfc_perror (pndTag, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
printf("%s", "Done, emulated tag is initialized");
|
||||
printf ("%s", "Done, emulated tag is initialized");
|
||||
|
||||
// Try to open the NFC reader
|
||||
pndReader = nfc_connect(&(pnddDevices[1]));
|
||||
|
||||
printf("Connected to the NFC reader device: %s", pndReader->acName);
|
||||
printf("%s", "Configuring NFC reader settings...");
|
||||
nfc_initiator_init(pndReader);
|
||||
if (!nfc_configure(pndReader,NDO_HANDLE_CRC,false) ||
|
||||
!nfc_configure(pndReader,NDO_HANDLE_PARITY,false) ||
|
||||
!nfc_configure(pndReader,NDO_ACCEPT_INVALID_FRAMES,true)) {
|
||||
nfc_perror(pndReader, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("%s", "Done, relaying frames now!");
|
||||
pndReader = nfc_connect (&(pnddDevices[1]));
|
||||
|
||||
while(!quitting)
|
||||
{
|
||||
printf ("Connected to the NFC reader device: %s", pndReader->acName);
|
||||
printf ("%s", "Configuring NFC reader settings...");
|
||||
nfc_initiator_init (pndReader);
|
||||
if (!nfc_configure (pndReader, NDO_HANDLE_CRC, false) ||
|
||||
!nfc_configure (pndReader, NDO_HANDLE_PARITY, false) ||
|
||||
!nfc_configure (pndReader, NDO_ACCEPT_INVALID_FRAMES, true)) {
|
||||
nfc_perror (pndReader, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
printf ("%s", "Done, relaying frames now!");
|
||||
|
||||
while (!quitting) {
|
||||
// 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
|
||||
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26)
|
||||
{
|
||||
if (szReaderRxBits == 7 && abtReaderRx[0] == 0x26) {
|
||||
// Drop down field for a very short time (original tag will reboot)
|
||||
if (!nfc_configure(pndReader,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror(pndReader, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror (pndReader, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if(!quiet_output)
|
||||
printf("\n");
|
||||
if (!nfc_configure(pndReader,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror(pndReader, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!quiet_output)
|
||||
printf ("\n");
|
||||
if (!nfc_configure (pndReader, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror (pndReader, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the reader frame to the screen
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("R: ");
|
||||
print_hex_par(abtReaderRx,szReaderRxBits,abtReaderRxPar);
|
||||
if (!quiet_output) {
|
||||
printf ("R: ");
|
||||
print_hex_par (abtReaderRx, szReaderRxBits, abtReaderRxPar);
|
||||
}
|
||||
// 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
|
||||
if (!nfc_target_send_bits(pndTag,abtTagRx,szTagRxBits,abtTagRxPar)) {
|
||||
nfc_perror(pndTag, "nfc_target_send_bits");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_target_send_bits (pndTag, abtTagRx, szTagRxBits, abtTagRxPar)) {
|
||||
nfc_perror (pndTag, "nfc_target_send_bits");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Print the tag frame to the screen
|
||||
if(!quiet_output)
|
||||
{
|
||||
printf("T: ");
|
||||
print_hex_par(abtTagRx,szTagRxBits,abtTagRxPar);
|
||||
if (!quiet_output) {
|
||||
printf ("T: ");
|
||||
print_hex_par (abtTagRx, szTagRxBits, abtTagRxPar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nfc_disconnect(pndTag);
|
||||
nfc_disconnect(pndReader);
|
||||
exit(EXIT_SUCCESS);
|
||||
nfc_disconnect (pndTag);
|
||||
nfc_disconnect (pndReader);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
* @file nfc-sam.c
|
||||
* @brief Configure the reader to comunicate with a SAM (Secure Access Module).
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -32,14 +32,14 @@
|
|||
|
||||
#ifndef _WIN32
|
||||
// Needed by sleep() under Unix
|
||||
#include <unistd.h>
|
||||
#define sleep sleep
|
||||
#define SUSP_TIME 1 // secs.
|
||||
# include <unistd.h>
|
||||
# define sleep sleep
|
||||
# define SUSP_TIME 1 // secs.
|
||||
#else
|
||||
// Needed by Sleep() under Windows
|
||||
#include <winbase.h>
|
||||
#define sleep Sleep
|
||||
#define SUSP_TIME 1000 // msecs.
|
||||
# include <winbase.h>
|
||||
# define sleep Sleep
|
||||
# define SUSP_TIME 1000 // msecs.
|
||||
#endif
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
@ -49,183 +49,178 @@
|
|||
#include "chips/pn53x.h"
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
#define TIMEOUT 60 // secs.
|
||||
#define TIMEOUT 60 // secs.
|
||||
|
||||
#define NORMAL_MODE 1
|
||||
#define VIRTUAL_CARD_MODE 2
|
||||
#define WIRED_CARD_MODE 3
|
||||
#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 };
|
||||
size_t szCmd = 0;
|
||||
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
byte_t pncmd_sam_config[] = { 0xD4, 0x14, 0x00, 0x00 };
|
||||
size_t szCmd = 0;
|
||||
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
pncmd_sam_config[2] = mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case VIRTUAL_CARD_MODE:
|
||||
|
||||
switch (mode) {
|
||||
case VIRTUAL_CARD_MODE:
|
||||
{
|
||||
// Only the VIRTUAL_CARD_MODE requires 4 bytes.
|
||||
szCmd = sizeof(pncmd_sam_config);
|
||||
szCmd = sizeof (pncmd_sam_config);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
{
|
||||
szCmd = sizeof(pncmd_sam_config)-1;
|
||||
szCmd = sizeof (pncmd_sam_config) - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Direct call
|
||||
if (!pn53x_transceive(pnd,pncmd_sam_config,szCmd,abtRx,&szRxLen)) {
|
||||
ERR("%s %d", "Unable to execute SAMConfiguration command with mode byte:", mode);
|
||||
if (!pn53x_transceive (pnd, pncmd_sam_config, szCmd, abtRx, &szRxLen)) {
|
||||
ERR ("%s %d", "Unable to execute SAMConfiguration command with mode byte:", mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wait_one_minute()
|
||||
void
|
||||
wait_one_minute ()
|
||||
{
|
||||
int secs = 0;
|
||||
|
||||
printf("|");
|
||||
fflush(stdout);
|
||||
|
||||
while (secs < TIMEOUT)
|
||||
{
|
||||
sleep(SUSP_TIME);
|
||||
int secs = 0;
|
||||
|
||||
printf ("|");
|
||||
fflush (stdout);
|
||||
|
||||
while (secs < TIMEOUT) {
|
||||
sleep (SUSP_TIME);
|
||||
secs++;
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
printf (".");
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
// Display libnfc version
|
||||
const char* acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
const char *acLibnfcVersion = nfc_version ();
|
||||
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
// Connect using the first available NFC device
|
||||
pnd = nfc_connect(NULL);
|
||||
pnd = nfc_connect (NULL);
|
||||
|
||||
if (pnd == NULL) {
|
||||
ERR("%s", "Unable to connect to NFC device.");
|
||||
ERR ("%s", "Unable to connect to NFC device.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Connected to NFC reader: %s\n",pnd->acName);
|
||||
|
||||
printf ("Connected to NFC reader: %s\n", pnd->acName);
|
||||
|
||||
// Print the example's menu
|
||||
printf("\nSelect the comunication mode:\n");
|
||||
printf("[1] Virtual card mode.\n");
|
||||
printf("[2] Wired card mode.\n");
|
||||
printf("[3] Dual card mode.\n");
|
||||
printf(">> ");
|
||||
|
||||
printf ("\nSelect the comunication mode:\n");
|
||||
printf ("[1] Virtual card mode.\n");
|
||||
printf ("[2] Wired card mode.\n");
|
||||
printf ("[3] Dual card mode.\n");
|
||||
printf (">> ");
|
||||
|
||||
// Take user's choice
|
||||
char input = getchar();
|
||||
int mode = input-'0'+1;
|
||||
printf("\n");
|
||||
char input = getchar ();
|
||||
int mode = input - '0' + 1;
|
||||
printf ("\n");
|
||||
if (mode < VIRTUAL_CARD_MODE || mode > DUAL_CARD_MODE) {
|
||||
ERR("%s", "Invalid selection.");
|
||||
ERR ("%s", "Invalid selection.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Connect with the SAM
|
||||
sam_connection(pnd, mode);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case VIRTUAL_CARD_MODE:
|
||||
sam_connection (pnd, mode);
|
||||
|
||||
switch (mode) {
|
||||
case VIRTUAL_CARD_MODE:
|
||||
{
|
||||
// FIXME: after the loop the reader doesn't respond to host commands...
|
||||
printf("Now the SAM is readable for 1 minute from an external reader.\n");
|
||||
wait_one_minute();
|
||||
printf ("Now the SAM is readable for 1 minute from an external reader.\n");
|
||||
wait_one_minute ();
|
||||
}
|
||||
break;
|
||||
|
||||
case WIRED_CARD_MODE:
|
||||
|
||||
case WIRED_CARD_MODE:
|
||||
{
|
||||
nfc_target_info_t nti;
|
||||
|
||||
|
||||
// Set connected NFC device to initiator mode
|
||||
nfc_initiator_init(pnd);
|
||||
nfc_initiator_init (pnd);
|
||||
|
||||
// Drop the field for a while
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Let the reader only try once to find a tag
|
||||
if (!nfc_configure(pnd,NDO_INFINITE_SELECT,false)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Configure the CRC and Parity settings
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_CRC,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (!nfc_configure(pnd,NDO_HANDLE_PARITY,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Enable field so more power consuming cards can power themselves up
|
||||
if (!nfc_configure(pnd,NDO_ACTIVATE_FIELD,true)) {
|
||||
nfc_perror(pnd, "nfc_configure");
|
||||
exit(EXIT_FAILURE);
|
||||
if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
|
||||
nfc_perror (pnd, "nfc_configure");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Read the SAM's info
|
||||
if (!nfc_initiator_select_passive_target(pnd,NM_ISO14443A_106,NULL,0,&nti)) {
|
||||
ERR("%s", "Reading of SAM info failed.");
|
||||
if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
|
||||
ERR ("%s", "Reading of SAM info failed.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("The following ISO14443A tag (SAM) was found:\n\n");
|
||||
|
||||
printf ("The following ISO14443A tag (SAM) was found:\n\n");
|
||||
print_nfc_iso14443a_info (nti.nai);
|
||||
}
|
||||
break;
|
||||
|
||||
case DUAL_CARD_MODE:
|
||||
|
||||
case DUAL_CARD_MODE:
|
||||
{
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
// FIXME: it does not work as expected...Probably the issue is in "nfc_target_init"
|
||||
// which doesn't provide a way to set custom data for SENS_RES, NFCID1, SEL_RES, etc.
|
||||
if (!nfc_target_init(pnd,abtRx,&szRxLen))
|
||||
if (!nfc_target_init (pnd, abtRx, &szRxLen))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
printf("Now both the NFC reader and SAM are readable for 1 minute from an external reader.\n");
|
||||
wait_one_minute();
|
||||
printf ("Now both the NFC reader and SAM are readable for 1 minute from an external reader.\n");
|
||||
wait_one_minute ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Disconnect from the SAM
|
||||
sam_connection(pnd, NORMAL_MODE);
|
||||
sam_connection (pnd, NORMAL_MODE);
|
||||
|
||||
// Disconnect from NFC device
|
||||
nfc_disconnect(pnd);
|
||||
|
||||
nfc_disconnect (pnd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -21,152 +21,165 @@ static const byte_t OddParity[256] = {
|
|||
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];
|
||||
}
|
||||
|
||||
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
|
||||
for (szByteNr=0; szByteNr<szLen; szByteNr++)
|
||||
{
|
||||
for (szByteNr = 0; szByteNr < szLen; 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++)
|
||||
{
|
||||
printf("%02x ",pbtData[szPos]);
|
||||
for (szPos = 0; szPos < szBytes; 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;
|
||||
size_t szPos;
|
||||
size_t szBytes = szBits/8;
|
||||
size_t szPos;
|
||||
size_t szBytes = szBits / 8;
|
||||
|
||||
for (szPos=0; szPos < szBytes; szPos++)
|
||||
{
|
||||
printf("%02x ",pbtData[szPos]);
|
||||
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||
printf ("%02x ", pbtData[szPos]);
|
||||
}
|
||||
|
||||
uRemainder = szBits % 8;
|
||||
// Print the rest bits
|
||||
if (uRemainder != 0)
|
||||
{
|
||||
if (uRemainder != 0) {
|
||||
if (uRemainder < 5)
|
||||
printf("%01x (%d bits)",pbtData[szBytes], uRemainder);
|
||||
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
|
||||
else
|
||||
printf("%02x (%d bits)",pbtData[szBytes], uRemainder);
|
||||
printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
|
||||
}
|
||||
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;
|
||||
size_t szPos;
|
||||
size_t szBytes = szBits/8;
|
||||
size_t szPos;
|
||||
size_t szBytes = szBits / 8;
|
||||
|
||||
for (szPos=0; szPos < szBytes; szPos++)
|
||||
{
|
||||
printf("%02x",pbtData[szPos]);
|
||||
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos])
|
||||
{
|
||||
printf("! ");
|
||||
for (szPos = 0; szPos < szBytes; szPos++) {
|
||||
printf ("%02x", pbtData[szPos]);
|
||||
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos]) {
|
||||
printf ("! ");
|
||||
} else {
|
||||
printf(" ");
|
||||
printf (" ");
|
||||
}
|
||||
}
|
||||
|
||||
uRemainder = szBits % 8;
|
||||
// Print the rest bits, these cannot have parity bit
|
||||
if (uRemainder != 0)
|
||||
{
|
||||
if (uRemainder != 0) {
|
||||
if (uRemainder < 5)
|
||||
printf("%01x (%d bits)",pbtData[szBytes], uRemainder);
|
||||
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
|
||||
else
|
||||
printf("%02x (%d bits)",pbtData[szBytes], uRemainder);
|
||||
printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
|
||||
}
|
||||
printf("\n");
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
#define SAK_ISO14443_4_COMPLIANT 0x20
|
||||
#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(" UID (NFCID%c): ",(nai.abtUid[0]==0x08?'3':'1')); print_hex(nai.abtUid, nai.szUidLen);
|
||||
printf(" SAK (SEL_RES): "); print_hex(&nai.btSak,1);
|
||||
printf (" ATQA (SENS_RES): ");
|
||||
print_hex (nai.abtAtqa, 2);
|
||||
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) {
|
||||
printf(" ATS (ATR): ");
|
||||
print_hex(nai.abtAts, nai.szAtsLen);
|
||||
printf (" ATS (ATR): ");
|
||||
print_hex (nai.abtAts, nai.szAtsLen);
|
||||
}
|
||||
if ( (nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT) ) {
|
||||
printf(" Compliant with: ");
|
||||
if (nai.btSak & SAK_ISO14443_4_COMPLIANT) printf("ISO/IEC 14443-4 ");
|
||||
if (nai.btSak & SAK_ISO18092_COMPLIANT) printf("ISO/IEC 18092");
|
||||
printf("\n");
|
||||
if ((nai.btSak & SAK_ISO14443_4_COMPLIANT) || (nai.btSak & SAK_ISO18092_COMPLIANT)) {
|
||||
printf (" Compliant with: ");
|
||||
if (nai.btSak & SAK_ISO14443_4_COMPLIANT)
|
||||
printf ("ISO/IEC 14443-4 ");
|
||||
if (nai.btSak & SAK_ISO18092_COMPLIANT)
|
||||
printf ("ISO/IEC 18092");
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
void print_nfc_felica_info(const nfc_felica_info_t nfi)
|
||||
{
|
||||
printf(" ID (NFCID2): "); 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_felica_info (const nfc_felica_info_t nfi)
|
||||
{
|
||||
printf(" ATQB: "); print_hex(nbi.abtAtqb,12);
|
||||
printf(" ID: "); print_hex(nbi.abtId,4);
|
||||
printf(" CID: %02x\n",nbi.btCid);
|
||||
if (nbi.szInfLen>0) {
|
||||
printf(" INF: "); print_hex(nbi.abtInf,nbi.szInfLen);
|
||||
printf (" ID (NFCID2): ");
|
||||
print_hex (nfi.abtId, 8);
|
||||
printf (" Parameter (PAD): ");
|
||||
print_hex (nfi.abtPad, 8);
|
||||
}
|
||||
|
||||
void
|
||||
print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi)
|
||||
{
|
||||
printf (" ATQB: ");
|
||||
print_hex (nbi.abtAtqb, 12);
|
||||
printf (" ID: ");
|
||||
print_hex (nbi.abtId, 4);
|
||||
printf (" CID: %02x\n", nbi.btCid);
|
||||
if (nbi.szInfLen > 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tries to parse arguments to find 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;
|
||||
int arg;
|
||||
nfc_device_desc_t *pndd = 0;
|
||||
int arg;
|
||||
*szFound = 0;
|
||||
|
||||
// Get commandline options
|
||||
for (arg=1;arg<argc;arg++) {
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
|
||||
if (0 == strcmp(argv[arg], "--device")) {
|
||||
if (0 == strcmp (argv[arg], "--device")) {
|
||||
|
||||
if (argc > arg+1) {
|
||||
char buffer[256];
|
||||
if (argc > arg + 1) {
|
||||
char buffer[256];
|
||||
|
||||
pndd = malloc(sizeof(nfc_device_desc_t));
|
||||
pndd = malloc (sizeof (nfc_device_desc_t));
|
||||
|
||||
strncpy(buffer, argv[++arg], 256);
|
||||
strncpy (buffer, argv[++arg], 256);
|
||||
|
||||
// Driver.
|
||||
pndd->pcDriver = (char *)malloc(256);
|
||||
strcpy(pndd->pcDriver, strtok(buffer, ":"));
|
||||
pndd->pcDriver = (char *) malloc (256);
|
||||
strcpy (pndd->pcDriver, strtok (buffer, ":"));
|
||||
|
||||
// Port.
|
||||
pndd->pcPort = (char *)malloc(256);
|
||||
strcpy(pndd->pcPort, strtok(NULL, ":"));
|
||||
pndd->pcPort = (char *) malloc (256);
|
||||
strcpy (pndd->pcPort, strtok (NULL, ":"));
|
||||
|
||||
// Speed.
|
||||
sscanf(strtok(NULL, ":"), "%u", &pndd->uiSpeed);
|
||||
sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);
|
||||
|
||||
*szFound = 1;
|
||||
}
|
||||
|
@ -176,4 +189,3 @@ nfc_device_desc_t* parse_device_desc(int argc, const char *argv[], size_t* szFou
|
|||
|
||||
return pndd;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,22 +22,22 @@
|
|||
*/
|
||||
|
||||
#ifndef _EXAMPLES_NFC_UTILS_H_
|
||||
#define _EXAMPLES_NFC_UTILS_H_
|
||||
# define _EXAMPLES_NFC_UTILS_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
|
||||
byte_t oddparity(const byte_t bt);
|
||||
void oddparity_byte_ts(const byte_t* pbtData, const size_t szLen, byte_t* pbtPar);
|
||||
byte_t oddparity (const byte_t bt);
|
||||
void oddparity_byte_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar);
|
||||
|
||||
void print_hex(const byte_t* pbtData, const size_t szLen);
|
||||
void print_hex_bits(const byte_t* pbtData, const size_t szBits);
|
||||
void print_hex_par(const byte_t* pbtData, const size_t szBits, const byte_t* pbtDataPar);
|
||||
void print_hex (const byte_t * pbtData, const size_t szLen);
|
||||
void print_hex_bits (const byte_t * pbtData, const size_t szBits);
|
||||
void print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar);
|
||||
|
||||
void print_nfc_iso14443a_info(const nfc_iso14443a_info_t nai);
|
||||
void print_nfc_iso14443b_info(const nfc_iso14443b_info_t nbi);
|
||||
void print_nfc_felica_info(const nfc_felica_info_t nfi);
|
||||
void print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai);
|
||||
void print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi);
|
||||
void print_nfc_felica_info (const nfc_felica_info_t nfi);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <err.h>
|
||||
|
@ -33,40 +33,36 @@
|
|||
|
||||
#define MAX_FRAME_LEN 264
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
nfc_device_t *pnd;
|
||||
nfc_target_info_t ti;
|
||||
byte_t abtRecv[MAX_FRAME_LEN];
|
||||
size_t szRecvBits;
|
||||
byte_t send[] = "Hello World!";
|
||||
byte_t abtRecv[MAX_FRAME_LEN];
|
||||
size_t szRecvBits;
|
||||
byte_t send[] = "Hello World!";
|
||||
|
||||
if (argc > 1) {
|
||||
errx (1, "usage: %s", argv[0]);
|
||||
}
|
||||
|
||||
pnd = nfc_connect(NULL);
|
||||
if (!pnd || !nfc_initiator_init(pnd)
|
||||
|| !nfc_initiator_select_dep_target(pnd, NM_PASSIVE_DEP, NULL, 0,
|
||||
NULL, 0, NULL, 0, &ti)) {
|
||||
printf
|
||||
("unable to connect, initialize, or select the target\n");
|
||||
pnd = nfc_connect (NULL);
|
||||
if (!pnd || !nfc_initiator_init (pnd)
|
||||
|| !nfc_initiator_select_dep_target (pnd, NM_PASSIVE_DEP, NULL, 0, NULL, 0, NULL, 0, &ti)) {
|
||||
printf ("unable to connect, initialize, or select the target\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Sending : %s\n", send);
|
||||
if (!nfc_initiator_transceive_bytes(pnd,
|
||||
send,
|
||||
strlen((char*)send), abtRecv,
|
||||
&szRecvBits)) {
|
||||
printf("unable to send data\n");
|
||||
printf ("Sending : %s\n", send);
|
||||
if (!nfc_initiator_transceive_bytes (pnd, send, strlen ((char *) send), abtRecv, &szRecvBits)) {
|
||||
printf ("unable to send data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
abtRecv[szRecvBits] = 0;
|
||||
printf("Received: %s\n", abtRecv);
|
||||
printf ("Received: %s\n", abtRecv);
|
||||
|
||||
nfc_initiator_deselect_target(pnd);
|
||||
nfc_disconnect(pnd);
|
||||
nfc_initiator_deselect_target (pnd);
|
||||
nfc_disconnect (pnd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <err.h>
|
||||
|
@ -33,35 +33,36 @@
|
|||
|
||||
#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];
|
||||
size_t szRecvBits;
|
||||
byte_t send[] = "Hello Mars!";
|
||||
nfc_device_t *pnd = nfc_connect(NULL);
|
||||
byte_t abtRecv[MAX_FRAME_LEN];
|
||||
size_t szRecvBits;
|
||||
byte_t send[] = "Hello Mars!";
|
||||
nfc_device_t *pnd = nfc_connect (NULL);
|
||||
|
||||
if (argc > 1) {
|
||||
errx (1, "usage: %s", argv[0]);
|
||||
}
|
||||
|
||||
if (!pnd || !nfc_target_init(pnd, abtRecv, &szRecvBits)) {
|
||||
printf("unable to connect or initialize\n");
|
||||
if (!pnd || !nfc_target_init (pnd, abtRecv, &szRecvBits)) {
|
||||
printf ("unable to connect or initialize\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!nfc_target_receive_bytes(pnd, abtRecv, &szRecvBits)) {
|
||||
printf("unable to receive data\n");
|
||||
if (!nfc_target_receive_bytes (pnd, abtRecv, &szRecvBits)) {
|
||||
printf ("unable to receive data\n");
|
||||
return 1;
|
||||
}
|
||||
abtRecv[szRecvBits] = 0;
|
||||
printf("Received: %s\n", abtRecv);
|
||||
printf("Sending : %s\n", send);
|
||||
printf ("Received: %s\n", abtRecv);
|
||||
printf ("Sending : %s\n", send);
|
||||
|
||||
if (!nfc_target_send_bytes(pnd, send, 11)) {
|
||||
printf("unable to send data\n");
|
||||
if (!nfc_target_send_bytes (pnd, send, 11)) {
|
||||
printf ("unable to send data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfc_disconnect(pnd);
|
||||
nfc_disconnect (pnd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,17 +35,18 @@
|
|||
#define MAX_DEVICE_COUNT 16
|
||||
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
size_t szFound;
|
||||
size_t i;
|
||||
nfc_device_t* pnd;
|
||||
size_t szFound;
|
||||
size_t i;
|
||||
nfc_device_t *pnd;
|
||||
nfc_device_desc_t *pnddDevices;
|
||||
const char* acLibnfcVersion;
|
||||
bool result;
|
||||
const char *acLibnfcVersion;
|
||||
bool result;
|
||||
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
const byte_t pncmd_diagnose_communication_line_test[] = { 0xD4, 0x00, 0x00, 0x06, 'l', 'i', 'b', 'n', 'f', 'c' };
|
||||
const byte_t pncmd_diagnose_rom_test[] = { 0xD4, 0x00, 0x01 };
|
||||
const byte_t pncmd_diagnose_ram_test[] = { 0xD4, 0x00, 0x02 };
|
||||
|
@ -53,10 +54,9 @@ int main(int argc, const char* argv[])
|
|||
if (argc > 1) {
|
||||
errx (1, "usage: %s", argv[0]);
|
||||
}
|
||||
|
||||
// Display libnfc version
|
||||
acLibnfcVersion = nfc_version();
|
||||
printf("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
acLibnfcVersion = nfc_version ();
|
||||
printf ("%s use libnfc %s\n", argv[0], acLibnfcVersion);
|
||||
|
||||
if (!(pnddDevices = malloc (MAX_DEVICE_COUNT * sizeof (*pnddDevices)))) {
|
||||
fprintf (stderr, "malloc() failed\n");
|
||||
|
@ -66,38 +66,42 @@ int main(int argc, const char* argv[])
|
|||
nfc_list_devices (pnddDevices, MAX_DEVICE_COUNT, &szFound);
|
||||
|
||||
if (szFound == 0) {
|
||||
INFO("%s", "No device found.");
|
||||
INFO ("%s", "No device found.");
|
||||
}
|
||||
|
||||
for (i = 0; i < szFound; i++) {
|
||||
pnd = nfc_connect(&(pnddDevices[i]));
|
||||
pnd = nfc_connect (&(pnddDevices[i]));
|
||||
|
||||
if (pnd == NULL) {
|
||||
ERR("%s", "Unable to connect to NFC device.");
|
||||
ERR ("%s", "Unable to connect to NFC device.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("NFC device [%s] connected.\n",pnd->acName);
|
||||
printf ("NFC device [%s] connected.\n", pnd->acName);
|
||||
|
||||
// FIXME: Direct call
|
||||
result = pn53x_transceive(pnd,pncmd_diagnose_communication_line_test,sizeof(pncmd_diagnose_communication_line_test),abtRx,&szRxLen);
|
||||
if ( result ) {
|
||||
result = (memcmp(pncmd_diagnose_communication_line_test+2, abtRx, sizeof(pncmd_diagnose_communication_line_test)-2 ) == 0);
|
||||
result =
|
||||
pn53x_transceive (pnd, pncmd_diagnose_communication_line_test, sizeof (pncmd_diagnose_communication_line_test),
|
||||
abtRx, &szRxLen);
|
||||
if (result) {
|
||||
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");
|
||||
|
||||
// FIXME: Direct call
|
||||
result = pn53x_transceive(pnd,pncmd_diagnose_rom_test,sizeof(pncmd_diagnose_rom_test),abtRx,&szRxLen);
|
||||
if ( result ) {
|
||||
result = pn53x_transceive (pnd, pncmd_diagnose_rom_test, sizeof (pncmd_diagnose_rom_test), abtRx, &szRxLen);
|
||||
if (result) {
|
||||
result = ((szRxLen == 1) && (abtRx[0] == 0x00));
|
||||
}
|
||||
printf(" ROM test: %s\n", result ? "OK" : "Failed");
|
||||
printf (" ROM test: %s\n", result ? "OK" : "Failed");
|
||||
|
||||
// FIXME: Direct call
|
||||
result = pn53x_transceive(pnd,pncmd_diagnose_ram_test,sizeof(pncmd_diagnose_ram_test),abtRx,&szRxLen);
|
||||
if ( result ) {
|
||||
result = pn53x_transceive (pnd, pncmd_diagnose_ram_test, sizeof (pncmd_diagnose_ram_test), abtRx, &szRxLen);
|
||||
if (result) {
|
||||
result = ((szRxLen == 1) && (abtRx[0] == 0x00));
|
||||
}
|
||||
printf(" RAM test: %s\n", result ? "OK" : "Failed");
|
||||
printf (" RAM test: %s\n", result ? "OK" : "Failed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,25 +22,25 @@
|
|||
*/
|
||||
|
||||
#ifndef _LIBNFC_MESSAGES_H_
|
||||
#define _LIBNFC_MESSAGES_H_
|
||||
# define _LIBNFC_MESSAGES_H_
|
||||
|
||||
#include <err.h>
|
||||
# include <err.h>
|
||||
|
||||
// #define DEBUG /* DEBUG flag can also be enabled using ./configure --enable-debug */
|
||||
|
||||
// Useful macros
|
||||
#ifdef DEBUG
|
||||
# ifdef DEBUG
|
||||
// #define DBG(x, args...) printf("DBG %s:%d: " x "\n", __FILE__, __LINE__,## args )
|
||||
#define DBG(...) do { \
|
||||
# define DBG(...) do { \
|
||||
warnx ("DBG %s:%d", __FILE__, __LINE__); \
|
||||
warnx (" " __VA_ARGS__ ); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG(...) {}
|
||||
#endif
|
||||
# else
|
||||
# define DBG(...) {}
|
||||
# endif
|
||||
|
||||
#define INFO(...) warnx ("INFO: " __VA_ARGS__ )
|
||||
#define WARN(...) warnx ("WARNING: " __VA_ARGS__ )
|
||||
#define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
|
||||
# define INFO(...) warnx ("INFO: " __VA_ARGS__ )
|
||||
# define WARN(...) warnx ("WARNING: " __VA_ARGS__ )
|
||||
# define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
|
||||
|
||||
#endif // _LIBNFC_MESSAGES_H_
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_TYPES_H__
|
||||
#define __NFC_TYPES_H__
|
||||
# define __NFC_TYPES_H__
|
||||
|
||||
/**
|
||||
* @file types.h
|
||||
|
@ -30,45 +30,45 @@
|
|||
*
|
||||
* Define libnfc specific types: typedef, enum, struct, etc.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <stdbool.h>
|
||||
# include <stdio.h>
|
||||
|
||||
typedef uint8_t byte_t;
|
||||
|
||||
typedef enum {
|
||||
NC_PN531 = 0x10,
|
||||
NC_PN532 = 0x20,
|
||||
NC_PN533 = 0x30,
|
||||
NC_PN531 = 0x10,
|
||||
NC_PN532 = 0x20,
|
||||
NC_PN533 = 0x30,
|
||||
} nfc_chip_t;
|
||||
|
||||
struct driver_callbacks; // Prototype the callback struct
|
||||
struct driver_callbacks; // Prototype the callback struct
|
||||
|
||||
typedef void* nfc_device_spec_t; // Device connection specification
|
||||
typedef void *nfc_device_spec_t; // Device connection specification
|
||||
|
||||
#define DEVICE_NAME_LENGTH 256
|
||||
# define DEVICE_NAME_LENGTH 256
|
||||
/**
|
||||
* @struct nfc_device_t
|
||||
* @brief NFC device information
|
||||
*/
|
||||
typedef struct {
|
||||
/** Callback functions for handling device specific wrapping */
|
||||
const struct driver_callbacks* pdc;
|
||||
const struct driver_callbacks *pdc;
|
||||
/** Device name string, including device wrapper firmware */
|
||||
char acName[DEVICE_NAME_LENGTH];
|
||||
char acName[DEVICE_NAME_LENGTH];
|
||||
/** PN53X chip type, this is useful for some "bug" work-arounds */
|
||||
nfc_chip_t nc;
|
||||
/** Pointer to the device connection specification */
|
||||
nfc_device_spec_t nds;
|
||||
nfc_device_spec_t nds;
|
||||
/** This represents if the PN53X device was initialized succesful */
|
||||
bool bActive;
|
||||
bool bActive;
|
||||
/** Is the crc automaticly added, checked and removed from the frames */
|
||||
bool bCrc;
|
||||
bool bCrc;
|
||||
/** Does the PN53x chip handles parity bits, all parities are handled as data */
|
||||
bool bPar;
|
||||
bool bPar;
|
||||
/** Should the PN53x chip handle frames encapsulation and chaining */
|
||||
bool bEasyFraming;
|
||||
bool bEasyFraming;
|
||||
/** The last tx bits setting, we need to reset this if it does not apply anymore */
|
||||
uint8_t ui8TxBits;
|
||||
/** Last error reported by the PCD / encountered by the PCD driver
|
||||
|
@ -79,7 +79,7 @@ typedef struct {
|
|||
* |+---------- Driver-level specific error
|
||||
* +----------- Driver-level general error (common to all drivers)
|
||||
*/
|
||||
int iLastError;
|
||||
int iLastError;
|
||||
} nfc_device_t;
|
||||
|
||||
|
||||
|
@ -91,11 +91,11 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
/** Device name (e.g. "ACS ACR 38U-CCID 00 00") */
|
||||
char acDevice[DEVICE_NAME_LENGTH];
|
||||
char acDevice[DEVICE_NAME_LENGTH];
|
||||
/** Driver name (e.g. "PN532_UART")*/
|
||||
char* pcDriver;
|
||||
char *pcDriver;
|
||||
/** Port (e.g. "/dev/ttyUSB0") */
|
||||
char* pcPort;
|
||||
char *pcPort;
|
||||
/** Port speed (e.g. "115200") */
|
||||
uint32_t uiSpeed;
|
||||
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */
|
||||
|
@ -108,7 +108,7 @@ typedef struct {
|
|||
*/
|
||||
struct chip_callbacks {
|
||||
/** Error lookup */
|
||||
const char* (*strerror) (const nfc_device_t *pnd);
|
||||
const char *(*strerror) (const nfc_device_t * pnd);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -117,23 +117,27 @@ struct chip_callbacks {
|
|||
*/
|
||||
struct driver_callbacks {
|
||||
/** Driver name */
|
||||
const char* acDriver;
|
||||
const char *acDriver;
|
||||
/** Chip specific callback functions */
|
||||
const struct chip_callbacks *pcc;
|
||||
/** Pick devices callback */
|
||||
nfc_device_desc_t *(*pick_device)(void);
|
||||
nfc_device_desc_t *(*pick_device) (void);
|
||||
/** List devices callback */
|
||||
bool (*list_devices)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
bool (*list_devices) (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
/** Connect callback */
|
||||
nfc_device_t* (*connect)(const nfc_device_desc_t* pndd);
|
||||
nfc_device_t *(*connect) (const nfc_device_desc_t * pndd);
|
||||
/** 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 */
|
||||
void (*disconnect)(nfc_device_t* pnd);
|
||||
void (*disconnect) (nfc_device_t * pnd);
|
||||
};
|
||||
|
||||
// Compiler directive, set struct alignment to 1 byte_t for compatibility
|
||||
#pragma pack(1)
|
||||
# pragma pack(1)
|
||||
|
||||
/**
|
||||
* @enum nfc_device_option_t
|
||||
|
@ -141,23 +145,23 @@ struct driver_callbacks {
|
|||
*/
|
||||
typedef enum {
|
||||
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends the CRC bytes to the frames that are transmitted. It will parse the last bytes from received frames as incoming CRC bytes. They will be verified against the used modulation and protocol. If an frame is expected with incorrect CRC bytes this option should be disabled. Example frames where this is useful are the ATQA and UID+BCC that are transmitted without CRC bytes during the anti-collision phase of the ISO14443-A protocol. */
|
||||
NDO_HANDLE_CRC = 0x00,
|
||||
NDO_HANDLE_CRC = 0x00,
|
||||
/** Parity bits in the network layer of ISO14443-A are by default generated and validated in the PN53X chip. This is a very convenient feature. On certain times though it is useful to get full control of the transmitted data. The proprietary MIFARE Classic protocol uses for example custom (encrypted) parity bits. For interoperability it is required to be completely compatible, including the arbitrary parity bits. When this option is disabled, the functions to communicating bits should be used. */
|
||||
NDO_HANDLE_PARITY = 0x01,
|
||||
NDO_HANDLE_PARITY = 0x01,
|
||||
/** This option can be used to enable or disable the electronic field of the NFC device. */
|
||||
NDO_ACTIVATE_FIELD = 0x10,
|
||||
NDO_ACTIVATE_FIELD = 0x10,
|
||||
/** The internal CRYPTO1 co-processor can be used to transmit messages encrypted. This option is automatically activated after a successful MIFARE Classic authentication. */
|
||||
NDO_ACTIVATE_CRYPTO1 = 0x11,
|
||||
NDO_ACTIVATE_CRYPTO1 = 0x11,
|
||||
/** The default configuration defines that the PN53X chip will try indefinitely to invite a tag in the field to respond. This could be desired when it is certain a tag will enter the field. On the other hand, when this is uncertain, it will block the application. This option could best be compared to the (NON)BLOCKING option used by (socket)network programming. */
|
||||
NDO_INFINITE_SELECT = 0x20,
|
||||
NDO_INFINITE_SELECT = 0x20,
|
||||
/** If this option is enabled, frames that carry less than 4 bits are allowed. According to the standards these frames should normally be handles as invalid frames. */
|
||||
NDO_ACCEPT_INVALID_FRAMES = 0x30,
|
||||
NDO_ACCEPT_INVALID_FRAMES = 0x30,
|
||||
/** If the NFC device should only listen to frames, it could be useful to let it gather multiple frames in a sequence. They will be stored in the internal FIFO of the PN53X chip. This could be retrieved by using the receive data functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long), it will overwrite the first received frames, so quick retrieving of the received data is desirable. */
|
||||
NDO_ACCEPT_MULTIPLE_FRAMES = 0x31,
|
||||
NDO_ACCEPT_MULTIPLE_FRAMES = 0x31,
|
||||
/** This option can be used to enable or disable the auto-switching mode to ISO14443-4 is device is compliant */
|
||||
NDO_AUTO_ISO14443_4 = 0x40,
|
||||
NDO_AUTO_ISO14443_4 = 0x40,
|
||||
/** Use automatic frames encapsulation and chaining. */
|
||||
NDO_EASY_FRAMING = 0x41,
|
||||
NDO_EASY_FRAMING = 0x41,
|
||||
} nfc_device_option_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -169,15 +173,15 @@ typedef enum {
|
|||
*/
|
||||
typedef enum {
|
||||
/** ISO14443-A (NXP MIFARE) http://en.wikipedia.org/wiki/MIFARE */
|
||||
NM_ISO14443A_106 = 0x00,
|
||||
NM_ISO14443A_106 = 0x00,
|
||||
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
|
||||
NM_FELICA_212 = 0x01,
|
||||
NM_FELICA_212 = 0x01,
|
||||
/** JIS X 6319-4 (Sony Felica) http://en.wikipedia.org/wiki/FeliCa */
|
||||
NM_FELICA_424 = 0x02,
|
||||
NM_FELICA_424 = 0x02,
|
||||
/** ISO14443-B http://en.wikipedia.org/wiki/ISO/IEC_14443 */
|
||||
NM_ISO14443B_106 = 0x03,
|
||||
NM_ISO14443B_106 = 0x03,
|
||||
/** Jewel Topaz (Innovision Research & Development) */
|
||||
NM_JEWEL_106 = 0x04,
|
||||
NM_JEWEL_106 = 0x04,
|
||||
/** Active DEP */
|
||||
NM_ACTIVE_DEP = 0x05,
|
||||
/** Passive DEP */
|
||||
|
@ -189,10 +193,10 @@ typedef enum {
|
|||
* @brief NFC tag information in Data Exchange Protocol
|
||||
*/
|
||||
typedef struct {
|
||||
byte_t NFCID3i[10];
|
||||
byte_t btDID;
|
||||
byte_t btBSt;
|
||||
byte_t btBRt;
|
||||
byte_t NFCID3i[10];
|
||||
byte_t btDID;
|
||||
byte_t btBSt;
|
||||
byte_t btBRt;
|
||||
} nfc_dep_info_t;
|
||||
|
||||
/**
|
||||
|
@ -200,12 +204,12 @@ typedef struct {
|
|||
* @brief NFC ISO14443A tag (MIFARE) information
|
||||
*/
|
||||
typedef struct {
|
||||
byte_t abtAtqa[2];
|
||||
byte_t btSak;
|
||||
size_t szUidLen;
|
||||
byte_t abtUid[10];
|
||||
size_t szAtsLen;
|
||||
byte_t abtAts[36];
|
||||
byte_t abtAtqa[2];
|
||||
byte_t btSak;
|
||||
size_t szUidLen;
|
||||
byte_t abtUid[10];
|
||||
size_t szAtsLen;
|
||||
byte_t abtAts[36];
|
||||
} nfc_iso14443a_info_t;
|
||||
|
||||
/**
|
||||
|
@ -213,11 +217,11 @@ typedef struct {
|
|||
* @brief NFC FeLiCa tag information
|
||||
*/
|
||||
typedef struct {
|
||||
size_t szLen;
|
||||
byte_t btResCode;
|
||||
byte_t abtId[8];
|
||||
byte_t abtPad[8];
|
||||
byte_t abtSysCode[2];
|
||||
size_t szLen;
|
||||
byte_t btResCode;
|
||||
byte_t abtId[8];
|
||||
byte_t abtPad[8];
|
||||
byte_t abtSysCode[2];
|
||||
} nfc_felica_info_t;
|
||||
|
||||
/**
|
||||
|
@ -225,15 +229,15 @@ typedef struct {
|
|||
* @brief NFC ISO14443B tag information
|
||||
*/
|
||||
typedef struct {
|
||||
byte_t abtAtqb[12];
|
||||
byte_t abtId[4];
|
||||
byte_t btParam1;
|
||||
byte_t btParam2;
|
||||
byte_t btParam3;
|
||||
byte_t btParam4;
|
||||
byte_t btCid;
|
||||
size_t szInfLen;
|
||||
byte_t abtInf[64];
|
||||
byte_t abtAtqb[12];
|
||||
byte_t abtId[4];
|
||||
byte_t btParam1;
|
||||
byte_t btParam2;
|
||||
byte_t btParam3;
|
||||
byte_t btParam4;
|
||||
byte_t btCid;
|
||||
size_t szInfLen;
|
||||
byte_t abtInf[64];
|
||||
} nfc_iso14443b_info_t;
|
||||
|
||||
/**
|
||||
|
@ -241,8 +245,8 @@ typedef struct {
|
|||
* @brief NFC Jewel tag information
|
||||
*/
|
||||
typedef struct {
|
||||
byte_t btSensRes[2];
|
||||
byte_t btId[4];
|
||||
byte_t btSensRes[2];
|
||||
byte_t btId[4];
|
||||
} nfc_jewel_info_t;
|
||||
|
||||
/**
|
||||
|
@ -306,6 +310,6 @@ typedef struct {
|
|||
} nfc_target_t;
|
||||
|
||||
// Reset struct alignment to default
|
||||
#pragma pack()
|
||||
# pragma pack()
|
||||
|
||||
#endif // _LIBNFC_TYPES_H_
|
||||
|
|
|
@ -25,79 +25,96 @@
|
|||
*/
|
||||
|
||||
#ifndef _LIBNFC_H_
|
||||
#define _LIBNFC_H_
|
||||
# define _LIBNFC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
# include <stdint.h>
|
||||
# include <stdbool.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN32
|
||||
/* Windows platform */
|
||||
#ifndef _WINDLL
|
||||
# ifndef _WINDLL
|
||||
/* CMake compilation */
|
||||
#ifdef nfc_EXPORTS
|
||||
#define NFC_EXPORT __declspec(dllexport)
|
||||
#else /* nfc_EXPORTS */
|
||||
#define NFC_EXPORT __declspec(dllimport)
|
||||
#endif /* nfc_EXPORTS */
|
||||
#else /* _WINDLL */
|
||||
# ifdef nfc_EXPORTS
|
||||
# define NFC_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
/* nfc_EXPORTS */
|
||||
# define NFC_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
/* nfc_EXPORTS */
|
||||
# else
|
||||
/* _WINDLL */
|
||||
/* Manual makefile */
|
||||
#define NFC_EXPORT
|
||||
#endif /* _WINDLL */
|
||||
#else /* _WIN32 */
|
||||
#define NFC_EXPORT
|
||||
#endif /* _WIN32 */
|
||||
# define NFC_EXPORT
|
||||
# endif
|
||||
/* _WINDLL */
|
||||
# else
|
||||
/* _WIN32 */
|
||||
# define NFC_EXPORT
|
||||
# endif
|
||||
/* _WIN32 */
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif // __cplusplus
|
||||
|
||||
/* NFC Device/Hardware manipulation */
|
||||
NFC_EXPORT void nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
NFC_EXPORT nfc_device_t* nfc_connect(nfc_device_desc_t* pndd);
|
||||
NFC_EXPORT void nfc_disconnect(nfc_device_t* pnd);
|
||||
NFC_EXPORT bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool bEnable);
|
||||
NFC_EXPORT void nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
NFC_EXPORT nfc_device_t *nfc_connect (nfc_device_desc_t * pndd);
|
||||
NFC_EXPORT void nfc_disconnect (nfc_device_t * pnd);
|
||||
NFC_EXPORT bool nfc_configure (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
||||
|
||||
/* NFC initiator: act as "reader" */
|
||||
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_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_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_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen);
|
||||
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_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_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_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_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_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_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
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_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_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen);
|
||||
|
||||
/* Error reporting */
|
||||
NFC_EXPORT const char *nfc_strerror (const nfc_device_t *pnd);
|
||||
NFC_EXPORT int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen);
|
||||
NFC_EXPORT void nfc_perror (const nfc_device_t *pnd, const char *pcString);
|
||||
NFC_EXPORT const char *nfc_strerror (const nfc_device_t * pnd);
|
||||
NFC_EXPORT int nfc_strerror_r (const nfc_device_t * pnd, char *pcStrErrBuf, size_t szBufLen);
|
||||
NFC_EXPORT void nfc_perror (const nfc_device_t * pnd, const char *pcString);
|
||||
|
||||
/* Special data accessors */
|
||||
NFC_EXPORT const char* nfc_device_name(nfc_device_t* pnd);
|
||||
NFC_EXPORT const char *nfc_device_name (nfc_device_t * pnd);
|
||||
|
||||
/* Misc. functions */
|
||||
NFC_EXPORT void iso14443a_crc(byte_t* pbtData, size_t szLen, byte_t* pbtCrc);
|
||||
NFC_EXPORT void append_iso14443a_crc(byte_t* pbtData, size_t szLen);
|
||||
NFC_EXPORT const char* nfc_version(void);
|
||||
NFC_EXPORT void iso14443a_crc (byte_t * pbtData, size_t szLen, byte_t * pbtCrc);
|
||||
NFC_EXPORT void append_iso14443a_crc (byte_t * pbtData, size_t szLen);
|
||||
NFC_EXPORT const char *nfc_version (void);
|
||||
|
||||
/* Common device-level errors */
|
||||
#define DEIO 0x1000 /* Input/output error */
|
||||
#define DEINVAL 0x2000 /* Invalid argument */
|
||||
#define DETIMEOUT 0x3000 /* Operation timeout */
|
||||
# define DEIO 0x1000/* Input/output error */
|
||||
# define DEINVAL 0x2000/* Invalid argument */
|
||||
# define DETIMEOUT 0x3000/* Operation timeout */
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif // _LIBNFC_H_
|
||||
|
||||
# endif // __cplusplus
|
||||
#endif // _LIBNFC_H_
|
||||
|
|
|
@ -22,4 +22,3 @@
|
|||
*/
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ http://www.teuniz.net/RS-232/index.html
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include "uart.h"
|
||||
|
@ -42,50 +42,47 @@ http://www.teuniz.net/RS-232/index.html
|
|||
// Test if we are dealing with unix operating systems
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
# include <sys/select.h>
|
||||
# include <termios.h>
|
||||
typedef struct termios term_info;
|
||||
typedef struct {
|
||||
int fd; // Serial port file descriptor
|
||||
term_info tiOld; // Terminal info before using the port
|
||||
term_info tiNew; // Terminal info during the transaction
|
||||
int fd; // Serial port file descriptor
|
||||
term_info tiOld; // Terminal info before using the port
|
||||
term_info tiNew; // Terminal info during the transaction
|
||||
} serial_port_unix;
|
||||
|
||||
// timeval struct that define timeout delay for serial port
|
||||
const struct timeval timeout = {
|
||||
.tv_sec = 0, // 0 second
|
||||
.tv_usec = 60000 // 60 ms
|
||||
const struct timeval timeout = {
|
||||
.tv_sec = 0, // 0 second
|
||||
.tv_usec = 60000 // 60 ms
|
||||
};
|
||||
|
||||
// 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);
|
||||
if(sp->fd == -1)
|
||||
{
|
||||
uart_close(sp);
|
||||
sp->fd = open (pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (sp->fd == -1) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
if(tcgetattr(sp->fd,&sp->tiOld) == -1)
|
||||
{
|
||||
uart_close(sp);
|
||||
if (tcgetattr (sp->fd, &sp->tiOld) == -1) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
// Make sure the port is not claimed already
|
||||
if (sp->tiOld.c_iflag & CCLAIMED)
|
||||
{
|
||||
uart_close(sp);
|
||||
if (sp->tiOld.c_iflag & CCLAIMED) {
|
||||
uart_close (sp);
|
||||
return CLAIMED_SERIAL_PORT;
|
||||
}
|
||||
|
||||
// Copy the old terminal info struct
|
||||
sp->tiNew = sp->tiOld;
|
||||
|
||||
|
@ -94,103 +91,118 @@ serial_port uart_open(const char* pcPortName)
|
|||
sp->tiNew.c_oflag = 0;
|
||||
sp->tiNew.c_lflag = 0;
|
||||
|
||||
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[VMIN] = 0; // block until n bytes are received
|
||||
sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
|
||||
|
||||
if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1)
|
||||
{
|
||||
uart_close(sp);
|
||||
if (tcsetattr (sp->fd, TCSANOW, &sp->tiNew) == -1) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
tcflush(sp->fd, TCIFLUSH);
|
||||
tcflush (sp->fd, TCIFLUSH);
|
||||
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);
|
||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||
DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
const serial_port_unix *spu = (serial_port_unix *) sp;
|
||||
|
||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||
// uint32_t <=> speed_t associations by hand.
|
||||
speed_t stPortSpeed = B9600;
|
||||
switch(uiPortSpeed) {
|
||||
case 9600: stPortSpeed = B9600;
|
||||
switch (uiPortSpeed) {
|
||||
case 9600:
|
||||
stPortSpeed = B9600;
|
||||
break;
|
||||
case 19200: stPortSpeed = B19200;
|
||||
case 19200:
|
||||
stPortSpeed = B19200;
|
||||
break;
|
||||
case 38400: stPortSpeed = B38400;
|
||||
case 38400:
|
||||
stPortSpeed = B38400;
|
||||
break;
|
||||
#ifdef B57600
|
||||
case 57600: stPortSpeed = B57600;
|
||||
# ifdef B57600
|
||||
case 57600:
|
||||
stPortSpeed = B57600;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B115200
|
||||
case 115200: stPortSpeed = B115200;
|
||||
# endif
|
||||
# ifdef B115200
|
||||
case 115200:
|
||||
stPortSpeed = B115200;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B230400
|
||||
case 230400: stPortSpeed = B230400;
|
||||
# endif
|
||||
# ifdef B230400
|
||||
case 230400:
|
||||
stPortSpeed = B230400;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B460800
|
||||
case 460800: stPortSpeed = B460800;
|
||||
# endif
|
||||
# ifdef B460800
|
||||
case 460800:
|
||||
stPortSpeed = B460800;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).", uiPortSpeed);
|
||||
# endif
|
||||
default:
|
||||
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)
|
||||
cfsetispeed((struct termios*)&(spu->tiNew), stPortSpeed);
|
||||
cfsetospeed((struct termios*)&(spu->tiNew), stPortSpeed);
|
||||
if( tcsetattr(spu->fd, TCSADRAIN, &(spu->tiNew)) == -1)
|
||||
{
|
||||
ERR("%s", "Unable to apply new speed settings.");
|
||||
cfsetispeed ((struct termios *) &(spu->tiNew), stPortSpeed);
|
||||
cfsetospeed ((struct termios *) &(spu->tiNew), stPortSpeed);
|
||||
if (tcsetattr (spu->fd, TCSADRAIN, &(spu->tiNew)) == -1) {
|
||||
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;
|
||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||
switch (cfgetispeed(&spu->tiNew))
|
||||
{
|
||||
case B9600: uiPortSpeed = 9600;
|
||||
const serial_port_unix *spu = (serial_port_unix *) sp;
|
||||
switch (cfgetispeed (&spu->tiNew)) {
|
||||
case B9600:
|
||||
uiPortSpeed = 9600;
|
||||
break;
|
||||
case B19200: uiPortSpeed = 19200;
|
||||
case B19200:
|
||||
uiPortSpeed = 19200;
|
||||
break;
|
||||
case B38400: uiPortSpeed = 38400;
|
||||
case B38400:
|
||||
uiPortSpeed = 38400;
|
||||
break;
|
||||
#ifdef B57600
|
||||
case B57600: uiPortSpeed = 57600;
|
||||
# ifdef B57600
|
||||
case B57600:
|
||||
uiPortSpeed = 57600;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B115200
|
||||
case B115200: uiPortSpeed = 115200;
|
||||
# endif
|
||||
# ifdef B115200
|
||||
case B115200:
|
||||
uiPortSpeed = 115200;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B230400
|
||||
case B230400: uiPortSpeed = 230400;
|
||||
# endif
|
||||
# ifdef B230400
|
||||
case B230400:
|
||||
uiPortSpeed = 230400;
|
||||
break;
|
||||
#endif
|
||||
#ifdef B460800
|
||||
case B460800: uiPortSpeed = 460800;
|
||||
# endif
|
||||
# ifdef B460800
|
||||
case B460800:
|
||||
uiPortSpeed = 460800;
|
||||
break;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
|
||||
return uiPortSpeed;
|
||||
}
|
||||
|
||||
void uart_close(const serial_port sp)
|
||||
void
|
||||
uart_close (const serial_port sp)
|
||||
{
|
||||
if (((serial_port_unix*)sp)->fd >= 0) {
|
||||
tcsetattr(((serial_port_unix*)sp)->fd,TCSANOW,&((serial_port_unix*)sp)->tiOld);
|
||||
close(((serial_port_unix*)sp)->fd);
|
||||
if (((serial_port_unix *) sp)->fd >= 0) {
|
||||
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->tiOld);
|
||||
close (((serial_port_unix *) sp)->fd);
|
||||
}
|
||||
free(sp);
|
||||
free (sp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,11 +211,11 @@ void uart_close(const serial_port sp)
|
|||
* @return 0 on success, otherwise driver error code
|
||||
*/
|
||||
int
|
||||
uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
uart_receive (serial_port sp, byte_t * pbtRx, size_t * pszRxLen)
|
||||
{
|
||||
int res;
|
||||
int byteCount;
|
||||
fd_set rfds;
|
||||
int res;
|
||||
int byteCount;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
// Reset the output count
|
||||
|
@ -211,37 +223,34 @@ uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
|
||||
do {
|
||||
// Reset file descriptor
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(((serial_port_unix*)sp)->fd,&rfds);
|
||||
FD_ZERO (&rfds);
|
||||
FD_SET (((serial_port_unix *) sp)->fd, &rfds);
|
||||
tv = timeout;
|
||||
res = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &tv);
|
||||
res = select (((serial_port_unix *) sp)->fd + 1, &rfds, NULL, NULL, &tv);
|
||||
|
||||
// Read error
|
||||
if (res < 0) {
|
||||
DBG("%s", "RX error.");
|
||||
DBG ("%s", "RX error.");
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
// Read time-out
|
||||
if (res == 0) {
|
||||
if (*pszRxLen == 0) {
|
||||
// Error, we received no data
|
||||
DBG("%s", "RX time-out, buffer empty.");
|
||||
DBG ("%s", "RX time-out, buffer empty.");
|
||||
return DETIMEOUT;
|
||||
} else {
|
||||
// We received some data, but nothing more is available
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Stop if the OS has some troubles reading the data
|
||||
if (res <= 0) {
|
||||
|
@ -261,36 +270,33 @@ uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
* @return 0 on success, otherwise a driver error is returned
|
||||
*/
|
||||
int
|
||||
uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTxLen)
|
||||
{
|
||||
int32_t res;
|
||||
size_t szPos = 0;
|
||||
fd_set rfds;
|
||||
size_t szPos = 0;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
while (szPos < szTxLen)
|
||||
{
|
||||
while (szPos < szTxLen) {
|
||||
// Reset file descriptor
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(((serial_port_unix*)sp)->fd,&rfds);
|
||||
FD_ZERO (&rfds);
|
||||
FD_SET (((serial_port_unix *) sp)->fd, &rfds);
|
||||
tv = timeout;
|
||||
res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv);
|
||||
res = select (((serial_port_unix *) sp)->fd + 1, NULL, &rfds, NULL, &tv);
|
||||
|
||||
// Write error
|
||||
if (res < 0) {
|
||||
DBG("%s", "TX error.");
|
||||
DBG ("%s", "TX error.");
|
||||
return DEIO;
|
||||
}
|
||||
|
||||
// Write time-out
|
||||
if (res == 0) {
|
||||
DBG("%s", "TX time-out.");
|
||||
DBG ("%s", "TX time-out.");
|
||||
return DETIMEOUT;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Stop if the OS has some troubles sending the data
|
||||
if (res <= 0) {
|
||||
return DEIO;
|
||||
|
@ -304,109 +310,109 @@ uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
#else
|
||||
// The windows serial port implementation
|
||||
|
||||
typedef struct {
|
||||
HANDLE hPort; // Serial port handle
|
||||
DCB dcb; // Device control settings
|
||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||
typedef struct {
|
||||
HANDLE hPort; // Serial port handle
|
||||
DCB dcb; // Device control settings
|
||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||
} serial_port_windows;
|
||||
|
||||
serial_port uart_open(const char* pcPortName)
|
||||
serial_port
|
||||
uart_open (const char *pcPortName)
|
||||
{
|
||||
char acPortName[255];
|
||||
serial_port_windows* sp = malloc(sizeof(serial_port_windows));
|
||||
char acPortName[255];
|
||||
serial_port_windows *sp = malloc (sizeof (serial_port_windows));
|
||||
|
||||
// Copy the input "com?" to "\\.\COM?" format
|
||||
sprintf(acPortName,"\\\\.\\%s",pcPortName);
|
||||
_strupr(acPortName);
|
||||
sprintf (acPortName, "\\\\.\\%s", pcPortName);
|
||||
_strupr (acPortName);
|
||||
|
||||
// Try to open the serial port
|
||||
sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
|
||||
if (sp->hPort == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
uart_close(sp);
|
||||
sp->hPort = CreateFileA (acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (sp->hPort == INVALID_HANDLE_VALUE) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
// Prepare the device control
|
||||
memset(&sp->dcb, 0, sizeof(DCB));
|
||||
sp->dcb.DCBlength = sizeof(DCB);
|
||||
if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb))
|
||||
{
|
||||
uart_close(sp);
|
||||
memset (&sp->dcb, 0, sizeof (DCB));
|
||||
sp->dcb.DCBlength = sizeof (DCB);
|
||||
if (!BuildCommDCBA ("baud=9600 data=8 parity=N stop=1", &sp->dcb)) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
// Update the active serial port
|
||||
if(!SetCommState(sp->hPort,&sp->dcb))
|
||||
{
|
||||
uart_close(sp);
|
||||
if (!SetCommState (sp->hPort, &sp->dcb)) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
sp->ct.ReadIntervalTimeout = 0;
|
||||
sp->ct.ReadTotalTimeoutMultiplier = 0;
|
||||
sp->ct.ReadTotalTimeoutConstant = 30;
|
||||
sp->ct.ReadIntervalTimeout = 0;
|
||||
sp->ct.ReadTotalTimeoutMultiplier = 0;
|
||||
sp->ct.ReadTotalTimeoutConstant = 30;
|
||||
sp->ct.WriteTotalTimeoutMultiplier = 0;
|
||||
sp->ct.WriteTotalTimeoutConstant = 30;
|
||||
sp->ct.WriteTotalTimeoutConstant = 30;
|
||||
|
||||
if(!SetCommTimeouts(sp->hPort,&sp->ct))
|
||||
{
|
||||
uart_close(sp);
|
||||
if (!SetCommTimeouts (sp->hPort, &sp->ct)) {
|
||||
uart_close (sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||
PurgeComm (sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||
|
||||
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) {
|
||||
CloseHandle(((serial_port_windows*)sp)->hPort);
|
||||
if (((serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle (((serial_port_windows *) sp)->hPort);
|
||||
}
|
||||
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;
|
||||
|
||||
DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
// Set port speed (Input and Output)
|
||||
switch(uiPortSpeed) {
|
||||
case 9600:
|
||||
case 19200:
|
||||
case 38400:
|
||||
case 57600:
|
||||
case 115200:
|
||||
case 230400:
|
||||
case 460800:
|
||||
switch (uiPortSpeed) {
|
||||
case 9600:
|
||||
case 19200:
|
||||
case 38400:
|
||||
case 57600:
|
||||
case 115200:
|
||||
case 230400:
|
||||
case 460800:
|
||||
break;
|
||||
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);
|
||||
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);
|
||||
};
|
||||
|
||||
spw = (serial_port_windows*)sp;
|
||||
spw = (serial_port_windows *) sp;
|
||||
spw->dcb.BaudRate = uiPortSpeed;
|
||||
if (!SetCommState(spw->hPort, &spw->dcb))
|
||||
{
|
||||
ERR("Unable to apply new speed settings.");
|
||||
if (!SetCommState (spw->hPort, &spw->dcb)) {
|
||||
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;
|
||||
if (!GetCommState(spw->hPort, (serial_port)&spw->dcb))
|
||||
const serial_port_windows *spw = (serial_port_windows *) sp;
|
||||
if (!GetCommState (spw->hPort, (serial_port) & spw->dcb))
|
||||
return spw->dcb.BaudRate;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
if (!*pszRxLen)
|
||||
|
@ -414,10 +420,11 @@ int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
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;
|
||||
if (!WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL)) {
|
||||
DWORD dwTxLen = 0;
|
||||
if (!WriteFile (((serial_port_windows *) sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL)) {
|
||||
return DEIO;
|
||||
}
|
||||
if (!dwTxLen)
|
||||
|
|
|
@ -24,68 +24,67 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_BUS_UART_H__
|
||||
#define __NFC_BUS_UART_H__
|
||||
# define __NFC_BUS_UART_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
// Handle platform specific includes
|
||||
#ifndef _WIN32
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#include <sys/time.h>
|
||||
# ifndef _WIN32
|
||||
# include <termios.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <limits.h>
|
||||
# include <sys/time.h>
|
||||
|
||||
// unistd.h is needed for usleep() fct.
|
||||
#include <unistd.h>
|
||||
#define delay_ms( X ) usleep( X * 1000 )
|
||||
#else
|
||||
#include <windows.h>
|
||||
# include <unistd.h>
|
||||
# define delay_ms( X ) usleep( X * 1000 )
|
||||
# else
|
||||
# include <windows.h>
|
||||
|
||||
#define snprintf _snprintf
|
||||
#define strdup _strdup
|
||||
#define delay_ms( X ) Sleep( X )
|
||||
#endif
|
||||
# define snprintf _snprintf
|
||||
# define strdup _strdup
|
||||
# define delay_ms( X ) Sleep( X )
|
||||
# endif
|
||||
|
||||
// Path to the serial port is OS-dependant.
|
||||
// Try to guess what we should use.
|
||||
//
|
||||
// XXX: Some review from users cross-compiling is welcome!
|
||||
#if defined (_WIN32)
|
||||
#define DEFAULT_SERIAL_PORTS { "COM1", "COM2", "COM3", "COM4", NULL }
|
||||
#elif defined(__APPLE__)
|
||||
# if defined (_WIN32)
|
||||
# define DEFAULT_SERIAL_PORTS { "COM1", "COM2", "COM3", "COM4", NULL }
|
||||
# elif defined(__APPLE__)
|
||||
// XXX: find UART connection string for PN53X device on Mac OS X when multiples devices are used
|
||||
#define DEFAULT_SERIAL_PORTS { "/dev/tty.SLAB_USBtoUART", NULL }
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
# define DEFAULT_SERIAL_PORTS { "/dev/tty.SLAB_USBtoUART", NULL }
|
||||
# elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
// XXX: Not tested
|
||||
#define DEFAULT_SERIAL_PORTS { "/dev/cuau0", "/dev/cuau1", "/dev/cuau2", "/dev/cuau3", NULL }
|
||||
#elif defined (__linux__)
|
||||
#define DEFAULT_SERIAL_PORTS { "/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2", "/dev/ttyUSB3", "/dev/tty0", "/dev/tty1", "/dev/tty2", "/dev/tty3", NULL }
|
||||
#else
|
||||
#error "Can't determine serial string for your system"
|
||||
#endif
|
||||
# define DEFAULT_SERIAL_PORTS { "/dev/cuau0", "/dev/cuau1", "/dev/cuau2", "/dev/cuau3", NULL }
|
||||
# elif defined (__linux__)
|
||||
# define DEFAULT_SERIAL_PORTS { "/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2", "/dev/ttyUSB3", "/dev/tty0", "/dev/tty1", "/dev/tty2", "/dev/tty3", NULL }
|
||||
# else
|
||||
# error "Can't determine serial string for your system"
|
||||
# endif
|
||||
|
||||
// Define shortcut to types to make code more readable
|
||||
typedef void* serial_port;
|
||||
#define INVALID_SERIAL_PORT (void*)(~1)
|
||||
#define CLAIMED_SERIAL_PORT (void*)(~2)
|
||||
typedef void *serial_port;
|
||||
# define INVALID_SERIAL_PORT (void*)(~1)
|
||||
# define CLAIMED_SERIAL_PORT (void*)(~2)
|
||||
|
||||
serial_port uart_open(const char* pcPortName);
|
||||
void uart_close(const serial_port sp);
|
||||
serial_port uart_open (const char *pcPortName);
|
||||
void uart_close (const serial_port sp);
|
||||
|
||||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
|
||||
uint32_t uart_get_speed(const serial_port sp);
|
||||
void uart_set_speed (serial_port sp, const uint32_t uiPortSpeed);
|
||||
uint32_t uart_get_speed (const serial_port sp);
|
||||
|
||||
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_receive (serial_port sp, byte_t * pbtRx, size_t * pszRxLen);
|
||||
int uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTxLen);
|
||||
|
||||
#endif // __NFC_BUS_UART_H__
|
||||
|
||||
|
|
|
@ -16,18 +16,17 @@
|
|||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file chips.h
|
||||
* @brief NFC chips header
|
||||
*/
|
||||
|
||||
#ifndef __NFC_CHIPS_H__
|
||||
#define __NFC_CHIPS_H__
|
||||
# define __NFC_CHIPS_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#include "chips/pn53x.h"
|
||||
# include "chips/pn53x.h"
|
||||
|
||||
#endif // __NFC_CHIPS_H__
|
||||
|
||||
|
|
1027
libnfc/chips/pn53x.c
1027
libnfc/chips/pn53x.c
File diff suppressed because it is too large
Load diff
|
@ -23,94 +23,111 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_CHIPS_PN53X_H__
|
||||
#define __NFC_CHIPS_PN53X_H__
|
||||
# define __NFC_CHIPS_PN53X_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#define MAX_FRAME_LEN 264
|
||||
# define MAX_FRAME_LEN 264
|
||||
|
||||
// Registers and symbols masks used to covers parts within a register
|
||||
#define REG_CIU_TX_MODE 0x6302
|
||||
#define SYMBOL_TX_CRC_ENABLE 0x80
|
||||
#define REG_CIU_RX_MODE 0x6303
|
||||
#define SYMBOL_RX_CRC_ENABLE 0x80
|
||||
#define SYMBOL_RX_NO_ERROR 0x08
|
||||
#define SYMBOL_RX_MULTIPLE 0x04
|
||||
#define REG_CIU_TX_AUTO 0x6305
|
||||
#define SYMBOL_FORCE_100_ASK 0x40
|
||||
#define SYMBOL_AUTO_WAKE_UP 0x20
|
||||
#define SYMBOL_INITIAL_RF_ON 0x04
|
||||
#define REG_CIU_MANUAL_RCV 0x630D
|
||||
#define SYMBOL_PARITY_DISABLE 0x10
|
||||
#define REG_CIU_STATUS2 0x6338
|
||||
#define SYMBOL_MF_CRYPTO1_ON 0x08
|
||||
#define REG_CIU_CONTROL 0x633C
|
||||
#define SYMBOL_INITIATOR 0x10
|
||||
#define SYMBOL_RX_LAST_BITS 0x07
|
||||
#define REG_CIU_BIT_FRAMING 0x633D
|
||||
#define SYMBOL_TX_LAST_BITS 0x07
|
||||
# define REG_CIU_TX_MODE 0x6302
|
||||
# define SYMBOL_TX_CRC_ENABLE 0x80
|
||||
# define REG_CIU_RX_MODE 0x6303
|
||||
# define SYMBOL_RX_CRC_ENABLE 0x80
|
||||
# define SYMBOL_RX_NO_ERROR 0x08
|
||||
# define SYMBOL_RX_MULTIPLE 0x04
|
||||
# define REG_CIU_TX_AUTO 0x6305
|
||||
# define SYMBOL_FORCE_100_ASK 0x40
|
||||
# define SYMBOL_AUTO_WAKE_UP 0x20
|
||||
# define SYMBOL_INITIAL_RF_ON 0x04
|
||||
# define REG_CIU_MANUAL_RCV 0x630D
|
||||
# define SYMBOL_PARITY_DISABLE 0x10
|
||||
# define REG_CIU_STATUS2 0x6338
|
||||
# define SYMBOL_MF_CRYPTO1_ON 0x08
|
||||
# define REG_CIU_CONTROL 0x633C
|
||||
# define SYMBOL_INITIATOR 0x10
|
||||
# define SYMBOL_RX_LAST_BITS 0x07
|
||||
# define REG_CIU_BIT_FRAMING 0x633D
|
||||
# define SYMBOL_TX_LAST_BITS 0x07
|
||||
|
||||
#define SYMBOL_PARAM_fAutomaticRATS 0x10
|
||||
#define SYMBOL_PARAM_fAutomaticATR_RES 0x04
|
||||
# define SYMBOL_PARAM_fAutomaticRATS 0x10
|
||||
# define SYMBOL_PARAM_fAutomaticATR_RES 0x04
|
||||
|
||||
// Internal parameters flags
|
||||
#define PARAM_NONE 0x00
|
||||
#define PARAM_NAD_USED 0x01
|
||||
#define PARAM_DID_USED 0x02
|
||||
#define PARAM_AUTO_ATR_RES 0x04
|
||||
#define PARAM_AUTO_RATS 0x10
|
||||
#define PARAM_14443_4_PICC 0x20
|
||||
#define PARAM_NO_AMBLE 0x40
|
||||
# define PARAM_NONE 0x00
|
||||
# define PARAM_NAD_USED 0x01
|
||||
# define PARAM_DID_USED 0x02
|
||||
# define PARAM_AUTO_ATR_RES 0x04
|
||||
# define PARAM_AUTO_RATS 0x10
|
||||
# define PARAM_14443_4_PICC 0x20
|
||||
# define PARAM_NO_AMBLE 0x40
|
||||
|
||||
// Radio Field Configure Items // Configuration Data length
|
||||
#define RFCI_FIELD 0x01 // 1
|
||||
#define RFCI_TIMING 0x02 // 3
|
||||
#define RFCI_RETRY_DATA 0x04 // 1
|
||||
#define RFCI_RETRY_SELECT 0x05 // 3
|
||||
#define RFCI_ANALOG_TYPE_A_106 0x0A // 11
|
||||
#define RFCI_ANALOG_TYPE_A_212_424 0x0B // 8
|
||||
#define RFCI_ANALOG_TYPE_B 0x0C // 3
|
||||
#define RFCI_ANALOG_TYPE_14443_4 0x0D // 9
|
||||
# define RFCI_FIELD 0x01 // 1
|
||||
# define RFCI_TIMING 0x02 // 3
|
||||
# define RFCI_RETRY_DATA 0x04 // 1
|
||||
# define RFCI_RETRY_SELECT 0x05 // 3
|
||||
# define RFCI_ANALOG_TYPE_A_106 0x0A // 11
|
||||
# define RFCI_ANALOG_TYPE_A_212_424 0x0B // 8
|
||||
# define RFCI_ANALOG_TYPE_B 0x0C // 3
|
||||
# define RFCI_ANALOG_TYPE_14443_4 0x0D // 9
|
||||
|
||||
/* PN53x specific device-level errors */
|
||||
#define DENACK 0x0100 /* NACK */
|
||||
#define DEACKMISMATCH 0x0200 /* Unexpected data */
|
||||
#define DEISERRFRAME 0x0300 /* Error frame */
|
||||
#define DENOTSUP 0x0400 /* Not supported */
|
||||
# define DENACK 0x0100/* NACK */
|
||||
# define DEACKMISMATCH 0x0200/* Unexpected data */
|
||||
# define DEISERRFRAME 0x0300/* Error frame */
|
||||
# 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_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_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_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_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_transceive_check_ack_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);
|
||||
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_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_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_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_InDeselect(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_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_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_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_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_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_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_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_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_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_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_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_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_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);
|
||||
|
||||
static const struct chip_callbacks pn53x_callbacks_list = {
|
||||
pn53x_strerror
|
||||
pn53x_strerror
|
||||
};
|
||||
|
||||
#endif // __NFC_CHIPS_PN53X_H__
|
||||
|
||||
|
|
|
@ -23,65 +23,81 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_DRIVERS_H__
|
||||
#define __NFC_DRIVERS_H__
|
||||
# define __NFC_DRIVERS_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#include "chips/pn53x.h"
|
||||
# include "chips/pn53x.h"
|
||||
|
||||
#if defined (DRIVER_ACR122_ENABLED)
|
||||
#include "drivers/acr122.h"
|
||||
#endif /* DRIVER_ACR122_ENABLED */
|
||||
# if defined (DRIVER_ACR122_ENABLED)
|
||||
# include "drivers/acr122.h"
|
||||
# endif
|
||||
/* DRIVER_ACR122_ENABLED */
|
||||
|
||||
#if defined (DRIVER_PN531_USB_ENABLED) || defined (DRIVER_PN533_USB_ENABLED)
|
||||
#include "drivers/pn53x_usb.h"
|
||||
#endif /* DRIVER_PN531_USB_ENABLED || DRIVER_PN533_USB_ENABLED */
|
||||
# if defined (DRIVER_PN531_USB_ENABLED) || defined (DRIVER_PN533_USB_ENABLED)
|
||||
# include "drivers/pn53x_usb.h"
|
||||
# endif
|
||||
/* DRIVER_PN531_USB_ENABLED || DRIVER_PN533_USB_ENABLED */
|
||||
|
||||
#if defined (DRIVER_PN531_USB_ENABLED)
|
||||
#include "drivers/pn531_usb.h"
|
||||
#endif /* DRIVER_PN531_USB_ENABLED */
|
||||
# if defined (DRIVER_PN531_USB_ENABLED)
|
||||
# include "drivers/pn531_usb.h"
|
||||
# endif
|
||||
/* DRIVER_PN531_USB_ENABLED */
|
||||
|
||||
#if defined (DRIVER_PN533_USB_ENABLED)
|
||||
#include "drivers/pn533_usb.h"
|
||||
#endif /* DRIVER_PN533_USB_ENABLED */
|
||||
# if defined (DRIVER_PN533_USB_ENABLED)
|
||||
# include "drivers/pn533_usb.h"
|
||||
# endif
|
||||
/* DRIVER_PN533_USB_ENABLED */
|
||||
|
||||
#if defined (DRIVER_ARYGON_ENABLED)
|
||||
#include "drivers/arygon.h"
|
||||
#endif /* DRIVER_ARYGON_ENABLED */
|
||||
# if defined (DRIVER_ARYGON_ENABLED)
|
||||
# include "drivers/arygon.h"
|
||||
# endif
|
||||
/* DRIVER_ARYGON_ENABLED */
|
||||
|
||||
#if defined (DRIVER_PN532_UART_ENABLED)
|
||||
#include "drivers/pn532_uart.h"
|
||||
#endif /* DRIVER_PN532_UART_ENABLED */
|
||||
# if defined (DRIVER_PN532_UART_ENABLED)
|
||||
# include "drivers/pn532_uart.h"
|
||||
# endif
|
||||
/* DRIVER_PN532_UART_ENABLED */
|
||||
|
||||
#define DRIVERS_MAX_DEVICES 16
|
||||
#define MAX_FRAME_LEN 264
|
||||
# define DRIVERS_MAX_DEVICES 16
|
||||
# define MAX_FRAME_LEN 264
|
||||
|
||||
static const struct driver_callbacks drivers_callbacks_list[] = {
|
||||
// Driver Name Chip callbacks Pick Device List Devices Connect Transceive Disconnect
|
||||
#if defined (DRIVER_ACR122_ENABLED)
|
||||
{ ACR122_DRIVER_NAME, &pn53x_callbacks_list, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect },
|
||||
#endif /* DRIVER_ACR122_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 },
|
||||
#endif /* DRIVER_PN531_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 },
|
||||
#endif /* DRIVER_PN533_USB_ENABLED */
|
||||
#if defined (DRIVER_ARYGON_ENABLED)
|
||||
{ ARYGON_DRIVER_NAME, &pn53x_callbacks_list, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect },
|
||||
#endif /* DRIVER_ARYGON_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 },
|
||||
#endif /* DRIVER_PN532_UART_ENABLED */
|
||||
# if defined (DRIVER_ACR122_ENABLED)
|
||||
{ACR122_DRIVER_NAME, &pn53x_callbacks_list, acr122_pick_device, acr122_list_devices, acr122_connect,
|
||||
acr122_transceive, acr122_disconnect},
|
||||
# endif
|
||||
/* DRIVER_ACR122_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},
|
||||
# endif
|
||||
/* DRIVER_PN531_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},
|
||||
# endif
|
||||
/* DRIVER_PN533_USB_ENABLED */
|
||||
# if defined (DRIVER_ARYGON_ENABLED)
|
||||
{ARYGON_DRIVER_NAME, &pn53x_callbacks_list, arygon_pick_device, arygon_list_devices, arygon_connect,
|
||||
arygon_transceive, arygon_disconnect},
|
||||
# endif
|
||||
/* DRIVER_ARYGON_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},
|
||||
# endif
|
||||
/* DRIVER_PN532_UART_ENABLED */
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
# ifdef DEBUG
|
||||
/*
|
||||
* FIXME: Helper macro for dumping drivers messages.
|
||||
* Here is not the best place for such a macro, however, I
|
||||
* can't see any convenient place ATM.
|
||||
*/
|
||||
# define PRINT_HEX(pcTag, pbtData, szBytes) do { \
|
||||
# define PRINT_HEX(pcTag, pbtData, szBytes) do { \
|
||||
size_t __szPos; \
|
||||
printf(" %s: ", pcTag); \
|
||||
for (__szPos=0; __szPos < (size_t)(szBytes); __szPos++) { \
|
||||
|
@ -89,7 +105,6 @@ static const struct driver_callbacks drivers_callbacks_list[] = {
|
|||
} \
|
||||
printf("\n"); \
|
||||
} while (0);
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif // __NFC_DRIVERS_H__
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -38,7 +38,7 @@
|
|||
#include <winscard.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <wintypes.h>
|
||||
# include <wintypes.h>
|
||||
#endif
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
@ -50,7 +50,7 @@
|
|||
#define SCARD_OPERATION_ERROR 0x63
|
||||
|
||||
#ifndef SCARD_PROTOCOL_UNDEFINED
|
||||
#define SCARD_PROTOCOL_UNDEFINED SCARD_PROTOCOL_UNSET
|
||||
# define SCARD_PROTOCOL_UNDEFINED SCARD_PROTOCOL_UNSET
|
||||
#endif
|
||||
|
||||
#define FIRMWARE_TEXT "ACR122U" // Tested on: ACR122U101(ACS), ACR122U102(Tikitag), ACR122U203(ACS)
|
||||
|
@ -74,12 +74,12 @@ typedef struct {
|
|||
static SCARDCONTEXT _SCardContext;
|
||||
static int _iSCardContextRefCount = 0;
|
||||
|
||||
SCARDCONTEXT*
|
||||
acr122_get_scardcontext(void)
|
||||
SCARDCONTEXT *
|
||||
acr122_get_scardcontext (void)
|
||||
{
|
||||
if ( _iSCardContextRefCount == 0 )
|
||||
{
|
||||
if (SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&_SCardContext) != SCARD_S_SUCCESS) return NULL;
|
||||
if (_iSCardContextRefCount == 0) {
|
||||
if (SCardEstablishContext (SCARD_SCOPE_USER, NULL, NULL, &_SCardContext) != SCARD_S_SUCCESS)
|
||||
return NULL;
|
||||
}
|
||||
_iSCardContextRefCount++;
|
||||
|
||||
|
@ -87,14 +87,12 @@ acr122_get_scardcontext(void)
|
|||
}
|
||||
|
||||
void
|
||||
acr122_free_scardcontext(void)
|
||||
acr122_free_scardcontext (void)
|
||||
{
|
||||
if (_iSCardContextRefCount)
|
||||
{
|
||||
if (_iSCardContextRefCount) {
|
||||
_iSCardContextRefCount--;
|
||||
if (!_iSCardContextRefCount)
|
||||
{
|
||||
SCardReleaseContext(_SCardContext);
|
||||
if (!_iSCardContextRefCount) {
|
||||
SCardReleaseContext (_SCardContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,15 +104,15 @@ acr122_pick_device (void)
|
|||
nfc_device_desc_t *pndd;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
size_t szN;
|
||||
|
||||
if (!acr122_list_devices (pndd, 1, &szN)) {
|
||||
DBG("%s", "acr122_list_devices failed");
|
||||
DBG ("%s", "acr122_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
DBG("%s", "No device found");
|
||||
DBG ("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -133,30 +131,29 @@ acr122_pick_device (void)
|
|||
* @return true if succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
acr122_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
||||
{
|
||||
size_t szPos = 0;
|
||||
char acDeviceNames[256+64*DRIVERS_MAX_DEVICES];
|
||||
size_t szDeviceNamesLen = sizeof(acDeviceNames);
|
||||
size_t szPos = 0;
|
||||
char acDeviceNames[256 + 64 * DRIVERS_MAX_DEVICES];
|
||||
size_t szDeviceNamesLen = sizeof (acDeviceNames);
|
||||
uint32_t uiBusIndex = 0;
|
||||
SCARDCONTEXT *pscc;
|
||||
bool bSupported;
|
||||
int i;
|
||||
bool bSupported;
|
||||
int i;
|
||||
|
||||
// Clear the reader list
|
||||
memset(acDeviceNames, '\0', szDeviceNamesLen);
|
||||
memset (acDeviceNames, '\0', szDeviceNamesLen);
|
||||
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
// Test if context succeeded
|
||||
if (!(pscc = acr122_get_scardcontext ()))
|
||||
{
|
||||
DBG("%s","PCSC context not found");
|
||||
if (!(pscc = acr122_get_scardcontext ())) {
|
||||
DBG ("%s", "PCSC context not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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):");
|
||||
|
||||
|
@ -167,22 +164,19 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
|||
|
||||
bSupported = false;
|
||||
for (i = 0; supported_devices[i] && !bSupported; i++) {
|
||||
int l = strlen(supported_devices[i]);
|
||||
bSupported = 0 == strncmp(supported_devices[i], acDeviceNames + szPos, l);
|
||||
int l = strlen (supported_devices[i]);
|
||||
bSupported = 0 == strncmp (supported_devices[i], acDeviceNames + szPos, l);
|
||||
}
|
||||
|
||||
if (bSupported)
|
||||
{
|
||||
if (bSupported) {
|
||||
// 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].pcDriver = ACR122_DRIVER_NAME;
|
||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||
(*pszDeviceFound)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
|
||||
} else {
|
||||
DBG ("PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
|
||||
}
|
||||
|
||||
// Find next device name position
|
||||
|
@ -190,52 +184,54 @@ acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *p
|
|||
}
|
||||
acr122_free_scardcontext ();
|
||||
|
||||
if(*pszDeviceFound)
|
||||
if (*pszDeviceFound)
|
||||
return true;
|
||||
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* pas;
|
||||
char* pcFirmware;
|
||||
acr122_spec_t *pas;
|
||||
char *pcFirmware;
|
||||
|
||||
SCARDCONTEXT *pscc;
|
||||
|
||||
DBG("Attempt to connect to %s",pndd->acDevice);
|
||||
DBG ("Attempt to connect to %s", pndd->acDevice);
|
||||
// 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
|
||||
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
|
||||
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.
|
||||
DBG("%s","PCSC connect failed");
|
||||
DBG ("%s", "PCSC connect failed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Configure I/O settings for card communication
|
||||
as.ioCard.cbPciLength = sizeof(SCARD_IO_REQUEST);
|
||||
as.ioCard.cbPciLength = sizeof (SCARD_IO_REQUEST);
|
||||
|
||||
// Retrieve the current firmware version
|
||||
pcFirmware = acr122_firmware((nfc_device_t*)&as);
|
||||
if (strstr(pcFirmware,FIRMWARE_TEXT) != NULL)
|
||||
{
|
||||
pcFirmware = acr122_firmware ((nfc_device_t *) & as);
|
||||
if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
|
||||
// Allocate memory and store the device specification
|
||||
pas = malloc(sizeof(acr122_spec_t));
|
||||
pas = malloc (sizeof (acr122_spec_t));
|
||||
*pas = as;
|
||||
|
||||
// Done, we found the reader we are looking for
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strcpy(pnd->acName,pndd->acDevice);
|
||||
strcpy(pnd->acName + strlen(pnd->acName)," / ");
|
||||
strcpy(pnd->acName + strlen(pnd->acName),pcFirmware);
|
||||
pnd = malloc (sizeof (nfc_device_t));
|
||||
strcpy (pnd->acName, pndd->acDevice);
|
||||
strcpy (pnd->acName + strlen (pnd->acName), " / ");
|
||||
strcpy (pnd->acName + strlen (pnd->acName), pcFirmware);
|
||||
pnd->nc = NC_PN532;
|
||||
pnd->nds = (nfc_device_spec_t)pas;
|
||||
pnd->nds = (nfc_device_spec_t) pas;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
|
@ -246,23 +242,25 @@ nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd)
|
|||
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;
|
||||
SCardDisconnect(pas->hCard,SCARD_LEAVE_CARD);
|
||||
acr122_spec_t *pas = (acr122_spec_t *) pnd->nds;
|
||||
SCardDisconnect (pas->hCard, SCARD_LEAVE_CARD);
|
||||
acr122_free_scardcontext ();
|
||||
free(pas);
|
||||
free(pnd);
|
||||
free (pas);
|
||||
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 };
|
||||
size_t szRxCmdLen = sizeof(abtRxCmd);
|
||||
byte_t abtRxBuf[ACR122_RESPONSE_LEN];
|
||||
size_t szRxBufLen;
|
||||
byte_t abtTxBuf[ACR122_WRAP_LEN+ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00 };
|
||||
acr122_spec_t* pas = (acr122_spec_t*)pnd->nds;
|
||||
byte_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
|
||||
size_t szRxCmdLen = sizeof (abtRxCmd);
|
||||
byte_t abtRxBuf[ACR122_RESPONSE_LEN];
|
||||
size_t szRxBufLen;
|
||||
byte_t abtTxBuf[ACR122_WRAP_LEN + ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00 };
|
||||
acr122_spec_t *pas = (acr122_spec_t *) pnd->nds;
|
||||
|
||||
// FIXME: Should be handled by the library.
|
||||
// Make sure the command does not overflow the send buffer
|
||||
|
@ -270,111 +268,116 @@ bool acr122_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
|||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store the length of the command we are going to send
|
||||
abtTxBuf[4] = szTxLen;
|
||||
|
||||
// Prepare and transmit the send buffer
|
||||
memcpy(abtTxBuf+5,pbtTx,szTxLen);
|
||||
szRxBufLen = sizeof(abtRxBuf);
|
||||
memcpy (abtTxBuf + 5, pbtTx, szTxLen);
|
||||
szRxBufLen = sizeof (abtRxBuf);
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTxBuf,szTxLen+5);
|
||||
PRINT_HEX ("TX", abtTxBuf, szTxLen + 5);
|
||||
#endif
|
||||
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
{
|
||||
if (SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtTxBuf,szTxLen+5,abtRxBuf,szRxBufLen,(void*)&szRxBufLen) != SCARD_S_SUCCESS) {
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||
if (SCardControl
|
||||
(pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTxLen + 5, abtRxBuf, szRxBufLen,
|
||||
(void *) &szRxBufLen) != SCARD_S_SUCCESS) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
} 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;
|
||||
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
|
||||
if (szRxBufLen != 2) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the operation was successful, so an answer is available
|
||||
if (*abtRxBuf == SCARD_OPERATION_ERROR) {
|
||||
pnd->iLastError = DEISERRFRAME;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve the response bytes
|
||||
abtRxCmd[4] = abtRxBuf[1];
|
||||
szRxBufLen = sizeof(abtRxBuf);
|
||||
if (SCardTransmit(pas->hCard,&(pas->ioCard),abtRxCmd,szRxCmdLen,NULL,abtRxBuf,(void*)&szRxBufLen) != SCARD_S_SUCCESS) {
|
||||
szRxBufLen = sizeof (abtRxBuf);
|
||||
if (SCardTransmit (pas->hCard, &(pas->ioCard), abtRxCmd, szRxCmdLen, NULL, abtRxBuf, (void *) &szRxBufLen) !=
|
||||
SCARD_S_SUCCESS) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||
#endif
|
||||
|
||||
// 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
|
||||
if (szRxBufLen < 4 || (szRxBufLen-4) > *pszRxLen) {
|
||||
if (szRxBufLen < 4 || (szRxBufLen - 4) > *pszRxLen) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
// Wipe out the 4 APDU emulation bytes: D5 4B .. .. .. 90 00
|
||||
*pszRxLen = ((size_t)szRxBufLen)-4;
|
||||
memcpy(pbtRx,abtRxBuf+2,*pszRxLen);
|
||||
*pszRxLen = ((size_t) szRxBufLen) - 4;
|
||||
memcpy (pbtRx, abtRxBuf + 2, *pszRxLen);
|
||||
|
||||
// Transmission went successful
|
||||
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;
|
||||
|
||||
acr122_spec_t* pas = (acr122_spec_t*)nds;
|
||||
acr122_spec_t *pas = (acr122_spec_t *) nds;
|
||||
static char abtFw[11];
|
||||
size_t szFwLen = sizeof(abtFw);
|
||||
memset(abtFw,0x00,szFwLen);
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
{
|
||||
uiResult = SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtGetFw,sizeof(abtGetFw),abtFw,szFwLen,(void*)&szFwLen);
|
||||
size_t szFwLen = sizeof (abtFw);
|
||||
memset (abtFw, 0x00, szFwLen);
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||
uiResult =
|
||||
SCardControl (pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof (abtGetFw), abtFw, szFwLen,
|
||||
(void *) &szFwLen);
|
||||
} 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
|
||||
if (uiResult != SCARD_S_SUCCESS)
|
||||
{
|
||||
printf("No ACR122 firmware received, Error: %08x\n",uiResult);
|
||||
#ifdef DEBUG
|
||||
if (uiResult != SCARD_S_SUCCESS) {
|
||||
printf ("No ACR122 firmware received, Error: %08x\n", uiResult);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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 };
|
||||
acr122_spec_t* pas = (acr122_spec_t*)nds;
|
||||
byte_t abtBuf[2];
|
||||
size_t szBufLen = sizeof(abtBuf);
|
||||
(void)bOn;
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED)
|
||||
{
|
||||
return (SCardControl(pas->hCard,IOCTL_CCID_ESCAPE_SCARD_CTL_CODE,abtLed,sizeof(abtLed),abtBuf,szBufLen,(void*)&szBufLen) == SCARD_S_SUCCESS);
|
||||
byte_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
||||
acr122_spec_t *pas = (acr122_spec_t *) nds;
|
||||
byte_t abtBuf[2];
|
||||
size_t szBufLen = sizeof (abtBuf);
|
||||
(void) bOn;
|
||||
if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
|
||||
return (SCardControl
|
||||
(pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtLed, sizeof (abtLed), abtBuf, szBufLen,
|
||||
(void *) &szBufLen) == SCARD_S_SUCCESS);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,29 +22,29 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_ACR122_H__
|
||||
#define __NFC_DRIVER_ACR122_H__
|
||||
# define __NFC_DRIVER_ACR122_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
# include <stdint.h>
|
||||
# include <stdbool.h>
|
||||
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#define ACR122_DRIVER_NAME "ACR122"
|
||||
# define ACR122_DRIVER_NAME "ACR122"
|
||||
|
||||
nfc_device_desc_t* acr122_pick_device(void);
|
||||
bool acr122_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t *acr122_pick_device (void);
|
||||
bool acr122_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_t* acr122_connect(const nfc_device_desc_t* pndd);
|
||||
void acr122_disconnect(nfc_device_t* pnd);
|
||||
nfc_device_t *acr122_connect (const nfc_device_desc_t * pndd);
|
||||
void acr122_disconnect (nfc_device_t * pnd);
|
||||
|
||||
// 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
|
||||
char* acr122_firmware(const nfc_device_spec_t nds);
|
||||
bool acr122_led_red(const nfc_device_spec_t nds, bool bOn);
|
||||
char *acr122_firmware (const nfc_device_spec_t nds);
|
||||
bool acr122_led_red (const nfc_device_spec_t nds, bool bOn);
|
||||
|
||||
#endif // ! __NFC_DRIVER_ACR122_H__
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include "../drivers.h"
|
||||
|
@ -69,7 +69,7 @@
|
|||
|
||||
#define SERIAL_DEFAULT_PORT_SPEED 9600
|
||||
|
||||
bool arygon_check_communication(const nfc_device_spec_t nds);
|
||||
bool arygon_check_communication (const nfc_device_spec_t nds);
|
||||
|
||||
/**
|
||||
* @note ARYGON-ADRA (PN531): ???,n,8,1
|
||||
|
@ -84,15 +84,15 @@ arygon_pick_device (void)
|
|||
nfc_device_desc_t *pndd;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
size_t szN;
|
||||
|
||||
if (!arygon_list_devices (pndd, 1, &szN)) {
|
||||
DBG("%s", "arygon_list_devices failed");
|
||||
DBG ("%s", "arygon_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
DBG("%s", "No device found");
|
||||
DBG ("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -101,79 +101,87 @@ arygon_pick_device (void)
|
|||
}
|
||||
|
||||
bool
|
||||
arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
arygon_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
||||
{
|
||||
/** @note: Due to UART bus we can't know if its really a pn532 without
|
||||
* sending some PN53x commands. But using this way to probe devices, we can
|
||||
* have serious problem with other device on this bus */
|
||||
#ifndef SERIAL_AUTOPROBE_ENABLED
|
||||
(void)pnddDevices;
|
||||
(void)szDevices;
|
||||
(void) pnddDevices;
|
||||
(void) szDevices;
|
||||
*pszDeviceFound = 0;
|
||||
DBG("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||
DBG ("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||
return false;
|
||||
#else /* SERIAL_AUTOPROBE_ENABLED */
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
serial_port sp;
|
||||
const char* pcPorts[] = DEFAULT_SERIAL_PORTS;
|
||||
const char* pcPort;
|
||||
int iDevice = 0;
|
||||
const char *pcPorts[] = DEFAULT_SERIAL_PORTS;
|
||||
const char *pcPort;
|
||||
int iDevice = 0;
|
||||
|
||||
while( (pcPort = pcPorts[iDevice++]) ) {
|
||||
sp = uart_open(pcPort);
|
||||
DBG("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
|
||||
while ((pcPort = pcPorts[iDevice++])) {
|
||||
sp = uart_open (pcPort);
|
||||
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))
|
||||
{
|
||||
uart_set_speed(sp, SERIAL_DEFAULT_PORT_SPEED);
|
||||
if(!arygon_check_communication((nfc_device_spec_t)sp)) continue;
|
||||
uart_close(sp);
|
||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||
uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
|
||||
if (!arygon_check_communication ((nfc_device_spec_t) sp))
|
||||
continue;
|
||||
uart_close (sp);
|
||||
|
||||
// ARYGON reader is found
|
||||
snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "ARYGON", pcPort);
|
||||
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "ARYGON", pcPort);
|
||||
pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
|
||||
pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
|
||||
pnddDevices[*pszDeviceFound].pcPort = strdup(pcPort);
|
||||
pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort);
|
||||
pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED;
|
||||
DBG("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice);
|
||||
DBG ("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice);
|
||||
(*pszDeviceFound)++;
|
||||
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if((*pszDeviceFound) >= szDevices) break;
|
||||
if ((*pszDeviceFound) >= szDevices)
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s", pcPort);
|
||||
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s", pcPort);
|
||||
#endif /* DEBUG */
|
||||
# ifdef DEBUG
|
||||
if (sp == INVALID_SERIAL_PORT)
|
||||
DBG ("Invalid serial port: %s", pcPort);
|
||||
if (sp == CLAIMED_SERIAL_PORT)
|
||||
DBG ("Serial port already claimed: %s", pcPort);
|
||||
# endif
|
||||
/* DEBUG */
|
||||
}
|
||||
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
||||
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;
|
||||
nfc_device_t* pnd = NULL;
|
||||
nfc_device_t *pnd = NULL;
|
||||
|
||||
DBG("Attempt to connect to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open(pndd->pcPort);
|
||||
DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open (pndd->pcPort);
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
|
||||
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort);
|
||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
|
||||
if (sp == INVALID_SERIAL_PORT)
|
||||
ERR ("Invalid serial port: %s", pndd->pcPort);
|
||||
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);
|
||||
|
||||
DBG("Successfully connected to: %s",pndd->pcPort);
|
||||
DBG ("Successfully connected to: %s", pndd->pcPort);
|
||||
|
||||
// We have a connection
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strncpy(pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
|
||||
pnd = malloc (sizeof (nfc_device_t));
|
||||
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
|
||||
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
|
||||
|
||||
pnd->nc = NC_PN532;
|
||||
pnd->nds = (nfc_device_spec_t)sp;
|
||||
pnd->nds = (nfc_device_spec_t) sp;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
|
@ -181,19 +189,21 @@ nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd)
|
|||
return pnd;
|
||||
}
|
||||
|
||||
void arygon_disconnect(nfc_device_t* pnd)
|
||||
void
|
||||
arygon_disconnect (nfc_device_t * pnd)
|
||||
{
|
||||
uart_close((serial_port)pnd->nds);
|
||||
free(pnd);
|
||||
uart_close ((serial_port) pnd->nds);
|
||||
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 abtRxBuf[BUFFER_LENGTH];
|
||||
size_t szRxBufLen = BUFFER_LENGTH;
|
||||
size_t szPos;
|
||||
int res;
|
||||
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];
|
||||
size_t szRxBufLen = BUFFER_LENGTH;
|
||||
size_t szPos;
|
||||
int res;
|
||||
// TODO: Move this one level up for libnfc-1.6
|
||||
uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
|
||||
|
@ -202,57 +212,55 @@ bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
|||
// Packet length checksum
|
||||
abtTxBuf[5] = BUFFER_LENGTH - abtTxBuf[4];
|
||||
// Copy the PN53X command into the packet buffer
|
||||
memmove(abtTxBuf+6,pbtTx,szTxLen);
|
||||
memmove (abtTxBuf + 6, pbtTx, szTxLen);
|
||||
|
||||
// Calculate data payload checksum
|
||||
abtTxBuf[szTxLen+6] = 0;
|
||||
for(szPos=0; szPos < szTxLen; szPos++) {
|
||||
abtTxBuf[szTxLen+6] -= abtTxBuf[szPos+6];
|
||||
abtTxBuf[szTxLen + 6] = 0;
|
||||
for (szPos = 0; szPos < szTxLen; szPos++) {
|
||||
abtTxBuf[szTxLen + 6] -= abtTxBuf[szPos + 6];
|
||||
}
|
||||
|
||||
// End of stream marker
|
||||
abtTxBuf[szTxLen+7] = 0;
|
||||
abtTxBuf[szTxLen + 7] = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTxBuf,szTxLen+8);
|
||||
PRINT_HEX ("TX", abtTxBuf, szTxLen + 8);
|
||||
#endif
|
||||
res = uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+8);
|
||||
res = uart_send ((serial_port) pnd->nds, abtTxBuf, szTxLen + 8);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
ERR ("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bzero(abtRxBuf, sizeof(abtRxBuf));
|
||||
bzero (abtRxBuf, sizeof (abtRxBuf));
|
||||
#endif
|
||||
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||
res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||
#endif
|
||||
|
||||
// WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time
|
||||
if (!pn53x_transceive_check_ack_frame_callback(pnd, abtRxBuf, szRxBufLen))
|
||||
if (!pn53x_transceive_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
|
||||
szRxBufLen -= sizeof(ack_frame);
|
||||
memmove(abtRxBuf, abtRxBuf+sizeof(ack_frame), szRxBufLen);
|
||||
|
||||
szRxBufLen -= sizeof (ack_frame);
|
||||
memmove (abtRxBuf, abtRxBuf + sizeof (ack_frame), szRxBufLen);
|
||||
|
||||
if (szRxBufLen == 0) {
|
||||
szRxBufLen = BUFFER_LENGTH;
|
||||
do {
|
||||
delay_ms(10);
|
||||
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||
} while (res != 0 );
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
#endif
|
||||
delay_ms (10);
|
||||
res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
|
||||
} while (res != 0);
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -266,56 +274,61 @@ bool arygon_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTx
|
|||
return false;
|
||||
}
|
||||
*/
|
||||
if (!pn53x_transceive_check_error_frame_callback(pnd, abtRxBuf, szRxBufLen))
|
||||
if (!pn53x_transceive_check_error_frame_callback (pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
|
||||
// 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)
|
||||
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)
|
||||
*pszRxLen = szRxBufLen - 9;
|
||||
memcpy(pbtRx, abtRxBuf+7, *pszRxLen);
|
||||
memcpy (pbtRx, abtRxBuf + 7, *pszRxLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO Use tranceive function instead of raw uart send/receive for communication check.
|
||||
bool
|
||||
arygon_check_communication(const nfc_device_spec_t nds)
|
||||
arygon_check_communication (const nfc_device_spec_t nds)
|
||||
{
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
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};
|
||||
int res;
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
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 };
|
||||
int res;
|
||||
|
||||
/** 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
|
||||
PRINT_HEX("TX", pncmd_communication_test,sizeof(pncmd_communication_test));
|
||||
PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
|
||||
#endif
|
||||
res = uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test));
|
||||
res = uart_send ((serial_port) nds, pncmd_communication_test, sizeof (pncmd_communication_test));
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
ERR ("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
res = uart_receive((serial_port)nds,abtRx,&szRxLen);
|
||||
|
||||
res = uart_receive ((serial_port) nds, abtRx, &szRxLen);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,szRxLen);
|
||||
PRINT_HEX ("RX", abtRx, szRxLen);
|
||||
#endif
|
||||
|
||||
if(0 != memcmp(abtRx,attempted_result,sizeof(attempted_result))) {
|
||||
DBG("%s", "Communication test failed, result doesn't match to attempted one.");
|
||||
if (0 != memcmp (abtRx, attempted_result, sizeof (attempted_result))) {
|
||||
DBG ("%s", "Communication test failed, result doesn't match to attempted one.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,21 +22,21 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_ARYGON_H__
|
||||
#define __NFC_DRIVER_ARYGON_H__
|
||||
# define __NFC_DRIVER_ARYGON_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#define ARYGON_DRIVER_NAME "ARYGON"
|
||||
# define ARYGON_DRIVER_NAME "ARYGON"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_desc_t * arygon_pick_device (void);
|
||||
bool arygon_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t *arygon_pick_device (void);
|
||||
bool arygon_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
|
||||
nfc_device_t* arygon_connect(const nfc_device_desc_t* pndd);
|
||||
void arygon_disconnect(nfc_device_t* pnd);
|
||||
nfc_device_t *arygon_connect (const nfc_device_desc_t * pndd);
|
||||
void arygon_disconnect (nfc_device_t * pnd);
|
||||
|
||||
// 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__
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Thanks to d18c7db and Okko for example code
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -35,39 +35,41 @@ Thanks to d18c7db and Okko for example code
|
|||
#include "../drivers.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;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd))))
|
||||
{
|
||||
size_t szN;
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
|
||||
if (!pn531_usb_list_devices (pndd, 1, &szN))
|
||||
{
|
||||
DBG("%s", "pn531_usb_list_devices failed");
|
||||
if (!pn531_usb_list_devices (pndd, 1, &szN)) {
|
||||
DBG ("%s", "pn531_usb_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0)
|
||||
{
|
||||
DBG("%s", "No device found");
|
||||
if (szN == 0) {
|
||||
DBG ("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_PN531_USB_H__
|
||||
#define __NFC_DRIVER_PN531_USB_H__
|
||||
# define __NFC_DRIVER_PN531_USB_H__
|
||||
|
||||
#define PN531_USB_DRIVER_NAME "PN531_USB"
|
||||
# define PN531_USB_DRIVER_NAME "PN531_USB"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_t* pn531_usb_connect(const nfc_device_desc_t* pndd);
|
||||
bool pn531_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t * pn531_usb_pick_device (void);
|
||||
nfc_device_t *pn531_usb_connect (const nfc_device_desc_t * pndd);
|
||||
bool pn531_usb_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
nfc_device_desc_t *pn531_usb_pick_device (void);
|
||||
|
||||
#endif // ! __NFC_DRIVER_PN531_USB_H__
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include "../drivers.h"
|
||||
|
@ -43,8 +43,8 @@
|
|||
|
||||
#define SERIAL_DEFAULT_PORT_SPEED 115200
|
||||
|
||||
void pn532_uart_wakeup(const nfc_device_spec_t nds);
|
||||
bool pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success);
|
||||
void pn532_uart_wakeup (const nfc_device_spec_t nds);
|
||||
bool pn532_uart_check_communication (const nfc_device_spec_t nds, bool * success);
|
||||
|
||||
nfc_device_desc_t *
|
||||
pn532_uart_pick_device (void)
|
||||
|
@ -52,15 +52,15 @@ pn532_uart_pick_device (void)
|
|||
nfc_device_desc_t *pndd;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
size_t szN;
|
||||
|
||||
if (!pn532_uart_list_devices (pndd, 1, &szN)) {
|
||||
DBG("%s", "pn532_uart_list_devices failed");
|
||||
DBG ("%s", "pn532_uart_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
DBG("%s", "No device found");
|
||||
DBG ("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -69,95 +69,102 @@ pn532_uart_pick_device (void)
|
|||
}
|
||||
|
||||
bool
|
||||
pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
pn532_uart_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
||||
{
|
||||
/** @note: Due to UART bus we can't know if its really a pn532 without
|
||||
* sending some PN53x commands. But using this way to probe devices, we can
|
||||
* have serious problem with other device on this bus */
|
||||
#ifndef SERIAL_AUTOPROBE_ENABLED
|
||||
(void)pnddDevices;
|
||||
(void)szDevices;
|
||||
(void) pnddDevices;
|
||||
(void) szDevices;
|
||||
*pszDeviceFound = 0;
|
||||
DBG("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||
DBG ("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
|
||||
return false;
|
||||
#else /* SERIAL_AUTOPROBE_ENABLED */
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
serial_port sp;
|
||||
const char* pcPorts[] = DEFAULT_SERIAL_PORTS;
|
||||
const char* pcPort;
|
||||
int iDevice = 0;
|
||||
|
||||
while( (pcPort = pcPorts[iDevice++]) ) {
|
||||
sp = uart_open(pcPort);
|
||||
DBG("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
|
||||
const char *pcPorts[] = DEFAULT_SERIAL_PORTS;
|
||||
const char *pcPort;
|
||||
int iDevice = 0;
|
||||
|
||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT))
|
||||
{
|
||||
bool bComOk;
|
||||
while ((pcPort = pcPorts[iDevice++])) {
|
||||
sp = uart_open (pcPort);
|
||||
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)) {
|
||||
bool bComOk;
|
||||
// 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);
|
||||
// PN532 could be powered down, we need to wake it up before line testing.
|
||||
pn532_uart_wakeup((nfc_device_spec_t)sp);
|
||||
pn532_uart_wakeup ((nfc_device_spec_t) sp);
|
||||
// Check communication using "Diagnose" command, with "Comunication test" (0x00)
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp, &bComOk))
|
||||
if (!pn532_uart_check_communication ((nfc_device_spec_t) sp, &bComOk))
|
||||
return false;
|
||||
if (!bComOk)
|
||||
continue;
|
||||
uart_close(sp);
|
||||
uart_close (sp);
|
||||
|
||||
snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", pcPort);
|
||||
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", pcPort);
|
||||
pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
|
||||
pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME;
|
||||
pnddDevices[*pszDeviceFound].pcPort = strdup(pcPort);
|
||||
pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort);
|
||||
pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED;
|
||||
DBG("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice);
|
||||
DBG ("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice);
|
||||
(*pszDeviceFound)++;
|
||||
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if((*pszDeviceFound) >= szDevices) break;
|
||||
if ((*pszDeviceFound) >= szDevices)
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (sp == INVALID_SERIAL_PORT) DBG("Invalid serial port: %s", pcPort);
|
||||
if (sp == CLAIMED_SERIAL_PORT) DBG("Serial port already claimed: %s", pcPort);
|
||||
#endif /* DEBUG */
|
||||
# ifdef DEBUG
|
||||
if (sp == INVALID_SERIAL_PORT)
|
||||
DBG ("Invalid serial port: %s", pcPort);
|
||||
if (sp == CLAIMED_SERIAL_PORT)
|
||||
DBG ("Serial port already claimed: %s", pcPort);
|
||||
# endif
|
||||
/* DEBUG */
|
||||
}
|
||||
#endif /* SERIAL_AUTOPROBE_ENABLED */
|
||||
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;
|
||||
nfc_device_t* pnd = NULL;
|
||||
bool bComOk;
|
||||
nfc_device_t *pnd = NULL;
|
||||
bool bComOk;
|
||||
|
||||
DBG("Attempt to connect to: %s at %d bauds.",pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open(pndd->pcPort);
|
||||
DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
|
||||
sp = uart_open (pndd->pcPort);
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT) ERR("Invalid serial port: %s",pndd->pcPort);
|
||||
if (sp == CLAIMED_SERIAL_PORT) ERR("Serial port already claimed: %s",pndd->pcPort);
|
||||
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) return NULL;
|
||||
if (sp == INVALID_SERIAL_PORT)
|
||||
ERR ("Invalid serial port: %s", pndd->pcPort);
|
||||
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);
|
||||
|
||||
// PN532 could be powered down, we need to wake it up before line testing.
|
||||
pn532_uart_wakeup((nfc_device_spec_t)sp);
|
||||
pn532_uart_wakeup ((nfc_device_spec_t) sp);
|
||||
// Check communication using "Diagnose" command, with "Comunication test" (0x00)
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp, &bComOk))
|
||||
return NULL;
|
||||
if (!pn532_uart_check_communication ((nfc_device_spec_t) sp, &bComOk))
|
||||
return NULL;
|
||||
if (!bComOk)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
DBG("Successfully connected to: %s",pndd->pcPort);
|
||||
DBG ("Successfully connected to: %s", pndd->pcPort);
|
||||
|
||||
// We have a connection
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strncpy(pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
|
||||
pnd = malloc (sizeof (nfc_device_t));
|
||||
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
|
||||
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
|
||||
|
||||
pnd->nc = NC_PN532;
|
||||
pnd->nds = (nfc_device_spec_t)sp;
|
||||
pnd->nds = (nfc_device_spec_t) sp;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
|
@ -165,19 +172,22 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
return pnd;
|
||||
}
|
||||
|
||||
void pn532_uart_disconnect(nfc_device_t* pnd)
|
||||
void
|
||||
pn532_uart_disconnect (nfc_device_t * pnd)
|
||||
{
|
||||
uart_close((serial_port)pnd->nds);
|
||||
free(pnd);
|
||||
uart_close ((serial_port) pnd->nds);
|
||||
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 abtRxBuf[BUFFER_LENGTH];
|
||||
size_t szRxBufLen = BUFFER_LENGTH;
|
||||
size_t szPos;
|
||||
int res;
|
||||
byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRxBuf[BUFFER_LENGTH];
|
||||
size_t szRxBufLen = BUFFER_LENGTH;
|
||||
size_t szPos;
|
||||
int res;
|
||||
// TODO: Move this one level up for libnfc-1.6
|
||||
uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
|
||||
|
@ -186,63 +196,60 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
|||
// Packet length checksum
|
||||
abtTxBuf[4] = BUFFER_LENGTH - abtTxBuf[3];
|
||||
// Copy the PN53X command into the packet buffer
|
||||
memmove(abtTxBuf+5,pbtTx,szTxLen);
|
||||
memmove (abtTxBuf + 5, pbtTx, szTxLen);
|
||||
|
||||
// Calculate data payload checksum
|
||||
abtTxBuf[szTxLen+5] = 0;
|
||||
for(szPos=0; szPos < szTxLen; szPos++)
|
||||
{
|
||||
abtTxBuf[szTxLen+5] -= abtTxBuf[szPos+5];
|
||||
abtTxBuf[szTxLen + 5] = 0;
|
||||
for (szPos = 0; szPos < szTxLen; szPos++) {
|
||||
abtTxBuf[szTxLen + 5] -= abtTxBuf[szPos + 5];
|
||||
}
|
||||
|
||||
// End of stream marker
|
||||
abtTxBuf[szTxLen+6] = 0;
|
||||
abtTxBuf[szTxLen + 6] = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTxBuf,szTxLen+7);
|
||||
PRINT_HEX ("TX", abtTxBuf, szTxLen + 7);
|
||||
#endif
|
||||
res = uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+7);
|
||||
if(res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||
res = uart_send ((serial_port) pnd->nds, abtTxBuf, szTxLen + 7);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
ERR ("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
||||
res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
|
||||
if (res != 0) {
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||
#endif
|
||||
|
||||
// WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time
|
||||
if (!pn53x_transceive_check_ack_frame_callback(pnd, abtRxBuf, szRxBufLen))
|
||||
if (!pn53x_transceive_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
|
||||
return false;
|
||||
szRxBufLen -= sizeof(ack_frame);
|
||||
memmove(abtRxBuf, abtRxBuf+sizeof(ack_frame), szRxBufLen);
|
||||
szRxBufLen -= sizeof (ack_frame);
|
||||
memmove (abtRxBuf, abtRxBuf + sizeof (ack_frame), szRxBufLen);
|
||||
|
||||
if (szRxBufLen == 0) {
|
||||
szRxBufLen = BUFFER_LENGTH;
|
||||
do {
|
||||
delay_ms(10);
|
||||
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||
} while (res != 0 );
|
||||
delay_ms (10);
|
||||
res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
|
||||
} while (res != 0);
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||
PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", ack_frame,6);
|
||||
PRINT_HEX ("TX", ack_frame, 6);
|
||||
#endif
|
||||
res = uart_send((serial_port)pnd->nds,ack_frame,6);
|
||||
res = uart_send ((serial_port) pnd->nds, ack_frame, 6);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
ERR ("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = res;
|
||||
return false;
|
||||
}
|
||||
|
@ -251,76 +258,79 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
|||
return false;
|
||||
|
||||
// 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)
|
||||
if(szRxBufLen < 9) {
|
||||
if (szRxBufLen < 9) {
|
||||
pnd->iLastError = DEINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||
*pszRxLen = szRxBufLen - 9;
|
||||
memcpy(pbtRx, abtRxBuf+7, *pszRxLen);
|
||||
memcpy (pbtRx, abtRxBuf + 7, *pszRxLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
pn532_uart_wakeup(const nfc_device_spec_t nds)
|
||||
pn532_uart_wakeup (const nfc_device_spec_t nds)
|
||||
{
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
size_t szRxLen;
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
size_t szRxLen;
|
||||
/** PN532C106 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) */
|
||||
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
|
||||
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
|
||||
uart_send((serial_port)nds, pncmd_pn532c106_wakeup_preamble, sizeof(pncmd_pn532c106_wakeup_preamble));
|
||||
if(0 == uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||
uart_send ((serial_port) nds, pncmd_pn532c106_wakeup_preamble, sizeof (pncmd_pn532c106_wakeup_preamble));
|
||||
if (0 == uart_receive ((serial_port) nds, abtRx, &szRxLen)) {
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,szRxLen);
|
||||
PRINT_HEX ("RX", abtRx, szRxLen);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||
pn532_uart_check_communication (const nfc_device_spec_t nds, bool * success)
|
||||
{
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
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};
|
||||
int res;
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
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 };
|
||||
int res;
|
||||
|
||||
/** 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;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", pncmd_communication_test,sizeof(pncmd_communication_test));
|
||||
PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
|
||||
#endif
|
||||
res = uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test));
|
||||
res = uart_send ((serial_port) nds, pncmd_communication_test, sizeof (pncmd_communication_test));
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
ERR ("%s", "Unable to transmit data. (TX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
res = uart_receive((serial_port)nds,abtRx,&szRxLen);
|
||||
|
||||
res = uart_receive ((serial_port) nds, abtRx, &szRxLen);
|
||||
if (res != 0) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
ERR ("%s", "Unable to receive data. (RX)");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,szRxLen);
|
||||
PRINT_HEX ("RX", abtRx, szRxLen);
|
||||
#endif
|
||||
|
||||
if(0 == memcmp(abtRx,attempted_result,sizeof(attempted_result)))
|
||||
if (0 == memcmp (abtRx, attempted_result, sizeof (attempted_result)))
|
||||
*success = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,21 +22,21 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_PN532_UART_H__
|
||||
#define __NFC_DRIVER_PN532_UART_H__
|
||||
# define __NFC_DRIVER_PN532_UART_H__
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
#define PN532_UART_DRIVER_NAME "PN532_UART"
|
||||
# define PN532_UART_DRIVER_NAME "PN532_UART"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_desc_t * pn532_uart_pick_device (void);
|
||||
bool pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t *pn532_uart_pick_device (void);
|
||||
bool pn532_uart_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
|
||||
nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd);
|
||||
void pn532_uart_disconnect(nfc_device_t* pnd);
|
||||
nfc_device_t *pn532_uart_connect (const nfc_device_desc_t * pndd);
|
||||
void pn532_uart_disconnect (nfc_device_t * pnd);
|
||||
|
||||
// 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__
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Thanks to d18c7db and Okko for example code
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -35,20 +35,21 @@ Thanks to d18c7db and Okko for example code
|
|||
#include "../drivers.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;
|
||||
|
||||
if ((pndd = malloc (sizeof (*pndd)))) {
|
||||
size_t szN;
|
||||
size_t szN;
|
||||
|
||||
if (!pn533_usb_list_devices (pndd, 1, &szN)) {
|
||||
DBG("%s", "pn533_usb_list_devices failed");
|
||||
DBG ("%s", "pn533_usb_list_devices failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (szN == 0) {
|
||||
DBG("%s", "No device found");
|
||||
DBG ("%s", "No device found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -56,16 +57,20 @@ nfc_device_desc_t * pn533_usb_pick_device (void)
|
|||
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
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,13 @@
|
|||
*/
|
||||
|
||||
#ifndef __NFC_DRIVER_PN533_USB_H__
|
||||
#define __NFC_DRIVER_PN533_USB_H__
|
||||
# define __NFC_DRIVER_PN533_USB_H__
|
||||
|
||||
#define PN533_USB_DRIVER_NAME "PN533_USB"
|
||||
# define PN533_USB_DRIVER_NAME "PN533_USB"
|
||||
|
||||
// Functions used by developer to handle connection to this device
|
||||
nfc_device_t* pn533_usb_connect(const nfc_device_desc_t* pndd);
|
||||
bool pn533_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound);
|
||||
nfc_device_desc_t * pn533_usb_pick_device (void);
|
||||
nfc_device_t *pn533_usb_connect (const nfc_device_desc_t * pndd);
|
||||
bool pn533_usb_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
|
||||
nfc_device_desc_t *pn533_usb_pick_device (void);
|
||||
|
||||
#endif // ! __NFC_DRIVER_PN533_USB_H__
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
/*
|
||||
|
@ -46,113 +46,109 @@ Thanks to d18c7db and Okko for example code
|
|||
#define USB_TIMEOUT 30000
|
||||
|
||||
// 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 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
|
||||
for(uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++)
|
||||
{
|
||||
for (uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++) {
|
||||
// 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
|
||||
uiEndPoint = puid->endpoint[uiIndex].bEndpointAddress;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_device *dev;
|
||||
usb_dev_handle *udev;
|
||||
uint32_t uiBusIndex = 0;
|
||||
char string[256];
|
||||
char string[256];
|
||||
|
||||
string[0]= '\0';
|
||||
usb_init();
|
||||
string[0] = '\0';
|
||||
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).
|
||||
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).
|
||||
if ((ret= usb_find_devices() < 0)) return false;
|
||||
if ((ret = usb_find_devices () < 0))
|
||||
return false;
|
||||
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++)
|
||||
{
|
||||
for(i = 0; i < num_candidates; ++i)
|
||||
{
|
||||
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++) {
|
||||
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);
|
||||
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
|
||||
// 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
|
||||
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
|
||||
continue;
|
||||
}
|
||||
if (dev->descriptor.iManufacturer || dev->descriptor.iProduct)
|
||||
{
|
||||
udev = usb_open(dev);
|
||||
if(udev)
|
||||
{
|
||||
usb_get_string_simple(udev, dev->descriptor.iManufacturer, string, sizeof(string));
|
||||
if(strlen(string) > 0)
|
||||
strcpy(string + strlen(string)," / ");
|
||||
usb_get_string_simple(udev, dev->descriptor.iProduct, string + strlen(string), sizeof(string) - strlen(string));
|
||||
if (dev->descriptor.iManufacturer || dev->descriptor.iProduct) {
|
||||
udev = usb_open (dev);
|
||||
if (udev) {
|
||||
usb_get_string_simple (udev, dev->descriptor.iManufacturer, string, sizeof (string));
|
||||
if (strlen (string) > 0)
|
||||
strcpy (string + strlen (string), " / ");
|
||||
usb_get_string_simple (udev, dev->descriptor.iProduct, string + strlen (string),
|
||||
sizeof (string) - strlen (string));
|
||||
}
|
||||
usb_close(udev);
|
||||
usb_close (udev);
|
||||
}
|
||||
if(strlen(string) == 0)
|
||||
strcpy(pnddDevices[*pszDeviceFound].acDevice, target_name);
|
||||
if (strlen (string) == 0)
|
||||
strcpy (pnddDevices[*pszDeviceFound].acDevice, target_name);
|
||||
else
|
||||
strcpy(pnddDevices[*pszDeviceFound].acDevice, string);
|
||||
strcpy (pnddDevices[*pszDeviceFound].acDevice, string);
|
||||
pnddDevices[*pszDeviceFound].pcDriver = target_name;
|
||||
pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
|
||||
(*pszDeviceFound)++;
|
||||
// Test if we reach the maximum "wanted" devices
|
||||
if((*pszDeviceFound) == szDevices)
|
||||
{
|
||||
if ((*pszDeviceFound) == szDevices) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(*pszDeviceFound)
|
||||
if (*pszDeviceFound)
|
||||
return true;
|
||||
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;
|
||||
usb_spec_t* pus;
|
||||
nfc_device_t *pnd = NULL;
|
||||
usb_spec_t *pus;
|
||||
usb_spec_t us;
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
|
@ -162,44 +158,39 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * targe
|
|||
us.uiEndPointOut = 0;
|
||||
us.pudh = NULL;
|
||||
|
||||
DBG("Attempt to connect to %s device", target_name);
|
||||
usb_init();
|
||||
DBG ("Attempt to connect to %s device", target_name);
|
||||
usb_init ();
|
||||
|
||||
uiBusIndex= pndd->uiBusIndex;
|
||||
uiBusIndex = pndd->uiBusIndex;
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--)
|
||||
{
|
||||
for (bus = usb_get_busses (); bus; bus = bus->next) {
|
||||
for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--) {
|
||||
// DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
|
||||
if(uiBusIndex == 0)
|
||||
{
|
||||
if (uiBusIndex == 0) {
|
||||
// Open the USB device
|
||||
us.pudh = usb_open(dev);
|
||||
us.pudh = usb_open (dev);
|
||||
|
||||
get_end_points(dev,&us);
|
||||
if(usb_set_configuration(us.pudh,1) < 0)
|
||||
{
|
||||
DBG("%s", "Setting config failed");
|
||||
usb_close(us.pudh);
|
||||
get_end_points (dev, &us);
|
||||
if (usb_set_configuration (us.pudh, 1) < 0) {
|
||||
DBG ("%s", "Setting config failed");
|
||||
usb_close (us.pudh);
|
||||
// we failed to use the specified device
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(usb_claim_interface(us.pudh,0) < 0)
|
||||
{
|
||||
DBG("%s", "Can't claim interface");
|
||||
usb_close(us.pudh);
|
||||
if (usb_claim_interface (us.pudh, 0) < 0) {
|
||||
DBG ("%s", "Can't claim interface");
|
||||
usb_close (us.pudh);
|
||||
// we failed to use the specified device
|
||||
return NULL;
|
||||
}
|
||||
// Allocate memory for the device info and specification, fill it and return the info
|
||||
pus = malloc(sizeof(usb_spec_t));
|
||||
pus = malloc (sizeof (usb_spec_t));
|
||||
*pus = us;
|
||||
pnd = malloc(sizeof(nfc_device_t));
|
||||
strcpy(pnd->acName,target_name);
|
||||
pnd = malloc (sizeof (nfc_device_t));
|
||||
strcpy (pnd->acName, target_name);
|
||||
pnd->nc = target_chip;
|
||||
pnd->nds = (nfc_device_spec_t)pus;
|
||||
pnd->nds = (nfc_device_spec_t) pus;
|
||||
pnd->bActive = true;
|
||||
pnd->bCrc = true;
|
||||
pnd->bPar = true;
|
||||
|
@ -209,38 +200,40 @@ nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * targe
|
|||
}
|
||||
}
|
||||
// We ran out of devices before the index required
|
||||
DBG("%s","Device index not found!");
|
||||
DBG ("%s", "Device index not found!");
|
||||
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;
|
||||
int ret;
|
||||
usb_spec_t *pus = (usb_spec_t *) pnd->nds;
|
||||
int ret;
|
||||
|
||||
if((ret = usb_release_interface(pus->pudh,0)) < 0) {
|
||||
ERR("usb_release_interface failed (%i)",ret);
|
||||
if ((ret = usb_release_interface (pus->pudh, 0)) < 0) {
|
||||
ERR ("usb_release_interface failed (%i)", ret);
|
||||
}
|
||||
|
||||
if((ret = usb_close(pus->pudh)) < 0) {
|
||||
ERR("usb_close failed (%i)",ret);
|
||||
if ((ret = usb_close (pus->pudh)) < 0) {
|
||||
ERR ("usb_close failed (%i)", ret);
|
||||
}
|
||||
/*
|
||||
if((ret = usb_reset(pus->pudh)) < 0) {
|
||||
ERR("usb_reset failed (%i, if errno: %s)",ret, strerror(-ret));
|
||||
}
|
||||
*/
|
||||
free(pnd->nds);
|
||||
free(pnd);
|
||||
free (pnd->nds);
|
||||
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;
|
||||
int ret = 0;
|
||||
byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
usb_spec_t* pus = (usb_spec_t*)pnd->nds;
|
||||
size_t uiPos = 0;
|
||||
int ret = 0;
|
||||
byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
usb_spec_t *pus = (usb_spec_t *) pnd->nds;
|
||||
// TODO: Move this one level up for libnfc-1.6
|
||||
uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
|
||||
|
||||
|
@ -249,88 +242,81 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
// Packet length checksum
|
||||
abtTx[4] = 0x0100 - abtTx[3];
|
||||
// Copy the PN53X command into the packet abtTx
|
||||
memmove(abtTx+5,pbtTx,szTxLen);
|
||||
memmove (abtTx + 5, pbtTx, szTxLen);
|
||||
|
||||
// Calculate data payload checksum
|
||||
abtTx[szTxLen+5] = 0;
|
||||
for(uiPos=0; uiPos < szTxLen; uiPos++)
|
||||
{
|
||||
abtTx[szTxLen+5] -= abtTx[uiPos+5];
|
||||
abtTx[szTxLen + 5] = 0;
|
||||
for (uiPos = 0; uiPos < szTxLen; uiPos++) {
|
||||
abtTx[szTxLen + 5] -= abtTx[uiPos + 5];
|
||||
}
|
||||
|
||||
// End of stream marker
|
||||
abtTx[szTxLen+6] = 0;
|
||||
abtTx[szTxLen + 6] = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", abtTx,szTxLen+7);
|
||||
PRINT_HEX ("TX", abtTx, szTxLen + 7);
|
||||
#endif
|
||||
|
||||
ret = usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
DBG("usb_bulk_write failed with error %d", ret);
|
||||
ret = usb_bulk_write (pus->pudh, pus->uiEndPointOut, (char *) abtTx, szTxLen + 7, USB_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
DBG ("usb_bulk_write failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
DBG( "usb_bulk_read failed with error %d", ret);
|
||||
ret = usb_bulk_read (pus->pudh, pus->uiEndPointIn, (char *) abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
DBG ("usb_bulk_read failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,ret);
|
||||
PRINT_HEX ("RX", abtRx, ret);
|
||||
#endif
|
||||
|
||||
if (!pn53x_transceive_check_ack_frame_callback (pnd, abtRx, ret))
|
||||
return false;
|
||||
|
||||
ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if( ret < 0 )
|
||||
{
|
||||
DBG("usb_bulk_read failed with error %d", ret);
|
||||
ret = usb_bulk_read (pus->pudh, pus->uiEndPointIn, (char *) abtRx, BUFFER_LENGTH, USB_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
DBG ("usb_bulk_read failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("RX", abtRx,ret);
|
||||
PRINT_HEX ("RX", abtRx, ret);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", ack_frame,6);
|
||||
PRINT_HEX ("TX", ack_frame, 6);
|
||||
#endif
|
||||
usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char *)ack_frame, 6, USB_TIMEOUT);
|
||||
usb_bulk_write (pus->pudh, pus->uiEndPointOut, (char *) ack_frame, 6, USB_TIMEOUT);
|
||||
|
||||
if (!pn53x_transceive_check_error_frame_callback (pnd, abtRx, ret))
|
||||
return false;
|
||||
|
||||
// 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)
|
||||
if(ret < 9)
|
||||
{
|
||||
DBG("%s","No data");
|
||||
if (ret < 9) {
|
||||
DBG ("%s", "No data");
|
||||
pnd->iLastError = DEINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the preceding and appending bytes 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
|
||||
*pszRxLen = ret - 7 - 2;
|
||||
|
||||
// Get register: nuke extra byte (awful hack)
|
||||
if ((abtRx[5]==0xd5) && (abtRx[6]==0x07) && (*pszRxLen==2)) {
|
||||
// DBG("awful hack: abtRx[7]=%02x, abtRx[8]=%02x, we only keep abtRx[8]=%02x", abtRx[7], abtRx[8], abtRx[8]);
|
||||
*pszRxLen = (*pszRxLen) - 1;
|
||||
memcpy( pbtRx, abtRx + 8, *pszRxLen);
|
||||
return true;
|
||||
if ((abtRx[5] == 0xd5) && (abtRx[6] == 0x07) && (*pszRxLen == 2)) {
|
||||
// DBG("awful hack: abtRx[7]=%02x, abtRx[8]=%02x, we only keep abtRx[8]=%02x", abtRx[7], abtRx[8], abtRx[8]);
|
||||
*pszRxLen = (*pszRxLen) - 1;
|
||||
memcpy (pbtRx, abtRx + 8, *pszRxLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
memcpy( pbtRx, abtRx + 7, *pszRxLen);
|
||||
memcpy (pbtRx, abtRx + 7, *pszRxLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <usb.h>
|
||||
|
||||
typedef struct {
|
||||
usb_dev_handle* pudh;
|
||||
usb_dev_handle *pudh;
|
||||
uint32_t uiEndPointIn;
|
||||
uint32_t uiEndPointOut;
|
||||
} usb_spec_t;
|
||||
|
@ -34,8 +34,10 @@ typedef struct {
|
|||
uint16_t idProduct;
|
||||
} usb_candidate_t;
|
||||
|
||||
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 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_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,usb_candidate_t candidates[], int num_candidates, char * target_name);
|
||||
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 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_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound,
|
||||
usb_candidate_t candidates[], int num_candidates, char *target_name);
|
||||
|
|
|
@ -23,30 +23,32 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.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;
|
||||
|
||||
do {
|
||||
bt = *pbtData++;
|
||||
bt = (bt^(byte_t)(wCrc & 0x00FF));
|
||||
bt = (bt^(bt<<4));
|
||||
wCrc = (wCrc >> 8)^((uint32_t)bt << 8)^((uint32_t)bt<<3)^((uint32_t)bt>>4);
|
||||
bt = (bt ^ (byte_t) (wCrc & 0x00FF));
|
||||
bt = (bt ^ (bt << 4));
|
||||
wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
|
||||
} while (--szLen);
|
||||
|
||||
*pbtCrc++ = (byte_t) (wCrc & 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);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -31,52 +31,55 @@
|
|||
#include "mirror-subr.h"
|
||||
|
||||
static const byte_t ByteMirror[256] = {
|
||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30,
|
||||
0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98,
|
||||
0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64,
|
||||
0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc,
|
||||
0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02,
|
||||
0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2,
|
||||
0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a,
|
||||
0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
|
||||
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e,
|
||||
0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81,
|
||||
0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
|
||||
0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
|
||||
0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15,
|
||||
0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad,
|
||||
0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43,
|
||||
0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
|
||||
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b,
|
||||
0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97,
|
||||
0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f,
|
||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30,
|
||||
0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98,
|
||||
0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64,
|
||||
0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc,
|
||||
0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02,
|
||||
0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2,
|
||||
0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a,
|
||||
0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
|
||||
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e,
|
||||
0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81,
|
||||
0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
|
||||
0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
|
||||
0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15,
|
||||
0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad,
|
||||
0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43,
|
||||
0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
|
||||
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b,
|
||||
0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97,
|
||||
0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f,
|
||||
0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
|
||||
};
|
||||
|
||||
byte_t mirror(byte_t bt)
|
||||
byte_t
|
||||
mirror (byte_t 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++;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -22,16 +22,16 @@
|
|||
*/
|
||||
|
||||
#ifndef _LIBNFC_MIRROR_SUBR_H_
|
||||
#define _LIBNFC_MIRROR_SUBR_H_
|
||||
# define _LIBNFC_MIRROR_SUBR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
# include <stdint.h>
|
||||
|
||||
#include <nfc/nfc-types.h>
|
||||
# include <nfc/nfc-types.h>
|
||||
|
||||
|
||||
byte_t mirror(byte_t bt);
|
||||
uint32_t mirror32(uint32_t ui32Bits);
|
||||
uint64_t mirror64(uint64_t ui64Bits);
|
||||
void mirror_byte_ts(byte_t *pbts, size_t szLen);
|
||||
byte_t mirror (byte_t bt);
|
||||
uint32_t mirror32 (uint32_t ui32Bits);
|
||||
uint64_t mirror64 (uint64_t ui64Bits);
|
||||
void mirror_byte_ts (byte_t * pbts, size_t szLen);
|
||||
|
||||
#endif // _LIBNFC_MIRROR_SUBR_H_
|
||||
|
|
391
libnfc/nfc.c
391
libnfc/nfc.c
|
@ -16,14 +16,14 @@
|
|||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file nfc.c
|
||||
* @brief NFC library implementation
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -34,9 +34,9 @@
|
|||
#include <nfc/nfc.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
# include <windows.h>
|
||||
|
||||
#define snprintf sprintf_s
|
||||
# define snprintf sprintf_s
|
||||
#endif
|
||||
|
||||
#include "chips.h"
|
||||
|
@ -44,7 +44,7 @@
|
|||
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
nfc_device_desc_t * nfc_pick_device (void);
|
||||
nfc_device_desc_t *nfc_pick_device (void);
|
||||
|
||||
/**
|
||||
* @brief Probe for the first discoverable supported devices (ie. only available for some drivers)
|
||||
|
@ -56,12 +56,11 @@ nfc_pick_device (void)
|
|||
uint32_t uiDriver;
|
||||
nfc_device_desc_t *nddRes;
|
||||
|
||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
||||
{
|
||||
if (drivers_callbacks_list[uiDriver].pick_device != NULL)
|
||||
{
|
||||
for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
|
||||
if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
|
||||
nddRes = drivers_callbacks_list[uiDriver].pick_device ();
|
||||
if (nddRes != NULL) return nddRes;
|
||||
if (nddRes != NULL)
|
||||
return nddRes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,27 +74,23 @@ nfc_pick_device (void)
|
|||
* @param pszDeviceFound number of devices found.
|
||||
*/
|
||||
void
|
||||
nfc_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
|
||||
nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
|
||||
{
|
||||
uint32_t uiDriver;
|
||||
size_t szN;
|
||||
size_t szN;
|
||||
|
||||
*pszDeviceFound = 0;
|
||||
|
||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
||||
{
|
||||
if (drivers_callbacks_list[uiDriver].list_devices != NULL)
|
||||
{
|
||||
for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
|
||||
if (drivers_callbacks_list[uiDriver].list_devices != NULL) {
|
||||
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;
|
||||
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
|
||||
{
|
||||
DBG("No listing function avaible for %s driver",drivers_callbacks_list[uiDriver].acDriver);
|
||||
} else {
|
||||
DBG ("No listing function avaible for %s driver", drivers_callbacks_list[uiDriver].acDriver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,77 +108,83 @@ 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.
|
||||
* 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;
|
||||
|
||||
// Search through the device list for an available device
|
||||
for (uiDriver=0; uiDriver<sizeof(drivers_callbacks_list)/sizeof(drivers_callbacks_list[0]); uiDriver++)
|
||||
{
|
||||
if(pndd == NULL) {
|
||||
for (uiDriver = 0; uiDriver < sizeof (drivers_callbacks_list) / sizeof (drivers_callbacks_list[0]); uiDriver++) {
|
||||
if (pndd == NULL) {
|
||||
// No device description specified: try to automatically claim a device
|
||||
if(drivers_callbacks_list[uiDriver].pick_device != NULL) {
|
||||
DBG("Autodetecting available devices using %s driver.", drivers_callbacks_list[uiDriver].acDriver);
|
||||
if (drivers_callbacks_list[uiDriver].pick_device != NULL) {
|
||||
DBG ("Autodetecting available devices using %s driver.", drivers_callbacks_list[uiDriver].acDriver);
|
||||
pndd = drivers_callbacks_list[uiDriver].pick_device ();
|
||||
|
||||
if(pndd != NULL) {
|
||||
DBG("Auto-connecting to %s using %s driver", pndd->acDevice, drivers_callbacks_list[uiDriver].acDriver);
|
||||
pnd = drivers_callbacks_list[uiDriver].connect(pndd);
|
||||
if(pnd == NULL) {
|
||||
DBG("No device available using %s driver",drivers_callbacks_list[uiDriver].acDriver);
|
||||
if (pndd != NULL) {
|
||||
DBG ("Auto-connecting to %s using %s driver", pndd->acDevice, drivers_callbacks_list[uiDriver].acDriver);
|
||||
pnd = drivers_callbacks_list[uiDriver].connect (pndd);
|
||||
if (pnd == NULL) {
|
||||
DBG ("No device available using %s driver", drivers_callbacks_list[uiDriver].acDriver);
|
||||
pndd = NULL;
|
||||
}
|
||||
|
||||
free(pndd);
|
||||
free (pndd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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;
|
||||
} else {
|
||||
pnd = drivers_callbacks_list[uiDriver].connect(pndd);
|
||||
pnd = drivers_callbacks_list[uiDriver].connect (pndd);
|
||||
}
|
||||
}
|
||||
|
||||
// Test if the connection was successful
|
||||
if (pnd != NULL)
|
||||
{
|
||||
DBG("[%s] has been claimed.", pnd->acName);
|
||||
if (pnd != NULL) {
|
||||
DBG ("[%s] has been claimed.", pnd->acName);
|
||||
// Great we have claimed a device
|
||||
pnd->pdc = &(drivers_callbacks_list[uiDriver]);
|
||||
|
||||
if (!pn53x_get_firmware_version(pnd))
|
||||
return NULL;
|
||||
if (!pn53x_get_firmware_version (pnd))
|
||||
return NULL;
|
||||
|
||||
// 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
|
||||
// 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_PARITY,true)) return NULL;
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_CRC, true))
|
||||
return NULL;
|
||||
if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true))
|
||||
return NULL;
|
||||
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false)) return NULL;
|
||||
if (!nfc_configure (pnd, NDO_ACCEPT_MULTIPLE_FRAMES, false))
|
||||
return NULL;
|
||||
|
||||
return pnd;
|
||||
} else {
|
||||
DBG("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver);
|
||||
DBG ("No device found using driver: %s", drivers_callbacks_list[uiDriver].acDriver);
|
||||
}
|
||||
}
|
||||
// Too bad, no reader is ready to be claimed
|
||||
|
@ -196,15 +197,16 @@ 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.
|
||||
*/
|
||||
void nfc_disconnect(nfc_device_t* pnd)
|
||||
void
|
||||
nfc_disconnect (nfc_device_t * pnd)
|
||||
{
|
||||
if(pnd) {
|
||||
if (pnd) {
|
||||
// Release and deselect all active communications
|
||||
nfc_initiator_deselect_target(pnd);
|
||||
nfc_initiator_deselect_target (pnd);
|
||||
// Disable RF field to avoid heating
|
||||
nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
|
||||
nfc_configure (pnd, NDO_ACTIVATE_FIELD, false);
|
||||
// Disconnect, clean up and release the device
|
||||
pnd->pdc->disconnect(pnd);
|
||||
pnd->pdc->disconnect (pnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,11 +221,12 @@ void nfc_disconnect(nfc_device_t* pnd)
|
|||
* 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
return pn53x_configure(pnd, ndo, bEnable);
|
||||
return pn53x_configure (pnd, ndo, bEnable);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
* 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;
|
||||
|
||||
// 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)
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
@ -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.
|
||||
* @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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -290,126 +301,125 @@ bool nfc_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t n
|
|||
* @note For every initial modulation type there is a different collection of information returned (in nfc_target_info_t pointer pti) They all fit in the data-type which is called nfc_target_info_t. This is a union which contains the tag information that belongs to the according initial modulation type.
|
||||
*/
|
||||
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* pnti)
|
||||
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 * pnti)
|
||||
{
|
||||
byte_t abtInit[MAX_FRAME_LEN];
|
||||
size_t szInitLen;
|
||||
byte_t abtInit[MAX_FRAME_LEN];
|
||||
size_t szInitLen;
|
||||
|
||||
size_t szTargetsData;
|
||||
byte_t abtTargetsData[MAX_FRAME_LEN];
|
||||
size_t szTargetsData;
|
||||
byte_t abtTargetsData[MAX_FRAME_LEN];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
// 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
|
||||
switch(nmInitModulation)
|
||||
{
|
||||
case NM_ISO14443A_106:
|
||||
switch (szInitDataLen)
|
||||
{
|
||||
case 7:
|
||||
abtInit[0] = 0x88;
|
||||
memcpy(abtInit+1,pbtInitData,7);
|
||||
szInitLen = 8;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
abtInit[0] = 0x88;
|
||||
memcpy(abtInit+1,pbtInitData,3);
|
||||
abtInit[4] = 0x88;
|
||||
memcpy(abtInit+5,pbtInitData+3,7);
|
||||
szInitLen = 12;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
default:
|
||||
memcpy(abtInit,pbtInitData,szInitDataLen);
|
||||
szInitLen = szInitDataLen;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memcpy(abtInit,pbtInitData,szInitDataLen);
|
||||
szInitLen = szInitDataLen;
|
||||
break;
|
||||
}
|
||||
|
||||
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
|
||||
if (abtTargetsData[0] == 0) return false;
|
||||
|
||||
// Is a tag info struct available
|
||||
if (pnti)
|
||||
{
|
||||
// Fill the tag info struct with the values corresponding to this init modulation
|
||||
switch(nmInitModulation)
|
||||
{
|
||||
case NM_ISO14443A_106:
|
||||
if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) {
|
||||
return false;
|
||||
}
|
||||
switch (nmInitModulation) {
|
||||
case NM_ISO14443A_106:
|
||||
switch (szInitDataLen) {
|
||||
case 7:
|
||||
abtInit[0] = 0x88;
|
||||
memcpy (abtInit + 1, pbtInitData, 7);
|
||||
szInitLen = 8;
|
||||
break;
|
||||
|
||||
case NM_FELICA_212:
|
||||
if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_FELICA_212, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NM_FELICA_424:
|
||||
if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_FELICA_424, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
abtInit[0] = 0x88;
|
||||
memcpy (abtInit + 1, pbtInitData, 3);
|
||||
abtInit[4] = 0x88;
|
||||
memcpy (abtInit + 5, pbtInitData + 3, 7);
|
||||
szInitLen = 12;
|
||||
break;
|
||||
|
||||
case NM_ISO14443B_106:
|
||||
if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_ISO14443B_106, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
memcpy (abtInit, pbtInitData, szInitDataLen);
|
||||
szInitLen = szInitDataLen;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NM_JEWEL_106:
|
||||
if(!pn53x_decode_target_data(abtTargetsData+1, szTargetsData-1, pnd->nc, NTT_JEWEL_106, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
memcpy (abtInit, pbtInitData, szInitDataLen);
|
||||
szInitLen = szInitDataLen;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Should not be possible, so whatever...
|
||||
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
|
||||
if (abtTargetsData[0] == 0)
|
||||
return false;
|
||||
|
||||
// Is a tag info struct available
|
||||
if (pnti) {
|
||||
// Fill the tag info struct with the values corresponding to this init modulation
|
||||
switch (nmInitModulation) {
|
||||
case NM_ISO14443A_106:
|
||||
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_GENERIC_PASSIVE_106, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NM_FELICA_212:
|
||||
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_FELICA_212, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NM_FELICA_424:
|
||||
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_FELICA_424, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NM_ISO14443B_106:
|
||||
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_ISO14443B_106, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NM_JEWEL_106:
|
||||
if (!pn53x_decode_target_data (abtTargetsData + 1, szTargetsData - 1, pnd->nc, NTT_JEWEL_106, pnti)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should not be possible, so whatever...
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
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_target_info_t nti;
|
||||
size_t szTargetFound = 0;
|
||||
byte_t* pbtInitData = NULL;
|
||||
size_t szInitDataLen = 0;
|
||||
size_t szTargetFound = 0;
|
||||
byte_t *pbtInitData = NULL;
|
||||
size_t szInitDataLen = 0;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
// Let the reader only try once to find a target
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
|
||||
if(nmInitModulation == NM_ISO14443B_106) {
|
||||
|
||||
if (nmInitModulation == NM_ISO14443B_106) {
|
||||
// Application Family Identifier (AFI) must equals 0x00 in order to wakeup all ISO14443-B PICCs (see ISO/IEC 14443-3)
|
||||
pbtInitData = (byte_t*)"\x00";
|
||||
pbtInitData = (byte_t *) "\x00";
|
||||
szInitDataLen = 1;
|
||||
}
|
||||
while (nfc_initiator_select_passive_target (pnd, nmInitModulation, pbtInitData, szInitDataLen, &nti)) {
|
||||
nfc_initiator_deselect_target(pnd);
|
||||
nfc_initiator_deselect_target (pnd);
|
||||
|
||||
if(szTargets > szTargetFound) {
|
||||
memcpy( &(anti[szTargetFound]), &nti, sizeof(nfc_target_info_t) );
|
||||
if (szTargets > szTargetFound) {
|
||||
memcpy (&(anti[szTargetFound]), &nti, sizeof (nfc_target_info_t));
|
||||
}
|
||||
szTargetFound++;
|
||||
}
|
||||
|
@ -425,11 +435,12 @@ 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.
|
||||
*/
|
||||
bool nfc_initiator_deselect_target(nfc_device_t* pnd)
|
||||
bool
|
||||
nfc_initiator_deselect_target (nfc_device_t * pnd)
|
||||
{
|
||||
pnd->iLastError = 0;
|
||||
|
||||
return (pn53x_InDeselect(pnd, 0)); // 0 mean deselect all selected targets
|
||||
return (pn53x_InDeselect (pnd, 0)); // 0 mean deselect all selected targets
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -444,14 +455,14 @@ bool nfc_initiator_deselect_target(nfc_device_t* pnd)
|
|||
* @param pszTargetFound found targets count
|
||||
*/
|
||||
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_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)
|
||||
{
|
||||
pnd->iLastError = 0;
|
||||
|
||||
return pn53x_InAutoPoll(pnd, pnttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound);
|
||||
return pn53x_InAutoPoll (pnd, pnttTargetTypes, szTargetTypes, btPollNr, btPeriod, pntTargets, pszTargetFound);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -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).
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -501,11 +516,12 @@ 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
return pn53x_target_init(pnd, pbtRx, pszRxBits);
|
||||
return pn53x_target_init (pnd, pbtRx, pszRxBits);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -527,11 +544,12 @@ 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
return pn53x_target_receive_bytes(pnd, pbtRx, pszRxLen);
|
||||
return pn53x_target_receive_bytes (pnd, pbtRx, pszRxLen);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -540,11 +558,12 @@ 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
return pn53x_target_send_bits(pnd, pbtTx, szTxBits, pbtTxPar);
|
||||
return pn53x_target_send_bits (pnd, pbtTx, szTxBits, pbtTxPar);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -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
|
||||
* @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);
|
||||
}
|
||||
|
@ -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
|
||||
* @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;
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
@ -593,7 +616,8 @@ void nfc_perror (const nfc_device_t *pnd, const char *pcString)
|
|||
* @brief Returns 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;
|
||||
}
|
||||
|
@ -604,11 +628,12 @@ const char* nfc_device_name(nfc_device_t* pnd)
|
|||
* @brief Returns the library version
|
||||
* @return Returns a string with the library version
|
||||
*/
|
||||
const char* nfc_version(void)
|
||||
const char *
|
||||
nfc_version (void)
|
||||
{
|
||||
#ifdef SVN_REVISION
|
||||
return PACKAGE_VERSION" (r"SVN_REVISION")";
|
||||
#else
|
||||
#ifdef SVN_REVISION
|
||||
return PACKAGE_VERSION " (r" SVN_REVISION ")";
|
||||
#else
|
||||
return PACKAGE_VERSION;
|
||||
#endif // SVN_REVISION
|
||||
#endif // SVN_REVISION
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue