Re: attaching a USB device by libusb_device or libusb_device_handle on Android

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Iordan,
  could you open a MR?

Il giorno gio 23 dic 2021 alle ore 03:59 i iordanov <iiordanov@xxxxxxxxx> ha scritto:
Hi Uri,

Thanks for your assistance. I got it working. I'm attaching a patch
that does the job, and would really like it if we can make it
acceptable for inclusion into spice-gtk.

In general, the changes accomplish the following:

- Add the ability to allocate a SpiceUsbDevice using a file descriptor

I suppose you are speaking about allocate_device_for_file_descriptor. It's not called anywhere in the code so I suppose it is a public API. In this case it should start with something like spice_. Also it should have a bit more documentation and be listed in src/spice-glib-sym-file. But src/usb-backend.h is not a public header and we don't want it to be so it does not seem a good idea to declare there.

- Added a field that can keep a reference to the device handle that is
created by libusb from a file descriptor. This handle is used on
Android in place of a call to libusb_open() that would fail.
- On Android, set option LIBUSB_OPTION_NO_DEVICE_DISCOVERY prior to
libusb_init()
- Implement a method of retrieving the SpiceUsbBackend context from
the SpiceUsbDeviceManager (which holds the properly initialized libusb
context). This backend can be passed to the new
allocate_device_for_file_descriptor() method.

This seems like a bad idea. It exposes something internal. Why not having just one additional function in device manager like

gboolean
spice_usb_device_manager_add_device_from_fd(SpiceUsbDeviceManager *manager, GError **err);

The device could be communicated using device_added signal (if results if not FALSE), error can be returned, no additional interface to expose.
Or returning directory a SpiceUsbDevice* instead of a gboolean (but in this case interface will have to be blocking).


Please let me know what changes you think are needed.

Many thanks!
iordan


Frediano

