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/01/16 18:34:06 UTC

[incubator-plc4x] 02/02: - Added DFDL Schema for S7 Protocol.

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/incubator-plc4x.git

commit 0d03828c6b53408b2c97daca27935b3cbc5f2061
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Jan 16 19:34:00 2019 +0100

    - Added DFDL Schema for S7 Protocol.
---
 src/main/dfdl/s7-protocol.dfdl.xsd | 587 +++++++++++++++++++++++++++++++++++++
 1 file changed, 587 insertions(+)

diff --git a/src/main/dfdl/s7-protocol.dfdl.xsd b/src/main/dfdl/s7-protocol.dfdl.xsd
new file mode 100644
index 0000000..6e90a81
--- /dev/null
+++ b/src/main/dfdl/s7-protocol.dfdl.xsd
@@ -0,0 +1,587 @@
+<!--
+  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.
+  -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
+           xmlns:fn="http://www.w3.org/2005/xpath-functions"
+           xmlns:s7="http://plc4x.apache.org/s7"
+           targetNamespace="http://plc4x.apache.org/s7">
+
+    <xs:annotation>
+        <xs:appinfo source="http://www.ogf.org/dfdl/">
+            <dfdl:defineVariable name="messageType" type="xs:string"/>
+            <dfdl:format representation="binary"
+                         binaryNumberRep="binary"
+                         byteOrder="bigEndian"
+                         lengthKind="implicit" lengthUnits="bytes" length="0"
+                         occursCountKind="implicit"
+                         textOutputMinLength="0"
+                         alignment="1" alignmentUnits="bits"
+                         leadingSkip="0" trailingSkip="0"
+                         textPadKind="none" ignoreCase="no"
+                         encoding="utf-8" truncateSpecifiedLengthString="no"
+                         initiator="" terminator=""
+                         sequenceKind="ordered" separator=""
+                         escapeSchemeRef=""  initiatedContent="no"/>
+        </xs:appinfo>
+    </xs:annotation>
+
+    <!--
+
+        Simple type definition.
+
+    -->
+
+    <xs:simpleType name="bit" dfdl:lengthUnits="bits" dfdl:length="1" dfdl:lengthKind="explicit">
+        <xs:restriction base="xs:boolean" />
+    </xs:simpleType>
+
+    <xs:simpleType name="byte" dfdl:lengthUnits="bytes" dfdl:length="1" dfdl:lengthKind="explicit">
+        <xs:restriction base="xs:unsignedByte"/>
+    </xs:simpleType>
+
+    <xs:simpleType name="short" dfdl:lengthUnits="bytes" dfdl:length="2" dfdl:lengthKind="explicit">
+        <xs:restriction base="xs:unsignedShort"/>
+    </xs:simpleType>
+
+    <xs:simpleType name="hexByte" dfdl:lengthUnits="bytes" dfdl:length="1" dfdl:lengthKind="explicit">
+        <xs:restriction base="xs:hexBinary" />
+    </xs:simpleType>
+
+    <!--
+
+        S7 Types
+
+    -->
+
+    <xs:element name="S7Message">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- S7 Magic Byte always 0x32 -->
+                <xs:element name="magicByte" type="s7:byte">
+                    <xs:annotation>
+                        <xs:appinfo source="http://www.ogf.org/dfdl/">
+                            <dfdl:assert message="Magic number was not 0x32."
+                                         test="{. eq 50}" />
+                        </xs:appinfo>
+                    </xs:annotation>
+                </xs:element>
+                <xs:element name="type" type="s7:byte"/>
+                <!--
+                    Unfortunately the response for a CPU Functions request follows the rules of a
+                    response, however has the header structure of a request
+                    (no error code or error class). As mapping to the same type is not allowed,
+                    we map to strings and use that as choice-key.
+                -->
+                <xs:choice dfdl:choiceDispatchKey="{
+                                if(type eq 1) then 'request'
+                                else if(type eq 3) then 'response'
+                                else if(type eq 7) then 'response'
+                                else 'unknown'
+                            }">
+                    <xs:element dfdl:choiceBranchKey="request" ref="s7:S7RequestMessage"/>
+                    <xs:element dfdl:choiceBranchKey="response" ref="s7:S7ResponseMessage"/>
+                </xs:choice>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestMessage">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- Reserved value always 0x0000 -->
+                <xs:element name="reserved" type="s7:short" fixed="0"/>
+                <xs:element name="tpduReference" type="s7:short"/>
+                <xs:element name="parametersLength" type="s7:short"/>
+                <xs:element name="payloadsLength" type="s7:short"/>
+                <xs:element name="parameters" minOccurs="0"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{../parametersLength}"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../parametersLength gt 0) then 1 else 0}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="parameter" maxOccurs="unbounded">
+                                <xs:complexType>
+                                    <xs:sequence>
+                                        <xs:element name="type" type="s7:byte"/>
+                                        <xs:choice dfdl:choiceDispatchKey="{type}">
+                                            <xs:element dfdl:choiceBranchKey="240" ref="s7:S7GeneralParameterSetupCommunication"/>
+                                            <xs:element dfdl:choiceBranchKey="0" ref="s7:SS7RequestParameterCPUService"/>
+                                            <xs:element dfdl:choiceBranchKey="4" ref="s7:S7RequestParameterReadVar"/>
+                                            <xs:element dfdl:choiceBranchKey="5" ref="s7:S7RequestParameterWriteVar"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+                <!--
+                   As we might be outputting an empty payload block for a parameter that might not have a payload,
+                   we have to output this element if the parameters are not empty. The case that the payloads are
+                   not empty but the parameters are can't happen during normal operation.
+               -->
+                <xs:element name="payloads" minOccurs="0"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{../payloadsLength}"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../parametersLength gt 0) then 1 else 0}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <!--
+                                For every parameter we'll be outputting a payload block, even if this might be empty.
+                                This is required in order to find the matching parameter for every payload we might
+                                be having. We need to match these as otherwise we couldn't determin the type of a
+                                payload as this has no type information and we need to be able to access the number
+                                of items for a read/write request in order to process the correct number of items in
+                                the payload.
+                            -->
+                            <xs:element name="payload" maxOccurs="unbounded"
+                                        dfdl:occursCountKind="expression" dfdl:occursCount="{fn:count(../../parameters[1]/parameter)}">
+                                <xs:complexType>
+                                    <xs:sequence>
+                                        <xs:choice dfdl:choiceDispatchKey="{../../parameters[1]/parameter[dfdl:occursIndex()]/type}">
+                                            <xs:element dfdl:choiceBranchKey="240" ref="s7:S7GeneralPayloadSetupCommunication"/>
+                                            <xs:element dfdl:choiceBranchKey="0" ref="s7:S7RequestPayloadCpuServices"/>
+                                            <xs:element dfdl:choiceBranchKey="4" ref="s7:S7RequestPayloadReadVar"/>
+                                            <xs:element dfdl:choiceBranchKey="5" ref="s7:S7RequestPayloadWriteVar"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponseMessage">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- Reserved value always 0x0000 -->
+                <xs:element name="reserved" type="s7:short" fixed="0"/>
+                <xs:element name="tpduReference" type="s7:short"/>
+                <xs:element name="parametersLength" type="s7:short"/>
+                <xs:element name="payloadsLength" type="s7:short"/>
+                <!-- UserData (type 7) responses don't have the error class and code -->
+                <xs:element name="errorClass" type="s7:byte" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../../type eq 3) then 1 else 0}"/>
+                <xs:element name="errorCode" type="s7:byte" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../../type eq 3) then 1 else 0}"/>
+                <xs:element name="parameters" minOccurs="0"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{../parametersLength}"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../parametersLength gt 0) then 1 else 0}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="parameter" maxOccurs="unbounded">
+                                <xs:complexType>
+                                    <xs:sequence>
+                                        <xs:element name="type" type="s7:byte"/>
+                                        <xs:choice dfdl:choiceDispatchKey="{type}">
+                                            <xs:element dfdl:choiceBranchKey="240" ref="s7:S7GeneralParameterSetupCommunication"/>
+                                            <xs:element dfdl:choiceBranchKey="0" ref="s7:S7ResponseParameterCPUService"/>
+                                            <xs:element dfdl:choiceBranchKey="4" ref="s7:S7ResponseParameterReadVar"/>
+                                            <xs:element dfdl:choiceBranchKey="5" ref="s7:S7ResponseParameterWriteVar"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+                <!--
+                    As we might be outputting an empty payload block for a parameter that might not have a payload,
+                    we have to output this element if the parameters are not empty. The case that the payloads are
+                    not empty but the parameters are can't happen during normal operation.
+                -->
+                <xs:element name="payloads" minOccurs="0"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{../payloadsLength}"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../parametersLength gt 0) then 1 else 0}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <!--
+                                For every parameter we'll be outputting a payload block, even if this might be empty.
+                                This is required in order to find the matching parameter for every payload we might
+                                be having. We need to match these as otherwise we couldn't determin the type of a
+                                payload as this has no type information and we need to be able to access the number
+                                of items for a read/write request in order to process the correct number of items in
+                                the payload.
+                            -->
+                            <xs:element name="payload" maxOccurs="unbounded"
+                                        dfdl:occursCountKind="expression" dfdl:occursCount="{fn:count(../../parameters[1]/parameter)}">
+                                <xs:complexType>
+                                    <xs:sequence>
+                                        <xs:choice dfdl:choiceDispatchKey="{../../parameters[1]/parameter[dfdl:occursIndex()]/type}">
+                                            <xs:element dfdl:choiceBranchKey="240" ref="s7:S7GeneralPayloadSetupCommunication"/>
+                                            <xs:element dfdl:choiceBranchKey="0" ref="s7:S7ResponsePayloadCpuServices"/>
+                                            <xs:element dfdl:choiceBranchKey="4" ref="s7:S7ResponsePayloadReadVar"/>
+                                            <xs:element dfdl:choiceBranchKey="5" ref="s7:S7ResponsePayloadWriteVar"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <!--
+
+        Parameters.
+
+    -->
+
+    <xs:element name="S7GeneralParameterSetupCommunication">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- Reserved value always 0x00 -->
+                <xs:element name="reserved" type="s7:byte" fixed="0"/>
+                <xs:element name="maxAmqCaller" type="s7:short"/>
+                <xs:element name="maxAmqCallee" type="s7:short"/>
+                <xs:element name="pduLength" type="s7:short"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="SS7RequestParameterCPUService">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- Fixed header 0x0112 274 -> -->
+                <xs:element name="header" type="s7:short"/><!-- fixed="274"-->
+                <xs:element name="length" type="s7:byte"/><!-- fixed="4"-->
+                <!-- Request: 0x11 -> 17 -->
+                <xs:element name="typeCode" type="s7:byte"/><!-- fixed="17"-->
+                <!-- First 4 bits: Request 0x40, last 4 bits: Function Group 0x04 = 0x44 -> 68 -->
+                <xs:element name="functionGroup" type="s7:byte"/><!-- fixed="68"-->
+                <!-- READ SSL = 0x01 -->
+                <xs:element name="subFunctionGroup" type="s7:byte"/><!-- fixed="1"-->
+                <xs:element name="sequenceNumber" type="s7:byte"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponseParameterCPUService">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- Fixed header 0x0112 274 -> -->
+                <xs:element name="header" type="s7:short"/><!-- fixed="274"-->
+                <xs:element name="paramLength" type="s7:byte"/><!-- fixed="8"-->
+                <!-- Response: 0x12 -> 18 -->
+                <xs:element name="typeCode" type="s7:byte"/><!-- fixed="18"-->
+                <!-- First 4 bits: Response 0x80, last 4 bits: Function Group 0x04 = 0x84 -> 132 -->
+                <xs:element name="functionGroup" type="s7:byte"/><!-- fixed="132"-->
+                <!-- READ SSL = 0x01 -->
+                <xs:element name="subFunctionGroup" type="s7:byte"/><!-- fixed="1"-->
+                <xs:element name="sequenceNumber" type="s7:byte"/>
+                <xs:element name="dataUnitReferenceNumber" type="s7:byte"/>
+                <xs:element name="lastDataUnit" type="s7:byte"/>
+                <xs:element name="error" type="s7:short"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestParameterReadVar">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="numItems" type="s7:byte"/>
+                <xs:element name="items" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../numItems gt 0) then 1 else 0}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="item" minOccurs="0"
+                                        dfdl:occursCountKind="expression" dfdl:occursCount="{../../numItems}">
+                                <xs:complexType>
+                                    <xs:sequence>
+                                        <xs:element name="type" type="s7:byte"/>
+                                        <xs:choice dfdl:choiceDispatchKey="{type}">
+                                            <xs:element dfdl:choiceBranchKey="18" ref="s7:S7RequestParameterReadVarAnyItem"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestParameterReadVarAnyItem">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="paramLength" type="s7:byte"/><!-- fixed="10"-->
+                <!-- Addressing Mode: Any 0x10 -> 16 -->
+                <xs:element name="addressingMode" type="s7:byte"/><!-- fixed="16"-->
+                <xs:element name="dataType" type="s7:byte"/>
+                <xs:element name="numElements" type="s7:short"/>
+                <xs:element name="dataBlockNumber" type="s7:short"/>
+                <xs:element name="memoryArea" type="s7:byte"/>
+                <!--
+                 The next 3 bytes (24 bits) contain the byte- and bit-offset,
+                 were the last byte contains the bit-offset in the last 3 bits
+                 and the byteOffset is encoded in the higher level 21 bits
+                -->
+                <xs:element name="byteOffset" type="xs:unsignedInt"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="21"/>
+                <xs:element name="bitOffset" type="xs:unsignedInt"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="3"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponseParameterReadVar">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="numItems" type="s7:byte"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestParameterWriteVar">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="numItems" type="s7:byte"/>
+                <xs:element name="items" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{if(../numItems gt 0) then 1 else 0}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="item" minOccurs="0"
+                                        dfdl:occursCountKind="expression" dfdl:occursCount="{../../numItems}">
+                                <xs:complexType>
+                                    <xs:sequence>
+                                        <xs:element name="type" type="s7:byte"/>
+                                        <xs:choice dfdl:choiceDispatchKey="{type}">
+                                            <xs:element dfdl:choiceBranchKey="18" ref="s7:S7RequestParameterWriteVarAnyItem"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestParameterWriteVarAnyItem">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="itemLength" type="s7:byte"/><!-- fixed="10"-->
+                <!-- Addressing Mode: Any 0x10 -> 16 -->
+                <xs:element name="addressingMode" type="s7:byte"/><!-- fixed="16"-->
+                <xs:element name="dataType" type="s7:byte"/>
+                <xs:element name="numElements" type="s7:short"/>
+                <xs:element name="dataBlockNumber" type="s7:short"/>
+                <xs:element name="memoryArea" type="s7:byte"/>
+                <!--
+                 The next 3 bytes (24 bits) contain the byte- and bit-offset,
+                 were the last byte contains the bit-offset in the last 3 bits
+                 and the byteOffset is encoded in the higher level 21 bits
+                -->
+                <xs:element name="byteOffset" type="xs:unsignedInt"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="21"/>
+                <xs:element name="bitOffset" type="xs:unsignedInt"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bits" dfdl:length="3"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponseParameterWriteVar">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="numItems" type="s7:byte"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <!--
+
+        Payloads.
+
+    -->
+
+    <xs:element name="S7GeneralPayloadSetupCommunication" type="xs:byte" dfdl:lengthKind="explicit" dfdl:length="0"/>
+
+    <xs:element name="S7RequestPayloadCpuServices">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="transportSize" type="s7:byte"/><!-- fixed="9"-->
+                <xs:element name="length" type="s7:byte"/>
+                <xs:element name="sslId" type="s7:short"/>
+                <xs:element name="sslIndex" type="s7:short"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponsePayloadCpuServices">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="returnCode" type="s7:byte"/>
+                <!-- Transport Size: Octet String = 0x09 -> 9 -->
+                <xs:element name="transportSize" type="s7:byte"/><!-- fixed="9"-->
+                <xs:element name="length" type="s7:short"/>
+                <xs:element name="sslId" type="s7:short"/>
+                <xs:element name="sslIndex" type="s7:short"/>
+                <xs:element name="partialList" minOccurs="0"
+                            dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{../length - 4}"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{../length gt 4}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="partialListLengthInWords" type="s7:short"/>
+                            <xs:element name="partialListCount" type="s7:short"/>
+                            <xs:element name="sslDataRecords">
+                                <xs:complexType>
+                                    <xs:sequence dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="{../length - 8}">
+                                        <xs:choice>
+                                            <xs:element ref="s7:S7ResponsePayloadCpuServicesSslDataRecordModuleIdentification"/>
+                                        </xs:choice>
+                                    </xs:sequence>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponsePayloadCpuServicesSslDataRecordModuleIdentification">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="index" type="s7:short"/>
+                <xs:element name="articleNumber" type="xs:unsignedByte"
+                            dfdl:lengthUnits="bytes" dfdl:length="20" dfdl:lengthKind="explicit"/>
+                <xs:element name="bgType" type="s7:short"/>
+                <xs:element name="moduleOrOsVersion" type="s7:short"/>
+                <xs:element name="pgDescriptionFileVersion" type="s7:short"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestPayloadReadVar" type="xs:byte" dfdl:lengthKind="explicit" dfdl:length="0"/>
+
+    <xs:element name="S7ResponsePayloadReadVar">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- The number of items which should be read is transmitted in the matching parameter -->
+                <xs:element name="numItems" type="s7:byte"
+                            dfdl:inputValueCalc="{
+                                ../../../../parameters[1]/parameter[dfdl:occursIndex()]/s7:S7ResponseParameterReadVar/numItems
+                            }"/>
+                <xs:element name="item" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{../numItems}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="returnCode" type="s7:byte"/>
+                            <xs:element name="transportSize" type="s7:byte"/>
+                            <xs:element name="rawLength" type="s7:short"/>
+                            <!--
+                                For some reason the types BIT, BYTE_WORD_DWORD and INTEGER are transferred in "bits",
+                                the rest is transferred in "bytes"
+                            -->
+                            <xs:element name="lengthInBytes" type="s7:short" dfdl:inputValueCalc="{
+                                    if((../transportSize eq 3) or (../transportSize eq 4) or (../transportSize eq 5))
+                                            then fn:ceiling(../rawLength div 8)
+                                            else ../rawLength}"/>
+                            <xs:element name="data" type="xs:hexBinary"
+                                        dfdl:byteOrder="bigEndian" dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit"
+                                        dfdl:length="{../lengthInBytes}"/>
+                            <!--
+                                Transport sizes: BIT, BYTE_WORD_DWORD and OCTET_STRING require a blank byte.
+                                However only if this is not the last item in the result.
+                            -->
+                            <xs:element name="reserved" type="s7:byte" minOccurs="0"
+                                        dfdl:occursCountKind="expression" dfdl:occursCount="{
+                                            if(((../transportSize eq 3) or
+                                                (../transportSize eq 4) or
+                                                (../transportSize eq 9)) and
+                                                (dfdl:occursIndex() ne ../../numItems)) then 1 else 0}"/>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7RequestPayloadWriteVar">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- The number of items which should be read is transmitted in the matching parameter -->
+                <xs:element name="numItems" type="s7:byte"
+                            dfdl:inputValueCalc="{
+                                ../../../../parameters[1]/parameter[dfdl:occursIndex()]/s7:S7RequestParameterWriteVar/numItems
+                            }"/>
+                <xs:element name="item" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{../numItems}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="returnCode" type="s7:byte"/>
+                            <xs:element name="transportSize" type="s7:byte"/>
+                            <xs:element name="rawLength" type="s7:short"/>
+                            <!--
+                                For some reason the types BIT, BYTE_WORD_DWORD and INTEGER are transferred in "bits",
+                                the rest is transferred in "bytes"
+                            -->
+                            <xs:element name="lengthInBytes" type="s7:short" dfdl:inputValueCalc="{
+                                    if((../transportSize eq 3) or (../transportSize eq 4) or (../transportSize eq 5))
+                                            then fn:ceiling(../rawLength div 8)
+                                            else ../rawLength}"/>
+                            <xs:element name="data" type="xs:hexBinary"
+                                        dfdl:byteOrder="bigEndian" dfdl:lengthUnits="bytes" dfdl:lengthKind="explicit"
+                                        dfdl:length="{../lengthInBytes}"/>
+                            <!--
+                                Transport sizes: BIT, BYTE_WORD_DWORD and OCTET_STRING require a blank byte.
+                                However only if this is not the last item in the result.
+
+                                Actually the S7 device will never process data that contains more
+                                than one item in a write request, so this is rather a cosmetic fine-tuning.
+                            -->
+                            <xs:element name="reserved" type="s7:byte" minOccurs="0"
+                                        dfdl:occursCountKind="expression" dfdl:occursCount="{
+                                            if(((../transportSize eq 3) or
+                                                (../transportSize eq 4) or
+                                                (../transportSize eq 9)) and
+                                                (dfdl:occursIndex() ne ../../numItems)) then 1 else 0}"/>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="S7ResponsePayloadWriteVar">
+        <xs:complexType>
+            <xs:sequence>
+                <!-- The number of items which should be read is transmitted in the matching parameter -->
+                <xs:element name="numItems" type="s7:byte"
+                            dfdl:inputValueCalc="{
+                                ../../../../parameters[1]/parameter[dfdl:occursIndex()]/s7:S7ResponseParameterWriteVar/numItems
+                            }"/>
+                <xs:element name="item" minOccurs="0"
+                            dfdl:occursCountKind="expression" dfdl:occursCount="{../numItems}">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="returnCode" type="s7:byte"/>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+</xs:schema>
\ No newline at end of file