Second part of error handling.
- Define two sets of DE<FOOBAR> macros: the first one for 'generic' errors which could be encountered regardless of the NFC device the library is acting with (0xX000), and ont set for device-dependant errors (0x0X00). - Make some more functions accept a nfc_device_t* as first argument to have access to the iLastError; - Reset errors when entering public API functions; - Save errors when applicable; - Distinguish system-level errors (e.g. I/O error) and operational errors (the PCD returns an unexpected value); - Minor tweaks. Update issue 65 Status: Feedback New review: Owner: rconty@il4p.fr Cc: rtartiere@il4p.fr Summary: Review the error-handling code. Branch: /branches/libnfc-error-handling For this development, a strong emphasis has been set on making changes that will not go through our way on the way to libnfc-1.6+. For this reason, some constructs are not natural (e.g. error codes defined in two different places), please keep this in mind when reviewing.
This commit is contained in:
parent
d7e0b926ac
commit
08eb21aa9d
9 changed files with 166 additions and 31 deletions
include/nfc
libnfc
|
@ -69,7 +69,14 @@ typedef struct {
|
|||
bool bPar;
|
||||
/** 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 */
|
||||
/** Last error reported by the PCD / encountered by the PCD driver
|
||||
* MSB LSB
|
||||
* | 00 | 00 |
|
||||
* || ||
|
||||
* || ++----- Chip-level error (as reported by the PCD)
|
||||
* |+---------- Driver-level specific error
|
||||
* +----------- Driver-level general error (common to all drivers)
|
||||
*/
|
||||
int iLastError;
|
||||
} nfc_device_t;
|
||||
|
||||
|
|
|
@ -92,6 +92,11 @@ 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 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
|
|
@ -36,6 +36,7 @@ http://www.teuniz.net/RS-232/index.html
|
|||
|
||||
#include "uart.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
// Test if we are dealing with unix operating systems
|
||||
|
@ -106,8 +107,9 @@ serial_port uart_open(const char* pcPortName)
|
|||
return sp;
|
||||
}
|
||||
|
||||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
void uart_set_speed(nfc_device_t* pnd, const uint32_t uiPortSpeed)
|
||||
{
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
// Set port speed (Input and Output)
|
||||
|
||||
|
@ -149,8 +151,9 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t uart_get_speed(const serial_port sp)
|
||||
uint32_t uart_get_speed(const nfc_device_t* pnd)
|
||||
{
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
uint32_t uiPortSpeed = 0;
|
||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||
switch (cfgetispeed(&spu->tiNew))
|
||||
|
@ -191,12 +194,13 @@ void uart_close(const serial_port sp)
|
|||
free(sp);
|
||||
}
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
int res;
|
||||
int byteCount;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
|
||||
// Reset the output count
|
||||
*pszRxLen = 0;
|
||||
|
@ -211,6 +215,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
// Read error
|
||||
if (res < 0) {
|
||||
DBG("%s", "RX error.");
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -219,6 +224,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
if (*pszRxLen == 0) {
|
||||
// Error, we received no data
|
||||
DBG("%s", "RX time-out, buffer empty.");
|
||||
pnd->iLastError = DETIMEOUT;
|
||||
return false;
|
||||
} else {
|
||||
// We received some data, but nothing more is available
|
||||
|
@ -228,13 +234,19 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
|
||||
// Retrieve the count of the incoming bytes
|
||||
res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
|
||||
if (res < 0) return false;
|
||||
if (res < 0) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
// There is something available, read the data
|
||||
res = read(((serial_port_unix*)sp)->fd,pbtRx+(*pszRxLen),byteCount);
|
||||
|
||||
// Stop if the OS has some troubles reading the data
|
||||
if (res <= 0) return false;
|
||||
if (res <= 0) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
*pszRxLen += res;
|
||||
|
||||
|
@ -243,12 +255,13 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
bool uart_send(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
int32_t res;
|
||||
size_t szPos = 0;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
|
||||
while (szPos < szTxLen)
|
||||
{
|
||||
|
@ -261,12 +274,14 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
// Write error
|
||||
if (res < 0) {
|
||||
DBG("%s", "TX error.");
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write time-out
|
||||
if (res == 0) {
|
||||
DBG("%s", "TX time-out.");
|
||||
pnd->iLastError = DETIMEOUT;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -274,7 +289,10 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
|||
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 false;
|
||||
if (res <= 0) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
szPos += res;
|
||||
}
|
||||
|
@ -342,6 +360,7 @@ serial_port uart_open(const char* pcPortName)
|
|||
|
||||
void uart_close(const serial_port sp)
|
||||
{
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
if (((serial_port_windows*)sp)->hPort != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(((serial_port_windows*)sp)->hPort);
|
||||
}
|
||||
|
@ -350,6 +369,7 @@ void uart_close(const serial_port sp)
|
|||
|
||||
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||
{
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
serial_port_windows* spw;
|
||||
|
||||
DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||
|
@ -377,6 +397,7 @@ void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
|||
|
||||
uint32_t uart_get_speed(const serial_port sp)
|
||||
{
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
const serial_port_windows* spw = (serial_port_windows*)sp;
|
||||
if (!GetCommState(spw->hPort, (serial_port)&spw->dcb))
|
||||
return spw->dcb.BaudRate;
|
||||
|
@ -384,16 +405,24 @@ uint32_t uart_get_speed(const serial_port sp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||
bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||
{
|
||||
ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL);
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
if (!ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL)) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
return (*pszRxLen != 0);
|
||||
}
|
||||
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
bool uart_send(nfc_device_t* pnd, const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
serial_port sp = (serial_port)pnd->nds;
|
||||
DWORD dwTxLen = 0;
|
||||
return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL);
|
||||
if (!WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL)) {
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
return (dwTxLen != 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,11 +81,11 @@ typedef void* serial_port;
|
|||
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(nfc_device_t* pnd, const uint32_t uiPortSpeed);
|
||||
uint32_t uart_get_speed(const nfc_device_t* pnd);
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
|
||||
bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
||||
bool uart_send(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
||||
|
||||
#endif // __NFC_BUS_UART_H__
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
// FIXME: WTF are doing debug macros in this file?
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
|
@ -69,17 +70,19 @@ static const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
|||
|
||||
bool pn53x_transceive_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
||||
{
|
||||
(void) pnd; // I guess we will want to set some error here at some point
|
||||
|
||||
if (szRxFrameLen == sizeof (pn53x_ack_frame)) {
|
||||
if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
|
||||
DBG("%s", "PN53x ACKed");
|
||||
return true;
|
||||
} else if (0 == memcmp (pbtRxFrame, pn53x_nack_frame, sizeof (pn53x_nack_frame))) {
|
||||
DBG("%s", "PN53x NACKed");
|
||||
// TODO: Try to recover
|
||||
// A counter could allow the command to be sent again (e.g. max 3 times)
|
||||
pnd->iLastError = DENACK;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pnd->iLastError = DEACKMISMATCH;
|
||||
ERR("%s", "Unexpected PN53x reply!");
|
||||
#if defined(DEBUG)
|
||||
// coredump so that we can have a backtrace about how this code was reached.
|
||||
|
@ -382,6 +385,7 @@ static struct sErrorMessage {
|
|||
int iErrorCode;
|
||||
const char *pcErrorMsg;
|
||||
} sErrorMessages[] = {
|
||||
/* Chip-level errors */
|
||||
{ 0x00, "Success" },
|
||||
{ 0x01, "Timeout" },
|
||||
{ 0x02, "CRC Error" },
|
||||
|
@ -411,7 +415,16 @@ static struct sErrorMessage {
|
|||
{ 0x2B, "Card Discarded" },
|
||||
{ 0x2C, "NFCID3 Mismatch" },
|
||||
{ 0x2D, "Over Current" },
|
||||
{ 0x2E, "NAD Missing in DEP Frame" }
|
||||
{ 0x2E, "NAD Missing in DEP Frame" },
|
||||
|
||||
/* Driver-level error */
|
||||
{ DENACK, "Received NACK" },
|
||||
{ DEACKMISMATCH, "Expected ACK/NACK" },
|
||||
{ DEISERRFRAME, "Received an error frame" },
|
||||
/* TODO: Move me in more generic code for libnfc 1.6 */
|
||||
{ DEINVAL, "Invalid argument" },
|
||||
{ DEIO, "Input/output error" },
|
||||
{ DETIMEOUT, "Operation timed-out" }
|
||||
};
|
||||
|
||||
const char *
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
#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 */
|
||||
|
||||
bool pn53x_transceive_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);
|
||||
byte_t pn53x_get_reg(nfc_device_t* pnd, uint16_t ui16Reg);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "pn532_uart.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
// Bus
|
||||
|
@ -43,7 +44,7 @@
|
|||
#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 pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success);
|
||||
|
||||
nfc_device_desc_t *
|
||||
pn532_uart_pick_device (void)
|
||||
|
@ -101,12 +102,16 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_
|
|||
|
||||
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);
|
||||
// PN532 could be powered down, we need to wake it up before line testing.
|
||||
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)) continue;
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp), &bComOk)
|
||||
return false;
|
||||
if (!bComOk)
|
||||
continue;
|
||||
uart_close(sp);
|
||||
|
||||
snprintf(pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", acPort);
|
||||
|
@ -134,6 +139,7 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
{
|
||||
serial_port sp;
|
||||
nfc_device_t* pnd = NULL;
|
||||
bool bComOk;
|
||||
|
||||
if( pndd == NULL ) {
|
||||
DBG("%s", "pn532_uart_connect() need an nfc_device_desc_t struct.");
|
||||
|
@ -151,7 +157,10 @@ nfc_device_t* pn532_uart_connect(const nfc_device_desc_t* pndd)
|
|||
// PN532 could be powered down, we need to wake it up before line testing.
|
||||
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)) return NULL;
|
||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp, &bComOk))
|
||||
return NULL;
|
||||
if (!bComOk)
|
||||
return NULL;
|
||||
|
||||
DBG("Successfully connected to: %s",pndd->pcPort);
|
||||
|
||||
|
@ -206,12 +215,14 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
|||
#endif
|
||||
if (!uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+7)) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
szRxBufLen = 6;
|
||||
if (!uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen)) {
|
||||
ERR("%s", "Unable to receive data. (RX)");
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -236,13 +247,17 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
|||
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) {
|
||||
pnd->iLastError = DEINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", ack_frame,6);
|
||||
#endif
|
||||
if (!uart_send((serial_port)pnd->nds,ack_frame,6)) {
|
||||
ERR("%s", "Unable to transmit data. (TX)");
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -274,7 +289,7 @@ pn532_uart_wakeup(const nfc_device_spec_t nds)
|
|||
}
|
||||
|
||||
bool
|
||||
pn532_uart_check_communication(const nfc_device_spec_t nds)
|
||||
pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||
{
|
||||
byte_t abtRx[BUFFER_LENGTH];
|
||||
size_t szRxLen;
|
||||
|
@ -283,10 +298,13 @@ pn532_uart_check_communication(const nfc_device_spec_t nds)
|
|||
/** 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 };
|
||||
|
||||
*success = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRINT_HEX("TX", pncmd_communication_test,sizeof(pncmd_communication_test));
|
||||
#endif
|
||||
uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test));
|
||||
if (!uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test)))
|
||||
return false;
|
||||
|
||||
if(!uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||
return false;
|
||||
|
@ -295,10 +313,9 @@ pn532_uart_check_communication(const nfc_device_spec_t nds)
|
|||
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.");
|
||||
return false;
|
||||
}
|
||||
if(0 == memcmp(abtRx,attempted_result,sizeof(attempted_result)))
|
||||
*success = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ Thanks to d18c7db and Okko for example code
|
|||
#include "../drivers.h"
|
||||
#include "../chips/pn53x.h"
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
#include <nfc/nfc-messages.h>
|
||||
|
||||
#define BUFFER_LENGTH 256
|
||||
|
@ -271,6 +272,7 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
if( ret < 0 )
|
||||
{
|
||||
DBG("usb_bulk_write failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -278,6 +280,7 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
if( ret < 0 )
|
||||
{
|
||||
DBG( "usb_bulk_read failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -292,6 +295,7 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
if( ret < 0 )
|
||||
{
|
||||
DBG("usb_bulk_read failed with error %d", ret);
|
||||
pnd->iLastError = DEIO;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -311,6 +315,7 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
if(ret < 9)
|
||||
{
|
||||
DBG("%s","No data");
|
||||
pnd->iLastError = DEINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -327,5 +332,8 @@ bool pn53x_usb_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
|
||||
memcpy( pbtRx, abtRx + 7, *pszRxLen);
|
||||
|
||||
if (abtRx[5] != pbtTx[0] + 1) {
|
||||
pnd->iLastError = DEISERRFRAME;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
55
libnfc/nfc.c
55
libnfc/nfc.c
|
@ -258,6 +258,9 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
|||
{
|
||||
byte_t btValue;
|
||||
byte_t abtCmd[sizeof(pncmd_rf_configure)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_rf_configure,sizeof(pncmd_rf_configure));
|
||||
|
||||
// Make sure we are dealing with a active device
|
||||
|
@ -330,6 +333,9 @@ bool nfc_configure(nfc_device_t* pnd, const nfc_device_option_t ndo, const bool
|
|||
*/
|
||||
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;
|
||||
|
||||
|
@ -364,6 +370,9 @@ bool nfc_initiator_select_dep_target(nfc_device_t* pnd, const nfc_modulation_t n
|
|||
size_t szRxLen;
|
||||
size_t offset;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_jump_for_dep)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_jump_for_dep,sizeof(pncmd_initiator_jump_for_dep));
|
||||
|
||||
if(nmInitModulation == NM_ACTIVE_DEP) {
|
||||
|
@ -433,6 +442,9 @@ nfc_initiator_select_passive_target(nfc_device_t* pnd,
|
|||
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;
|
||||
|
||||
|
@ -551,6 +563,9 @@ bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_
|
|||
bool bCollisionDetected = false;
|
||||
size_t szTargetFound = 0;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Let the reader only try once to find a target
|
||||
nfc_configure (pnd, NDO_INFINITE_SELECT, false);
|
||||
|
||||
|
@ -628,6 +643,9 @@ bool nfc_initiator_list_passive_targets(nfc_device_t* pnd, const nfc_modulation_
|
|||
*/
|
||||
bool nfc_initiator_deselect_target(nfc_device_t* pnd)
|
||||
{
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
return (pn53x_InDeselect(pnd, 0)); // 0 mean deselect all selected targets
|
||||
}
|
||||
|
||||
|
@ -652,6 +670,9 @@ nfc_initiator_poll_targets(nfc_device_t* pnd,
|
|||
byte_t abtRx[256];
|
||||
bool res;
|
||||
byte_t *pbtTxInAutoPoll;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
if(pnd->nc == NC_PN531) {
|
||||
// errno = ENOSUPP
|
||||
return false;
|
||||
|
@ -671,7 +692,7 @@ nfc_initiator_poll_targets(nfc_device_t* pnd,
|
|||
res = pn53x_transceive(pnd, pbtTxInAutoPoll, szTxInAutoPoll, abtRx, &szRxLen);
|
||||
|
||||
if((szRxLen == 0)||(res == false)) {
|
||||
DBG("pnd->pdc->tranceive() failed: szRxLen=%ld, res=%d", (unsigned long) szRxLen, res);
|
||||
DBG("pn53x_transceive() failed: szRxLen=%ld, res=%d", (unsigned long) szRxLen, res);
|
||||
return false;
|
||||
} else {
|
||||
*pszTargetFound = abtRx[0];
|
||||
|
@ -720,6 +741,9 @@ bool nfc_initiator_transceive_bits(nfc_device_t* pnd, const byte_t* pbtTx, const
|
|||
size_t szFrameBytes = 0;
|
||||
uint8_t ui8Bits = 0;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
|
||||
|
||||
// Check if we should prepare the parity bits ourself
|
||||
|
@ -781,6 +805,9 @@ bool nfc_initiator_transceive_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx,
|
|||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_exchange_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_exchange_data,sizeof(pncmd_initiator_exchange_data));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -825,6 +852,9 @@ bool nfc_initiator_transceive_bytes(nfc_device_t* pnd, const byte_t* pbtTx, cons
|
|||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
byte_t abtCmd[sizeof(pncmd_initiator_exchange_raw_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_initiator_exchange_raw_data,sizeof(pncmd_initiator_exchange_raw_data));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -867,6 +897,9 @@ bool nfc_target_init(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits)
|
|||
bool bCrc = pnd->bCrc;
|
||||
bool bPar = pnd->bPar;
|
||||
byte_t abtCmd[sizeof(pncmd_target_init)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_init,sizeof(pncmd_target_init));
|
||||
|
||||
// Clear the target init struct, reset to all zeros
|
||||
|
@ -923,6 +956,9 @@ bool nfc_target_receive_bits(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxBits
|
|||
size_t szFrameBits;
|
||||
uint8_t ui8Bits;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Try to gather a received frame from the reader
|
||||
if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
|
||||
|
||||
|
@ -959,6 +995,9 @@ bool nfc_target_receive_dep_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszR
|
|||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Try to gather a received frame from the reader
|
||||
if (!pn53x_transceive(pnd,pncmd_target_get_data,2,abtRx,&szRxLen)) return false;
|
||||
|
||||
|
@ -983,6 +1022,9 @@ bool nfc_target_receive_bytes(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen
|
|||
byte_t abtRx[MAX_FRAME_LEN];
|
||||
size_t szRxLen;
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
|
||||
// Try to gather a received frame from the reader
|
||||
if (!pn53x_transceive(pnd,pncmd_target_receive,2,abtRx,&szRxLen)) return false;
|
||||
|
||||
|
@ -1008,6 +1050,9 @@ bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
size_t szFrameBytes = 0;
|
||||
uint8_t ui8Bits = 0;
|
||||
byte_t abtCmd[sizeof(pncmd_target_send)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
|
||||
|
||||
// Check if we should prepare the parity bits ourself
|
||||
|
@ -1048,6 +1093,9 @@ bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, const size_t s
|
|||
bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_target_send)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_send,sizeof(pncmd_target_send));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -1072,6 +1120,9 @@ bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
|||
bool nfc_target_send_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||
{
|
||||
byte_t abtCmd[sizeof(pncmd_target_set_data)];
|
||||
|
||||
pnd->iLastError = 0;
|
||||
|
||||
memcpy(abtCmd,pncmd_target_set_data,sizeof(pncmd_target_set_data));
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
|
@ -1097,7 +1148,7 @@ const char *nfc_strerror (const nfc_device_t *pnd)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen caracters
|
||||
* @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)
|
||||
|
|
Loading…
Add table
Reference in a new issue