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 2022/05/05 17:28:06 UTC

[plc4x] branch develop updated: fix(knx): Fixed a problem in the mspec-generation which caused problems in decoding mainly floating-point values

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


The following commit(s) were added to refs/heads/develop by this push:
     new 375bff2c37 fix(knx): Fixed a problem in the mspec-generation which caused problems in decoding mainly floating-point values
375bff2c37 is described below

commit 375bff2c37c17b76ba44a5d4eb6d1637fae4c409
Author: cdutz <ch...@c-ware.de>
AuthorDate: Thu May 5 19:27:59 2022 +0200

    fix(knx): Fixed a problem in the mspec-generation which caused problems in decoding mainly floating-point values
---
 .../knxnetip/context/KnxNetIpDriverContext.java    |   2 +-
 .../knxnetip/protocol/KnxNetIpProtocolLogic.java   |  10 +-
 protocols/knxnetip/src/main/xslt/knx-types.xsl     | 111 ++++++++++++++-------
 3 files changed, 82 insertions(+), 41 deletions(-)

diff --git a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/context/KnxNetIpDriverContext.java b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/context/KnxNetIpDriverContext.java
index b09986622c..5ed2f2a827 100644
--- a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/context/KnxNetIpDriverContext.java
+++ b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/context/KnxNetIpDriverContext.java
@@ -126,7 +126,7 @@ public class KnxNetIpDriverContext implements DriverContext, HasConfiguration<Kn
         return tunnelConnectionType;
     }
 
