Various cleanups.
- New functions nfc_device_new(), nfc_device_free(); - Add experimental abort mechanism for the PN53x USB driver; - Move chip-specific variables from nfc_device_t to pn53x_data (Fixes Issue 124).
This commit is contained in:
parent
8d27768097
commit
ad530f6d02
10 changed files with 181 additions and 143 deletions
|
@ -55,10 +55,6 @@ typedef struct {
|
||||||
bool bEasyFraming;
|
bool bEasyFraming;
|
||||||
/** Should the PN53x chip switch automatically in ISO14443-4 when ISO14443 */
|
/** Should the PN53x chip switch automatically in ISO14443-4 when ISO14443 */
|
||||||
bool bAutoIso14443_4;
|
bool bAutoIso14443_4;
|
||||||
/** Register cache for REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS: The last TX bits setting, we need to reset this if it does not apply anymore */
|
|
||||||
uint8_t ui8TxBits;
|
|
||||||
/** Register cache for SetParameters function. */
|
|
||||||
uint8_t ui8Parameters;
|
|
||||||
/** Supported modulation encoded in a byte */
|
/** Supported modulation encoded in a byte */
|
||||||
byte_t btSupportByte;
|
byte_t btSupportByte;
|
||||||
/** Last error reported by the PCD / encountered by the PCD driver
|
/** Last error reported by the PCD / encountered by the PCD driver
|
||||||
|
@ -70,11 +66,8 @@ typedef struct {
|
||||||
* +----------- Driver-level general error (common to all drivers)
|
* +----------- Driver-level general error (common to all drivers)
|
||||||
*/
|
*/
|
||||||
int iLastError;
|
int iLastError;
|
||||||
/** Last sent command */
|
|
||||||
int iLastCommand;
|
|
||||||
int iAbortFds[2];
|
int iAbortFds[2];
|
||||||
} nfc_device_t;
|
} nfc_device_t;
|
||||||
// TODO: Move chip's specifics in a chips structure (e.g. iLastCommand, ui8Parameters, ui8TxBits)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct nfc_device_desc_t
|
* @struct nfc_device_desc_t
|
||||||
|
|
|
@ -5,7 +5,7 @@ INCLUDES = $(all_includes) $(LIBNFC_CFLAGS)
|
||||||
|
|
||||||
noinst_HEADERS = drivers.h mirror-subr.h nfc-internal.h
|
noinst_HEADERS = drivers.h mirror-subr.h nfc-internal.h
|
||||||
lib_LTLIBRARIES = libnfc.la
|
lib_LTLIBRARIES = libnfc.la
|
||||||
libnfc_la_SOURCES = nfc.c iso14443-subr.c mirror-subr.c
|
libnfc_la_SOURCES = nfc.c iso14443-subr.c mirror-subr.c nfc-device.c
|
||||||
libnfc_la_LDFLAGS = -no-undefined -version-info 1:0:0
|
libnfc_la_LDFLAGS = -no-undefined -version-info 1:0:0
|
||||||
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
libnfc_la_CFLAGS = @DRIVERS_CFLAGS@
|
||||||
libnfc_la_LIBADD = \
|
libnfc_la_LIBADD = \
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
||||||
|
|
||||||
// TODO: reorder functions according to header
|
// TODO: reorder functions according to header
|
||||||
|
|
||||||
// TODO: Count max bytes for InJumpForDEP reply
|
// TODO: Count max bytes for InJumpForDEP reply
|
||||||
|
@ -78,7 +80,7 @@ pn53x_init(nfc_device_t * pnd)
|
||||||
pnd->bPar = true;
|
pnd->bPar = true;
|
||||||
|
|
||||||
// Reset the ending transmission bits register, it is unknown what the last tranmission used there
|
// Reset the ending transmission bits register, it is unknown what the last tranmission used there
|
||||||
pnd->ui8TxBits = 0;
|
CHIP_DATA (pnd)->ui8TxBits = 0;
|
||||||
if (!pn53x_write_register (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, 0x00)) {
|
if (!pn53x_write_register (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, 0x00)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +147,9 @@ pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, b
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pnd->iLastError)
|
||||||
|
return false;
|
||||||
|
|
||||||
*pszRx = (size_t) res;
|
*pszRx = (size_t) res;
|
||||||
|
|
||||||
switch (pbtTx[0]) {
|
switch (pbtTx[0]) {
|
||||||
|
@ -221,8 +226,8 @@ pn53x_write_register (nfc_device_t * pnd, const uint16_t ui16Reg, const uint8_t
|
||||||
bool
|
bool
|
||||||
pn53x_set_parameters (nfc_device_t * pnd, const uint8_t ui8Parameter, const bool bEnable)
|
pn53x_set_parameters (nfc_device_t * pnd, const uint8_t ui8Parameter, const bool bEnable)
|
||||||
{
|
{
|
||||||
uint8_t ui8Value = (bEnable) ? (pnd->ui8Parameters | ui8Parameter) : (pnd->ui8Parameters & ~(ui8Parameter));
|
uint8_t ui8Value = (bEnable) ? (CHIP_DATA (pnd)->ui8Parameters | ui8Parameter) : (CHIP_DATA (pnd)->ui8Parameters & ~(ui8Parameter));
|
||||||
if (ui8Value != pnd->ui8Parameters) {
|
if (ui8Value != CHIP_DATA (pnd)->ui8Parameters) {
|
||||||
return pn53x_SetParameters(pnd, ui8Value);
|
return pn53x_SetParameters(pnd, ui8Value);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -237,7 +242,7 @@ pn53x_SetParameters (nfc_device_t * pnd, const uint8_t ui8Value)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// We save last parameters in register cache
|
// We save last parameters in register cache
|
||||||
pnd->ui8Parameters = ui8Value;
|
CHIP_DATA (pnd)->ui8Parameters = ui8Value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,13 +250,13 @@ bool
|
||||||
pn53x_set_tx_bits (nfc_device_t * pnd, const uint8_t ui8Bits)
|
pn53x_set_tx_bits (nfc_device_t * pnd, const uint8_t ui8Bits)
|
||||||
{
|
{
|
||||||
// Test if we need to update the transmission bits register setting
|
// Test if we need to update the transmission bits register setting
|
||||||
if (pnd->ui8TxBits != ui8Bits) {
|
if (CHIP_DATA (pnd)->ui8TxBits != ui8Bits) {
|
||||||
// Set the amount of transmission bits in the PN53X chip register
|
// Set the amount of transmission bits in the PN53X chip register
|
||||||
if (!pn53x_write_register (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, ui8Bits))
|
if (!pn53x_write_register (pnd, REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS, ui8Bits))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Store the new setting
|
// Store the new setting
|
||||||
((nfc_device_t *) pnd)->ui8TxBits = ui8Bits;
|
CHIP_DATA (pnd)->ui8TxBits = ui8Bits;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1416,10 +1421,6 @@ pn53x_TgInitAsTarget (nfc_device_t * pnd, pn53x_target_mode_t ptm,
|
||||||
if (!pn53x_transceive (pnd, abtCmd, 36 + szOptionalBytes, abtRx, &szRx))
|
if (!pn53x_transceive (pnd, abtCmd, 36 + szOptionalBytes, abtRx, &szRx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (szRx == 0) {
|
|
||||||
return false; // transceive was aborted
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: the first byte is skip:
|
// Note: the first byte is skip:
|
||||||
// its the "mode" byte which contains baudrate, DEP and Framing type (Mifare, active or FeliCa) datas.
|
// its the "mode" byte which contains baudrate, DEP and Framing type (Mifare, active or FeliCa) datas.
|
||||||
if(pbtModeByte) {
|
if(pbtModeByte) {
|
||||||
|
@ -1474,7 +1475,9 @@ pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx)
|
||||||
{
|
{
|
||||||
byte_t abtCmd[1];
|
byte_t abtCmd[1];
|
||||||
|
|
||||||
if (pnd->bEasyFraming) {
|
// FIXME In DEP mode we MUST use TgGetData but we don't known the current mode.
|
||||||
|
// DEP mode && EasyFramming || EasyFramming && ISO14443-4 && PN532
|
||||||
|
if (pnd->bEasyFraming && (CHIP_DATA(pnd)->type == PN532)) {
|
||||||
abtCmd[0] = TgGetData;
|
abtCmd[0] = TgGetData;
|
||||||
} else {
|
} else {
|
||||||
abtCmd[0] = TgGetInitiatorCommand;
|
abtCmd[0] = TgGetInitiatorCommand;
|
||||||
|
@ -1489,6 +1492,8 @@ pn53x_target_receive_bytes (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx)
|
||||||
// Save the received byte count
|
// Save the received byte count
|
||||||
*pszRx = szRx - 1;
|
*pszRx = szRx - 1;
|
||||||
|
|
||||||
|
// FIXME szRx can be 0
|
||||||
|
|
||||||
// Copy the received bytes
|
// Copy the received bytes
|
||||||
memcpy (pbtRx, abtRx + 1, *pszRx);
|
memcpy (pbtRx, abtRx + 1, *pszRx);
|
||||||
|
|
||||||
|
@ -1543,7 +1548,7 @@ pn53x_target_send_bytes (nfc_device_t * pnd, const byte_t * pbtTx, const size_t
|
||||||
if (!pnd->bPar)
|
if (!pnd->bPar)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (pnd->bEasyFraming) {
|
if (pnd->bEasyFraming && (CHIP_DATA(pnd)->type == PN532)) {
|
||||||
abtCmd[0] = TgSetData;
|
abtCmd[0] = TgSetData;
|
||||||
} else {
|
} else {
|
||||||
abtCmd[0] = TgResponseToInitiator;
|
abtCmd[0] = TgResponseToInitiator;
|
||||||
|
|
|
@ -125,6 +125,12 @@ struct pn53x_data {
|
||||||
pn53x_type type;
|
pn53x_type type;
|
||||||
pn53x_state state;
|
pn53x_state state;
|
||||||
const struct pn53x_io * io;
|
const struct pn53x_io * io;
|
||||||
|
/** Register cache for REG_CIU_BIT_FRAMING, SYMBOL_TX_LAST_BITS: The last TX bits setting, we need to reset this if it does not apply anymore */
|
||||||
|
uint8_t ui8TxBits;
|
||||||
|
/** Register cache for SetParameters function. */
|
||||||
|
uint8_t ui8Parameters;
|
||||||
|
/** Last sent command */
|
||||||
|
uint8_t ui8LastCommand;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PN53x specific types */
|
/* PN53x specific types */
|
||||||
|
|
|
@ -194,7 +194,7 @@ nfc_device_t *
|
||||||
acr122_connect (const nfc_device_desc_t * pndd)
|
acr122_connect (const nfc_device_desc_t * pndd)
|
||||||
{
|
{
|
||||||
char *pcFirmware;
|
char *pcFirmware;
|
||||||
nfc_device_t *pnd = malloc (sizeof (*pnd));
|
nfc_device_t *pnd = nfc_device_new ();
|
||||||
pnd->driver_data = malloc (sizeof (struct acr122_data));
|
pnd->driver_data = malloc (sizeof (struct acr122_data));
|
||||||
pnd->chip_data = malloc (sizeof (struct pn53x_data));
|
pnd->chip_data = malloc (sizeof (struct pn53x_data));
|
||||||
|
|
||||||
|
@ -233,9 +233,7 @@ acr122_connect (const nfc_device_desc_t * pndd)
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free (pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free (pnd->chip_data);
|
|
||||||
free (pnd);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -246,9 +244,7 @@ acr122_disconnect (nfc_device_t * pnd)
|
||||||
SCardDisconnect (DRIVER_DATA (pnd)->hCard, SCARD_LEAVE_CARD);
|
SCardDisconnect (DRIVER_DATA (pnd)->hCard, SCARD_LEAVE_CARD);
|
||||||
acr122_free_scardcontext ();
|
acr122_free_scardcontext ();
|
||||||
|
|
||||||
free (pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free (pnd->chip_data);
|
|
||||||
free (pnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -65,6 +65,9 @@
|
||||||
#define ARYGON_DEFAULT_SPEED 9600
|
#define ARYGON_DEFAULT_SPEED 9600
|
||||||
#define ARYGON_DRIVER_NAME "ARYGON"
|
#define ARYGON_DRIVER_NAME "ARYGON"
|
||||||
|
|
||||||
|
#define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
|
||||||
|
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
||||||
|
|
||||||
const struct pn53x_io arygon_tama_io;
|
const struct pn53x_io arygon_tama_io;
|
||||||
|
|
||||||
struct arygon_data {
|
struct arygon_data {
|
||||||
|
@ -105,18 +108,17 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
|
||||||
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
|
||||||
uart_set_speed (sp, ARYGON_DEFAULT_SPEED);
|
uart_set_speed (sp, ARYGON_DEFAULT_SPEED);
|
||||||
|
|
||||||
nfc_device_t nd;
|
nfc_device_t *pnd = nfc_device_new ();
|
||||||
nd.driver = &arygon_driver;
|
pnd->driver = &arygon_driver;
|
||||||
nd.driver_data = malloc(sizeof(struct arygon_data));
|
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
||||||
((struct arygon_data*)(nd.driver_data))->port = sp;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
nd.chip_data = malloc(sizeof(struct pn53x_data));
|
pnd->chip_data = malloc(sizeof(struct pn53x_data));
|
||||||
((struct pn53x_data*)(nd.chip_data))->type = PN532;
|
CHIP_DATA (pnd)->type = PN532;
|
||||||
((struct pn53x_data*)(nd.chip_data))->state = NORMAL;
|
CHIP_DATA (pnd)->state = NORMAL;
|
||||||
((struct pn53x_data*)(nd.chip_data))->io = &arygon_tama_io;
|
CHIP_DATA (pnd)->io = &arygon_tama_io;
|
||||||
|
|
||||||
bool res = arygon_reset_tama(&nd);
|
bool res = arygon_reset_tama (pnd);
|
||||||
free(nd.driver_data);
|
nfc_device_free (pnd);
|
||||||
free(nd.chip_data);
|
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
if(!res)
|
if(!res)
|
||||||
continue;
|
continue;
|
||||||
|
@ -164,23 +166,21 @@ arygon_connect (const nfc_device_desc_t * pndd)
|
||||||
uart_set_speed (sp, pndd->uiSpeed);
|
uart_set_speed (sp, pndd->uiSpeed);
|
||||||
|
|
||||||
// We have a connection
|
// We have a connection
|
||||||
pnd = malloc (sizeof (nfc_device_t));
|
pnd = nfc_device_new ();
|
||||||
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
|
strncpy (pnd->acName, pndd->acDevice, sizeof (pnd->acName));
|
||||||
|
|
||||||
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
pnd->driver_data = malloc(sizeof(struct arygon_data));
|
||||||
((struct arygon_data*)(pnd->driver_data))->port = sp;
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
pnd->chip_data = malloc(sizeof(struct pn53x_data));
|
pnd->chip_data = malloc(sizeof(struct pn53x_data));
|
||||||
|
|
||||||
// The PN53x chip connected to ARYGON MCU doesn't seems to be in SLEEP mode
|
// The PN53x chip connected to ARYGON MCU doesn't seems to be in SLEEP mode
|
||||||
((struct pn53x_data*)(pnd->chip_data))->state = NORMAL;
|
CHIP_DATA (pnd)->state = NORMAL;
|
||||||
((struct pn53x_data*)(pnd->chip_data))->io = &arygon_tama_io;
|
CHIP_DATA (pnd)->io = &arygon_tama_io;
|
||||||
pnd->driver = &arygon_driver;
|
pnd->driver = &arygon_driver;
|
||||||
|
|
||||||
// Check communication using "Reset TAMA" command
|
// Check communication using "Reset TAMA" command
|
||||||
if (!arygon_reset_tama(pnd)) {
|
if (!arygon_reset_tama(pnd)) {
|
||||||
free(pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free(pnd->chip_data);
|
|
||||||
free(pnd);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,10 +191,8 @@ arygon_connect (const nfc_device_desc_t * pndd)
|
||||||
void
|
void
|
||||||
arygon_disconnect (nfc_device_t * pnd)
|
arygon_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
uart_close (((struct arygon_data*)(pnd->driver_data))->port);
|
uart_close (DRIVER_DATA (pnd)->port);
|
||||||
free(pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free(pnd->chip_data);
|
|
||||||
free (pnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ARYGON_TX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD + 1)
|
#define ARYGON_TX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD + 1)
|
||||||
|
@ -204,11 +202,11 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
|
||||||
{
|
{
|
||||||
byte_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"
|
byte_t abtFrame[ARYGON_TX_BUFFER_LEN] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"
|
||||||
|
|
||||||
pnd->iLastCommand = pbtData[0];
|
CHIP_DATA (pnd)->ui8LastCommand = pbtData[0];
|
||||||
size_t szFrame = 0;
|
size_t szFrame = 0;
|
||||||
pn53x_build_frame (abtFrame + 1, &szFrame, pbtData, szData);
|
pn53x_build_frame (abtFrame + 1, &szFrame, pbtData, szData);
|
||||||
|
|
||||||
int res = uart_send (((struct arygon_data*)(pnd->driver_data))->port, abtFrame, szFrame + 1);
|
int res = uart_send (DRIVER_DATA (pnd)->port, abtFrame, szFrame + 1);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ERR ("%s", "Unable to transmit data. (TX)");
|
ERR ("%s", "Unable to transmit data. (TX)");
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
|
@ -216,7 +214,7 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t abtRxBuf[6];
|
byte_t abtRxBuf[6];
|
||||||
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, sizeof (abtRxBuf), 0);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, sizeof (abtRxBuf), 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ERR ("%s", "Unable to read ACK");
|
ERR ("%s", "Unable to read ACK");
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
|
@ -224,7 +222,7 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pn53x_check_ack_frame (pnd, abtRxBuf, sizeof(abtRxBuf))) {
|
if (pn53x_check_ack_frame (pnd, abtRxBuf, sizeof(abtRxBuf))) {
|
||||||
((struct pn53x_data*)(pnd->chip_data))->state = EXECUTE;
|
CHIP_DATA (pnd)->state = EXECUTE;
|
||||||
} else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) {
|
} else if (0 == memcmp(arygon_error_unknown_mode, abtRxBuf, sizeof(abtRxBuf))) {
|
||||||
ERR( "Bad frame format." );
|
ERR( "Bad frame format." );
|
||||||
return false;
|
return false;
|
||||||
|
@ -237,12 +235,12 @@ arygon_tama_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szDat
|
||||||
int
|
int
|
||||||
arygon_abort (nfc_device_t *pnd)
|
arygon_abort (nfc_device_t *pnd)
|
||||||
{
|
{
|
||||||
((struct pn53x_data*)(pnd->chip_data))->state = NORMAL;
|
CHIP_DATA (pnd)->state = NORMAL;
|
||||||
|
|
||||||
// Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
|
// Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
|
||||||
byte_t dummy[] = { 0x32, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 0x6c, 0x69, 0x62, 0x6e, 0x66, 0x63, 0xbe, 0x00 };
|
byte_t dummy[] = { 0x32, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 0x6c, 0x69, 0x62, 0x6e, 0x66, 0x63, 0xbe, 0x00 };
|
||||||
|
|
||||||
uart_send (((struct arygon_data*)(pnd->driver_data))->port, dummy, sizeof (dummy));
|
uart_send (DRIVER_DATA (pnd)->port, dummy, sizeof (dummy));
|
||||||
|
|
||||||
// Using Arygon device we can't send ACK frame to abort the running command
|
// Using Arygon device we can't send ACK frame to abort the running command
|
||||||
return (pn53x_check_communication (pnd)) ? 0 : -1;
|
return (pn53x_check_communication (pnd)) ? 0 : -1;
|
||||||
|
@ -255,7 +253,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
size_t len;
|
size_t len;
|
||||||
int abort_fd = 0;
|
int abort_fd = 0;
|
||||||
|
|
||||||
switch (pnd->iLastCommand) {
|
switch (CHIP_DATA (pnd)->ui8LastCommand) {
|
||||||
case InAutoPoll:
|
case InAutoPoll:
|
||||||
case TgInitAsTarget:
|
case TgInitAsTarget:
|
||||||
case TgGetData:
|
case TgGetData:
|
||||||
|
@ -265,7 +263,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 5, abort_fd);
|
int res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 5, abort_fd);
|
||||||
|
|
||||||
if (abort_fd && (DEABORT == res)) {
|
if (abort_fd && (DEABORT == res)) {
|
||||||
return arygon_abort (pnd);
|
return arygon_abort (pnd);
|
||||||
|
@ -286,7 +284,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
|
|
||||||
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
||||||
// Error frame
|
// Error frame
|
||||||
uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 3, 0);
|
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0);
|
||||||
ERR ("%s", "Application level error detected");
|
ERR ("%s", "Application level error detected");
|
||||||
pnd->iLastError = DEISERRFRAME;
|
pnd->iLastError = DEISERRFRAME;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -314,7 +312,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
}
|
}
|
||||||
|
|
||||||
// TFI + PD0 (CC+1)
|
// TFI + PD0 (CC+1)
|
||||||
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 2, 0);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ERR ("%s", "Unable to receive data. (RX)");
|
ERR ("%s", "Unable to receive data. (RX)");
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
|
@ -327,14 +325,14 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abtRxBuf[1] != pnd->iLastCommand + 1) {
|
if (abtRxBuf[1] != CHIP_DATA (pnd)->ui8LastCommand + 1) {
|
||||||
ERR ("%s", "Command Code verification failed");
|
ERR ("%s", "Command Code verification failed");
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, pbtData, len, 0);
|
res = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ERR ("%s", "Unable to receive data. (RX)");
|
ERR ("%s", "Unable to receive data. (RX)");
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
|
@ -342,7 +340,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRxBuf, 2, 0);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ERR ("%s", "Unable to receive data. (RX)");
|
ERR ("%s", "Unable to receive data. (RX)");
|
||||||
pnd->iLastError = res;
|
pnd->iLastError = res;
|
||||||
|
@ -350,7 +348,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t btDCS = (256 - 0xD5);
|
byte_t btDCS = (256 - 0xD5);
|
||||||
btDCS -= pnd->iLastCommand + 1;
|
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
|
||||||
for (size_t szPos = 0; szPos < len; szPos++) {
|
for (size_t szPos = 0; szPos < len; szPos++) {
|
||||||
btDCS -= pbtData[szPos];
|
btDCS -= pbtData[szPos];
|
||||||
}
|
}
|
||||||
|
@ -366,7 +364,7 @@ arygon_tama_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLe
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
((struct pn53x_data*)(pnd->chip_data))->state = NORMAL;
|
CHIP_DATA (pnd)->state = NORMAL;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,12 +376,12 @@ arygon_firmware (nfc_device_t * pnd, char * str)
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
|
|
||||||
|
|
||||||
int res = uart_send (((struct arygon_data*)(pnd->driver_data))->port, arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd));
|
int res = uart_send (DRIVER_DATA (pnd)->port, arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd));
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
DBG ("Unable to send ARYGON firmware command.");
|
DBG ("Unable to send ARYGON firmware command.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRx, szRx, 0);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRx, szRx, 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
DBG ("Unable to retrieve ARYGON firmware version.");
|
DBG ("Unable to retrieve ARYGON firmware version.");
|
||||||
return;
|
return;
|
||||||
|
@ -406,11 +404,11 @@ arygon_reset_tama (nfc_device_t * pnd)
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
uart_send (((struct arygon_data*)(pnd->driver_data))->port, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
|
uart_send (DRIVER_DATA (pnd)->port, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
|
||||||
|
|
||||||
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
|
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
|
||||||
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
|
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
|
||||||
res = uart_receive (((struct arygon_data*)(pnd->driver_data))->port, abtRx, szRx, 0);
|
res = uart_receive (DRIVER_DATA (pnd)->port, abtRx, szRx, 0);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
DBG ("No reply to 'reset TAMA' command.");
|
DBG ("No reply to 'reset TAMA' command.");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -88,25 +88,26 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
|
||||||
// Serial port claimed but we need to check if a PN532_UART is connected.
|
// Serial port claimed but we need to check if a PN532_UART is connected.
|
||||||
uart_set_speed (sp, PN532_UART_DEFAULT_SPEED);
|
uart_set_speed (sp, PN532_UART_DEFAULT_SPEED);
|
||||||
|
|
||||||
nfc_device_t nd;
|
nfc_device_t *pnd = nfc_device_new ();
|
||||||
nd.driver = &pn532_uart_driver;
|
pnd->iLastError = 0;
|
||||||
nd.driver_data = malloc(sizeof(struct pn532_uart_data));
|
pnd->driver = &pn532_uart_driver;
|
||||||
((struct pn532_uart_data*)(nd.driver_data))->port = sp;
|
pnd->driver_data = malloc(sizeof(struct pn532_uart_data));
|
||||||
nd.chip_data = malloc(sizeof(struct pn53x_data));
|
DRIVER_DATA (pnd)->port = sp;
|
||||||
((struct pn53x_data*)(nd.chip_data))->type = PN532;
|
pnd->chip_data = malloc(sizeof(struct pn53x_data));
|
||||||
((struct pn53x_data*)(nd.chip_data))->state = SLEEP;
|
CHIP_DATA (pnd)->type = PN532;
|
||||||
((struct pn53x_data*)(nd.chip_data))->io = &pn532_uart_io;
|
CHIP_DATA (pnd)->state = SLEEP;
|
||||||
|
CHIP_DATA (pnd)->io = &pn532_uart_io;
|
||||||
|
|
||||||
|
|
||||||
// PN532 could be powered down, we need to wake it up before line testing.
|
|
||||||
// TODO pn532_uart_wakeup ((nfc_device_spec_t) sp);
|
|
||||||
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
||||||
bool res = pn53x_check_communication (&nd);
|
bool res = pn53x_check_communication (pnd);
|
||||||
free(nd.driver_data);
|
if(!res) {
|
||||||
free(nd.chip_data);
|
nfc_perror (pnd, "pn53x_check_communication");
|
||||||
|
}
|
||||||
|
nfc_device_free (pnd);
|
||||||
uart_close (sp);
|
uart_close (sp);
|
||||||
if(!res)
|
if(!res) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
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].pcDriver = PN532_UART_DRIVER_NAME;
|
pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME;
|
||||||
|
@ -164,6 +165,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
|
||||||
|
|
||||||
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
// Check communication using "Diagnose" command, with "Communication test" (0x00)
|
||||||
if (!pn53x_check_communication (pnd)) {
|
if (!pn53x_check_communication (pnd)) {
|
||||||
|
nfc_perror (pnd, "pn53x_check_communication");
|
||||||
pn532_uart_disconnect(pnd);
|
pn532_uart_disconnect(pnd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -176,9 +178,7 @@ void
|
||||||
pn532_uart_disconnect (nfc_device_t * pnd)
|
pn532_uart_disconnect (nfc_device_t * pnd)
|
||||||
{
|
{
|
||||||
uart_close (DRIVER_DATA(pnd)->port);
|
uart_close (DRIVER_DATA(pnd)->port);
|
||||||
free (pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free (pnd->chip_data);
|
|
||||||
free (pnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
#define PN532_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
||||||
|
@ -198,7 +198,7 @@ pn532_uart_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||||
pnd->iLastCommand = pbtData[0];
|
CHIP_DATA (pnd)->ui8LastCommand = pbtData[0];
|
||||||
size_t szFrame = 0;
|
size_t szFrame = 0;
|
||||||
|
|
||||||
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
|
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
|
||||||
|
@ -233,7 +233,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
||||||
size_t len;
|
size_t len;
|
||||||
int abort_fd = 0;
|
int abort_fd = 0;
|
||||||
|
|
||||||
switch (pnd->iLastCommand) {
|
switch (CHIP_DATA (pnd)->ui8LastCommand) {
|
||||||
case InAutoPoll:
|
case InAutoPoll:
|
||||||
case TgInitAsTarget:
|
case TgInitAsTarget:
|
||||||
case TgGetData:
|
case TgGetData:
|
||||||
|
@ -305,7 +305,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abtRxBuf[1] != pnd->iLastCommand + 1) {
|
if (abtRxBuf[1] != CHIP_DATA (pnd)->ui8LastCommand + 1) {
|
||||||
ERR ("%s", "Command Code verification failed");
|
ERR ("%s", "Command Code verification failed");
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -328,7 +328,7 @@ pn532_uart_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t btDCS = (256 - 0xD5);
|
byte_t btDCS = (256 - 0xD5);
|
||||||
btDCS -= pnd->iLastCommand + 1;
|
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
|
||||||
for (size_t szPos = 0; szPos < len; szPos++) {
|
for (size_t szPos = 0; szPos < len; szPos++) {
|
||||||
btDCS -= pbtData[szPos];
|
btDCS -= pbtData[szPos];
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file pn53x_usb.c
|
* @file pn53x_usb.c
|
||||||
* @brief Driver common routines for PN53x chips using USB
|
* @brief Driver for PN53x using USB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -32,6 +32,8 @@
|
||||||
Thanks to d18c7db and Okko for example code
|
Thanks to d18c7db and Okko for example code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
@ -72,9 +74,18 @@ bool pn53x_usb_get_usb_device_name (struct usb_device *dev, usb_dev_handle *udev
|
||||||
int
|
int
|
||||||
pn53x_usb_bulk_read (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx)
|
pn53x_usb_bulk_read (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx)
|
||||||
{
|
{
|
||||||
int ret = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, USB_TIMEOUT);
|
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, USB_TIMEOUT);
|
||||||
PRINT_HEX ("RX", abtRx, ret);
|
PRINT_HEX ("RX", abtRx, res);
|
||||||
return ret;
|
return res;
|
||||||
|
}
|
||||||
|
int
|
||||||
|
|
||||||
|
pn53x_usb_bulk_read_ex (struct pn53x_usb_data *data, byte_t abtRx[], const size_t szRx, int timeout)
|
||||||
|
{
|
||||||
|
int res = usb_bulk_read (data->pudh, data->uiEndPointIn, (char *) abtRx, szRx, timeout);
|
||||||
|
if (res > 0)
|
||||||
|
PRINT_HEX ("RX", abtRx, res);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -267,7 +278,7 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
||||||
}
|
}
|
||||||
data.model = pn53x_usb_get_device_model (dev->descriptor.idVendor, dev->descriptor.idProduct);
|
data.model = pn53x_usb_get_device_model (dev->descriptor.idVendor, dev->descriptor.idProduct);
|
||||||
// Allocate memory for the device info and specification, fill it and return the info
|
// Allocate memory for the device info and specification, fill it and return the info
|
||||||
pnd = malloc (sizeof (nfc_device_t));
|
pnd = nfc_device_new ();
|
||||||
pn53x_usb_get_usb_device_name (dev, data.pudh, pnd->acName, sizeof (pnd->acName));
|
pn53x_usb_get_usb_device_name (dev, data.pudh, pnd->acName, sizeof (pnd->acName));
|
||||||
|
|
||||||
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
|
pnd->driver_data = malloc(sizeof(struct pn53x_usb_data));
|
||||||
|
@ -283,46 +294,10 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
||||||
|
|
||||||
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
|
// HACK2: Then send a GetFirmware command to resync USB toggle bit between host & device
|
||||||
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
|
// in case host used set_configuration and expects the device to have reset its toggle bit, which PN53x doesn't do
|
||||||
#if 1
|
|
||||||
if (!pn53x_init (pnd)) {
|
if (!pn53x_init (pnd)) {
|
||||||
usb_close (data.pudh);
|
usb_close (data.pudh);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
byte_t abtTx[] = { 0x00, 0x00, 0xff, 0x02, 0xfe, 0xd4, 0x02, 0x2a, 0x00 };
|
|
||||||
byte_t abtRx[BUFFER_LENGTH];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pn53x_usb_bulk_write (data, abtTx, sizeof(abtTx));
|
|
||||||
if (ret < 0) {
|
|
||||||
DBG ("usb_bulk_write failed with error %d", ret);
|
|
||||||
usb_close (data.pudh);
|
|
||||||
// we failed to use the specified device
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
ret = pn53x_usb_bulk_read (data, (char *) abtRx, s);
|
|
||||||
if (ret < 0) {
|
|
||||||
DBG ("usb_bulk_read failed with error %d", ret);
|
|
||||||
usb_close (us.pudh);
|
|
||||||
// we failed to use the specified device
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (ret == 6) { // we got the ACK/NACK properly
|
|
||||||
if (!pn53x_check_ack_frame (pnd, abtRx, ret)) {
|
|
||||||
DBG ("pn53x_check_ack_frame failed");
|
|
||||||
usb_close (us.pudh);
|
|
||||||
// we failed to use the specified device
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
ret = pn53x_usb_bulk_read (data, (char *) abtRx, BUFFER_LENGTH);
|
|
||||||
if (ret < 0) {
|
|
||||||
DBG ("usb_bulk_read failed with error %d", ret);
|
|
||||||
usb_close (us.pudh);
|
|
||||||
// we failed to use the specified device
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return pnd;
|
return pnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,9 +307,7 @@ pn53x_usb_connect (const nfc_device_desc_t *pndd)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
// Free allocated structure on error.
|
// Free allocated structure on error.
|
||||||
free(pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free(pnd->chip_data);
|
|
||||||
free(pnd);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,9 +325,7 @@ pn53x_usb_disconnect (nfc_device_t * pnd)
|
||||||
if ((res = usb_close (DRIVER_DATA (pnd)->pudh)) < 0) {
|
if ((res = usb_close (DRIVER_DATA (pnd)->pudh)) < 0) {
|
||||||
ERR ("usb_close failed (%i)", res);
|
ERR ("usb_close failed (%i)", res);
|
||||||
}
|
}
|
||||||
free(pnd->driver_data);
|
nfc_device_free (pnd);
|
||||||
free(pnd->chip_data);
|
|
||||||
free(pnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PN53X_USB_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
#define PN53X_USB_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
|
||||||
|
@ -363,7 +334,7 @@ bool
|
||||||
pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
|
pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
|
||||||
{
|
{
|
||||||
byte_t abtFrame[PN53X_USB_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
byte_t abtFrame[PN53X_USB_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||||
pnd->iLastCommand = pbtData[0];
|
CHIP_DATA (pnd)->ui8LastCommand = pbtData[0];
|
||||||
size_t szFrame = 0;
|
size_t szFrame = 0;
|
||||||
|
|
||||||
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
|
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
|
||||||
|
@ -406,7 +377,7 @@ pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen)
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
int abort_fd = 0;
|
int abort_fd = 0;
|
||||||
|
|
||||||
switch (pnd->iLastCommand) {
|
switch (CHIP_DATA (pnd)->ui8LastCommand) {
|
||||||
case InAutoPoll:
|
case InAutoPoll:
|
||||||
case TgInitAsTarget:
|
case TgInitAsTarget:
|
||||||
case TgGetData:
|
case TgGetData:
|
||||||
|
@ -417,7 +388,35 @@ pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
byte_t abtRxBuf[PN53X_USB_BUFFER_LEN];
|
||||||
int res = pn53x_usb_bulk_read (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf));
|
int res;
|
||||||
|
|
||||||
|
read:
|
||||||
|
res = pn53x_usb_bulk_read_ex (DRIVER_DATA (pnd), abtRxBuf, sizeof (abtRxBuf), 250);
|
||||||
|
|
||||||
|
if (res == -ETIMEDOUT) {
|
||||||
|
struct timeval tv = {
|
||||||
|
.tv_sec = 0,
|
||||||
|
.tv_usec = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
fd_set readfds;
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(abort_fd, &readfds);
|
||||||
|
switch (select (abort_fd + 1, &readfds, NULL, NULL, &tv)) {
|
||||||
|
case -1:
|
||||||
|
// An error occured
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
// Timeout
|
||||||
|
goto read;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return (pn53x_usb_ack (pnd) >= 0) ? true : false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG ("usb_bulk_read failed with error %d", res);
|
DBG ("usb_bulk_read failed with error %d", res);
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
|
@ -474,7 +473,7 @@ pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen)
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
if (abtRxBuf[offset] != pnd->iLastCommand + 1) {
|
if (abtRxBuf[offset] != CHIP_DATA (pnd)->ui8LastCommand + 1) {
|
||||||
ERR ("%s", "Command Code verification failed");
|
ERR ("%s", "Command Code verification failed");
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = DEIO;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -485,7 +484,7 @@ pn53x_usb_receive (nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen)
|
||||||
offset += len;
|
offset += len;
|
||||||
|
|
||||||
byte_t btDCS = (256 - 0xD5);
|
byte_t btDCS = (256 - 0xD5);
|
||||||
btDCS -= pnd->iLastCommand + 1;
|
btDCS -= CHIP_DATA (pnd)->ui8LastCommand + 1;
|
||||||
for (size_t szPos = 0; szPos < len; szPos++) {
|
for (size_t szPos = 0; szPos < len; szPos++) {
|
||||||
btDCS -= pbtData[szPos];
|
btDCS -= pbtData[szPos];
|
||||||
}
|
}
|
||||||
|
|
35
libnfc/nfc-device.c
Normal file
35
libnfc/nfc-device.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* vim:set et sw=2 ts=2: */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "nfc-internal.h"
|
||||||
|
|
||||||
|
nfc_device_t *
|
||||||
|
nfc_device_new (void)
|
||||||
|
{
|
||||||
|
nfc_device_t *res = malloc (sizeof (*res));
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
err (EXIT_FAILURE, "nfc_device_new: malloc");
|
||||||
|
}
|
||||||
|
|
||||||
|
res->bCrc = true;
|
||||||
|
res->bPar = true;
|
||||||
|
res->bEasyFraming = true;
|
||||||
|
res->bAutoIso14443_4 = true;
|
||||||
|
res->iLastError = 0;
|
||||||
|
res->driver_data = NULL;
|
||||||
|
res->chip_data = NULL;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nfc_device_free (nfc_device_t *nfc_device)
|
||||||
|
{
|
||||||
|
if (nfc_device) {
|
||||||
|
free (nfc_device->driver_data);
|
||||||
|
free (nfc_device->chip_data);
|
||||||
|
free (nfc_device);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,8 @@
|
||||||
#ifndef __NFC_INTERNAL_H__
|
#ifndef __NFC_INTERNAL_H__
|
||||||
# define __NFC_INTERNAL_H__
|
# define __NFC_INTERNAL_H__
|
||||||
|
|
||||||
|
# include <nfc/nfc-types.h>
|
||||||
|
# include <stdbool.h>
|
||||||
# include <err.h>
|
# include <err.h>
|
||||||
|
|
||||||
// TODO: Put generic errors here
|
// TODO: Put generic errors here
|
||||||
|
@ -122,4 +124,8 @@ struct nfc_driver_t {
|
||||||
bool (*configure) (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
bool (*configure) (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nfc_device_t *nfc_device_new (void);
|
||||||
|
void nfc_device_free (nfc_device_t *nfc_device);
|
||||||
|
|
||||||
|
|
||||||
#endif // __NFC_INTERNAL_H__
|
#endif // __NFC_INTERNAL_H__
|
||||||
|
|
Loading…
Add table
Reference in a new issue