auto-sync
This commit is contained in:
parent
93120c4d60
commit
fad2c90887
|
@ -0,0 +1,34 @@
|
|||
package com.rusefi;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 3/6/2015
|
||||
*/
|
||||
public class ConfigurationImage {
|
||||
private final static String BIN_HEADER = "RUSEFI0.1";
|
||||
private final int size;
|
||||
private byte content[];
|
||||
|
||||
public ConfigurationImage(int size) {
|
||||
this.size = size;
|
||||
content = new byte[size];
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void saveToFile(String fileName) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(fileName);
|
||||
byte[] bytes = BIN_HEADER.getBytes();
|
||||
if (bytes.length != BIN_HEADER.length())
|
||||
throw new IllegalStateException("Encoding issue");
|
||||
fos.write(bytes);
|
||||
fos.write(content);
|
||||
fos.close();
|
||||
System.out.println("Saved to " + fileName);
|
||||
}
|
||||
}
|
|
@ -1,22 +1,48 @@
|
|||
package com.rusefi.binaryprotocol;
|
||||
|
||||
import com.rusefi.ConfigurationImage;
|
||||
import com.rusefi.io.DataListener;
|
||||
import com.rusefi.io.serial.SerialPortReader;
|
||||
import etch.util.CircularByteBuffer;
|
||||
import jssc.SerialPort;
|
||||
import jssc.SerialPortException;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* (c) Andrey Belomutskiy
|
||||
* 3/6/2015
|
||||
*/
|
||||
public class BinaryProtocol {
|
||||
private static final int BLOCKING_FACTOR = 256;
|
||||
private static final byte RESPONSE_OK = 0;
|
||||
private final SerialPort serialPort;
|
||||
private static final int BUFFER_SIZE = 10000;
|
||||
final CircularByteBuffer cbb;
|
||||
|
||||
public BinaryProtocol(SerialPort serialPort) {
|
||||
|
||||
public BinaryProtocol(SerialPort serialPort) throws SerialPortException {
|
||||
this.serialPort = serialPort;
|
||||
|
||||
cbb = new CircularByteBuffer(BUFFER_SIZE);
|
||||
DataListener listener = new DataListener() {
|
||||
@Override
|
||||
public void onDataArrived(byte[] freshData) {
|
||||
System.out.println(freshData.length + " byte(s) arrived");
|
||||
synchronized (cbb) {
|
||||
if (cbb.size() - cbb.length() < freshData.length) {
|
||||
System.out.println("buffer overflow not expected");
|
||||
cbb.clear();
|
||||
}
|
||||
cbb.put(freshData);
|
||||
cbb.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
serialPort.addEventListener(new SerialPortReader(serialPort, listener));
|
||||
}
|
||||
|
||||
static void waitForBytes(CircularByteBuffer cbb, int count) throws InterruptedException {
|
||||
private void waitForBytes(int count) throws InterruptedException {
|
||||
System.out.println("Waiting for " + count + " byte(s)");
|
||||
synchronized (cbb) {
|
||||
while (cbb.length() < count)
|
||||
|
@ -24,23 +50,38 @@ public class BinaryProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* this method adds two bytes for packet size before and four bytes for CRC after
|
||||
*/
|
||||
public static byte[] makePacket(byte[] command) {
|
||||
byte[] packet = new byte[command.length + 6];
|
||||
|
||||
packet[0] = (byte) (command.length / 256);
|
||||
packet[1] = (byte) command.length;
|
||||
|
||||
int index = packet.length - 1;
|
||||
System.arraycopy(command, 0, packet, 2, command.length);
|
||||
int crc = CRC.crc32(command);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
packet[index--] = (byte) crc;
|
||||
crc >>= 8;
|
||||
}
|
||||
putInt(packet, packet.length - 4, crc);
|
||||
return packet;
|
||||
}
|
||||
|
||||
private static void putInt(byte[] packet, int offset, int value) {
|
||||
int index = offset + 3;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
packet[index--] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private static void putShort(byte[] packet, int offset, int value) {
|
||||
int index = offset + 1;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
packet[index--] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendQueryCommand() throws SerialPortException {
|
||||
byte[] command = {'S'};
|
||||
sendCrcPacket(command);
|
||||
|
@ -49,6 +90,7 @@ public class BinaryProtocol {
|
|||
public void sendCrcPacket(byte[] command) throws SerialPortException {
|
||||
byte[] packet = makePacket(command);
|
||||
|
||||
System.out.println("Sending " + Arrays.toString(packet));
|
||||
serialPort.writeBytes(packet);
|
||||
}
|
||||
|
||||
|
@ -59,4 +101,62 @@ public class BinaryProtocol {
|
|||
public static int swap32(int x) {
|
||||
return (((x) >> 24) & 0xff) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) | (((x) << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
public byte[] receivePacket() throws InterruptedException, EOFException {
|
||||
synchronized (cbb) {
|
||||
waitForBytes(2);
|
||||
|
||||
int packetSize = BinaryProtocol.swap16(cbb.getShort());
|
||||
System.out.println("Got packet size " + packetSize);
|
||||
if (packetSize < 0 || packetSize > 300) {
|
||||
// invalid packet size
|
||||
return null;
|
||||
}
|
||||
waitForBytes(packetSize + 4);
|
||||
|
||||
byte[] packet = new byte[packetSize];
|
||||
int packetCrc;
|
||||
synchronized (cbb) {
|
||||
cbb.get(packet);
|
||||
packetCrc = BinaryProtocol.swap32(cbb.getInt());
|
||||
}
|
||||
int actualCrc = CRC.crc32(packet);
|
||||
|
||||
boolean isCrcOk = actualCrc == packetCrc;
|
||||
if (!isCrcOk) {
|
||||
System.out.println(String.format("%x", actualCrc) + " vs " + String.format("%x", packetCrc));
|
||||
return null;
|
||||
}
|
||||
System.out.println("packet " + Arrays.toString(packet) + ": crc OK");
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
public void readImage(ConfigurationImage image) throws SerialPortException, EOFException, InterruptedException {
|
||||
int offset = 0;
|
||||
|
||||
while (offset < image.getSize()) {
|
||||
int remainingSize = image.getSize() - offset;
|
||||
int requestSize = Math.min(remainingSize, BLOCKING_FACTOR);
|
||||
|
||||
byte packet[] = new byte[7];
|
||||
packet[0] = 'R';
|
||||
putShort(packet, 1, 0); // page
|
||||
putShort(packet, 3, swap16(offset));
|
||||
putShort(packet, 5, swap16(requestSize));
|
||||
|
||||
sendCrcPacket(packet);
|
||||
|
||||
byte[] response = receivePacket();
|
||||
if (response == null || response.length == 0 || response[0] != RESPONSE_OK || response.length != requestSize + 1) {
|
||||
System.out.println("Something is wrong, retrying...");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
offset += requestSize;
|
||||
}
|
||||
System.out.println("Got image!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.rusefi.binaryprotocol;
|
||||
|
||||
import com.rusefi.ConfigurationImage;
|
||||
import com.rusefi.io.DataListener;
|
||||
import com.rusefi.io.serial.PortHolder;
|
||||
import com.rusefi.io.serial.SerialPortReader;
|
||||
|
@ -8,6 +9,7 @@ import jssc.SerialPort;
|
|||
import jssc.SerialPortException;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@ -15,10 +17,9 @@ import java.util.Arrays;
|
|||
* 3/6/2015
|
||||
*/
|
||||
public class BinaryProtocolCmd {
|
||||
private static final int BUFFER_SIZE = 10000;
|
||||
private static SerialPort serialPort;
|
||||
|
||||
public static void main(String[] args) throws SerialPortException, InterruptedException, EOFException {
|
||||
public static void main(String[] args) throws SerialPortException, InterruptedException, IOException {
|
||||
if (args.length != 1) {
|
||||
System.out.println("Exactly one parameter expected");
|
||||
return;
|
||||
|
@ -35,49 +36,16 @@ public class BinaryProtocolCmd {
|
|||
BinaryProtocol bp = new BinaryProtocol(serialPort);
|
||||
|
||||
|
||||
final CircularByteBuffer cbb = new CircularByteBuffer(BUFFER_SIZE);
|
||||
DataListener listener = new DataListener() {
|
||||
@Override
|
||||
public void onDataArrived(byte[] freshData) {
|
||||
System.out.println(freshData.length + " byte(s) arrived");
|
||||
synchronized (cbb) {
|
||||
if (cbb.size() - cbb.length() < freshData.length) {
|
||||
System.out.println("buffer overflow not expected");
|
||||
cbb.clear();
|
||||
}
|
||||
cbb.put(freshData);
|
||||
cbb.notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
serialPort.addEventListener(new SerialPortReader(serialPort, listener));
|
||||
PortHolder.setupPort(serialPort, 38400);
|
||||
System.out.println("Looks good");
|
||||
bp.sendQueryCommand();
|
||||
bp.receivePacket();
|
||||
|
||||
ConfigurationImage image = new ConfigurationImage(14008);
|
||||
|
||||
synchronized (cbb) {
|
||||
BinaryProtocol.waitForBytes(cbb, 2);
|
||||
|
||||
int packetSize = BinaryProtocol.swap16(cbb.getShort());
|
||||
System.out.println("Got packet size " + packetSize);
|
||||
BinaryProtocol.waitForBytes(cbb, packetSize + 4);
|
||||
byte[] packet = new byte[packetSize];
|
||||
int packetCrc;
|
||||
synchronized (cbb) {
|
||||
cbb.get(packet);
|
||||
packetCrc = BinaryProtocol.swap32(cbb.getInt());
|
||||
}
|
||||
int actualCrc = CRC.crc32(packet);
|
||||
|
||||
boolean isCrcOk = actualCrc == packetCrc;
|
||||
if(!isCrcOk) {
|
||||
System.out.println(String.format("%x", actualCrc) + " vs " + String.format("%x", packetCrc));
|
||||
}
|
||||
|
||||
System.out.println("packet " + Arrays.toString(packet) + ": crc ok=" + isCrcOk);
|
||||
}
|
||||
bp.readImage(image);
|
||||
|
||||
image.saveToFile("rusefi_configuration.bin");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -172,10 +172,10 @@ abstract public class ByteBuffer {
|
|||
return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
|
||||
}
|
||||
|
||||
public short getShort() throws EOFException {
|
||||
public int getShort() throws EOFException {
|
||||
int b0 = get() & 255;
|
||||
int b1 = get() & 255;
|
||||
return (short) (b0 | (b1 << 8));
|
||||
return (b0 | (b1 << 8));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue