mirror of https://github.com/rusefi/RomRaider.git
improve innovate protocol support
git-svn-id: https://svn2.assembla.com/svn/romraider/trunk@251 38686702-15cf-42e4-a595-3071df8bf5ea
This commit is contained in:
parent
31826ece0b
commit
bf97ee7a01
|
@ -33,4 +33,6 @@ public interface SerialConnection {
|
|||
void close();
|
||||
|
||||
String readLine();
|
||||
|
||||
int read();
|
||||
}
|
||||
|
|
|
@ -84,6 +84,15 @@ public final class SerialConnectionImpl implements SerialConnection {
|
|||
}
|
||||
}
|
||||
|
||||
public int read() {
|
||||
try {
|
||||
return is.read();
|
||||
} catch (IOException e) {
|
||||
close();
|
||||
throw new SerialCommunicationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void read(byte[] bytes) {
|
||||
try {
|
||||
is.read(bytes, 0, bytes.length);
|
||||
|
|
|
@ -37,8 +37,8 @@ public final class SerialConnectionManager implements ConnectionManager {
|
|||
checkNotNullOrEmpty(portName, "portName");
|
||||
checkNotNull(connectionProperties, "connectionProperties");
|
||||
// Use TestSerialConnection for testing!!
|
||||
// connection = new SerialConnectionImpl(portName, connectionProperties);
|
||||
connection = new TestSerialConnection(portName, connectionProperties);
|
||||
connection = new SerialConnectionImpl(portName, connectionProperties);
|
||||
// connection = new TestSerialConnection(portName, connectionProperties);
|
||||
}
|
||||
|
||||
// Send request and wait for response with known length
|
||||
|
|
|
@ -153,6 +153,10 @@ final class TestSerialConnection implements SerialConnection {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int read() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private int calculateNumResponseDataBytes() {
|
||||
return ((request.length - REQUEST_NON_DATA_BYTES) / ADDRESS_SIZE) * DATA_SIZE;
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.generic.serial.io;
|
||||
|
||||
public interface InnovateConnection {
|
||||
byte[] read();
|
||||
|
||||
void close();
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.generic.serial.io;
|
||||
|
||||
import com.romraider.io.connection.ConnectionProperties;
|
||||
import com.romraider.io.serial.connection.SerialConnection;
|
||||
import com.romraider.io.serial.connection.SerialConnectionImpl;
|
||||
import com.romraider.logger.ecu.exception.SerialCommunicationException;
|
||||
import static com.romraider.util.ByteUtil.matchOnes;
|
||||
import static com.romraider.util.ByteUtil.matchZeroes;
|
||||
import static com.romraider.util.HexUtil.asBytes;
|
||||
import static com.romraider.util.HexUtil.asHex;
|
||||
import static com.romraider.util.ParamChecker.checkGreaterThanZero;
|
||||
import static com.romraider.util.ParamChecker.checkNotNull;
|
||||
import static com.romraider.util.ParamChecker.checkNotNullOrEmpty;
|
||||
import static com.romraider.util.ThreadUtil.sleep;
|
||||
import org.apache.log4j.Logger;
|
||||
import static org.apache.log4j.Logger.getLogger;
|
||||
import java.io.IOException;
|
||||
import static java.lang.Math.min;
|
||||
import static java.lang.System.arraycopy;
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
|
||||
public final class InnovateConnectionImpl implements InnovateConnection {
|
||||
private static final Logger LOGGER = getLogger(InnovateConnectionImpl.class);
|
||||
private static final byte[] INNOVATE_HEADER = asBytes("0xB280");
|
||||
private final SerialConnection connection;
|
||||
private final int responseLength;
|
||||
private final long sendTimeout;
|
||||
private final String device;
|
||||
|
||||
public InnovateConnectionImpl(String device, String portName, ConnectionProperties connectionProperties, int responseLength) {
|
||||
checkNotNullOrEmpty(device, "device");
|
||||
checkNotNullOrEmpty(portName, "portName");
|
||||
checkNotNull(connectionProperties, "connectionProperties");
|
||||
checkGreaterThanZero(responseLength, "responseLength");
|
||||
this.device = device;
|
||||
this.sendTimeout = connectionProperties.getSendTimeout();
|
||||
this.responseLength = responseLength;
|
||||
connection = new SerialConnectionImpl(portName, connectionProperties);
|
||||
}
|
||||
|
||||
// FIX - YIKES!!
|
||||
public byte[] read() {
|
||||
try {
|
||||
connection.readStaleData();
|
||||
byte[] response = new byte[responseLength];
|
||||
int bufferLength = responseLength + INNOVATE_HEADER.length - 1;
|
||||
long start = currentTimeMillis();
|
||||
while (currentTimeMillis() - start <= sendTimeout) {
|
||||
sleep(1);
|
||||
int available = connection.available();
|
||||
if (available < bufferLength) continue;
|
||||
byte[] buffer = new byte[bufferLength];
|
||||
connection.read(buffer);
|
||||
LOGGER.trace(device + " input: " + asHex(buffer));
|
||||
int responseBeginIndex = 0;
|
||||
int bufferBeginIndex = findHeader(buffer);
|
||||
if (bufferBeginIndex < 0) {
|
||||
bufferBeginIndex = findLm1(buffer);
|
||||
if (bufferBeginIndex < 0) continue;
|
||||
LOGGER.trace(device + ": v1 protocol found - appending header...");
|
||||
arraycopy(INNOVATE_HEADER, 0, response, 0, INNOVATE_HEADER.length);
|
||||
responseBeginIndex = INNOVATE_HEADER.length;
|
||||
}
|
||||
int tailLength = responseLength - responseBeginIndex;
|
||||
arraycopy(buffer, bufferBeginIndex, response, responseBeginIndex, min(tailLength, (buffer.length - bufferBeginIndex)));
|
||||
int remainderLength = tailLength - (buffer.length - bufferBeginIndex);
|
||||
if (remainderLength > 0) {
|
||||
byte[] remainder = remainder(remainderLength, start);
|
||||
if (remainder.length == 0) continue;
|
||||
arraycopy(remainder, 0, response, responseLength - remainderLength, remainderLength);
|
||||
}
|
||||
LOGGER.trace(device + " Response: " + asHex(response));
|
||||
return response;
|
||||
}
|
||||
LOGGER.warn(device + " Response [read timeout]");
|
||||
return new byte[0];
|
||||
} catch (Exception e) {
|
||||
close();
|
||||
throw new SerialCommunicationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] remainder(int remainderLength, long start) throws IOException {
|
||||
while (currentTimeMillis() - start <= sendTimeout) {
|
||||
sleep(1);
|
||||
int available = connection.available();
|
||||
if (available >= remainderLength) {
|
||||
byte[] remainder = new byte[remainderLength];
|
||||
connection.read(remainder);
|
||||
return remainder;
|
||||
}
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public void close() {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
private int findHeader(byte[] bytes) {
|
||||
for (int i = 0; i < bytes.length - 1; i++) {
|
||||
if (matchOnes(bytes[i], 178) && matchOnes(bytes[i + 1], 128)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int findLm1(byte[] bytes) {
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (matchOnes(bytes[i], 128) && matchZeroes(bytes[i], 34)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,173 @@
|
|||
|
||||
package com.romraider.logger.innovate.generic.serial.io;
|
||||
|
||||
public interface InnovateRunner extends Runnable {
|
||||
void stop();
|
||||
import com.romraider.io.connection.ConnectionProperties;
|
||||
import com.romraider.io.serial.connection.SerialConnection;
|
||||
import com.romraider.io.serial.connection.SerialConnectionImpl;
|
||||
import com.romraider.logger.innovate.generic.mts.plugin.DataListener;
|
||||
import static com.romraider.util.ByteUtil.matchOnes;
|
||||
import static com.romraider.util.ByteUtil.matchZeroes;
|
||||
import static com.romraider.util.HexUtil.asHex;
|
||||
import com.romraider.util.Stoppable;
|
||||
import static com.romraider.util.ThreadUtil.sleep;
|
||||
import org.apache.log4j.Logger;
|
||||
import static org.apache.log4j.Logger.getLogger;
|
||||
import static java.lang.System.arraycopy;
|
||||
|
||||
public final class InnovateRunner implements Stoppable {
|
||||
private static final Logger LOGGER = getLogger(InnovateRunner.class);
|
||||
private static final double MAX_AFR = 20.33;
|
||||
private final SerialConnection connection;
|
||||
private final DataListener listener;
|
||||
private final String device;
|
||||
private boolean stop;
|
||||
|
||||
public InnovateRunner(String device, String port, DataListener listener) {
|
||||
this.connection = serialConnection(port);
|
||||
// LC-1 & LM-2
|
||||
// this.connection = new TestInnovateConnection("13036B00000000000000000000B2874313036B00000000000000000000B28743");
|
||||
// LM-1
|
||||
// this.connection = new TestInnovateConnection("8113037C1E66012600720049003B003B");
|
||||
this.listener = listener;
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
while (!stop) {
|
||||
byte b0 = nextByte();
|
||||
if (isHeaderHighByte(b0)) {
|
||||
byte b1 = nextByte();
|
||||
if (isHeaderLowByte(b1)) {
|
||||
int numWords = numWords(b0, b1);
|
||||
byte[] bytes = new byte[numWords * 2];
|
||||
connection.read(bytes);
|
||||
LOGGER.trace(device + " response: " + packet(b0, b1, bytes));
|
||||
process(bytes);
|
||||
} else {
|
||||
LOGGER.trace(device + " discarded: " + hex(b1));
|
||||
}
|
||||
} else if (isLm1HighByte(b0)) {
|
||||
byte b1 = nextByte();
|
||||
if (isLm1LowByte(b1)) {
|
||||
byte[] rest = new byte[14];
|
||||
connection.read(rest);
|
||||
byte[] bytes = new byte[16];
|
||||
bytes[0] = b0;
|
||||
bytes[1] = b1;
|
||||
arraycopy(rest, 0, bytes, 2, rest.length);
|
||||
LOGGER.trace(device + " response: " + asHex(bytes));
|
||||
process(bytes);
|
||||
} else {
|
||||
LOGGER.trace(device + " discarded: " + hex(b1));
|
||||
}
|
||||
} else {
|
||||
LOGGER.trace(device + " discarded: " + hex(b0));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void process(byte[] bytes) {
|
||||
if (isError(bytes)) {
|
||||
double error = -1d * getLambda(bytes);
|
||||
LOGGER.error(device + " error: " + error);
|
||||
listener.setData(error);
|
||||
} else if (isOk(bytes)) {
|
||||
double afr = getAfr(bytes);
|
||||
LOGGER.trace(device + " AFR: " + afr);
|
||||
listener.setData(afr > MAX_AFR ? MAX_AFR : afr);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
stop = true;
|
||||
}
|
||||
|
||||
private SerialConnectionImpl serialConnection(String port) {
|
||||
ConnectionProperties properties = new InnovateConnectionProperties();
|
||||
return new SerialConnectionImpl(port, properties);
|
||||
}
|
||||
|
||||
private void waitForBytes(int numBytes) {
|
||||
while (!stop && connection.available() < numBytes) {
|
||||
sleep(2L);
|
||||
}
|
||||
}
|
||||
|
||||
private byte nextByte() {
|
||||
waitForBytes(1);
|
||||
return (byte) connection.read();
|
||||
}
|
||||
|
||||
// 1x11xx1x
|
||||
private boolean isHeaderHighByte(byte b) {
|
||||
return matchOnes(b, 178);
|
||||
}
|
||||
|
||||
// 1xxxxxxx
|
||||
private boolean isHeaderLowByte(byte b) {
|
||||
return matchOnes(b, 128);
|
||||
}
|
||||
|
||||
// 1x0xxx0x
|
||||
private boolean isLm1HighByte(byte b) {
|
||||
return matchOnes(b, 128) && matchZeroes(b, 34);
|
||||
}
|
||||
|
||||
// 0xxxxxxx
|
||||
private boolean isLm1LowByte(byte b) {
|
||||
return matchZeroes(b, 128);
|
||||
}
|
||||
|
||||
private double getAfr(byte[] bytes) {
|
||||
return (getLambda(bytes) + 500) * getAf(bytes) / 10000.0;
|
||||
}
|
||||
|
||||
private int getAf(byte[] bytes) {
|
||||
return ((bytes[0] & 1) << 7) | bytes[1];
|
||||
}
|
||||
|
||||
// xxx000xx
|
||||
private boolean isOk(byte[] bytes) {
|
||||
return matchZeroes(bytes[0], 28);
|
||||
}
|
||||
|
||||
// xxx110xx
|
||||
private boolean isError(byte[] bytes) {
|
||||
return matchOnes(bytes[0], 24) && matchZeroes(bytes[0], 4);
|
||||
}
|
||||
|
||||
// 01xxxxxx 0xxxxxxx
|
||||
private int getLambda(byte[] bytes) {
|
||||
return ((bytes[2] & 63) << 7) | bytes[3];
|
||||
}
|
||||
|
||||
private int numWords(byte b0, byte b1) {
|
||||
int result = 0;
|
||||
if (matchOnes(b0, 1)) result |= 128;
|
||||
if (matchOnes(b1, 64)) result |= 64;
|
||||
if (matchOnes(b1, 32)) result |= 32;
|
||||
if (matchOnes(b1, 16)) result |= 16;
|
||||
if (matchOnes(b1, 8)) result |= 8;
|
||||
if (matchOnes(b1, 4)) result |= 4;
|
||||
if (matchOnes(b1, 2)) result |= 2;
|
||||
if (matchOnes(b1, 1)) result |= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
private String packet(byte b0, byte b1, byte[] bytes) {
|
||||
byte[] result = new byte[bytes.length + 2];
|
||||
result[0] = b0;
|
||||
result[1] = b1;
|
||||
arraycopy(bytes, 0, result, 2, bytes.length);
|
||||
return asHex(result);
|
||||
}
|
||||
|
||||
// FIX - Push this on to HexUtil
|
||||
private String hex(byte b) {
|
||||
return asHex(new byte[]{b});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.generic.serial.io;
|
||||
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettings;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.RawDataListener;
|
||||
|
||||
public final class InnovateRunnerImpl implements InnovateRunner {
|
||||
private final InnovateConnection connection;
|
||||
private final RawDataListener listener;
|
||||
private boolean stop;
|
||||
|
||||
public InnovateRunnerImpl(String device, InnovateSettings innovateSettings, RawDataListener listener, int responseLength) {
|
||||
connection = new InnovateConnectionImpl(device, innovateSettings.getPort(), new InnovateConnectionProperties(), responseLength);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
while (!stop) {
|
||||
byte[] bytes = connection.read();
|
||||
listener.setBytes(bytes);
|
||||
}
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
stop = true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.generic.serial.io;
|
||||
|
||||
import com.romraider.io.serial.connection.SerialConnection;
|
||||
import static com.romraider.util.HexUtil.asBytes;
|
||||
|
||||
public final class TestInnovateConnection implements SerialConnection {
|
||||
private final byte[] source;
|
||||
private int i;
|
||||
|
||||
public TestInnovateConnection(String hex) {
|
||||
this.source = asBytes(hex);
|
||||
}
|
||||
|
||||
public void write(byte[] bytes) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int available() {
|
||||
return source.length;
|
||||
}
|
||||
|
||||
public void read(byte[] bytes) {
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
bytes[j] = source[(i + j) % source.length];
|
||||
}
|
||||
i = (i + bytes.length);
|
||||
if (i >= source.length) i %= source.length;
|
||||
}
|
||||
|
||||
public byte[] readAvailable() {
|
||||
byte[] result = new byte[available()];
|
||||
read(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void readStaleData() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public String readLine() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int read() {
|
||||
byte[] result = new byte[1];
|
||||
read(result);
|
||||
return result[0];
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.generic.serial.plugin;
|
||||
|
||||
public interface InnovateSettings {
|
||||
void setPort(String port);
|
||||
|
||||
String getPort();
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.generic.serial.plugin;
|
||||
|
||||
public final class InnovateSettingsImpl implements InnovateSettings {
|
||||
private String port;
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.lc1.serial.plugin;
|
||||
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.DataConvertor;
|
||||
import static com.romraider.util.ByteUtil.matchOnes;
|
||||
import static com.romraider.util.ByteUtil.matchZeroes;
|
||||
import static com.romraider.util.HexUtil.asHex;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public final class Lc1DataConvertor implements DataConvertor {
|
||||
private static final Logger LOGGER = Logger.getLogger(Lc1DataConvertor.class);
|
||||
private static final double MAX_AFR = 20.33;
|
||||
|
||||
public double convert(byte[] bytes) {
|
||||
/*
|
||||
Example bytes: 10110010 10000010 01000011 00010011 00010111 00101111
|
||||
*/
|
||||
LOGGER.trace("Converting LC-1 bytes: " + asHex(bytes));
|
||||
if (isLc1(bytes) && isHeaderValid(bytes)) {
|
||||
if (isError(bytes)) {
|
||||
int error = -1 * getLambda(bytes);
|
||||
LOGGER.error("LC-1 error: " + asHex(bytes) + " --> " + error);
|
||||
return error;
|
||||
}
|
||||
if (isOk(bytes)) {
|
||||
double afr = getAfr(bytes);
|
||||
LOGGER.trace("LC-1 AFR: " + afr);
|
||||
return afr > MAX_AFR ? MAX_AFR : afr;
|
||||
}
|
||||
// out of range value seen on overrun...
|
||||
LOGGER.trace("LC-1 response out of range (overrun?): " + asHex(bytes));
|
||||
return MAX_AFR;
|
||||
}
|
||||
LOGGER.error("LC-1 unrecognized response: " + asHex(bytes));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private double getAfr(byte[] bytes) {
|
||||
return (getLambda(bytes) + 500) * getAf(bytes) / 10000.0;
|
||||
}
|
||||
|
||||
private int getAf(byte[] bytes) {
|
||||
return ((bytes[2] & 1) << 7) | bytes[3];
|
||||
}
|
||||
|
||||
// 010xxx1x
|
||||
private boolean isLc1(byte[] bytes) {
|
||||
return bytes.length >= 6 && matchOnes(bytes[2], 66) && matchZeroes(bytes[2], 160);
|
||||
}
|
||||
|
||||
// 1x11xx1x 1xxxxxxx
|
||||
private boolean isHeaderValid(byte[] bytes) {
|
||||
return matchOnes(bytes[0], 178) && matchOnes(bytes[1], 128);
|
||||
}
|
||||
|
||||
// 0100001x or 0100011x
|
||||
private boolean isOk(byte[] bytes) {
|
||||
if (matchOnes(bytes[2], 66) && matchZeroes(bytes[2], 188)) return true;
|
||||
return matchOnes(bytes[2], 70) && matchZeroes(bytes[2], 184);
|
||||
}
|
||||
|
||||
// 0101101x
|
||||
private boolean isError(byte[] bytes) {
|
||||
return matchOnes(bytes[2], 90) && matchZeroes(bytes[2], 164);
|
||||
}
|
||||
|
||||
// 01xxxxxx 0xxxxxxx
|
||||
private int getLambda(byte[] bytes) {
|
||||
return ((bytes[4] & 63) << 7) | bytes[5];
|
||||
}
|
||||
}
|
|
@ -20,12 +20,10 @@
|
|||
package com.romraider.logger.innovate.lc1.serial.plugin;
|
||||
|
||||
import com.romraider.logger.ecu.external.ExternalDataItem;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.DataConvertor;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.RawDataListener;
|
||||
import com.romraider.logger.innovate.generic.mts.plugin.DataListener;
|
||||
|
||||
public final class Lc1DataItem implements ExternalDataItem, RawDataListener {
|
||||
private final DataConvertor convertor = new Lc1DataConvertor();
|
||||
private byte[] bytes;
|
||||
public final class Lc1DataItem implements ExternalDataItem, DataListener {
|
||||
private double data;
|
||||
|
||||
public String getName() {
|
||||
return "Innovate LC-1";
|
||||
|
@ -40,11 +38,10 @@ public final class Lc1DataItem implements ExternalDataItem, RawDataListener {
|
|||
}
|
||||
|
||||
public double getData() {
|
||||
if (bytes == null) return 0.0;
|
||||
return convertor.convert(bytes);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setBytes(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
public void setData(double data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,25 +23,22 @@ import com.romraider.logger.ecu.EcuLogger;
|
|||
import com.romraider.logger.ecu.external.ExternalDataItem;
|
||||
import com.romraider.logger.ecu.external.ExternalDataSource;
|
||||
import com.romraider.logger.innovate.generic.serial.io.InnovateRunner;
|
||||
import com.romraider.logger.innovate.generic.serial.io.InnovateRunnerImpl;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettings;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettingsImpl;
|
||||
import static com.romraider.util.ThreadUtil.runAsDaemon;
|
||||
import javax.swing.Action;
|
||||
import static java.util.Arrays.asList;
|
||||
import java.util.List;
|
||||
|
||||
public final class Lc1DataSource implements ExternalDataSource {
|
||||
private InnovateSettings settings = new InnovateSettingsImpl();
|
||||
private Lc1DataItem dataItem = new Lc1DataItem();
|
||||
private InnovateRunner runner;
|
||||
private String port;
|
||||
|
||||
public String getName() {
|
||||
return "Innovate LC-1";
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return "0.02";
|
||||
return "0.03";
|
||||
}
|
||||
|
||||
public List<? extends ExternalDataItem> getDataItems() {
|
||||
|
@ -53,15 +50,15 @@ public final class Lc1DataSource implements ExternalDataSource {
|
|||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
settings.setPort(port);
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return settings.getPort();
|
||||
return port;
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
runner = new InnovateRunnerImpl("LC-1", settings, dataItem, 6);
|
||||
runner = new InnovateRunner("LC-1", port, dataItem);
|
||||
runAsDaemon(runner);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.lm1.serial.plugin;
|
||||
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.DataConvertor;
|
||||
import static com.romraider.util.ByteUtil.matchOnes;
|
||||
import static com.romraider.util.ByteUtil.matchZeroes;
|
||||
import static com.romraider.util.HexUtil.asBytes;
|
||||
import static com.romraider.util.HexUtil.asHex;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
//TODO: Remove dupe with Lc1DataConvertor
|
||||
public final class Lm1DataConvertor implements DataConvertor {
|
||||
private static final Logger LOGGER = Logger.getLogger(Lm1DataConvertor.class);
|
||||
private static final double MAX_AFR = 20.33;
|
||||
|
||||
public double convert(byte[] bytes) {
|
||||
LOGGER.trace("Converting LM-1 bytes: " + asHex(bytes));
|
||||
if (isLm1(bytes) && isHeaderValid(bytes)) {
|
||||
if (isError(bytes)) {
|
||||
int error = -1 * getLambda(bytes);
|
||||
LOGGER.error("LM-1 error: " + asHex(bytes) + " --> " + error);
|
||||
return error;
|
||||
}
|
||||
if (isOk(bytes)) {
|
||||
double afr = getAfr(bytes);
|
||||
LOGGER.trace("LM-1 AFR: " + afr);
|
||||
return afr > MAX_AFR ? MAX_AFR : afr;
|
||||
}
|
||||
// out of range value seen on overrun...
|
||||
LOGGER.trace("LM-1 response out of range (overrun?): " + asHex(bytes));
|
||||
return MAX_AFR;
|
||||
}
|
||||
LOGGER.error("LM-1 unrecognized response: " + asHex(bytes));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private double getAfr(byte[] bytes) {
|
||||
return (getLambda(bytes) + 500) * getAf(bytes) / 10000.0;
|
||||
}
|
||||
|
||||
private int getAf(byte[] bytes) {
|
||||
return ((bytes[2] & 1) << 7) | bytes[3];
|
||||
}
|
||||
|
||||
// 1x0xxx0x
|
||||
private boolean isLm1(byte[] bytes) {
|
||||
return bytes.length >= 6 && matchOnes(bytes[2], 128) && matchZeroes(bytes[2], 34);
|
||||
}
|
||||
|
||||
// 1x11xx1x 1xxxxxxx
|
||||
private boolean isHeaderValid(byte[] bytes) {
|
||||
return matchOnes(bytes[0], 178) && matchOnes(bytes[1], 128);
|
||||
}
|
||||
|
||||
// 1x00000x or 1x00010x
|
||||
private boolean isOk(byte[] bytes) {
|
||||
if (matchOnes(bytes[2], 128) && matchZeroes(bytes[2], 62)) return true;
|
||||
return matchOnes(bytes[2], 132) && matchZeroes(bytes[2], 58);
|
||||
}
|
||||
|
||||
// xxx001xx
|
||||
private boolean isOneTenth(byte[] bytes) {
|
||||
return matchOnes(bytes[2], 4) && matchZeroes(bytes[2], 24);
|
||||
}
|
||||
|
||||
// 1x01100x
|
||||
private boolean isError(byte[] bytes) {
|
||||
return matchOnes(bytes[2], 152) && matchZeroes(bytes[2], 38);
|
||||
}
|
||||
|
||||
// 00xxxxxx 0xxxxxxx
|
||||
private int getLambda(byte[] bytes) {
|
||||
return (bytes[4] << 7) | bytes[5];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
byte[] bytes = asBytes("B280851301371E04004C003A002800260034");
|
||||
// byte[] bytes = asBytes("0xB2808113036F1E650124007000470039003A");
|
||||
DataConvertor convertor = new Lm1DataConvertor();
|
||||
double result = convertor.convert(bytes);
|
||||
System.out.println("result = " + result);
|
||||
}
|
||||
}
|
|
@ -20,12 +20,10 @@
|
|||
package com.romraider.logger.innovate.lm1.serial.plugin;
|
||||
|
||||
import com.romraider.logger.ecu.external.ExternalDataItem;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.DataConvertor;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.RawDataListener;
|
||||
import com.romraider.logger.innovate.generic.mts.plugin.DataListener;
|
||||
|
||||
public final class Lm1DataItem implements ExternalDataItem, RawDataListener {
|
||||
private final DataConvertor convertor = new Lm1DataConvertor();
|
||||
private byte[] bytes;
|
||||
public final class Lm1DataItem implements ExternalDataItem, DataListener {
|
||||
private double data;
|
||||
|
||||
public String getName() {
|
||||
return "Innovate LM-1";
|
||||
|
@ -40,11 +38,10 @@ public final class Lm1DataItem implements ExternalDataItem, RawDataListener {
|
|||
}
|
||||
|
||||
public double getData() {
|
||||
if (bytes == null) return 0.0;
|
||||
return convertor.convert(bytes);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setBytes(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
public void setData(double data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,25 +23,22 @@ import com.romraider.logger.ecu.EcuLogger;
|
|||
import com.romraider.logger.ecu.external.ExternalDataItem;
|
||||
import com.romraider.logger.ecu.external.ExternalDataSource;
|
||||
import com.romraider.logger.innovate.generic.serial.io.InnovateRunner;
|
||||
import com.romraider.logger.innovate.generic.serial.io.InnovateRunnerImpl;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettings;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettingsImpl;
|
||||
import static com.romraider.util.ThreadUtil.runAsDaemon;
|
||||
import javax.swing.Action;
|
||||
import static java.util.Arrays.asList;
|
||||
import java.util.List;
|
||||
|
||||
public final class Lm1DataSource implements ExternalDataSource {
|
||||
private InnovateSettings settings = new InnovateSettingsImpl();
|
||||
private Lm1DataItem dataItem = new Lm1DataItem();
|
||||
private InnovateRunner runner;
|
||||
private String port;
|
||||
|
||||
public String getName() {
|
||||
return "Innovate LM-1";
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return "0.01";
|
||||
return "0.02";
|
||||
}
|
||||
|
||||
public List<? extends ExternalDataItem> getDataItems() {
|
||||
|
@ -53,15 +50,15 @@ public final class Lm1DataSource implements ExternalDataSource {
|
|||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
settings.setPort(port);
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return settings.getPort();
|
||||
return port;
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
runner = new InnovateRunnerImpl("LM-1", settings, dataItem, 18);
|
||||
runner = new InnovateRunner("LM-1", port, dataItem);
|
||||
runAsDaemon(runner);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* RomRaider Open-Source Tuning, Logging and Reflashing
|
||||
* Copyright (C) 2006-2009 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.innovate.lm2.serial.plugin;
|
||||
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.DataConvertor;
|
||||
import static com.romraider.util.ByteUtil.matchOnes;
|
||||
import static com.romraider.util.ByteUtil.matchZeroes;
|
||||
import static com.romraider.util.HexUtil.asBytes;
|
||||
import static com.romraider.util.HexUtil.asHex;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
//TODO: Remove dupe with Lc1DataConvertor
|
||||
public final class Lm2SerialDataConvertor implements DataConvertor {
|
||||
private static final Logger LOGGER = Logger.getLogger(Lm2SerialDataConvertor.class);
|
||||
private static final double MAX_AFR = 20.33;
|
||||
|
||||
public double convert(byte[] bytes) {
|
||||
LOGGER.trace("Converting LM-2 bytes: " + asHex(bytes));
|
||||
if (isLm2(bytes) && isHeaderValid(bytes)) {
|
||||
if (isError(bytes)) {
|
||||
int error = -1 * getLambda(bytes);
|
||||
LOGGER.error("LM-2 error: " + asHex(bytes) + " --> " + error);
|
||||
return error;
|
||||
}
|
||||
if (isOk(bytes)) {
|
||||
double afr = getAfr(bytes);
|
||||
LOGGER.trace("LM-2 AFR: " + afr);
|
||||
return afr > MAX_AFR ? MAX_AFR : afr;
|
||||
}
|
||||
// out of range value seen on overrun...
|
||||
LOGGER.trace("LM-2 response out of range (overrun?): " + asHex(bytes));
|
||||
return MAX_AFR;
|
||||
}
|
||||
LOGGER.error("LM-2 unrecognized response: " + asHex(bytes));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private double getAfr(byte[] bytes) {
|
||||
return (getLambda(bytes) + 500) * getAf(bytes) / 10000.0;
|
||||
}
|
||||
|
||||
private int getAf(byte[] bytes) {
|
||||
return ((bytes[2] & 1) << 7) | bytes[3];
|
||||
}
|
||||
|
||||
// 1x0xxx0x
|
||||
private boolean isLm2(byte[] bytes) {
|
||||
return bytes.length >= 6 && matchOnes(bytes[2], 128) && matchZeroes(bytes[2], 34);
|
||||
}
|
||||
|
||||
// 1x11xx1x 1xxxxxxx
|
||||
private boolean isHeaderValid(byte[] bytes) {
|
||||
return matchOnes(bytes[0], 178) && matchOnes(bytes[1], 128);
|
||||
}
|
||||
|
||||
// 1x00000x
|
||||
private boolean isOk(byte[] bytes) {
|
||||
return matchOnes(bytes[2], 128) && matchZeroes(bytes[2], 62);
|
||||
}
|
||||
|
||||
// 1x01100x
|
||||
private boolean isError(byte[] bytes) {
|
||||
return matchOnes(bytes[2], 152) && matchZeroes(bytes[2], 38);
|
||||
}
|
||||
|
||||
// 00xxxxxx 0xxxxxxx
|
||||
private int getLambda(byte[] bytes) {
|
||||
return (bytes[4] << 7) | bytes[5];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
byte[] bytes = asBytes("0xB2808113036F1E650124007000470039003A");
|
||||
DataConvertor convertor = new Lm2SerialDataConvertor();
|
||||
double result = convertor.convert(bytes);
|
||||
System.out.println("result = " + result);
|
||||
}
|
||||
}
|
|
@ -20,12 +20,10 @@
|
|||
package com.romraider.logger.innovate.lm2.serial.plugin;
|
||||
|
||||
import com.romraider.logger.ecu.external.ExternalDataItem;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.DataConvertor;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.RawDataListener;
|
||||
import com.romraider.logger.innovate.generic.mts.plugin.DataListener;
|
||||
|
||||
public final class Lm2SerialDataItem implements ExternalDataItem, RawDataListener {
|
||||
private final DataConvertor convertor = new Lm2SerialDataConvertor();
|
||||
private byte[] bytes;
|
||||
public final class Lm2SerialDataItem implements ExternalDataItem, DataListener {
|
||||
private double data;
|
||||
|
||||
public String getName() {
|
||||
return "Innovate LM-2 [serial]";
|
||||
|
@ -40,11 +38,10 @@ public final class Lm2SerialDataItem implements ExternalDataItem, RawDataListene
|
|||
}
|
||||
|
||||
public double getData() {
|
||||
if (bytes == null) return 0.0;
|
||||
return convertor.convert(bytes);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setBytes(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
public void setData(double data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
|
@ -23,25 +23,22 @@ import com.romraider.logger.ecu.EcuLogger;
|
|||
import com.romraider.logger.ecu.external.ExternalDataItem;
|
||||
import com.romraider.logger.ecu.external.ExternalDataSource;
|
||||
import com.romraider.logger.innovate.generic.serial.io.InnovateRunner;
|
||||
import com.romraider.logger.innovate.generic.serial.io.InnovateRunnerImpl;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettings;
|
||||
import com.romraider.logger.innovate.generic.serial.plugin.InnovateSettingsImpl;
|
||||
import static com.romraider.util.ThreadUtil.runAsDaemon;
|
||||
import javax.swing.Action;
|
||||
import static java.util.Arrays.asList;
|
||||
import java.util.List;
|
||||
|
||||
public final class Lm2SerialDataSource implements ExternalDataSource {
|
||||
private InnovateSettings settings = new InnovateSettingsImpl();
|
||||
private Lm2SerialDataItem dataItem = new Lm2SerialDataItem();
|
||||
private InnovateRunner runner;
|
||||
private String port;
|
||||
|
||||
public String getName() {
|
||||
return "Innovate LM-2 [serial]";
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return "0.01";
|
||||
return "0.02";
|
||||
}
|
||||
|
||||
public List<? extends ExternalDataItem> getDataItems() {
|
||||
|
@ -53,15 +50,15 @@ public final class Lm2SerialDataSource implements ExternalDataSource {
|
|||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
settings.setPort(port);
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return settings.getPort();
|
||||
return port;
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
runner = new InnovateRunnerImpl("LM-2", settings, dataItem, 18);
|
||||
runner = new InnovateRunner("LM-2", port, dataItem);
|
||||
runAsDaemon(runner);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@ public final class TestPlxConnection implements SerialConnection {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int read() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
index = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue