You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2022/11/04 15:45:30 UTC
[plc4x] 01/03: feat(plc-simulator/bacnet): bacnet simulator is now able to return a valid hard coded response
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit c1f1700932da9b2f0db523a8a2f10b1e85bde6e8
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Fri Nov 4 14:27:55 2022 +0100
feat(plc-simulator/bacnet): bacnet simulator is now able to return a valid hard coded response
---
.../server/bacnet/BacnetServerModule.java | 59 +++++----
.../bacnet/protocol/BacnetServerAdapter.java | 137 +++++++++++++++++++--
2 files changed, 153 insertions(+), 43 deletions(-)
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java
index f5a504778..8c69793ed 100644
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java
+++ b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java
@@ -19,35 +19,28 @@
package org.apache.plc4x.simulator.server.bacnet;
import io.netty.bootstrap.Bootstrap;
-import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
-import io.netty.channel.*;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.codec.DatagramPacketDecoder;
-import io.netty.handler.codec.DatagramPacketEncoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.MessageToMessageEncoder;
import org.apache.plc4x.java.bacnetip.BacNetIpDriver;
import org.apache.plc4x.java.bacnetip.readwrite.BVLC;
import org.apache.plc4x.java.bacnetip.readwrite.BacnetConstants;
-import org.apache.plc4x.java.cbus.CBusDriver;
-import org.apache.plc4x.java.cbus.readwrite.CBusConstants;
-import org.apache.plc4x.java.cbus.readwrite.CBusMessage;
-import org.apache.plc4x.java.cbus.readwrite.CBusOptions;
-import org.apache.plc4x.java.cbus.readwrite.RequestContext;
import org.apache.plc4x.java.spi.connection.GeneratedProtocolMessageCodec;
import org.apache.plc4x.java.spi.generation.ByteOrder;
-import org.apache.plc4x.java.spi.generation.ReadBufferByteBased;
-import org.apache.plc4x.java.spi.generation.WriteBufferByteBased;
import org.apache.plc4x.simulator.PlcSimulatorConfig;
import org.apache.plc4x.simulator.exceptions.SimulatorException;
import org.apache.plc4x.simulator.model.Context;
import org.apache.plc4x.simulator.server.ServerModule;
import org.apache.plc4x.simulator.server.bacnet.protocol.BacnetServerAdapter;
+import java.net.InetSocketAddress;
import java.util.List;
public class BacnetServerModule implements ServerModule {
@@ -88,24 +81,28 @@ public class BacnetServerModule implements ServerModule {
.handler(new ChannelInitializer<NioDatagramChannel>() {
@Override
public void initChannel(NioDatagramChannel channel) {
- ChannelPipeline pipeline = channel.pipeline();
- pipeline.addLast(new DatagramPacketDecoder(new MessageToMessageDecoder<ByteBuf>() {
- @Override
- protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
- byte[] bytes = new byte[msg.readableBytes()];
- msg.readBytes(bytes);
- out.add(BVLC.staticParse(new ReadBufferByteBased(bytes)));
- }
- }));
- pipeline.addLast(new DatagramPacketEncoder<>(new MessageToMessageEncoder<BVLC>() {
- @Override
- protected void encode(ChannelHandlerContext ctx, BVLC msg, List<Object> out) throws Exception {
- WriteBufferByteBased writeBuffer = new WriteBufferByteBased(msg.getLengthInBytes());
- msg.serialize(writeBuffer);
- out.add(writeBuffer.getBytes());
- }
- }));
- pipeline.addLast(new BacnetServerAdapter(context));
+ channel.pipeline()
+ .addLast(new MessageToMessageDecoder<DatagramPacket>() {
+ @Override
+ protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
+ final ByteBuf content = msg.content();
+ out.add(content.retain());
+ }
+ })
+ .addLast(new MessageToMessageEncoder<ByteBuf>() {
+ @Override
+ protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
+ msg.retain();
+ // TODO: find better way to implement request response
+ out.add(new DatagramPacket(msg, new InetSocketAddress("192.168.178.102", 47808)));
+ }
+ })
+ .addLast(new GeneratedProtocolMessageCodec<>(BVLC.class,
+ BVLC::staticParse, ByteOrder.BIG_ENDIAN,
+ null,
+ new BacNetIpDriver.ByteLengthEstimator(),
+ new BacNetIpDriver.CorruptPackageCleaner()))
+ .addLast(new BacnetServerAdapter(context));
}
});
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java
index 39da9a67a..92dfe3fb4 100644
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java
+++ b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java
@@ -18,24 +18,16 @@
*/
package org.apache.plc4x.simulator.server.bacnet.protocol;
+import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.apache.plc4x.java.bacnetip.readwrite.BVLC;
-import org.apache.plc4x.java.cbus.readwrite.*;
+import org.apache.plc4x.java.bacnetip.readwrite.Error;
+import org.apache.plc4x.java.bacnetip.readwrite.*;
+import org.apache.plc4x.java.bacnetip.readwrite.utils.StaticHelper;
import org.apache.plc4x.simulator.model.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
public class BacnetServerAdapter extends ChannelInboundHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(BacnetServerAdapter.class);
@@ -57,8 +49,129 @@ public class BacnetServerAdapter extends ChannelInboundHandlerAdapter {
if (!(msg instanceof BVLC)) {
return;
}
+ BVLC bvlc = (BVLC) msg;
+ if (!(bvlc instanceof BVLCOriginalUnicastNPDU)) {
+ // TODO: write useful error
+ ctx.writeAndFlush(new BVLCOriginalUnicastNPDU(
+ new NPDU(
+ (short) 1,
+ new NPDUControl(true, false, false, false, NPDUNetworkPriority.NORMAL_MESSAGE),
+ 0,
+ (short) 0,
+ null,
+ 0,
+ (short) 0,
+ null,
+ (short) 0,
+ null,
+ new APDUError(
+ (short) 0,
+ BACnetConfirmedServiceChoice.READ_PROPERTY,
+ new BACnetErrorGeneral(new Error(
+ new ErrorClassTagged(new BACnetTagHeader((byte) 0, TagClass.APPLICATION_TAGS, (byte) 1, (short) 0, (short) 0, 0, 0L), ErrorClass.COMMUNICATION, 0, (short) 0, TagClass.APPLICATION_TAGS),
+ new ErrorCodeTagged(new BACnetTagHeader((byte) 0, TagClass.APPLICATION_TAGS, (byte) 1, (short) 0, (short) 0, 0, 0L), ErrorCode.VENDOR_PROPRIETARY_VALUE, 0, (short) 0, TagClass.APPLICATION_TAGS)
+ )),
+ 0
+ ),
+ 0
+ ),
+ 0
+ )).addListener((ChannelFutureListener) f -> {
+ if (!f.isSuccess()) {
+ f.cause().printStackTrace();
+ }
+ });
+ return;
+ }
+ BVLCOriginalUnicastNPDU bvlcOriginalUnicastNPDU = (BVLCOriginalUnicastNPDU) bvlc;
+ // TODO: get messageTypeField
+ APDU apdu = bvlcOriginalUnicastNPDU.getNpdu().getApdu();
+ if (!(apdu instanceof APDUConfirmedRequest)) {
+ // TODO: write useful error
+ ctx.writeAndFlush(new BVLCOriginalUnicastNPDU(
+ new NPDU(
+ (short) 1,
+ new NPDUControl(true, false, false, false, NPDUNetworkPriority.NORMAL_MESSAGE),
+ 0,
+ (short) 0,
+ null,
+ 0,
+ (short) 0,
+ null,
+ (short) 0,
+ null,
+ new APDUError(
+ (short) 0,
+ BACnetConfirmedServiceChoice.READ_PROPERTY,
+ new BACnetErrorGeneral(new Error(
+ new ErrorClassTagged(new BACnetTagHeader((byte) 0, TagClass.APPLICATION_TAGS, (byte) 1, (short) 0, (short) 0, 0, 0L), ErrorClass.COMMUNICATION, 0, (short) 0, TagClass.APPLICATION_TAGS),
+ new ErrorCodeTagged(new BACnetTagHeader((byte) 0, TagClass.APPLICATION_TAGS, (byte) 1, (short) 0, (short) 0, 0, 0L), ErrorCode.VENDOR_PROPRIETARY_VALUE, 0, (short) 0, TagClass.APPLICATION_TAGS)
+ )),
+ 0
+ ),
+ 0
+ ),
+ 0
+ )).addListener((ChannelFutureListener) f -> {
+ if (!f.isSuccess()) {
+ f.cause().printStackTrace();
+ }
+ });
+ return;
+ }
+ APDUConfirmedRequest apduConfirmedRequest = (APDUConfirmedRequest) apdu;
// TODO: implement me
+ System.out.println("Got request");
System.out.println(msg);
+ BVLCOriginalUnicastNPDU response = new BVLCOriginalUnicastNPDU(
+ new NPDU(
+ (short) 1,
+ new NPDUControl(false, false, false, false, NPDUNetworkPriority.NORMAL_MESSAGE),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ new APDUComplexAck(
+ false,
+ false,
+ apduConfirmedRequest.getInvokeId(),
+ null,
+ null,
+ new BACnetServiceAckReadProperty(
+ StaticHelper.createBACnetContextTagObjectIdentifier((byte) 0, 2, 1L),
+ StaticHelper.createBACnetPropertyIdentifierTagged((byte) 1, 85),
+ null,
+ new BACnetConstructedDataAnalogValuePresentValue(
+ StaticHelper.createBACnetOpeningTag((short) 3),
+ StaticHelper.createBACnetTagHeaderBalanced(true, (short) 3, 3L),
+ StaticHelper.createBACnetClosingTag((short) 3),
+ StaticHelper.createBACnetApplicationTagReal(101L),
+ null,
+ null
+ ),
+ 0L
+ ),
+ null,
+ null,
+ 0
+ ),
+ 0
+ ),
+ 0
+ );
+ System.out.println("Writing response");
+ System.out.println(response);
+ ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> {
+ if (!f.isSuccess()) {
+ f.cause().printStackTrace();
+ }
+ });
+ ;
}
+
}