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/12/18 10:56:26 UTC

[plc4x] branch next-gen-core updated: Refactored Interface out of Plc4XProtocol

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

jfeinauer pushed a commit to branch next-gen-core
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/next-gen-core by this push:
     new dcd2108  Refactored Interface out of Plc4XProtocol
dcd2108 is described below

commit dcd2108325b04f233ce3ad7eefd82d27477a03d8
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Wed Dec 18 11:55:36 2019 +0100

    Refactored Interface out of Plc4XProtocol
---
 .../plc4x/java/s7/netty/Plc4XS7Protocol.java       |  22 +++-
 .../java/s7/readwrite/connection/S7Connection.java |  12 ++-
 .../s7/readwrite/protocol/Plc4xProtocolBase.java   |  47 +++++++++
 .../readwrite/protocol/Plc4xProtocolContext.java   | 116 +++++++++++++++++++++
 .../{Plc4xProtocol.java => Plc4xS7Protocol.java}   | 113 ++++++++------------
 5 files changed, 234 insertions(+), 76 deletions(-)

diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
index 6c789dd..859db9f 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java
@@ -20,7 +20,9 @@ package org.apache.plc4x.java.s7.netty;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
+import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.plc4x.java.api.exceptions.*;
@@ -30,7 +32,6 @@ import org.apache.plc4x.java.api.messages.PlcResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.model.PlcField;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
-import org.apache.plc4x.java.base.PlcMessageToMessageCodec;
 import org.apache.plc4x.java.base.events.ConnectedEvent;
 import org.apache.plc4x.java.base.messages.*;
 import org.apache.plc4x.java.base.messages.items.*;
@@ -50,6 +51,7 @@ import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.lang.reflect.Array;
+import java.lang.reflect.Field;
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
@@ -58,7 +60,6 @@ import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -73,12 +74,13 @@ import java.util.stream.IntStream;
  * When a {@link S7ResponseMessage} is received it takes the existing request container from its Map and finishes
  * the {@link PlcRequestContainer}s future with the {@link PlcResponse}.
  */
-public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequestContainer> {
+public class Plc4XS7Protocol extends io.netty.handler.codec.MessageToMessageCodec<S7Message, PlcRequestContainer> {
     private static final Logger logger = LoggerFactory.getLogger( Plc4XS7Protocol.class );
 
     private static final AtomicInteger tpduGenerator = new AtomicInteger(10);
 
     private Map<Short, PlcRequestContainer> requests;
+    private volatile ChannelHandler prevChannelHandler = null;
 
     public Plc4XS7Protocol() {
         this.requests = new HashMap<>();
@@ -841,4 +843,18 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ
         return dec + (incomingByte & 0x0f);
     }
 
+    protected ChannelHandler getPrevChannelHandler(ChannelHandlerContext ctx) {
+        if(prevChannelHandler == null) {
+            try {
+                Field prevField = FieldUtils.getField(ctx.getClass(), "prev", true);
+                if(prevField != null) {
+                    ChannelHandlerContext prevContext = (ChannelHandlerContext) prevField.get(ctx);
+                    prevChannelHandler = prevContext.handler();
+                }
+            } catch(Exception e) {
+                logger.error("Error accessing field 'prev'", e);
+            }
+        }
+        return prevChannelHandler;
+    }
 }
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java
index 8616533..712538e 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7Connection.java
@@ -29,7 +29,10 @@ import org.apache.plc4x.java.base.connection.NettyPlcConnection;
 import org.apache.plc4x.java.base.events.ConnectEvent;
 import org.apache.plc4x.java.base.events.ConnectedEvent;
 import org.apache.plc4x.java.base.messages.*;
-import org.apache.plc4x.java.s7.readwrite.protocol.Plc4xProtocol;
+import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
+import org.apache.plc4x.java.s7.readwrite.protocol.Plc4xProtocolBase;
+import org.apache.plc4x.java.s7.readwrite.protocol.Plc4xProtocolContext;
+import org.apache.plc4x.java.s7.readwrite.protocol.Plc4xS7Protocol;
 import org.apache.plc4x.java.s7.readwrite.protocol.S7Protocol;
 import org.apache.plc4x.java.s7.readwrite.types.COTPTpduSize;
 import org.apache.plc4x.java.s7.readwrite.types.DeviceGroup;
@@ -154,8 +157,11 @@ public class S7Connection extends NettyPlcConnection implements PlcReader, PlcWr
                     }
                 });
                 pipeline.addLast(new S7Protocol());
