termux / termux-app

Termux - a terminal emulator application for Android OS extendible by variety of packages.
https://f-droid.org/en/packages/com.termux
Other
36.07k stars 3.78k forks source link

Failing libusb_init example #1928

Closed umarcor closed 3 years ago

umarcor commented 3 years ago

Problem description

I'm trying to follow https://wiki.termux.com/wiki/Termux-usb. Installing Termux:API and the packages worked. termux-usb -l works too. However, the usbtest.c example fails.

Steps to reproduce

I wrote a minimal version named usbinit.c:

#include <stdio.h>
#include <assert.h>
#include <libusb-1.0/libusb.h>

int main(int argc, char **argv) {
  libusb_context *context;
  assert(!libusb_init(&context));
  libusb_exit(context);
}
termux-usb -l
gcc usbinit.c -lusb-1.0 -o usbinit
termux-usb -r /dev/bus/usb/001/003
termux-usb -e ./usbinit /dev/bus/usb/001/003

Output:

~: termux-usb -r /dev/bus/usb/001/003
Access granted.
~: termux-usb -e ./usbinit /dev/bus/usb/001/003
usbinit.c:7: main: assertion "!libusb_init(&context)" failed
/data/data/com.termux/files/usr/libexec/termux-callback: line 3: 3112 Aborted   $TERMUX_CALLBACK "$0"

Expected behavior

usbinit should execute without failure.

Additional information

Grimler91 commented 3 years ago

Downgrading libusb to 1.0.23 does not fix it. Not sure what else we might have changed that could be the problem.

ghost commented 3 years ago

Same bug on Android 10, (oukitel wp5) Termux 0.101 Termux:API 0.44

ghost commented 3 years ago

Ok, i found the issue!

We need to add a call to: (note: i initialised 'context' to NULL first, since it is passed to this call, before init: 'libusb_context *context = NULL;')

libusb_set_option(context, LIBUSB_OPTION_WEAK_AUTHORITY);

just BEFORE the libusb_init() one. Please test it, and if all ok, someone could update the wiki example code for termux-usb! Thanks.

ghost commented 3 years ago

Hello, though i solved the issue regarding the wiki libusb example, it does displays me the device information name, manufacturer...but i cannot get to read data from my device(which is a MIDI device: Akai midimix - works fine on Android), i think on Android we don't have to claim the device right? cause it returns me 'busy' when i try, i might need to call libusb_control_transfer() prior to trying to read anything... but i don't find much info, until now i can read nothing from the device either synchronous/asynchronous with bulk_transfer or interrupt_transfer, any help greatly appreciated, if someone has a working example to read some data from a USB device...not much examples online and just documentation is not enough for me to get anything atm, thanks!

[edit] i'm trying to hack out libusb examples, especially the HID test one, i can get a fully detailled description of my device, so i see for instance it has 3 interfaces and multiples endpoints so maybe 1 ITF for reading, 1 for the LEDs?...i'm not sure. But i still can't read user input data from it...I'll try to get a clean version for the detailled device infos, would be usefull for any device.

Grimler91 commented 3 years ago

@ChewbakaJones what code are you trying to run? Have you modified it so that it uses libusb_wrap_sys_device + libusb_get_device instead of libusb_open?

I have an example modification for a sports watch here.

Will give your libusb_set_option fix a try later.

ghost commented 3 years ago

Here is a modified version of the tool provided by libusb adapted for Termux, usefull to dump infos and debug USB devices, you may want to try it on your PS3 or XBOX controller if you have some...i don't have that to try here.

termux-usb-test-infos.c : https://gist.github.com/ChewbakaJones/e54fd750b6a0dec5603e565c4adc8813

Example usage (build it, then usage):


$ gcc -o termux-usb-test-infos termux-usb-test-infos.c -lusb-1.0


$ termux-usb -l [ "/dev/bus/usb/001/006" ]

$ termux-usb -r /dev/bus/usb/001/006 Access granted.

