tear out unnecessary console functionality
This commit is contained in:
parent
f93db9d6c3
commit
2724505cc2
|
@ -82,7 +82,6 @@ public class rusEFI extends Activity {
|
|||
private TextView mStatusView;
|
||||
private TextView mResultView; // global dump of all messages
|
||||
private TextView broadcastStatus;
|
||||
private EditText authTokenUI;
|
||||
private TextView authStatusMessage;
|
||||
private TextView authStatusClickableUrl;
|
||||
|
||||
|
@ -119,30 +118,6 @@ public class rusEFI extends Activity {
|
|||
|
||||
mStatusView = findViewById(R.id.text_status);
|
||||
mResultView = findViewById(R.id.text_result);
|
||||
authTokenUI = findViewById(R.id.authToken);
|
||||
authTokenUI.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
String text = authTokenUI.getText().toString();
|
||||
if (AuthTokenUtil.isToken(text)) {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(rusEFI.this);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putString(AuthTokenUtil.AUTH_TOKEN, text);
|
||||
editor.apply();
|
||||
authStatusMessage.setVisibility(View.GONE);
|
||||
authStatusClickableUrl.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
authStatusMessage = findViewById(R.id.authStatus1);
|
||||
authStatusClickableUrl = findViewById(R.id.authStatus2);
|
||||
|
@ -158,8 +133,7 @@ public class rusEFI extends Activity {
|
|||
|
||||
//dfuUpload.downloadFileIfNotPresent(mResultView);
|
||||
|
||||
String authToken = readPersistedAuthToken();
|
||||
authTokenUI.setText(authToken);
|
||||
String authToken = "";
|
||||
int visibility = AuthTokenUtil.isToken(authToken) ? View.GONE : View.VISIBLE;
|
||||
authStatusMessage.setVisibility(visibility);
|
||||
authStatusClickableUrl.setVisibility(visibility);
|
||||
|
@ -169,11 +143,6 @@ public class rusEFI extends Activity {
|
|||
// SoundBroadcast.checkOrRequestPermission(this);
|
||||
}
|
||||
|
||||
private String readPersistedAuthToken() {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(rusEFI.this);
|
||||
return preferences.getString(AuthTokenUtil.AUTH_TOKEN, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
java -jar console/rusefi_console.jar set_auth_token $1
|
|
@ -16,8 +16,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.rusefi.io.can.Elm327Connector.ELM327_DEFAULT_BAUDRATE;
|
||||
|
||||
/**
|
||||
* Andrey Belomutskiy, (c) 2013-2020
|
||||
*/
|
||||
|
@ -29,7 +27,6 @@ public class PortDetector {
|
|||
|
||||
public enum DetectorMode {
|
||||
DETECT_TS,
|
||||
DETECT_ELM327,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,9 +58,6 @@ public class PortDetector {
|
|||
Thread thread = AUTO_DETECT_PORT.newThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mode == DetectorMode.DETECT_ELM327) {
|
||||
BaudRateHolder.INSTANCE.baudRate = ELM327_DEFAULT_BAUDRATE;
|
||||
}
|
||||
new SerialAutoChecker(mode, serialPort, portFound).openAndCheckResponse(mode, result, callback);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.devexperts.logging.Logging;
|
|||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.can.Elm327Connector;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
import com.rusefi.io.serial.BufferedSerialIoStream;
|
||||
import com.rusefi.io.serial.SerialIoStream;
|
||||
|
@ -36,13 +35,7 @@ public class SerialAutoChecker {
|
|||
public String checkResponse(IoStream stream, Function<CallbackContext, Void> callback) {
|
||||
if (stream == null)
|
||||
return null;
|
||||
if (mode == PortDetector.DetectorMode.DETECT_ELM327) {
|
||||
if (Elm327Connector.checkConnection(serialPort, stream)) {
|
||||
// todo: this method is supposed to return signature not serial port!
|
||||
return serialPort;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
IncomingDataBuffer incomingData = stream.getDataBuffer();
|
||||
try {
|
||||
HelloCommand.send(stream);
|
||||
|
@ -82,11 +75,7 @@ public class SerialAutoChecker {
|
|||
|
||||
@Nullable
|
||||
private IoStream getStreamByMode(PortDetector.DetectorMode mode) {
|
||||
if (mode == PortDetector.DetectorMode.DETECT_ELM327) {
|
||||
return SerialIoStream.openPort(serialPort);
|
||||
} else {
|
||||
return BufferedSerialIoStream.openPort(serialPort);
|
||||
}
|
||||
return BufferedSerialIoStream.openPort(serialPort);
|
||||
}
|
||||
|
||||
public static class CallbackContext {
|
||||
|
|
|
@ -1,306 +0,0 @@
|
|||
package com.rusefi.io.can;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.io.DataListener;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.rusefi.Timeouts.SECOND;
|
||||
|
||||
public class Elm327Connector implements Closeable {
|
||||
private final static Logging log = Logging.getLogging(Elm327Connector.class);
|
||||
|
||||
static {
|
||||
log.configureDebugEnabled(false);
|
||||
}
|
||||
|
||||
private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes();
|
||||
|
||||
// public final static int ELM327_DEFAULT_BAUDRATE = 115200; // OBDlink SX, 1.3a STN1110
|
||||
public final static int ELM327_DEFAULT_BAUDRATE = 38400;
|
||||
private final static int BIG_TIMEOUT = 2 * SECOND;
|
||||
private final static int TIMEOUT = 70;
|
||||
public static final String HELLO = "ATZ";
|
||||
public static final String ELM_EOL = "\r";
|
||||
// those are inverted between ECU side and PC side
|
||||
private static final int CAN_PC_SERIAL_RX_ID = Fields.CAN_ECU_SERIAL_TX_ID;
|
||||
private static final int CAN_PC_SERIAL_TX_ID = Fields.CAN_ECU_SERIAL_RX_ID;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
/**
|
||||
* Connection to ELM327 device where text based ELM protocol happens
|
||||
*/
|
||||
private final IoStream underlyingStream;
|
||||
/**
|
||||
* Binary serial stream for TS traffic
|
||||
*/
|
||||
private final Elm327IoStream tsStream;
|
||||
private String partialLine = "";
|
||||
private final List<String> completeLines = new ArrayList<>();
|
||||
private boolean isCommandMode = false;
|
||||
|
||||
public Elm327Connector(IoStream underlyingStream) {
|
||||
this.underlyingStream = underlyingStream;
|
||||
underlyingStream.setInputListener(listener);
|
||||
tsStream = new Elm327IoStream(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: HUH? what's that about?!
|
||||
*/
|
||||
public static void whyDoWeNeedToSleepBetweenCommands() {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Elm327IoStream getTsStream() {
|
||||
return tsStream;
|
||||
}
|
||||
|
||||
public boolean start(String msg) {
|
||||
log.info("* Elm327.start()");
|
||||
|
||||
boolean initConnection = initConnection(msg);
|
||||
if (initConnection) {
|
||||
// reset to defaults
|
||||
sendCommand("ATD", "OK");
|
||||
|
||||
// Echo off
|
||||
sendCommand("ATE0", "OK");
|
||||
//waitForEcho = false;
|
||||
|
||||
// protocol #6 - ISO 15765-4 CAN (11 bit ID, 500 kbaud)
|
||||
sendCommand("ATSP6", "OK");
|
||||
|
||||
// set rx ID
|
||||
sendCommand("ATCF " + Integer.toHexString(CAN_PC_SERIAL_RX_ID), "OK");
|
||||
|
||||
// rx ID mask = "all bits set"
|
||||
sendCommand("ATCM FFF", "OK");
|
||||
|
||||
// set tx ID
|
||||
sendCommand("ATSH " + Integer.toHexString(CAN_PC_SERIAL_TX_ID), "OK");
|
||||
|
||||
// set FC tx ID (should match our tx ID)
|
||||
sendCommand("ATFCSH " + Integer.toHexString(CAN_PC_SERIAL_TX_ID), "OK");
|
||||
// set FC data
|
||||
sendCommand("ATFCSD 30 00 00", "OK");
|
||||
// use custom FC ID & data
|
||||
sendCommand("ATFCSM 1", "OK");
|
||||
|
||||
// disable data auto-formatting (less bytes in a stream)
|
||||
sendCommand("ATCAF 0", "OK");
|
||||
|
||||
// allow "long" 8-byte messages
|
||||
sendCommand("ATAL", "OK");
|
||||
|
||||
// disable spaces ("00 11 22" => "001122")
|
||||
sendCommand("ATS 0", "OK");
|
||||
|
||||
// disable silent monitoring (ELM will send ACK)
|
||||
sendCommand("ATCSM 0", "OK");
|
||||
|
||||
// read the ignition voltage
|
||||
String voltage = sendCommand("ATRV", "([0-9\\.]+)V");
|
||||
log.info("* Ignition voltage = " + voltage);
|
||||
}
|
||||
return initConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
log.info("* Elm327.close()");
|
||||
if (underlyingStream != null)
|
||||
underlyingStream.close();
|
||||
}
|
||||
|
||||
private final DataListener listener = freshData -> {
|
||||
// ELM327 uses a text protocol, so we convert the data to a string
|
||||
String freshStr = new String(freshData);
|
||||
while (true) {
|
||||
int newL = freshStr.indexOf('\r');
|
||||
//log.info("* onData: " + newL + " [" + freshStr + "]");
|
||||
|
||||
// split the stream into separate lines
|
||||
if (newL >= 0) {
|
||||
String curLine = this.partialLine;
|
||||
this.partialLine = "";
|
||||
if (newL > 0)
|
||||
curLine += freshStr.substring(0, newL);
|
||||
if (curLine.length() > 0)
|
||||
processLine(curLine);
|
||||
freshStr = freshStr.substring(newL + 1);
|
||||
continue;
|
||||
}
|
||||
this.partialLine += freshStr;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private final IsoTpConnector connector = new IsoTpConnector() {
|
||||
@Override
|
||||
public void sendCanData(byte[] hdr, byte[] data, int dataOffset, int dataLength) {
|
||||
byte[] total = combineArrays(hdr, data, dataOffset, dataLength);
|
||||
Elm327Connector.this.sendCanData(total);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData() {
|
||||
Elm327Connector.this.receiveData();
|
||||
}
|
||||
};
|
||||
|
||||
public void sendBytesToSerial(byte [] bytes) {
|
||||
IsoTpConnector.sendStrategy(bytes, connector);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
private boolean initConnection(String msg) {
|
||||
if (sendCommand(HELLO, "ELM327 v[0-9]+\\.[0-9]+", BIG_TIMEOUT) != null) {
|
||||
log.info("ELM DETECTED on " + msg + "! " + ELM327_DEFAULT_BAUDRATE);
|
||||
return true;
|
||||
}
|
||||
log.info("ELM NOT FOUND on " + msg + "! " + ELM327_DEFAULT_BAUDRATE);
|
||||
return false;
|
||||
}
|
||||
|
||||
private String sendCommand(String command, String responseFilter) {
|
||||
return sendCommand(command, responseFilter, TIMEOUT);
|
||||
}
|
||||
|
||||
private String sendCommand(String command, String responseFilter, int timeout) {
|
||||
log.info("* Elm327.cmd: " + command);
|
||||
isCommandMode = true;
|
||||
this.completeLines.clear();
|
||||
try {
|
||||
underlyingStream.write((command + ELM_EOL).getBytes());
|
||||
waitForResponse(timeout);
|
||||
} catch (IOException | InterruptedException ignore) {
|
||||
return null;
|
||||
} finally {
|
||||
isCommandMode = false;
|
||||
}
|
||||
|
||||
if (this.completeLines.size() < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int responseIdx = 0;
|
||||
// the first line can repeat the command (if echo is on)
|
||||
if (this.completeLines.get(0).equals(command)) {
|
||||
// then the response is in the 2nd line
|
||||
responseIdx = 1;
|
||||
}
|
||||
// return the response only if it matches the given regexp
|
||||
Pattern pattern = Pattern.compile(responseFilter);
|
||||
String inputLine = completeLines.get(responseIdx);
|
||||
Matcher matcher = pattern.matcher(inputLine);
|
||||
if (matcher.find()) {
|
||||
// store the echo mode
|
||||
//this.waitForEcho = responseIdx != 0;
|
||||
|
||||
return (matcher.groupCount() > 0) ? matcher.group(1) : matcher.group();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sendCanData(byte [] data) {
|
||||
if (log.debugEnabled()) {
|
||||
log.debug("sendCanData total " + IoStream.printByteArray(data));
|
||||
}
|
||||
//log.info("--------sendData offset="+Integer.toString(offset) + " len=" + Integer.toString(len) + "hdr.len=" + Integer.toString(hdr.length));
|
||||
|
||||
byte[] hexData = byteToString(data);
|
||||
|
||||
//log.info("* Elm327.data: " + (new String(hexData)));
|
||||
|
||||
try {
|
||||
underlyingStream.write(hexData);
|
||||
} catch (IOException ignore) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static byte[] byteToString(byte[] data) {
|
||||
int length = data.length;
|
||||
byte[] hexData = new byte[length * 2 + 1];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int j = i * 2;
|
||||
int v = data[i] & 0xFF;
|
||||
hexData[j] = HEX_ARRAY[v >>> 4];
|
||||
hexData[j + 1] = HEX_ARRAY[v & 0x0F];
|
||||
}
|
||||
hexData[length * 2] = '\r';
|
||||
return hexData;
|
||||
}
|
||||
|
||||
private byte[] receiveData() {
|
||||
synchronized (lock) {
|
||||
try {
|
||||
waitForResponse(TIMEOUT);
|
||||
//log.info("Elm327Connector.receiveData(): size=" + this.completeLines.size());
|
||||
return null;
|
||||
} catch (InterruptedException ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForResponse(int timeout) throws InterruptedException {
|
||||
synchronized (lock) {
|
||||
// multiple lines can be sent, we need to wait for them all
|
||||
while (true) {
|
||||
int numLines = completeLines.size();
|
||||
lock.wait(timeout);
|
||||
// if nothing changed
|
||||
if (completeLines.size() == numLines)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processLine(String line) {
|
||||
synchronized (lock) {
|
||||
log.info("Elm327Connector.processLine(): {" + line + "}");
|
||||
|
||||
// remove the 'cursor'
|
||||
if (line.charAt(0) == '>')
|
||||
line = line.substring(1);
|
||||
|
||||
if (isCommandMode) {
|
||||
// store the output as a response to the command (for verification)
|
||||
this.completeLines.add(line);
|
||||
lock.notifyAll();
|
||||
} else {
|
||||
// just send it back to the proxy
|
||||
sendDataBack(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendDataBack(String line) {
|
||||
byte [] canPacket = HexUtil.asBytes(line);
|
||||
tsStream.processCanPacket(canPacket);
|
||||
}
|
||||
|
||||
public static boolean checkConnection(String serialPort, IoStream stream) {
|
||||
Elm327Connector con = new Elm327Connector(stream);
|
||||
boolean found = con.initConnection(serialPort);
|
||||
con.close();
|
||||
return found;
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
package com.rusefi.io.can;
|
||||
|
||||
import com.opensr5.io.DataListener;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.binaryprotocol.IoHelper;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Elm327IoStream extends AbstractIoStream {
|
||||
private final Elm327Connector con;
|
||||
@NotNull
|
||||
private final IncomingDataBuffer dataBuffer;
|
||||
private DataListener dataListener;
|
||||
|
||||
// the buffer size is limited by CAN-TP protocol
|
||||
private final static int OUT_BUFFER_SIZE = 4095;
|
||||
private final ByteBuffer outBuf;
|
||||
|
||||
// this should match the TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME in the firmware
|
||||
// todo: move this to rusefi_config.txt / prepend.txt?
|
||||
private final static boolean sendShortPacketsInOneFrame = false;
|
||||
//private final static boolean receiveShortPacketsInOneFrame = sendShortPacketsInOneFrame;
|
||||
private final static boolean receiveShortPacketsInOneFrame = false;
|
||||
|
||||
private final IsoTpCanDecoder canDecoder = new IsoTpCanDecoder();
|
||||
|
||||
public Elm327IoStream(Elm327Connector con) {
|
||||
this.con = con;
|
||||
dataBuffer = createDataBuffer("elm327Stream");
|
||||
|
||||
// ByteBuffer inBuf = ByteBuffer.allocate(OUT_BUFFER_SIZE);
|
||||
outBuf = ByteBuffer.allocate(OUT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// we need to guarantee only one onDisconnect invocation for retry logic to be healthy
|
||||
synchronized (this) {
|
||||
if (!isClosed()) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IncomingDataBuffer getDataBuffer() {
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
super.write(bytes);
|
||||
|
||||
int offset = 0;
|
||||
int numBytes = bytes.length;
|
||||
// split the data if it doesn't fit in our out-buffer
|
||||
while (numBytes > outBuf.remaining()) {
|
||||
int remaining = outBuf.remaining();
|
||||
//log.info("* remaining= "+remaining + " numBytes="+numBytes+" offset="+offset);
|
||||
outBuf.put(bytes, offset, remaining);
|
||||
numBytes -= remaining;
|
||||
offset += remaining;
|
||||
flush();
|
||||
}
|
||||
//log.info("* rest numBytes="+numBytes+" offset="+offset);
|
||||
outBuf.put(bytes, offset, numBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
super.flush();
|
||||
byte [] bytes;
|
||||
// for smaller packets, send them in one 'simple' frame by stripping the header+footer off
|
||||
// i.e. un-pack CRC32 TS protocol
|
||||
// (2 = 16-bit length, 4 = 32-bit crc)
|
||||
if (sendShortPacketsInOneFrame && outBuf.position() >= 2 + 1 + 4 && outBuf.position() <= 2 + 7 + 4) {
|
||||
bytes = Arrays.copyOfRange(outBuf.array(), 2, outBuf.position() - 4);
|
||||
} else {
|
||||
bytes = Arrays.copyOf(outBuf.array(), outBuf.position());
|
||||
}
|
||||
con.sendBytesToSerial(bytes);
|
||||
outBuf.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputListener(final DataListener listener) {
|
||||
dataListener = listener;
|
||||
}
|
||||
|
||||
public void sendDataToClient(byte [] data) {
|
||||
// reconstruct a TS packet from the raw data
|
||||
byte [] packet;
|
||||
if (receiveShortPacketsInOneFrame && data.length >= 1 && data.length <= 7) {
|
||||
// short packets are sent without the header+footer, we need to reconstruct them
|
||||
packet = new byte [2 + data.length + 4];
|
||||
IoHelper.putShort(packet, 0, data.length);
|
||||
|
||||
System.arraycopy(data, 0, packet, 2, data.length);
|
||||
int crc = IoHelper.getCrc32(data);
|
||||
IoHelper.putInt(packet, 2 + data.length, crc);
|
||||
} else {
|
||||
// long packets are sent as-is
|
||||
packet = data;
|
||||
}
|
||||
|
||||
dataListener.onDataArrived(packet);
|
||||
}
|
||||
|
||||
public void processCanPacket(byte [] data) {
|
||||
byte [] rawData = canDecoder.decodePacket(data);
|
||||
if (rawData.length != 0)
|
||||
sendDataToClient(rawData);
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
package com.rusefi.io.stream;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.io.DataListener;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.can.IsoTpCanDecoder;
|
||||
import com.rusefi.io.can.IsoTpConnector;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import com.rusefi.io.serial.RateCounter;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import peak.can.basic.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static com.rusefi.config.generated.Fields.CAN_ECU_SERIAL_TX_ID;
|
||||
import static peak.can.basic.TPCANMessageType.PCAN_MESSAGE_STANDARD;
|
||||
|
||||
public class PCanIoStream extends AbstractIoStream {
|
||||
private static final int INFO_SKIP_RATE = 3-00;
|
||||
static Logging log = getLogging(PCanIoStream.class);
|
||||
|
||||
public static final TPCANHandle CHANNEL = TPCANHandle.PCAN_USBBUS1;
|
||||
private final IncomingDataBuffer dataBuffer;
|
||||
private final PCANBasic can;
|
||||
private final StatusConsumer statusListener;
|
||||
|
||||
private final RateCounter totalCounter = new RateCounter();
|
||||
private final RateCounter isoTpCounter = new RateCounter();
|
||||
private final IsoTpCanDecoder canDecoder = new IsoTpCanDecoder() {
|
||||
@Override
|
||||
protected void onTpFirstFrame() {
|
||||
sendCanPacket(FLOW_CONTROL);
|
||||
}
|
||||
};
|
||||
|
||||
private final IsoTpConnector isoTpConnector = new IsoTpConnector() {
|
||||
@Override
|
||||
public void sendCanData(byte[] hdr, byte[] data, int dataOffset, int dataLength) {
|
||||
byte[] total = combineArrays(hdr, data, dataOffset, dataLength);
|
||||
|
||||
sendCanPacket(total);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData() {
|
||||
}
|
||||
};
|
||||
private int logSkipRate;
|
||||
|
||||
@Nullable
|
||||
public static PCanIoStream createStream() {
|
||||
return createStream(message -> log.info(message));
|
||||
}
|
||||
|
||||
public static PCanIoStream createStream(StatusConsumer statusListener) {
|
||||
PCANBasic can = new PCANBasic();
|
||||
can.initializeAPI();
|
||||
TPCANStatus status = can.Initialize(CHANNEL, TPCANBaudrate.PCAN_BAUD_500K, TPCANType.PCAN_TYPE_NONE, 0, (short) 0);
|
||||
if (status != TPCANStatus.PCAN_ERROR_OK) {
|
||||
statusListener.append("Error initializing PCAN: " + status);
|
||||
return null;
|
||||
}
|
||||
statusListener.append("Creating PCAN stream...");
|
||||
return new PCanIoStream(can, statusListener);
|
||||
}
|
||||
|
||||
private void sendCanPacket(byte[] payLoad) {
|
||||
if (log.debugEnabled())
|
||||
log.debug("-------sendIsoTp " + payLoad.length + " byte(s):");
|
||||
|
||||
if (log.debugEnabled())
|
||||
log.debug("Sending " + IoStream.printHexBinary(payLoad));
|
||||
|
||||
TPCANMsg msg = new TPCANMsg(Fields.CAN_ECU_SERIAL_RX_ID, PCAN_MESSAGE_STANDARD.getValue(),
|
||||
(byte) payLoad.length, payLoad);
|
||||
TPCANStatus status = can.Write(CHANNEL, msg);
|
||||
if (status != TPCANStatus.PCAN_ERROR_OK) {
|
||||
statusListener.append("Unable to write the CAN message: " + status);
|
||||
System.exit(0);
|
||||
}
|
||||
// log.info("Send OK! length=" + payLoad.length);
|
||||
}
|
||||
|
||||
private PCanIoStream(PCANBasic can, StatusConsumer statusListener) {
|
||||
this.can = can;
|
||||
this.statusListener = statusListener;
|
||||
dataBuffer = createDataBuffer("[PCAN] ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
IsoTpConnector.sendStrategy(bytes, isoTpConnector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputListener(DataListener listener) {
|
||||
Executor threadExecutor = Executors.newSingleThreadExecutor(BinaryProtocolServer.getThreadFactory("PCAN reader"));
|
||||
threadExecutor.execute(() -> {
|
||||
while (!isClosed()) {
|
||||
readOnePacket(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void readOnePacket(DataListener listener) {
|
||||
// todo: can we reuse instance?
|
||||
// todo: should be? TPCANMsg rx = new TPCANMsg();
|
||||
// https://github.com/rusefi/rusefi/issues/4370 nasty work-around
|
||||
TPCANMsg rx = new TPCANMsg(Byte.MAX_VALUE);
|
||||
TPCANStatus status = can.Read(CHANNEL, rx, null);
|
||||
if (status == TPCANStatus.PCAN_ERROR_OK) {
|
||||
totalCounter.add();
|
||||
if (rx.getID() != CAN_ECU_SERIAL_TX_ID) {
|
||||
// if (log.debugEnabled())
|
||||
logSkipRate ++;
|
||||
if (logSkipRate % INFO_SKIP_RATE == 0) {
|
||||
debugPacket(rx);
|
||||
log.info("Skipping non " + String.format("%X", CAN_ECU_SERIAL_TX_ID) + " packet: " + String.format("%X", rx.getID()));
|
||||
log.info("Total rate " + totalCounter.getCurrentRate() + ", isotp rate " + isoTpCounter.getCurrentRate());
|
||||
}
|
||||
return;
|
||||
}
|
||||
debugPacket(rx);
|
||||
isoTpCounter.add();
|
||||
byte[] decode = canDecoder.decodePacket(rx.getData());
|
||||
listener.onDataArrived(decode);
|
||||
|
||||
// log.info("Decoded " + IoStream.printByteArray(decode));
|
||||
} else {
|
||||
// log.info("Receive " + status);
|
||||
}
|
||||
}
|
||||
|
||||
private void debugPacket(TPCANMsg rx) {
|
||||
if (log.debugEnabled())
|
||||
log.debug("Got [" + rx + "] id=" + String.format("%X", rx.getID()) + " len=" + rx.getLength() + ": " + IoStream.printByteArray(rx.getData()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingDataBuffer getDataBuffer() {
|
||||
return dataBuffer;
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
package com.rusefi.io.stream;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.io.DataListener;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.can.IsoTpCanDecoder;
|
||||
import com.rusefi.io.can.IsoTpConnector;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import tel.schich.javacan.CanChannels;
|
||||
import tel.schich.javacan.CanFrame;
|
||||
import tel.schich.javacan.NetworkDevice;
|
||||
import tel.schich.javacan.RawCanChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static com.rusefi.config.generated.Fields.CAN_ECU_SERIAL_TX_ID;
|
||||
import static tel.schich.javacan.CanFrame.FD_NO_FLAGS;
|
||||
import static tel.schich.javacan.CanSocketOptions.RECV_OWN_MSGS;
|
||||
|
||||
public class SocketCANIoStream extends AbstractIoStream {
|
||||
static Logging log = getLogging(SocketCANIoStream.class);
|
||||
private final IncomingDataBuffer dataBuffer;
|
||||
private final RawCanChannel socket;
|
||||
|
||||
private final IsoTpCanDecoder canDecoder = new IsoTpCanDecoder() {
|
||||
@Override
|
||||
protected void onTpFirstFrame() {
|
||||
sendCanPacket(FLOW_CONTROL);
|
||||
}
|
||||
};
|
||||
|
||||
private final IsoTpConnector isoTpConnector = new IsoTpConnector() {
|
||||
@Override
|
||||
public void sendCanData(byte[] hdr, byte[] data, int dataOffset, int dataLength) {
|
||||
byte[] total = combineArrays(hdr, data, dataOffset, dataLength);
|
||||
|
||||
sendCanPacket(total);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData() {
|
||||
}
|
||||
};
|
||||
|
||||
private void sendCanPacket(byte[] total) {
|
||||
if (log.debugEnabled())
|
||||
log.debug("-------sendIsoTp " + total.length + " byte(s):");
|
||||
|
||||
if (log.debugEnabled())
|
||||
log.debug("Sending " + IoStream.printHexBinary(total));
|
||||
|
||||
CanFrame packet = CanFrame.create(Fields.CAN_ECU_SERIAL_RX_ID, FD_NO_FLAGS, total);
|
||||
try {
|
||||
socket.write(packet);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public SocketCANIoStream() {
|
||||
try {
|
||||
NetworkDevice canInterface = NetworkDevice.lookup(System.getProperty("CAN_DEVICE_NAME", "can0"));
|
||||
socket = CanChannels.newRawChannel();
|
||||
socket.bind(canInterface);
|
||||
|
||||
socket.configureBlocking(true); // we want reader thread to wait for messages
|
||||
socket.setOption(RECV_OWN_MSGS, false);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error looking up", e);
|
||||
}
|
||||
// buffer could only be created once socket variable is not null due to callback
|
||||
dataBuffer = createDataBuffer("[SocketCAN] ");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SocketCANIoStream create() {
|
||||
return new SocketCANIoStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] bytes) throws IOException {
|
||||
IsoTpConnector.sendStrategy(bytes, isoTpConnector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputListener(DataListener listener) {
|
||||
Executor threadExecutor = Executors.newSingleThreadExecutor(BinaryProtocolServer.getThreadFactory("SocketCAN reader"));
|
||||
threadExecutor.execute(() -> {
|
||||
while (!isClosed()) {
|
||||
readOnePacket(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void readOnePacket(DataListener listener) {
|
||||
try {
|
||||
CanFrame rx = socket.read();
|
||||
if (log.debugEnabled())
|
||||
log.debug("GOT " + String.format("%X", rx));
|
||||
if (rx.getId() != CAN_ECU_SERIAL_TX_ID) {
|
||||
if (log.debugEnabled())
|
||||
log.debug("Skipping non " + String.format("%X", CAN_ECU_SERIAL_TX_ID) + " packet: " + String.format("%X", rx.getId()));
|
||||
return;
|
||||
}
|
||||
byte[] raw = new byte[rx.getDataLength()];
|
||||
rx.getData(raw, 0, raw.length);
|
||||
byte[] decode = canDecoder.decodePacket(raw);
|
||||
listener.onDataArrived(decode);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingDataBuffer getDataBuffer() {
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
public static IoStream createStream() {
|
||||
return new SocketCANIoStream();
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
package com.rusefi.io.tcp;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.CompatibleFunction;
|
||||
import com.rusefi.Listener;
|
||||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.binaryprotocol.IoHelper;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static com.rusefi.config.generated.Fields.TS_PROTOCOL;
|
||||
import static com.rusefi.core.FileUtil.close;
|
||||
|
||||
/**
|
||||
* Takes any IoStream and exposes it as local TCP/IP server socket
|
||||
*/
|
||||
public class BinaryProtocolProxy {
|
||||
private static final Logging log = getLogging(BinaryProtocolProxy.class);
|
||||
/**
|
||||
* we expect server to at least request output channels once in a while
|
||||
* it could be a while between user connecting authenticator and actually connecting application to authenticator
|
||||
* See Backend#APPLICATION_INACTIVITY_TIMEOUT
|
||||
*/
|
||||
public static final int USER_IO_TIMEOUT = 10 * Timeouts.MINUTE;
|
||||
|
||||
/**
|
||||
* @return starts a thread and returns a reference to ServerSocketReference
|
||||
*/
|
||||
public static ServerSocketReference createProxy(IoStream targetEcuSocket, int serverProxyPort, ClientApplicationActivityListener clientApplicationActivityListener, StatusConsumer statusConsumer) throws IOException {
|
||||
CompatibleFunction<Socket, Runnable> clientSocketRunnableFactory = clientSocket -> () -> {
|
||||
TcpIoStream clientStream = null;
|
||||
try {
|
||||
clientStream = new TcpIoStream("[[proxy]] ", clientSocket);
|
||||
runProxy(targetEcuSocket, clientStream, clientApplicationActivityListener, USER_IO_TIMEOUT);
|
||||
} catch (IOException e) {
|
||||
statusConsumer.append("ERROR BinaryProtocolProxy::run " + e);
|
||||
close(clientStream);
|
||||
}
|
||||
};
|
||||
return BinaryProtocolServer.tcpServerSocket(serverProxyPort, "proxy", clientSocketRunnableFactory, Listener.empty(), statusConsumer);
|
||||
}
|
||||
|
||||
public interface ClientApplicationActivityListener {
|
||||
ClientApplicationActivityListener VOID = () -> {
|
||||
};
|
||||
|
||||
void onActivity();
|
||||
}
|
||||
|
||||
public static void runProxy(IoStream targetEcu, IoStream clientStream, ClientApplicationActivityListener listener, int timeoutMs) throws IOException {
|
||||
/*
|
||||
* Each client socket is running on it's own thread
|
||||
*/
|
||||
while (!targetEcu.isClosed()) {
|
||||
byte firstByte = clientStream.getDataBuffer().readByte(timeoutMs);
|
||||
if (firstByte == Fields.TS_GET_PROTOCOL_VERSION_COMMAND_F) {
|
||||
log.info("Responding to GET_PROTOCOL_VERSION with " + TS_PROTOCOL);
|
||||
clientStream.write(TS_PROTOCOL.getBytes());
|
||||
clientStream.flush();
|
||||
continue;
|
||||
}
|
||||
BinaryProtocolServer.Packet clientRequest = readClientRequest(clientStream.getDataBuffer(), firstByte);
|
||||
byte[] packet = clientRequest.getPacket();
|
||||
if (packet.length > 1 && packet[0] == Fields.TS_ONLINE_PROTOCOL && packet[1] == NetworkConnector.DISCONNECT)
|
||||
throw new IOException("User requested disconnect");
|
||||
listener.onActivity();
|
||||
|
||||
/**
|
||||
* Two reasons for synchronization:
|
||||
* - we run gauge poking thread until TunerStudio connects
|
||||
* - technically there could be two parallel connections to local application port
|
||||
*/
|
||||
BinaryProtocolServer.Packet controllerResponse;
|
||||
synchronized (targetEcu) {
|
||||
sendToTarget(targetEcu, clientRequest);
|
||||
controllerResponse = targetEcu.readPacket();
|
||||
}
|
||||
|
||||
if (log.debugEnabled())
|
||||
log.debug("Relaying controller response length=" + controllerResponse.getPacket().length);
|
||||
clientStream.sendPacket(controllerResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static BinaryProtocolServer.Packet readClientRequest(IncomingDataBuffer in, byte firstByte) throws IOException {
|
||||
byte secondByte = in.readByte();
|
||||
int length = IoHelper.getInt(firstByte, secondByte);
|
||||
|
||||
return BinaryProtocolServer.readPromisedBytes(in, length);
|
||||
}
|
||||
|
||||
private static void sendToTarget(IoStream targetOutputStream, BinaryProtocolServer.Packet packet) throws IOException {
|
||||
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(packet.getPacket()));
|
||||
byte command = (byte) dis.read();
|
||||
|
||||
if (log.debugEnabled())
|
||||
log.debug("Relaying client command " + BinaryProtocol.findCommand(command));
|
||||
// sending proxied packet to controller
|
||||
targetOutputStream.sendPacket(packet);
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ import com.rusefi.io.LinkManager;
|
|||
import com.rusefi.io.commands.ByteRange;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
import com.rusefi.io.commands.WriteChunkCommand;
|
||||
import com.rusefi.server.rusEFISSLContext;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -57,8 +56,6 @@ public class BinaryProtocolServer {
|
|||
|
||||
public AtomicInteger unknownCommands = new AtomicInteger();
|
||||
|
||||
public static final ServerSocketFunction SECURE_SOCKET_FACTORY = rusEFISSLContext::getSSLServerSocket;
|
||||
|
||||
private final static ConcurrentHashMap<String, ThreadFactory> THREAD_FACTORIES_BY_NAME = new ConcurrentHashMap<>();
|
||||
|
||||
public void start(LinkManager linkManager) {
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
package com.rusefi.proxy;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.NamedThreadFactory;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import com.rusefi.io.tcp.TcpIoStream;
|
||||
import com.rusefi.server.SessionDetails;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static com.rusefi.core.FileUtil.close;
|
||||
|
||||
public class BaseBroadcastingThread {
|
||||
private static final Logging log = getLogging(BaseBroadcastingThread.class);
|
||||
private static final NamedThreadFactory BASE_BROADCASTING_THREAD = new NamedThreadFactory("network connector");
|
||||
private final Thread thread;
|
||||
|
||||
@SuppressWarnings("InfiniteLoopStatement")
|
||||
public BaseBroadcastingThread(Socket socket, SessionDetails sessionDetails, TcpIoStream.DisconnectListener disconnectListener, NetworkConnectorContext context) {
|
||||
thread = BASE_BROADCASTING_THREAD.newThread(() -> {
|
||||
TcpIoStream stream = null;
|
||||
try {
|
||||
stream = new TcpIoStream("[network connector] ", socket, disconnectListener);
|
||||
IncomingDataBuffer in = stream.getDataBuffer();
|
||||
boolean isFirstHello = true;
|
||||
while (true) {
|
||||
int ioTimeout;
|
||||
if (isFirstHello) {
|
||||
log.info("Waiting for proxy server to request session details");
|
||||
ioTimeout = context.firstPacketTimeout();
|
||||
} else {
|
||||
ioTimeout = context.consecutivePacketTimeout();
|
||||
}
|
||||
int length = BinaryProtocolServer.getPacketLength(in, () -> {
|
||||
throw new UnsupportedOperationException();
|
||||
}, ioTimeout);
|
||||
BinaryProtocolServer.Packet packet = BinaryProtocolServer.readPromisedBytes(in, length);
|
||||
byte[] payload = packet.getPacket();
|
||||
|
||||
byte command = payload[0];
|
||||
|
||||
if (isFirstHello && command == Fields.TS_HELLO_COMMAND) {
|
||||
// first TS_HELLO_COMMAND is PROXY request, consecutive TS_HELLO_COMMAND would be real deal from user desktop application
|
||||
isFirstHello = false;
|
||||
// respond on hello request with information about session
|
||||
log.info("Replying to controller connector@proxy: " + sessionDetails);
|
||||
new HelloCommand(sessionDetails.toJson()).handle(stream);
|
||||
} else {
|
||||
handleCommand(packet, stream);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("exiting thread " + e);
|
||||
close(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void handleCommand(BinaryProtocolServer.Packet packet, TcpIoStream stream) throws IOException {
|
||||
}
|
||||
|
||||
public void start() {
|
||||
thread.start();
|
||||
}
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
package com.rusefi.proxy;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.opensr5.ConfigurationImage;
|
||||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.AbstractConnectionStateListener;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import com.rusefi.io.tcp.TcpIoStream;
|
||||
import com.rusefi.core.rusEFIVersion;
|
||||
import com.rusefi.server.ControllerInfo;
|
||||
import com.rusefi.server.SessionDetails;
|
||||
import com.rusefi.server.rusEFISSLContext;
|
||||
import com.rusefi.tools.VehicleToken;
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
||||
|
||||
/**
|
||||
* Connector between rusEFI ECU and rusEFI server
|
||||
* see NetworkConnectorStartup
|
||||
*/
|
||||
public class NetworkConnector implements Closeable {
|
||||
/**
|
||||
* @see NetworkConnectorContext
|
||||
* See broadcash.sh
|
||||
*/
|
||||
public static final byte DISCONNECT = 14;
|
||||
public static final byte UPDATE_CONNECTOR_SOFTWARE_LATEST = 15;
|
||||
public static final byte UPDATE_FIRMWARE_LATEST = 16;
|
||||
public static final byte UPDATE_CONNECTOR_SOFTWARE_RELEASE = 17;
|
||||
public static final byte UPDATE_FIRMWARE_RELEASE = 17;
|
||||
private final static Logging log = Logging.getLogging(NetworkConnector.class);
|
||||
private boolean isClosed;
|
||||
|
||||
public NetworkConnectorResult start(Implementation implementation, String authToken, String controllerPort, NetworkConnectorContext context) {
|
||||
return start(implementation, authToken, controllerPort, context, new ReconnectListener() {
|
||||
@Override
|
||||
public void onReconnect() {
|
||||
log.info("onReconnect");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public NetworkConnectorResult start(Implementation implementation, String authToken, String controllerPort, NetworkConnectorContext context, ReconnectListener reconnectListener) {
|
||||
LinkManager controllerConnector = new LinkManager()
|
||||
.setCompositeLogicEnabled(false)
|
||||
.setNeedPullData(false);
|
||||
|
||||
CountDownLatch onConnected = new CountDownLatch(1);
|
||||
controllerConnector.startAndConnect(controllerPort, new AbstractConnectionStateListener() {
|
||||
@Override
|
||||
public void onConnectionEstablished() {
|
||||
onConnected.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
log.info("Connecting to controller...");
|
||||
try {
|
||||
onConnected.await(1, TimeUnit.MINUTES);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
if (onConnected.getCount() != 0) {
|
||||
log.info("Connection to controller failed");
|
||||
return NetworkConnectorResult.ERROR;
|
||||
}
|
||||
|
||||
return start(implementation, authToken, context, reconnectListener, controllerConnector, ActivityListener.VOID);
|
||||
}
|
||||
|
||||
public NetworkConnectorResult start(Implementation implementation, String authToken, NetworkConnectorContext context, ReconnectListener reconnectListener, LinkManager linkManager, ActivityListener activityListener) {
|
||||
ControllerInfo controllerInfo;
|
||||
try {
|
||||
controllerInfo = getControllerInfo(linkManager, linkManager.getConnector().getBinaryProtocol().getStream());
|
||||
} catch (IOException e) {
|
||||
return NetworkConnectorResult.ERROR;
|
||||
}
|
||||
|
||||
int vehicleToken = VehicleToken.getOrCreate();
|
||||
|
||||
BinaryProtocolServer.getThreadFactory("Proxy Reconnect").newThread(() -> {
|
||||
Semaphore proxyReconnectSemaphore = new Semaphore(1);
|
||||
try {
|
||||
while (!isClosed) {
|
||||
proxyReconnectSemaphore.acquire();
|
||||
|
||||
try {
|
||||
start(implementation,
|
||||
activityListener,
|
||||
context.serverPortForControllers(), linkManager, authToken, (String message) -> {
|
||||
log.error(message + " Disconnect from proxy server detected, now sleeping " + context.reconnectDelay() + " seconds");
|
||||
sleep(context.reconnectDelay() * Timeouts.SECOND);
|
||||
log.debug("Releasing semaphore");
|
||||
proxyReconnectSemaphore.release();
|
||||
reconnectListener.onReconnect();
|
||||
}, vehicleToken, controllerInfo, context);
|
||||
} catch (IOException e) {
|
||||
log.error("IO error", e);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}).start();
|
||||
|
||||
return new NetworkConnectorResult(controllerInfo, vehicleToken);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SessionDetails start(Implementation implementation, ActivityListener activityListener, int serverPortForControllers, LinkManager linkManager, String authToken, final TcpIoStream.DisconnectListener disconnectListener, int oneTimeToken, ControllerInfo controllerInfo, final NetworkConnectorContext context) throws IOException {
|
||||
IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream();
|
||||
|
||||
SessionDetails deviceSessionDetails = new SessionDetails(implementation, controllerInfo, authToken, oneTimeToken, rusEFIVersion.CONSOLE_VERSION);
|
||||
|
||||
Socket socket;
|
||||
try {
|
||||
log.info("Connecting to proxy server " + HttpUtil.RUSEFI_PROXY_HOSTNAME + " " + serverPortForControllers);
|
||||
socket = rusEFISSLContext.getSSLSocket(HttpUtil.RUSEFI_PROXY_HOSTNAME, serverPortForControllers);
|
||||
} catch (IOException e) {
|
||||
// socket open exception is a special case and should be handled separately
|
||||
disconnectListener.onDisconnect("on socket open");
|
||||
return deviceSessionDetails;
|
||||
}
|
||||
BaseBroadcastingThread baseBroadcastingThread = new BaseBroadcastingThread(socket,
|
||||
deviceSessionDetails,
|
||||
disconnectListener, context) {
|
||||
@Override
|
||||
protected void handleCommand(BinaryProtocolServer.Packet packet, TcpIoStream stream) throws IOException {
|
||||
super.handleCommand(packet, stream);
|
||||
byte command = packet.getPacket()[0];
|
||||
if (command == Fields.TS_ONLINE_PROTOCOL) {
|
||||
byte connectorCommand = packet.getPacket()[1];
|
||||
log.info("Got connector command " + packet.getPacket());
|
||||
if (connectorCommand == NetworkConnector.UPDATE_CONNECTOR_SOFTWARE_LATEST) {
|
||||
context.onConnectorSoftwareUpdateToLatestRequest();
|
||||
} else if (connectorCommand == NetworkConnector.UPDATE_CONNECTOR_SOFTWARE_RELEASE) {
|
||||
context.onConnectorSoftwareUpdateToReleaseRequest();
|
||||
} else if (connectorCommand == NetworkConnector.UPDATE_FIRMWARE_LATEST) {
|
||||
context.onFirmwareUpdateToLatestRequest();
|
||||
} else if (connectorCommand == NetworkConnector.UPDATE_FIRMWARE_RELEASE) {
|
||||
context.onFirmwareUpdateToReleaseRequest();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Relaying request to controller " + BinaryProtocol.findCommand(command));
|
||||
targetEcuSocket.sendPacket(packet);
|
||||
|
||||
BinaryProtocolServer.Packet response = targetEcuSocket.readPacket();
|
||||
log.info("Relaying response to proxy size=" + response.getPacket().length);
|
||||
stream.sendPacket(response);
|
||||
activityListener.onActivity(targetEcuSocket);
|
||||
}
|
||||
};
|
||||
baseBroadcastingThread.start();
|
||||
return deviceSessionDetails;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ControllerInfo getControllerInfo(LinkManager linkManager, IoStream targetEcuSocket) throws IOException {
|
||||
HelloCommand.send(targetEcuSocket);
|
||||
String helloResponse = HelloCommand.getHelloResponse(targetEcuSocket.getDataBuffer());
|
||||
if (helloResponse == null)
|
||||
throw new IOException("Error getting hello response");
|
||||
String controllerSignature = helloResponse.trim();
|
||||
|
||||
ConfigurationImage image = linkManager.getConnector().getBinaryProtocol().getControllerConfiguration();
|
||||
String vehicleName = Fields.VEHICLENAME.getStringValue(image);
|
||||
String engineMake = Fields.ENGINEMAKE.getStringValue(image);
|
||||
String engineCode = Fields.ENGINECODE.getStringValue(image);
|
||||
return new ControllerInfo(vehicleName, engineMake, engineCode, controllerSignature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
isClosed = true;
|
||||
}
|
||||
|
||||
public static class NetworkConnectorResult {
|
||||
static NetworkConnectorResult ERROR = new NetworkConnectorResult(null, 0);
|
||||
private final ControllerInfo controllerInfo;
|
||||
private final int oneTimeToken;
|
||||
|
||||
public NetworkConnectorResult(ControllerInfo controllerInfo, int oneTimeToken) {
|
||||
this.controllerInfo = controllerInfo;
|
||||
this.oneTimeToken = oneTimeToken;
|
||||
}
|
||||
|
||||
public ControllerInfo getControllerInfo() {
|
||||
return controllerInfo;
|
||||
}
|
||||
|
||||
public int getOneTimeToken() {
|
||||
return oneTimeToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NetworkConnectorResult{" +
|
||||
"controllerInfo=" + controllerInfo +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public interface ReconnectListener {
|
||||
ReconnectListener VOID = new ReconnectListener() {
|
||||
@Override
|
||||
public void onReconnect() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
void onReconnect();
|
||||
}
|
||||
|
||||
public interface ActivityListener {
|
||||
ActivityListener VOID = new ActivityListener() {
|
||||
@Override
|
||||
public void onActivity(IoStream targetEcuSocket) {
|
||||
|
||||
}
|
||||
};
|
||||
void onActivity(IoStream targetEcuSocket);
|
||||
}
|
||||
|
||||
public enum Implementation {
|
||||
Android,
|
||||
Plugin,
|
||||
SBC,
|
||||
Unknown;
|
||||
|
||||
public static Implementation find(String name) {
|
||||
for (Implementation implementation : values()) {
|
||||
if (implementation.name().equalsIgnoreCase(name))
|
||||
return implementation;
|
||||
}
|
||||
return Unknown;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package com.rusefi.proxy;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.proxy.client.LocalApplicationProxyContext;
|
||||
import com.rusefi.tools.online.ProxyClient;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
|
||||
public class NetworkConnectorContext {
|
||||
private static final Logging log = getLogging(NetworkConnectorContext.class);
|
||||
private static final int UPDATE_LATEST_SBC_EXIT_CODE = 15;
|
||||
public static final int UPDATE_LATEST_FIRMWARE_EXIT_CODE = 16;
|
||||
private static final int UPDATE_RELEASE_SBC_EXIT_CODE = 17;
|
||||
public static final int UPDATE_RELEASE_FIRMWARE_EXIT_CODE = 18;
|
||||
|
||||
public int reconnectDelay() {
|
||||
return 15; // this one is seconds
|
||||
}
|
||||
|
||||
public int firstPacketTimeout() {
|
||||
return Timeouts.CMD_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Application is supposed to be constantly poking the controller one way or another
|
||||
*
|
||||
* @see LocalApplicationProxyContext#gaugePokingPeriod()
|
||||
*/
|
||||
public int consecutivePacketTimeout() {
|
||||
return 30 * Timeouts.SECOND;
|
||||
}
|
||||
|
||||
public int serverPortForControllers() {
|
||||
return ProxyClient.SERVER_PORT_FOR_CONTROLLERS;
|
||||
}
|
||||
|
||||
public void onConnectorSoftwareUpdateToLatestRequest() {
|
||||
log.info("onConnectorSoftwareUpdateToLatestRequest");
|
||||
System.exit(UPDATE_LATEST_SBC_EXIT_CODE);
|
||||
}
|
||||
|
||||
public void onConnectorSoftwareUpdateToReleaseRequest() {
|
||||
log.info("onConnectorSoftwareUpdateToReleaseRequest");
|
||||
System.exit(UPDATE_RELEASE_SBC_EXIT_CODE);
|
||||
}
|
||||
|
||||
public void onFirmwareUpdateToLatestRequest() {
|
||||
log.info("onFirmwareUpdateRequest");
|
||||
System.exit(UPDATE_LATEST_FIRMWARE_EXIT_CODE);
|
||||
}
|
||||
|
||||
public void onFirmwareUpdateToReleaseRequest() {
|
||||
log.info("onFirmwareUpdateRequest");
|
||||
System.exit(UPDATE_RELEASE_FIRMWARE_EXIT_CODE);
|
||||
}
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
package com.rusefi.proxy.client;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.NamedThreadFactory;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.commands.GetOutputsCommand;
|
||||
import com.rusefi.io.commands.HelloCommand;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import com.rusefi.io.serial.StreamStatistics;
|
||||
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||
import com.rusefi.io.tcp.ServerSocketReference;
|
||||
import com.rusefi.io.tcp.TcpIoStream;
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.server.ApplicationRequest;
|
||||
import com.rusefi.server.rusEFISSLContext;
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import com.rusefi.tools.online.ProxyClient;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static com.rusefi.Timeouts.BINARY_IO_TIMEOUT;
|
||||
import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
||||
|
||||
/**
|
||||
* Remote user process which facilitates connection between local tuning application and real ECU via rusEFI proxy service
|
||||
*/
|
||||
public class LocalApplicationProxy implements Closeable {
|
||||
private static final ThreadFactory THREAD_FACTORY = new NamedThreadFactory("gauge poking", true);
|
||||
private static final Logging log = getLogging(LocalApplicationProxy.class);
|
||||
public static final int SERVER_PORT_FOR_APPLICATIONS = HttpUtil.getIntProperty("applications.port", 8002);
|
||||
private final ApplicationRequest applicationRequest;
|
||||
/**
|
||||
* local TCP server socket which local tuning application connects to
|
||||
*/
|
||||
private final ServerSocketReference serverHolder;
|
||||
private final IoStream authenticatorToProxyStream;
|
||||
|
||||
public LocalApplicationProxy(ApplicationRequest applicationRequest, ServerSocketReference serverHolder, IoStream authenticatorToProxyStream) {
|
||||
this.applicationRequest = applicationRequest;
|
||||
this.serverHolder = serverHolder;
|
||||
this.authenticatorToProxyStream = authenticatorToProxyStream;
|
||||
}
|
||||
|
||||
public IoStream getAuthenticatorToProxyStream() {
|
||||
return authenticatorToProxyStream;
|
||||
}
|
||||
|
||||
public static HttpResponse requestSoftwareUpdate(int httpPort, ApplicationRequest applicationRequest, UpdateType type) throws IOException {
|
||||
HttpPost httpPost = new HttpPost(ProxyClient.getHttpAddress(httpPort) + ProxyClient.UPDATE_CONNECTOR_SOFTWARE);
|
||||
|
||||
List<NameValuePair> form = new ArrayList<>();
|
||||
form.add(new BasicNameValuePair(ProxyClient.JSON, applicationRequest.toJson()));
|
||||
form.add(new BasicNameValuePair(ProxyClient.UPDATE_TYPE, type.name()));
|
||||
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form, Consts.UTF_8);
|
||||
|
||||
httpPost.setEntity(entity);
|
||||
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
return httpclient.execute(httpPost);
|
||||
}
|
||||
|
||||
public ApplicationRequest getApplicationRequest() {
|
||||
return applicationRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param applicationRequest remote session we want to connect to
|
||||
* @param jsonHttpPort
|
||||
* @param disconnectListener
|
||||
* @param connectionListener
|
||||
*/
|
||||
public static ServerSocketReference startAndRun(LocalApplicationProxyContext context, ApplicationRequest applicationRequest, int jsonHttpPort, TcpIoStream.DisconnectListener disconnectListener, ConnectionListener connectionListener) throws IOException {
|
||||
String version = context.executeGet(ProxyClient.getHttpAddress(jsonHttpPort) + ProxyClient.VERSION_PATH);
|
||||
log.info("Server says version=" + version);
|
||||
if (!version.contains(ProxyClient.BACKEND_VERSION)) {
|
||||
String message = "Unexpected backend version " + version + " while we want " + ProxyClient.BACKEND_VERSION;
|
||||
log.error(message);
|
||||
System.out.println(message);
|
||||
/**
|
||||
* let's give wrapper script a chance to update us
|
||||
*/
|
||||
throw new IncompatibleBackendException(message);
|
||||
}
|
||||
|
||||
AbstractIoStream authenticatorToProxyStream = new TcpIoStream("authenticatorToProxyStream ", rusEFISSLContext.getSSLSocket(HttpUtil.RUSEFI_PROXY_HOSTNAME, context.serverPortForRemoteApplications()), disconnectListener);
|
||||
LocalApplicationProxy.sendHello(authenticatorToProxyStream, applicationRequest);
|
||||
|
||||
AtomicLong lastActivity = new AtomicLong(System.currentTimeMillis());
|
||||
BinaryProtocolProxy.ClientApplicationActivityListener clientApplicationActivityListener = () -> lastActivity.set(System.currentTimeMillis());
|
||||
|
||||
/**
|
||||
* We need to entertain proxy server and remote controller while user has already connected to proxy but has not yet started TunerStudio
|
||||
*/
|
||||
THREAD_FACTORY.newThread(() -> {
|
||||
try {
|
||||
while (true) {
|
||||
sleep(context.gaugePokingPeriod());
|
||||
if (isTimeForApplicationToConnect(lastActivity.get(), BINARY_IO_TIMEOUT / 2)) {
|
||||
// TODO: why is this logic duplicated from BinaryProtocol?
|
||||
byte[] commandPacket = new byte[5];
|
||||
commandPacket[0] = Fields.TS_OUTPUT_COMMAND;
|
||||
System.arraycopy(GetOutputsCommand.createRequest(), 0, commandPacket, 1, 4);
|
||||
|
||||
// we do not really need the data, we just need to take response from the socket
|
||||
authenticatorToProxyStream.sendAndGetPacket(commandPacket, "Gauge Poker");
|
||||
}
|
||||
|
||||
if (isTimeForApplicationToConnect(lastActivity.get(), context.startUpIdle())) {
|
||||
// we should not keep controller blocked since we are not connecting application, time to auto-disconnect
|
||||
authenticatorToProxyStream.close();
|
||||
disconnectListener.onDisconnect("Giving up connection");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Gauge poker", e);
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
ServerSocketReference serverHolder = BinaryProtocolProxy.createProxy(authenticatorToProxyStream, context.authenticatorPort(), clientApplicationActivityListener, StatusConsumer.ANONYMOUS);
|
||||
LocalApplicationProxy localApplicationProxy = new LocalApplicationProxy(applicationRequest, serverHolder, authenticatorToProxyStream);
|
||||
connectionListener.onConnected(localApplicationProxy, authenticatorToProxyStream);
|
||||
return serverHolder;
|
||||
}
|
||||
|
||||
private static boolean isTimeForApplicationToConnect(long start, int idle) {
|
||||
return System.currentTimeMillis() - start > idle;
|
||||
}
|
||||
|
||||
public static void sendHello(IoStream authenticatorToProxyStream, ApplicationRequest applicationRequest) throws IOException {
|
||||
log.info("Pushing " + applicationRequest);
|
||||
// right from connection push session authentication data
|
||||
new HelloCommand(applicationRequest.toJson()).handle(authenticatorToProxyStream);
|
||||
}
|
||||
|
||||
public static void start() {
|
||||
throw new UnsupportedOperationException("TODO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
serverHolder.close();
|
||||
byte[] request = new byte[2];
|
||||
request[0] = Fields.TS_ONLINE_PROTOCOL;
|
||||
request[1] = NetworkConnector.DISCONNECT;
|
||||
try {
|
||||
authenticatorToProxyStream.sendPacket(request);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
authenticatorToProxyStream.close();
|
||||
}
|
||||
|
||||
public interface ConnectionListener {
|
||||
ConnectionListener VOID = (localApplicationProxy, authenticatorToProxyStream) -> {
|
||||
};
|
||||
|
||||
void onConnected(LocalApplicationProxy localApplicationProxy, StreamStatistics authenticatorToProxyStream);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package com.rusefi.proxy.client;
|
||||
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class LocalApplicationProxyContextImpl implements LocalApplicationProxyContext {
|
||||
@Override
|
||||
public String executeGet(String url) throws IOException {
|
||||
return HttpUtil.executeGet(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int serverPortForRemoteApplications() {
|
||||
return LocalApplicationProxy.SERVER_PORT_FOR_APPLICATIONS;
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package com.rusefi.proxy.client;
|
||||
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
|
||||
public enum UpdateType {
|
||||
CONTROLLER(NetworkConnector.UPDATE_CONNECTOR_SOFTWARE_LATEST),
|
||||
FIRMWARE(NetworkConnector.UPDATE_FIRMWARE_LATEST),
|
||||
CONTROLLER_RELEASE(NetworkConnector.UPDATE_CONNECTOR_SOFTWARE_RELEASE),
|
||||
FIRMWARE_RELEASE(NetworkConnector.UPDATE_FIRMWARE_RELEASE),
|
||||
;
|
||||
|
||||
private final byte code;
|
||||
|
||||
UpdateType(int code) {
|
||||
this.code = (byte) code;
|
||||
}
|
||||
|
||||
public byte getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ApplicationRequest {
|
||||
private static final String SESSION = "session";
|
||||
|
||||
private final SessionDetails sessionDetails;
|
||||
private final UserDetails vehicleOwner;
|
||||
|
||||
public ApplicationRequest(SessionDetails sessionDetails, UserDetails vehicleOwner) {
|
||||
this.sessionDetails = sessionDetails;
|
||||
this.vehicleOwner = vehicleOwner;
|
||||
}
|
||||
|
||||
public SessionDetails getSessionDetails() {
|
||||
return sessionDetails;
|
||||
}
|
||||
|
||||
public UserDetails getVehicleOwner() {
|
||||
return vehicleOwner;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put(SESSION, sessionDetails.toJson());
|
||||
vehicleOwner.put(jsonObject);
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
|
||||
public static ApplicationRequest valueOf(String jsonString) {
|
||||
JSONObject jsonObject = HttpUtil.parse(jsonString);
|
||||
|
||||
UserDetails userDetails = UserDetails.valueOf(jsonObject);
|
||||
|
||||
SessionDetails session = SessionDetails.valueOf((String) jsonObject.get(SESSION));
|
||||
return new ApplicationRequest(session, userDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ApplicationRequest that = (ApplicationRequest) o;
|
||||
return vehicleOwner.equals(that.vehicleOwner) &&
|
||||
sessionDetails.equals(that.sessionDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sessionDetails, vehicleOwner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApplicationRequest{" +
|
||||
"sessionDetails=" + sessionDetails +
|
||||
", targetUserId=" + vehicleOwner +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Controller description without any sensitive information
|
||||
*/
|
||||
public class ControllerInfo {
|
||||
public static final String VEHICLE_NAME = "vehicleName";
|
||||
public static final String ENGINE_MAKE = "engineMake";
|
||||
public static final String ENGINE_CODE = "engineCode";
|
||||
public static final String SIGNATURE = "signature";
|
||||
|
||||
private final String vehicleName;
|
||||
private final String engineMake;
|
||||
private final String engineCode;
|
||||
private final String signature;
|
||||
|
||||
public ControllerInfo(String vehicleName, String engineCode, String engineMake, String signature) {
|
||||
Objects.requireNonNull(vehicleName);
|
||||
Objects.requireNonNull(engineMake);
|
||||
Objects.requireNonNull(engineCode);
|
||||
|
||||
this.vehicleName = vehicleName;
|
||||
this.engineCode = engineCode;
|
||||
this.engineMake = engineMake;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ControllerInfo{" +
|
||||
"vehicleName='" + vehicleName + '\'' +
|
||||
", engineMake='" + engineMake + '\'' +
|
||||
", engineCode='" + engineCode + '\'' +
|
||||
", signature='" + signature + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getVehicleName() {
|
||||
return vehicleName;
|
||||
}
|
||||
|
||||
public String getEngineMake() {
|
||||
return engineMake;
|
||||
}
|
||||
|
||||
public String getEngineCode() {
|
||||
return engineCode;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ControllerInfo valueOf(String jsonString) {
|
||||
JSONObject jsonObject = HttpUtil.parse(jsonString);
|
||||
return valueOf(jsonObject);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ControllerInfo valueOf(JSONObject jsonObject) {
|
||||
String vehicleName = (String) jsonObject.get(VEHICLE_NAME);
|
||||
String engineMake = (String) jsonObject.get(ENGINE_MAKE);
|
||||
String engineCode = (String) jsonObject.get(ENGINE_CODE);
|
||||
String signature = (String) jsonObject.get(SIGNATURE);
|
||||
|
||||
return new ControllerInfo(vehicleName, engineCode, engineMake, signature);
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put(ENGINE_MAKE, engineMake);
|
||||
jsonObject.put(ENGINE_CODE, engineCode);
|
||||
jsonObject.put(VEHICLE_NAME, vehicleName);
|
||||
jsonObject.put(SIGNATURE, signature);
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ControllerInfo that = (ControllerInfo) o;
|
||||
return vehicleName.equals(that.vehicleName) &&
|
||||
engineMake.equals(that.engineMake) &&
|
||||
engineCode.equals(that.engineCode) &&
|
||||
signature.equals(that.signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(vehicleName, engineMake, engineCode, signature);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class ControllerStateDetails {
|
||||
public static final String RPM = "RPM";
|
||||
public static final String CLT = "CLT";
|
||||
private final double clt;
|
||||
private final int rpm;
|
||||
|
||||
public ControllerStateDetails(double clt, int rpm) {
|
||||
this.clt = clt;
|
||||
this.rpm = rpm;
|
||||
}
|
||||
|
||||
public double getClt() {
|
||||
return clt;
|
||||
}
|
||||
|
||||
public int getRpm() {
|
||||
return rpm;
|
||||
}
|
||||
|
||||
public static ControllerStateDetails valueOf(String jsonString) {
|
||||
JSONObject jsonObject = HttpUtil.parse(jsonString);
|
||||
double clt = Double.parseDouble((String) jsonObject.get(CLT));
|
||||
int rpm = Integer.parseInt((String) jsonObject.get(RPM));
|
||||
|
||||
return new ControllerStateDetails(clt, rpm);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class JsonUserDetailsResolver implements UserDetailsResolver {
|
||||
private final static Logging log = Logging.getLogging(JsonUserDetailsResolver.class);
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public UserDetails apply(String authToken) {
|
||||
|
||||
try {
|
||||
String responseString = HttpUtil.executeGet(HttpUtil.RUSEFI_ONLINE_JSON_API_PREFIX + "getUserByToken&rusefi_token=" + authToken);
|
||||
JSONObject json = HttpUtil.getJsonResponse(responseString);
|
||||
log.info("String " + json);
|
||||
Object getUserByToken = json.get("getUserByToken");
|
||||
if (getUserByToken instanceof String) {
|
||||
log.info("AUTH FAILED: Result " + getUserByToken);
|
||||
return null;
|
||||
}
|
||||
JSONObject details = (JSONObject) getUserByToken;
|
||||
String id = (String) details.get("ID");
|
||||
String name = (String) details.get("NAME");
|
||||
|
||||
UserDetails result = new UserDetails(name, Integer.parseInt(id));
|
||||
log.info("AUTH SUCCESS " + result);
|
||||
return result;
|
||||
} catch (IOException | ParseException e) {
|
||||
log.error("JsonUserDetailsResolver error" + e);
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* A session from Controller, including some sensitive information
|
||||
*/
|
||||
public class SessionDetails {
|
||||
public static final String VEHICLE_TOKEN = "vehicleToken";
|
||||
public static final String AUTH_TOKEN = "authToken";
|
||||
public static final String CONNECTOR_VERSION = "connectorVersion";
|
||||
public static final String IMPLEMENTATION = "implementation";
|
||||
public static final String AGE = "age";
|
||||
public static final String LOCAL_IP = "local_ip";
|
||||
|
||||
private static final String CONTROLLER = "controller";
|
||||
private static final String HARDCODED_ONE_TIME_CODE = System.getProperty("ONE_TIME_CODE");
|
||||
|
||||
private final ControllerInfo controllerInfo;
|
||||
|
||||
private final int vehicleToken;
|
||||
private final String authToken;
|
||||
private final NetworkConnector.Implementation implementation;
|
||||
private final int consoleVersion;
|
||||
@Nullable
|
||||
private final String localIpAddress;
|
||||
|
||||
public SessionDetails(NetworkConnector.Implementation implementation, ControllerInfo controllerInfo, String authToken, int oneTimeCode, int consoleVersion) {
|
||||
this(implementation, controllerInfo, authToken, oneTimeCode, consoleVersion, findLocalIpAddress());
|
||||
}
|
||||
|
||||
private static String findLocalIpAddress() {
|
||||
try {
|
||||
String hostAddress = InetAddress.getLocalHost().getHostAddress();
|
||||
if (hostAddress == null)
|
||||
return "unable to resolve local IP";
|
||||
return hostAddress;
|
||||
} catch (UnknownHostException e) {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public SessionDetails(NetworkConnector.Implementation implementation, ControllerInfo controllerInfo, String authToken, int oneTimeCode, int consoleVersion, String localIpAddress) {
|
||||
this.implementation = Objects.requireNonNull(implementation);
|
||||
this.consoleVersion = consoleVersion;
|
||||
this.localIpAddress = localIpAddress;
|
||||
Objects.requireNonNull(controllerInfo);
|
||||
Objects.requireNonNull(authToken);
|
||||
this.controllerInfo = controllerInfo;
|
||||
this.vehicleToken = oneTimeCode;
|
||||
this.authToken = authToken;
|
||||
}
|
||||
|
||||
public String getLocalIpAddress() {
|
||||
return localIpAddress;
|
||||
}
|
||||
|
||||
public static int createOneTimeCode() {
|
||||
return HARDCODED_ONE_TIME_CODE == null ? new Random().nextInt(100000) : Integer.parseInt(HARDCODED_ONE_TIME_CODE);
|
||||
}
|
||||
|
||||
public NetworkConnector.Implementation getImplementation() {
|
||||
return implementation;
|
||||
}
|
||||
|
||||
public int getOneTimeToken() {
|
||||
return vehicleToken;
|
||||
}
|
||||
|
||||
public ControllerInfo getControllerInfo() {
|
||||
return controllerInfo;
|
||||
}
|
||||
|
||||
public String getAuthToken() {
|
||||
return authToken;
|
||||
}
|
||||
|
||||
public int getConsoleVersion() {
|
||||
return consoleVersion;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put(CONTROLLER, controllerInfo.toJson());
|
||||
jsonObject.put(VEHICLE_TOKEN, vehicleToken);
|
||||
jsonObject.put(AUTH_TOKEN, authToken);
|
||||
jsonObject.put(CONNECTOR_VERSION, consoleVersion);
|
||||
jsonObject.put(IMPLEMENTATION, implementation.name());
|
||||
jsonObject.put(LOCAL_IP, localIpAddress);
|
||||
return jsonObject.toJSONString();
|
||||
}
|
||||
|
||||
public static SessionDetails valueOf(String jsonString) {
|
||||
JSONObject jsonObject = HttpUtil.parse(jsonString);
|
||||
|
||||
String authToken = (String) jsonObject.get(AUTH_TOKEN);
|
||||
long oneTimeCode = (Long) jsonObject.get(VEHICLE_TOKEN);
|
||||
long connectorVersion = (long) jsonObject.get(CONNECTOR_VERSION);
|
||||
String localIp = (String) jsonObject.get(LOCAL_IP);
|
||||
NetworkConnector.Implementation implementation = NetworkConnector.Implementation.find((String) jsonObject.get(IMPLEMENTATION));
|
||||
|
||||
ControllerInfo controllerInfo = ControllerInfo.valueOf((String) jsonObject.get(CONTROLLER));
|
||||
|
||||
return new SessionDetails(implementation, controllerInfo, authToken, (int) oneTimeCode, (int) connectorVersion, localIp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SessionDetails that = (SessionDetails) o;
|
||||
return vehicleToken == that.vehicleToken &&
|
||||
controllerInfo.equals(that.controllerInfo) &&
|
||||
authToken.equals(that.authToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(controllerInfo, vehicleToken, authToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SessionDetails{" +
|
||||
"controllerInfo=" + controllerInfo +
|
||||
", authToken='" + authToken + '\'' +
|
||||
", implementation='" + implementation + '\'' +
|
||||
", consoleVersion='" + consoleVersion + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* rusEFI Online user - ID and username
|
||||
*/
|
||||
public class UserDetails {
|
||||
public static final String USER_ID = "user_id";
|
||||
public static final String USERNAME = "username";
|
||||
private final String userName;
|
||||
private final int userId;
|
||||
|
||||
public UserDetails(String userName, int userId) {
|
||||
this.userName = userName;
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public static UserDetails valueOf(JSONObject element) {
|
||||
long userId = (long) element.get(USER_ID);
|
||||
String userName = (String) element.get(USERNAME);
|
||||
return new UserDetails(userName, (int) userId);
|
||||
}
|
||||
|
||||
void put(JSONObject jsonObject) {
|
||||
jsonObject.put(USER_ID, getUserId());
|
||||
jsonObject.put(USERNAME, getUserName());
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserDetails that = (UserDetails) o;
|
||||
return userId == that.userId && userName.equals(that.userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(userName, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserDetails{" +
|
||||
"userName='" + userName + '\'' +
|
||||
", id=" + userId +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface UserDetailsResolver {
|
||||
/***
|
||||
* @param authToken
|
||||
* @return null in case authentication issues
|
||||
*/
|
||||
@Nullable
|
||||
UserDetails apply(String authToken);
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
package com.rusefi.server;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Objects;
|
||||
|
||||
public class rusEFISSLContext {
|
||||
private static final String TLS = "TLS";
|
||||
|
||||
// I assume that jenkins own setup is interfering with our attempts to change system properties :(
|
||||
// also open question to get SSL context adjusted without touching system properties
|
||||
private static boolean isJenkins = true;//System.getProperty("JENKINS_URL") != null;
|
||||
|
||||
// private static KeyStore key;
|
||||
|
||||
// todo: one day once rusEFI has a proper commercial certificate this should be removed
|
||||
private static TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
public void checkClientTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static void init(String fileName, String password) throws MalformedURLException {
|
||||
// system property setup does not work under Jenkins?
|
||||
if (!isJenkins)
|
||||
setupCertificates(new File(fileName), password);
|
||||
|
||||
//key = getFromPath(fileName, "PKCS12", password);
|
||||
}
|
||||
|
||||
public static ServerSocket getSSLServerSocket(int port) {
|
||||
try {
|
||||
if (isJenkins)
|
||||
return new ServerSocket(port);
|
||||
return SSLServerSocketFactory.getDefault().createServerSocket(port);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error binding secure server socket " + port, e);
|
||||
}
|
||||
// try {
|
||||
// return getSSLServerSocketFactory(key, TLS).createServerSocket(port);
|
||||
// } catch (Exception e) {
|
||||
// throw new IllegalStateException(e);
|
||||
// }
|
||||
}
|
||||
|
||||
public static Socket getSSLSocket(String host, int port) throws IOException {
|
||||
if (isJenkins) {
|
||||
Socket socket = new Socket(host, port);
|
||||
// responsiveness matters (getting a byte sent to be received as promptly as possible)
|
||||
socket.setTcpNoDelay(true);
|
||||
return socket;
|
||||
}
|
||||
return getSSLSocketFactory(null /*key*/, TLS).createSocket(host, port);
|
||||
}
|
||||
|
||||
/*
|
||||
private static SSLServerSocketFactory getSSLServerSocketFactory(KeyStore trustKey, String sslAlgorithm) {
|
||||
try {
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(trustKey);
|
||||
|
||||
SSLContext context = SSLContext.getInstance(sslAlgorithm);
|
||||
context.init(null, tmf.getTrustManagers(), null);
|
||||
|
||||
return context.getServerSocketFactory();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
*/
|
||||
private static SSLSocketFactory getSSLSocketFactory(KeyStore trustKey, String sslAlgorithm) {
|
||||
try {
|
||||
// TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
// tmf.init(trustKey);
|
||||
|
||||
SSLContext context = SSLContext.getInstance(sslAlgorithm);
|
||||
context.init(null, trustAllCerts/*tmf.getTrustManagers()*/, null);
|
||||
|
||||
return context.getSocketFactory();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupCertificates(File certificate, String password) throws MalformedURLException {
|
||||
if (!certificate.exists())
|
||||
throw new IllegalStateException("Certificate not found " + certificate);
|
||||
Objects.requireNonNull(password, "password");
|
||||
|
||||
String file = certificate.toURI().toURL().getFile();
|
||||
System.setProperty("javax.net.ssl.keyStore", file);
|
||||
System.setProperty("javax.net.ssl.keyStorePassword", password);
|
||||
System.setProperty("javax.net.ssl.trustStore", file);
|
||||
System.setProperty("javax.net.ssl.trustStorePassword", password);
|
||||
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
|
||||
}
|
||||
/*
|
||||
private static KeyStore getFromPath(String path, String algorithm, String filePassword) {
|
||||
try {
|
||||
File f = new File(path);
|
||||
|
||||
if (!f.exists())
|
||||
throw new RuntimeException("File not found: " + path);
|
||||
|
||||
FileInputStream keyFile = new FileInputStream(f);
|
||||
KeyStore keystore = KeyStore.getInstance(algorithm);
|
||||
keystore.load(keyFile, filePassword.toCharArray());
|
||||
keyFile.close();
|
||||
|
||||
return keystore;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package com.rusefi.tools;
|
||||
|
||||
import com.rusefi.server.SessionDetails;
|
||||
import com.rusefi.core.preferences.storage.Node;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.rusefi.core.preferences.storage.PersistentConfiguration.getConfig;
|
||||
|
||||
public class VehicleToken {
|
||||
private static final String VEHICLE_TOKEN = "VEHICLE_TOKEN";
|
||||
|
||||
public static int getOrCreate() {
|
||||
String value = getConfig().getRoot().getProperty(VEHICLE_TOKEN, null);
|
||||
if (value == null || !Node.isNumeric(value)) {
|
||||
value = refresh();
|
||||
}
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String refresh() {
|
||||
String value = Integer.toString(SessionDetails.createOneTimeCode());
|
||||
getConfig().getRoot().setProperty(VEHICLE_TOKEN, value);
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ public class HttpUtil {
|
|||
private static final Logging log = getLogging(Logging.class);
|
||||
|
||||
// todo: migrate proxy http json API server to TLS
|
||||
public static final String RUSEFI_PROXY_JSON_PROTOCOL = "http://";
|
||||
public static final int PROXY_JSON_API_HTTP_PORT = getIntProperty("http.port", 8001);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
package com.rusefi.tools.online;
|
||||
|
||||
import com.rusefi.proxy.client.LocalApplicationProxy;
|
||||
import com.rusefi.server.ControllerInfo;
|
||||
import com.rusefi.server.SessionDetails;
|
||||
import com.rusefi.server.UserDetails;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.rusefi.tools.online.HttpUtil.RUSEFI_PROXY_HOSTNAME;
|
||||
import static com.rusefi.tools.online.HttpUtil.getIntProperty;
|
||||
|
||||
public class ProxyClient {
|
||||
public static final String LIST_CONTROLLERS_PATH = "/list_controllers";
|
||||
public static final String LIST_APPLICATIONS_PATH = "/list_applications";
|
||||
public static final String VERSION_PATH = "/version";
|
||||
public static final String UPDATE_CONNECTOR_SOFTWARE = "/update_connector_software";
|
||||
public static final String BACKEND_VERSION = "0.0005";
|
||||
public static final String IS_USED = "isUsed";
|
||||
public static final String OWNER = "owner";
|
||||
/**
|
||||
* @see HttpUtil#PROXY_JSON_API_HTTP_PORT
|
||||
* @see LocalApplicationProxy#SERVER_PORT_FOR_APPLICATIONS
|
||||
*/
|
||||
public static final int SERVER_PORT_FOR_CONTROLLERS = getIntProperty("controllers.port", 8003);
|
||||
public static final String JSON = "json";
|
||||
public static final String UPDATE_TYPE = "type";
|
||||
|
||||
public static List<PublicSession> getOnlineApplications(int httpPort) throws IOException {
|
||||
return getOnlineApplications(getHttpAddress(httpPort) + LIST_CONTROLLERS_PATH);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getHttpAddress(int httpPort) {
|
||||
return HttpUtil.RUSEFI_PROXY_JSON_PROTOCOL + RUSEFI_PROXY_HOSTNAME + ":" + httpPort;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PublicSession> getOnlineApplications(String url) throws IOException {
|
||||
String responseString = HttpUtil.executeGet(url);
|
||||
|
||||
List<PublicSession> userLists = new ArrayList<>();
|
||||
try {
|
||||
JSONArray array = HttpUtil.getJsonResponse(responseString);
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
JSONObject element = (JSONObject) array.get(i);
|
||||
|
||||
ControllerInfo ci = ControllerInfo.valueOf(element);
|
||||
UserDetails vehicleOwner = UserDetails.valueOf(element);
|
||||
boolean isUsed = (Boolean) element.get(IS_USED);
|
||||
String ownerName = (String) element.get(OWNER);
|
||||
String age = (String) element.get(SessionDetails.AGE);
|
||||
String implementation = (String) element.get(SessionDetails.IMPLEMENTATION);
|
||||
userLists.add(new PublicSession(vehicleOwner, ci, isUsed, ownerName, age, implementation));
|
||||
}
|
||||
|
||||
System.out.println("object=" + array);
|
||||
} catch (ParseException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
return userLists;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
package com.rusefi.tools.online;
|
||||
|
||||
import com.rusefi.server.ControllerInfo;
|
||||
import com.rusefi.server.UserDetails;
|
||||
|
||||
public class PublicSession {
|
||||
/**
|
||||
* owner of physical ECU/vehicle
|
||||
*/
|
||||
private final UserDetails vehicleOwner;
|
||||
private final ControllerInfo controllerInfo;
|
||||
private final boolean isUsed;
|
||||
/**
|
||||
* Person currently in control of tuning session
|
||||
*/
|
||||
private final String tunerName;
|
||||
private final String age;
|
||||
private final String implementation;
|
||||
|
||||
public PublicSession(UserDetails vehicleOwner, ControllerInfo controllerInfo, boolean isUsed, String tunerName, String age, String implementation) {
|
||||
this.vehicleOwner = vehicleOwner;
|
||||
this.controllerInfo = controllerInfo;
|
||||
this.isUsed = isUsed;
|
||||
this.tunerName = tunerName;
|
||||
this.age = age;
|
||||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
public String getImplementation() {
|
||||
return implementation;
|
||||
}
|
||||
|
||||
public String getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public UserDetails getVehicleOwner() {
|
||||
return vehicleOwner;
|
||||
}
|
||||
|
||||
public ControllerInfo getControllerInfo() {
|
||||
return controllerInfo;
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return isUsed;
|
||||
}
|
||||
|
||||
public String getTunerName() {
|
||||
return tunerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PublicSession{" +
|
||||
"userDetails=" + vehicleOwner +
|
||||
", controllerInfo=" + controllerInfo +
|
||||
", isUsed=" + isUsed +
|
||||
", ownerName='" + tunerName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: IRcvEventProcessor.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* This interface is implemented by classes which need to process the CAN Receive-Event.
|
||||
*/
|
||||
public interface IRcvEventProcessor
|
||||
{
|
||||
/**
|
||||
* This method is called by the RcvEventDispatcher to process the CAN Receive-Event
|
||||
* by the current implementor
|
||||
* @param channel CAN channel to process event
|
||||
*/
|
||||
public void processRcvEvent(TPCANHandle channel);
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: MutableTPCANHandle.java 7377 2020-08-07 14:40:53Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-07 16:40:53 +0200 (ven., 07 août 2020) $
|
||||
*
|
||||
* Demo Application for PCANBasic JAVA JNI Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* The MutableTPCANHandle class wraps a value of the immutable enumeration TPCANHandle in an object (to be used with the JNI library).
|
||||
*
|
||||
* @version 1.0
|
||||
* @LastChange $Date: $
|
||||
* @author $Author: $
|
||||
*
|
||||
* @Copyright (C) 1999-2021 PEAK-System Technik GmbH, Darmstadt
|
||||
* more Info at http://www.peak-system.com
|
||||
*/
|
||||
public class MutableTPCANHandle
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param value TPCANHandle value
|
||||
*/
|
||||
public MutableTPCANHandle()
|
||||
{
|
||||
this(TPCANHandle.PCAN_NONEBUS);
|
||||
}
|
||||
/**
|
||||
* Constructor
|
||||
* @param value TPCANHandle value
|
||||
*/
|
||||
public MutableTPCANHandle(TPCANHandle value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor based on internal TPCANHandle enum value
|
||||
* @param value TPCANHandle as string
|
||||
*/
|
||||
public MutableTPCANHandle(short value)
|
||||
{
|
||||
this.value = TPCANHandle.PCAN_NONEBUS;
|
||||
for(TPCANHandle handle: TPCANHandle.values()) {
|
||||
if (value == handle.getValue())
|
||||
this.value = handle;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets TPCANHandle value
|
||||
* @return TPCANHandle value
|
||||
*/
|
||||
public TPCANHandle getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets TPCANHandle value
|
||||
* @param value TPCANHandle value
|
||||
*/
|
||||
public void setValue(TPCANHandle value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
public TPCANHandle value;
|
||||
|
||||
/**
|
||||
* Overrides toString() to display int value
|
||||
* @return MutableInteger's value as a string
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
}
|
|
@ -1,335 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: PCANBasic.java 12274 2021-08-30 12:20:04Z Fabrice $
|
||||
* @LastChange $Date: 2021-08-30 14:20:04 +0200 (Mon, 30 Aug 2021) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2021 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* This is the main class for using the PCANBasic API with your java
|
||||
* applications. Steps to use this api:<br><br>
|
||||
* <pre>
|
||||
* 1. Create a new PCANBasic object:<br>
|
||||
* example: <br>
|
||||
* can = new PCANBasic();
|
||||
*
|
||||
* 2. Call the initializeAPI method<br>
|
||||
* example: <br>
|
||||
* can.initializeAPI();<br>
|
||||
*
|
||||
* 3. Call the Initialize method passing the TPCANHandle parameter which you want use, TPCANBaudrate and other parameters for Non-PNP devices <br>
|
||||
* example: <br>
|
||||
* can.initialize(TPCANHandle.PCAN_USBBUS1, TPCANBaudrate.PCAN_BAUD_1M);<br>
|
||||
*
|
||||
* 4. Call the read or write method passing the TPCANHandle parameter which is initialized and you want use<br>
|
||||
* example:
|
||||
* TPCANMsg msg = new TPCANMsg();;
|
||||
* can.Read(TPCANHandle.PCAN_USBBUS1, msg, null);
|
||||
* can.Write(TPCANHandle.PCAN_USBBUS1, msg);
|
||||
* (do not forget to check if msg is null after calling the Read method)<br>
|
||||
*
|
||||
* 5. At the end call the Uninitialize method
|
||||
* example:
|
||||
* can.Uninitialize(TPCANHandle.PCAN_USBBUS1);
|
||||
* </pre>
|
||||
* <br>
|
||||
* A minimalistic program that writes every can message that it receives
|
||||
* (ping-pong)<br>
|
||||
* looks like this:<br>
|
||||
* <pre>
|
||||
*import peak.can.basic.*;
|
||||
*
|
||||
*public class MinimalisticProgram
|
||||
*{
|
||||
* public static void main(String[] args)
|
||||
* {
|
||||
* PCANBasic can = null;
|
||||
* TPCANMsg msg = null;
|
||||
* TPCANStatus status = null;
|
||||
* can = new PCANBasic();
|
||||
* if(!can.initializeAPI())
|
||||
* {
|
||||
* System.out.println("Unable to initialize the API");
|
||||
* System.exit(0);
|
||||
* }
|
||||
* status = can.Initialize(TPCANHandle.PCAN_PCIBUS1, TPCANBaudrate.PCAN_BAUD_1M, TPCANType.PCAN_TYPE_NONE, 0, (short) 0);
|
||||
* msg = new TPCANMsg();
|
||||
* while(true)
|
||||
* {
|
||||
* while(can.Read(TPCANHandle.PCAN_PCIBUS1, msg, null) == TPCANStatus.PCAN_ERROR_OK)
|
||||
* {
|
||||
* status = can.Write(TPCANHandle.PCAN_PCIBUS1, msg);
|
||||
* if(status != TPCANStatus.PCAN_ERROR_OK)
|
||||
* {
|
||||
* System.out.println("Unable to write the CAN message");
|
||||
* System.exit(0);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*}
|
||||
* </pre>
|
||||
*/
|
||||
public class PCANBasic {
|
||||
|
||||
/**
|
||||
* Initializes a PCAN Channel
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @param Btr0Btr1 The speed for the communication (BTR0BTR1 code)
|
||||
* @param HwType NON PLUG'n'PLAY: The type of hardware and operation mode
|
||||
* @param IOPort NON PLUG'n'PLAY: The I/O address for the parallel port
|
||||
* @param Interrupt NON PLUG'n'PLAY: Interrupt number of the parallel port
|
||||
* @return a TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus Initialize(
|
||||
TPCANHandle Channel,
|
||||
TPCANBaudrate Btr0Btr1,
|
||||
TPCANType HwType,
|
||||
int IOPort,
|
||||
short Interrupt);
|
||||
|
||||
/**
|
||||
* Initializes a FD capable PCAN Channel
|
||||
*
|
||||
* <p>
|
||||
* See PCAN_BR_* values Bitrate string must follow the following
|
||||
* construction rules: - parameters and values must be separated by '=' -
|
||||
* Couples of Parameter/value must be separated by ',' - Following Parameter
|
||||
* must be filled out: f_clock, data_brp, data_sjw, data_tseg1, data_tseg2,
|
||||
* nom_brp, nom_sjw, nom_tseg1, nom_tseg2. - Following Parameters are
|
||||
* optional (not used yet): data_ssp_offset, nom_samp
|
||||
* </p>
|
||||
* <p>
|
||||
* Example: f_clock_mhz=80, nom_brp=1, nom_tset1=63, nom_tseg2=16,
|
||||
* nom_sjw=7, data_brp=4, data_tset1=12, data_tseg2=7, data_sjw=1
|
||||
* </p>
|
||||
*
|
||||
* @param Channel The handle of a FD capable PCAN Channel
|
||||
* @param BitrateFD The speed for the communication (FD Bitrate string)
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus InitializeFD(
|
||||
TPCANHandle Channel,
|
||||
TPCANBitrateFD BitrateFD);
|
||||
|
||||
/**
|
||||
* Uninitializes one or all PCAN Channels initialized by CAN_Initialize
|
||||
* Giving the TPCANHandle value "PCAN_NONEBUS", uninitialize all initialized
|
||||
* channels
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus Uninitialize(TPCANHandle Channel);
|
||||
|
||||
/**
|
||||
* Resets the receive and transmit queues of the PCAN Channel A reset of the
|
||||
* CAN controller is not performed.
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus Reset(
|
||||
TPCANHandle Channel);
|
||||
|
||||
/**
|
||||
* Gets the current status of a PCAN Channel
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus GetStatus(
|
||||
TPCANHandle Channel);
|
||||
|
||||
/**
|
||||
* Transmits a CAN message
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @param MessageBuffer A TPCANMsg buffer with the message to be read
|
||||
* @param TimestampBuffer A TPCANTimestamp structure buffer to get the
|
||||
* reception time of the message. If this value is not desired, this
|
||||
* parameter should be passed as NULL
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus Read(
|
||||
TPCANHandle Channel,
|
||||
TPCANMsg MessageBuffer,
|
||||
TPCANTimestamp TimestampBuffer);
|
||||
|
||||
/**
|
||||
* Reads a CAN message from the receive queue of a FD capable PCAN Channel
|
||||
*
|
||||
* @param Channel The handle of a FD capable PCAN Channel
|
||||
* @param MessageBuffer A TPCANMsgFD structure buffer to store the CAN
|
||||
* message
|
||||
* @param TimestampBuffer A TPCANTimestampFD buffer to get the reception
|
||||
* time of the message
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus ReadFD(
|
||||
TPCANHandle Channel,
|
||||
TPCANMsgFD MessageBuffer,
|
||||
TPCANTimestampFD TimestampBuffer);
|
||||
|
||||
/**
|
||||
* Transmits a CAN message
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @param MessageBuffer A TPCANMsg buffer with the message to be sent
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus Write(
|
||||
TPCANHandle Channel,
|
||||
TPCANMsg MessageBuffer);
|
||||
|
||||
/**
|
||||
* Transmits a CAN message over a FD capable PCAN Channel
|
||||
*
|
||||
* @param Channel The handle of a FD capable PCAN Channel
|
||||
* @param MessageBuffer A TPCANMsgFD buffer with the message to be sent
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus WriteFD(
|
||||
TPCANHandle Channel,
|
||||
TPCANMsgFD MessageBuffer);
|
||||
|
||||
/**
|
||||
* Configures the reception filter. The message filter will be expanded with
|
||||
* every call to this function. If it is desired to reset the filter, please
|
||||
* use the CAN_SetParameter function
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @param FromID The lowest CAN ID to be received
|
||||
* @param ToID The highest CAN ID to be received
|
||||
* @param Mode Message type, Standard (11-bit identifier) or Extended
|
||||
* (29-bit identifier)
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus FilterMessages(
|
||||
TPCANHandle Channel,
|
||||
int FromID,
|
||||
int ToID,
|
||||
TPCANMode Mode);
|
||||
|
||||
/**
|
||||
* Retrieves a PCAN Channel value Parameters can be present or not according
|
||||
* with the kind of Hardware (PCAN Channel) being used. If a parameter is
|
||||
* not available, a PCAN_ERROR_ILLPARAMTYPE error will be returned
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @param Parameter The TPCANParameter parameter to get
|
||||
* @param Buffer Buffer for the parameter value
|
||||
* @param BufferLength Size in bytes of the buffer
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus GetValue(
|
||||
TPCANHandle Channel,
|
||||
TPCANParameter Parameter,
|
||||
Object Buffer,
|
||||
int BufferLength);
|
||||
|
||||
/**
|
||||
* Configures or sets a PCAN Channel value Parameters can be present or not
|
||||
* according with the kind of Hardware (PCAN Channel) being used. If a
|
||||
* parameter is not available, a PCAN_ERROR_ILLPARAMTYPE error will be
|
||||
* returned
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @param Parameter The TPCANParameter parameter to get
|
||||
* @param Buffer Buffer for the parameter value
|
||||
* @param BufferLength Size in bytes of the buffer
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus SetValue(
|
||||
TPCANHandle Channel,
|
||||
TPCANParameter Parameter,
|
||||
Object Buffer,
|
||||
int BufferLength);
|
||||
|
||||
/**
|
||||
* Returns a descriptive text of a given TPCANStatus error code, in any
|
||||
* desired language The current languages available for translation are:
|
||||
* Neutral (0x00), German (0x07), English (0x09), Spanish (0x0A), Italian
|
||||
* (0x10) and French (0x0C)
|
||||
*
|
||||
* @param Error A TPCANStatus error code
|
||||
* @param Language Indicates a 'Primary language ID'
|
||||
* @param Buffer Buffer for a null terminated char array
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus GetErrorText(
|
||||
TPCANStatus Error,
|
||||
short Language,
|
||||
StringBuffer Buffer);
|
||||
|
||||
/**
|
||||
* Finds a PCAN-Basic channel that matches with the given parameters
|
||||
*
|
||||
* @param Parameters A comma separated string contained pairs of parameter-name/value to be matched within a PCAN-Basic channel
|
||||
* @param FoundChannel Buffer for returning the PCAN-Basic channel
|
||||
* @param Buffer Buffer for a null terminated char array
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus LookUpChannel(
|
||||
StringBuffer Parameters,
|
||||
MutableTPCANHandle FoundChannel);
|
||||
|
||||
/**
|
||||
* Sets the handle of the Receive-Event for the Channel. static method
|
||||
* peak.can.basic.RcvEventDispatcher.dispatchRcvEvent is used to notify each
|
||||
* Receive-Event
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus SetRcvEvent(TPCANHandle Channel);
|
||||
|
||||
/**
|
||||
* Resets the handle of the Receive-Event for the Channel.
|
||||
*
|
||||
* @param Channel The handle of a PCAN Channel
|
||||
* @return A TPCANStatus error code
|
||||
*/
|
||||
public native TPCANStatus ResetRcvEvent(TPCANHandle Channel);
|
||||
|
||||
/**
|
||||
* Initializes the PCANBasic API
|
||||
*
|
||||
* @return a boolean to indicate if API is successfully loaded
|
||||
*/
|
||||
public native boolean initializeAPI();
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("pcanbasic_jni");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.out.println(e.getMessage());
|
||||
System.loadLibrary("PCANBasic_JNI");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: RcvEventDispatcher.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* This class is a gateway between the PCAN Light JNI and the application to dispatch the CAN Receive-Event.
|
||||
*
|
||||
* RcvEventDispatcher contains a public static method dispatchRcvEvent which is called from the JNI to notify the Java
|
||||
* application when the handle of the Receive-Event detects a state change.
|
||||
*/
|
||||
public class RcvEventDispatcher
|
||||
{
|
||||
static private IRcvEventProcessor listener;
|
||||
|
||||
/**
|
||||
* Gets the Receive-Event processor
|
||||
* @return a IRcvEventProcessor
|
||||
*/
|
||||
public static IRcvEventProcessor getListener()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Receive-Event processor
|
||||
* @param listener a IRcvEventProcessor implementor
|
||||
*/
|
||||
public static void setListener(IRcvEventProcessor listener)
|
||||
{
|
||||
RcvEventDispatcher.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* This static public method will call from JNI to process the Receive-Event
|
||||
* by the listener
|
||||
* @param channel CAN Channel to dispatch the event to.
|
||||
*/
|
||||
static public void dispatchRcvEvent(TPCANHandle channel)
|
||||
{
|
||||
if(listener != null)
|
||||
listener.processRcvEvent(channel);
|
||||
}
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANBaudrate.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Baud rate codes = BTR0/BTR1 register values for the CAN controller. You can
|
||||
* define your own Baud rate with the BTROBTR1 register. Take a look at
|
||||
* www.peak-system.com for our free software "BAUDTOOL" to calculate the
|
||||
* BTROBTR1 register for every baudrate and sample point.
|
||||
*/
|
||||
public enum TPCANBaudrate {
|
||||
|
||||
/**
|
||||
* 1 MBit/s
|
||||
*/
|
||||
PCAN_BAUD_1M(0x0014, false),
|
||||
/**
|
||||
* 800 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_800K(0x0016, false),
|
||||
/**
|
||||
* 500 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_500K(0x001C, false),
|
||||
/**
|
||||
* 250 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_250K(0x011C, false),
|
||||
/**
|
||||
* 125 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_125K(0x031C, false),
|
||||
/**
|
||||
* 100 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_100K(0x432F, false),
|
||||
/**
|
||||
* 95,238 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_95K(0xC34E, false),
|
||||
/**
|
||||
* 83,33 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_83K(0x852B, false),
|
||||
/**
|
||||
* 50 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_50K(0x472F, false),
|
||||
/**
|
||||
* 47,619 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_47K(0x1414, false),
|
||||
/**
|
||||
* 33,333 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_33K(0x8B2F, false),
|
||||
/**
|
||||
* 20 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_20K(0x532F, false),
|
||||
/**
|
||||
* 10 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_10K(0x672F, false),
|
||||
/**
|
||||
* 5 kBit/s
|
||||
*/
|
||||
PCAN_BAUD_5K(0x7F7F, false),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User0(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User1(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User2(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User3(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User4(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User5(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User6(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User7(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User8(0x0, true),
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
PCAN_BAUD_User9(0x0, true);
|
||||
|
||||
private int value;
|
||||
private final boolean user;
|
||||
|
||||
private TPCANBaudrate(int value, boolean user) {
|
||||
this.value = value;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the baud rate code.
|
||||
* @return value of the baud rate code
|
||||
*/
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user-defined value.
|
||||
* @param value Baud rate code
|
||||
*/
|
||||
public void setValue(int value) {
|
||||
if (user) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the user-defined value
|
||||
*/
|
||||
public void clearValue() {
|
||||
if (user) {
|
||||
this.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a TPCANBaudrate matching the corresponding Baud rate code
|
||||
* @param value Baud rate code
|
||||
* @return null or a TPCANBaudrate matching the Baud rate code
|
||||
*/
|
||||
public static TPCANBaudrate valueOf(int value) {
|
||||
for (TPCANBaudrate rate : values()) {
|
||||
if (rate.getValue() == value) {
|
||||
return rate;
|
||||
}
|
||||
}
|
||||
for (TPCANBaudrate rate : values()) {
|
||||
if (rate.user && rate.getValue() == 0) {
|
||||
rate.value = value;
|
||||
return rate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
|
@ -1,65 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANBitrateFD.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* FD bit rates for the CAN FD controller. You can
|
||||
* define your own bit rate with the FD string, as shown in this exemple:
|
||||
* "f_clock_mhz=20, nom_brp=5, nom_tseg1=2, nom_tseg2=1, nom_sjw=1,
|
||||
* data_brp=2, data_tseg1=3, data_tseg2=1, data_sjw=1"
|
||||
*/
|
||||
public class TPCANBitrateFD {
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* Creates a CAN FD bitrate
|
||||
* @param value A CAN FD bitrate string (for instance:
|
||||
* "f_clock_mhz=20, nom_brp=5, nom_tseg1=2, nom_tseg2=1, nom_sjw=1,
|
||||
* data_brp=2, data_tseg1=3, data_tseg2=1, data_sjw=1")
|
||||
*/
|
||||
public TPCANBitrateFD(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string configuration of the bitrate code.
|
||||
* @return The bitrate string configuration
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
/**
|
||||
* Sets string configuration of the bitrate code.
|
||||
* @param value The new bitrate string configuration
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
};
|
|
@ -1,103 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANBitrateFDValue.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Baud rate codes = BTR0/BTR1 register values for the CAN controller. You can
|
||||
* define your own Baud rate with the BTROBTR1 register. Take a look at
|
||||
* www.peak-system.com for our free software "BAUDTOOL" to calculate the
|
||||
* BTROBTR1 register for every baudrate and sample point.
|
||||
*/
|
||||
public enum TPCANBitrateFDValue {
|
||||
|
||||
/**
|
||||
* Clock frequency in Herz (80000000, 60000000, 40000000, 30000000,
|
||||
* 24000000, 20000000)
|
||||
*/
|
||||
PCAN_BR_CLOCK("f_clock"),
|
||||
/**
|
||||
* Clock frequency in Megaherz (80, 60, 40, 30, 24, 20)
|
||||
*/
|
||||
PCAN_BR_CLOCK_MHZ("f_clock_mhz"),
|
||||
/**
|
||||
* Clock prescaler for nominal time quantum
|
||||
*/
|
||||
PCAN_BR_NOM_BRP("nom_brp"),
|
||||
/**
|
||||
* TSEG1 segment for nominal bit rate in time quanta
|
||||
*/
|
||||
PCAN_BR_NOM_TSEG1("nom_tseg1"),
|
||||
/**
|
||||
* TSEG2 segment for nominal bit rate in time quanta
|
||||
*/
|
||||
PCAN_BR_NOM_TSEG2("nom_tseg2"),
|
||||
/**
|
||||
* Synchronization Jump Width for nominal bit rate in time quanta
|
||||
*/
|
||||
PCAN_BR_NOM_SJW("nom_sjw"),
|
||||
/**
|
||||
* Sample point for nominal bit rate
|
||||
*/
|
||||
PCAN_BR_NOM_SAMPLE("nom_sam"),
|
||||
/**
|
||||
* Clock prescaler for highspeed data time quantum
|
||||
*/
|
||||
PCAN_BR_DATA_BRP("data_brp"),
|
||||
/**
|
||||
* TSEG1 segment for fast data bit rate in time quanta
|
||||
*/
|
||||
PCAN_BR_DATA_TSEG1("data_tseg1"),
|
||||
/**
|
||||
* TSEG2 segment for fast data bit rate in time quanta
|
||||
*/
|
||||
PCAN_BR_DATA_TSEG2("data_tseg2"),
|
||||
/**
|
||||
* Synchronization Jump Width for highspeed data bit rate in time quanta
|
||||
*/
|
||||
PCAN_BR_DATA_SJW("data_sjw"),
|
||||
/**
|
||||
* Secondary sample point delay for highspeed data bitrate in cyles
|
||||
*/
|
||||
PCAN_BR_DATA_SAMPLE("data_ssp_offset");
|
||||
|
||||
private final String value;
|
||||
|
||||
private TPCANBitrateFDValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The string value of Bitrate FD string parameter
|
||||
* @return String corresponding to the bitrate FD string parameter
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
};
|
|
@ -1,111 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANChannelInformation.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Class storing the channel's information retrieved with parameter TPCANParameter.PCAN_ATTACHED_CHANNELS.
|
||||
*/
|
||||
public class TPCANChannelInformation {
|
||||
private TPCANHandle _channel_handle; // PCAN channel handle
|
||||
private TPCANDevice _device_type; // Kind of PCAN device
|
||||
private byte _controller_number; // CAN-Controller number
|
||||
private int _device_features; // Device capabilities flag (see FEATURE_*)
|
||||
private String _device_name; // Device name
|
||||
private int _device_id; // Device number
|
||||
private int _channel_condition; // Availability status of a PCAN-Channel
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public TPCANChannelInformation()
|
||||
{
|
||||
}
|
||||
|
||||
public TPCANHandle getChannelHandle() {
|
||||
return _channel_handle;
|
||||
}
|
||||
public void setChannelHandle(TPCANHandle handle) {
|
||||
this._channel_handle = handle;
|
||||
}
|
||||
|
||||
public TPCANDevice getDeviceType() {
|
||||
return _device_type;
|
||||
}
|
||||
public void setDeviceType(TPCANDevice type) {
|
||||
this._device_type = type;
|
||||
}
|
||||
|
||||
public byte getControllerNumber() {
|
||||
return _controller_number;
|
||||
}
|
||||
public void setControllerNumber(byte value) {
|
||||
this._controller_number = value;
|
||||
}
|
||||
|
||||
public int getDeviceFeatures() {
|
||||
return _device_features;
|
||||
}
|
||||
public void setDeviceFeatures(int features) {
|
||||
this._device_features = features;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return _device_name;
|
||||
}
|
||||
public void setDeviceName(String name) {
|
||||
this._device_name = name;
|
||||
}
|
||||
|
||||
public int getDeviceId() {
|
||||
return _device_id;
|
||||
}
|
||||
public void setDeviceId(int id) {
|
||||
this._device_id = id;
|
||||
}
|
||||
|
||||
public int getChannelCondition() {
|
||||
return _channel_condition;
|
||||
}
|
||||
public void setChannelCondition(int value) {
|
||||
this._channel_condition = value;
|
||||
}
|
||||
|
||||
public String toListString(String listIndent) {
|
||||
String str = "";
|
||||
str += "\n" + listIndent + "channel_handle = " + getChannelHandle();
|
||||
str += "\n" + listIndent + "device_type = " + getDeviceType();
|
||||
str += "\n" + listIndent + "controller_number = " + getControllerNumber();
|
||||
str += "\n" + listIndent + "device_features = " + getDeviceFeatures();
|
||||
str += "\n" + listIndent + "device_name = " + getDeviceName();
|
||||
str += "\n" + listIndent + "device_id = 0x" + Integer.toHexString(getDeviceId());
|
||||
str += "\n" + listIndent + "channel_condition = " + getChannelCondition();
|
||||
return str;
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANDevice.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Represents a PCAN device
|
||||
*/
|
||||
public enum TPCANDevice {
|
||||
|
||||
/**
|
||||
* Undefined, unknown or not selected PCAN device value
|
||||
*/
|
||||
PCAN_NONE((byte) 0x00),
|
||||
/**
|
||||
* PCAN Non-Plug'n'Play devices. NOT USED WITHIN PCAN-Basic API
|
||||
*/
|
||||
PCAN_PEAKCAN((byte) 0x01),
|
||||
/**
|
||||
* PCAN-ISA, PCAN-PC/104, and PCAN-PC/104-Plus
|
||||
*/
|
||||
PCAN_ISA((byte) 0x02),
|
||||
/**
|
||||
* PCAN-Dongle
|
||||
*/
|
||||
PCAN_DNG((byte) 0x03),
|
||||
/**
|
||||
* PCAN-PCI, PCAN-cPCI, PCAN-miniPCI, and PCAN-PCI Express
|
||||
*/
|
||||
PCAN_PCI((byte) 0x04),
|
||||
/**
|
||||
* PCAN-USB and PCAN-USB Pro
|
||||
*/
|
||||
PCAN_USB((byte) 0x05),
|
||||
/**
|
||||
* PCAN-PC Card
|
||||
*/
|
||||
PCAN_PCC((byte) 0x06),
|
||||
/**
|
||||
* PCAN Virtual hardware. NOT USED WITHIN PCAN-Basic API
|
||||
*/
|
||||
PCAN_VIRTUAL((byte) 0x07),
|
||||
/**
|
||||
* PCAN Gateway devices
|
||||
*/
|
||||
PCAN_LAN((byte) 0x08);
|
||||
|
||||
private TPCANDevice(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the CAN device
|
||||
* @return Byte value of the CAN device
|
||||
*/
|
||||
public byte getValue() {
|
||||
return this.value;
|
||||
}
|
||||
private final byte value;
|
||||
};
|
|
@ -1,284 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANHandle.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* Represents a PCAN-hardware channel handle.
|
||||
*/
|
||||
public enum TPCANHandle
|
||||
{
|
||||
|
||||
/**Undefined/default value for a PCAN bus*/
|
||||
PCAN_NONEBUS((short) 0x00),
|
||||
|
||||
/**PCAN-ISA interface, channel 1*/
|
||||
PCAN_ISABUS1((short) 0x21),
|
||||
/**PCAN-ISA interface, channel 2*/
|
||||
PCAN_ISABUS2((short) 0x22),
|
||||
/**PCAN-ISA interface, channel 3*/
|
||||
PCAN_ISABUS3((short) 0x23),
|
||||
/**PCAN-ISA interface, channel 4*/
|
||||
PCAN_ISABUS4((short) 0x24),
|
||||
/**PCAN-ISA interface, channel 5*/
|
||||
PCAN_ISABUS5((short) 0x25),
|
||||
/**PCAN-ISA interface, channel 6*/
|
||||
PCAN_ISABUS6((short) 0x26),
|
||||
/**PCAN-ISA interface, channel 7*/
|
||||
PCAN_ISABUS7((short) 0x27),
|
||||
/**PCAN-ISA interface, channel 8*/
|
||||
PCAN_ISABUS8((short) 0x28),
|
||||
|
||||
/**PCAN-Dongle/LPT interface, channel 1*/
|
||||
PCAN_DNGBUS1((short) 0x31),
|
||||
|
||||
/**PCAN-PCI interface, channel 1*/
|
||||
PCAN_PCIBUS1((short) 0x41),
|
||||
/**PCAN-PCI interface, channel 2*/
|
||||
PCAN_PCIBUS2((short) 0x42),
|
||||
/**PCAN-PCI interface, channel 3*/
|
||||
PCAN_PCIBUS3((short) 0x43),
|
||||
/**PCAN-PCI interface, channel 4*/
|
||||
PCAN_PCIBUS4((short) 0x44),
|
||||
/**PCAN-PCI interface, channel 5*/
|
||||
PCAN_PCIBUS5((short) 0x45),
|
||||
/**PCAN-PCI interface, channel 6*/
|
||||
PCAN_PCIBUS6((short) 0x46),
|
||||
/**PCAN-PCI interface, channel 7*/
|
||||
PCAN_PCIBUS7((short) 0x47),
|
||||
/**PCAN-PCI interface, channel 8*/
|
||||
PCAN_PCIBUS8((short) 0x48),
|
||||
/**PCAN-PCI interface, channel 9*/
|
||||
PCAN_PCIBUS9((short) 0x409),
|
||||
/**PCAN-PCI interface, channel 10*/
|
||||
PCAN_PCIBUS10((short) 0x40A),
|
||||
/**PCAN-PCI interface, channel 11*/
|
||||
PCAN_PCIBUS11((short) 0x40B),
|
||||
/**PCAN-PCI interface, channel 12*/
|
||||
PCAN_PCIBUS12((short) 0x40C),
|
||||
/**PCAN-PCI interface, channel 13*/
|
||||
PCAN_PCIBUS13((short) 0x40D),
|
||||
/**PCAN-PCI interface, channel 14*/
|
||||
PCAN_PCIBUS14((short) 0x40E),
|
||||
/**PCAN-PCI interface, channel 15*/
|
||||
PCAN_PCIBUS15((short) 0x40F),
|
||||
/**PCAN-PCI interface, channel 16*/
|
||||
PCAN_PCIBUS16((short) 0x410),
|
||||
|
||||
/**PCAN-USB interface, channel 1*/
|
||||
PCAN_USBBUS1((short) 0x51),
|
||||
/**PCAN-USB interface, channel 2*/
|
||||
PCAN_USBBUS2((short) 0x52),
|
||||
/**PCAN-USB interface, channel 3*/
|
||||
PCAN_USBBUS3((short) 0x53),
|
||||
/**PCAN-USB interface, channel 4*/
|
||||
PCAN_USBBUS4((short) 0x54),
|
||||
/**PCAN-USB interface, channel 5*/
|
||||
PCAN_USBBUS5((short) 0x55),
|
||||
/**PCAN-USB interface, channel 6*/
|
||||
PCAN_USBBUS6((short) 0x56),
|
||||
/**PCAN-USB interface, channel 7*/
|
||||
PCAN_USBBUS7((short) 0x57),
|
||||
/**PCAN-USB interface, channel 8*/
|
||||
PCAN_USBBUS8((short) 0x58),
|
||||
/**PCAN-USB interface, channel 9*/
|
||||
PCAN_USBBUS9((short) 0x509),
|
||||
/**PCAN-USB interface, channel 10*/
|
||||
PCAN_USBBUS10((short) 0x50A),
|
||||
/**PCAN-USB interface, channel 11*/
|
||||
PCAN_USBBUS11((short) 0x50B),
|
||||
/**PCAN-USB interface, channel 12*/
|
||||
PCAN_USBBUS12((short) 0x50C),
|
||||
/**PCAN-USB interface, channel 13*/
|
||||
PCAN_USBBUS13((short) 0x50D),
|
||||
/**PCAN-USB interface, channel 14*/
|
||||
PCAN_USBBUS14((short) 0x50E),
|
||||
/**PCAN-USB interface, channel 15*/
|
||||
PCAN_USBBUS15((short) 0x50F),
|
||||
/**PCAN-USB interface, channel 16*/
|
||||
PCAN_USBBUS16((short) 0x510),
|
||||
|
||||
/**PCAN-PC Card interface, channel 1*/
|
||||
PCAN_PCCBUS1((short) 0x61),
|
||||
/**PCAN-PC Card interface, channel 2*/
|
||||
PCAN_PCCBUS2((short) 0x62),
|
||||
|
||||
/**PCAN-LAN1 interface, channel 1*/
|
||||
PCAN_LANBUS1((short) 0x801),
|
||||
/**PCAN-LAN2 interface, channel 2*/
|
||||
PCAN_LANBUS2((short) 0x802),
|
||||
/**PCAN-LAN3 interface, channel 3*/
|
||||
PCAN_LANBUS3((short) 0x803),
|
||||
/**PCAN-LAN4 interface, channel 4*/
|
||||
PCAN_LANBUS4((short) 0x804),
|
||||
/**PCAN-LAN5 interface, channel 5*/
|
||||
PCAN_LANBUS5((short) 0x805),
|
||||
/**PCAN-LAN6 interface, channel 6*/
|
||||
PCAN_LANBUS6((short) 0x806),
|
||||
/**PCAN-LAN7 interface, channel 7*/
|
||||
PCAN_LANBUS7((short) 0x807),
|
||||
/**PCAN-LAN8 interface, channel 8*/
|
||||
PCAN_LANBUS8((short) 0x808),
|
||||
/**PCAN-LAN interface, channel 9*/
|
||||
PCAN_LANBUS9((short) 0x809),
|
||||
/**PCAN-LAN interface, channel 10*/
|
||||
PCAN_LANBUS10((short) 0x80A),
|
||||
/**PCAN-LAN interface, channel 11*/
|
||||
PCAN_LANBUS11((short) 0x80B),
|
||||
/**PCAN-LAN interface, channel 12*/
|
||||
PCAN_LANBUS12((short) 0x80C),
|
||||
/**PCAN-LAN interface, channel 13*/
|
||||
PCAN_LANBUS13((short) 0x80D),
|
||||
/**PCAN-LAN interface, channel 14*/
|
||||
PCAN_LANBUS14((short) 0x80E),
|
||||
/**PCAN-LAN interface, channel 15*/
|
||||
PCAN_LANBUS15((short) 0x80F),
|
||||
/**PCAN-LAN interface, channel 16*/
|
||||
PCAN_LANBUS16((short) 0x810);
|
||||
|
||||
/**
|
||||
* Creates a CAN Handle
|
||||
* @param value value of the CAN Handle
|
||||
*/
|
||||
private TPCANHandle(short value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the CAN handle
|
||||
* @return Value of the CAN handle
|
||||
*/
|
||||
public short getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns All PCAN Channels which are initializable (All except PCAN_NONEBUS)
|
||||
* @return PCAN Channels array
|
||||
*/
|
||||
public static Object[] initializableChannels()
|
||||
{
|
||||
TPCANHandle[] values = TPCANHandle.values();
|
||||
int size = values.length;
|
||||
Deque<TPCANHandle> result = new ArrayDeque<TPCANHandle>(size);
|
||||
for (int i = 1; i < size; i++)
|
||||
{
|
||||
result.add(values[i]);
|
||||
}
|
||||
return result.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the provided TPCANHandle is an USB Device
|
||||
* @param handle to verify
|
||||
* @return true if the TPCANHandle is an USB Device, false if not
|
||||
*/
|
||||
public static boolean isPCANUSBHardware(TPCANHandle handle)
|
||||
{
|
||||
switch (handle)
|
||||
{
|
||||
case PCAN_USBBUS1:
|
||||
case PCAN_USBBUS2:
|
||||
case PCAN_USBBUS3:
|
||||
case PCAN_USBBUS4:
|
||||
case PCAN_USBBUS5:
|
||||
case PCAN_USBBUS6:
|
||||
case PCAN_USBBUS7:
|
||||
case PCAN_USBBUS8:
|
||||
case PCAN_USBBUS9:
|
||||
case PCAN_USBBUS10:
|
||||
case PCAN_USBBUS11:
|
||||
case PCAN_USBBUS12:
|
||||
case PCAN_USBBUS13:
|
||||
case PCAN_USBBUS14:
|
||||
case PCAN_USBBUS15:
|
||||
case PCAN_USBBUS16:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the provided TPCANHandle is an PC-Card Device
|
||||
* @param handle to verify
|
||||
* @return true if the TPCANHandle is an PC-Card Device, false if not
|
||||
*/
|
||||
public static boolean isPCANPCCardHardware(TPCANHandle handle)
|
||||
{
|
||||
switch (handle)
|
||||
{
|
||||
case PCAN_PCCBUS1:
|
||||
case PCAN_PCCBUS2:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the provided TPCANHandle contains a SJA1000 controller
|
||||
* @param handle to verify
|
||||
* @param type the PCAN device associated with the handle
|
||||
* @return true if the TPCANHandle contains a SJA1000 controller, false if not
|
||||
*/
|
||||
public static boolean containsSJA(TPCANHandle handle, TPCANType type)
|
||||
{
|
||||
switch (handle)
|
||||
{
|
||||
case PCAN_DNGBUS1:
|
||||
case PCAN_ISABUS1:
|
||||
case PCAN_ISABUS2:
|
||||
case PCAN_ISABUS3:
|
||||
case PCAN_ISABUS4:
|
||||
case PCAN_ISABUS5:
|
||||
case PCAN_ISABUS6:
|
||||
case PCAN_ISABUS7:
|
||||
case PCAN_ISABUS8:
|
||||
switch (type)
|
||||
{
|
||||
case PCAN_TYPE_DNG_SJA:
|
||||
case PCAN_TYPE_DNG_SJA_EPP:
|
||||
case PCAN_TYPE_ISA_SJA:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private final short value;
|
||||
};
|
|
@ -1,101 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANMessageType.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Represents the type of a PCAN message
|
||||
*/
|
||||
public enum TPCANMessageType {
|
||||
|
||||
/**
|
||||
* The PCAN message is a CAN Standard Frame (11-bit identifier)
|
||||
*/
|
||||
PCAN_MESSAGE_STANDARD((byte) 0x00),
|
||||
/**
|
||||
* The PCAN message is a CAN Remote-Transfer-Request Frame
|
||||
*/
|
||||
PCAN_MESSAGE_RTR((byte) 0x01),
|
||||
/**
|
||||
* The PCAN message is a CAN Extended Frame (29-bit identifier)
|
||||
*/
|
||||
PCAN_MESSAGE_EXTENDED((byte) 0x02),
|
||||
/**
|
||||
* The PCAN message represents a FD frame in terms of CiA Specs
|
||||
*/
|
||||
PCAN_MESSAGE_FD((byte) 0x04),
|
||||
/**
|
||||
* The PCAN message represents a FD bit rate switch (CAN data at a higher
|
||||
* bitrate)
|
||||
*/
|
||||
PCAN_MESSAGE_BRS((byte) 0x08),
|
||||
/**
|
||||
* The PCAN message represents a FD error state indicator(CAN FD transmitter was
|
||||
* error active)
|
||||
*/
|
||||
PCAN_MESSAGE_ESI((byte) 0x10),
|
||||
/**
|
||||
* The PCAN message represents an error frame
|
||||
*/
|
||||
PCAN_MESSAGE_ERRFRAME((byte) 0x40),
|
||||
/**
|
||||
* The PCAN message represents a PCAN status message
|
||||
*/
|
||||
PCAN_MESSAGE_STATUS((byte) 0x80);
|
||||
|
||||
private TPCANMessageType(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the message type
|
||||
*
|
||||
* @return Value of the message type
|
||||
*/
|
||||
public byte getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private final byte value;
|
||||
|
||||
/**
|
||||
* Gets the value of an EnumSet
|
||||
*
|
||||
* @param type collection of TPCANMessageType
|
||||
* @return value of the EnumSet
|
||||
*/
|
||||
public static byte getValue(EnumSet<TPCANMessageType> type) {
|
||||
byte result = 0;
|
||||
for (TPCANMessageType t : type)
|
||||
result |= t.value;
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANMode.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Represents a PCAN filter mode.
|
||||
*/
|
||||
public enum TPCANMode {
|
||||
|
||||
/**
|
||||
* Mode is Standard (11-bit identifier).
|
||||
*/
|
||||
PCAN_MODE_STANDARD(TPCANMessageType.PCAN_MESSAGE_STANDARD.getValue()),
|
||||
/**
|
||||
* Mode is Extended (29-bit identifier).
|
||||
*/
|
||||
PCAN_MODE_EXTENDED(TPCANMessageType.PCAN_MESSAGE_EXTENDED.getValue());
|
||||
|
||||
private TPCANMode(byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the CAN ID type
|
||||
* @return Value of the CAN ID type
|
||||
*/
|
||||
public byte getValue() {
|
||||
return this.value;
|
||||
}
|
||||
private final byte value;
|
||||
};
|
|
@ -1,218 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANMsg.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Defines a CAN message.
|
||||
*/
|
||||
public class TPCANMsg implements Cloneable
|
||||
{
|
||||
|
||||
/**
|
||||
* 11bit message type (standard)
|
||||
* @deprecated Use enum TPCANMessageType instead
|
||||
*/
|
||||
@Deprecated
|
||||
static public final byte MSGTYPE_STANDARD = TPCANMessageType.PCAN_MESSAGE_STANDARD.getValue();
|
||||
/**
|
||||
* Remote request
|
||||
* @deprecated Use enum TPCANMessageType instead
|
||||
*/
|
||||
@Deprecated
|
||||
static public final byte MSGTYPE_RTR = TPCANMessageType.PCAN_MESSAGE_RTR.getValue();
|
||||
/**
|
||||
* 29bit message type (extended)
|
||||
* @deprecated Use enum TPCANMessageType instead
|
||||
*/
|
||||
@Deprecated
|
||||
static public final byte MSGTYPE_EXTENDED = TPCANMessageType.PCAN_MESSAGE_EXTENDED.getValue();
|
||||
|
||||
private int _id;
|
||||
private byte _type;
|
||||
private byte _length;
|
||||
private byte _data[];
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public TPCANMsg()
|
||||
{
|
||||
_data = new byte[8];
|
||||
}
|
||||
|
||||
// rusEFI custom https://github.com/rusefi/rusefi/issues/4370 workaround
|
||||
public TPCANMsg(byte length)
|
||||
{
|
||||
_data = new byte[length];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new message object.
|
||||
* @param id the message id
|
||||
* @param type the message type
|
||||
* @param length the message length
|
||||
* @param data the message data
|
||||
*/
|
||||
public TPCANMsg(int id, byte type, byte length, byte[] data)
|
||||
{
|
||||
_id = id;
|
||||
_type = type;
|
||||
_length = length;
|
||||
_data = new byte[length];
|
||||
System.arraycopy(data, 0, _data, 0, length);
|
||||
}
|
||||
/**
|
||||
* Constructs a new message object.
|
||||
* @param id the message id
|
||||
* @param type the message type as an enumeration set
|
||||
* @param length the message length
|
||||
* @param data the message data
|
||||
*/
|
||||
public TPCANMsg(int id, EnumSet<TPCANMessageType> type, byte length, byte[] data)
|
||||
{
|
||||
_id = id;
|
||||
_type = TPCANMessageType.getValue(type);
|
||||
_length = length;
|
||||
_data = new byte[length];
|
||||
System.arraycopy(data, 0, _data, 0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id of this message.
|
||||
* @param id the message id
|
||||
*/
|
||||
public void setID(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data and length of this message.
|
||||
* @param data the message data
|
||||
* @param length the message length
|
||||
*/
|
||||
public void setData(byte[] data, byte length)
|
||||
{
|
||||
_length = length;
|
||||
System.arraycopy(data, 0, _data, 0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of this message.
|
||||
* @param length the length of the message
|
||||
*/
|
||||
public void setLength(byte length)
|
||||
{
|
||||
_length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this message.
|
||||
* @param type the message type
|
||||
*/
|
||||
public void setType(byte type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
/**
|
||||
* Sets the type of this message.
|
||||
* @param type the message type
|
||||
*/
|
||||
public void setType(TPCANMessageType type)
|
||||
{
|
||||
_type = type.getValue();
|
||||
}
|
||||
/**
|
||||
* Sets the type of this message.
|
||||
* @param type the message type
|
||||
*/
|
||||
public void setType(EnumSet<TPCANMessageType> type)
|
||||
{
|
||||
_type = TPCANMessageType.getValue(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this message.
|
||||
* @return the message id
|
||||
*/
|
||||
public int getID()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data of this message.
|
||||
* @return the message data
|
||||
*/
|
||||
public byte[] getData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of this message.
|
||||
* @return the message length
|
||||
*/
|
||||
public byte getLength()
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of this message.
|
||||
* @return the message type
|
||||
*/
|
||||
public byte getType()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones this message object.
|
||||
* @return The cloned message object.
|
||||
*/
|
||||
@Override
|
||||
public Object clone()
|
||||
{
|
||||
TPCANMsg msg = null;
|
||||
try
|
||||
{
|
||||
msg = (TPCANMsg) super.clone();
|
||||
msg._data = _data.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
|
@ -1,237 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANMsgFD.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Defines a CAN FD message.
|
||||
*/
|
||||
public class TPCANMsgFD implements Cloneable
|
||||
{
|
||||
private int _id;
|
||||
private EnumSet<TPCANMessageType> _type;
|
||||
private byte _dlc;
|
||||
private byte _len;
|
||||
private byte _data[];
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public TPCANMsgFD()
|
||||
{
|
||||
_data = new byte[64];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new message object.
|
||||
* @param id the message id
|
||||
* @param type the message type
|
||||
* @param dlc the message data length code
|
||||
* @param data the message data
|
||||
*/
|
||||
public TPCANMsgFD(int id, EnumSet<TPCANMessageType> type, byte dlc, byte[] data)
|
||||
{
|
||||
_id = id;
|
||||
_type = type;
|
||||
_dlc = dlc;
|
||||
_len = getLengthFromDLC(dlc);
|
||||
_data = new byte[64];
|
||||
System.arraycopy(data, 0, _data, 0, _len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id of this message.
|
||||
* @param id the message id
|
||||
*/
|
||||
public void setID(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data and length of this message.
|
||||
* @param data the message data
|
||||
* @param dlc the message length
|
||||
*/
|
||||
public void setData(byte[] data, byte dlc)
|
||||
{
|
||||
setDlc(dlc);
|
||||
System.arraycopy(data, 0, _data, 0, _len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data length code of this message.
|
||||
* @param dlc the data length code of the message
|
||||
*/
|
||||
public void setDlc(byte dlc)
|
||||
{
|
||||
_dlc = dlc;
|
||||
_len = getLengthFromDLC(dlc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this message.
|
||||
* @param type the message type
|
||||
*/
|
||||
public void setType(EnumSet<TPCANMessageType> type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this message.
|
||||
* @param type the message type
|
||||
*/
|
||||
public void setType(byte type)
|
||||
{
|
||||
EnumSet<TPCANMessageType> eset;
|
||||
|
||||
eset = EnumSet.noneOf(TPCANMessageType.class);
|
||||
for (TPCANMessageType t : TPCANMessageType.values()) {
|
||||
if ((type & t.getValue()) == t.getValue())
|
||||
eset.add(t);
|
||||
}
|
||||
// fix type PCAN_MESSAGE_STANDARD (value is 0)
|
||||
if (eset.contains(TPCANMessageType.PCAN_MESSAGE_EXTENDED) ||
|
||||
eset.contains(TPCANMessageType.PCAN_MESSAGE_STATUS) ||
|
||||
eset.contains(TPCANMessageType.PCAN_MESSAGE_RTR) ||
|
||||
eset.contains(TPCANMessageType.PCAN_MESSAGE_BRS) ||
|
||||
eset.contains(TPCANMessageType.PCAN_MESSAGE_ESI))
|
||||
eset.remove(TPCANMessageType.PCAN_MESSAGE_STANDARD);
|
||||
_type = eset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this message.
|
||||
* @return the message id
|
||||
*/
|
||||
public int getID()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data of this message.
|
||||
* @return the message data
|
||||
*/
|
||||
public byte[] getData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data length code of this message.
|
||||
* @return the message length
|
||||
*/
|
||||
public byte getDlc()
|
||||
{
|
||||
return _dlc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of this message based on its DLC.
|
||||
* @return the message length
|
||||
*/
|
||||
public byte getLengthFromDLC()
|
||||
{
|
||||
return getLengthFromDLC(_dlc);
|
||||
}
|
||||
/**
|
||||
* Gets the length of a message based on a DLC.
|
||||
* @param dlc data length code
|
||||
* @return the message length
|
||||
*/
|
||||
public static byte getLengthFromDLC(byte dlc)
|
||||
{
|
||||
switch(dlc)
|
||||
{
|
||||
case 9:
|
||||
return 12;
|
||||
case 10:
|
||||
return 16;
|
||||
case 11:
|
||||
return 20;
|
||||
case 12:
|
||||
return 24;
|
||||
case 13:
|
||||
return 32;
|
||||
case 14:
|
||||
return 48;
|
||||
case 15:
|
||||
return 64;
|
||||
default:
|
||||
return dlc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of this message.
|
||||
* @return the message type
|
||||
*/
|
||||
public EnumSet<TPCANMessageType> getTypeEnum()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
/**
|
||||
* Gets the type of this message.
|
||||
* @return the message type
|
||||
*/
|
||||
public byte getType()
|
||||
{
|
||||
byte res;
|
||||
|
||||
res = 0;
|
||||
for (TPCANMessageType t : _type)
|
||||
res |= t.getValue();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones this message object.
|
||||
* @return The cloned message object.
|
||||
*/
|
||||
@Override
|
||||
public Object clone()
|
||||
{
|
||||
TPCANMsgFD msg = null;
|
||||
try
|
||||
{
|
||||
msg = (TPCANMsgFD) super.clone();
|
||||
msg._data = _data.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,434 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANParameter.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* Parameter definition.
|
||||
*/
|
||||
public enum TPCANParameter {
|
||||
|
||||
/**
|
||||
* PCAN-USB device number parameter
|
||||
*
|
||||
* @deprecated Deprecated parameter. Use PCAN_DEVICE_ID instead
|
||||
*/
|
||||
PCAN_DEVICE_NUMBER(0x01),
|
||||
/**
|
||||
* PCAN-USB device number parameter
|
||||
*/
|
||||
PCAN_DEVICE_ID(0x01),
|
||||
/**
|
||||
* PCAN-PC Card 5-Volt power parameter
|
||||
*/
|
||||
PCAN_5VOLTS_POWER(0x02),
|
||||
/**
|
||||
* PCAN receive event handler parameter
|
||||
*/
|
||||
PCAN_RECEIVE_EVENT(0x03),
|
||||
/**
|
||||
* PCAN message filter parameter
|
||||
*/
|
||||
PCAN_MESSAGE_FILTER(0x04),
|
||||
/**
|
||||
* PCAN-Basic API version parameter
|
||||
*/
|
||||
PCAN_API_VERSION(0x05),
|
||||
/**
|
||||
* PCAN device channel version parameter
|
||||
*/
|
||||
PCAN_CHANNEL_VERSION(0x06),
|
||||
/**
|
||||
* PCAN Reset-On-Busoff parameter
|
||||
*/
|
||||
PCAN_BUSOFF_AUTORESET(0x07),
|
||||
/**
|
||||
* PCAN Listen-Only parameter
|
||||
*/
|
||||
PCAN_LISTEN_ONLY(0x08),
|
||||
/**
|
||||
* Directory path for trace files
|
||||
*/
|
||||
PCAN_LOG_LOCATION(0x09),
|
||||
/**
|
||||
* Debug-Trace activation status
|
||||
*/
|
||||
PCAN_LOG_STATUS(0x0A),
|
||||
/**
|
||||
* Configuration of the debugged information (LOG_FUNCTION_***)
|
||||
*/
|
||||
PCAN_LOG_CONFIGURE(0x0B),
|
||||
/**
|
||||
* Custom insertion of text into the log file
|
||||
*/
|
||||
PCAN_LOG_TEXT(0x0C),
|
||||
/**
|
||||
* Availability status of a PCAN-Channel
|
||||
*/
|
||||
PCAN_CHANNEL_CONDITION(0x0D),
|
||||
/**
|
||||
* PCAN hardware name parameter
|
||||
*/
|
||||
PCAN_HARDWARE_NAME(0x0E),
|
||||
/**
|
||||
* Message reception status of a PCAN-Channel
|
||||
*/
|
||||
PCAN_RECEIVE_STATUS(0x0F),
|
||||
/**
|
||||
* CAN-Controller number of a PCAN-Channel
|
||||
*/
|
||||
PCAN_CONTROLLER_NUMBER(0x10),
|
||||
/**
|
||||
* Directory path for PCAN trace files
|
||||
*/
|
||||
PCAN_TRACE_LOCATION(0x11),
|
||||
/**
|
||||
* CAN tracing activation status
|
||||
*/
|
||||
PCAN_TRACE_STATUS(0x12),
|
||||
/**
|
||||
* Configuration of the maximum file size of a CAN trace
|
||||
*/
|
||||
PCAN_TRACE_SIZE(0x13),
|
||||
/**
|
||||
* Configuration of the trace file storing mode (TRACE_FILE_***)
|
||||
*/
|
||||
PCAN_TRACE_CONFIGURE(0x14),
|
||||
/**
|
||||
* Physical identification of a USB based PCAN-Channel by blinking its
|
||||
* associated LED
|
||||
*/
|
||||
PCAN_CHANNEL_IDENTIFYING(0x15),
|
||||
/**
|
||||
* Capabilities of a PCAN device (FEATURE_***)
|
||||
*/
|
||||
PCAN_CHANNEL_FEATURES(0x16),
|
||||
/**
|
||||
* Using of an existing bit rate (PCAN-View connected to a channel)
|
||||
*/
|
||||
PCAN_BITRATE_ADAPTING(0x17),
|
||||
/**
|
||||
* Configured Bit rate as Btr0Btr1 value
|
||||
*/
|
||||
PCAN_BITRATE_INFO(0x18),
|
||||
/**
|
||||
* Configured Bit rate as TPCANBitrateFD string
|
||||
*/
|
||||
PCAN_BITRATE_INFO_FD(0x19),
|
||||
/**
|
||||
* Configured nominal CAN Bus speed as Bits per seconds
|
||||
*/
|
||||
PCAN_BUSSPEED_NOMINAL(0x1A),
|
||||
/**
|
||||
* Configured CAN data speed as Bits per seconds
|
||||
*/
|
||||
PCAN_BUSSPEED_DATA(0x1B),
|
||||
/**
|
||||
* Remote address of a LAN channel as string in IPv4 format
|
||||
*/
|
||||
PCAN_IP_ADDRESS(0x1C),
|
||||
/**
|
||||
* Status of the Virtual PCAN-Gateway Service
|
||||
*/
|
||||
PCAN_LAN_SERVICE_STATUS(0x1D),
|
||||
/**
|
||||
* Status messages reception status within a PCAN-Channel
|
||||
*/
|
||||
PCAN_ALLOW_STATUS_FRAMES(0x1E),
|
||||
/**
|
||||
* RTR messages reception status within a PCAN-Channel
|
||||
*/
|
||||
PCAN_ALLOW_RTR_FRAMES(0x1F),
|
||||
/**
|
||||
* Error messages reception status within a PCAN-Channel
|
||||
*/
|
||||
PCAN_ALLOW_ERROR_FRAMES(0x20),
|
||||
/**
|
||||
* Delay, in microseconds, between sending frames
|
||||
*/
|
||||
PCAN_INTERFRAME_DELAY(0x21),
|
||||
/**
|
||||
* Filter over code and mask patterns for 11-Bit messages
|
||||
*/
|
||||
PCAN_ACCEPTANCE_FILTER_11BIT(0x22),
|
||||
/**
|
||||
* Filter over code and mask patterns for 29-Bit messages
|
||||
*/
|
||||
PCAN_ACCEPTANCE_FILTER_29BIT(0x23),
|
||||
/**
|
||||
* Output mode of 32 digital I/O pin of a PCAN-USB Chip. 1: Output-Active 0 :
|
||||
* Output Inactive
|
||||
*/
|
||||
PCAN_IO_DIGITAL_CONFIGURATION(0x24),
|
||||
/**
|
||||
* Value assigned to a 32 digital I/O pins of a PCAN-USB Chip
|
||||
*/
|
||||
PCAN_IO_DIGITAL_VALUE(0x25),
|
||||
/**
|
||||
* Value assigned to a 32 digital I/O pins of a PCAN-USB Chip - Multiple digital
|
||||
* I/O pins to 1 = High
|
||||
*/
|
||||
PCAN_IO_DIGITAL_SET(0x26),
|
||||
/**
|
||||
* Clear multiple digital I/O pins to 0
|
||||
*/
|
||||
PCAN_IO_DIGITAL_CLEAR(0x27),
|
||||
/**
|
||||
* Get value of a single analog input pin
|
||||
*/
|
||||
PCAN_IO_ANALOG_VALUE(0x28),
|
||||
/**
|
||||
* Get the version of the firmware used by the device associated with a
|
||||
* PCAN-Channel
|
||||
*/
|
||||
PCAN_FIRMWARE_VERSION(0x29),
|
||||
/**
|
||||
* Get the amount of PCAN channels attached to a system
|
||||
*/
|
||||
PCAN_ATTACHED_CHANNELS_COUNT(0x2A),
|
||||
/**
|
||||
* Get information about PCAN channels attached to a system
|
||||
*/
|
||||
PCAN_ATTACHED_CHANNELS(0x2B);
|
||||
|
||||
private TPCANParameter(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier of the CAN parameter
|
||||
*
|
||||
* @return Identifier of the CAN parameter
|
||||
*/
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of PCAN Parameters which are customizable as array
|
||||
*
|
||||
* @return the list of PCAN Parameters which are customizable as array
|
||||
*/
|
||||
public static TPCANParameter[] customizableParameters() {
|
||||
Deque<TPCANParameter> result = new ArrayDeque<TPCANParameter>();
|
||||
result.add(TPCANParameter.PCAN_DEVICE_ID);
|
||||
result.add(TPCANParameter.PCAN_5VOLTS_POWER);
|
||||
result.add(TPCANParameter.PCAN_API_VERSION);
|
||||
result.add(TPCANParameter.PCAN_CHANNEL_VERSION);
|
||||
result.add(TPCANParameter.PCAN_BUSOFF_AUTORESET);
|
||||
result.add(TPCANParameter.PCAN_LISTEN_ONLY);
|
||||
result.add(TPCANParameter.PCAN_LOG_LOCATION);
|
||||
result.add(TPCANParameter.PCAN_LOG_STATUS);
|
||||
result.add(TPCANParameter.PCAN_LOG_CONFIGURE);
|
||||
result.add(TPCANParameter.PCAN_CHANNEL_CONDITION);
|
||||
result.add(TPCANParameter.PCAN_HARDWARE_NAME);
|
||||
result.add(TPCANParameter.PCAN_RECEIVE_STATUS);
|
||||
result.add(TPCANParameter.PCAN_CONTROLLER_NUMBER);
|
||||
result.add(TPCANParameter.PCAN_TRACE_LOCATION);
|
||||
result.add(TPCANParameter.PCAN_TRACE_STATUS);
|
||||
result.add(TPCANParameter.PCAN_TRACE_SIZE);
|
||||
result.add(TPCANParameter.PCAN_TRACE_CONFIGURE);
|
||||
result.add(TPCANParameter.PCAN_CHANNEL_IDENTIFYING);
|
||||
result.add(TPCANParameter.PCAN_CHANNEL_FEATURES);
|
||||
result.add(TPCANParameter.PCAN_BITRATE_ADAPTING);
|
||||
result.add(TPCANParameter.PCAN_BITRATE_INFO);
|
||||
result.add(TPCANParameter.PCAN_BITRATE_INFO_FD);
|
||||
result.add(TPCANParameter.PCAN_BUSSPEED_NOMINAL);
|
||||
result.add(TPCANParameter.PCAN_BUSSPEED_DATA);
|
||||
result.add(TPCANParameter.PCAN_IP_ADDRESS);
|
||||
|
||||
result.add(TPCANParameter.PCAN_LAN_SERVICE_STATUS);
|
||||
result.add(TPCANParameter.PCAN_ALLOW_STATUS_FRAMES);
|
||||
result.add(TPCANParameter.PCAN_ALLOW_RTR_FRAMES);
|
||||
result.add(TPCANParameter.PCAN_ALLOW_ERROR_FRAMES);
|
||||
result.add(TPCANParameter.PCAN_INTERFRAME_DELAY);
|
||||
result.add(TPCANParameter.PCAN_ACCEPTANCE_FILTER_11BIT);
|
||||
result.add(TPCANParameter.PCAN_ACCEPTANCE_FILTER_29BIT);
|
||||
result.add(TPCANParameter.PCAN_IO_DIGITAL_CONFIGURATION);
|
||||
result.add(TPCANParameter.PCAN_IO_DIGITAL_VALUE);
|
||||
result.add(TPCANParameter.PCAN_IO_DIGITAL_SET);
|
||||
result.add(TPCANParameter.PCAN_IO_DIGITAL_CLEAR);
|
||||
result.add(TPCANParameter.PCAN_IO_ANALOG_VALUE);
|
||||
result.add(TPCANParameter.PCAN_FIRMWARE_VERSION);
|
||||
result.add(TPCANParameter.PCAN_ATTACHED_CHANNELS_COUNT);
|
||||
result.add(TPCANParameter.PCAN_ATTACHED_CHANNELS);
|
||||
|
||||
return result.toArray(new TPCANParameter[result.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description for the given TPCANParameter
|
||||
*
|
||||
* @param param TPCANParameter for which we need description
|
||||
* @return a string description for the given TPCANParameter
|
||||
*/
|
||||
public static String getParameterDescription(TPCANParameter param) {
|
||||
String description = "";
|
||||
switch (param) {
|
||||
case PCAN_DEVICE_NUMBER:
|
||||
case PCAN_DEVICE_ID:
|
||||
description = "This parameter is used on PCAN-USB hardware to distinguish between 2 (or more) of them on the same computer. This value is persistent, i.e. the identifier will not be lost after disconnecting and connecting again the hardware.";
|
||||
break;
|
||||
case PCAN_5VOLTS_POWER:
|
||||
description = "This parameter is used on PCAN-PC Card hardware for switching the external 5V on the D-Sub connector of the PC Card. This is useful when connecting external bus converter modules to the card (AU5790 / TJA1954)).";
|
||||
break;
|
||||
case PCAN_RECEIVE_EVENT:
|
||||
description = "This parameter allows the user to easily configure the message filter of a PCAN channel. With it is possible to fully open or complete close the filter.";
|
||||
break;
|
||||
case PCAN_MESSAGE_FILTER:
|
||||
description = "This parameter is used to let the PCAN driver notify an application when CAN messages are placed in its receive queue.";
|
||||
break;
|
||||
case PCAN_API_VERSION:
|
||||
description = "This parameter is used to get information about the PCAN-Basic API implementation version.";
|
||||
break;
|
||||
case PCAN_CHANNEL_VERSION:
|
||||
description = "This parameter is used to get version information about the Driver of a PCAN Channel.";
|
||||
break;
|
||||
case PCAN_BUSOFF_AUTORESET:
|
||||
description = "This parameter instructs the PCAN driver to reset automatically the CAN controller of a PCAN channel when a bus-off state is detected. Since no communication is possible on a bus-off state, it is useful to let the driver to catch this event automatically and reset the controller, avoiding extra handling of this problem in an end application.";
|
||||
break;
|
||||
case PCAN_LISTEN_ONLY:
|
||||
description = "This parameter allows the user to set a CAN hardware in Listen-Only mode. When this mode is set, the CAN controller doens't take part on active events (eg. transmit CAN messages) but stays in a passive mode (CAN monitor), in which it can analyse the traffic on the CAN bus used by a PCAN channel. See also the Philips Data Sheet \"SJA1000 Stand-alone CAN controller\".";
|
||||
break;
|
||||
case PCAN_LOG_LOCATION:
|
||||
description = "This value is used to set the folder location on a computer for the Log-File generated by the PCAN-Basic API, within a debug session. Setting this value starts recording debug information automatically. If a debug session is running (a log file is being written), PCAN_LOG_LOCATION instructs the API to close the current log file and to start the process again with the new folder information. Note that the name of the log file cannot be specified, this name is fixed as PCANBasic.log.";
|
||||
break;
|
||||
case PCAN_LOG_STATUS:
|
||||
description = "This value is used to control the activity status of a debug session within the PCAN-Basic API. If the log status is set to ON without having set a location for the log file or without having configured the information to be traced, then the session process will start with the default values.";
|
||||
break;
|
||||
case PCAN_LOG_CONFIGURE:
|
||||
description = "This value is used to configure the debug information to be included in the log file generated in a debug session within the PCAN-Basic API.";
|
||||
break;
|
||||
case PCAN_LOG_TEXT:
|
||||
description = "This Parameter is used to insert custom information in the log file generated in a debug session within the PCAN-Basic API.";
|
||||
break;
|
||||
case PCAN_CHANNEL_CONDITION:
|
||||
description = "This parameter is used to check and detect available PCAN hardware on a computer, even before trying to connect any of them. This is useful when an application wants the user to select which hardware should be using in a communication session.";
|
||||
break;
|
||||
case PCAN_HARDWARE_NAME:
|
||||
description = "This parameter is to read the Name of the Hardware.";
|
||||
break;
|
||||
case PCAN_RECEIVE_STATUS:
|
||||
description = "This Parameter is to get the reception status of a PCAN-Channel.";
|
||||
break;
|
||||
case PCAN_CONTROLLER_NUMBER:
|
||||
description = "This Parameter is to get CAN-Controller number of a PCAN-Channel. Only usefull with 2 Channel HW.";
|
||||
break;
|
||||
case PCAN_TRACE_LOCATION:
|
||||
description = "This Parameter is used to configure the Trace File Directory.";
|
||||
break;
|
||||
case PCAN_TRACE_STATUS:
|
||||
description = "This Parameter is used to control the activity of the Tracer status.";
|
||||
break;
|
||||
case PCAN_TRACE_SIZE:
|
||||
description = "This Parameter is used to configure the maximum file size of a CAN trace.";
|
||||
break;
|
||||
case PCAN_TRACE_CONFIGURE:
|
||||
description = "This Parameter is used to configure the trace file storing mode (TRACE_FILE_***).";
|
||||
break;
|
||||
case PCAN_CHANNEL_IDENTIFYING:
|
||||
description = "This Parameter is used to Physically identify a USB based PCAN-Channel by blinking its associated LED.";
|
||||
break;
|
||||
case PCAN_CHANNEL_FEATURES:
|
||||
description = "This Parameter is used to get the capabilities of a PCAN device.";
|
||||
break;
|
||||
case PCAN_BITRATE_ADAPTING:
|
||||
description = "This Parameter is used to force an initialization process to succeed, even if the PCAN-Channel is being used by a PCAN-View with a different or unknown bit rate.";
|
||||
break;
|
||||
case PCAN_BITRATE_INFO:
|
||||
description = "This Parameter is used to read the currently configured communication speed of a PCAN Channel connected as standard CAN.";
|
||||
break;
|
||||
case PCAN_BITRATE_INFO_FD:
|
||||
description = "This Parameter is used to read the currently configured communication speed, as a parameterized string value (FD Bit rate String), of a PCAN Channel connected as CAN FD.";
|
||||
break;
|
||||
case PCAN_BUSSPEED_NOMINAL:
|
||||
description = "This Parameter is used to read the configured nominal CAN Bus speed as Bits per seconds.";
|
||||
break;
|
||||
case PCAN_BUSSPEED_DATA:
|
||||
description = "This Parameter is used to read configured CAN data speed as Bits per seconds.";
|
||||
break;
|
||||
case PCAN_IP_ADDRESS:
|
||||
description = "This Parameter is used to read the remote address of a LAN channel as string in IPv4 format.";
|
||||
break;
|
||||
case PCAN_LAN_SERVICE_STATUS:
|
||||
description = "This Parameter is used to read the status of the Virtual PCAN-Gateway Service.";
|
||||
break;
|
||||
case PCAN_ALLOW_STATUS_FRAMES:
|
||||
description = "This Parameter is used to configure the reception of status messages within a PCAN-Channel.";
|
||||
break;
|
||||
case PCAN_ALLOW_RTR_FRAMES:
|
||||
description = "This Parameter is used to configure the reception of RTR messages within a PCAN-Channel.";
|
||||
break;
|
||||
case PCAN_ALLOW_ERROR_FRAMES:
|
||||
description = "This Parameter is used to configure the reception of Error messages within a PCAN-Channel.";
|
||||
break;
|
||||
case PCAN_INTERFRAME_DELAY:
|
||||
description = "This Parameter is used to configure the delay, in microseconds, between sending frames.";
|
||||
break;
|
||||
case PCAN_ACCEPTANCE_FILTER_11BIT:
|
||||
description = "This Parameter is used to configure the filter over code and mask patterns for 11-Bit messages.";
|
||||
break;
|
||||
case PCAN_ACCEPTANCE_FILTER_29BIT:
|
||||
description = "This Parameter is used to configure the filter over code and mask patterns for 29-Bit messages.";
|
||||
break;
|
||||
case PCAN_IO_DIGITAL_CONFIGURATION:
|
||||
description = "This Parameter is used to configure the output mode of 32 digital I/O pin of a PCAN-USB Chip (1: Output Active, 0: Output Inactive).";
|
||||
break;
|
||||
case PCAN_IO_DIGITAL_VALUE:
|
||||
description = "This Parameter is used to configure the value assigned to a 32 digital I/O pins of a PCAN-USB Chip.";
|
||||
break;
|
||||
case PCAN_IO_DIGITAL_SET:
|
||||
description = "This Parameter is used to configure the value assigned to a 32 digital I/O pins of a PCAN-USB Chip (Multiple digital I/O pins to 1 = High).";
|
||||
break;
|
||||
case PCAN_IO_DIGITAL_CLEAR:
|
||||
description = "This Parameter is used to clear multiple digital I/O pins to 0.";
|
||||
break;
|
||||
case PCAN_IO_ANALOG_VALUE:
|
||||
description = "This Parameter is used to read the value of a single analog input pin.";
|
||||
break;
|
||||
case PCAN_FIRMWARE_VERSION:
|
||||
description = "This Parameter is used to read the version of the firmware used by the device associated with a PCAN-Channel.";
|
||||
break;
|
||||
case PCAN_ATTACHED_CHANNELS_COUNT:
|
||||
description = "This Parameter is used to read the amount of PCAN channels attached to a system.";
|
||||
break;
|
||||
case PCAN_ATTACHED_CHANNELS:
|
||||
description = "This Parameter is used to read information about PCAN channels attached to a system.";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
private final int value;
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANParameterValue.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
import java.util.*;
|
||||
//import java.util.RegularEnumSet;
|
||||
|
||||
/**
|
||||
* Parameter values definition
|
||||
*/
|
||||
public enum TPCANParameterValue
|
||||
{
|
||||
/** The PCAN parameter is not set (inactive) */
|
||||
PCAN_PARAMETER_OFF(0),
|
||||
/** The PCAN parameter is set (active) */
|
||||
PCAN_PARAMETER_ON(1),
|
||||
|
||||
/** The PCAN filter is closed. No messages will be received */
|
||||
PCAN_FILTER_CLOSE(0),
|
||||
/** The PCAN filter is fully opened. All messages will be received */
|
||||
PCAN_FILTER_OPEN(1),
|
||||
/** The PCAN filter is custom configured. Only registered messages will be received */
|
||||
PCAN_FILTER_CUSTOM(2),
|
||||
|
||||
/** The PCAN-Channel handle is illegal */
|
||||
PCAN_CHANNEL_UNAVAILABLE(0),
|
||||
/** The PCAN-Channel handle is valid to connect/initialize */
|
||||
PCAN_CHANNEL_AVAILABLE(1),
|
||||
/** The PCAN-Channel handle is valid, but is already being used */
|
||||
PCAN_CHANNEL_OCCUPIED(2),
|
||||
/** The PCAN-Channel handle is already being used by a PCAN-View application, but is available to connect */
|
||||
PCAN_CHANNEL_PCANVIEW(PCAN_CHANNEL_AVAILABLE.value | PCAN_CHANNEL_OCCUPIED.value),
|
||||
|
||||
/** Logs system exceptions / errors */
|
||||
LOG_FUNCTION_DEFAULT(0x00),
|
||||
/** Logs the entries to the PCAN-Basic API functions */
|
||||
LOG_FUNCTION_ENTRY(0x01),
|
||||
/** Logs the parameters passed to the PCAN-Basic API functions */
|
||||
LOG_FUNCTION_PARAMETERS(0x02),
|
||||
/** Logs the exits from the PCAN-Basic API functions */
|
||||
LOG_FUNCTION_LEAVE(0x04),
|
||||
/** Logs the CAN messages passed to the CAN_Write function */
|
||||
LOG_FUNCTION_WRITE(0x08),
|
||||
/** Logs the CAN messages received within the CAN_Read function */
|
||||
LOG_FUNCTION_READ(0x10),
|
||||
/** Logs all possible information within the PCAN-Basic API functions */
|
||||
LOG_FUNCTION_ALL(0xFFFF),
|
||||
|
||||
/** A single file is written until it size reaches PCAN_TRACE_SIZE */
|
||||
TRACE_FILE_SINGLE(0x00),
|
||||
/** Traced data is distributed in several files with size PCAN_TRACE_SIZE */
|
||||
TRACE_FILE_SEGMENTED(0x01),
|
||||
/** Includes the date into the name of the trace file */
|
||||
TRACE_FILE_DATE(0x02),
|
||||
/** Includes the start time into the name of the trace file */
|
||||
TRACE_FILE_TIME(0x04),
|
||||
/** Causes the overwriting of available traces (same name) */
|
||||
TRACE_FILE_OVERWRITE(0x80),
|
||||
|
||||
/** Device supports flexible data-rate (CAN-FD) */
|
||||
FEATURE_FD_CAPABLE(0x01),
|
||||
/** Device supports a delay between sending frames (FPGA based USB devices) */
|
||||
FEATURE_DELAY_CAPABLE(0x02),
|
||||
/** Device supports I/O functionality for electronic circuits (USB-Chip devices) */
|
||||
FEATURE_IO_CAPABLE(0x04),
|
||||
|
||||
/** The service is not running */
|
||||
SERVICE_STATUS_STOPPED(0x01),
|
||||
/** The service is running */
|
||||
SERVICE_STATUS_RUNNING(0x04);
|
||||
|
||||
/** Maximum length of the name of a device: 32 characters + terminator */
|
||||
public static final int MAX_LENGTH_HARDWARE_NAME = 33;
|
||||
/** Maximum length of a version string: 17 characters + terminator */
|
||||
public static final int MAX_LENGTH_VERSION_STRING = 18;
|
||||
/** Recommended length for an error string: 255 characters + terminator */
|
||||
public static final int MIN_LENGTH_ERROR_STRING = 256;
|
||||
|
||||
private TPCANParameterValue(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the CAN parameter's value
|
||||
* @return Value of the CAN parameter's value
|
||||
*/
|
||||
public int getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a int value into the TPCANParameterValue PCAN_PARAMETER_ON or PCAN_PARAMETER_OFF
|
||||
* @param value parsed value
|
||||
* @return Corresponding TPCANParameterValue
|
||||
*/
|
||||
static public TPCANParameterValue parseOnOff(int value)
|
||||
{
|
||||
if(value == TPCANParameterValue.PCAN_PARAMETER_ON.getValue())
|
||||
return TPCANParameterValue.PCAN_PARAMETER_ON;
|
||||
else if(value == TPCANParameterValue.PCAN_PARAMETER_OFF.getValue())
|
||||
return TPCANParameterValue.PCAN_PARAMETER_OFF;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Parses a int value into the TPCANParameterValue PCAN_CHANNEL_AVAILABLE, PCAN_CHANNEL_ILLEGAL, PCAN_CHANNEL_OCCUPIED or PCAN_CHANNEL_UNOCCUPIED
|
||||
* @param value parsed value
|
||||
* @return Corresponding TPCANParameterValue
|
||||
*/
|
||||
static public TPCANParameterValue parseCondition(int value)
|
||||
{
|
||||
if(value == TPCANParameterValue.PCAN_CHANNEL_AVAILABLE.getValue())
|
||||
return TPCANParameterValue.PCAN_CHANNEL_AVAILABLE;
|
||||
else if(value == TPCANParameterValue.PCAN_CHANNEL_UNAVAILABLE.getValue())
|
||||
return TPCANParameterValue.PCAN_CHANNEL_UNAVAILABLE;
|
||||
else if(value == TPCANParameterValue.PCAN_CHANNEL_OCCUPIED.getValue())
|
||||
return TPCANParameterValue.PCAN_CHANNEL_OCCUPIED;
|
||||
else if(value == TPCANParameterValue.PCAN_CHANNEL_PCANVIEW.getValue())
|
||||
return TPCANParameterValue.PCAN_CHANNEL_PCANVIEW;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Parses a int value into the TPCANParameterValue PCAN_FILTER_CLOSE, PCAN_FILTER_OPEN or PCAN_FILTER_CUSTOM.
|
||||
* @param value parsed value
|
||||
* @return Corresponding TPCANParameterValue
|
||||
*/
|
||||
static public TPCANParameterValue parseFilterStatus(int value)
|
||||
{
|
||||
if(value == TPCANParameterValue.PCAN_FILTER_CLOSE.getValue())
|
||||
return TPCANParameterValue.PCAN_FILTER_CLOSE;
|
||||
else if(value == TPCANParameterValue.PCAN_FILTER_OPEN.getValue())
|
||||
return TPCANParameterValue.PCAN_FILTER_OPEN;
|
||||
else if(value == TPCANParameterValue.PCAN_FILTER_CUSTOM.getValue())
|
||||
return TPCANParameterValue.PCAN_FILTER_CUSTOM;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a int value into the TPCANParameterValue PCAN_CHANNEL_AVAILABLE, PCAN_CHANNEL_ILLEGAL, PCAN_CHANNEL_OCCUPIED or PCAN_CHANNEL_UNOCCUPIED
|
||||
* @param value parsed value
|
||||
* @return Corresponding TPCANParameterValue
|
||||
*/
|
||||
static public EnumSet<TPCANParameterValue> parseFeatures(int value)
|
||||
{
|
||||
EnumSet<TPCANParameterValue> result = EnumSet.noneOf(TPCANParameterValue.class);
|
||||
if((value & TPCANParameterValue.FEATURE_DELAY_CAPABLE.getValue()) != 0)
|
||||
result.add(TPCANParameterValue.FEATURE_DELAY_CAPABLE);
|
||||
if((value & TPCANParameterValue.FEATURE_FD_CAPABLE.getValue()) != 0)
|
||||
result.add(TPCANParameterValue.FEATURE_FD_CAPABLE);
|
||||
if((value & TPCANParameterValue.FEATURE_IO_CAPABLE.getValue()) != 0)
|
||||
result.add(TPCANParameterValue.FEATURE_IO_CAPABLE);
|
||||
return result;
|
||||
}
|
||||
private final int value;
|
||||
};
|
|
@ -1,173 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANStatus.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Represent the PCAN error and status codes
|
||||
*/
|
||||
public enum TPCANStatus {
|
||||
|
||||
/**
|
||||
* No Error
|
||||
*/
|
||||
PCAN_ERROR_OK(0x00000),
|
||||
/**
|
||||
* Transmit buffer in CAN controller is full
|
||||
*/
|
||||
PCAN_ERROR_XMTFULL(0x00001),
|
||||
/**
|
||||
* CAN controller was read too late
|
||||
*/
|
||||
PCAN_ERROR_OVERRUN(0x00002),
|
||||
/**
|
||||
* Bus error: an error counter reached the 'light' limit
|
||||
*/
|
||||
PCAN_ERROR_BUSLIGHT(0x00004),
|
||||
/**
|
||||
* Bus error: an error counter reached the 'heavy' limit
|
||||
*/
|
||||
PCAN_ERROR_BUSHEAVY(0x00008),
|
||||
/**
|
||||
* Bus error: an error counter reached the 'warning' limit
|
||||
*/
|
||||
PCAN_ERROR_BUSWARNING(PCAN_ERROR_BUSHEAVY.value),
|
||||
/**
|
||||
* Bus error: the CAN controller is error passive
|
||||
*/
|
||||
PCAN_ERROR_BUSPASSIVE(0x40000),
|
||||
/**
|
||||
* Bus error: the CAN controller is in bus-off state
|
||||
*/
|
||||
PCAN_ERROR_BUSOFF(0x00010),
|
||||
/**
|
||||
* PCAN_ERROR_ANYBUSERR
|
||||
*/
|
||||
PCAN_ERROR_ANYBUSERR(PCAN_ERROR_BUSWARNING.value |
|
||||
PCAN_ERROR_BUSLIGHT.value | PCAN_ERROR_BUSHEAVY.value |
|
||||
PCAN_ERROR_BUSOFF.value | PCAN_ERROR_BUSPASSIVE.value),
|
||||
/**
|
||||
* Receive queue is empty
|
||||
*/
|
||||
PCAN_ERROR_QRCVEMPTY(0x00020),
|
||||
/**
|
||||
* Receive queue was read too late
|
||||
*/
|
||||
PCAN_ERROR_QOVERRUN(0x00040),
|
||||
/**
|
||||
* Transmit queue is full
|
||||
*/
|
||||
PCAN_ERROR_QXMTFULL(0x00080),
|
||||
/**
|
||||
* Test of the CAN controller hardware registers failed (no hardware found)
|
||||
*/
|
||||
PCAN_ERROR_REGTEST(0x00100),
|
||||
/**
|
||||
* Driver not loaded
|
||||
*/
|
||||
PCAN_ERROR_NODRIVER(0x00200),
|
||||
/**
|
||||
* Hardware already in use by a Net
|
||||
*/
|
||||
PCAN_ERROR_HWINUSE(0x00400),
|
||||
/**
|
||||
* A Client is already connected to the Net
|
||||
*/
|
||||
PCAN_ERROR_NETINUSE(0x00800),
|
||||
/**
|
||||
* Hardware handle is invalid
|
||||
*/
|
||||
PCAN_ERROR_ILLHW(0x01400),
|
||||
/**
|
||||
* Net handle is invalid
|
||||
*/
|
||||
PCAN_ERROR_ILLNET(0x01800),
|
||||
/**
|
||||
* Client handle is invalid
|
||||
*/
|
||||
PCAN_ERROR_ILLCLIENT(0x01C00),
|
||||
/**
|
||||
* Mask for all handle errors
|
||||
*/
|
||||
PCAN_ERROR_ILLHANDLE(PCAN_ERROR_ILLHW.value | PCAN_ERROR_ILLNET.value | PCAN_ERROR_ILLCLIENT.value),
|
||||
/**
|
||||
* Resource (FIFO, Client, timeout) cannot be created
|
||||
*/
|
||||
PCAN_ERROR_RESOURCE(0x02000),
|
||||
/**
|
||||
* Invalid parameter
|
||||
*/
|
||||
PCAN_ERROR_ILLPARAMTYPE(0x04000),
|
||||
/**
|
||||
* Invalid parameter value
|
||||
*/
|
||||
PCAN_ERROR_ILLPARAMVAL(0x08000),
|
||||
/**
|
||||
* Unknow error
|
||||
*/
|
||||
PCAN_ERROR_UNKNOWN(0x10000),
|
||||
/**
|
||||
* Invalid data, function, or action.
|
||||
*/
|
||||
PCAN_ERROR_ILLDATA(0x20000),
|
||||
/**
|
||||
* Driver object state is wrong for the attempted operation
|
||||
*/
|
||||
PCAN_ERROR_ILLMODE(0x80000),
|
||||
/**
|
||||
* An operation was successfully carried out, however, irregularities were
|
||||
* registered
|
||||
*
|
||||
* @remark Value was changed from 0x40000 to 0x4000000
|
||||
*/
|
||||
PCAN_ERROR_CAUTION(0x2000000),
|
||||
/**
|
||||
* Channel is not initialized
|
||||
*/
|
||||
PCAN_ERROR_INITIALIZE(0x4000000),
|
||||
/**
|
||||
* Invalid operation
|
||||
*
|
||||
* @remark Value was changed from 0x80000 to 0x8000000
|
||||
*/
|
||||
PCAN_ERROR_ILLOPERATION(0x8000000);
|
||||
|
||||
private TPCANStatus(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of the CAN status code
|
||||
* @return Value of the CAN status code
|
||||
*/
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
private final int value;
|
||||
};
|
|
@ -1,101 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANTimestamp.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Defines the point of time at which a CAN message was received.
|
||||
*/
|
||||
public class TPCANTimestamp
|
||||
{
|
||||
private long millis;
|
||||
private short millis_overflow;
|
||||
private short micros;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public TPCANTimestamp()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets microseconds
|
||||
* @return microseconds (0-999)
|
||||
*/
|
||||
public short getMicros()
|
||||
{
|
||||
return micros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets microseconds
|
||||
* @param micros microseconds (0-999)
|
||||
*/
|
||||
public void setMicros(short micros)
|
||||
{
|
||||
this.micros = micros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets milliseconds
|
||||
* @return milliseconds
|
||||
*/
|
||||
public long getMillis()
|
||||
{
|
||||
return millis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets milliseconds
|
||||
* @param millis milliseconds
|
||||
*/
|
||||
public void setMillis(long millis)
|
||||
{
|
||||
this.millis = millis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets milliseconds overflow
|
||||
* @return milliseconds overflow
|
||||
*/
|
||||
public short getMillis_overflow()
|
||||
{
|
||||
return millis_overflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets milliseconds overflow
|
||||
* @param millis_overflow milliseconds overflow
|
||||
*/
|
||||
public void setMillis_overflow(short millis_overflow)
|
||||
{
|
||||
this.millis_overflow = millis_overflow;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANTimestampFD.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
|
||||
/**
|
||||
* Defines the point of time at which a CAN message was received.
|
||||
*/
|
||||
public class TPCANTimestampFD
|
||||
{
|
||||
private long _timestamp;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public TPCANTimestampFD()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the timestamp
|
||||
*/
|
||||
public long getValue() {
|
||||
return _timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timestamp the timestamp to set
|
||||
*/
|
||||
public void setValue(long timestamp) {
|
||||
this._timestamp = timestamp;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-only */
|
||||
/*
|
||||
* $Id: TPCANType.java 7391 2020-08-10 08:32:30Z Fabrice $
|
||||
* @LastChange $Date: 2020-08-10 10:32:30 +0200 (Mon, 10 Aug 2020) $
|
||||
*
|
||||
* PCANBasic JAVA Interface.
|
||||
*
|
||||
* Copyright (C) 2001-2020 PEAK System-Technik GmbH <www.peak-system.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCAN is a registered Trademark of PEAK-System Germany GmbH
|
||||
*
|
||||
* Author: Jonathan Urban/Uwe Wilhelm/Fabrice Vergnaud
|
||||
* Contact: <linux@peak-system.com>
|
||||
* Maintainer: Fabrice Vergnaud <f.vergnaud@peak-system.com>
|
||||
*/
|
||||
package peak.can.basic;
|
||||
/**
|
||||
* Represents a PCAN device
|
||||
*/
|
||||
public enum TPCANType
|
||||
{
|
||||
/**Undefined, unknown or not selected PCAN type value*/
|
||||
PCAN_TYPE_NONE((byte)0x00),
|
||||
/**PCAN-ISA 82C200*/
|
||||
PCAN_TYPE_ISA((byte)0x01),
|
||||
/**PCAN-ISA SJA1000*/
|
||||
PCAN_TYPE_ISA_SJA((byte)0x09),
|
||||
/**PHYTEC ISA*/
|
||||
PCAN_TYPE_ISA_PHYTEC((byte)0x04),
|
||||
/**PCAN-Dongle 82C200*/
|
||||
PCAN_TYPE_DNG((byte)0x02),
|
||||
/**PCAN-Dongle EPP 82C200*/
|
||||
PCAN_TYPE_DNG_EPP((byte)0x03),
|
||||
/**PCAN-Dongle SJA1000*/
|
||||
PCAN_TYPE_DNG_SJA((byte)0x05),
|
||||
/**PCAN-Dongle EPP SJA1000*/
|
||||
PCAN_TYPE_DNG_SJA_EPP((byte)0x06);
|
||||
|
||||
private TPCANType(byte value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier of the CAN hardware type
|
||||
* @return Identifier of the CAN hardware type
|
||||
*/
|
||||
public byte getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
private final byte value;
|
||||
};
|
|
@ -1,81 +0,0 @@
|
|||
package com.rusefi.binaryprotocol.test;
|
||||
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.io.can.Elm327Connector;
|
||||
import com.rusefi.io.serial.BaudRateHolder;
|
||||
import com.rusefi.io.serial.SerialIoStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.binaryprotocol.IoHelper.checkResponseCode;
|
||||
import static com.rusefi.io.can.Elm327Connector.ELM327_DEFAULT_BAUDRATE;
|
||||
|
||||
public class Elm327Sandbox {
|
||||
public static void main(String[] args) throws InterruptedException, IOException {
|
||||
BaudRateHolder.INSTANCE.baudRate = ELM327_DEFAULT_BAUDRATE;
|
||||
String serialPort = "COM7";
|
||||
Elm327Connector connector = new Elm327Connector(SerialIoStream.openPort(serialPort));
|
||||
boolean initConnection = connector.start(serialPort);
|
||||
if (!initConnection)
|
||||
return;
|
||||
|
||||
IoStream tsStream = connector.getTsStream();
|
||||
|
||||
IncomingDataBuffer dataBuffer = tsStream.getDataBuffer();
|
||||
System.out.println("Hello new ELM327 connection, pending=" + dataBuffer.getPendingCount());
|
||||
|
||||
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
|
||||
LinkManager linkManager = new LinkManager();
|
||||
SandboxCommon.verifyCrcNoPending(tsStream, linkManager);
|
||||
|
||||
// SandboxCommon.runFcommand("First time", tsStream);
|
||||
if (1 == 1)
|
||||
return;
|
||||
|
||||
/*
|
||||
SandboxCommon.runFcommand("First time", tsStream);
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
|
||||
SandboxCommon.runFcommand("Second time", tsStream);
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
*/
|
||||
|
||||
SandboxCommon.verifySignature(tsStream, "", "ELM");
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
|
||||
SandboxCommon.verifySignature(tsStream, "Let's do it again! ", "ELM");
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
|
||||
{
|
||||
tsStream.sendPacket(new byte[]{Fields.TS_HELLO_COMMAND});
|
||||
byte[] response = dataBuffer.getPacket("[hello command]");
|
||||
if (!checkResponseCode(response, (byte) Fields.TS_RESPONSE_OK))
|
||||
return;
|
||||
String signature = new String(response, 1, response.length - 1);
|
||||
System.out.println(Fields.TS_HELLO_COMMAND + " returned " + signature);
|
||||
|
||||
if (!signature.startsWith(Fields.PROTOCOL_SIGNATURE_PREFIX))
|
||||
throw new IllegalStateException("Unexpected S " + signature);
|
||||
}
|
||||
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
System.out.println("****************************************");
|
||||
System.out.println("******** ELM327 LOOKS GREAT **********");
|
||||
System.out.println("****************************************");
|
||||
|
||||
|
||||
SandboxCommon.verifyCrcNoPending(tsStream, linkManager);
|
||||
SandboxCommon.verifyCrcNoPending(tsStream, linkManager);
|
||||
|
||||
SandboxCommon.readImage(tsStream, linkManager);
|
||||
|
||||
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package com.rusefi.io.can;
|
||||
|
||||
import com.rusefi.io.IoStream;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class Elm327ConnectorTest {
|
||||
@Test
|
||||
public void testBytesToString() {
|
||||
assertEquals("30 46 0D ",
|
||||
IoStream.printHexBinary(Elm327Connector.byteToString(new byte[]{0xF}))
|
||||
);
|
||||
|
||||
|
||||
assertEquals("31 30 30 42 30 30 30 35 36 42 30 30 30 30 35 30 0D ",
|
||||
IoStream.printHexBinary(Elm327Connector.byteToString(new byte[]{16, 11, 0, 5, 107, 0, 0, 80}))
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.rusefi.io.can;
|
||||
|
||||
import com.rusefi.io.IoStream;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class IsoTpConnectorTest {
|
||||
@Test
|
||||
public void testConnector() {
|
||||
|
||||
byte[] crcWrappedCrcRequest = new byte[]{
|
||||
0, 5, 107, 0, 0, 80, 95, 105, -81, -96, 112};
|
||||
|
||||
|
||||
List<String> packets = new ArrayList<>();
|
||||
|
||||
IsoTpConnector testConnector = new IsoTpConnector() {
|
||||
@Override
|
||||
public void sendCanData(byte[] hdr, byte[] data, int dataOffset, int dataLength) {
|
||||
byte[] total = combineArrays(hdr, data, dataOffset, dataLength);
|
||||
|
||||
String packetAsString = IoStream.printHexBinary(Elm327Connector.byteToString(total));
|
||||
packets.add(packetAsString);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveData() {
|
||||
}
|
||||
};
|
||||
|
||||
IsoTpConnector.sendStrategy(crcWrappedCrcRequest, testConnector);
|
||||
|
||||
assertEquals(2, packets.size());
|
||||
// 10 0B 50
|
||||
assertEquals("31 30 30 42 30 30 30 35 36 42 30 30 30 30 35 30 0D ", packets.get(0));
|
||||
// 21 5F 69 AF A0 70
|
||||
assertEquals("32 31 35 46 36 39 41 46 41 30 37 30 0D ", packets.get(1));
|
||||
}
|
||||
}
|
|
@ -12,10 +12,6 @@ import com.rusefi.io.LinkConnector;
|
|||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import com.rusefi.io.tcp.TcpIoStream;
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.server.ControllerInfo;
|
||||
import com.rusefi.server.SessionDetails;
|
||||
import com.rusefi.server.rusEFISSLContext;
|
||||
import com.rusefi.core.FileUtil;
|
||||
import com.rusefi.tune.xml.Constant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -38,7 +34,6 @@ public class TestHelper extends MockitoTestHelper {
|
|||
private static final Logging log = getLogging(TestHelper.class);
|
||||
public static final String TEST_SIGNATURE_1 = "rusEFI master.2020.07.06.frankenso_na6.2468827536";
|
||||
public static final String TEST_SIGNATURE_2 = "rusEFI master.2020.07.11.proteus_f4.1986715563";
|
||||
public static final ControllerInfo CONTROLLER_INFO = new ControllerInfo("name", "make", "code", Fields.TS_SIGNATURE);
|
||||
public static final String TEST_TOKEN_1 = "00000000-1234-1234-1234-123456789012";
|
||||
public static final String TEST_TOKEN_3 = "33333333-3333-1234-1234-123456789012";
|
||||
|
||||
|
@ -71,17 +66,6 @@ public class TestHelper extends MockitoTestHelper {
|
|||
return server;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IoStream secureConnectToLocalhost(int controllerPort) {
|
||||
IoStream targetEcuSocket;
|
||||
try {
|
||||
targetEcuSocket = new TcpIoStream("[local]", rusEFISSLContext.getSSLSocket(LOCALHOST, controllerPort));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to connect to controller " + LOCALHOST + ":" + controllerPort);
|
||||
}
|
||||
return targetEcuSocket;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IoStream connectToLocalhost(int controllerPort) {
|
||||
IoStream targetEcuSocket;
|
||||
|
@ -104,12 +88,6 @@ public class TestHelper extends MockitoTestHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public static SessionDetails createTestSession(String authToken, String signature) {
|
||||
ControllerInfo ci = new ControllerInfo("vehicle", "make", "code", signature);
|
||||
|
||||
return new SessionDetails(NetworkConnector.Implementation.Unknown, ci, authToken, SessionDetails.createOneTimeCode(), rusEFIVersion.CONSOLE_VERSION);
|
||||
}
|
||||
|
||||
public static void assertLatch(String message, CountDownLatch reconnectCounter) throws InterruptedException {
|
||||
assertLatch(message, reconnectCounter, READ_IMAGE_TIMEOUT);
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package com.rusefi.auth;
|
||||
|
||||
public class AuthTokenUtil {
|
||||
|
||||
public static final int TOKEN_LENGTH = 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12;
|
||||
public static final String TOKEN_PROFILE_URL = "https://rusefi.com/forum/ucp.php?i=254";
|
||||
public static final String TOKEN_WARNING = "Please copy token from your forum profile";
|
||||
public static final String AUTH_TOKEN = "auth_token";
|
||||
|
||||
public static boolean isToken(String content) {
|
||||
if (content == null)
|
||||
return false;
|
||||
content = content.trim();
|
||||
if (content.length() != TOKEN_LENGTH)
|
||||
return false;
|
||||
return content.charAt(8) == '-' && content.charAt(8 + 1 + 4) == '-';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.rusefi.ui.test;
|
||||
|
||||
import com.rusefi.auth.AuthTokenUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AuthTokenUtilTest {
|
||||
@Test
|
||||
public void test() {
|
||||
assertFalse(AuthTokenUtil.isToken(null));
|
||||
assertTrue(AuthTokenUtil.isToken(" 11112222-5719-4444-84d4-111122223333 "));
|
||||
|
||||
assertFalse(AuthTokenUtil.isToken(" 11112222x5719-4444-84d4-111122223333 "));
|
||||
|
||||
assertFalse(AuthTokenUtil.isToken(" 11112222-5719-4444-84d4-11112222333 "));
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package com.rusefi.tools.online;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.core.FileUtil;
|
||||
import com.rusefi.tune.xml.Msq;
|
||||
import com.rusefi.ui.AuthTokenPanel;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.concurrent.BasicFuture;
|
||||
import org.apache.http.concurrent.FutureCallback;
|
||||
import org.apache.http.entity.mime.MultipartEntity;
|
||||
import org.apache.http.entity.mime.content.FileBody;
|
||||
import org.apache.http.entity.mime.content.StringBody;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Online {
|
||||
private final static Logging log = Logging.getLogging(Online.class);
|
||||
|
||||
public static final String outputXmlFileName = FileUtil.RUSEFI_SETTINGS_FOLDER + File.separator + "output.msq";
|
||||
private static final String url = "https://rusefi.com/online/upload.php";
|
||||
|
||||
/**
|
||||
* blocking call for http file upload
|
||||
*/
|
||||
public static UploadResult upload(File fileName, String authTokenValue) {
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
|
||||
String responseString;
|
||||
try {
|
||||
FileBody uploadFilePart = new FileBody(fileName);
|
||||
MultipartEntity reqEntity = new MultipartEntity();
|
||||
reqEntity.addPart("upload-file", uploadFilePart);
|
||||
reqEntity.addPart("rusefi_token", new StringBody(authTokenValue));
|
||||
|
||||
httpPost.setEntity(reqEntity);
|
||||
|
||||
HttpResponse response = httpclient.execute(httpPost);
|
||||
log.debug("response=" + response);
|
||||
log.debug("code " + response.getStatusLine().getStatusCode());
|
||||
responseString = HttpUtil.getResponse(response);
|
||||
|
||||
} catch (IOException e) {
|
||||
return new UploadResult(true, "Upload io ERROR " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject object = HttpUtil.getJsonResponse(responseString);
|
||||
|
||||
log.debug("object=" + object);
|
||||
JSONArray info = (JSONArray) object.get("info");
|
||||
JSONArray error = (JSONArray) object.get("error");
|
||||
if (error != null) {
|
||||
log.error("error " + error);
|
||||
return new UploadResult(true, error);
|
||||
} else {
|
||||
log.debug("info " + info);
|
||||
return new UploadResult(false, info);
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
return new UploadResult(true, "Upload Error " + responseString);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* we are here in case of individual tune upload
|
||||
*/
|
||||
public static BasicFuture<UploadResult> uploadTune(Msq tune, AuthTokenPanel authTokenPanel, JComponent parent, FutureCallback<UploadResult> callback) {
|
||||
try {
|
||||
tune.writeXmlFile(outputXmlFileName);
|
||||
} catch (JAXBException | IOException e) {
|
||||
throw new IllegalStateException("While writing tune", e);
|
||||
}
|
||||
|
||||
return uploadFile(parent, callback, outputXmlFileName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BasicFuture<UploadResult> uploadFile(JComponent parent, FutureCallback<UploadResult> callback, final String fileName) {
|
||||
BasicFuture<UploadResult> result = new BasicFuture<>(callback);
|
||||
String authToken = AuthTokenPanel.getAuthToken();
|
||||
if (!AuthTokenPanel.hasToken()) {
|
||||
AuthTokenPanel.showError(parent);
|
||||
return null;
|
||||
}
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UploadResult array = upload(new File(fileName), authToken);
|
||||
result.completed(array);
|
||||
}
|
||||
}).start();
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package com.rusefi.tools.online;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
|
||||
public class UploadResult {
|
||||
private final boolean isError;
|
||||
private final JSONArray message;
|
||||
|
||||
public UploadResult(boolean isError, JSONArray message) {
|
||||
this.isError = isError;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public UploadResult(boolean isError, String value) {
|
||||
message = new JSONArray();
|
||||
message.add(value);
|
||||
this.isError = isError;
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return isError;
|
||||
}
|
||||
|
||||
public JSONArray getMessageArray() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public String getFirstMessage() {
|
||||
return message.get(0).toString();
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
package com.rusefi.ui;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.auth.AuthTokenUtil;
|
||||
import com.rusefi.core.preferences.storage.PersistentConfiguration;
|
||||
import com.rusefi.ui.util.URLLabel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.core.preferences.storage.PersistentConfiguration.getConfig;
|
||||
|
||||
public class AuthTokenPanel {
|
||||
private final static Logging log = Logging.getLogging(AuthTokenPanel.class);
|
||||
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
private final JTextField authTokenTestField = new JTextField();
|
||||
|
||||
public AuthTokenPanel() {
|
||||
|
||||
JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
content.setBorder(BorderFactory.createTitledBorder("rusEFI Online Authentication Token"));
|
||||
|
||||
authTokenTestField.setPreferredSize(new Dimension(200, 24));
|
||||
|
||||
String authToken = getAuthToken();
|
||||
log.info("Auth token from settings: " + authToken);
|
||||
|
||||
authTokenTestField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
onTextChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
onTextChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
onTextChange();
|
||||
}
|
||||
});
|
||||
|
||||
final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
|
||||
JButton paste = new JButton("Paste from clipboard");
|
||||
paste.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
String data = (String) clipboard.getData(DataFlavor.stringFlavor);
|
||||
if (AuthTokenUtil.isToken(data)) {
|
||||
authTokenTestField.setText(data);
|
||||
}
|
||||
} catch (IOException | UnsupportedFlavorException ex) {
|
||||
// ignoring this exception
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.addFlavorListener(e -> {
|
||||
setPasteButtonEnabledBasedOnClipboardContent(clipboard, paste);
|
||||
});
|
||||
|
||||
setPasteButtonEnabledBasedOnClipboardContent(clipboard, paste);
|
||||
|
||||
top.add(authTokenTestField);
|
||||
top.add(paste);
|
||||
/*
|
||||
JButton save = new JButton("Save");
|
||||
save.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
grabText();
|
||||
}
|
||||
});
|
||||
top.add(save);
|
||||
*/
|
||||
content.add(top);
|
||||
if (authToken.trim().isEmpty()) {
|
||||
authToken = AuthTokenUtil.TOKEN_WARNING;
|
||||
}
|
||||
content.add(new URLLabel("Manage authentication token at your forum profile", AuthTokenUtil.TOKEN_PROFILE_URL), BorderLayout.SOUTH);
|
||||
authTokenTestField.setText(authToken);
|
||||
}
|
||||
|
||||
public static void setAuthToken(String value) {
|
||||
getConfig().getRoot().setProperty(AuthTokenUtil.AUTH_TOKEN, value);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getAuthToken() {
|
||||
return getConfig().getRoot().getProperty(AuthTokenUtil.AUTH_TOKEN);
|
||||
}
|
||||
|
||||
private void setPasteButtonEnabledBasedOnClipboardContent(Clipboard clipboard, JButton paste) {
|
||||
try {
|
||||
String data = (String) clipboard.getData(DataFlavor.stringFlavor);
|
||||
paste.setEnabled(AuthTokenUtil.isToken(data));
|
||||
} catch (IOException | IllegalStateException | UnsupportedFlavorException ex) {
|
||||
log.info("Ignoring " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void persistToken() {
|
||||
setAuthToken(AuthTokenPanel.this.authTokenTestField.getText());
|
||||
PersistentConfiguration.getConfig().save();
|
||||
}
|
||||
|
||||
private void onTextChange() {
|
||||
if (AuthTokenUtil.isToken(authTokenTestField.getText())) {
|
||||
persistToken();
|
||||
}
|
||||
}
|
||||
|
||||
public JPanel getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public static boolean hasToken() {
|
||||
return AuthTokenUtil.isToken(getAuthToken());
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return authTokenTestField.getText();
|
||||
}
|
||||
|
||||
public static void showError(JComponent parent) {
|
||||
JOptionPane.showMessageDialog(parent, "Does not work without auth token, see below.", "Auth Token", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.rusefi.ui.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Misc {
|
||||
@NotNull
|
||||
public static URLLabel getRusEFI_online_manual() {
|
||||
return new URLLabel("rusEFI Online manual", "https://github.com/rusefi/rusefi/wiki/Online");
|
||||
}
|
||||
}
|
|
@ -13,7 +13,6 @@ import com.rusefi.ui.*;
|
|||
import com.rusefi.ui.console.MainFrame;
|
||||
import com.rusefi.ui.console.TabbedPanel;
|
||||
import com.rusefi.ui.engine.EngineSnifferPanel;
|
||||
import com.rusefi.ui.logview.LogViewer;
|
||||
import com.rusefi.ui.lua.LuaScriptPanel;
|
||||
import com.rusefi.ui.util.DefaultExceptionHandler;
|
||||
import com.rusefi.ui.util.JustOneInstance;
|
||||
|
@ -117,15 +116,12 @@ public class ConsoleUI {
|
|||
// tabbedPane.add("Wizards", new Wizard().createPane());
|
||||
|
||||
tabbedPane.addTab("Live Data", LiveDataPane.createLazy(uiContext).getContent());
|
||||
tabbedPane.addTab("Sensors Live Data", new SensorsLiveDataPane(uiContext).getContent());
|
||||
|
||||
if (tabbedPane.paneSettings.showTriggerShapePane)
|
||||
tabbedPane.addTab("Trigger Shape", new AverageAnglePanel(uiContext).getPanel());
|
||||
|
||||
MessagesCentral.getInstance().postMessage(ConsoleUI.class, "COMPOSITE_OFF_RPM=" + BinaryProtocolLogger.COMPOSITE_OFF_RPM);
|
||||
|
||||
tabbedPane.addTab("rusEFI Online", new OnlineTab(uiContext).getContent());
|
||||
|
||||
uiContext.sensorLogger.init();
|
||||
|
||||
int selectedIndex = getConfig().getRoot().getIntProperty(TAB_INDEX, DEFAULT_TAB_INDEX);
|
||||
|
|
|
@ -1,492 +0,0 @@
|
|||
package com.rusefi;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
|
||||
public final class Histograms {
|
||||
private static final Logging log = getLogging(Histograms.class);
|
||||
private static final String MAGIC = "total";
|
||||
public static final double H_ACCURACY = 0.05;
|
||||
public static final int BOUND_LENGTH = (int) (Math.log(Long.MAX_VALUE) / Math.log(1.0 + H_ACCURACY));
|
||||
|
||||
public static final long LONG_MAX_INT = 0x7fffffffffffffffL;
|
||||
|
||||
public static final double H_CONFIDENCE = 0.8;
|
||||
public static final int SBI_SIZE = 1000;
|
||||
|
||||
// ======= Initialization =======
|
||||
|
||||
private final HashMap<String, StatisticsGroup> total_stats = new HashMap<>();
|
||||
private final long start_time = System.currentTimeMillis();
|
||||
public final ThreadLocal<LocalStats> local_stats = ThreadLocal.withInitial(LocalStats::new);
|
||||
private final HashSet<LocalStats> all_local_stats = new HashSet<>();
|
||||
|
||||
private long last_dump = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* this method updates totals & resets snapshot
|
||||
* todo: get rid of TOS 'Profiler' and make this method protected?
|
||||
*
|
||||
* @see #getCurrentStatistics()
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> dumpStats() {
|
||||
Collection<StatisticsGroup> values = takeAndResetSnapshot();
|
||||
List<StatisticsGroup> al = new ArrayList<>(values);
|
||||
|
||||
synchronized (total_stats) {
|
||||
for (StatisticsGroup source : values) {
|
||||
String type = source.type + ".TOTAL";
|
||||
StatisticsGroup dest = total_stats.get(type);
|
||||
if (dest == null)
|
||||
total_stats.put(type, dest = new StatisticsGroup(type));
|
||||
dest.add(source);
|
||||
}
|
||||
al.addAll(total_stats.values());
|
||||
}
|
||||
return sortAndAddTimes(al);
|
||||
}
|
||||
|
||||
/**
|
||||
* this method displays currently gathered histogram without affecting state
|
||||
*
|
||||
* @see #dumpStats()
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
@NotNull
|
||||
public List<String> getCurrentStatistics() {
|
||||
Collection<StatisticsGroup> snapshot = getCurrentSnapshot();
|
||||
return sortAndAddTimes(new ArrayList<>(snapshot));
|
||||
}
|
||||
|
||||
private List<String> sortAndAddTimes(List<StatisticsGroup> al) {
|
||||
Collections.sort(al, new Comparator<StatisticsGroup>() {
|
||||
public int compare(StatisticsGroup o1, StatisticsGroup o2) {
|
||||
return o1.type.compareTo(o2.type);
|
||||
}
|
||||
});
|
||||
long time = System.currentTimeMillis();
|
||||
List<String> result = new ArrayList<>();
|
||||
for (StatisticsGroup sg : al)
|
||||
result.add(toString(sg, time - (sg.type.endsWith(".TOTAL") ? start_time : last_dump)));
|
||||
last_dump = time;
|
||||
return result;
|
||||
}
|
||||
|
||||
// ========= Internal Data Structures ========
|
||||
|
||||
/**
|
||||
* Accuracy of histogram - the ratio of bar width to its value.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Confidence interval to be printed together with min/max interval.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Confidence quantity bounds for logging.
|
||||
*/
|
||||
private final double[] confidence_bounds;
|
||||
|
||||
/**
|
||||
* Confidence interval separators for logging.
|
||||
*/
|
||||
private final String[] confidence_separators;
|
||||
|
||||
/**
|
||||
* Bounds of histogram bars. Bar number 'i' covers interval
|
||||
* from bounds[i] inclusive to bounds[i + 1] exclusive.
|
||||
*/
|
||||
private final long[] bounds;
|
||||
|
||||
/**
|
||||
* Index for direct access to intervals with small bounds.
|
||||
*/
|
||||
private final int[] small_bounds_index;
|
||||
|
||||
|
||||
/**
|
||||
* Construct new instance of profiler with specified parameters.
|
||||
*/
|
||||
public Histograms() {
|
||||
|
||||
confidence_bounds = new double[]{0.5 - H_CONFIDENCE * 0.5, 0.5, 0.5 + H_CONFIDENCE * 0.5};
|
||||
confidence_separators = new String[]{"(", " [", "-", "-", "] ", ")"};
|
||||
|
||||
log.info("BOUND_LENGTH=" + BOUND_LENGTH);
|
||||
|
||||
bounds = new long[BOUND_LENGTH];
|
||||
bounds[0] = 0;
|
||||
for (int i = 1; i < BOUND_LENGTH; i++) {
|
||||
long prev = bounds[i - 1];
|
||||
long next = prev + (long) ((double) prev * H_ACCURACY);
|
||||
if (next == prev) // Ensure minimum step for small numbers.
|
||||
next = prev + 1;
|
||||
if (next < prev) // Overflow over Long.MAX_VALUE occurred.
|
||||
next = LONG_MAX_INT;
|
||||
bounds[i] = next;
|
||||
}
|
||||
bounds[BOUND_LENGTH - 1] = LONG_MAX_INT;
|
||||
|
||||
small_bounds_index = new int[SBI_SIZE];
|
||||
for (int i = 0, j = 0; j < SBI_SIZE; i++)
|
||||
while (j < bounds[i + 1] && j < SBI_SIZE)
|
||||
small_bounds_index[j++] = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns histogram index for specified value.
|
||||
*/
|
||||
public int getIndex(long value) {
|
||||
if (value < 0)
|
||||
return 0;
|
||||
if (value < small_bounds_index.length)
|
||||
return small_bounds_index[(int) value];
|
||||
int l = small_bounds_index[small_bounds_index.length - 1];
|
||||
int r = bounds.length - 1;
|
||||
while (l < r) {
|
||||
int m = (l + r) >> 1;
|
||||
if (bounds[m] > value)
|
||||
r = m - 1;
|
||||
else if (bounds[m + 1] <= value)
|
||||
l = m + 1;
|
||||
else
|
||||
return m;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public static final class LocalStats {
|
||||
public HashMap<ValueType, StatisticsGroup> stats; // Type -> StatisticsGroup
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds specified samples to statistics.
|
||||
*/
|
||||
public void addValue(ValueType t, String name, long value) {
|
||||
String type = t.getName();
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
int index = getIndex(value);
|
||||
LocalStats ls = local_stats.get();
|
||||
boolean create;
|
||||
create = ls.stats == null;
|
||||
if (create)
|
||||
ls.stats = new HashMap<>();
|
||||
StatisticsGroup sg = ls.stats.get(t);
|
||||
if (sg == null)
|
||||
ls.stats.put(t, sg = new StatisticsGroup(type));
|
||||
sg.add(name, index, value);
|
||||
if (create)
|
||||
synchronized (all_local_stats) {
|
||||
all_local_stats.add(ls);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns current statistics without resetting anything
|
||||
*/
|
||||
private Collection<StatisticsGroup> getCurrentSnapshot() {
|
||||
List<LocalStats> lss = getLocalStats(false);
|
||||
HashMap<String, StatisticsGroup> snapshot = new HashMap<>();
|
||||
for (LocalStats ls : lss) {
|
||||
// in case of a snapshot without reset, we have to merge under the lock
|
||||
mergeStats(snapshot, ls.stats);
|
||||
}
|
||||
return snapshot.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns snapshot of all gathered statistics and clears them in process.
|
||||
*/
|
||||
private Collection<StatisticsGroup> takeAndResetSnapshot() {
|
||||
List<LocalStats> lss = getLocalStats(true);
|
||||
HashMap<String, StatisticsGroup> snapshot = new HashMap<>();
|
||||
for (LocalStats ls : lss) {
|
||||
HashMap<ValueType, StatisticsGroup> stats;
|
||||
stats = ls.stats;
|
||||
/**
|
||||
* we will re-register this LocalStats on next #add() invocation
|
||||
* @see #add(String, String, int, long)
|
||||
*/
|
||||
ls.stats = null;
|
||||
mergeStats(snapshot, stats);
|
||||
}
|
||||
return snapshot.values();
|
||||
}
|
||||
|
||||
private static void mergeStats(HashMap<String, StatisticsGroup> snapshot, HashMap<ValueType, StatisticsGroup> stats) {
|
||||
if (stats != null)
|
||||
for (StatisticsGroup source : stats.values()) {
|
||||
StatisticsGroup dest = snapshot.get(source.type);
|
||||
if (dest == null)
|
||||
snapshot.put(source.type, source);
|
||||
else
|
||||
dest.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
private List<LocalStats> getLocalStats(boolean reset) {
|
||||
List<LocalStats> lss;
|
||||
synchronized (all_local_stats) {
|
||||
lss = new ArrayList<>(all_local_stats);
|
||||
if (reset)
|
||||
all_local_stats.clear();
|
||||
}
|
||||
return lss;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts specified statistics of specified statistics group for logging.
|
||||
*/
|
||||
private static void sortStatistics(StatisticsGroup sg, Statistics[] sts) {
|
||||
final boolean use_total = sg.type.startsWith(MAGIC);
|
||||
Arrays.sort(sts, new Comparator<Statistics>() {
|
||||
public int compare(Statistics st1, Statistics st2) {
|
||||
if (use_total && st1.total_value != st2.total_value)
|
||||
return st1.total_value < st2.total_value ? -1 : 1;
|
||||
return st1.name.compareTo(st2.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ========== Formatting Methods ==========
|
||||
|
||||
private static final double[] multipliers = {1.0, 10.0, 100.0};
|
||||
private final NumberFormat formatter = NumberFormat.getNumberInstance();
|
||||
private final FieldPosition field = new FieldPosition(0);
|
||||
|
||||
/**
|
||||
* Formats specified value into specified string buffer. Not thread-safe.
|
||||
*/
|
||||
private StringBuffer format(double d, StringBuffer sb) {
|
||||
int i = Math.abs(d) < 9.995 ? 2 : Math.abs(d) < 99.95 ? 1 : 0;
|
||||
formatter.setMinimumFractionDigits(0);
|
||||
formatter.setMaximumFractionDigits(i);
|
||||
return formatter.format(Math.floor(d * multipliers[i] + 0.5) / multipliers[i], sb, field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends header for specified statistics group for logging.
|
||||
*/
|
||||
private void appendHeader(StringBuffer sb, StatisticsGroup sg, long duration) {
|
||||
double time = duration;
|
||||
String time_scale = "ms";
|
||||
if (time >= 24 * 3600 * 1000 * 0.995) {
|
||||
time /= 24.0 * 3600.0 * 1000.0;
|
||||
time_scale = "days";
|
||||
} else if (time >= 3600 * 1000 * 0.995) {
|
||||
time /= 3600.0 * 1000.0;
|
||||
time_scale = "hours";
|
||||
} else if (time >= 60 * 1000 * 0.995) {
|
||||
time /= 60.0 * 1000.0;
|
||||
time_scale = "min";
|
||||
} else if (time >= 1000 * 0.995) {
|
||||
time /= 1000.0;
|
||||
time_scale = "sec";
|
||||
}
|
||||
|
||||
sb.append(sg.type).append(" statistics for ");
|
||||
format(time, sb).append(time_scale).append(" with ");
|
||||
format(H_ACCURACY * 100.0, sb).append("% accuracy and ");
|
||||
format(H_CONFIDENCE * 100.0, sb).append("% confidence:");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends specified statistics (main part) for logging.
|
||||
*/
|
||||
public void appendStatistics(StringBuffer sb, Statistics st, List<Long> report) {
|
||||
format(st.total_value, sb).append(" / ").append(st.total_count).append(" = ");
|
||||
format((double) st.total_value / (double) st.total_count, sb);
|
||||
|
||||
if (st.total_count < 0) {
|
||||
sb.append("Total count is less then ZERO!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.total_count <= 5) {
|
||||
// There are too little samples for statistics.
|
||||
sb.append(" are");
|
||||
for (int j = 0; j < st.histogram.length; j++)
|
||||
for (int k = 0; k < st.histogram[j]; k++) {
|
||||
sb.append(' ');
|
||||
format((bounds[j] + bounds[j + 1]) / 2, sb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Print full min/confidence/max statistics.
|
||||
sb.append(" in ").append(confidence_separators[0]);
|
||||
int min = 0;
|
||||
while (st.histogram[min] == 0)
|
||||
min++;
|
||||
// 'min' is index of interval with min sample.
|
||||
format(bounds[min], sb).append(confidence_separators[1]);
|
||||
report.add(bounds[min]);
|
||||
|
||||
|
||||
long acc = 0;
|
||||
// 'acc' is accumulated number of samples in [0, min - 1].
|
||||
for (int j = 0; j < confidence_bounds.length; j++) {
|
||||
long k = (long) Math.floor((double) st.total_count * confidence_bounds[j]);
|
||||
// Always drop at least 1 'non-confident' sample...
|
||||
if (k == 0)
|
||||
k = 1;
|
||||
if (k == st.total_count)
|
||||
k = st.total_count - 1;
|
||||
// 'k' is desired number of samples.
|
||||
while (acc + st.histogram[min] < k)
|
||||
acc += st.histogram[min++];
|
||||
if (k < st.total_count / 2) // Converge to median (from left).
|
||||
while (acc + st.histogram[min] <= k)
|
||||
acc += st.histogram[min++];
|
||||
// Now: acc <= k <= acc + st.histogram[min]
|
||||
// And desired number of samples is within [min, min + 1)
|
||||
double d = bounds[min];
|
||||
if (acc != k)
|
||||
d += (double) (bounds[min + 1] - 1 - bounds[min]) *
|
||||
(double) (k - acc) /
|
||||
(double) st.histogram[min];
|
||||
format(d, sb).append(confidence_separators[j + 2]);
|
||||
report.add((long)d);
|
||||
}
|
||||
|
||||
int max = st.histogram.length - 1;
|
||||
while (st.histogram[max] == 0)
|
||||
max--;
|
||||
// 'max' is index of interval with max sample.
|
||||
long maxValue = bounds[max + 1] - 1;
|
||||
format(maxValue, sb).append(confidence_separators[5]);
|
||||
report.add(maxValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats specified statistics group for logging.
|
||||
*/
|
||||
private String toString(StatisticsGroup sg, long duration) {
|
||||
StringBuffer sb = new StringBuffer(100 + sg.data.size() * 100);
|
||||
appendHeader(sb, sg, duration);
|
||||
Statistics[] sts = sg.data.values().toArray(new Statistics[0]);
|
||||
sortStatistics(sg, sts);
|
||||
for (Statistics st : sts) {
|
||||
appendStatistics(sb, st, new ArrayList<>());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// ========== Internal Classes ==========
|
||||
|
||||
/**
|
||||
* Performance statistics for single operation.
|
||||
*/
|
||||
public static class Statistics {
|
||||
private static final long[] EMPTY_HISTOGRAM = new long[0];
|
||||
|
||||
public final String name;
|
||||
|
||||
public long total_value;
|
||||
public long total_count;
|
||||
public long[] histogram;
|
||||
|
||||
private Statistics(String name) {
|
||||
this.name = name;
|
||||
this.histogram = EMPTY_HISTOGRAM;
|
||||
}
|
||||
|
||||
private Statistics(Statistics st) {
|
||||
this.name = st.name;
|
||||
this.total_value = st.total_value;
|
||||
this.total_count = st.total_count;
|
||||
this.histogram = st.histogram.length == 0 ? EMPTY_HISTOGRAM : st.histogram.clone();
|
||||
}
|
||||
|
||||
public void add(int index, int count, long value) {
|
||||
total_value += value;
|
||||
total_count += count;
|
||||
if (index >= histogram.length) {
|
||||
int new_length = Math.max(histogram.length, 10);
|
||||
while (index >= new_length)
|
||||
new_length = new_length << 1;
|
||||
long[] new_histogram = new long[new_length];
|
||||
System.arraycopy(histogram, 0, new_histogram, 0, histogram.length);
|
||||
histogram = new_histogram;
|
||||
}
|
||||
histogram[index] += count;
|
||||
}
|
||||
|
||||
public void add(Statistics st) {
|
||||
total_value += st.total_value;
|
||||
total_count += st.total_count;
|
||||
long[] hist = st.histogram;
|
||||
if (histogram.length < st.histogram.length) {
|
||||
hist = histogram;
|
||||
histogram = st.histogram.clone();
|
||||
}
|
||||
for (int i = hist.length; --i >= 0; )
|
||||
histogram[i] += hist[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group of statistics of the same type.
|
||||
*/
|
||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||
public static class StatisticsGroup {
|
||||
public final String type;
|
||||
public final HashMap<String, Statistics> data; // Maps statistics name (String) to Statistics.
|
||||
|
||||
private StatisticsGroup(String type) {
|
||||
this.type = type;
|
||||
this.data = new HashMap<>();
|
||||
}
|
||||
|
||||
public void add(String name, int index, long value) {
|
||||
Statistics st = data.get(name);
|
||||
if (st == null)
|
||||
data.put(name, st = new Statistics(name));
|
||||
st.add(index, 1, value);
|
||||
}
|
||||
|
||||
public void add(StatisticsGroup sg) {
|
||||
for (Iterator<Statistics> it = sg.data.values().iterator(); it.hasNext(); ) {
|
||||
Statistics source = it.next();
|
||||
Statistics dest = data.get(source.name);
|
||||
if (dest == null)
|
||||
data.put(source.name, new Statistics(source));
|
||||
else
|
||||
dest.add(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of a value.
|
||||
*/
|
||||
public enum ValueType {
|
||||
INVOCATION("Invocation");
|
||||
/**
|
||||
* Value type that is used to mean a method call.
|
||||
*/
|
||||
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Gets the name of this {@link ValueType}.
|
||||
*
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
ValueType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ import com.rusefi.maintenance.DriverInstall;
|
|||
import com.rusefi.maintenance.ExecHelper;
|
||||
import com.rusefi.maintenance.FirmwareFlasher;
|
||||
import com.rusefi.maintenance.ProgramSelector;
|
||||
import com.rusefi.ui.PcanConnectorUI;
|
||||
import com.rusefi.ui.util.HorizontalLine;
|
||||
import com.rusefi.ui.util.URLLabel;
|
||||
import com.rusefi.ui.util.UiUtils;
|
||||
|
@ -138,7 +137,6 @@ public class StartupFrame {
|
|||
JPanel topButtons = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
|
||||
topButtons.add(createShowDeviceManagerButton());
|
||||
topButtons.add(DriverInstall.createButton());
|
||||
topButtons.add(createPcanConnectorButton());
|
||||
realHardwarePanel.add(topButtons, "right, wrap");
|
||||
}
|
||||
realHardwarePanel.add(connectPanel, "right, wrap");
|
||||
|
@ -304,13 +302,6 @@ public class StartupFrame {
|
|||
};
|
||||
}
|
||||
|
||||
private Component createPcanConnectorButton() {
|
||||
JButton button = new JButton("PCAN");
|
||||
button.setToolTipText("PCAN connector for TS");
|
||||
button.addActionListener(e -> PcanConnectorUI.show());
|
||||
return button;
|
||||
}
|
||||
|
||||
private Component createShowDeviceManagerButton() {
|
||||
JButton showDeviceManager = new JButton(AutoupdateUtil.loadIcon("DeviceManager.png"));
|
||||
showDeviceManager.setMargin(new Insets(0, 0, 0, 0));
|
||||
|
|
|
@ -5,9 +5,6 @@ import com.rusefi.NamedThreadFactory;
|
|||
import com.rusefi.Timeouts;
|
||||
import com.rusefi.core.Sensor;
|
||||
import com.rusefi.core.SensorCentral;
|
||||
import com.rusefi.tools.online.Online;
|
||||
import com.rusefi.tools.online.UploadResult;
|
||||
import com.rusefi.ui.AuthTokenPanel;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
@ -56,21 +53,8 @@ public class BinarySensorLogRestarter implements SensorLog {
|
|||
public synchronized void close() {
|
||||
if (logger != null) {
|
||||
logger.close();
|
||||
String fileName = logger.getFileName();
|
||||
scheduleUpload(fileName);
|
||||
}
|
||||
logger = null;
|
||||
seenRunning = 0;
|
||||
}
|
||||
|
||||
private void scheduleUpload(String fileName) {
|
||||
FileLog.MAIN.logLine("Will upload " + fileName);
|
||||
UPLOAD_EXECUTOR.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UploadResult result = Online.upload(new File(fileName), AuthTokenPanel.getAuthToken());
|
||||
System.out.println(result.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package com.rusefi.tools;
|
||||
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.io.serial.AbstractIoStream;
|
||||
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||
import com.rusefi.io.tcp.TcpConnector;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CANConnectorStartup {
|
||||
public static void start(AbstractIoStream tsStream, StatusConsumer statusListener) throws IOException {
|
||||
if (tsStream == null)
|
||||
throw new IOException("Failed to initialise connector");
|
||||
|
||||
String signature = BinaryProtocol.getSignature(tsStream);
|
||||
if (signature == null) {
|
||||
statusListener.append("Error: no ECU signature from " + tsStream);
|
||||
} else {
|
||||
statusListener.append("Got [" + signature + "] ECU signature via " + tsStream);
|
||||
}
|
||||
BinaryProtocolProxy.createProxy(tsStream, TcpConnector.DEFAULT_PORT, BinaryProtocolProxy.ClientApplicationActivityListener.VOID, statusListener);
|
||||
|
||||
}
|
||||
}
|
|
@ -21,14 +21,10 @@ import com.rusefi.io.IoStream;
|
|||
import com.rusefi.io.LinkManager;
|
||||
import com.rusefi.io.stream.PCanIoStream;
|
||||
import com.rusefi.io.stream.SocketCANIoStream;
|
||||
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import com.rusefi.io.tcp.ServerSocketReference;
|
||||
import com.rusefi.maintenance.ExecHelper;
|
||||
import com.rusefi.proxy.client.LocalApplicationProxy;
|
||||
import com.rusefi.tools.online.Online;
|
||||
import com.rusefi.tune.xml.Msq;
|
||||
import com.rusefi.ui.AuthTokenPanel;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
import com.rusefi.ui.light.LightweightGUI;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -46,14 +42,13 @@ import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
|
|||
import static com.rusefi.binaryprotocol.IoHelper.getCrc32;
|
||||
|
||||
public class ConsoleTools {
|
||||
public static final String SET_AUTH_TOKEN = "set_auth_token";
|
||||
public static final String RUS_EFI_NOT_DETECTED = "rusEFI not detected";
|
||||
private static final Map<String, ConsoleTool> TOOLS = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private static final Map<String, String> toolsHelp = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private static final StatusConsumer statusListener = new StatusConsumer() {
|
||||
final Logging log = getLogging(CANConnectorStartup.class);
|
||||
final Logging log = getLogging(ConsoleTools.class);
|
||||
@Override
|
||||
public void append(String message) {
|
||||
log.info(message);
|
||||
|
@ -72,22 +67,6 @@ public class ConsoleTools {
|
|||
registerTool("get_image_tune_crc", ConsoleTools::calcBinaryImageTuneCrc, "Calculate tune CRC for given binary tune");
|
||||
registerTool("get_xml_tune_crc", ConsoleTools::calcXmlImageTuneCrc, "Calculate tune CRC for given XML tune");
|
||||
|
||||
registerTool("network_connector", strings -> NetworkConnectorStartup.start(), "Connect your rusEFI ECU to rusEFI Online");
|
||||
registerTool("network_authenticator", strings -> LocalApplicationProxy.start(), "rusEFI Online Authenticator");
|
||||
registerTool("elm327_connector", strings -> Elm327ConnectorStartup.start(), "Connect your rusEFI ECU using ELM327 CAN-bus adapter");
|
||||
registerTool("pcan_connector", strings -> {
|
||||
|
||||
PCanIoStream stream = PCanIoStream.createStream();
|
||||
CANConnectorStartup.start(stream, statusListener);
|
||||
}, "Connect your rusEFI ECU using PCAN CAN-bus adapter");
|
||||
if (!FileLog.isWindows()) {
|
||||
registerTool("socketcan_connector", strings -> CANConnectorStartup.start(SocketCANIoStream.create(), statusListener), "Connect your rusEFI ECU using SocketCAN CAN-bus adapter");
|
||||
}
|
||||
registerTool("print_auth_token", args -> printAuthToken(), "Print current rusEFI Online authentication token.");
|
||||
registerTool("print_vehicle_token", args -> printVehicleToken(), "Prints vehicle access token.");
|
||||
registerTool(SET_AUTH_TOKEN, ConsoleTools::setAuthToken, "Set rusEFI Online authentication token.");
|
||||
registerTool("upload_tune", ConsoleTools::uploadTune, "Upload specified tune file to rusEFI Online using auth token from settings");
|
||||
|
||||
registerTool("read_tune", args -> readTune(), "Read tune from controller");
|
||||
registerTool("write_tune", ConsoleTools::writeTune, "Write specified XML tune into controller");
|
||||
registerTool("get_performance_trace", args -> PerformanceTraceHelper.getPerformanceTune(), "DEV TOOL: Get performance trace from ECU");
|
||||
|
@ -97,8 +76,6 @@ public class ConsoleTools {
|
|||
registerTool("lightui", strings -> lightUI(), "Start lightweight GUI for tiny screens");
|
||||
registerTool("dfu", DfuTool::run, "Program specified file into ECU via DFU");
|
||||
|
||||
registerTool("local_proxy", ConsoleTools::localProxy, "Detect rusEFI ECU and proxy serial <> TCP");
|
||||
|
||||
registerTool("detect", ConsoleTools::detect, "Find attached rusEFI");
|
||||
registerTool("send_command", new ConsoleTool() {
|
||||
@Override
|
||||
|
@ -119,23 +96,6 @@ public class ConsoleTools {
|
|||
}, "Sends a command to switch rusEFI controller into DFU mode.");
|
||||
}
|
||||
|
||||
private static void localProxy(String[] strings) throws IOException {
|
||||
String autoDetectedPort = autoDetectPort();
|
||||
if (autoDetectedPort == null) {
|
||||
System.out.println(RUS_EFI_NOT_DETECTED);
|
||||
return;
|
||||
}
|
||||
IoStream ecuStream = LinkManager.open(autoDetectedPort);
|
||||
|
||||
ServerSocketReference serverHolder = BinaryProtocolProxy.createProxy(ecuStream, 29001, new BinaryProtocolProxy.ClientApplicationActivityListener() {
|
||||
@Override
|
||||
public void onActivity() {
|
||||
|
||||
}
|
||||
}, StatusConsumer.ANONYMOUS);
|
||||
|
||||
}
|
||||
|
||||
private static void version(String[] strings) {
|
||||
// version is printed by already, all we need is to do nothing
|
||||
}
|
||||
|
@ -175,13 +135,6 @@ public class ConsoleTools {
|
|||
LightweightGUI.start();
|
||||
}
|
||||
|
||||
private static void uploadTune(String[] args) {
|
||||
String fileName = args[1];
|
||||
String authToken = AuthTokenPanel.getAuthToken();
|
||||
System.out.println("Trying to upload " + fileName + " using " + authToken);
|
||||
Online.upload(new File(fileName), authToken);
|
||||
}
|
||||
|
||||
private static void registerTool(String command, ConsoleTool callback, String help) {
|
||||
TOOLS.put(command, callback);
|
||||
toolsHelp.put(command, help);
|
||||
|
@ -216,27 +169,6 @@ public class ConsoleTools {
|
|||
FiringOrderTSLogic.invoke(args[1]);
|
||||
}
|
||||
|
||||
private static void setAuthToken(String[] args) {
|
||||
String newToken = args[1];
|
||||
System.out.println("Saving auth token " + newToken);
|
||||
AuthTokenPanel.setAuthToken(newToken);
|
||||
}
|
||||
|
||||
private static void printVehicleToken() {
|
||||
int vehicleToken = VehicleToken.getOrCreate();
|
||||
System.out.println("Vehicle token: " + vehicleToken);
|
||||
}
|
||||
|
||||
private static void printAuthToken() {
|
||||
String authToken = AuthTokenPanel.getAuthToken();
|
||||
if (authToken.trim().isEmpty()) {
|
||||
System.out.println("Auth token not defined. Please use " + SET_AUTH_TOKEN + " command");
|
||||
System.out.println("\tPlease see https://github.com/rusefi/rusefi/wiki/Online");
|
||||
return;
|
||||
}
|
||||
System.out.println("Auth token: " + authToken);
|
||||
}
|
||||
|
||||
private static void runFunctionalTest(String[] args) throws InterruptedException {
|
||||
// passing port argument if it was specified
|
||||
String[] toolArgs = args.length == 1 ? new String[0] : new String[]{args[1]};
|
||||
|
@ -358,12 +290,6 @@ public class ConsoleTools {
|
|||
String inputBinaryFileName = args[1];
|
||||
ConfigurationImage image = ConfigurationImageFile.readFromFile(inputBinaryFileName);
|
||||
System.out.println("Got " + image.getSize() + " of configuration from " + inputBinaryFileName);
|
||||
|
||||
Msq tune = MsqFactory.valueOf(image);
|
||||
tune.writeXmlFile(Online.outputXmlFileName);
|
||||
String authToken = AuthTokenPanel.getAuthToken();
|
||||
System.out.println("Using " + authToken);
|
||||
Online.upload(new File(Online.outputXmlFileName), authToken);
|
||||
}
|
||||
|
||||
static void detect(String[] strings) throws IOException {
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package com.rusefi.tools;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.autodetect.PortDetector;
|
||||
import com.rusefi.autodetect.SerialAutoChecker;
|
||||
import com.rusefi.io.can.Elm327Connector;
|
||||
import com.rusefi.io.serial.SerialIoStream;
|
||||
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||
import com.rusefi.io.tcp.TcpConnector;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Elm327ConnectorStartup {
|
||||
private final static Logging log = Logging.getLogging(Elm327ConnectorStartup.class);
|
||||
|
||||
public static void start() throws IOException {
|
||||
SerialAutoChecker.AutoDetectResult detectResult = PortDetector.autoDetectSerial(null, PortDetector.DetectorMode.DETECT_ELM327);
|
||||
String autoDetectedPort = detectResult.getSerialPort();
|
||||
//String autoDetectedPort = "COM73";
|
||||
if (autoDetectedPort == null) {
|
||||
System.err.println(ConsoleTools.RUS_EFI_NOT_DETECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
Elm327Connector elm327Connector = new Elm327Connector(SerialIoStream.openPort(autoDetectedPort));
|
||||
elm327Connector.start(autoDetectedPort);
|
||||
|
||||
BinaryProtocolProxy.createProxy(elm327Connector.getTsStream(), TcpConnector.DEFAULT_PORT, new BinaryProtocolProxy.ClientApplicationActivityListener() {
|
||||
@Override
|
||||
public void onActivity() {
|
||||
System.out.println("onActivity");
|
||||
Elm327Connector.whyDoWeNeedToSleepBetweenCommands();
|
||||
}
|
||||
}, StatusConsumer.ANONYMOUS);
|
||||
|
||||
log.info("Running Elm327 connector for " + autoDetectedPort);
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package com.rusefi.tools;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.auth.AuthTokenUtil;
|
||||
import com.rusefi.autodetect.PortDetector;
|
||||
import com.rusefi.proxy.NetworkConnector;
|
||||
import com.rusefi.proxy.NetworkConnectorContext;
|
||||
import com.rusefi.tools.online.HttpUtil;
|
||||
import com.rusefi.tools.online.ProxyClient;
|
||||
import com.rusefi.ui.AuthTokenPanel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class NetworkConnectorStartup {
|
||||
private final static Logging log = Logging.getLogging(NetworkConnectorStartup.class);
|
||||
|
||||
public static void start() {
|
||||
String authToken = AuthTokenPanel.getAuthToken();
|
||||
if (!AuthTokenUtil.isToken(authToken)) {
|
||||
System.err.println("Please configure authentication token using 'set_auth_token' command");
|
||||
return;
|
||||
}
|
||||
|
||||
String autoDetectedPort = PortDetector.autoDetectSerial(null).getSerialPort();
|
||||
if (autoDetectedPort == null) {
|
||||
System.err.println(ConsoleTools.RUS_EFI_NOT_DETECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkConnectorContext connectorContext = new NetworkConnectorContext();
|
||||
|
||||
NetworkConnector.NetworkConnectorResult networkConnectorResult = new NetworkConnector().start(NetworkConnector.Implementation.SBC, authToken, autoDetectedPort, connectorContext, new NetworkConnector.ReconnectListener() {
|
||||
@Override
|
||||
public void onReconnect() {
|
||||
try {
|
||||
String version = HttpUtil.executeGet(ProxyClient.getHttpAddress(HttpUtil.PROXY_JSON_API_HTTP_PORT) + ProxyClient.VERSION_PATH);
|
||||
if (!version.contains(ProxyClient.BACKEND_VERSION)) {
|
||||
String message = "Unexpected backend version " + version + " while we want " + ProxyClient.BACKEND_VERSION;
|
||||
log.error(message);
|
||||
System.out.println(message);
|
||||
// let's give wrapper bash script a chance to update software
|
||||
System.exit(NetworkConnectorContext.UPDATE_RELEASE_FIRMWARE_EXIT_CODE);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Ignoring", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
log.info("Running with oneTimeToken=" + networkConnectorResult.getOneTimeToken());
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package com.rusefi.ui;
|
||||
|
||||
import com.rusefi.binaryprotocol.MsqFactory;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.tools.online.Online;
|
||||
import com.rusefi.tune.xml.Msq;
|
||||
import com.rusefi.ui.util.Misc;
|
||||
import org.putgemin.VerticalFlowLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class OnlineTab {
|
||||
|
||||
private final JPanel content = new JPanel(new VerticalFlowLayout());
|
||||
|
||||
public OnlineTab(UIContext uiContext) {
|
||||
AuthTokenPanel authTokenPanel = new AuthTokenPanel();
|
||||
|
||||
content.add(Misc.getRusEFI_online_manual());
|
||||
|
||||
content.add(authTokenPanel.getContent());
|
||||
|
||||
JButton upload = new JButton("Upload");
|
||||
upload.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Msq tune = MsqFactory.valueOf(uiContext.getLinkManager().getCurrentStreamState().getControllerConfiguration());
|
||||
Online.uploadTune(tune, authTokenPanel, content, null);
|
||||
}
|
||||
});
|
||||
content.add(upload);
|
||||
}
|
||||
|
||||
public JPanel getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package com.rusefi.ui;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.NamedThreadFactory;
|
||||
import com.rusefi.io.stream.PCanIoStream;
|
||||
import com.rusefi.tools.CANConnectorStartup;
|
||||
import com.rusefi.core.ui.FrameHelper;
|
||||
import com.rusefi.ui.util.UiUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
|
||||
public class PcanConnectorUI {
|
||||
private static final Logging log = getLogging(PcanConnectorUI.class);
|
||||
|
||||
public static void show() {
|
||||
FrameHelper frame = new FrameHelper(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(new JLabel("Running PCAN connector for TS"), BorderLayout.NORTH);
|
||||
JTextArea logTextArea = new JTextArea();
|
||||
panel.add(logTextArea, BorderLayout.CENTER);
|
||||
|
||||
StatusConsumer statusConsumer = string -> SwingUtilities.invokeLater(() -> {
|
||||
log.info(string);
|
||||
logTextArea.append(string + "\r\n");
|
||||
UiUtils.trueLayout(logTextArea);
|
||||
});
|
||||
|
||||
new NamedThreadFactory("PCAN-connector").newThread(() -> {
|
||||
PCanIoStream stream = PCanIoStream.createStream(statusConsumer);
|
||||
try {
|
||||
if (stream != null)
|
||||
CANConnectorStartup.start(stream, statusConsumer);
|
||||
} catch (IOException e) {
|
||||
statusConsumer.append("Error " + e);
|
||||
}
|
||||
}).start();
|
||||
|
||||
frame.showFrame(panel);
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package com.rusefi.ui;
|
||||
|
||||
import org.putgemin.VerticalFlowLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Andrey Belomutskiy, (c) 2013-2020
|
||||
*/
|
||||
public class SensorsLiveDataPane {
|
||||
/**
|
||||
* this is the panel we expose to the outside world
|
||||
*/
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
|
||||
public SensorsLiveDataPane(UIContext uiContext) {
|
||||
JPanel vertical = new JPanel(new VerticalFlowLayout());
|
||||
|
||||
|
||||
JScrollPane scroll = new JScrollPane(vertical, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
content.add(scroll, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
public JPanel getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.rusefi.PaneSettings;
|
|||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.core.MessagesCentral;
|
||||
import com.rusefi.io.ConnectionStatusLogic;
|
||||
import com.rusefi.ui.LogDownloader;
|
||||
import com.rusefi.ui.UIContext;
|
||||
|
||||
import javax.swing.*;
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.opensr5.ini.field.ScalarIniField;
|
|||
import com.rusefi.TestHelper;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.tcp.BinaryProtocolProxy;
|
||||
import com.rusefi.io.tcp.BinaryProtocolServer;
|
||||
import com.rusefi.io.tcp.TcpConnector;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
|
@ -82,40 +81,4 @@ public class TcpCommunicationIntegrationTest {
|
|||
clientManager.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxy() throws InterruptedException, IOException {
|
||||
ConfigurationImage serverImage = TestHelper.prepareImage(239, TestHelper.createIniField(Fields.CYLINDERSCOUNT));
|
||||
int controllerPort = 6102;
|
||||
|
||||
// create virtual controller
|
||||
TestHelper.createVirtualController(controllerPort, serverImage, new BinaryProtocolServer.Context());
|
||||
int proxyPort = 6103;
|
||||
|
||||
|
||||
// connect proxy to virtual controller
|
||||
IoStream targetEcuSocket = TestHelper.connectToLocalhost(controllerPort);
|
||||
final AtomicInteger relayCommandCounter = new AtomicInteger();
|
||||
BinaryProtocolProxy.createProxy(targetEcuSocket, proxyPort, () -> relayCommandCounter.incrementAndGet(),
|
||||
StatusConsumer.ANONYMOUS);
|
||||
|
||||
CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1);
|
||||
|
||||
// connect to proxy and read virtual controller through it
|
||||
LinkManager clientManager = new LinkManager();
|
||||
clientManager.startAndConnect(TcpConnector.LOCALHOST + ":" + proxyPort, new ConnectionStateListener() {
|
||||
@Override
|
||||
public void onConnectionEstablished() {
|
||||
connectionEstablishedCountDownLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(String s) {
|
||||
System.out.println("Failed");
|
||||
}
|
||||
});
|
||||
assertLatch("Connection established", connectionEstablishedCountDownLatch);
|
||||
|
||||
clientManager.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package com.rusefi.test;
|
||||
|
||||
import com.rusefi.Histograms;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* 12/18/13
|
||||
*/
|
||||
public class HistogramsTest {
|
||||
|
||||
@Test
|
||||
public void testHistogram() {
|
||||
Histograms h = new Histograms();
|
||||
|
||||
|
||||
String key = "hello";
|
||||
Histograms.ValueType type = Histograms.ValueType.INVOCATION;
|
||||
h.addValue(type, key, 30);
|
||||
|
||||
|
||||
Histograms.LocalStats ls = h.local_stats.get();
|
||||
|
||||
Histograms.StatisticsGroup sg = ls.stats.get(type);
|
||||
|
||||
Histograms.Statistics data = sg.data.get(key);
|
||||
|
||||
assertEquals(40, data.histogram.length);
|
||||
|
||||
|
||||
assertEquals(80, h.getIndex(239));
|
||||
assertEquals(223, h.getIndex(239239));
|
||||
assertEquals(364, h.getIndex(239239239));
|
||||
|
||||
|
||||
Random r = new Random();
|
||||
for (int i = 0; i < 2342334; i++)
|
||||
h.addValue(type, key, r.nextInt());
|
||||
|
||||
|
||||
assertEquals(640, data.histogram.length);
|
||||
|
||||
|
||||
System.out.println(h.dumpStats());
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue