org.bidib.jibidibc.jserialcomm.JSerialCommSerialConnector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jbidibc-jserialcomm Show documentation
Show all versions of jbidibc-jserialcomm Show documentation
jBiDiB jbidibc jserialcomm POM
package org.bidib.jibidibc.jserialcomm;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.bidib.jbidibc.core.BidibLibrary;
import org.bidib.jbidibc.core.MessageReceiver;
import org.bidib.jbidibc.core.base.AbstractBaseBidib;
import org.bidib.jbidibc.core.exception.PortNotFoundException;
import org.bidib.jbidibc.core.exception.PortNotOpenedException;
import org.bidib.jbidibc.core.helpers.Context;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.serial.LineStatusListener;
import org.bidib.jbidibc.serial.SerialMessageEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
public class JSerialCommSerialConnector extends AbstractBaseBidib {
private static final Logger LOGGER = LoggerFactory.getLogger(JSerialCommSerialConnector.class);
private static final Logger MSG_RAW_LOGGER = LoggerFactory.getLogger("RAW");
private SerialPort comPort;
private MessageReceiver messageReceiver;
private LineStatusListener lineStatusListener;
/**
* @return the messageReceiver
*/
public MessageReceiver getMessageReceiver() {
return messageReceiver;
}
/**
* @param messageReceiver
* the messageReceiver to set
*/
public void setMessageReceiver(MessageReceiver messageReceiver) {
this.messageReceiver = messageReceiver;
}
/**
* @return the lineStatusListener
*/
public LineStatusListener getLineStatusListener() {
return lineStatusListener;
}
/**
* @param lineStatusListener
* the lineStatusListener to set
*/
public void setLineStatusListener(LineStatusListener lineStatusListener) {
this.lineStatusListener = lineStatusListener;
}
protected boolean isImplAvaiable() {
return (comPort != null);
}
@Override
public boolean isOpened() {
return comPort != null && comPort.isOpen();
}
@Override
protected void internalOpen(String portName, Context context) throws PortNotFoundException, PortNotOpenedException {
super.internalOpen(portName, context);
Boolean useHardwareFlowControl = context.get("serial.useHardwareFlowControl", Boolean.class, Boolean.TRUE);
LOGGER.info("Open port with portName: {}, useHardwareFlowControl: {}", portName, useHardwareFlowControl);
final MessageReceiver serialMessageReceiver = getMessageReceiver();
comPort = SerialPort.getCommPort(portName);
if (useHardwareFlowControl) {
comPort.setFlowControl(SerialPort.FLOW_CONTROL_RTS_ENABLED | SerialPort.FLOW_CONTROL_CTS_ENABLED);
}
else {
comPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);
}
Integer baudRate = context.get("serial.baudrate", Integer.class, Integer.valueOf(115200));
LOGGER.info("Open port with baudRate: {}", baudRate);
comPort.setComPortParameters(baudRate, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
boolean opened = comPort.openPort();
if (!opened) {
LOGGER.warn("Port was not opened: {}", portName);
throw new PortNotOpenedException("Port was not opened: " + portName, "unknown");
}
startReceiverAndQueues(serialMessageReceiver, context);
setConnected(true);
comPort.addDataListener(new SerialPortDataListener() {
@Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
@Override
public void serialEvent(SerialPortEvent event) {
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE)
return;
byte[] data = new byte[comPort.bytesAvailable()];
int numRead = comPort.readBytes(data, data.length);
LOGGER.debug("Read bytes count: {}", numRead);
receive(data, data.length);
}
});
if (useHardwareFlowControl) {
// Activate DTR
try {
LOGGER.info("Activate DTR.");
comPort.setDTR(); // pin 1 in DIN8; on main connector, this is DTR
}
catch (Exception e) {
LOGGER.warn("Set DTR true failed.", e);
}
}
}
@Override
public boolean close() {
if (comPort != null) {
long start = System.currentTimeMillis();
LOGGER.info("Close the port, comPort: {}", comPort);
comPort.removeDataListener();
comPort.closePort();
final MessageReceiver serialMessageReceiver = getMessageReceiver();
stopReceiverAndQueues(serialMessageReceiver);
long end = System.currentTimeMillis();
LOGGER.info("Closed the port. duration: {}", end - start);
fireCtsChanged(false);
setConnected(false);
comPort = null;
return true;
}
else {
LOGGER.info("No port to close available.");
}
return false;
}
public List getPortIdentifiers() {
List portIdentifiers = new ArrayList<>();
for (SerialPort serialPort : SerialPort.getCommPorts()) {
portIdentifiers.add(serialPort.getSystemPortName());
}
return portIdentifiers;
}
protected void fireCtsChanged(boolean ready) {
LOGGER.info("CTS has changed, ready: {}", ready);
// signal changed line status to the bidib implementation
if (lineStatusListener != null) {
lineStatusListener.notifyLineStatusChanged(ready);
}
}
private ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream(100);
@Override
protected void sendData(ByteArrayOutputStream data) {
if (comPort != null && data != null) {
try {
if (!firstPacketSent) {
LOGGER.info("Send initial sequence.");
try {
byte[] initialSequence = new byte[] { (byte) BidibLibrary.BIDIB_PKT_MAGIC };
if (MSG_RAW_LOGGER.isInfoEnabled()) {
MSG_RAW_LOGGER
.info(">> [{}] - {}", initialSequence.length, ByteUtils.bytesToHex(initialSequence));
}
comPort.writeBytes(initialSequence, initialSequence.length);
Thread.sleep(10);
if (MSG_RAW_LOGGER.isInfoEnabled()) {
MSG_RAW_LOGGER
.info(">> [{}] - {}", initialSequence.length, ByteUtils.bytesToHex(initialSequence));
}
comPort.writeBytes(initialSequence, initialSequence.length);
firstPacketSent = true;
LOGGER.info("Send initial sequence passed.");
}
catch (Exception ex) {
LOGGER.warn("Send initial sequence failed.", ex);
}
}
sendBuffer.reset();
SerialMessageEncoder.encodeMessage(data, sendBuffer);
if (MSG_RAW_LOGGER.isInfoEnabled()) {
MSG_RAW_LOGGER
.info(">> [{}] - {}", sendBuffer.toByteArray().length,
ByteUtils.bytesToHex(sendBuffer.toByteArray()));
}
int sent = comPort.writeBytes(sendBuffer.toByteArray(), sendBuffer.size());
if (sent == 0) {
MSG_RAW_LOGGER.warn(">> sent bytes: {}", sent);
byte[] bytes = data.toByteArray();
LOGGER
.error("The message has not been sent to comPort: {}, message: {}", comPort,
ByteUtils.bytesToHex(bytes));
throw new RuntimeException("Write message to output failed: " + ByteUtils.bytesToHex(bytes));
}
else {
MSG_RAW_LOGGER.info(">> sent bytes: {}", sent);
}
}
catch (IOException ex) {
byte[] bytes = data.toByteArray();
LOGGER
.warn("Send message to output stream failed: [{}] - {}", bytes.length, ByteUtils.bytesToHex(bytes));
throw new RuntimeException("Send message to output stream failed: " + ByteUtils.bytesToHex(bytes), ex);
}
finally {
sendBuffer.reset();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy