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
|
|
@ -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…
Add table
Add a link
Reference in a new issue