$ termux-usb -e ./termux-usb-test-infos /dev/bus/usb/001/006

OR for debug infos:

$ termux-usb -e "./termux-usb-test-infos -d " /dev/bus/usb/001/006


@Grimler91 i started with the termux-usb wiki code snippet but now i was looking at the libusb samples...i still can't read my MIDI device's input, but i got much more infos about it already, you may wanna try this code on some other USB devices, HID or pads or storage to see..the smart watch code won't help me much, but you got able to interact with that device on Termux already?

Grimler91 commented 3 years ago

i still can't read my MIDI device's input

What input? What is it suppose to give you? termux-usb just allows existing libusb application to work (after some modifications) on android without root, you cannot really use termux-usb to reverse-engineer (or create from scratch) the communication with any usb device

the smart watch code won't help me much

No, that code just shows an example of the modification needed to make it possible for existing libusb-based programs to work via the android API without root.

but you got able to interact with that device on Termux already?

The application I forked, ttwatch, works on android with termux-usb after those modifications, yes.

ghost commented 3 years ago

I just want to read the raw midi events with libusb, like when i'm turning a knob on the device it must send a packet with 1 byte that is the value of the knob, just like for a gamepad. Nice to hear you got the smartwatch working, i guess if this works my device is much more simple...

umarcor commented 3 years ago

I tried mofidying the minimal snippet above according to @ChewbakaJones' explanation:

#include <stdio.h>
#include <assert.h>
#include <libusb-1.0/libusb.h>

int main(int argc, char **argv) {
  libusb_context *context = NULL;
  libusb_set_option(context, LIBUSB_OPTION_WEAK_AUTHORITY);
  assert(!libusb_init(&context));
  libusb_exit(context);
}

I'm still getting an error:

~: termux-usb -e ./usbinit /dev/bus/usb/001/003
/home/builder/termux-packages/.termux-builder/libusb/src/libusb/os/linux_usbfs.c:419: void op_exit(struct libusb_context *): assertion "init_count != 0" failed
/data/data/com.termux/files/usr/libexec/termux-callback: line 3: 16012 Aborted   $TERMUX_CALLBACK "$0"
meltdown03 commented 3 years ago

I tried mofidying the minimal snippet above according to @ChewbakaJones' explanation:

#include <stdio.h>
#include <assert.h>
#include <libusb-1.0/libusb.h>

int main(int argc, char **argv) {
  libusb_context *context = NULL;
  libusb_set_option(context, LIBUSB_OPTION_WEAK_AUTHORITY);
  assert(!libusb_init(&context));
  libusb_exit(context);
}

I'm still getting an error:

~: termux-usb -e ./usbinit /dev/bus/usb/001/003
/home/builder/termux-packages/.termux-builder/libusb/src/libusb/os/linux_usbfs.c:419: void op_exit(struct libusb_context *): assertion "init_count != 0" failed
/data/data/com.termux/files/usr/libexec/termux-callback: line 3: 16012 Aborted   $TERMUX_CALLBACK "$0"
  • Termux application version: 0.108 (Termux:API 0.47)
  • Android OS version: 8.1.0
  • Device model: Redmi 5 Plus

This is an error with libusb, see: https://github.com/libusb/libusb/commit/e78cafbaa2692f5b6e8e8f0ff306f5826c5dd94d

It should be fixed in the next version of libusb. It should only affect the exiting of libusb. After adding the line: libusb_set_option(NULL, LIBUSB_OPTION_WEAK_AUTHORITY) to the usbtest.c example, it works, then shows the error at exit.

Your source code isn't doing anything so you just see the error.

meltdown03 commented 3 years ago

I verified it works without error by building libusb from the GitHub source in termux. If you want a step-by-step on how to build it, let me know. It's just a few lines in the terminal.

agnostic-apollo commented 3 years ago

Closing since its fixed and not a termux-app issue. Someone should update the wiki though.