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