new getControlLines() and getSupportedControLines() methods

getControlLines() requires less USB calls than calling getRTS() + ... + getRI() individually.
getSupportedControlLines() tells you, which control lines are supported by a driver. Previously you had to check the driver implementation.
pull/297/head
kai-morich 2020-06-28 20:10:45 +02:00
rodzic 13df128226
commit 7423fd9d79
10 zmienionych plików z 181 dodań i 23 usunięć

Wyświetl plik

@ -37,6 +37,7 @@ import com.hoho.android.usbserial.util.SerialInputOutputManager;
import java.io.IOException;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.concurrent.Executors;
public class TerminalFragment extends Fragment implements SerialInputOutputManager.Listener {
@ -312,29 +313,42 @@ public class TerminalFragment extends Fragment implements SerialInputOutputManag
if (btn.equals(rtsBtn)) { ctrl = "RTS"; usbSerialPort.setRTS(btn.isChecked()); }
if (btn.equals(dtrBtn)) { ctrl = "DTR"; usbSerialPort.setDTR(btn.isChecked()); }
} catch (IOException e) {
status("set" + ctrl + " failed: " + e.getMessage());
status("set" + ctrl + "() failed: " + e.getMessage());
}
}
private boolean refresh() {
String ctrl = "";
try {
ctrl = "RTS"; rtsBtn.setChecked(usbSerialPort.getRTS());
ctrl = "CTS"; ctsBtn.setChecked(usbSerialPort.getCTS());
ctrl = "DTR"; dtrBtn.setChecked(usbSerialPort.getDTR());
ctrl = "DSR"; dsrBtn.setChecked(usbSerialPort.getDSR());
ctrl = "CD"; cdBtn.setChecked(usbSerialPort.getCD());
ctrl = "RI"; riBtn.setChecked(usbSerialPort.getRI());
EnumSet<UsbSerialPort.ControlLine> controlLines = usbSerialPort.getControlLines();
rtsBtn.setChecked(controlLines.contains(UsbSerialPort.ControlLine.RTS));
ctsBtn.setChecked(controlLines.contains(UsbSerialPort.ControlLine.CTS));
dtrBtn.setChecked(controlLines.contains(UsbSerialPort.ControlLine.DTR));
dsrBtn.setChecked(controlLines.contains(UsbSerialPort.ControlLine.DSR));
cdBtn.setChecked(controlLines.contains(UsbSerialPort.ControlLine.CD));
riBtn.setChecked(controlLines.contains(UsbSerialPort.ControlLine.RI));
} catch (IOException e) {
status("get" + ctrl + " failed: " + e.getMessage() + " -> stopped control line refresh");
status("getControlLines() failed: " + e.getMessage() + " -> stopped control line refresh");
return false;
}
return true;
}
void start() {
if (connected && refresh())
mainLooper.postDelayed(runnable, refreshInterval);
if (connected) {
try {
EnumSet<UsbSerialPort.ControlLine> controlLines = usbSerialPort.getSupportedControlLines();
if (!controlLines.contains(UsbSerialPort.ControlLine.RTS)) rtsBtn.setVisibility(View.INVISIBLE);
if (!controlLines.contains(UsbSerialPort.ControlLine.CTS)) ctsBtn.setVisibility(View.INVISIBLE);
if (!controlLines.contains(UsbSerialPort.ControlLine.DTR)) dtrBtn.setVisibility(View.INVISIBLE);
if (!controlLines.contains(UsbSerialPort.ControlLine.DSR)) dsrBtn.setVisibility(View.INVISIBLE);
if (!controlLines.contains(UsbSerialPort.ControlLine.CD)) cdBtn.setVisibility(View.INVISIBLE);
if (!controlLines.contains(UsbSerialPort.ControlLine.RI)) riBtn.setVisibility(View.INVISIBLE);
} catch (IOException e) {
Toast.makeText(getActivity(), "getSupportedControlLines() failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
if (refresh())
mainLooper.postDelayed(runnable, refreshInterval);
}
}
void stop() {

Wyświetl plik

@ -11,7 +11,7 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments = [ // Raspi Windows LinuxVM ...
'rfc2217_server_host': '192.168.0.100',
'rfc2217_server_host': '192.168.0.110',
'rfc2217_server_nonstandard_baudrates': 'true', // true false false
]
}

Wyświetl plik

@ -1564,12 +1564,20 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
inputLinesSupported = true;
inputLinesConnected = true;
}
EnumSet<UsbSerialPort.ControlLine> supportedControlLines = EnumSet.of(UsbSerialPort.ControlLine.RTS, UsbSerialPort.ControlLine.DTR);
if(inputLinesSupported) {
supportedControlLines.add(UsbSerialPort.ControlLine.CTS);
supportedControlLines.add(UsbSerialPort.ControlLine.DSR);
supportedControlLines.add(UsbSerialPort.ControlLine.CD);
supportedControlLines.add(UsbSerialPort.ControlLine.RI);
}
usbOpen(EnumSet.of(UsbOpenFlags.NO_CONTROL_LINE_INIT));
usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
telnetParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
Thread.sleep(sleep);
assertEquals(supportedControlLines, usbSerialPort.getSupportedControlLines());
if(usbSerialDriver instanceof ProlificSerialDriver) {
// the initial status is sometimes not available or wrong.
// this is more likely if other tests have been executed before.
@ -1579,6 +1587,10 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
assertTrue(usbSerialPort.getRI());
}
data = "none".getBytes();
assertEquals(inputLinesConnected
? EnumSet.of(UsbSerialPort.ControlLine.RI)
: EnumSet.noneOf(UsbSerialPort.ControlLine.class),
usbSerialPort.getControlLines());
assertFalse(usbSerialPort.getRTS());
assertFalse(usbSerialPort.getCTS());
assertFalse(usbSerialPort.getDTR());
@ -1598,6 +1610,10 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
data = "rts ".getBytes();
usbSerialPort.setRTS(true);
Thread.sleep(sleep);
assertEquals(inputLinesConnected
? EnumSet.of(UsbSerialPort.ControlLine.RTS, UsbSerialPort.ControlLine.CTS)
: EnumSet.of(UsbSerialPort.ControlLine.RTS),
usbSerialPort.getControlLines());
assertTrue(usbSerialPort.getRTS());
assertEquals(usbSerialPort.getCTS(), inputLinesConnected);
assertFalse(usbSerialPort.getDTR());
@ -1612,6 +1628,10 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
data = "both".getBytes();
usbSerialPort.setDTR(true);
Thread.sleep(sleep);
assertEquals(inputLinesConnected
? EnumSet.of(UsbSerialPort.ControlLine.RTS, UsbSerialPort.ControlLine.DTR, UsbSerialPort.ControlLine.CD)
: EnumSet.of(UsbSerialPort.ControlLine.RTS, UsbSerialPort.ControlLine.DTR),
usbSerialPort.getControlLines());
assertTrue(usbSerialPort.getRTS());
assertFalse(usbSerialPort.getCTS());
assertTrue(usbSerialPort.getDTR());
@ -1626,6 +1646,10 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
data = "dtr ".getBytes();
usbSerialPort.setRTS(false);
Thread.sleep(sleep);
assertEquals(inputLinesConnected
? EnumSet.of(UsbSerialPort.ControlLine.DTR, UsbSerialPort.ControlLine.DSR)
: EnumSet.of(UsbSerialPort.ControlLine.DTR),
usbSerialPort.getControlLines());
assertFalse(usbSerialPort.getRTS());
assertFalse(usbSerialPort.getCTS());
assertTrue(usbSerialPort.getDTR());
@ -1646,6 +1670,10 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
usbOpen(EnumSet.of(UsbOpenFlags.NO_CONTROL_LINE_INIT, UsbOpenFlags.NO_IOMANAGER_THREAD));
usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
EnumSet<UsbSerialPort.ControlLine> retainedControlLines = EnumSet.noneOf(UsbSerialPort.ControlLine.class);
if(outputRetained) retainedControlLines.add(UsbSerialPort.ControlLine.DTR);
if(inputRetained) retainedControlLines.add(UsbSerialPort.ControlLine.DSR);
assertEquals(retainedControlLines, usbSerialPort.getControlLines());
assertFalse(usbSerialPort.getRTS());
assertFalse(usbSerialPort.getCTS());
assertEquals(usbSerialPort.getDTR(), outputRetained);

Wyświetl plik

@ -30,6 +30,7 @@ import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -300,6 +301,18 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
sendAcmControlMessage(SET_CONTROL_LINE_STATE, value, null);
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(mRts) set.add(ControlLine.RTS);
if(mDtr) set.add(ControlLine.DTR);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.of(ControlLine.RTS, ControlLine.DTR);
}
}
public static Map<Integer, int[]> getSupportedDevices() {

Wyświetl plik

@ -28,6 +28,7 @@ import android.hardware.usb.UsbInterface;
import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -173,7 +174,7 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
}
}
private byte getControlLines() throws IOException {
private byte getStatus() throws IOException {
byte[] buffer = new byte[2];
int ret = controlIn(0x95, 0x0706, 0, buffer);
if (ret < 0)
@ -304,17 +305,17 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
@Override
public boolean getCD() throws IOException {
return (getControlLines() & GCL_CD) == 0;
return (getStatus() & GCL_CD) == 0;
}
@Override
public boolean getCTS() throws IOException {
return (getControlLines() & GCL_CTS) == 0;
return (getStatus() & GCL_CTS) == 0;
}
@Override
public boolean getDSR() throws IOException {
return (getControlLines() & GCL_DSR) == 0;
return (getStatus() & GCL_DSR) == 0;
}
@Override
@ -330,7 +331,7 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
@Override
public boolean getRI() throws IOException {
return (getControlLines() & GCL_RI) == 0;
return (getStatus() & GCL_RI) == 0;
}
@Override
@ -344,6 +345,23 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
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> getSupportedControlLines() throws IOException {
return EnumSet.allOf(ControlLine.class);
}
}
public static Map<Integer, int[]> getSupportedDevices() {

Wyświetl plik

@ -29,6 +29,7 @@ import android.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.EnumSet;
/**
* A base class shared by several driver implementations.
@ -249,6 +250,12 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
@Override
public abstract void setRTS(boolean value) throws IOException;
@Override
public abstract EnumSet<ControlLine> getControlLines() throws IOException;
@Override
public abstract EnumSet<ControlLine> getSupportedControlLines() throws IOException;
@Override
public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
return false;

Wyświetl plik

@ -29,6 +29,7 @@ import android.hardware.usb.UsbInterface;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -299,6 +300,19 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
setConfigSingle(SILABSER_SET_DTR_RTS_REQUEST_CODE, rts ? RTS_ENABLE : RTS_DISABLE);
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(rts) set.add(ControlLine.RTS);
if(dtr) set.add(ControlLine.DTR);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.of(ControlLine.RTS, ControlLine.DTR);
}
@Override
public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
int value = (purgeReadBuffers ? FLUSH_READ_CODE : 0)

Wyświetl plik

@ -28,6 +28,7 @@ import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -527,6 +528,24 @@ public class FtdiSerialDriver implements UsbSerialDriver {
mRtsState = value;
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
int status = getModemStatus();
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(mRtsState) set.add(ControlLine.RTS);
if((status & SIO_MODEM_STATUS_CTS) != 0) set.add(ControlLine.CTS);
if(mDtrState) set.add(ControlLine.DTR);
if((status & SIO_MODEM_STATUS_DSR) != 0) set.add(ControlLine.DSR);
if((status & SIO_MODEM_STATUS_RLSD) != 0) set.add(ControlLine.CD);
if((status & SIO_MODEM_STATUS_RI) != 0) set.add(ControlLine.RI);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.allOf(ControlLine.class);
}
@Override
public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
if (purgeWriteBuffers) {

Wyświetl plik

@ -37,6 +37,7 @@ import android.util.Log;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -426,7 +427,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
@Override
public boolean getDTR() throws IOException {
return ((mControlLinesValue & CONTROL_DTR) == CONTROL_DTR);
return (mControlLinesValue & CONTROL_DTR) != 0;
}
@Override
@ -447,7 +448,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
@Override
public boolean getRTS() throws IOException {
return ((mControlLinesValue & CONTROL_RTS) == CONTROL_RTS);
return (mControlLinesValue & CONTROL_RTS) != 0;
}
@Override
@ -461,6 +462,25 @@ public class ProlificSerialDriver implements UsbSerialDriver {
setControlLines(newControlLinesValue);
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
int status = getStatus();
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if((mControlLinesValue & CONTROL_RTS) != 0) set.add(ControlLine.RTS);
if((status & STATUS_FLAG_CTS) != 0) set.add(ControlLine.CTS);
if((mControlLinesValue & CONTROL_DTR) != 0) set.add(ControlLine.DTR);
if((status & STATUS_FLAG_DSR) != 0) set.add(ControlLine.DSR);
if((status & STATUS_FLAG_CD) != 0) set.add(ControlLine.CD);
if((status & STATUS_FLAG_RI) != 0) set.add(ControlLine.RI);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.allOf(ControlLine.class);
}
@Override
public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
if (purgeWriteBuffers) {

Wyświetl plik

@ -27,6 +27,7 @@ import android.hardware.usb.UsbManager;
import java.io.Closeable;
import java.io.IOException;
import java.util.EnumSet;
/**
* Interface for a single serial port.
@ -86,6 +87,12 @@ public interface UsbSerialPort extends Closeable {
/** 2 stop bits. */
public static final int STOPBITS_2 = 2;
/** values for get[Supported]ControlLines() */
public enum ControlLine { RTS, CTS, DTR, DSR, CD, RI };
/**
* Returns the driver used by this port.
*/
public UsbSerialDriver getDriver();
/**
@ -100,6 +107,9 @@ public interface UsbSerialPort extends Closeable {
/**
* The serial number of the underlying UsbDeviceConnection, or {@code null}.
*
* @return value from {@link UsbDeviceConnection#getSerial()}
* @throws SecurityException starting with target SDK 29 (Android 10) if permission for USB device is not granted
*/
public String getSerial();
@ -189,8 +199,7 @@ public interface UsbSerialPort extends Closeable {
public boolean getDTR() throws IOException;
/**
* Sets the DTR (Data Terminal Ready) bit on the underlying UART, if
* supported.
* Sets the DTR (Data Terminal Ready) bit on the underlying UART, if supported.
*
* @param value the value to set
* @throws IOException if an error occurred during writing
@ -214,14 +223,30 @@ public interface UsbSerialPort extends Closeable {
public boolean getRTS() throws IOException;
/**
* Sets the RTS (Request To Send) bit on the underlying UART, if
* supported.
* Sets the RTS (Request To Send) bit on the underlying UART, if supported.
*
* @param value the value to set
* @throws IOException if an error occurred during writing
*/
public void setRTS(boolean value) throws IOException;
/**
* Gets all control line values from the underlying UART, if supported.
* Requires less USB calls than calling getRTS() + ... + getRI() individually.
*
* @return EnumSet.contains(...) is {@code true} if set, else {@code false}
* @throws IOException
*/
public EnumSet<ControlLine> getControlLines() throws IOException;
/**
* Gets all control line supported flags.
*
* @return EnumSet.contains(...) is {@code true} if supported, else {@code false}
* @throws IOException
*/
public EnumSet<ControlLine> getSupportedControlLines() throws IOException;
/**
* purge non-transmitted output data and / or non-read input data
* @param purgeWriteBuffers {@code true} to discard non-transmitted output data