kopia lustrzana https://github.com/mik3y/usb-serial-for-android
composite CDC devices: get correct ACM data interface from IAD (#499)
rodzic
7aecce7943
commit
54ff9bfa44
|
@ -1,4 +1,3 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="NullableNotNullManager">
|
<component name="NullableNotNullManager">
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
# `tinyusb_dev_cdc_dual_ports.uf2`
|
||||||
|
|
||||||
|
compiled from `C:/Program Files/Raspberry Pi/Pico SDK v1.5.1/pico-sdk/lib/tinyusb/examples/device/cdc_dual_ports`
|
||||||
|
to `C:/Users/` _user_`/Documents/Pico-v1.5.1/pico-examples/build/usb/device/tinyusb_device_examples/cdc_dual_ports/tinyusb_dev_cdc_dual_ports.uf2`
|
||||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -12,6 +12,9 @@ import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.hoho.android.usbserial.util.HexDump;
|
||||||
|
import com.hoho.android.usbserial.util.UsbUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
@ -107,6 +110,10 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void openInt() throws IOException {
|
protected void openInt() throws IOException {
|
||||||
|
Log.d(TAG, "interfaces:");
|
||||||
|
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||||
|
Log.d(TAG, mDevice.getInterface(i).toString());
|
||||||
|
}
|
||||||
if (mPortNumber == -1) {
|
if (mPortNumber == -1) {
|
||||||
Log.d(TAG,"device might be castrated ACM device, trying single interface logic");
|
Log.d(TAG,"device might be castrated ACM device, trying single interface logic");
|
||||||
openSingleInterface();
|
openSingleInterface();
|
||||||
|
@ -142,13 +149,30 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openInterface() 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;
|
mControlInterface = null;
|
||||||
mDataInterface = null;
|
mDataInterface = null;
|
||||||
|
int j = getInterfaceIdFromDescriptors();
|
||||||
|
Log.d(TAG, "interface count=" + mDevice.getInterfaceCount() + ", IAD=" + j);
|
||||||
|
if (j >= 0) {
|
||||||
|
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||||
|
UsbInterface usbInterface = mDevice.getInterface(i);
|
||||||
|
if (usbInterface.getId() == j || usbInterface.getId() == j+1) {
|
||||||
|
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM &&
|
||||||
|
usbInterface.getInterfaceSubclass() == USB_SUBCLASS_ACM) {
|
||||||
|
mControlIndex = usbInterface.getId();
|
||||||
|
mControlInterface = usbInterface;
|
||||||
|
}
|
||||||
|
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
|
||||||
|
mDataInterface = usbInterface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mControlInterface == null || mDataInterface == null) {
|
||||||
|
Log.d(TAG, "no IAD fallback");
|
||||||
|
int controlInterfaceCount = 0;
|
||||||
|
int dataInterfaceCount = 0;
|
||||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||||
UsbInterface usbInterface = mDevice.getInterface(i);
|
UsbInterface usbInterface = mDevice.getInterface(i);
|
||||||
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM &&
|
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM &&
|
||||||
|
@ -160,33 +184,22 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
controlInterfaceCount++;
|
controlInterfaceCount++;
|
||||||
}
|
}
|
||||||
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
|
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
|
||||||
if(dataInterfaceCount == mPortNumber + rndisControlInterfaceCount) {
|
if (dataInterfaceCount == mPortNumber) {
|
||||||
mDataInterface = usbInterface;
|
mDataInterface = usbInterface;
|
||||||
}
|
}
|
||||||
dataInterfaceCount++;
|
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) {
|
if(mControlInterface == null) {
|
||||||
throw new IOException("No control interface");
|
throw new IOException("No control interface");
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Control iface=" + mControlInterface);
|
Log.d(TAG, "Control interface id " + mControlInterface.getId());
|
||||||
|
|
||||||
if (!mConnection.claimInterface(mControlInterface, true)) {
|
if (!mConnection.claimInterface(mControlInterface, true)) {
|
||||||
throw new IOException("Could not claim control interface");
|
throw new IOException("Could not claim control interface");
|
||||||
}
|
}
|
||||||
|
|
||||||
mControlEndpoint = mControlInterface.getEndpoint(0);
|
mControlEndpoint = mControlInterface.getEndpoint(0);
|
||||||
if (mControlEndpoint.getDirection() != UsbConstants.USB_DIR_IN || mControlEndpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
|
if (mControlEndpoint.getDirection() != UsbConstants.USB_DIR_IN || mControlEndpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
|
||||||
throw new IOException("Invalid control endpoint");
|
throw new IOException("Invalid control endpoint");
|
||||||
|
@ -195,12 +208,10 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
if(mDataInterface == null) {
|
if(mDataInterface == null) {
|
||||||
throw new IOException("No data interface");
|
throw new IOException("No data interface");
|
||||||
}
|
}
|
||||||
Log.d(TAG, "data iface=" + mDataInterface);
|
Log.d(TAG, "data interface id " + mDataInterface.getId());
|
||||||
|
|
||||||
if (!mConnection.claimInterface(mDataInterface, true)) {
|
if (!mConnection.claimInterface(mDataInterface, true)) {
|
||||||
throw new IOException("Could not claim data interface");
|
throw new IOException("Could not claim data interface");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mDataInterface.getEndpointCount(); i++) {
|
for (int i = 0; i < mDataInterface.getEndpointCount(); i++) {
|
||||||
UsbEndpoint ep = mDataInterface.getEndpoint(i);
|
UsbEndpoint ep = mDataInterface.getEndpoint(i);
|
||||||
if (ep.getDirection() == UsbConstants.USB_DIR_IN && ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
|
if (ep.getDirection() == UsbConstants.USB_DIR_IN && ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
|
||||||
|
@ -210,6 +221,36 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getInterfaceIdFromDescriptors() {
|
||||||
|
ArrayList<byte[]> descriptors = UsbUtils.getDescriptors(mConnection);
|
||||||
|
Log.d(TAG, "USB descriptor:");
|
||||||
|
for(byte[] descriptor : descriptors)
|
||||||
|
Log.d(TAG, HexDump.toHexString(descriptor));
|
||||||
|
|
||||||
|
if (descriptors.size() > 0 &&
|
||||||
|
descriptors.get(0).length == 18 &&
|
||||||
|
descriptors.get(0)[1] == 1 && // bDescriptorType
|
||||||
|
descriptors.get(0)[4] == (byte)(UsbConstants.USB_CLASS_MISC) && //bDeviceClass
|
||||||
|
descriptors.get(0)[5] == 2 && // bDeviceSubClass
|
||||||
|
descriptors.get(0)[6] == 1) { // bDeviceProtocol
|
||||||
|
// is IAD device, see https://www.usb.org/sites/default/files/iadclasscode_r10.pdf
|
||||||
|
int port = -1;
|
||||||
|
for (int d = 1; d < descriptors.size(); d++) {
|
||||||
|
if (descriptors.get(d).length == 8 &&
|
||||||
|
descriptors.get(d)[1] == 0x0b && // bDescriptorType == IAD
|
||||||
|
descriptors.get(d)[4] == UsbConstants.USB_CLASS_COMM && // bFunctionClass == CDC
|
||||||
|
descriptors.get(d)[5] == USB_SUBCLASS_ACM) { // bFunctionSubClass == ACM
|
||||||
|
port++;
|
||||||
|
if (port == mPortNumber &&
|
||||||
|
descriptors.get(d)[3] == 2) { // bInterfaceCount
|
||||||
|
return descriptors.get(d)[2]; // bFirstInterface
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
private int sendAcmControlMessage(int request, int value, byte[] buf) throws IOException {
|
private int sendAcmControlMessage(int request, int value, byte[] buf) throws IOException {
|
||||||
int len = mConnection.controlTransfer(
|
int len = mConnection.controlTransfer(
|
||||||
USB_RT_ACM, request, value, mControlIndex, buf, buf != null ? buf.length : 0, 5000);
|
USB_RT_ACM, request, value, mControlIndex, buf, buf != null ? buf.length : 0, 5000);
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.hoho.android.usbserial.util;
|
||||||
|
|
||||||
|
import android.hardware.usb.UsbDeviceConnection;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class UsbUtils {
|
||||||
|
|
||||||
|
public static ArrayList<byte[]> getDescriptors(UsbDeviceConnection connection) {
|
||||||
|
ArrayList<byte[]> descriptors = new ArrayList<>();
|
||||||
|
byte[] rawDescriptors = connection.getRawDescriptors();
|
||||||
|
if (rawDescriptors != null) {
|
||||||
|
int pos = 0;
|
||||||
|
while (pos < rawDescriptors.length) {
|
||||||
|
int len = rawDescriptors[pos] & 0xFF;
|
||||||
|
if (len == 0)
|
||||||
|
break;
|
||||||
|
if (pos + len > rawDescriptors.length)
|
||||||
|
len = rawDescriptors.length - pos;
|
||||||
|
byte[] descriptor = new byte[len];
|
||||||
|
System.arraycopy(rawDescriptors, pos, descriptor, 0, len);
|
||||||
|
descriptors.add(descriptor);
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,10 @@ import static com.hoho.android.usbserial.driver.CdcAcmSerialDriver.USB_SUBCLASS_
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertThrows;
|
import static org.junit.Assert.assertThrows;
|
||||||
|
import static org.mockito.Mockito.clearInvocations;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.hardware.usb.UsbConstants;
|
import android.hardware.usb.UsbConstants;
|
||||||
|
@ -13,6 +16,8 @@ import android.hardware.usb.UsbDeviceConnection;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
|
|
||||||
|
import com.hoho.android.usbserial.util.HexDump;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -29,15 +34,37 @@ public class CdcAcmSerialDriverTest {
|
||||||
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
|
||||||
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* digispark - no IAD
|
||||||
|
* UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=2,mSubclass=2,mProtocol=1,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=131,mAttributes=3,mMaxPacketSize=8,mInterval=255]]
|
||||||
|
* UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=1,mAttributes=2,mMaxPacketSize=8,mInterval=0]
|
||||||
|
* UsbEndpoint[mAddress=129,mAttributes=2,mMaxPacketSize=8,mInterval=0]]
|
||||||
|
*/
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray(
|
||||||
|
"12 01 10 01 02 00 00 08 D0 16 7E 08 00 01 01 02 00 01\n" +
|
||||||
|
"09 02 43 00 02 01 00 80 32\n" +
|
||||||
|
"09 04 00 00 01 02 02 01 00\n" +
|
||||||
|
"05 24 00 10 01\n" +
|
||||||
|
"04 24 02 02\n" +
|
||||||
|
"05 24 06 00 01\n" +
|
||||||
|
"05 24 01 03 01\n" +
|
||||||
|
"07 05 83 03 08 00 FF\n" +
|
||||||
|
"09 04 01 00 02 0A 00 00 00\n" +
|
||||||
|
"07 05 01 02 08 00 00\n" +
|
||||||
|
"07 05 81 02 08 00 00"));
|
||||||
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
|
||||||
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
|
||||||
when(usbDevice.getInterfaceCount()).thenReturn(2);
|
when(usbDevice.getInterfaceCount()).thenReturn(2);
|
||||||
when(usbDevice.getInterface(0)).thenReturn(controlInterface);
|
when(usbDevice.getInterface(0)).thenReturn(controlInterface);
|
||||||
when(usbDevice.getInterface(1)).thenReturn(dataInterface);
|
when(usbDevice.getInterface(1)).thenReturn(dataInterface);
|
||||||
|
when(controlInterface.getId()).thenReturn(0);
|
||||||
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
||||||
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
||||||
when(controlInterface.getEndpointCount()).thenReturn(1);
|
when(controlInterface.getEndpointCount()).thenReturn(1);
|
||||||
when(controlInterface.getEndpoint(0)).thenReturn(controlEndpoint);
|
when(controlInterface.getEndpoint(0)).thenReturn(controlEndpoint);
|
||||||
|
when(dataInterface.getId()).thenReturn(1);
|
||||||
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
when(dataInterface.getEndpointCount()).thenReturn(2);
|
when(dataInterface.getEndpointCount()).thenReturn(2);
|
||||||
when(dataInterface.getEndpoint(0)).thenReturn(writeEndpoint);
|
when(dataInterface.getEndpoint(0)).thenReturn(writeEndpoint);
|
||||||
|
@ -98,7 +125,7 @@ public class CdcAcmSerialDriverTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multiPortDevice() throws Exception {
|
public void multiPortDevice() throws Exception {
|
||||||
int n = 4;
|
int n = 2;
|
||||||
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
|
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
|
||||||
UsbDevice usbDevice = mock(UsbDevice.class);
|
UsbDevice usbDevice = mock(UsbDevice.class);
|
||||||
UsbInterface[] controlInterfaces = new UsbInterface[n];
|
UsbInterface[] controlInterfaces = new UsbInterface[n];
|
||||||
|
@ -107,6 +134,42 @@ public class CdcAcmSerialDriverTest {
|
||||||
UsbEndpoint[] readEndpoints = new UsbEndpoint[n];
|
UsbEndpoint[] readEndpoints = new UsbEndpoint[n];
|
||||||
UsbEndpoint[] writeEndpoints = new UsbEndpoint[n];
|
UsbEndpoint[] writeEndpoints = new UsbEndpoint[n];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pi zero - dual port
|
||||||
|
* UsbInterface[mId=0,mAlternateSetting=0,mName=TinyUSB CDC,mClass=2,mSubclass=2,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=129,mAttributes=3,mMaxPacketSize=8,mInterval=16]]
|
||||||
|
* UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=2,mAttributes=2,mMaxPacketSize=64,mInterval=0]
|
||||||
|
* UsbEndpoint[mAddress=130,mAttributes=2,mMaxPacketSize=64,mInterval=0]]
|
||||||
|
* UsbInterface[mId=2,mAlternateSetting=0,mName=TinyUSB CDC,mClass=2,mSubclass=2,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=131,mAttributes=3,mMaxPacketSize=8,mInterval=16]]
|
||||||
|
* UsbInterface[mId=3,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=4,mAttributes=2,mMaxPacketSize=64,mInterval=0]
|
||||||
|
* UsbEndpoint[mAddress=132,mAttributes=2,mMaxPacketSize=64,mInterval=0]]
|
||||||
|
*/
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray(
|
||||||
|
"12 01 00 02 EF 02 01 40 FE CA 02 40 00 01 01 02 03 01\n" +
|
||||||
|
"09 02 8D 00 04 01 00 80 32\n" +
|
||||||
|
"08 0B 00 02 02 02 00 00\n" +
|
||||||
|
"09 04 00 00 01 02 02 00 04\n" +
|
||||||
|
"05 24 00 20 01\n" +
|
||||||
|
"05 24 01 00 01\n" +
|
||||||
|
"04 24 02 02\n" +
|
||||||
|
"05 24 06 00 01\n" +
|
||||||
|
"07 05 81 03 08 00 10\n" +
|
||||||
|
"09 04 01 00 02 0A 00 00 00\n" +
|
||||||
|
"07 05 02 02 40 00 00\n" +
|
||||||
|
"07 05 82 02 40 00 00\n" +
|
||||||
|
"08 0B 02 02 02 02 00 00\n" +
|
||||||
|
"09 04 02 00 01 02 02 00 04\n" +
|
||||||
|
"05 24 00 20 01\n" +
|
||||||
|
"05 24 01 00 03\n" +
|
||||||
|
"04 24 02 02\n" +
|
||||||
|
"05 24 06 02 03\n" +
|
||||||
|
"07 05 83 03 08 00 10\n" +
|
||||||
|
"09 04 03 00 02 0A 00 00 00\n" +
|
||||||
|
"07 05 04 02 40 00 00\n" +
|
||||||
|
"07 05 84 02 40 00 00\n"));
|
||||||
when(usbDevice.getInterfaceCount()).thenReturn(2*n);
|
when(usbDevice.getInterfaceCount()).thenReturn(2*n);
|
||||||
for(int i=0; i<n; i++) {
|
for(int i=0; i<n; i++) {
|
||||||
controlInterfaces[i] = mock(UsbInterface.class);
|
controlInterfaces[i] = mock(UsbInterface.class);
|
||||||
|
@ -116,12 +179,14 @@ public class CdcAcmSerialDriverTest {
|
||||||
writeEndpoints[i] = mock(UsbEndpoint.class);
|
writeEndpoints[i] = mock(UsbEndpoint.class);
|
||||||
when(usbDeviceConnection.claimInterface(controlInterfaces[i], true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(controlInterfaces[i], true)).thenReturn(true);
|
||||||
when(usbDeviceConnection.claimInterface(dataInterfaces[i], true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(dataInterfaces[i], true)).thenReturn(true);
|
||||||
when(usbDevice.getInterface(2*i+0)).thenReturn(controlInterfaces[i]);
|
when(usbDevice.getInterface(2*i )).thenReturn(controlInterfaces[i]);
|
||||||
when(usbDevice.getInterface(2*i+1)).thenReturn(dataInterfaces[i]);
|
when(usbDevice.getInterface(2*i+1)).thenReturn(dataInterfaces[i]);
|
||||||
|
when(controlInterfaces[i].getId()).thenReturn(2*i);
|
||||||
when(controlInterfaces[i].getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
when(controlInterfaces[i].getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
||||||
when(controlInterfaces[i].getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
when(controlInterfaces[i].getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
||||||
when(controlInterfaces[i].getEndpointCount()).thenReturn(1);
|
when(controlInterfaces[i].getEndpointCount()).thenReturn(1);
|
||||||
when(controlInterfaces[i].getEndpoint(0)).thenReturn(controlEndpoints[i]);
|
when(controlInterfaces[i].getEndpoint(0)).thenReturn(controlEndpoints[i]);
|
||||||
|
when(dataInterfaces[i].getId()).thenReturn(2*i+1);
|
||||||
when(dataInterfaces[i].getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
when(dataInterfaces[i].getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
when(dataInterfaces[i].getEndpointCount()).thenReturn(2);
|
when(dataInterfaces[i].getEndpointCount()).thenReturn(2);
|
||||||
when(dataInterfaces[i].getEndpoint(0)).thenReturn(writeEndpoints[i]);
|
when(dataInterfaces[i].getEndpoint(0)).thenReturn(writeEndpoints[i]);
|
||||||
|
@ -133,18 +198,39 @@ public class CdcAcmSerialDriverTest {
|
||||||
when(writeEndpoints[i].getDirection()).thenReturn(UsbConstants.USB_DIR_OUT);
|
when(writeEndpoints[i].getDirection()).thenReturn(UsbConstants.USB_DIR_OUT);
|
||||||
when(writeEndpoints[i].getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_BULK);
|
when(writeEndpoints[i].getType()).thenReturn(UsbConstants.USB_ENDPOINT_XFER_BULK);
|
||||||
}
|
}
|
||||||
int i = 2;
|
int i = 1;
|
||||||
CdcAcmSerialDriver driver = new CdcAcmSerialDriver(usbDevice);
|
CdcAcmSerialDriver driver = new CdcAcmSerialDriver(usbDevice);
|
||||||
CdcAcmSerialDriver.CdcAcmSerialPort port = (CdcAcmSerialDriver.CdcAcmSerialPort) driver.getPorts().get(i);
|
CdcAcmSerialDriver.CdcAcmSerialPort port = (CdcAcmSerialDriver.CdcAcmSerialPort) driver.getPorts().get(i);
|
||||||
port.mConnection = usbDeviceConnection;
|
port.mConnection = usbDeviceConnection;
|
||||||
|
// reset invocations from countPorts()
|
||||||
|
clearInvocations(controlInterfaces[0]);
|
||||||
|
clearInvocations(controlInterfaces[1]);
|
||||||
|
|
||||||
port.openInt();
|
port.openInt();
|
||||||
assertEquals(readEndpoints[i], port.mReadEndpoint);
|
assertEquals(readEndpoints[i], port.mReadEndpoint);
|
||||||
assertEquals(writeEndpoints[i], port.mWriteEndpoint);
|
assertEquals(writeEndpoints[i], port.mWriteEndpoint);
|
||||||
|
verify(controlInterfaces[0], times(0)).getInterfaceClass(); // not openInterface with 'no IAD fallback'
|
||||||
|
verify(controlInterfaces[1], times(2)).getInterfaceClass(); // openInterface with IAD
|
||||||
|
port.closeInt();
|
||||||
|
clearInvocations(controlInterfaces[0]);
|
||||||
|
clearInvocations(controlInterfaces[1]);
|
||||||
|
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(null);
|
||||||
|
port.openInt();
|
||||||
|
verify(controlInterfaces[0], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
|
||||||
|
verify(controlInterfaces[1], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
|
||||||
|
port.closeInt();
|
||||||
|
clearInvocations(controlInterfaces[0]);
|
||||||
|
clearInvocations(controlInterfaces[1]);
|
||||||
|
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray("01 02 02 82 02")); // truncated descriptor
|
||||||
|
port.openInt();
|
||||||
|
verify(controlInterfaces[0], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
|
||||||
|
verify(controlInterfaces[1], times(2)).getInterfaceClass(); // openInterface with 'no IAD fallback'
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compositeDevice() throws Exception {
|
public void compositeDevice() throws Exception {
|
||||||
// mock BBC micro:bit
|
|
||||||
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
|
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
|
||||||
UsbDevice usbDevice = mock(UsbDevice.class);
|
UsbDevice usbDevice = mock(UsbDevice.class);
|
||||||
UsbInterface massStorageInterface = mock(UsbInterface.class);
|
UsbInterface massStorageInterface = mock(UsbInterface.class);
|
||||||
|
@ -156,6 +242,42 @@ public class CdcAcmSerialDriverTest {
|
||||||
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
|
||||||
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BBC micro:bit
|
||||||
|
* UsbInterface[mId=0,mAlternateSetting=0,mName=USB_MSC,mClass=8,mSubclass=6,mProtocol=80,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=130,mAttributes=2,mMaxPacketSize=64,mInterval=0]
|
||||||
|
* UsbEndpoint[mAddress=2,mAttributes=2,mMaxPacketSize=64,mInterval=0]]
|
||||||
|
* UsbInterface[mId=1,mAlternateSetting=0,mName=mbed Serial Port,mClass=2,mSubclass=2,mProtocol=1,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=131,mAttributes=3,mMaxPacketSize=16,mInterval=32]]
|
||||||
|
* UsbInterface[mId=2,mAlternateSetting=0,mName=mbed Serial Port,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=4,mAttributes=2,mMaxPacketSize=64,mInterval=0]
|
||||||
|
* UsbEndpoint[mAddress=132,mAttributes=2,mMaxPacketSize=64,mInterval=0]]
|
||||||
|
* UsbInterface[mId=3,mAlternateSetting=0,mName=CMSIS-DAP,mClass=3,mSubclass=0,mProtocol=0,mEndpoints=[
|
||||||
|
* UsbEndpoint[mAddress=129,mAttributes=3,mMaxPacketSize=64,mInterval=1]
|
||||||
|
* UsbEndpoint[mAddress=1,mAttributes=3,mMaxPacketSize=64,mInterval=1]]
|
||||||
|
* UsbInterface[mId=4,mAlternateSetting=0,mName=WebUSB: CMSIS-DAP,mClass=255,mSubclass=3,mProtocol=0,mEndpoints=[]
|
||||||
|
*/
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray(
|
||||||
|
"12 01 10 02 EF 02 01 40 28 0D 04 02 00 10 01 02 03 01\n" +
|
||||||
|
"09 02 8B 00 05 01 00 80 FA\n" +
|
||||||
|
"09 04 00 00 02 08 06 50 08\n" +
|
||||||
|
"07 05 82 02 40 00 00\n" +
|
||||||
|
"07 05 02 02 40 00 00\n" +
|
||||||
|
"08 0B 01 02 02 02 01 04\n" +
|
||||||
|
"09 04 01 00 01 02 02 01 04\n" +
|
||||||
|
"05 24 00 10 01\n" +
|
||||||
|
"05 24 01 03 02\n" +
|
||||||
|
"04 24 02 06\n" +
|
||||||
|
"05 24 06 01 02\n" +
|
||||||
|
"07 05 83 03 10 00 20\n" +
|
||||||
|
"09 04 02 00 02 0A 00 00 05\n" +
|
||||||
|
"07 05 04 02 40 00 00\n" +
|
||||||
|
"07 05 84 02 40 00 00\n" +
|
||||||
|
"09 04 03 00 02 03 00 00 06\n" +
|
||||||
|
"09 21 00 01 00 01 22 21 00\n" +
|
||||||
|
"07 05 81 03 40 00 01\n" +
|
||||||
|
"07 05 01 03 40 00 01\n" +
|
||||||
|
"09 04 04 00 00 FF 03 00 07"));
|
||||||
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
|
||||||
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
|
||||||
when(usbDevice.getInterfaceCount()).thenReturn(5);
|
when(usbDevice.getInterfaceCount()).thenReturn(5);
|
||||||
|
@ -164,11 +286,16 @@ public class CdcAcmSerialDriverTest {
|
||||||
when(usbDevice.getInterface(2)).thenReturn(dataInterface);
|
when(usbDevice.getInterface(2)).thenReturn(dataInterface);
|
||||||
when(usbDevice.getInterface(3)).thenReturn(hidInterface);
|
when(usbDevice.getInterface(3)).thenReturn(hidInterface);
|
||||||
when(usbDevice.getInterface(4)).thenReturn(vendorInterface);
|
when(usbDevice.getInterface(4)).thenReturn(vendorInterface);
|
||||||
|
when(massStorageInterface.getId()).thenReturn(0);
|
||||||
when(massStorageInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_MASS_STORAGE);
|
when(massStorageInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_MASS_STORAGE);
|
||||||
|
when(controlInterface.getId()).thenReturn(1);
|
||||||
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
||||||
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
||||||
|
when(dataInterface.getId()).thenReturn(2);
|
||||||
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
|
when(hidInterface.getId()).thenReturn(3);
|
||||||
when(hidInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_HID);
|
when(hidInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_HID);
|
||||||
|
when(vendorInterface.getId()).thenReturn(4);
|
||||||
when(vendorInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_VENDOR_SPEC);
|
when(vendorInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_VENDOR_SPEC);
|
||||||
|
|
||||||
when(controlInterface.getEndpointCount()).thenReturn(1);
|
when(controlInterface.getEndpointCount()).thenReturn(1);
|
||||||
|
@ -189,34 +316,145 @@ public class CdcAcmSerialDriverTest {
|
||||||
port.openInt();
|
port.openInt();
|
||||||
assertEquals(readEndpoint, port.mReadEndpoint);
|
assertEquals(readEndpoint, port.mReadEndpoint);
|
||||||
assertEquals(writeEndpoint, port.mWriteEndpoint);
|
assertEquals(writeEndpoint, port.mWriteEndpoint);
|
||||||
|
|
||||||
|
ProbeTable probeTable = UsbSerialProber.getDefaultProbeTable();
|
||||||
|
Class<? extends UsbSerialDriver> probeDriver = probeTable.findDriver(usbDevice);
|
||||||
|
assertEquals(driver.getClass(), probeDriver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
|
||||||
|
// has multiple USB_CLASS_CDC_DATA interfaces => get correct with IAD
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray(
|
||||||
|
"12 01 00 02 EF 02 01 40 FE CA 02 40 00 01 01 02 03 01\n" +
|
||||||
|
"09 02 8D 00 04 01 00 80 32\n" +
|
||||||
|
"08 0B 00 02 E0 01 03 00\n" +
|
||||||
|
"09 04 00 00 01 E0 01 03 04\n" +
|
||||||
|
"05 24 00 10 01\n" +
|
||||||
|
"05 24 01 00 01\n" +
|
||||||
|
"04 24 02 00\n" +
|
||||||
|
"05 24 06 00 01\n" +
|
||||||
|
"07 05 81 03 08 00 01\n" +
|
||||||
|
"09 04 01 00 02 0A 00 00 00\n" +
|
||||||
|
"07 05 82 02 40 00 00\n" +
|
||||||
|
"07 05 02 02 40 00 00\n" +
|
||||||
|
"08 0B 02 02 02 02 00 00\n" +
|
||||||
|
"09 04 02 00 01 02 02 00 04\n" +
|
||||||
|
"05 24 00 20 01\n" +
|
||||||
|
"05 24 01 00 03\n" +
|
||||||
|
"04 24 02 02\n" +
|
||||||
|
"05 24 06 02 03\n" +
|
||||||
|
"07 05 83 03 08 00 10\n" +
|
||||||
|
"09 04 03 00 02 0A 00 00 00\n" +
|
||||||
|
"07 05 04 02 40 00 00\n" +
|
||||||
|
"07 05 84 02 40 00 00"));
|
||||||
|
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.getId()).thenReturn(0);
|
||||||
|
when(rndisControlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER);
|
||||||
|
when(rndisControlInterface.getInterfaceSubclass()).thenReturn(1);
|
||||||
|
when(rndisControlInterface.getInterfaceProtocol()).thenReturn(3);
|
||||||
|
when(rndisDataInterface.getId()).thenReturn(1);
|
||||||
|
when(rndisDataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
|
when(controlInterface.getId()).thenReturn(2);
|
||||||
|
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
||||||
|
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
||||||
|
when(dataInterface.getId()).thenReturn(3);
|
||||||
|
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
|
@Test
|
||||||
public void compositeRndisDevice() throws Exception {
|
public void compositeAlternateSettingDevice() throws Exception {
|
||||||
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
|
UsbDeviceConnection usbDeviceConnection = mock(UsbDeviceConnection.class);
|
||||||
UsbDevice usbDevice = mock(UsbDevice.class);
|
UsbDevice usbDevice = mock(UsbDevice.class);
|
||||||
UsbInterface rndisControlInterface = mock(UsbInterface.class);
|
UsbInterface ethernetControlInterface = mock(UsbInterface.class);
|
||||||
UsbInterface rndisDataInterface = mock(UsbInterface.class);
|
UsbInterface ethernetDummyInterface = mock(UsbInterface.class);
|
||||||
|
UsbInterface ethernetDataInterface = mock(UsbInterface.class);
|
||||||
UsbInterface controlInterface = mock(UsbInterface.class);
|
UsbInterface controlInterface = mock(UsbInterface.class);
|
||||||
UsbInterface dataInterface = mock(UsbInterface.class);
|
UsbInterface dataInterface = mock(UsbInterface.class);
|
||||||
UsbEndpoint controlEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint controlEndpoint = mock(UsbEndpoint.class);
|
||||||
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint readEndpoint = mock(UsbEndpoint.class);
|
||||||
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
|
UsbEndpoint writeEndpoint = mock(UsbEndpoint.class);
|
||||||
|
|
||||||
|
// has multiple USB_CLASS_CDC_DATA interfaces => get correct with IAD
|
||||||
|
when(usbDeviceConnection.getRawDescriptors()).thenReturn(HexDump.hexStringToByteArray(
|
||||||
|
"12 01 00 02 EF 02 01 40 FE CA 02 40 00 01 01 02 03 01\n" +
|
||||||
|
"09 02 9A 00 04 01 00 80 32\n" +
|
||||||
|
"08 0B 00 02 02 06 00 00\n" +
|
||||||
|
"09 04 00 00 01 02 06 00 04\n" +
|
||||||
|
"05 24 00 20 01\n" +
|
||||||
|
"05 24 06 00 01\n" +
|
||||||
|
"0D 24 0F 04 00 00 00 00 DC 05 00 00 00\n" +
|
||||||
|
"07 05 81 03 08 00 01\n" +
|
||||||
|
"09 04 01 00 00 0A 00 00 00\n" +
|
||||||
|
"09 04 01 01 02 0A 00 00 00\n" +
|
||||||
|
"07 05 82 02 40 00 00\n" +
|
||||||
|
"07 05 02 02 40 00 00\n" +
|
||||||
|
"08 0B 02 02 02 02 00 00\n" +
|
||||||
|
"09 04 02 00 01 02 02 00 04\n" +
|
||||||
|
"05 24 00 20 01\n" +
|
||||||
|
"05 24 01 00 03\n" +
|
||||||
|
"04 24 02 02\n" +
|
||||||
|
"05 24 06 02 03\n" +
|
||||||
|
"07 05 83 03 08 00 10\n" +
|
||||||
|
"09 04 03 00 02 0A 00 00 00\n" +
|
||||||
|
"07 05 04 02 40 00 00\n" +
|
||||||
|
"07 05 84 02 40 00 00"));
|
||||||
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(controlInterface,true)).thenReturn(true);
|
||||||
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
|
when(usbDeviceConnection.claimInterface(dataInterface,true)).thenReturn(true);
|
||||||
when(usbDevice.getInterfaceCount()).thenReturn(4);
|
when(usbDevice.getInterfaceCount()).thenReturn(5);
|
||||||
when(usbDevice.getInterface(0)).thenReturn(rndisControlInterface);
|
when(usbDevice.getInterface(0)).thenReturn(ethernetControlInterface);
|
||||||
when(usbDevice.getInterface(1)).thenReturn(rndisDataInterface);
|
when(usbDevice.getInterface(1)).thenReturn(ethernetDummyInterface);
|
||||||
when(usbDevice.getInterface(2)).thenReturn(controlInterface);
|
when(usbDevice.getInterface(2)).thenReturn(ethernetDataInterface);
|
||||||
when(usbDevice.getInterface(3)).thenReturn(dataInterface);
|
when(usbDevice.getInterface(3)).thenReturn(controlInterface);
|
||||||
when(rndisControlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_WIRELESS_CONTROLLER);
|
when(usbDevice.getInterface(4)).thenReturn(dataInterface);
|
||||||
when(rndisControlInterface.getInterfaceSubclass()).thenReturn(1);
|
when(ethernetControlInterface.getId()).thenReturn(0);
|
||||||
when(rndisControlInterface.getInterfaceProtocol()).thenReturn(3);
|
when(ethernetControlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
||||||
when(rndisDataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
when(ethernetControlInterface.getInterfaceSubclass()).thenReturn(6);
|
||||||
|
when(ethernetDummyInterface.getId()).thenReturn(1);
|
||||||
|
when(ethernetDummyInterface.getAlternateSetting()).thenReturn(0);
|
||||||
|
when(ethernetDummyInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
|
when(ethernetDataInterface.getId()).thenReturn(1);
|
||||||
|
when(ethernetDataInterface.getAlternateSetting()).thenReturn(1);
|
||||||
|
when(ethernetDataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
|
when(controlInterface.getId()).thenReturn(2);
|
||||||
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
when(controlInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_COMM);
|
||||||
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
when(controlInterface.getInterfaceSubclass()).thenReturn(USB_SUBCLASS_ACM);
|
||||||
|
when(dataInterface.getId()).thenReturn(3);
|
||||||
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
when(dataInterface.getInterfaceClass()).thenReturn(UsbConstants.USB_CLASS_CDC_DATA);
|
||||||
|
|
||||||
when(controlInterface.getEndpointCount()).thenReturn(1);
|
when(controlInterface.getEndpointCount()).thenReturn(1);
|
||||||
|
|
Ładowanie…
Reference in New Issue