Skip to content

Commit dff2107

Browse files
committed
- Added Android CMake toolchain file (requires some configuration)
- Added function ftdi_usb_open2 designed to work with modified libusb open2 and device2
1 parent 4effe14 commit dff2107

4 files changed

Lines changed: 90 additions & 34 deletions

File tree

README.Android

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
A toolchain file is provided for cross-compiling this library to an armeabi-v7a platform. See cmake/Toolchain-Android-armeabi-v7a.cmake.
2+
3+
The Android build requires a modified version of libusb available here:
4+
5+
https://github.com/kuldeepdhaka/libusb/tree/android-open2
6+
7+
Build libusb-1.0 with an Android NDK toolchain and place the resulting .so and .h files in a convenient location. See the toolchain file for more detailed instructions.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
set(CMAKE_SYSTEM_NAME Android)
2+
set(CMAKE_SYSTEM_VERSION 21)
3+
set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
4+
set(CMAKE_ANDROID_ARM_NEON ON)
5+
set(CMAKE_ANDROID_ARM_MODE ON)
6+
# Change this path to point to ndk installation location
7+
set(CMAKE_ANDROID_NDK /opt/android/ndk/android-ndk-r14)
8+
set(CMAKE_ANDROID_STL_TYPE none)
9+
10+
# Change this path to point to armeabi-v7a libusb-1.0.so location
11+
# We also expect to find libusb.h here.
12+
# armeabi-v7a
13+
# usr
14+
# include
15+
# libusb-1.0
16+
# libusb.h
17+
# lib
18+
# libusb-1.0.so
19+
# NOTE: This is a special flavor of libusb. See README for details
20+
SET(CMAKE_FIND_ROOT_PATH /home/mkline/armeabi-v7a-inst)
21+
22+
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
23+
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
24+
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

src/ftdi.c

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -564,44 +564,18 @@ static unsigned int _ftdi_determine_max_packet_size(struct ftdi_context *ftdi, l
564564
return packet_size;
565565
}
566566

567-
/**
568-
Opens a ftdi device given by an usb_device.
569-
570-
\param ftdi pointer to ftdi_context
571-
\param dev libusb usb_dev to use
572-
573-
\retval 0: all fine
574-
\retval -3: unable to config device
575-
\retval -4: unable to open device
576-
\retval -5: unable to claim device
577-
\retval -6: reset failed
578-
\retval -7: set baudrate failed
579-
\retval -8: ftdi context invalid
580-
\retval -9: libusb_get_device_descriptor() failed
581-
\retval -10: libusb_get_config_descriptor() failed
582-
\retval -11: libusb_detach_kernel_driver() failed
583-
\retval -12: libusb_get_configuration() failed
584-
*/
585-
int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev)
586-
{
567+
static int ftdi_usb_open_dev_internal(struct ftdi_context *ftdi, libusb_device *dev) {
587568
struct libusb_device_descriptor desc;
588569
struct libusb_config_descriptor *config0;
589-
int cfg, cfg0, detach_errno = 0;
590-
591-
if (ftdi == NULL)
592-
ftdi_error_return(-8, "ftdi context invalid");
593-
594-
if (libusb_open(dev, &ftdi->usb_dev) < 0)
595-
ftdi_error_return(-4, "libusb_open() failed");
596-
570+
int cfg, cfg0 = 0;
571+
int detach_errno = 0;
572+
597573
if (libusb_get_device_descriptor(dev, &desc) < 0)
598574
ftdi_error_return(-9, "libusb_get_device_descriptor() failed");
599-
600575
if (libusb_get_config_descriptor(dev, 0, &config0) < 0)
601576
ftdi_error_return(-10, "libusb_get_config_descriptor() failed");
602577
cfg0 = config0->bConfigurationValue;
603578
libusb_free_config_descriptor (config0);
604-
605579
// Try to detach ftdi_sio kernel module.
606580
//
607581
// The return code is kept in a separate variable and only parsed
@@ -613,7 +587,7 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev)
613587
if (libusb_detach_kernel_driver(ftdi->usb_dev, ftdi->interface) !=0)
614588
detach_errno = errno;
615589
}
616-
590+
617591
if (libusb_get_configuration (ftdi->usb_dev, &cfg) < 0)
618592
ftdi_error_return(-12, "libusb_get_configuration () failed");
619593
// set configuration (needed especially for windows)
@@ -634,7 +608,7 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev)
634608
}
635609
}
636610
}
637-
611+
638612
if (libusb_claim_interface(ftdi->usb_dev, ftdi->interface) < 0)
639613
{
640614
ftdi_usb_close_internal (ftdi);
@@ -676,7 +650,6 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev)
676650