-                pipeline.addLast(new Plc4xProtocol(callingTsapId, calledTsapId, tpduSize,
-                    maxAmqCaller, maxAmqCallee, controllerType));
+                Plc4xProtocolBase<TPKTPacket> plc4xS7Protocol = new Plc4xS7Protocol(callingTsapId, calledTsapId, tpduSize,
+                    maxAmqCaller, maxAmqCallee, controllerType);
+                Plc4xProtocolContext<TPKTPacket> context = plc4xS7Protocol.getContext();
+                pipeline.addLast(context);
+                context.setPipeline(pipeline);
             }
         };
     }
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocolBase.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocolBase.java
new file mode 100644
index 0000000..a69768f
--- /dev/null
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocolBase.java
@@ -0,0 +1,47 @@
+/*
+ * 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.s7.readwrite.protocol;
+
+import org.apache.plc4x.java.base.messages.PlcRequestContainer;
+import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
+
+import java.util.function.Consumer;
+
+public abstract class Plc4xProtocolBase<T> {
+
+    protected final Plc4xProtocolContext<T> context;
+
+    public Plc4xProtocolBase(Class<T> clazz) {
+        // TODO create here?
+        this.context = new Plc4xProtocolContext<T>(this, clazz);
+    }
+
+    public Plc4xProtocolContext<T> getContext() {
+        return context;
+    }
+
+    public void onConnect() {
+        // Intentionally do nothing here
+    }
+
+    protected abstract void encode(PlcRequestContainer msg, Consumer<T> sendHandler) throws Exception;
+
+    protected abstract void decode(T msg) throws Exception;
+}
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocolContext.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocolContext.java
new file mode 100644
index 0000000..60036d6
--- /dev/null
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocolContext.java
@@ -0,0 +1,116 @@
+/*
+ * 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.s7.readwrite.protocol;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPipeline;
+import io.netty.handler.codec.MessageToMessageCodec;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.plc4x.java.base.events.ConnectEvent;
+import org.apache.plc4x.java.base.events.ConnectedEvent;
+import org.apache.plc4x.java.base.messages.PlcRequestContainer;
+import org.apache.plc4x.java.s7.readwrite.events.IsoTPConnectedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class Plc4xProtocolContext<T> extends MessageToMessageCodec<T, PlcRequestContainer> {
+
+    private static final Logger logger = LoggerFactory.getLogger(Plc4xProtocolContext.class);
+
+    private final Plc4xProtocolBase<T> parent;
+    private volatile ChannelHandler prevChannelHandler = null;
+    private ChannelPipeline pipeline;
+
+    // VERY DIRTY
+    private Consumer<Object> handler;
+
+    public Plc4xProtocolContext(Plc4xProtocolBase<T> parent, Class<T> clazz) {
+        super(clazz, PlcRequestContainer.class);
+        this.parent = parent;
+    }
+
+
+    @Override protected void encode(ChannelHandlerContext channelHandlerContext, PlcRequestContainer plcRequestContainer, List<Object> list) throws Exception {
+        logger.info("Encoding {}", plcRequestContainer);
+        parent.encode(plcRequestContainer, o -> list.add(o));
+    }
+
+    @Override protected void decode(ChannelHandlerContext channelHandlerContext, T t, List<Object> list) throws Exception {
+        logger.info("Decoding {}", t);
+        parent.decode(t);
+    }
+
+    public void send(T packet) {
+        logger.info("Sending {}", packet);
+        pipeline.writeAndFlush(packet);
+    }
+
+    public void fireConnected() {
+        logger.info("Firing Connected!");
+        pipeline.fireUserEventTriggered(new ConnectedEvent());
+    }
+
+    /**
+     * If the S7 protocol layer is used over Iso TP, then after receiving a {@link IsoTPConnectedEvent} the
+     * corresponding S7 setup communication message has to be sent in order to negotiate the S7 protocol layer.
+     *
+     * @param ctx the current protocol layers context
+     * @param evt the event
+     * @throws Exception throws an exception if something goes wrong internally
+     */
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        // If the connection has just been established, start setting up the connection
+        // by sending a connection request to the plc.
+        if (evt instanceof ConnectEvent) {
+            this.parent.onConnect();
+        } else {
+            super.userEventTriggered(ctx, evt);
+        }
+    }
+
+    protected ChannelHandler getPrevChannelHandler(ChannelHandlerContext ctx) {
+        if (prevChannelHandler == null) {
+            try {
+                Field prevField = FieldUtils.getField(ctx.getClass(), "prev", true);
+                if (prevField != null) {
+                    ChannelHandlerContext prevContext = (ChannelHandlerContext) prevField.get(ctx);
+                    prevChannelHandler = prevContext.handler();
+                }
+            } catch (Exception e) {
+                logger.error("Error accessing field 'prev'", e);
+            }
+        }
+        return prevChannelHandler;
+    }
+
+    public void setPipeline(ChannelPipeline pipeline) {
+        this.pipeline = pipeline;
+    }
+
+    public ChannelPipeline getPipeline() {
+        return pipeline;
+    }
+}
diff --git a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocol.java b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java
similarity index 86%
rename from sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocol.java
rename to sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java
index d4e2eff..be09319 100644
--- a/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xProtocol.java
+++ b/sandbox/test-java-s7-driver/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/Plc4xS7Protocol.java
@@ -1,21 +1,21 @@
 /*
-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.
-*/
+ * 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.s7.readwrite.protocol;
 
 import io.netty.buffer.ByteBuf;
