ELM327 connector: second HELLO fails fix #3654

This commit is contained in:
rusefillc 2021-12-04 23:16:21 -05:00
parent 9333127fcc
commit 2538d731d1
2 changed files with 58 additions and 7 deletions

View File

@ -1,9 +1,18 @@
package com.rusefi.io.can;
import com.devexperts.logging.Logging;
import com.rusefi.io.IoStream;
import java.util.Arrays;
// CAN multiframe decoder state
class IsoTpCanDecoder {
private static Logging log = Logging.getLogging(IsoTpCanDecoder.class);
static {
log.configureDebugEnabled(false);
}
private final static int ISO_TP_FRAME_FLOW_CONTROL = 3;
final static int ISO_TP_FRAME_SINGLE = 0;
final static int ISO_TP_FRAME_FIRST = 1;
@ -14,7 +23,8 @@ class IsoTpCanDecoder {
public byte[] decodePacket(byte[] data) throws Exception {
int frameType = (data[0] >> 4) & 0xf;
int numBytesAvailable, frameIdx;
int numBytesAvailable;
int frameIdx;
int dataOffset;
switch (frameType) {
case ISO_TP_FRAME_SINGLE:
@ -24,8 +34,11 @@ class IsoTpCanDecoder {
break;
case ISO_TP_FRAME_FIRST:
this.waitingForNumBytes = ((data[0] & 0xf) << 8) | data[1];
if (log.debugEnabled())
log.debug("Total expected: " + waitingForNumBytes);
this.waitingForFrameIndex = 1;
numBytesAvailable = Math.min(this.waitingForNumBytes, 6);
waitingForNumBytes -= numBytesAvailable;
dataOffset = 2;
break;
case ISO_TP_FRAME_CONSECUTIVE:
@ -36,13 +49,18 @@ class IsoTpCanDecoder {
this.waitingForFrameIndex = (this.waitingForFrameIndex + 1) & 0xf;
numBytesAvailable = Math.min(this.waitingForNumBytes, 7);
dataOffset = 1;
waitingForNumBytes -= numBytesAvailable;
if (log.debugEnabled())
log.debug("ISO_TP_FRAME_CONSECUTIVE Got " + numBytesAvailable + ", still expecting: " + waitingForNumBytes);
break;
case ISO_TP_FRAME_FLOW_CONTROL:
throw new Exception("ISO_TP_FRAME_FLOW_CONTROL: should we just ignore the FC frame?");
default:
throw new Exception("Unknown frame type");
}
return Arrays.copyOfRange(data, dataOffset, dataOffset + numBytesAvailable);
byte[] bytes = Arrays.copyOfRange(data, dataOffset, dataOffset + numBytesAvailable);
if (log.debugEnabled())
log.debug(numBytesAvailable + " bytes(s) arrived in this packet:" + IoStream.printHexBinary(bytes));
return bytes;
}
}

View File

@ -1,6 +1,8 @@
package com.rusefi.binaryprotocol.test;
import com.rusefi.binaryprotocol.BinaryProtocol;
import com.rusefi.binaryprotocol.IncomingDataBuffer;
import com.rusefi.config.generated.Fields;
import com.rusefi.io.IoStream;
import com.rusefi.io.can.Elm327Connector;
import com.rusefi.io.serial.BaudRateHolder;
@ -19,10 +21,41 @@ public class Elm327Sandbox {
IoStream tsStream = connector.getTsStream();
String signature = BinaryProtocol.getSignature(tsStream);
System.out.println("Got " + signature + " signature via CAN/ELM327");
IncomingDataBuffer dataBuffer = tsStream.getDataBuffer();
System.out.println("Hello new connection " + dataBuffer.getPendingCount());
String signature2 = BinaryProtocol.getSignature(tsStream);
System.out.println("Got " + signature2 + " signature via CAN/ELM327");
runFcommand("First time", tsStream);
whyDoWeNeedToSleepBetweenCommands();
runFcommand("Second time", tsStream);
whyDoWeNeedToSleepBetweenCommands();
{
String signature = BinaryProtocol.getSignature(tsStream);
System.out.println("Got " + signature + " signature via CAN/ELM327");
}
whyDoWeNeedToSleepBetweenCommands();
{
String signature = BinaryProtocol.getSignature(tsStream);
System.out.println("Let's do it again! Got " + signature + " signature via CAN/ELM327");
}
}
private static void runFcommand(String prefix, IoStream tsStream) throws IOException {
IncomingDataBuffer dataBuffer = tsStream.getDataBuffer();
tsStream.sendPacket(new byte[]{Fields.TS_COMMAND_F});
byte[] fResponse = new byte[3];
dataBuffer.waitForBytes("hello", System.currentTimeMillis(), fResponse.length);
dataBuffer.getData(fResponse);
System.out.println(prefix + " Got F response " + IoStream.printHexBinary(fResponse));
}
/**
* TODO: HUH? what's that about?!
*/
private static void whyDoWeNeedToSleepBetweenCommands() throws InterruptedException {
Thread.sleep(200);
}
}