[elerotransmitterstick] Drop responses that do not fit the command that was sent. (#9562)

Signed-off-by: vbier <volker.bier@web.de>
This commit is contained in:
vbier 2020-12-31 11:01:01 +01:00 committed by GitHub
parent 220115c734
commit ee72664d47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 13 deletions

View File

@ -28,7 +28,7 @@ public class CommandPacket {
data = new byte[bytes.length + 1];
System.arraycopy(bytes, 0, data, 0, bytes.length);
data[bytes.length] = checksum(data);
data[bytes.length] = checksum(bytes);
}
public byte[] getBytes() {
@ -36,7 +36,7 @@ public class CommandPacket {
}
public long getResponseTimeout() {
if (data[2] == EASY_CHECK) {
if (isEasyCheck()) {
return 1000;
}
@ -54,6 +54,10 @@ public class CommandPacket {
return (byte) (256 - val);
}
public boolean isEasyCheck() {
return data[2] == EASY_CHECK;
}
@Override
public String toString() {
return HexUtils.bytesToHex(data);

View File

@ -46,6 +46,16 @@ public class Response {
return status;
}
public boolean isResponseFor(CommandPacket cmd) {
if (cmd == null || cmd.isEasyCheck()) {
return false;
}
byte[] cmdBytes = cmd.getBytes();
int[] cmdChannels = ResponseUtil.getChannelIds(cmdBytes[3], cmdBytes[4]);
return Arrays.equals(channels, cmdChannels);
}
@Override
public String toString() {
return status + " for channels " + Arrays.toString(channels);

View File

@ -30,7 +30,7 @@ public class ResponseUtil {
/**
* returns the list of channels (starting with 1)
*/
private static int[] getChannelIds(byte upperChannelByte, byte lowerChannelByte) {
public static int[] getChannelIds(byte upperChannelByte, byte lowerChannelByte) {
int[] result = new int[16];
int idx = 0;

View File

@ -25,6 +25,7 @@ import org.openhab.core.io.transport.serial.SerialPortEventListener;
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
import org.openhab.core.util.HexUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,6 +39,7 @@ public class SerialConnection {
private boolean open;
private String portName;
private final List<Byte> bytes = new ArrayList<>();
private CommandPacket lastSentPacket = null;
private Response response = null;
private final SerialPortManager serialPortManager;
@ -106,17 +108,15 @@ public class SerialConnection {
// send a packet to the stick and wait for the response
public synchronized Response sendPacket(CommandPacket p) throws IOException {
if (open) {
Response r = response;
Response r = null;
synchronized (bytes) {
response = null;
lastSentPacket = p;
logger.debug("Writing packet to stick: {}", p);
serialPort.getOutputStream().write(p.getBytes());
if (r != null) {
return r;
}
final long responseTimeout = p.getResponseTimeout();
try {
logger.trace("Waiting {} ms for answer from stick...", responseTimeout);
@ -155,9 +155,10 @@ public class SerialConnection {
}
if (logger.isTraceEnabled()) {
logger.trace("buffer contains {} bytes: {}", bytes.size(),
ArrayUtils.toPrimitive(bytes.toArray(new Byte[bytes.size()])));
logger.trace("buffer contains bytes: {}",
HexUtils.bytesToHex(ArrayUtils.toPrimitive(bytes.toArray(new Byte[bytes.size()]))));
}
if (bytes.size() > 1) {
// second byte should be length byte (has to be either 0x04 or 0x05)
int len = bytes.get(1);
@ -179,7 +180,13 @@ public class SerialConnection {
long val = bytes.get(0) + bytes.get(1) + bytes.get(2) + bytes.get(3) + bytes.get(4)
+ bytes.get(5);
if (val % 256 == 0) {
response = ResponseUtil.createResponse(bytes.get(3), bytes.get(4));
Response r = ResponseUtil.createResponse(bytes.get(3), bytes.get(4));
if (lastSentPacket != null && lastSentPacket.isEasyCheck()) {
response = r;
} else {
logger.warn("response type does not match command {}. Skipping response.",
lastSentPacket);
}
} else {
logger.warn("invalid response checksum. Skipping response.");
}
@ -191,7 +198,12 @@ public class SerialConnection {
long val = bytes.get(0) + bytes.get(1) + bytes.get(2) + bytes.get(3) + bytes.get(4)
+ bytes.get(5) + bytes.get(6);
if (val % 256 == 0) {
response = ResponseUtil.createResponse(bytes.get(3), bytes.get(4), bytes.get(5));
Response r = ResponseUtil.createResponse(bytes.get(3), bytes.get(4), bytes.get(5));
if (r.isResponseFor(lastSentPacket)) {
response = r;
} else {
logger.warn("response does not match command channels. Skipping response.");
}
} else {
logger.warn("invalid response checksum. Skipping response.");
}

View File

@ -274,7 +274,7 @@ public class TransmitterStick {
try {
// in case we have no commands that are currently due, wait for a new one
if (dueCommands.isEmpty()) {
logger.debug("No due commands, invoking take on queue...");
logger.trace("No due commands, invoking take on queue...");
dueCommands.add(cmdQueue.take());
logger.trace("take returned {}", dueCommands.first());
}