src/app/host-serial/libftdi/ftdi.c
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
{
    int offset = 0, ret, i, num_of_chunks, chunk_remains;
    int packet_size = ftdi->max_packet_size;
    int actual_length = 1;

    if (ftdi == NULL || ftdi->usb_dev == NULL)
        ftdi_error_return(-666, "USB device unavailable");

    // Packet size sanity check (avoid division by zero)
    if (packet_size == 0)
        ftdi_error_return(-1, "max_packet_size is bogus (zero)");

    // everything we want is still in the readbuffer?
    if (size <= (int)ftdi->readbuffer_remaining)
    {
        memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);

        // Fix offsets
        ftdi->readbuffer_remaining -= size;
        ftdi->readbuffer_offset += size;

        /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */

        return size;
    }
    // something still in the readbuffer, but not enough to satisfy 'size'?
    if (ftdi->readbuffer_remaining != 0)
    {
        memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);

        // Fix offset
        offset += ftdi->readbuffer_remaining;
    }
    // do the actual USB read
    while (offset < size && actual_length > 0)
    {
        ftdi->readbuffer_remaining = 0;
        ftdi->readbuffer_offset = 0;
        /* returns how much received */
        ret = libusb_bulk_transfer (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer, ftdi->readbuffer_chunksize, &actual_length, ftdi->usb_read_timeout);
        if (ret < 0)
            ftdi_error_return(ret, "usb bulk read failed");

        if (actual_length > 2)
        {
            // skip FTDI status bytes.
            // Maybe stored in the future to enable modem use
            num_of_chunks = actual_length / packet_size;
            chunk_remains = actual_length % packet_size;
            //printf("actual_length = %X, num_of_chunks = %X, chunk_remains = %X, readbuffer_offset = %X\n", actual_length, num_of_chunks, chunk_remains, ftdi->readbuffer_offset);

            ftdi->readbuffer_offset += 2;
            actual_length -= 2;

            if (actual_length > packet_size - 2)
            {
                for (i = 1; i < num_of_chunks; i++)
                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
                             ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
                             packet_size - 2);
                if (chunk_remains > 2)
                {
                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
                             ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
                             chunk_remains-2);
                    actual_length -= 2*num_of_chunks;
                }
                else
                    actual_length -= 2*(num_of_chunks-1)+chunk_remains;
            }
        }
        else if (actual_length <= 2)
        {
            // no more data to read?
            return offset;
        }
        if (actual_length > 0)
        {
            // data still fits in buf?
            if (offset+actual_length <= size)
            {
                memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, actual_length);
                //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]);
                offset += actual_length;

                /* Did we read exactly the right amount of bytes? */
                if (offset == size)
                    //printf("read_data exact rem %d offset %d\n",
                    //ftdi->readbuffer_remaining, offset);
                    return offset;
            }
            else
            {
                // only copy part of the data or size <= readbuffer_chunksize
                int part_size = size-offset;
                memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);

                ftdi->readbuffer_offset += part_size;
                ftdi->readbuffer_remaining = actual_length-part_size;
                offset += part_size;

                /* printf("Returning part: %d - size: %d - offset: %d - actual_length: %d - remaining: %d\n",
                part_size, size, offset, actual_length, ftdi->readbuffer_remaining); */

                return offset;
            }
        }
    }
    // never reached
    return -127;
}
/**
    Reads data in chunks (see ftdi_read_data_set_chunksize()) from the chip.

    Automatically strips the two modem status bytes transfered during every read.

    \param ftdi pointer to ftdi_context
    \param buf Buffer to store data in
    \param size Size of the buffer

    \retval -666: USB device unavailable
    \retval <0: error code from libusb_bulk_transfer()
    \retval  0: no data was available
    \retval >0: number of bytes read

*/
Reads data in chunks ) from the chip.
Automatically strips the two modem status bytes transfered during every read.

\param ftdi pointer to ftdi_context
\param buf Buffer to store data in
\param size Size of the buffer

\retval -666: USB device unavailable
\retval <0: error code from libusb_bulk_transfer()
\retval  0: no data was available
\retval >0: number of bytes read
Reads data in chunks ) from the chip . Automatically strips the two modem status bytes transfered during every read . \ param ftdi pointer to ftdi_context \ param buf Buffer to store data in \ param size Size of the buffer \ retval - 666 : USB device unavailable \ retval <0 : error code from libusb_bulk_transfer () \ retval 0 : no data was available \ retval > 0 : number of bytes read
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
{
    int offset = 0, ret, i, num_of_chunks, chunk_remains;
    int packet_size = ftdi->max_packet_size;
    int actual_length = 1;
    if (ftdi == NULL || ftdi->usb_dev == NULL)
        ftdi_error_return(-666, "USB device unavailable");
    if (packet_size == 0)
        ftdi_error_return(-1, "max_packet_size is bogus (zero)");
    if (size <= (int)ftdi->readbuffer_remaining)
    {
        memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
        ftdi->readbuffer_remaining -= size;
        ftdi->readbuffer_offset += size;
        return size;
    }
    if (ftdi->readbuffer_remaining != 0)
    {
        memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
        offset += ftdi->readbuffer_remaining;
    }
    while (offset < size && actual_length > 0)
    {
        ftdi->readbuffer_remaining = 0;
        ftdi->readbuffer_offset = 0;
        ret = libusb_bulk_transfer (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer, ftdi->readbuffer_chunksize, &actual_length, ftdi->usb_read_timeout);
        if (ret < 0)
            ftdi_error_return(ret, "usb bulk read failed");
        if (actual_length > 2)
        {
            num_of_chunks = actual_length / packet_size;
            chunk_remains = actual_length % packet_size;
            ftdi->readbuffer_offset += 2;
            actual_length -= 2;
            if (actual_length > packet_size - 2)
            {
                for (i = 1; i < num_of_chunks; i++)
                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
                             ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
                             packet_size - 2);
                if (chunk_remains > 2)
                {
                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
                             ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
                             chunk_remains-2);
                    actual_length -= 2*num_of_chunks;
                }
                else
                    actual_length -= 2*(num_of_chunks-1)+chunk_remains;
            }
        }
        else if (actual_length <= 2)
        {
            return offset;
        }
        if (actual_length > 0)
        {
            if (offset+actual_length <= size)
            {
                memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, actual_length);
                offset += actual_length;
                if (offset == size)
                    return offset;
            }
            else
            {
                int part_size = size-offset;
                memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
                ftdi->readbuffer_offset += part_size;
                ftdi->readbuffer_remaining = actual_length-part_size;
                offset += part_size;
                return offset;
            }
        }
    }
    return -127;
}
int ftdi_read_data ( struct ftdi_context * ftdi , unsigned char * buf , int size ) { int offset = 0 , ret , i , num_of_chunks , chunk_remains ; int packet_size = ftdi -> max_packet_size ; int actual_length = 1 ; if ( ftdi == NULL || ftdi -> usb_dev == NULL ) ftdi_error_return ( -666 , " " ) ; if ( packet_size == 0 ) ftdi_error_return ( -1 , " " ) ; if ( size <= ( int ) ftdi -> readbuffer_remaining ) { memcpy ( buf , ftdi -> readbuffer + ftdi -> readbuffer_offset , size ) ; ftdi -> readbuffer_remaining -= size ; ftdi -> readbuffer_offset += size ; return size ; } if ( ftdi -> readbuffer_remaining != 0 ) { memcpy ( buf , ftdi -> readbuffer + ftdi -> readbuffer_offset , ftdi -> readbuffer_remaining ) ; offset += ftdi -> readbuffer_remaining ; } while ( offset < size && actual_length > 0 ) { ftdi -> readbuffer_remaining = 0 ; ftdi -> readbuffer_offset = 0 ; ret = libusb_bulk_transfer ( ftdi -> usb_dev , ftdi -> out_ep , ftdi -> readbuffer , ftdi -> readbuffer_chunksize , & actual_length , ftdi -> usb_read_timeout ) ; if ( ret < 0 ) ftdi_error_return ( ret , " " ) ; if ( actual_length > 2 ) { num_of_chunks = actual_length / packet_size ; chunk_remains = actual_length % packet_size ; ftdi -> readbuffer_offset += 2 ; actual_length -= 2 ; if ( actual_length > packet_size - 2 ) { for ( i = 1 ; i < num_of_chunks ; i ++ ) memmove ( ftdi -> readbuffer + ftdi -> readbuffer_offset + ( packet_size - 2 ) * i , ftdi -> readbuffer + ftdi -> readbuffer_offset + packet_size * i , packet_size - 2 ) ; if ( chunk_remains > 2 ) { memmove ( ftdi -> readbuffer + ftdi -> readbuffer_offset + ( packet_size - 2 ) * i , ftdi -> readbuffer + ftdi -> readbuffer_offset + packet_size * i , chunk_remains - 2 ) ; actual_length -= 2 * num_of_chunks ; } else actual_length -= 2 * ( num_of_chunks - 1 ) + chunk_remains ; } } else if ( actual_length <= 2 ) { return offset ; } if ( actual_length > 0 ) { if ( offset + actual_length <= size ) { memcpy ( buf + offset , ftdi -> readbuffer + ftdi -> readbuffer_offset , actual_length ) ; offset += actual_length ; if ( offset == size ) return offset ; } else { int part_size = size - offset ; memcpy ( buf + offset , ftdi -> readbuffer + ftdi -> readbuffer_offset , part_size ) ; ftdi -> readbuffer_offset += part_size ; ftdi -> readbuffer_remaining = actual_length - part_size ; offset += part_size ; return offset ; } } } return -127 ; }
Reads data in chunks (see ftdi_read_data_set_chunksize()) from the chip.
Reads data in chunks ( see ftdi_read_data_set_chunksize () ) from the chip .
// Packet size sanity check (avoid division by zero) // everything we want is still in the readbuffer? // Fix offsets /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */ // something still in the readbuffer, but not enough to satisfy 'size'? // Fix offset // do the actual USB read /* returns how much received */ // skip FTDI status bytes. // Maybe stored in the future to enable modem use //printf("actual_length = %X, num_of_chunks = %X, chunk_remains = %X, readbuffer_offset = %X\n", actual_length, num_of_chunks, chunk_remains, ftdi->readbuffer_offset); // no more data to read? // data still fits in buf? //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]); /* Did we read exactly the right amount of bytes? */ //printf("read_data exact rem %d offset %d\n", //ftdi->readbuffer_remaining, offset); // only copy part of the data or size <= readbuffer_chunksize /* printf("Returning part: %d - size: %d - offset: %d - actual_length: %d - remaining: %d\n",
                part_size, size, offset, actual_length, ftdi->readbuffer_remaining); */ // never reached