kopia lustrzana https://github.com/mik3y/usb-serial-for-android
Porównaj commity
3 Commity
11ccb5b949
...
9c30dc5ffa
Autor | SHA1 | Data |
---|---|---|
kai-morich | 9c30dc5ffa | |
kai-morich | b06118b156 | |
kai-morich | de6d5aa384 |
|
@ -8,9 +8,8 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: set up JDK 1.17
|
||||
uses: actions/setup-java@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
|
|
@ -13,7 +13,7 @@ android {
|
|||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunnerArguments = [ // Raspi Windows LinuxVM ...
|
||||
'rfc2217_server_host': '192.168.0.143',
|
||||
'rfc2217_server_host': '192.168.0.145',
|
||||
'rfc2217_server_nonstandard_baudrates': 'true', // true false false
|
||||
]
|
||||
}
|
||||
|
|
|
@ -22,10 +22,12 @@ import android.util.Log;
|
|||
|
||||
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.Ch34xSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.ChromeCcdSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.CommonUsbSerialPort;
|
||||
import com.hoho.android.usbserial.driver.CommonUsbSerialPortWrapper;
|
||||
import com.hoho.android.usbserial.driver.Cp21xxSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.FtdiSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.GsmModemSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.ProbeTable;
|
||||
import com.hoho.android.usbserial.driver.ProlificSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.ProlificSerialPortWrapper;
|
||||
|
@ -71,6 +73,7 @@ import static org.junit.Assert.assertNotEquals;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
@ -1616,15 +1619,10 @@ public class DeviceTest {
|
|||
|
||||
@Test
|
||||
public void wrongDriver() throws Exception {
|
||||
|
||||
UsbDeviceConnection wrongDeviceConnection;
|
||||
UsbSerialDriver wrongSerialDriver;
|
||||
UsbSerialPort wrongSerialPort;
|
||||
|
||||
if(!(usb.serialDriver instanceof CdcAcmSerialDriver)) {
|
||||
wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
wrongSerialDriver = new CdcAcmSerialDriver(usb.serialDriver.getDevice());
|
||||
wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new CdcAcmSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
wrongSerialPort.setParameters(115200, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); // ch340 fails here
|
||||
|
@ -1645,9 +1643,9 @@ public class DeviceTest {
|
|||
}
|
||||
}
|
||||
if(!(usb.serialDriver instanceof Ch34xSerialDriver)) {
|
||||
wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
wrongSerialDriver = new Ch34xSerialDriver(usb.serialDriver.getDevice());
|
||||
wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new Ch34xSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
fail("error expected");
|
||||
|
@ -1661,9 +1659,9 @@ public class DeviceTest {
|
|||
}
|
||||
// FTDI only recovers from Cp21xx control commands with power toggle, so skip this combination!
|
||||
if(!(usb.serialDriver instanceof Cp21xxSerialDriver | usb.serialDriver instanceof FtdiSerialDriver)) {
|
||||
wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
wrongSerialDriver = new Cp21xxSerialDriver(usb.serialDriver.getDevice());
|
||||
wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new Cp21xxSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
//if(usb.usbSerialDriver instanceof FtdiSerialDriver)
|
||||
|
@ -1679,9 +1677,9 @@ public class DeviceTest {
|
|||
}
|
||||
}
|
||||
if(!(usb.serialDriver instanceof FtdiSerialDriver)) {
|
||||
wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
wrongSerialDriver = new FtdiSerialDriver(usb.serialDriver.getDevice());
|
||||
wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new FtdiSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
if(usb.serialDriver instanceof Cp21xxSerialDriver)
|
||||
|
@ -1697,9 +1695,9 @@ public class DeviceTest {
|
|||
}
|
||||
}
|
||||
if(!(usb.serialDriver instanceof ProlificSerialDriver)) {
|
||||
wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
wrongSerialDriver = new ProlificSerialDriver(usb.serialDriver.getDevice());
|
||||
wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new ProlificSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
fail("error expected");
|
||||
|
@ -1711,6 +1709,36 @@ public class DeviceTest {
|
|||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
if(!(usb.serialDriver instanceof GsmModemSerialDriver)) {
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new GsmModemSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
assertThrows(UnsupportedOperationException.class, () -> wrongSerialPort.setParameters(9200, 8, 1, 0));
|
||||
assertEquals(EnumSet.noneOf(ControlLine.class), wrongSerialPort.getSupportedControlLines());
|
||||
try {
|
||||
wrongSerialPort.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
if(!(usb.serialDriver instanceof ChromeCcdSerialDriver)) {
|
||||
UsbDeviceConnection wrongDeviceConnection = usbManager.openDevice(usb.serialDriver.getDevice());
|
||||
UsbSerialDriver wrongSerialDriver = new ChromeCcdSerialDriver(usb.serialDriver.getDevice());
|
||||
UsbSerialPort wrongSerialPort = wrongSerialDriver.getPorts().get(0);
|
||||
try {
|
||||
wrongSerialPort.open(wrongDeviceConnection);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
assertThrows(UnsupportedOperationException.class, () -> wrongSerialPort.setParameters(9200, 8, 1, 0));
|
||||
assertEquals(EnumSet.noneOf(ControlLine.class), wrongSerialPort.getSupportedControlLines());
|
||||
try {
|
||||
wrongSerialPort.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
// test that device recovers from wrong commands
|
||||
usb.open();
|
||||
telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
|
@ -1743,7 +1771,11 @@ public class DeviceTest {
|
|||
Boolean inputLineFalse = usb.inputLinesSupported ? Boolean.FALSE : null;
|
||||
Boolean inputLineTrue = usb.inputLinesConnected ? Boolean.TRUE : inputLineFalse;
|
||||
|
||||
EnumSet<ControlLine> supportedControlLines = EnumSet.of(ControlLine.RTS, ControlLine.DTR);
|
||||
EnumSet<ControlLine> supportedControlLines = EnumSet.noneOf(ControlLine.class);
|
||||
if(usb.outputLinesSupported) {
|
||||
supportedControlLines.add(ControlLine.RTS);
|
||||
supportedControlLines.add(ControlLine.DTR);
|
||||
}
|
||||
if(usb.inputLinesSupported) {
|
||||
supportedControlLines.add(ControlLine.CTS);
|
||||
supportedControlLines.add(ControlLine.DSR);
|
||||
|
@ -1760,6 +1792,16 @@ public class DeviceTest {
|
|||
Thread.sleep(sleep);
|
||||
|
||||
assertEquals(supportedControlLines, usb.serialPort.getSupportedControlLines());
|
||||
if(supportedControlLines == EnumSet.noneOf(ControlLine.class)) {
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getControlLines());
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getRTS());
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getCTS());
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getDTR());
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getDSR());
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getCD());
|
||||
assertThrows(UnsupportedOperationException.class, () -> usb.serialPort.getRI());
|
||||
return;
|
||||
}
|
||||
|
||||
// control lines reset on initial open
|
||||
data = "none".getBytes();
|
||||
|
|
|
@ -56,6 +56,7 @@ public class UsbWrapper implements SerialInputOutputManager.Listener {
|
|||
|
||||
// device properties
|
||||
public boolean isCp21xxRestrictedPort; // second port of Cp2105 has limited dataBits, stopBits, parity
|
||||
public boolean outputLinesSupported;
|
||||
public boolean inputLinesSupported;
|
||||
public boolean inputLinesConnected;
|
||||
public boolean inputLinesOnlyRtsCts;
|
||||
|
@ -99,9 +100,10 @@ public class UsbWrapper implements SerialInputOutputManager.Listener {
|
|||
|
||||
// extract some device properties:
|
||||
isCp21xxRestrictedPort = serialDriver instanceof Cp21xxSerialDriver && serialDriver.getPorts().size()==2 && serialPort.getPortNumber() == 1;
|
||||
// output lines are supported by all drivers
|
||||
// input lines are supported by all drivers except CDC
|
||||
// output lines are supported by all common drivers
|
||||
// input lines are supported by all common drivers except CDC
|
||||
if (serialDriver instanceof FtdiSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
inputLinesSupported = true;
|
||||
if(serialDriver.getDevice().getProductId() == UsbId.FTDI_FT2232H)
|
||||
inputLinesConnected = true; // I only have 74LS138 connected at FT2232, not at FT232
|
||||
|
@ -110,16 +112,21 @@ public class UsbWrapper implements SerialInputOutputManager.Listener {
|
|||
inputLinesOnlyRtsCts = true; // I only test with FT230X that has only these 2 control lines. DTR is silently ignored
|
||||
}
|
||||
} else if (serialDriver instanceof Cp21xxSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
inputLinesSupported = true;
|
||||
if(serialDriver.getPorts().size() == 1)
|
||||
inputLinesConnected = true; // I only have 74LS138 connected at CP2102, not at CP2105
|
||||
} else if (serialDriver instanceof ProlificSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
inputLinesSupported = true;
|
||||
inputLinesConnected = true;
|
||||
} else if (serialDriver instanceof Ch34xSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
inputLinesSupported = true;
|
||||
if(serialDriver.getDevice().getProductId() == UsbId.QINHENG_CH340)
|
||||
inputLinesConnected = true; // I only have 74LS138 connected at CH340, not connected at CH341A
|
||||
} else if (serialDriver instanceof CdcAcmSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
}
|
||||
|
||||
if (serialDriver instanceof Cp21xxSerialDriver) {
|
||||
|
|
|
@ -22,366 +22,366 @@ import java.util.Map;
|
|||
|
||||
public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private static final String TAG = Ch34xSerialDriver.class.getSimpleName();
|
||||
private static final String TAG = Ch34xSerialDriver.class.getSimpleName();
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
|
||||
private static final int LCR_ENABLE_RX = 0x80;
|
||||
private static final int LCR_ENABLE_TX = 0x40;
|
||||
private static final int LCR_MARK_SPACE = 0x20;
|
||||
private static final int LCR_PAR_EVEN = 0x10;
|
||||
private static final int LCR_ENABLE_PAR = 0x08;
|
||||
private static final int LCR_STOP_BITS_2 = 0x04;
|
||||
private static final int LCR_CS8 = 0x03;
|
||||
private static final int LCR_CS7 = 0x02;
|
||||
private static final int LCR_CS6 = 0x01;
|
||||
private static final int LCR_CS5 = 0x00;
|
||||
private static final int LCR_ENABLE_RX = 0x80;
|
||||
private static final int LCR_ENABLE_TX = 0x40;
|
||||
private static final int LCR_MARK_SPACE = 0x20;
|
||||
private static final int LCR_PAR_EVEN = 0x10;
|
||||
private static final int LCR_ENABLE_PAR = 0x08;
|
||||
private static final int LCR_STOP_BITS_2 = 0x04;
|
||||
private static final int LCR_CS8 = 0x03;
|
||||
private static final int LCR_CS7 = 0x02;
|
||||
private static final int LCR_CS6 = 0x01;
|
||||
private static final int LCR_CS5 = 0x00;
|
||||
|
||||
private static final int GCL_CTS = 0x01;
|
||||
private static final int GCL_DSR = 0x02;
|
||||
private static final int GCL_RI = 0x04;
|
||||
private static final int GCL_CD = 0x08;
|
||||
private static final int SCL_DTR = 0x20;
|
||||
private static final int SCL_RTS = 0x40;
|
||||
private static final int GCL_CTS = 0x01;
|
||||
private static final int GCL_DSR = 0x02;
|
||||
private static final int GCL_RI = 0x04;
|
||||
private static final int GCL_CD = 0x08;
|
||||
private static final int SCL_DTR = 0x20;
|
||||
private static final int SCL_RTS = 0x40;
|
||||
|
||||
public Ch34xSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new Ch340SerialPort(mDevice, 0);
|
||||
}
|
||||
public Ch34xSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new Ch340SerialPort(mDevice, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
}
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
}
|
||||
|
||||
public class Ch340SerialPort extends CommonUsbSerialPort {
|
||||
public class Ch340SerialPort extends CommonUsbSerialPort {
|
||||
|
||||
private static final int USB_TIMEOUT_MILLIS = 5000;
|
||||
private static final int USB_TIMEOUT_MILLIS = 5000;
|
||||
|
||||
private final int DEFAULT_BAUD_RATE = 9600;
|
||||
private final int DEFAULT_BAUD_RATE = 9600;
|
||||
|
||||
private boolean dtr = false;
|
||||
private boolean rts = false;
|
||||
private boolean dtr = false;
|
||||
private boolean rts = false;
|
||||
|
||||
public Ch340SerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
}
|
||||
public Ch340SerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbSerialDriver getDriver() {
|
||||
return Ch34xSerialDriver.this;
|
||||
}
|
||||
@Override
|
||||
public UsbSerialDriver getDriver() {
|
||||
return Ch34xSerialDriver.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void openInt() throws IOException {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
UsbInterface usbIface = mDevice.getInterface(i);
|
||||
if (!mConnection.claimInterface(usbIface, true)) {
|
||||
throw new IOException("Could not claim data interface");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void openInt() throws IOException {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
UsbInterface usbIface = mDevice.getInterface(i);
|
||||
if (!mConnection.claimInterface(usbIface, true)) {
|
||||
throw new IOException("Could not claim data interface");
|
||||
}
|
||||
}
|
||||
|
||||
UsbInterface dataIface = mDevice.getInterface(mDevice.getInterfaceCount() - 1);
|
||||
for (int i = 0; i < dataIface.getEndpointCount(); i++) {
|
||||
UsbEndpoint ep = dataIface.getEndpoint(i);
|
||||
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
|
||||
if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
|
||||
mReadEndpoint = ep;
|
||||
} else {
|
||||
mWriteEndpoint = ep;
|
||||
}
|
||||
}
|
||||
}
|
||||
UsbInterface dataIface = mDevice.getInterface(mDevice.getInterfaceCount() - 1);
|
||||
for (int i = 0; i < dataIface.getEndpointCount(); i++) {
|
||||
UsbEndpoint ep = dataIface.getEndpoint(i);
|
||||
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
|
||||
if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
|
||||
mReadEndpoint = ep;
|
||||
} else {
|
||||
mWriteEndpoint = ep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initialize();
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
}
|
||||
initialize();
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeInt() {
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++)
|
||||
mConnection.releaseInterface(mDevice.getInterface(i));
|
||||
} catch(Exception ignored) {}
|
||||
}
|
||||
@Override
|
||||
protected void closeInt() {
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++)
|
||||
mConnection.releaseInterface(mDevice.getInterface(i));
|
||||
} catch(Exception ignored) {}
|
||||
}
|
||||
|
||||
private int controlOut(int request, int value, int index) {
|
||||
final int REQTYPE_HOST_TO_DEVICE = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT;
|
||||
return mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request,
|
||||
value, index, null, 0, USB_TIMEOUT_MILLIS);
|
||||
}
|
||||
private int controlOut(int request, int value, int index) {
|
||||
final int REQTYPE_HOST_TO_DEVICE = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT;
|
||||
return mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request,
|
||||
value, index, null, 0, USB_TIMEOUT_MILLIS);
|
||||
}
|
||||
|
||||
|
||||
private int controlIn(int request, int value, int index, byte[] buffer) {
|
||||
final int REQTYPE_DEVICE_TO_HOST = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN;
|
||||
return mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, request,
|
||||
value, index, buffer, buffer.length, USB_TIMEOUT_MILLIS);
|
||||
}
|
||||
private int controlIn(int request, int value, int index, byte[] buffer) {
|
||||
final int REQTYPE_DEVICE_TO_HOST = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN;
|
||||
return mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, request,
|
||||
value, index, buffer, buffer.length, USB_TIMEOUT_MILLIS);
|
||||
}
|
||||
|
||||
|
||||
private void checkState(String msg, int request, int value, int[] expected) throws IOException {
|
||||
byte[] buffer = new byte[expected.length];
|
||||
int ret = controlIn(request, value, 0, buffer);
|
||||
private void checkState(String msg, int request, int value, int[] expected) throws IOException {
|
||||
byte[] buffer = new byte[expected.length];
|
||||
int ret = controlIn(request, value, 0, buffer);
|
||||
|
||||
if (ret < 0) {
|
||||
throw new IOException("Failed send cmd [" + msg + "]");
|
||||
}
|
||||
if (ret < 0) {
|
||||
throw new IOException("Failed send cmd [" + msg + "]");
|
||||
}
|
||||
|
||||
if (ret != expected.length) {
|
||||
throw new IOException("Expected " + expected.length + " bytes, but get " + ret + " [" + msg + "]");
|
||||
}
|
||||
if (ret != expected.length) {
|
||||
throw new IOException("Expected " + expected.length + " bytes, but get " + ret + " [" + msg + "]");
|
||||
}
|
||||
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
if (expected[i] == -1) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
if (expected[i] == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int current = buffer[i] & 0xff;
|
||||
if (expected[i] != current) {
|
||||
throw new IOException("Expected 0x" + Integer.toHexString(expected[i]) + " byte, but get 0x" + Integer.toHexString(current) + " [" + msg + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
int current = buffer[i] & 0xff;
|
||||
if (expected[i] != current) {
|
||||
throw new IOException("Expected 0x" + Integer.toHexString(expected[i]) + " byte, but get 0x" + Integer.toHexString(current) + " [" + msg + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setControlLines() throws IOException {
|
||||
if (controlOut(0xa4, ~((dtr ? SCL_DTR : 0) | (rts ? SCL_RTS : 0)), 0) < 0) {
|
||||
throw new IOException("Failed to set control lines");
|
||||
}
|
||||
}
|
||||
private void setControlLines() throws IOException {
|
||||
if (controlOut(0xa4, ~((dtr ? SCL_DTR : 0) | (rts ? SCL_RTS : 0)), 0) < 0) {
|
||||
throw new IOException("Failed to set control lines");
|
||||
}
|
||||
}
|
||||
|
||||
private byte getStatus() throws IOException {
|
||||
byte[] buffer = new byte[2];
|
||||
int ret = controlIn(0x95, 0x0706, 0, buffer);
|
||||
if (ret < 0)
|
||||
throw new IOException("Error getting control lines");
|
||||
return buffer[0];
|
||||
}
|
||||
private byte getStatus() throws IOException {
|
||||
byte[] buffer = new byte[2];
|
||||
int ret = controlIn(0x95, 0x0706, 0, buffer);
|
||||
if (ret < 0)
|
||||
throw new IOException("Error getting control lines");
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
private void initialize() throws IOException {
|
||||
checkState("init #1", 0x5f, 0, new int[]{-1 /* 0x27, 0x30 */, 0x00});
|
||||
private void initialize() throws IOException {
|
||||
checkState("init #1", 0x5f, 0, new int[]{-1 /* 0x27, 0x30 */, 0x00});
|
||||
|
||||
if (controlOut(0xa1, 0, 0) < 0) {
|
||||
throw new IOException("Init failed: #2");
|
||||
}
|
||||
if (controlOut(0xa1, 0, 0) < 0) {
|
||||
throw new IOException("Init failed: #2");
|
||||
}
|
||||
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
|
||||
checkState("init #4", 0x95, 0x2518, new int[]{-1 /* 0x56, c3*/, 0x00});
|
||||
checkState("init #4", 0x95, 0x2518, new int[]{-1 /* 0x56, c3*/, 0x00});
|
||||
|
||||
if (controlOut(0x9a, 0x2518, LCR_ENABLE_RX | LCR_ENABLE_TX | LCR_CS8) < 0) {
|
||||
throw new IOException("Init failed: #5");
|
||||
}
|
||||
if (controlOut(0x9a, 0x2518, LCR_ENABLE_RX | LCR_ENABLE_TX | LCR_CS8) < 0) {
|
||||
throw new IOException("Init failed: #5");
|
||||
}
|
||||
|
||||
checkState("init #6", 0x95, 0x0706, new int[]{-1/*0xf?*/, -1/*0xec,0xee*/});
|
||||
checkState("init #6", 0x95, 0x0706, new int[]{-1/*0xf?*/, -1/*0xec,0xee*/});
|
||||
|
||||
if (controlOut(0xa1, 0x501f, 0xd90a) < 0) {
|
||||
throw new IOException("Init failed: #7");
|
||||
}
|
||||
if (controlOut(0xa1, 0x501f, 0xd90a) < 0) {
|
||||
throw new IOException("Init failed: #7");
|
||||
}
|
||||
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
|
||||
setControlLines();
|
||||
setControlLines();
|
||||
|
||||
checkState("init #10", 0x95, 0x0706, new int[]{-1/* 0x9f, 0xff*/, -1/*0xec,0xee*/});
|
||||
}
|
||||
checkState("init #10", 0x95, 0x0706, new int[]{-1/* 0x9f, 0xff*/, -1/*0xec,0xee*/});
|
||||
}
|
||||
|
||||
|
||||
private void setBaudRate(int baudRate) throws IOException {
|
||||
long factor;
|
||||
long divisor;
|
||||
private void setBaudRate(int baudRate) throws IOException {
|
||||
long factor;
|
||||
long divisor;
|
||||
|
||||
if (baudRate == 921600) {
|
||||
divisor = 7;
|
||||
factor = 0xf300;
|
||||
} else {
|
||||
final long BAUDBASE_FACTOR = 1532620800;
|
||||
final int BAUDBASE_DIVMAX = 3;
|
||||
if (baudRate == 921600) {
|
||||
divisor = 7;
|
||||
factor = 0xf300;
|
||||
} else {
|
||||
final long BAUDBASE_FACTOR = 1532620800;
|
||||
final int BAUDBASE_DIVMAX = 3;
|
||||
|
||||
if(BuildConfig.DEBUG && (baudRate & (3<<29)) == (1<<29))
|
||||
baudRate &= ~(1<<29); // for testing purpose bypass dedicated baud rate handling
|
||||
factor = BAUDBASE_FACTOR / baudRate;
|
||||
divisor = BAUDBASE_DIVMAX;
|
||||
while ((factor > 0xfff0) && divisor > 0) {
|
||||
factor >>= 3;
|
||||
divisor--;
|
||||
}
|
||||
if (factor > 0xfff0) {
|
||||
throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
|
||||
}
|
||||
factor = 0x10000 - factor;
|
||||
}
|
||||
if(BuildConfig.DEBUG && (baudRate & (3<<29)) == (1<<29))
|
||||
baudRate &= ~(1<<29); // for testing purpose bypass dedicated baud rate handling
|
||||
factor = BAUDBASE_FACTOR / baudRate;
|
||||
divisor = BAUDBASE_DIVMAX;
|
||||
while ((factor > 0xfff0) && divisor > 0) {
|
||||
factor >>= 3;
|
||||
divisor--;
|
||||
}
|
||||
if (factor > 0xfff0) {
|
||||
throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
|
||||
}
|
||||
factor = 0x10000 - factor;
|
||||
}
|
||||
|
||||
divisor |= 0x0080; // else ch341a waits until buffer full
|
||||
int val1 = (int) ((factor & 0xff00) | divisor);
|
||||
int val2 = (int) (factor & 0xff);
|
||||
Log.d(TAG, String.format("baud rate=%d, 0x1312=0x%04x, 0x0f2c=0x%04x", baudRate, val1, val2));
|
||||
int ret = controlOut(0x9a, 0x1312, val1);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting baud rate: #1)");
|
||||
}
|
||||
ret = controlOut(0x9a, 0x0f2c, val2);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting baud rate: #2");
|
||||
}
|
||||
}
|
||||
divisor |= 0x0080; // else ch341a waits until buffer full
|
||||
int val1 = (int) ((factor & 0xff00) | divisor);
|
||||
int val2 = (int) (factor & 0xff);
|
||||
Log.d(TAG, String.format("baud rate=%d, 0x1312=0x%04x, 0x0f2c=0x%04x", baudRate, val1, val2));
|
||||
int ret = controlOut(0x9a, 0x1312, val1);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting baud rate: #1)");
|
||||
}
|
||||
ret = controlOut(0x9a, 0x0f2c, val2);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting baud rate: #2");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameters(int baudRate, int dataBits, int stopBits, @Parity int parity) throws IOException {
|
||||
if(baudRate <= 0) {
|
||||
throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
|
||||
}
|
||||
setBaudRate(baudRate);
|
||||
@Override
|
||||
public void setParameters(int baudRate, int dataBits, int stopBits, @Parity int parity) throws IOException {
|
||||
if(baudRate <= 0) {
|
||||
throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
|
||||
}
|
||||
setBaudRate(baudRate);
|
||||
|
||||
int lcr = LCR_ENABLE_RX | LCR_ENABLE_TX;
|
||||
int lcr = LCR_ENABLE_RX | LCR_ENABLE_TX;
|
||||
|
||||
switch (dataBits) {
|
||||
case DATABITS_5:
|
||||
lcr |= LCR_CS5;
|
||||
break;
|
||||
case DATABITS_6:
|
||||
lcr |= LCR_CS6;
|
||||
break;
|
||||
case DATABITS_7:
|
||||
lcr |= LCR_CS7;
|
||||
break;
|
||||
case DATABITS_8:
|
||||
lcr |= LCR_CS8;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid data bits: " + dataBits);
|
||||
}
|
||||
switch (dataBits) {
|
||||
case DATABITS_5:
|
||||
lcr |= LCR_CS5;
|
||||
break;
|
||||
case DATABITS_6:
|
||||
lcr |= LCR_CS6;
|
||||
break;
|
||||
case DATABITS_7:
|
||||
lcr |= LCR_CS7;
|
||||
break;
|
||||
case DATABITS_8:
|
||||
lcr |= LCR_CS8;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid data bits: " + dataBits);
|
||||
}
|
||||
|
||||
switch (parity) {
|
||||
case PARITY_NONE:
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
lcr |= LCR_ENABLE_PAR;
|
||||
break;
|
||||
case PARITY_EVEN:
|
||||
lcr |= LCR_ENABLE_PAR | LCR_PAR_EVEN;
|
||||
break;
|
||||
case PARITY_MARK:
|
||||
lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE;
|
||||
break;
|
||||
case PARITY_SPACE:
|
||||
lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE | LCR_PAR_EVEN;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid parity: " + parity);
|
||||
}
|
||||
switch (parity) {
|
||||
case PARITY_NONE:
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
lcr |= LCR_ENABLE_PAR;
|
||||
break;
|
||||
case PARITY_EVEN:
|
||||
lcr |= LCR_ENABLE_PAR | LCR_PAR_EVEN;
|
||||
break;
|
||||
case PARITY_MARK:
|
||||
lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE;
|
||||
break;
|
||||
case PARITY_SPACE:
|
||||
lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE | LCR_PAR_EVEN;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid parity: " + parity);
|
||||
}
|
||||
|
||||
switch (stopBits) {
|
||||
case STOPBITS_1:
|
||||
break;
|
||||
case STOPBITS_1_5:
|
||||
throw new UnsupportedOperationException("Unsupported stop bits: 1.5");
|
||||
case STOPBITS_2:
|
||||
lcr |= LCR_STOP_BITS_2;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
|
||||
}
|
||||
switch (stopBits) {
|
||||
case STOPBITS_1:
|
||||
break;
|
||||
case STOPBITS_1_5:
|
||||
throw new UnsupportedOperationException("Unsupported stop bits: 1.5");
|
||||
case STOPBITS_2:
|
||||
lcr |= LCR_STOP_BITS_2;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
|
||||
}
|
||||
|
||||
int ret = controlOut(0x9a, 0x2518, lcr);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting control byte");
|
||||
}
|
||||
}
|
||||
int ret = controlOut(0x9a, 0x2518, lcr);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting control byte");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCD() throws IOException {
|
||||
return (getStatus() & GCL_CD) == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean getCD() throws IOException {
|
||||
return (getStatus() & GCL_CD) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCTS() throws IOException {
|
||||
return (getStatus() & GCL_CTS) == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean getCTS() throws IOException {
|
||||
return (getStatus() & GCL_CTS) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDSR() throws IOException {
|
||||
return (getStatus() & GCL_DSR) == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean getDSR() throws IOException {
|
||||
return (getStatus() & GCL_DSR) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDTR() throws IOException {
|
||||
return dtr;
|
||||
}
|
||||
@Override
|
||||
public boolean getDTR() throws IOException {
|
||||
return dtr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDTR(boolean value) throws IOException {
|
||||
dtr = value;
|
||||
setControlLines();
|
||||
}
|
||||
@Override
|
||||
public void setDTR(boolean value) throws IOException {
|
||||
dtr = value;
|
||||
setControlLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRI() throws IOException {
|
||||
return (getStatus() & GCL_RI) == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean getRI() throws IOException {
|
||||
return (getStatus() & GCL_RI) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRTS() throws IOException {
|
||||
return rts;
|
||||
}
|
||||
@Override
|
||||
public boolean getRTS() throws IOException {
|
||||
return rts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRTS(boolean value) throws IOException {
|
||||
rts = value;
|
||||
setControlLines();
|
||||
}
|
||||
@Override
|
||||
public void setRTS(boolean value) throws IOException {
|
||||
rts = value;
|
||||
setControlLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ControlLine> getControlLines() throws IOException {
|
||||
int status = getStatus();
|
||||
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
|
||||
if(rts) set.add(ControlLine.RTS);
|
||||
if((status & GCL_CTS) == 0) set.add(ControlLine.CTS);
|
||||
if(dtr) set.add(ControlLine.DTR);
|
||||
if((status & GCL_DSR) == 0) set.add(ControlLine.DSR);
|
||||
if((status & GCL_CD) == 0) set.add(ControlLine.CD);
|
||||
if((status & GCL_RI) == 0) set.add(ControlLine.RI);
|
||||
return set;
|
||||
}
|
||||
@Override
|
||||
public EnumSet<ControlLine> getControlLines() throws IOException {
|
||||
int status = getStatus();
|
||||
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
|
||||
if(rts) set.add(ControlLine.RTS);
|
||||
if((status & GCL_CTS) == 0) set.add(ControlLine.CTS);
|
||||
if(dtr) set.add(ControlLine.DTR);
|
||||
if((status & GCL_DSR) == 0) set.add(ControlLine.DSR);
|
||||
if((status & GCL_CD) == 0) set.add(ControlLine.CD);
|
||||
if((status & GCL_RI) == 0) set.add(ControlLine.RI);
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
|
||||
return EnumSet.allOf(ControlLine.class);
|
||||
}
|
||||
@Override
|
||||
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
|
||||
return EnumSet.allOf(ControlLine.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBreak(boolean value) throws IOException {
|
||||
byte[] req = new byte[2];
|
||||
if(controlIn(0x95, 0x1805, 0, req) < 0) {
|
||||
throw new IOException("Error getting BREAK condition");
|
||||
}
|
||||
if(value) {
|
||||
req[0] &= ~1;
|
||||
req[1] &= ~0x40;
|
||||
} else {
|
||||
req[0] |= 1;
|
||||
req[1] |= 0x40;
|
||||
}
|
||||
int val = (req[1] & 0xff) << 8 | (req[0] & 0xff);
|
||||
if(controlOut(0x9a, 0x1805, val) < 0) {
|
||||
throw new IOException("Error setting BREAK condition");
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setBreak(boolean value) throws IOException {
|
||||
byte[] req = new byte[2];
|
||||
if(controlIn(0x95, 0x1805, 0, req) < 0) {
|
||||
throw new IOException("Error getting BREAK condition");
|
||||
}
|
||||
if(value) {
|
||||
req[0] &= ~1;
|
||||
req[1] &= ~0x40;
|
||||
} else {
|
||||
req[0] |= 1;
|
||||
req[1] |= 0x40;
|
||||
}
|
||||
int val = (req[1] & 0xff) << 8 | (req[0] & 0xff);
|
||||
if(controlOut(0x9a, 0x1805, val) < 0) {
|
||||
throw new IOException("Error setting BREAK condition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>();
|
||||
supportedDevices.put(UsbId.VENDOR_QINHENG, new int[]{
|
||||
UsbId.QINHENG_CH340,
|
||||
UsbId.QINHENG_CH341A,
|
||||
});
|
||||
return supportedDevices;
|
||||
}
|
||||
@SuppressWarnings({"unused"})
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>();
|
||||
supportedDevices.put(UsbId.VENDOR_QINHENG, new int[]{
|
||||
UsbId.QINHENG_CH340,
|
||||
UsbId.QINHENG_CH341A,
|
||||
});
|
||||
return supportedDevices;
|
||||
}
|
||||
|
||||
}
|
|
@ -34,12 +34,12 @@ public class ChromeCcdSerialDriver implements UsbSerialDriver{
|
|||
public ChromeCcdSerialDriver(UsbDevice mDevice) {
|
||||
this.mDevice = mDevice;
|
||||
mPorts = new ArrayList<UsbSerialPort>();
|
||||
for (int i = 0; i < 3; i++)
|
||||
mPorts.add(new ChromeCcdSerialPort(mDevice, i));
|
||||
for (int i = 0; i < 3; i++)
|
||||
mPorts.add(new ChromeCcdSerialPort(mDevice, i));
|
||||
}
|
||||
|
||||
public class ChromeCcdSerialPort extends CommonUsbSerialPort {
|
||||
private UsbInterface mDataInterface;
|
||||
private UsbInterface mDataInterface;
|
||||
|
||||
public ChromeCcdSerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
|
@ -48,26 +48,26 @@ public class ChromeCcdSerialDriver implements UsbSerialDriver{
|
|||
@Override
|
||||
protected void openInt() throws IOException {
|
||||
Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
|
||||
mDataInterface = mDevice.getInterface(mPortNumber);
|
||||
if (!mConnection.claimInterface(mDataInterface, true)) {
|
||||
throw new IOException("Could not claim shared control/data interface");
|
||||
}
|
||||
mDataInterface = mDevice.getInterface(mPortNumber);
|
||||
if (!mConnection.claimInterface(mDataInterface, true)) {
|
||||
throw new IOException("Could not claim shared control/data interface");
|
||||
}
|
||||
Log.d(TAG, "endpoint count=" + mDataInterface.getEndpointCount());
|
||||
for (int i = 0; i < mDataInterface.getEndpointCount(); ++i) {
|
||||
UsbEndpoint ep = mDataInterface.getEndpoint(i);
|
||||
if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
|
||||
mReadEndpoint = ep;
|
||||
mReadEndpoint = ep;
|
||||
} else if ((ep.getDirection() == UsbConstants.USB_DIR_OUT) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
|
||||
mWriteEndpoint = ep;
|
||||
mWriteEndpoint = ep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeInt() {
|
||||
try {
|
||||
mConnection.releaseInterface(mDataInterface);
|
||||
} catch(Exception ignored) {}
|
||||
try {
|
||||
mConnection.releaseInterface(mDataInterface);
|
||||
} catch(Exception ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,11 +80,6 @@ public class ChromeCcdSerialDriver implements UsbSerialDriver{
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ControlLine> getControlLines() throws IOException {
|
||||
return EnumSet.noneOf(ControlLine.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
|
||||
return EnumSet.noneOf(ControlLine.class);
|
||||
|
|
|
@ -305,7 +305,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
|||
public void setRTS(boolean value) throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public abstract EnumSet<ControlLine> getControlLines() throws IOException;
|
||||
public EnumSet<ControlLine> getControlLines() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public abstract EnumSet<ControlLine> getSupportedControlLines() throws IOException;
|
||||
|
|
|
@ -89,14 +89,9 @@ public class GsmModemSerialDriver implements UsbSerialDriver{
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ControlLine> getControlLines() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
return EnumSet.noneOf(ControlLine.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue