@@ -55,6 +55,7 @@ def get_interface(dev, interface, alternate=0):
55
55
VENDOR_TEST_CTRL_OUT_STATUS_DELAY = 8
56
56
VENDOR_TEST_CTRL_IN_SIZES = 9
57
57
VENDOR_TEST_CTRL_OUT_SIZES = 10
58
+ VENDOR_TEST_READ_START = 11
58
59
VENDOR_TEST_UNSUPPORTED_REQUEST = 32
59
60
60
61
REQUEST_GET_STATUS = 0
@@ -982,38 +983,63 @@ def halt_ep_test(dev, ep_out, ep_in, ep_to_halt, log):
982
983
"""
983
984
MIN_HALT_DELAY = 0.01
984
985
MAX_HALT_DELAY = 0.1
985
- delay = random .uniform (MIN_HALT_DELAY , MAX_HALT_DELAY )
986
- ctrl_kwargs = {
987
- 'bmRequestType' : build_request_type (CTRL_OUT , CTRL_TYPE_STANDARD , CTRL_RECIPIENT_ENDPOINT ),
988
- 'bRequest' : REQUEST_SET_FEATURE ,
989
- 'wValue' : FEATURE_ENDPOINT_HALT ,
990
- 'wIndex' : ep_to_halt .bEndpointAddress }
986
+ POST_HALT_DELAY = 0.1
991
987
ctrl_error = Event ()
992
988
989
+ for ep in (ep_out , ep_in ):
990
+ try :
991
+ if (usb .control .get_status (dev , ep ) == 1 ):
992
+ raise_unconditionally (lineno (), 'Endpoints must NOT be halted at the start of this test' )
993
+ except usb .core .USBError as err :
994
+ raise_unconditionally (lineno (), 'Unable to get endpoint status ({!r}).' .format (err ))
995
+
993
996
def timer_handler ():
994
997
"""Halt an endpoint using a USB control request."""
995
998
try :
996
- dev .ctrl_transfer (** ctrl_kwargs )
999
+ usb .control .set_feature (dev , FEATURE_ENDPOINT_HALT , ep_to_halt )
1000
+ if (usb .control .get_status (dev , ep_to_halt ) != 1 ):
1001
+ raise RuntimeError ('Invalid endpoint status after halt operation' )
997
1002
except Exception as err :
998
- log ('Endpoint {:#04x} halt failed ({}).' .format (ctrl_kwargs ['wIndex' ], err ))
999
1003
ctrl_error .set ()
1004
+ log ('Endpoint {:#04x} halt failed ({}).' .format (ep_to_halt .bEndpointAddress , err ))
1005
+ # Whether the halt operation was successful or not,
1006
+ # wait a bit so the main thread has a chance to run into a USBError
1007
+ # or report the failure of halt operation.
1008
+ time .sleep (POST_HALT_DELAY )
1000
1009
1010
+ delay = random .uniform (MIN_HALT_DELAY , MAX_HALT_DELAY )
1001
1011
delayed_halt = Timer (delay , timer_handler )
1002
1012
delayed_halt .start ()
1003
- end_ts = time .time () + 1.5 * delay
1004
- try :
1005
- while time .time () < end_ts and not ctrl_error .is_set ():
1006
- loopback_ep_test (ep_out , ep_in , ep_out .wMaxPacketSize )
1007
- except usb .core .USBError as err :
1008
- if err .errno not in (32 , 110 ):
1009
- raise_unconditionally (lineno (), 'Unexpected error ({!r}).' .format (err ))
1013
+ # Keep transferring data to and from the device until one of the endpoints
1014
+ # is halted.
1015
+ while delayed_halt .is_alive ():
1010
1016
if ctrl_error .is_set ():
1011
1017
raise_unconditionally (lineno (), 'Halting endpoint {0.bEndpointAddress:#04x} failed'
1012
1018
.format (ep_to_halt ))
1013
- else :
1014
- raise_unconditionally (lineno (), 'Halting endpoint {0.bEndpointAddress:#04x}'
1015
- ' during transmission did not raise USBError.'
1016
- .format (ep_to_halt ))
1019
+ try :
1020
+ loopback_ep_test (ep_out , ep_in , ep_out .wMaxPacketSize )
1021
+ except usb .core .USBError as err :
1022
+ try :
1023
+ ep_status = usb .control .get_status (dev , ep_to_halt )
1024
+ except usb .core .USBError as err :
1025
+ raise_unconditionally (lineno (), 'Unable to get endpoint status ({!r}).' .format (err ))
1026
+ if ep_status == 1 :
1027
+ # OK, got USBError because of endpoint halt
1028
+ return
1029
+ else :
1030
+ raise_unconditionally (lineno (), 'Unexpected error ({!r}).' .format (err ))
1031
+ raise_unconditionally (lineno (), 'Halting endpoint {0.bEndpointAddress:#04x}'
1032
+ ' during transmission did not raise USBError.'
1033
+ .format (ep_to_halt ))
1034
+
1035
+
1036
+ def request_endpoint_read_start (dev , ep ):
1037
+ ctrl_kwargs = {
1038
+ 'bmRequestType' : build_request_type (CTRL_OUT , CTRL_TYPE_VENDOR , CTRL_RECIPIENT_ENDPOINT ),
1039
+ 'bRequest' : VENDOR_TEST_READ_START ,
1040
+ 'wValue' : 0 ,
1041
+ 'wIndex' : ep .bEndpointAddress }
1042
+ dev .ctrl_transfer (** ctrl_kwargs )
1017
1043
1018
1044
1019
1045
USB_ERROR_FMT = str ('Got {0!r} while testing endpoints '
@@ -1054,7 +1080,7 @@ def ep_test_data_correctness(dev, log, verbose=False):
1054
1080
1055
1081
if verbose :
1056
1082
log ('Testing OUT/IN data correctness for bulk endpoint pair.' )
1057
- for payload_size in range (1 , bulk_out .wMaxPacketSize + 1 ):
1083
+ for payload_size in range (bulk_out .wMaxPacketSize + 1 ):
1058
1084
try :
1059
1085
loopback_ep_test (bulk_out , bulk_in , payload_size )
1060
1086
except usb .USBError as err :
@@ -1113,21 +1139,19 @@ def ep_test_halt(dev, log, verbose=False):
1113
1139
while time .time () < end_ts :
1114
1140
halt_ep_test (dev , bulk_out , bulk_in , bulk_out , log )
1115
1141
bulk_out .clear_halt ()
1116
- intf . set_altsetting () # Force the device to start reading data from all OUT endpoints again.
1142
+ request_endpoint_read_start ( dev , bulk_out )
1117
1143
halt_ep_test (dev , bulk_out , bulk_in , bulk_in , log )
1118
1144
bulk_in .clear_halt ()
1119
- intf .set_altsetting () # Force the device to start reading data from all OUT endpoints again.
1120
1145
1121
1146
if verbose :
1122
1147
log ('Testing endpoint halt at a random point of interrupt transmission.' )
1123
1148
end_ts = time .time () + 1.0
1124
1149
while time .time () < end_ts :
1125
1150
halt_ep_test (dev , interrupt_out , interrupt_in , interrupt_out , log )
1126
1151
interrupt_out .clear_halt ()
1127
- intf . set_altsetting () # Force the device to start reading data from all OUT endpoints again.
1152
+ request_endpoint_read_start ( dev , interrupt_out )
1128
1153
halt_ep_test (dev , interrupt_out , interrupt_in , interrupt_in , log )
1129
- interrupt_out .clear_halt ()
1130
- intf .set_altsetting () # Force the device to start reading data from all OUT endpoints again.
1154
+ interrupt_in .clear_halt ()
1131
1155
1132
1156
1133
1157
def ep_test_parallel_transfers (dev , log , verbose = False ):
@@ -1285,7 +1309,13 @@ def ep_test_abort(dev, log, verbose=False):
1285
1309
log ('Testing aborting an in progress transfer for IN endpoints.' )
1286
1310
for ep_in in (bulk_in , interrupt_in ):
1287
1311
payload_size = (NUM_PACKETS_UNTIL_ABORT + NUM_PACKETS_AFTER_ABORT ) * ep_in .wMaxPacketSize
1288
- payload_in = ep_in .read (payload_size )
1312
+ payload_in = array .array ('B' )
1313
+ while len (payload_in ) < payload_size :
1314
+ try :
1315
+ packet = ep_in .read (ep_in .wMaxPacketSize )
1316
+ payload_in .extend (packet )
1317
+ except usb .core .USBError as err :
1318
+ break
1289
1319
if verbose :
1290
1320
log ('The size of data successfully received from endpoint {0.bEndpointAddress:#04x}: {1} B.'
1291
1321
.format (ep_in , len (payload_in )))
@@ -1303,8 +1333,13 @@ def ep_test_abort(dev, log, verbose=False):
1303
1333
log ('Testing aborting an in progress transfer for OUT endpoints.' )
1304
1334
for ep_out in (bulk_out , interrupt_out ):
1305
1335
payload_size = (NUM_PACKETS_UNTIL_ABORT + NUM_PACKETS_AFTER_ABORT ) * ep_out .wMaxPacketSize
1306
- payload_out = array .array ('B' , (0x01 for _ in range (payload_size )))
1307
- num_bytes_written = ep_out .write (payload_out )
1336
+ payload_out = array .array ('B' , (0x01 for _ in range (ep_out .wMaxPacketSize )))
1337
+ num_bytes_written = 0
1338
+ while num_bytes_written < payload_size :
1339
+ try :
1340
+ num_bytes_written += ep_out .write (payload_out )
1341
+ except usb .core .USBError :
1342
+ break
1308
1343
if verbose :
1309
1344
log ('The size of data successfully sent to endpoint {0.bEndpointAddress:#04x}: {1} B.'
1310
1345
.format (ep_out , num_bytes_written ))
0 commit comments