-    public EtsModel getEts5Model() {
+    public EtsModel getEtsModel() {
         return etsModel;
     }
 
diff --git a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java
index e042a41a5b..0a82d408cd 100644
--- a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java
+++ b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java
@@ -271,7 +271,7 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
             final PlcValue value = request.getPlcValue(fieldName);
             byte dataFirstByte = 0;
             byte[] data = null;
-            final EtsModel etsModel = knxNetIpDriverContext.getEts5Model();
+            final EtsModel etsModel = knxNetIpDriverContext.getEtsModel();
             if (etsModel != null) {
                 final String destinationAddressString = etsModel.parseGroupAddress(destinationAddress);
                 final GroupAddress groupAddress = etsModel.getGroupAddresses().get(destinationAddressString);
@@ -282,7 +282,7 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
                     return future;
                 }
 
-                // Use the data in the ets5 model to correctly check and serialize the PlcValue
+                // Use the data in the ets model to correctly check and serialize the PlcValue
                 try {
                     final WriteBufferByteBased writeBuffer = new WriteBufferByteBased(KnxDatapoint.getLengthInBytes(value, groupAddress.getType()));
                     KnxDatapoint.staticSerialize(writeBuffer, value, groupAddress.getType());
@@ -461,9 +461,9 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
             KnxGroupAddress.staticParse(addressBuffer, knxNetIpDriverContext.getGroupAddressType());
         final String destinationAddress = toString(knxGroupAddress);
 
-        // If there is an ETS5 model provided, continue decoding the payload.
-        if (knxNetIpDriverContext.getEts5Model() != null) {
-            final EtsModel etsModel = knxNetIpDriverContext.getEts5Model();
+        // If there is an ETS model provided, continue decoding the payload.
+        if (knxNetIpDriverContext.getEtsModel() != null) {
+            final EtsModel etsModel = knxNetIpDriverContext.getEtsModel();
             final GroupAddress groupAddress = etsModel.getGroupAddresses().get(destinationAddress);
             final String areaName = etsModel.getTopologyName(destinationAddress.substring(
                 0, destinationAddress.indexOf('/')));
diff --git a/protocols/knxnetip/src/main/xslt/knx-types.xsl b/protocols/knxnetip/src/main/xslt/knx-types.xsl
index c1ed193874..c8ecf6e962 100644
--- a/protocols/knxnetip/src/main/xslt/knx-types.xsl
+++ b/protocols/knxnetip/src/main/xslt/knx-types.xsl
@@ -120,91 +120,114 @@
             [simple   bit    value]
         ]
         ['BYTE' BYTE
-            [simple   uint 8    value]
+            [reserved uint 8    '0x00']
+            [simple   uint 8    value ]
         ]
         ['WORD' WORD
+            [reserved uint 8    '0x00']
             [simple   uint 16    value]
         ]
         ['DWORD' DWORD
+            [reserved uint 8    '0x00']
             [simple   uint 32    value]
         ]
         ['LWORD' LWORD
+            [reserved uint 8    '0x00']
             [simple   uint 64    value]
         ]
         ['USINT' USINT
+            [reserved uint 8    '0x00']
             [simple   uint 8     value]
         ]
         ['SINT' SINT
+            [reserved uint 8    '0x00']
             [simple   int 8      value]
         ]
         ['UINT' UINT
+            [reserved uint 8    '0x00']
             [simple   uint 16    value]
         ]
         ['INT' INT
+            [reserved uint 8    '0x00']
             [simple   int 16     value]
         ]
         ['UDINT' UDINT
+            [reserved uint 8    '0x00']
             [simple   uint 32    value]
         ]
         ['DINT' DINT
+            [reserved uint 8    '0x00']
             [simple   int 32     value]
         ]
         ['ULINT' ULINT
+            [reserved uint 8    '0x00']
             [simple   uint 64    value]
         ]
         ['LINT' LINT
+            [reserved uint 8    '0x00']
             [simple   int 64     value]
         ]
         ['REAL' REAL
+            [reserved uint 8    '0x00']
             [simple   float 32 value]
         ]
         ['LREAL' LREAL
-            [simple   float 64 value]
+            [reserved uint 8    '0x00']
+            [simple   float 64  value ]
         ]
         ['CHAR' CHAR
-            [simple   uint 8     value]
+            [reserved uint 8    '0x00']
+            [simple   uint 8    value ]
         ]
         ['WCHAR' WCHAR
-            [simple   uint 16    value]
+            [reserved uint 8    '0x00']
+            [simple   uint 16   value ]
         ]
         //['STRING' STRING
         //]
         //['WSTRING' WSTRING
         //]
         ['TIME' TIME
-            [simple uint 32 value]
+            [reserved uint 8    '0x00']
+            [simple   uint 32   value ]
         ]
         ['LTIME' LTIME
-            [simple uint 64 value]
+            [reserved uint 8    '0x00']
+            [simple   uint 64   value ]
         ]
         ['DATE' DATE
-            [simple uint 16 value]
+            [reserved uint 8    '0x00']
+            [simple   uint 16   value ]
         ]
         ['TIME_OF_DAY' TIME_OF_DAY
-            [simple uint 32 value]
+            [reserved uint 8    '0x00']
+            [simple   uint 32   value ]
         ]
         ['TOD' TIME_OF_DAY
-            [simple uint 32 value]
+            [reserved uint 8    '0x00']
+            [simple   uint 32   value ]
         ]
         ['DATE_AND_TIME' DATE_AND_TIME
-            [simple uint 16 year]
-            [simple uint 8  month]
-            [simple uint 8  day]
-            [simple uint 8  dayOfWeek]
-            [simple uint 8  hour]
-            [simple uint 8  minutes]
-            [simple uint 8  seconds]
-            [simple uint 32 nanos]
+            [reserved uint 8  '0x00'   ]
+            [simple   uint 16 year     ]
+            [simple   uint 8  month    ]
+            [simple   uint 8  day      ]
+            [simple   uint 8  dayOfWeek]
+            [simple   uint 8  hour     ]
+            [simple   uint 8  minutes  ]
+            [simple   uint 8  seconds  ]
+            [simple   uint 32 nanos    ]
         ]
         ['DT' DATE_AND_TIME
-            [simple uint 16 year]
-            [simple uint 8  month]
-            [simple uint 8  day]
-            [simple uint 8  dayOfWeek]
-            [simple uint 8  hour]
-            [simple uint 8  minutes]
-            [simple uint 8  seconds]
-            [simple uint 32 nanos]
+            [reserved uint 8  '0x00'   ]
+            [simple   uint 16 year     ]
+            [simple   uint 8  month    ]
+            [simple   uint 8  day      ]
+            [simple   uint 8  dayOfWeek]
+            [simple   uint 8  hour     ]
+            [simple   uint 8  minutes  ]
+            [simple   uint 8  seconds  ]
+            [simple   uint 32 nanos    ]
         ]
 
     <xsl:for-each select="knx:KNX/knx:MasterData/knx:DatapointTypes/knx:DatapointType/knx:DatapointSubtypes/knx:DatapointSubtype">
@@ -387,9 +410,25 @@
                         <xsl:with-param name="fields" select="$resolvedFields/*"/>
                     </xsl:call-template>
                 </xsl:variable>
-                <xsl:if test="(($size mod 8) != 0) and (($size mod 8) &lt;= 6)">
-            [reserved uint <xsl:value-of select="8 - ($size mod 8)"/> '0x00']
-                </xsl:if>
+           // Field Size <xsl:value-of select="$size"/>
+                <xsl:choose>
+                    <!--
+                        If less or equal 6 bits are needed in the first byte, we can use the first byte.
+                        Also if a fully byte-aligned value is read, we need to discard the first byte fully.
+                    -->
+                    <xsl:when test="($size mod 8) &lt;= 6">
+           [reserved uint <xsl:value-of select="8 - ($size mod 8)"/> '0x00']
+
+                    </xsl:when>
+                    <!--
+                        If we're reading something that needs 7 bits from the first byte, we need to discard
+                        that and start reading from the second byte.
+                    -->
+                    <xsl:when test="($size mod 8) = 7">
+                        [reserved uint 9 '0x000']
+
+                    </xsl:when>
+                </xsl:choose>
                 <xsl:for-each select="$resolvedFields/*">
                     <xsl:variable name="fieldType">
                         <xsl:choose>
@@ -437,7 +476,7 @@
             </xsl:when>
             <xsl:when test="$datapointSubtype/knx:Format/knx:Bit">
             [reserved uint 7 '0x00']
-            [simple   bit    value]
+            [simple   bit    value ]
             </xsl:when>
             <xsl:when test="$datapointSubtype/knx:Format/knx:String">
                 <xsl:variable name="encoding">
@@ -446,25 +485,27 @@
                         <xsl:when test="$datapointSubtype/knx:Format/knx:String/@Encoding = 'iso-8859-1'">ISO-8859-1</xsl:when>
                     </xsl:choose>
                 </xsl:variable>
+            [reserved uint 8 '0x00']
             [simple   string <xsl:value-of select="$datapointSubtype/knx:Format/knx:String/@Width"/> value encoding='"<xsl:value-of select="$encoding"/>"']
             </xsl:when>
             <xsl:when test="$datapointSubtype/knx:Format/knx:UnsignedInteger">
                 <xsl:choose>
-                    <xsl:when test="fn:number($datapointSubtype/knx:Format/knx:UnsignedInteger/@Width) &lt; 6">
-            [reserved uint <xsl:value-of select="8 - fn:number($datapointSubtype/knx:Format/knx:UnsignedInteger/@Width)"/> '0x00']
+                    <xsl:when test="(fn:number($datapointSubtype/knx:Format/knx:UnsignedInteger/@Width) mod 8) &lt;= 6">
+            [reserved uint <xsl:value-of select="8 - (fn:number($datapointSubtype/knx:Format/knx:UnsignedInteger/@Width) mod 8)"/> '0x00']
                     </xsl:when>
                 </xsl:choose>
             [simple   uint <xsl:value-of select="$datapointSubtype/knx:Format/knx:UnsignedInteger/@Width"/> value]
             </xsl:when>
             <xsl:when test="$datapointSubtype/knx:Format/knx:SignedInteger">
                 <xsl:choose>
-                    <xsl:when test="fn:number($datapointSubtype/knx:Format/knx:SignedInteger/@Width) &lt; 6">
-            [reserved uint <xsl:value-of select="8 - fn:number($datapointSubtype/knx:Format/knx:SignedInteger/@Width)"/> '0x00']
+                    <xsl:when test="(fn:number($datapointSubtype/knx:Format/knx:SignedInteger/@Width) mod 8) &lt;= 6">
+            [reserved uint <xsl:value-of select="8 - (fn:number($datapointSubtype/knx:Format/knx:SignedInteger/@Width) mod 8)"/> '0x00']
                     </xsl:when>
                 </xsl:choose>
             [simple   int <xsl:value-of select="$datapointSubtype/knx:Format/knx:SignedInteger/@Width"/> value]
             </xsl:when>
             <xsl:when test="$datapointSubtype/knx:Format/knx:Float">
+            [reserved uint 8 '0x00']
                 <xsl:choose>
                     <xsl:when test="fn:number($datapointSubtype/knx:Format/knx:Float/@Width) = 16">
             [simple   float 16 value]
@@ -479,8 +520,8 @@
             </xsl:when>
             <xsl:when test="$datapointSubtype/knx:Format/knx:Enumeration">
                 <xsl:choose>
-                    <xsl:when test="fn:number($datapointSubtype/knx:Format/knx:Enumeration/@Width) &lt; 6">
-            [reserved uint <xsl:value-of select="8 - fn:number($datapointSubtype/knx:Format/knx:Enumeration/@Width)"/> '0x00']
+                    <xsl:when test="(fn:number($datapointSubtype/knx:Format/knx:Enumeration/@Width) mod 8) &lt;= 6">
+            [reserved uint <xsl:value-of select="8 - (fn:number($datapointSubtype/knx:Format/knx:Enumeration/@Width) mod 8)"/> '0x00']
                     </xsl:when>
                 </xsl:choose>
             [simple   uint <xsl:value-of select="$datapointSubtype/knx:Format/knx:Enumeration/@Width"/> value]