From: Venkatesh S. <ven...@ii...> - 2014-07-05 21:06:48
|
Hello Guys I am Venkatesh Shukla. I have been working with Subsurface as a part of Google Summer of Code '14. My work involves helping to extend Subsurface to android. Subsurface, is an open-source community dedicated to bringing the best dive logging software to all the divers out there across all platforms. As is expected its next leap is owards android. Now, one of the most common usage of subsurface is to connect your divecomputer (devices which you take with you while diving and it records all your dive data) to the system and download all the information. Then it analyses the information and presents all the information to the users. For communication with divecomputers, Subsurface uses libdivecomputer. Now, my main aim is to enable usage of libdivecomputer on Android. That way we can connect the divecomputers to android devices and download all its details on the go. Now, for accessing USB devices on Android, it seems the best option to use libusb. It gives all appropriate commands and eases USB usage. Most of all the codebase of subsurface and libusb is in C, hence there won't be any language related issues. I need your help guys for usage of libusb on Android. Divecomputers come with many chipsets like pl2303, ftdi, cp210x etc. In systems such as linux, macos, libdivecomputer relies on tty devices for all communication with these chips. But as tty devices are not available on android, the way around is the usage of chip specific scripts. For instance, for talking with ftdi chipset, one can use libftdi. Libftdi in turn uses libusb for all its communication with usb devices. As you can see, the pivotal part of my project is enabling libusb on android. I have done some work in this regard. Let me elaborate. On using libusb directly on android, we are faced with this error. I stderr : libusb: 0.000000 error [op_open] libusb couldn't open USB device /dev/bus/usb/001/002: Permission denied. I stderr : libusb: 0.000055 error [op_open] libusb requires write access to USB device nodes. Clearly this is a permissions issue. Android does not allow access to USB devices per se. Now, android usually has static permissions system, whereby you add all the permissions you will be needing in the Manifest and you are granted those. But in case of USB devices, android goes a step further. You still have to ask for permission to use USB devices in the Manifest. Besides, you also have to get the permission at runtime when a USB device is attached. This complicates stuff. So, as the logical step I tried to get the device permission from the user and then open the USB device natively. But still the error persists. A simple code illustrating this is here : https://github.com/venkateshshukla/libusb-android-error Now this shows that the only way you access the USB devices is by using its java based USB API. But based on some inspirations [1], I tried another way around. The steps taken were these. 1. Get permissions from the user. The mechanism for this is explicitly explained in the Android documentation [2]. Remember this part is only possible using Java. Proceed to step 2 on receiving permission. 2. Now, open the required USB device. Still in Java side of android. Specifically, the function would be The UsbManager.openDevice(UsbDevice); 3. Now, extract the file descriptor of the USB device. This is the crucial aspect. The function for this is UsbDeviceConnection.getFileDescriptor(); 4. The UsbDevice is already open. Now jump on the native side of the application. Using the file descriptor extracted above, we will get a libusb_device_handle. This device handle can be used as is normal in libusb API. The essential point here would be not to try to open the USB device again. As it would lead to errors (Device Busy). Just substitute the file descriptor obtained from android USB API. Now, for using the file descriptor obtained from the android to obtain the device handle, I have made certain changes in libusb. A patch containing these changes is attached. The biggest advantage of the above mechanism would be that it would allow usage of libusb on android as on other systems without having superuser permissions. Without involving root permissions, applications that use libusb can port themselves on android and be available to all users - not the only ones that are brave enough to root their phones. Also, I see no major changes in USB API in the upcoming android L version yet [3]. Even though if something changes radically in android, they would always remain backward compatible. Android doesn't changes things drastically. Please give your feedback and comments on the patch, my approach and the general idea of using libusb on android. I apologize for the formatting error on the earlier mail. Sincerely Venkatesh Shukla Dept. of Electrical Engineering Indian Institute of Technology Banaras Hindu University Varanasi India References [1] http://stackoverflow.com/questions/14149801/modify-libusb-to-accept-file-descriptor [2] http://developer.android.com/guide/topics/connectivity/usb/host.html [3] http://developer.android.com/preview/reference.html |