Skip to content

Commit

Permalink
skip RNDIS related data interfaces in composite CDC devices (#469)
Browse files Browse the repository at this point in the history
  • Loading branch information
kai-morich committed Mar 11, 2023
1 parent 6c648e9 commit 85f64af
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ private void openSingleInterface() throws IOException {
private void openInterface() throws IOException {
Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());

int rndisControlInterfaceCount = 0;
int controlInterfaceCount = 0;
int dataInterfaceCount = 0;
mControlInterface = null;
Expand All @@ -146,11 +147,22 @@ private void openInterface() throws IOException {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,53 @@ public void compositeDevice() throws Exception {
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);
Expand Down

0 comments on commit 85f64af

Please sign in to comment.