|
|
@ -2,12 +2,17 @@ package com.my.graphiteDigesterBg.diframe.connection; |
|
|
|
import com.fazecast.jSerialComm.SerialPort; |
|
|
|
import com.fazecast.jSerialComm.SerialPortDataListener; |
|
|
|
import com.fazecast.jSerialComm.SerialPortEvent; |
|
|
|
import com.my.graphiteDigesterBg.diframe.DiCommandRequest; |
|
|
|
import com.my.graphiteDigesterBg.diframe.DiDevice; |
|
|
|
import com.my.graphiteDigesterBg.diframe.DiDeviceConnection; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
import org.springframework.core.env.Environment; |
|
|
|
import java.nio.ByteBuffer; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Timer; |
|
|
|
import java.util.TimerTask; |
|
|
|
public class DiConSerialPort implements DiDeviceConnection { |
|
|
|
// logger |
|
|
|
public static final Logger LOG = LoggerFactory.getLogger(DiConSerialPort.class); |
|
|
@ -15,6 +20,19 @@ public class DiConSerialPort implements DiDeviceConnection { |
|
|
|
private DiDevice device; |
|
|
|
// serial port connection |
|
|
|
private SerialPort connection; |
|
|
|
// requests |
|
|
|
private final List<DiCommandRequest> requests; |
|
|
|
// received data |
|
|
|
private ByteBuffer receivedData; |
|
|
|
// received data timer |
|
|
|
private Timer receivedDataTimer; |
|
|
|
|
|
|
|
// constructor |
|
|
|
public DiConSerialPort() { |
|
|
|
this.requests = new ArrayList<>(); |
|
|
|
this.receivedData = null; |
|
|
|
this.receivedDataTimer = null; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setDevice(DiDevice device) { |
|
|
@ -55,18 +73,83 @@ public class DiConSerialPort implements DiDeviceConnection { |
|
|
|
|
|
|
|
// handle on data |
|
|
|
private void handleOnData(SerialPortEvent serialPortEvent) { |
|
|
|
if ( null != this.receivedDataTimer ) { |
|
|
|
this.receivedDataTimer.cancel(); |
|
|
|
this.receivedDataTimer = null; |
|
|
|
} |
|
|
|
|
|
|
|
if ( null == this.receivedData ) { |
|
|
|
this.receivedData = ByteBuffer.allocate(0); |
|
|
|
} |
|
|
|
byte[] data = serialPortEvent.getReceivedData(); |
|
|
|
System.out.println("Received data of size: " + data.length); |
|
|
|
for (byte b : data) { |
|
|
|
System.out.print((char)b); |
|
|
|
ByteBuffer newBuffer = ByteBuffer.allocate(this.receivedData.capacity() + data.length); |
|
|
|
newBuffer.put(this.receivedData).put(data); |
|
|
|
this.receivedData = newBuffer; |
|
|
|
|
|
|
|
TimerTask timerTask = new TimerTask() { |
|
|
|
@Override |
|
|
|
public void run() { |
|
|
|
DiConSerialPort.this.handleOnDataTimeout(); |
|
|
|
} |
|
|
|
}; |
|
|
|
this.receivedDataTimer = new Timer(); |
|
|
|
Integer frameTimeout = this.device.getEnv().getProperty("device.connection.frameTimeout", Integer.class, 1000); |
|
|
|
this.receivedDataTimer.schedule(timerTask, frameTimeout); |
|
|
|
} |
|
|
|
|
|
|
|
// handle on data timeout |
|
|
|
private void handleOnDataTimeout() { |
|
|
|
String mode = this.device.getEnv().getProperty("device.connection.mode"); |
|
|
|
if ( "binary".equals(mode) ) { |
|
|
|
this.handleOnDataTimeoutForBinaryMode(); |
|
|
|
} else { |
|
|
|
throw new RuntimeException("Unknown command mode: " + mode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// handle on data timeout for binary mode |
|
|
|
private void handleOnDataTimeoutForBinaryMode() { |
|
|
|
byte messageType = this.receivedData.get(5); |
|
|
|
if ( 0x01 == messageType ) { |
|
|
|
this.handleOnDataTimeoutForBinaryModeAckMessage(); |
|
|
|
} else { |
|
|
|
throw new RuntimeException("unknown message type"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// handle on data timeout for binary mode ack message |
|
|
|
private void handleOnDataTimeoutForBinaryModeAckMessage() { |
|
|
|
short messageId = this.receivedData.getShort(0); |
|
|
|
DiCommandRequest request = null; |
|
|
|
for ( DiCommandRequest requestItem : this.requests ) { |
|
|
|
if ( requestItem.id == messageId ) { |
|
|
|
request = requestItem; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if ( null == request ) { |
|
|
|
throw new RuntimeException("unknown message id: " + messageId); |
|
|
|
} |
|
|
|
request.response = this.receivedData; |
|
|
|
request.isResponseReceived = true; |
|
|
|
this.receivedData = null; |
|
|
|
synchronized ( request ) { |
|
|
|
request.notify(); |
|
|
|
} |
|
|
|
System.out.println("\n"); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public ByteBuffer call(ByteBuffer parameter) { |
|
|
|
byte[] data = parameter.array(); |
|
|
|
public void call(DiCommandRequest request) { |
|
|
|
this.requests.add(request); |
|
|
|
byte[] data = request.parameter.array(); |
|
|
|
this.connection.writeBytes(data, data.length); |
|
|
|
return null; |
|
|
|
synchronized ( request ) { |
|
|
|
try { |
|
|
|
request.wait(); |
|
|
|
} catch (InterruptedException e) { |
|
|
|
throw new RuntimeException(e); |
|
|
|
} |
|
|
|
} |
|
|
|
LOG.info("Command response received: {}", request.response); |
|
|
|
} |
|
|
|
} |