Skip to content

Commit d5e9d8d

Browse files
committed
Avoid O(n) endpoint lookup for each URB submission
1 parent 6b93648 commit d5e9d8d

File tree

3 files changed

+19
-31
lines changed

3 files changed

+19
-31
lines changed

app/src/main/java/org/cgutman/usbip/service/AttachedDeviceContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import android.hardware.usb.UsbConfiguration;
44
import android.hardware.usb.UsbDevice;
55
import android.hardware.usb.UsbDeviceConnection;
6+
import android.hardware.usb.UsbEndpoint;
7+
import android.util.SparseArray;
68

79
import org.cgutman.usbip.server.protocol.dev.UsbIpSubmitUrb;
810

@@ -13,6 +15,7 @@ public class AttachedDeviceContext {
1315
public UsbDevice device;
1416
public UsbDeviceConnection devConn;
1517
public UsbConfiguration activeConfiguration;
18+
public SparseArray<UsbEndpoint> activeConfigurationEndpointsByNumDir;
1619
public ThreadPoolExecutor requestPool;
1720
public HashSet<UsbIpSubmitUrb> activeMessages;
1821
}

app/src/main/java/org/cgutman/usbip/service/UsbIpService.java

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -623,37 +623,9 @@ public void submitUrbRequest(Socket s, UsbIpSubmitUrb msg) {
623623
else {
624624
// Find the correct endpoint
625625
UsbEndpoint selectedEndpoint = null;
626-
if (context.activeConfiguration != null) {
627-
for (int i = 0; i < context.activeConfiguration.getInterfaceCount(); i++) {
628-
// Check each interface
629-
UsbInterface iface = context.activeConfiguration.getInterface(i);
630-
for (int j = 0; j < iface.getEndpointCount(); j++) {
631-
// Check the endpoint number
632-
UsbEndpoint endpoint = iface.getEndpoint(j);
633-
if (msg.ep == endpoint.getEndpointNumber()) {
634-
// Check the direction
635-
if (msg.direction == UsbIpDevicePacket.USBIP_DIR_IN) {
636-
if (endpoint.getDirection() != UsbConstants.USB_DIR_IN) {
637-
continue;
638-
}
639-
}
640-
else {
641-
if (endpoint.getDirection() != UsbConstants.USB_DIR_OUT) {
642-
continue;
643-
}
644-
}
645-
646-
// This the right endpoint
647-
selectedEndpoint = endpoint;
648-
break;
649-
}
650-
}
651-
652-
// Check if we found the endpoint on the last interface
653-
if (selectedEndpoint != null) {
654-
break;
655-
}
656-
}
626+
if (context.activeConfigurationEndpointsByNumDir != null) {
627+
int endptNumDir = msg.ep + (msg.direction == UsbIpDevicePacket.USBIP_DIR_IN ? UsbConstants.USB_DIR_IN : 0);
628+
selectedEndpoint = context.activeConfigurationEndpointsByNumDir.get(endptNumDir);
657629
}
658630
else {
659631
System.err.println("Attempted to transfer to non-control EP before SET_CONFIGURATION!");

app/src/main/java/org/cgutman/usbip/usb/UsbControlHelper.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.hardware.usb.UsbEndpoint;
77
import android.hardware.usb.UsbInterface;
88
import android.os.Build;
9+
import android.util.SparseArray;
910

1011
import org.cgutman.usbip.service.AttachedDeviceContext;
1112

@@ -106,6 +107,18 @@ public static boolean handleInternalControlTransfer(AttachedDeviceContext device
106107
// This is now the active configuration
107108
deviceContext.activeConfiguration = config;
108109

110+
// Construct the cache of endpoint mappings
111+
deviceContext.activeConfigurationEndpointsByNumDir = new SparseArray<>();
112+
for (int j = 0; j < deviceContext.activeConfiguration.getInterfaceCount(); j++) {
113+
UsbInterface iface = deviceContext.activeConfiguration.getInterface(j);
114+
for (int k = 0; k < iface.getEndpointCount(); k++) {
115+
UsbEndpoint endp = iface.getEndpoint(k);
116+
deviceContext.activeConfigurationEndpointsByNumDir.put(
117+
endp.getDirection() | endp.getEndpointNumber(),
118+
endp);
119+
}
120+
}
121+
109122
System.out.println("Claiming all interfaces from new configuration: "+deviceContext.activeConfiguration.getId());
110123
for (int j = 0; j < deviceContext.activeConfiguration.getInterfaceCount(); j++) {
111124
UsbInterface iface = deviceContext.activeConfiguration.getInterface(j);

0 commit comments

Comments
 (0)