core: convert ftdi.c to C++

Replace malloc/free of one structure by C++ idioms and add a
destructor to the struct. Otherwise, don't touch the code.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-02 22:36:34 +02:00 committed by bstoeger
parent e29a0c1b29
commit 7c2b580bfa
2 changed files with 38 additions and 53 deletions

View file

@ -17,7 +17,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
endif() endif()
if(FTDISUPPORT) if(FTDISUPPORT)
set(SERIAL_FTDI serial_ftdi.c) set(SERIAL_FTDI serial_ftdi.cpp)
endif() endif()
if(BTSUPPORT) if(BTSUPPORT)

View file

@ -22,7 +22,7 @@
* MA 02110-1301 USA * MA 02110-1301 USA
*/ */
#include <stdlib.h> // malloc, free #include <memory>
#include <string.h> // strerror #include <string.h> // strerror
#include <errno.h> // errno #include <errno.h> // errno
#include <sys/time.h> // gettimeofday #include <sys/time.h> // gettimeofday
@ -49,15 +49,15 @@
#define VID 0x0403 // Vendor ID of FTDI #define VID 0x0403 // Vendor ID of FTDI
typedef struct ftdi_serial_t { struct ftdi_serial_t {
/* Library context. */ /* Library context. */
dc_context_t *context; dc_context_t *context = nullptr;
/* /*
* The file descriptor corresponding to the serial port. * The file descriptor corresponding to the serial port.
* Also a libftdi_ftdi_ctx could be used? * Also a libftdi_ftdi_ctx could be used?
*/ */
struct ftdi_context *ftdi_ctx; struct ftdi_context *ftdi_ctx = nullptr;
long timeout; long timeout = -1; // Default to blocking reads.
/* /*
* Serial port settings are saved into this variable immediately * Serial port settings are saved into this variable immediately
* after the port is opened. These settings are restored when the * after the port is opened. These settings are restored when the
@ -66,16 +66,21 @@ typedef struct ftdi_serial_t {
* Custom implementation using libftdi functions could be done. * Custom implementation using libftdi functions could be done.
*/ */
unsigned int baudrate; // Default to full-duplex.
unsigned int nbits; unsigned int baudrate = 0;
unsigned int databits; unsigned int nbits = 0;
unsigned int stopbits; unsigned int databits = 0;
unsigned int parity; unsigned int stopbits = 0;
} ftdi_serial_t; unsigned int parity = 0;
~ftdi_serial_t() {
if (ftdi_ctx)
ftdi_free(ftdi_ctx);
}
};
static dc_status_t serial_ftdi_get_available (void *io, size_t *value) static dc_status_t serial_ftdi_get_available (void *io, size_t *value)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -114,7 +119,7 @@ static unsigned int serial_ftdi_get_msec(void)
static dc_status_t serial_ftdi_sleep (void *io, unsigned int timeout) static dc_status_t serial_ftdi_sleep (void *io, unsigned int timeout)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -173,17 +178,11 @@ static dc_status_t serial_ftdi_open (void **io, dc_context_t *context)
{ {
INFO("serial_ftdi_open called"); INFO("serial_ftdi_open called");
// Allocate memory. // Allocate memory.
ftdi_serial_t *device = (ftdi_serial_t *) malloc (sizeof (ftdi_serial_t)); auto device = std::make_unique<ftdi_serial_t>();
if (device == NULL) {
INFO("couldn't allocate memory");
SYSERROR (errno);
return DC_STATUS_NOMEMORY;
}
INFO("setting up ftdi_ctx"); INFO("setting up ftdi_ctx");
struct ftdi_context *ftdi_ctx = ftdi_new(); struct ftdi_context *ftdi_ctx = ftdi_new();
if (ftdi_ctx == NULL) { if (ftdi_ctx == NULL) {
INFO("failed ftdi_new()"); INFO("failed ftdi_new()");
free(device);
SYSERROR (errno); SYSERROR (errno);
return DC_STATUS_NOMEMORY; return DC_STATUS_NOMEMORY;
} }
@ -191,48 +190,34 @@ static dc_status_t serial_ftdi_open (void **io, dc_context_t *context)
// Library context. // Library context.
//device->context = context; //device->context = context;
// Default to blocking reads.
device->timeout = -1;
// Default to full-duplex.
device->baudrate = 0;
device->nbits = 0;
device->databits = 0;
device->stopbits = 0;
device->parity = 0;
// Initialize device ftdi context // Initialize device ftdi context
INFO("initialize ftdi_ctx"); INFO("initialize ftdi_ctx");
ftdi_init(ftdi_ctx); ftdi_init(ftdi_ctx);
if (ftdi_set_interface(ftdi_ctx,INTERFACE_ANY)) { if (ftdi_set_interface(ftdi_ctx,INTERFACE_ANY)) {
free(device);
ERROR ("%s", ftdi_get_error_string(ftdi_ctx)); ERROR ("%s", ftdi_get_error_string(ftdi_ctx));
return DC_STATUS_IO; return DC_STATUS_IO;
} }
INFO("call serial_ftdi_open_device"); INFO("call serial_ftdi_open_device");
if (serial_ftdi_open_device(ftdi_ctx) < 0) { if (serial_ftdi_open_device(ftdi_ctx) < 0) {
free(device);
ERROR ("%s", ftdi_get_error_string(ftdi_ctx)); ERROR ("%s", ftdi_get_error_string(ftdi_ctx));
return DC_STATUS_IO; return DC_STATUS_IO;
} }
if (ftdi_usb_reset(ftdi_ctx)) { if (ftdi_usb_reset(ftdi_ctx)) {
free(device);
ERROR ("%s", ftdi_get_error_string(ftdi_ctx)); ERROR ("%s", ftdi_get_error_string(ftdi_ctx));
return DC_STATUS_IO; return DC_STATUS_IO;
} }
if (ftdi_usb_purge_buffers(ftdi_ctx)) { if (ftdi_usb_purge_buffers(ftdi_ctx)) {
free(device);
ERROR ("%s", ftdi_get_error_string(ftdi_ctx)); ERROR ("%s", ftdi_get_error_string(ftdi_ctx));
return DC_STATUS_IO; return DC_STATUS_IO;
} }
device->ftdi_ctx = ftdi_ctx; device->ftdi_ctx = ftdi_ctx;
*io = device; *io = device.release();
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
} }
@ -242,7 +227,7 @@ static dc_status_t serial_ftdi_open (void **io, dc_context_t *context)
// //
static dc_status_t serial_ftdi_close (void *io) static dc_status_t serial_ftdi_close (void *io)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
@ -254,13 +239,11 @@ static dc_status_t serial_ftdi_close (void *io)
if (ret < 0) { if (ret < 0) {
ERROR ("Unable to close the ftdi device : %d (%s)", ERROR ("Unable to close the ftdi device : %d (%s)",
ret, ftdi_get_error_string(device->ftdi_ctx)); ret, ftdi_get_error_string(device->ftdi_ctx));
return ret; return (dc_status_t)ret;
} }
ftdi_free(device->ftdi_ctx);
// Free memory. // Free memory.
free (device); delete device;
return DC_STATUS_SUCCESS; return DC_STATUS_SUCCESS;
} }
@ -270,7 +253,7 @@ static dc_status_t serial_ftdi_close (void *io)
// //
static dc_status_t serial_ftdi_configure (void *io, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol) static dc_status_t serial_ftdi_configure (void *io, unsigned int baudrate, unsigned int databits, dc_parity_t parity, dc_stopbits_t stopbits, dc_flowcontrol_t flowcontrol)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -373,7 +356,7 @@ static dc_status_t serial_ftdi_configure (void *io, unsigned int baudrate, unsig
// //
static dc_status_t serial_ftdi_set_timeout (void *io, int timeout) static dc_status_t serial_ftdi_set_timeout (void *io, int timeout)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -387,7 +370,7 @@ static dc_status_t serial_ftdi_set_timeout (void *io, int timeout)
static dc_status_t serial_ftdi_read (void *io, void *data, size_t size, size_t *actual) static dc_status_t serial_ftdi_read (void *io, void *data, size_t size, size_t *actual)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -396,7 +379,7 @@ static dc_status_t serial_ftdi_read (void *io, void *data, size_t size, size_t *
long timeout = device->timeout; long timeout = device->timeout;
// Simulate blocking read as 10s timeout // Simulate blocking read as 10s timeout
if (timeout == -1) if (timeout <= -1)
timeout = 10000; timeout = 10000;
unsigned int start_time = serial_ftdi_get_msec(); unsigned int start_time = serial_ftdi_get_msec();
@ -409,8 +392,8 @@ static dc_status_t serial_ftdi_read (void *io, void *data, size_t size, size_t *
ERROR ("%s", ftdi_get_error_string(device->ftdi_ctx)); ERROR ("%s", ftdi_get_error_string(device->ftdi_ctx));
return DC_STATUS_IO; //Error during read call. return DC_STATUS_IO; //Error during read call.
} else if (n == 0) { } else if (n == 0) {
if (serial_ftdi_get_msec() - start_time > timeout) { if (serial_ftdi_get_msec() - start_time > (unsigned int)timeout) {
ERROR("FTDI read timed out."); ERROR("%s", "FTDI read timed out.");
return DC_STATUS_TIMEOUT; return DC_STATUS_TIMEOUT;
} }
serial_ftdi_sleep (device, 1); serial_ftdi_sleep (device, 1);
@ -429,7 +412,7 @@ static dc_status_t serial_ftdi_read (void *io, void *data, size_t size, size_t *
static dc_status_t serial_ftdi_write (void *io, const void *data, size_t size, size_t *actual) static dc_status_t serial_ftdi_write (void *io, const void *data, size_t size, size_t *actual)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -460,7 +443,7 @@ static dc_status_t serial_ftdi_write (void *io, const void *data, size_t size, s
static dc_status_t serial_ftdi_purge (void *io, dc_direction_t queue) static dc_status_t serial_ftdi_purge (void *io, dc_direction_t queue)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -497,14 +480,16 @@ static dc_status_t serial_ftdi_purge (void *io, dc_direction_t queue)
static dc_status_t serial_ftdi_set_break (void *io, unsigned int level) static dc_status_t serial_ftdi_set_break (void *io, unsigned int level)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
INFO ("Break: value=%i", level); INFO ("Break: value=%i", level);
if (ftdi_set_line_property2(device->ftdi_ctx, device->databits, device->stopbits, device->parity, level)) { if (ftdi_set_line_property2(device->ftdi_ctx, (ftdi_bits_type)device->databits,
(ftdi_stopbits_type)device->stopbits, (ftdi_parity_type)device->parity,
(ftdi_break_type)level)) {
ERROR ("%s", ftdi_get_error_string(device->ftdi_ctx)); ERROR ("%s", ftdi_get_error_string(device->ftdi_ctx));
return DC_STATUS_IO; return DC_STATUS_IO;
} }
@ -514,7 +499,7 @@ static dc_status_t serial_ftdi_set_break (void *io, unsigned int level)
static dc_status_t serial_ftdi_set_dtr (void *io, unsigned int value) static dc_status_t serial_ftdi_set_dtr (void *io, unsigned int value)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;
@ -531,7 +516,7 @@ static dc_status_t serial_ftdi_set_dtr (void *io, unsigned int value)
static dc_status_t serial_ftdi_set_rts (void *io, unsigned int level) static dc_status_t serial_ftdi_set_rts (void *io, unsigned int level)
{ {
ftdi_serial_t *device = io; ftdi_serial_t *device = (ftdi_serial_t *)io;
if (device == NULL) if (device == NULL)
return DC_STATUS_INVALIDARGS; return DC_STATUS_INVALIDARGS;