You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2019/08/07 08:47:48 UTC

[plc4x] 01/17: DLC-207

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

cdutz pushed a commit to branch feature/implement-df1-driver
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit f93faa0b3cffecb819ec470c0045bfc320225b22
Author: v.emmert <v....@pragmaticminds.de>
AuthorDate: Mon Jul 29 13:32:10 2019 +0200

    DLC-207
    
    DF1 driver prototype
---
 sandbox/test-java-df1-driver/pom.xml               |  21 ++
 .../plc4x/protocol/df1/BenchmarkGeneratedDf1.java  | 225 +++++++++++++++++----
 .../main/resources/protocols/df1/protocol.mspec    | 222 ++++++++++++++++++++
 3 files changed, 431 insertions(+), 37 deletions(-)

diff --git a/sandbox/test-java-df1-driver/pom.xml b/sandbox/test-java-df1-driver/pom.xml
index ccfb11b..3ddc53b 100644
--- a/sandbox/test-java-df1-driver/pom.xml
+++ b/sandbox/test-java-df1-driver/pom.xml
@@ -78,6 +78,27 @@
       <scope>provided</scope>
     </dependency>
 
+  <!--  &lt;!&ndash; https://mvnrepository.com/artifact/org.rxtx/rxtx &ndash;&gt;
+    <dependency>
+      <groupId>org.rxtx</groupId>
+      <artifactId>rxtx</artifactId>
+      <version>2.1.7</version>
+    </dependency>-->
+
+    <dependency>
+      <groupId>com.github.purejavacomm</groupId>
+      <artifactId>purejavacomm</artifactId>
+      <version>1.0.2.RELEASE</version>
+    </dependency>
+
+
+    <!-- https://mvnrepository.com/artifact/com.fazecast/jSerialComm -->
+    <dependency>
+      <groupId>com.fazecast</groupId>
+      <artifactId>jSerialComm</artifactId>
+      <version>2.5.1</version>
+    </dependency>
+
     <dependency>
       <groupId>org.apache.plc4x</groupId>
       <artifactId>plc4x-protocols-df1</artifactId>
diff --git a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
index 0718330..715f983 100644
--- a/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
+++ b/sandbox/test-java-df1-driver/src/main/java/org/apache/plc4x/protocol/df1/BenchmarkGeneratedDf1.java
@@ -17,55 +17,206 @@
  * under the License.
  */
 
-package org.apache.plc4x.protocol.df1;import org.apache.commons.codec.binary.Hex;
+package org.apache.plc4x.protocol.df1;
+
+import com.fazecast.jSerialComm.SerialPort;
+import org.apache.commons.codec.binary.Hex;
 import org.apache.plc4x.java.df1.TPKTPacket;
 import org.apache.plc4x.java.df1.io.TPKTPacketIO;
 import org.apache.plc4x.java.utils.ReadBuffer;
 import org.apache.plc4x.java.utils.WriteBuffer;
