add j2534 support

git-svn-id: https://svn2.assembla.com/svn/romraider/trunk@156 38686702-15cf-42e4-a595-3071df8bf5ea
This commit is contained in:
kascade 2008-09-23 12:28:57 +00:00
parent 7977fbc9fa
commit c4114ab743
11 changed files with 135 additions and 85 deletions

View File

@ -22,7 +22,6 @@
package com.romraider.io.connection;
public interface ConnectionManager {
void send(byte[] request, byte[] response, long sendTimeout);
byte[] send(byte[] bytes, long maxWait);

View File

@ -43,6 +43,7 @@ public final class J2534ConnectionManager implements ConnectionManager {
public J2534ConnectionManager(ConnectionProperties connectionProperties) {
checkNotNull(connectionProperties, "connectionProperties");
initJ2534(connectionProperties.getBaudRate());
LOGGER.info("J2534 connection initialised");
}
// Send request and wait for response with known length
@ -66,14 +67,21 @@ public final class J2534ConnectionManager implements ConnectionManager {
stopMsgFilter();
disconnectChannel();
closeDevice();
resetHandles();
LOGGER.info("J2534 connection closed");
}
private void initJ2534(int baudRate) {
this.deviceId = api.open();
deviceId = api.open();
try {
version(deviceId);
this.channelId = api.connect(deviceId, FLAG_ISO9141_NO_CHECKSUM, baudRate);
channelId = api.connect(deviceId, FLAG_ISO9141_NO_CHECKSUM, baudRate);
setConfig(channelId);
this.msgId = api.startPassMsgFilter(channelId, (byte) 0x00, (byte) 0x00);
msgId = api.startPassMsgFilter(channelId, (byte) 0x00, (byte) 0x00);
} catch (Exception e) {
close();
throw new J2534Exception("Error during J2534 init: " + e.getMessage(), e);
}
}
private void version(int deviceId) {
@ -91,25 +99,31 @@ public final class J2534ConnectionManager implements ConnectionManager {
private void stopMsgFilter() {
try {
api.stopMsgFilter(channelId, msgId);
if (channelId > 0 && msgId > 0) api.stopMsgFilter(channelId, msgId);
} catch (Exception e) {
LOGGER.warn("Error stopping msg filter");
LOGGER.warn("Error stopping msg filter: " + e.getMessage());
}
}
private void disconnectChannel() {
try {
api.disconnect(channelId);
if (channelId > 0) api.disconnect(channelId);
} catch (Exception e) {
LOGGER.warn("Error disconnecting channel");
LOGGER.warn("Error disconnecting channel: " + e.getMessage());
}
}
private void closeDevice() {
try {
api.close(deviceId);
if (deviceId > 0) api.close(deviceId);
} catch (Exception e) {
LOGGER.warn("Error closing device");
LOGGER.warn("Error closing device: " + e.getMessage());
}
}
private void resetHandles() {
channelId = 0;
deviceId = 0;
msgId = 0;
}
}

View File

@ -4,4 +4,8 @@ public final class J2534Exception extends RuntimeException {
public J2534Exception(String msg) {
super(msg);
}
public J2534Exception(String msg, Throwable t) {
super(msg, t);
}
}

View File

@ -21,13 +21,16 @@
package com.romraider.logger.ecu.comms.io.connection;
import com.romraider.logger.ecu.comms.query.EcuInitCallback;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import java.util.Collection;
public interface LoggerConnection {
void ecuReset();
void ecuInit(EcuInitCallback callback);
void sendAddressReads(Collection<EcuQuery> queries);
void close();
}

View File

@ -21,23 +21,38 @@
package com.romraider.logger.ecu.comms.io.connection;
import com.romraider.io.connection.ConnectionManager;
import com.romraider.io.connection.ConnectionProperties;
import com.romraider.io.j2534.api.J2534ConnectionManager;
import com.romraider.io.serial.connection.SerialConnectionManager;
import com.romraider.logger.ecu.exception.UnsupportedProtocolException;
import org.apache.log4j.Logger;
import static org.apache.log4j.Logger.getLogger;
public final class LoggerConnectionFactory {
private static final LoggerConnectionFactory INSTANCE = new LoggerConnectionFactory();
private static final Logger LOGGER = getLogger(LoggerConnectionFactory.class);
private LoggerConnectionFactory() {
}
public static LoggerConnectionFactory getInstance() {
return INSTANCE;
public static LoggerConnection getConnection(String protocolName, String portName, ConnectionProperties connectionProperties) {
ConnectionManager manager = getManager(portName, connectionProperties);
return instantiateConnection(protocolName, manager);
}
public LoggerConnection getLoggerConnection(String protocolName, String portName, ConnectionProperties connectionProperties) {
private static ConnectionManager getManager(String portName, ConnectionProperties connectionProperties) {
try {
Class<?> cls = Class.forName(this.getClass().getPackage().getName() + "." + protocolName + "LoggerConnection");
return (LoggerConnection) cls.getConstructor(String.class, ConnectionProperties.class).newInstance(portName, connectionProperties);
return new J2534ConnectionManager(connectionProperties);
} catch (Exception e) {
LOGGER.info("J2534 connection not available [" + e.getMessage() + "], trying serial connection...");
return new SerialConnectionManager(portName, connectionProperties);
}
}
private static LoggerConnection instantiateConnection(String protocolName, ConnectionManager manager) {
try {
Class<?> cls = Class.forName(LoggerConnectionFactory.class.getPackage().getName() + "." + protocolName + "LoggerConnection");
return (LoggerConnection) cls.getConstructor(ConnectionManager.class).newInstance(manager);
} catch (Exception e) {
throw new UnsupportedProtocolException("'" + protocolName + "' is not a supported protocol", e);
}

View File

@ -22,38 +22,52 @@
package com.romraider.logger.ecu.comms.io.connection;
import com.romraider.io.connection.ConnectionManager;
import com.romraider.io.connection.ConnectionProperties;
import com.romraider.io.j2534.api.J2534ConnectionManager;
import com.romraider.logger.ecu.comms.io.protocol.LoggerProtocol;
import com.romraider.logger.ecu.comms.io.protocol.SSMLoggerProtocol;
import com.romraider.logger.ecu.comms.query.EcuInitCallback;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import static com.romraider.util.HexUtil.asHex;
import static com.romraider.util.ParamChecker.checkNotNull;
import static com.romraider.util.ParamChecker.checkNotNullOrEmpty;
import org.apache.log4j.Logger;
import static org.apache.log4j.Logger.getLogger;
import java.util.Collection;
public final class SSMLoggerConnection implements LoggerConnection {
private static final Logger LOGGER = getLogger(SSMLoggerConnection.class);
private static final long SEND_TIMEOUT = 2000L;
private final LoggerProtocol protocol = new SSMLoggerProtocol();
private final ConnectionManager manager;
public SSMLoggerConnection(String portName, ConnectionProperties connectionProperties) {
checkNotNullOrEmpty(portName, "portName");
checkNotNull(connectionProperties);
// this.manager = new SerialConnectionManager(portName, connectionProperties);
this.manager = new J2534ConnectionManager(connectionProperties);
public SSMLoggerConnection(ConnectionManager manager) {
checkNotNull(manager, "manager");
this.manager = manager;
}
public void ecuReset() {
byte[] request = protocol.constructEcuResetRequest();
LOGGER.debug("Ecu Reset Request ---> " + asHex(request));
byte[] response = manager.send(request, SEND_TIMEOUT);
byte[] processedResponse = protocol.preprocessResponse(request, response);
LOGGER.debug("Ecu Reset Response <--- " + asHex(processedResponse));
protocol.processEcuResetResponse(processedResponse);
}
public void ecuInit(EcuInitCallback callback) {
byte[] request = protocol.constructEcuInitRequest();
LOGGER.debug("Ecu Init Request ---> " + asHex(request));
byte[] response = manager.send(request, SEND_TIMEOUT);
byte[] processedResponse = protocol.preprocessResponse(request, response);
LOGGER.debug("Ecu Init Response <--- " + asHex(processedResponse));
protocol.processEcuInitResponse(callback, processedResponse);
}
public void sendAddressReads(Collection<EcuQuery> queries) {
byte[] request = protocol.constructReadAddressRequest(queries);
byte[] response = protocol.constructReadAddressResponse(queries);
LOGGER.trace("ECU Request ---> " + asHex(request));
manager.send(request, response, SEND_TIMEOUT);
byte[] processedResponse = protocol.preprocessResponse(request, response);
// LOGGER.trace("ECU Request ---> " + asHex(request));
// LOGGER.trace("ECU Response <--- " + asHex(processedResponse));
LOGGER.trace("ECU Response <--- " + asHex(processedResponse));
protocol.processReadAddressResponses(queries, processedResponse);
}

View File

@ -21,16 +21,25 @@
package com.romraider.logger.ecu.comms.io.protocol;
import com.romraider.logger.ecu.comms.query.EcuInitCallback;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import java.util.Collection;
public interface LoggerProtocol {
byte[] constructEcuInitRequest();
byte[] constructEcuResetRequest();
byte[] constructReadAddressRequest(Collection<EcuQuery> queries);
byte[] constructReadAddressResponse(Collection<EcuQuery> queries);
byte[] preprocessResponse(byte[] request, byte[] response);
void processEcuInitResponse(EcuInitCallback callback, byte[] response);
void processEcuResetResponse(byte[] response);
void processReadAddressResponses(Collection<EcuQuery> queries, byte[] response);
}

View File

@ -29,7 +29,10 @@ import static com.romraider.io.protocol.ssm.SSMProtocol.REQUEST_NON_DATA_BYTES;
import static com.romraider.io.protocol.ssm.SSMProtocol.RESPONSE_NON_DATA_BYTES;
import static com.romraider.io.protocol.ssm.SSMResponseProcessor.extractResponseData;
import static com.romraider.io.protocol.ssm.SSMResponseProcessor.filterRequestFromResponse;
import com.romraider.logger.ecu.comms.query.EcuInit;
import com.romraider.logger.ecu.comms.query.EcuInitCallback;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import static com.romraider.util.ParamChecker.checkNotNull;
import static com.romraider.util.ParamChecker.checkNotNullOrEmpty;
import java.util.ArrayList;
import java.util.Collection;
@ -39,6 +42,14 @@ import java.util.Map;
public final class SSMLoggerProtocol implements LoggerProtocol {
private final Protocol protocol = new SSMProtocol();
public byte[] constructEcuInitRequest() {
return protocol.constructEcuInitRequest();
}
public byte[] constructEcuResetRequest() {
return protocol.constructEcuResetRequest();
}
public byte[] constructReadAddressRequest(Collection<EcuQuery> queries) {
Collection<EcuQuery> filteredQueries = filterDuplicates(queries);
return protocol.constructReadAddressRequest(convertToByteAddresses(filteredQueries));
@ -60,6 +71,19 @@ public final class SSMLoggerProtocol implements LoggerProtocol {
return filterRequestFromResponse(request, response);
}
public void processEcuInitResponse(EcuInitCallback callback, byte[] response) {
checkNotNull(callback, "callback");
checkNotNullOrEmpty(response, "response");
protocol.checkValidEcuInitResponse(response);
EcuInit ecuInit = protocol.parseEcuInitResponse(response);
callback.callback(ecuInit);
}
public void processEcuResetResponse(byte[] response) {
checkNotNullOrEmpty(response, "response");
protocol.checkValidEcuResetResponse(response);
}
// processes the response bytes and sets individual responses on corresponding query objects
@SuppressWarnings({"PointlessArithmeticExpression"})
public void processReadAddressResponses(Collection<EcuQuery> queries, byte[] response) {

View File

@ -22,11 +22,8 @@
package com.romraider.logger.ecu.comms.manager;
import com.romraider.Settings;
import com.romraider.io.connection.ConnectionManager;
import com.romraider.io.connection.ConnectionProperties;
import com.romraider.io.j2534.api.J2534ConnectionManager;
import com.romraider.io.protocol.Protocol;
import static com.romraider.io.protocol.ProtocolFactory.getProtocol;
import com.romraider.logger.ecu.comms.io.connection.LoggerConnection;
import static com.romraider.logger.ecu.comms.io.connection.LoggerConnectionFactory.getConnection;
import com.romraider.logger.ecu.comms.query.EcuInitCallback;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import com.romraider.logger.ecu.comms.query.EcuQueryImpl;
@ -43,7 +40,6 @@ import com.romraider.logger.ecu.ui.MessageListener;
import com.romraider.logger.ecu.ui.StatusChangeListener;
import com.romraider.logger.ecu.ui.handler.DataUpdateHandler;
import com.romraider.logger.ecu.ui.handler.file.FileLoggerControllerSwitchMonitor;
import static com.romraider.util.HexUtil.asHex;
import static com.romraider.util.ParamChecker.checkNotNull;
import static com.romraider.util.ThreadUtil.runAsDaemon;
import static com.romraider.util.ThreadUtil.sleep;
@ -141,23 +137,15 @@ public final class QueryManagerImpl implements QueryManager {
private boolean doEcuInit() {
try {
Protocol protocol = getProtocol(settings.getLoggerProtocol());
ConnectionProperties connectionProperties = settings.getLoggerConnectionProperties();
// ConnectionManager connectionManager = new SerialConnectionManager(settings.getLoggerPort(), connectionProperties);
ConnectionManager connectionManager = new J2534ConnectionManager(connectionProperties);
LoggerConnection connection = getConnection(settings.getLoggerProtocol(), settings.getLoggerPort(),
settings.getLoggerConnectionProperties());
try {
messageListener.reportMessage("Sending ECU Init...");
byte[] request = protocol.constructEcuInitRequest();
LOGGER.debug("Ecu Init Request ---> " + asHex(request));
byte[] response = connectionManager.send(request, 500L);
byte[] processedResponse = protocol.preprocessResponse(request, response);
protocol.checkValidEcuInitResponse(processedResponse);
LOGGER.debug("Ecu Init Response <--- " + asHex(processedResponse));
ecuInitCallback.callback(protocol.parseEcuInitResponse(processedResponse));
connection.ecuInit(ecuInitCallback);
messageListener.reportMessage("Sending ECU Init...done.");
return true;
} finally {
connectionManager.close();
connection.close();
}
} catch (Exception e) {
messageListener.reportMessage("Unable to send ECU init - check correct serial port has been selected, cable is connected and ignition is on.");

View File

@ -23,16 +23,16 @@ package com.romraider.logger.ecu.comms.manager;
import com.romraider.Settings;
import com.romraider.logger.ecu.comms.io.connection.LoggerConnection;
import com.romraider.logger.ecu.comms.io.connection.LoggerConnectionFactory;
import static com.romraider.logger.ecu.comms.io.connection.LoggerConnectionFactory.getConnection;
import com.romraider.logger.ecu.comms.query.EcuQuery;
import com.romraider.logger.ecu.exception.NotConnectedException;
import com.romraider.logger.ecu.exception.SerialCommunicationException;
import static com.romraider.util.ParamChecker.checkNotNull;
import org.apache.log4j.Logger;
import static org.apache.log4j.Logger.getLogger;
import java.util.Collection;
public final class TransmissionManagerImpl implements TransmissionManager {
private static final Logger LOGGER = Logger.getLogger(TransmissionManagerImpl.class);
private static final Logger LOGGER = getLogger(TransmissionManagerImpl.class);
private final Settings settings;
private LoggerConnection connection;
@ -43,30 +43,21 @@ public final class TransmissionManagerImpl implements TransmissionManager {
public void start() {
try {
connection = LoggerConnectionFactory.getInstance().getLoggerConnection(settings.getLoggerProtocol(), settings.getLoggerPort(),
settings.getLoggerConnectionProperties());
LOGGER.info("Connected to: " + settings.getLoggerPort() + "; using protocol: " + settings.getLoggerProtocol() + "; conn props: "
+ settings.getLoggerConnectionProperties());
connection = getConnection(settings.getLoggerProtocol(), settings.getLoggerPort(), settings.getLoggerConnectionProperties());
LOGGER.info("Connected.");
} catch (Throwable e) {
stop();
throw new SerialCommunicationException("Unable to connect to port: " + settings.getLoggerPort() + ", with protocol: "
+ settings.getLoggerProtocol(), e);
}
}
public void sendQueries(Collection<EcuQuery> queries) {
checkNotNull(queries, "queries");
if (connection != null) {
if (connection == null) throw new NotConnectedException("TransmissionManager must be started before queries can be sent!");
connection.sendAddressReads(queries);
} else {
throw new NotConnectedException("TransmissionManager must be started before queries can be sent!");
}
}
public void stop() {
if (connection != null) {
connection.close();
}
if (connection != null) connection.close();
LOGGER.info("Disconnected.");
}

View File

@ -22,13 +22,9 @@
package com.romraider.logger.ecu.comms.reset;
import com.romraider.Settings;
import com.romraider.io.connection.ConnectionManager;
import com.romraider.io.connection.ConnectionProperties;
import com.romraider.io.j2534.api.J2534ConnectionManager;
import com.romraider.io.protocol.Protocol;
import static com.romraider.io.protocol.ProtocolFactory.getProtocol;
import com.romraider.logger.ecu.comms.io.connection.LoggerConnection;
import static com.romraider.logger.ecu.comms.io.connection.LoggerConnectionFactory.getConnection;
import com.romraider.logger.ecu.ui.MessageListener;
import static com.romraider.util.HexUtil.asHex;
import static com.romraider.util.ParamChecker.checkNotNull;
import org.apache.log4j.Logger;
@ -45,22 +41,15 @@ public final class ResetManagerImpl implements ResetManager {
public boolean resetEcu() {
try {
Protocol protocol = getProtocol(settings.getLoggerProtocol());
ConnectionProperties connectionProperties = settings.getLoggerConnectionProperties();
// ConnectionManager connectionManager = new SerialConnectionManager(settings.getLoggerPort(), connectionProperties);
ConnectionManager connectionManager = new J2534ConnectionManager(connectionProperties);
LoggerConnection connection = getConnection(settings.getLoggerProtocol(), settings.getLoggerPort(),
settings.getLoggerConnectionProperties());
try {
messageListener.reportMessage("Sending ECU Reset...");
byte[] request = protocol.constructEcuResetRequest();
LOGGER.debug("Ecu Reset Request ---> " + asHex(request));
byte[] response = connectionManager.send(request, 500L);
byte[] processedResponse = protocol.preprocessResponse(request, response);
protocol.checkValidEcuResetResponse(processedResponse);
LOGGER.debug("Ecu Reset Response <--- " + asHex(processedResponse));
connection.ecuReset();
messageListener.reportMessage("Sending ECU Reset...done.");
return true;
} finally {
connectionManager.close();
connection.close();
}
} catch (Exception e) {
messageListener.reportMessage("Unable to reset ecu - check correct serial port has been selected, cable is connected and ignition is on.");