drivers/pn532_uart,arygon: Make valgrind happy with UART-based drivers

This commit is contained in:
Romuald Conty 2011-06-28 13:16:44 +00:00
parent e6051ceca4
commit eec2794d2d
5 changed files with 82 additions and 61 deletions

View file

@ -696,8 +696,7 @@ parse_args (int argc, const char *argv[], size_t * szFound, bool * verbose)
strcpy (pndd->pcDriver, strtok (buffer, ":")); strcpy (pndd->pcDriver, strtok (buffer, ":"));
// Port. // Port.
pndd->pcPort = (char *) malloc (256); strcpy (pndd->acPort, strtok (NULL, ":"));
strcpy (pndd->pcPort, strtok (NULL, ":"));
// Speed. // Speed.
sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed); sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed);

View file

@ -35,6 +35,8 @@
typedef uint8_t byte_t; typedef uint8_t byte_t;
# define DEVICE_NAME_LENGTH 256 # define DEVICE_NAME_LENGTH 256
# define DEVICE_PORT_LENGTH 64
/** /**
* @struct nfc_device_t * @struct nfc_device_t
* @brief NFC device information * @brief NFC device information
@ -81,7 +83,7 @@ typedef struct {
/** Driver name (e.g. "PN532_UART")*/ /** Driver name (e.g. "PN532_UART")*/
char *pcDriver; char *pcDriver;
/** Port (e.g. "/dev/ttyUSB0") */ /** Port (e.g. "/dev/ttyUSB0") */
char *pcPort; char acPort[DEVICE_PORT_LENGTH];
/** Port speed (e.g. "115200") */ /** Port speed (e.g. "115200") */
uint32_t uiSpeed; uint32_t uiSpeed;
/** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */ /** Device index for backward compatibility (used to choose one specific device in USB or PSCS devices list) */

View file

