libftdi Archives

Subject: ftdi_eeprom_get_strings() failure when the device has no serial number

From: David Walton <dwaltoneng@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Wed, 17 Jul 2024 11:42:15 +1000
I have installed the latest version of libftdi in a RPi: "libftdi 1.5 (major: 1, minor: 5, micro: 0, snapshot ver: v1.5-42-gde9f01e)"

ftdi_eeprom_get_strings() fails with a segmentation fault if the connected device does not have a serial number. ftdi_eeprom_get_strings() calls strncpy(serial, eeprom->serial, serial_len);, however if the device has no serial number, then eeprom->serial == NULL

Am I taking the wrong approach, is there a way around this without modifying libftdi?. The code I am running is as follows:

/* Based on simple.c

   Simple libftdi usage example

   This program is distributed under the GPL, version 2
*/

#include <stdio.h>
#include <stdlib.h>
#include <ftdi.h>

int main(void)
{
    int ret;
    struct ftdi_context *ftdi;
    struct ftdi_version_info version;
    if ((ftdi = ftdi_new()) == 0)
    {
        fprintf(stderr, "ftdi_new failed\n");
        return EXIT_FAILURE;
    }

    version = ftdi_get_library_version();
    printf("Initialized libftdi %s (major: %d, minor: %d, micro: %d, snapshot ver: %s)\n",
           version.version_str, version.major, version.minor, version.micro,
           version.snapshot_str);

    if ((ret = ftdi_usb_open_desc(ftdi, 0x0403, 0x6010, "Lattice FTUSB Interface Cable", NULL)) < 0)
    {
        fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_read_eeprom(ftdi)) < 0)
    {
        fprintf(stderr, "unable to open ftdi eeprom: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    int value;
    if ((ret = ftdi_get_eeprom_value(ftdi, CHIP_SIZE, &value)) < 0)
    {
        fprintf(stderr, "unable to get ftdi eeprom size: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    if (value < 0)
    {
        fprintf(stderr, "No EEPROM found or EEPROM empty\n");
        return EXIT_FAILURE;
    }

    if ((ret = ftdi_eeprom_decode(ftdi, 0)) < 0)
    {
        fprintf(stderr, "unable to decode ftdi eeprom: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    char manufacturer[512] = "\0";
    char product[512] = "\0";
    char serial[512] = "\0";
    struct ftdi_eeprom *eeprom = ftdi->eeprom;
    if ((ret = ftdi_eeprom_get_strings(ftdi, manufacturer, sizeof(manufacturer), product, sizeof(product), serial, sizeof(serial))) < 0)
    {
        fprintf(stderr, "unable to get ftdi device info: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }
    printf("manufacturer = %s, product = %s, serial = %s\n", manufacturer, product, serial);

    if (ftdi->type != TYPE_2232H)
    {
        fprintf(stderr, "Expected a FT2232H\n");
    }

    if ((ret = ftdi_usb_close(ftdi)) < 0)
    {
        fprintf(stderr, "unable to close ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }

    ftdi_free(ftdi);

    return EXIT_SUCCESS;
}



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


Current Thread