This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 05157ad4421a51e1e178bb20f04d28d183553f75
Author: Christofer Dutz <[email protected]>
AuthorDate: Tue Sep 24 09:44:44 2019 +0200

    - Added a new Udp driver base
---
 plc4j/protocols/driver-bases/pom.xml               |   1 +
 plc4j/protocols/driver-bases/{ => udp}/pom.xml     |  47 ++++++---
 .../base/connection/UdpSocketChannelFactory.java   | 110 +++++++++++++++++++++
 3 files changed, 143 insertions(+), 15 deletions(-)

diff --git a/plc4j/protocols/driver-bases/pom.xml 
b/plc4j/protocols/driver-bases/pom.xml
index 0034532..2895a35 100644
--- a/plc4j/protocols/driver-bases/pom.xml
+++ b/plc4j/protocols/driver-bases/pom.xml
@@ -39,6 +39,7 @@
     <module>raw-socket</module>
     <module>serial</module>
     <module>tcp</module>
+    <module>udp</module>
     <module>test</module>
   </modules>
 
diff --git a/plc4j/protocols/driver-bases/pom.xml 
b/plc4j/protocols/driver-bases/udp/pom.xml
similarity index 53%
copy from plc4j/protocols/driver-bases/pom.xml
copy to plc4j/protocols/driver-bases/udp/pom.xml
index 0034532..cb1bc05 100644
--- a/plc4j/protocols/driver-bases/pom.xml
+++ b/plc4j/protocols/driver-bases/udp/pom.xml
@@ -23,23 +23,40 @@
 
   <parent>
     <groupId>org.apache.plc4x</groupId>
-    <artifactId>plc4j-protocols</artifactId>
+    <artifactId>plc4j-protocols-driver-bases</artifactId>
     <version>0.5.0-SNAPSHOT</version>
   </parent>
 
-  <artifactId>plc4j-protocols-driver-bases</artifactId>
-  <packaging>pom</packaging>
-
-  <name>PLC4J: Protocols: Driver-Bases</name>
-  <description>Collection of base-types for implementing different types of 
drivers.</description>
-
-  <modules>
-    <module>base</module>
-    <module>pcap-socket</module>
-    <module>raw-socket</module>
-    <module>serial</module>
-    <module>tcp</module>
-    <module>test</module>
-  </modules>
+  <artifactId>plc4j-protocol-driver-base-udp</artifactId>
+  <name>PLC4J: Protocol: Driver-Base: UDP</name>
+  <description>Base classes needed to implement plc4x drivers based on UDP 
connections.</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-protocol-driver-base</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-api</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-transport</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-common</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
 
 </project>
\ No newline at end of file
diff --git 
a/plc4j/protocols/driver-bases/udp/src/main/java/org/apache/plc4x/java/base/connection/UdpSocketChannelFactory.java
 
b/plc4j/protocols/driver-bases/udp/src/main/java/org/apache/plc4x/java/base/connection/UdpSocketChannelFactory.java
new file mode 100644
index 0000000..942afc4
--- /dev/null
+++ 
b/plc4j/protocols/driver-bases/udp/src/main/java/org/apache/plc4x/java/base/connection/UdpSocketChannelFactory.java
@@ -0,0 +1,110 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.base.connection;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioDatagramChannel;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+public class UdpSocketChannelFactory implements ChannelFactory {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(UdpSocketChannelFactory.class);
+
+    private static final int PING_TIMEOUT_MS = 1_000;
+
+    private final InetAddress address;
+    private final int port;
+
+    public UdpSocketChannelFactory(InetAddress address, int port) {
+        this.address = address;
+        this.port = port;
+    }
+
+    @Override
+    public Channel createChannel(ChannelHandler channelHandler)
+        throws PlcConnectionException {
+        try {
+            final NioEventLoopGroup workerGroup = new NioEventLoopGroup();
+
+            Bootstrap bootstrap = new Bootstrap();
+            bootstrap.group(workerGroup);
+            bootstrap.channel(NioDatagramChannel.class);
+            //bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
+            //bootstrap.option(ChannelOption.TCP_NODELAY, true);
+            // TODO we should use an explicit (configurable?) timeout here
+            // bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000);
+            bootstrap.handler(channelHandler);
+            // Start the client.
+            final ChannelFuture f = bootstrap.connect(address, port);
+            f.addListener(new GenericFutureListener<Future<? super Void>>() {
+                @Override public void operationComplete(Future<? super Void> 
future) throws Exception {
+                    if (!future.isSuccess()) {
+                        logger.info("Unable to connect, shutting down worker 
thread.");
+                        workerGroup.shutdownGracefully();
+                    }
+                }
+            });
+            // Wait for sync
+            f.sync();
+            f.awaitUninterruptibly(); // jf: unsure if we need that
+            // Wait till the session is finished initializing.
+            return f.channel();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new PlcConnectionException("Error creating channel.", e);
+        } catch (Exception e) {
+            throw new PlcConnectionException("Error creating channel.", e);
+        }
+    }
+
+    @Override
+    public void ping() throws PlcException {
+        // TODO: Replace this check with a more accurate one ...
+        InetSocketAddress address = new InetSocketAddress(getAddress(), 
getPort());
+        try (Socket s = new Socket()) {
+            s.connect(address, PING_TIMEOUT_MS);
+            // TODO keep the address for a (timely) next request???
+            s.setReuseAddress(true);
+        } catch (Exception e) {
+            throw new PlcConnectionException("Unable to ping remote host");
+        }
+    }
+
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+}

Reply via email to