@@ -42,6 +42,7 @@ public async Task<List<DeviceInfo>> GetDevices() {
4242 }
4343
4444 private uint _interface ;
45+ private uint _alternate ;
4546 private uint ? _readEndpoint ;
4647 private uint ? _writeEndpoint ;
4748 private int ? _deviceFd ;
@@ -94,7 +95,7 @@ public void Initialize(string? id, byte[]? direct = null) {
9495 validity = false ;
9596 }
9697 _interface = reader . ReadByte ( ) ;
97- file . Seek ( 1 , SeekOrigin . Current ) ;
98+ _alternate = reader . ReadByte ( ) ;
9899 var numEndpoints = ( int ) reader . ReadByte ( ) ;
99100 Log . Debug ( "Number of endpoints: {0}" , numEndpoints ) ;
100101 var clss = reader . ReadByte ( ) ;
@@ -107,9 +108,10 @@ public void Initialize(string? id, byte[]? direct = null) {
107108 Log . Debug ( "$$ Endpoint index {0} $$" , j ) ;
108109 var len = reader . ReadByte ( ) ;
109110 var type = reader . ReadByte ( ) ;
110- if ( type == 0x24 ) {
111+ while ( type == 0x24 ) {
111112 Log . Debug ( "!! Class-dependant descriptor, skipping (len = {0} - 2)" , len ) ;
112- file . Seek ( len - 2 , SeekOrigin . Current ) ; continue ;
113+ file . Seek ( len - 2 , SeekOrigin . Current ) ;
114+ len = reader . ReadByte ( ) ; type = reader . ReadByte ( ) ;
113115 }
114116 if ( type != 0x05 ) {
115117 Log . Debug ( "!! USB_DT_ENDPOINT fail (value = {0:X2})" , type ) ;
@@ -140,27 +142,23 @@ public void Initialize(string? id, byte[]? direct = null) {
140142
141143 file . Dispose ( ) ;
142144 if ( ! found ) throw new InvalidOperationException ( "Failed to find valid endpoints!" ) ;
143- Log . Debug ( "Interface: 0x{0:X2}, Read Endpoint: 0x{1 :X2}, Write Endpoint: 0x{2 :X2}" ,
144- _interface , _readEndpoint , _writeEndpoint ) ;
145+ Log . Debug ( "Interface: 0x{0:X2}, Alternate: 0x{1:X2}, Read Endpoint: 0x{2 :X2}, Write Endpoint: 0x{3 :X2}" ,
146+ _interface , _alternate , _readEndpoint , _writeEndpoint ) ;
145147
146148 // Return in case of direct
147149 if ( direct != null ) return ;
148150
149151 // Create a device file handle
150152 if ( ( _deviceFd = Interop . Open ( path , Interop . O_RDWR ) ) < 0 )
151153 Interop . HandleError ( "Failed to open the device for RW" ) ;
152-
153- // Reset USB device
154- var zeroRef = 0u ;
155- if ( Interop . IoCtl ( _deviceFd . Value , Interop . USBDEVFS_RESET , ref zeroRef ) < 0 )
156- Interop . HandleError ( "Failed to reset USB device" ) ;
157-
154+
158155 // Detach kernel driver if present
159156 var driver = new Interop . GetDriver {
160157 Interface = ( int ) _interface
161158 } ;
162159
163160 if ( Interop . IoCtl ( _deviceFd . Value , Interop . USBDEVFS_GETDRIVER , ref driver ) > 0 ) {
161+ Log . Debug ( "Kernel driver detected, detaching it!" ) ;
164162 var ioctl = new Interop . UsbIoCtl {
165163 CommandCode = ( int ) Interop . USBDEVFS_DISCONNECT ,
166164 Interface = ( int ) _interface ,
@@ -172,7 +170,7 @@ public void Initialize(string? id, byte[]? direct = null) {
172170
173171 _detached = true ;
174172 }
175-
173+
176174 // Claim interface
177175 if ( Interop . IoCtl ( _deviceFd . Value , Interop . USBDEVFS_CLAIMINTERFACE , ref _interface ) < 0 )
178176 Interop . HandleError ( "Failed to claim interface" ) ;
@@ -249,26 +247,33 @@ public void ReadZLP() {
249247
250248 public void Dispose ( ) {
251249 // Release the interface
252- if ( _connected && _deviceFd . HasValue )
253- if ( Interop . IoCtl ( _deviceFd . Value , Interop . USBDEVFS_RELEASEINTERFACE , ref _interface ) < 0 )
254- Interop . HandleError ( "Failed to release interface" ) ;
250+ try {
251+ if ( _connected && _deviceFd . HasValue )
252+ if ( Interop . IoCtl ( _deviceFd . Value , Interop . USBDEVFS_RELEASEINTERFACE , ref _interface ) < 0 )
253+ Interop . HandleError ( "Failed to release interface" ) ;
254+ } catch { /* Ignored */ }
255255
256256 // Attach the kernel driver back
257- if ( _detached ) {
258- var ioctl = new Interop . UsbIoCtl {
259- CommandCode = ( int ) Interop . USBDEVFS_CONNECT ,
260- Interface = ( int ) _interface ,
261- Data = nint . Zero
262- } ;
263- if ( Interop . IoCtl ( _deviceFd ! . Value , Interop . USBDEVFS_IOCTL , ref ioctl ) < 0 )
264- Interop . HandleError ( "Failed to attach kernel driver" ) ;
265- }
266-
257+ try {
258+ if ( _detached ) {
259+ var ioctl = new Interop . UsbIoCtl {
260+ CommandCode = ( int ) Interop . USBDEVFS_CONNECT ,
261+ Interface = ( int ) _interface ,
262+ Data = nint . Zero
263+ } ;
264+ if ( Interop . IoCtl ( _deviceFd ! . Value , Interop . USBDEVFS_IOCTL , ref ioctl ) < 0 )
265+ Interop . HandleError ( "Failed to attach kernel driver" ) ;
266+ }
267+ } catch { /* Ignored */ }
268+
267269 // Close device file handle
268- if ( _deviceFd . HasValue && Interop . Close ( _deviceFd . Value ) < 0 )
269- Interop . HandleError ( "Failed to close device descriptor" ) ;
270+ try {
271+ if ( _deviceFd . HasValue && Interop . Close ( _deviceFd . Value ) < 0 )
272+ Interop . HandleError ( "Failed to close device descriptor" ) ;
273+ } catch { /* Ignored */ }
270274
271275 _connected = false ;
276+ _detached = false ;
272277 }
273278
274279 public static unsafe class Interop {
@@ -291,11 +296,12 @@ private static uint _IOR(uint type, uint nr, uint size)
291296 private static uint _IOW ( uint type , uint nr , uint size )
292297 => ( 1U << _IOC_DIRSHIFT ) | ( type << _IOC_TYPESHIFT )
293298 | ( nr << _IOC_NRSHIFT ) | ( size << _IOC_SIZESHIFT ) ;
299+ public static uint USBDEVFS_SETINTERFACE = _IOR ( 'U' , 4 , ( uint ) sizeof ( SetInterface ) ) ;
300+ public static uint USBDEVFS_GETDRIVER = _IOW ( 'U' , 8 , ( uint ) sizeof ( GetDriver ) ) ;
294301 public static uint USBDEVFS_BULK = _IOWR ( 'U' , 2 , ( uint ) sizeof ( BulkTransfer ) ) ;
295302 public static uint USBDEVFS_IOCTL = _IOWR ( 'U' , 18 , ( uint ) sizeof ( UsbIoCtl ) ) ;
296- public static uint USBDEVFS_CLAIMINTERFACE = _IOR ( 'U' , 15 , sizeof ( uint ) ) ;
297303 public static uint USBDEVFS_RELEASEINTERFACE = _IOR ( 'U' , 16 , sizeof ( uint ) ) ;
298- public static uint USBDEVFS_GETDRIVER = _IOW ( 'U' , 8 , ( uint ) sizeof ( GetDriver ) ) ;
304+ public static uint USBDEVFS_CLAIMINTERFACE = _IOR ( 'U' , 15 , sizeof ( uint ) ) ;
299305 public static uint USBDEVFS_DISCONNECT = _IO ( 'U' , 22 ) ;
300306 public static uint USBDEVFS_CONNECT = _IO ( 'U' , 23 ) ;
301307 public static uint USBDEVFS_RESET = _IO ( 'U' , 20 ) ;
@@ -306,6 +312,11 @@ public struct BulkTransfer {
306312 public uint Timeout ;
307313 public nint Data ;
308314 }
315+
316+ public struct SetInterface {
317+ public uint Interface ;
318+ public uint Alternate ;
319+ }
309320
310321 public struct GetDriver {
311322 public int Interface ;
@@ -336,9 +347,15 @@ public static extern int Open([MarshalAs(UnmanagedType.LPStr)]
336347 [ DllImport ( "libc" , EntryPoint = "ioctl" , SetLastError = true ) ]
337348 public static extern int IoCtl ( int fd , ulong request , ref GetDriver driver ) ;
338349
350+ [ DllImport ( "libc" , EntryPoint = "ioctl" , SetLastError = true ) ]
351+ public static extern int IoCtl ( int fd , ulong request , ref SetInterface ioctl ) ;
352+
339353 [ DllImport ( "libc" , EntryPoint = "ioctl" , SetLastError = true ) ]
340354 public static extern int IoCtl ( int fd , ulong request , ref uint iface ) ;
341355
356+ [ DllImport ( "libc" , EntryPoint = "ioctl" , SetLastError = true ) ]
357+ public static extern int IoCtl ( int fd , ulong request , nint ptr ) ;
358+
342359 [ DllImport ( "libc" , EntryPoint = "strerror" ) ]
343360 public static extern nint StrError ( int code ) ;
344361
0 commit comments