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