2010-01-12 17:58:13 +00:00
/*-
2009-10-12 14:52:26 +00:00
* Public platform independent Near Field Communication ( NFC ) library
*
* Copyright ( C ) 2009 , Roel Verdult
2011-03-04 09:28:25 +00:00
* Copyright ( C ) 2010 , Romuald Conty
* Copyright ( C ) 2011 , Romain Tartière , Romuald Conty
2009-10-12 14:52:26 +00:00
*
* This program is free software : you can redistribute it and / or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation , either version 3 of the License , or ( at your
* option ) any later version .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* 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/>
2010-01-12 17:58:13 +00:00
*/
/**
2009-11-04 10:14:17 +00:00
* @ file arygon . c
2010-01-12 17:58:13 +00:00
* @ brief ARYGON readers driver
*
* This driver can handle ARYGON readers that use UART as bus .
* UART connection can be direct ( host < - > arygon_uc ) or could be provided by internal USB to serial interface ( e . g . host < - > ftdi_chip < - > arygon_uc )
2009-10-12 14:52:26 +00:00
*/
2011-10-17 13:03:56 +00:00
/* vim: set ts=2 sw=2 et: */
2010-01-15 10:18:11 +00:00
# ifdef HAVE_CONFIG_H
2010-09-07 17:51:03 +00:00
# include "config.h"
2010-01-15 10:18:11 +00:00
# endif // HAVE_CONFIG_H
2011-03-04 09:28:25 +00:00
# include "arygon.h"
2010-01-12 17:58:13 +00:00
2009-11-24 13:03:48 +00:00
# include <stdio.h>
2011-10-17 13:03:56 +00:00
# include <inttypes.h>
2010-04-12 14:51:50 +00:00
# include <string.h>
2011-03-04 09:28:25 +00:00
# include <sys/param.h>
# include <string.h>
2011-05-05 09:27:17 +00:00
# include <unistd.h>
2009-09-08 10:25:59 +00:00
2011-03-04 09:28:25 +00:00
# include <nfc/nfc.h>
2009-06-11 09:12:00 +00:00
2011-03-05 19:54:52 +00:00
# include "drivers.h"
# include "nfc-internal.h"
# include "chips/pn53x.h"
# include "chips/pn53x-internal.h"
2010-04-12 14:51:50 +00:00
# include "uart.h"
2009-11-10 09:47:59 +00:00
2009-08-28 16:54:04 +00:00
/** @def DEV_ARYGON_PROTOCOL_ARYGON_ASCII
* @ brief High level language in ASCII format . ( Common µ C commands and Mifare ® commands )
*/
# define DEV_ARYGON_PROTOCOL_ARYGON_ASCII '0'
/** @def DEV_ARYGON_MODE_HL_ASCII
* @ brief High level language in Binary format With AddressingByte for party line . ( Common µ C commands and Mifare ® commands )
*/
# define DEV_ARYGON_PROTOCOL_ARYGON_BINARY_WAB '1'
/** @def DEV_ARYGON_PROTOCOL_TAMA
* @ brief Philips protocol ( TAMA language ) in binary format .
*/
# define DEV_ARYGON_PROTOCOL_TAMA '2'
/** @def DEV_ARYGON_PROTOCOL_TAMA_WAB
* @ brief Philips protocol ( TAMA language ) in binary With AddressingByte for party line .
*/
# define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
2011-03-05 10:56:35 +00:00
# define ARYGON_DEFAULT_SPEED 9600
2011-10-17 13:03:56 +00:00
# define ARYGON_DRIVER_NAME "arygon"
2011-09-12 14:50:01 +00:00
# define LOG_CATEGORY "libnfc.driver.arygon"
2011-03-05 10:56:35 +00:00
2011-03-09 13:37:16 +00:00
# define DRIVER_DATA(pnd) ((struct arygon_data*)(pnd->driver_data))
2011-03-05 10:56:35 +00:00
const struct pn53x_io arygon_tama_io ;
2011-03-04 09:28:25 +00:00
struct arygon_data {
serial_port port ;
2011-05-09 11:14:43 +00:00
# ifndef WIN32
2011-05-05 09:27:17 +00:00
int iAbortFds [ 2 ] ;
2011-05-09 11:14:43 +00:00
# else
volatile bool abort_flag ;
# endif
2011-03-04 09:28:25 +00:00
} ;
2009-09-14 15:05:02 +00:00
2011-11-24 10:54:42 +00:00
static const uint8_t arygon_error_none [ ] = " FF000000 \x0d \x0a " ;
static const uint8_t arygon_error_incomplete_command [ ] = " FF0C0000 \x0d \x0a " ;
static const uint8_t arygon_error_unknown_mode [ ] = " FF060000 \x0d \x0a " ;
2010-10-11 10:54:49 +00:00
2012-01-05 13:56:12 +00:00
int arygon_reset_tama ( nfc_device * pnd ) ;
2011-11-25 15:21:10 +00:00
void arygon_firmware ( nfc_device * pnd , char * str ) ;
2010-04-12 14:51:50 +00:00
bool
2011-11-25 15:21:10 +00:00
arygon_probe ( nfc_connstring connstrings [ ] , size_t connstrings_len , size_t * pszDeviceFound )
2009-06-11 09:12:00 +00:00
{
2011-03-04 09:28:25 +00:00
/** @note: Due to UART bus we can't know if its really an ARYGON without
* sending some commands . But using this way to probe devices , we can
2010-04-12 14:51:50 +00:00
* have serious problem with other device on this bus */
# ifndef SERIAL_AUTOPROBE_ENABLED
2011-10-17 13:03:56 +00:00
( void ) connstrings ;
( void ) connstrings_len ;
2010-04-12 14:51:50 +00:00
* pszDeviceFound = 0 ;
2011-10-17 13:03:56 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_INFO , " Serial auto-probing have been disabled at compile time. Skipping autoprobe. " ) ;
2010-04-12 14:51:50 +00:00
return false ;
# else /* SERIAL_AUTOPROBE_ENABLED */
* pszDeviceFound = 0 ;
2009-06-11 09:12:00 +00:00
serial_port sp ;
2011-06-28 13:16:44 +00:00
char * * acPorts = uart_list_ports ( ) ;
const char * acPort ;
2010-09-07 17:51:03 +00:00
int iDevice = 0 ;
2010-08-17 13:29:01 +00:00
2011-06-28 13:16:44 +00:00
while ( ( acPort = acPorts [ iDevice + + ] ) ) {
sp = uart_open ( acPort ) ;
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_TRACE , " Trying to find ARYGON device on serial port: %s at %d bauds. " , acPort , ARYGON_DEFAULT_SPEED ) ;
2009-09-14 15:05:02 +00:00
2010-09-07 17:51:03 +00:00
if ( ( sp ! = INVALID_SERIAL_PORT ) & & ( sp ! = CLAIMED_SERIAL_PORT ) ) {
2011-05-25 10:31:19 +00:00
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input ( sp ) ;
2011-03-05 10:56:35 +00:00
uart_set_speed ( sp , ARYGON_DEFAULT_SPEED ) ;
2011-03-04 09:28:25 +00:00
2011-11-23 15:55:40 +00:00
nfc_device * pnd = nfc_device_new ( ) ;
2011-03-09 13:37:16 +00:00
pnd - > driver = & arygon_driver ;
pnd - > driver_data = malloc ( sizeof ( struct arygon_data ) ) ;
DRIVER_DATA ( pnd ) - > port = sp ;
2011-05-09 18:47:48 +00:00
// Alloc and init chip's data
pn53x_data_new ( pnd , & arygon_tama_io ) ;
2011-03-09 13:37:16 +00:00
2011-09-29 14:53:52 +00:00
# ifndef WIN32
// pipe-based abort mecanism
pipe ( DRIVER_DATA ( pnd ) - > iAbortFds ) ;
# else
DRIVER_DATA ( pnd ) - > abort_flag = false ;
# endif
2012-01-05 13:56:12 +00:00
int res = arygon_reset_tama ( pnd ) ;
2011-06-28 13:16:44 +00:00
pn53x_data_free ( pnd ) ;
2011-03-09 13:37:16 +00:00
nfc_device_free ( pnd ) ;
2010-09-07 17:51:03 +00:00
uart_close ( sp ) ;
2012-01-05 13:56:12 +00:00
if ( res < 0 ) {
2011-03-04 09:28:25 +00:00
continue ;
2011-10-17 13:03:56 +00:00
}
2010-04-22 10:22:41 +00:00
// ARYGON reader is found
2011-10-17 13:03:56 +00:00
snprintf ( connstrings [ * pszDeviceFound ] , sizeof ( nfc_connstring ) , " %s:%s:% " PRIu32 , ARYGON_DRIVER_NAME , acPort , ARYGON_DEFAULT_SPEED ) ;
2010-04-12 14:51:50 +00:00
( * pszDeviceFound ) + + ;
// Test if we reach the maximum "wanted" devices
2011-10-17 13:03:56 +00:00
if ( ( * pszDeviceFound ) > = connstrings_len )
2010-09-07 17:51:03 +00:00
break ;
2010-04-12 14:51:50 +00:00
}
}
2011-06-28 13:16:44 +00:00
iDevice = 0 ;
while ( ( acPort = acPorts [ iDevice + + ] ) ) {
free ( ( void * ) acPort ) ;
}
free ( acPorts ) ;
2010-01-18 11:23:07 +00:00
# endif /* SERIAL_AUTOPROBE_ENABLED */
2010-04-12 14:51:50 +00:00
return true ;
}
2011-10-17 13:03:56 +00:00
struct arygon_descriptor {
char port [ 128 ] ;
uint32_t speed ;
} ;
int
arygon_connstring_decode ( const nfc_connstring connstring , struct arygon_descriptor * desc )
{
char * cs = malloc ( strlen ( connstring ) + 1 ) ;
if ( ! cs ) {
perror ( " malloc " ) ;
return - 1 ;
}
strcpy ( cs , connstring ) ;
const char * driver_name = strtok ( cs , " : " ) ;
if ( ! driver_name ) {
// Parse error
free ( cs ) ;
return - 1 ;
}
if ( 0 ! = strcmp ( driver_name , ARYGON_DRIVER_NAME ) ) {
// Driver name does not match.
free ( cs ) ;
return 0 ;
}
const char * port = strtok ( NULL , " : " ) ;
if ( ! port ) {
// Only driver name was specified (or parsing error)
free ( cs ) ;
return 1 ;
}
strncpy ( desc - > port , port , sizeof ( desc - > port ) - 1 ) ;
desc - > port [ sizeof ( desc - > port ) - 1 ] = ' \0 ' ;
2011-11-25 15:21:10 +00:00
const char * speed_s = strtok ( NULL , " : " ) ;
2011-10-17 13:03:56 +00:00
if ( ! speed_s ) {
// speed not specified (or parsing error)
free ( cs ) ;
return 2 ;
}
unsigned long speed ;
if ( sscanf ( speed_s , " %lu " , & speed ) ! = 1 ) {
// speed_s is not a number
free ( cs ) ;
return 2 ;
}
desc - > speed = speed ;
free ( cs ) ;
return 3 ;
}
2011-11-23 15:55:40 +00:00
nfc_device *
2011-10-17 13:03:56 +00:00
arygon_connect ( const nfc_connstring connstring )
2010-04-12 14:51:50 +00:00
{
2011-10-17 13:03:56 +00:00
struct arygon_descriptor ndd ;
int connstring_decode_level = arygon_connstring_decode ( connstring , & ndd ) ;
if ( connstring_decode_level < 2 ) {
return NULL ;
}
if ( connstring_decode_level < 3 ) {
ndd . speed = ARYGON_DEFAULT_SPEED ;
}
2010-04-12 14:51:50 +00:00
serial_port sp ;
2011-11-23 15:55:40 +00:00
nfc_device * pnd = NULL ;
2010-01-18 11:23:07 +00:00
2011-10-17 13:03:56 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_TRACE , " Attempt to connect to: %s at %d bauds. " , ndd . port , ndd . speed ) ;
sp = uart_open ( ndd . port ) ;
2010-04-12 14:51:50 +00:00
2010-09-07 17:51:03 +00:00
if ( sp = = INVALID_SERIAL_PORT )
2011-10-17 13:03:56 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " Invalid serial port: %s " , ndd . port ) ;
2010-09-07 17:51:03 +00:00
if ( sp = = CLAIMED_SERIAL_PORT )
2011-10-17 13:03:56 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " Serial port already claimed: %s " , ndd . port ) ;
2010-09-07 17:51:03 +00:00
if ( ( sp = = CLAIMED_SERIAL_PORT ) | | ( sp = = INVALID_SERIAL_PORT ) )
return NULL ;
2009-09-14 15:05:02 +00:00
2011-05-25 10:31:19 +00:00
// We need to flush input to be sure first reply does not comes from older byte transceive
uart_flush_input ( sp ) ;
2011-10-17 13:03:56 +00:00
uart_set_speed ( sp , ndd . speed ) ;
2009-08-28 16:54:04 +00:00
2009-06-11 09:12:00 +00:00
// We have a connection
2011-03-09 13:37:16 +00:00
pnd = nfc_device_new ( ) ;
2011-10-17 13:03:56 +00:00
snprintf ( pnd - > acName , sizeof ( pnd - > acName ) , " %s:%s " , ARYGON_DRIVER_NAME , ndd . port ) ;
2010-10-06 15:12:33 +00:00
2011-03-04 09:28:25 +00:00
pnd - > driver_data = malloc ( sizeof ( struct arygon_data ) ) ;
2011-03-09 13:37:16 +00:00
DRIVER_DATA ( pnd ) - > port = sp ;
2011-10-17 13:03:56 +00:00
2011-05-25 10:25:17 +00:00
// Alloc and init chip's data
pn53x_data_new ( pnd , & arygon_tama_io ) ;
2011-03-04 11:26:15 +00:00
2011-05-25 10:25:17 +00:00
// The PN53x chip connected to ARYGON MCU doesn't seems to be in LowVBat mode
2011-04-27 13:16:36 +00:00
CHIP_DATA ( pnd ) - > power_mode = NORMAL ;
2011-05-25 10:25:17 +00:00
2011-04-04 19:04:43 +00:00
// empirical tuning
CHIP_DATA ( pnd ) - > timer_correction = 46 ;
2011-03-04 09:28:25 +00:00
pnd - > driver = & arygon_driver ;
2011-05-09 11:14:43 +00:00
# ifndef WIN32
2011-05-05 09:27:17 +00:00
// pipe-based abort mecanism
pipe ( DRIVER_DATA ( pnd ) - > iAbortFds ) ;
2011-05-09 11:14:43 +00:00
# else
DRIVER_DATA ( pnd ) - > abort_flag = false ;
# endif
2011-05-05 09:27:17 +00:00
2011-09-29 14:53:52 +00:00
// Check communication using "Reset TAMA" command
2012-01-05 13:56:12 +00:00
if ( arygon_reset_tama ( pnd ) < 0 ) {
2011-10-17 13:03:56 +00:00
arygon_disconnect ( pnd ) ;
2011-09-29 14:53:52 +00:00
return NULL ;
}
2011-04-20 14:06:12 +00:00
char arygon_firmware_version [ 10 ] ;
arygon_firmware ( pnd , arygon_firmware_version ) ;
char * pcName ;
pcName = strdup ( pnd - > acName ) ;
snprintf ( pnd - > acName , sizeof ( pnd - > acName ) , " %s %s " , pcName , arygon_firmware_version ) ;
free ( pcName ) ;
2011-03-04 09:28:25 +00:00
pn53x_init ( pnd ) ;
2009-11-09 11:23:33 +00:00
return pnd ;
2009-08-28 16:54:04 +00:00
}
2009-06-11 09:12:00 +00:00
2010-09-07 17:51:03 +00:00
void
2011-11-25 15:21:10 +00:00
arygon_disconnect ( nfc_device * pnd )
2009-06-11 09:12:00 +00:00
{
2011-05-05 09:27:17 +00:00
// Release UART port
2011-03-09 13:37:16 +00:00
uart_close ( DRIVER_DATA ( pnd ) - > port ) ;
2011-05-05 09:27:17 +00:00
2011-05-09 11:14:43 +00:00
# ifndef WIN32
2011-05-05 09:27:17 +00:00
// Release file descriptors used for abort mecanism
close ( DRIVER_DATA ( pnd ) - > iAbortFds [ 0 ] ) ;
close ( DRIVER_DATA ( pnd ) - > iAbortFds [ 1 ] ) ;
2011-05-09 11:14:43 +00:00
# endif
2011-05-05 09:27:17 +00:00
2011-06-28 13:16:44 +00:00
pn53x_data_free ( pnd ) ;
2011-03-09 13:37:16 +00:00
nfc_device_free ( pnd ) ;
2009-08-28 16:54:04 +00:00
}
2009-06-11 09:12:00 +00:00
2011-04-14 15:50:04 +00:00
# define ARYGON_TX_BUFFER_LEN (PN53x_NORMAL_FRAME__DATA_MAX_LEN + PN53x_NORMAL_FRAME__OVERHEAD + 1)
2011-03-04 09:28:25 +00:00
# define ARYGON_RX_BUFFER_LEN (PN53x_EXTENDED_FRAME__DATA_MAX_LEN + PN53x_EXTENDED_FRAME__OVERHEAD)
2012-01-05 13:24:41 +00:00
int
2011-11-25 15:21:10 +00:00
arygon_tama_send ( nfc_device * pnd , const uint8_t * pbtData , const size_t szData , int timeout )
2009-06-11 09:12:00 +00:00
{
2011-05-25 10:31:19 +00:00
// Before sending anything, we need to discard from any junk bytes
uart_flush_input ( DRIVER_DATA ( pnd ) - > port ) ;
2011-11-24 10:54:42 +00:00
uint8_t abtFrame [ ARYGON_TX_BUFFER_LEN ] = { DEV_ARYGON_PROTOCOL_TAMA , 0x00 , 0x00 , 0xff } ; // Every packet must start with "0x32 0x00 0x00 0xff"
2009-08-28 16:54:04 +00:00
2011-03-04 09:28:25 +00:00
size_t szFrame = 0 ;
2011-04-14 15:50:04 +00:00
if ( szData > PN53x_NORMAL_FRAME__DATA_MAX_LEN ) {
// ARYGON Reader with PN532 equipped does not support extended frame (bug in ARYGON firmware?)
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_TRACE , " ARYGON device does not support more than %d bytes as payload (requested: %zd) " , PN53x_NORMAL_FRAME__DATA_MAX_LEN , szData ) ;
2011-12-15 16:02:38 +00:00
pnd - > last_error = NFC_EDEVNOTSUPP ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-04-14 15:50:04 +00:00
}
2012-01-04 16:44:40 +00:00
if ( pn53x_build_frame ( abtFrame + 1 , & szFrame , pbtData , szData ) < 0 ) {
2011-12-15 16:02:38 +00:00
pnd - > last_error = NFC_EINVARG ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-04-14 15:50:04 +00:00
}
2009-08-28 16:54:04 +00:00
2011-09-22 13:03:47 +00:00
int res = uart_send ( DRIVER_DATA ( pnd ) - > port , abtFrame , szFrame + 1 , timeout ) ;
2010-08-31 12:55:45 +00:00
if ( res ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Unable to transmit data. (TX) " ) ;
2011-12-15 16:02:38 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2009-08-28 16:54:04 +00:00
}
2011-03-04 09:28:25 +00:00
2011-11-24 10:54:42 +00:00
uint8_t abtRxBuf [ 6 ] ;
2011-09-22 13:03:47 +00:00
res = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRxBuf , sizeof ( abtRxBuf ) , 0 , timeout ) ;
2010-08-31 12:55:45 +00:00
if ( res ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Unable to read ACK " ) ;
2011-12-15 16:02:38 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2009-08-28 16:54:04 +00:00
}
2012-01-04 16:32:16 +00:00
if ( pn53x_check_ack_frame ( pnd , abtRxBuf , sizeof ( abtRxBuf ) ) = = 0 ) {
2011-04-27 13:16:36 +00:00
// The PN53x is running the sent command
2011-03-04 09:28:25 +00:00
} else if ( 0 = = memcmp ( arygon_error_unknown_mode , abtRxBuf , sizeof ( abtRxBuf ) ) ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " Bad frame format. " ) ;
2011-04-20 14:06:12 +00:00
// We have already read 6 bytes and arygon_error_unknown_mode is 10 bytes long
// so we have to read 4 remaining bytes to be synchronized at the next receiving pass.
2012-01-05 13:24:41 +00:00
pnd - > last_error = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRxBuf , 4 , 0 , timeout ) ;
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
} else {
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2012-01-05 13:24:41 +00:00
return NFC_SUCCESS ;
2011-03-04 09:28:25 +00:00
}
2010-04-13 14:11:10 +00:00
2011-03-04 19:59:49 +00:00
int
2011-11-23 15:55:40 +00:00
arygon_abort ( nfc_device * pnd )
2011-03-04 19:59:49 +00:00
{
2011-03-05 21:28:18 +00:00
// Send a valid TAMA packet to wakup the PN53x (we will not have an answer, according to Arygon manual)
2011-11-24 10:54:42 +00:00
uint8_t dummy [ ] = { 0x32 , 0x00 , 0x00 , 0xff , 0x09 , 0xf7 , 0xd4 , 0x00 , 0x00 , 0x6c , 0x69 , 0x62 , 0x6e , 0x66 , 0x63 , 0xbe , 0x00 } ;
2011-03-05 21:28:18 +00:00
2011-11-25 11:37:30 +00:00
uart_send ( DRIVER_DATA ( pnd ) - > port , dummy , sizeof ( dummy ) , 0 ) ;
2011-03-05 21:28:18 +00:00
2011-03-04 19:59:49 +00:00
// Using Arygon device we can't send ACK frame to abort the running command
2012-01-04 20:02:51 +00:00
return pn53x_check_communication ( pnd ) ;
2011-03-04 19:59:49 +00:00
}
2011-03-04 09:28:25 +00:00
int
2011-11-25 15:21:10 +00:00
arygon_tama_receive ( nfc_device * pnd , uint8_t * pbtData , const size_t szDataLen , int timeout )
2011-03-04 09:28:25 +00:00
{
2011-11-24 10:54:42 +00:00
uint8_t abtRxBuf [ 5 ] ;
2011-03-04 09:28:25 +00:00
size_t len ;
2011-11-25 15:21:10 +00:00
void * abort_p = NULL ;
2011-03-04 19:59:49 +00:00
2011-05-09 11:14:43 +00:00
# ifndef WIN32
2011-09-29 14:53:52 +00:00
abort_p = & ( DRIVER_DATA ( pnd ) - > iAbortFds [ 1 ] ) ;
2011-05-09 11:14:43 +00:00
# else
2011-10-17 13:03:56 +00:00
abort_p = ( void * ) & ( DRIVER_DATA ( pnd ) - > abort_flag ) ;
2011-05-09 11:14:43 +00:00
# endif
2011-03-04 19:59:49 +00:00
2011-12-15 16:02:38 +00:00
pnd - > last_error = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRxBuf , 5 , abort_p , timeout ) ;
2011-03-04 19:59:49 +00:00
2011-12-19 00:23:21 +00:00
if ( abort_p & & ( NFC_EOPABORTED = = pnd - > last_error ) ) {
2011-03-09 14:10:40 +00:00
arygon_abort ( pnd ) ;
2011-12-15 16:02:38 +00:00
/* last_error got reset by arygon_abort() */
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EOPABORTED ;
return pnd - > last_error ;
2011-03-04 19:59:49 +00:00
}
2010-09-07 17:51:03 +00:00
2011-12-15 16:02:38 +00:00
if ( pnd - > last_error ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Unable to receive data. (RX) " ) ;
2011-12-19 00:23:21 +00:00
return pnd - > last_error ;
2010-08-31 12:55:45 +00:00
}
2009-08-28 16:54:04 +00:00
2011-11-24 10:54:42 +00:00
const uint8_t pn53x_preamble [ 3 ] = { 0x00 , 0x00 , 0xff } ;
2011-03-04 09:28:25 +00:00
if ( 0 ! = ( memcmp ( abtRxBuf , pn53x_preamble , 3 ) ) ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Frame preamble+start code mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2010-08-20 10:40:00 +00:00
2011-03-04 09:28:25 +00:00
if ( ( 0x01 = = abtRxBuf [ 3 ] ) & & ( 0xff = = abtRxBuf [ 4 ] ) ) {
// Error frame
2011-09-22 13:03:47 +00:00
uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRxBuf , 3 , 0 , timeout ) ;
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Application level error detected " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
} else if ( ( 0xff = = abtRxBuf [ 3 ] ) & & ( 0xff = = abtRxBuf [ 4 ] ) ) {
// Extended frame
2011-05-06 15:03:08 +00:00
// ARYGON devices does not support extended frame sending
2011-03-04 09:28:25 +00:00
abort ( ) ;
} else {
// Normal frame
if ( 256 ! = ( abtRxBuf [ 3 ] + abtRxBuf [ 4 ] ) ) {
// TODO: Retry
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Length checksum mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2010-08-20 10:40:00 +00:00
2011-03-04 09:28:25 +00:00
// abtRxBuf[3] (LEN) include TFI + (CC+1)
len = abtRxBuf [ 3 ] - 2 ;
}
2010-08-20 10:40:00 +00:00
2011-03-04 09:28:25 +00:00
if ( len > szDataLen ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu) " , szDataLen , len ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2009-08-28 16:54:04 +00:00
2011-03-04 09:28:25 +00:00
// TFI + PD0 (CC+1)
2011-12-15 16:02:38 +00:00
pnd - > last_error = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRxBuf , 2 , 0 , timeout ) ;
if ( pnd - > last_error ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Unable to receive data. (RX) " ) ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
if ( abtRxBuf [ 0 ] ! = 0xD5 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " TFI Mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2012-01-06 09:20:55 +00:00
if ( abtRxBuf [ 1 ] ! = CHIP_DATA ( pnd ) - > lastCommand + 1 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Command Code verification failed " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
if ( len ) {
2011-12-15 16:02:38 +00:00
pnd - > last_error = uart_receive ( DRIVER_DATA ( pnd ) - > port , pbtData , len , 0 , timeout ) ;
if ( pnd - > last_error ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Unable to receive data. (RX) " ) ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
}
2011-12-15 16:02:38 +00:00
pnd - > last_error = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRxBuf , 2 , 0 , timeout ) ;
if ( pnd - > last_error ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Unable to receive data. (RX) " ) ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2011-11-24 10:54:42 +00:00
uint8_t btDCS = ( 256 - 0xD5 ) ;
2012-01-06 09:20:55 +00:00
btDCS - = CHIP_DATA ( pnd ) - > lastCommand + 1 ;
2011-03-04 09:28:25 +00:00
for ( size_t szPos = 0 ; szPos < len ; szPos + + ) {
btDCS - = pbtData [ szPos ] ;
}
if ( btDCS ! = abtRxBuf [ 0 ] ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Data checksum mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
if ( 0x00 ! = abtRxBuf [ 1 ] ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_ERROR , " %s " , " Frame postamble mismatch " ) ;
2011-12-19 00:23:21 +00:00
pnd - > last_error = NFC_EIO ;
2012-01-05 13:24:41 +00:00
return pnd - > last_error ;
2011-03-04 09:28:25 +00:00
}
2011-04-27 13:16:36 +00:00
// The PN53x command is done and we successfully received the reply
2011-03-04 09:28:25 +00:00
return len ;
2009-06-11 09:12:00 +00:00
}
2010-04-15 14:41:13 +00:00
2010-10-22 15:21:06 +00:00
void
2011-11-25 15:21:10 +00:00
arygon_firmware ( nfc_device * pnd , char * str )
2010-10-22 15:21:06 +00:00
{
2011-11-24 10:54:42 +00:00
const uint8_t arygon_firmware_version_cmd [ ] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII , ' a ' , ' v ' } ;
uint8_t abtRx [ 16 ] ;
2011-03-04 09:28:25 +00:00
size_t szRx = sizeof ( abtRx ) ;
2010-10-22 15:21:06 +00:00
2011-11-25 11:37:30 +00:00
int res = uart_send ( DRIVER_DATA ( pnd ) - > port , arygon_firmware_version_cmd , sizeof ( arygon_firmware_version_cmd ) , 0 ) ;
2011-03-04 09:28:25 +00:00
if ( res ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_TRACE , " Unable to send ARYGON firmware command. " ) ;
2011-03-04 09:28:25 +00:00
return ;
}
2011-11-25 11:37:30 +00:00
res = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRx , szRx , 0 , 0 ) ;
2010-10-22 15:21:06 +00:00
if ( res ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_TRACE , " Unable to retrieve ARYGON firmware version. " ) ;
2010-10-22 15:21:06 +00:00
return ;
}
2011-03-04 09:28:25 +00:00
2010-10-22 15:21:06 +00:00
if ( 0 = = memcmp ( abtRx , arygon_error_none , 6 ) ) {
2011-11-25 15:21:10 +00:00
uint8_t * p = abtRx + 6 ;
2010-10-22 15:21:06 +00:00
unsigned int szData ;
2010-11-17 08:29:41 +00:00
sscanf ( ( const char * ) p , " %02x%s " , & szData , p ) ;
2010-10-22 15:21:06 +00:00
memcpy ( str , p , szData ) ;
2010-11-17 08:29:41 +00:00
* ( str + szData ) = ' \0 ' ;
2010-10-22 15:21:06 +00:00
}
}
2012-01-05 13:56:12 +00:00
int
2011-11-25 15:21:10 +00:00
arygon_reset_tama ( nfc_device * pnd )
2010-10-22 14:29:44 +00:00
{
2011-11-24 10:54:42 +00:00
const uint8_t arygon_reset_tama_cmd [ ] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII , ' a ' , ' r ' } ;
uint8_t abtRx [ 10 ] ; // Attempted response is 10 bytes long
2011-03-04 09:28:25 +00:00
size_t szRx = sizeof ( abtRx ) ;
2010-10-22 14:29:44 +00:00
int res ;
2012-01-04 20:02:51 +00:00
uart_send ( DRIVER_DATA ( pnd ) - > port , arygon_reset_tama_cmd , sizeof ( arygon_reset_tama_cmd ) , 500 ) ;
2010-10-22 14:29:44 +00:00
// Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
// or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
2011-11-25 11:37:30 +00:00
res = uart_receive ( DRIVER_DATA ( pnd ) - > port , abtRx , szRx , 0 , 1000 ) ;
2010-10-22 14:29:44 +00:00
if ( res ! = 0 ) {
2011-09-12 14:50:01 +00:00
log_put ( LOG_CATEGORY , NFC_PRIORITY_TRACE , " No reply to 'reset TAMA' command. " ) ;
2012-01-05 13:56:12 +00:00
pnd - > last_error = NFC_EIO ;
return pnd - > last_error ;
2010-10-22 14:29:44 +00:00
}
2011-03-08 10:55:44 +00:00
2010-10-22 14:29:44 +00:00
if ( 0 ! = memcmp ( abtRx , arygon_error_none , sizeof ( arygon_error_none ) - 1 ) ) {
2012-01-05 13:56:12 +00:00
pnd - > last_error = NFC_EIO ;
return pnd - > last_error ;
2010-10-22 14:29:44 +00:00
}
2012-01-05 13:56:12 +00:00
return NFC_SUCCESS ;
2010-10-22 14:29:44 +00:00
}
2012-01-05 14:49:02 +00:00
int
2011-11-25 15:21:10 +00:00
arygon_abort_command ( nfc_device * pnd )
2011-05-05 09:27:17 +00:00
{
if ( pnd ) {
2011-05-09 11:14:43 +00:00
# ifndef WIN32
2011-05-05 09:27:17 +00:00
close ( DRIVER_DATA ( pnd ) - > iAbortFds [ 0 ] ) ;
pipe ( DRIVER_DATA ( pnd ) - > iAbortFds ) ;
2011-05-09 11:14:43 +00:00
# else
DRIVER_DATA ( pnd ) - > abort_flag = true ;
# endif
2011-05-05 09:27:17 +00:00
}
2012-01-05 14:49:02 +00:00
return NFC_SUCCESS ;
2011-05-05 09:27:17 +00:00
}
2011-03-05 10:06:52 +00:00
const struct pn53x_io arygon_tama_io = {
. send = arygon_tama_send ,
. receive = arygon_tama_receive ,
} ;
2010-09-07 17:51:03 +00:00
2011-03-04 09:28:25 +00:00
const struct nfc_driver_t arygon_driver = {
2011-10-17 13:03:56 +00:00
. name = ARYGON_DRIVER_NAME ,
. probe = arygon_probe ,
. connect = arygon_connect ,
. disconnect = arygon_disconnect ,
. strerror = pn53x_strerror ,
2011-03-05 10:06:52 +00:00
2011-03-05 10:56:35 +00:00
. initiator_init = pn53x_initiator_init ,
. initiator_select_passive_target = pn53x_initiator_select_passive_target ,
2011-10-03 11:19:08 +00:00
. initiator_poll_target = pn53x_initiator_poll_target ,
2011-03-05 10:56:35 +00:00
. initiator_select_dep_target = pn53x_initiator_select_dep_target ,
. initiator_deselect_target = pn53x_initiator_deselect_target ,
. initiator_transceive_bytes = pn53x_initiator_transceive_bytes ,
. initiator_transceive_bits = pn53x_initiator_transceive_bits ,
2011-04-04 14:16:36 +00:00
. initiator_transceive_bytes_timed = pn53x_initiator_transceive_bytes_timed ,
. initiator_transceive_bits_timed = pn53x_initiator_transceive_bits_timed ,
2011-03-05 10:56:35 +00:00
. target_init = pn53x_target_init ,
. target_send_bytes = pn53x_target_send_bytes ,
. target_receive_bytes = pn53x_target_receive_bytes ,
. target_send_bits = pn53x_target_send_bits ,
. target_receive_bits = pn53x_target_receive_bits ,
2011-12-14 16:01:00 +00:00
. device_set_property_bool = pn53x_set_property_bool ,
2011-12-14 13:27:11 +00:00
. device_set_property_int = pn53x_set_property_int ,
2011-05-05 09:27:17 +00:00
. abort_command = arygon_abort_command ,
2011-10-17 13:03:56 +00:00
. idle = NULL , // FIXME arygon driver does not support idle()
2011-03-04 09:28:25 +00:00
} ;
2010-04-22 10:22:41 +00:00