On Tue, Dec 21, 2021 at 8:05 AM Uri Lublin <uril@xxxxxxxxxx> wrote:
>
> Hi,
>
> On Tue, Dec 21, 2021 at 9:24 AM i iordanov <iiordanov@xxxxxxxxx> wrote:
> >
> > Hello,
> >
> > Thanks for responding! As mentioned, I am trying to find a working,
> > programmatic way to pass a USB devices by either libusb_device or
> > libusb_device_handle from aSPICE and Opaque.
> >
> > I've now compiled libusb, usbredir 0.12, and recompiled spice-gtk 0.39
> > with usbredir support.
> >
> > The code I came up with looks like the following. The integer
> > fileDescriptor holds a file descriptor for the USB device obtained in
> > java after requesting permissions from the user.
> >
> > The first bit is from
> > https://github.com/libusb/libusb/blob/master/android/README.
> >
> > NOTE: For the part after the call to allocate_backend_device(), I had
> > to include the entire usb-backend.c file as you do in your tests in
> > spice-gtk, since I couldn't find a public API that allows me to
> > construct a SpiceUsbDevice. This may be a feature request that I'd
> > need to open with your project provided we can get USB redirection to
> > work in the first place.
> >
> > ======================================
> > JNIEXPORT void JNICALL
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor(JNIEnv
> > *env,
> >
> >  jobject obj,
> >
> >  jint fileDescriptor)
> > {
> >     // START: https://github.com/libusb/libusb/blob/master/android/README
> >
> >     libusb_context *ctx = NULL;
> >     libusb_device_handle *devh = NULL;
> >     int r = 0;
> >     r = libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY, NULL);
> >     if (r != LIBUSB_SUCCESS) {
> >         LOGE("%s: libusb_set_option failed", __FUNCTION__);
> >         return;
> >     }
> >     r = libusb_init(&ctx);
> >     if (r < 0) {
> >         LOGE("%s: libusb_init failed", __FUNCTION__);
> >         return;
> >     }
> >
> >     LOGD("%s: calling libusb_wrap_sys_device", __FUNCTION__);
> >     r = libusb_wrap_sys_device(ctx, (intptr_t)fileDescriptor, &devh);
> >     if (r < 0) {
> >         LOGE("%s: libusb_wrap_sys_device failed", __FUNCTION__);
> >         return;
> >     } else if (devh == NULL) {
> >         LOGE("%s: libusb_wrap_sys_device returned invalid handle",
> > __FUNCTION__);
> >         return;
> >     }
> >
> >     // END: https://github.com/libusb/libusb/blob/master/android/README
>
>
> That means the code should not call libusb_init without setting
> NO_DEVICE_DISCOVERY.
> Likely it should not call libusb_open either.
> The current code does call those functions and also gets the list of
> USB devices.
>
> >
> >     // Calling functionality from usb-backend.c
> >     SpiceUsbDevice *device = allocate_backend_device(libusb_get_device(devh));
>
> I think you need to call libusb_set_option (as above) before any libusb_init().
> Also, maybe you can pass here devh too (or only, and get the device
> inside the function)
> and skip calling libusb_open.
>
> >
> >     SpiceUsbDeviceManager *manager =
> > spice_usb_device_manager_get(global_conn->session, NULL);
> >     if (manager == NULL) {
> >         LOGE("%s: spice_usb_device_manager_get returned null manager",
> > __FUNCTION__);
> >         return;
> >     }
> >
> >     LOGD("%s: Attaching device via
> > spice_usb_device_manager_connect_device_async", __FUNCTION__);
> >     spice_usb_device_manager_connect_device_async(manager, device,
> > NULL, NULL, NULL);
> > }
> > ======================================
> >
> > During initialization I do get a few errors, which I suppose are due
> > to spice-gtk attempting to read USB devices directly, but I am not
> > certain:
>
> It seems libusb_init() fails.
>
> >
> > ======================================
> > 2021-12-21 02:13:59.761 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:286 New session (compiled from package
> > spice-gtk 0.39.4-ce0b8)
> > 2021-12-21 02:13:59.762 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:290 Supported channels: main, display, inputs,
> > cursor, playback, record, usbredir
> > 2021-12-21 02:13:59.765 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:391 auto-connect filter set to
> > 0x03,-1,-1,-1,0|-1,-1,-1,-1,1
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > E/GLib+android-spice: spice_usb_backend_deregister_hotplug: assertion
> > 'be != NULL' failed
> > 2021-12-21 02:13:59.762 3011-3011/com.iiordanov.aSPICE W/Thread-4:
> > type=1400 audit(0.0:1572): avc: denied { read } for name="usb"
> > dev="tmpfs" ino=1397419
> > scontext=u:r:untrusted_app:s0:c181,c257,c512,c768
> > tcontext=u:object_r:usb_device:s0 tclass=dir permissive=0
> > app=com.iiordanov.aSPICE
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:1578 Could not initialize SpiceUsbDeviceManager
> > - Error initializing LIBUSB support: Input/Output Error [-1]
>
> For example here.
>
> Regards,
>     Uri.
>
>
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:391 auto-connect filter set to
> > 0x03,-1,-1,-1,0|-1,-1,-1,-1,1
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > E/GLib+android-spice: spice_usb_backend_deregister_hotplug: assertion
> > 'be != NULL' failed
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:1578 Could not initialize SpiceUsbDeviceManager
> > - Error initializing LIBUSB support: Input/Output Error [-1]
> > 2021-12-21 02:13:59.766 3011-3060/com.iiordanov.aSPICE
> > W/GLib+android-spice: Error initializing LIBUSB support: Input/Output
> > Error [-1]
> > ======================================
> >
> > The rest of the log looks very encouraging, save for the fact that no
> > device is attached to the remote. The same device does attach when I
> > use spicy from my laptop to the same VM. Here is the log that is
> > output from the above code and subsequently by spice-gtk:
> >
> > ======================================
> > 2021-12-21 02:13:59.957 3011-3060/com.iiordanov.aSPICE
> > D/SpiceCommunicator: Passing fd: 85 to SPICE for device:
> > UsbDevice[mName=/dev/bus/usb/001/002,mVendorId=7741,mProductId=8338,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=CBM
> >     ,mProductName=Flash Disk
> > ,mVersion=1.00,mSerialNumberReader=android.hardware.usb.IUsbSerialReader$Stub$Proxy@ecfcac3,
> > mHasAudioPlayback=false, mHasAudioCapture=false, mHasMidi=false,
> > mHasVideoCapture=false, mHasVideoPlayback=false, mConfigurations=[
> >     UsbConfiguration[mId=1,mName=null,mAttributes=128,mMaxPower=50,mInterfaces=[
> >     UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[
> >     UsbEndpoint[mAddress=1,mAttributes=2,mMaxPacketSize=512,mInterval=0]
> >     UsbEndpoint[mAddress=129,mAttributes=2,mMaxPacketSize=512,mInterval=0]]]]
> > 2021-12-21 02:13:59.957 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > start
> > 2021-12-21 02:13:59.957 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > calling libusb_wrap_sys_device
> > 2021-12-21 02:13:59.958 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > calling allocate_backend_device
> > 2021-12-21 02:13:59.958 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > calling spice_usb_device_manager_get
> > 2021-12-21 02:13:59.956 3011-3011/com.iiordanov.aSPICE W/Thread-4:
> > type=1400 audit(0.0:1578): avc: denied { read } for name="usb"
> > dev="tmpfs" ino=1397419
> > scontext=u:r:untrusted_app:s0:c181,c257,c512,c768
> > tcontext=u:object_r:usb_device:s0 tclass=dir permissive=0
> > app=com.iiordanov.aSPICE
> > 2021-12-21 02:13:59.958 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:391 auto-connect filter set to
> > 0x03,-1,-1,-1,0|-1,-1,-1,-1,1
> > 2021-12-21 02:13:59.960 3011-3060/com.iiordanov.aSPICE
> > D/android-service:
> > Java_com_undatech_opaque_SpiceCommunicator_SpiceSetNativeFileDescriptor:
> > Attaching device via spice_usb_device_manager_connect_device_async
> > 2021-12-21 02:13:59.960 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/usb-device-manager.c:1103 connecting device 0x70efaf1490
> > 2021-12-21 02:13:59.960 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/channel-usbredir.c:344 usbredir-9:0: connecting device
> > 1e3d:2092 (0x70efaf1490) to channel 0x725fae4540
> > 2021-12-21 02:13:59.960 3011-3079/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 1 in 0x1052: yes
> > 2021-12-21 02:13:59.961 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2703 usbredir-9:0: Open coroutine starting
> > 0x725fae4540
> > 2021-12-21 02:13:59.962 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2540 usbredir-9:0: Started background coroutine
> > 0x725fae43f8
> > 2021-12-21 02:13:59.962 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2265 usbredir-9:0: Using plain text, port 6001
> > 2021-12-21 02:13:59.962 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2703 usbredir-9:1: Open coroutine starting
> > 0x725fae4340
> > 2021-12-21 02:13:59.963 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2540 usbredir-9:1: Started background coroutine
> > 0x725fae41f8
> > 2021-12-21 02:13:59.963 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2265 usbredir-9:1: Using plain text, port 6001
> > 2021-12-21 02:13:59.965 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2196 open host MYHOST:6001
> > 2021-12-21 02:13:59.965 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2118 usbredir-9:0: connecting 0x709fb7aaf0...
> > 2021-12-21 02:13:59.965 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2196 open host MYHOST:6001
> > 2021-12-21 02:13:59.966 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2118 usbredir-9:1: connecting 0x709fa7caf0...
> > 2021-12-21 02:13:59.992 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2102 usbredir-9:0: connect ready
> > 2021-12-21 02:13:59.992 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1372 usbredir-9:0: channel type 9 id 0 num
> > common caps 1 num caps 1
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1396 usbredir-9:0: Peer version: 2:2
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1952 usbredir-9:0: spice_channel_recv_link_msg:
> > 2 caps
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1966 usbredir-9:0: got remote common caps:
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0xB
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1973 usbredir-9:0: got remote channel caps:
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0x1
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 0 in 0xB: yes
> > 2021-12-21 02:14:00.002 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 1 in 0xB: yes
> > 2021-12-21 02:14:00.003 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 3 in 0xB: yes
> > 2021-12-21 02:14:00.003 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2005 usbredir-9:0: use mini header: 1
> > 2021-12-21 02:14:00.003 3011-3060/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-session.c:2102 usbredir-9:1: connect ready
> > 2021-12-21 02:14:00.003 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1372 usbredir-9:1: channel type 9 id 1 num
> > common caps 1 num caps 1
> > 2021-12-21 02:14:00.005 3011-3115/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1303 usbredir-9:0: channel up, state 3
> > 2021-12-21 02:14:00.013 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1396 usbredir-9:1: Peer version: 2:2
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1952 usbredir-9:1: spice_channel_recv_link_msg:
> > 2 caps
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1966 usbredir-9:1: got remote common caps:
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0xB
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1973 usbredir-9:1: got remote channel caps:
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1902     0:0x1
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 0 in 0xB: yes
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 1 in 0xB: yes
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2921 test cap 3 in 0xB: yes
> > 2021-12-21 02:14:00.014 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:2005 usbredir-9:1: use mini header: 1
> > 2021-12-21 02:14:00.018 3011-3116/com.iiordanov.aSPICE D/GLib+GSpice:
> > ../src/spice-channel.c:1303 usbredir-9:1: channel up, state 3
> > ======================================
> >
> > Your help and suggestions are highly appreciated!
> >
> > Sincerely,
> > iordan
> >
> > On Mon, Dec 20, 2021 at 5:57 AM Uri Lublin <uril@xxxxxxxxxx> wrote:
> > >
> > > Hi iordan,
> > >
> > > On Mon, Dec 20, 2021 at 9:46 AM i iordanov <iiordanov@xxxxxxxxx> wrote:
> > > >
> > > > Hi guys,
> > > >
> > > > I saw that the developers at libusb have done a bunch of work to
> > > > support accessing USB devices on unrooted Android devices, and in
> > > > response to a user request, I decided to look into the current state
> > > > of the implementation.
> > >
> > > Congrats to libusb developers.
> > >
> > > >
> > > > I am able to obtain permissions and get both:
> > > >
> > > > libusb_device *dev
> > > >
> > > > and
> > > >
> > > > libusb_device_handle *handle
> > > >
> > > > for an attached USB stick, but now do not have a good idea how to
> > > > request libspice to attach the device to the remote.
> > > >
> > > > Is there an API exposed that would permit me to attach devices by
> > > > either libusb_device or libusb_device_handle? In either case, any
> > > > pointers on how to accomplish this are welcome!
> > >
> > > On the client side, you need to build usbredir and rebuild spice-gtk
> > > with usbredir enabled.
> > >
> > > On the server side you need to build usbredir and rebuild Qemu with
> > > usbredir enabled.
> > > You also need to add to your VM configuration some USB devices and
> > > attach them to SPICE.
> > > See SPICE User Manual [1] "USB redirection" for details.
> > >
> > > [1] https://www.spice-space.org/spice-user-manual.html
> > >
> > > Regards,
> > >     Uri.
> > >
> > > >
> > > > Sincerely,
> > > > iordan
> > > >
> > > > --
> > > > The conscious mind has only one thread of execution.
> > > >
> > >
> >
> >
> > --
> > The conscious mind has only one thread of execution.
> >
>


--
The conscious mind has only one thread of execution.

[Index of Archives]     [Linux Virtualization]     [Linux Virtualization]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]