@@ -38,7 +38,7 @@ public class WindowsUSBDevice extends USBDeviceImpl {
3838 private List <InterfaceHandle > interfaceHandles_ ;
3939 private boolean isOpen_ ;
4040
41- WindowsUSBDevice (WindowsUSBDeviceRegistry registry , String devicePath , Map <Integer , String > children ,
41+ WindowsUSBDevice (String devicePath , Map <Integer , String > children ,
4242 int vendorId , int productId , MemorySegment configDesc ) {
4343 super (devicePath , vendorId , productId );
4444 asyncTask = WindowsAsyncTask .instance ();
@@ -199,60 +199,42 @@ public synchronized void releaseInterface(int interfaceNumber) {
199199 setClaimed (interfaceNumber , false );
200200 }
201201
202- private MemorySegment createSetupPacket (USBDirection direction , USBControlTransfer setup , MemorySegment data ,
203- Arena arena ) {
204- var setupPacket = new SetupPacket (arena );
205- var bmRequest =
206- (direction == USBDirection .IN ? 0x80 : 0 ) | (setup .requestType ().ordinal () << 5 ) | setup .recipient ().ordinal ();
207- setupPacket .setRequestType (bmRequest );
208- setupPacket .setRequest (setup .request ());
209- setupPacket .setValue (setup .value ());
210- setupPacket .setIndex (setup .index ());
211- setupPacket .setLength (data != null ? (int ) data .byteSize () : 0 );
212- return setupPacket .segment ();
213- }
214-
215202 @ Override
216- public byte [] controlTransferIn (USBControlTransfer setup , int length ) {
217- checkIsOpen ();
218- var intfHandle = findControlTransferInterface (setup );
219-
203+ public void controlTransferOut (USBControlTransfer setup , byte [] data ) {
220204 try (var arena = Arena .openConfined ()) {
221- var buffer = arena .allocate (length );
222- var setupPacket = createSetupPacket (USBDirection .IN , setup , buffer , arena );
223- var lengthHolder = arena .allocate (JAVA_INT );
224- var lastErrorState = arena .allocate (Win .LAST_ERROR_STATE .layout ());
225205
226- if (WinUSB2 .WinUsb_ControlTransfer (intfHandle .interfaceHandle , setupPacket , buffer ,
227- (int ) buffer .byteSize (), lengthHolder , NULL , lastErrorState ) == 0 )
228- throwLastError (lastErrorState , "Control transfer IN failed" );
206+ // copy data to native memory
207+ var transfer = createSyncControlTransfer ();
208+ int dataLength = data != null ? data .length : 0 ;
209+ transfer .dataSize = dataLength ;
210+ if (dataLength != 0 ) {
211+ var buffer = arena .allocate (data .length );
212+ buffer .copyFrom (MemorySegment .ofArray (data ));
213+ transfer .data = buffer ;
214+ } else {
215+ transfer .data = NULL ;
216+ }
229217
230- int rxLength = lengthHolder .get (JAVA_INT , 0 );
231- return buffer .asSlice (0 , rxLength ).toArray (JAVA_BYTE );
218+ synchronized (transfer ) {
219+ submitControlTransfer (USBDirection .OUT , setup , transfer );
220+ waitForTransfer (transfer , 0 , USBDirection .OUT , 0 );
221+ }
232222 }
233223 }
234224
235225 @ Override
236- public void controlTransferOut (USBControlTransfer setup , byte [] data ) {
237- checkIsOpen ();
238- var intfHandle = findControlTransferInterface (setup );
239-
226+ public byte [] controlTransferIn (USBControlTransfer setup , int length ) {
240227 try (var arena = Arena .openConfined ()) {
228+ var transfer = createSyncControlTransfer ();
229+ transfer .data = arena .allocate (length );
230+ transfer .dataSize = length ;
241231
242- // copy data to native memory
243- int dataLength = data != null ? data .length : 0 ;
244- MemorySegment buffer = arena .allocate (dataLength );
245- if (dataLength != 0 )
246- buffer .copyFrom (MemorySegment .ofArray (data ));
247-
248- // create setup packet
249- var setupPacket = createSetupPacket (USBDirection .OUT , setup , buffer , arena );
250- var lengthHolder = arena .allocate (JAVA_INT );
251- var lastErrorState = arena .allocate (Win .LAST_ERROR_STATE .layout ());
232+ synchronized (transfer ) {
233+ submitControlTransfer (USBDirection .IN , setup , transfer );
234+ waitForTransfer (transfer , 0 , USBDirection .IN , 0 );
235+ }
252236
253- if (WinUSB2 .WinUsb_ControlTransfer (intfHandle .interfaceHandle , setupPacket , buffer ,
254- (int ) buffer .byteSize (), lengthHolder , NULL , lastErrorState ) == 0 )
255- throwLastError (lastErrorState , "Control transfer OUT failed" );
237+ return transfer .data .asSlice (0 , transfer .resultSize ).toArray (JAVA_BYTE );
256238 }
257239 }
258240
@@ -287,6 +269,12 @@ public byte[] transferIn(int endpointNumber, int timeout) {
287269 }
288270 }
289271
272+ private WindowsTransfer createSyncControlTransfer () {
273+ var transfer = new WindowsTransfer ();
274+ transfer .completion = USBDeviceImpl ::onSyncTransferCompleted ;
275+ return transfer ;
276+ }
277+
290278 private WindowsTransfer createSyncTransfer (MemorySegment data ) {
291279 var transfer = new WindowsTransfer ();
292280 transfer .data = data ;
@@ -305,6 +293,33 @@ protected void throwOSException(int errorCode, String message, Object... args) {
305293 throwException (errorCode , message , args );
306294 }
307295
296+ synchronized void submitControlTransfer (USBDirection direction , USBControlTransfer setup , WindowsTransfer transfer ) {
297+ checkIsOpen ();
298+ var intfHandle = findControlTransferInterface (setup );
299+
300+ try (var arena = Arena .openConfined ()) {
301+ var setupPacket = new SetupPacket (arena );
302+ var bmRequest =
303+ (direction == USBDirection .IN ? 0x80 : 0 ) | (setup .requestType ().ordinal () << 5 ) | setup .recipient ().ordinal ();
304+ setupPacket .setRequestType (bmRequest );
305+ setupPacket .setRequest (setup .request ());
306+ setupPacket .setValue (setup .value ());
307+ setupPacket .setIndex (setup .index ());
308+ setupPacket .setLength (transfer .dataSize );
309+
310+ var lastErrorState = arena .allocate (Win .LAST_ERROR_STATE .layout ());
311+ asyncTask .prepareForSubmission (transfer );
312+
313+ // submit transfer
314+ if (WinUSB2 .WinUsb_ControlTransfer (intfHandle .interfaceHandle , setupPacket .segment (), transfer .data ,
315+ transfer .dataSize , NULL , transfer .overlapped , lastErrorState ) == 0 ) {
316+ int err = Win .getLastError (lastErrorState );
317+ if (err != Kernel32 .ERROR_IO_PENDING ())
318+ throwException (err , "Submitting control transfer failed" );
319+ }
320+ }
321+ }
322+
308323 synchronized void submitTransferOut (int endpointNumber , WindowsTransfer transfer ) {
309324 var endpoint = getEndpoint (USBDirection .OUT , endpointNumber , USBTransferType .BULK , USBTransferType .INTERRUPT );
310325 var intfHandle = getInterfaceHandle (endpoint .interfaceNumber ());
0 commit comments