@ -56,16 +56,17 @@ char *serial_ports_device_radix[] = { "ttyUSB", "ttyS", NULL };
# error "Can't determine serial string for your system" # error "Can't determine serial string for your system"
# endif # endif
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
} serial_port_unix;
// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct // Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
# define CCLAIMED 0x80000000 # define CCLAIMED 0x80000000
typedef struct {
int fd; // Serial port file descriptor
struct termios termios_backup; // Terminal info before using the port
struct termios termios_new; // Terminal info during the transaction
} serial_port_unix;
void uart_close_ext (const serial_port sp, const bool restore_termios);
serial_port serial_port
uart_open (const char *pcPortName) uart_open (const char *pcPortName)
{ {
@ -76,32 +77,32 @@ uart_open (const char *pcPortName)
sp->fd = open (pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK); sp->fd = open (pcPortName, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (sp->fd == -1) { if (sp->fd == -1) {
uart_close (sp); uart_close_ext (sp, false);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
if (tcgetattr (sp->fd, &sp->tiOld) == -1) { if (tcgetattr (sp->fd, &sp->termios_backup) == -1) {
uart_close (sp); uart_close_ext (sp, false);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
// Make sure the port is not claimed already // Make sure the port is not claimed already
if (sp->tiOld.c_iflag & CCLAIMED) { if (sp->termios_backup.c_iflag & CCLAIMED) {
uart_close (sp); uart_close_ext (sp, false);
return CLAIMED_SERIAL_PORT; return CLAIMED_SERIAL_PORT;
} }
// Copy the old terminal info struct // Copy the old terminal info struct
sp->tiNew = sp->tiOld; sp->termios_new = sp->termios_backup;
sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; sp->termios_new.c_cflag = CS8 | CLOCAL | CREAD;
sp->tiNew.c_iflag = CCLAIMED | IGNPAR; sp->termios_new.c_iflag = CCLAIMED | IGNPAR;
sp->tiNew.c_oflag = 0; sp->termios_new.c_oflag = 0;
sp->tiNew.c_lflag = 0; sp->termios_new.c_lflag = 0;
sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received sp->termios_new.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->termios_new.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
if (tcsetattr (sp->fd, TCSANOW, &sp->tiNew) == -1) { if (tcsetattr (sp->fd, TCSANOW, &sp->termios_new) == -1) {
uart_close (sp); uart_close_ext (sp, true);
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;
} }
return sp; return sp;
@ -134,7 +135,7 @@ void
uart_set_speed (serial_port sp, const uint32_t uiPortSpeed) uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
{ {
DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed); DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
const serial_port_unix *spu = (serial_port_unix *) sp; serial_port_unix *spu = (serial_port_unix *) sp;
// Portability note: on some systems, B9600 != 9600 so we have to do // Portability note: on some systems, B9600 != 9600 so we have to do
// uint32_t <=> speed_t associations by hand. // uint32_t <=> speed_t associations by hand.
@ -176,9 +177,9 @@ uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
}; };
// Set port speed (Input and Output) // Set port speed (Input and Output)
cfsetispeed ((struct termios *) &(spu->tiNew), stPortSpeed); cfsetispeed (&(spu->termios_new), stPortSpeed);
cfsetospeed ((struct termios *) &(spu->tiNew), stPortSpeed); cfsetospeed (&(spu->termios_new), stPortSpeed);
if (tcsetattr (spu->fd, TCSADRAIN, &(spu->tiNew)) == -1) { if (tcsetattr (spu->fd, TCSADRAIN, &(spu->termios_new)) == -1) {
ERR ("%s", "Unable to apply new speed settings."); ERR ("%s", "Unable to apply new speed settings.");
} }
} }
@ -188,7 +189,7 @@ uart_get_speed (serial_port sp)
{ {
uint32_t uiPortSpeed = 0; uint32_t uiPortSpeed = 0;
const serial_port_unix *spu = (serial_port_unix *) sp; const serial_port_unix *spu = (serial_port_unix *) sp;
switch (cfgetispeed (&spu->tiNew)) { switch (cfgetispeed (&spu->termios_new)) {
case B9600: case B9600:
uiPortSpeed = 9600; uiPortSpeed = 9600;
break; break;
@ -224,15 +225,22 @@ uart_get_speed (serial_port sp)
} }
void void
uart_close (const serial_port sp) uart_close_ext (const serial_port sp, const bool restore_termios)
{ {
if (((serial_port_unix *) sp)->fd >= 0) { if (((serial_port_unix *) sp)->fd >= 0) {
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->tiOld); if (restore_termios)
tcsetattr (((serial_port_unix *) sp)->fd, TCSANOW, &((serial_port_unix *) sp)->termios_backup);
close (((serial_port_unix *) sp)->fd); close (((serial_port_unix *) sp)->fd);
} }
free (sp); free (sp);
} }
void
uart_close (const serial_port sp)
{
uart_close_ext (sp, true);
}
static const struct timeval tvTimeout = { static const struct timeval tvTimeout = {
.tv_sec = 1, .tv_sec = 1,
.tv_usec = 0 .tv_usec = 0

View file

@ -102,13 +102,13 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
*pszDeviceFound = 0; *pszDeviceFound = 0;
serial_port sp; serial_port sp;
char **pcPorts = uart_list_ports (); char **acPorts = uart_list_ports ();
const char *pcPort; const char *acPort;
int iDevice = 0; int iDevice = 0;
while ((pcPort = pcPorts[iDevice++])) { while ((acPort = acPorts[iDevice++])) {
sp = uart_open (pcPort); sp = uart_open (acPort);
DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, ARYGON_DEFAULT_SPEED); DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", acPort, ARYGON_DEFAULT_SPEED);
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) { if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
// We need to flush input to be sure first reply does not comes from older byte transceive // We need to flush input to be sure first reply does not comes from older byte transceive
@ -124,15 +124,16 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
pn53x_data_new (pnd, &arygon_tama_io); pn53x_data_new (pnd, &arygon_tama_io);
bool res = arygon_reset_tama (pnd); bool res = arygon_reset_tama (pnd);
pn53x_data_free (pnd);
nfc_device_free (pnd); nfc_device_free (pnd);
uart_close (sp); uart_close (sp);
if(!res) if(!res)
continue; continue;
// ARYGON reader is found // 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", acPort);
pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME; pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort); strncpy (pnddDevices[*pszDeviceFound].acPort, acPort, DEVICE_PORT_LENGTH - 1); pnddDevices[*pszDeviceFound].acPort[DEVICE_PORT_LENGTH - 1] = '\0';
pnddDevices[*pszDeviceFound].uiSpeed = ARYGON_DEFAULT_SPEED; pnddDevices[*pszDeviceFound].uiSpeed = ARYGON_DEFAULT_SPEED;
(*pszDeviceFound)++; (*pszDeviceFound)++;
@ -142,13 +143,17 @@ arygon_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDev
} }
# ifdef DEBUG # ifdef DEBUG
if (sp == INVALID_SERIAL_PORT) if (sp == INVALID_SERIAL_PORT)
DBG ("Invalid serial port: %s", pcPort); DBG ("Invalid serial port: %s", acPort);
if (sp == CLAIMED_SERIAL_PORT) if (sp == CLAIMED_SERIAL_PORT)
DBG ("Serial port already claimed: %s", pcPort); DBG ("Serial port already claimed: %s", acPort);
# endif # endif
/* DEBUG */ /* DEBUG */
} }
free (pcPorts); iDevice = 0;
while ((acPort = acPorts[iDevice++])) {
free ((void*)acPort);
}
free (acPorts);
#endif /* SERIAL_AUTOPROBE_ENABLED */ #endif /* SERIAL_AUTOPROBE_ENABLED */
return true; return true;
} }
@ -159,13 +164,13 @@ arygon_connect (const nfc_device_desc_t * pndd)
serial_port sp; 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); DBG ("Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed);
sp = uart_open (pndd->pcPort); sp = uart_open (pndd->acPort);
if (sp == INVALID_SERIAL_PORT) if (sp == INVALID_SERIAL_PORT)
ERR ("Invalid serial port: %s", pndd->pcPort); ERR ("Invalid serial port: %s", pndd->acPort);
if (sp == CLAIMED_SERIAL_PORT) if (sp == CLAIMED_SERIAL_PORT)
ERR ("Serial port already claimed: %s", pndd->pcPort); ERR ("Serial port already claimed: %s", pndd->acPort);
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
return NULL; return NULL;
@ -226,7 +231,7 @@ arygon_disconnect (nfc_device_t * pnd)
close (DRIVER_DATA (pnd)->iAbortFds[1]); close (DRIVER_DATA (pnd)->iAbortFds[1]);
#endif #endif
pn53x_data_free(pnd); pn53x_data_free (pnd);
nfc_device_free (pnd); nfc_device_free (pnd);
} }

