auto-sync

This commit is contained in:
rusEfi 2015-03-07 20:09:11 -06:00
parent 7cd1490dc9
commit 86f64baea6
7 changed files with 196 additions and 12 deletions

View File

@ -1,5 +1,6 @@
package com.rusefi;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@ -37,16 +38,22 @@ public class ConfigurationImage {
System.out.println("Saved to " + fileName);
}
public boolean readFromFile(String fileName) throws IOException {
public static ConfigurationImage readFromFile(String fileName, Logger logger) throws IOException {
File file = new File(fileName);
int size = (int) file.length();
int contentSize = size - BIN_HEADER.length();
FileInputStream fis = new FileInputStream(fileName);
byte[] header = new byte[BIN_HEADER.length()];
int result = fis.read(header);
if (result != header.length)
return false;
return null;
if (!Arrays.equals(header, BIN_HEADER.getBytes()))
return false;
result = fis.read(content);
return result == content.length;
return null;
ConfigurationImage image = new ConfigurationImage(contentSize);
result = fis.read(image.content);
return result == image.getContent().length ? image : null;
}
public byte[] getContent() {

View File

@ -7,6 +7,9 @@ import com.rusefi.core.Pair;
* 3/6/2015
*/
public class ConfigurationImageDiff {
/**
* @return NULL if images are the same from OFFSET and to the end
*/
public static Pair<Integer, Integer> findDifferences(ConfigurationImage image1, ConfigurationImage image2, int position) {
byte[] c1 = image1.getContent();
byte[] c2 = image2.getContent();

View File

@ -22,6 +22,7 @@ public class BinaryProtocol {
private final SerialPort serialPort;
private static final int BUFFER_SIZE = 10000;
final CircularByteBuffer cbb;
private boolean isBurnPendig;
public BinaryProtocol(final Logger logger, SerialPort serialPort) throws SerialPortException {
this.logger = logger;
@ -152,7 +153,7 @@ public class BinaryProtocol {
sendCrcPacket(packet);
byte[] response = receivePacket();
if (response == null || response.length == 0 || response[0] != RESPONSE_OK || response.length != requestSize + 1) {
if (!checkResponseCode(response, RESPONSE_OK) || response.length != requestSize + 1) {
logger.error("Something is wrong, retrying...");
continue;
}
@ -164,4 +165,48 @@ public class BinaryProtocol {
}
logger.info("Got image!");
}
private boolean checkResponseCode(byte[] response, byte code) {
return response != null && response.length > 0 && response[0] == code;
}
public void writeData(byte[] content, Integer offset, int size, Logger logger) throws SerialPortException, EOFException, InterruptedException {
if (size > BLOCKING_FACTOR) {
writeData(content, offset, BLOCKING_FACTOR, logger);
writeData(content, offset + BLOCKING_FACTOR, size - BLOCKING_FACTOR, logger);
return;
}
isBurnPendig = true;
byte packet[] = new byte[7 + size];
packet[0] = 'C';
putShort(packet, 1, 0); // page
putShort(packet, 3, swap16(offset));
putShort(packet, 5, swap16(size));
System.arraycopy(content, offset, packet, 7, size);
while (true) {
sendCrcPacket(packet);
byte[] response = receivePacket();
if (!checkResponseCode(response, RESPONSE_OK)
//|| response.length != requestSize + 1
) {
logger.error("Something is wrong, retrying...");
continue;
}
break;
}
}
public void burn() {
if (!isBurnPendig)
return;
isBurnPendig = false;
}
}

View File

@ -2,23 +2,17 @@ package com.rusefi.binaryprotocol;
import com.rusefi.ConfigurationImage;
import com.rusefi.Logger;
import com.rusefi.io.DataListener;
import com.rusefi.io.serial.PortHolder;
import com.rusefi.io.serial.SerialPortReader;
import etch.util.CircularByteBuffer;
import jssc.SerialPort;
import jssc.SerialPortException;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
/**
* (c) Andrey Belomutskiy
* 3/6/2015
*/
public class BinaryProtocolCmd {
private static SerialPort serialPort;
public static void main(String[] args) throws SerialPortException, InterruptedException, IOException {
if (args.length != 1) {
@ -30,6 +24,7 @@ public class BinaryProtocolCmd {
Logger logger = Logger.STDOUT;
SerialPort serialPort;
serialPort = new SerialPort(port);
boolean opened = serialPort.openPort();
if (!opened) {

View File

@ -0,0 +1,128 @@
package com.rusefi;
import com.rusefi.binaryprotocol.BinaryProtocol;
import com.rusefi.core.Pair;
import com.rusefi.io.serial.PortHolder;
import com.rusefi.ui.StatusWindow;
import jssc.SerialPort;
import jssc.SerialPortException;
import javax.swing.*;
import java.io.EOFException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* (c) Andrey Belomutskiy 2013-2015
* 3/7/2015
*/
public class UploadChanges {
private static final Executor EXEC = Executors.newSingleThreadExecutor();
public static void main(String[] args) throws SerialPortException, InvocationTargetException, InterruptedException {
if (args.length != 1) {
System.out.println("Exactly one parameter expected");
return;
}
final String port = args[0];
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
try {
showUi(port);
} catch (SerialPortException | IOException | InterruptedException e) {
throw new IllegalStateException(e);
}
}
});
}
private static void showUi(String port) throws SerialPortException, IOException, InterruptedException {
final StatusWindow wnd = new StatusWindow();
wnd.showFrame("rusEfi bin upload");
final Logger logger = new Logger() {
@Override
public void trace(final String msg) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println(msg);
wnd.appendMsg(msg);
}
});
}
@Override
public void info(final String msg) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println(msg);
wnd.appendMsg(msg);
}
});
}
@Override
public void error(final String msg) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println(msg);
wnd.appendMsg(msg);
}
});
}
};
SerialPort serialPort;
serialPort = new SerialPort(port);
boolean opened = serialPort.openPort();
if (!opened) {
logger.error("failed to open " + port);
}
PortHolder.setupPort(serialPort, 38400);
logger.info("Looks good");
final ConfigurationImage ci1 = ConfigurationImage.readFromFile("rus_saved.bin", logger);
final ConfigurationImage ci2 = ConfigurationImage.readFromFile("rusefi_configuration.bin", logger);
final BinaryProtocol bp = new BinaryProtocol(logger, serialPort);
EXEC.execute(new Runnable() {
@Override
public void run() {
try {
patch(ci1, ci2, bp, logger);
} catch (InterruptedException | EOFException | SerialPortException e) {
logger.error("Error: " + e);
throw new IllegalStateException(e);
}
}
});
}
private static void patch(ConfigurationImage ci1, ConfigurationImage ci2, BinaryProtocol bp, Logger logger) throws InterruptedException, EOFException, SerialPortException {
int offset = 0;
while (offset < ci1.getSize()) {
Pair<Integer, Integer> range = ConfigurationImageDiff.findDifferences(ci1, ci2, offset);
if (range == null)
return;
logger.info("Need to patch: " + range);
bp.writeData(ci2.getContent(), range.first, range.second - range.first, logger);
offset = range.second;
}
bp.burn();
}
}

View File

@ -3,6 +3,9 @@ package com.rusefi.maintenance;
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* (c) Andrey Belomutskiy 2013-2015
*/
public class EraseChip extends ProcessStatusWindow {
private final JButton button = new JButton("Erase Chip");

View File

@ -7,6 +7,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* (c) Andrey Belomutskiy 2013-2015
*/
public class ProcessStatusWindow {
public static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("win");