677651
// Determine maximum packet size
678652
ftdi->max_packet_size = _ftdi_determine_max_packet_size(ftdi, dev);
679-
680653
if (ftdi_set_baudrate (ftdi, 9600) != 0)
681654
{
682655
ftdi_usb_close_internal (ftdi);
@@ -686,6 +659,58 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev)
686659
ftdi_error_return(0, "all fine");
687660
}
688661

662+
/**
663+
Opens a ftdi device given by an usb_device.
664+
665+
\param ftdi pointer to ftdi_context
666+
\param dev libusb usb_dev to use
667+
668+
\retval 0: all fine
669+
\retval -3: unable to config device
670+
\retval -4: unable to open device
671+
\retval -5: unable to claim device
672+
\retval -6: reset failed
673+
\retval -7: set baudrate failed
674+
\retval -8: ftdi context invalid
675+
\retval -9: libusb_get_device_descriptor() failed
676+
\retval -10: libusb_get_config_descriptor() failed
677+
\retval -11: libusb_detach_kernel_driver() failed
678+
\retval -12: libusb_get_configuration() failed
679+
*/
680+
int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev)
681+
{
682+
if (ftdi == NULL)
683+
ftdi_error_return(-8, "ftdi context invalid");
684+
if (libusb_open(dev, &ftdi->usb_dev) < 0)
685+
ftdi_error_return(-4, "libusb_open() failed");
686+
return ftdi_usb_open_dev_internal(ftdi, dev);
687+
}
688+
689+
/**
690+
Opens the FTDI device based on the modified libusb open2 and device2 functions.
691+
See https://github.com/kuldeepdhaka/libusb/tree/android-open2.
692+
693+
\param ftdi pointer to ftdi_context
694+
\param dev_node device name from Android layer (UsbDevice::getDeviceName())
695+
\param fd file descriptor from Android layer (UsbDeviceConnection::getFileDescriptor())
696+
697+
Uses the same return codes as ftdi_usb_open_dev.
698+
*/
699+
int ftdi_usb_open2(struct ftdi_context *ftdi, const char *dev_node, int fd)
700+
{
701+
if (ftdi == NULL)
702+
ftdi_error_return(-8, "ftdi context invalid");
703+
libusb_device *dev = libusb_get_device2(ftdi->usb_ctx, dev_node);
704+
if (dev == NULL)
705+
ftdi_error_return(-4, "libusb_getdevice2() failed");
706+
if (libusb_open2(dev, &ftdi->usb_dev, fd)) {
707+
// FIXME: This may not be the right cleanup for libusb_get_device2
708+
libusb_unref_device(dev);
709+
ftdi_error_return(-4, "libusb_open2() failed");
710+
}
711+
return ftdi_usb_open_dev_internal(ftdi, dev);
712+
}
713+
689714
/**
690715
Opens the first device with a given vendor and product ids.
691716

src/ftdi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,8 @@ extern "C"
496496
char *serial, int serial_len);
497497
int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer,
498498
char * product, char * serial);
499-
500499
int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product);
500+
int ftdi_usb_open2(struct ftdi_context *ftdi, const char *dev_node, int fd);
501501
int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product,
502502
const char* description, const char* serial);
503503
int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product,

0 commit comments

Comments
 (0)