+import purejavacomm.CommPortIdentifier;
 
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Arrays;
+import java.util.BitSet;
 
 public class BenchmarkGeneratedDf1 {
 
     public static void main(String[] args) throws Exception {
-        byte[] rData = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
-        long start = System.currentTimeMillis();
-        int numRunsParse = 2000000;
-        TPKTPacketIO tpktPacketIO = new TPKTPacketIO();
-
-        // Benchmark the parsing code
-        TPKTPacket packet = null;
-        for(int i = 0; i < numRunsParse; i++) {
-            ReadBuffer rBuf = new ReadBuffer(rData);
-            packet = tpktPacketIO.parse(rBuf);
-        }
-        long endParsing = System.currentTimeMillis();
-
-        System.out.println("Parsed " + numRunsParse + " packets in " + (endParsing - start) + "ms");
-        System.out.println("That's " + ((float) (endParsing - start) / numRunsParse) + "ms per packet");
-
-        // Benchmark the serializing code
-        int numRunsSerialize = 2000000;
-        byte[] oData = null;
-        for(int i = 0; i < numRunsSerialize; i++) {
-            WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
-            tpktPacketIO.serialize(wBuf, packet);
-            oData = wBuf.getData();
-        }
-        long endSerializing = System.currentTimeMillis();
-
-        System.out.println("Serialized " + numRunsSerialize + " packets in " + (endSerializing - endParsing) + "ms");
-        System.out.println("That's " + ((float) (endSerializing - endParsing) / numRunsSerialize) + "ms per packet");
-        if(!Arrays.equals(rData, oData)) {
-            for(int i = 0; i < rData.length; i++) {
-                if(rData[i] != oData[i]) {
-                    System.out.println("Difference in byte " + i);
-                }
+//        byte[] rData = Hex.decodeHex("0300006702f080320100000001005600000407120a10060001032b84000160120a10020001032b840001a0120a10010001032b840001a9120a10050001032b84000150120a10020001032b84000198120a10040001032b84000140120a10020001032b84000190");
+//        long start = System.currentTimeMillis();
+//        int numRunsParse = 2000000;
+//        TPKTPacketIO tpktPacketIO = new TPKTPacketIO();
+//
+//
+//        CommPortIdentifier id = CommPortIdentifier.getPortIdentifier("");
+//
+//
+//        // Benchmark the parsing code
+//        TPKTPacket packet = null;
+//        for(int i = 0; i < numRunsParse; i++) {
+//            ReadBuffer rBuf = new ReadBuffer(rData);
+//            packet = tpktPacketIO.parse(rBuf);
+//        }
+//        long endParsing = System.currentTimeMillis();
+//
+//        System.out.println("Parsed " + numRunsParse + " packets in " + (endParsing - start) + "ms");
+//        System.out.println("That's " + ((float) (endParsing - start) / numRunsParse) + "ms per packet");
+//
+//        // Benchmark the serializing code
+//        int numRunsSerialize = 2000000;
+//        byte[] oData = null;
+//        for(int i = 0; i < numRunsSerialize; i++) {
+//            WriteBuffer wBuf = new WriteBuffer(packet.getLengthInBytes());
+//            tpktPacketIO.serialize(wBuf, packet);
+//            oData = wBuf.getData();
+//        }
+//        long endSerializing = System.currentTimeMillis();
+//
+//        System.out.println("Serialized " + numRunsSerialize + " packets in " + (endSerializing - endParsing) + "ms");
+//        System.out.println("That's " + ((float) (endSerializing - endParsing) / numRunsSerialize) + "ms per packet");
+//        if(!Arrays.equals(rData, oData)) {
+//            for(int i = 0; i < rData.length; i++) {
+//                if(rData[i] != oData[i]) {
+//                    System.out.println("Difference in byte " + i);
+//                }
+//            }
+//            System.out.println("Not equals");
+//        } else {
+//            System.out.println("Bytes equal");
+//        }
+
+
+//         neu
+
+//        int[] bccmsg = {0x08, 0x09, 0x06, 0x10, 0x10, 0x04, 0x03};
+//        int c_BCC = CalcBCC(bccmsg);
+//        System.out.println("hex: " + Integer.toHexString(c_BCC));
+//        int[] bccmsg2 = {0x08, 0x09, 0x06, 0x02, 0x04, 0x03};
+//        int c_BCC2 = CalcBCC(bccmsg2);
+//        System.out.println("hex: " + Integer.toHexString(c_BCC2));
+//
+//        System.exit(0);
+
+
+        SerialPort comPort = SerialPort.getCommPorts()[0];
+        comPort.openPort();
+
+        comPort.setComPortParameters(19200, 8, SerialPort.ONE_STOP_BIT, SerialPort.NO_PARITY);
+//        comPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
+
+        System.out.print(comPort.getSystemPortName() + " | ");
+        System.out.print(comPort.getPortDescription() + " | ");
+        System.out.print(comPort.getDescriptivePortName() + " | Baud rate: ");
+        System.out.print(comPort.getBaudRate());
+
+//        System.out.println(comPort.getReadTimeout());
+//        System.out.println(comPort.getWriteTimeout());
+
+
+        byte[] c_STX = {0x02};
+        byte[] c_SOH = {0x01};
+        byte[] c_ETX = {0x03};
+        byte[] c_EOT = {0x04};
+        byte[] c_ENQ = {0x05};
+        byte[] c_ACK = {0x06};
+        byte[] c_DLE = {0x10};
+        byte[] c_NAK = {0x0f};
+
+        byte[] c_DST = {0x09};
+        byte[] c_SRC = {0x00};
+        byte[] c_CMD = {0x01};
+        byte[] c_STS = {0x00};
+        byte[] c_TNS = {0x01, 0x00};
+        byte[] c_ADR = {0x11, 0x00};
+        byte[] c_SZE = {0x02};
+//        byte[] c_BCC = {-30};
+
+//        byte[] c_STN = {0x11};
+//        byte[] c_DST = {0x01};
+//        byte[] c_SRC = {0x00};
+//        byte[] c_SZE = {0x0c};
+//        byte[] c_TNS = {0x41, 0x00};
+//        byte[] c_ADR = {0x12, 0x00};
+//        byte[] c_CRC = {-49, 0x40};
+
+
+//        byte[] message = {0x10, 0x01, 0x11, 0x10, 0x02, 0x09, 0x00, 0x01, 0x00, 0x41, 0x00, 0x12, 0x00, 0x0c, 0x10, 0x03}; // halfduplex msg
+//        comPort.writeBytes(message, message.length);
+
+//        byte[] message = {0x10, 0x05, 0x11, -17};         // halfduplex poll
+//        comPort.writeBytes(message, message.length);
+
+
+        comPort.writeBytes(c_DLE, 1);     // fullduplex msg Seite 235
+        comPort.writeBytes(c_STX, 1);
+        comPort.writeBytes(c_DST, 1);
+        comPort.writeBytes(c_SRC, 1);
+        comPort.writeBytes(c_CMD, 1);
+        comPort.writeBytes(c_STS, 1);
+        comPort.writeBytes(c_TNS, 2);
+        comPort.writeBytes(c_ADR, 2);
+        comPort.writeBytes(c_SZE, 1);
+        comPort.writeBytes(c_DLE, 1);
+        comPort.writeBytes(c_ETX, 1);
+
+
+        int[] crcmsg = {c_DST[0], c_SRC[0], c_CMD[0], c_STS[0], c_TNS[0], c_TNS[1], c_ADR[0], c_ADR[1], c_SZE[0], c_ETX[0]}; // fullduplex CRC
+//        int[] crcmsg = {0x11, 0x02, 0x09, 0x00, 0x01, 0x00, 0x41, 0x00, 0x12, 0x00, 0x0c, 0x03}; // halfduplex CRC
+
+        int[] c_CRC = CalcCRC(crcmsg);
+        byte[] crc1 = {(byte)c_CRC[0]};
+        byte[] crc2 = {(byte)c_CRC[1]};
+        comPort.writeBytes(crc1, 1);
+        comPort.writeBytes(crc2, 1);
+
+
+        while (comPort.bytesAvailable() == 0) {
+            Thread.sleep(22); }
+
+        byte[] readBuffer = new byte[comPort.bytesAvailable()];
+        int numRead = comPort.readBytes(readBuffer, readBuffer.length);
+        System.out.println("Read " + numRead + " bytes.");
+
+        for (byte c_RCV : readBuffer) {
+            System.out.print(Integer.toHexString(c_RCV) + " | "); }
+
+        if (numRead > 1) {
+            if (readBuffer[1] != 0x15) {
+                comPort.writeBytes(c_DLE, 1);
+                comPort.writeBytes(c_ACK, 1);
             }
-            System.out.println("Not equals");
-        } else {
-            System.out.println("Bytes equal");
         }
+
+        comPort.closePort();
+
     }
 
+        private static int[] CalcCRC(int[] crcBytes) {
+            int tmp = 0;
+            int crcL, crcR;
+
+            for (int newByte : crcBytes ) {
+                crcL = tmp >> 8;
+                crcR = tmp & 0xFF;
+                tmp = (crcL << 8) + (newByte ^ crcR);
+                for (int j=0; j<8; j++)
+                    if (tmp % 2 == 1) {     // check if LSB shifted out is 1 or 0
+                        tmp = tmp >> 1;
+                        tmp = tmp ^ 0xA001;
+                    } else {
+                        tmp = tmp >> 1;
+                    }
+            }
+
+//            return ((tmp & 0xFF) << 8) + (tmp >> 8);  // returns lowbyte|highbyte as one number, change return to non-array
+
+            int[] tmparray = {(tmp & 0xFF), (tmp >> 8)};
+            return tmparray;
+        }
+
+        private static int CalcBCC(int[] crcBytes) {
+            int tmp = 0;
+            int j = 0;
+
+            for (int newByte : crcBytes) {
+                tmp = tmp + newByte;
+                if (newByte == 0x10) {
+                    j = ++j; }
+            }
+            tmp = tmp - ((j/2) * 0x10);  // get rid of double DLE
+            return ((~tmp) & 0b11111111) + 1;
+        }
 }
diff --git a/sandbox/test-java-s7-driver/src/main/resources/protocols/df1/protocol.mspec b/sandbox/test-java-s7-driver/src/main/resources/protocols/df1/protocol.mspec
new file mode 100644
index 0000000..734216d
--- /dev/null
+++ b/sandbox/test-java-s7-driver/src/main/resources/protocols/df1/protocol.mspec
@@ -0,0 +1,222 @@
+//
+// 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.
+//
+
+////////////////////////////////////////////////////////////////
+// IsoOnTcp/TPKT
+////////////////////////////////////////////////////////////////
+
+[type 'TPKTPacket'
+    [const    uint 8     'protocolId' '0x03']
+    [reserved uint 8     '0x00']
+    [reserved uint 8     '0x00']
+    [implicit uint 16    'len'        'payload.lengthInBytes + 4']
+    [field    COTPPacket 'payload']
+]
+
+////////////////////////////////////////////////////////////////
+// COTP
+////////////////////////////////////////////////////////////////
+
+[discriminatedType 'COTPPacket'
+    [implicit      uint 8 'headerLength' 'lengthInBytes - (payload.lengthInBytes + 1)']
+    [discriminator uint 8 'tpduCode']
+    [typeSwitch 'tpduCode'
+        ['0xF0' COTPPacketData
+            [field bit    'eot']
+            [field uint 7 'tpduRef']
+        ]
+        ['0xE0' COTPPacketConnectionRequest
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+            [field uint 8  'protocolClass']
+        ]
+        ['0xD0' COTPPacketConnectionResponse
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+            [field uint 8  'protocolClass']
+        ]
+        ['0x80' COTPPacketDisconnectRequest
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+            [field uint 8  'protocolClass']
+        ]
+        ['0xC0' COTPPacketDisconnectResponse
+            [field uint 16 'destinationReference']
+            [field uint 16 'sourceReference']
+        ]
+        ['0x70' COTPPacketTpduError
+            [field uint 16 'destinationReference']
+            [field uint 8  'rejectCause']
+        ]
+    ]
+    [arrayField COTPParameter 'parameters' length '(headerLength + 1) - curPos' ['(headerLength + 1) - curPos']]
+    [field      S7Message     'payload']
+]
+
+[discriminatedType 'COTPParameter' [uint 8 'rest']
+    [discriminator uint 8 'parameterType']
+    [typeSwitch 'parameterType'
+        ['0xC0' COTPParameterTpduSize
+            [field uint 8 'tpduSize']
+        ]
+        ['0xC1' COTPParameterCallingTsap
+            [field uint 16 'tsapId']
+        ]
+        ['0xC2' COTPParameterCalledTsap
+            [field uint 16 'tsapId']
+        ]
+        ['0xC3' COTPParameterChecksum
+            [field uint 8 'checksum']
+        ]
+        ['0xE0' COTPParameterDisconnectAdditionalInformation
+            [arrayField uint 8 'data' count 'rest']
+        ]
+    ]
+]
+
+////////////////////////////////////////////////////////////////
+// S7
+////////////////////////////////////////////////////////////////
+
+[discriminatedType 'S7Message'
+    [const         uint 8  'protocolId'      '0x32']
+    [discriminator uint 8  'messageType']
+    [reserved      uint 16 '0x0000']
+    [field         uint 16 'tpduReference']
+    [implicit      uint 16 'parameterLength' 'parameter.lengthInBytes']
+    [implicit      uint 16 'payloadLength'   'payload.lengthInBytes']
+    [typeSwitch 'messageType'
+        ['0x01' S7MessageRequest
+        ]
+        ['0x03' S7MessageResponse
+            [field uint 8 'errorClass']
+            [field uint 8 'errorCode']
+        ]
+        ['0x07' S7MessageUserData
+        ]
+    ]
+    [field S7Parameter 'parameter' ['messageType']]
+    [field S7Payload   'payload'   ['messageType', 'parameter']]
+]
+
+////////////////////////////////////////////////////////////////
+// Parameters
+
+[discriminatedType 'S7Parameter' [uint 8 'messageType']
+    [discriminator uint 8 'parameterType']
+    [typeSwitch 'parameterType','messageType'
+        ['0xF0' S7ParameterSetupCommunication
+            [reserved uint 8  '0x00']
+            [field    uint 16 'maxAmqCaller']
+            [field    uint 16 'maxAmqCallee']
+            [field    uint 16 'pduLength']
+        ]
+        ['0x04','0x01' S7ParameterReadVarRequest
+            [implicit   uint 8                    'numItems' 'COUNT(items)']
+            [arrayField S7VarRequestParameterItem 'items'    count 'numItems']
+        ]
+        ['0x04','0x03' S7ParameterReadVarResponse
+            [field uint 8 'numItems']
+        ]
+        ['0x05','0x01' S7ParameterWriteVarRequest
+            [implicit   uint 8                    'numItems' 'COUNT(items)']
+            [arrayField S7VarRequestParameterItem 'items'    count 'numItems']
+        ]
+        ['0x05','0x03' S7ParameterWriteVarResponse
+            [field uint 8 'numItems']
+        ]
+        ['0x00','0x07' S7ParameterUserData
+            [implicit   uint 8       'numItems' 'COUNT(items)']
+            [arrayField UserDataItem 'items' count 'numItems']
+        ]
+    ]
+]
+
+[discriminatedType 'S7VarRequestParameterItem'
+    [discriminator uint 8 'parameterItemType']
+    [typeSwitch 'parameterItemType'
+        ['0x12' S7VarRequestParameterItemAddress
+            [implicit uint 8    'addressLength' 'address.lengthInBytes']
+            [field    S7Address 'address']
+        ]
+    ]
+]
+
+[discriminatedType 'S7Address'
+    [discriminator uint 8 'addressType']
+    [typeSwitch 'addressType'
+        ['0x10' S7AddressAny
+            [field    uint 8  'transportSize']
+            [field    uint 16 'numberOfElements']
+            [field    uint 16 'dbNumber']
+            [field    uint 8  'area']
+            [reserved uint 5  '0x00']
+            [field    uint 16 'byteAddress']
+            [field    uint 3  'bitAddress']
+        ]
+    ]
+]
+
+// TODO: CPUFunctions still need some love ...
+[discriminatedType 'UserDataItem'
+    [discriminator uint 8 'itemType']
+    [typeSwitch 'itemType'
+        ['0x12' UserDataItemCPUFunctions
+            [implicit      uint 8  'parameterLength' 'lengthInBytes']
+            [field         uint 16 'cpuFunctionType']
+            [field         uint 8  'subFunctionGroup']
+            [field         uint 8  'sequenceNumber']
+            [optionalField uint 8  'dataUnitReferenceNumber' 'parameterLength == 8']
+            [optionalField uint 8  'lastDataUnit' 'parameterLength == 8']
+            [optionalField uint 8  'errorCode' 'parameterLength == 8']
+        ]
+    ]
+]
+
+////////////////////////////////////////////////////////////////
+// Payloads
+
+[discriminatedType 'S7Payload' [uint 8 'messageType', S7Parameter 'parameter']
+    [typeSwitch 'parameter.discriminatorValues[0]', 'messageType'
+        ['0xF0' S7PayloadSetupCommunication]
+        ['0x04','0x01' S7PayloadReadVarRequest]
+        ['0x04','0x03' S7PayloadReadVarResponse
+            [arrayField S7VarPayloadDataItem 'items' count 'CAST(parameter, S7ParameterReadVarResponse).numItems']
+        ]
+        ['0x05','0x01' S7PayloadWriteVarRequest
+            [arrayField S7VarPayloadDataItem 'items' count 'COUNT(CAST(parameter, S7ParameterWriteVarRequest).items)']
+        ]
+        ['0x05','0x03' S7PayloadWriteVarResponse
+            [arrayField S7VarPayloadStatusItem 'items' count 'CAST(parameter, S7ParameterWriteVarResponse).numItems']
+        ]
+        ['0x00','0x07' S7PayloadUserData
+        ]
+    ]
+]
+
+[type 'S7VarPayloadDataItem'
+    [field      uint 8  'returnCode']
+    [field      uint 8  'transportSize']
+    [field      uint 16 'dataLength']
+    [arrayField uint 8  'data' count 'dataLength']
+]
+
+[type 'S7VarPayloadStatusItem'
+    [field uint 8 'returnCode']
+]
\ No newline at end of file