@@ -28,7 +28,6 @@ import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.PlcResponse;
 import org.apache.plc4x.java.api.model.PlcField;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
-import org.apache.plc4x.java.base.PlcMessageToMessageCodec;
 import org.apache.plc4x.java.base.events.ConnectEvent;
 import org.apache.plc4x.java.base.events.ConnectedEvent;
 import org.apache.plc4x.java.base.messages.*;
@@ -49,13 +48,14 @@ import java.time.LocalTime;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcRequestContainer> {
+public class Plc4xS7Protocol extends Plc4xProtocolBase<TPKTPacket> {
 
-    private static final Logger logger = LoggerFactory.getLogger(Plc4xProtocol.class);
+    private static final Logger logger = LoggerFactory.getLogger(Plc4xS7Protocol.class);
 
     private final int callingTsapId;
     private int calledTsapId;
@@ -68,8 +68,10 @@ public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcReque
     private static final AtomicInteger tpduGenerator = new AtomicInteger(10);
     private final Map<Integer, PlcRequestContainer> requests;
 
-    public Plc4xProtocol(int callingTsapId, int calledTsapId, COTPTpduSize tpduSize,
-                         int maxAmqCaller, int maxAmqCallee, S7ControllerType controllerType) {
+    public Plc4xS7Protocol(int callingTsapId, int calledTsapId, COTPTpduSize tpduSize,
+                           int maxAmqCaller, int maxAmqCallee, S7ControllerType controllerType) {
+        // FIXME REMOVE
+        super(TPKTPacket.class);
         this.callingTsapId = callingTsapId;
         this.calledTsapId = calledTsapId;
         this.cotpTpduSize = tpduSize;
@@ -81,37 +83,22 @@ public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcReque
         requests = new HashMap<>();
     }
 
-    /**
-     * If the S7 protocol layer is used over Iso TP, then after receiving a {@link IsoTPConnectedEvent} the
-     * corresponding S7 setup communication message has to be sent in order to negotiate the S7 protocol layer.
-     *
-     * @param ctx the current protocol layers context
-     * @param evt the event
-     * @throws Exception throws an exception if something goes wrong internally
-     */
     @Override
-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
-        // If the connection has just been established, start setting up the connection
-        // by sending a connection request to the plc.
-        if (evt instanceof ConnectEvent) {
-            logger.debug("ISO Transport Protocol Sending Connection Request");
-            // Open the session on ISO Transport Protocol first.
-            COTPPacketConnectionRequest connectionRequest = new COTPPacketConnectionRequest(
-                new COTPParameter[] {
-                    new COTPParameterCalledTsap(calledTsapId),
-                    new COTPParameterCallingTsap(callingTsapId),
-                    new COTPParameterTpduSize(cotpTpduSize)
-                }, null, (short) 0x0000, (short) 0x000F, COTPProtocolClass.CLASS_0);
-            TPKTPacket packet = new TPKTPacket(connectionRequest);
-            ctx.channel().writeAndFlush(packet);
-        }
-        else {
-            super.userEventTriggered(ctx, evt);
-        }
+    public void onConnect() {
+        logger.debug("ISO Transport Protocol Sending Connection Request");
+        // Open the session on ISO Transport Protocol first.
+        COTPPacketConnectionRequest connectionRequest = new COTPPacketConnectionRequest(
+            new COTPParameter[] {
+                new COTPParameterCalledTsap(calledTsapId),
+                new COTPParameterCallingTsap(callingTsapId),
+                new COTPParameterTpduSize(cotpTpduSize)
+            }, null, (short) 0x0000, (short) 0x000F, COTPProtocolClass.CLASS_0);
+        TPKTPacket packet = new TPKTPacket(connectionRequest);
+        context.send(packet);
     }
 
     @Override
-    protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
+    protected void encode(PlcRequestContainer msg, Consumer<TPKTPacket> sendHandler) throws Exception {
         if(msg.getRequest() instanceof DefaultPlcReadRequest) {
             DefaultPlcReadRequest request = (DefaultPlcReadRequest) msg.getRequest();
             List<S7VarRequestParameterItem> requestItems = new ArrayList<>(request.getNumberOfFields());
@@ -119,32 +106,17 @@ public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcReque
                 requestItems.add(new S7VarRequestParameterItemAddress(toS7Address(field)));
             }
             final int tpduId = tpduGenerator.getAndIncrement();
-            out.add(new TPKTPacket(new COTPPacketData(null,
+            sendHandler.accept(new TPKTPacket(new COTPPacketData(null,
                 new S7MessageRequest(tpduId,
                     new S7ParameterReadVarRequest(requestItems.toArray(new S7VarRequestParameterItem[0])),
                     new S7PayloadReadVarRequest()),
                 true, (short) tpduId)));
             requests.put(tpduId, msg);
-/*        } else if(msg.getRequest() instanceof DefaultPlcWriteRequest) {
-            DefaultPlcWriteRequest request = (DefaultPlcWriteRequest) msg.getRequest();
-            List<S7VarRequestParameterItem> requestItems = new ArrayList<>(request.getNumberOfFields());
-            List<S7VarPayloadDataItem> payloadItems = new ArrayList<>(request.getNumberOfFields());
-            for (PlcField field : request.getFields()) {
-                requestItems.add(new S7VarRequestParameterItemAddress(toS7Address(field)));
-                payloadItems.add((new S7VarPayloadDataItem(0xff, DataTransportSize.BYTE_WORD_DWORD, 1, field)));
-            }
-            final int tpduId = tpduGenerator.getAndIncrement();
-            out.add(new TPKTPacket(new COTPPacketData(null,
-                new S7MessageRequest(3,
-                    new S7ParameterWriteVarRequest(requestItems.toArray(new S7VarRequestParameterItem[0])),
-                    new S7PayloadWriteVarRequest(payloadItems.toArray(new S7VarPayloadDataItem[0]))),
-                true, (short) 0)));
-            requests.put((short) tpduId, msg);*/
         }
     }
 
     @Override
-    protected void decode(ChannelHandlerContext ctx, TPKTPacket msg, List<Object> out) throws Exception {
+    protected void decode(TPKTPacket msg) throws Exception {
         if((msg == null) || (msg.getPayload() == null)) {
             return;
         }
@@ -174,7 +146,7 @@ public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcReque
                 new S7PayloadSetupCommunication());
             COTPPacketData cotpPacketData = new COTPPacketData(null, s7Message, true, (short) 1);
             TPKTPacket tpktPacket = new TPKTPacket(cotpPacketData);
-            ctx.channel().writeAndFlush(tpktPacket);
+            context.send(tpktPacket);
         }
 
         else if(msg.getPayload() instanceof COTPPacketData) {
@@ -200,10 +172,11 @@ public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcReque
                         }));
                         COTPPacketData cotpPacketData = new COTPPacketData(null, identifyRemoteMessage, true, (short) 2);
                         TPKTPacket tpktPacket = new TPKTPacket(cotpPacketData);
-                        ctx.channel().writeAndFlush(tpktPacket);
+                        context.send(tpktPacket);
                     } else {
                         // Send an event that connection setup is complete.
-                        ctx.channel().pipeline().fireUserEventTriggered(new ConnectedEvent());
+                        context.fireConnected();
+
                     }
                 } else if (parameter instanceof S7ParameterReadVarResponse) {
                     final PlcRequestContainer requestContainer = requests.remove(s7MessageResponse.getTpduReference());
@@ -228,7 +201,7 @@ public class Plc4xProtocol extends PlcMessageToMessageCodec<TPKTPacket, PlcReque
                                     controllerType = lookupControllerType(articleNumber);
 
                                     // Send an event that connection setup is complete.
-                                    ctx.channel().pipeline().fireUserEventTriggered(new ConnectedEvent());
+                                    context.fireConnected();
                                 }
                             }
                         }