libftdi Archives

Subject: Re: Better error code from ftdi_write_data()

From: Ларионов Даниил <scumcoder@xxxxxxxxx>
To: thomas.jarosch@xxxxxxxxxxxxx
Cc: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Tue, 30 Aug 2022 22:46:53 +0300
Greetings.

> I'm also open for other API designs if something better comes up.

IMHO whenever a wrapper (in this case libftdi) has to pass an error to the 
calling code, and this error *can* be (but not always is) caused by the wrapped 
code (in this case libusb), the only way is to use a variant.

Here is a quick mockup of the API that I’d add (please note that I didn’t even 
try to compile this):


enum ftdi_error_source
{
    // Let's not forget that non-scoped enums inject their members into 
surrounding namespace (in this case global),
    // so give every member a prefix
    ftdi_error_source_unknown, // so that memset(0x00) will always give correct 
meaning
    ftdi_error_source_libftdi,
    ftdi_error_source_libusb
};

// This enum is BADLY needed; in this case I jerry-rigged it from libftdi's 
manual
enum ftdi_error_code
{
    // The same numerical value can mean completely different things depending 
on the called function, hence cumbersome prefixes;
    // if this enum is going to be divorced from corresponding return values 
then this mess can be cleaned up

    // ftdi_init
    ftdi_error_code_init_all_fine = 0,
    ftdi_error_code_init_couldnt_allocate_read_buffer = -1,
    ftdi_error_code_init_couldnt_allocate_struct_buffer = -2,
    ftdi_error_code_init_libusb_init_failed = -3,

    // ftdi_set_interface
    ftdi_error_code_set_interface_all_fine = 0,
    ftdi_error_code_set_interface_unknown_interface = -1,
    ftdi_error_code_set_interface_USB_device_unavailable = -2,
    
ftdi_error_code_set_interface_Device_already_open_interface_cant_be_set_in_that_state
 = -3,

    // ftdi_usb_open/ftdi_usb_open_desc/ftdi_usb_open_desc_index
    ftdi_error_code_usb_open_all_fine = 0,
    ftdi_error_code_usb_open_usb_find_busses_failed = -1,
    ftdi_error_code_usb_open_usb_find_devices_failed = -2,
    ftdi_error_code_usb_open_usb_device_not_found = -3,
    ftdi_error_code_usb_open_unable_to_open_device = -4,
    ftdi_error_code_usb_open_unable_to_claim_device = -5,
    ftdi_error_code_usb_open_reset_failed = -6,
    ftdi_error_code_usb_open_set_baudrate_failed = -7,
    ftdi_error_code_usb_open_get_product_description_failed = -8,
    ftdi_error_code_usb_open_get_serial_number_failed = -9,
    ftdi_error_code_usb_open_unable_to_close_device = -10,
    ftdi_error_code_usb_open_ftdi_context_invalid = -11,
    ftdi_error_code_usb_open_libusb_get_device_list_failed = -12,
    ftdi_error_code_usb_open_libusb_get_device_descriptor_failed = -13,

    // ftdi_usb_close
    ftdi_error_code_usb_close_all_fine = 0,
    ftdi_error_code_usb_close_usb_release_failed = -1,
    ftdi_error_code_usb_close_ftdi_context_invalid = -3,

    // ftdi_read_data
    ftdi_error_code_read_data_USB_device_unavailable = -666
};

struct ftdi_error_variant
{
    union any_error
    {
        ftdi_error_code libftdi;
        libusb_error libusb;
    };

    ftdi_error_source source; // denotes which member of any_error is valid
    any_error error;
};

// Fills error->source with ftdi_error_source_unknown if no error has occurred
void ftdi_get_last_error(ftdi_error_variant *error);


-- Даниил Ларионов


> Hi Rick,
> 
> You wrote on Tue, Mar 08, 2022 at 06:57:49PM +0000:
> 
>> I'm using libftdi to control a mass spectrometer and am getting hangups 
>> every few days. The symptom is that ftdi_write_data returns -1. Sometimes I 
>> can clear the fault and continue by calling ftdi_usb_purge_buffers(&ftdic), 
>> but I still have a residual number of cases that simply lock the system.
>>
>> I wonder if it would make sense to change the logic slightly in 
>> ftdi_write_data:
>>
>> int ftdi_write_data(struct ftdi_context *ftdi, const unsigned char *buf, int 
>> size)
>> {
>> ...
>> if(libusb_bulk_transfer(ftdi->usb_dev, ftdi->in_ep, (unsigned char 
>> *)buf+offset, write_size, &actual_length, ftdi->usb_write_timeout) < 0)
>> ftdi_error_return(-1, "usb bulk write failed");
>> ...
>> }
>>
>> It seems like saving the return value from libusb_bulk_transfer and 
>> returning that value rather than -1 would make the error culprit more 
>> visible. As it is, the -1 gives no information about what caused 
>> libusb_bulk_transfer() to fail.
>>
>> Please let me know if you have any other suggestions for how to recover from 
>> a ftdi_write_data error. I suppose, I could close the context and start 
>> over, but maybe there are better approaches. The target application should 
>> run for up to a year reliably without rebooting.
> 
> Sorry for the long delay, I maintain libftdi in my spare time.
> 
> The problem is changing the return values for ftdi_write_data()
> would break existing libftdi applications. One thing we could do
> is to store the error code in an extra variable and have a get() function for 
> this.
> 
> So may be something like ftdi_get_last_libusb_error()?
> 
> I'm also open for other API designs if something better comes up.
> 
> Cheers,
> Thomas
> 
> --
> libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
> To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx

--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread