Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.bidib.jbidibc.gateway.GatewaySerialBidib Maven / Gradle / Ivy
package org.bidib.jbidibc.gateway;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.bidib.jbidibc.core.BidibInterface;
import org.bidib.jbidibc.core.BidibMessageProcessor;
import org.bidib.jbidibc.core.exception.InvalidLibraryException;
import org.bidib.jbidibc.core.helpers.Context;
import org.bidib.jbidibc.core.node.NodeRegistry;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.serial.AbstractSerialBidib;
import org.bidib.jbidibc.serial.SerialMessageEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.serialpundit.core.SerialComException;
import com.serialpundit.serial.ISerialComDataListener;
import com.serialpundit.serial.ISerialComEventListener;
import com.serialpundit.serial.SerialComLineEvent;
import com.serialpundit.serial.SerialComManager;
import com.serialpundit.serial.SerialComManager.BAUDRATE;
import com.serialpundit.serial.SerialComManager.DATABITS;
import com.serialpundit.serial.SerialComManager.FLOWCONTROL;
import com.serialpundit.serial.SerialComManager.PARITY;
import com.serialpundit.serial.SerialComManager.STOPBITS;
public class GatewaySerialBidib extends AbstractSerialBidib {
private static final Logger LOGGER = LoggerFactory.getLogger(GatewaySerialBidib.class);
private static final Logger MSG_RAW_LOGGER = LoggerFactory.getLogger("RAW");
private SerialComManager scm;
private long handle = -1;
private ISerialComDataListener dataListener;
private ISerialComEventListener eventListener;
private boolean addEventListener = false;
private boolean useHardwareFlowControl = false;
private GatewaySerialBidib() {
}
/**
* Get a new initialized instance of GatewaySerialBidib.
*
* @return the instance of ScmSerialBidib
*/
public static BidibInterface createInstance() {
LOGGER.info("Create new instance of GatewaySerialBidib.");
GatewaySerialBidib instance = new GatewaySerialBidib();
instance.initialize();
return instance;
}
@Override
protected BidibMessageProcessor createMessageReceiver(NodeRegistry nodeRegistry) {
LOGGER.info("Set the ignoreMissingTransferListeners flag on the NodeRegistry.");
nodeRegistry.setIgnoreMissingTransferListeners(true);
return new GatewayResponseReceiver(nodeRegistry);
}
@Override
public void close() {
// close the port if available
if (scm != null) {
LOGGER.info("Close the port, handle: {}", handle);
long start = System.currentTimeMillis();
// unregister data listener
LOGGER.info("Unregister data listener: {}", dataListener);
if (dataListener != null && handle > 0) {
try {
scm.unregisterDataListener(handle, dataListener);
}
catch (SerialComException ex) {
LOGGER.warn("Unregister dataListener failed.", ex);
}
try {
Thread.sleep(200);
}
catch (InterruptedException ex) {
LOGGER.warn("Sleep after unregister data listener failed.", ex);
}
}
dataListener = null;
// unregister line event listener
if (eventListener != null && handle > 0) {
LOGGER.info("Unregister line event listener.");
try {
scm.unregisterLineEventListener(handle, eventListener);
}
catch (SerialComException ex) {
LOGGER.warn("Unregister lineEventListener failed.", ex);
}
try {
Thread.sleep(200);
}
catch (InterruptedException ex) {
LOGGER.warn("Sleep after unregister line event listener failed.", ex);
}
}
eventListener = null;
final BidibMessageProcessor serialMessageReceiver = getMessageReceiver();
stopReceiverAndQueues(serialMessageReceiver);
if (handle > 0) {
try {
LOGGER.info("Close the COM port: {}", handle);
// port.close();
scm.closeComPort(handle);
}
catch (Exception e) {
LOGGER.warn("Close port failed.", e);
}
}
else {
LOGGER.info("Don't close port because handle is not valid.");
}
long end = System.currentTimeMillis();
LOGGER.info("Closed the port. duration: {}", end - start);
setConnected(false);
scm = null;
handle = -1;
cleanupAfterClose(serialMessageReceiver);
}
else {
LOGGER.info("No port to close available.");
}
}
@Override
public List getPortIdentifiers() {
List portIdentifiers = new ArrayList();
try {
String tempDir = System.getProperty("java.io.tmpdir");
File temp = new File(tempDir, "jbidibc");
// temp.mkdirs();
if (scm == null) {
LOGGER.info("Create the scm instance.");
scm = new SerialComManager("scm", temp.getAbsolutePath(), true, false);
}
String[] ports = scm.listAvailableComPorts();
for (String portIdentifier : ports) {
portIdentifiers.add(portIdentifier);
}
}
catch (UnsatisfiedLinkError ule) {
LOGGER.warn("Get comm port identifiers failed.", ule);
throw new InvalidLibraryException(ule.getMessage(), ule.getCause());
}
catch (Error error) {
LOGGER.warn("Get comm port identifiers failed.", error);
throw new RuntimeException(error.getMessage(), error.getCause());
}
catch (IOException ex) {
LOGGER.warn("Get comm port identifiers failed.", ex);
throw new InvalidLibraryException(ex.getMessage(), ex.getCause());
}
return portIdentifiers;
}
@Override
protected boolean isImplAvaiable() {
return (scm != null);
}
private BAUDRATE getBaudRate(int baudRate) {
for (BAUDRATE br : BAUDRATE.values()) {
if (br.getValue() == baudRate) {
return br;
}
}
return BAUDRATE.B115200;
}
@Override
protected void internalOpen(String portName, final Context context) throws Exception {
final BidibMessageProcessor serialMessageReceiver = getMessageReceiver();
String tempDir = System.getProperty("java.io.tmpdir");
File temp = new File(tempDir, "jbidibc");
scm = new SerialComManager("scm", temp.getAbsolutePath(), true, false);
LOGGER.info("Open port with portName: {}", portName);
// open the port
handle = scm.openComPort(portName, true, true, true);
LOGGER.info("Opened serial port, handle: {}", handle);
if (useHardwareFlowControl) {
scm.configureComPortControl(handle, FLOWCONTROL.RTS_CTS, 'x', 'x', false, true);
}
else {
scm.configureComPortControl(handle, FLOWCONTROL.NONE, 'x', 'x', false, true);
}
Integer baudRate = context.get("serial.baudrate", Integer.class, Integer.valueOf(115200));
LOGGER.info("Open port with baudRate: {}", baudRate);
BAUDRATE scmBaudRate = getBaudRate(baudRate);
scm.configureComPortData(handle, DATABITS.DB_8, STOPBITS.SB_1, PARITY.P_NONE, scmBaudRate, 0);
startReceiverAndQueues(serialMessageReceiver, context);
setConnected(true);
// add event listener
if (addEventListener) {
eventListener = new ISerialComEventListener() {
@Override
public void onNewSerialEvent(SerialComLineEvent lineEvent) {
LOGGER.error("eventCTS : {}, eventDSR : {}", lineEvent.getCTS(), lineEvent.getDSR());
}
};
scm.registerLineEventListener(handle, eventListener);
}
dataListener = new ISerialComDataListener() {
@Override
public void onNewSerialDataAvailable(final byte[] data) {
// TODO remove the logger
MSG_RAW_LOGGER.info("<<<< Serial data available, len: {}", data.length);
receive(data, data.length);
// TODO remove the logger
MSG_RAW_LOGGER.info("<<<< Serial data received.");
}
@Override
public void onDataListenerError(int errorNum) {
LOGGER.error("Data listener notified an error: {}", errorNum);
if (isConnected()) {
LOGGER.info("Close the port.");
setConnected(false);
if (dataListener != null) {
try {
LOGGER.info("Unregister data listener.");
scm.unregisterDataListener(handle, dataListener);
dataListener = null;
}
catch (Exception ex) {
LOGGER.warn("Unregister data listener after error detection failed.", ex);
}
}
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
LOGGER.info("Error detected. Close the port.");
if (dataListener != null) {
try {
scm.unregisterDataListener(handle, dataListener);
dataListener = null;
}
catch (Exception ex) {
LOGGER.warn("Unregister data listener after error detection failed.", ex);
}
}
if (eventListener != null) {
try {
scm.unregisterLineEventListener(handle, eventListener);
eventListener = null;
}
catch (Exception ex) {
LOGGER.warn("Unregister event listener after error detection failed.", ex);
}
}
try {
close();
}
catch (Exception ex) {
LOGGER.warn("Close scm port failed.", ex);
}
}
});
t1.start();
}
else {
LOGGER.info("Port is closed.");
}
}
};
LOGGER.info("Registering data listener fro handle: {}.", handle);
// register data listener for this port
scm.registerDataListener(handle, dataListener);
LOGGER.info("Registered data listener.");
if (useHardwareFlowControl) {
// Activate DTR
// try {
// LOGGER.info("Activate DTR.");
//
// scm.setDTR(handle, true); // pin 1 in DIN8; on main connector, this is DTR
// }
// catch (Exception e) {
// LOGGER.warn("Set DTR true failed.", e);
// }
try {
LOGGER.info("Activate RTS.");
scm.setRTS(handle, true);
}
catch (Exception e) {
LOGGER.warn("Set RTS true failed.", e);
}
}
}
@Override
public boolean isOpened() {
boolean isOpened = (handle > 0);
return isOpened;
}
private ByteArrayOutputStream output = new ByteArrayOutputStream(100);
@Override
protected void sendData(ByteArrayOutputStream data) {
if (handle > 0 && data != null) {
byte[] bytes = data.toByteArray();
try {
if (MSG_RAW_LOGGER.isInfoEnabled()) {
MSG_RAW_LOGGER.info(">> [{}] - {}", bytes.length, ByteUtils.bytesToHex(bytes));
}
// MSG_OUTPUTSTREAM_LOGGER.info(">>>>");
output.reset();
SerialMessageEncoder.encodeMessage(data, output);
int sent = scm.writeBytes(handle, output.toByteArray());
if (sent == 0) {
MSG_RAW_LOGGER.warn(">> sent bytes: {}", sent);
LOGGER.error("The message has not been sent to handle: {}, message: {}", handle,
ByteUtils.bytesToHex(bytes));
throw new RuntimeException("Write message to output failed: " + ByteUtils.bytesToHex(bytes));
}
else {
MSG_RAW_LOGGER.info(">> sent bytes: {}", sent);
}
}
catch (Exception ex) {
LOGGER.warn("Send message to output stream failed: [{}] - {}", bytes.length,
ByteUtils.bytesToHex(bytes), ex);
throw new RuntimeException("Send message to output stream failed: " + ByteUtils.bytesToHex(bytes), ex);
}
finally {
output.reset();
}
}
}
}