skip RNDIS related data interfaces in composite CDC devices (#469)

pull/521/head
kai-morich 2023-03-11 15:21:59 +01:00
rodzic 6c648e9f56
commit 85f64aff96
2 zmienionych plików z 60 dodań i 1 usunięć

Wyświetl plik

@ -132,6 +132,7 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
private void openInterface() throws IOException {
Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
int rndisControlInterfaceCount = 0;
int controlInterfaceCount = 0;
int dataInterfaceCount = 0;
mControlInterface = null;
@ -146,11 +147,22 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
controlInterfaceCount++;
}
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
if(dataInterfaceCount == mPortNumber) {
if(dataInterfaceCount == mPortNumber + rndisControlInterfaceCount) {
mDataInterface = usbInterface;
}
dataInterfaceCount++;
}
if (mDataInterface == null &&
usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_WIRELESS_CONTROLLER &&
usbInterface.getInterfaceSubclass() == 1 &&
usbInterface.getInterfaceProtocol() == 3) {
/*
* RNDIS is a MSFT variant of CDC-ACM states the Linux kernel in rndis_host.c
* The devices provide IAD descriptors to indicate consecutive interfaces belonging
* together, but this is not exposed to Java. So simply skip related data interfaces.
*/
rndisControlInterfaceCount++;
}
}
if(mControlInterface == null) {

Wyświetl plik

@ -179,6 +179,53 @@ public class CdcAcmSerialDriverTest {
assertEquals(writeEndpoint, port.mWriteEndpoint);
}
@Test
public void compositeRndisDevice() throws Exception {
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
UsbDevice usbDevice = mock(UsbDevice.class);
UsbInterface rndisControlInterface = mock(UsbInterface.class);
UsbInterface rndisDataInterface = mock(UsbInterface.class);
UsbInterface controlInterface = mock(UsbInterface.class);
UsbInterface dataInterface = mock(UsbInterface.class);
UsbEndpoint controlEndpoint = mock(UsbEndpoint.class);
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
when(usbDevice.getInterfaceCount()).thenReturn(4);
when(usbDevice.getInterface(0)).thenReturn(rndisControlInterface);
when(usbDevice.getInterface(1)).thenReturn(rndisDataInterface);
when(usbDevice.getInterface(2)).thenReturn(controlInterface);
when(usbDevice.getInterface(3)).thenReturn(dataInterface);
when(rndisControlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER);
when(rndisControlInterface.getInterfaceSubclass()).thenReturn(1);
when(rndisControlInterface.getInterfaceProtocol()).thenReturn(3);
when(rndisDataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
when(controlInterface.getEndpointCount()).thenReturn(1);
when(controlInterface.getEndpoint(0)).thenReturn(controlEndpoint);
when(dataInterface.getEndpointCount()).thenReturn(2);
when(dataInterface.getEndpoint(0)).thenReturn(writeEndpoint);
when(dataInterface.getEndpoint(1)).thenReturn(readEndpoint);
when(controlEndpoint.getDirection()).thenReturn(UsbConstants.USB_DIR_IN);
when(controlEndpoint.getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_INT);
when(readEndpoint.getDirection()).thenReturn(UsbConstants.USB_DIR_IN);
when(readEndpoint.getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_BULK);
when(writeEndpoint.getDirection()).thenReturn(UsbConstants.USB_DIR_OUT);
when(writeEndpoint.getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_BULK);
CdcAcmSerialDriver driver = new CdcAcmSerialDriver(usbDevice);
CdcAcmSerialDriver.CdcAcmSerialPort port = (CdcAcmSerialDriver.CdcAcmSerialPort) driver.getPorts().get(0);
port.mConnection = usbDeviceConnection;
port.openInt();
assertEquals(readEndpoint, port.mReadEndpoint);
assertEquals(writeEndpoint, port.mWriteEndpoint);
}
@Test
public void invalidStandardDevice() throws Exception {
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);