View file

@ -78,13 +78,13 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
*pszDeviceFound = 0; *pszDeviceFound = 0;
serial_port sp; serial_port sp;
char **pcPorts = uart_list_ports (); char **acPorts = uart_list_ports ();
const char *pcPort; const char *acPort;
int iDevice = 0; int iDevice = 0;
while ((pcPort = pcPorts[iDevice++])) { while ((acPort = acPorts[iDevice++])) {
sp = uart_open (pcPort); sp = uart_open (acPort);
DBG ("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, PN532_UART_DEFAULT_SPEED); DBG ("Trying to find PN532 device on serial port: %s at %d bauds.", acPort, PN532_UART_DEFAULT_SPEED);
if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) { if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
// We need to flush input to be sure first reply does not comes from older byte transceive // We need to flush input to be sure first reply does not comes from older byte transceive
@ -109,15 +109,16 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
if(!res) { if(!res) {
nfc_perror (pnd, "pn53x_check_communication"); nfc_perror (pnd, "pn53x_check_communication");
} }
pn53x_data_free (pnd);
nfc_device_free (pnd); nfc_device_free (pnd);
uart_close (sp); uart_close (sp);
if(!res) { if(!res) {
continue; continue;
} }
snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", pcPort); snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", acPort);
pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME; pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME;
pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort); strncpy (pnddDevices[*pszDeviceFound].acPort, acPort, DEVICE_PORT_LENGTH - 1); pnddDevices[*pszDeviceFound].acPort[DEVICE_PORT_LENGTH - 1] = '\0';
pnddDevices[*pszDeviceFound].uiSpeed = PN532_UART_DEFAULT_SPEED; pnddDevices[*pszDeviceFound].uiSpeed = PN532_UART_DEFAULT_SPEED;
(*pszDeviceFound)++; (*pszDeviceFound)++;
@ -127,13 +128,18 @@ pn532_uart_probe (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * ps
} }
# ifdef DEBUG # ifdef DEBUG
if (sp == INVALID_SERIAL_PORT) if (sp == INVALID_SERIAL_PORT)
DBG ("Invalid serial port: %s", pcPort); DBG ("Invalid serial port: %s", acPort);
if (sp == CLAIMED_SERIAL_PORT) if (sp == CLAIMED_SERIAL_PORT)
DBG ("Serial port already claimed: %s", pcPort); DBG ("Serial port already claimed: %s", acPort);
# endif # endif
/* DEBUG */ /* DEBUG */
} }
free (pcPorts);
iDevice = 0;
while ((acPort = acPorts[iDevice++])) {
free ((void*)acPort);
}
free (acPorts);
#endif /* SERIAL_AUTOPROBE_ENABLED */ #endif /* SERIAL_AUTOPROBE_ENABLED */
return true; return true;
} }
@ -144,13 +150,13 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
serial_port sp; 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); DBG ("Attempt to connect to: %s at %d bauds.", pndd->acPort, pndd->uiSpeed);
sp = uart_open (pndd->pcPort); sp = uart_open (pndd->acPort);
if (sp == INVALID_SERIAL_PORT) if (sp == INVALID_SERIAL_PORT)
ERR ("Invalid serial port: %s", pndd->pcPort); ERR ("Invalid serial port: %s", pndd->acPort);
if (sp == CLAIMED_SERIAL_PORT) if (sp == CLAIMED_SERIAL_PORT)
ERR ("Serial port already claimed: %s", pndd->pcPort); ERR ("Serial port already claimed: %s", pndd->acPort);
if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
return NULL; return NULL;
@ -159,7 +165,7 @@ pn532_uart_connect (const nfc_device_desc_t * pndd)
uart_set_speed (sp, pndd->uiSpeed); uart_set_speed (sp, pndd->uiSpeed);
// We have a connection // We have a connection
pnd = malloc (sizeof (nfc_device_t)); pnd = nfc_device_new ();
strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1); strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0'; pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
@ -206,6 +212,7 @@ pn532_uart_disconnect (nfc_device_t * pnd)
close (DRIVER_DATA (pnd)->iAbortFds[1]); close (DRIVER_DATA (pnd)->iAbortFds[1]);
#endif #endif
pn53x_data_free (pnd);
nfc_device_free (pnd); nfc_device_free (pnd);
} }