/* * RomRaider Open-Source Tuning, Logging and Reflashing * Copyright (C) 2006-2014 RomRaider.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.romraider.io.j2534.api; import static com.romraider.util.ParamChecker.checkNotNull; import static org.apache.log4j.Logger.getLogger; import org.apache.log4j.Logger; import com.romraider.io.connection.ConnectionManager; import com.romraider.io.connection.ConnectionProperties; import com.romraider.io.j2534.api.J2534Impl.Config; import com.romraider.io.j2534.api.J2534Impl.Protocol; import com.romraider.io.j2534.api.J2534Impl.TxFlags; import com.romraider.logger.ecu.comms.manager.PollingState; import com.romraider.util.SettingsManager; public final class J2534ConnectionISO15765 implements ConnectionManager { private static final Logger LOGGER = getLogger(J2534ConnectionISO15765.class); private J2534 api; private int channelId; private int deviceId; private int msgId; private final long timeout; public J2534ConnectionISO15765( ConnectionProperties connectionProperties, String library) { api = null; timeout = 2000; initJ2534(500000, library); LOGGER.info("J2534/ISO15765 connection initialized"); } // Send request and wait for response with known length @Override public void send(byte[] request, byte[] response, PollingState pollState) { checkNotNull(request, "request"); checkNotNull(response, "response"); checkNotNull(pollState, "pollState"); pollState.setFastPoll(false); pollState.setCurrentState(PollingState.State.STATE_0); api.writeMsg(channelId, request, timeout, TxFlags.ISO15765_FRAME_PAD); final byte[] readMsg = api.readMsg(channelId, 1, timeout); System.arraycopy(readMsg, 0, response, 0, readMsg.length) ; } // Send request and wait specified time for one response with unknown length @Override public byte[] send(byte[] request) { checkNotNull(request, "request"); api.writeMsg(channelId, request, timeout, TxFlags.ISO15765_FRAME_PAD); return api.readMsg(channelId, 1, timeout); } @Override public void clearLine() { // LOGGER.debug("J2534/ISO15765 clearing buffers"); // api.clearBuffers(channelId); } @Override public void close() { stopFcFilter(); disconnectChannel(); closeDevice(); } private void initJ2534(int baudRate, String library) { api = new J2534Impl(Protocol.ISO15765, library); deviceId = api.open(); try { version(deviceId); channelId = api.connect(deviceId, 0, baudRate); setConfig(channelId); final byte[] mask = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; final byte[] pattern = SettingsManager.getSettings().getDestinationTarget().getAddress(); final byte[] flowCntrl = SettingsManager.getSettings().getDestinationTarget().getTester(); msgId = api.startFlowCntrlFilter( channelId, mask, pattern, flowCntrl, TxFlags.ISO15765_FRAME_PAD); LOGGER.debug(String.format( "J2534/ISO15765 success: deviceId:%d, channelId:%d, msgId:%d", deviceId, channelId, msgId)); } catch (Exception e) { LOGGER.debug(String.format( "J2534/ISO15765 exception: deviceId:%d, channelId:%d, msgId:%d", deviceId, channelId, msgId)); close(); throw new J2534Exception("J2534/ISO15765 Error opening device: " + e.getMessage(), e); } } private void version(int deviceId) { if (!LOGGER.isDebugEnabled()) return; final Version version = api.readVersion(deviceId); LOGGER.info("J2534 Version => firmware: " + version.firmware + ", dll: " + version.dll + ", api: " + version.api); } private void setConfig(int channelId) { final ConfigItem loopback = new ConfigItem(Config.LOOPBACK.getValue(), 0); final ConfigItem bs = new ConfigItem(Config.ISO15765_BS.getValue(), 0); final ConfigItem stMin = new ConfigItem(Config.ISO15765_STMIN.getValue(), 0); final ConfigItem bs_tx = new ConfigItem(Config.BS_TX.getValue(), 0xffff); final ConfigItem st_tx = new ConfigItem(Config.STMIN_TX.getValue(), 0xffff); final ConfigItem wMax = new ConfigItem(Config.ISO15765_WFT_MAX.getValue(), 0); api.setConfig(channelId, loopback, bs, stMin, bs_tx, st_tx, wMax); } private void stopFcFilter() { try { api.stopMsgFilter(channelId, msgId); LOGGER.debug("J2534/ISO15765 stopped message filter:" + msgId); } catch (Exception e) { LOGGER.warn("J2534/ISO15765 Error stopping msg filter: " + e.getMessage()); } } private void disconnectChannel() { try { api.disconnect(channelId); LOGGER.debug("J2534/ISO15765 disconnected channel:" + channelId); } catch (Exception e) { LOGGER.warn("J2534/ISO15765 Error disconnecting channel: " + e.getMessage()); } } private void closeDevice() { try { api.close(deviceId); LOGGER.info("J2534/ISO15765 closed connection to device:" + deviceId); } catch (Exception e) { LOGGER.warn("J2534/ISO15765 Error closing device: " + e.getMessage()); } } }