Merge branch 'master' into master
This commit is contained in:
commit
732a282190
15 changed files with 148 additions and 60 deletions
|
|
@ -77,6 +77,8 @@
|
|||
const char *serial_ports_device_radix[] = { "tty.SLAB_USBtoUART", "tty.usbserial", "tty.usbmodem", NULL };
|
||||
# elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__FreeBSD_kernel__)
|
||||
const char *serial_ports_device_radix[] = { "cuaU", "cuau", NULL };
|
||||
# elif defined (__NetBSD__)
|
||||
const char *serial_ports_device_radix[] = { "tty0", "ttyC", "ttyS", "ttyU", "ttyY" , NULL };
|
||||
# elif defined (__linux__) || defined (__CYGWIN__)
|
||||
const char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", "ttyACM", "ttyAMA", "ttyO", NULL };
|
||||
# else
|
||||
|
|
|
|||
|
|
@ -81,32 +81,38 @@
|
|||
#define TgGetTargetStatus 0x8A
|
||||
|
||||
/** @note PN53x's normal frame:
|
||||
* See the PN532 (firmware) user manual, section 6.2.1.1: Normal information
|
||||
* frame, figure 13. Normal information frame, page 28 rev. 02 - 2007-11-07.
|
||||
*
|
||||
* .-- Start
|
||||
* | .-- Packet length
|
||||
* | | .-- Length checksum
|
||||
* | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | .-- Code
|
||||
* | | | | | .-- Packet checksum
|
||||
* | | | | | | .-- Postamble
|
||||
* V | | | | | |
|
||||
* ----- V V V V V V
|
||||
* 00 FF 02 FE D4 02 2A 00
|
||||
* .-- Preamble
|
||||
* | .-- Start
|
||||
* | | .-- Packet length
|
||||
* | | | .-- Length checksum
|
||||
* | | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | | .-- Code
|
||||
* | | | | | | .-- Packet checksum
|
||||
* | | | | | | | .-- Postamble
|
||||
* | V | | | | | |
|
||||
* V ----- V V V V V V
|
||||
* 00 00 FF 02 FE D4 02 2A 00
|
||||
*/
|
||||
|
||||
/** @note PN53x's extended frame:
|
||||
* See the PN532 (firmware) user manual, section 6.2.1.2: Extended information
|
||||
* frame, figure 14. Normal information frame, page 29 rev. 02 - 2007-11-07.
|
||||
*
|
||||
* .-- Start
|
||||
* | .-- Fixed to FF to enable extended frame
|
||||
* | | .-- Packet length
|
||||
* | | | .-- Length checksum
|
||||
* | | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | | .-- Code
|
||||
* | | | | | | .-- Packet checksum
|
||||
* | | | | | | | .-- Postamble
|
||||
* V V V | | | | |
|
||||
* ----- ----- ----- V V V V V
|
||||
* 00 FF FF FF 00 02 FE D4 02 2A 00
|
||||
* .-- Preamble
|
||||
* | .-- Start
|
||||
* | | .-- Fixed to FF to enable extended frame
|
||||
* | | | .-- Packet length
|
||||
* | | | | .-- Length checksum
|
||||
* | | | | | .-- Direction (D4 Host to PN, D5 PN to Host)
|
||||
* | | | | | | .-- Code
|
||||
* | | | | | | | .-- Packet checksum
|
||||
* | | | | | | | | .-- Postamble
|
||||
* | V V V | | | | |
|
||||
* V ----- ----- ----- V V V V V
|
||||
* 00 00 FF FF FF 00 02 FE D4 02 2A 00
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
|
||||
#elif defined(__APPLE__)
|
||||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__)
|
||||
#elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__)
|
||||
# define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
|
||||
#elif defined (__linux__)
|
||||
# include <reader.h>
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@
|
|||
// I2C address of the PN532 chip.
|
||||
#define PN532_I2C_ADDR 0x24
|
||||
|
||||
/*
|
||||
* When sending lots of data, the pn532 occasionally fails to respond in time.
|
||||
* Since it happens so rarely, lets try to fix it by re-sending the data. This
|
||||
* define allows for fine tuning the number of retries.
|
||||
*/
|
||||
#define PN532_SEND_RETRIES 3
|
||||
|
||||
// Internal data structs
|
||||
const struct pn53x_io pn532_i2c_io;
|
||||
|
||||
|
|
@ -67,13 +74,9 @@ struct pn532_i2c_data {
|
|||
volatile bool abort_flag;
|
||||
};
|
||||
|
||||
/* Delay for the loop waiting for READY frame (in ms) */
|
||||
#define PN532_RDY_LOOP_DELAY 90
|
||||
|
||||
const struct timespec rdyDelay = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = PN532_RDY_LOOP_DELAY * 1000 * 1000
|
||||
};
|
||||
/* preamble and start bytes, see pn532-internal.h for details */
|
||||
const uint8_t pn53x_preamble_and_start[] = { 0x00, 0x00, 0xff };
|
||||
#define PN53X_PREAMBLE_AND_START_LEN (sizeof(pn53x_preamble_and_start) / sizeof(pn53x_preamble_and_start[0]))
|
||||
|
||||
/* Private Functions Prototypes */
|
||||
|
||||
|
|
@ -96,6 +99,70 @@ static size_t pn532_i2c_scan(const nfc_context *context, nfc_connstring connstri
|
|||
|
||||
#define DRIVER_DATA(pnd) ((struct pn532_i2c_data*)(pnd->driver_data))
|
||||
|
||||
/*
|
||||
* Bus free time (in ms) between a STOP condition and START condition. See
|
||||
* tBuf in the PN532 data sheet, section 12.25: Timing for the I2C interface,
|
||||
* table 320. I2C timing specification, page 211, rev. 3.2 - 2007-12-07.
|
||||
*/
|
||||
#define PN532_BUS_FREE_TIME 5
|
||||
static struct timespec __transaction_stop;
|
||||
|
||||
/**
|
||||
* @brief Wrapper around i2c_read to ensure proper timing by respecting the
|
||||
* minimal free bus time between a STOP condition and a START condition.
|
||||
*
|
||||
* @note This is not thread safe, but since libnfc is single threaded
|
||||
* this should be okay.
|
||||
*
|
||||
* @param id I2C device
|
||||
* @param buf pointer on buffer used to store data
|
||||
* @param len length of the buffer
|
||||
* @return length (in bytes) of read data, or driver error code (negative value)
|
||||
*/
|
||||
static ssize_t pn532_i2c_read(const i2c_device id,
|
||||
uint8_t *buf, const size_t len)
|
||||
{
|
||||
struct timespec transaction_start, bus_free_time = { 0 };
|
||||
ssize_t ret;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &transaction_start);
|
||||
bus_free_time.tv_nsec = (PN532_BUS_FREE_TIME * 1000 * 1000) -
|
||||
(transaction_start.tv_nsec - __transaction_stop.tv_nsec);
|
||||
nanosleep(&bus_free_time, NULL);
|
||||
|
||||
ret = i2c_read(id, buf, len);
|
||||
clock_gettime(CLOCK_MONOTONIC, &__transaction_stop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wrapper around i2c_write to ensure proper timing by respecting the
|
||||
* minimal free bus time between a STOP condition and a START condition.
|
||||
*
|
||||
* @note This is not thread safe, but since libnfc is single threaded
|
||||
* this should be okay.
|
||||
*
|
||||
* @param id I2C device
|
||||
* @param buf pointer on buffer containing data
|
||||
* @param len length of the buffer
|
||||
* @return NFC_SUCCESS on success, otherwise driver error code
|
||||
*/
|
||||
static ssize_t pn532_i2c_write(const i2c_device id,
|
||||
const uint8_t *buf, const size_t len)
|
||||
{
|
||||
struct timespec transaction_start, bus_free_time = { 0 };
|
||||
ssize_t ret;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &transaction_start);
|
||||
bus_free_time.tv_nsec = (PN532_BUS_FREE_TIME * 1000 * 1000) -
|
||||
(transaction_start.tv_nsec - __transaction_stop.tv_nsec);
|
||||
nanosleep(&bus_free_time, NULL);
|
||||
|
||||
ret = i2c_write(id, buf, len);
|
||||
clock_gettime(CLOCK_MONOTONIC, &__transaction_stop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scan all available I2C buses to find PN532 devices.
|
||||
*
|
||||
|
|
@ -308,6 +375,7 @@ static int
|
|||
pn532_i2c_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int timeout)
|
||||
{
|
||||
int res = 0;
|
||||
uint8_t retries;
|
||||
|
||||
// Discard any existing data ?
|
||||
|
||||
|
|
@ -334,15 +402,22 @@ pn532_i2c_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, int
|
|||
break;
|
||||
};
|
||||
|
||||
uint8_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff"
|
||||
uint8_t abtFrame[PN532_BUFFER_LEN];
|
||||
size_t szFrame = 0;
|
||||
|
||||
memcpy(abtFrame, pn53x_preamble_and_start, PN53X_PREAMBLE_AND_START_LEN); // Every packet must start with the preamble and start bytes.
|
||||
if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) {
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
}
|
||||
|
||||
res = i2c_write(DRIVER_DATA(pnd)->dev, abtFrame, szFrame);
|
||||
for (retries = PN532_SEND_RETRIES; retries > 0; retries--) {
|
||||
res = pn532_i2c_write(DRIVER_DATA(pnd)->dev, abtFrame, szFrame);
|
||||
if (res >= 0)
|
||||
break;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Failed to transmit data. Retries left: %d.", retries - 1);
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
||||
|
|
@ -400,10 +475,7 @@ pn532_i2c_wait_rdyframe(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLe
|
|||
}
|
||||
|
||||
do {
|
||||
// Wait a little bit before reading
|
||||
nanosleep(&rdyDelay, (struct timespec *) NULL);
|
||||
|
||||
int recCount = i2c_read(DRIVER_DATA(pnd)->dev, i2cRx, szDataLen + 1);
|
||||
int recCount = pn532_i2c_read(DRIVER_DATA(pnd)->dev, i2cRx, szDataLen + 1);
|
||||
|
||||
if (DRIVER_DATA(pnd)->abort_flag) {
|
||||
// Reset abort flag
|
||||
|
|
@ -477,9 +549,7 @@ pn532_i2c_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, int
|
|||
goto error;
|
||||
}
|
||||
|
||||
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
||||
|
||||
if (0 != (memcmp(frameBuf, pn53x_preamble, 3))) {
|
||||
if (0 != (memcmp(frameBuf, pn53x_preamble_and_start, PN53X_PREAMBLE_AND_START_LEN))) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
goto error;
|
||||
|
|
@ -572,7 +642,7 @@ error:
|
|||
int
|
||||
pn532_i2c_ack(nfc_device *pnd)
|
||||
{
|
||||
return i2c_write(DRIVER_DATA(pnd)->dev, pn53x_ack_frame, sizeof(pn53x_ack_frame));
|
||||
return pn532_i2c_write(DRIVER_DATA(pnd)->dev, pn53x_ack_frame, sizeof(pn53x_ack_frame));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,6 +39,5 @@
|
|||
uint8_t mirror(uint8_t bt);
|
||||
uint32_t mirror32(uint32_t ui32Bits);
|
||||
uint64_t mirror64(uint64_t ui64Bits);
|
||||
void mirror_uint8_ts(uint8_t *pbts, size_t szLen);
|
||||
|
||||
#endif // _LIBNFC_MIRROR_SUBR_H_
|
||||
|
|
|
|||
|
|
@ -242,7 +242,6 @@ connstring_decode(const nfc_connstring connstring, const char *driver_name, cons
|
|||
int res = sscanf(connstring, format, param0, param1, param2);
|
||||
|
||||
if (res < 1 || ((0 != strcmp(param0, driver_name)) &&
|
||||
(bus_name != NULL) &&
|
||||
(0 != strcmp(param0, bus_name)))) {
|
||||
// Driver name does not match.
|
||||
res = 0;
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ nfc_initiator_poll_target(nfc_device *pnd,
|
|||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode)
|
||||
* @param nbr desired baud rate
|
||||
* @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param pndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param[out] pnt is a \a nfc_target struct pointer where target information will be put.
|
||||
* @param timeout in milliseconds
|
||||
*
|
||||
|
|
@ -673,7 +673,7 @@ nfc_initiator_select_dep_target(nfc_device *pnd,
|
|||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
* @param ndm desired D.E.P. mode (\a NDM_ACTIVE or \a NDM_PASSIVE for active, respectively passive mode)
|
||||
* @param nbr desired baud rate
|
||||
* @param ndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param pndiInitiator pointer \a nfc_dep_info struct that contains \e NFCID3 and \e General \e Bytes to set to the initiator device (optionnal, can be \e NULL)
|
||||
* @param[out] pnt is a \a nfc_target struct pointer where target information will be put.
|
||||
* @param timeout in milliseconds
|
||||
*
|
||||
|
|
@ -972,7 +972,7 @@ nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t s
|
|||
* @param pnd \a nfc_device struct pointer that represent currently used device
|
||||
*
|
||||
* This function switch the device in idle mode.
|
||||
* In initiator mode, the RF field is turned off and the device is set to low power mode (if avaible);
|
||||
* In initiator mode, the RF field is turned off and the device is set to low power mode (if available);
|
||||
* In target mode, the emulation is stoped (no target available from external initiator) and the device is set to low power mode (if avaible).
|
||||
*/
|
||||
int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue