You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by ld...@apache.org on 2022/08/02 00:25:58 UTC
[plc4x] 01/01: Prototype of ADS symbol scanner.
This is an automated email from the ASF dual-hosted git repository.
ldywicki pushed a commit to branch splatch/ads-symbol-discovery
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 7f1f52fd4f52fa0072882747d6e3e9eb28faad5f
Author: Łukasz Dywicki <lu...@code-house.org>
AuthorDate: Tue Aug 2 02:25:29 2022 +0200
Prototype of ADS symbol scanner.
Signed-off-by: Łukasz Dywicki <lu...@code-house.org>
---
.../org/apache/plc4x/protocol/ads/Scanner.java | 151 +++++++++++++++++++++
1 file changed, 151 insertions(+)
diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/Scanner.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/Scanner.java
new file mode 100644
index 000000000..4c55e0d66
--- /dev/null
+++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/Scanner.java
@@ -0,0 +1,151 @@
+/*
+ * 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
+ *
+ * https://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.protocol.ads;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.ads.readwrite.AdsDataType;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
+import org.apache.plc4x.java.api.value.PlcValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Scanner {
+
+ private static Logger logger = LoggerFactory.getLogger(Scanner.class);
+
+ public static void main(String[] args) throws Exception {
+ if (args.length != 5) {
+ System.out.println("Usage: java -jar ... [ip -address] [target ams] [target ams port] [source ams] [source ams port]");
+ System.out.println("All fields are required. AMS route must be created beforehand.");
+ System.out.println("Example parameter sequence:");
+ System.out.println(" 192.168.2.251 39.42.54.209.1.1 851 192.168.2.232.1.1 851");
+ return;
+ }
+
+ String targetIp = args[0];
+ String targetAmsId = args[1];
+ String targetAmsPort = args[2];
+
+ String sourceAmsId = args[3];
+ String sourceAmsPort = args[4];
+
+ String connectionString = "ads:tcp://" + targetIp + "?targetAmsNetId=" + targetAmsId + "&targetAmsPort=" + targetAmsPort + "&sourceAmsNetId=" + sourceAmsId + "&sourceAmsPort=" + sourceAmsPort;
+ System.out.println("Launching connection " + connectionString);
+
+ // Establish a connection to the plc using the url provided as first argument
+ try (PlcConnection plcConnection = new PlcDriverManager().getConnection(connectionString)) {
+ PlcConnectionMetadata metadata = plcConnection.getMetadata();
+ System.out.println("read: " + metadata.canRead());
+ System.out.println("write: " + metadata.canWrite());
+
+ // read symbols
+ System.out.println("Reading symbol info");
+ PlcReadRequest.Builder readRequestBuilder = plcConnection.readRequestBuilder();
+ PlcReadRequest request = readRequestBuilder.addItem("SYM_UPLOADINFO2", "0xf00f/0x0:SINT[24]").build();
+ PlcReadResponse rsp = request.execute().get();
+ ByteBuffer buffer = toBuffer(rsp, "SYM_UPLOADINFO2");
+
+ //System.err.println("first answer " + Hex.dump(buffer.array()));
+ int symbolAnswerSize = buffer.getInt(4);
+ System.out.println("Expecting symbol table containing " + symbolAnswerSize + " bytes");
+
+ request = plcConnection.readRequestBuilder().addItem("SYM_UPLOAD", "0xf00b/0x0:SINT[" + symbolAnswerSize + "]").build();
+ PlcReadResponse readResponse = request.execute().get();
+ buffer = toBuffer(readResponse, "SYM_UPLOAD");
+ //System.err.println("second answer " + Hex.dump(buffer.array()));
+
+ System.out.println(" | PLC4X Field | Hex | ");
+ System.out.println("##### | Query Syntax | Index | Offset | Type | Name | Size (B) | Type | Flag | Comment");
+ System.out.println("------+------------------------------+-----------+-----------+----------+----------------------------------------+----------+------+------+");
+
+ int index = 0;
+ int pos = 0;
+
+ List<String> supportedTypes = Arrays.stream(AdsDataType.values())
+ .map(AdsDataType::name)
+ .map(String::toUpperCase)
+ .map(s -> s + '\0')
+ .collect(Collectors.toList());
+
+ while (buffer.remaining() > 0) {
+ int sectionLen = buffer.getInt();
+
+ int group = buffer.getInt();
+ int offset = buffer.getInt();
+ int symbolSize = buffer.getInt();
+ int symbolType = buffer.getInt();
+ int symbolFlags = buffer.getInt();
+ short nameLength = (short) (buffer.getShort() + 1);
+ short typeLength = (short) (buffer.getShort() + 1);
+ short commentLength = (short) (buffer.getShort() + 1);
+
+ String name= slice(buffer, nameLength);
+ String type = slice(buffer, typeLength);
+ String comment = slice(buffer, commentLength);
+
+ if (supportedTypes.contains(type.toUpperCase())) {
+ System.out.printf("%5s |", index++);
+ System.out.printf("%30s |", "0x" + Integer.toHexString(group) + "/0x" + Integer.toHexString(offset) + ":" + type);
+ System.out.printf("%10s |", "0x" + Integer.toHexString(group));
+ System.out.printf("%10s |", "0x" + Integer.toHexString(offset));
+ System.out.printf("%10s |", type);
+ System.out.printf("%-40s |", name);
+ System.out.printf("%9s |", symbolSize);
+ System.out.printf("%5s |", symbolType);
+ System.out.printf("%5s |", symbolFlags);
+ System.out.println(comment);
+ }
+
+ pos += sectionLen;
+ buffer.position(pos);
+
+ }
+ }
+ }
+
+ private static String slice(ByteBuffer buffer, short length) {
+ byte[] arr = new byte[length];
+ buffer.get(arr);
+ return new String(arr, StandardCharsets.UTF_8);
+ }
+
+ private static ByteBuffer toBuffer(PlcReadResponse rsp, String fieldName) {
+ System.out.println(rsp.getFieldNames() + " " + rsp.getField(fieldName) + " " + rsp.getResponseCode(fieldName));
+ List<PlcValue> symbols = (List<PlcValue>) rsp.getObject(fieldName);
+ ByteBuffer buffer = ByteBuffer.allocate(symbols.size()).order(ByteOrder.LITTLE_ENDIAN);
+
+ for (PlcValue byteVal : symbols) {
+ byte byteValue = byteVal.getByte();
+ //System.err.println("data " + Hex.encodeHexString(new byte[] {byteValue}));
+ buffer.put(byteValue);
+ }
+ buffer.rewind();
+ return buffer;
+ }
+
+}