/* * RomRaider Open-Source Tuning, Logging and Reflashing * Copyright (C) 2006-2015 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.logger.ecu.comms.io.connection; import static com.romraider.util.HexUtil.asHex; import static com.romraider.util.ParamChecker.checkNotNull; import static org.apache.log4j.Logger.getLogger; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import com.romraider.Settings; import com.romraider.io.connection.ConnectionManager; import com.romraider.io.protocol.ProtocolFactory; import com.romraider.logger.ecu.comms.io.protocol.LoggerProtocolDS2; import com.romraider.logger.ecu.comms.manager.PollingState; import com.romraider.logger.ecu.comms.manager.PollingStateImpl; import com.romraider.logger.ecu.comms.query.EcuInitCallback; import com.romraider.logger.ecu.comms.query.EcuQuery; import com.romraider.logger.ecu.comms.query.EcuQueryRangeTest; import com.romraider.logger.ecu.definition.EcuData; import com.romraider.logger.ecu.definition.Module; import com.romraider.util.SettingsManager; public final class DS2LoggerConnection implements LoggerConnection { private static final Logger LOGGER = getLogger(DS2LoggerConnection.class); private final LoggerProtocolDS2 protocol; private final ConnectionManager manager; Settings settings = SettingsManager.getSettings(); public DS2LoggerConnection(ConnectionManager manager) { checkNotNull(manager, "manager"); this.manager = manager; this.protocol = (LoggerProtocolDS2) ProtocolFactory.getProtocol( settings.getLoggerProtocol(), settings.getTransportProtocol()); } @Override public void ecuReset(Module module, int resetCode) { byte[] request = protocol.constructEcuResetRequest(module, resetCode); LOGGER.debug(module + " Reset Request ---> " + asHex(request)); byte[] response = manager.send(request); byte[] processedResponse = protocol.preprocessResponse(request, response, new PollingStateImpl()); LOGGER.debug(module + " Reset Response <--- " + asHex(processedResponse)); protocol.processEcuResetResponse(processedResponse); } @Override public void ecuInit(EcuInitCallback callback, Module module) { byte[] request = protocol.constructEcuInitRequest(module); LOGGER.debug(module + " Init Request ---> " + asHex(request)); byte[] response = manager.send(request); LOGGER.trace(module + " Init Raw Response <--- " + asHex(response)); byte[] processedResponse = protocol.preprocessResponse(request, response, new PollingStateImpl()); LOGGER.debug(module + " Init Response <--- " + asHex(processedResponse)); protocol.processEcuInitResponse(callback, processedResponse); } @Override public final void sendAddressReads( Collection<EcuQuery> queries, Module module, PollingState pollState) { final Map<String, Collection<EcuQuery>> groupList = getGroupList(queries); for (String group : groupList.keySet().toArray(new String[0])) { final Collection<EcuQuery> querySet = groupList.get(group); byte[] request = new byte[0]; byte[] response = new byte[0]; if (group.equalsIgnoreCase("0x0b0x020e")) { for (EcuQuery query : querySet) { final Collection<EcuQuery> queryList = new ArrayList<EcuQuery>(); queryList.add(query); request = protocol.constructReadAddressRequest( module, queryList); LOGGER.debug("Mode:" + pollState.getCurrentState() + " " + module + " Request ---> " + asHex(request)); response = protocol.constructReadAddressResponse( queryList, request.length); protocol.processReadAddressResponses( queryList, sendRcv(module, request, response, pollState), pollState); } } else if (group.equalsIgnoreCase("0x060x00")) { final EcuQueryRangeTest range = new EcuQueryRangeTest(querySet); final Collection<EcuQuery> newQuery = range.validate(); int length = range.getLength(); if (newQuery != null && length > 0) { request = protocol.constructReadMemoryRange( module, newQuery, length); LOGGER.debug("Mode:" + pollState.getCurrentState() + " " + module + " Request ---> " + asHex(request)); response = protocol.constructReadMemoryRangeResponse( request.length, length); protocol.processReadMemoryRangeResponse( querySet, sendRcv(module, request, response, pollState)); } else { for (EcuQuery query : querySet) { final Collection<EcuQuery> queryList = new ArrayList<EcuQuery>(); queryList.add(query); request = protocol.constructReadMemoryRequest( module, queryList); LOGGER.debug("Mode:" + pollState.getCurrentState() + " " + module + " Request ---> " + asHex(request)); response = protocol.constructReadAddressResponse( queryList, request.length); protocol.processReadAddressResponses( queryList, sendRcv(module, request, response, pollState), pollState); } } } else { request = protocol.constructReadGroupRequest( module, group); LOGGER.debug("Mode:" + pollState.getCurrentState() + " " + module + " Request ---> " + asHex(request)); response = protocol.constructReadGroupResponse( querySet, request.length); protocol.processReadAddressResponses( querySet, sendRcv(module, request, response, pollState), pollState); } } } @Override public void clearLine() { manager.clearLine(); } @Override public void close() { manager.close(); } @Override public final void sendAddressWrites( Map<EcuQuery, byte[]> writeQueries, Module module) { for (EcuQuery writeKey : writeQueries.keySet()) { if (writeKey.getBytes().length == 3) { final byte[] request = protocol.constructWriteAddressRequest( module, writeKey.getBytes(), writeQueries.get(writeKey)[0]); LOGGER.debug(module + " Write Request ---> " + asHex(request)); final byte[] response = manager.send(request); byte[] processedResponse = protocol.preprocessResponse( request, response, new PollingStateImpl()); LOGGER.debug(module + " Write Response <--- " + asHex(processedResponse)); protocol.processWriteResponse( writeQueries.get(writeKey), processedResponse); } } } // Create a map of groups each with a value of a list of queries having the same group private Map<String, Collection<EcuQuery>> getGroupList(Collection<EcuQuery> queries) { final Map<String, Collection<EcuQuery>> groups = new HashMap<String, Collection<EcuQuery>>(); String group; String subGroup; for (EcuQuery query : queries) { group = ((EcuData) query.getLoggerData()).getGroup(); subGroup = ((EcuData) query.getLoggerData()).getSubgroup(); group = group + (subGroup == null ? "" : subGroup); if (!groups.containsKey(group)) { final Collection<EcuQuery> queryList = new ArrayList<EcuQuery>(); queryList.add(query); groups.put(group, queryList); } else { groups.get(group).add(query); } } return groups; } private byte[] sendRcv(Module module, byte[] request, byte[] response, PollingState pollState) { manager.send(request, response, pollState); LOGGER.trace(module + " Read Raw Response <--- " + asHex(response)); final byte[] processedResponse = protocol.preprocessResponse( request, response, pollState); LOGGER.debug("Mode:" + pollState.getCurrentState() + " " + module + " Response <--- " + asHex(processedResponse)); return processedResponse; } }