@@ -162,11 +162,9 @@ def __init__(self, root_dir="/"):
162
162
self ._bulk_in_ep = None
163
163
self ._bulk_out_ep = None
164
164
self ._intr_ep = None
165
- self ._bulk_in_buf = None
166
- self ._bulk_out_buf = None
167
- self ._rx_buf = None
168
- self ._tx_buf = None
169
- self ._rx_packet = None
165
+ self ._itf_num = None
166
+
167
+ # Create packet and container buffers
170
168
self ._container_buf = bytearray (MTP_MAX_PACKET_SIZE )
171
169
self ._container_mview = memoryview (self ._container_buf )
172
170
@@ -193,21 +191,22 @@ def __init__(self, root_dir="/"):
193
191
self ._transfer_offset = 0
194
192
self ._transfer_length = 0
195
193
self ._transfer_file = None
194
+
195
+ # Initialize with default parameters
196
+ self .init ()
196
197
197
198
def init (self , packet_size = MTP_MAX_PACKET_SIZE ):
198
199
"""Initialize the MTP interface with the given configuration.
199
200
200
201
Args:
201
202
packet_size: Maximum packet size for bulk transfers (default: 512)
202
203
"""
203
- # Create buffers
204
- self ._bulk_in_buf = Buffer (packet_size * 2 ) # Double buffering
205
- self ._bulk_out_buf = Buffer (packet_size * 2 )
204
+ # Create buffers for data transfer
206
205
self ._rx_buf = bytearray (packet_size )
207
206
self ._rx_packet = memoryview (self ._rx_buf )
208
207
self ._tx_buf = bytearray (packet_size )
209
208
210
- # Set internal state
209
+ # Reset internal state
211
210
self ._transaction_id = 0
212
211
self ._session_open = False
213
212
self ._handles = {}
@@ -297,56 +296,53 @@ def get_object_info(self, handle):
297
296
except OSError :
298
297
return None
299
298
300
- def desc_cfg (self , desc ):
299
+ def desc_cfg (self , desc , itf_num , ep_num , strs ):
301
300
"""Build configuration descriptor.
302
301
303
302
Args:
304
303
desc: Descriptor builder object
304
+ itf_num: Interface number to use
305
+ ep_num: First endpoint number to use
306
+ strs: String descriptor array
305
307
"""
306
- # Calculate total descriptor length
307
- len_itf = 9 # Interface descriptor
308
- len_eps = 7 * 3 # 3 endpoint descriptors
309
- len_itf_assoc = 8 # Interface Association Descriptor
310
- len_func = 5 # Functional descriptor (minimal)
311
-
312
- total_len = len_itf + len_eps + len_itf_assoc + len_func
313
-
314
- # Reserve space
315
- itf_idx = desc .reserve (total_len )
316
- self ._itf_num = itf_idx
317
-
318
- # Build descriptor
319
- # Interface Association Descriptor
320
- desc .interface_assoc (
321
- itf_idx , 1 , MTP_CLASS , MTP_SUBCLASS , MTP_PROTOCOL , "MTP"
322
- )
308
+ # Store interface number
309
+ self ._itf_num = itf_num
310
+
311
+ # Interface Association Descriptor for MTP
312
+ desc .interface_assoc (itf_num , 1 , MTP_CLASS , MTP_SUBCLASS , MTP_PROTOCOL )
323
313
324
314
# Interface descriptor
325
- desc .interface (
326
- itf_idx , 0 , 3 , MTP_CLASS , MTP_SUBCLASS , MTP_PROTOCOL , "MTP"
315
+ desc .interface (itf_num , 3 , MTP_CLASS , MTP_SUBCLASS , MTP_PROTOCOL )
316
+
317
+ # Class-specific functional descriptor
318
+ desc .pack (
319
+ "<BBBBB" ,
320
+ 5 , # bFunctionLength
321
+ 0x24 , # bDescriptorType - CS_INTERFACE
322
+ 0x00 , # bDescriptorSubtype
323
+ 0x01 , # bcdMTPVersion - 1.0 LSB
324
+ 0x00 , # bcdMTPVersion - 1.0 MSB
327
325
)
328
326
329
- # Minimal functional descriptor
330
- desc .add (b"\x05 \x24 \x00 \x01 \x00 " ) # Minimal class-specific descriptor
331
-
332
327
# Endpoint descriptors
333
328
# Bulk OUT endpoint
334
- self ._bulk_out_ep = usb . device . get (). alloc_ep ( 1 , usb . device . EP_TYPE_BULK , MTP_BULK_EP_SIZE )
335
- desc .endpoint (self ._bulk_out_ep , usb . device . EP_TYPE_BULK , MTP_BULK_EP_SIZE )
329
+ self ._bulk_out_ep = ep_num
330
+ desc .endpoint (self ._bulk_out_ep , "bulk" , MTP_BULK_EP_SIZE , 0 )
336
331
337
332
# Bulk IN endpoint
338
- self ._bulk_in_ep = usb . device . get (). alloc_ep ( 1 , usb . device . EP_TYPE_BULK , MTP_BULK_EP_SIZE )
339
- desc .endpoint (self ._bulk_in_ep | 0x80 , usb . device . EP_TYPE_BULK , MTP_BULK_EP_SIZE )
333
+ self ._bulk_in_ep = ( ep_num + 1 ) | 0x80
334
+ desc .endpoint (self ._bulk_in_ep , "bulk" , MTP_BULK_EP_SIZE , 0 )
340
335
341
336
# Interrupt IN endpoint for events
342
- self ._intr_ep = usb . device . get (). alloc_ep ( 1 , usb . device . EP_TYPE_INTERRUPT , MTP_INTERRUPT_EP_SIZE )
343
- desc .endpoint (self ._intr_ep | 0x80 , usb . device . EP_TYPE_INTERRUPT , MTP_INTERRUPT_EP_SIZE , 10 ) # 10ms interval
337
+ self ._intr_ep = ( ep_num + 2 ) | 0x80
338
+ desc .endpoint (self ._intr_ep , "interrupt" , MTP_INTERRUPT_EP_SIZE , 10 ) # 10ms interval
344
339
345
- def control_req (self , req , * args , ** kwargs ):
346
- """Handle class-specific control requests .
340
+ def on_interface_control_xfer (self , stage , request ):
341
+ """Handle class-specific interface control transfers .
347
342
348
343
Args:
349
- req: USB_SETUP_DESCRIPTOR setup packet
344
+ stage: Stage of the control transfer
345
+ request: The setup packet
350
346
351
347
Returns:
352
348
True if request was handled, False otherwise
@@ -380,27 +376,26 @@ def on_open(self):
380
376
381
377
def is_open (self ):
382
378
"""Check if the device is configured and open."""
383
- return usb . device . get ().configured () and not self . _session_open
379
+ return super ().is_open ()
384
380
385
381
def _submit_out_transfer (self ):
386
382
"""Submit an OUT transfer to receive data."""
387
- if not usb . device . get ().configured ():
383
+ if not super ().is_open ():
388
384
return
389
- usb .device .get ().submit_xfer (
390
- self ._bulk_out_ep , self ._rx_packet , self ._on_data_received
391
- )
385
+
386
+ self .submit_xfer (self ._bulk_out_ep , self ._rx_packet , self ._on_data_received )
392
387
393
- def _on_data_received (self , ep , data , status ):
388
+ def _on_data_received (self , ep , res , num_bytes ):
394
389
"""Handle received data from the USB host.
395
390
396
391
Args:
397
392
ep: Endpoint number
398
- data: Received data
399
- status: Transfer status
393
+ res: Result code (0 for success)
394
+ num_bytes: Number of bytes received
400
395
"""
401
- if status == usb . device . XFER_COMPLETED and len ( data ) > 0 :
396
+ if res == 0 and num_bytes > 0 :
402
397
# Process the received data
403
- self ._process_container (data )
398
+ self ._process_container (self . _rx_packet [: num_bytes ] )
404
399
405
400
# Submit a new transfer
406
401
self ._submit_out_transfer ()
@@ -411,7 +406,7 @@ def _send_data(self, data):
411
406
Args:
412
407
data: Data to send
413
408
"""
414
- if not usb . device . get ().configured ():
409
+ if not super ().is_open ():
415
410
return
416
411
417
412
# Copy data to the transmit buffer
@@ -420,17 +415,15 @@ def _send_data(self, data):
420
415
tx_view [:length ] = data [:length ]
421
416
422
417
# Submit the transfer
423
- usb .device .get ().submit_xfer (
424
- self ._bulk_in_ep | 0x80 , tx_view [:length ], self ._on_data_sent
425
- )
418
+ self .submit_xfer (self ._bulk_in_ep , tx_view [:length ], self ._on_data_sent )
426
419
427
- def _on_data_sent (self , ep , data , status ):
420
+ def _on_data_sent (self , ep , res , num_bytes ):
428
421
"""Handle completion of data transmission.
429
422
430
423
Args:
431
424
ep: Endpoint number
432
- data: Sent data
433
- status: Transfer status
425
+ res: Result code (0 for success)
426
+ num_bytes: Number of bytes sent
434
427
"""
435
428
pass # Could be used for flow control
436
429
0 commit comments