You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/08/11 14:32:06 UTC
[plc4x] branch netty-serial-nio updated: Some improvements.
This is an automated email from the ASF dual-hosted git repository.
jfeinauer pushed a commit to branch netty-serial-nio
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/netty-serial-nio by this push:
new acfbbf4 Some improvements.
acfbbf4 is described below
commit acfbbf411032ef5880533bd0f2d1b4ad2542e1d6
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sun Aug 11 16:31:59 2019 +0200
Some improvements.
---
.../plc4x/java/base/connection/SerialChannel.java | 41 +++++++++++++++-------
.../java/base/connection/SerialChannelFactory.java | 25 +++++++++----
.../java/base/connection/SerialChannelHandler.java | 17 +++++++--
.../java/base/connection/SerialSocketAddress.java | 28 +++++++++++++++
.../base/connection/SerialChannelFactoryTest.java | 33 ++++++++++++++++-
5 files changed, 120 insertions(+), 24 deletions(-)
diff --git a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannel.java b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannel.java
index 9c48cf8..aa7a32f 100644
--- a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannel.java
+++ b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannel.java
@@ -19,9 +19,7 @@
package org.apache.plc4x.java.base.connection;
-import com.fazecast.jSerialComm.SerialPort;
-import com.fazecast.jSerialComm.SerialPortDataListener;
-import com.fazecast.jSerialComm.SerialPortEvent;
+import com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages_ca;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.AbstractChannel;
@@ -37,7 +35,6 @@ import io.netty.channel.EventLoop;
import io.netty.channel.FileRegion;
import io.netty.channel.RecvByteBufAllocator;
import io.netty.channel.VoidChannelPromise;
-import io.netty.channel.jsc.JSerialCommDeviceAddress;
import io.netty.channel.nio.AbstractNioByteChannel;
import io.netty.channel.nio.AbstractNioChannel;
import io.netty.channel.nio.NioEventLoop;
@@ -163,14 +160,18 @@ public class SerialChannel extends AbstractNioByteChannel implements DuplexChann
@Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
this.remoteAddress = remoteAddress;
- if (!(remoteAddress instanceof JSerialCommDeviceAddress)) {
- throw new IllegalArgumentException("Socket Address has to be of type " + JSerialCommDeviceAddress.class);
+ if (!(remoteAddress instanceof SerialSocketAddress)) {
+ throw new IllegalArgumentException("Socket Address has to be of type " + SerialSocketAddress.class);
}
- logger.debug("Connecting to Socket Address '{}'", ((JSerialCommDeviceAddress) remoteAddress).value());
+ logger.debug("Connecting to Socket Address '{}'", ((SerialSocketAddress) remoteAddress).getIdentifier());
try {
- // TODO this should take port from remote Adress
- comPort = SerialChannelHandler.DummyHandler.INSTANCE;
+ // A bit hacky but to make a Test Connection start the String with TEST
+ if (((SerialSocketAddress) remoteAddress).getIdentifier().startsWith("TEST")) {
+ comPort = SerialChannelHandler.DummyHandler.INSTANCE;
+ } else {
+ comPort = new SerialChannelHandler.SerialPortHandler(remoteAddress);
+ }
logger.debug("Using Com Port {}, trying to open port", comPort.getIdentifier());
if (comPort.open()) {
logger.debug("Opened port successful to {}", comPort.getIdentifier());
@@ -189,6 +190,12 @@ public class SerialChannel extends AbstractNioByteChannel implements DuplexChann
}
}
+ @Override protected void doClose() throws Exception {
+ if (this.comPort != null) {
+ this.comPort.close();
+ }
+ }
+
@Override
protected void doFinishConnect() throws Exception {
throw new NotImplementedException("");
@@ -383,6 +390,7 @@ public class SerialChannel extends AbstractNioByteChannel implements DuplexChann
@Override
public void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
+ SerialChannel.this.remoteAddress = remoteAddress;
eventLoop().execute(() -> {
try {
final boolean sucess = doConnect(remoteAddress, localAddress);
@@ -392,7 +400,7 @@ public class SerialChannel extends AbstractNioByteChannel implements DuplexChann
// Finally, close the promise
promise.setSuccess();
} else {
- promise.setFailure(new RuntimeException("Unable to open the com port " + remoteAddress.toString()));
+ promise.setFailure(new RuntimeException("Unable to open the com port '" + ((SerialSocketAddress) remoteAddress).getIdentifier() + "'"));
}
} catch (Exception e) {
promise.setFailure(e);
@@ -407,9 +415,16 @@ public class SerialChannel extends AbstractNioByteChannel implements DuplexChann
@Override
public void close(ChannelPromise promise) {
- logger.debug("Closing the Serial Port '{}'", this.remoteAddress());
- // TODO this should close the Serial Port
- throw new NotImplementedException("");
+ logger.debug("Closing the Serial Port '{}'", ((SerialSocketAddress) SerialChannel.this.remoteAddress).getIdentifier());
+ eventLoop().execute(() -> {
+ try {
+ doClose();
+ promise.setSuccess();
+ } catch (Exception e) {
+ logger.warn("Unable to close the connection", e);
+ promise.setFailure(e);
+ }
+ });
}
@Override
diff --git a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java
index 27b84c3..2e0e422 100644
--- a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java
+++ b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelFactory.java
@@ -22,13 +22,12 @@ import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.jsc.JSerialCommChannel;
-import io.netty.channel.jsc.JSerialCommDeviceAddress;
import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.oio.OioEventLoopGroup;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import java.net.SocketAddress;
import java.util.concurrent.Executor;
public class SerialChannelFactory implements ChannelFactory {
@@ -42,15 +41,27 @@ public class SerialChannelFactory implements ChannelFactory {
@Override
public Channel createChannel(ChannelHandler channelHandler)
throws PlcConnectionException {
- JSerialCommDeviceAddress address = new JSerialCommDeviceAddress(serialPort);
+ SocketAddress address = new SerialSocketAddress(serialPort);
try {
Bootstrap bootstrap = new Bootstrap();
- bootstrap.group(new NioEventLoopGroup(0, (Executor)null, new SerialSelectorProvider()));
+ final NioEventLoopGroup eventLoop = new NioEventLoopGroup(0, (Executor) null, new SerialSelectorProvider());
+ bootstrap.group(eventLoop);
bootstrap.channel(SerialChannel.class);
bootstrap.handler(channelHandler);
// Start the client.
- ChannelFuture f = bootstrap.connect(address).sync();
+ ChannelFuture f = bootstrap.connect(address);
+ f.addListener(new GenericFutureListener<Future<? super Void>>() {
+ @Override public void operationComplete(Future<? super Void> future) throws Exception {
+ if (future.isSuccess()) {
+ System.out.println("Connection sucesfull!");
+ } else {
+ System.out.println("Connection not sucessfull: " + future.cause().getMessage());
+ eventLoop.shutdownGracefully();
+ }
+ }
+ });
+ f.sync();
f.awaitUninterruptibly();
// Wait till the session is finished initializing.
return f.channel();
diff --git a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelHandler.java b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelHandler.java
index e001458..6773602 100644
--- a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelHandler.java
+++ b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialChannelHandler.java
@@ -6,6 +6,7 @@ import com.fazecast.jSerialComm.SerialPortEvent;
import io.netty.channel.jsc.JSerialCommDeviceAddress;
import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
/**
* This is a wrapper mostly for testing {@link SerialChannel}, @{@link SerialPollingSelector},
@@ -30,6 +31,8 @@ public abstract class SerialChannelHandler {
*/
abstract void registerSelectionKey(SerialSelectionKey selectionKey);
+ public abstract void close();
+
public static class DummyHandler extends SerialChannelHandler {
public static final DummyHandler INSTANCE = new DummyHandler(null);
@@ -52,6 +55,10 @@ public abstract class SerialChannelHandler {
this.selectionKey = selectionKey;
}
+ @Override public void close() {
+ // NOOP
+ }
+
public void fireEvent(int readyOp) {
((SerialPollingSelector) this.selectionKey.selector())
.addEvent(new SerialPollingSelector.SelectorEvent(this.selectionKey, readyOp));
@@ -65,7 +72,7 @@ public abstract class SerialChannelHandler {
public SerialPortHandler(SocketAddress address) {
super(address);
- comPort = SerialPort.getCommPort(((JSerialCommDeviceAddress) address).value());
+ comPort = SerialPort.getCommPort(((SerialSocketAddress) address).getIdentifier());
}
@Override public boolean open() {
@@ -85,10 +92,14 @@ public abstract class SerialChannelHandler {
@Override
public void serialEvent(SerialPortEvent event) {
- // TODO notify the selector that something happens
- selectionKey.selector().wakeup();
+ ((SerialPollingSelector) selectionKey.selector())
+ .addEvent(new SerialPollingSelector.SelectorEvent(selectionKey, SelectionKey.OP_READ));
}
});
}
+
+ @Override public void close() {
+ this.comPort.closePort();
+ }
}
}
diff --git a/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialSocketAddress.java b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialSocketAddress.java
new file mode 100644
index 0000000..fc8fdea
--- /dev/null
+++ b/plc4j/protocols/driver-bases/serial/src/main/java/org/apache/plc4x/java/base/connection/SerialSocketAddress.java
@@ -0,0 +1,28 @@
+package org.apache.plc4x.java.base.connection;
+
+import java.net.SocketAddress;
+import java.util.Objects;
+
+public class SerialSocketAddress extends SocketAddress {
+
+ private final String identifier;
+
+ public SerialSocketAddress(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SerialSocketAddress that = (SerialSocketAddress) o;
+ return Objects.equals(identifier, that.identifier);
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(identifier);
+ }
+}
diff --git a/plc4j/protocols/driver-bases/serial/src/test/java/org/apache/plc4x/java/base/connection/SerialChannelFactoryTest.java b/plc4j/protocols/driver-bases/serial/src/test/java/org/apache/plc4x/java/base/connection/SerialChannelFactoryTest.java
index b333cda..3bea440 100644
--- a/plc4j/protocols/driver-bases/serial/src/test/java/org/apache/plc4x/java/base/connection/SerialChannelFactoryTest.java
+++ b/plc4j/protocols/driver-bases/serial/src/test/java/org/apache/plc4x/java/base/connection/SerialChannelFactoryTest.java
@@ -19,11 +19,13 @@
package org.apache.plc4x.java.base.connection;
+import com.fazecast.jSerialComm.SerialPort;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
+import io.netty.channel.jsc.JSerialCommDeviceAddress;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.ByteToMessageCodec;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
@@ -46,8 +48,18 @@ public class SerialChannelFactoryTest {
private static final Logger logger = LoggerFactory.getLogger(SerialChannelFactoryTest.class);
@Test
+ public void showAllPorts() {
+ System.out.println("-------------------------------------");
+ System.out.println(" Starting to Display all Serial Ports");
+ System.out.println("-------------------------------------");
+ for (SerialPort commPort : SerialPort.getCommPorts()) {
+ System.out.println(commPort.getDescriptivePortName());
+ }
+ }
+
+ @Test
public void createChannel() throws PlcConnectionException, InterruptedException, UnknownHostException {
- SerialChannelFactory asdf = new SerialChannelFactory("asdf");
+ SerialChannelFactory asdf = new SerialChannelFactory("TEST-port1");
final TcpSocketChannelFactory factory = new TcpSocketChannelFactory(InetAddress.getLocalHost(), 5432);
final Channel channel = asdf.createChannel(new ChannelInitializer<SerialChannel>() {
@Override protected void initChannel(SerialChannel ch) throws Exception {
@@ -63,6 +75,25 @@ public class SerialChannelFactoryTest {
channel.close().sync();
}
+ @Test
+ public void createChannelToSBL() throws PlcConnectionException, InterruptedException, UnknownHostException {
+ SerialChannelFactory asdf = new SerialChannelFactory("JBLFlip3-SPPDev");
+ Channel channel = null;
+ try {
+ channel = asdf.createChannel(new ChannelInitializer<SerialChannel>() {
+ @Override protected void initChannel(SerialChannel ch) throws Exception {
+ ch.pipeline().addLast(new DemoCodec());
+ }
+ });
+ } catch (Exception e) {
+ // do nothing
+ }
+ Thread.sleep(5_000);
+ if (channel != null) {
+ channel.close().sync();
+ }
+ }
+
private static class DemoCodec extends ByteToMessageCodec<Object> {
@Override protected void encode(ChannelHandlerContext channelHandlerContext, Object o, ByteBuf byteBuf) throws Exception {
// do nothing here